1 /*
2  * Copyright 2017-2022 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.11.
30  *
31  * Current version: 2.2.11
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  */
89 #define FSL_HASHCRYPT_DRIVER_VERSION (MAKE_VERSION(2, 2, 11))
90 /*@}*/
91 
92 /*! @brief Algorithm definitions correspond with the values for Mode field in Control register !*/
93 #define HASHCRYPT_MODE_SHA1   0x1
94 #define HASHCRYPT_MODE_SHA256 0x2
95 #define HASHCRYPT_MODE_AES    0x4
96 
97 /*! @brief Algorithm used for Hashcrypt operation */
98 typedef enum _hashcrypt_algo_t
99 {
100     kHASHCRYPT_Sha1   = HASHCRYPT_MODE_SHA1,   /*!< SHA_1 */
101     kHASHCRYPT_Sha256 = HASHCRYPT_MODE_SHA256, /*!< SHA_256 */
102     kHASHCRYPT_Aes    = HASHCRYPT_MODE_AES,    /*!< AES */
103 } hashcrypt_algo_t;
104 
105 /*! @} */
106 
107 /*******************************************************************************
108  * AES Definitions
109  *******************************************************************************/
110 
111 /*!
112  * @addtogroup hashcrypt_driver_aes
113  * @{
114  */
115 
116 /*! AES block size in bytes */
117 #define HASHCRYPT_AES_BLOCK_SIZE 16U
118 #define AES_ENCRYPT              0
119 #define AES_DECRYPT              1
120 
121 /*! @brief AES mode */
122 typedef enum _hashcrypt_aes_mode_t
123 {
124     kHASHCRYPT_AesEcb = 0U, /*!< AES ECB mode */
125     kHASHCRYPT_AesCbc = 1U, /*!< AES CBC mode */
126     kHASHCRYPT_AesCtr = 2U, /*!< AES CTR mode */
127 } hashcrypt_aes_mode_t;
128 
129 /*! @brief Size of AES key */
130 typedef enum _hashcrypt_aes_keysize_t
131 {
132     kHASHCRYPT_Aes128     = 0U, /*!< AES 128 bit key */
133     kHASHCRYPT_Aes192     = 1U, /*!< AES 192 bit key */
134     kHASHCRYPT_Aes256     = 2U, /*!< AES 256 bit key */
135     kHASHCRYPT_InvalidKey = 3U, /*!< AES invalid key */
136 } hashcrypt_aes_keysize_t;
137 
138 /*! @brief HASHCRYPT key source selection.
139  *
140  */
141 typedef enum _hashcrypt_key
142 {
143     kHASHCRYPT_UserKey   = 0xc3c3U, /*!< HASHCRYPT user key */
144     kHASHCRYPT_SecretKey = 0x3c3cU, /*!< HASHCRYPT secret key (dedicated hw bus from PUF) */
145 } hashcrypt_key_t;
146 
147 /*! @brief Specify HASHCRYPT's key resource. */
148 struct _hashcrypt_handle
149 {
150     uint32_t keyWord[8]; /*!< Copy of user key (set by HASHCRYPT_AES_SetKey(). */
151     hashcrypt_aes_keysize_t keySize;
152     hashcrypt_key_t keyType; /*!< For operations with key (such as AES encryption/decryption), specify key type. */
153 } __attribute__((aligned));
154 
155 typedef struct _hashcrypt_handle hashcrypt_handle_t;
156 
157 /*!
158  *@}
159  */ /* end of hashcrypt_driver_aes */
160 
161 /*******************************************************************************
162  * HASH Definitions
163  ******************************************************************************/
164 /*!
165  * @addtogroup hashcrypt_driver_hash
166  * @{
167  */
168 
169 /*! @brief HASHCRYPT HASH Context size. */
170 #if defined(FSL_FEATURE_HASHCRYPT_HAS_RELOAD_FEATURE) && (FSL_FEATURE_HASHCRYPT_HAS_RELOAD_FEATURE > 0)
171 #define HASHCRYPT_HASH_CTX_SIZE 30
172 #else
173 #define HASHCRYPT_HASH_CTX_SIZE 22
174 #endif
175 
176 /*! @brief Storage type used to save hash context. */
177 typedef struct _hashcrypt_hash_ctx_t
178 {
179     uint32_t x[HASHCRYPT_HASH_CTX_SIZE]; /*!< storage */
180 } hashcrypt_hash_ctx_t;
181 
182 /*! @brief HASHCRYPT background hash callback function. */
183 typedef void (*hashcrypt_callback_t)(HASHCRYPT_Type *base, hashcrypt_hash_ctx_t *ctx, status_t status, void *userData);
184 
185 /*!
186  *@}
187  */ /* end of hashcrypt_driver_hash */
188 
189 /*******************************************************************************
190  * API
191  ******************************************************************************/
192 #if defined(__cplusplus)
193 extern "C" {
194 #endif
195 
196 /*!
197  * @addtogroup hashcrypt_driver
198  * @{
199  */
200 
201 /*!
202  * @brief Enables clock and disables reset for HASHCRYPT peripheral.
203  *
204  * Enable clock and disable reset for HASHCRYPT.
205  *
206  * @param base HASHCRYPT base address
207  */
208 void HASHCRYPT_Init(HASHCRYPT_Type *base);
209 
210 /*!
211  * @brief Disables clock for HASHCRYPT peripheral.
212  *
213  * Disable clock and enable reset.
214  *
215  * @param base HASHCRYPT base address
216  */
217 void HASHCRYPT_Deinit(HASHCRYPT_Type *base);
218 
219 /*!
220  *@}
221  */ /* end of hashcrypt_driver */
222 
223 /*******************************************************************************
224  * AES API
225  ******************************************************************************/
226 
227 /*!
228  * @addtogroup hashcrypt_driver_aes
229  * @{
230  */
231 
232 /*!
233  * @brief Set AES key to hashcrypt_handle_t struct and optionally to HASHCRYPT.
234  *
235  * Sets the AES key for encryption/decryption with the hashcrypt_handle_t structure.
236  * The hashcrypt_handle_t input argument specifies key source.
237  *
238  * @param   base HASHCRYPT peripheral base address.
239  * @param   handle Handle used for the request.
240  * @param   key 0-mod-4 aligned pointer to AES key.
241  * @param   keySize AES key size in bytes. Shall equal 16, 24 or 32.
242  * @return  status from set key operation
243  */
244 status_t HASHCRYPT_AES_SetKey(HASHCRYPT_Type *base, hashcrypt_handle_t *handle, const uint8_t *key, size_t keySize);
245 
246 /*!
247  * @brief Encrypts AES on one or multiple 128-bit block(s).
248  *
249  * Encrypts AES.
250  * The source plaintext and destination ciphertext can overlap in system memory.
251  *
252  * @param base HASHCRYPT peripheral base address
253  * @param handle Handle used for this request.
254  * @param plaintext Input plain text to encrypt
255  * @param[out] ciphertext Output cipher text
256  * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
257  * @return Status from encrypt operation
258  */
259 status_t HASHCRYPT_AES_EncryptEcb(
260     HASHCRYPT_Type *base, hashcrypt_handle_t *handle, const uint8_t *plaintext, uint8_t *ciphertext, size_t size);
261 
262 /*!
263  * @brief Decrypts AES on one or multiple 128-bit block(s).
264  *
265  * Decrypts AES.
266  * The source ciphertext and destination plaintext can overlap in system memory.
267  *
268  * @param base HASHCRYPT peripheral base address
269  * @param handle Handle used for this request.
270  * @param ciphertext Input plain text to encrypt
271  * @param[out] plaintext Output cipher text
272  * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
273  * @return Status from decrypt operation
274  */
275 status_t HASHCRYPT_AES_DecryptEcb(
276     HASHCRYPT_Type *base, hashcrypt_handle_t *handle, const uint8_t *ciphertext, uint8_t *plaintext, size_t size);
277 
278 /*!
279  * @brief Encrypts AES using CBC block mode.
280  *
281  * @param base HASHCRYPT peripheral base address
282  * @param handle Handle used for this request.
283  * @param plaintext Input plain text to encrypt
284  * @param[out] ciphertext Output cipher text
285  * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
286  * @param iv Input initial vector to combine with the first input block.
287  * @return Status from encrypt operation
288  */
289 status_t HASHCRYPT_AES_EncryptCbc(HASHCRYPT_Type *base,
290                                   hashcrypt_handle_t *handle,
291                                   const uint8_t *plaintext,
292                                   uint8_t *ciphertext,
293                                   size_t size,
294                                   const uint8_t iv[16]);
295 
296 /*!
297  * @brief Decrypts AES using CBC block mode.
298  *
299  * @param base HASHCRYPT peripheral base address
300  * @param handle Handle used for this request.
301  * @param ciphertext Input cipher text to decrypt
302  * @param[out] plaintext Output plain text
303  * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
304  * @param iv Input initial vector to combine with the first input block.
305  * @return Status from decrypt operation
306  */
307 status_t HASHCRYPT_AES_DecryptCbc(HASHCRYPT_Type *base,
308                                   hashcrypt_handle_t *handle,
309                                   const uint8_t *ciphertext,
310                                   uint8_t *plaintext,
311                                   size_t size,
312                                   const uint8_t iv[16]);
313 
314 /*!
315  * @brief Encrypts or decrypts AES using CTR block mode.
316  *
317  * Encrypts or decrypts AES using CTR block mode.
318  * AES CTR mode uses only forward AES cipher and same algorithm for encryption and decryption.
319  * The only difference between encryption and decryption is that, for encryption, the input argument
320  * is plain text and the output argument is cipher text. For decryption, the input argument is cipher text
321  * and the output argument is plain text.
322  *
323  * @param base HASHCRYPT peripheral base address
324  * @param handle Handle used for this request.
325  * @param input Input data for CTR block mode
326  * @param[out] output Output data for CTR block mode
327  * @param size Size of input and output data in bytes
328  * @param[in,out] counter Input counter (updates on return)
329  * @param[out] counterlast Output cipher of last counter, for chained CTR calls (statefull encryption). NULL can be
330  * passed if chained calls are
331  * not used.
332  * @param[out] szLeft Output number of bytes in left unused in counterlast block. NULL can be passed if chained calls
333  * are not used.
334  * @return Status from encrypt operation
335  */
336 status_t HASHCRYPT_AES_CryptCtr(HASHCRYPT_Type *base,
337                                 hashcrypt_handle_t *handle,
338                                 const uint8_t *input,
339                                 uint8_t *output,
340                                 size_t size,
341                                 uint8_t counter[HASHCRYPT_AES_BLOCK_SIZE],
342                                 uint8_t counterlast[HASHCRYPT_AES_BLOCK_SIZE],
343                                 size_t *szLeft);
344 
345 /*!
346  * @brief Encrypts or decrypts AES using OFB block mode.
347  *
348  * Encrypts or decrypts AES using OFB block mode.
349  * AES OFB mode uses only forward AES cipher and same algorithm for encryption and decryption.
350  * The only difference between encryption and decryption is that, for encryption, the input argument
351  * is plain text and the output argument is cipher text. For decryption, the input argument is cipher text
352  * and the output argument is plain text.
353  *
354  * @param base HASHCRYPT peripheral base address
355  * @param handle Handle used for this request.
356  * @param input Input data for OFB block mode
357  * @param[out] output Output data for OFB block mode
358  * @param size Size of input and output data in bytes
359  * @param iv Input initial vector to combine with the first input block.
360  * @return Status from encrypt operation
361  */
362 
363 status_t HASHCRYPT_AES_CryptOfb(HASHCRYPT_Type *base,
364                                 hashcrypt_handle_t *handle,
365                                 const uint8_t *input,
366                                 uint8_t *output,
367                                 size_t size,
368                                 const uint8_t iv[HASHCRYPT_AES_BLOCK_SIZE]);
369 
370 /*!
371  * @brief Encrypts AES using CFB block mode.
372  *
373  * @param base HASHCRYPT peripheral base address
374  * @param handle Handle used for this request.
375  * @param plaintext Input plain text to encrypt
376  * @param[out] ciphertext Output cipher text
377  * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
378  * @param iv Input initial vector to combine with the first input block.
379  * @return Status from encrypt operation
380  */
381 
382 status_t HASHCRYPT_AES_EncryptCfb(HASHCRYPT_Type *base,
383                                   hashcrypt_handle_t *handle,
384                                   const uint8_t *plaintext,
385                                   uint8_t *ciphertext,
386                                   size_t size,
387                                   const uint8_t iv[16]);
388 
389 /*!
390  * @brief Decrypts AES using CFB block mode.
391  *
392  * @param base HASHCRYPT peripheral base address
393  * @param handle Handle used for this request.
394  * @param ciphertext Input cipher text to decrypt
395  * @param[out] plaintext Output plaintext text
396  * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
397  * @param iv Input initial vector to combine with the first input block.
398  * @return Status from encrypt operation
399  */
400 
401 status_t HASHCRYPT_AES_DecryptCfb(HASHCRYPT_Type *base,
402                                   hashcrypt_handle_t *handle,
403                                   const uint8_t *ciphertext,
404                                   uint8_t *plaintext,
405                                   size_t size,
406                                   const uint8_t iv[16]);
407 /*!
408  *@}
409  */ /* end of hashcrypt_driver_aes */
410 
411 /*******************************************************************************
412  * HASH API
413  ******************************************************************************/
414 
415 /*!
416  * @addtogroup hashcrypt_driver_hash
417  * @{
418  */
419 
420 /*!
421  * @brief Create HASH on given data
422  *
423  * Perform the full SHA in one function call. The function is blocking.
424  *
425  * @param base HASHCRYPT peripheral base address
426  * @param algo Underlaying algorithm to use for hash computation.
427  * @param input Input data
428  * @param inputSize Size of input data in bytes
429  * @param[out] output Output hash data
430  * @param[out] outputSize Output parameter storing the size of the output hash in bytes
431  * @return Status of the one call hash operation.
432  */
433 status_t HASHCRYPT_SHA(HASHCRYPT_Type *base,
434                        hashcrypt_algo_t algo,
435                        const uint8_t *input,
436                        size_t inputSize,
437                        uint8_t *output,
438                        size_t *outputSize);
439 
440 /*!
441  * @brief Initialize HASH context
442  *
443  * This function initializes the HASH.
444  *
445  * @param base HASHCRYPT peripheral base address
446  * @param[out] ctx Output hash context
447  * @param algo Underlaying algorithm to use for hash computation.
448  * @return Status of initialization
449  */
450 status_t HASHCRYPT_SHA_Init(HASHCRYPT_Type *base, hashcrypt_hash_ctx_t *ctx, hashcrypt_algo_t algo);
451 
452 /*!
453  * @brief Add data to current HASH
454  *
455  * Add data to current HASH. This can be called repeatedly with an arbitrary amount of data to be
456  * hashed. The functions blocks. If it returns kStatus_Success, the running hash
457  * has been updated (HASHCRYPT has processed the input data), so the memory at \p input pointer
458  * can be released back to system. The HASHCRYPT context buffer is updated with the running hash
459  * and with all necessary information to support possible context switch.
460  *
461  * @param base HASHCRYPT peripheral base address
462  * @param[in,out] ctx HASH context
463  * @param input Input data
464  * @param inputSize Size of input data in bytes
465  * @return Status of the hash update operation
466  */
467 status_t HASHCRYPT_SHA_Update(HASHCRYPT_Type *base, hashcrypt_hash_ctx_t *ctx, const uint8_t *input, size_t inputSize);
468 
469 /*!
470  * @brief Finalize hashing
471  *
472  * Outputs the final hash (computed by HASHCRYPT_HASH_Update()) and erases the context.
473  *
474  * @param base HASHCRYPT peripheral base address
475  * @param[in,out] ctx Input hash context
476  * @param[out] output Output hash data
477  * @param[in,out] outputSize Optional parameter (can be passed as NULL). On function entry, it specifies the size of
478  * output[] buffer. On function return, it stores the number of updated output bytes.
479  * @return Status of the hash finish operation
480  */
481 status_t HASHCRYPT_SHA_Finish(HASHCRYPT_Type *base, hashcrypt_hash_ctx_t *ctx, uint8_t *output, size_t *outputSize);
482 
483 /*!
484  *@}
485  */ /* end of hashcrypt_driver_hash */
486 
487 /*!
488  * @addtogroup hashcrypt_background_driver_hash
489  * @{
490  */
491 
492 /*!
493  * @brief Initializes the HASHCRYPT handle for background hashing.
494  *
495  * This function initializes the hash context for background hashing
496  * (Non-blocking) APIs. This is less typical interface to hash function, but can be used
497  * for parallel processing, when main CPU has something else to do.
498  * Example is digital signature RSASSA-PKCS1-V1_5-VERIFY((n,e),M,S) algorithm, where
499  * background hashing of M can be started, then CPU can compute S^e mod n
500  * (in parallel with background hashing) and once the digest becomes available,
501  * CPU can proceed to comparison of EM with EM'.
502  *
503  * @param base HASHCRYPT peripheral base address.
504  * @param[out] ctx Hash context.
505  * @param callback Callback function.
506  * @param userData User data (to be passed as an argument to callback function, once callback is invoked from isr).
507  */
508 void HASHCRYPT_SHA_SetCallback(HASHCRYPT_Type *base,
509                                hashcrypt_hash_ctx_t *ctx,
510                                hashcrypt_callback_t callback,
511                                void *userData);
512 
513 /*!
514  * @brief Create running hash on given data.
515  *
516  * Configures the HASHCRYPT to compute new running hash as AHB master
517  * and returns immediately. HASHCRYPT AHB Master mode supports only aligned \p input
518  * address and can be called only once per continuous block of data. Every call to this function
519  * must be preceded with HASHCRYPT_SHA_Init() and finished with HASHCRYPT_SHA_Finish().
520  * Once callback function is invoked by HASHCRYPT isr, it should set a flag
521  * for the main application to finalize the hashing (padding) and to read out the final digest
522  * by calling HASHCRYPT_SHA_Finish().
523  *
524  * @param base HASHCRYPT peripheral base address
525  * @param ctx Specifies callback. Last incomplete 512-bit block of the input is copied into clear buffer for padding.
526  * @param input 32-bit word aligned pointer to Input data.
527  * @param inputSize Size of input data in bytes (must be word aligned)
528  * @return Status of the hash update operation.
529  */
530 status_t HASHCRYPT_SHA_UpdateNonBlocking(HASHCRYPT_Type *base,
531                                          hashcrypt_hash_ctx_t *ctx,
532                                          const uint8_t *input,
533                                          size_t inputSize);
534 /*!
535  *@}
536  */ /* end of hashcrypt_background_driver_hash */
537 
538 #if defined(__cplusplus)
539 }
540 #endif
541 
542 #endif /* _FSL_HASHCRYPT_H_ */
543