MCUXpresso_LPC55S69/devices/LPC55S69/drivers/fsl_hashcrypt.h

550 lines
20 KiB
C

/*
* Copyright 2017-2023 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef FSL_HASHCRYPT_H_
#define FSL_HASHCRYPT_H_
#include "fsl_common.h"
/*! @brief HASHCRYPT status return codes. */
enum _hashcrypt_status
{
kStatus_HASHCRYPT_Again =
MAKE_STATUS(kStatusGroup_HASHCRYPT, 0), /*!< Non-blocking function shall be called again. */
};
/*******************************************************************************
* Definitions
*******************************************************************************/
/*!
* @addtogroup hashcrypt_driver
* @{
*/
/*! @name Driver version */
/*! @{ */
/*! @brief HASHCRYPT driver version. Version 2.2.14.
*
* Current version: 2.2.14
*
* Change log:
* - Version 2.0.0
* - Initial version
* - Version 2.0.1
* - Support loading AES key from unaligned address
* - Version 2.0.2
* - Support loading AES key from unaligned address for different compiler and core variants
* - Version 2.0.3
* - Remove SHA512 and AES ICB algorithm definitions
* - Version 2.0.4
* - Add SHA context switch support
* - Version 2.1.0
* - Update the register name and macro to align with new header.
* - Version 2.1.1
* - Fix MISRA C-2012.
* - Version 2.1.2
* - Support loading AES input data from unaligned address.
* - Version 2.1.3
* - Fix MISRA C-2012.
* - Version 2.1.4
* - Fix context switch cannot work when switching from AES.
* - Version 2.1.5
* - Add data synchronization barrier inside hashcrypt_sha_ldm_stm_16_words()
* to prevent possible optimization issue.
* - Version 2.2.0
* - Add AES-OFB and AES-CFB mixed IP/SW modes.
* - Version 2.2.1
* - Add data synchronization barrier inside hashcrypt_sha_ldm_stm_16_words()
* prevent compiler from reordering memory write when -O2 or higher is used.
* - Version 2.2.2
* - Add data synchronization barrier inside hashcrypt_sha_ldm_stm_16_words()
* to fix optimization issue
* - Version 2.2.3
* - Added check for size in hashcrypt_aes_one_block to prevent overflowing COUNT field in MEMCTRL register, if its
* bigger than COUNT field do a multiple runs.
* - Version 2.2.4
* - In all HASHCRYPT_AES_xx functions have been added setting CTRL_MODE bitfield to 0 after processing data, which
* decreases power consumption.
* - Version 2.2.5
* - Add data synchronization barrier and instruction synchronization barrier inside
* hashcrypt_sha_process_message_data() to fix optimization issue
* - Version 2.2.6
* - Add data synchronization barrier inside HASHCRYPT_SHA_Update() and hashcrypt_get_data() function to fix
* optimization issue on MDK and ARMGCC release targets
* - Version 2.2.7
* - Add data synchronization barrier inside HASHCRYPT_SHA_Update() to fix optimization issue on MCUX IDE release
* target
* - Version 2.2.8
* - Unify hashcrypt hashing behavior between aligned and unaligned input data
* - Version 2.2.9
* - Add handling of set ERROR bit in the STATUS register
* - Version 2.2.10
* - Fix missing error statement in hashcrypt_save_running_hash()
* - Version 2.2.11
* - Fix incorrect SHA-256 calculation for long messages with reload
* - Version 2.2.12
* - Fix hardfault issue on the Keil compiler due to unaligned memcpy() input on some optimization levels
* - Version 2.2.13
* - Added function hashcrypt_seed_prng() which loading random number into PRNG_SEED register before AES operation for
* SCA protection
* - Version 2.2.14
* - Modify function hashcrypt_get_data() to prevent issue with unaligned access
*/
#define FSL_HASHCRYPT_DRIVER_VERSION (MAKE_VERSION(2, 2, 14))
/*! @} */
/*! @brief Algorithm definitions correspond with the values for Mode field in Control register !*/
#define HASHCRYPT_MODE_SHA1 0x1
#define HASHCRYPT_MODE_SHA256 0x2
#define HASHCRYPT_MODE_AES 0x4
/*! @brief Algorithm used for Hashcrypt operation */
typedef enum _hashcrypt_algo_t
{
kHASHCRYPT_Sha1 = HASHCRYPT_MODE_SHA1, /*!< SHA_1 */
kHASHCRYPT_Sha256 = HASHCRYPT_MODE_SHA256, /*!< SHA_256 */
kHASHCRYPT_Aes = HASHCRYPT_MODE_AES, /*!< AES */
} hashcrypt_algo_t;
/*! @} */
/*******************************************************************************
* AES Definitions
*******************************************************************************/
/*!
* @addtogroup hashcrypt_driver_aes
* @{
*/
/*! AES block size in bytes */
#define HASHCRYPT_AES_BLOCK_SIZE 16U
#define AES_ENCRYPT 0
#define AES_DECRYPT 1
/*! @brief AES mode */
typedef enum _hashcrypt_aes_mode_t
{
kHASHCRYPT_AesEcb = 0U, /*!< AES ECB mode */
kHASHCRYPT_AesCbc = 1U, /*!< AES CBC mode */
kHASHCRYPT_AesCtr = 2U, /*!< AES CTR mode */
} hashcrypt_aes_mode_t;
/*! @brief Size of AES key */
typedef enum _hashcrypt_aes_keysize_t
{
kHASHCRYPT_Aes128 = 0U, /*!< AES 128 bit key */
kHASHCRYPT_Aes192 = 1U, /*!< AES 192 bit key */
kHASHCRYPT_Aes256 = 2U, /*!< AES 256 bit key */
kHASHCRYPT_InvalidKey = 3U, /*!< AES invalid key */
} hashcrypt_aes_keysize_t;
/*! @brief HASHCRYPT key source selection.
*
*/
typedef enum _hashcrypt_key
{
kHASHCRYPT_UserKey = 0xc3c3U, /*!< HASHCRYPT user key */
kHASHCRYPT_SecretKey = 0x3c3cU, /*!< HASHCRYPT secret key (dedicated hw bus from PUF) */
} hashcrypt_key_t;
/*! @brief Specify HASHCRYPT's key resource. */
struct _hashcrypt_handle
{
uint32_t keyWord[8]; /*!< Copy of user key (set by HASHCRYPT_AES_SetKey(). */
hashcrypt_aes_keysize_t keySize;
hashcrypt_key_t keyType; /*!< For operations with key (such as AES encryption/decryption), specify key type. */
} __attribute__((aligned));
typedef struct _hashcrypt_handle hashcrypt_handle_t;
/*!
*@}
*/ /* end of hashcrypt_driver_aes */
/*******************************************************************************
* HASH Definitions
******************************************************************************/
/*!
* @addtogroup hashcrypt_driver_hash
* @{
*/
/*! @brief HASHCRYPT HASH Context size. */
#if defined(FSL_FEATURE_HASHCRYPT_HAS_RELOAD_FEATURE) && (FSL_FEATURE_HASHCRYPT_HAS_RELOAD_FEATURE > 0)
#define HASHCRYPT_HASH_CTX_SIZE 30
#else
#define HASHCRYPT_HASH_CTX_SIZE 22
#endif
/*! @brief Storage type used to save hash context. */
typedef struct _hashcrypt_hash_ctx_t
{
uint32_t x[HASHCRYPT_HASH_CTX_SIZE]; /*!< storage */
} hashcrypt_hash_ctx_t;
/*! @brief HASHCRYPT background hash callback function. */
typedef void (*hashcrypt_callback_t)(HASHCRYPT_Type *base, hashcrypt_hash_ctx_t *ctx, status_t status, void *userData);
/*!
*@}
*/ /* end of hashcrypt_driver_hash */
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @addtogroup hashcrypt_driver
* @{
*/
/*!
* @brief Enables clock and disables reset for HASHCRYPT peripheral.
*
* Enable clock and disable reset for HASHCRYPT.
*
* @param base HASHCRYPT base address
*/
void HASHCRYPT_Init(HASHCRYPT_Type *base);
/*!
* @brief Disables clock for HASHCRYPT peripheral.
*
* Disable clock and enable reset.
*
* @param base HASHCRYPT base address
*/
void HASHCRYPT_Deinit(HASHCRYPT_Type *base);
/*!
*@}
*/ /* end of hashcrypt_driver */
/*******************************************************************************
* AES API
******************************************************************************/
/*!
* @addtogroup hashcrypt_driver_aes
* @{
*/
/*!
* @brief Set AES key to hashcrypt_handle_t struct and optionally to HASHCRYPT.
*
* Sets the AES key for encryption/decryption with the hashcrypt_handle_t structure.
* The hashcrypt_handle_t input argument specifies key source.
*
* @param base HASHCRYPT peripheral base address.
* @param handle Handle used for the request.
* @param key 0-mod-4 aligned pointer to AES key.
* @param keySize AES key size in bytes. Shall equal 16, 24 or 32.
* @return status from set key operation
*/
status_t HASHCRYPT_AES_SetKey(HASHCRYPT_Type *base, hashcrypt_handle_t *handle, const uint8_t *key, size_t keySize);
/*!
* @brief Encrypts AES on one or multiple 128-bit block(s).
*
* Encrypts AES.
* The source plaintext and destination ciphertext can overlap in system memory.
*
* @param base HASHCRYPT peripheral base address
* @param handle Handle used for this request.
* @param plaintext Input plain text to encrypt
* @param[out] ciphertext Output cipher text
* @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
* @return Status from encrypt operation
*/
status_t HASHCRYPT_AES_EncryptEcb(
HASHCRYPT_Type *base, hashcrypt_handle_t *handle, const uint8_t *plaintext, uint8_t *ciphertext, size_t size);
/*!
* @brief Decrypts AES on one or multiple 128-bit block(s).
*
* Decrypts AES.
* The source ciphertext and destination plaintext can overlap in system memory.
*
* @param base HASHCRYPT peripheral base address
* @param handle Handle used for this request.
* @param ciphertext Input plain text to encrypt
* @param[out] plaintext Output cipher text
* @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
* @return Status from decrypt operation
*/
status_t HASHCRYPT_AES_DecryptEcb(
HASHCRYPT_Type *base, hashcrypt_handle_t *handle, const uint8_t *ciphertext, uint8_t *plaintext, size_t size);
/*!
* @brief Encrypts AES using CBC block mode.
*
* @param base HASHCRYPT peripheral base address
* @param handle Handle used for this request.
* @param plaintext Input plain text to encrypt
* @param[out] ciphertext Output cipher text
* @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
* @param iv Input initial vector to combine with the first input block.
* @return Status from encrypt operation
*/
status_t HASHCRYPT_AES_EncryptCbc(HASHCRYPT_Type *base,
hashcrypt_handle_t *handle,
const uint8_t *plaintext,
uint8_t *ciphertext,
size_t size,
const uint8_t iv[16]);
/*!
* @brief Decrypts AES using CBC block mode.
*
* @param base HASHCRYPT peripheral base address
* @param handle Handle used for this request.
* @param ciphertext Input cipher text to decrypt
* @param[out] plaintext Output plain text
* @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
* @param iv Input initial vector to combine with the first input block.
* @return Status from decrypt operation
*/
status_t HASHCRYPT_AES_DecryptCbc(HASHCRYPT_Type *base,
hashcrypt_handle_t *handle,
const uint8_t *ciphertext,
uint8_t *plaintext,
size_t size,
const uint8_t iv[16]);
/*!
* @brief Encrypts or decrypts AES using CTR block mode.
*
* Encrypts or decrypts AES using CTR block mode.
* AES CTR mode uses only forward AES cipher and same algorithm for encryption and decryption.
* The only difference between encryption and decryption is that, for encryption, the input argument
* is plain text and the output argument is cipher text. For decryption, the input argument is cipher text
* and the output argument is plain text.
*
* @param base HASHCRYPT peripheral base address
* @param handle Handle used for this request.
* @param input Input data for CTR block mode
* @param[out] output Output data for CTR block mode
* @param size Size of input and output data in bytes
* @param[in,out] counter Input counter (updates on return)
* @param[out] counterlast Output cipher of last counter, for chained CTR calls (statefull encryption). NULL can be
* passed if chained calls are
* not used.
* @param[out] szLeft Output number of bytes in left unused in counterlast block. NULL can be passed if chained calls
* are not used.
* @return Status from encrypt operation
*/
status_t HASHCRYPT_AES_CryptCtr(HASHCRYPT_Type *base,
hashcrypt_handle_t *handle,
const uint8_t *input,
uint8_t *output,
size_t size,
uint8_t counter[HASHCRYPT_AES_BLOCK_SIZE],
uint8_t counterlast[HASHCRYPT_AES_BLOCK_SIZE],
size_t *szLeft);
/*!
* @brief Encrypts or decrypts AES using OFB block mode.
*
* Encrypts or decrypts AES using OFB block mode.
* AES OFB mode uses only forward AES cipher and same algorithm for encryption and decryption.
* The only difference between encryption and decryption is that, for encryption, the input argument
* is plain text and the output argument is cipher text. For decryption, the input argument is cipher text
* and the output argument is plain text.
*
* @param base HASHCRYPT peripheral base address
* @param handle Handle used for this request.
* @param input Input data for OFB block mode
* @param[out] output Output data for OFB block mode
* @param size Size of input and output data in bytes
* @param iv Input initial vector to combine with the first input block.
* @return Status from encrypt operation
*/
status_t HASHCRYPT_AES_CryptOfb(HASHCRYPT_Type *base,
hashcrypt_handle_t *handle,
const uint8_t *input,
uint8_t *output,
size_t size,
const uint8_t iv[HASHCRYPT_AES_BLOCK_SIZE]);
/*!
* @brief Encrypts AES using CFB block mode.
*
* @param base HASHCRYPT peripheral base address
* @param handle Handle used for this request.
* @param plaintext Input plain text to encrypt
* @param[out] ciphertext Output cipher text
* @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
* @param iv Input initial vector to combine with the first input block.
* @return Status from encrypt operation
*/
status_t HASHCRYPT_AES_EncryptCfb(HASHCRYPT_Type *base,
hashcrypt_handle_t *handle,
const uint8_t *plaintext,
uint8_t *ciphertext,
size_t size,
const uint8_t iv[16]);
/*!
* @brief Decrypts AES using CFB block mode.
*
* @param base HASHCRYPT peripheral base address
* @param handle Handle used for this request.
* @param ciphertext Input cipher text to decrypt
* @param[out] plaintext Output plaintext text
* @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
* @param iv Input initial vector to combine with the first input block.
* @return Status from encrypt operation
*/
status_t HASHCRYPT_AES_DecryptCfb(HASHCRYPT_Type *base,
hashcrypt_handle_t *handle,
const uint8_t *ciphertext,
uint8_t *plaintext,
size_t size,
const uint8_t iv[16]);
/*!
*@}
*/ /* end of hashcrypt_driver_aes */
/*******************************************************************************
* HASH API
******************************************************************************/
/*!
* @addtogroup hashcrypt_driver_hash
* @{
*/
/*!
* @brief Create HASH on given data
*
* Perform the full SHA in one function call. The function is blocking.
*
* @param base HASHCRYPT peripheral base address
* @param algo Underlaying algorithm to use for hash computation.
* @param input Input data
* @param inputSize Size of input data in bytes
* @param[out] output Output hash data
* @param[out] outputSize Output parameter storing the size of the output hash in bytes
* @return Status of the one call hash operation.
*/
status_t HASHCRYPT_SHA(HASHCRYPT_Type *base,
hashcrypt_algo_t algo,
const uint8_t *input,
size_t inputSize,
uint8_t *output,
size_t *outputSize);
/*!
* @brief Initialize HASH context
*
* This function initializes the HASH.
*
* @param base HASHCRYPT peripheral base address
* @param[out] ctx Output hash context
* @param algo Underlaying algorithm to use for hash computation.
* @return Status of initialization
*/
status_t HASHCRYPT_SHA_Init(HASHCRYPT_Type *base, hashcrypt_hash_ctx_t *ctx, hashcrypt_algo_t algo);
/*!
* @brief Add data to current HASH
*
* Add data to current HASH. This can be called repeatedly with an arbitrary amount of data to be
* hashed. The functions blocks. If it returns kStatus_Success, the running hash
* has been updated (HASHCRYPT has processed the input data), so the memory at \p input pointer
* can be released back to system. The HASHCRYPT context buffer is updated with the running hash
* and with all necessary information to support possible context switch.
*
* @param base HASHCRYPT peripheral base address
* @param[in,out] ctx HASH context
* @param input Input data
* @param inputSize Size of input data in bytes
* @return Status of the hash update operation
*/
status_t HASHCRYPT_SHA_Update(HASHCRYPT_Type *base, hashcrypt_hash_ctx_t *ctx, const uint8_t *input, size_t inputSize);
/*!
* @brief Finalize hashing
*
* Outputs the final hash (computed by HASHCRYPT_HASH_Update()) and erases the context.
*
* @param base HASHCRYPT peripheral base address
* @param[in,out] ctx Input hash context
* @param[out] output Output hash data
* @param[in,out] outputSize Optional parameter (can be passed as NULL). On function entry, it specifies the size of
* output[] buffer. On function return, it stores the number of updated output bytes.
* @return Status of the hash finish operation
*/
status_t HASHCRYPT_SHA_Finish(HASHCRYPT_Type *base, hashcrypt_hash_ctx_t *ctx, uint8_t *output, size_t *outputSize);
/*!
*@}
*/ /* end of hashcrypt_driver_hash */
/*!
* @addtogroup hashcrypt_background_driver_hash
* @{
*/
/*!
* @brief Initializes the HASHCRYPT handle for background hashing.
*
* This function initializes the hash context for background hashing
* (Non-blocking) APIs. This is less typical interface to hash function, but can be used
* for parallel processing, when main CPU has something else to do.
* Example is digital signature RSASSA-PKCS1-V1_5-VERIFY((n,e),M,S) algorithm, where
* background hashing of M can be started, then CPU can compute S^e mod n
* (in parallel with background hashing) and once the digest becomes available,
* CPU can proceed to comparison of EM with EM'.
*
* @param base HASHCRYPT peripheral base address.
* @param[out] ctx Hash context.
* @param callback Callback function.
* @param userData User data (to be passed as an argument to callback function, once callback is invoked from isr).
*/
void HASHCRYPT_SHA_SetCallback(HASHCRYPT_Type *base,
hashcrypt_hash_ctx_t *ctx,
hashcrypt_callback_t callback,
void *userData);
/*!
* @brief Create running hash on given data.
*
* Configures the HASHCRYPT to compute new running hash as AHB master
* and returns immediately. HASHCRYPT AHB Master mode supports only aligned \p input
* address and can be called only once per continuous block of data. Every call to this function
* must be preceded with HASHCRYPT_SHA_Init() and finished with HASHCRYPT_SHA_Finish().
* Once callback function is invoked by HASHCRYPT isr, it should set a flag
* for the main application to finalize the hashing (padding) and to read out the final digest
* by calling HASHCRYPT_SHA_Finish().
*
* @param base HASHCRYPT peripheral base address
* @param ctx Specifies callback. Last incomplete 512-bit block of the input is copied into clear buffer for padding.
* @param input 32-bit word aligned pointer to Input data.
* @param inputSize Size of input data in bytes (must be word aligned)
* @return Status of the hash update operation.
*/
status_t HASHCRYPT_SHA_UpdateNonBlocking(HASHCRYPT_Type *base,
hashcrypt_hash_ctx_t *ctx,
const uint8_t *input,
size_t inputSize);
/*!
*@}
*/ /* end of hashcrypt_background_driver_hash */
#if defined(__cplusplus)
}
#endif
#endif /* FSL_HASHCRYPT_H_ */