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 Copyright (C) The Internet Society (2001). All Rights Reserved.
14
15 This document and translations of it may be copied and furnished to
16 others, and derivative works that comment on or otherwise explain it
17 or assist in its implementation may be prepared, copied, published
18 and distributed, in whole or in part, without restriction of any
19 kind, provided that the above copyright notice and this paragraph are
20 included on all such copies and derivative works. However, this
21 document itself may not be modified in any way, such as by removing
22 the copyright notice or references to the Internet Society or other
23 Internet organizations, except as needed for the purpose of
24 developing Internet standards in which case the procedures for
25 copyrights defined in the Internet Standards process must be
26 followed, or as required to translate it into languages other than
27 English.
28
29 The limited permissions granted above are perpetual and will not be
30 revoked by the Internet Society or its successors or assigns.
31
32 This document and the information contained herein is provided on an
33 ""AS IS"" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
34 TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
35 BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
36 HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
37 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
38 */
39 /**************************************************************************/
40
41
42 /**************************************************************************/
43 /**************************************************************************/
44 /** */
45 /** NetX Crypto Component */
46 /** */
47 /** SHA1 Digest Algorithm (SHA1) */
48 /** */
49 /**************************************************************************/
50 /**************************************************************************/
51
52 #include "nx_crypto_sha1.h"
53
54 /* Define macros for the SHA1 transform function. */
55
56 /* Define the SHA1 basic F1, F2, F3, and F4 functions. */
57
58 #define F1(x, y, z) (((x) & (y)) | ((~x) & (z)))
59 #define F2(x, y, z) ((x) ^ (y) ^ (z))
60 #define F3(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
61 #define F4(x, y, z) ((x) ^ (y) ^ (z))
62
63
64 /* Define the SHA1 left shift circular function. */
65
66 #define LEFT_SHIFT_CIRCULAR(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
67
68
69 /* Define the padding array. This is used to pad the message such that its length is
70 64 bits shy of being a multiple of 512 bits long. */
71
72 const UCHAR _nx_crypto_sha1_padding[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
73
74
75 /**************************************************************************/
76 /* */
77 /* FUNCTION RELEASE */
78 /* */
79 /* _nx_crypto_sha1_initialize PORTABLE C */
80 /* 6.1 */
81 /* AUTHOR */
82 /* */
83 /* Timothy Stapko, Microsoft Corporation */
84 /* */
85 /* DESCRIPTION */
86 /* */
87 /* This function initializes the SHA1 context. It must be called prior */
88 /* to creating the SHA1 digest. */
89 /* */
90 /* INPUT */
91 /* */
92 /* context SHA1 context pointer */
93 /* */
94 /* OUTPUT */
95 /* */
96 /* status Completion status */
97 /* algorithm Algorithm type */
98 /* */
99 /* CALLS */
100 /* */
101 /* None */
102 /* */
103 /* CALLED BY */
104 /* */
105 /* _nx_crypto_method_sha1_operation Handle SHA1 operation */
106 /* */
107 /* RELEASE HISTORY */
108 /* */
109 /* DATE NAME DESCRIPTION */
110 /* */
111 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
112 /* 09-30-2020 Timothy Stapko Modified comment(s), */
113 /* updated constants, */
114 /* resulting in version 6.1 */
115 /* */
116 /**************************************************************************/
_nx_crypto_sha1_initialize(NX_CRYPTO_SHA1 * context,UINT algorithm)117 NX_CRYPTO_KEEP UINT _nx_crypto_sha1_initialize(NX_CRYPTO_SHA1 *context, UINT algorithm)
118 {
119 NX_CRYPTO_PARAMETER_NOT_USED(algorithm);
120
121 /* Determine if the context is non-null. */
122 if (context == NX_CRYPTO_NULL)
123 {
124 return(NX_CRYPTO_PTR_ERROR);
125 }
126
127 /* First, clear the bit count for this context. */
128 context -> nx_sha1_bit_count[0] = 0; /* Clear the lower 32-bits of the count.*/
129 context -> nx_sha1_bit_count[1] = 0; /* Clear the upper 32-bits of the count.*/
130
131 /* Finally, setup the context states. */
132 context -> nx_sha1_states[0] = 0x67452301UL; /* Setup state A. */
133 context -> nx_sha1_states[1] = 0xEFCDAB89UL; /* Setup state B. */
134 context -> nx_sha1_states[2] = 0x98BADCFEUL; /* Setup state C. */
135 context -> nx_sha1_states[3] = 0x10325476UL; /* Setup state D. */
136 context -> nx_sha1_states[4] = 0xC3D2E1F0UL; /* Setup state E. */
137
138 /* Return success. */
139 return(NX_CRYPTO_SUCCESS);
140 }
141
142
143 /**************************************************************************/
144 /* */
145 /* FUNCTION RELEASE */
146 /* */
147 /* _nx_crypto_sha1_update PORTABLE C */
148 /* 6.1 */
149 /* AUTHOR */
150 /* */
151 /* Timothy Stapko, Microsoft Corporation */
152 /* */
153 /* DESCRIPTION */
154 /* */
155 /* This function updates the digest calculation with new input from */
156 /* the caller. */
157 /* */
158 /* INPUT */
159 /* */
160 /* context SHA1 context pointer */
161 /* input_ptr Pointer to byte(s) of input */
162 /* input_length Length of bytes of input */
163 /* */
164 /* OUTPUT */
165 /* */
166 /* status Completion status */
167 /* */
168 /* CALLS */
169 /* */
170 /* _nx_crypto_sha1_process_buffer Process complete buffer */
171 /* using SHA1 */
172 /* */
173 /* CALLED BY */
174 /* */
175 /* _nx_crypto_sha1_digest_calculate Calculate the SHA1 digest */
176 /* _nx_crypto_method_sha1_operation Handle SHA1 operation */
177 /* */
178 /* RELEASE HISTORY */
179 /* */
180 /* DATE NAME DESCRIPTION */
181 /* */
182 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
183 /* 09-30-2020 Timothy Stapko Modified comment(s), */
184 /* verified memcpy use cases, */
185 /* resulting in version 6.1 */
186 /* */
187 /**************************************************************************/
_nx_crypto_sha1_update(NX_CRYPTO_SHA1 * context,UCHAR * input_ptr,UINT input_length)188 NX_CRYPTO_KEEP UINT _nx_crypto_sha1_update(NX_CRYPTO_SHA1 *context, UCHAR *input_ptr, UINT input_length)
189 {
190
191 ULONG current_bytes;
192 ULONG needed_fill_bytes;
193
194
195 /* Determine if the context is non-null. */
196 if (context == NX_CRYPTO_NULL)
197 {
198 return(NX_CRYPTO_PTR_ERROR);
199 }
200
201 /* Determine if there is a length. */
202 if (input_length == 0)
203 {
204 return(NX_CRYPTO_SUCCESS);
205 }
206
207 /* Calculate the current byte count mod 64. Note the reason for the
208 shift by 3 is to account for the 8 bits per byte. */
209 current_bytes = (context -> nx_sha1_bit_count[0] >> 3) & 0x3F;
210
211 /* Calculate the current number of bytes needed to be filled. */
212 needed_fill_bytes = 64 - current_bytes;
213
214 /* Update the total bit count based on the input length. */
215 context -> nx_sha1_bit_count[0] += (input_length << 3);
216
217 /* Determine if there is roll-over of the bit count into the MSW. */
218 if (context -> nx_sha1_bit_count[0] < (input_length << 3))
219 {
220
221 /* Yes, increment the MSW of the bit count. */
222 context -> nx_sha1_bit_count[1]++;
223 }
224
225 /* Update upper total bit count word. */
226 context -> nx_sha1_bit_count[1] += (input_length >> 29);
227
228 /* Check for a partial buffer that needs to be transformed. */
229 if ((current_bytes) && (input_length >= needed_fill_bytes))
230 {
231
232 /* Yes, we can complete the buffer and transform it. */
233
234 /* Copy the appropriate portion of the input buffer into the internal
235 buffer of the context. */
236 NX_CRYPTO_MEMCPY((void *)&(context -> nx_sha1_buffer[current_bytes]), (void *)input_ptr, needed_fill_bytes); /* Use case of memcpy is verified. */
237
238 /* Process the 64-byte (512 bit) buffer. */
239 _nx_crypto_sha1_process_buffer(context, context -> nx_sha1_buffer);
240
241 /* Adjust the pointers and length accordingly. */
242 input_length = input_length - needed_fill_bytes;
243 input_ptr = input_ptr + needed_fill_bytes;
244
245 /* Clear the remaining bits, since the buffer was processed. */
246 current_bytes = 0;
247 }
248
249 /* Process any and all whole blocks of input. */
250 while (input_length >= 64)
251 {
252
253 /* Process this 64-byte (512 bit) buffer. */
254 _nx_crypto_sha1_process_buffer(context, input_ptr);
255
256 /* Adjust the pointers and length accordingly. */
257 input_length = input_length - 64;
258 input_ptr = input_ptr + 64;
259 }
260
261 /* Determine if there is anything left. */
262 if (input_length)
263 {
264
265 /* Save the remaining bytes in the internal buffer after any remaining bytes
266 that it is processed later. */
267 NX_CRYPTO_MEMCPY((void *)&(context -> nx_sha1_buffer[current_bytes]), (void *)input_ptr, input_length); /* Use case of memcpy is verified. */
268 }
269
270 /* Return success. */
271 return(NX_CRYPTO_SUCCESS);
272 }
273
274
275 /**************************************************************************/
276 /* */
277 /* FUNCTION RELEASE */
278 /* */
279 /* _nx_crypto_sha1_digest_calculate PORTABLE C */
280 /* 6.1 */
281 /* AUTHOR */
282 /* */
283 /* Timothy Stapko, Microsoft Corporation */
284 /* */
285 /* DESCRIPTION */
286 /* */
287 /* This function finishes calculation of the SHA1 digest. It is called */
288 /* where there is no further input needed for the digest. The resulting*/
289 /* 20-byte (160-bit) SHA1 digest is returned to the caller. */
290 /* */
291 /* INPUT */
292 /* */
293 /* context SHA1 context pointer */
294 /* digest Pointer to return digest in */
295 /* algorithm Algorithm type */
296 /* */
297 /* OUTPUT */
298 /* */
299 /* status Completion status */
300 /* */
301 /* CALLS */
302 /* */
303 /* _nx_crypto_sha1_update Update the digest with padding*/
304 /* and length of digest */
305 /* */
306 /* CALLED BY */
307 /* */
308 /* _nx_crypto_method_sha1_operation Handle SHA1 operation */
309 /* */
310 /* RELEASE HISTORY */
311 /* */
312 /* DATE NAME DESCRIPTION */
313 /* */
314 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
315 /* 09-30-2020 Timothy Stapko Modified comment(s), */
316 /* updated constants, */
317 /* resulting in version 6.1 */
318 /* */
319 /**************************************************************************/
_nx_crypto_sha1_digest_calculate(NX_CRYPTO_SHA1 * context,UCHAR digest[20],UINT algorithm)320 NX_CRYPTO_KEEP UINT _nx_crypto_sha1_digest_calculate(NX_CRYPTO_SHA1 *context, UCHAR digest[20], UINT algorithm)
321 {
322
323 UCHAR bit_count_string[8];
324 ULONG current_byte_count;
325 ULONG padding_bytes;
326
327 NX_CRYPTO_PARAMETER_NOT_USED(algorithm);
328
329 /* Move the lower portion of the bit count into the array. */
330 bit_count_string[0] = (UCHAR)(context -> nx_sha1_bit_count[1] >> 24);
331 bit_count_string[1] = (UCHAR)(context -> nx_sha1_bit_count[1] >> 16);
332 bit_count_string[2] = (UCHAR)(context -> nx_sha1_bit_count[1] >> 8);
333 bit_count_string[3] = (UCHAR)(context -> nx_sha1_bit_count[1]);
334 bit_count_string[4] = (UCHAR)(context -> nx_sha1_bit_count[0] >> 24);
335 bit_count_string[5] = (UCHAR)(context -> nx_sha1_bit_count[0] >> 16);
336 bit_count_string[6] = (UCHAR)(context -> nx_sha1_bit_count[0] >> 8);
337 bit_count_string[7] = (UCHAR)(context -> nx_sha1_bit_count[0]);
338
339 /* Calculate the current byte count. */
340 current_byte_count = (context -> nx_sha1_bit_count[0] >> 3) & 0x3F;
341
342 /* Calculate the padding bytes needed. */
343 padding_bytes = (current_byte_count < 56) ? (56 - current_byte_count) : (120 - current_byte_count);
344
345 /* Add any padding required. */
346 _nx_crypto_sha1_update(context, (UCHAR*)_nx_crypto_sha1_padding, padding_bytes);
347
348 /* Add the in the length. */
349 _nx_crypto_sha1_update(context, bit_count_string, 8);
350
351 /* Now store the digest in the caller specified destination. */
352 digest[0] = (UCHAR)(context -> nx_sha1_states[0] >> 24);
353 digest[1] = (UCHAR)(context -> nx_sha1_states[0] >> 16);
354 digest[2] = (UCHAR)(context -> nx_sha1_states[0] >> 8);
355 digest[3] = (UCHAR)(context -> nx_sha1_states[0]);
356 digest[4] = (UCHAR)(context -> nx_sha1_states[1] >> 24);
357 digest[5] = (UCHAR)(context -> nx_sha1_states[1] >> 16);
358 digest[6] = (UCHAR)(context -> nx_sha1_states[1] >> 8);
359 digest[7] = (UCHAR)(context -> nx_sha1_states[1]);
360 digest[8] = (UCHAR)(context -> nx_sha1_states[2] >> 24);
361 digest[9] = (UCHAR)(context -> nx_sha1_states[2] >> 16);
362 digest[10] = (UCHAR)(context -> nx_sha1_states[2] >> 8);
363 digest[11] = (UCHAR)(context -> nx_sha1_states[2]);
364 digest[12] = (UCHAR)(context -> nx_sha1_states[3] >> 24);
365 digest[13] = (UCHAR)(context -> nx_sha1_states[3] >> 16);
366 digest[14] = (UCHAR)(context -> nx_sha1_states[3] >> 8);
367 digest[15] = (UCHAR)(context -> nx_sha1_states[3]);
368 digest[16] = (UCHAR)(context -> nx_sha1_states[4] >> 24);
369 digest[17] = (UCHAR)(context -> nx_sha1_states[4] >> 16);
370 digest[18] = (UCHAR)(context -> nx_sha1_states[4] >> 8);
371 digest[19] = (UCHAR)(context -> nx_sha1_states[4]);
372
373 #ifdef NX_SECURE_KEY_CLEAR
374 NX_CRYPTO_MEMSET(bit_count_string, 0, sizeof(bit_count_string));
375 #endif /* NX_SECURE_KEY_CLEAR */
376
377 /* Return successful completion. */
378 return(NX_CRYPTO_SUCCESS);
379 }
380
381
382 /**************************************************************************/
383 /* */
384 /* FUNCTION RELEASE */
385 /* */
386 /* _nx_crypto_sha1_process_buffer PORTABLE C */
387 /* 6.1 */
388 /* AUTHOR */
389 /* */
390 /* Timothy Stapko, Microsoft Corporation */
391 /* */
392 /* DESCRIPTION */
393 /* */
394 /* This function actually uses the SHA1 algorithm to process a 64-byte */
395 /* (512 bit) buffer. */
396 /* */
397 /* INPUT */
398 /* */
399 /* context SHA1 context pointer */
400 /* buffer Pointer to 64-byte buffer */
401 /* */
402 /* OUTPUT */
403 /* */
404 /* status Completion status */
405 /* */
406 /* CALLS */
407 /* */
408 /* None */
409 /* */
410 /* CALLED BY */
411 /* */
412 /* _nx_crypto_sha1_update Update the digest with padding*/
413 /* and length of digest */
414 /* */
415 /* RELEASE HISTORY */
416 /* */
417 /* DATE NAME DESCRIPTION */
418 /* */
419 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
420 /* 09-30-2020 Timothy Stapko Modified comment(s), */
421 /* resulting in version 6.1 */
422 /* */
423 /**************************************************************************/
_nx_crypto_sha1_process_buffer(NX_CRYPTO_SHA1 * context,UCHAR buffer[64])424 NX_CRYPTO_KEEP VOID _nx_crypto_sha1_process_buffer(NX_CRYPTO_SHA1 *context, UCHAR buffer[64])
425 {
426
427 ULONG *w;
428 UINT t;
429 ULONG temp;
430 ULONG a, b, c, d, e;
431
432
433 /* Setup pointers to the word array. */
434 w = context -> nx_sha1_word_array;
435
436 /* Initialize the first 16 words of the word array, taking care of the
437 endian issues at the same time. */
438 for (t = 0; t < 16; t++)
439 {
440
441 /* Setup each entry. */
442 w[t] = (((ULONG)buffer[t * 4]) << 24) | (((ULONG)buffer[(t * 4) + 1]) << 16) | (((ULONG)buffer[(t * 4) + 2]) << 8) | ((ULONG)buffer[(t * 4) + 3]);
443 }
444
445 /* Setup the remaining entries of the word array. */
446 for (t = 16; t < 80; t++)
447 {
448
449 /* Setup each entry. */
450 w[t] = LEFT_SHIFT_CIRCULAR((w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16]), 1);
451 }
452
453 /* Initialize the state variables. */
454 a = context -> nx_sha1_states[0];
455 b = context -> nx_sha1_states[1];
456 c = context -> nx_sha1_states[2];
457 d = context -> nx_sha1_states[3];
458 e = context -> nx_sha1_states[4];
459
460 /* Now, perform Round 1 operations. */
461 for (t = 0; t < 20; t++)
462 {
463
464 /* Compute round 1 (t = 0 through t = 19). */
465 temp = LEFT_SHIFT_CIRCULAR(a, 5) + F1(b, c, d) + e + w[t] + 0x5A827999UL;
466 e = d;
467 d = c;
468 c = LEFT_SHIFT_CIRCULAR(b, 30);
469 b = a;
470 a = temp;
471 }
472
473 /* Now, perform Round 2 operations. */
474 for (t = 20; t < 40; t++)
475 {
476
477 /* Compute round 2 (t = 20 through t = 39). */
478 temp = LEFT_SHIFT_CIRCULAR(a, 5) + F2(b, c, d) + e + w[t] + 0x6ED9EBA1UL;
479 e = d;
480 d = c;
481 c = LEFT_SHIFT_CIRCULAR(b, 30);
482 b = a;
483 a = temp;
484 }
485
486 /* Now, perform Round 3 operations. */
487 for (t = 40; t < 60; t++)
488 {
489
490 /* Compute round 3 (t = 40 through t = 59). */
491 temp = LEFT_SHIFT_CIRCULAR(a, 5) + F3(b, c, d) + e + w[t] + 0x8F1BBCDCUL;
492 e = d;
493 d = c;
494 c = LEFT_SHIFT_CIRCULAR(b, 30);
495 b = a;
496 a = temp;
497 }
498
499 /* Finally, perform Round 4 operations. */
500 for (t = 60; t < 80; t++)
501 {
502
503 /* Compute round 4 (t = 60 through t = 79). */
504 temp = LEFT_SHIFT_CIRCULAR(a, 5) + F4(b, c, d) + e + w[t] + 0xCA62C1D6UL;
505 e = d;
506 d = c;
507 c = LEFT_SHIFT_CIRCULAR(b, 30);
508 b = a;
509 a = temp;
510 }
511
512 /* Save the resulting in this SHA1 context. */
513 context -> nx_sha1_states[0] += a;
514 context -> nx_sha1_states[1] += b;
515 context -> nx_sha1_states[2] += c;
516 context -> nx_sha1_states[3] += d;
517 context -> nx_sha1_states[4] += e;
518
519 #ifdef NX_SECURE_KEY_CLEAR
520 a = 0; b = 0; c = 0; d = 0; e = 0;
521 temp = 0;
522 #endif /* NX_SECURE_KEY_CLEAR */
523 }
524
525
526 /**************************************************************************/
527 /* */
528 /* FUNCTION RELEASE */
529 /* */
530 /* _nx_crypto_method_sha1_init PORTABLE C */
531 /* 6.1 */
532 /* AUTHOR */
533 /* */
534 /* Timothy Stapko, Microsoft Corporation */
535 /* */
536 /* DESCRIPTION */
537 /* */
538 /* This function is the common crypto method init callback for */
539 /* Microsoft supported SHA1 cryptographic algorithm. */
540 /* */
541 /* INPUT */
542 /* */
543 /* method Pointer to crypto method */
544 /* key Pointer to key */
545 /* key_size_in_bits Length of key size in bits */
546 /* handler Returned crypto handler */
547 /* crypto_metadata Metadata area */
548 /* crypto_metadata_size Size of the metadata area */
549 /* */
550 /* OUTPUT */
551 /* */
552 /* status Completion status */
553 /* */
554 /* CALLS */
555 /* */
556 /* None */
557 /* */
558 /* CALLED BY */
559 /* */
560 /* Application Code */
561 /* */
562 /* RELEASE HISTORY */
563 /* */
564 /* DATE NAME DESCRIPTION */
565 /* */
566 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
567 /* 09-30-2020 Timothy Stapko Modified comment(s), */
568 /* resulting in version 6.1 */
569 /* */
570 /**************************************************************************/
_nx_crypto_method_sha1_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)571 NX_CRYPTO_KEEP UINT _nx_crypto_method_sha1_init(struct NX_CRYPTO_METHOD_STRUCT *method,
572 UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits,
573 VOID **handle,
574 VOID *crypto_metadata,
575 ULONG crypto_metadata_size)
576 {
577
578 NX_CRYPTO_PARAMETER_NOT_USED(key);
579 NX_CRYPTO_PARAMETER_NOT_USED(key_size_in_bits);
580 NX_CRYPTO_PARAMETER_NOT_USED(handle);
581
582 NX_CRYPTO_STATE_CHECK
583
584 if (method == NX_CRYPTO_NULL)
585 {
586 return(NX_CRYPTO_PTR_ERROR);
587 }
588
589 if (crypto_metadata == NX_CRYPTO_NULL)
590 {
591
592 /* metadata is not passed by IPsec. */
593 #ifndef NX_IPSEC_ENABLE
594 return(NX_CRYPTO_PTR_ERROR);
595 #endif
596 }
597 else if (((((ULONG)crypto_metadata) & 0x3) != 0) || (crypto_metadata_size < sizeof(NX_CRYPTO_SHA1)))
598 {
599 return(NX_CRYPTO_PTR_ERROR);
600 }
601
602 return(NX_CRYPTO_SUCCESS);
603 }
604
605
606 /**************************************************************************/
607 /* */
608 /* FUNCTION RELEASE */
609 /* */
610 /* _nx_crypto_method_sha1_cleanup PORTABLE C */
611 /* 6.1 */
612 /* AUTHOR */
613 /* */
614 /* Timothy Stapko, Microsoft Corporation */
615 /* */
616 /* DESCRIPTION */
617 /* */
618 /* This function cleans up the crypto metadata. */
619 /* */
620 /* INPUT */
621 /* */
622 /* crypto_metadata Crypto metadata */
623 /* */
624 /* OUTPUT */
625 /* */
626 /* status Completion status */
627 /* */
628 /* CALLS */
629 /* */
630 /* NX_CRYPTO_MEMSET Set the memory */
631 /* */
632 /* CALLED BY */
633 /* */
634 /* Application Code */
635 /* */
636 /* RELEASE HISTORY */
637 /* */
638 /* DATE NAME DESCRIPTION */
639 /* */
640 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
641 /* 09-30-2020 Timothy Stapko Modified comment(s), */
642 /* resulting in version 6.1 */
643 /* */
644 /**************************************************************************/
_nx_crypto_method_sha1_cleanup(VOID * crypto_metadata)645 NX_CRYPTO_KEEP UINT _nx_crypto_method_sha1_cleanup(VOID *crypto_metadata)
646 {
647
648 NX_CRYPTO_STATE_CHECK
649
650 #ifdef NX_SECURE_KEY_CLEAR
651 if (!crypto_metadata)
652 return (NX_CRYPTO_SUCCESS);
653
654 /* Clean up the crypto metadata. */
655 NX_CRYPTO_MEMSET(crypto_metadata, 0, sizeof(NX_CRYPTO_SHA1));
656 #else
657 NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata);
658 #endif/* NX_SECURE_KEY_CLEAR */
659
660 return(NX_CRYPTO_SUCCESS);
661 }
662
663
664 /**************************************************************************/
665 /* */
666 /* FUNCTION RELEASE */
667 /* */
668 /* _nx_crypto_method_sha1_operation PORTABLE C */
669 /* 6.3.0 */
670 /* AUTHOR */
671 /* */
672 /* Timothy Stapko, Microsoft Corporation */
673 /* */
674 /* DESCRIPTION */
675 /* */
676 /* This function encrypts and decrypts a message using */
677 /* the SHA1 algorithm. */
678 /* */
679 /* INPUT */
680 /* */
681 /* op SHA1 operation */
682 /* handle Crypto handle */
683 /* method Cryption Method Object */
684 /* key Encryption Key */
685 /* key_size_in_bits Key size in bits */
686 /* input Input data */
687 /* input_length_in_byte Input data size */
688 /* iv_ptr Initial vector */
689 /* output Output buffer */
690 /* output_length_in_byte Output buffer size */
691 /* crypto_metadata Metadata area */
692 /* crypto_metadata_size Metadata area size */
693 /* packet_ptr Pointer to packet */
694 /* nx_crypto_hw_process_callback Callback function pointer */
695 /* */
696 /* OUTPUT */
697 /* */
698 /* status Completion status */
699 /* */
700 /* CALLS */
701 /* */
702 /* _nx_crypto_sha1_initialize Initialize the SHA1 context */
703 /* _nx_crypto_sha1_update Update the digest with padding*/
704 /* and length of digest */
705 /* _nx_crypto_sha1_digest_calculate Calculate the SHA1 digest */
706 /* */
707 /* CALLED BY */
708 /* */
709 /* Application Code */
710 /* */
711 /* RELEASE HISTORY */
712 /* */
713 /* DATE NAME DESCRIPTION */
714 /* */
715 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
716 /* 09-30-2020 Timothy Stapko Modified comment(s), */
717 /* resulting in version 6.1 */
718 /* 10-31-2023 Yanwu Cai Modified comment(s), */
719 /* resulting in version 6.3.0 */
720 /* */
721 /**************************************************************************/
_nx_crypto_method_sha1_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))722 NX_CRYPTO_KEEP UINT _nx_crypto_method_sha1_operation(UINT op, /* Encrypt, Decrypt, Authenticate */
723 VOID *handle, /* Crypto handler */
724 struct NX_CRYPTO_METHOD_STRUCT *method,
725 UCHAR *key,
726 NX_CRYPTO_KEY_SIZE key_size_in_bits,
727 UCHAR *input,
728 ULONG input_length_in_byte,
729 UCHAR *iv_ptr,
730 UCHAR *output,
731 ULONG output_length_in_byte,
732 VOID *crypto_metadata,
733 ULONG crypto_metadata_size,
734 VOID *packet_ptr,
735 VOID (*nx_crypto_hw_process_callback)(VOID *packet_ptr, UINT status))
736 {
737 NX_CRYPTO_SHA1 *ctx = (NX_CRYPTO_SHA1 *)crypto_metadata;
738 #ifdef NX_IPSEC_ENABLE
739 NX_CRYPTO_SHA1 metadata;
740 #endif
741
742 NX_CRYPTO_PARAMETER_NOT_USED(handle);
743 NX_CRYPTO_PARAMETER_NOT_USED(key);
744 NX_CRYPTO_PARAMETER_NOT_USED(key_size_in_bits);
745 NX_CRYPTO_PARAMETER_NOT_USED(iv_ptr);
746 NX_CRYPTO_PARAMETER_NOT_USED(output_length_in_byte);
747 NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
748 NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
749
750 NX_CRYPTO_STATE_CHECK
751
752 if (method == NX_CRYPTO_NULL)
753 {
754 return(NX_CRYPTO_PTR_ERROR);
755 }
756
757 /* Verify the metadata address is 4-byte aligned. */
758 if (crypto_metadata == NX_CRYPTO_NULL)
759 {
760 #ifdef NX_IPSEC_ENABLE
761 /* metadata is not passed by IPsec. */
762 ctx = &metadata;
763 #else
764 return(NX_CRYPTO_PTR_ERROR);
765 #endif
766 }
767 else if (((((ULONG)crypto_metadata) & 0x3) != 0) || (crypto_metadata_size < sizeof(NX_CRYPTO_SHA1)))
768 {
769 return(NX_CRYPTO_PTR_ERROR);
770 }
771
772 switch (op)
773 {
774 case NX_CRYPTO_HASH_INITIALIZE:
775 _nx_crypto_sha1_initialize(ctx, method -> nx_crypto_algorithm);
776 break;
777
778 case NX_CRYPTO_HASH_UPDATE:
779 _nx_crypto_sha1_update(ctx, input, input_length_in_byte);
780 break;
781
782 case NX_CRYPTO_HASH_CALCULATE:
783 if(output_length_in_byte < 20)
784 return(NX_CRYPTO_INVALID_BUFFER_SIZE);
785 _nx_crypto_sha1_digest_calculate(ctx, output, method -> nx_crypto_algorithm);
786 break;
787
788 default:
789 if(output_length_in_byte < 20)
790 return(NX_CRYPTO_INVALID_BUFFER_SIZE);
791 _nx_crypto_sha1_initialize(ctx, method -> nx_crypto_algorithm);
792 _nx_crypto_sha1_update(ctx, input, input_length_in_byte);
793 _nx_crypto_sha1_digest_calculate(ctx, output, method -> nx_crypto_algorithm);
794 #if defined(NX_SECURE_KEY_CLEAR) && defined(NX_IPSEC_ENABLE)
795 if (crypto_metadata == NX_CRYPTO_NULL)
796 {
797 memset(ctx, 0, sizeof(NX_CRYPTO_SHA1));
798 }
799 #endif
800 break;
801 }
802
803 return NX_CRYPTO_SUCCESS;
804 }
805
806