1 /* 2 * Copyright 2017-2024 NXP 3 * All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 #ifndef FSL_HASHCRYPT_H_ 8 #define FSL_HASHCRYPT_H_ 9 10 #include "fsl_common.h" 11 12 /*! @brief HASHCRYPT status return codes. */ 13 enum _hashcrypt_status 14 { 15 kStatus_HASHCRYPT_Again = 16 MAKE_STATUS(kStatusGroup_HASHCRYPT, 0), /*!< Non-blocking function shall be called again. */ 17 }; 18 19 /******************************************************************************* 20 * Definitions 21 *******************************************************************************/ 22 23 /*! 24 * @addtogroup hashcrypt_driver 25 * @{ 26 */ 27 /*! @name Driver version */ 28 /*! @{ */ 29 /*! @brief HASHCRYPT driver version. Version 2.2.15. 30 * 31 * Current version: 2.2.15 32 * 33 * Change log: 34 * - Version 2.0.0 35 * - Initial version 36 * - Version 2.0.1 37 * - Support loading AES key from unaligned address 38 * - Version 2.0.2 39 * - Support loading AES key from unaligned address for different compiler and core variants 40 * - Version 2.0.3 41 * - Remove SHA512 and AES ICB algorithm definitions 42 * - Version 2.0.4 43 * - Add SHA context switch support 44 * - Version 2.1.0 45 * - Update the register name and macro to align with new header. 46 * - Version 2.1.1 47 * - Fix MISRA C-2012. 48 * - Version 2.1.2 49 * - Support loading AES input data from unaligned address. 50 * - Version 2.1.3 51 * - Fix MISRA C-2012. 52 * - Version 2.1.4 53 * - Fix context switch cannot work when switching from AES. 54 * - Version 2.1.5 55 * - Add data synchronization barrier inside hashcrypt_sha_ldm_stm_16_words() 56 * to prevent possible optimization issue. 57 * - Version 2.2.0 58 * - Add AES-OFB and AES-CFB mixed IP/SW modes. 59 * - Version 2.2.1 60 * - Add data synchronization barrier inside hashcrypt_sha_ldm_stm_16_words() 61 * prevent compiler from reordering memory write when -O2 or higher is used. 62 * - Version 2.2.2 63 * - Add data synchronization barrier inside hashcrypt_sha_ldm_stm_16_words() 64 * to fix optimization issue 65 * - Version 2.2.3 66 * - Added check for size in hashcrypt_aes_one_block to prevent overflowing COUNT field in MEMCTRL register, if its 67 * bigger than COUNT field do a multiple runs. 68 * - Version 2.2.4 69 * - In all HASHCRYPT_AES_xx functions have been added setting CTRL_MODE bitfield to 0 after processing data, which 70 * decreases power consumption. 71 * - Version 2.2.5 72 * - Add data synchronization barrier and instruction synchronization barrier inside 73 * hashcrypt_sha_process_message_data() to fix optimization issue 74 * - Version 2.2.6 75 * - Add data synchronization barrier inside HASHCRYPT_SHA_Update() and hashcrypt_get_data() function to fix 76 * optimization issue on MDK and ARMGCC release targets 77 * - Version 2.2.7 78 * - Add data synchronization barrier inside HASHCRYPT_SHA_Update() to fix optimization issue on MCUX IDE release 79 * target 80 * - Version 2.2.8 81 * - Unify hashcrypt hashing behavior between aligned and unaligned input data 82 * - Version 2.2.9 83 * - Add handling of set ERROR bit in the STATUS register 84 * - Version 2.2.10 85 * - Fix missing error statement in hashcrypt_save_running_hash() 86 * - Version 2.2.11 87 * - Fix incorrect SHA-256 calculation for long messages with reload 88 * - Version 2.2.12 89 * - Fix hardfault issue on the Keil compiler due to unaligned memcpy() input on some optimization levels 90 * - Version 2.2.13 91 * - Added function hashcrypt_seed_prng() which loading random number into PRNG_SEED register before AES operation for 92 * SCA protection 93 * - Version 2.2.14 94 * - Modify function hashcrypt_get_data() to prevent issue with unaligned access 95 * - Version 2.2.15 96 * - Add wait on DIGEST BIT inside hashcrypt_sha_one_block() to fix issues with some optimization flags 97 */ 98 #define FSL_HASHCRYPT_DRIVER_VERSION (MAKE_VERSION(2, 2, 15)) 99 /*! @} */ 100 101 /*! @brief Algorithm definitions correspond with the values for Mode field in Control register !*/ 102 #define HASHCRYPT_MODE_SHA1 0x1 103 #define HASHCRYPT_MODE_SHA256 0x2 104 #define HASHCRYPT_MODE_AES 0x4 105 106 /*! @brief Algorithm used for Hashcrypt operation */ 107 typedef enum _hashcrypt_algo_t 108 { 109 kHASHCRYPT_Sha1 = HASHCRYPT_MODE_SHA1, /*!< SHA_1 */ 110 kHASHCRYPT_Sha256 = HASHCRYPT_MODE_SHA256, /*!< SHA_256 */ 111 kHASHCRYPT_Aes = HASHCRYPT_MODE_AES, /*!< AES */ 112 } hashcrypt_algo_t; 113 114 /*! @} */ 115 116 /******************************************************************************* 117 * AES Definitions 118 *******************************************************************************/ 119 120 /*! 121 * @addtogroup hashcrypt_driver_aes 122 * @{ 123 */ 124 125 /*! AES block size in bytes */ 126 #define HASHCRYPT_AES_BLOCK_SIZE 16U 127 #define AES_ENCRYPT 0 128 #define AES_DECRYPT 1 129 130 /*! @brief AES mode */ 131 typedef enum _hashcrypt_aes_mode_t 132 { 133 kHASHCRYPT_AesEcb = 0U, /*!< AES ECB mode */ 134 kHASHCRYPT_AesCbc = 1U, /*!< AES CBC mode */ 135 kHASHCRYPT_AesCtr = 2U, /*!< AES CTR mode */ 136 } hashcrypt_aes_mode_t; 137 138 /*! @brief Size of AES key */ 139 typedef enum _hashcrypt_aes_keysize_t 140 { 141 kHASHCRYPT_Aes128 = 0U, /*!< AES 128 bit key */ 142 kHASHCRYPT_Aes192 = 1U, /*!< AES 192 bit key */ 143 kHASHCRYPT_Aes256 = 2U, /*!< AES 256 bit key */ 144 kHASHCRYPT_InvalidKey = 3U, /*!< AES invalid key */ 145 } hashcrypt_aes_keysize_t; 146 147 /*! @brief HASHCRYPT key source selection. 148 * 149 */ 150 typedef enum _hashcrypt_key 151 { 152 kHASHCRYPT_UserKey = 0xc3c3U, /*!< HASHCRYPT user key */ 153 kHASHCRYPT_SecretKey = 0x3c3cU, /*!< HASHCRYPT secret key (dedicated hw bus from PUF) */ 154 } hashcrypt_key_t; 155 156 /*! @brief Specify HASHCRYPT's key resource. */ 157 struct _hashcrypt_handle 158 { 159 uint32_t keyWord[8]; /*!< Copy of user key (set by HASHCRYPT_AES_SetKey(). */ 160 hashcrypt_aes_keysize_t keySize; 161 hashcrypt_key_t keyType; /*!< For operations with key (such as AES encryption/decryption), specify key type. */ 162 } __attribute__((aligned)); 163 164 typedef struct _hashcrypt_handle hashcrypt_handle_t; 165 166 /*! 167 *@} 168 */ /* end of hashcrypt_driver_aes */ 169 170 /******************************************************************************* 171 * HASH Definitions 172 ******************************************************************************/ 173 /*! 174 * @addtogroup hashcrypt_driver_hash 175 * @{ 176 */ 177 178 /*! @brief HASHCRYPT HASH Context size. */ 179 #if defined(FSL_FEATURE_HASHCRYPT_HAS_RELOAD_FEATURE) && (FSL_FEATURE_HASHCRYPT_HAS_RELOAD_FEATURE > 0) 180 #define HASHCRYPT_HASH_CTX_SIZE 30 181 #else 182 #define HASHCRYPT_HASH_CTX_SIZE 22 183 #endif 184 185 /*! @brief Storage type used to save hash context. */ 186 typedef struct _hashcrypt_hash_ctx_t 187 { 188 uint32_t x[HASHCRYPT_HASH_CTX_SIZE]; /*!< storage */ 189 } hashcrypt_hash_ctx_t; 190 191 /*! @brief HASHCRYPT background hash callback function. */ 192 typedef void (*hashcrypt_callback_t)(HASHCRYPT_Type *base, hashcrypt_hash_ctx_t *ctx, status_t status, void *userData); 193 194 /*! 195 *@} 196 */ /* end of hashcrypt_driver_hash */ 197 198 /******************************************************************************* 199 * API 200 ******************************************************************************/ 201 #if defined(__cplusplus) 202 extern "C" { 203 #endif 204 205 /*! 206 * @addtogroup hashcrypt_driver 207 * @{ 208 */ 209 210 /*! 211 * @brief Enables clock and disables reset for HASHCRYPT peripheral. 212 * 213 * Enable clock and disable reset for HASHCRYPT. 214 * 215 * @param base HASHCRYPT base address 216 */ 217 void HASHCRYPT_Init(HASHCRYPT_Type *base); 218 219 /*! 220 * @brief Disables clock for HASHCRYPT peripheral. 221 * 222 * Disable clock and enable reset. 223 * 224 * @param base HASHCRYPT base address 225 */ 226 void HASHCRYPT_Deinit(HASHCRYPT_Type *base); 227 228 /*! 229 *@} 230 */ /* end of hashcrypt_driver */ 231 232 /******************************************************************************* 233 * AES API 234 ******************************************************************************/ 235 236 /*! 237 * @addtogroup hashcrypt_driver_aes 238 * @{ 239 */ 240 241 /*! 242 * @brief Set AES key to hashcrypt_handle_t struct and optionally to HASHCRYPT. 243 * 244 * Sets the AES key for encryption/decryption with the hashcrypt_handle_t structure. 245 * The hashcrypt_handle_t input argument specifies key source. 246 * 247 * @param base HASHCRYPT peripheral base address. 248 * @param handle Handle used for the request. 249 * @param key 0-mod-4 aligned pointer to AES key. 250 * @param keySize AES key size in bytes. Shall equal 16, 24 or 32. 251 * @return status from set key operation 252 */ 253 status_t HASHCRYPT_AES_SetKey(HASHCRYPT_Type *base, hashcrypt_handle_t *handle, const uint8_t *key, size_t keySize); 254 255 /*! 256 * @brief Encrypts AES on one or multiple 128-bit block(s). 257 * 258 * Encrypts AES. 259 * The source plaintext and destination ciphertext can overlap in system memory. 260 * 261 * @param base HASHCRYPT peripheral base address 262 * @param handle Handle used for this request. 263 * @param plaintext Input plain text to encrypt 264 * @param[out] ciphertext Output cipher text 265 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. 266 * @return Status from encrypt operation 267 */ 268 status_t HASHCRYPT_AES_EncryptEcb( 269 HASHCRYPT_Type *base, hashcrypt_handle_t *handle, const uint8_t *plaintext, uint8_t *ciphertext, size_t size); 270 271 /*! 272 * @brief Decrypts AES on one or multiple 128-bit block(s). 273 * 274 * Decrypts AES. 275 * The source ciphertext and destination plaintext can overlap in system memory. 276 * 277 * @param base HASHCRYPT peripheral base address 278 * @param handle Handle used for this request. 279 * @param ciphertext Input plain text to encrypt 280 * @param[out] plaintext Output cipher text 281 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. 282 * @return Status from decrypt operation 283 */ 284 status_t HASHCRYPT_AES_DecryptEcb( 285 HASHCRYPT_Type *base, hashcrypt_handle_t *handle, const uint8_t *ciphertext, uint8_t *plaintext, size_t size); 286 287 /*! 288 * @brief Encrypts AES using CBC block mode. 289 * 290 * @param base HASHCRYPT peripheral base address 291 * @param handle Handle used for this request. 292 * @param plaintext Input plain text to encrypt 293 * @param[out] ciphertext Output cipher text 294 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. 295 * @param iv Input initial vector to combine with the first input block. 296 * @return Status from encrypt operation 297 */ 298 status_t HASHCRYPT_AES_EncryptCbc(HASHCRYPT_Type *base, 299 hashcrypt_handle_t *handle, 300 const uint8_t *plaintext, 301 uint8_t *ciphertext, 302 size_t size, 303 const uint8_t iv[16]); 304 305 /*! 306 * @brief Decrypts AES using CBC block mode. 307 * 308 * @param base HASHCRYPT peripheral base address 309 * @param handle Handle used for this request. 310 * @param ciphertext Input cipher text to decrypt 311 * @param[out] plaintext Output plain text 312 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. 313 * @param iv Input initial vector to combine with the first input block. 314 * @return Status from decrypt operation 315 */ 316 status_t HASHCRYPT_AES_DecryptCbc(HASHCRYPT_Type *base, 317 hashcrypt_handle_t *handle, 318 const uint8_t *ciphertext, 319 uint8_t *plaintext, 320 size_t size, 321 const uint8_t iv[16]); 322 323 /*! 324 * @brief Encrypts or decrypts AES using CTR block mode. 325 * 326 * Encrypts or decrypts AES using CTR block mode. 327 * AES CTR mode uses only forward AES cipher and same algorithm for encryption and decryption. 328 * The only difference between encryption and decryption is that, for encryption, the input argument 329 * is plain text and the output argument is cipher text. For decryption, the input argument is cipher text 330 * and the output argument is plain text. 331 * 332 * @param base HASHCRYPT peripheral base address 333 * @param handle Handle used for this request. 334 * @param input Input data for CTR block mode 335 * @param[out] output Output data for CTR block mode 336 * @param size Size of input and output data in bytes 337 * @param[in,out] counter Input counter (updates on return) 338 * @param[out] counterlast Output cipher of last counter, for chained CTR calls (statefull encryption). NULL can be 339 * passed if chained calls are 340 * not used. 341 * @param[out] szLeft Output number of bytes in left unused in counterlast block. NULL can be passed if chained calls 342 * are not used. 343 * @return Status from encrypt operation 344 */ 345 status_t HASHCRYPT_AES_CryptCtr(HASHCRYPT_Type *base, 346 hashcrypt_handle_t *handle, 347 const uint8_t *input, 348 uint8_t *output, 349 size_t size, 350 uint8_t counter[HASHCRYPT_AES_BLOCK_SIZE], 351 uint8_t counterlast[HASHCRYPT_AES_BLOCK_SIZE], 352 size_t *szLeft); 353 354 /*! 355 * @brief Encrypts or decrypts AES using OFB block mode. 356 * 357 * Encrypts or decrypts AES using OFB block mode. 358 * AES OFB mode uses only forward AES cipher and same algorithm for encryption and decryption. 359 * The only difference between encryption and decryption is that, for encryption, the input argument 360 * is plain text and the output argument is cipher text. For decryption, the input argument is cipher text 361 * and the output argument is plain text. 362 * 363 * @param base HASHCRYPT peripheral base address 364 * @param handle Handle used for this request. 365 * @param input Input data for OFB block mode 366 * @param[out] output Output data for OFB block mode 367 * @param size Size of input and output data in bytes 368 * @param iv Input initial vector to combine with the first input block. 369 * @return Status from encrypt operation 370 */ 371 372 status_t HASHCRYPT_AES_CryptOfb(HASHCRYPT_Type *base, 373 hashcrypt_handle_t *handle, 374 const uint8_t *input, 375 uint8_t *output, 376 size_t size, 377 const uint8_t iv[HASHCRYPT_AES_BLOCK_SIZE]); 378 379 /*! 380 * @brief Encrypts AES using CFB block mode. 381 * 382 * @param base HASHCRYPT peripheral base address 383 * @param handle Handle used for this request. 384 * @param plaintext Input plain text to encrypt 385 * @param[out] ciphertext Output cipher text 386 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. 387 * @param iv Input initial vector to combine with the first input block. 388 * @return Status from encrypt operation 389 */ 390 391 status_t HASHCRYPT_AES_EncryptCfb(HASHCRYPT_Type *base, 392 hashcrypt_handle_t *handle, 393 const uint8_t *plaintext, 394 uint8_t *ciphertext, 395 size_t size, 396 const uint8_t iv[16]); 397 398 /*! 399 * @brief Decrypts AES using CFB block mode. 400 * 401 * @param base HASHCRYPT peripheral base address 402 * @param handle Handle used for this request. 403 * @param ciphertext Input cipher text to decrypt 404 * @param[out] plaintext Output plaintext text 405 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. 406 * @param iv Input initial vector to combine with the first input block. 407 * @return Status from encrypt operation 408 */ 409 410 status_t HASHCRYPT_AES_DecryptCfb(HASHCRYPT_Type *base, 411 hashcrypt_handle_t *handle, 412 const uint8_t *ciphertext, 413 uint8_t *plaintext, 414 size_t size, 415 const uint8_t iv[16]); 416 /*! 417 *@} 418 */ /* end of hashcrypt_driver_aes */ 419 420 /******************************************************************************* 421 * HASH API 422 ******************************************************************************/ 423 424 /*! 425 * @addtogroup hashcrypt_driver_hash 426 * @{ 427 */ 428 429 /*! 430 * @brief Create HASH on given data 431 * 432 * Perform the full SHA in one function call. The function is blocking. 433 * 434 * @param base HASHCRYPT peripheral base address 435 * @param algo Underlaying algorithm to use for hash computation. 436 * @param input Input data 437 * @param inputSize Size of input data in bytes 438 * @param[out] output Output hash data 439 * @param[out] outputSize Output parameter storing the size of the output hash in bytes 440 * @return Status of the one call hash operation. 441 */ 442 status_t HASHCRYPT_SHA(HASHCRYPT_Type *base, 443 hashcrypt_algo_t algo, 444 const uint8_t *input, 445 size_t inputSize, 446 uint8_t *output, 447 size_t *outputSize); 448 449 /*! 450 * @brief Initialize HASH context 451 * 452 * This function initializes the HASH. 453 * 454 * @param base HASHCRYPT peripheral base address 455 * @param[out] ctx Output hash context 456 * @param algo Underlaying algorithm to use for hash computation. 457 * @return Status of initialization 458 */ 459 status_t HASHCRYPT_SHA_Init(HASHCRYPT_Type *base, hashcrypt_hash_ctx_t *ctx, hashcrypt_algo_t algo); 460 461 /*! 462 * @brief Add data to current HASH 463 * 464 * Add data to current HASH. This can be called repeatedly with an arbitrary amount of data to be 465 * hashed. The functions blocks. If it returns kStatus_Success, the running hash 466 * has been updated (HASHCRYPT has processed the input data), so the memory at \p input pointer 467 * can be released back to system. The HASHCRYPT context buffer is updated with the running hash 468 * and with all necessary information to support possible context switch. 469 * 470 * @param base HASHCRYPT peripheral base address 471 * @param[in,out] ctx HASH context 472 * @param input Input data 473 * @param inputSize Size of input data in bytes 474 * @return Status of the hash update operation 475 */ 476 status_t HASHCRYPT_SHA_Update(HASHCRYPT_Type *base, hashcrypt_hash_ctx_t *ctx, const uint8_t *input, size_t inputSize); 477 478 /*! 479 * @brief Finalize hashing 480 * 481 * Outputs the final hash (computed by HASHCRYPT_HASH_Update()) and erases the context. 482 * 483 * @param base HASHCRYPT peripheral base address 484 * @param[in,out] ctx Input hash context 485 * @param[out] output Output hash data 486 * @param[in,out] outputSize Optional parameter (can be passed as NULL). On function entry, it specifies the size of 487 * output[] buffer. On function return, it stores the number of updated output bytes. 488 * @return Status of the hash finish operation 489 */ 490 status_t HASHCRYPT_SHA_Finish(HASHCRYPT_Type *base, hashcrypt_hash_ctx_t *ctx, uint8_t *output, size_t *outputSize); 491 492 /*! 493 *@} 494 */ /* end of hashcrypt_driver_hash */ 495 496 /*! 497 * @addtogroup hashcrypt_background_driver_hash 498 * @{ 499 */ 500 501 /*! 502 * @brief Initializes the HASHCRYPT handle for background hashing. 503 * 504 * This function initializes the hash context for background hashing 505 * (Non-blocking) APIs. This is less typical interface to hash function, but can be used 506 * for parallel processing, when main CPU has something else to do. 507 * Example is digital signature RSASSA-PKCS1-V1_5-VERIFY((n,e),M,S) algorithm, where 508 * background hashing of M can be started, then CPU can compute S^e mod n 509 * (in parallel with background hashing) and once the digest becomes available, 510 * CPU can proceed to comparison of EM with EM'. 511 * 512 * @param base HASHCRYPT peripheral base address. 513 * @param[out] ctx Hash context. 514 * @param callback Callback function. 515 * @param userData User data (to be passed as an argument to callback function, once callback is invoked from isr). 516 */ 517 void HASHCRYPT_SHA_SetCallback(HASHCRYPT_Type *base, 518 hashcrypt_hash_ctx_t *ctx, 519 hashcrypt_callback_t callback, 520 void *userData); 521 522 /*! 523 * @brief Create running hash on given data. 524 * 525 * Configures the HASHCRYPT to compute new running hash as AHB master 526 * and returns immediately. HASHCRYPT AHB Master mode supports only aligned \p input 527 * address and can be called only once per continuous block of data. Every call to this function 528 * must be preceded with HASHCRYPT_SHA_Init() and finished with HASHCRYPT_SHA_Finish(). 529 * Once callback function is invoked by HASHCRYPT isr, it should set a flag 530 * for the main application to finalize the hashing (padding) and to read out the final digest 531 * by calling HASHCRYPT_SHA_Finish(). 532 * 533 * @param base HASHCRYPT peripheral base address 534 * @param ctx Specifies callback. Last incomplete 512-bit block of the input is copied into clear buffer for padding. 535 * @param input 32-bit word aligned pointer to Input data. 536 * @param inputSize Size of input data in bytes (must be word aligned) 537 * @return Status of the hash update operation. 538 */ 539 status_t HASHCRYPT_SHA_UpdateNonBlocking(HASHCRYPT_Type *base, 540 hashcrypt_hash_ctx_t *ctx, 541 const uint8_t *input, 542 size_t inputSize); 543 /*! 544 *@} 545 */ /* end of hashcrypt_background_driver_hash */ 546 547 #if defined(__cplusplus) 548 } 549 #endif 550 551 #endif /* FSL_HASHCRYPT_H_ */ 552