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