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