1 /*
2  * Copyright 2017-2024 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_hashcrypt.h"
9 
10 /* Component ID definition, used by tools. */
11 #ifndef FSL_COMPONENT_ID
12 #define FSL_COMPONENT_ID "platform.drivers.hashcrypt"
13 #endif
14 
15 /*******************************************************************************
16  * Definitions
17  *******************************************************************************/
18 
19 /*!< SHA-1 and SHA-256 block size  */
20 #define SHA_BLOCK_SIZE 64U
21 /*!< max number of blocks that can be proccessed in one run (master mode) */
22 #define SHA_MASTER_MAX_BLOCKS 2048U
23 /*!< max number of blocks the SHA engine can copy, starting at MEMADDR */
24 #define SHA_MAX_BLOCK_COUNT 2047U
25 
26 /*!< Use standard C library memcpy  */
27 #define hashcrypt_memcpy memcpy
28 
29 /*! Internal states of the HASH creation process */
30 typedef enum _hashcrypt_sha_algo_state
31 {
32     kHASHCRYPT_HashInit = 1u, /*!< Init state, the NEW bit in SHA Control register has not been written yet. */
33     kHASHCRYPT_HashUpdate, /*!< Update state, DIGEST registers contain running hash, NEW bit in SHA control register has
34                               been written. */
35 } hashcrypt_sha_algo_state_t;
36 
37 /*! 64-byte block represented as byte array of 16 32-bit words */
38 typedef union _sha_hash_block
39 {
40     uint32_t w[SHA_BLOCK_SIZE / 4]; /*!< array of 32-bit words */
41     uint8_t b[SHA_BLOCK_SIZE];      /*!< byte array */
42 } hashcrypt_sha_block_t;
43 
44 /*! internal sha context structure */
45 typedef struct _hashcrypt_sha_ctx_internal
46 {
47     hashcrypt_sha_block_t blk; /*!< memory buffer. only full 64-byte blocks are written to SHA during hash updates */
48     size_t blksz;              /*!< number of valid bytes in memory buffer */
49     hashcrypt_algo_t algo;     /*!< selected algorithm from the set of supported algorithms */
50     hashcrypt_sha_algo_state_t state;  /*!< finite machine state of the hash software process */
51     size_t fullMessageSize;            /*!< track message size during SHA_Update(). The value is used for padding. */
52     uint32_t remainingBlcks;           /*!< number of remaining blocks to process in AHB master mode */
53     hashcrypt_callback_t hashCallback; /*!< pointer to HASH callback function */
54     void
55         *userData; /*!< user data to be passed as an argument to callback function, once callback is invoked from isr */
56 #if defined(FSL_FEATURE_HASHCRYPT_HAS_RELOAD_FEATURE) && (FSL_FEATURE_HASHCRYPT_HAS_RELOAD_FEATURE > 0)
57     uint32_t runningHash[8]; /*!< running hash. up to SHA-256, that is 32 bytes. */
58 #endif
59 } hashcrypt_sha_ctx_internal_t;
60 
61 #if defined(FSL_FEATURE_HASHCRYPT_HAS_RELOAD_FEATURE) && (FSL_FEATURE_HASHCRYPT_HAS_RELOAD_FEATURE > 0)
62 #define SHA1_LEN   5u
63 #define SHA256_LEN 8u
64 #endif
65 
66 /*!< SHA-1 and SHA-256 digest length in bytes  */
67 enum _hashcrypt_sha_digest_len
68 {
69     kHASHCRYPT_OutLenSha1   = 20u,
70     kHASHCRYPT_OutLenSha256 = 32u,
71 };
72 
73 /*!< pointer to hash context structure used by isr */
74 static hashcrypt_hash_ctx_t *s_ctx;
75 
76 /*!< macro for checking build time condition. It is used to assure the hashcrypt_sha_ctx_internal_t can fit into
77  * hashcrypt_hash_ctx_t */
78 #define BUILD_ASSERT(condition, msg) extern int msg[1 - 2 * (!(condition))] __attribute__((unused))
79 
80 /*******************************************************************************
81  * Code
82  ******************************************************************************/
83 
84 /*!
85  * @brief Swap bytes withing 32-bit word.
86  *
87  * This function changes endianess of a 32-bit word.
88  *
89  * @param in 32-bit unsigned integer
90  * @return 32-bit unsigned integer with different endianess (big endian to little endian and vice versa).
91  */
92 
93 #define swap_bytes(in) __REV(in)
94 
95 /*!
96  * @brief Increment a 16 byte integer.
97  *
98  * This function increments by one a 16 byte integer.
99  *
100  * @param input Pointer to a 16 byte integer to be incremented by one.
101  */
ctrIncrement(uint8_t * input)102 static void ctrIncrement(uint8_t *input)
103 {
104     int i = 15;
105     while (input[i] == (uint8_t)0xFFu)
106     {
107         input[i] = (uint8_t)0x00u;
108         i--;
109         if (i < 0)
110         {
111             return;
112         }
113     }
114 
115     if (i >= 0)
116     {
117         input[i] += (uint8_t)1u;
118     }
119 }
120 
121 /*!
122  * @brief Reads an unaligned word.
123  *
124  * This function creates a 32-bit word from an input array of four bytes.
125  *
126  * @param src Input array of four bytes. The array can start at any address in memory.
127  * @return 32-bit unsigned int created from the input byte array.
128  */
129 
130 /* Force lower optimization for Keil, otherwise it replaces inline LDR with LDM */
131 #if defined(__CC_ARM)
132 #pragma push
133 #pragma O0
134 #endif
135 
hashcrypt_get_word_from_unaligned(const uint8_t * srcAddr)136 static inline uint32_t hashcrypt_get_word_from_unaligned(const uint8_t *srcAddr)
137 {
138 #if (!(defined(__CORTEX_M)) || (defined(__CORTEX_M) && (__CORTEX_M == 0)))
139     register const uint8_t *src = srcAddr;
140     /* Cortex M0 does not support misaligned loads */
141     if (0U != ((uint32_t)src & 0x3u))
142     {
143         union _align_bytes_t
144         {
145             uint32_t word;
146             uint8_t byte[sizeof(uint32_t)];
147         } my_bytes;
148 
149         my_bytes.byte[0] = *src;
150         my_bytes.byte[1] = src[1];
151         my_bytes.byte[2] = src[2];
152         my_bytes.byte[3] = src[3];
153         return my_bytes.word;
154     }
155     else
156     {
157         /* addr aligned to 0-modulo-4 so it is safe to type cast */
158         return *((const uint32_t *)(uint32_t)src);
159     }
160 #elif defined(__CC_ARM)
161     /* -O3 optimization in Keil 5.15 and 5.16a uses LDM instruction here (LDM r4!, {r0})
162      *    which is wrong, because srcAddr might be unaligned.
163      *    LDM on unaligned address causes hard-fault. in contrary,
164      *    LDR supports unaligned address on Cortex M4 */
165 
166     register uint32_t retVal;
167     __asm
168     {
169         LDR retVal, [srcAddr]
170     }
171     return retVal;
172 #else
173     return *((const uint32_t *)(uintptr_t)srcAddr);
174 #endif
175 }
176 
177 /* End lower optimization */
178 #if defined(__CC_ARM)
179 #pragma pop
180 #endif
181 
hashcrypt_get_key_from_unaligned_src(uint8_t * dest,const uint8_t * src,size_t size)182 static status_t hashcrypt_get_key_from_unaligned_src(uint8_t *dest, const uint8_t *src, size_t size)
183 {
184     status_t retVal = kStatus_InvalidArgument;
185     uint32_t i;
186 
187     /* destination is SDK driver internal workspace and it must be aligned */
188     assert(0x0u == ((uint32_t)dest & 0x1u));
189     if (0U != ((uint32_t)dest & 0x1u))
190     {
191         return retVal;
192     }
193 
194     for (i = 0; i < ((uint32_t)size / 4u); i++)
195     {
196         ((uint32_t *)(uintptr_t)dest)[i] = hashcrypt_get_word_from_unaligned(&src[i * sizeof(uint32_t)]);
197     }
198 
199     return kStatus_Success;
200 }
201 
202 /*!
203  * @brief LDM to SHA engine INDATA and ALIAS registers.
204  *
205  * This function writes 16 words starting from the src address (must be word aligned)
206  * to the dst address. Dst address does not increment (destination is peripheral module register INDATA).
207  * Src address increments to load 16 consecutive words.
208  *
209  * @param dst peripheral register address (word aligned)
210  * @param src address of the input 512-bit block (16 words) (word aligned)
211  *
212  */
hashcrypt_sha_ldm_stm_16_words(HASHCRYPT_Type * base,const uint32_t * src)213 __STATIC_FORCEINLINE void hashcrypt_sha_ldm_stm_16_words(HASHCRYPT_Type *base, const uint32_t *src)
214 {
215     /*
216     typedef struct _one_block
217     {
218         uint32_t a[8];
219     } one_block_t;
220 
221     volatile one_block_t *ldst = (void *)(uintptr_t)(&base->INDATA);
222     one_block_t *lsrc = (void *)(uintptr_t)src;
223     *ldst = lsrc[0];
224     *ldst = lsrc[1];
225     */
226 
227     base->MEMADDR = HASHCRYPT_MEMADDR_BASE(src);
228     base->MEMCTRL = HASHCRYPT_MEMCTRL_MASTER(1) | HASHCRYPT_MEMCTRL_COUNT(1);
229 }
230 
231 /*!
232  * @brief Loads data to Hashcrypt engine INDATA register.
233  *
234  * This function writes desired number of bytes starting from the src address
235  * to the dst address. Dst address does not increment (destination is peripheral module register INDATA).
236  * Src address increments to load consecutive words.
237  *
238  * @param src address of the input block
239  * @param size number of bytes to write
240  *
241  */
hashcrypt_load_data(HASHCRYPT_Type * base,uint32_t * src,size_t size)242 __STATIC_INLINE void hashcrypt_load_data(HASHCRYPT_Type *base, uint32_t *src, size_t size)
243 {
244     /* 16 bytes aligned input block */
245     uint32_t __attribute__((aligned(4))) inAlign[HASHCRYPT_AES_BLOCK_SIZE / sizeof(uint32_t)];
246     uint32_t *in;
247     uint8_t i;
248 
249     in = src;
250     /* Check if address of src data is aligned */
251     if ((0U != ((uint32_t)in & 3U)))
252     {
253         for (i = 0; i < ((uint32_t)size / 4U); i++)
254         {
255             inAlign[i] = hashcrypt_get_word_from_unaligned((uint8_t *)&src[i]);
256         }
257         in = &inAlign[0];
258     }
259 
260     if (size >= sizeof(uint32_t))
261     {
262         base->INDATA = in[0];
263         size -= sizeof(uint32_t);
264     }
265 
266     for (uint32_t j = 0; j < size / 4U; j++)
267     {
268         base->ALIAS[j] = in[j + 1U];
269     }
270 }
271 
272 /*!
273  * @brief Checks availability of HW AES key.
274  *
275  * This function checks if the AES key is present at dedicated hardware bus
276  * and can be used at actual security level.
277  *
278  * @param base HASHCRYPT peripheral base address
279  * @param handle Handle used for this request.
280  * @return kStatus_Success if available, kStatus_Fail otherwise.
281  *
282  */
hashcrypt_check_need_key(HASHCRYPT_Type * base,hashcrypt_handle_t * handle)283 static status_t hashcrypt_check_need_key(HASHCRYPT_Type *base, hashcrypt_handle_t *handle)
284 {
285     if (handle->keyType == kHASHCRYPT_SecretKey)
286     {
287         volatile uint32_t wait = 50u;
288         /* wait until STATUS register is non-zero */
289         while ((wait > 0U) && (base->STATUS == 0U))
290         {
291             wait--;
292         }
293         /* if NEEDKEY bit is not set, HW key is available */
294         if (0U == (base->STATUS & HASHCRYPT_STATUS_NEEDKEY_MASK))
295         {
296             return kStatus_Success;
297         }
298         /* NEEDKEY is set, HW key is not available */
299         return kStatus_Fail;
300     }
301     else
302     {
303         /* in case user key is used, return success */
304         return kStatus_Success;
305     }
306 }
307 
308 /*!
309  * @brief Read OUTDATA registers.
310  *
311  * This function copies OUTDATA to output buffer.
312  *
313  * @param base Hachcrypt peripheral base address.
314  * @param[out] output Output buffer.
315  * @param Number of bytes to copy.
316  * @return kStatus_Success if no hashing error, kStatus_Fail otherwise.
317  */
hashcrypt_get_data(HASHCRYPT_Type * base,uint8_t * output,size_t outputSize)318 static status_t hashcrypt_get_data(HASHCRYPT_Type *base, uint8_t *output, size_t outputSize)
319 {
320     status_t status = kStatus_Fail;
321     uint32_t digest[8];
322 
323     while ((0U == (base->STATUS & HASHCRYPT_STATUS_DIGEST_MASK)) &&
324            (0U == (base->STATUS & HASHCRYPT_STATUS_ERROR_MASK)))
325     {
326     }
327 
328     if (0U == (base->STATUS & HASHCRYPT_STATUS_ERROR_MASK))
329     {
330         status = kStatus_Success;
331     }
332 
333     /* Data Synchronization Barrier */
334     __DSB();
335 
336     for (int i = 0; i < 8; i++)
337     {
338         digest[i] = swap_bytes(base->DIGEST0[i]);
339     }
340 
341     if (outputSize > sizeof(digest))
342     {
343         outputSize = sizeof(digest);
344     }
345     (void)hashcrypt_memcpy(output, (const uint8_t *)(uintptr_t)digest, outputSize);
346 
347     return status;
348 }
349 
350 /*!
351  * @brief Initialize the Hashcrypt engine for new operation.
352  *
353  * This function sets NEW and MODE fields in Hashcrypt Control register to start new operation.
354  *
355  * @param base Hashcrypt peripheral base address.
356  * @param hashcrypt_algo_t Internal context.
357  */
hashcrypt_engine_init(HASHCRYPT_Type * base,hashcrypt_algo_t algo)358 static void hashcrypt_engine_init(HASHCRYPT_Type *base, hashcrypt_algo_t algo)
359 {
360     /* NEW bit must be set before we switch from previous mode otherwise new mode will not work correctly */
361     base->CTRL = HASHCRYPT_CTRL_NEW_HASH(1);
362     base->CTRL = HASHCRYPT_CTRL_MODE(algo) | HASHCRYPT_CTRL_NEW_HASH(1);
363 }
364 
365 /*!
366  * @brief Deinitialization of the Hashcrypt engine.
367  *
368  * This function sets MODE field in Hashcrypt Control register to zero - disabled.
369  * This reduces power consumption of HASHCRYPT.
370  *
371  * @param base Hashcrypt peripheral base address.
372  */
hashcrypt_engine_deinit(HASHCRYPT_Type * base)373 static inline void hashcrypt_engine_deinit(HASHCRYPT_Type *base)
374 {
375     base->CTRL &= ~(HASHCRYPT_CTRL_MODE_MASK);
376 }
377 
378 /*!
379  * @brief Loads user key to INDATA register.
380  *
381  * This function writes user key stored in handle into HashCrypt INDATA register.
382  *
383  * @param base Hashcrypt peripheral base address.
384  * @param handle Handle used for this request.
385  */
hashcrypt_aes_load_userKey(HASHCRYPT_Type * base,hashcrypt_handle_t * handle)386 static void hashcrypt_aes_load_userKey(HASHCRYPT_Type *base, hashcrypt_handle_t *handle)
387 {
388     size_t keySize = 0;
389 
390     switch (handle->keySize)
391     {
392         case kHASHCRYPT_Aes128:
393             keySize = 16;
394             break;
395         case kHASHCRYPT_Aes192:
396             keySize = 24;
397             break;
398         case kHASHCRYPT_Aes256:
399             keySize = 32;
400             break;
401         default:
402             /* All the cases have been listed above, the default clause should not be reached. */
403             break;
404     }
405     if (keySize == 0U)
406     {
407         return;
408     }
409     hashcrypt_load_data(base, &handle->keyWord[0], keySize);
410 }
411 
412 /*!
413  * @brief Performs AES encryption/decryption of one data block.
414  *
415  * This function encrypts/decrypts one block of data with specified size.
416  *
417  * @param base Hashcrypt peripheral base address.
418  * @param input input data
419  * @param output output data
420  * @param size size of data block to process in bytes (must be 16bytes multiple).
421  */
hashcrypt_aes_one_block_aligned(HASHCRYPT_Type * base,const uint8_t * input,uint8_t * output,size_t size)422 static status_t hashcrypt_aes_one_block_aligned(HASHCRYPT_Type *base,
423                                                 const uint8_t *input,
424                                                 uint8_t *output,
425                                                 size_t size)
426 {
427     status_t status = kStatus_Fail;
428     uint32_t idx    = 0;
429 
430     base->MEMADDR = HASHCRYPT_MEMADDR_BASE(input);
431     base->MEMCTRL = HASHCRYPT_MEMCTRL_MASTER(1) | HASHCRYPT_MEMCTRL_COUNT(size / 16U);
432     while (size >= HASHCRYPT_AES_BLOCK_SIZE)
433     {
434         /* Get result */
435         while ((0U == (base->STATUS & HASHCRYPT_STATUS_DIGEST_MASK)) &&
436                (0U == (base->STATUS & HASHCRYPT_STATUS_ERROR_MASK)))
437         {
438         }
439 
440         for (int i = 0; i < 4; i++)
441         {
442             ((uint32_t *)(uintptr_t)output + idx)[i] = swap_bytes(base->DIGEST0[i]);
443         }
444 
445         idx += HASHCRYPT_AES_BLOCK_SIZE / 4U;
446         size -= HASHCRYPT_AES_BLOCK_SIZE;
447     }
448 
449     if (0U == (base->STATUS & HASHCRYPT_STATUS_ERROR_MASK))
450     {
451         status = kStatus_Success;
452     }
453 
454     return status;
455 }
456 
457 /*!
458  * @brief Performs AES encryption/decryption of one data block.
459  *
460  * This function encrypts/decrypts one block of data with specified size.
461  *
462  * @param base Hashcrypt peripheral base address.
463  * @param input input data
464  * @param output output data
465  * @param size size of data block to process in bytes (must be 16bytes multiple).
466  */
hashcrypt_aes_one_block_unaligned(HASHCRYPT_Type * base,const uint8_t * input,uint8_t * output,size_t size)467 static status_t hashcrypt_aes_one_block_unaligned(HASHCRYPT_Type *base,
468                                                   const uint8_t *input,
469                                                   uint8_t *output,
470                                                   size_t size)
471 {
472     status_t status = kStatus_Fail;
473 
474     /* we use AHB master mode as much as possible */
475     /* however, it can work only with aligned input data */
476     /* so, if unaligned, we do memcpy to temp buffer on stack, which is aligned, and use AHB mode to read data in */
477     /* then we read data back to it and do memcpy to the output buffer */
478     uint32_t temp[256 / sizeof(uint32_t)];
479     int cnt = 0;
480     while (size != 0U)
481     {
482         size_t actSz     = size >= 256u ? 256u : size;
483         size_t actSzOrig = actSz;
484         /* Memcpy input not typecast; see memcpy *important* note in hashcrypt_sha_one_block() */
485         (void)hashcrypt_memcpy(temp, (input + 256 * cnt), actSz);
486         size -= actSz;
487         base->MEMADDR   = HASHCRYPT_MEMADDR_BASE(temp);
488         base->MEMCTRL   = HASHCRYPT_MEMCTRL_MASTER(1) | HASHCRYPT_MEMCTRL_COUNT(actSz / 16U);
489         uint32_t outidx = 0;
490         while (actSz != 0U)
491         {
492             while ((0U == (base->STATUS & HASHCRYPT_STATUS_DIGEST_MASK)) &&
493                    (0U == (base->STATUS & HASHCRYPT_STATUS_ERROR_MASK)))
494             {
495             }
496             for (int i = 0; i < 4; i++)
497             {
498                 (temp + outidx)[i] = swap_bytes(base->DIGEST0[i]);
499             }
500             outidx += HASHCRYPT_AES_BLOCK_SIZE / 4U;
501             actSz -= HASHCRYPT_AES_BLOCK_SIZE;
502         }
503         (void)hashcrypt_memcpy(output + 256 * cnt, (const uint8_t *)(uintptr_t)temp, actSzOrig);
504         cnt++;
505     }
506 
507     if (0U == (base->STATUS & HASHCRYPT_STATUS_ERROR_MASK))
508     {
509         status = kStatus_Success;
510     }
511 
512     return status;
513 }
514 
515 /*!
516  * @brief Performs AES encryption/decryption of one data block.
517  *
518  * This function encrypts/decrypts one block of data with specified size.
519  *
520  * @param base Hashcrypt peripheral base address.
521  * @param input input data
522  * @param output output data
523  * @param size size of data block to process in bytes (must be 16bytes multiple).
524  */
hashcrypt_aes_one_block(HASHCRYPT_Type * base,const uint8_t * input,uint8_t * output,size_t size)525 static status_t hashcrypt_aes_one_block(HASHCRYPT_Type *base, const uint8_t *input, uint8_t *output, size_t size)
526 {
527     status_t status = kStatus_Fail;
528 
529     /*MEMCTRL bitfield for COUNT is 11 bits, and this limits the number of blocks to process in one Master run to 2047
530     (2^11 -1)  blocks . Each block is 16bytes long, so biggest data size  which can we do in one Master run is (2047
531     blocks *16 bytes) = 32752 So, when size is overflowing HASHCRYPT_MEMCTRL_COUNT field of MEMCTRL register, we split
532     our data into more smaller chunks */
533 
534     if (size > 32752U)
535 
536     {
537         size_t numBlock      = size / 32752U;              /* number of blocks, each block is processed in one run*/
538         size_t remainingSize = size - (numBlock * 32752U); /* size of last  block */
539 
540         if ((0U != ((uint32_t)input & 0x3u)) || (0U != ((uint32_t)output & 0x3u))) /* If data is unaligned*/
541         {
542             for (uint32_t i = 0; i < numBlock; i++)
543             {
544                 status = hashcrypt_aes_one_block_unaligned(base, input, output, 32752U);
545                 input += 32752U;
546                 output += 32752U;
547             }
548             status = hashcrypt_aes_one_block_unaligned(base, input, output, remainingSize);
549         }
550         else /* If data is aligned*/
551         {
552             for (uint32_t i = 0; i < numBlock; i++)
553             {
554                 status = hashcrypt_aes_one_block_aligned(base, input, output, 32752U);
555                 input += 32752U;
556                 output += 32752U;
557             }
558             status = hashcrypt_aes_one_block_aligned(base, input, output, remainingSize);
559         }
560     }
561 
562     else /* size is less than COUNT field of MEMCTRL register  so we can process all data at once */
563     {
564         /* we use AHB master mode as much as possible */
565         /* however, it can work only with aligned input data */
566         /* so, if unaligned, we do memcpy to temp buffer on stack, which is aligned, and use AHB mode to read data in */
567         /* then we read data back to it and do memcpy to the output buffer */
568         if ((0U != ((uint32_t)input & 0x3u)) || (0U != ((uint32_t)output & 0x3u)))
569         {
570             status = hashcrypt_aes_one_block_unaligned(base, input, output, size);
571         }
572         else
573         {
574             status = hashcrypt_aes_one_block_aligned(base, input, output, size);
575         }
576     }
577     return status;
578 }
579 
580 /*!
581  * @brief Check validity of algoritm.
582  *
583  * This function checks the validity of input argument.
584  *
585  * @param algo Tested algorithm value.
586  * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise.
587  */
hashcrypt_sha_check_input_alg(HASHCRYPT_Type * base,hashcrypt_algo_t algo)588 static status_t hashcrypt_sha_check_input_alg(HASHCRYPT_Type *base, hashcrypt_algo_t algo)
589 {
590     if ((algo == kHASHCRYPT_Sha1) || (algo == kHASHCRYPT_Sha256))
591     {
592         return kStatus_Success;
593     }
594 
595     return kStatus_InvalidArgument;
596 }
597 
598 /*!
599  * @brief Check validity of input arguments.
600  *
601  * This function checks the validity of input arguments.
602  *
603  * @param base SHA peripheral base address.
604  * @param ctx Memory buffer given by user application where the SHA_Init/SHA_Update/SHA_Finish store context.
605  * @param algo Tested algorithm value.
606  * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise.
607  */
hashcrypt_sha_check_input_args(HASHCRYPT_Type * base,hashcrypt_hash_ctx_t * ctx,hashcrypt_algo_t algo)608 static status_t hashcrypt_sha_check_input_args(HASHCRYPT_Type *base, hashcrypt_hash_ctx_t *ctx, hashcrypt_algo_t algo)
609 {
610     /* Check validity of input algorithm */
611     if (kStatus_Success != hashcrypt_sha_check_input_alg(base, algo))
612     {
613         return kStatus_InvalidArgument;
614     }
615 
616     if ((NULL == ctx) || (NULL == base))
617     {
618         return kStatus_InvalidArgument;
619     }
620 
621     return kStatus_Success;
622 }
623 
624 /*!
625  * @brief Check validity of internal software context.
626  *
627  * This function checks if the internal context structure looks correct.
628  *
629  * @param ctxInternal Internal context.
630  * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise.
631  */
hashcrypt_sha_check_context(HASHCRYPT_Type * base,hashcrypt_sha_ctx_internal_t * ctxInternal)632 static status_t hashcrypt_sha_check_context(HASHCRYPT_Type *base, hashcrypt_sha_ctx_internal_t *ctxInternal)
633 {
634     if ((NULL == ctxInternal) || (kStatus_Success != hashcrypt_sha_check_input_alg(base, ctxInternal->algo)))
635     {
636         return kStatus_InvalidArgument;
637     }
638     return kStatus_Success;
639 }
640 
641 /*!
642  * @brief Load 512-bit block (16 words) into SHA engine.
643  *
644  * This function aligns the input block and moves it into SHA engine INDATA.
645  * CPU polls the WAITING bit and then moves data by using LDM and STM instructions.
646  *
647  * @param base SHA peripheral base address.
648  * @param blk 512-bit block
649  */
hashcrypt_sha_one_block(HASHCRYPT_Type * base,const uint8_t * blk)650 static void hashcrypt_sha_one_block(HASHCRYPT_Type *base, const uint8_t *blk)
651 {
652     uint32_t temp[SHA_BLOCK_SIZE / sizeof(uint32_t)];
653     const uint32_t *actBlk;
654 
655     /* make sure the 512-bit block is word aligned */
656     if (0U != ((uintptr_t)blk & 0x3u))
657     {
658         (void)hashcrypt_memcpy(temp, blk, SHA_BLOCK_SIZE);
659         /* Important: do not cast blk to any other type then uint8_t. Depending on the compiler and optimization level,
660          * compiler might decide to use a mempy implementation that does not work on non aligned addresses, resulting in
661          * a hard fault */
662         actBlk = (const uint32_t *)(uintptr_t)temp;
663     }
664     else
665     {
666         actBlk = (const uint32_t *)(uintptr_t)blk;
667     }
668 
669     /* poll waiting. */
670     while (0U == (base->STATUS & HASHCRYPT_STATUS_WAITING_MASK))
671     {
672     }
673     /* feed INDATA (and ALIASes). use STM instruction. */
674     hashcrypt_sha_ldm_stm_16_words(base, actBlk);
675 
676     /* wait for DIGEST computation. */
677     while (0U == (base->STATUS & HASHCRYPT_STATUS_DIGEST_MASK))
678     {
679     }
680 }
681 
682 /*!
683  * @brief Adds message to current hash.
684  *
685  * This function merges the message to fill the internal buffer, empties the internal buffer if
686  * it becomes full, then process all remaining message data.
687  *
688  *
689  * @param base SHA peripheral base address.
690  * @param ctxInternal Internal context.
691  * @param message Input message.
692  * @param messageSize Size of input message in bytes.
693  * @return kStatus_Success if message hashed, kStatus_Fail otherwise.
694  */
hashcrypt_sha_process_message_data(HASHCRYPT_Type * base,hashcrypt_sha_ctx_internal_t * ctxInternal,const uint8_t * message,size_t messageSize)695 static status_t hashcrypt_sha_process_message_data(HASHCRYPT_Type *base,
696                                                    hashcrypt_sha_ctx_internal_t *ctxInternal,
697                                                    const uint8_t *message,
698                                                    size_t messageSize)
699 {
700     status_t status = kStatus_Fail;
701 
702     /* first fill the internal buffer to full block */
703     if (ctxInternal->blksz != 0U)
704     {
705         size_t toCopy = SHA_BLOCK_SIZE - ctxInternal->blksz;
706         (void)hashcrypt_memcpy(&ctxInternal->blk.b[ctxInternal->blksz], message, toCopy);
707         message += toCopy;
708         messageSize -= toCopy;
709 
710         /* process full internal block */
711         hashcrypt_sha_one_block(base, &ctxInternal->blk.b[0]);
712     }
713 
714     /* process all full blocks in message[] */
715     if (messageSize >= SHA_BLOCK_SIZE)
716     {
717         if (0U != ((uintptr_t)message & 0x3u))
718         {
719             while (messageSize >= SHA_BLOCK_SIZE)
720             {
721                 hashcrypt_sha_one_block(base, message);
722                 message += SHA_BLOCK_SIZE;
723                 messageSize -= SHA_BLOCK_SIZE;
724             }
725         }
726         else
727         {
728             /* number of blocks and number of rounds needed to compute hash */
729             uint32_t blkNum        = (messageSize >> 6); /* div by 64 bytes */
730             uint32_t blkFullRounds = blkNum / SHA_MAX_BLOCK_COUNT;
731 
732             /* feed the SHA engine with the maximum possible number of blocks */
733             while (blkFullRounds >= 1U)
734             {
735                 /* poll waiting. */
736                 while (0U == (base->STATUS & HASHCRYPT_STATUS_WAITING_MASK))
737                 {
738                 }
739                 uint32_t blkBytes = SHA_MAX_BLOCK_COUNT * 64u; /* number of bytes in maximum block count */
740 
741                 __DSB();
742                 base->MEMADDR = HASHCRYPT_MEMADDR_BASE(message);
743                 base->MEMCTRL = HASHCRYPT_MEMCTRL_MASTER(1) | HASHCRYPT_MEMCTRL_COUNT(SHA_MAX_BLOCK_COUNT);
744                 __DSB();
745 
746                 while ((0U == (base->STATUS & HASHCRYPT_STATUS_DIGEST_MASK)) &&
747                        (0U == (base->STATUS & HASHCRYPT_STATUS_ERROR_MASK)))
748                 {
749                 }
750                 message += blkBytes;
751                 messageSize -= blkBytes;
752                 blkFullRounds -= 1U;
753                 blkNum -= SHA_MAX_BLOCK_COUNT;
754             }
755 
756             if (blkNum != 0U)
757             {
758                 /* same as above, but only for the remaining number of blocks < SHA_MAX_BLOCK_COUNT */
759                 while (0U == (base->STATUS & HASHCRYPT_STATUS_WAITING_MASK))
760                 {
761                 }
762                 uint32_t blkBytes = blkNum * 64u; /* number of bytes in 64 bytes blocks */
763 
764                 __DSB();
765                 base->MEMADDR = HASHCRYPT_MEMADDR_BASE(message);
766                 base->MEMCTRL = HASHCRYPT_MEMCTRL_MASTER(1) | HASHCRYPT_MEMCTRL_COUNT(blkNum);
767                 __DSB();
768 
769                 while ((0U == (base->STATUS & HASHCRYPT_STATUS_DIGEST_MASK)) &&
770                        (0U == (base->STATUS & HASHCRYPT_STATUS_ERROR_MASK)))
771                 {
772                 }
773                 message += blkBytes;
774                 messageSize -= blkBytes;
775             }
776         }
777     }
778 
779     if (0U == (base->STATUS & HASHCRYPT_STATUS_ERROR_MASK))
780     {
781         status = kStatus_Success;
782     }
783 
784     /* copy last incomplete message bytes into internal block */
785     (void)hashcrypt_memcpy(&ctxInternal->blk.b[0], message, messageSize);
786     ctxInternal->blksz = messageSize;
787     return status;
788 }
789 
790 /*!
791  * @brief Finalize the running hash to make digest.
792  *
793  * This function empties the internal buffer, adds padding bits, and generates final digest.
794  *
795  * @param base SHA peripheral base address.
796  * @param ctxInternal Internal context.
797  * @return kStatus_Success if finalized, kStatus_Fail otherwise.
798  */
hashcrypt_sha_finalize(HASHCRYPT_Type * base,hashcrypt_sha_ctx_internal_t * ctxInternal)799 static status_t hashcrypt_sha_finalize(HASHCRYPT_Type *base, hashcrypt_sha_ctx_internal_t *ctxInternal)
800 {
801     status_t status = kStatus_Fail;
802     hashcrypt_sha_block_t lastBlock;
803 
804     (void)memset(&lastBlock, 0, sizeof(hashcrypt_sha_block_t));
805 
806     /* this is last call, so need to flush buffered message bytes along with padding */
807     if (ctxInternal->blksz <= 55u)
808     {
809         /* last data is 440 bits or less. */
810         (void)hashcrypt_memcpy(&lastBlock.b[0], &ctxInternal->blk.b[0], ctxInternal->blksz);
811         lastBlock.b[ctxInternal->blksz]       = (uint8_t)0x80U;
812         lastBlock.w[SHA_BLOCK_SIZE / 4U - 1U] = swap_bytes(8u * ctxInternal->fullMessageSize);
813         hashcrypt_sha_one_block(base, &lastBlock.b[0]);
814     }
815     else
816     {
817         if (ctxInternal->blksz < SHA_BLOCK_SIZE)
818         {
819             ctxInternal->blk.b[ctxInternal->blksz] = (uint8_t)0x80U;
820             for (uint32_t i = ctxInternal->blksz + 1u; i < SHA_BLOCK_SIZE; i++)
821             {
822                 ctxInternal->blk.b[i] = 0;
823             }
824         }
825         else
826         {
827             lastBlock.b[0] = (uint8_t)0x80U;
828         }
829 
830         hashcrypt_sha_one_block(base, &ctxInternal->blk.b[0]);
831         lastBlock.w[SHA_BLOCK_SIZE / 4U - 1U] = swap_bytes(8u * ctxInternal->fullMessageSize);
832         hashcrypt_sha_one_block(base, &lastBlock.b[0]);
833     }
834     /* poll wait for final digest */
835     while ((0U == (base->STATUS & HASHCRYPT_STATUS_DIGEST_MASK)) &&
836            (0U == (base->STATUS & HASHCRYPT_STATUS_ERROR_MASK)))
837     {
838     }
839 
840     if (0U == (base->STATUS & HASHCRYPT_STATUS_ERROR_MASK))
841     {
842         status = kStatus_Success;
843     }
844 
845     return status;
846 }
847 
hashcrypt_save_running_hash(HASHCRYPT_Type * base,hashcrypt_sha_ctx_internal_t * ctxInternal)848 static status_t hashcrypt_save_running_hash(HASHCRYPT_Type *base, hashcrypt_sha_ctx_internal_t *ctxInternal)
849 {
850 #if defined(FSL_FEATURE_HASHCRYPT_HAS_RELOAD_FEATURE) && (FSL_FEATURE_HASHCRYPT_HAS_RELOAD_FEATURE > 0)
851     status_t status = kStatus_Fail;
852     size_t len      = (ctxInternal->algo == kHASHCRYPT_Sha1) ? SHA1_LEN : SHA256_LEN;
853 
854     /* Wait until digest is ready */
855     while ((0U == (base->STATUS & HASHCRYPT_STATUS_DIGEST_MASK)) &&
856            (0U == (base->STATUS & HASHCRYPT_STATUS_ERROR_MASK)))
857     {
858     }
859 
860     /* Store partial digest to context */
861     for (uint32_t i = 0; i < len; i++)
862     {
863         ctxInternal->runningHash[i] = base->DIGEST0[i];
864     }
865 
866     if (0U == (base->STATUS & HASHCRYPT_STATUS_ERROR_MASK))
867     {
868         status = kStatus_Success;
869     }
870 
871     return status;
872 #else
873     return kStatus_Success;
874 #endif
875 }
876 
hashcrypt_restore_running_hash(HASHCRYPT_Type * base,hashcrypt_sha_ctx_internal_t * ctxInternal)877 static void hashcrypt_restore_running_hash(HASHCRYPT_Type *base, hashcrypt_sha_ctx_internal_t *ctxInternal)
878 {
879 #if defined(FSL_FEATURE_HASHCRYPT_HAS_RELOAD_FEATURE) && (FSL_FEATURE_HASHCRYPT_HAS_RELOAD_FEATURE > 0)
880     size_t len = (ctxInternal->algo == kHASHCRYPT_Sha1) ? SHA1_LEN : SHA256_LEN;
881 
882     /* When switching from different mode, need to set NEW bit to work properly */
883     if ((base->CTRL & HASHCRYPT_CTRL_MODE_MASK) != HASHCRYPT_CTRL_MODE(ctxInternal->algo))
884     {
885         base->CTRL = HASHCRYPT_CTRL_NEW_HASH(1);
886         base->CTRL = HASHCRYPT_CTRL_MODE(ctxInternal->algo) | HASHCRYPT_CTRL_NEW_HASH(1);
887     }
888     /* Set RELOAD bit to allow registers to be used */
889     base->CTRL |= HASHCRYPT_CTRL_RELOAD_MASK;
890 
891     /* Reload partial hash digest */
892     for (uint32_t i = 0; i < len; i++)
893     {
894         base->RELOAD[i] = ctxInternal->runningHash[i];
895     }
896     /* Clear RELOAD register before continuing */
897     base->CTRL &= ~HASHCRYPT_CTRL_RELOAD_MASK;
898 #endif
899 }
900 
901 /* Load random number into PRNG_SEED register */
902 /* Used in AES operations for SCA protection */
hashcrypt_seed_prng(HASHCRYPT_Type * base)903 static void hashcrypt_seed_prng(HASHCRYPT_Type *base)
904 {
905 #if defined(FSL_FEATURE_HASHCRYPT_HAS_RELOAD_FEATURE) && (FSL_FEATURE_HASHCRYPT_HAS_RELOAD_FEATURE > 0)
906 
907 #if defined(FSL_FEATURE_SOC_LPC_RNG1_COUNT) && (FSL_FEATURE_SOC_LPC_RNG1_COUNT > 0)
908     base->PRNG_SEED = RNG->RANDOM_NUMBER;
909 #endif /* defined(FSL_FEATURE_SOC_LPC_RNG1_COUNT) && (FSL_FEATURE_SOC_LPC_RNG1_COUNT > 0) */
910 
911 #if defined(FSL_FEATURE_SOC_TRNG_COUNT) && (FSL_FEATURE_SOC_TRNG_COUNT > 0)
912     base->PRNG_SEED = TRNG->ENT[15];
913 #endif /* defined(FSL_FEATURE_SOC_TRNG_COUNT) && (FSL_FEATURE_SOC_TRNG_COUNT > 0) */
914 
915 #endif /* defined(FSL_FEATURE_HASHCRYPT_HAS_RELOAD_FEATURE) && (FSL_FEATURE_HASHCRYPT_HAS_RELOAD_FEATURE > 0) */
916 }
917 
HASHCRYPT_SHA(HASHCRYPT_Type * base,hashcrypt_algo_t algo,const uint8_t * input,size_t inputSize,uint8_t * output,size_t * outputSize)918 status_t HASHCRYPT_SHA(HASHCRYPT_Type *base,
919                        hashcrypt_algo_t algo,
920                        const uint8_t *input,
921                        size_t inputSize,
922                        uint8_t *output,
923                        size_t *outputSize)
924 {
925     hashcrypt_hash_ctx_t hashCtx;
926     status_t status;
927 
928     status = HASHCRYPT_SHA_Init(base, &hashCtx, algo);
929     if (status != kStatus_Success)
930     {
931         return status;
932     }
933 
934     status = HASHCRYPT_SHA_Update(base, &hashCtx, input, inputSize);
935     if (status != kStatus_Success)
936     {
937         return status;
938     }
939 
940     status = HASHCRYPT_SHA_Finish(base, &hashCtx, output, outputSize);
941 
942     return status;
943 }
944 
HASHCRYPT_SHA_Init(HASHCRYPT_Type * base,hashcrypt_hash_ctx_t * ctx,hashcrypt_algo_t algo)945 status_t HASHCRYPT_SHA_Init(HASHCRYPT_Type *base, hashcrypt_hash_ctx_t *ctx, hashcrypt_algo_t algo)
946 {
947     status_t status;
948 
949     hashcrypt_sha_ctx_internal_t *ctxInternal;
950     /* compile time check for the correct structure size */
951     BUILD_ASSERT(sizeof(hashcrypt_hash_ctx_t) >= sizeof(hashcrypt_sha_ctx_internal_t), hashcrypt_hash_ctx_t_size);
952 
953     status = hashcrypt_sha_check_input_args(base, ctx, algo);
954     if (status != kStatus_Success)
955     {
956         return status;
957     }
958 
959     /* set algorithm in context struct for later use */
960     ctxInternal        = (hashcrypt_sha_ctx_internal_t *)(uint32_t)ctx;
961     ctxInternal->algo  = algo;
962     ctxInternal->blksz = 0u;
963 #ifdef HASHCRYPT_SHA_DO_WIPE_CONTEXT
964     for (int i = 0; i < sizeof(ctxInternal->blk.w) / sizeof(ctxInternal->blk.w[0]); i++)
965     {
966         ctxInternal->blk.w[i] = 0u;
967     }
968 #endif /* HASHCRYPT_SHA_DO_WIPE_CONTEXT */
969     ctxInternal->state           = kHASHCRYPT_HashInit;
970     ctxInternal->fullMessageSize = 0;
971     return kStatus_Success;
972 }
973 
HASHCRYPT_SHA_Update(HASHCRYPT_Type * base,hashcrypt_hash_ctx_t * ctx,const uint8_t * input,size_t inputSize)974 status_t HASHCRYPT_SHA_Update(HASHCRYPT_Type *base, hashcrypt_hash_ctx_t *ctx, const uint8_t *input, size_t inputSize)
975 {
976     bool isUpdateState;
977     status_t status;
978     hashcrypt_sha_ctx_internal_t *ctxInternal;
979     size_t blockSize;
980 
981     if (inputSize == 0U)
982     {
983         return kStatus_Success;
984     }
985 
986     ctxInternal = (hashcrypt_sha_ctx_internal_t *)(uint32_t)ctx;
987 #ifdef HASHCRYPT_SHA_DO_CHECK_CONTEXT
988     status = hashcrypt_sha_check_context(base, ctxInternal);
989     if (kStatus_Success != status)
990     {
991         return status;
992     }
993 #endif /* HASHCRYPT_SHA_DO_CHECK_CONTEXT */
994 
995     ctxInternal->fullMessageSize += inputSize;
996     blockSize = SHA_BLOCK_SIZE;
997     /* if we are still less than 64 bytes, keep only in context */
998     if ((ctxInternal->blksz + inputSize) <= blockSize)
999     {
1000         (void)hashcrypt_memcpy((&ctxInternal->blk.b[0]) + ctxInternal->blksz, input, inputSize);
1001         ctxInternal->blksz += inputSize;
1002         return kStatus_Success;
1003     }
1004     else
1005     {
1006         isUpdateState = ctxInternal->state == kHASHCRYPT_HashUpdate;
1007         if (!isUpdateState)
1008         {
1009             /* start NEW hash */
1010             hashcrypt_engine_init(base, ctxInternal->algo);
1011             ctxInternal->state = kHASHCRYPT_HashUpdate;
1012         }
1013         else
1014         {
1015             hashcrypt_restore_running_hash(base, ctxInternal);
1016         }
1017     }
1018 
1019     /* process message data */
1020     /* Data Synchronization Barrier */
1021     __DSB();
1022     status = hashcrypt_sha_process_message_data(base, ctxInternal, input, inputSize);
1023     if (kStatus_Success != status)
1024     {
1025         return status;
1026     }
1027 
1028     __DSB();
1029     status = hashcrypt_save_running_hash(base, ctxInternal);
1030     return status;
1031 }
1032 
HASHCRYPT_SHA_Finish(HASHCRYPT_Type * base,hashcrypt_hash_ctx_t * ctx,uint8_t * output,size_t * outputSize)1033 status_t HASHCRYPT_SHA_Finish(HASHCRYPT_Type *base, hashcrypt_hash_ctx_t *ctx, uint8_t *output, size_t *outputSize)
1034 {
1035     size_t algOutSize = 0;
1036     status_t status;
1037     hashcrypt_sha_ctx_internal_t *ctxInternal;
1038 #ifdef HASHCRYPT_SHA_DO_CHECK_CONTEXT
1039     uint32_t *ctxW;
1040     uint32_t i;
1041 #endif /* HASHCRYPT_SHA_DO_CHECK_CONTEXT */
1042 
1043     if (output == NULL)
1044     {
1045         return kStatus_InvalidArgument;
1046     }
1047 
1048     ctxInternal = (hashcrypt_sha_ctx_internal_t *)(uint32_t)ctx;
1049 #ifdef HASHCRYPT_SHA_DO_CHECK_CONTEXT
1050     status = hashcrypt_sha_check_context(base, ctxInternal);
1051     if (kStatus_Success != status)
1052     {
1053         return status;
1054     }
1055 #endif /* HASHCRYPT_SHA_DO_CHECK_CONTEXT */
1056 
1057     if (ctxInternal->state == kHASHCRYPT_HashInit)
1058     {
1059         hashcrypt_engine_init(base, ctxInternal->algo);
1060     }
1061     else
1062     {
1063         hashcrypt_restore_running_hash(base, ctxInternal);
1064     }
1065 
1066     size_t outSize = 0u;
1067 
1068     /* compute algorithm output length */
1069     switch (ctxInternal->algo)
1070     {
1071         case kHASHCRYPT_Sha1:
1072             outSize = (size_t)kHASHCRYPT_OutLenSha1;
1073             break;
1074         case kHASHCRYPT_Sha256:
1075             outSize = (size_t)kHASHCRYPT_OutLenSha256;
1076             break;
1077         default:
1078             /* All the cases have been listed above, the default clause should not be reached. */
1079             break;
1080     }
1081     algOutSize = outSize;
1082 
1083     /* flush message last incomplete block, if there is any, and add padding bits */
1084     status = hashcrypt_sha_finalize(base, ctxInternal);
1085     if (kStatus_Success != status)
1086     {
1087         return status;
1088     }
1089 
1090     if (outputSize != NULL)
1091     {
1092         if (algOutSize < *outputSize)
1093         {
1094             *outputSize = algOutSize;
1095         }
1096         else
1097         {
1098             algOutSize = *outputSize;
1099         }
1100     }
1101 
1102     status = hashcrypt_get_data(base, output, algOutSize);
1103     if (kStatus_Success != status)
1104     {
1105         return status;
1106     }
1107 
1108 #ifdef HASHCRYPT_SHA_DO_WIPE_CONTEXT
1109     ctxW = (uint32_t *)ctx;
1110     for (i = 0; i < HASHCRYPT_HASH_CTX_SIZE; i++)
1111     {
1112         ctxW[i] = 0u;
1113     }
1114 #endif /* HASHCRYPT_SHA_DO_WIPE_CONTEXT */
1115     return status;
1116 }
1117 
HASHCRYPT_SHA_SetCallback(HASHCRYPT_Type * base,hashcrypt_hash_ctx_t * ctx,hashcrypt_callback_t callback,void * userData)1118 void HASHCRYPT_SHA_SetCallback(HASHCRYPT_Type *base,
1119                                hashcrypt_hash_ctx_t *ctx,
1120                                hashcrypt_callback_t callback,
1121                                void *userData)
1122 {
1123     hashcrypt_sha_ctx_internal_t *ctxInternal;
1124 
1125     s_ctx                     = ctx;
1126     ctxInternal               = (hashcrypt_sha_ctx_internal_t *)(uint32_t)ctx;
1127     ctxInternal->hashCallback = callback;
1128     ctxInternal->userData     = userData;
1129 
1130     (void)EnableIRQ(HASHCRYPT_IRQn);
1131 }
1132 
HASHCRYPT_SHA_UpdateNonBlocking(HASHCRYPT_Type * base,hashcrypt_hash_ctx_t * ctx,const uint8_t * input,size_t inputSize)1133 status_t HASHCRYPT_SHA_UpdateNonBlocking(HASHCRYPT_Type *base,
1134                                          hashcrypt_hash_ctx_t *ctx,
1135                                          const uint8_t *input,
1136                                          size_t inputSize)
1137 {
1138     hashcrypt_sha_ctx_internal_t *ctxInternal;
1139     uint32_t numBlocks;
1140     status_t status;
1141 
1142     if (inputSize == 0U)
1143     {
1144         return kStatus_Success;
1145     }
1146 
1147     if (0U != ((uintptr_t)input & 0x3U))
1148     {
1149         return kStatus_Fail;
1150     }
1151 
1152     ctxInternal = (hashcrypt_sha_ctx_internal_t *)(uint32_t)ctx;
1153     status      = hashcrypt_sha_check_context(base, ctxInternal);
1154     if (kStatus_Success != status)
1155     {
1156         return status;
1157     }
1158 
1159     ctxInternal->fullMessageSize = inputSize;
1160     ctxInternal->remainingBlcks  = inputSize / SHA_BLOCK_SIZE;
1161     ctxInternal->blksz           = inputSize % SHA_BLOCK_SIZE;
1162 
1163     /* copy last incomplete block to context */
1164     if ((ctxInternal->blksz > 0U) && (ctxInternal->blksz <= SHA_BLOCK_SIZE))
1165     {
1166         (void)hashcrypt_memcpy((&ctxInternal->blk.b[0]), input + SHA_BLOCK_SIZE * ctxInternal->remainingBlcks,
1167                                ctxInternal->blksz);
1168     }
1169 
1170     if (ctxInternal->remainingBlcks >= SHA_MASTER_MAX_BLOCKS)
1171     {
1172         numBlocks = SHA_MASTER_MAX_BLOCKS - 1U;
1173     }
1174     else
1175     {
1176         numBlocks = ctxInternal->remainingBlcks;
1177     }
1178     /* update remainingBlks so that ISR can run another hash if necessary */
1179     ctxInternal->remainingBlcks -= numBlocks;
1180 
1181     /* compute hash using AHB Master mode for full blocks */
1182     if (numBlocks > 0U)
1183     {
1184         ctxInternal->state = kHASHCRYPT_HashUpdate;
1185         hashcrypt_engine_init(base, ctxInternal->algo);
1186 
1187         /* Enable digest and error interrupts and start hash */
1188         base->INTENSET = HASHCRYPT_INTENCLR_DIGEST_MASK | HASHCRYPT_INTENCLR_ERROR_MASK;
1189         base->MEMADDR  = HASHCRYPT_MEMADDR_BASE(input);
1190         base->MEMCTRL  = HASHCRYPT_MEMCTRL_MASTER(1) | HASHCRYPT_MEMCTRL_COUNT(numBlocks);
1191     }
1192     /* no full blocks, invoke callback directly */
1193     else
1194     {
1195         ctxInternal->hashCallback(HASHCRYPT, ctx, status, ctxInternal->userData);
1196     }
1197 
1198     return status;
1199 }
1200 
HASHCRYPT_AES_SetKey(HASHCRYPT_Type * base,hashcrypt_handle_t * handle,const uint8_t * key,size_t keySize)1201 status_t HASHCRYPT_AES_SetKey(HASHCRYPT_Type *base, hashcrypt_handle_t *handle, const uint8_t *key, size_t keySize)
1202 {
1203     status_t retVal = kStatus_InvalidArgument;
1204 
1205     switch (keySize)
1206     {
1207         case 16:
1208             handle->keySize = kHASHCRYPT_Aes128;
1209             break;
1210         case 24:
1211             handle->keySize = kHASHCRYPT_Aes192;
1212             break;
1213         case 32:
1214             handle->keySize = kHASHCRYPT_Aes256;
1215             break;
1216         default:
1217             handle->keySize = kHASHCRYPT_InvalidKey;
1218             break;
1219     }
1220 
1221     if (handle->keySize == kHASHCRYPT_InvalidKey)
1222     {
1223         return retVal;
1224     }
1225 
1226     if (handle->keyType == kHASHCRYPT_SecretKey)
1227     {
1228         /* for kHASHCRYPT_SecretKey just return Success */
1229         retVal = kStatus_Success;
1230     }
1231     else if (handle->keyType == kHASHCRYPT_UserKey)
1232     {
1233         retVal = hashcrypt_get_key_from_unaligned_src((uint8_t *)&handle->keyWord[0], key, keySize);
1234     }
1235     else
1236     {
1237         retVal = kStatus_InvalidArgument;
1238     }
1239 
1240     return retVal;
1241 }
1242 
HASHCRYPT_AES_EncryptEcb(HASHCRYPT_Type * base,hashcrypt_handle_t * handle,const uint8_t * plaintext,uint8_t * ciphertext,size_t size)1243 status_t HASHCRYPT_AES_EncryptEcb(
1244     HASHCRYPT_Type *base, hashcrypt_handle_t *handle, const uint8_t *plaintext, uint8_t *ciphertext, size_t size)
1245 {
1246     status_t status = kStatus_Fail;
1247 
1248     if ((0U != (size % 16u)) || (handle->keySize == kHASHCRYPT_InvalidKey))
1249     {
1250         return kStatus_InvalidArgument;
1251     }
1252 
1253     hashcrypt_seed_prng(base);
1254 
1255     uint32_t keyType = (handle->keyType == kHASHCRYPT_UserKey) ? 0U : 1u;
1256     base->CRYPTCFG   = HASHCRYPT_CRYPTCFG_AESMODE(kHASHCRYPT_AesEcb) | HASHCRYPT_CRYPTCFG_AESDECRYPT(AES_ENCRYPT) |
1257                      HASHCRYPT_CRYPTCFG_AESSECRET(keyType) | HASHCRYPT_CRYPTCFG_AESKEYSZ(handle->keySize) |
1258                      HASHCRYPT_CRYPTCFG_MSW1ST_OUT(1) | HASHCRYPT_CRYPTCFG_SWAPKEY(1) | HASHCRYPT_CRYPTCFG_SWAPDAT(1) |
1259                      HASHCRYPT_CRYPTCFG_MSW1ST(1);
1260 
1261     hashcrypt_engine_init(base, kHASHCRYPT_Aes);
1262 
1263     /* in case of HW AES key, check if it is available */
1264     if (hashcrypt_check_need_key(base, handle) != kStatus_Success)
1265     {
1266         hashcrypt_engine_deinit(base);
1267         return kStatus_Fail;
1268     }
1269 
1270     /* load key if kHASHCRYPT_UserKey is selected */
1271     if (handle->keyType == kHASHCRYPT_UserKey)
1272     {
1273         hashcrypt_aes_load_userKey(base, handle);
1274     }
1275 
1276     /* load message and get result */
1277     status = hashcrypt_aes_one_block(base, plaintext, ciphertext, size);
1278     /* After processing all data, hashcrypt engine is set to disabled to lower power consumption */
1279     hashcrypt_engine_deinit(base);
1280 
1281     return status;
1282 }
1283 
HASHCRYPT_AES_DecryptEcb(HASHCRYPT_Type * base,hashcrypt_handle_t * handle,const uint8_t * ciphertext,uint8_t * plaintext,size_t size)1284 status_t HASHCRYPT_AES_DecryptEcb(
1285     HASHCRYPT_Type *base, hashcrypt_handle_t *handle, const uint8_t *ciphertext, uint8_t *plaintext, size_t size)
1286 {
1287     status_t status = kStatus_Fail;
1288 
1289     if ((0U != (size % 16u)) || (handle->keySize == kHASHCRYPT_InvalidKey))
1290     {
1291         return kStatus_InvalidArgument;
1292     }
1293 
1294     hashcrypt_seed_prng(base);
1295 
1296     uint32_t keyType = (handle->keyType == kHASHCRYPT_UserKey) ? 0U : 1u;
1297     base->CRYPTCFG   = HASHCRYPT_CRYPTCFG_AESMODE(kHASHCRYPT_AesEcb) | HASHCRYPT_CRYPTCFG_AESDECRYPT(AES_DECRYPT) |
1298                      HASHCRYPT_CRYPTCFG_AESSECRET(keyType) | HASHCRYPT_CRYPTCFG_AESKEYSZ(handle->keySize) |
1299                      HASHCRYPT_CRYPTCFG_MSW1ST_OUT(1) | HASHCRYPT_CRYPTCFG_SWAPKEY(1) | HASHCRYPT_CRYPTCFG_SWAPDAT(1) |
1300                      HASHCRYPT_CRYPTCFG_MSW1ST(1);
1301 
1302     hashcrypt_engine_init(base, kHASHCRYPT_Aes);
1303 
1304     /* in case of HW AES key, check if it is available */
1305     if (hashcrypt_check_need_key(base, handle) != kStatus_Success)
1306     {
1307         hashcrypt_engine_deinit(base);
1308         return kStatus_Fail;
1309     }
1310 
1311     /* load key if kHASHCRYPT_UserKey is selected */
1312     if (handle->keyType == kHASHCRYPT_UserKey)
1313     {
1314         hashcrypt_aes_load_userKey(base, handle);
1315     }
1316 
1317     /* load message and get result */
1318     status = hashcrypt_aes_one_block(base, ciphertext, plaintext, size);
1319 
1320     /* After processing all data, hashcrypt engine is set to disabled to lower power consumption */
1321     hashcrypt_engine_deinit(base);
1322     return status;
1323 }
1324 
HASHCRYPT_AES_EncryptCbc(HASHCRYPT_Type * base,hashcrypt_handle_t * handle,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t iv[16])1325 status_t HASHCRYPT_AES_EncryptCbc(HASHCRYPT_Type *base,
1326                                   hashcrypt_handle_t *handle,
1327                                   const uint8_t *plaintext,
1328                                   uint8_t *ciphertext,
1329                                   size_t size,
1330                                   const uint8_t iv[16])
1331 {
1332     status_t status = kStatus_Fail;
1333 
1334     if (0U != ((size % 16u)) || (handle->keySize == kHASHCRYPT_InvalidKey))
1335     {
1336         return kStatus_InvalidArgument;
1337     }
1338 
1339     hashcrypt_seed_prng(base);
1340 
1341     uint32_t keyType = (handle->keyType == kHASHCRYPT_UserKey) ? 0U : 1u;
1342     base->CRYPTCFG   = HASHCRYPT_CRYPTCFG_AESMODE(kHASHCRYPT_AesCbc) | HASHCRYPT_CRYPTCFG_AESDECRYPT(AES_ENCRYPT) |
1343                      HASHCRYPT_CRYPTCFG_AESSECRET(keyType) | HASHCRYPT_CRYPTCFG_AESKEYSZ(handle->keySize) |
1344                      HASHCRYPT_CRYPTCFG_MSW1ST_OUT(1) | HASHCRYPT_CRYPTCFG_SWAPKEY(1) | HASHCRYPT_CRYPTCFG_SWAPDAT(1) |
1345                      HASHCRYPT_CRYPTCFG_MSW1ST(1);
1346 
1347     hashcrypt_engine_init(base, kHASHCRYPT_Aes);
1348 
1349     /* in case of HW AES key, check if it is available */
1350     if (hashcrypt_check_need_key(base, handle) != kStatus_Success)
1351     {
1352         hashcrypt_engine_deinit(base);
1353         return kStatus_Fail;
1354     }
1355 
1356     /* load key if kHASHCRYPT_UserKey is selected */
1357     if (handle->keyType == kHASHCRYPT_UserKey)
1358     {
1359         hashcrypt_aes_load_userKey(base, handle);
1360     }
1361 
1362     /* load 16b iv */
1363     hashcrypt_load_data(base, (uint32_t *)(uintptr_t)iv, 16);
1364 
1365     /* load message and get result */
1366     status = hashcrypt_aes_one_block(base, plaintext, ciphertext, size);
1367 
1368     /* After processing all data, hashcrypt engine is set to disabled to lower power consumption */
1369     hashcrypt_engine_deinit(base);
1370     return status;
1371 }
1372 
HASHCRYPT_AES_DecryptCbc(HASHCRYPT_Type * base,hashcrypt_handle_t * handle,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t iv[16])1373 status_t HASHCRYPT_AES_DecryptCbc(HASHCRYPT_Type *base,
1374                                   hashcrypt_handle_t *handle,
1375                                   const uint8_t *ciphertext,
1376                                   uint8_t *plaintext,
1377                                   size_t size,
1378                                   const uint8_t iv[16])
1379 {
1380     status_t status = kStatus_Fail;
1381 
1382     if ((0U != (size % 16u)) || (handle->keySize == kHASHCRYPT_InvalidKey))
1383     {
1384         return kStatus_InvalidArgument;
1385     }
1386 
1387     hashcrypt_seed_prng(base);
1388 
1389     uint32_t keyType = (handle->keyType == kHASHCRYPT_UserKey) ? 0U : 1u;
1390     base->CRYPTCFG   = HASHCRYPT_CRYPTCFG_AESMODE(kHASHCRYPT_AesCbc) | HASHCRYPT_CRYPTCFG_AESDECRYPT(AES_DECRYPT) |
1391                      HASHCRYPT_CRYPTCFG_AESSECRET(keyType) | HASHCRYPT_CRYPTCFG_AESKEYSZ(handle->keySize) |
1392                      HASHCRYPT_CRYPTCFG_MSW1ST_OUT(1) | HASHCRYPT_CRYPTCFG_SWAPKEY(1) | HASHCRYPT_CRYPTCFG_SWAPDAT(1) |
1393                      HASHCRYPT_CRYPTCFG_MSW1ST(1);
1394 
1395     hashcrypt_engine_init(base, kHASHCRYPT_Aes);
1396 
1397     /* in case of HW AES key, check if it is available */
1398     if (hashcrypt_check_need_key(base, handle) != kStatus_Success)
1399     {
1400         hashcrypt_engine_deinit(base);
1401         return kStatus_Fail;
1402     }
1403 
1404     /* load key if kHASHCRYPT_UserKey is selected */
1405     if (handle->keyType == kHASHCRYPT_UserKey)
1406     {
1407         hashcrypt_aes_load_userKey(base, handle);
1408     }
1409 
1410     /* load iv */
1411     hashcrypt_load_data(base, (uint32_t *)(uintptr_t)iv, 16);
1412 
1413     /* load message and get result */
1414     status = hashcrypt_aes_one_block(base, ciphertext, plaintext, size);
1415 
1416     /* After processing all data, hashcrypt engine is set to disabled to lower power consumption */
1417     hashcrypt_engine_deinit(base);
1418     return status;
1419 }
1420 
HASHCRYPT_AES_CryptCtr(HASHCRYPT_Type * base,hashcrypt_handle_t * handle,const uint8_t * input,uint8_t * output,size_t size,uint8_t counter[HASHCRYPT_AES_BLOCK_SIZE],uint8_t counterlast[HASHCRYPT_AES_BLOCK_SIZE],size_t * szLeft)1421 status_t HASHCRYPT_AES_CryptCtr(HASHCRYPT_Type *base,
1422                                 hashcrypt_handle_t *handle,
1423                                 const uint8_t *input,
1424                                 uint8_t *output,
1425                                 size_t size,
1426                                 uint8_t counter[HASHCRYPT_AES_BLOCK_SIZE],
1427                                 uint8_t counterlast[HASHCRYPT_AES_BLOCK_SIZE],
1428                                 size_t *szLeft)
1429 {
1430     uint32_t lastSize;
1431     uint8_t lastBlock[HASHCRYPT_AES_BLOCK_SIZE] = {0};
1432     uint8_t *lastEncryptedCounter;
1433     status_t status = kStatus_Fail;
1434 
1435     if (handle->keySize == kHASHCRYPT_InvalidKey)
1436     {
1437         return kStatus_InvalidArgument;
1438     }
1439 
1440     hashcrypt_seed_prng(base);
1441 
1442     uint32_t keyType = (handle->keyType == kHASHCRYPT_UserKey) ? 0U : 1u;
1443     base->CRYPTCFG   = HASHCRYPT_CRYPTCFG_AESMODE(kHASHCRYPT_AesCtr) | HASHCRYPT_CRYPTCFG_AESDECRYPT(AES_ENCRYPT) |
1444                      HASHCRYPT_CRYPTCFG_AESSECRET(keyType) | HASHCRYPT_CRYPTCFG_AESKEYSZ(handle->keySize) |
1445                      HASHCRYPT_CRYPTCFG_MSW1ST_OUT(1) | HASHCRYPT_CRYPTCFG_SWAPKEY(1) | HASHCRYPT_CRYPTCFG_SWAPDAT(1) |
1446                      HASHCRYPT_CRYPTCFG_MSW1ST(1);
1447 
1448     hashcrypt_engine_init(base, kHASHCRYPT_Aes);
1449 
1450     /* in case of HW AES key, check if it is available */
1451     if (hashcrypt_check_need_key(base, handle) != kStatus_Success)
1452     {
1453         hashcrypt_engine_deinit(base);
1454         return kStatus_Fail;
1455     }
1456 
1457     /* load key if kHASHCRYPT_UserKey is selected */
1458     if (handle->keyType == kHASHCRYPT_UserKey)
1459     {
1460         hashcrypt_aes_load_userKey(base, handle);
1461     }
1462 
1463     /* load nonce */
1464     hashcrypt_load_data(base, (uint32_t *)(uintptr_t)counter, 16);
1465 
1466     lastSize = size % HASHCRYPT_AES_BLOCK_SIZE;
1467     size -= lastSize;
1468 
1469     /* encrypt full 16byte blocks */
1470     status = hashcrypt_aes_one_block(base, input, output, size);
1471     if (status != kStatus_Success)
1472     {
1473         hashcrypt_engine_deinit(base);
1474         return status;
1475     }
1476 
1477     while (size != 0U)
1478     {
1479         ctrIncrement(counter);
1480         size -= 16u;
1481         input += 16;
1482         output += 16;
1483     }
1484 
1485     if (lastSize != 0U)
1486     {
1487         if (counterlast != NULL)
1488         {
1489             lastEncryptedCounter = counterlast;
1490         }
1491         else
1492         {
1493             lastEncryptedCounter = lastBlock;
1494         }
1495 
1496         /* Perform encryption with all zeros to get last counter. XOR with zeros doesn't change. */
1497         status = hashcrypt_aes_one_block(base, lastBlock, lastEncryptedCounter, HASHCRYPT_AES_BLOCK_SIZE);
1498         if (status != kStatus_Success)
1499         {
1500             hashcrypt_engine_deinit(base);
1501             return status;
1502         }
1503         /* remain output = input XOR counterlast */
1504         for (uint32_t i = 0; i < lastSize; i++)
1505         {
1506             output[i] = input[i] ^ lastEncryptedCounter[i];
1507         }
1508         /* Increment counter parameter */
1509         ctrIncrement(counter);
1510     }
1511     else
1512     {
1513         lastSize = HASHCRYPT_AES_BLOCK_SIZE;
1514         /* no remaining bytes in couterlast so clearing it */
1515         if (counterlast != NULL)
1516         {
1517             (void)memset(counterlast, 0, HASHCRYPT_AES_BLOCK_SIZE);
1518         }
1519     }
1520 
1521     if (szLeft != NULL)
1522     {
1523         *szLeft = HASHCRYPT_AES_BLOCK_SIZE - lastSize;
1524     }
1525 
1526     /* After processing all data, hashcrypt engine is set to disabled to lower power consumption */
1527     hashcrypt_engine_deinit(base);
1528     return kStatus_Success;
1529 }
1530 
HASHCRYPT_AES_CryptOfb(HASHCRYPT_Type * base,hashcrypt_handle_t * handle,const uint8_t * input,uint8_t * output,size_t size,const uint8_t iv[HASHCRYPT_AES_BLOCK_SIZE])1531 status_t HASHCRYPT_AES_CryptOfb(HASHCRYPT_Type *base,
1532                                 hashcrypt_handle_t *handle,
1533                                 const uint8_t *input,
1534                                 uint8_t *output,
1535                                 size_t size,
1536                                 const uint8_t iv[HASHCRYPT_AES_BLOCK_SIZE])
1537 {
1538     status_t status                               = kStatus_Fail;
1539     uint8_t zeroes[HASHCRYPT_AES_BLOCK_SIZE]      = {0};
1540     uint8_t blockOutput[HASHCRYPT_AES_BLOCK_SIZE] = {0};
1541 
1542     if (handle->keySize == kHASHCRYPT_InvalidKey)
1543     {
1544         return kStatus_InvalidArgument;
1545     }
1546 
1547     uint32_t keyType = (handle->keyType == kHASHCRYPT_UserKey) ? 0U : 1u;
1548 
1549     hashcrypt_seed_prng(base);
1550 
1551     base->CRYPTCFG = HASHCRYPT_CRYPTCFG_AESMODE(kHASHCRYPT_AesCbc) | HASHCRYPT_CRYPTCFG_AESDECRYPT(AES_ENCRYPT) |
1552                      HASHCRYPT_CRYPTCFG_AESSECRET(keyType) | HASHCRYPT_CRYPTCFG_AESKEYSZ(handle->keySize) |
1553                      HASHCRYPT_CRYPTCFG_MSW1ST_OUT(1) | HASHCRYPT_CRYPTCFG_SWAPKEY(1) | HASHCRYPT_CRYPTCFG_SWAPDAT(1) |
1554                      HASHCRYPT_CRYPTCFG_MSW1ST(1);
1555 
1556     hashcrypt_engine_init(base, kHASHCRYPT_Aes);
1557 
1558     /* in case of HW AES key, check if it is available */
1559     if (hashcrypt_check_need_key(base, handle) != kStatus_Success)
1560     {
1561         hashcrypt_engine_deinit(base);
1562         return kStatus_Fail;
1563     }
1564 
1565     /* load key if kHASHCRYPT_UserKey is selected */
1566     if (handle->keyType == kHASHCRYPT_UserKey)
1567     {
1568         hashcrypt_aes_load_userKey(base, handle);
1569     }
1570 
1571     /* load iv */
1572     hashcrypt_load_data(base, (uint32_t *)(uintptr_t)iv, HASHCRYPT_AES_BLOCK_SIZE);
1573 
1574     /*Use AES CBC mode and feed input with zeroes as input*/
1575     /*Output block is then XORed with input*/
1576 
1577     while (size >= 16u)
1578     {
1579         status = hashcrypt_aes_one_block(base, zeroes, blockOutput, HASHCRYPT_AES_BLOCK_SIZE);
1580         if (status != kStatus_Success)
1581         {
1582             hashcrypt_engine_deinit(base);
1583             return status;
1584         }
1585         /* XOR input with output block to get output*/
1586         for (uint32_t i = 0; i < HASHCRYPT_AES_BLOCK_SIZE; i++)
1587         {
1588             output[i] = input[i] ^ blockOutput[i];
1589         }
1590         size -= 16u;
1591         output += 16;
1592         input += 16;
1593     }
1594 
1595     /* OFB can have non-block multiple size.*/
1596     if (size != 0U)
1597     {
1598         status = hashcrypt_aes_one_block(base, zeroes, blockOutput, HASHCRYPT_AES_BLOCK_SIZE);
1599         if (status != kStatus_Success)
1600         {
1601             hashcrypt_engine_deinit(base);
1602             return status;
1603         }
1604 
1605         /* XOR input with output block to get output*/
1606         for (uint32_t i = 0; i < size; i++)
1607         {
1608             output[i] = input[i] ^ blockOutput[i];
1609         }
1610     }
1611 
1612     /* After processing all data, hashcrypt engine is set to disabled to lower power consumption */
1613     hashcrypt_engine_deinit(base);
1614     return status;
1615 }
1616 
HASHCRYPT_AES_EncryptCfb(HASHCRYPT_Type * base,hashcrypt_handle_t * handle,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t iv[HASHCRYPT_AES_BLOCK_SIZE])1617 status_t HASHCRYPT_AES_EncryptCfb(HASHCRYPT_Type *base,
1618                                   hashcrypt_handle_t *handle,
1619                                   const uint8_t *plaintext,
1620                                   uint8_t *ciphertext,
1621                                   size_t size,
1622                                   const uint8_t iv[HASHCRYPT_AES_BLOCK_SIZE])
1623 {
1624     status_t status                               = kStatus_Fail;
1625     uint8_t zeroes[HASHCRYPT_AES_BLOCK_SIZE]      = {0};
1626     uint8_t blockOutput[HASHCRYPT_AES_BLOCK_SIZE] = {0};
1627 
1628     /* For CFB mode size must be 16-byte multiple */
1629     if ((0U != (size % 16u)) || (handle->keySize == kHASHCRYPT_InvalidKey))
1630     {
1631         return kStatus_InvalidArgument;
1632     }
1633 
1634     uint32_t keyType = (handle->keyType == kHASHCRYPT_UserKey) ? 0U : 1u;
1635 
1636     hashcrypt_seed_prng(base);
1637 
1638     base->CRYPTCFG = HASHCRYPT_CRYPTCFG_AESMODE(kHASHCRYPT_AesCbc) | HASHCRYPT_CRYPTCFG_AESDECRYPT(AES_ENCRYPT) |
1639                      HASHCRYPT_CRYPTCFG_AESSECRET(keyType) | HASHCRYPT_CRYPTCFG_AESKEYSZ(handle->keySize) |
1640                      HASHCRYPT_CRYPTCFG_MSW1ST_OUT(1) | HASHCRYPT_CRYPTCFG_SWAPKEY(1) | HASHCRYPT_CRYPTCFG_SWAPDAT(1) |
1641                      HASHCRYPT_CRYPTCFG_MSW1ST(1);
1642 
1643     hashcrypt_engine_init(base, kHASHCRYPT_Aes);
1644 
1645     /* in case of HW AES key, check if it is available */
1646     if (hashcrypt_check_need_key(base, handle) != kStatus_Success)
1647     {
1648         hashcrypt_engine_deinit(base);
1649         return kStatus_Fail;
1650     }
1651 
1652     /* load key if kHASHCRYPT_UserKey is selected */
1653     if (handle->keyType == kHASHCRYPT_UserKey)
1654     {
1655         hashcrypt_aes_load_userKey(base, handle);
1656     }
1657 
1658     /* load iv */
1659     hashcrypt_load_data(base, (uint32_t *)(uintptr_t)iv, HASHCRYPT_AES_BLOCK_SIZE);
1660 
1661     /*Use AES CBC mode and feed input with zeroes for first block */
1662     /*Output block is then XORed with plaintext to get ciphertext*/
1663 
1664     status = hashcrypt_aes_one_block(base, zeroes, blockOutput, HASHCRYPT_AES_BLOCK_SIZE);
1665     if (status != kStatus_Success)
1666     {
1667         hashcrypt_engine_deinit(base);
1668         return status;
1669     }
1670     /* XOR plaintext with output block to get ciphertext*/
1671     for (uint32_t i = 0; i < HASHCRYPT_AES_BLOCK_SIZE; i++)
1672     {
1673         ciphertext[i] = plaintext[i] ^ blockOutput[i];
1674     }
1675     size -= 16u;
1676 
1677     /*Remaining blocks use previous plaintext as input for aes block function */
1678     while (size >= 16u)
1679     {
1680         status = hashcrypt_aes_one_block(base, plaintext, blockOutput, HASHCRYPT_AES_BLOCK_SIZE);
1681         ciphertext += 16;
1682         plaintext += 16;
1683 
1684         if (status != kStatus_Success)
1685         {
1686             hashcrypt_engine_deinit(base);
1687             return status;
1688         }
1689         /* XOR plaintext with output block to get ciphertext*/
1690         for (uint32_t i = 0; i < HASHCRYPT_AES_BLOCK_SIZE; i++)
1691         {
1692             ciphertext[i] = plaintext[i] ^ blockOutput[i];
1693         }
1694         size -= 16u;
1695     }
1696 
1697     /* After processing all data, hashcrypt engine is set to disabled to lower power consumption */
1698     hashcrypt_engine_deinit(base);
1699     return status;
1700 }
1701 
HASHCRYPT_AES_DecryptCfb(HASHCRYPT_Type * base,hashcrypt_handle_t * handle,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t iv[HASHCRYPT_AES_BLOCK_SIZE])1702 status_t HASHCRYPT_AES_DecryptCfb(HASHCRYPT_Type *base,
1703                                   hashcrypt_handle_t *handle,
1704                                   const uint8_t *ciphertext,
1705                                   uint8_t *plaintext,
1706                                   size_t size,
1707                                   const uint8_t iv[HASHCRYPT_AES_BLOCK_SIZE])
1708 {
1709     status_t status                               = kStatus_Fail;
1710     uint8_t zeroes[HASHCRYPT_AES_BLOCK_SIZE]      = {0};
1711     uint8_t blockOutput[HASHCRYPT_AES_BLOCK_SIZE] = {0};
1712 
1713     /* For CFB mode size must be 16-byte multiple */
1714     if ((0U != (size % 16u)) || (handle->keySize == kHASHCRYPT_InvalidKey))
1715     {
1716         return kStatus_InvalidArgument;
1717     }
1718 
1719     uint32_t keyType = (handle->keyType == kHASHCRYPT_UserKey) ? 0U : 1u;
1720 
1721     hashcrypt_seed_prng(base);
1722 
1723     base->CRYPTCFG = HASHCRYPT_CRYPTCFG_AESMODE(kHASHCRYPT_AesCbc) | HASHCRYPT_CRYPTCFG_AESDECRYPT(AES_ENCRYPT) |
1724                      HASHCRYPT_CRYPTCFG_AESSECRET(keyType) | HASHCRYPT_CRYPTCFG_AESKEYSZ(handle->keySize) |
1725                      HASHCRYPT_CRYPTCFG_MSW1ST_OUT(1) | HASHCRYPT_CRYPTCFG_SWAPKEY(1) | HASHCRYPT_CRYPTCFG_SWAPDAT(1) |
1726                      HASHCRYPT_CRYPTCFG_MSW1ST(1);
1727 
1728     hashcrypt_engine_init(base, kHASHCRYPT_Aes);
1729 
1730     /* in case of HW AES key, check if it is available */
1731     if (hashcrypt_check_need_key(base, handle) != kStatus_Success)
1732     {
1733         hashcrypt_engine_deinit(base);
1734         return kStatus_Fail;
1735     }
1736 
1737     /* load key if kHASHCRYPT_UserKey is selected */
1738     if (handle->keyType == kHASHCRYPT_UserKey)
1739     {
1740         hashcrypt_aes_load_userKey(base, handle);
1741     }
1742 
1743     /* load iv */
1744     hashcrypt_load_data(base, (uint32_t *)(uintptr_t)iv, HASHCRYPT_AES_BLOCK_SIZE);
1745 
1746     /*Use AES CBC mode and feed input with zeroes for first block */
1747     /*Output block is then XORed with ciphertext to get plaintext*/
1748 
1749     status = hashcrypt_aes_one_block(base, zeroes, blockOutput, HASHCRYPT_AES_BLOCK_SIZE);
1750     if (status != kStatus_Success)
1751     {
1752         hashcrypt_engine_deinit(base);
1753         return status;
1754     }
1755     /* XOR ciphertext with output block to get plaintext*/
1756     for (uint32_t i = 0; i < HASHCRYPT_AES_BLOCK_SIZE; i++)
1757     {
1758         plaintext[i] = ciphertext[i] ^ blockOutput[i];
1759     }
1760     size -= 16u;
1761 
1762     /*Remaining blocks use previous plaintext as input for aes block function */
1763     while (size >= 16u)
1764     {
1765         status = hashcrypt_aes_one_block(base, plaintext, blockOutput, HASHCRYPT_AES_BLOCK_SIZE);
1766         ciphertext += 16;
1767         plaintext += 16;
1768 
1769         if (status != kStatus_Success)
1770         {
1771             hashcrypt_engine_deinit(base);
1772             return status;
1773         }
1774         /* XOR plaintext with ciphertext block to get plaintext*/
1775         for (uint32_t i = 0; i < HASHCRYPT_AES_BLOCK_SIZE; i++)
1776         {
1777             plaintext[i] = ciphertext[i] ^ blockOutput[i];
1778         }
1779         size -= 16u;
1780     }
1781 
1782     /* After processing all data, hashcrypt engine is set to disabled to lower power consumption */
1783     hashcrypt_engine_deinit(base);
1784     return status;
1785 }
1786 
1787 void HASHCRYPT_DriverIRQHandler(void);
HASHCRYPT_DriverIRQHandler(void)1788 void HASHCRYPT_DriverIRQHandler(void)
1789 {
1790     hashcrypt_sha_ctx_internal_t *ctxInternal;
1791     HASHCRYPT_Type *base = HASHCRYPT;
1792     uint32_t numBlocks;
1793     status_t status;
1794 
1795     ctxInternal = (hashcrypt_sha_ctx_internal_t *)(uint32_t)s_ctx;
1796 
1797     if (0U == (base->STATUS & HASHCRYPT_STATUS_ERROR_MASK))
1798     {
1799         if (ctxInternal->remainingBlcks > 0U)
1800         {
1801             if (ctxInternal->remainingBlcks >= SHA_MASTER_MAX_BLOCKS)
1802             {
1803                 numBlocks = SHA_MASTER_MAX_BLOCKS - 1U;
1804             }
1805             else
1806             {
1807                 numBlocks = ctxInternal->remainingBlcks;
1808             }
1809             /* some blocks still remaining, update remainingBlcks for next ISR and start another hash */
1810             ctxInternal->remainingBlcks -= numBlocks;
1811             base->MEMCTRL = HASHCRYPT_MEMCTRL_MASTER(1) | HASHCRYPT_MEMCTRL_COUNT(numBlocks);
1812             return;
1813         }
1814         /* no full blocks left, disable interrupts and AHB master mode */
1815         base->INTENCLR = HASHCRYPT_INTENCLR_DIGEST_MASK | HASHCRYPT_INTENCLR_ERROR_MASK;
1816         base->MEMCTRL  = HASHCRYPT_MEMCTRL_MASTER(0);
1817         status         = hashcrypt_save_running_hash(base, ctxInternal);
1818     }
1819     else
1820     {
1821         status = kStatus_Fail;
1822     }
1823 
1824     /* Invoke callback if there is one */
1825     if (NULL != ctxInternal->hashCallback)
1826     {
1827         ctxInternal->hashCallback(HASHCRYPT, s_ctx, status, ctxInternal->userData);
1828     }
1829 }
1830 
HASHCRYPT_Init(HASHCRYPT_Type * base)1831 void HASHCRYPT_Init(HASHCRYPT_Type *base)
1832 {
1833 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
1834     CLOCK_EnableClock(kCLOCK_HashCrypt);
1835 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
1836     RESET_PeripheralReset(kHASHCRYPT_RST_SHIFT_RSTn);
1837 }
1838 
HASHCRYPT_Deinit(HASHCRYPT_Type * base)1839 void HASHCRYPT_Deinit(HASHCRYPT_Type *base)
1840 {
1841     RESET_SetPeripheralReset(kHASHCRYPT_RST_SHIFT_RSTn);
1842 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
1843     CLOCK_DisableClock(kCLOCK_HashCrypt);
1844 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
1845 }
1846