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