/***************************************************************************//**
* @file
* @brief Silicon Labs Secure Engine Manager API.
*******************************************************************************
* # License
* Copyright 2020 Silicon Laboratories Inc. www.silabs.com
*******************************************************************************
*
* SPDX-License-Identifier: Zlib
*
* The licensor of this software is Silicon Laboratories Inc.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
******************************************************************************/
#ifndef SL_SE_MANAGER_CIPHER_H
#define SL_SE_MANAGER_CIPHER_H
#include "em_device.h"
#if defined(SEMAILBOX_PRESENT) || defined(DOXYGEN)
/// @addtogroup sl_se_manager
/// @{
/***************************************************************************//**
* @addtogroup sl_se_manager_cipher Cipher
*
* @brief
* Symmetric encryption, AEAD and MAC.
*
* @details
* API for performing symmetric encryption, Authenticated Encryption and
* Additional Data (AEAD) operations, and computing Message Authentication
* Codes (MACs) using the Secure Engine.
*
* @{
******************************************************************************/
#include "sl_se_manager_key_handling.h"
#include "sl_se_manager_types.h"
#include "em_se.h"
#include "sl_status.h"
#include
#include
#include
#ifdef __cplusplus
extern "C" {
#endif
// -----------------------------------------------------------------------------
// Prototypes
/***************************************************************************//**
* @brief
* AES-ECB block encryption/decryption.
*
* @param[in] cmd_ctx
* Pointer to an SE command context object.
*
* @param[in] key
* Pointer to sl_se_key_descriptor_t structure.
*
* @param[in] mode
* Crypto operation type (encryption or decryption).
*
* @param[in] length
* Length of the input data.
*
* @param[in] input
* Buffer holding the input data.
*
* @param[out] output
* Buffer holding the output data.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_aes_crypt_ecb(sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key,
sl_se_cipher_operation_t mode,
size_t length,
const unsigned char *input,
unsigned char *output);
/***************************************************************************//**
* @brief
* AES-CBC buffer encryption/decryption.
*
* @note
* Length should be a multiple of the block size (16 bytes).
*
* @param[in] cmd_ctx
* Pointer to an SE command context object.
*
* @param[in] key
* Pointer to sl_se_key_descriptor_t structure.
*
* @param[in] mode
* Crypto operation type (encryption or decryption).
*
* @param[in] length
* Length of the input data.
*
* @param[in,out] iv
* Initialization vector (updated after use).
*
* @param[in] input
* Buffer holding the input data.
*
* @param[out] output
* Buffer holding the output data.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_aes_crypt_cbc(sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key,
sl_se_cipher_operation_t mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output);
/***************************************************************************//**
* @brief
* AES-CFB128 buffer encryption/decryption.
*
* @param[in] cmd_ctx
* Pointer to an SE command context object.
*
* @param[in] key
* Pointer to sl_se_key_descriptor_t structure.
*
* @param[in] mode
* Crypto operation type (encryption or decryption).
*
* @param[in] length
* Length of the input data.
*
* @param[in,out] iv_off
* Offset in IV (updated after use).
*
* @param[in,out] iv
* Initialization vector (updated after use).
*
* @param[in] input
* Buffer holding the input data.
*
* @param[out] output
* Buffer holding the output data.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_aes_crypt_cfb128(sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key,
sl_se_cipher_operation_t mode,
size_t length,
uint32_t *iv_off,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output);
/***************************************************************************//**
* @brief
* AES-CFB8 buffer encryption/decryption.
*
* @param[in] cmd_ctx
* Pointer to an SE command context object.
*
* @param[in] key
* Pointer to sl_se_key_descriptor_t structure.
*
* @param[in] mode
* Crypto operation type (encryption or decryption).
*
* @param[in] length
* Length of the input data.
*
* @param[in,out] iv
* Initialization vector (updated after use).
*
* @param[in] input
* Buffer holding the input data.
*
* @param[out] output
* Buffer holding the output data.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_aes_crypt_cfb8(sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key,
sl_se_cipher_operation_t mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output);
/***************************************************************************//**
* @brief
* AES-CTR buffer encryption/decryption.
*
* @param[in] cmd_ctx
* Pointer to an SE command context object.
*
* @param[in] key
* Pointer to sl_se_key_descriptor_t structure.
*
* @param[in] length
* Length of the input data.
*
* @param[in] nc_off
* The offset in the current stream_block (for resuming
* within current cipher stream). The offset pointer to
* should be 0 at the start of a stream.
*
* @param[in,out] nonce_counter
* The 128-bit nonce and counter.
*
* @param[in,out] stream_block
* The saved stream-block for resuming (updated after use).
*
* @param[in] input
* Buffer holding the input data.
*
* @param[out] output
* Buffer holding the output data.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_aes_crypt_ctr(sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key,
size_t length,
uint32_t *nc_off,
unsigned char nonce_counter[16],
unsigned char stream_block[16],
const unsigned char *input,
unsigned char *output);
/***************************************************************************//**
* @brief
* AES-CCM buffer encryption.
*
* @param[in] cmd_ctx
* Pointer to an SE command context object.
*
* @param[in] key
* Pointer to sl_se_key_descriptor_t structure.
*
* @param[in] length
* The length of the input data in Bytes.
*
* @param[in] iv
* Initialization vector (nonce).
*
* @param[in] iv_len
* The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13.
*
* @param[in] add
* The additional data field.
*
* @param[in] add_len
* The length of additional data in Bytes.
*
* @param[in] input
* The buffer holding the input data.
*
* @param[out] output
* The buffer holding the output data. Must be at least @p length Bytes wide.
*
* @param[in,out] tag
* The buffer holding the tag.
*
* @param[in] tag_len
* The length of the tag to generate in Bytes: 4, 6, 8, 10, 12, 14 or 16.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_ccm_encrypt_and_tag(sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key,
size_t length,
const unsigned char *iv, size_t iv_len,
const unsigned char *add, size_t add_len,
const unsigned char *input,
unsigned char *output,
unsigned char *tag, size_t tag_len);
/***************************************************************************//**
* @brief
* AES-CCM buffer decryption.
*
* @param[in] cmd_ctx
* Pointer to an SE command context object.
*
* @param[in] key
* Pointer to sl_se_key_descriptor_t structure.
*
* @param[in] length
* The length of the input data in Bytes.
*
* @param[in] iv
* Initialization vector.
*
* @param[in] iv_len
* The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13.
*
* @param[in] add
* The additional data field.
*
* @param[in] add_len
* The length of additional data in Bytes.
*
* @param[in] input
* The buffer holding the input data.
*
* @param[out] output
* The buffer holding the output data. Must be at least @p length Bytes wide.
*
* @param[in] tag
* The buffer holding the tag.
*
* @param[in] tag_len
* The length of the tag in Bytes. Must be 4, 6, 8, 10, 12, 14 or 16.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_ccm_auth_decrypt(sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key,
size_t length,
const unsigned char *iv, size_t iv_len,
const unsigned char *add, size_t add_len,
const unsigned char *input,
unsigned char *output,
const unsigned char *tag, size_t tag_len);
/***************************************************************************//**
* @brief
* Prepare a CCM streaming command context object.
*
* @details
* Prepare a CCM streaming command context object to be used in subsequent
* CCM streaming function calls.
*
* @param[in] ccm_ctx
* Pointer to a CCM streaming context object.
*
* @param[in] cmd_ctx
* Pointer to a SE command context object.
*
* @param[in] key
* Pointer to sl_se_key_descriptor_t structure.
*
* @param[in] mode
* The operation to perform: SL_SE_ENCRYPT or SL_SE_DECRYPT.
*
* @param[in] total_message_length
* The total length of the text to encrypt/decrypt
*
* @param[in] iv
* The initialization vector (commonly referred to as nonce for CCM).
*
* @param[in] iv_len
* The length of the IV.
*
* @param[in] add
* The buffer holding the additional data.
*
* @param[in] add_len
* The length of the additional data.
*
* @param[in] tag_len
* Encryption: The length of the tag to generate. Must be 0, 4, 6, 8, 10, 12, 14 or 16.
* Decryption: The length of the tag to authenticate. Must be 0, 4, 6, 8, 10, 12, 14 or 16.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_ccm_multipart_starts(sl_se_ccm_multipart_context_t *ccm_ctx,
sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key,
sl_se_cipher_operation_t mode,
uint32_t total_message_length,
const uint8_t *iv,
size_t iv_len,
const uint8_t *add,
size_t add_len,
size_t tag_len);
/***************************************************************************//**
* @brief
* This function feeds an input buffer into an ongoing CCM computation.
*
* It is called between sl_se_ccm_multipart_starts() and sl_se_ccm_multipart_finish().
* Can be called repeatedly.
*
* @param[in] ccm_ctx
* Pointer to a CCM streaming context object.
*
* @param[in] cmd_ctx
* Pointer to a SE command context object.
*
* @param[in] key
* Pointer to sl_se_key_descriptor_t structure.
*
* @param[in] length
* The length of the input data. This must be a multiple of 16 except in
* the last call before sl_se_ccm_multipart_finish().
*
* @param[in] input
* Buffer holding the input data, must be at least @p length bytes wide.
*
* @param[out] output
* Buffer for holding the output data, must be at least @p length bytes wide.
*
* @param[out] output_length
* Length of data that has been encrypted/decrypted.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_ccm_multipart_update(sl_se_ccm_multipart_context_t *ccm_ctx,
sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key,
size_t length,
const uint8_t *input,
uint8_t *output,
size_t *output_length);
/***************************************************************************//**
* @brief
* Finish a CCM streaming operation and return the resulting CCM tag.
*
* It is called after sl_se_ccm_multipart_update().
*
* @param[in] ccm_ctx
* Pointer to a CCM streaming context object.
*
* @param[in] cmd_ctx
* Pointer to an SE command context object.
*
* @param[in] key
* Pointer to sl_se_key_descriptor_t structure.
*
* @param[in, out] tag
* Encryption: The buffer for holding the tag.
* Decryption: The tag to authenticate.
*
* @param[in] tag_size
* The size of the tag buffer. Must be equal or greater to the length of the expected tag.
*
* @param[out] output
* Buffer for holding the output data.
*
* @param[in] output_size
* Output buffer size. Must be equal or greater to the stored data from
* sl_se_ccm_multipart_update (maximum 16 bytes).
*
* @param[out] output_length
* Length of data that has been encrypted/decrypted.
*
* @return
* Returns SL_SE_INVALID_SIGNATURE if authentication step fails.
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_ccm_multipart_finish(sl_se_ccm_multipart_context_t *ccm_ctx,
sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key,
uint8_t *tag,
uint8_t tag_size,
uint8_t *output,
uint8_t output_size,
uint8_t *output_length);
/***************************************************************************//**
* @brief
* This function performs GCM encryption or decryption of a buffer.
*
* @note
* For encryption, the output buffer can be the same as the input buffer.
* For decryption, the output buffer cannot be the same as input buffer.
* If the buffers overlap, the output buffer must trail at least 8 bytes
* behind the input buffer.
*
* @warning
* When this function performs a decryption, it outputs the authentication
* tag and does not verify that the data is authentic. You should use this
* function to perform encryption only. For decryption, use
* sl_se_gcm_auth_decrypt() instead.
*
* @param[in] cmd_ctx
* Pointer to an SE command context object.
*
* @param[in] key
* Pointer to sl_se_key_descriptor_t structure.
*
* @param[in] mode
* Crypto operation type (encryption or decryption).
* - SL_SE_ENCRYPT: The ciphertext is written to @p output and the
* authentication tag is written to @p tag.
* - SL_SE_DECRYPT: The plaintext is written to @p output and the
* authentication tag is written to @p tag.
* Note that this mode is not recommended, because it does
* not verify the authenticity of the data. For this
* reason, you should use sl_se_gcm_auth_decrypt() instead.
*
* @param[in] length
* The length of the input data, which is equal to the length of the output
* data.
*
* @param[in] iv
* The initialization vector.
*
* @param[in] iv_len
* The length of the iv. Must be @b 12 bytes.
*
* @param[in] add
* The buffer holding the additional data.
*
* @param[in] add_len
* The length of the additional data in bytes.
*
* @param[in] input
* The buffer holding the input data. Its size is @b length bytes.
*
* @param[out] output
* The buffer for holding the output data. It must have room for @b length
* bytes.
*
* @param[in] tag_len
* The length of the tag to generate (in bytes).
*
* @param[out] tag
* The buffer for holding the tag.
*
* @return
* SL_STATUS_OK when the command was executed successfully, otherwise an
* appropriate error code (@ref sl_status.h).
******************************************************************************/
sl_status_t sl_se_gcm_crypt_and_tag(sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key,
sl_se_cipher_operation_t mode,
size_t length,
const unsigned char *iv,
size_t iv_len,
const unsigned char *add,
size_t add_len,
const unsigned char *input,
unsigned char *output,
size_t tag_len,
unsigned char *tag);
/***************************************************************************//**
* @brief
* This function performs a GCM authenticated decryption of a buffer.
*
* @note
* The output buffer cannot be the same as input buffer. If the buffers
* overlap, the output buffer must trail at least 8 bytes behind the input
* buffer.
*
* @param[in] cmd_ctx
* Pointer to an SE command context object.
*
* @param[in] key
* Pointer to sl_se_key_descriptor_t structure.
*
* @param[in] length
* The length of the ciphertext to decrypt, which is also the length of the
* decrypted plaintext.
*
* @param[in] iv
* The initialization vector.
*
* @param[in] iv_len
* The length of the iv. Must be @b 12 bytes.
*
* @param[in] add
* The buffer holding the additional data.
*
* @param[in] add_len
* The length of the additional data in bytes.
*
* @param[in] tag
* The buffer holding the tag to verify.
*
* @param[in] tag_len
* The length of the tag to verify (in bytes).
*
* @param[in] input
* The buffer holding the ciphertext. Its size is @b length bytes.
*
* @param[out] output
* The buffer for holding the decrypted plaintext. It must have room for
* @b length bytes.
*
* @return
* SL_STATUS_OK when the command was executed successfully, otherwise an
* appropriate error code (@ref sl_status.h).
******************************************************************************/
sl_status_t sl_se_gcm_auth_decrypt(sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key,
size_t length,
const unsigned char *iv,
size_t iv_len,
const unsigned char *add,
size_t add_len,
const unsigned char *input,
unsigned char *output,
size_t tag_len,
const unsigned char *tag);
/***************************************************************************//**
* @brief
* This function calculates the full generic CMAC on the input buffer with
* the provided key.
*
* @param[in] cmd_ctx
* Pointer to an SE command context object.
*
* @param[in] key
* Pointer to sl_se_key_descriptor_t structure.
*
* @param[in] input
* Buffer holding the input data, must be at least @p input_len bytes wide.
*
* @param[in] input_len
* The length of the input data in bytes.
*
* @param[out] output
* Buffer holding the 16-byte output data, must be at least 16 bytes wide.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_cmac(sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key,
const unsigned char *input,
size_t input_len,
unsigned char *output);
/***************************************************************************//**
* @brief
* Prepare a CMAC streaming command context object.
*
* @details
* Prepare a CMAC streaming command context object to be used in subsequent
* CMAC streaming function calls.
*
* @param[in] cmac_ctx
* Pointer to a CMAC streaming context object.
*
* @param[in] cmd_ctx
* Pointer to an SE command context object.
*
* @param[in] key
* Pointer to sl_se_key_descriptor_t structure.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_cmac_multipart_starts(sl_se_cmac_multipart_context_t *cmac_ctx,
sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key);
/***************************************************************************//**
* @brief
* Deprecated, please switch to using \ref sl_se_cmac_multipart_starts().
*
* Prepare a CMAC streaming command context object.
*
* @details
* Prepare a CMAC streaming command context object to be used in subsequent
* CMAC streaming function calls.
*
* @param[in] cmac_ctx
* Pointer to a CMAC streaming context object.
*
* @param[in] cmd_ctx
* Pointer to an SE command context object.
*
* @param[in] key
* Pointer to sl_se_key_descriptor_t structure.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_cmac_starts(sl_se_cmac_streaming_context_t *cmac_ctx,
sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key) SL_DEPRECATED_API_SDK_3_3;
/***************************************************************************//**
* @brief
* This function feeds an input buffer into an ongoing CMAC computation.
*
* @details
* It is called between sl_se_cmac_multipart_starts() and sl_se_cmac_multipart_finish().
* Can be called repeatedly.
*
* @param[in,out] cmac_ctx
* Pointer to a CMAC streaming context object.
*
* @param[in] cmd_ctx
* Pointer to an SE command context object.
*
* @param[in] key
* Pointer to sl_se_key_descriptor_t structure.
*
* @param[in] input
* Buffer holding the input data, must be at least @p input_len bytes wide.
*
* @param[in] input_len
* The length of the input data in bytes.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_cmac_multipart_update(sl_se_cmac_multipart_context_t *cmac_ctx,
sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key,
const uint8_t *input,
size_t input_len);
/***************************************************************************//**
* @brief
* Deprecated, please switch to using \ref sl_se_cmac_multipart_update().
*
* This function feeds an input buffer into an ongoing CMAC computation.
*
* @details
* It is called between sl_se_cmac_multipart_starts() and sl_se_cmac_multipart_finish().
* Can be called repeatedly.
*
* @param[in,out] cmac_ctx
* Pointer to a CMAC streaming context object.
*
* @param[in] input
* Buffer holding the input data, must be at least @p input_len bytes wide.
*
* @param[in] input_len
* The length of the input data in bytes.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_cmac_update(sl_se_cmac_streaming_context_t *cmac_ctx,
const uint8_t *input,
size_t input_len) SL_DEPRECATED_API_SDK_3_3;
/***************************************************************************//**
* @brief
* Finish a CMAC streaming operation and return the resulting CMAC tag.
*
* @details
* It is called after sl_se_cmac_multipart_update().
*
* @param[in,out] cmac_ctx
* Pointer to a CMAC streaming context object.
*
* @param[in] cmd_ctx
* Pointer to an SE command context object.
*
* @param[in] key
* Pointer to sl_se_key_descriptor_t structure.
*
* @param[out] output
* Buffer holding the 16-byte CMAC tag, must be at least 16 bytes wide.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_cmac_multipart_finish(sl_se_cmac_multipart_context_t *cmac_ctx,
sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key,
uint8_t *output);
/***************************************************************************//**
* @brief
* Deprecated, please switch to using \ref sl_se_cmac_multipart_finish().
*
* Finish a CMAC streaming operation and return the resulting CMAC tag.
*
* @details
* It is called after sl_se_cmac_update().
*
* @param[in,out] cmac_ctx
* Pointer to a CMAC streaming context object.
*
* @param[out] output
* Buffer holding the 16-byte CMAC tag, must be at least 16 bytes wide.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_cmac_finish(sl_se_cmac_streaming_context_t *cmac_ctx,
uint8_t *output) SL_DEPRECATED_API_SDK_3_3;
/***************************************************************************//**
* @brief
* Deprecated, please switch to using \ref sl_se_gcm_multipart_starts().
*
* Prepare a GCM streaming command context object.
* @details
* Prepare a GCM streaming command context object to be used in subsequent
* GCM streaming function calls.
*
* @param[in] gcm_ctx
* Pointer to a GCM streaming context object.
*
* @param[in] cmd_ctx
* Pointer to an SE command context object.
*
* @param[in] key
* Pointer to sl_se_key_descriptor_t structure.
*
* @param mode
* The operation to perform: SL_SE_ENCRYPT or SL_SE_DECRYPT.
*
* @param iv
* The initialization vector.
*
* @param iv_len
* The length of the IV.
*
* @param add
* The buffer holding the additional data, or NULL if @p add_len is 0.
*
* @param add_len
* The length of the additional data. If 0, @p add is NULL.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_gcm_starts(sl_se_gcm_streaming_context_t *gcm_ctx,
sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key,
sl_se_cipher_operation_t mode,
const uint8_t *iv,
size_t iv_len,
const uint8_t *add,
size_t add_len) SL_DEPRECATED_API_SDK_3_3;
/***************************************************************************//**
* @brief
* Prepare a GCM streaming command context object.
*
* @details
* Prepare a GCM streaming command context object to be used in subsequent
* GCM streaming function calls.
*
* @param[in, out] gcm_ctx
* Pointer to a GCM streaming context object.
*
* @param[in] cmd_ctx
* Pointer to an SE command context object.
*
* @param[in] key
* Pointer to sl_se_key_descriptor_t structure.
*
* @param[in] mode
* The operation to perform: SL_SE_ENCRYPT or SL_SE_DECRYPT.
*
* @param[in] iv
* The initialization vector.
*
* @param[in] iv_len
* The length of the IV.
*
* @param[in] add
* The buffer holding the additional data, or NULL if @p add_len is 0.
*
* @param[in] add_len
* The length of the additional data. If 0, @p add is NULL.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_gcm_multipart_starts(sl_se_gcm_multipart_context_t *gcm_ctx,
sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key,
sl_se_cipher_operation_t mode,
const uint8_t *iv,
size_t iv_len,
const uint8_t *add,
size_t add_len);
/***************************************************************************//**
* @brief
* Deprecated, please switch to using \ref sl_se_gcm_multipart_update().
*
* This function feeds an input buffer into an ongoing GCM computation.
*
* It is called between sl_se_gcm_starts() and sl_se_gcm_finish().
* Can be called repeatedly.
*
* @param[in] gcm_ctx
* Pointer to a GCM streaming context object.
*
* @param[in] length
* The length of the input data. This must be a multiple of 16 except in
* the last call before sl_se_gcm_finish().
*
* @param[in] input
* Buffer holding the input data, must be at least @p length bytes wide.
*
* @param[out] output
* Buffer for holding the output data, must be at least @p length bytes wide.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_gcm_update(sl_se_gcm_streaming_context_t *gcm_ctx,
size_t length,
const uint8_t *input,
uint8_t *output) SL_DEPRECATED_API_SDK_3_3;
/***************************************************************************//**
* @brief
* This function feeds an input buffer into an ongoing GCM computation.
*
* It is called between sl_se_gcm_multipart_starts() and sl_se_gcm_multiapart_finish().
* Can be called repeatedly.
*
* @param[in, out] gcm_ctx
* Pointer to a GCM streaming context object.
*
* @param[in] length
* The length of the input data.
*
* @param[in] input
* Buffer holding the input data, must be at least @p length bytes wide.
*
* @param[out] output
* Buffer for holding the output data, must be at least @p length bytes wide.
*
* @param[out] output_length
* Length of data that has been encrypted/decrypted.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_gcm_multipart_update(sl_se_gcm_multipart_context_t *gcm_ctx,
sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key,
size_t length,
const uint8_t *input,
uint8_t *output,
size_t *output_length);
/***************************************************************************//**
* @brief
* Deprecated, please switch to using \ref sl_se_gcm_multipart_finish().
*
* Finish a GCM streaming operation and return the resulting GCM tag.
*
* It is called after sl_se_gcm_update().
*
* @param[in] gcm_ctx
* Pointer to a GCM streaming context object.
*
* @param[out] tag
* The buffer for holding the tag.
*
* @param[in] tag_len
* The length of the tag to generate. Must be at least four.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_gcm_finish(sl_se_gcm_streaming_context_t *gcm_ctx,
uint8_t *tag,
size_t tag_len) SL_DEPRECATED_API_SDK_3_3;
/***************************************************************************//**
* @brief
* Finish a GCM streaming operation and return the resulting GCM tag.
*
* It is called after sl_se_gcm_multipart_update().
*
* @param[in, out] gcm_ctx
* Pointer to a GCM streaming context object.
*
* @param[in, out] tag
* Encryption: The buffer for holding the tag.
* Decryption: The tag to authenticate.
*
* @param[in] tag_length
* Encryption: Length of the output tag.
* Decryption: Length of tag to verify
*
* @param[out] output
* Buffer for holding the output data.
*
* @param[in] output_size
* Output buffer size. Must be equal or greater to the stored data from
* sl_se_gcm_multipart_update (stored data is maximum 16 bytes).
*
* @param[out] output_length
* Length of data that has been encrypted/decrypted.
*
* @return
* Returns SL_SE_INVALID_SIGNATURE if authentication step fails.
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_gcm_multipart_finish(sl_se_gcm_multipart_context_t *gcm_ctx,
sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key,
uint8_t *tag,
uint8_t tag_length,
uint8_t *output,
uint8_t output_size,
uint8_t *output_length);
/***************************************************************************//**
* @brief
* Compute a HMAC on a full message.
*
* @details
* This function computes a Keyed-Hashed Message Authentication Code (HMAC)
* for the given input message. HMAC can be used with any iterative
* cryptographic hash function, e.g., SHA-1 in combination with a
* secret shared key. The cryptographic strength of HMAC depends on the
* properties of the underlying hash function. For instance, if the algorithm
* is chosen to be SHA-256, it will generate a 32 bytes HMAC.
* This function supports SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512.
* The key can be of any length. If the key is shorter than the block size
* of the hash function the SE will append zeros to the key so the key size
* matches the block size of the hash function. If the key is longer than the
* block size of the hash function the key will be hashed to
* produce a key digest, then append zeros so the resulting 'hashed' key size
* matches the block size of the hash function. In any case the minimal
* recommended key length is the digest size of the hash function.
*
* @param[in] cmd_ctx
* Pointer to an SE command context object.
*
* @param[in] key
* Pointer to sl_se_key_descriptor_t structure specifying the key to use in
* the HMAC computation.
*
* @param[in] hash_type
* Which hashing algorithm to use.
*
* @param[in] message
* Pointer to the message buffer to compute the hash/digest from.
*
* @param[in] message_len
* Number of bytes in message.
*
* @param[out] output
* Pointer to memory buffer to store the final HMAC output.
*
* @param[in] output_len
* The length of the HMAC output memory buffer, must be at least the size
* of the corresponding hash type.
*
* @return Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_hmac(sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key,
sl_se_hash_type_t hash_type,
const uint8_t *message,
size_t message_len,
uint8_t *output,
size_t output_len);
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT) || defined(DOXYGEN)
/***************************************************************************//**
* @brief
* ChaCha20 buffer encryption/decryption, as defined by RFC8439 section 2.4.
*
* @param[in] cmd_ctx
* Pointer to an SE command context object.
*
* @param[in] mode
* Crypto operation type (encryption or decryption).
*
* @param[in] key
* Pointer to sl_se_key_descriptor_t structure.
*
* @param[in] length
* Length of the input data.
*
* @param[in] initial_counter
* The initial counter value as defined in RFC8439 section 2.4.
*
* @param[in] nonce
* The nonce, also called initialisation vector, as defined in RFC8439 section
* 2.4.
*
* @param[in] input
* Buffer holding the input data.
*
* @param[out] output
* Buffer holding the output data.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_chacha20_crypt(sl_se_command_context_t *cmd_ctx,
sl_se_cipher_operation_t mode,
const sl_se_key_descriptor_t *key,
size_t length,
const unsigned char initial_counter[4],
const unsigned char nonce[12],
const unsigned char *input,
unsigned char *output);
/***************************************************************************//**
* @brief
* ChaCha20-Poly1305 authenticated encryption with additional data, as defined
* by RFC8439 section 2.8.
*
* @param[in] cmd_ctx
* Pointer to an SE command context object.
*
* @param[in] key
* Pointer to sl_se_key_descriptor_t structure.
*
* @param[in] length
* The length of the input data in bytes.
*
* @param[in] nonce
* The nonce, also called initialisation vector, as defined in RFC8439 section
* 2.8.
*
* @param[in] add
* The buffer holding additional authenticated data. Can be NULL if @p add_len
* equals 0.
*
* @param[in] add_len
* The length of the additional authenticated data in bytes.
*
* @param[in] input
* The buffer holding the plaintext input.
*
* @param[out] output
* The buffer holding the ciphertext output. Can be NULL, in which case the
* generated ciphertext will be discarded. Must be at least @p length bytes
* wide.
*
* @param[out] tag
* The buffer holding the tag. This function will produce a 128-bit tag, so
* this buffer must be at least 16 bytes wide. Can be NULL, in which case the
* generated tag will be discarded.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_chacha20_poly1305_encrypt_and_tag(sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key,
size_t length,
const unsigned char nonce[12],
const unsigned char *add, size_t add_len,
const unsigned char *input,
unsigned char *output,
unsigned char *tag);
/***************************************************************************//**
* @brief
* ChaCha20-Poly1305 authenticated decryption with additional data, as defined
* by RFC8439 section 2.8.
*
* @param[in] cmd_ctx
* Pointer to an SE command context object.
*
* @param[in] key
* Pointer to sl_se_key_descriptor_t structure.
*
* @param[in] length
* The length of the input data in Bytes.
*
* @param[in] nonce
* The nonce, also called initialisation vector, as defined in RFC8439 section
* 2.8.
*
* @param[in] add
* The buffer holding additional authenticated data. Can be NULL if @p add_len
* equals 0.
*
* @param[in] add_len
* The length of the additional authenticated data in bytes.
*
* @param[in] input
* The buffer holding the ciphertext to decrypt. Can be NULL if @p length
* equals 0.
*
* @param[out] output
* The buffer holding the plaintext output. Can be NULL, in which case the
* decrypted plaintext will be discarded, or when @p length equals 0. Must be
* at least @p length bytes wide.
*
* @param[in] tag
* The buffer holding the tag to verify.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_chacha20_poly1305_auth_decrypt(sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key,
size_t length,
const unsigned char nonce[12],
const unsigned char *add, size_t add_len,
const unsigned char *input,
unsigned char *output,
const unsigned char tag[16]);
/***************************************************************************//**
* @brief
* Generate a Poly1305 MAC (message authentication code) for a given message
* using an ephemeral key derived using ChaCha20.
*
* @note
* This function first derives a Poly1305 key based on a ChaCha20 key and
* nonce, which are input to this function. The key derivation adheres to
* RFC8439 section 2.6. The derived key is then used to calculate a MAC of the
* input data, according to RFC8439 section 2.5.
*
* @param[in] cmd_ctx
* Pointer to an SE command context object.
*
* @param[in] key
* Pointer to sl_se_key_descriptor_t structure containing a ChaCha20 key.
*
* @param[in] length
* The length of the input data in Bytes.
*
* @param[in] nonce
* The nonce, also called initialisation vector, as defined in RFC8439 section
* 2.6.
*
* @param[in] input
* The buffer holding the input data.
*
* @param[out] tag
* The buffer holding the tag. This function will produce a 128-bit tag, so
* this buffer must be at least 16 bytes wide.
*
* @return
* Status code, @ref sl_status.h.
******************************************************************************/
sl_status_t sl_se_poly1305_genkey_tag(sl_se_command_context_t *cmd_ctx,
const sl_se_key_descriptor_t *key,
size_t length,
const unsigned char nonce[12],
const unsigned char *input,
unsigned char *tag);
#endif // (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
#ifdef __cplusplus
}
#endif
/// @} (end addtogroup sl_se_manager_cipher)
/// @} (end addtogroup sl_se_manager)
#endif // defined(SEMAILBOX_PRESENT)
#endif // SL_SE_MANAGER_CIPHER_H