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 /**************************************************************************/
15 /**                                                                       */
16 /** NetX Crypto Component                                                 */
17 /**                                                                       */
18 /**   SHA-256 Digest Algorithm (SHA2)                                     */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 #include "nx_crypto_sha2.h"
24 
25 /* Constants used in the SHA-256 digest calculation. */
26 const ULONG _sha2_round_constants[64] =
27 {
28     0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
29     0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
30     0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
31     0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
32     0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
33     0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
34     0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
35     0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
36 };
37 
38 
39 /* Define the SHA2 logic functions.  */
40 #define CH_FUNC(x, y, z)           (((x) & (y)) ^ ((~(x)) & (z)))
41 #define MAJ_FUNC(x, y, z)          (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
42 
43 #define RIGHT_SHIFT_CIRCULAR(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
44 #define LARGE_SIGMA_0(x)           (RIGHT_SHIFT_CIRCULAR((x),  2) ^ RIGHT_SHIFT_CIRCULAR((x), 13) ^ RIGHT_SHIFT_CIRCULAR((x), 22))
45 #define LARGE_SIGMA_1(x)           (RIGHT_SHIFT_CIRCULAR((x),  6) ^ RIGHT_SHIFT_CIRCULAR((x), 11) ^ RIGHT_SHIFT_CIRCULAR((x), 25))
46 #define SMALL_SIGMA_0(x)           (RIGHT_SHIFT_CIRCULAR((x),  7) ^ RIGHT_SHIFT_CIRCULAR((x), 18) ^ ((x) >> 3))
47 #define SMALL_SIGMA_1(x)           (RIGHT_SHIFT_CIRCULAR((x), 17) ^ RIGHT_SHIFT_CIRCULAR((x), 19) ^ ((x) >> 10))
48 
49 #define W0(t) ((((ULONG)buffer[(t) * 4]) << 24) | (((ULONG)buffer[((t) * 4) + 1]) << 16) | (((ULONG)buffer[((t) * 4) + 2]) << 8) | ((ULONG)buffer[((t) * 4) + 3]))
50 #define W16(t) (SMALL_SIGMA_1(w[(t) - 2]) + w[(t) - 7] + SMALL_SIGMA_0(w[(t) - 15]) + w[(t) - 16])
51 
52 /* Define the padding array.  This is used to pad the message such that its length is
53    64 bits shy of being a multiple of 512 bits long.  */
54 const UCHAR   _nx_crypto_sha256_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};
55 
56 
57 /**************************************************************************/
58 /*                                                                        */
59 /*  FUNCTION                                               RELEASE        */
60 /*                                                                        */
61 /*    _nx_crypto_sha256_initialize                        PORTABLE C      */
62 /*                                                           6.1          */
63 /*                                                                        */
64 /*  AUTHOR                                                                */
65 /*                                                                        */
66 /*    Timothy Stapko, Microsoft Corporation                               */
67 /*                                                                        */
68 /*  DESCRIPTION                                                           */
69 /*                                                                        */
70 /*    This function initializes the SHA256 context. It must be called     */
71 /*    prior to creating a SHA256 digest.                                  */
72 /*                                                                        */
73 /*  INPUT                                                                 */
74 /*                                                                        */
75 /*    context                               SHA256 context pointer        */
76 /*                                                                        */
77 /*  OUTPUT                                                                */
78 /*                                                                        */
79 /*    status                                Completion status             */
80 /*                                                                        */
81 /*  CALLS                                                                 */
82 /*                                                                        */
83 /*    None                                                                */
84 /*                                                                        */
85 /*  CALLED BY                                                             */
86 /*                                                                        */
87 /*    _nx_crypto_method_sha256_operation    Handle SHA256 operation       */
88 /*                                                                        */
89 /*  RELEASE HISTORY                                                       */
90 /*                                                                        */
91 /*    DATE              NAME                      DESCRIPTION             */
92 /*                                                                        */
93 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
94 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
95 /*                                            resulting in version 6.1    */
96 /*                                                                        */
97 /**************************************************************************/
_nx_crypto_sha256_initialize(NX_CRYPTO_SHA256 * context,UINT algorithm)98 NX_CRYPTO_KEEP UINT  _nx_crypto_sha256_initialize(NX_CRYPTO_SHA256 *context, UINT algorithm )
99 {
100     /* Determine if the context is non-null.  */
101     if (context == NX_CRYPTO_NULL)
102     {
103         return(NX_CRYPTO_PTR_ERROR);
104     }
105 
106     /* First, clear the bit count for this context.  */
107     context -> nx_sha256_bit_count[0] =  0;                   /* Clear the lower 32-bits of the count.*/
108     context -> nx_sha256_bit_count[1] =  0;                   /* Clear the upper 32-bits of the count.*/
109 
110     if ((algorithm == NX_CRYPTO_AUTHENTICATION_HMAC_SHA2_256) ||
111         (algorithm == NX_CRYPTO_HASH_SHA256))
112     {
113 
114         /* Initialize SHA-256 state. */
115         context -> nx_sha256_states[0] = 0x6a09e667; /* A H0 */
116         context -> nx_sha256_states[1] = 0xbb67ae85; /* B H1 */
117         context -> nx_sha256_states[2] = 0x3c6ef372; /* C H2 */
118         context -> nx_sha256_states[3] = 0xa54ff53a; /* D H3 */
119         context -> nx_sha256_states[4] = 0x510e527f; /* E H4 */
120         context -> nx_sha256_states[5] = 0x9b05688c; /* F H5 */
121         context -> nx_sha256_states[6] = 0x1f83d9ab; /* G H6 */
122         context -> nx_sha256_states[7] = 0x5be0cd19; /* H H7 */
123     }
124     else
125     {
126 
127         /* Initialize SHA-224 state. */
128         context -> nx_sha256_states[0] = 0xc1059ed8; /* A H0 */
129         context -> nx_sha256_states[1] = 0x367cd507; /* B H1 */
130         context -> nx_sha256_states[2] = 0x3070dd17; /* C H2 */
131         context -> nx_sha256_states[3] = 0xf70e5939; /* D H3 */
132         context -> nx_sha256_states[4] = 0xffc00b31; /* E H4 */
133         context -> nx_sha256_states[5] = 0x68581511; /* F H5 */
134         context -> nx_sha256_states[6] = 0x64f98fa7; /* G H6 */
135         context -> nx_sha256_states[7] = 0xbefa4fa4; /* H H7 */
136     }
137 
138     /* Return success.  */
139     return(NX_CRYPTO_SUCCESS);
140 }
141 
142 
143 /**************************************************************************/
144 /*                                                                        */
145 /*  FUNCTION                                               RELEASE        */
146 /*                                                                        */
147 /*    _nx_crypto_sha256_update                            PORTABLE C      */
148 /*                                                           6.1          */
149 /*                                                                        */
150 /*  AUTHOR                                                                */
151 /*                                                                        */
152 /*    Timothy Stapko, Microsoft Corporation                               */
153 /*                                                                        */
154 /*  DESCRIPTION                                                           */
155 /*                                                                        */
156 /*    This function updates the SHA256 digest with new input from the     */
157 /*    caller.                                                             */
158 /*                                                                        */
159 /*  INPUT                                                                 */
160 /*                                                                        */
161 /*    context                               SHA256 context pointer        */
162 /*    input_ptr                             Pointer to input data         */
163 /*    input_length                          Number of bytes in input      */
164 /*                                                                        */
165 /*  OUTPUT                                                                */
166 /*                                                                        */
167 /*    status                                Completion status             */
168 /*                                                                        */
169 /*  CALLS                                                                 */
170 /*                                                                        */
171 /*    _nx_crypto_sha256_process_buffer      Process complete buffer       */
172 /*                                            using SHA256                */
173 /*                                                                        */
174 /*  CALLED BY                                                             */
175 /*                                                                        */
176 /*    _nx_crypto_sha256_digest_calculate   Calculate the SHA256 digest    */
177 /*    _nx_crypto_method_sha256_operation   Handle SHA256 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_sha256_update(NX_CRYPTO_SHA256 * context,UCHAR * input_ptr,UINT input_length)189 NX_CRYPTO_KEEP UINT _nx_crypto_sha256_update(NX_CRYPTO_SHA256 *context, UCHAR *input_ptr, UINT input_length)
190 {
191 ULONG current_bytes;
192 ULONG needed_fill_bytes;
193 
194     /* Determine if the context is non-null.  */
195     if (context == NX_CRYPTO_NULL)
196     {
197         return(NX_CRYPTO_PTR_ERROR);
198     }
199 
200     /* Determine if there is a length.  */
201     if (input_length == 0)
202     {
203         return(NX_CRYPTO_SUCCESS);
204     }
205 
206     /* Calculate the current byte count mod 64. Note the reason for the
207        shift by 3 is to account for the 8 bits per byte.  */
208     current_bytes =  (context -> nx_sha256_bit_count[0] >> 3) & 0x3F;
209 
210     /* Calculate the current number of bytes needed to be filled.  */
211     needed_fill_bytes =  64 - current_bytes;
212 
213     /* Update the total bit count based on the input length.  */
214     context -> nx_sha256_bit_count[0] += (input_length << 3);
215 
216     /* Determine if there is roll-over of the bit count into the MSW.  */
217     if (context -> nx_sha256_bit_count[0] < (input_length << 3))
218     {
219 
220         /* Yes, increment the MSW of the bit count.  */
221         context -> nx_sha256_bit_count[1]++;
222     }
223 
224     /* Update upper total bit count word.  */
225     context -> nx_sha256_bit_count[1] +=  (input_length >> 29);
226 
227     /* Check for a partial buffer that needs to be transformed.  */
228     if ((current_bytes) && (input_length >= needed_fill_bytes))
229     {
230         /* Yes, we can complete the buffer and transform it.  */
231 
232         /* Copy the appropriate portion of the input buffer into the internal
233            buffer of the context.  */
234         NX_CRYPTO_MEMCPY((void *)&(context -> nx_sha256_buffer[current_bytes]), (void *)input_ptr, needed_fill_bytes); /* Use case of memcpy is verified. */
235 
236         /* Process the 64-byte (512 bit) buffer.  */
237         _nx_crypto_sha256_process_buffer(context, context -> nx_sha256_buffer);
238 
239         /* Adjust the pointers and length accordingly.  */
240         input_length =  input_length - needed_fill_bytes;
241         input_ptr =     input_ptr + needed_fill_bytes;
242 
243         /* Clear the remaining bits, since the buffer was processed.  */
244         current_bytes =  0;
245     }
246 
247     /* Process any and all whole blocks of input.  */
248     while (input_length >= 64)
249     {
250 
251         /* Process this 64-byte (512 bit) buffer.  */
252         _nx_crypto_sha256_process_buffer(context, input_ptr);
253 
254         /* Adjust the pointers and length accordingly.  */
255         input_length =  input_length - 64;
256         input_ptr =     input_ptr + 64;
257     }
258 
259     /* Determine if there is anything left.  */
260     if (input_length)
261     {
262         /* Save the remaining bytes in the internal buffer after any remaining bytes
263            so that it is processed later.  */
264         NX_CRYPTO_MEMCPY((void *)&(context -> nx_sha256_buffer[current_bytes]), (void *)input_ptr, input_length); /* Use case of memcpy is verified. */
265     }
266 
267     /* Return success.  */
268     return(NX_CRYPTO_SUCCESS);
269 }
270 
271 
272 /**************************************************************************/
273 /*                                                                        */
274 /*  FUNCTION                                               RELEASE        */
275 /*                                                                        */
276 /*    _nx_crypto_sha256_digest_calculate                  PORTABLE C      */
277 /*                                                           6.1.10       */
278 /*                                                                        */
279 /*  AUTHOR                                                                */
280 /*                                                                        */
281 /*    Timothy Stapko, Microsoft Corporation                               */
282 /*                                                                        */
283 /*  DESCRIPTION                                                           */
284 /*                                                                        */
285 /*    This function calculates the final SHA256 digest. It is called      */
286 /*    when there is no more input for the digest and returns the 32-byte  */
287 /*    (256-bit) SHA256 digest to the caller.                              */
288 /*                                                                        */
289 /*  INPUT                                                                 */
290 /*                                                                        */
291 /*    context                               SHA256 context pointer        */
292 /*    digest                                Pointer to return buffer      */
293 /*                                                                        */
294 /*  OUTPUT                                                                */
295 /*                                                                        */
296 /*    status                                Completion status             */
297 /*                                                                        */
298 /*  CALLS                                                                 */
299 /*                                                                        */
300 /*    _nx_crypto_sha256_update              Final update to the digest    */
301 /*                                            with padding and length     */
302 /*                                                                        */
303 /*  CALLED BY                                                             */
304 /*                                                                        */
305 /*    _nx_crypto_method_sha256_operation    Handle SHA256 operation       */
306 /*                                                                        */
307 /*  RELEASE HISTORY                                                       */
308 /*                                                                        */
309 /*    DATE              NAME                      DESCRIPTION             */
310 /*                                                                        */
311 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
312 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
313 /*                                            resulting in version 6.1    */
314 /*  01-31-2022     Timothy Stapko           Modified comment(s),          */
315 /*                                            improved performance,       */
316 /*                                            resulting in version 6.1.10 */
317 /*                                                                        */
318 /**************************************************************************/
_nx_crypto_sha256_digest_calculate(NX_CRYPTO_SHA256 * context,UCHAR * digest,UINT algorithm)319 NX_CRYPTO_KEEP UINT _nx_crypto_sha256_digest_calculate(NX_CRYPTO_SHA256 *context, UCHAR *digest, UINT algorithm)
320 {
321 UINT bit_count_string[2];
322 ULONG current_byte_count;
323 ULONG padding_bytes;
324 
325 
326     /* Move the lower portion of the bit count into the array.  */
327     bit_count_string[0] = context -> nx_sha256_bit_count[1];
328     NX_CRYPTO_CHANGE_ULONG_ENDIAN(bit_count_string[0]);
329     bit_count_string[1] = context -> nx_sha256_bit_count[0];
330     NX_CRYPTO_CHANGE_ULONG_ENDIAN(bit_count_string[1]);
331 
332     /* Calculate the current byte count.  */
333     current_byte_count =  (context -> nx_sha256_bit_count[0] >> 3) & 0x3F;
334 
335     /* Calculate the padding bytes needed.  */
336     padding_bytes =  (current_byte_count < 56) ? (56 - current_byte_count) : (120 - current_byte_count);
337 
338     /* Add any padding required.  */
339     _nx_crypto_sha256_update(context, (UCHAR*)_nx_crypto_sha256_padding, padding_bytes);
340 
341     /* Add the in the length.  */
342     _nx_crypto_sha256_update(context, (UCHAR*)bit_count_string, 8);
343 
344     /* Now store the digest in the caller specified destination.  */
345     digest[0] =  (UCHAR)(context -> nx_sha256_states[0] >> 24);
346     digest[1] =  (UCHAR)(context -> nx_sha256_states[0] >> 16);
347     digest[2] =  (UCHAR)(context -> nx_sha256_states[0] >> 8);
348     digest[3] =  (UCHAR)(context -> nx_sha256_states[0]);
349     digest[4] =  (UCHAR)(context -> nx_sha256_states[1] >> 24);
350     digest[5] =  (UCHAR)(context -> nx_sha256_states[1] >> 16);
351     digest[6] =  (UCHAR)(context -> nx_sha256_states[1] >> 8);
352     digest[7] =  (UCHAR)(context -> nx_sha256_states[1]);
353     digest[8] =  (UCHAR)(context -> nx_sha256_states[2] >> 24);
354     digest[9] =  (UCHAR)(context -> nx_sha256_states[2] >> 16);
355     digest[10] =  (UCHAR)(context -> nx_sha256_states[2] >> 8);
356     digest[11] =  (UCHAR)(context -> nx_sha256_states[2]);
357     digest[12] =  (UCHAR)(context -> nx_sha256_states[3] >> 24);
358     digest[13] =  (UCHAR)(context -> nx_sha256_states[3] >> 16);
359     digest[14] =  (UCHAR)(context -> nx_sha256_states[3] >> 8);
360     digest[15] =  (UCHAR)(context -> nx_sha256_states[3]);
361     digest[16] =  (UCHAR)(context -> nx_sha256_states[4] >> 24);
362     digest[17] =  (UCHAR)(context -> nx_sha256_states[4] >> 16);
363     digest[18] =  (UCHAR)(context -> nx_sha256_states[4] >> 8);
364     digest[19] =  (UCHAR)(context -> nx_sha256_states[4]);
365     digest[20] =  (UCHAR)(context -> nx_sha256_states[5] >> 24);
366     digest[21] =  (UCHAR)(context -> nx_sha256_states[5] >> 16);
367     digest[22] =  (UCHAR)(context -> nx_sha256_states[5] >> 8);
368     digest[23] =  (UCHAR)(context -> nx_sha256_states[5]);
369     digest[24] =  (UCHAR)(context -> nx_sha256_states[6] >> 24);
370     digest[25] =  (UCHAR)(context -> nx_sha256_states[6] >> 16);
371     digest[26] =  (UCHAR)(context -> nx_sha256_states[6] >> 8);
372     digest[27] =  (UCHAR)(context -> nx_sha256_states[6]);
373     if ((algorithm == NX_CRYPTO_AUTHENTICATION_HMAC_SHA2_256) ||
374         (algorithm == NX_CRYPTO_HASH_SHA256))
375     {
376         digest[28] =  (UCHAR)(context -> nx_sha256_states[7] >> 24);
377         digest[29] =  (UCHAR)(context -> nx_sha256_states[7] >> 16);
378         digest[30] =  (UCHAR)(context -> nx_sha256_states[7] >> 8);
379         digest[31] =  (UCHAR)(context -> nx_sha256_states[7]);
380     }
381 
382 #ifdef NX_SECURE_KEY_CLEAR
383     NX_CRYPTO_MEMSET(bit_count_string, 0, sizeof(bit_count_string));
384 #endif /* NX_SECURE_KEY_CLEAR  */
385 
386     /* Return successful completion.  */
387     return(NX_CRYPTO_SUCCESS);
388 }
389 
390 
391 /**************************************************************************/
392 /*                                                                        */
393 /*  FUNCTION                                               RELEASE        */
394 /*                                                                        */
395 /*    _nx_crypto_sha256_process_buffer                    PORTABLE C      */
396 /*                                                           6.1.10       */
397 /*                                                                        */
398 /*  AUTHOR                                                                */
399 /*                                                                        */
400 /*    Timothy Stapko, Microsoft Corporation                               */
401 /*                                                                        */
402 /*  DESCRIPTION                                                           */
403 /*                                                                        */
404 /*    This function implements the SHA256 algorithm which works on        */
405 /*    64-byte (512-bit) blocks of data.                                   */
406 /*                                                                        */
407 /*  INPUT                                                                 */
408 /*                                                                        */
409 /*    context                               SHA256 context pointer        */
410 /*    buffer                                Pointer to 64-byte buffer     */
411 /*                                                                        */
412 /*  OUTPUT                                                                */
413 /*                                                                        */
414 /*    None                                                                */
415 /*                                                                        */
416 /*  CALLS                                                                 */
417 /*                                                                        */
418 /*    None                                                                */
419 /*                                                                        */
420 /*  CALLED BY                                                             */
421 /*                                                                        */
422 /*    _nx_crypto_sha256_update              Final update to the digest    */
423 /*                                            with padding and length     */
424 /*                                                                        */
425 /*  RELEASE HISTORY                                                       */
426 /*                                                                        */
427 /*    DATE              NAME                      DESCRIPTION             */
428 /*                                                                        */
429 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
430 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
431 /*                                            resulting in version 6.1    */
432 /*  01-31-2022     Timothy Stapko           Modified comment(s),          */
433 /*                                            improved performance,       */
434 /*                                            resulting in version 6.1.10 */
435 /*                                                                        */
436 /**************************************************************************/
_nx_crypto_sha256_process_buffer(NX_CRYPTO_SHA256 * context,UCHAR buffer[64])437 NX_CRYPTO_KEEP VOID _nx_crypto_sha256_process_buffer(NX_CRYPTO_SHA256 *context, UCHAR buffer[64])
438 {
439 ULONG *w;
440 UINT   t;
441 ULONG  temp1, temp2;
442 ULONG  a, b, c, d, e, f, g, h;
443 
444 
445     /* Setup pointers to the word array.  */
446     w =  context -> nx_sha256_word_array;
447 
448     /* Initialize the state variables.  */
449     a =  context -> nx_sha256_states[0];
450     b =  context -> nx_sha256_states[1];
451     c =  context -> nx_sha256_states[2];
452     d =  context -> nx_sha256_states[3];
453     e =  context -> nx_sha256_states[4];
454     f =  context -> nx_sha256_states[5];
455     g =  context -> nx_sha256_states[6];
456     h =  context -> nx_sha256_states[7];
457 
458     /* Now, perform Round operations.  */
459     for (t = 0; t < 16; t += 8)
460     {
461 
462         /* Setup each entry.  */
463         w[t] =  W0(t);
464         temp1 = h + LARGE_SIGMA_1(e) + CH_FUNC(e, f, g) + _sha2_round_constants[t] + w[t];
465         temp2 = LARGE_SIGMA_0(a) + MAJ_FUNC(a, b, c);
466         d = d + temp1;
467         h = temp1 + temp2;
468 
469         w[t + 1] =  W0(t + 1);
470         temp1 = g + LARGE_SIGMA_1(d) + CH_FUNC(d, e, f) + _sha2_round_constants[t + 1] + w[t + 1];
471         temp2 = LARGE_SIGMA_0(h) + MAJ_FUNC(h, a, b);
472         c = c + temp1;
473         g = temp1 + temp2;
474 
475         w[t + 2] =  W0(t + 2);
476         temp1 = f + LARGE_SIGMA_1(c) + CH_FUNC(c, d, e) + _sha2_round_constants[t + 2] + w[t + 2];
477         temp2 = LARGE_SIGMA_0(g) + MAJ_FUNC(g, h, a);
478         b = b + temp1;
479         f = temp1 + temp2;
480 
481         w[t + 3] =  W0(t + 3);
482         temp1 = e + LARGE_SIGMA_1(b) + CH_FUNC(b, c, d) + _sha2_round_constants[t + 3] + w[t + 3];
483         temp2 = LARGE_SIGMA_0(f) + MAJ_FUNC(f, g, h);
484         a = a + temp1;
485         e = temp1 + temp2;
486 
487         w[t + 4] =  W0(t + 4);
488         temp1 = d + LARGE_SIGMA_1(a) + CH_FUNC(a, b, c) + _sha2_round_constants[t + 4] + w[t + 4];
489         temp2 = LARGE_SIGMA_0(e) + MAJ_FUNC(e, f, g);
490         h = h + temp1;
491         d = temp1 + temp2;
492 
493 
494         w[t + 5] =  W0(t + 5);
495         temp1 = c + LARGE_SIGMA_1(h) + CH_FUNC(h, a, b) + _sha2_round_constants[t + 5] + w[t + 5];
496         temp2 = LARGE_SIGMA_0(d) + MAJ_FUNC(d, e, f);
497         g = g + temp1;
498         c = temp1 + temp2;
499 
500         w[t + 6] =  W0(t + 6);
501         temp1 = b + LARGE_SIGMA_1(g) + CH_FUNC(g, h, a) + _sha2_round_constants[t + 6] + w[t + 6];
502         temp2 = LARGE_SIGMA_0(c) + MAJ_FUNC(c, d, e);
503         f = f + temp1;
504         b = temp1 + temp2;
505 
506         w[t + 7] =  W0(t + 7);
507         temp1 = a + LARGE_SIGMA_1(f) + CH_FUNC(f, g, h) + _sha2_round_constants[t + 7] + w[t + 7];
508         temp2 = LARGE_SIGMA_0(b) + MAJ_FUNC(b, c, d);
509         e = e + temp1;
510         a = temp1 + temp2;
511     }
512 
513     for (; t < 64; t += 8)
514     {
515 
516         /* Setup each entry.  */
517         w[t] =  W16(t);
518         temp1 = h + LARGE_SIGMA_1(e) + CH_FUNC(e, f, g) + _sha2_round_constants[t] + w[t];
519         temp2 = LARGE_SIGMA_0(a) + MAJ_FUNC(a, b, c);
520         d = d + temp1;
521         h = temp1 + temp2;
522 
523         w[t + 1] =  W16(t + 1);
524         temp1 = g + LARGE_SIGMA_1(d) + CH_FUNC(d, e, f) + _sha2_round_constants[t + 1] + w[t + 1];
525         temp2 = LARGE_SIGMA_0(h) + MAJ_FUNC(h, a, b);
526         c = c + temp1;
527         g = temp1 + temp2;
528 
529         w[t + 2] =  W16(t + 2);
530         temp1 = f + LARGE_SIGMA_1(c) + CH_FUNC(c, d, e) + _sha2_round_constants[t + 2] + w[t + 2];
531         temp2 = LARGE_SIGMA_0(g) + MAJ_FUNC(g, h, a);
532         b = b + temp1;
533         f = temp1 + temp2;
534 
535         w[t + 3] =  W16(t + 3);
536         temp1 = e + LARGE_SIGMA_1(b) + CH_FUNC(b, c, d) + _sha2_round_constants[t + 3] + w[t + 3];
537         temp2 = LARGE_SIGMA_0(f) + MAJ_FUNC(f, g, h);
538         a = a + temp1;
539         e = temp1 + temp2;
540 
541         w[t + 4] =  W16(t + 4);
542         temp1 = d + LARGE_SIGMA_1(a) + CH_FUNC(a, b, c) + _sha2_round_constants[t + 4] + w[t + 4];
543         temp2 = LARGE_SIGMA_0(e) + MAJ_FUNC(e, f, g);
544         h = h + temp1;
545         d = temp1 + temp2;
546 
547 
548         w[t + 5] =  W16(t + 5);
549         temp1 = c + LARGE_SIGMA_1(h) + CH_FUNC(h, a, b) + _sha2_round_constants[t + 5] + w[t + 5];
550         temp2 = LARGE_SIGMA_0(d) + MAJ_FUNC(d, e, f);
551         g = g + temp1;
552         c = temp1 + temp2;
553 
554         w[t + 6] =  W16(t + 6);
555         temp1 = b + LARGE_SIGMA_1(g) + CH_FUNC(g, h, a) + _sha2_round_constants[t + 6] + w[t + 6];
556         temp2 = LARGE_SIGMA_0(c) + MAJ_FUNC(c, d, e);
557         f = f + temp1;
558         b = temp1 + temp2;
559 
560         w[t + 7] =  W16(t + 7);
561         temp1 = a + LARGE_SIGMA_1(f) + CH_FUNC(f, g, h) + _sha2_round_constants[t + 7] + w[t + 7];
562         temp2 = LARGE_SIGMA_0(b) + MAJ_FUNC(b, c, d);
563         e = e + temp1;
564         a = temp1 + temp2;
565 
566     }
567 
568     /* Save the resulting in this SHA256 context.  */
569     context -> nx_sha256_states[0] +=  a;
570     context -> nx_sha256_states[1] +=  b;
571     context -> nx_sha256_states[2] +=  c;
572     context -> nx_sha256_states[3] +=  d;
573     context -> nx_sha256_states[4] +=  e;
574     context -> nx_sha256_states[5] +=  f;
575     context -> nx_sha256_states[6] +=  g;
576     context -> nx_sha256_states[7] +=  h;
577 
578 #ifdef NX_SECURE_KEY_CLEAR
579     a = 0; b = 0; c = 0; d = 0;
580     e = 0; f = 0; g = 0; h = 0;
581     temp1 = 0; temp2 = 0;
582 #endif /* NX_SECURE_KEY_CLEAR  */
583 }
584 
585 
586 /**************************************************************************/
587 /*                                                                        */
588 /*  FUNCTION                                               RELEASE        */
589 /*                                                                        */
590 /*    _nx_crypto_method_sha256_init                       PORTABLE C      */
591 /*                                                           6.3.0        */
592 /*  AUTHOR                                                                */
593 /*                                                                        */
594 /*    Timothy Stapko, Microsoft Corporation                               */
595 /*                                                                        */
596 /*  DESCRIPTION                                                           */
597 /*                                                                        */
598 /*    This function is the common crypto method init callback for         */
599 /*    Microsoft supported SHA256 cryptographic algorithm.                 */
600 /*                                                                        */
601 /*  INPUT                                                                 */
602 /*                                                                        */
603 /*    method                                Pointer to crypto method      */
604 /*    key                                   Pointer to key                */
605 /*    key_size_in_bits                      Length of key size in bits    */
606 /*    handler                               Returned crypto handler       */
607 /*    crypto_metadata                       Metadata area                 */
608 /*    crypto_metadata_size                  Size of the metadata area     */
609 /*                                                                        */
610 /*  OUTPUT                                                                */
611 /*                                                                        */
612 /*    status                                Completion status             */
613 /*                                                                        */
614 /*  CALLS                                                                 */
615 /*                                                                        */
616 /*    None                                                                */
617 /*                                                                        */
618 /*  CALLED BY                                                             */
619 /*                                                                        */
620 /*    Application Code                                                    */
621 /*                                                                        */
622 /*  RELEASE HISTORY                                                       */
623 /*                                                                        */
624 /*    DATE              NAME                      DESCRIPTION             */
625 /*                                                                        */
626 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
627 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
628 /*                                            resulting in version 6.1    */
629 /*  10-31-2023     Yanwu Cai                Modified comment(s),          */
630 /*                                            resulting in version 6.3.0  */
631 /*                                                                        */
632 /**************************************************************************/
_nx_crypto_method_sha256_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)633 NX_CRYPTO_KEEP UINT  _nx_crypto_method_sha256_init(struct  NX_CRYPTO_METHOD_STRUCT *method,
634                                                    UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits,
635                                                    VOID  **handle,
636                                                    VOID  *crypto_metadata,
637                                                    ULONG crypto_metadata_size)
638 {
639 
640     NX_CRYPTO_PARAMETER_NOT_USED(key);
641     NX_CRYPTO_PARAMETER_NOT_USED(key_size_in_bits);
642     NX_CRYPTO_PARAMETER_NOT_USED(handle);
643 
644     NX_CRYPTO_STATE_CHECK
645 
646     if ((method == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL))
647     {
648         return(NX_CRYPTO_PTR_ERROR);
649     }
650 
651     /* Verify the metadata address is 4-byte aligned. */
652     if((((ULONG)crypto_metadata) & 0x3) != 0)
653     {
654         return(NX_CRYPTO_PTR_ERROR);
655     }
656 
657     if(crypto_metadata_size < sizeof(NX_CRYPTO_SHA256))
658     {
659         return(NX_CRYPTO_PTR_ERROR);
660     }
661 
662     return(NX_CRYPTO_SUCCESS);
663 }
664 
665 
666 /**************************************************************************/
667 /*                                                                        */
668 /*  FUNCTION                                               RELEASE        */
669 /*                                                                        */
670 /*    _nx_crypto_method_sha256_cleanup                    PORTABLE C      */
671 /*                                                           6.1          */
672 /*  AUTHOR                                                                */
673 /*                                                                        */
674 /*    Timothy Stapko, Microsoft Corporation                               */
675 /*                                                                        */
676 /*  DESCRIPTION                                                           */
677 /*                                                                        */
678 /*    This function cleans up the crypto metadata.                        */
679 /*                                                                        */
680 /*  INPUT                                                                 */
681 /*                                                                        */
682 /*    crypto_metadata                       Crypto metadata               */
683 /*                                                                        */
684 /*  OUTPUT                                                                */
685 /*                                                                        */
686 /*    status                                Completion status             */
687 /*                                                                        */
688 /*  CALLS                                                                 */
689 /*                                                                        */
690 /*    NX_CRYPTO_MEMSET                      Set the memory                */
691 /*                                                                        */
692 /*  CALLED BY                                                             */
693 /*                                                                        */
694 /*    Application Code                                                    */
695 /*                                                                        */
696 /*  RELEASE HISTORY                                                       */
697 /*                                                                        */
698 /*    DATE              NAME                      DESCRIPTION             */
699 /*                                                                        */
700 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
701 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
702 /*                                            resulting in version 6.1    */
703 /*                                                                        */
704 /**************************************************************************/
_nx_crypto_method_sha256_cleanup(VOID * crypto_metadata)705 NX_CRYPTO_KEEP UINT  _nx_crypto_method_sha256_cleanup(VOID *crypto_metadata)
706 {
707 
708     NX_CRYPTO_STATE_CHECK
709 
710 #ifdef NX_SECURE_KEY_CLEAR
711     if (!crypto_metadata)
712         return (NX_CRYPTO_SUCCESS);
713 
714     /* Clean up the crypto metadata.  */
715     NX_CRYPTO_MEMSET(crypto_metadata, 0, sizeof(NX_CRYPTO_SHA256));
716 #else
717     NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata);
718 #endif/* NX_SECURE_KEY_CLEAR  */
719 
720     return(NX_CRYPTO_SUCCESS);
721 }
722 
723 
724 /**************************************************************************/
725 /*                                                                        */
726 /*  FUNCTION                                               RELEASE        */
727 /*                                                                        */
728 /*    _nx_crypto_method_sha256_operation                 PORTABLE C       */
729 /*                                                           6.3.0        */
730 /*  AUTHOR                                                                */
731 /*                                                                        */
732 /*    Timothy Stapko, Microsoft Corporation                               */
733 /*                                                                        */
734 /*  DESCRIPTION                                                           */
735 /*                                                                        */
736 /*    This function encrypts and decrypts a message using                 */
737 /*    the SHA256 algorithm.                                               */
738 /*                                                                        */
739 /*  INPUT                                                                 */
740 /*                                                                        */
741 /*    op                                    SHA256 operation              */
742 /*    handle                                Crypto handle                 */
743 /*    method                                Cryption Method Object        */
744 /*    key                                   Encryption Key                */
745 /*    key_size_in_bits                      Key size in bits              */
746 /*    input                                 Input data                    */
747 /*    input_length_in_byte                  Input data size               */
748 /*    iv_ptr                                Initial vector                */
749 /*    output                                Output buffer                 */
750 /*    output_length_in_byte                 Output buffer size            */
751 /*    crypto_metadata                       Metadata area                 */
752 /*    crypto_metadata_size                  Metadata area size            */
753 /*    packet_ptr                            Pointer to packet             */
754 /*    nx_crypto_hw_process_callback         Callback function pointer     */
755 /*                                                                        */
756 /*  OUTPUT                                                                */
757 /*                                                                        */
758 /*    status                                Completion status             */
759 /*                                                                        */
760 /*  CALLS                                                                 */
761 /*                                                                        */
762 /*    _nx_crypto_sha256_initialize          Initialize the SHA256 context */
763 /*    _nx_crypto_sha256_update              Update the digest with padding*/
764 /*                                            and length of digest        */
765 /*    _nx_crypto_sha256_digest_calculate    Calculate the SHA256 digest   */
766 /*                                                                        */
767 /*  CALLED BY                                                             */
768 /*                                                                        */
769 /*    Application Code                                                    */
770 /*                                                                        */
771 /*  RELEASE HISTORY                                                       */
772 /*                                                                        */
773 /*    DATE              NAME                      DESCRIPTION             */
774 /*                                                                        */
775 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
776 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
777 /*                                            resulting in version 6.1    */
778 /*  10-31-2023     Yanwu Cai                Modified comment(s),          */
779 /*                                            resulting in version 6.3.0  */
780 /*                                                                        */
781 /**************************************************************************/
_nx_crypto_method_sha256_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))782 NX_CRYPTO_KEEP UINT  _nx_crypto_method_sha256_operation(UINT op,      /* Encrypt, Decrypt, Authenticate */
783                                                         VOID *handle, /* Crypto handler */
784                                                         struct NX_CRYPTO_METHOD_STRUCT *method,
785                                                         UCHAR *key,
786                                                         NX_CRYPTO_KEY_SIZE key_size_in_bits,
787                                                         UCHAR *input,
788                                                         ULONG input_length_in_byte,
789                                                         UCHAR *iv_ptr,
790                                                         UCHAR *output,
791                                                         ULONG output_length_in_byte,
792                                                         VOID *crypto_metadata,
793                                                         ULONG crypto_metadata_size,
794                                                         VOID *packet_ptr,
795                                                         VOID (*nx_crypto_hw_process_callback)(VOID *packet_ptr, UINT status))
796 {
797 NX_CRYPTO_SHA256 *ctx;
798 
799     NX_CRYPTO_PARAMETER_NOT_USED(handle);
800     NX_CRYPTO_PARAMETER_NOT_USED(key);
801     NX_CRYPTO_PARAMETER_NOT_USED(key_size_in_bits);
802     NX_CRYPTO_PARAMETER_NOT_USED(iv_ptr);
803     NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
804     NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
805 
806     NX_CRYPTO_STATE_CHECK
807 
808     if (method == NX_CRYPTO_NULL)
809     {
810         return(NX_CRYPTO_PTR_ERROR);
811     }
812 
813     /* Verify the metadata address is 4-byte aligned. */
814     if((crypto_metadata == NX_CRYPTO_NULL) || ((((ULONG)crypto_metadata) & 0x3) != 0))
815     {
816         return(NX_CRYPTO_PTR_ERROR);
817     }
818 
819     if(crypto_metadata_size < sizeof(NX_CRYPTO_SHA256))
820     {
821         return(NX_CRYPTO_PTR_ERROR);
822     }
823 
824     ctx = (NX_CRYPTO_SHA256 *)crypto_metadata;
825 
826     if ((method -> nx_crypto_algorithm != NX_CRYPTO_AUTHENTICATION_HMAC_SHA2_256) &&
827         (method -> nx_crypto_algorithm != NX_CRYPTO_HASH_SHA224) &&
828         (method -> nx_crypto_algorithm != NX_CRYPTO_HASH_SHA256))
829     {
830         /* Incorrect method. */
831         return(NX_CRYPTO_NOT_SUCCESSFUL);
832     }
833 
834     switch (op)
835     {
836     case NX_CRYPTO_HASH_INITIALIZE:
837         _nx_crypto_sha256_initialize((NX_CRYPTO_SHA256 *)crypto_metadata, method -> nx_crypto_algorithm);
838         break;
839 
840     case NX_CRYPTO_HASH_UPDATE:
841         _nx_crypto_sha256_update((NX_CRYPTO_SHA256 *)crypto_metadata, input, input_length_in_byte);
842         break;
843 
844     case NX_CRYPTO_HASH_CALCULATE:
845         if ((method -> nx_crypto_algorithm == NX_CRYPTO_AUTHENTICATION_HMAC_SHA2_256) ||
846             (method -> nx_crypto_algorithm == NX_CRYPTO_HASH_SHA256))
847         {
848             if(output_length_in_byte < 32)
849                 return(NX_CRYPTO_INVALID_BUFFER_SIZE);
850         }
851         else if(output_length_in_byte < 28)
852             return(NX_CRYPTO_INVALID_BUFFER_SIZE);
853         _nx_crypto_sha256_digest_calculate((NX_CRYPTO_SHA256 *)crypto_metadata, output,
854                                            method -> nx_crypto_algorithm);
855         break;
856 
857     default:
858         if ((method -> nx_crypto_algorithm == NX_CRYPTO_AUTHENTICATION_HMAC_SHA2_256) ||
859             (method -> nx_crypto_algorithm == NX_CRYPTO_HASH_SHA256))
860         {
861             if(output_length_in_byte < 32)
862                 return(NX_CRYPTO_INVALID_BUFFER_SIZE);
863         }
864         else if(output_length_in_byte < 28)
865             return(NX_CRYPTO_INVALID_BUFFER_SIZE);
866 
867         _nx_crypto_sha256_initialize(ctx, method -> nx_crypto_algorithm);
868         _nx_crypto_sha256_update(ctx, input, input_length_in_byte);
869         _nx_crypto_sha256_digest_calculate(ctx, output, method -> nx_crypto_algorithm);
870         break;
871     }
872 
873     return NX_CRYPTO_SUCCESS;
874 }
875 
876