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