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