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