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