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