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