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