1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** NetX Crypto Component */
17 /** */
18 /** HMAC Mode */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #include "nx_crypto_hmac.h"
24
25 /**************************************************************************/
26 /* */
27 /* FUNCTION RELEASE */
28 /* */
29 /* _nx_crypto_hmac PORTABLE C */
30 /* 6.1 */
31 /* */
32 /* AUTHOR */
33 /* */
34 /* Timothy Stapko, Microsoft Corporation */
35 /* */
36 /* DESCRIPTION */
37 /* */
38 /* This function calculates the HMAC. */
39 /* */
40 /* INPUT */
41 /* */
42 /* hmac_metadata pointer to HMAC metadata */
43 /* input_ptr input byte stream */
44 /* input_length input byte stream length */
45 /* key_ptr key stream */
46 /* key_length key stream length */
47 /* digest_ptr generated crypto digest */
48 /* */
49 /* OUTPUT */
50 /* */
51 /* status Completion status */
52 /* */
53 /* CALLS */
54 /* */
55 /* _nx_crypto_hmac_initialize Perform HMAC initialization */
56 /* _nx_crypto_hmac_update Perform HMAC update */
57 /* _nx_crypto_hmac_digest_calculate Calculate HMAC digest */
58 /* */
59 /* CALLED BY */
60 /* */
61 /* Application Code */
62 /* _nx_crypto_method_hmac_md5_operation Handle HMAC-MD5 operation */
63 /* _nx_crypto_method_hmac_sha1_operation Handle HMAC-SHA1 operation */
64 /* _nx_crypto_method_hmac_sha256_operation Handle HMAC-SHA256 operation*/
65 /* */
66 /* RELEASE HISTORY */
67 /* */
68 /* DATE NAME DESCRIPTION */
69 /* */
70 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
71 /* 09-30-2020 Timothy Stapko Modified comment(s), */
72 /* resulting in version 6.1 */
73 /* */
74 /**************************************************************************/
_nx_crypto_hmac(NX_CRYPTO_HMAC * hmac_metadata,UCHAR * input_ptr,UINT input_length,UCHAR * key_ptr,UINT key_length,UCHAR * digest_ptr,UINT digest_length)75 NX_CRYPTO_KEEP UINT _nx_crypto_hmac(NX_CRYPTO_HMAC *hmac_metadata,
76 UCHAR *input_ptr, UINT input_length,
77 UCHAR *key_ptr, UINT key_length,
78 UCHAR *digest_ptr, UINT digest_length)
79 {
80
81 /* Initialize, update and calculate. */
82 _nx_crypto_hmac_initialize(hmac_metadata, key_ptr, key_length);
83 _nx_crypto_hmac_update(hmac_metadata, input_ptr, input_length);
84 _nx_crypto_hmac_digest_calculate(hmac_metadata, digest_ptr, digest_length);
85
86 /* Return success. */
87 return(NX_CRYPTO_SUCCESS);
88 }
89
90
91 /**************************************************************************/
92 /* */
93 /* FUNCTION RELEASE */
94 /* */
95 /* _nx_crypto_hmac_initialize PORTABLE C */
96 /* 6.1 */
97 /* */
98 /* AUTHOR */
99 /* */
100 /* Timothy Stapko, Microsoft Corporation */
101 /* */
102 /* DESCRIPTION */
103 /* */
104 /* This function performs HMAC initialization. */
105 /* */
106 /* INPUT */
107 /* */
108 /* hmac_metadata pointer to HMAC metadata */
109 /* key_ptr key stream */
110 /* key_length key stream length */
111 /* */
112 /* OUTPUT */
113 /* */
114 /* status Completion status */
115 /* */
116 /* CALLS */
117 /* */
118 /* [crypto_digest_calculate] Calculate crypto digest */
119 /* [crypto_initialize] Perform crypto initialization */
120 /* [crypto_update] Perform crypto update */
121 /* */
122 /* CALLED BY */
123 /* */
124 /* Application Code */
125 /* _nx_crypto_hmac Calculate the HMAC */
126 /* _nx_crypto_method_hmac_md5_operation Handle HMAC-MD5 operation */
127 /* _nx_crypto_method_hmac_sha1_operation Handle HMAC-SHA1 operation */
128 /* _nx_crypto_method_hmac_sha256_operation Handle HMAC-SHA256 operation*/
129 /* _nx_crypto_method_hmac_sha512_operation Handle HMAC-SHA512 operation*/
130 /* */
131 /* RELEASE HISTORY */
132 /* */
133 /* DATE NAME DESCRIPTION */
134 /* */
135 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
136 /* 09-30-2020 Timothy Stapko Modified comment(s), */
137 /* verified memcpy use cases, */
138 /* resulting in version 6.1 */
139 /* */
140 /**************************************************************************/
_nx_crypto_hmac_initialize(NX_CRYPTO_HMAC * hmac_metadata,UCHAR * key_ptr,UINT key_length)141 NX_CRYPTO_KEEP UINT _nx_crypto_hmac_initialize(NX_CRYPTO_HMAC *hmac_metadata, UCHAR *key_ptr, UINT key_length)
142 {
143 UCHAR temp_key[128];
144 UINT i;
145
146 /* If key is longer than block size, reset it to key=CRYPTO(key). */
147 if (key_length > hmac_metadata -> block_size)
148 {
149
150 hmac_metadata -> crypto_initialize(hmac_metadata -> context, hmac_metadata -> algorithm);
151
152 hmac_metadata -> crypto_update(hmac_metadata -> context, key_ptr, key_length);
153
154 hmac_metadata -> crypto_digest_calculate(hmac_metadata -> context, temp_key, hmac_metadata -> algorithm);
155
156 key_ptr = temp_key;
157
158 key_length = hmac_metadata -> output_length;
159 }
160
161 hmac_metadata -> crypto_initialize(hmac_metadata -> context, hmac_metadata -> algorithm);
162
163 /* The HMAC_CRYPTO transform looks like:
164
165 CRYPTO(K XOR opad, CRYPTO(K XOR ipad, text))
166
167 where K is an n byte key,
168 ipad is the byte 0x36 repeated block_size times,
169 opad is the byte 0x5c repeated block_size times,
170 and text is the data being protected. */
171
172 NX_CRYPTO_MEMSET(hmac_metadata -> k_ipad, 0, hmac_metadata -> block_size);
173
174 NX_CRYPTO_MEMSET(hmac_metadata -> k_opad, 0, hmac_metadata -> block_size);
175
176 NX_CRYPTO_MEMCPY(hmac_metadata -> k_ipad, key_ptr, key_length); /* Use case of memcpy is verified. */
177
178 NX_CRYPTO_MEMCPY(hmac_metadata -> k_opad, key_ptr, key_length); /* Use case of memcpy is verified. */
179
180
181 /* XOR key with ipad and opad values. */
182 for (i = 0; i < hmac_metadata -> block_size; i++)
183 {
184 hmac_metadata -> k_ipad[i] ^= 0x36;
185 hmac_metadata -> k_opad[i] ^= 0x5c;
186 }
187
188 /* Kick off the inner hash with our padded key. */
189 hmac_metadata -> crypto_update(hmac_metadata -> context, hmac_metadata -> k_ipad, hmac_metadata -> block_size);
190
191 #ifdef NX_SECURE_KEY_CLEAR
192 NX_CRYPTO_MEMSET(temp_key, 0, sizeof(temp_key));
193 #endif /* NX_SECURE_KEY_CLEAR */
194
195 /* Return success. */
196 return(NX_CRYPTO_SUCCESS);
197 }
198
199
200 /**************************************************************************/
201 /* */
202 /* FUNCTION RELEASE */
203 /* */
204 /* _nx_crypto_hmac_update PORTABLE C */
205 /* 6.1 */
206 /* */
207 /* AUTHOR */
208 /* */
209 /* Timothy Stapko, Microsoft Corporation */
210 /* */
211 /* DESCRIPTION */
212 /* */
213 /* This function performs HMAC update. */
214 /* */
215 /* INPUT */
216 /* */
217 /* hmac_metadata pointer to HMAC metadata */
218 /* input_ptr input byte stream */
219 /* input_length input byte stream length */
220 /* */
221 /* OUTPUT */
222 /* */
223 /* status Completion status */
224 /* */
225 /* CALLS */
226 /* */
227 /* [crypto_update] Perform crypto update */
228 /* */
229 /* CALLED BY */
230 /* */
231 /* Application Code */
232 /* _nx_crypto_hmac Calculate the HMAC */
233 /* */
234 /* RELEASE HISTORY */
235 /* */
236 /* DATE NAME DESCRIPTION */
237 /* */
238 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
239 /* 09-30-2020 Timothy Stapko Modified comment(s), */
240 /* resulting in version 6.1 */
241 /* */
242 /**************************************************************************/
_nx_crypto_hmac_update(NX_CRYPTO_HMAC * hmac_metadata,UCHAR * input_ptr,UINT input_length)243 NX_CRYPTO_KEEP UINT _nx_crypto_hmac_update(NX_CRYPTO_HMAC *hmac_metadata, UCHAR *input_ptr, UINT input_length)
244 {
245
246 /* Update inner CRYPTO. */
247 hmac_metadata -> crypto_update(hmac_metadata -> context, input_ptr, input_length);
248
249 /* Return success. */
250 return(NX_CRYPTO_SUCCESS);
251 }
252
253
254 /**************************************************************************/
255 /* */
256 /* FUNCTION RELEASE */
257 /* */
258 /* _nx_crypto_hmac_digest_calculate PORTABLE C */
259 /* 6.1 */
260 /* */
261 /* AUTHOR */
262 /* */
263 /* Timothy Stapko, Microsoft Corporation */
264 /* */
265 /* DESCRIPTION */
266 /* */
267 /* This function performs HMAC digest calculation. */
268 /* */
269 /* INPUT */
270 /* */
271 /* hmac_metadata pointer to HMAC metadata */
272 /* digest_ptr generated crypto digest */
273 /* */
274 /* OUTPUT */
275 /* */
276 /* status Completion status */
277 /* */
278 /* CALLS */
279 /* */
280 /* [crypto_digest_calculate] Calculate crypto digest */
281 /* [crypto_initialize] Perform crypto initialization */
282 /* [crypto_update] Perform crypto update */
283 /* */
284 /* CALLED BY */
285 /* */
286 /* Application Code */
287 /* _nx_crypto_hmac Calculate the HMAC */
288 /* */
289 /* RELEASE HISTORY */
290 /* */
291 /* DATE NAME DESCRIPTION */
292 /* */
293 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
294 /* 09-30-2020 Timothy Stapko Modified comment(s), */
295 /* verified memcpy use cases, */
296 /* resulting in version 6.1 */
297 /* */
298 /**************************************************************************/
_nx_crypto_hmac_digest_calculate(NX_CRYPTO_HMAC * hmac_metadata,UCHAR * digest_ptr,UINT digest_length)299 NX_CRYPTO_KEEP UINT _nx_crypto_hmac_digest_calculate(NX_CRYPTO_HMAC *hmac_metadata, UCHAR *digest_ptr, UINT digest_length)
300 {
301 UCHAR icv_ptr[64];
302
303 /* Perform outer CRYPTO. */
304
305 hmac_metadata -> crypto_digest_calculate(hmac_metadata -> context, icv_ptr, hmac_metadata -> algorithm);
306
307 hmac_metadata -> crypto_initialize(hmac_metadata -> context, hmac_metadata -> algorithm);
308
309 hmac_metadata -> crypto_update(hmac_metadata -> context, hmac_metadata -> k_opad, hmac_metadata -> block_size);
310
311 hmac_metadata -> crypto_update(hmac_metadata -> context, icv_ptr, hmac_metadata -> output_length);
312
313 hmac_metadata -> crypto_digest_calculate(hmac_metadata -> context, icv_ptr, hmac_metadata -> algorithm);
314
315 NX_CRYPTO_MEMCPY(digest_ptr, icv_ptr, (digest_length > hmac_metadata -> output_length ? hmac_metadata -> output_length : digest_length)); /* Use case of memcpy is verified. */
316
317 #ifdef NX_SECURE_KEY_CLEAR
318 NX_CRYPTO_MEMSET(icv_ptr, 0, sizeof(icv_ptr));
319 #endif /* NX_SECURE_KEY_CLEAR */
320
321 /* Return success. */
322 return(NX_CRYPTO_SUCCESS);
323 }
324
325
326 /**************************************************************************/
327 /* */
328 /* FUNCTION RELEASE */
329 /* */
330 /* _nx_crypto_hmac_metadata_set PORTABLE C */
331 /* 6.1 */
332 /* */
333 /* AUTHOR */
334 /* */
335 /* Timothy Stapko, Microsoft Corporation */
336 /* */
337 /* DESCRIPTION */
338 /* */
339 /* This function sets HMAC metadata. */
340 /* */
341 /* INPUT */
342 /* */
343 /* hmac_metadata pointer to HMAC metadata */
344 /* context crypto context */
345 /* k_ipad ipad key */
346 /* k_opad opad key */
347 /* algorithm algorithm */
348 /* block_size block size */
349 /* output_length output length */
350 /* crypto_intitialize initializtion function */
351 /* crypto_update update function */
352 /* crypto_digest_calculate digest calculation function */
353 /* */
354 /* OUTPUT */
355 /* */
356 /* None */
357 /* */
358 /* CALLS */
359 /* */
360 /* None */
361 /* */
362 /* CALLED BY */
363 /* */
364 /* Application Code */
365 /* _nx_crypto_method_hmac_md5_operation Handle HMAC-MD5 operation */
366 /* _nx_crypto_method_hmac_sha1_operation Handle HMAC-SHA1 operation */
367 /* _nx_crypto_method_hmac_sha256_operation Handle HMAC-SHA256 operation*/
368 /* _nx_crypto_method_hmac_sha512_operation Handle HMAC-SHA512 operation*/
369 /* */
370 /* RELEASE HISTORY */
371 /* */
372 /* DATE NAME DESCRIPTION */
373 /* */
374 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
375 /* 09-30-2020 Timothy Stapko Modified comment(s), */
376 /* resulting in version 6.1 */
377 /* */
378 /**************************************************************************/
_nx_crypto_hmac_metadata_set(NX_CRYPTO_HMAC * hmac_metadata,VOID * context,UINT algorithm,UINT block_size,UINT output_length,UINT (* crypto_initialize)(VOID *,UINT),UINT (* crypto_update)(VOID *,UCHAR *,UINT),UINT (* crypto_digest_calculate)(VOID *,UCHAR *,UINT))379 NX_CRYPTO_KEEP VOID _nx_crypto_hmac_metadata_set(NX_CRYPTO_HMAC *hmac_metadata,
380 VOID *context,
381 UINT algorithm, UINT block_size, UINT output_length,
382 UINT (*crypto_initialize)(VOID *, UINT),
383 UINT (*crypto_update)(VOID *, UCHAR *, UINT),
384 UINT (*crypto_digest_calculate)(VOID *, UCHAR *, UINT))
385 {
386
387 hmac_metadata -> context = context;
388 hmac_metadata -> algorithm = algorithm;
389 hmac_metadata -> block_size = block_size;
390 hmac_metadata -> output_length = output_length;
391 hmac_metadata -> crypto_initialize = crypto_initialize;
392 hmac_metadata -> crypto_update = crypto_update;
393 hmac_metadata -> crypto_digest_calculate = crypto_digest_calculate;
394 }
395
396 /**************************************************************************/
397 /* */
398 /* FUNCTION RELEASE */
399 /* */
400 /* _nx_crypto_hmac_hash_initialize PORTABLE C */
401 /* 6.1 */
402 /* */
403 /* AUTHOR */
404 /* */
405 /* Timothy Stapko, Microsoft Corporation */
406 /* */
407 /* DESCRIPTION */
408 /* */
409 /* This function is a build-in wrappers for hash initialization. */
410 /* */
411 /* INPUT */
412 /* */
413 /* context Crypto context */
414 /* algorithm Hash algorithm */
415 /* */
416 /* OUTPUT */
417 /* */
418 /* status Completion status */
419 /* */
420 /* CALLS */
421 /* */
422 /* None */
423 /* */
424 /* CALLED BY */
425 /* */
426 /* None */
427 /* */
428 /* RELEASE HISTORY */
429 /* */
430 /* DATE NAME DESCRIPTION */
431 /* */
432 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
433 /* 09-30-2020 Timothy Stapko Modified comment(s), */
434 /* resulting in version 6.1 */
435 /* */
436 /**************************************************************************/
_nx_crypto_hmac_hash_initialize(VOID * context,UINT algorithm)437 UINT _nx_crypto_hmac_hash_initialize(VOID *context, UINT algorithm)
438 {
439 NX_CRYPTO_HMAC *hmac;
440 NX_CRYPTO_METHOD *hash;
441 UINT metadata_size;
442 UINT status;
443
444 NX_CRYPTO_PARAMETER_NOT_USED(algorithm);
445
446 /* Get the HMAC context. */
447 hmac = (NX_CRYPTO_HMAC*)context;
448
449 /* Get the hash method and it's metadata. */
450 hash = hmac->hash_method;
451 metadata_size = hash->nx_crypto_metadata_area_size;
452
453 status = hash->nx_crypto_operation(NX_CRYPTO_HASH_INITIALIZE,
454 NX_CRYPTO_NULL,
455 hash,
456 NX_CRYPTO_NULL,
457 0,
458 NX_CRYPTO_NULL,
459 0,
460 NX_CRYPTO_NULL,
461 NX_CRYPTO_NULL,
462 0,
463 hmac->hash_context,
464 metadata_size,
465 NX_CRYPTO_NULL,
466 NX_CRYPTO_NULL);
467
468
469 return(status);
470 }
471
472
473 /**************************************************************************/
474 /* */
475 /* FUNCTION RELEASE */
476 /* */
477 /* _nx_crypto_hmac_hash_update PORTABLE C */
478 /* 6.1 */
479 /* */
480 /* AUTHOR */
481 /* */
482 /* Timothy Stapko, Microsoft Corporation */
483 /* */
484 /* DESCRIPTION */
485 /* */
486 /* This function is a build-in wrappers for hash data update. */
487 /* */
488 /* INPUT */
489 /* */
490 /* context Crypto context */
491 /* input Input Stream */
492 /* input_length Input Stream Length */
493 /* */
494 /* OUTPUT */
495 /* */
496 /* status Completion status */
497 /* */
498 /* CALLS */
499 /* */
500 /* None */
501 /* */
502 /* CALLED BY */
503 /* */
504 /* None */
505 /* */
506 /* RELEASE HISTORY */
507 /* */
508 /* DATE NAME DESCRIPTION */
509 /* */
510 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
511 /* 09-30-2020 Timothy Stapko Modified comment(s), */
512 /* resulting in version 6.1 */
513 /* */
514 /**************************************************************************/
_nx_crypto_hmac_hash_update(VOID * context,UCHAR * input,UINT input_length)515 UINT _nx_crypto_hmac_hash_update(VOID *context, UCHAR *input, UINT input_length)
516 {
517 NX_CRYPTO_HMAC *hmac;
518 NX_CRYPTO_METHOD *hash;
519 UINT metadata_size;
520 UINT status;
521
522 /* Get the HMAC context. */
523 hmac = (NX_CRYPTO_HMAC*)context;
524
525 /* Get the hash method and it's metadata. */
526 hash = hmac->hash_method;
527 metadata_size = hash->nx_crypto_metadata_area_size;
528
529 /* Perform an update using the generic crypto API. */
530 status = hash->nx_crypto_operation(NX_CRYPTO_HASH_UPDATE,
531 NX_CRYPTO_NULL,
532 hash,
533 NX_CRYPTO_NULL,
534 0,
535 input,
536 input_length,
537 NX_CRYPTO_NULL,
538 NX_CRYPTO_NULL,
539 0,
540 hmac->hash_context,
541 metadata_size,
542 NX_CRYPTO_NULL,
543 NX_CRYPTO_NULL);
544
545 return(status);
546 }
547
548
549 /**************************************************************************/
550 /* */
551 /* FUNCTION RELEASE */
552 /* */
553 /* _nx_crypto_hmac_hash_digest_calculate PORTABLE C */
554 /* 6.1 */
555 /* */
556 /* AUTHOR */
557 /* */
558 /* Timothy Stapko, Microsoft Corporation */
559 /* */
560 /* DESCRIPTION */
561 /* */
562 /* This function is a build-in wrappers for hash digest calculate. */
563 /* */
564 /* INPUT */
565 /* */
566 /* context Crypto context */
567 /* digest Digest for output */
568 /* algorithm Hash algorithm */
569 /* */
570 /* OUTPUT */
571 /* */
572 /* status Completion status */
573 /* */
574 /* CALLS */
575 /* */
576 /* None */
577 /* */
578 /* CALLED BY */
579 /* */
580 /* None */
581 /* */
582 /* RELEASE HISTORY */
583 /* */
584 /* DATE NAME DESCRIPTION */
585 /* */
586 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
587 /* 09-30-2020 Timothy Stapko Modified comment(s), */
588 /* resulting in version 6.1 */
589 /* */
590 /**************************************************************************/
_nx_crypto_hmac_hash_digest_calculate(VOID * context,UCHAR * digest,UINT algorithm)591 UINT _nx_crypto_hmac_hash_digest_calculate(VOID *context, UCHAR *digest, UINT algorithm)
592 {
593 NX_CRYPTO_HMAC *hmac;
594 NX_CRYPTO_METHOD *hash;
595 UINT metadata_size;
596 UINT status;
597
598 NX_CRYPTO_PARAMETER_NOT_USED(algorithm);
599
600 /* Get the HMAC context. */
601 hmac = (NX_CRYPTO_HMAC*)context;
602
603 /* Get the hash method and it's metadata. */
604 hash = hmac->hash_method;
605 metadata_size = hash->nx_crypto_metadata_area_size;
606
607 /* Perform a digest calculation using the generic crypto API. */
608 status = hash->nx_crypto_operation(NX_CRYPTO_HASH_CALCULATE,
609 NX_CRYPTO_NULL,
610 hash,
611 NX_CRYPTO_NULL,
612 0,
613 NX_CRYPTO_NULL,
614 0,
615 NX_CRYPTO_NULL,
616 digest,
617 (hash->nx_crypto_ICV_size_in_bits >> 3),
618 hmac->hash_context,
619 metadata_size,
620 NX_CRYPTO_NULL,
621 NX_CRYPTO_NULL);
622
623 return(status);
624 }
625
626
627 /**************************************************************************/
628 /* */
629 /* FUNCTION RELEASE */
630 /* */
631 /* _nx_crypto_method_hmac_init PORTABLE C */
632 /* 6.3.0 */
633 /* AUTHOR */
634 /* */
635 /* Timothy Stapko, Microsoft Corporation */
636 /* */
637 /* DESCRIPTION */
638 /* */
639 /* This function is the common crypto method initialization routine */
640 /* for the Microsoft implementation of the HMAC cryptographic */
641 /* algorithm. */
642 /* */
643 /* INPUT */
644 /* */
645 /* method Pointer to crypto method */
646 /* key Pointer to key */
647 /* key_size_in_bits Length of key size in bits */
648 /* handler Returned crypto handler */
649 /* crypto_metadata Metadata area */
650 /* crypto_metadata_size Size of the metadata area */
651 /* */
652 /* OUTPUT */
653 /* */
654 /* status Completion status */
655 /* */
656 /* CALLS */
657 /* */
658 /* None */
659 /* */
660 /* CALLED BY */
661 /* */
662 /* Application Code */
663 /* */
664 /* RELEASE HISTORY */
665 /* */
666 /* DATE NAME DESCRIPTION */
667 /* */
668 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
669 /* 09-30-2020 Timothy Stapko Modified comment(s), */
670 /* resulting in version 6.1 */
671 /* 10-31-2023 Yanwu Cai Modified comment(s), */
672 /* resulting in version 6.3.0 */
673 /* */
674 /**************************************************************************/
_nx_crypto_method_hmac_init(struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,VOID ** handle,VOID * crypto_metadata,ULONG crypto_metadata_size)675 NX_CRYPTO_KEEP UINT _nx_crypto_method_hmac_init(struct NX_CRYPTO_METHOD_STRUCT *method,
676 UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits,
677 VOID **handle,
678 VOID *crypto_metadata,
679 ULONG crypto_metadata_size)
680 {
681 /* NX_CRYPTO_HMAC *hmac;*/
682
683 NX_CRYPTO_PARAMETER_NOT_USED(handle);
684 NX_CRYPTO_PARAMETER_NOT_USED(key_size_in_bits);
685
686 NX_CRYPTO_STATE_CHECK
687
688 if ((method == NX_CRYPTO_NULL) || (key == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL))
689 {
690 return(NX_CRYPTO_PTR_ERROR);
691 }
692
693 /* Verify the metadata address is 4-byte aligned. */
694 if((((ULONG)crypto_metadata) & 0x3) != 0)
695 {
696 return(NX_CRYPTO_PTR_ERROR);
697 }
698
699 if(crypto_metadata_size < sizeof(NX_CRYPTO_HMAC))
700 {
701 return(NX_CRYPTO_PTR_ERROR);
702 }
703
704 #if 0
705 hmac = (NX_CRYPTO_HMAC *)crypto_metadata;
706
707 /* Set the method for later. */
708 hmac->hash_method = method;
709 #endif
710
711 return(NX_CRYPTO_SUCCESS);
712 }
713
714
715 /**************************************************************************/
716 /* */
717 /* FUNCTION RELEASE */
718 /* */
719 /* _nx_crypto_method_hmac_cleanup PORTABLE C */
720 /* 6.1 */
721 /* AUTHOR */
722 /* */
723 /* Timothy Stapko, Microsoft Corporation */
724 /* */
725 /* DESCRIPTION */
726 /* */
727 /* This function cleans up the crypto metadata for the HMAC operation. */
728 /* */
729 /* INPUT */
730 /* */
731 /* crypto_metadata Crypto metadata */
732 /* */
733 /* OUTPUT */
734 /* */
735 /* status Completion status */
736 /* */
737 /* CALLS */
738 /* */
739 /* NX_CRYPTO_MEMSET Set the memory */
740 /* */
741 /* CALLED BY */
742 /* */
743 /* Application Code */
744 /* */
745 /* RELEASE HISTORY */
746 /* */
747 /* DATE NAME DESCRIPTION */
748 /* */
749 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
750 /* 09-30-2020 Timothy Stapko Modified comment(s), */
751 /* resulting in version 6.1 */
752 /* */
753 /**************************************************************************/
_nx_crypto_method_hmac_cleanup(VOID * crypto_metadata)754 NX_CRYPTO_KEEP UINT _nx_crypto_method_hmac_cleanup(VOID *crypto_metadata)
755 {
756
757 NX_CRYPTO_STATE_CHECK
758
759 #ifdef NX_SECURE_KEY_CLEAR
760 if (!crypto_metadata)
761 return (NX_CRYPTO_SUCCESS);
762
763 /* Clean up the crypto metadata. */
764 NX_CRYPTO_MEMSET(crypto_metadata, 0, sizeof(NX_CRYPTO_HMAC));
765 #else
766 NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata);
767 #endif/* NX_SECURE_KEY_CLEAR */
768
769 return(NX_CRYPTO_SUCCESS);
770 }
771
772
773
774
775
776 /**************************************************************************/
777 /* */
778 /* FUNCTION RELEASE */
779 /* */
780 /* _nx_crypto_method_hmac_operation PORTABLE C */
781 /* 6.3.0 */
782 /* */
783 /* AUTHOR */
784 /* */
785 /* Timothy Stapko, Microsoft Corporation */
786 /* */
787 /* DESCRIPTION */
788 /* */
789 /* This function is the generic operation for HMAC. HMAC does not care */
790 /* what hash is used as long as the hash size is known. Therefore, this*/
791 /* method may be used with an arbitrary hash routine as long as the */
792 /* hash has an NX_CRYPTO_METHOD instance properly filled out. */
793 /* */
794 /* INPUT */
795 /* */
796 /* hmac_metadata pointer to HMAC metadata */
797 /* context crypto context */
798 /* k_ipad ipad key */
799 /* k_opad opad key */
800 /* algorithm algorithm */
801 /* block_size block size */
802 /* output_length output length */
803 /* crypto_intitialize initializtion function */
804 /* crypto_update update function */
805 /* crypto_digest_calculate digest calculation function */
806 /* */
807 /* OUTPUT */
808 /* */
809 /* None */
810 /* */
811 /* CALLS */
812 /* */
813 /* None */
814 /* */
815 /* CALLED BY */
816 /* */
817 /* Application Code */
818 /* */
819 /* RELEASE HISTORY */
820 /* */
821 /* DATE NAME DESCRIPTION */
822 /* */
823 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
824 /* 09-30-2020 Timothy Stapko Modified comment(s), */
825 /* resulting in version 6.1 */
826 /* 10-31-2023 Yanwu Cai Modified comment(s), */
827 /* resulting in version 6.3.0 */
828 /* */
829 /**************************************************************************/
_nx_crypto_method_hmac_operation(UINT op,VOID * handle,struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,UCHAR * input,ULONG input_length_in_byte,UCHAR * iv_ptr,UCHAR * output,ULONG output_length_in_byte,VOID * crypto_metadata,ULONG crypto_metadata_size,VOID * packet_ptr,VOID (* nx_crypto_hw_process_callback)(VOID * packet_ptr,UINT status))830 NX_CRYPTO_KEEP UINT _nx_crypto_method_hmac_operation(UINT op, /* Encrypt, Decrypt, Authenticate */
831 VOID *handle, /* Crypto handler */
832 struct NX_CRYPTO_METHOD_STRUCT *method,
833 UCHAR *key,
834 NX_CRYPTO_KEY_SIZE key_size_in_bits,
835 UCHAR *input,
836 ULONG input_length_in_byte,
837 UCHAR *iv_ptr,
838 UCHAR *output,
839 ULONG output_length_in_byte,
840 VOID *crypto_metadata,
841 ULONG crypto_metadata_size,
842 VOID *packet_ptr,
843 VOID (*nx_crypto_hw_process_callback)(VOID *packet_ptr, UINT status))
844 {
845 NX_CRYPTO_HMAC *hmac;
846 UINT status;
847
848 NX_CRYPTO_PARAMETER_NOT_USED(handle);
849 NX_CRYPTO_PARAMETER_NOT_USED(iv_ptr);
850 NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
851 NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
852
853 NX_CRYPTO_STATE_CHECK
854
855 /* Verify the metadata address is 4-byte aligned. */
856 if((method == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL) || ((((ULONG)crypto_metadata) & 0x3) != 0))
857 {
858 return(NX_CRYPTO_PTR_ERROR);
859 }
860
861 if(crypto_metadata_size < sizeof(NX_CRYPTO_HMAC))
862 {
863 return(NX_CRYPTO_PTR_ERROR);
864 }
865
866 /* Get our control block for HKDF. */
867 hmac = (NX_CRYPTO_HMAC *)(crypto_metadata);
868
869 /* Get the metadata for our hash routine. */
870 hmac->context = hmac;
871 hmac->hash_context = ((UCHAR*)(crypto_metadata)) + sizeof(NX_CRYPTO_HMAC);
872
873 status = NX_CRYPTO_SUCCESS;
874 switch (op)
875 {
876 case NX_CRYPTO_HMAC_SET_HASH:
877 hmac->hash_method = method;
878
879 /* Set up the HMAC metadata using the HMAC context for the hash context - this is because our built-in routines
880 * (_nx_crypto_hmac_hash_initialize/update/digest_calculate) need the full HMAC context, unlike when HMAC routines
881 * are built around HMAC (as opposed to when HMAC is used as a hash wrapper). */
882 _nx_crypto_hmac_metadata_set(hmac, hmac,
883 method->nx_crypto_algorithm, method->nx_crypto_block_size_in_bytes, method->nx_crypto_ICV_size_in_bits >> 3,
884 _nx_crypto_hmac_hash_initialize,
885 _nx_crypto_hmac_hash_update,
886 _nx_crypto_hmac_hash_digest_calculate);
887
888 /* Initialize the hash routine. */
889 status = method->nx_crypto_init(method, NX_CRYPTO_NULL, 0, NX_CRYPTO_NULL, hmac->hash_context, method->nx_crypto_metadata_area_size);
890 break;
891
892 case NX_CRYPTO_HASH_INITIALIZE:
893 /* Initialize the hash method. */
894 if(key == NX_CRYPTO_NULL)
895 {
896 return(NX_CRYPTO_PTR_ERROR);
897 }
898
899 status = _nx_crypto_hmac_initialize(hmac, key, key_size_in_bits >> 3);
900 break;
901
902 case NX_CRYPTO_HASH_UPDATE:
903 status = _nx_crypto_hmac_update(hmac, input, input_length_in_byte);
904 break;
905
906 case NX_CRYPTO_HASH_CALCULATE:
907 if(output_length_in_byte == 0)
908 {
909 return(NX_CRYPTO_INVALID_BUFFER_SIZE);
910 }
911 status = _nx_crypto_hmac_digest_calculate(hmac, output,
912 (output_length_in_byte > (ULONG)((hmac-> hash_method -> nx_crypto_ICV_size_in_bits) >> 3) ?
913 ((hmac-> hash_method -> nx_crypto_ICV_size_in_bits) >> 3) : output_length_in_byte));
914 break;
915
916 default:
917 /* Do entire HMAC operation in one pass (init, update, calculate). */
918 if(key == NX_CRYPTO_NULL)
919 {
920 return(NX_CRYPTO_PTR_ERROR);
921 }
922
923 if(output_length_in_byte == 0)
924 {
925 return(NX_CRYPTO_INVALID_BUFFER_SIZE);
926 }
927 _nx_crypto_hmac(hmac, input, input_length_in_byte, key, (key_size_in_bits >> 3), output,
928 (output_length_in_byte > (ULONG)((hmac -> hash_method -> nx_crypto_ICV_size_in_bits) >> 3) ?
929 ((hmac -> hash_method -> nx_crypto_ICV_size_in_bits) >> 3) : output_length_in_byte));
930 break;
931 }
932
933 return(status);
934
935
936
937 }
938
939