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