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 /**   ECJPAKE                                                             */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 #include "nx_crypto_ecjpake.h"
24 #include "nx_crypto_huge_number.h"
25 
26 /**************************************************************************/
27 /*                                                                        */
28 /*  FUNCTION                                               RELEASE        */
29 /*                                                                        */
30 /*    _nx_crypto_ecjpake_init                             PORTABLE C      */
31 /*                                                           6.1.7        */
32 /*  AUTHOR                                                                */
33 /*                                                                        */
34 /*    Timothy Stapko, Microsoft Corporation                               */
35 /*                                                                        */
36 /*  DESCRIPTION                                                           */
37 /*                                                                        */
38 /*    This function initializes the ECJPAKE context.                      */
39 /*                                                                        */
40 /*  INPUT                                                                 */
41 /*                                                                        */
42 /*    ecjpake                               Pointer to ECJPAKE context    */
43 /*    curve                                 Pointer to curve              */
44 /*    hash_method                           Hash method used by ECJPAKE   */
45 /*    hash_metadata                         Metadata of hash method       */
46 /*    hash_metadata_size                    Size of metadata              */
47 /*    scratch_pptr                          Pointer to scratch buffer     */
48 /*                                                                        */
49 /*  OUTPUT                                                                */
50 /*                                                                        */
51 /*    None                                                                */
52 /*                                                                        */
53 /*  CALLS                                                                 */
54 /*                                                                        */
55 /*    NX_CRYPTO_EC_POINT_INITIALIZE         Initialize EC point           */
56 /*    NX_CRYPTO_HUGE_NUMBER_INITIALIZE      Initialize the buffer of      */
57 /*                                            huge number                 */
58 /*                                                                        */
59 /*  CALLED BY                                                             */
60 /*                                                                        */
61 /*    _nx_crypto_method_ecjpake_operation   Initialize ECJPAKE crypto     */
62 /*                                                                        */
63 /*  RELEASE HISTORY                                                       */
64 /*                                                                        */
65 /*    DATE              NAME                      DESCRIPTION             */
66 /*                                                                        */
67 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
68 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
69 /*                                            resulting in version 6.1    */
70 /*                                                                        */
71 /**************************************************************************/
_nx_crypto_ecjpake_init(NX_CRYPTO_ECJPAKE * ecjpake,NX_CRYPTO_EC * curve,NX_CRYPTO_METHOD * hash_method,VOID * hash_metadata,ULONG hash_metadata_size,HN_UBASE ** scratch_pptr)72 NX_CRYPTO_KEEP VOID _nx_crypto_ecjpake_init(NX_CRYPTO_ECJPAKE *ecjpake,
73                                             NX_CRYPTO_EC *curve,
74                                             NX_CRYPTO_METHOD *hash_method,
75                                             VOID *hash_metadata,
76                                             ULONG hash_metadata_size,
77                                             HN_UBASE **scratch_pptr)
78 {
79 HN_UBASE *scratch_ptr = *scratch_pptr;
80 UINT      buffer_size = curve -> nx_crypto_ec_n.nx_crypto_huge_buffer_size;
81 
82     ecjpake -> nx_crypto_ecjpake_curve = curve;
83     ecjpake -> nx_crypto_ecjpake_hash_method = hash_method;
84     ecjpake -> nx_crypto_ecjpake_hash_metadata_size = hash_metadata_size;
85     if (hash_metadata == NX_CRYPTO_NULL)
86     {
87         ecjpake -> nx_crypto_ecjpake_hash_metadata = scratch_ptr;
88         scratch_ptr += hash_metadata_size >> HN_SIZE_SHIFT;
89     }
90     else
91     {
92         ecjpake -> nx_crypto_ecjpake_hash_metadata = hash_metadata;
93     }
94 
95     NX_CRYPTO_EC_POINT_INITIALIZE(&ecjpake -> nx_crypto_ecjpake_public_x1,
96                                   NX_CRYPTO_EC_POINT_AFFINE, scratch_ptr, buffer_size);
97     NX_CRYPTO_EC_POINT_INITIALIZE(&ecjpake -> nx_crypto_ecjpake_public_x2,
98                                   NX_CRYPTO_EC_POINT_AFFINE, scratch_ptr, buffer_size);
99     NX_CRYPTO_EC_POINT_INITIALIZE(&ecjpake -> nx_crypto_ecjpake_public_x3,
100                                   NX_CRYPTO_EC_POINT_AFFINE, scratch_ptr, buffer_size);
101     NX_CRYPTO_EC_POINT_INITIALIZE(&ecjpake -> nx_crypto_ecjpake_public_x4,
102                                   NX_CRYPTO_EC_POINT_AFFINE, scratch_ptr, buffer_size);
103 
104     NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&ecjpake -> nx_crypto_ecjpake_private_x2, scratch_ptr, buffer_size);
105 
106     *scratch_pptr = scratch_ptr;
107 }
108 
109 /**************************************************************************/
110 /*                                                                        */
111 /*  FUNCTION                                               RELEASE        */
112 /*                                                                        */
113 /*    _nx_crypto_ecjpake_hello_generate                   PORTABLE C      */
114 /*                                                           6.1          */
115 /*  AUTHOR                                                                */
116 /*                                                                        */
117 /*    Timothy Stapko, Microsoft Corporation                               */
118 /*                                                                        */
119 /*  DESCRIPTION                                                           */
120 /*                                                                        */
121 /*    This function generates the message for TLS hello.                  */
122 /*                                                                        */
123 /*  INPUT                                                                 */
124 /*                                                                        */
125 /*    ecjpake                               Pointer to ECJPAKE context    */
126 /*    id                                    Client or Server              */
127 /*    id_len                                Length of ID                  */
128 /*    output                                Output buffer                 */
129 /*    output_length                         Length of output buffer       */
130 /*    actual_size                           Actual size of output         */
131 /*    scratch                               Pointer to scratch            */
132 /*                                                                        */
133 /*  OUTPUT                                                                */
134 /*                                                                        */
135 /*    Status                                Completion status             */
136 /*                                                                        */
137 /*  CALLS                                                                 */
138 /*                                                                        */
139 /*    NX_CRYPTO_EC_POINT_INITIALIZE         Initialize EC point           */
140 /*    NX_CRYPTO_HUGE_NUMBER_INITIALIZE      Initialize the buffer of      */
141 /*                                            huge number                 */
142 /*    _nx_crypto_ec_point_extract_uncompressed                            */
143 /*                                          Extract point to byte stream  */
144 /*                                            in uncompressed format      */
145 /*    _nx_crypto_ecjpake_schnorr_zkp_generate                             */
146 /*                                          Perform Schnorr ZKP generation*/
147 /*    _nx_crypto_huge_number_extract_fixed_size                           */
148 /*                                          Extract huge number           */
149 /*    _nx_crypto_ec_key_pair_generation_extra                             */
150 /*                                          Generate EC Key Pair          */
151 /*                                                                        */
152 /*  CALLED BY                                                             */
153 /*                                                                        */
154 /*    _nx_crypto_method_ecjpake_operation   Initialize ECJPAKE crypto     */
155 /*                                                                        */
156 /*  RELEASE HISTORY                                                       */
157 /*                                                                        */
158 /*    DATE              NAME                      DESCRIPTION             */
159 /*                                                                        */
160 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
161 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
162 /*                                            resulting in version 6.1    */
163 /*                                                                        */
164 /**************************************************************************/
_nx_crypto_ecjpake_hello_generate(NX_CRYPTO_ECJPAKE * ecjpake,CHAR * id,UINT id_len,UCHAR * output,ULONG output_length,ULONG * actual_size,HN_UBASE * scratch)165 NX_CRYPTO_KEEP UINT _nx_crypto_ecjpake_hello_generate(NX_CRYPTO_ECJPAKE *ecjpake,
166                                                       CHAR *id, UINT id_len,
167                                                       UCHAR *output, ULONG output_length,
168                                                       ULONG *actual_size,
169                                                       HN_UBASE *scratch)
170 {
171 NX_CRYPTO_EC         *curve = ecjpake -> nx_crypto_ecjpake_curve;
172 UINT                  curve_size = (curve -> nx_crypto_ec_bits + 7) >> 3;
173 UINT                  buffer_size = curve -> nx_crypto_ec_n.nx_crypto_huge_buffer_size;
174 NX_CRYPTO_HUGE_NUMBER private_key, r;
175 NX_CRYPTO_EC_POINT    v;
176 UINT                  total_length = 0;
177 UINT                  length;
178 UINT                  status;
179 
180     NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&private_key, scratch, buffer_size);
181     NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&r, scratch, buffer_size);
182     NX_CRYPTO_EC_POINT_INITIALIZE(&v, NX_CRYPTO_EC_POINT_AFFINE, scratch, buffer_size);
183 
184     status = _nx_crypto_ec_key_pair_generation_extra(curve, &curve -> nx_crypto_ec_g, &private_key,
185                                             &ecjpake -> nx_crypto_ecjpake_public_x1, scratch);
186 
187     if(status != NX_CRYPTO_SUCCESS)
188     {
189         return(status);
190     }
191 
192     status = _nx_crypto_ecjpake_schnorr_zkp_generate(ecjpake -> nx_crypto_ecjpake_hash_method,
193                                             ecjpake -> nx_crypto_ecjpake_hash_metadata,
194                                             curve,
195                                             &curve -> nx_crypto_ec_g,
196                                             &v,
197                                             &ecjpake -> nx_crypto_ecjpake_public_x1,
198                                             id, id_len,
199                                             &private_key,
200                                             &r,
201                                             scratch);
202 
203     if(status != NX_CRYPTO_SUCCESS)
204     {
205         return(status);
206     }
207 
208     _nx_crypto_ec_point_extract_uncompressed(curve,
209                                              &ecjpake -> nx_crypto_ecjpake_public_x1,
210                                              &output[total_length + 1],
211                                              output_length - (total_length + 1),
212                                              &length);
213     output[total_length] = (UCHAR)length;
214     total_length += (length + 1);
215     _nx_crypto_ec_point_extract_uncompressed(curve,
216                                              &v,
217                                              &output[total_length + 1],
218                                              output_length - (total_length + 1),
219                                              &length);
220     output[total_length] = (UCHAR)length;
221     total_length += (length + 1);
222     length = curve_size;
223     status = _nx_crypto_huge_number_extract_fixed_size(&r,
224                                               &output[total_length + 1],
225                                               length);
226 
227     if (status != NX_CRYPTO_SUCCESS)
228     {
229         return(status);
230     }
231 
232     output[total_length] = (UCHAR)length;
233     total_length += (length + 1);
234 
235     status = _nx_crypto_ec_key_pair_generation_extra(curve, &curve -> nx_crypto_ec_g,
236                                             &ecjpake -> nx_crypto_ecjpake_private_x2,
237                                             &ecjpake -> nx_crypto_ecjpake_public_x2, scratch);
238 
239     if (status != NX_CRYPTO_SUCCESS)
240     {
241         return(status);
242     }
243 
244     status = _nx_crypto_ecjpake_schnorr_zkp_generate(ecjpake -> nx_crypto_ecjpake_hash_method,
245                                             ecjpake -> nx_crypto_ecjpake_hash_metadata,
246                                             curve,
247                                             &curve -> nx_crypto_ec_g,
248                                             &v,
249                                             &ecjpake -> nx_crypto_ecjpake_public_x2,
250                                             id, id_len,
251                                             &ecjpake -> nx_crypto_ecjpake_private_x2,
252                                             &r,
253                                             scratch);
254 
255     if(status != NX_CRYPTO_SUCCESS)
256     {
257         return(status);
258     }
259 
260     _nx_crypto_ec_point_extract_uncompressed(curve,
261                                              &ecjpake -> nx_crypto_ecjpake_public_x2,
262                                              &output[total_length + 1],
263                                              output_length - (total_length + 1),
264                                              &length);
265     output[total_length] = (UCHAR)length;
266     total_length += (length + 1);
267     _nx_crypto_ec_point_extract_uncompressed(curve,
268                                              &v,
269                                              &output[total_length + 1],
270                                              output_length - (total_length + 1),
271                                              &length);
272     output[total_length] = (UCHAR)length;
273     total_length += (length + 1);
274     length = curve_size;
275     status = _nx_crypto_huge_number_extract_fixed_size(&r,
276                                               &output[total_length + 1],
277                                               length);
278     output[total_length] = (UCHAR)length;
279 
280     *actual_size = total_length + length + 1;
281 
282     return(status);
283 }
284 
285 /**************************************************************************/
286 /*                                                                        */
287 /*  FUNCTION                                               RELEASE        */
288 /*                                                                        */
289 /*    _nx_crypto_ecjpake_hello_process                    PORTABLE C      */
290 /*                                                           6.1          */
291 /*  AUTHOR                                                                */
292 /*                                                                        */
293 /*    Timothy Stapko, Microsoft Corporation                               */
294 /*                                                                        */
295 /*  DESCRIPTION                                                           */
296 /*                                                                        */
297 /*    This function processes the message for TLS hello.                  */
298 /*                                                                        */
299 /*  INPUT                                                                 */
300 /*                                                                        */
301 /*    ecjpake                               Pointer to ECJPAKE context    */
302 /*    id                                    Client or Server              */
303 /*    id_len                                Length of ID                  */
304 /*    input                                 Input buffer                  */
305 /*    input_length                          Length of input buffer        */
306 /*    scratch                               Pointer to scratch            */
307 /*                                                                        */
308 /*  OUTPUT                                                                */
309 /*                                                                        */
310 /*    status                                Completion status             */
311 /*                                                                        */
312 /*  CALLS                                                                 */
313 /*                                                                        */
314 /*    NX_CRYPTO_EC_POINT_INITIALIZE         Initialize EC point           */
315 /*    NX_CRYPTO_HUGE_NUMBER_INITIALIZE      Initialize the buffer of      */
316 /*                                            huge number                 */
317 /*    _nx_crypto_ec_point_setup             Set up point from byte steam  */
318 /*    _nx_crypto_ecjpake_schnorr_zkp_verify Perform Schnorr ZKP           */
319 /*                                            verification                */
320 /*    _nx_crypto_huge_number_setup          Setup huge number             */
321 /*                                                                        */
322 /*  CALLED BY                                                             */
323 /*                                                                        */
324 /*    _nx_crypto_method_ecjpake_operation   Initialize ECJPAKE crypto     */
325 /*                                                                        */
326 /*  RELEASE HISTORY                                                       */
327 /*                                                                        */
328 /*    DATE              NAME                      DESCRIPTION             */
329 /*                                                                        */
330 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
331 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
332 /*                                            resulting in version 6.1    */
333 /*                                                                        */
334 /**************************************************************************/
_nx_crypto_ecjpake_hello_process(NX_CRYPTO_ECJPAKE * ecjpake,CHAR * id,UINT id_len,UCHAR * input,UINT input_length,HN_UBASE * scratch)335 NX_CRYPTO_KEEP UINT _nx_crypto_ecjpake_hello_process(NX_CRYPTO_ECJPAKE *ecjpake,
336                                                      CHAR *id, UINT id_len,
337                                                      UCHAR *input, UINT input_length,
338                                                      HN_UBASE *scratch)
339 {
340 NX_CRYPTO_EC         *curve = ecjpake -> nx_crypto_ecjpake_curve;
341 UINT                  buffer_size = curve -> nx_crypto_ec_n.nx_crypto_huge_buffer_size;
342 NX_CRYPTO_HUGE_NUMBER r;
343 NX_CRYPTO_EC_POINT    v;
344 UINT                  status;
345 UINT                  total_length = 0;
346 
347     NX_CRYPTO_PARAMETER_NOT_USED(input_length);
348 
349     NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&r, scratch, buffer_size);
350     NX_CRYPTO_EC_POINT_INITIALIZE(&v, NX_CRYPTO_EC_POINT_AFFINE, scratch, buffer_size);
351 
352     /* Setup X3. */
353     status = _nx_crypto_ec_point_setup(&ecjpake -> nx_crypto_ecjpake_public_x3,
354                                        &input[total_length + 1],
355                                        (UINT)input[total_length]);
356     if (status)
357     {
358         return(status);
359     }
360 
361     total_length += (UINT)(input[total_length] + 1);
362 
363     /* Setup r and v. */
364     status = _nx_crypto_ec_point_setup(&v, &input[total_length + 1], (UINT)input[total_length]);
365     if (status)
366     {
367         return(status);
368     }
369 
370     total_length += (UINT)(input[total_length] + 1);
371     status = _nx_crypto_huge_number_setup(&r, &input[total_length + 1], (UINT)input[total_length]);
372     if (status)
373     {
374         return(status);
375     }
376 
377     total_length += (UINT)(input[total_length] + 1);
378 
379     status = _nx_crypto_ecjpake_schnorr_zkp_verify(ecjpake -> nx_crypto_ecjpake_hash_method,
380                                                    ecjpake -> nx_crypto_ecjpake_hash_metadata,
381                                                    curve,
382                                                    &curve -> nx_crypto_ec_g,
383                                                    &v,
384                                                    &ecjpake -> nx_crypto_ecjpake_public_x3,
385                                                    id, id_len,
386                                                    &r,
387                                                    scratch);
388     if (status)
389     {
390         return(status);
391     }
392 
393     /* Setup X4. */
394     status = _nx_crypto_ec_point_setup(&ecjpake -> nx_crypto_ecjpake_public_x4,
395                                        &input[total_length + 1],
396                                        (UINT)input[total_length]);
397     if (status)
398     {
399         return(status);
400     }
401 
402     total_length += (UINT)(input[total_length] + 1);
403 
404     /* Setup r and v. */
405     status = _nx_crypto_ec_point_setup(&v, &input[total_length + 1], (UINT)input[total_length]);
406     if (status)
407     {
408         return(status);
409     }
410 
411     total_length += (UINT)(input[total_length] + 1);
412     status = _nx_crypto_huge_number_setup(&r, &input[total_length + 1], (UINT)input[total_length]);
413     if (status)
414     {
415         return(status);
416     }
417 
418     status = _nx_crypto_ecjpake_schnorr_zkp_verify(ecjpake -> nx_crypto_ecjpake_hash_method,
419                                                    ecjpake -> nx_crypto_ecjpake_hash_metadata,
420                                                    curve,
421                                                    &curve -> nx_crypto_ec_g,
422                                                    &v,
423                                                    &ecjpake -> nx_crypto_ecjpake_public_x4,
424                                                    id, id_len,
425                                                    &r,
426                                                    scratch);
427 
428     return(status);
429 }
430 
431 /**************************************************************************/
432 /*                                                                        */
433 /*  FUNCTION                                               RELEASE        */
434 /*                                                                        */
435 /*    _nx_crypto_ecjpake_key_exchange_generate            PORTABLE C      */
436 /*                                                           6.1          */
437 /*  AUTHOR                                                                */
438 /*                                                                        */
439 /*    Timothy Stapko, Microsoft Corporation                               */
440 /*                                                                        */
441 /*  DESCRIPTION                                                           */
442 /*                                                                        */
443 /*    This function generates the message for TLS key exchange.           */
444 /*                                                                        */
445 /*  INPUT                                                                 */
446 /*                                                                        */
447 /*    ecjpake                               Pointer to ECJPAKE context    */
448 /*    shared_secret                         Pointer to shared secret      */
449 /*    shared_secret_len                     Length of shared secret       */
450 /*    id                                    Client or Server              */
451 /*    id_len                                Length of ID                  */
452 /*    output                                Output buffer                 */
453 /*    output_length                         Length of output buffer       */
454 /*    actual_size                           Actual size of output         */
455 /*    scratch                               Pointer to scratch            */
456 /*                                                                        */
457 /*  OUTPUT                                                                */
458 /*                                                                        */
459 /*    status                                Completion status             */
460 /*                                                                        */
461 /*  CALLS                                                                 */
462 /*                                                                        */
463 /*    NX_CRYPTO_EC_POINT_INITIALIZE         Initialize EC point           */
464 /*    NX_CRYPTO_HUGE_NUMBER_INITIALIZE      Initialize the buffer of      */
465 /*                                            huge number                 */
466 /*    _nx_crypto_ec_point_extract_uncompressed                            */
467 /*                                          Extract point to byte stream  */
468 /*                                            in uncompressed format      */
469 /*    _nx_crypto_ecjpake_public_key_generate                              */
470 /*                                          Perform public key generation */
471 /*    _nx_crypto_ecjpake_schnorr_zkp_generate                             */
472 /*                                          Perform Schnorr ZKP generation*/
473 /*    _nx_crypto_huge_number_extract_fixed_size                           */
474 /*                                          Extract huge number           */
475 /*    _nx_crypto_huge_number_modulus        Perform a modulus operation   */
476 /*    _nx_crypto_huge_number_setup          Setup huge number             */
477 /*                                                                        */
478 /*  CALLED BY                                                             */
479 /*                                                                        */
480 /*    _nx_crypto_method_ecjpake_operation   Initialize ECJPAKE crypto     */
481 /*                                                                        */
482 /*  RELEASE HISTORY                                                       */
483 /*                                                                        */
484 /*    DATE              NAME                      DESCRIPTION             */
485 /*                                                                        */
486 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
487 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
488 /*                                            resulting in version 6.1    */
489 /*                                                                        */
490 /**************************************************************************/
_nx_crypto_ecjpake_key_exchange_generate(NX_CRYPTO_ECJPAKE * ecjpake,UCHAR * shared_secret,UINT shared_secret_len,CHAR * id,UINT id_len,UCHAR * output,ULONG output_length,ULONG * actual_size,HN_UBASE * scratch)491 NX_CRYPTO_KEEP UINT _nx_crypto_ecjpake_key_exchange_generate(NX_CRYPTO_ECJPAKE *ecjpake,
492                                                              UCHAR *shared_secret,
493                                                              UINT shared_secret_len,
494                                                              CHAR *id, UINT id_len,
495                                                              UCHAR *output, ULONG output_length,
496                                                              ULONG *actual_size,
497                                                              HN_UBASE *scratch)
498 {
499 NX_CRYPTO_EC         *curve = ecjpake -> nx_crypto_ecjpake_curve;
500 UINT                  curve_size = (curve -> nx_crypto_ec_bits + 7) >> 3;
501 UINT                  buffer_size = curve -> nx_crypto_ec_n.nx_crypto_huge_buffer_size;
502 NX_CRYPTO_HUGE_NUMBER private_key, r, s;
503 NX_CRYPTO_EC_POINT    ga;
504 NX_CRYPTO_EC_POINT    public_key, v;
505 UINT                  total_length = 0;
506 UINT                  length;
507 UINT                  status;
508 
509     NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&private_key, scratch, buffer_size);
510     NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&r, scratch, buffer_size);
511     NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&s, scratch,
512                                      (shared_secret_len + 3) & (ULONG) ~3);
513     NX_CRYPTO_EC_POINT_INITIALIZE(&ga, NX_CRYPTO_EC_POINT_AFFINE, scratch, buffer_size);
514     NX_CRYPTO_EC_POINT_INITIALIZE(&public_key, NX_CRYPTO_EC_POINT_AFFINE, scratch, buffer_size);
515     NX_CRYPTO_EC_POINT_INITIALIZE(&v, NX_CRYPTO_EC_POINT_AFFINE, scratch, buffer_size);
516 
517     _nx_crypto_huge_number_setup(&s, shared_secret, shared_secret_len);
518     _nx_crypto_huge_number_modulus(&s, &curve -> nx_crypto_ec_n);
519 
520     _nx_crypto_ecjpake_public_key_generate(curve,
521                                            &ecjpake -> nx_crypto_ecjpake_public_x1,
522                                            &ecjpake -> nx_crypto_ecjpake_public_x3,
523                                            &ecjpake -> nx_crypto_ecjpake_public_x4,
524                                            &ecjpake -> nx_crypto_ecjpake_private_x2,
525                                            &s,
526                                            &ga,
527                                            &public_key,
528                                            &private_key,
529                                            scratch);
530 
531     status = _nx_crypto_ecjpake_schnorr_zkp_generate(ecjpake -> nx_crypto_ecjpake_hash_method,
532                                             ecjpake -> nx_crypto_ecjpake_hash_metadata,
533                                             curve,
534                                             &ga,
535                                             &v,
536                                             &public_key,
537                                             id, id_len,
538                                             &private_key,
539                                             &r,
540                                             scratch);
541 
542     if(status != NX_CRYPTO_SUCCESS)
543     {
544         return(status);
545     }
546 
547     _nx_crypto_ec_point_extract_uncompressed(curve,
548                                              &public_key,
549                                              &output[total_length + 1],
550                                              output_length - (total_length + 1),
551                                              &length);
552     output[total_length] = (UCHAR)length;
553     total_length += (length + 1);
554     _nx_crypto_ec_point_extract_uncompressed(curve,
555                                              &v,
556                                              &output[total_length + 1],
557                                              output_length - (total_length + 1),
558                                              &length);
559     output[total_length] = (UCHAR)length;
560     total_length += (length + 1);
561     length = curve_size;
562     status = _nx_crypto_huge_number_extract_fixed_size(&r,
563                                                        &output[total_length + 1],
564                                                        length);
565     output[total_length] = (UCHAR)length;
566 
567     *actual_size = total_length + length + 1;
568 
569     return(status);
570 }
571 
572 /**************************************************************************/
573 /*                                                                        */
574 /*  FUNCTION                                               RELEASE        */
575 /*                                                                        */
576 /*    _nx_crypto_ecjpake_key_exchange_process             PORTABLE C      */
577 /*                                                           6.1          */
578 /*  AUTHOR                                                                */
579 /*                                                                        */
580 /*    Timothy Stapko, Microsoft Corporation                               */
581 /*                                                                        */
582 /*  DESCRIPTION                                                           */
583 /*                                                                        */
584 /*    This function processes the message for TLS key exchange.           */
585 /*                                                                        */
586 /*  INPUT                                                                 */
587 /*                                                                        */
588 /*    ecjpake                               Pointer to ECJPAKE context    */
589 /*    shared_secret                         Pointer to shared secret      */
590 /*    shared_secret_len                     Length of shared secret       */
591 /*    id                                    Client or Server              */
592 /*    id_len                                Length of ID                  */
593 /*    input                                 Input buffer                  */
594 /*    input_length                          Length of input buffer        */
595 /*    pms                                   Input buffer                  */
596 /*    scratch                               Pointer to scratch            */
597 /*                                                                        */
598 /*  OUTPUT                                                                */
599 /*                                                                        */
600 /*    status                                Completion status             */
601 /*                                                                        */
602 /*  CALLS                                                                 */
603 /*                                                                        */
604 /*    NX_CRYPTO_EC_POINT_INITIALIZE         Initialize EC point           */
605 /*    NX_CRYPTO_HUGE_NUMBER_COPY            Copy huge number              */
606 /*    NX_CRYPTO_HUGE_NUMBER_INITIALIZE      Initialize the buffer of      */
607 /*                                            huge number                 */
608 /*    _nx_crypto_ec_point_setup             Set up point from byte steam  */
609 /*    _nx_crypto_ecjpake_pre_master_secret_generate                       */
610 /*    _nx_crypto_ecjpake_schnorr_zkp_verify Perform Schnorr ZKP           */
611 /*                                            verification                */
612 /*    _nx_crypto_huge_number_modulus        Perform a modulus operation   */
613 /*    _nx_crypto_huge_number_setup          Setup huge number             */
614 /*    [nx_crypto_ec_add]                    Perform addtion for EC        */
615 /*                                                                        */
616 /*  CALLED BY                                                             */
617 /*                                                                        */
618 /*    _nx_crypto_method_ecjpake_operation   Initialize ECJPAKE crypto     */
619 /*                                                                        */
620 /*  RELEASE HISTORY                                                       */
621 /*                                                                        */
622 /*    DATE              NAME                      DESCRIPTION             */
623 /*                                                                        */
624 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
625 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
626 /*                                            resulting in version 6.1    */
627 /*                                                                        */
628 /**************************************************************************/
_nx_crypto_ecjpake_key_exchange_process(NX_CRYPTO_ECJPAKE * ecjpake,UCHAR * shared_secret,UINT shared_secret_len,CHAR * id,UINT id_len,UCHAR * input,UINT input_length,UCHAR * pms,HN_UBASE * scratch)629 NX_CRYPTO_KEEP UINT _nx_crypto_ecjpake_key_exchange_process(NX_CRYPTO_ECJPAKE *ecjpake,
630                                                             UCHAR *shared_secret,
631                                                             UINT shared_secret_len,
632                                                             CHAR *id, UINT id_len,
633                                                             UCHAR *input, UINT input_length,
634                                                             UCHAR *pms,
635                                                             HN_UBASE *scratch)
636 {
637 NX_CRYPTO_EC         *curve = ecjpake -> nx_crypto_ecjpake_curve;
638 UINT                  buffer_size = curve -> nx_crypto_ec_n.nx_crypto_huge_buffer_size;
639 NX_CRYPTO_HUGE_NUMBER r, s;
640 NX_CRYPTO_EC_POINT    ga;
641 NX_CRYPTO_EC_POINT    public_key, v;
642 UINT                  status;
643 UINT                  total_length = 0;
644 
645     NX_CRYPTO_PARAMETER_NOT_USED(input_length);
646 
647     NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&r, scratch, buffer_size);
648     NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&s, scratch,
649                                      (shared_secret_len + 3) & (ULONG) ~3);
650     NX_CRYPTO_EC_POINT_INITIALIZE(&ga, NX_CRYPTO_EC_POINT_AFFINE, scratch, buffer_size);
651     NX_CRYPTO_EC_POINT_INITIALIZE(&public_key, NX_CRYPTO_EC_POINT_AFFINE, scratch, buffer_size);
652     NX_CRYPTO_EC_POINT_INITIALIZE(&v, NX_CRYPTO_EC_POINT_AFFINE, scratch, buffer_size);
653 
654     status = _nx_crypto_huge_number_setup(&s, shared_secret, shared_secret_len);
655 
656     if(status != NX_CRYPTO_SUCCESS)
657     {
658         return(status);
659     }
660 
661     _nx_crypto_huge_number_modulus(&s, &curve -> nx_crypto_ec_n);
662 
663     /* G = X1 + X2 + X3 */
664     NX_CRYPTO_HUGE_NUMBER_COPY(&ga.nx_crypto_ec_point_x,
665                                &ecjpake -> nx_crypto_ecjpake_public_x1.nx_crypto_ec_point_x);
666     NX_CRYPTO_HUGE_NUMBER_COPY(&ga.nx_crypto_ec_point_y,
667                                &ecjpake -> nx_crypto_ecjpake_public_x1.nx_crypto_ec_point_y);
668     curve -> nx_crypto_ec_add(curve, &ga, &ecjpake -> nx_crypto_ecjpake_public_x2, scratch);
669     curve -> nx_crypto_ec_add(curve, &ga, &ecjpake -> nx_crypto_ecjpake_public_x3, scratch);
670 
671     /* Setup public_key. */
672     status = _nx_crypto_ec_point_setup(&public_key,
673                               &input[total_length + 1],
674                               (UINT)input[total_length]);
675 
676     if(status != NX_CRYPTO_SUCCESS)
677     {
678         return(status);
679     }
680 
681     total_length += (UINT)(input[total_length] + 1);
682 
683     /* Setup r and v. */
684     _nx_crypto_ec_point_setup(&v, &input[total_length + 1], (UINT)input[total_length]);
685     total_length += (UINT)(input[total_length] + 1);
686     status = _nx_crypto_huge_number_setup(&r, &input[total_length + 1], (UINT)input[total_length]);
687 
688     if(status != NX_CRYPTO_SUCCESS)
689     {
690         return(status);
691     }
692 
693 
694     status = _nx_crypto_ecjpake_schnorr_zkp_verify(ecjpake -> nx_crypto_ecjpake_hash_method,
695                                                    ecjpake -> nx_crypto_ecjpake_hash_metadata,
696                                                    curve,
697                                                    &ga,
698                                                    &v,
699                                                    &public_key,
700                                                    id, id_len,
701                                                    &r,
702                                                    scratch);
703     if (status)
704     {
705         return(status);
706     }
707 
708     status = _nx_crypto_ecjpake_pre_master_secret_generate(ecjpake -> nx_crypto_ecjpake_hash_method,
709                                                            ecjpake -> nx_crypto_ecjpake_hash_metadata,
710                                                            curve,
711                                                            &ecjpake -> nx_crypto_ecjpake_public_x4,
712                                                            &s,
713                                                            &public_key,
714                                                            &ecjpake -> nx_crypto_ecjpake_private_x2,
715                                                            pms,
716                                                            scratch);
717 
718     return(status);
719 }
720 
721 /**************************************************************************/
722 /*                                                                        */
723 /*  FUNCTION                                               RELEASE        */
724 /*                                                                        */
725 /*    _nx_crypto_ecjpake_schnorr_zkp_hash                 PORTABLE C      */
726 /*                                                           6.1          */
727 /*  AUTHOR                                                                */
728 /*                                                                        */
729 /*    Timothy Stapko, Microsoft Corporation                               */
730 /*                                                                        */
731 /*  DESCRIPTION                                                           */
732 /*                                                                        */
733 /*    This function performs Schnorr ZKP hash calculation.                */
734 /*                                                                        */
735 /*  INPUT                                                                 */
736 /*                                                                        */
737 /*    hash_method                           Hash method used by ECJPAKE   */
738 /*    hash_metadata                         Metadata of hash method       */
739 /*    curve                                 Pointer to curve              */
740 /*    g                                     Generator                     */
741 /*    v                                     ZKP ephemeral public key      */
742 /*    x                                     Public key to be verified     */
743 /*    h                                     Hash for output               */
744 /*    id                                    Client or Server              */
745 /*    id_len                                Length of ID                  */
746 /*    scratch                               Pointer to scratch            */
747 /*                                                                        */
748 /*  OUTPUT                                                                */
749 /*                                                                        */
750 /*    status                                Completion status             */
751 /*                                                                        */
752 /*  CALLS                                                                 */
753 /*                                                                        */
754 /*    _nx_crypto_ec_point_extract_uncompressed                            */
755 /*                                          Extract point to byte stream  */
756 /*                                            in uncompressed format      */
757 /*    _nx_crypto_huge_number_modulus        Perform a modulus operation   */
758 /*    _nx_crypto_huge_number_setup          Setup huge number             */
759 /*    [nx_crypto_operation]                 Crypto opeartion              */
760 /*                                                                        */
761 /*  CALLED BY                                                             */
762 /*                                                                        */
763 /*    _nx_crypto_ecjpake_schnorr_zkp_generate                             */
764 /*                                          Perform Schnorr ZKP generation*/
765 /*    _nx_crypto_ecjpake_schnorr_zkp_verify Perform Schnorr ZKP           */
766 /*                                            verification                */
767 /*                                                                        */
768 /*  RELEASE HISTORY                                                       */
769 /*                                                                        */
770 /*    DATE              NAME                      DESCRIPTION             */
771 /*                                                                        */
772 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
773 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
774 /*                                            resulting in version 6.1    */
775 /*                                                                        */
776 /**************************************************************************/
_nx_crypto_ecjpake_schnorr_zkp_hash(NX_CRYPTO_METHOD * hash_method,VOID * hash_metadata,NX_CRYPTO_EC * curve,NX_CRYPTO_EC_POINT * g,NX_CRYPTO_EC_POINT * v,NX_CRYPTO_EC_POINT * x,NX_CRYPTO_HUGE_NUMBER * h,CHAR * id,UINT id_len,HN_UBASE * scratch)777 NX_CRYPTO_KEEP UINT _nx_crypto_ecjpake_schnorr_zkp_hash(NX_CRYPTO_METHOD *hash_method,
778                                                         VOID *hash_metadata,
779                                                         NX_CRYPTO_EC *curve,
780                                                         NX_CRYPTO_EC_POINT *g,
781                                                         NX_CRYPTO_EC_POINT *v,
782                                                         NX_CRYPTO_EC_POINT *x,
783                                                         NX_CRYPTO_HUGE_NUMBER *h,
784                                                         CHAR *id,
785                                                         UINT id_len,
786                                                         HN_UBASE *scratch)
787 {
788 UINT size;
789 UINT status;
790 VOID *handler;
791 
792     if (hash_method -> nx_crypto_init)
793     {
794         status = hash_method -> nx_crypto_init(hash_method,
795                                       NX_CRYPTO_NULL,
796                                       0,
797                                       &handler,
798                                       hash_metadata,
799                                       hash_method -> nx_crypto_metadata_area_size);
800 
801         if(status != NX_CRYPTO_SUCCESS)
802         {
803             return(status);
804         }
805     }
806 
807     status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_INITIALIZE,
808                                        NX_CRYPTO_NULL,
809                                        hash_method,
810                                        NX_CRYPTO_NULL,
811                                        0,
812                                        NX_CRYPTO_NULL,
813                                        0,
814                                        NX_CRYPTO_NULL,
815                                        NX_CRYPTO_NULL,
816                                        0,
817                                        hash_metadata,
818                                        hash_method -> nx_crypto_metadata_area_size,
819                                        NX_CRYPTO_NULL,
820                                        NX_CRYPTO_NULL);
821 
822     if(status != NX_CRYPTO_SUCCESS)
823     {
824         return(status);
825     }
826 
827     size = g -> nx_crypto_ec_point_x.nx_crypto_huge_buffer_size +
828            g -> nx_crypto_ec_point_y.nx_crypto_huge_buffer_size + 1;
829     _nx_crypto_ec_point_extract_uncompressed(curve, g, (UCHAR *)scratch, size, &size);
830     NX_CRYPTO_CHANGE_ULONG_ENDIAN(size);
831     status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_UPDATE,
832                                        NX_CRYPTO_NULL,
833                                        hash_method,
834                                        NX_CRYPTO_NULL,
835                                        0,
836                                        (UCHAR *)&size,
837                                        sizeof(ULONG),
838                                        NX_CRYPTO_NULL,
839                                        NX_CRYPTO_NULL,
840                                        0,
841                                        hash_metadata,
842                                        hash_method -> nx_crypto_metadata_area_size,
843                                        NX_CRYPTO_NULL,
844                                        NX_CRYPTO_NULL);
845 
846     if(status != NX_CRYPTO_SUCCESS)
847     {
848         return(status);
849     }
850 
851     NX_CRYPTO_CHANGE_ULONG_ENDIAN(size);
852     status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_UPDATE,
853                                        NX_CRYPTO_NULL,
854                                        hash_method,
855                                        NX_CRYPTO_NULL,
856                                        0,
857                                        (UCHAR *)scratch,
858                                        size,
859                                        NX_CRYPTO_NULL,
860                                        NX_CRYPTO_NULL,
861                                        0,
862                                        hash_metadata,
863                                        hash_method -> nx_crypto_metadata_area_size,
864                                        NX_CRYPTO_NULL,
865                                        NX_CRYPTO_NULL);
866 
867     if(status != NX_CRYPTO_SUCCESS)
868     {
869         return(status);
870     }
871 
872 
873     size = v -> nx_crypto_ec_point_x.nx_crypto_huge_buffer_size +
874            v -> nx_crypto_ec_point_y.nx_crypto_huge_buffer_size + 1;
875     _nx_crypto_ec_point_extract_uncompressed(curve, v, (UCHAR *)scratch, size, &size);
876     NX_CRYPTO_CHANGE_ULONG_ENDIAN(size);
877     status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_UPDATE,
878                                        NX_CRYPTO_NULL,
879                                        hash_method,
880                                        NX_CRYPTO_NULL,
881                                        0,
882                                        (UCHAR *)&size,
883                                        sizeof(ULONG),
884                                        NX_CRYPTO_NULL,
885                                        NX_CRYPTO_NULL,
886                                        0,
887                                        hash_metadata,
888                                        hash_method -> nx_crypto_metadata_area_size,
889                                        NX_CRYPTO_NULL,
890                                        NX_CRYPTO_NULL);
891 
892     if(status != NX_CRYPTO_SUCCESS)
893     {
894         return(status);
895     }
896 
897     NX_CRYPTO_CHANGE_ULONG_ENDIAN(size);
898     status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_UPDATE,
899                                        NX_CRYPTO_NULL,
900                                        hash_method,
901                                        NX_CRYPTO_NULL,
902                                        0,
903                                        (UCHAR *)scratch,
904                                        size,
905                                        NX_CRYPTO_NULL,
906                                        NX_CRYPTO_NULL,
907                                        0,
908                                        hash_metadata,
909                                        hash_method -> nx_crypto_metadata_area_size,
910                                        NX_CRYPTO_NULL,
911                                        NX_CRYPTO_NULL);
912 
913     if(status != NX_CRYPTO_SUCCESS)
914     {
915         return(status);
916     }
917 
918 
919     size = x -> nx_crypto_ec_point_x.nx_crypto_huge_buffer_size +
920            x -> nx_crypto_ec_point_y.nx_crypto_huge_buffer_size + 1;
921     _nx_crypto_ec_point_extract_uncompressed(curve, x, (UCHAR *)scratch, size, &size);
922     NX_CRYPTO_CHANGE_ULONG_ENDIAN(size);
923     status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_UPDATE,
924                                        NX_CRYPTO_NULL,
925                                        hash_method,
926                                        NX_CRYPTO_NULL,
927                                        0,
928                                        (UCHAR *)&size,
929                                        sizeof(ULONG),
930                                        NX_CRYPTO_NULL,
931                                        NX_CRYPTO_NULL,
932                                        0,
933                                        hash_metadata,
934                                        hash_method -> nx_crypto_metadata_area_size,
935                                        NX_CRYPTO_NULL,
936                                        NX_CRYPTO_NULL);
937 
938     if(status != NX_CRYPTO_SUCCESS)
939     {
940         return(status);
941     }
942 
943     NX_CRYPTO_CHANGE_ULONG_ENDIAN(size);
944     status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_UPDATE,
945                                        NX_CRYPTO_NULL,
946                                        hash_method,
947                                        NX_CRYPTO_NULL,
948                                        0,
949                                        (UCHAR *)scratch,
950                                        size,
951                                        NX_CRYPTO_NULL,
952                                        NX_CRYPTO_NULL,
953                                        0,
954                                        hash_metadata,
955                                        hash_method -> nx_crypto_metadata_area_size,
956                                        NX_CRYPTO_NULL,
957                                        NX_CRYPTO_NULL);
958 
959     if(status != NX_CRYPTO_SUCCESS)
960     {
961         return(status);
962     }
963 
964     NX_CRYPTO_CHANGE_ULONG_ENDIAN(id_len);
965     status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_UPDATE,
966                                        NX_CRYPTO_NULL,
967                                        hash_method,
968                                        NX_CRYPTO_NULL,
969                                        0,
970                                        (UCHAR *)&id_len,
971                                        sizeof(ULONG),
972                                        NX_CRYPTO_NULL,
973                                        NX_CRYPTO_NULL,
974                                        0,
975                                        hash_metadata,
976                                        hash_method -> nx_crypto_metadata_area_size,
977                                        NX_CRYPTO_NULL,
978                                        NX_CRYPTO_NULL);
979 
980     if(status != NX_CRYPTO_SUCCESS)
981     {
982         return(status);
983     }
984 
985     NX_CRYPTO_CHANGE_ULONG_ENDIAN(id_len);
986     status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_UPDATE,
987                                        NX_CRYPTO_NULL,
988                                        hash_method,
989                                        NX_CRYPTO_NULL,
990                                        0,
991                                        (UCHAR *)id,
992                                        id_len,
993                                        NX_CRYPTO_NULL,
994                                        NX_CRYPTO_NULL,
995                                        0,
996                                        hash_metadata,
997                                        hash_method -> nx_crypto_metadata_area_size,
998                                        NX_CRYPTO_NULL,
999                                        NX_CRYPTO_NULL);
1000 
1001     if(status != NX_CRYPTO_SUCCESS)
1002     {
1003         return(status);
1004     }
1005 
1006     status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_CALCULATE,
1007                                        NX_CRYPTO_NULL,
1008                                        hash_method,
1009                                        NX_CRYPTO_NULL,
1010                                        0,
1011                                        NX_CRYPTO_NULL,
1012                                        0,
1013                                        NX_CRYPTO_NULL,
1014                                        (UCHAR *)scratch,
1015                                        hash_method -> nx_crypto_ICV_size_in_bits >> 3,
1016                                        hash_metadata,
1017                                        hash_method -> nx_crypto_metadata_area_size,
1018                                        NX_CRYPTO_NULL,
1019                                        NX_CRYPTO_NULL);
1020 
1021     if(status != NX_CRYPTO_SUCCESS)
1022     {
1023         return(status);
1024     }
1025 
1026 
1027     status = _nx_crypto_huge_number_setup(h, (UCHAR *)scratch,
1028                                           hash_method -> nx_crypto_ICV_size_in_bits >> 3);
1029 
1030     if (status != NX_CRYPTO_SUCCESS)
1031     {
1032         return(status);
1033     }
1034 
1035     _nx_crypto_huge_number_modulus(h, &curve -> nx_crypto_ec_n);
1036 
1037     if (hash_method -> nx_crypto_cleanup)
1038     {
1039         status = hash_method -> nx_crypto_cleanup(hash_metadata);
1040     }
1041 
1042     return(status);
1043 }
1044 
1045 /**************************************************************************/
1046 /*                                                                        */
1047 /*  FUNCTION                                               RELEASE        */
1048 /*                                                                        */
1049 /*    _nx_crypto_ecjpake_schnorr_zkp_generate             PORTABLE C      */
1050 /*                                                           6.1          */
1051 /*  AUTHOR                                                                */
1052 /*                                                                        */
1053 /*    Timothy Stapko, Microsoft Corporation                               */
1054 /*                                                                        */
1055 /*  DESCRIPTION                                                           */
1056 /*                                                                        */
1057 /*    This function performs Schnorr ZKP generation.                      */
1058 /*                                                                        */
1059 /*  INPUT                                                                 */
1060 /*                                                                        */
1061 /*    hash_method                           Hash method used by ECJPAKE   */
1062 /*    hash_metadata                         Metadata of hash method       */
1063 /*    curve                                 Pointer to curve              */
1064 /*    g                                     Generator                     */
1065 /*    v                                     ZKP ephemeral public key      */
1066 /*    public_key                            Public key generated          */
1067 /*    id                                    Client or Server              */
1068 /*    id_len                                Length of ID                  */
1069 /*    private_key                           Private key generated         */
1070 /*    r                                     Schnorr signature for output  */
1071 /*    scratch                               Pointer to scratch            */
1072 /*                                                                        */
1073 /*  OUTPUT                                                                */
1074 /*                                                                        */
1075 /*    Status                                Completion status             */
1076 /*                                                                        */
1077 /*  CALLS                                                                 */
1078 /*                                                                        */
1079 /*    NX_CRYPTO_HUGE_NUMBER_COPY            Copy huge number              */
1080 /*    NX_CRYPTO_HUGE_NUMBER_INITIALIZE      Initialize the buffer of      */
1081 /*                                            huge number                 */
1082 /*    _nx_crypto_huge_number_modulus        Perform a modulus operation   */
1083 /*    _nx_crypto_huge_number_multiply       Multiply two huge numbers     */
1084 /*    _nx_crypto_huge_number_subtract       Calculate subtraction for     */
1085 /*                                             huge numbers               */
1086 /*    _nx_crypto_ecjpake_schnorr_zkp_hash   Perform Schnorr ZKP hash      */
1087 /*                                            calculation                 */
1088 /*    _nx_crypto_ec_key_pair_generation_extra                             */
1089 /*                                          Generate EC Key Pair          */
1090 /*                                                                        */
1091 /*  CALLED BY                                                             */
1092 /*                                                                        */
1093 /*    _nx_crypto_ecjpake_hello_generate     Generate hello message        */
1094 /*    _nx_crypto_ecjpake_key_exchange_generate                            */
1095 /*                                          Generate key exchange message */
1096 /*                                                                        */
1097 /*  RELEASE HISTORY                                                       */
1098 /*                                                                        */
1099 /*    DATE              NAME                      DESCRIPTION             */
1100 /*                                                                        */
1101 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1102 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1103 /*                                            resulting in version 6.1    */
1104 /*                                                                        */
1105 /**************************************************************************/
_nx_crypto_ecjpake_schnorr_zkp_generate(NX_CRYPTO_METHOD * hash_method,VOID * hash_metadata,NX_CRYPTO_EC * curve,NX_CRYPTO_EC_POINT * g,NX_CRYPTO_EC_POINT * v,NX_CRYPTO_EC_POINT * public_key,CHAR * id,UINT id_len,NX_CRYPTO_HUGE_NUMBER * private_key,NX_CRYPTO_HUGE_NUMBER * r,HN_UBASE * scratch)1106 NX_CRYPTO_KEEP UINT _nx_crypto_ecjpake_schnorr_zkp_generate(NX_CRYPTO_METHOD *hash_method,
1107                                                             VOID *hash_metadata,
1108                                                             NX_CRYPTO_EC *curve,
1109                                                             NX_CRYPTO_EC_POINT *g,
1110                                                             NX_CRYPTO_EC_POINT *v,
1111                                                             NX_CRYPTO_EC_POINT *public_key,
1112                                                             CHAR *id,
1113                                                             UINT id_len,
1114                                                             NX_CRYPTO_HUGE_NUMBER *private_key,
1115                                                             NX_CRYPTO_HUGE_NUMBER *r,
1116                                                             HN_UBASE *scratch)
1117 {
1118 UINT                  buffer_size = curve -> nx_crypto_ec_n.nx_crypto_huge_buffer_size;
1119 NX_CRYPTO_HUGE_NUMBER h, temp1, temp2;
1120 UINT status;
1121 
1122     NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&h, scratch, buffer_size);
1123     NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&temp1, scratch, buffer_size << 1);
1124     NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&temp2, scratch, buffer_size << 1);
1125 
1126     _nx_crypto_ec_key_pair_generation_extra(curve, g, &temp1, v, scratch);
1127 
1128     status = _nx_crypto_ecjpake_schnorr_zkp_hash(hash_method,
1129                                         hash_metadata,
1130                                         curve,
1131                                         g,
1132                                         v,
1133                                         public_key,
1134                                         &h,
1135                                         id,
1136                                         id_len,
1137                                         scratch);
1138 
1139     if(status != NX_CRYPTO_SUCCESS)
1140     {
1141         return(status);
1142     }
1143 
1144     _nx_crypto_huge_number_multiply(&h, private_key, &temp2);
1145     _nx_crypto_huge_number_subtract(&temp1, &temp2);
1146     _nx_crypto_huge_number_modulus(&temp1, &curve -> nx_crypto_ec_n);
1147     NX_CRYPTO_HUGE_NUMBER_COPY(r, &temp1);
1148 
1149     return(NX_CRYPTO_SUCCESS);
1150 }
1151 
1152 /**************************************************************************/
1153 /*                                                                        */
1154 /*  FUNCTION                                               RELEASE        */
1155 /*                                                                        */
1156 /*    _nx_crypto_ecjpake_schnorr_zkp_verify               PORTABLE C      */
1157 /*                                                           6.1          */
1158 /*  AUTHOR                                                                */
1159 /*                                                                        */
1160 /*    Timothy Stapko, Microsoft Corporation                               */
1161 /*                                                                        */
1162 /*  DESCRIPTION                                                           */
1163 /*                                                                        */
1164 /*    This function performs Schnorr ZKP verification.                    */
1165 /*                                                                        */
1166 /*  INPUT                                                                 */
1167 /*                                                                        */
1168 /*    hash_method                           Hash method used by ECJPAKE   */
1169 /*    hash_metadata                         Metadata of hash method       */
1170 /*    curve                                 Pointer to curve              */
1171 /*    g                                     Generator                     */
1172 /*    v                                     ZKP ephemeral public key      */
1173 /*    public_key                            Public key generated          */
1174 /*    id                                    Client or Server              */
1175 /*    id_len                                Length of ID                  */
1176 /*    r                                     Schnorr signature             */
1177 /*    scratch                               Pointer to scratch            */
1178 /*                                                                        */
1179 /*  OUTPUT                                                                */
1180 /*                                                                        */
1181 /*    status                                Completion status             */
1182 /*                                                                        */
1183 /*  CALLS                                                                 */
1184 /*                                                                        */
1185 /*    NX_CRYPTO_EC_POINT_INITIALIZE         Initialize EC point           */
1186 /*    NX_CRYPTO_HUGE_NUMBER_INITIALIZE      Initialize the buffer of      */
1187 /*                                            huge number                 */
1188 /*    _nx_crypto_ecjpake_schnorr_zkp_hash   Perform Schnorr ZKP hash      */
1189 /*                                            calculation                 */
1190 /*    _nx_crypto_huge_number_compare        Compare two huge numbers      */
1191 /*    [nx_crypto_ec_add]                    Perform addtion for EC        */
1192 /*    [nx_crypto_ec_multiple]               Perform multiplication for EC */
1193 /*                                                                        */
1194 /*  CALLED BY                                                             */
1195 /*                                                                        */
1196 /*    _nx_crypto_ecjpake_hello_process      Process hello message         */
1197 /*    _nx_crypto_ecjpake_key_exchange_process                             */
1198 /*                                          Process key exchange message  */
1199 /*                                                                        */
1200 /*  RELEASE HISTORY                                                       */
1201 /*                                                                        */
1202 /*    DATE              NAME                      DESCRIPTION             */
1203 /*                                                                        */
1204 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1205 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1206 /*                                            resulting in version 6.1    */
1207 /*                                                                        */
1208 /**************************************************************************/
_nx_crypto_ecjpake_schnorr_zkp_verify(NX_CRYPTO_METHOD * hash_method,VOID * hash_metadata,NX_CRYPTO_EC * curve,NX_CRYPTO_EC_POINT * g,NX_CRYPTO_EC_POINT * v,NX_CRYPTO_EC_POINT * public_key,CHAR * id,UINT id_len,NX_CRYPTO_HUGE_NUMBER * r,HN_UBASE * scratch)1209 NX_CRYPTO_KEEP UINT _nx_crypto_ecjpake_schnorr_zkp_verify(NX_CRYPTO_METHOD *hash_method,
1210                                                           VOID *hash_metadata,
1211                                                           NX_CRYPTO_EC *curve,
1212                                                           NX_CRYPTO_EC_POINT *g,
1213                                                           NX_CRYPTO_EC_POINT *v,
1214                                                           NX_CRYPTO_EC_POINT *public_key,
1215                                                           CHAR *id,
1216                                                           UINT id_len,
1217                                                           NX_CRYPTO_HUGE_NUMBER *r,
1218                                                           HN_UBASE *scratch)
1219 {
1220 NX_CRYPTO_HUGE_NUMBER h;
1221 NX_CRYPTO_EC_POINT    temp1, temp2;
1222 
1223     NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&h, scratch,
1224                                      curve -> nx_crypto_ec_n.nx_crypto_huge_buffer_size);
1225     NX_CRYPTO_EC_POINT_INITIALIZE(&temp1,
1226                                   NX_CRYPTO_EC_POINT_AFFINE, scratch,
1227                                   public_key -> nx_crypto_ec_point_x.nx_crypto_huge_buffer_size);
1228     NX_CRYPTO_EC_POINT_INITIALIZE(&temp2,
1229                                   NX_CRYPTO_EC_POINT_AFFINE, scratch,
1230                                   g -> nx_crypto_ec_point_x.nx_crypto_huge_buffer_size);
1231 
1232     _nx_crypto_ecjpake_schnorr_zkp_hash(hash_method,
1233                                         hash_metadata,
1234                                         curve,
1235                                         g,
1236                                         v,
1237                                         public_key,
1238                                         &h,
1239                                         id,
1240                                         id_len,
1241                                         scratch);
1242 
1243     curve -> nx_crypto_ec_multiple(curve, public_key, &h, &temp1, scratch);
1244     curve -> nx_crypto_ec_multiple(curve, g, r, &temp2, scratch);
1245     curve -> nx_crypto_ec_add(curve, &temp1, &temp2, scratch);
1246 
1247     if ((_nx_crypto_huge_number_compare(&temp1.nx_crypto_ec_point_x,
1248                                         &v -> nx_crypto_ec_point_x) == NX_CRYPTO_HUGE_NUMBER_EQUAL) &&
1249         (_nx_crypto_huge_number_compare(&temp1.nx_crypto_ec_point_y,
1250                                         &v -> nx_crypto_ec_point_y) == NX_CRYPTO_HUGE_NUMBER_EQUAL))
1251     {
1252         return(NX_CRYPTO_SUCCESS);
1253     }
1254     else
1255     {
1256         return(NX_CRYPTO_NOT_SUCCESSFUL);
1257     }
1258 }
1259 
1260 /**************************************************************************/
1261 /*                                                                        */
1262 /*  FUNCTION                                               RELEASE        */
1263 /*                                                                        */
1264 /*    _nx_crypto_ecjpake_public_key_generate              PORTABLE C      */
1265 /*                                                           6.1          */
1266 /*  AUTHOR                                                                */
1267 /*                                                                        */
1268 /*    Timothy Stapko, Microsoft Corporation                               */
1269 /*                                                                        */
1270 /*  DESCRIPTION                                                           */
1271 /*                                                                        */
1272 /*    This function performs public key generation.                       */
1273 /*                                                                        */
1274 /*  INPUT                                                                 */
1275 /*                                                                        */
1276 /*    curve                                 Pointer to curve              */
1277 /*    x1                                    Public key x1                 */
1278 /*    x3                                    Public key x3                 */
1279 /*    x4                                    Public key x4                 */
1280 /*    x2                                    Private key x2                */
1281 /*    s                                     Shared secret                 */
1282 /*    g                                     Base point                    */
1283 /*    public_key                            Public key for output         */
1284 /*    private_key                           Private key for output        */
1285 /*    scratch                               Pointer to scratch            */
1286 /*                                                                        */
1287 /*  OUTPUT                                                                */
1288 /*                                                                        */
1289 /*    None                                                                */
1290 /*                                                                        */
1291 /*  CALLS                                                                 */
1292 /*                                                                        */
1293 /*    NX_CRYPTO_HUGE_NUMBER_INITIALIZE      Initialize the buffer of      */
1294 /*                                            huge number                 */
1295 /*    NX_CRYPTO_HUGE_NUMBER_COPY            Copy huge number              */
1296 /*    _nx_crypto_huge_number_modulus        Perform a modulus operation   */
1297 /*    _nx_crypto_huge_number_multiply       Multiply two huge numbers     */
1298 /*    [nx_crypto_ec_add]                    Perform addtion for EC        */
1299 /*    [nx_crypto_ec_multiple]               Perform multiplication for EC */
1300 /*                                                                        */
1301 /*  CALLED BY                                                             */
1302 /*                                                                        */
1303 /*    _nx_crypto_ecjpake_key_exchange_generate                            */
1304 /*                                          Generate key exchange message */
1305 /*                                                                        */
1306 /*  RELEASE HISTORY                                                       */
1307 /*                                                                        */
1308 /*    DATE              NAME                      DESCRIPTION             */
1309 /*                                                                        */
1310 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1311 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1312 /*                                            resulting in version 6.1    */
1313 /*                                                                        */
1314 /**************************************************************************/
_nx_crypto_ecjpake_public_key_generate(NX_CRYPTO_EC * curve,NX_CRYPTO_EC_POINT * x1,NX_CRYPTO_EC_POINT * x3,NX_CRYPTO_EC_POINT * x4,NX_CRYPTO_HUGE_NUMBER * x2,NX_CRYPTO_HUGE_NUMBER * s,NX_CRYPTO_EC_POINT * g,NX_CRYPTO_EC_POINT * public_key,NX_CRYPTO_HUGE_NUMBER * private_key,HN_UBASE * scratch)1315 NX_CRYPTO_KEEP VOID _nx_crypto_ecjpake_public_key_generate(NX_CRYPTO_EC *curve,
1316                                                            NX_CRYPTO_EC_POINT *x1,
1317                                                            NX_CRYPTO_EC_POINT *x3,
1318                                                            NX_CRYPTO_EC_POINT *x4,
1319                                                            NX_CRYPTO_HUGE_NUMBER *x2,
1320                                                            NX_CRYPTO_HUGE_NUMBER *s,
1321                                                            NX_CRYPTO_EC_POINT *g,
1322                                                            NX_CRYPTO_EC_POINT *public_key,
1323                                                            NX_CRYPTO_HUGE_NUMBER *private_key,
1324                                                            HN_UBASE *scratch)
1325 {
1326 NX_CRYPTO_HUGE_NUMBER temp1;
1327 
1328     /* G = X1 + X3 + X4 */
1329     NX_CRYPTO_HUGE_NUMBER_COPY(&g -> nx_crypto_ec_point_x, &x1 -> nx_crypto_ec_point_x);
1330     NX_CRYPTO_HUGE_NUMBER_COPY(&g -> nx_crypto_ec_point_y, &x1 -> nx_crypto_ec_point_y);
1331     curve -> nx_crypto_ec_add(curve, g, x3, scratch);
1332     curve -> nx_crypto_ec_add(curve, g, x4, scratch);
1333 
1334     /* private_key = x2 * s mod n */
1335     NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&temp1, scratch,
1336                                      curve -> nx_crypto_ec_n.nx_crypto_huge_buffer_size << 1);
1337     _nx_crypto_huge_number_multiply(x2, s, &temp1);
1338     _nx_crypto_huge_number_modulus(&temp1, &curve -> nx_crypto_ec_n);
1339     NX_CRYPTO_HUGE_NUMBER_COPY(private_key, &temp1);
1340 
1341     /* public_key = G * xs */
1342     curve -> nx_crypto_ec_multiple(curve, g, private_key, public_key, scratch);
1343 }
1344 
1345 /**************************************************************************/
1346 /*                                                                        */
1347 /*  FUNCTION                                               RELEASE        */
1348 /*                                                                        */
1349 /*    _nx_crypto_ecjpake_pre_master_secret_generate       PORTABLE C      */
1350 /*                                                           6.1          */
1351 /*  AUTHOR                                                                */
1352 /*                                                                        */
1353 /*    Timothy Stapko, Microsoft Corporation                               */
1354 /*                                                                        */
1355 /*  DESCRIPTION                                                           */
1356 /*                                                                        */
1357 /*    This function performs pre-master secret generation.                */
1358 /*                                                                        */
1359 /*  INPUT                                                                 */
1360 /*                                                                        */
1361 /*    hash_method                           Hash method used by ECJPAKE   */
1362 /*    hash_metadata                         Metadata of hash method       */
1363 /*    curve                                 Pointer to curve              */
1364 /*    x4                                    Public key x4                 */
1365 /*    s                                     Shared secret                 */
1366 /*    public_key                            Public key                    */
1367 /*    x2                                    Private key x2                */
1368 /*    pms                                   Pre-master key                */
1369 /*    scratch                               Pointer to scratch            */
1370 /*                                                                        */
1371 /*  OUTPUT                                                                */
1372 /*                                                                        */
1373 /*    Status                                Completion status             */
1374 /*                                                                        */
1375 /*  CALLS                                                                 */
1376 /*                                                                        */
1377 /*    _nx_crypto_huge_number_extract_fixed_size                           */
1378 /*                                          Extract huge number           */
1379 /*    NX_CRYPTO_EC_POINT_INITIALIZE         Initialize EC point           */
1380 /*    NX_CRYPTO_HUGE_NUMBER_COPY            Copy huge number              */
1381 /*    [nx_crypto_ec_multiple]               Perform multiplication for EC */
1382 /*    [nx_crypto_ec_subtract]               Perform subtraction for EC    */
1383 /*    [nx_crypto_operation]                 Crypto opeartion              */
1384 /*                                                                        */
1385 /*  CALLED BY                                                             */
1386 /*                                                                        */
1387 /*    _nx_crypto_ecjpake_key_exchange_process                             */
1388 /*                                          Process key exchange message  */
1389 /*                                                                        */
1390 /*  RELEASE HISTORY                                                       */
1391 /*                                                                        */
1392 /*    DATE              NAME                      DESCRIPTION             */
1393 /*                                                                        */
1394 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1395 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1396 /*                                            resulting in version 6.1    */
1397 /*                                                                        */
1398 /**************************************************************************/
_nx_crypto_ecjpake_pre_master_secret_generate(NX_CRYPTO_METHOD * hash_method,VOID * hash_metadata,NX_CRYPTO_EC * curve,NX_CRYPTO_EC_POINT * x4,NX_CRYPTO_HUGE_NUMBER * s,NX_CRYPTO_EC_POINT * public_key,NX_CRYPTO_HUGE_NUMBER * x2,UCHAR * pms,HN_UBASE * scratch)1399 NX_CRYPTO_KEEP UINT _nx_crypto_ecjpake_pre_master_secret_generate(NX_CRYPTO_METHOD *hash_method,
1400                                                                   VOID *hash_metadata,
1401                                                                   NX_CRYPTO_EC *curve,
1402                                                                   NX_CRYPTO_EC_POINT *x4,
1403                                                                   NX_CRYPTO_HUGE_NUMBER *s,
1404                                                                   NX_CRYPTO_EC_POINT *public_key,
1405                                                                   NX_CRYPTO_HUGE_NUMBER *x2,
1406                                                                   UCHAR *pms,
1407                                                                   HN_UBASE *scratch)
1408 {
1409 NX_CRYPTO_EC_POINT temp1, temp2;
1410 UCHAR             *input;
1411 VOID              *handler;
1412 UINT               input_size = (curve -> nx_crypto_ec_bits + 7) >> 3;
1413 UINT               status;
1414 
1415     NX_CRYPTO_EC_POINT_INITIALIZE(&temp1,
1416                                   NX_CRYPTO_EC_POINT_AFFINE, scratch,
1417                                   public_key -> nx_crypto_ec_point_x.nx_crypto_huge_buffer_size);
1418     NX_CRYPTO_EC_POINT_INITIALIZE(&temp2,
1419                                   NX_CRYPTO_EC_POINT_AFFINE, scratch,
1420                                   public_key -> nx_crypto_ec_point_x.nx_crypto_huge_buffer_size);
1421     input = (UCHAR *)scratch;
1422     scratch += input_size;
1423 
1424     /* PMSK = (public_key - X4 * x2 * s) * x2 */
1425     NX_CRYPTO_HUGE_NUMBER_COPY(&temp1.nx_crypto_ec_point_x, &x4 -> nx_crypto_ec_point_x);
1426     NX_CRYPTO_HUGE_NUMBER_COPY(&temp1.nx_crypto_ec_point_y, &x4 -> nx_crypto_ec_point_y);
1427     curve -> nx_crypto_ec_multiple(curve, &temp1, x2, &temp2, scratch);
1428     curve -> nx_crypto_ec_multiple(curve, &temp2, s, &temp1, scratch);
1429     NX_CRYPTO_HUGE_NUMBER_COPY(&temp2.nx_crypto_ec_point_x, &public_key -> nx_crypto_ec_point_x);
1430     NX_CRYPTO_HUGE_NUMBER_COPY(&temp2.nx_crypto_ec_point_y, &public_key -> nx_crypto_ec_point_y);
1431     curve -> nx_crypto_ec_subtract(curve, &temp2, &temp1, scratch);
1432     curve -> nx_crypto_ec_multiple(curve, &temp2, x2, &temp1, scratch);
1433 
1434     /* PMS = SHA-256(str(32, X coordinate of PMSK)) */
1435     status = _nx_crypto_huge_number_extract_fixed_size(&temp1.nx_crypto_ec_point_x, input, input_size);
1436 
1437     if(status != NX_CRYPTO_SUCCESS)
1438     {
1439         return(status);
1440     }
1441 
1442     if (hash_method -> nx_crypto_init)
1443     {
1444         status = hash_method -> nx_crypto_init(hash_method,
1445                                       NX_CRYPTO_NULL,
1446                                       0,
1447                                       &handler,
1448                                       hash_metadata,
1449                                       hash_method -> nx_crypto_metadata_area_size);
1450 
1451         if(status != NX_CRYPTO_SUCCESS)
1452         {
1453             return(status);
1454         }
1455     }
1456 
1457     status = hash_method -> nx_crypto_operation(NX_CRYPTO_AUTHENTICATE,
1458                                        NX_CRYPTO_NULL,
1459                                        hash_method,
1460                                        NX_CRYPTO_NULL,
1461                                        0,
1462                                        input,
1463                                        input_size,
1464                                        NX_CRYPTO_NULL,
1465                                        pms,
1466                                        hash_method -> nx_crypto_ICV_size_in_bits >> 3,
1467                                        hash_metadata,
1468                                        hash_method -> nx_crypto_metadata_area_size,
1469                                        NX_CRYPTO_NULL,
1470                                        NX_CRYPTO_NULL);
1471 
1472     if(status != NX_CRYPTO_SUCCESS)
1473     {
1474         return(status);
1475     }
1476 
1477 
1478     if (hash_method -> nx_crypto_cleanup)
1479     {
1480         status = hash_method -> nx_crypto_cleanup(hash_metadata);
1481     }
1482 
1483     return(status);
1484 }
1485 
1486 /**************************************************************************/
1487 /*                                                                        */
1488 /*  FUNCTION                                               RELEASE        */
1489 /*                                                                        */
1490 /*    _nx_crypto_ecjpake_key_encryption_key_generate      PORTABLE C      */
1491 /*                                                           6.1          */
1492 /*  AUTHOR                                                                */
1493 /*                                                                        */
1494 /*    Timothy Stapko, Microsoft Corporation                               */
1495 /*                                                                        */
1496 /*  DESCRIPTION                                                           */
1497 /*                                                                        */
1498 /*    This function performs key encryption key generation.               */
1499 /*                                                                        */
1500 /*  INPUT                                                                 */
1501 /*                                                                        */
1502 /*    hash_method                           Hash method used by ECJPAKE   */
1503 /*    hash_metadata                         Metadata of hash method       */
1504 /*    key_expansion                         Pointer to key expansion      */
1505 /*    key_expansion_len                     Length of key expansion       */
1506 /*    key_encryption_key                    Key encryption key for output */
1507 /*                                                                        */
1508 /*  OUTPUT                                                                */
1509 /*                                                                        */
1510 /*    Status                                Completion status             */
1511 /*                                                                        */
1512 /*  CALLS                                                                 */
1513 /*                                                                        */
1514 /*    [nx_crypto_operation]                 Crypto opeartion              */
1515 /*                                                                        */
1516 /*  CALLED BY                                                             */
1517 /*                                                                        */
1518 /*    Application Code                                                    */
1519 /*                                                                        */
1520 /*  RELEASE HISTORY                                                       */
1521 /*                                                                        */
1522 /*    DATE              NAME                      DESCRIPTION             */
1523 /*                                                                        */
1524 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1525 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1526 /*                                            verified memcpy use cases,  */
1527 /*                                            resulting in version 6.1    */
1528 /*  06-02-2021     Bhupendra Naphade        Modified comment(s),          */
1529 /*                                            renamed FIPS symbol to      */
1530 /*                                            self-test,                  */
1531 /*                                            resulting in version 6.1.7  */
1532 /*                                                                        */
1533 /**************************************************************************/
1534 #ifndef NX_CRYPTO_SELF_TEST
_nx_crypto_ecjpake_key_encryption_key_generate(NX_CRYPTO_METHOD * hash_method,VOID * hash_metadata,UCHAR * key_expansion,UINT key_expansion_len,UCHAR * key_encryption_key)1535 UINT _nx_crypto_ecjpake_key_encryption_key_generate(NX_CRYPTO_METHOD *hash_method,
1536                                                     VOID *hash_metadata,
1537                                                     UCHAR *key_expansion,
1538                                                     UINT key_expansion_len,
1539                                                     UCHAR *key_encryption_key)
1540 {
1541 UCHAR buffer[32];
1542 VOID *handler;
1543 UINT status;
1544 
1545     if (hash_method -> nx_crypto_init)
1546     {
1547         status = hash_method -> nx_crypto_init(hash_method,
1548                                       NX_CRYPTO_NULL,
1549                                       0,
1550                                       &handler,
1551                                       hash_metadata,
1552                                       hash_method -> nx_crypto_metadata_area_size);
1553 
1554         if(status != NX_CRYPTO_SUCCESS)
1555         {
1556             return(status);
1557         }
1558     }
1559 
1560     /* KEK = SHA-256(key expansion)[0..15] */
1561     status = hash_method -> nx_crypto_operation(NX_CRYPTO_AUTHENTICATE,
1562                                        NX_CRYPTO_NULL,
1563                                        hash_method,
1564                                        NX_CRYPTO_NULL,
1565                                        0,
1566                                        key_expansion,
1567                                        key_expansion_len,
1568                                        NX_CRYPTO_NULL,
1569                                        buffer,
1570                                        hash_method -> nx_crypto_ICV_size_in_bits >> 3,
1571                                        hash_metadata,
1572                                        hash_method -> nx_crypto_metadata_area_size,
1573                                        NX_CRYPTO_NULL,
1574                                        NX_CRYPTO_NULL);
1575 
1576     if(status != NX_CRYPTO_SUCCESS)
1577     {
1578         return(status);
1579     }
1580 
1581 
1582     NX_CRYPTO_MEMCPY(key_encryption_key, buffer, 16); /* Use case of memcpy is verified. */
1583 
1584     if (hash_method -> nx_crypto_cleanup)
1585     {
1586         status = hash_method -> nx_crypto_cleanup(hash_metadata);
1587     }
1588 
1589     return(status);
1590 }
1591 #endif
1592 /**************************************************************************/
1593 /*                                                                        */
1594 /*  FUNCTION                                               RELEASE        */
1595 /*                                                                        */
1596 /*    _nx_crypto_method_ecjpake_init                      PORTABLE C      */
1597 /*                                                           6.3.0        */
1598 /*  AUTHOR                                                                */
1599 /*                                                                        */
1600 /*    Timothy Stapko, Microsoft Corporation                               */
1601 /*                                                                        */
1602 /*  DESCRIPTION                                                           */
1603 /*                                                                        */
1604 /*    This function initializes the ECJPAKE crypto method.                */
1605 /*                                                                        */
1606 /*  INPUT                                                                 */
1607 /*                                                                        */
1608 /*    method                                Crypto Method Object          */
1609 /*    key                                   Key                           */
1610 /*    key_size_in_bits                      Size of the key, in bits      */
1611 /*    handle                                Handle, specified by user     */
1612 /*    crypto_metadata                       Metadata area                 */
1613 /*    crypto_metadata_size                  Size of the metadata area     */
1614 /*                                                                        */
1615 /*  OUTPUT                                                                */
1616 /*                                                                        */
1617 /*    status                                Completion status             */
1618 /*                                                                        */
1619 /*  CALLS                                                                 */
1620 /*                                                                        */
1621 /*    None                                                                */
1622 /*                                                                        */
1623 /*  CALLED BY                                                             */
1624 /*                                                                        */
1625 /*    Application Code                                                    */
1626 /*                                                                        */
1627 /*  RELEASE HISTORY                                                       */
1628 /*                                                                        */
1629 /*    DATE              NAME                      DESCRIPTION             */
1630 /*                                                                        */
1631 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1632 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1633 /*                                            resulting in version 6.1    */
1634 /*  10-31-2023     Yanwu Cai                Modified comment(s),          */
1635 /*                                            resulting in version 6.3.0  */
1636 /*                                                                        */
1637 /**************************************************************************/
_nx_crypto_method_ecjpake_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)1638 NX_CRYPTO_KEEP UINT  _nx_crypto_method_ecjpake_init(struct NX_CRYPTO_METHOD_STRUCT *method,
1639                                                     UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits,
1640                                                     VOID **handle,
1641                                                     VOID *crypto_metadata,
1642                                                     ULONG crypto_metadata_size)
1643 {
1644 NX_CRYPTO_ECJPAKE *ecjpake;
1645 UINT               i;
1646 
1647     NX_CRYPTO_PARAMETER_NOT_USED(handle);
1648 
1649     NX_CRYPTO_STATE_CHECK
1650 
1651     if (key_size_in_bits == 0)
1652     {
1653         /* PSK length must not be 0. */
1654         return(NX_CRYPTO_NOT_SUCCESSFUL);
1655     }
1656 
1657     if ((method == NX_CRYPTO_NULL) || (key == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL))
1658     {
1659         return(NX_CRYPTO_PTR_ERROR);
1660     }
1661 
1662     /* Verify the metadata address is 4-byte aligned. */
1663     if((((ULONG)crypto_metadata) & 0x3) != 0)
1664     {
1665         return(NX_CRYPTO_PTR_ERROR);
1666     }
1667 
1668     if(crypto_metadata_size < sizeof(NX_CRYPTO_ECJPAKE))
1669     {
1670         return(NX_CRYPTO_PTR_ERROR);
1671     }
1672 
1673     for (i = 0; i < (key_size_in_bits >> 3); i++)
1674     {
1675         if (key[i] == 0)
1676         {
1677             /* No NULL character in the PSK. */
1678             return(NX_CRYPTO_NOT_SUCCESSFUL);
1679         }
1680     }
1681 
1682     NX_CRYPTO_MEMSET(crypto_metadata, 0, crypto_metadata_size);
1683 
1684     ecjpake = (NX_CRYPTO_ECJPAKE *)crypto_metadata;
1685     ecjpake -> nx_crypto_ecjpake_psk = key;
1686     ecjpake -> nx_crypto_ecjpake_psk_length = key_size_in_bits >> 3;
1687     ecjpake -> nx_crypto_ecjpake_scratch_ptr = (HN_UBASE *)ecjpake -> nx_crypto_ecjpake_scratch_buffer;
1688 
1689     return(NX_CRYPTO_SUCCESS);
1690 }
1691 
1692 
1693 /**************************************************************************/
1694 /*                                                                        */
1695 /*  FUNCTION                                               RELEASE        */
1696 /*                                                                        */
1697 /*    _nx_crypto_method_ecjpake_cleanup                   PORTABLE C      */
1698 /*                                                           6.1          */
1699 /*  AUTHOR                                                                */
1700 /*                                                                        */
1701 /*    Timothy Stapko, Microsoft Corporation                               */
1702 /*                                                                        */
1703 /*  DESCRIPTION                                                           */
1704 /*                                                                        */
1705 /*    This function cleans up the crypto metadata.                        */
1706 /*                                                                        */
1707 /*  INPUT                                                                 */
1708 /*                                                                        */
1709 /*    crypto_metadata                       Crypto metadata               */
1710 /*                                                                        */
1711 /*  OUTPUT                                                                */
1712 /*                                                                        */
1713 /*    status                                Completion status             */
1714 /*                                                                        */
1715 /*  CALLS                                                                 */
1716 /*                                                                        */
1717 /*    NX_CRYPTO_MEMSET                      Set the memory                */
1718 /*                                                                        */
1719 /*  CALLED BY                                                             */
1720 /*                                                                        */
1721 /*    Application Code                                                    */
1722 /*                                                                        */
1723 /*  RELEASE HISTORY                                                       */
1724 /*                                                                        */
1725 /*    DATE              NAME                      DESCRIPTION             */
1726 /*                                                                        */
1727 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1728 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1729 /*                                            resulting in version 6.1    */
1730 /*                                                                        */
1731 /**************************************************************************/
_nx_crypto_method_ecjpake_cleanup(VOID * crypto_metadata)1732 NX_CRYPTO_KEEP UINT  _nx_crypto_method_ecjpake_cleanup(VOID *crypto_metadata)
1733 {
1734 
1735     NX_CRYPTO_STATE_CHECK
1736 
1737 #ifdef NX_SECURE_KEY_CLEAR
1738     if (!crypto_metadata)
1739         return (NX_CRYPTO_SUCCESS);
1740 
1741     /* Clean up the crypto metadata.  */
1742     NX_CRYPTO_MEMSET(crypto_metadata, 0, sizeof(NX_CRYPTO_ECJPAKE));
1743 #else
1744     NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata);
1745 #endif/* NX_SECURE_KEY_CLEAR  */
1746 
1747     return(NX_CRYPTO_SUCCESS);
1748 }
1749 
1750 
1751 /**************************************************************************/
1752 /*                                                                        */
1753 /*  FUNCTION                                               RELEASE        */
1754 /*                                                                        */
1755 /*    _nx_crypto_method_ecjpake_operation                 PORTABLE C      */
1756 /*                                                           6.3.0        */
1757 /*  AUTHOR                                                                */
1758 /*                                                                        */
1759 /*    Timothy Stapko, Microsoft Corporation                               */
1760 /*                                                                        */
1761 /*  DESCRIPTION                                                           */
1762 /*                                                                        */
1763 /*    This function initializes the ECJPAKE crypto method.                */
1764 /*                                                                        */
1765 /*  INPUT                                                                 */
1766 /*                                                                        */
1767 /*    op                                    ECJPAKE operation             */
1768 /*    handle                                Crypto handle                 */
1769 /*    method                                Cryption Method Object        */
1770 /*    key                                   Encryption Key                */
1771 /*    key_size_in_bits                      Key size in bits              */
1772 /*    input                                 Input data                    */
1773 /*    input_length_in_byte                  Input data size               */
1774 /*    iv_ptr                                Initial vector                */
1775 /*    output                                Output buffer                 */
1776 /*    output_length_in_byte                 Output buffer size            */
1777 /*    crypto_metadata                       Metadata area                 */
1778 /*    crypto_metadata_size                  Metadata area size            */
1779 /*    packet_ptr                            Pointer to packet             */
1780 /*    nx_crypto_hw_process_callback         Callback function pointer     */
1781 /*                                                                        */
1782 /*  OUTPUT                                                                */
1783 /*                                                                        */
1784 /*    status                                Completion status             */
1785 /*                                                                        */
1786 /*  CALLS                                                                 */
1787 /*                                                                        */
1788 /*    _nx_crypto_ecjpake_hello_generate     Generate hello message        */
1789 /*    _nx_crypto_ecjpake_hello_process      Process hello message         */
1790 /*    _nx_crypto_ecjpake_init               Initialize the ECJPAKE context*/
1791 /*    _nx_crypto_ecjpake_key_exchange_process                             */
1792 /*                                          Process key exchange message  */
1793 /*    _nx_crypto_ecjpake_key_exchange_generate                            */
1794 /*                                          Generate key exchange message */
1795 /*                                                                        */
1796 /*  CALLED BY                                                             */
1797 /*                                                                        */
1798 /*    Application Code                                                    */
1799 /*                                                                        */
1800 /*  RELEASE HISTORY                                                       */
1801 /*                                                                        */
1802 /*    DATE              NAME                      DESCRIPTION             */
1803 /*                                                                        */
1804 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1805 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1806 /*                                            resulting in version 6.1    */
1807 /*  10-31-2023     Yanwu Cai                Modified comment(s),          */
1808 /*                                            resulting in version 6.3.0  */
1809 /*                                                                        */
1810 /**************************************************************************/
_nx_crypto_method_ecjpake_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 *,UINT))1811 NX_CRYPTO_KEEP UINT _nx_crypto_method_ecjpake_operation(UINT op,
1812                                                         VOID *handle,
1813                                                         struct NX_CRYPTO_METHOD_STRUCT *method,
1814                                                         UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits,
1815                                                         UCHAR *input, ULONG input_length_in_byte,
1816                                                         UCHAR *iv_ptr,
1817                                                         UCHAR *output, ULONG output_length_in_byte,
1818                                                         VOID *crypto_metadata, ULONG crypto_metadata_size,
1819                                                         VOID *packet_ptr,
1820                                                         VOID (*nx_crypto_hw_process_callback)(VOID *, UINT))
1821 {
1822 NX_CRYPTO_ECJPAKE          *ecjpake;
1823 NX_CRYPTO_EXTENDED_OUTPUT  *extended_output;
1824 CHAR                       *id = NX_CRYPTO_NULL;
1825 UINT                        id_size = 0;
1826 UINT                        status = NX_CRYPTO_SUCCESS;
1827 
1828     NX_CRYPTO_PARAMETER_NOT_USED(handle);
1829     NX_CRYPTO_PARAMETER_NOT_USED(iv_ptr);
1830     NX_CRYPTO_PARAMETER_NOT_USED(output_length_in_byte);
1831     NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
1832     NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
1833 
1834     NX_CRYPTO_STATE_CHECK
1835 
1836     /* Verify the metadata address is 4-byte aligned. */
1837     if((method == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL) || ((((ULONG)crypto_metadata) & 0x3) != 0))
1838     {
1839         return(NX_CRYPTO_PTR_ERROR);
1840     }
1841 
1842     if(crypto_metadata_size < sizeof(NX_CRYPTO_ECJPAKE))
1843     {
1844         return(NX_CRYPTO_PTR_ERROR);
1845     }
1846 
1847     if ((op == NX_CRYPTO_ECJPAKE_CLIENT_HELLO_GENERATE) ||
1848         (op == NX_CRYPTO_ECJPAKE_CLIENT_HELLO_PROCESS) ||
1849         (op == NX_CRYPTO_ECJPAKE_CLIENT_KEY_EXCHANGE_GENERATE) ||
1850         (op == NX_CRYPTO_ECJPAKE_CLIENT_KEY_EXCHANGE_PROCESS))
1851     {
1852         id = NX_CRYPTO_ECJPAKE_CLIENT_ID;
1853         id_size = sizeof(NX_CRYPTO_ECJPAKE_CLIENT_ID) - 1;
1854     }
1855     else if((op == NX_CRYPTO_ECJPAKE_SERVER_HELLO_GENERATE) ||
1856             (op == NX_CRYPTO_ECJPAKE_SERVER_HELLO_PROCESS) ||
1857             (op == NX_CRYPTO_ECJPAKE_SERVER_KEY_EXCHANGE_GENERATE) ||
1858             (op == NX_CRYPTO_ECJPAKE_SERVER_KEY_EXCHANGE_PROCESS))
1859     {
1860         id = NX_CRYPTO_ECJPAKE_SERVER_ID;
1861         id_size = sizeof(NX_CRYPTO_ECJPAKE_SERVER_ID) - 1;
1862     }
1863 
1864     ecjpake = (NX_CRYPTO_ECJPAKE *)crypto_metadata;
1865 
1866     if (op == NX_CRYPTO_ECJPAKE_HASH_METHOD_SET)
1867     {
1868 
1869         if (ecjpake -> nx_crypto_ecjpake_curve != NX_CRYPTO_NULL)
1870         {
1871             _nx_crypto_ecjpake_init(ecjpake, ecjpake -> nx_crypto_ecjpake_curve,
1872                                     (NX_CRYPTO_METHOD *)input, (VOID *)key,
1873                                     key_size_in_bits >> 3,
1874                                     &ecjpake -> nx_crypto_ecjpake_scratch_ptr);
1875         }
1876         else
1877         {
1878             ecjpake -> nx_crypto_ecjpake_hash_method = (NX_CRYPTO_METHOD *)input;
1879             ecjpake -> nx_crypto_ecjpake_hash_metadata = (VOID *)key;
1880             ecjpake -> nx_crypto_ecjpake_hash_metadata_size = key_size_in_bits >> 3;
1881         }
1882     }
1883     else if (op == NX_CRYPTO_ECJPAKE_CURVE_SET)
1884     {
1885         status = ((NX_CRYPTO_METHOD *)input) -> nx_crypto_operation(NX_CRYPTO_EC_CURVE_GET,
1886                                                                     NX_CRYPTO_NULL,
1887                                                                     (NX_CRYPTO_METHOD *)input,
1888                                                                     NX_CRYPTO_NULL, 0,
1889                                                                     NX_CRYPTO_NULL, 0,
1890                                                                     NX_CRYPTO_NULL,
1891                                                                     (UCHAR *)&ecjpake -> nx_crypto_ecjpake_curve,
1892                                                                     sizeof(NX_CRYPTO_METHOD *),
1893                                                                     NX_CRYPTO_NULL, 0,
1894                                                                     NX_CRYPTO_NULL, NX_CRYPTO_NULL);
1895 
1896         if (status)
1897         {
1898             return(status);
1899         }
1900 
1901         if (ecjpake -> nx_crypto_ecjpake_hash_method != NX_CRYPTO_NULL)
1902         {
1903             _nx_crypto_ecjpake_init(ecjpake, ecjpake -> nx_crypto_ecjpake_curve,
1904                                     ecjpake -> nx_crypto_ecjpake_hash_method,
1905                                     ecjpake -> nx_crypto_ecjpake_hash_metadata,
1906                                     ecjpake -> nx_crypto_ecjpake_hash_metadata_size,
1907                                     &ecjpake -> nx_crypto_ecjpake_scratch_ptr);
1908         }
1909     }
1910     else if ((op == NX_CRYPTO_ECJPAKE_CLIENT_HELLO_GENERATE) ||
1911              (op == NX_CRYPTO_ECJPAKE_SERVER_HELLO_GENERATE))
1912     {
1913         extended_output = (NX_CRYPTO_EXTENDED_OUTPUT *)output;
1914         status = _nx_crypto_ecjpake_hello_generate(ecjpake,
1915                                           id, id_size,
1916                                           extended_output -> nx_crypto_extended_output_data,
1917                                           extended_output -> nx_crypto_extended_output_length_in_byte,
1918                                           &extended_output -> nx_crypto_extended_output_actual_size,
1919                                           ecjpake -> nx_crypto_ecjpake_scratch_ptr);
1920     }
1921     else if ((op == NX_CRYPTO_ECJPAKE_CLIENT_HELLO_PROCESS) ||
1922              (op == NX_CRYPTO_ECJPAKE_SERVER_HELLO_PROCESS))
1923     {
1924         status = _nx_crypto_ecjpake_hello_process(ecjpake,
1925                                                   id, id_size,
1926                                                   input, input_length_in_byte,
1927                                                   ecjpake -> nx_crypto_ecjpake_scratch_ptr);
1928     }
1929     else if ((op == NX_CRYPTO_ECJPAKE_CLIENT_KEY_EXCHANGE_GENERATE) ||
1930              (op == NX_CRYPTO_ECJPAKE_SERVER_KEY_EXCHANGE_GENERATE))
1931     {
1932         extended_output = (NX_CRYPTO_EXTENDED_OUTPUT *)output;
1933         status = _nx_crypto_ecjpake_key_exchange_generate(ecjpake,
1934                                                  ecjpake -> nx_crypto_ecjpake_psk,
1935                                                  ecjpake -> nx_crypto_ecjpake_psk_length,
1936                                                  id, id_size,
1937                                                  extended_output -> nx_crypto_extended_output_data,
1938                                                  extended_output -> nx_crypto_extended_output_length_in_byte,
1939                                                  &extended_output -> nx_crypto_extended_output_actual_size,
1940                                                  ecjpake -> nx_crypto_ecjpake_scratch_ptr);
1941     }
1942     else if ((op == NX_CRYPTO_ECJPAKE_CLIENT_KEY_EXCHANGE_PROCESS) ||
1943              (op == NX_CRYPTO_ECJPAKE_SERVER_KEY_EXCHANGE_PROCESS))
1944     {
1945         status = _nx_crypto_ecjpake_key_exchange_process(ecjpake,
1946                                                          ecjpake -> nx_crypto_ecjpake_psk,
1947                                                          ecjpake -> nx_crypto_ecjpake_psk_length,
1948                                                          id, id_size,
1949                                                          input, input_length_in_byte,
1950                                                          output,
1951                                                          ecjpake -> nx_crypto_ecjpake_scratch_ptr);
1952     }
1953     else
1954     {
1955         status = NX_CRYPTO_NOT_SUCCESSFUL;
1956     }
1957 
1958     return(status);
1959 }
1960 
1961