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