1 /* eccsi.c
2 *
3 * Copyright (C) 2006-2021 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL.
6 *
7 * wolfSSL is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * wolfSSL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20 */
21
22
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <wolfssl/wolfcrypt/settings.h>
29
30 #ifdef NO_INLINE
31 #include <wolfssl/wolfcrypt/misc.h>
32 #else
33 #define WOLFSSL_MISC_INCLUDED
34 #include <wolfcrypt/src/misc.c>
35 #endif
36
37 #ifdef WOLFCRYPT_HAVE_ECCSI
38
39 #include <wolfssl/wolfcrypt/error-crypt.h>
40 #include <wolfssl/wolfcrypt/eccsi.h>
41 #include <wolfssl/wolfcrypt/asn_public.h>
42 #ifdef WOLFSSL_HAVE_SP_ECC
43 #include <wolfssl/wolfcrypt/sp.h>
44 #endif
45
46 /**
47 * Initialize the components of the ECCSI key and use the specified curve.
48 *
49 * Must be called before performing any operations.
50 * Free the ECCSI key with wc_FreeEccsiKey() when no longer needed.
51 *
52 * @param [in] key ECCSI key to initialize.
53 * @param [in] heap Heap hint.
54 * @param [in] devId Device identifier.
55 * Use INVALID_DEVID when no device used.
56 * @return 0 on success.
57 * @return BAD_FUNC_ARG when key is NULL.
58 * @return MEMORY_E when dynamic memory allocation fails.
59 */
wc_InitEccsiKey_ex(EccsiKey * key,int keySz,int curveId,void * heap,int devId)60 int wc_InitEccsiKey_ex(EccsiKey* key, int keySz, int curveId, void* heap,
61 int devId)
62 {
63 int err = 0;
64 ecc_key* ecc = NULL;
65 ecc_key* pubkey = NULL;
66 EccsiKeyParams* params = NULL;
67
68 if (key == NULL) {
69 err = BAD_FUNC_ARG;
70 }
71
72 if (err == 0) {
73 XMEMSET(key, 0, sizeof(*key));
74 key->heap = heap;
75 params = &key->params;
76
77 err = wc_ecc_init_ex(&key->ecc, heap, devId);
78 }
79 if (err == 0) {
80 ecc = &key->ecc;
81 err = wc_ecc_init_ex(&key->pubkey, heap, devId);
82 }
83 if (err == 0) {
84 key->pvt = wc_ecc_new_point_h(heap);
85 if (key->pvt == NULL) {
86 err = MEMORY_E;
87 }
88 }
89 if (err == 0) {
90 pubkey = &key->pubkey;
91 err = mp_init_multi(¶ms->order,
92 #ifdef WOLFCRYPT_ECCSI_CLIENT
93 ¶ms->a, ¶ms->b, ¶ms->prime, &key->tmp, &key->ssk
94 #else
95 NULL, NULL, NULL, NULL, NULL
96 #endif
97 );
98 }
99 if (err == 0) {
100 err = wc_ecc_set_curve(&key->ecc, keySz, curveId);
101 }
102 if (err == 0) {
103 err = wc_ecc_set_curve(&key->pubkey, keySz, curveId);
104 }
105
106 if (err != 0) {
107 wc_ecc_free(pubkey);
108 wc_ecc_free(ecc);
109 }
110
111 return err;
112 }
113
114 /**
115 * Initialize the components of the ECCSI key.
116 * Default curve used: NIST_P256 (ECC_SECP256R1)
117 *
118 * Must be called before performing any operations.
119 * Free the ECCSI key with wc_FreeEccsiKey() when no longer needed.
120 *
121 * @param [in] key ECCSI key to initialize.
122 * @param [in] heap Heap hint.
123 * @param [in] devId Device identifier.
124 * Use INVALID_DEVID when no device used.
125 * @return 0 on success.
126 * @return BAD_FUNC_ARG when key is NULL.
127 * @return MEMORY_E when dynamic memory allocation fails.
128 */
wc_InitEccsiKey(EccsiKey * key,void * heap,int devId)129 int wc_InitEccsiKey(EccsiKey* key, void* heap, int devId)
130 {
131 return wc_InitEccsiKey_ex(key, 32, ECC_SECP256R1, heap, devId);
132 }
133
134 /**
135 * Frees memory associated with components of the ECCIS key.
136 *
137 * Must be called when finished with the ECCIS key.
138 *
139 * @param [in] key ECCIS key.
140 */
wc_FreeEccsiKey(EccsiKey * key)141 void wc_FreeEccsiKey(EccsiKey* key)
142 {
143 if (key != NULL) {
144 EccsiKeyParams* params = &key->params;
145
146 wc_ecc_del_point_h(params->base, key->heap);
147 #ifdef WOLFCRYPT_ECCSI_CLIENT
148 mp_free(&key->ssk);
149 mp_free(&key->tmp);
150 mp_free(¶ms->prime);
151 mp_free(¶ms->b);
152 mp_free(¶ms->a);
153 #endif
154 mp_free(¶ms->order);
155 wc_ecc_del_point_h(key->pvt, key->heap);
156 wc_ecc_free(&key->pubkey);
157 wc_ecc_free(&key->ecc);
158 }
159 }
160
161 /*
162 * Order, as a hex string in the ECC object, loaded into mp_int in key.
163 * Flags that the order is available so it isn't loaded multiple times.
164 *
165 * @param [in] key ECCSI key.
166 * @return 0 on success.
167 * @return MEMORY_E when dynamic memory allocation fails.
168 */
eccsi_load_order(EccsiKey * key)169 static int eccsi_load_order(EccsiKey* key)
170 {
171 int err = 0;
172
173 if (!key->params.haveOrder) {
174 err = mp_read_radix(&key->params.order, key->ecc.dp->order,
175 MP_RADIX_HEX);
176 if (err == 0) {
177 key->params.haveOrder = 1;
178 }
179 }
180
181 return err;
182 }
183
184 #ifdef WOLFCRYPT_ECCSI_CLIENT
185 /*
186 * Parameters, as a hex strings in the ECC object, loaded into mp_ints in key.
187 *
188 * Parameters loaded: order, A, B, prime.
189 * Flags that each parameter is available so they aren't loaded multiple times.
190 *
191 * @param [in] key ECCSI key.
192 * @return 0 on success.
193 * @return MEMORY_E when dynamic memory allocation fails.
194 */
eccsi_load_ecc_params(EccsiKey * key)195 static int eccsi_load_ecc_params(EccsiKey* key)
196 {
197 int err = 0;
198 EccsiKeyParams* params = &key->params;
199
200 err = eccsi_load_order(key);
201 if ((err == 0) && (!params->haveA)) {
202 err = mp_read_radix(¶ms->a, key->ecc.dp->Af, MP_RADIX_HEX);
203 if (err == 0) {
204 params->haveA = 1;
205 }
206 }
207 if ((err == 0) && (!params->haveB)) {
208 err = mp_read_radix(¶ms->b, key->ecc.dp->Bf, MP_RADIX_HEX);
209 if (err == 0) {
210 params->haveB = 1;
211 }
212 }
213 if ((err == 0) && (!params->havePrime)) {
214 err = mp_read_radix(¶ms->prime, key->ecc.dp->prime, MP_RADIX_HEX);
215 if (err == 0) {
216 params->havePrime = 1;
217 }
218 }
219
220 return err;
221 }
222 #endif /* WOLFCRYPT_ECCSI_CLIENT */
223
224 /*
225 * Get the base point, hex encoded in the ECC object, as an ecc_point.
226 *
227 * Flags that base is available so it isn't loaded multiple times.
228
229 * @param [in] key ECCSI key.
230 * @param [out] base Base point of curve.
231 * @return 0 on success.
232 * @return MEMORY_E when dynamic memory allocation fails.
233 */
eccsi_load_base(EccsiKey * key)234 static int eccsi_load_base(EccsiKey* key)
235 {
236 int err = 0;
237 EccsiKeyParams* params = &key->params;
238
239 if (!params->haveBase) {
240 if (params->base == NULL) {
241 params->base = wc_ecc_new_point_h(key->heap);
242 if (params->base == NULL) {
243 err = MEMORY_E;
244 }
245 }
246 if (err == 0) {
247 err = mp_read_radix(params->base->x, key->ecc.dp->Gx, MP_RADIX_HEX);
248 }
249 if (err == 0) {
250 err = mp_read_radix(params->base->y, key->ecc.dp->Gy, MP_RADIX_HEX);
251 }
252 if (err == 0) {
253 err = mp_set(params->base->z, 1);
254 }
255 if (err == 0) {
256 params->haveBase = 1;
257 }
258 }
259
260 return err;
261 }
262
263 /*
264 * Encode the base point of the curve.
265 *
266 * Base point is hex encoded in the ECC object or cached as an ECC point from
267 * previous load calls.
268 *
269 * @param [in] key ECCSI key.
270 * @param [out] data Buffer to encode base point into.
271 * @param [out] dataSz Length of base point in bytes.
272 * @return 0 on success.
273 * @return MEMORY_E when dynamic memory allocation fails.
274 * @return Other -ve value when an internal operation fails.
275 */
eccsi_encode_base(EccsiKey * key,byte * data,word32 * dataSz)276 static int eccsi_encode_base(EccsiKey* key, byte* data, word32* dataSz)
277 {
278 int err;
279 int idx = wc_ecc_get_curve_idx(key->ecc.dp->id);
280
281 err = eccsi_load_base(key);
282 if (err == 0) {
283 err = wc_ecc_export_point_der(idx, key->params.base, data, dataSz);
284 }
285
286 return err;
287 }
288
289 #ifndef WOLFSSL_HAVE_SP_ECC
290 /*
291 * Convert the KPAK to montgomery form.
292 *
293 * The KPAK is needed in Montgomery form for verification.
294 *
295 * @param [in] key ECCSI key.
296 * @return 0 on success.
297 * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
298 * @return Other -ve value when an internal operation fails.
299 */
eccsi_kpak_to_mont(EccsiKey * key)300 static int eccsi_kpak_to_mont(EccsiKey* key)
301 {
302 int err = 0;
303 ecc_point* kpak = &key->ecc.pubkey;
304 mp_int* mu = &key->tmp;
305 mp_int* prime = &key->params.prime;
306
307 if (!key->kpakMont) {
308 err = mp_montgomery_calc_normalization(mu, prime);
309 if (err == 0) {
310 err = mp_mulmod(kpak->x, mu, prime, kpak->x);
311 }
312 if (err == 0) {
313 err = mp_mulmod(kpak->y, mu, prime, kpak->y);
314 }
315 if (err == 0) {
316 err = mp_mulmod(kpak->z, mu, prime, kpak->z);
317 }
318 if (err == 0) {
319 key->kpakMont = 1;
320 }
321 }
322
323 return err;
324 }
325 #endif
326
327 /*
328 * Convert the KPAK from montgomery form.
329 *
330 * The KPAK is needed in Montgomery form for verification.
331 *
332 * @param [in] key ECCSI key.
333 * @return 0 on success.
334 * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
335 * @return Other -ve value when an internal operation fails.
336 */
eccsi_kpak_from_mont(EccsiKey * key)337 static int eccsi_kpak_from_mont(EccsiKey* key)
338 {
339 int err = 0;
340 ecc_point* kpak = &key->ecc.pubkey;
341 mp_digit mp;
342 mp_int* prime = &key->params.prime;
343
344 if (key->kpakMont) {
345 err = mp_montgomery_setup(prime, &mp);
346 if (err == 0) {
347 err = mp_montgomery_reduce(kpak->x, prime, mp);
348 }
349 if (err == 0) {
350 err = mp_montgomery_reduce(kpak->y, prime, mp);
351 }
352 if (err == 0) {
353 err = mp_montgomery_reduce(kpak->z, prime, mp);
354 }
355 if (err == 0) {
356 key->kpakMont = 0;
357 }
358 }
359
360 return err;
361 }
362
363 /*
364 * Compute HS = hash( G | KPAK | ID | PVT )
365 *
366 * Use when making a (SSK,PVT) pair, signing and verifying.
367 *
368 * @param [in] key ECCSI key.
369 * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256
370 * @param [in] id Identity to create hash from.
371 * @param [in] idSz Length of identity in bytes.
372 * @param [in] pvt Public Validation Token (PVT) as an ECC point.
373 * @param [out] hash Buffer to hold hash data.
374 * @param [out] hashSz Length of hash data in bytes.
375 * @return 0 on success.
376 * @return MEMORY_E when dynamic memory allocation fails.
377 * @return Other -ve value when an internal operation fails.
378 */
eccsi_compute_hs(EccsiKey * key,enum wc_HashType hashType,const byte * id,word32 idSz,ecc_point * pvt,byte * hash,byte * hashSz)379 static int eccsi_compute_hs(EccsiKey* key, enum wc_HashType hashType,
380 const byte* id, word32 idSz, ecc_point* pvt, byte* hash, byte* hashSz)
381 {
382 int err;
383 word32 dataSz = 0;
384 int idx = wc_ecc_get_curve_idx(key->ecc.dp->id);
385 ecc_point* kpak = &key->ecc.pubkey;
386
387 /* HS = hash( G | KPAK | ID | PVT ) */
388 err = wc_HashInit_ex(&key->hash, hashType, key->heap, INVALID_DEVID);
389 if (err == 0) {
390 /* Base Point - G */
391 dataSz = sizeof(key->data);
392 err = eccsi_encode_base(key, key->data, &dataSz);
393 }
394 if (err == 0) {
395 err = wc_HashUpdate(&key->hash, hashType, key->data, dataSz);
396 }
397 if (err == 0) {
398 err = eccsi_kpak_from_mont(key);
399 }
400 if (err == 0) {
401 dataSz = sizeof(key->data);
402 /* KPAK - public key */
403 err = wc_ecc_export_point_der(idx, kpak, key->data, &dataSz);
404 }
405 if (err == 0) {
406 err = wc_HashUpdate(&key->hash, hashType, key->data, dataSz);
407 }
408 if (err == 0) {
409 /* Id - Signer's ID */
410 err = wc_HashUpdate(&key->hash, hashType, id, idSz);
411 }
412 if (err == 0) {
413 dataSz = sizeof(key->data);
414 /* PVT - Public Validation Token */
415 err = wc_ecc_export_point_der(idx, pvt, key->data, &dataSz);
416 }
417 if (err == 0) {
418 /* PVT - Public Validation Token */
419 err = wc_HashUpdate(&key->hash, hashType, key->data, dataSz);
420 }
421 if (err == 0) {
422 err = wc_HashFinal(&key->hash, hashType, hash);
423 }
424
425 if (err == 0) {
426 *hashSz = (byte)wc_HashGetDigestSize(hashType);
427 }
428
429 return err;
430 }
431
432 #ifdef WOLFCRYPT_ECCSI_KMS
433 /**
434 * Generate KMS Secret Auth Key (KSAK) and KMS Public Auth Key (KPAK).
435 *
436 * RFC 6507, Section 4.2
437 *
438 * Called when establishing a new KMS.\n
439 * KSAK must be kept secret while KPAK is required by clients for signing
440 * and verifying.\n
441 * Export key using wc_ExportEccsiKey(), once generated, to reuse the key.\n
442 * Export KPAK using wc_ExportEccsiPublicKey(), once generate to send to
443 * clients.
444 *
445 * Creates a random private key and multiplies it by the base point to calculate
446 * the public key.
447 *
448 * @param [in] key ECCSI key.
449 * @param [in] rng Random number generator.
450 * @return 0 on success.
451 * @return BAD_FUNC_ARG when key or rng is NULL.
452 * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
453 * @return Other -ve value when an internal operation fails.
454 */
wc_MakeEccsiKey(EccsiKey * key,WC_RNG * rng)455 int wc_MakeEccsiKey(EccsiKey* key, WC_RNG* rng)
456 {
457 int err = 0;
458
459 if ((key == NULL) || (rng == NULL)) {
460 err = BAD_FUNC_ARG;
461 }
462
463 if (err == 0) {
464 err = wc_ecc_make_key_ex(rng, key->ecc.dp->size, &key->ecc,
465 key->ecc.dp->id);
466 }
467
468 return err;
469 }
470
471 /*
472 * Encode a point into a buffer.
473 *
474 * X and y ordinate of point concatenated. Each number is zero padded tosize.
475 * Descriptor byte (0x04) is prepended when not raw.
476 *
477 * @param [in] point ECC point to encode.
478 * @param [in] size Size of prime in bytes - maximum ordinate length.
479 * @param [out] data Buffer to hold encoded data.
480 * NULL when needing length of encoded data.
481 * @param [in,out] sz In, the size of the buffer in bytes.
482 * Out, the size of the encoded data in bytes.
483 * @param [in] raw On 0, prepend descriptor byte.
484 * On 1, only include ordinates.
485 * @return 0 on success.
486 * @return BAD_FUNC_ARG when key or sz is NULL.
487 * @return LENGTH_ONLY_E when data is NULL - sz will hold the size in bytes of
488 * the encoded data.
489 * @return BUFFER_E when size of buffer is too small.
490 */
eccsi_encode_point(ecc_point * point,word32 size,byte * data,word32 * sz,int raw)491 static int eccsi_encode_point(ecc_point* point, word32 size, byte* data,
492 word32* sz, int raw)
493 {
494 int err = 0;
495
496 if (data == NULL) {
497 *sz = size * 2 + !raw;
498 err = LENGTH_ONLY_E;
499 }
500 if ((err == 0) && (*sz < size * 2 + !raw)) {
501 err = BUFFER_E;
502 }
503
504 if (err == 0) {
505 if (!raw) {
506 data[0] = 0x04;
507 data++;
508 }
509
510 /* Write out the point's x ordinate into key size bytes. */
511 err = mp_to_unsigned_bin_len(point->x, data, size);
512 }
513 if (err == 0) {
514 data += size;
515 /* Write out the point's y ordinate into key size bytes. */
516 err = mp_to_unsigned_bin_len(point->y, data, size);
517 }
518 if (err == 0) {
519 *sz = size * 2 + !raw;
520 }
521
522 return err;
523 }
524
525 /*
526 * Decode the data into an ECC point.
527 *
528 * X and y ordinate of point concatenated. Each number is zero padded to
529 * key size. Supports prepended descriptor byte (0x04).
530 *
531 * @param [out] point ECC point to encode.
532 * @param [in] size Size of prime in bytes - maximum ordinate length.
533 * @param [in] data Encoded public key.
534 * @param [in] sz Size of the encoded public key in bytes.
535 * @return 0 on success.
536 * @return BAD_FUNC_ARG when key or z is NULL.
537 * @return BUFFER_E when size of data is not equal to the expected size.
538 * @return ASN_PARSE_E when format byte is invalid.
539 * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
540 */
eccsi_decode_point(ecc_point * point,word32 size,const byte * data,word32 sz)541 static int eccsi_decode_point(ecc_point* point, word32 size, const byte* data,
542 word32 sz)
543 {
544 int err = 0;
545
546 if ((sz != size * 2) && (sz != size * 2 + 1)) {
547 err = BUFFER_E;
548 }
549
550 if ((err == 0) && (sz & 1)) {
551 if (data[0] != 0x04) {
552 err = ASN_PARSE_E;
553 }
554 data++;
555 }
556
557 if (err == 0) {
558 /* Read the public key point's x value from key size bytes. */
559 err = mp_read_unsigned_bin(point->x, data, size);
560 }
561 if (err == 0) {
562 data += size;
563 /* Read the public key point's y value from key size bytes. */
564 err = mp_read_unsigned_bin(point->y, data, size);
565 }
566 if (err == 0) {
567 err = mp_set(point->z, 1);
568 }
569
570 return err;
571 }
572
573 /*
574 * Encode the ECCSI key.
575 *
576 * Encodes the private key as big-endian bytes of fixed length.
577 * Encodes the public key x and y ordinates as big-endian bytes of fixed length.
578 *
579 * @param [in] key ECCSI key.
580 * @param [out] data Buffer to hold encoded ECCSI key.
581 * @return 0 on success.
582 * @return MEMORY_E when dynamic memory allocation fails (WOLFSSL_SMALL_STACK).
583 */
eccsi_encode_key(EccsiKey * key,byte * data)584 static int eccsi_encode_key(EccsiKey* key, byte* data)
585 {
586 int err;
587 word32 sz = (word32)key->ecc.dp->size * 2;
588
589 /* Write out the secret value into key size bytes. */
590 err = mp_to_unsigned_bin_len(&key->ecc.k, data, key->ecc.dp->size);
591 if (err == 0) {
592 data += key->ecc.dp->size;
593 /* Write the public key. */
594 err = eccsi_encode_point(&key->ecc.pubkey, (word32)key->ecc.dp->size,
595 data, &sz, 1);
596 }
597
598 return err;
599 }
600
601 /**
602 * Export the ECCSI key as encoded public/private ECC key.
603 *
604 * Use when saving the KMS key pair.
605 *
606 * Private key, x ordinate of public key and y ordinate of public key
607 * concatenated. Each number is zero padded to key size.
608 *
609 * @param [in] key ECCSI key.
610 * @param [out] data Buffer to hold encoded ECCSI key.
611 * NULL when requesting required length.
612 * @param [in,out] sz On in, size of buffer in bytes.
613 * On out, size of encoded ECCSI key in bytes.
614 * @return 0 on success.
615 * @return BAD_FUNC_ARG when key or sz is NULL
616 * @return BAD_STATE_E when no key to export.
617 * @return LENGTH_ONLY_E when data is NULL - sz is set.
618 * @return BUFFER_E when the buffer passed in is too small.
619 * @return MEMORY_E when dynamic memory allocation fails (WOLFSSL_SMALL_STACK).
620 */
wc_ExportEccsiKey(EccsiKey * key,byte * data,word32 * sz)621 int wc_ExportEccsiKey(EccsiKey* key, byte* data, word32* sz)
622 {
623 int err = 0;
624
625 if ((key == NULL) || (sz == NULL)) {
626 err = BAD_FUNC_ARG;
627 }
628
629 if ((err == 0) && (key->ecc.type != ECC_PRIVATEKEY)) {
630 err = BAD_STATE_E;
631 }
632
633 if (err == 0) {
634 if (data == NULL) {
635 *sz = key->ecc.dp->size * 3;
636 err = LENGTH_ONLY_E;
637 }
638 else if (*sz < (word32)key->ecc.dp->size * 3) {
639 err = BUFFER_E;
640 }
641 else {
642 *sz = key->ecc.dp->size * 3;
643 }
644 }
645 if (err == 0) {
646 err = eccsi_kpak_from_mont(key);
647 }
648 if (err == 0) {
649 /* Encode key */
650 err = eccsi_encode_key(key, data);
651 }
652
653 return err;
654 }
655
656 /*
657 * Import the ECCSI key as encoded public/private ECC key.
658 *
659 * Decodes the private key as big-endian bytes of fixed length.
660 * Decodes the public key x and y ordinates as big-endian bytes of fixed length.
661 *
662 * @param [in] key ECCSI key.
663 * @param [in] data Buffer holding encoded ECCSI key.
664 * @return 0 on success.
665 * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
666 */
eccsi_decode_key(EccsiKey * key,const byte * data)667 static int eccsi_decode_key(EccsiKey* key, const byte* data)
668 {
669 int err;
670
671 /* Read the secret value from key size bytes. */
672 err = mp_read_unsigned_bin(&key->ecc.k, data, key->ecc.dp->size);
673 if (err == 0) {
674 data += key->ecc.dp->size;
675 /* Read public key. */
676 err = eccsi_decode_point(&key->ecc.pubkey, (word32)key->ecc.dp->size,
677 data, key->ecc.dp->size * 2);
678 }
679
680 return err;
681 }
682
683 /**
684 * Import the ECCSI key as encoded public/private ECC key.
685 *
686 * Use when restoring the KMS key pair.
687 *
688 * Private key, x ordinate of public key and y ordinate of public key
689 * concatenated. Each number is zero padded to key size.
690 *
691 * @param [in] key ECCSI key.
692 * @param [in] data Buffer holding encoded ECCSI key.
693 * @param [in] sz Size of encoded ECCSI key in bytes.
694 * @return 0 on success.
695 * @return BAD_FUNC_ARG when key or data is NULL.
696 * @return BUFFER_E when size of data is not equal to the expected size.
697 * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
698 */
wc_ImportEccsiKey(EccsiKey * key,const byte * data,word32 sz)699 int wc_ImportEccsiKey(EccsiKey* key, const byte* data, word32 sz)
700 {
701 int err = 0;
702
703 if ((key == NULL) || (data == NULL)) {
704 err = BAD_FUNC_ARG;
705 }
706 if ((err == 0) && (sz != (word32)key->ecc.dp->size * 3)) {
707 err = BUFFER_E;
708 }
709
710 if (err == 0) {
711 key->kpakMont = 0;
712
713 /* Decode key */
714 err = eccsi_decode_key(key, data);
715 }
716 if (err == 0) {
717 key->ecc.type = ECC_PRIVATEKEY;
718 }
719
720 return err;
721 }
722
723 /**
724 * Export the ECCSI private key.
725 *
726 * Use when saving the KMS key.
727 *
728 * Private key is zero padded to key size.
729 *
730 * @param [in] key ECCSI key.
731 * @param [out] data Buffer to hold encoded ECCSI private key.
732 * NULL when requesting required length.
733 * @param [in,out] sz On in, size of buffer in bytes.
734 * On out, size of encoded ECCSI private key in bytes.
735 * @return 0 on success.
736 * @return BAD_FUNC_ARG when key or sz is NULL
737 * @return BAD_STATE_E when no key to export.
738 * @return LENGTH_ONLY_E when data is NULL - sz is set.
739 * @return BUFFER_E when the buffer passed in is too small.
740 * @return MEMORY_E when dynamic memory allocation fails (WOLFSSL_SMALL_STACK).
741 */
wc_ExportEccsiPrivateKey(EccsiKey * key,byte * data,word32 * sz)742 int wc_ExportEccsiPrivateKey(EccsiKey* key, byte* data, word32* sz)
743 {
744 int err = 0;
745
746 if ((key == NULL) || (sz == NULL)) {
747 err = BAD_FUNC_ARG;
748 }
749
750 if ((err == 0) && (key->ecc.type != ECC_PRIVATEKEY)) {
751 err = BAD_STATE_E;
752 }
753
754 if (err == 0) {
755 if (data == NULL) {
756 *sz = key->ecc.dp->size;
757 err = LENGTH_ONLY_E;
758 }
759 else if (*sz < (word32)key->ecc.dp->size) {
760 err = BUFFER_E;
761 }
762 else {
763 *sz = key->ecc.dp->size;
764 }
765 }
766 if (err == 0) {
767 err = mp_to_unsigned_bin_len(&key->ecc.k, data, key->ecc.dp->size);
768 }
769
770 return err;
771 }
772
773 /**
774 * Import the ECCSI private key.
775 *
776 * Use when restoring the KMS key pair.
777 *
778 * Private key is zero padded to key size.
779 *
780 * @param [in] key ECCSI key.
781 * @param [in] data Buffer holding encoded ECCSI private key.
782 * @param [in] sz Size of encoded ECCSI private key in bytes.
783 * @return 0 on success.
784 * @return BAD_FUNC_ARG when key or data is NULL.
785 * @return BUFFER_E when size of data is not equal to the expected size.
786 * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
787 */
wc_ImportEccsiPrivateKey(EccsiKey * key,const byte * data,word32 sz)788 int wc_ImportEccsiPrivateKey(EccsiKey* key, const byte* data, word32 sz)
789 {
790 int err = 0;
791
792 if ((key == NULL) || (data == NULL)) {
793 err = BAD_FUNC_ARG;
794 }
795 if ((err == 0) && (sz != (word32)key->ecc.dp->size)) {
796 err = BUFFER_E;
797 }
798
799 if (err == 0) {
800 err = mp_read_unsigned_bin(&key->ecc.k, data, key->ecc.dp->size);
801 }
802
803 return err;
804 }
805
806 /**
807 * Export the KMS Public Auth Key (KPAK) from the ECCSI object.
808 *
809 * KPAK is required by all clients in order to perform cryptographic operations.
810 *
811 * X and y ordinate of public key concatenated. Each number is zero padded to
812 * key size.
813 * Descriptor byte (0x04) is prepended when not raw.
814 *
815 * @param [in] key ECCSI key.
816 * @param [out] data Buffer to hold the encoded public key.
817 * @param [in,out] sz On in, size of buffer in bytes.
818 * On out, length of encoded public key in bytes.
819 * @param [in] raw On 0, prepend descriptor byte.
820 * On 1, only include ordinates.
821 * @return 0 on success.
822 * @return BAD_FUNC_ARG when key or sz is NULL.
823 * @return LENGTH_ONLY_E when data is NULL - sz is set.
824 * @return BUFFER_E when the buffer passed in is too small.
825 */
wc_ExportEccsiPublicKey(EccsiKey * key,byte * data,word32 * sz,int raw)826 int wc_ExportEccsiPublicKey(EccsiKey* key, byte* data, word32* sz, int raw)
827 {
828 int err = 0;
829
830 if ((key == NULL) || (sz == NULL)) {
831 err = BAD_FUNC_ARG;
832 }
833 if ((err == 0) && (key->ecc.type != ECC_PRIVATEKEY) &&
834 (key->ecc.type != ECC_PUBLICKEY)) {
835 err = BAD_STATE_E;
836 }
837
838 if ((err == 0) && (data != NULL)) {
839 err = eccsi_kpak_from_mont(key);
840 }
841 if (err == 0) {
842 /* Write out public key. */
843 err = eccsi_encode_point(&key->ecc.pubkey, (word32)key->ecc.dp->size,
844 data, sz, raw);
845 }
846
847 return err;
848 }
849
850 /*
851 * Generates an (SSK, PVT) Pair - signing key pair.
852 *
853 * RFC 6507, Section 5.1.1
854 *
855 * @param [in] key ECCSI key.
856 * @param [in] rng Random number generator.
857 * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256
858 * @param [in] id Identity to create hash from.
859 * @param [in] idSz Length of identity in bytes.
860 * @param [out] ssk Secret Signing Key as an MP integer.
861 * @param [out] pvt Public Validation Token (PVT) as an ECC point.
862 * @return 0 on success.
863 * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
864 * @return Other -ve value when an internal operation fails.
865 */
eccsi_make_pair(EccsiKey * key,WC_RNG * rng,enum wc_HashType hashType,const byte * id,word32 idSz,mp_int * ssk,ecc_point * pvt)866 static int eccsi_make_pair(EccsiKey* key, WC_RNG* rng,
867 enum wc_HashType hashType, const byte* id, word32 idSz, mp_int* ssk,
868 ecc_point* pvt)
869 {
870 int err = 0;
871 byte hashSz = 0;
872 int genTryCnt = 0;
873
874 do {
875 /* Don't infinitely make pairs when random number generator fails. */
876 if ((++genTryCnt) > ECCSI_MAX_GEN_COUNT) {
877 err = RNG_FAILURE_E;
878 }
879
880 if (err == 0) {
881 wc_ecc_free(&key->pubkey);
882
883 /* Step 1 and 2: Generate ephemeral key - v, PVT = [v]G */
884 err = wc_ecc_make_key_ex(rng, key->ecc.dp->size, &key->pubkey,
885 key->ecc.dp->id);
886 }
887 if (err == 0) {
888 err = wc_ecc_copy_point(&key->pubkey.pubkey, pvt);
889 }
890
891 /* Step 3: Compute HS */
892 if (err == 0) {
893 hashSz = (byte)sizeof(key->data);
894 err = eccsi_compute_hs(key, hashType, id, idSz, pvt, key->data,
895 &hashSz);
896 }
897
898 /* Step 4: Compute SSK = ( KSAK + HS * v ) modulo q */
899 if (err == 0) {
900 err = mp_read_unsigned_bin(ssk, key->data, hashSz);
901 }
902 if (err == 0) {
903 err = mp_mulmod(ssk, &key->pubkey.k, &key->params.order, ssk);
904 }
905 if (err == 0) {
906 err = mp_addmod(ssk, &key->ecc.k, &key->params.order, ssk);
907 }
908 }
909 while ((err == 0) && (mp_iszero(ssk) ||
910 (mp_cmp(ssk, &key->ecc.k) == MP_EQ)));
911 /* Step 5: ensure SSK and HS are non-zero (code lines above) */
912
913 /* Step 6: Copy out SSK (done during calc) and PVT. Erase v */
914 mp_forcezero(&key->pubkey.k);
915
916 return err;
917 }
918
919 /**
920 * Generates an (SSK, PVT) Pair - signing key pair.
921 *
922 * RFC 6507, Section 5.1.1
923 *
924 * ID should include information to indicate a revocation date.\n
925 * SSK must be zeroized after sending to client.\n
926 * SSK is sent to signing client only.\n
927 * PVT is sent to all client types.
928 *
929 * @param [in] key ECCSI key.
930 * @param [in] rng Random number generator.
931 * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256
932 * @param [in] id Identity to create hash from.
933 * @param [in] idSz Length of identity in bytes.
934 * @param [out] ssk Secret Signing Key as an MP integer.
935 * @param [out] pvt Public Validation Token (PVT) as an ECC point.
936 * @return 0 on success.
937 * @return BAD_FUNC_ARG when key, rng, id, ssk or pvt is NULL.
938 * @return BAD_STATE_E when curve not set (key not set).
939 * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
940 * @return Other -ve value when an internal operation fails.
941 */
wc_MakeEccsiPair(EccsiKey * key,WC_RNG * rng,enum wc_HashType hashType,const byte * id,word32 idSz,mp_int * ssk,ecc_point * pvt)942 int wc_MakeEccsiPair(EccsiKey* key, WC_RNG* rng, enum wc_HashType hashType,
943 const byte* id, word32 idSz, mp_int* ssk, ecc_point* pvt)
944 {
945 int err = 0;
946
947 if ((key == NULL) || (rng == NULL) || (id == NULL) || (ssk == NULL) ||
948 (pvt == NULL)) {
949 err = BAD_FUNC_ARG;
950 }
951 if ((err == 0) && (key->ecc.type != ECC_PRIVATEKEY)) {
952 err = BAD_STATE_E;
953 }
954
955 if (err == 0) {
956 err = eccsi_load_order(key);
957 }
958 if (err == 0) {
959 err = eccsi_make_pair(key, rng, hashType, id, idSz, ssk, pvt);
960 }
961
962 return err;
963 }
964
965 /**
966 * Encode the SSK and PVT into a buffer.
967 *
968 * SSK and PVT required by client signing messages.
969 *
970 * @param [in] key ECCSI key.
971 * @param [in] ssk Secret Signing Key as an MP integer.
972 * @param [in] pvt Public Validation Token (PVT) as an ECC point.
973 * @param [out] data Buffer to encode key pair into.
974 * @param [in,out] sz In, size of buffer in bytes.
975 * Out, size of encoded pair data in bytes.
976 * @return 0 on success.
977 * @return BAD_FUNC_ARG when key, ssk, pvt or sz is NULL.
978 * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
979 * @return LENGTH_ONLY_E when data is NULL - sz is set.
980 */
wc_EncodeEccsiPair(const EccsiKey * key,mp_int * ssk,ecc_point * pvt,byte * data,word32 * sz)981 int wc_EncodeEccsiPair(const EccsiKey* key, mp_int* ssk, ecc_point* pvt,
982 byte* data, word32* sz)
983 {
984 int err = 0;
985
986 if ((key == NULL) || (ssk == NULL) || (pvt == NULL) || (sz == NULL)) {
987 err = BAD_FUNC_ARG;
988 }
989
990 if ((err == 0) && (data == NULL)) {
991 *sz = key->ecc.dp->size * 3;
992 err = LENGTH_ONLY_E;
993 }
994 if ((err == 0) && (*sz < (word32)(key->ecc.dp->size * 3))) {
995 err = BUFFER_E;
996 }
997
998 if (err == 0) {
999 err = mp_to_unsigned_bin_len(ssk, data, key->ecc.dp->size);
1000 }
1001 if (err == 0) {
1002 data += key->ecc.dp->size;
1003 /* Write out the PVT's x ordinate into key size bytes. */
1004 err = mp_to_unsigned_bin_len(pvt->x, data, key->ecc.dp->size);
1005 }
1006 if (err == 0) {
1007 data += key->ecc.dp->size;
1008 /* Write out the PVT's y ordinate into key size bytes. */
1009 err = mp_to_unsigned_bin_len(pvt->y, data, key->ecc.dp->size);
1010 }
1011 if (err == 0) {
1012 *sz = key->ecc.dp->size * 3;
1013 }
1014
1015 return err;
1016 }
1017
1018 /**
1019 * Encode the Secret Signing Key (SSK).
1020 *
1021 * Use when saving the key pair.
1022 *
1023 * SSK is zero padded to key size.
1024 *
1025 * @param [in] key ECCSI key.
1026 * @param [in] ssk Secret Signing Key as an MP integer.
1027 * @param [out] data Buffer to hold encoded SSK.
1028 * NULL when requesting required length.
1029 * @param [in,out] sz On in, size of buffer in bytes.
1030 * On out, size of encoded ECCSI key in bytes.
1031 * @return 0 on success.
1032 * @return BAD_FUNC_ARG when key, ssk or sz is NULL
1033 * @return BAD_STATE_E when no key to export.
1034 * @return LENGTH_ONLY_E when data is NULL - sz is set.
1035 * @return BUFFER_E when the buffer passed in is too small.
1036 * @return MEMORY_E when dynamic memory allocation fails (WOLFSSL_SMALL_STACK).
1037 */
wc_EncodeEccsiSsk(const EccsiKey * key,mp_int * ssk,byte * data,word32 * sz)1038 int wc_EncodeEccsiSsk(const EccsiKey* key, mp_int* ssk, byte* data, word32* sz)
1039 {
1040 int err = 0;
1041
1042 if ((key == NULL) || (ssk == NULL) || (sz == NULL)) {
1043 err = BAD_FUNC_ARG;
1044 }
1045
1046 if ((err == 0) && (key->ecc.type != ECC_PRIVATEKEY)) {
1047 err = BAD_STATE_E;
1048 }
1049
1050 if (err == 0) {
1051 if (data == NULL) {
1052 *sz = key->ecc.dp->size;
1053 err = LENGTH_ONLY_E;
1054 }
1055 else if (*sz < (word32)key->ecc.dp->size) {
1056 err = BUFFER_E;
1057 }
1058 else {
1059 *sz = key->ecc.dp->size;
1060 }
1061 }
1062 if (err == 0) {
1063 err = mp_to_unsigned_bin_len(ssk, data, key->ecc.dp->size);
1064 }
1065
1066 return err;
1067 }
1068
1069 /**
1070 * Decode the Secret Signing Key (SSK).
1071 *
1072 * Use when restoring the key pair.
1073 *
1074 * SSK is zero padded to key size.
1075 *
1076 * @param [in] key ECCSI key.
1077 * @param [in] data Buffer holding encoded ECCSI key.
1078 * @param [in] sz Size of encoded ECCSI key in bytes.
1079 * @param [out] ssk Secret Signing Key as an MP integer.
1080 * @return 0 on success.
1081 * @return BAD_FUNC_ARG when key, data or ssk is NULL.
1082 * @return BUFFER_E when size of data is not equal to the expected size.
1083 * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
1084 */
wc_DecodeEccsiSsk(const EccsiKey * key,const byte * data,word32 sz,mp_int * ssk)1085 int wc_DecodeEccsiSsk(const EccsiKey* key, const byte* data, word32 sz,
1086 mp_int* ssk)
1087 {
1088 int err = 0;
1089
1090 if ((key == NULL) || (data == NULL) || (ssk == NULL)) {
1091 err = BAD_FUNC_ARG;
1092 }
1093 if ((err == 0) && (sz != (word32)key->ecc.dp->size)) {
1094 err = BUFFER_E;
1095 }
1096
1097 if (err == 0) {
1098 err = mp_read_unsigned_bin(ssk, data, key->ecc.dp->size);
1099 }
1100
1101 return err;
1102 }
1103
1104 /**
1105 * Encode the PVT into a buffer.
1106 *
1107 * PVT required by client verifying messages.
1108 *
1109 * X and y ordinate of public key concatenated. Each number is zero padded to
1110 * key size.
1111 * Descriptor byte (0x04) is prepended when not raw.
1112 *
1113 * @param [in] key ECCSI key.
1114 * @param [in] pvt Public Validation Token (PVT) as an ECC point.
1115 * @param [out] data Buffer to encode key pair into.
1116 * @param [in,out] sz In, size of buffer in bytes.
1117 * Out, size of encoded pair data in bytes.
1118 * @param [in] raw On 0, prepend descriptor byte.
1119 * On 1, only include ordinates.
1120 * @return 0 on success.
1121 * @return BAD_FUNC_ARG when key, pvt or sz is NULL.
1122 * @return BAD_STATE_E when PVT has not been set.
1123 * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
1124 * @return LENGTH_ONLY_E when data is NULL - sz is set.
1125 */
wc_EncodeEccsiPvt(const EccsiKey * key,ecc_point * pvt,byte * data,word32 * sz,int raw)1126 int wc_EncodeEccsiPvt(const EccsiKey* key, ecc_point* pvt, byte* data,
1127 word32* sz, int raw)
1128 {
1129 int err = 0;
1130
1131 if ((key == NULL) || (pvt == NULL) || (sz == NULL)) {
1132 err = BAD_FUNC_ARG;
1133 }
1134
1135 if (err == 0) {
1136 err = eccsi_encode_point(pvt, (word32)key->ecc.dp->size, data, sz, raw);
1137 }
1138
1139 return err;
1140 }
1141
1142 #endif /* WOLFCRYPT_ECCSI_KMS */
1143
1144 #ifdef WOLFCRYPT_ECCSI_CLIENT
1145 /**
1146 * Decode the SSK and PVT data into separate variables.
1147 *
1148 * A signing client decodes the data so that it can validate the pair and sign.
1149 *
1150 * @param [in] key ECCSI key.
1151 * @param [in] data Buffer holding key pair data.
1152 * @param [in] sz Size of data in bytes.
1153 * @param [out] ssk Secret Signing Key as an MP integer.
1154 * @param [out] pvt Public Validation Token (PVT) as an ECC point.
1155 * @return 0 on success.
1156 * @return BAD_FUNC_ARG when key, data, ssk or pvt is NULL.
1157 * @return LENGTH_ONLY_E when data is NULL - sz is set.
1158 * @return BUFFER_E when size of data is not equal to the expected size.
1159 * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
1160 */
wc_DecodeEccsiPair(const EccsiKey * key,const byte * data,word32 sz,mp_int * ssk,ecc_point * pvt)1161 int wc_DecodeEccsiPair(const EccsiKey* key, const byte* data, word32 sz,
1162 mp_int* ssk, ecc_point* pvt)
1163 {
1164 int err = 0;
1165
1166 if ((key == NULL) || (data == NULL) || (ssk == NULL) || (pvt == NULL)) {
1167 err = BAD_FUNC_ARG;
1168 }
1169 if ((err == 0) && (sz != (word32)(key->ecc.dp->size * 3))) {
1170 err = BUFFER_E;
1171 }
1172
1173 if (err == 0) {
1174 /* Read the SSK value from key size bytes. */
1175 err = mp_read_unsigned_bin(ssk, data, key->ecc.dp->size);
1176 }
1177 if (err == 0) {
1178 data += key->ecc.dp->size;
1179 /* Read the PVT's x value from key size bytes. */
1180 err = mp_read_unsigned_bin(pvt->x, data, key->ecc.dp->size);
1181 }
1182 if (err == 0) {
1183 data += key->ecc.dp->size;
1184 /* Read the PVT's y value from key size bytes. */
1185 err = mp_read_unsigned_bin(pvt->y, data, key->ecc.dp->size);
1186 }
1187 if (err == 0) {
1188 err = mp_set(pvt->z, 1);
1189 }
1190
1191 return err;
1192 }
1193
1194 /**
1195 * Decode the PVT data into an ECC point.
1196 *
1197 * A verifying client decodes the data so that it can verify a message.
1198 *
1199 * X and y ordinate of public key concatenated. Each number is zero padded to
1200 * key size.
1201 * Descriptor byte (0x04) is prepended when not raw.
1202 *
1203 * @param [in] key ECCSI key.
1204 * @param [in] data Buffer holding PVT data.
1205 * @param [in] sz Size of data in bytes.
1206 * @param [out] pvt Public Validation Token (PVT) as an ECC point.
1207 * @return 0 on success.
1208 * @return BAD_FUNC_ARG when key, data, ssk or pvt is NULL.
1209 * @return BUFFER_E when size of data is not equal to the expected size.
1210 * @return ASN_PARSE_E when format byte is invalid.
1211 * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
1212 */
wc_DecodeEccsiPvt(const EccsiKey * key,const byte * data,word32 sz,ecc_point * pvt)1213 int wc_DecodeEccsiPvt(const EccsiKey* key, const byte* data, word32 sz,
1214 ecc_point* pvt)
1215 {
1216 int err = 0;
1217
1218 if ((key == NULL) || (data == NULL) || (pvt == NULL)) {
1219 err = BAD_FUNC_ARG;
1220 }
1221
1222 if (err == 0) {
1223 err = eccsi_decode_point(pvt, (word32)key->ecc.dp->size, data, sz);
1224 }
1225
1226 return err;
1227 }
1228
1229 /**
1230 * Decode the PVT data, from a signature, into an ECC point.
1231 *
1232 * A verifying client decodes the data so that it can calculate the identity
1233 * hash.
1234 *
1235 * X and y ordinate of public key concatenated. Each number is zero padded to
1236 * key size.
1237 * Descriptor byte (0x04) is prepended when not raw.
1238 *
1239 * @param [in] key ECCSI key.
1240 * @param [in] sig Buffer holding signature data.
1241 * @param [in] sz Size of data in bytes.
1242 * @param [out] pvt Public Validation Token (PVT) as an ECC point.
1243 * @return 0 on success.
1244 * @return BAD_FUNC_ARG when key, data, ssk or pvt is NULL.
1245 * @return BUFFER_E when size of data is not equal to the expected size.
1246 * @return ASN_PARSE_E when format byte is invalid.
1247 * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
1248 */
wc_DecodeEccsiPvtFromSig(const EccsiKey * key,const byte * sig,word32 sz,ecc_point * pvt)1249 int wc_DecodeEccsiPvtFromSig(const EccsiKey* key, const byte* sig, word32 sz,
1250 ecc_point* pvt)
1251 {
1252 int err = 0;
1253
1254 if ((key == NULL) || (sig == NULL) || (pvt == NULL)) {
1255 err = BAD_FUNC_ARG;
1256 }
1257
1258 if (err == 0) {
1259 word32 rSz = key->ecc.dp->size * 2;
1260 err = eccsi_decode_point(pvt, (word32)key->ecc.dp->size, sig + rSz,
1261 sz - rSz);
1262 }
1263
1264 return err;
1265 }
1266
1267 /**
1268 * Import the KMS Public Auth Key (KPAK) into the ECCSI object.
1269 *
1270 * Clients import the KPAK to perform cryptographic operations.
1271 *
1272 * X and y ordinate of public key concatenated. Each number is zero padded to
1273 * key size.
1274 * Descriptor byte (0x04) is prepended when not raw.
1275 *
1276 * @param [in] key ECCSI key.
1277 * @param [in] data Encoded public key as an array of bytes.
1278 * @param [in] sz Length of encoded KPAK in bytes.
1279 * @param [in] trusted 1 when public key is trusted.
1280 * 0 when validation is required to be performed.
1281 * @return 0 on success.
1282 * @return BAD_FUNC_ARG when key or data is NULL.
1283 * @return BUFFER_E when size of data is not equal to the expected size.
1284 * @return ASN_PARSE_E when format byte is invalid.
1285 * @return ECC_OUT_OF_RANGE_E when point is invalid.
1286 * @return ECC_INF_E when point is at infinity and invalid.
1287 * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
1288 */
wc_ImportEccsiPublicKey(EccsiKey * key,const byte * data,word32 sz,int trusted)1289 int wc_ImportEccsiPublicKey(EccsiKey* key, const byte* data, word32 sz,
1290 int trusted)
1291 {
1292 int err = 0;
1293
1294 if ((key == NULL) || (data == NULL)) {
1295 err = BAD_FUNC_ARG;
1296 }
1297
1298 if (err == 0) {
1299 key->kpakMont = 0;
1300
1301 /* Read the public key. */
1302 err = eccsi_decode_point(&key->ecc.pubkey, (word32)key->ecc.dp->size,
1303 data, sz);
1304 }
1305 if (err == 0) {
1306 key->ecc.type = ECC_PUBLICKEY;
1307 }
1308 if ((err == 0) && (!trusted)) {
1309 err = wc_ecc_check_key(&key->ecc);
1310 }
1311
1312 return err;
1313 }
1314
1315 /*
1316 * Scalar multiply the base point of the curve and add a point.
1317 *
1318 * @param [in] key ECCSI key.
1319 * @param [in] n MP integer representing scalar to multiply by.
1320 * @param [in] a ECC point to add.
1321 * @param [out] res ECC point representation of the resulting point.
1322 * @param [in] mp Montgomery reduction multiplier.
1323 * @param [in] map 0 indicates to leave in projective representation.
1324 * 1 indicates map projective point to affine.
1325 * @return 0 on success.
1326 * @return MEMORY_E when dynamic memory allocation fails.
1327 * @return Other -ve value when an internal operation fails.
1328 */
eccsi_mulmod_base_add(EccsiKey * key,const mp_int * n,ecc_point * a,ecc_point * res,mp_digit mp,int map)1329 static int eccsi_mulmod_base_add(EccsiKey* key, const mp_int* n,
1330 ecc_point* a, ecc_point* res, mp_digit mp, int map)
1331 {
1332 int err = 0;
1333
1334 #ifdef WOLFSSL_HAVE_SP_ECC
1335 #ifndef WOLFSSL_SP_NO_256
1336 if ((key->ecc.idx != ECC_CUSTOM_IDX) &&
1337 (ecc_sets[key->ecc.idx].id == ECC_SECP256R1)) {
1338 err = sp_ecc_mulmod_base_add_256(n, a, 1, res, map, key->heap);
1339 }
1340 else
1341 #endif
1342 #endif
1343 #ifndef WOLFSSL_SP_MATH
1344 {
1345 EccsiKeyParams* params = &key->params;
1346 err = wc_ecc_mulmod(n, params->base, params->base, ¶ms->a,
1347 ¶ms->prime, 0);
1348 key->params.haveBase = 0;
1349 if (err == 0) {
1350 err = ecc_projective_add_point(params->base, a, res, ¶ms->a,
1351 ¶ms->prime, mp);
1352 }
1353 if ((err == 0) && map) {
1354 err = ecc_map(res, ¶ms->prime, mp);
1355 }
1356 }
1357 #else
1358 {
1359 err = NOT_COMPILED_IN;
1360 }
1361 (void)mp;
1362 #endif
1363
1364 return err;
1365 }
1366
1367 /*
1368 * Scalar multiply a point on the curve.
1369 *
1370 * @param [in] key ECCSI key.
1371 * @param [in] n MP integer representing scalar to multiply by.
1372 * @param [in] point ECC point representation of a point on the curve.
1373 * @param [out] res ECC point representation of the resulting point.
1374 * @param [in] map 0 indicates to leave in projective representation.
1375 * 1 indicates map projective point to affine.
1376 * @return 0 on success.
1377 * @return MEMORY_E when dynamic memory allocation fails.
1378 * @return Other -ve value when an internal operation fails.
1379 */
eccsi_mulmod_point(EccsiKey * key,const mp_int * n,ecc_point * point,ecc_point * res,int map)1380 static int eccsi_mulmod_point(EccsiKey* key, const mp_int* n, ecc_point* point,
1381 ecc_point* res, int map)
1382 {
1383 int err;
1384
1385 #ifdef WOLFSSL_HAVE_SP_ECC
1386 #ifndef WOLFSSL_SP_NO_256
1387 if ((key->ecc.idx != ECC_CUSTOM_IDX) &&
1388 (ecc_sets[key->ecc.idx].id == ECC_SECP256R1)) {
1389 err = sp_ecc_mulmod_256(n, point, res, map, key->heap);
1390 }
1391 else
1392 #endif
1393 #endif
1394 {
1395 EccsiKeyParams* params = &key->params;
1396
1397 err = wc_ecc_mulmod(n, point, res, ¶ms->a, ¶ms->prime, map);
1398 }
1399
1400 return err;
1401 }
1402
1403 /*
1404 * Scalar multiply a point on the curve and add a.
1405 *
1406 * @param [in] key ECCSI key.
1407 * @param [in] n MP integer representing scalar to multiply by.
1408 * @param [in] point ECC point representation of a point on the curve.
1409 * @param [in] a ECC point to add.
1410 * @param [out] res ECC point representation of the resulting point.
1411 * @param [in] mp Montgomery reduction multiplier.
1412 * @param [in] map 0 indicates to leave in projective representation.
1413 * 1 indicates map projective point to affine.
1414 * @return 0 on success.
1415 * @return MEMORY_E when dynamic memory allocation fails.
1416 * @return Other -ve value when an internal operation fails.
1417 */
eccsi_mulmod_point_add(EccsiKey * key,const mp_int * n,ecc_point * point,ecc_point * a,ecc_point * res,mp_digit mp,int map)1418 static int eccsi_mulmod_point_add(EccsiKey* key, const mp_int* n,
1419 ecc_point* point, ecc_point* a, ecc_point* res, mp_digit mp, int map)
1420 {
1421 #ifdef WOLFSSL_HAVE_SP_ECC
1422 #ifndef WOLFSSL_SP_NO_256
1423 int err = NOT_COMPILED_IN;
1424
1425 if ((key->ecc.idx != ECC_CUSTOM_IDX) &&
1426 (ecc_sets[key->ecc.idx].id == ECC_SECP256R1)) {
1427 err = sp_ecc_mulmod_add_256(n, point, a, 0, res, map, key->heap);
1428 }
1429
1430 (void)mp;
1431
1432 return err;
1433 #endif
1434 #else
1435 int err;
1436 EccsiKeyParams* params = &key->params;
1437
1438 err = wc_ecc_mulmod(n, point, res, ¶ms->a, ¶ms->prime, 0);
1439 if (err == 0) {
1440 err = ecc_projective_add_point(res, a, res, &key->params.a,
1441 ¶ms->prime, mp);
1442 }
1443 if ((err == 0) && map) {
1444 err = ecc_map(res, ¶ms->prime, mp);
1445 }
1446
1447 return err;
1448 #endif
1449 }
1450
1451 /**
1452 * Validate an (SSV, PVT) Pair.
1453 *
1454 * RFC 6507, Section 5.1.2
1455 *
1456 * A signing client should validate the key pair before first use.
1457 *
1458 * @param [in] key ECCSI key.
1459 * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256
1460 * @param [in] id Identity to create hash from.
1461 * @param [in] idSz Length of identity in bytes.
1462 * @param [in] ssk Secret Signing Key as an MP integer.
1463 * @param [in] pvt Public Validation Token (PVT) as an ECC point.
1464 * @param [out] valid 1 when pair is valid and 0 otherwise.
1465 * @return 0 on success.
1466 * @return BAD_FUNC_ARG when key, id, ssk, pvt or valid is NULL.
1467 * @return BAD_STATE_E when curve not set (key not set).
1468 * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
1469 * @return IS_POINT_E when point is not on the curve.
1470 * @return Other -ve value when an internal operation fails.
1471 */
wc_ValidateEccsiPair(EccsiKey * key,enum wc_HashType hashType,const byte * id,word32 idSz,const mp_int * ssk,ecc_point * pvt,int * valid)1472 int wc_ValidateEccsiPair(EccsiKey* key, enum wc_HashType hashType,
1473 const byte* id, word32 idSz, const mp_int* ssk, ecc_point* pvt,
1474 int* valid)
1475 {
1476 int err = 0;
1477 ecc_point* res = NULL;
1478 mp_int* hs = NULL;
1479 mp_digit mp = 0;
1480 byte hashSz = 0;
1481 EccsiKeyParams* params = NULL;
1482
1483 if ((key == NULL) || (id == NULL) || (ssk == NULL) || (pvt == NULL) ||
1484 (valid == NULL)) {
1485 err = BAD_FUNC_ARG;
1486 }
1487
1488 if ((err == 0) && (key->ecc.type != ECC_PRIVATEKEY) &&
1489 (key->ecc.type != ECC_PUBLICKEY)) {
1490 err = BAD_STATE_E;
1491 }
1492
1493 if (err != 0)
1494 return err;
1495
1496 SAVE_VECTOR_REGISTERS(return _svr_ret;);
1497
1498 params = &key->params;
1499 hs = &key->tmp;
1500 res = &key->pubkey.pubkey;
1501
1502 err = eccsi_load_base(key);
1503
1504 if (err == 0) {
1505 err = eccsi_load_ecc_params(key);
1506 }
1507 if (err == 0) {
1508 err = mp_montgomery_setup(¶ms->prime, &mp);
1509 }
1510
1511 /* Step 1: Validate PVT is on curve */
1512 if (err == 0) {
1513 err = wc_ecc_is_point(pvt, ¶ms->a, ¶ms->b, ¶ms->prime);
1514 if (err == -1) {
1515 err = IS_POINT_E;
1516 }
1517 }
1518
1519 /* Step 2: Compute HS = hash( G | KPAK | ID | PVT ) */
1520 if (err == 0) {
1521 hashSz = (byte)sizeof(key->data);
1522 /* Converts KPAK from mont. */
1523 err = eccsi_compute_hs(key, hashType, id, idSz, pvt, key->data,
1524 &hashSz);
1525 }
1526
1527 /* Step 3: Validate that KPAK = [SSK]G - [HS]PVT */
1528 if (err == 0) {
1529 err = mp_read_unsigned_bin(hs, key->data, hashSz);
1530 }
1531 /* [HS]PVT */
1532 if (err == 0) {
1533 err = eccsi_mulmod_point(key, hs, pvt, res, 0);
1534 }
1535 /* -[HS]PVT */
1536 if (err == 0) {
1537 err = mp_sub(¶ms->prime, res->y, res->y);
1538 }
1539 /* [SSK]G + -[HS]PVT */
1540 if (err == 0) {
1541 err = eccsi_mulmod_base_add(key, ssk, res, res, mp, 1);
1542 }
1543 if (valid != NULL) {
1544 *valid = (err == 0);
1545 if (err == 0) {
1546 ecc_point* kpak = &key->ecc.pubkey;
1547 /* Compare KPAK and [SSK]G + -[HS]PVT */
1548 *valid = (wc_ecc_cmp_point(res, kpak) == MP_EQ);
1549 }
1550 }
1551
1552 RESTORE_VECTOR_REGISTERS();
1553
1554 return err;
1555 }
1556
1557 /**
1558 * Validate Public Validation Token (PVT) is on the curve.
1559 *
1560 * RFC 6507, Section 5.1.2, Step 1
1561 *
1562 * A verifying client should validate the PVT before first use.
1563 *
1564 * @param [in] key ECCSI key.
1565 * @param [in] pvt Public Validation Token (PVT) as an ECC point.
1566 * @param [out] valid 1 when PVT is valid and 0 otherwise.
1567 * @return 0 on success.
1568 * @return BAD_FUNC_ARG when key, pvt or valid is NULL.
1569 * @return BAD_STATE_E when curve not set (key not set).
1570 * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
1571 * @return Other -ve value when an internal operation fails.
1572 */
wc_ValidateEccsiPvt(EccsiKey * key,const ecc_point * pvt,int * valid)1573 int wc_ValidateEccsiPvt(EccsiKey* key, const ecc_point* pvt, int* valid)
1574 {
1575 int err = 0;
1576
1577 if ((key == NULL)| (pvt == NULL) || (valid == NULL)) {
1578 err = BAD_FUNC_ARG;
1579 }
1580
1581 if (err == 0) {
1582 err = wc_ecc_set_curve(&key->pubkey, key->ecc.dp->size,
1583 key->ecc.dp->id);
1584 }
1585 if (err == 0) {
1586 err = wc_ecc_copy_point(pvt, &key->pubkey.pubkey);
1587 }
1588 if (err == 0) {
1589 *valid = (wc_ecc_check_key(&key->pubkey) == 0);
1590 }
1591
1592 return err;
1593 }
1594
1595 /**
1596 * Creates the Hash of the ID and PVT with the ECCSI key.
1597 *
1598 * The hash ID is required as input to the sign and verify operations.\n
1599 * Signing clients may cache this value.
1600 *
1601 * RFC 6507, Section 5.2.1, Step 3
1602 *
1603 * Set the calculated hash internally for use.
1604 *
1605 * @param [in] key ECCSI key.
1606 * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256
1607 * @param [in] id Identity to create hash from.
1608 * @param [in] idSz Length of identity in bytes.
1609 * @param [in] pvt Public Validation Token (PVT) as an ECC point.
1610 * @param [out] hash Buffer to hold hash result.
1611 * @param [out] hashSz Length of hash data in bytes.
1612 * @return 0 on success.
1613 * @return BAD_FUNC_ARG when key, id, pvt, hash or hashSz is NULL.
1614 * @return BAD_STATE_E when public key not set.
1615 * @return MEMORY_E when dynamic memory allocation fails.
1616 * @return Other -ve value when an internal operation fails.
1617 */
wc_HashEccsiId(EccsiKey * key,enum wc_HashType hashType,const byte * id,word32 idSz,ecc_point * pvt,byte * hash,byte * hashSz)1618 int wc_HashEccsiId(EccsiKey* key, enum wc_HashType hashType, const byte* id,
1619 word32 idSz, ecc_point* pvt, byte* hash, byte* hashSz)
1620 {
1621 int err = 0;
1622
1623 if ((key == NULL) || (id == NULL) || (pvt == NULL) || (hash == NULL) ||
1624 (hashSz == NULL)) {
1625 err = BAD_FUNC_ARG;
1626 }
1627 if ((err == 0) && (key->ecc.type != ECC_PRIVATEKEY) &&
1628 (key->ecc.type != ECC_PUBLICKEY)) {
1629 err = BAD_STATE_E;
1630 }
1631 /* Load the curve parameters for operations */
1632 if (err == 0) {
1633 err = eccsi_load_ecc_params(key);
1634 }
1635 if (err == 0) {
1636 err = eccsi_compute_hs(key, hashType, id, idSz, pvt, hash, hashSz);
1637 }
1638 if (err == 0) {
1639 XMEMCPY(key->idHash, hash, *hashSz);
1640 key->idHashSz = *hashSz;
1641 }
1642
1643 return err;
1644 }
1645
1646 /**
1647 * Set the identity hash for use with signing/verification.
1648 *
1649 * @param [in] key ECCSI key.
1650 * @param [in] hash Buffer with hash of identity.
1651 * @param [in] hashSz Length of hash data in bytes.
1652 * @return 0 on success.
1653 * @return BAD_FUNC_ARG when key or hash is NULL, or hashSz is greater than
1654 * WC_MAX_DIGEST_SIZE.
1655 */
wc_SetEccsiHash(EccsiKey * key,const byte * hash,byte hashSz)1656 int wc_SetEccsiHash(EccsiKey* key, const byte* hash, byte hashSz)
1657 {
1658 int err = 0;
1659
1660 if ((key == NULL) || (hash == NULL) || (hashSz > WC_MAX_DIGEST_SIZE)) {
1661 err = BAD_FUNC_ARG;
1662 }
1663 if (err == 0) {
1664 XMEMCPY(key->idHash, hash, hashSz);
1665 key->idHashSz = hashSz;
1666 }
1667
1668 return err;
1669 }
1670
1671 /**
1672 * Set an (SSV, PVT) Pair for signing.
1673 *
1674 * @param [in] key ECCSI key.
1675 * @param [in] ssk Secret Signing Key as an MP integer.
1676 * @param [in] pvt Public Validation Token (PVT) as an ECC point.
1677 * @return 0 on success.
1678 * @return BAD_FUNC_ARG when key, ssk or pvt is NULL.
1679 * @return MP math errors when copy fails
1680 */
wc_SetEccsiPair(EccsiKey * key,const mp_int * ssk,const ecc_point * pvt)1681 int wc_SetEccsiPair(EccsiKey* key, const mp_int* ssk, const ecc_point* pvt)
1682 {
1683 int err = 0;
1684
1685 if ((key == NULL) || (ssk == NULL) || (pvt == NULL)) {
1686 err = BAD_FUNC_ARG;
1687 }
1688
1689 if (err == 0) {
1690 err = mp_copy(ssk, &key->ssk);
1691 }
1692
1693 if (err == 0) {
1694 err = wc_ecc_copy_point(pvt, key->pvt);
1695 }
1696
1697 return err;
1698 }
1699
1700 #ifdef ECCSI_ORDER_MORE_BITS_THAN_PRIME
1701 /*
1702 * Fit the number to the maximum number of bytes.
1703 *
1704 * If the number is too big then subtract from order.
1705 * RFC 6507, Section 5.2.1, Note at end.
1706 * This should only happen when order is larger than prime in bits.
1707 *
1708 * @param [in] a MP integer to fix.
1709 * @param [in] order MP integer representing order of curve.
1710 * @param [in] max Maximum number of bytes to encode into.
1711 * @param [out] r MP integer that is the result after fixing.
1712 * @return 0 on success.
1713 * @return MEMORY_E when dynamic memory allocation fails.
1714 */
eccsi_fit_to_octets(const mp_int * a,mp_int * order,int max,mp_int * r)1715 static int eccsi_fit_to_octets(const mp_int* a, mp_int* order, int max,
1716 mp_int* r)
1717 {
1718 int err;
1719
1720 if (mp_count_bits(a) > max * 8) {
1721 err = mp_sub(order, (mp_int*)a, r);
1722 }
1723 else
1724 {
1725 err = mp_copy(a, r);
1726 }
1727
1728 return err;
1729 }
1730 #else
1731 /*
1732 * Fit the number to the maximum number of bytes.
1733 *
1734 * If the number is too big then subtract from order.
1735 * RFC 6507, Section 5.2.1, Note at end.
1736 * This should only happen when order is larger than prime in bits.
1737 *
1738 * @param [in] a MP integer to fix.
1739 * @param [in] order MP integer representing order of curve.
1740 * @param [in] max Maximum number of bytes to encode into.
1741 * @param [out] r MP integer that is the result after fixing.
1742 * @return 0 on success.
1743 * @return MEMORY_E when dynamic memory allocation fails.
1744 */
eccsi_fit_to_octets(const mp_int * a,const mp_int * order,int max,mp_int * r)1745 static int eccsi_fit_to_octets(const mp_int* a, const mp_int* order, int max,
1746 mp_int* r)
1747 {
1748 (void)order;
1749 (void)max;
1750
1751 /* Duplicate line to stop static analyzer complaining. */
1752 return mp_copy(a, r);
1753 }
1754 #endif
1755
1756 /*
1757 * Compute the HE = hash( HS | r | M ), hash value of signature.
1758 *
1759 * Partial result required for signing and verification.
1760 *
1761 * @param [in] key ECCSI key.
1762 * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256
1763 * @param [in] r MP integer that is the first signature element.
1764 * @param [in] msg Message of signature.
1765 * @param [in] msgSz Length of message in bytes.
1766 * @param [out] he Signature hash.
1767 * @param [out] heSz Length of signature hash in bytes
1768 * @return 0 on success.
1769 * @return MEMORY_E when dynamic memory allocation fails.
1770 * @return Other -ve value when an internal operation fails.
1771 */
eccsi_compute_he(EccsiKey * key,enum wc_HashType hashType,mp_int * r,const byte * msg,word32 msgSz,byte * he,word32 * heSz)1772 static int eccsi_compute_he(EccsiKey* key, enum wc_HashType hashType,
1773 mp_int* r, const byte* msg, word32 msgSz, byte* he, word32* heSz)
1774 {
1775 int err = 0;
1776 word32 dataSz = key->ecc.dp->size;
1777
1778 /* HE = hash( HS | r | M ) */
1779 err = wc_HashInit_ex(&key->hash, hashType, key->heap, INVALID_DEVID);
1780 if (err == 0) {
1781 /* HS */
1782 err = wc_HashUpdate(&key->hash, hashType, key->idHash, key->idHashSz);
1783 }
1784 if (err == 0) {
1785 err = mp_to_unsigned_bin_len(r, key->data, dataSz);
1786 }
1787 if (err == 0) {
1788 /* r */
1789 err = wc_HashUpdate(&key->hash, hashType, key->data, dataSz);
1790 }
1791 if (err == 0) {
1792 /* M */
1793 err = wc_HashUpdate(&key->hash, hashType, msg, msgSz);
1794 }
1795 if (err == 0) {
1796 err = wc_HashFinal(&key->hash, hashType, he);
1797 }
1798 if (err == 0) {
1799 *heSz = wc_HashGetDigestSize(hashType);
1800 }
1801
1802 return err;
1803 }
1804
1805 /*
1806 * Encode the signature = ( r | s | PVT )
1807 *
1808 * @param [in] key ECCSI key.
1809 * @param [in] r MP integer that is the first signature element.
1810 * @param [in] s MP integer that is the second signature element.
1811 * @param [in] pvt ECC point representing Public Validation Token.
1812 * @param [out] sig Signature of message.
1813 * @param [out] sigSz Length of signature in bytes.
1814 */
eccsi_encode_sig(const EccsiKey * key,mp_int * r,mp_int * s,byte * sig,word32 * sigSz)1815 static int eccsi_encode_sig(const EccsiKey* key, mp_int* r, mp_int* s,
1816 byte* sig, word32* sigSz)
1817 {
1818 int err;
1819 word32 sz = key->ecc.dp->size;
1820
1821 err = mp_to_unsigned_bin_len(r, sig, sz);
1822 if (err == 0) {
1823 err = mp_to_unsigned_bin_len(s, sig + sz, sz);
1824 }
1825 if (err == 0) {
1826 *sigSz = key->ecc.dp->size * 2 + 1;
1827 err = wc_ecc_export_point_der(wc_ecc_get_curve_idx(key->ecc.dp->id),
1828 key->pvt, sig + sz * 2, sigSz);
1829 }
1830 if (err == 0) {
1831 *sigSz = sz * 4 + 1;
1832 }
1833
1834 return err;
1835 }
1836
1837 /*
1838 * Sign the ECCSI hash (of ID with the key) to two mp_int objects: r and s.
1839 *
1840 * RFC 6507, Section 5.2.1, Steps 1 to 4
1841 *
1842 * @param [in] key ECCSI key.
1843 * @param [in] rng Random number generator.
1844 * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256
1845 * @param [in] msg Message to sign.
1846 * @param [in] msgSz Length of message in bytes.
1847 * @param [out] r First big number integer part of signature.
1848 * @param [out] s Second big number integer part of signature.
1849 * @return 0 on success.
1850 * @return MEMORY_E when dynamic memory allocation fails.
1851 * @return Other -ve value when an internal operation fails.
1852 */
eccsi_gen_sig(EccsiKey * key,WC_RNG * rng,enum wc_HashType hashType,const byte * msg,word32 msgSz,mp_int * r,mp_int * s)1853 static int eccsi_gen_sig(EccsiKey* key, WC_RNG* rng, enum wc_HashType hashType,
1854 const byte* msg, word32 msgSz, mp_int* r, mp_int* s)
1855 {
1856 int err = 0;
1857 word32 sz = key->ecc.dp->size;
1858 word32 heSz = 0;
1859 const mp_int* jx = NULL;
1860 mp_int* he = &key->tmp;
1861 int genTryCnt = 0;
1862
1863 do {
1864 /* Don't infinitely gen sigs when random number generator fails. */
1865 if ((++genTryCnt) > ECCSI_MAX_GEN_COUNT) {
1866 err = RNG_FAILURE_E;
1867 }
1868
1869 if (err == 0) {
1870 wc_ecc_free(&key->pubkey);
1871
1872 /* Step 1 and 2: Generate ephemeral key - j, J = [j]G, r = Jx */
1873 err = wc_ecc_make_key_ex(rng, sz, &key->pubkey, key->ecc.dp->id);
1874 }
1875 if (err == 0) {
1876 jx = key->pubkey.pubkey.x;
1877 err = eccsi_fit_to_octets(jx, &key->params.order, sz, r);
1878 }
1879
1880 /* Step 3: Compute HE = hash( HS | r | M ) */
1881 if (err == 0) {
1882 err = eccsi_compute_he(key, hashType, r, msg, msgSz, key->data,
1883 &heSz);
1884 }
1885
1886 /* Step 4: Verify that HE + r * SSK is non-zero modulo q */
1887 if (err == 0) {
1888 err = mp_read_unsigned_bin(he, key->data, heSz);
1889 }
1890 /* s' = r * SSK */
1891 if (err == 0) {
1892 err = mp_mulmod(r, &key->ssk, &key->params.order, s);
1893 }
1894 /* s' = HE + r * SSK */
1895 if (err == 0) {
1896 err = mp_addmod(he, s, &key->params.order, s);
1897 }
1898 }
1899 while ((err == 0) && (mp_iszero(s) || (mp_cmp(s, he) == MP_EQ)));
1900
1901 return err;
1902 }
1903
1904
1905 /**
1906 * Sign the ECCSI hash (of ID with the key).
1907 *
1908 * RFC 6507, Section 5.2.1
1909 *
1910 * Must have imported KPAK using wc_ImportEccsiPublicKey() before calling.\n
1911 * Use wc_HashEccsiId() to calculate the hash and wc_SetEccsiHash() to set
1912 * the identity hash to use.
1913 *
1914 * @param [in] key ECCSI key.
1915 * @param [in] rng Random number generator.
1916 * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256
1917 * @param [in] msg Message to sign.
1918 * @param [in] msgSz Length of message in bytes.
1919 * @param [out] sig Signature of message.
1920 * @param [out] sigSz Length of signature in bytes.
1921 * @return 0 on success.
1922 * @return BAD_FUNC_ARG when key, rng, msg or sigSz is NULL.
1923 * @return BAD_STATE_E when the curve or id hash has not been set (no key set).
1924 * @return LENGTH_ONLY_E when sig is NULL - sigSz is set.
1925 * @return MEMORY_E when dynamic memory allocation fails.
1926 * @return Other -ve value when an internal operation fails.
1927 */
wc_SignEccsiHash(EccsiKey * key,WC_RNG * rng,enum wc_HashType hashType,const byte * msg,word32 msgSz,byte * sig,word32 * sigSz)1928 int wc_SignEccsiHash(EccsiKey* key, WC_RNG* rng, enum wc_HashType hashType,
1929 const byte* msg, word32 msgSz, byte* sig, word32* sigSz)
1930 {
1931 int err = 0;
1932 mp_int* r = NULL;
1933 mp_int* s = NULL;
1934 mp_int* j = NULL;
1935 word32 sz = 0;
1936
1937 if ((key == NULL) || (rng == NULL) || (msg == NULL) || (sigSz == NULL)) {
1938 err = BAD_FUNC_ARG;
1939 }
1940 if ((err == 0) && (key->ecc.type != ECC_PUBLICKEY) &&
1941 (key->ecc.type != ECC_PRIVATEKEY)) {
1942 err = BAD_STATE_E;
1943 }
1944 if ((err == 0) && (sig != NULL) && (key->idHashSz == 0)) {
1945 err = BAD_STATE_E;
1946 }
1947
1948 if (err == 0) {
1949 sz = key->ecc.dp->size;
1950 if (sig == NULL) {
1951 *sigSz = sz * 4 + 1;
1952 err = LENGTH_ONLY_E;
1953 }
1954 }
1955 if ((err == 0) && (*sigSz < sz * 4 + 1)) {
1956 err = BAD_FUNC_ARG;
1957 }
1958
1959 if (err == 0) {
1960 r = key->pubkey.pubkey.y;
1961 s = key->pubkey.pubkey.z;
1962
1963 err = eccsi_load_order(key);
1964 }
1965
1966 if (err == 0) {
1967 /* Steps 1 to 4. */
1968 err = eccsi_gen_sig(key, rng, hashType, msg, msgSz, r, s);
1969 }
1970
1971 /* Step 5: s' = ( (( HE + r * SSK )^-1) * j ) modulo q, erase j */
1972 if (err == 0) {
1973 err = mp_invmod(s, &key->params.order, s);
1974 }
1975 if (err == 0) {
1976 j = &key->pubkey.k;
1977 err = mp_mulmod(s, j, &key->params.order, s);
1978 }
1979 if (err == 0) {
1980 mp_forcezero(j);
1981
1982 /* Step 6: s = s' fitted */
1983 err = eccsi_fit_to_octets(s, &key->params.order, sz, s);
1984 }
1985
1986 /* Step 7: Output Signature = ( r | s | PVT ) */
1987 if (err == 0) {
1988 err = eccsi_encode_sig(key, r, s, sig, sigSz);
1989 }
1990
1991 return err;
1992 }
1993
1994 /*
1995 * Decode the s part of the signature = ( r | s | PVT )
1996 *
1997 * @param [in] key ECCSI key.
1998 * @param [in] sig Signature of message.
1999 * @param [in] sigSz Length of signature in bytes.
2000 * @param [out] s MP integer that is the second signature element.
2001 * @return 0 on success.
2002 * @return MEMORY_E when dynamic memory allocation fails.
2003 * @return Other -ve value when an internal operation fails.
2004 */
eccsi_decode_sig_s(const EccsiKey * key,const byte * sig,word32 sigSz,mp_int * s)2005 static int eccsi_decode_sig_s(const EccsiKey* key, const byte* sig,
2006 word32 sigSz, mp_int* s)
2007 {
2008 int err = 0;
2009 word32 sz = key->ecc.dp->size;
2010
2011 if (sigSz != sz * 4 + 1) {
2012 err = BAD_FUNC_ARG;
2013 }
2014
2015 if (err == 0) {
2016 err = mp_read_unsigned_bin(s, sig + sz, sz);
2017 }
2018
2019 return err;
2020 }
2021
2022 /*
2023 * Decode the r and pvt part of the signature = ( r | s | PVT )
2024 *
2025 * @param [in] key ECCSI key.
2026 * @param [in] sig Signature of message.
2027 * @param [in] sigSz Length of signature in bytes.
2028 * @param [out] r MP integer that is the first signature element.
2029 * @param [out] pvt ECC point representing Public Validation Token.
2030 * @return 0 on success.
2031 * @return MEMORY_E when dynamic memory allocation fails.
2032 * @return Other -ve value when an internal operation fails.
2033 */
eccsi_decode_sig_r_pvt(const EccsiKey * key,const byte * sig,word32 sigSz,mp_int * r,ecc_point * pvt)2034 static int eccsi_decode_sig_r_pvt(const EccsiKey* key, const byte* sig,
2035 word32 sigSz, mp_int* r, ecc_point* pvt)
2036 {
2037 int err = 0;
2038 word32 sz = key->ecc.dp->size;
2039
2040 if (sigSz != sz * 4 + 1) {
2041 err = BAD_FUNC_ARG;
2042 }
2043
2044 if (err == 0) {
2045 err = mp_read_unsigned_bin(r, sig, sz);
2046 }
2047 if (err == 0) {
2048 /* must free previous public point otherwise wc_ecc_import_point_der
2049 * could leak memory */
2050 mp_clear(pvt->x);
2051 mp_clear(pvt->y);
2052 mp_clear(pvt->z);
2053
2054 err = wc_ecc_import_point_der(sig + sz * 2, sz * 2 + 1,
2055 wc_ecc_get_curve_idx(key->ecc.dp->id), pvt);
2056 }
2057
2058 return err;
2059 }
2060
2061 /*
2062 * Calculate Y point as part of verification process.
2063 *
2064 * Y = [HS]PVT + KPAK
2065 *
2066 * @param [in] key ECCSI key.
2067 * @param [in] pvt ECC point representing Public Validation Token.
2068 * @param [in] mp Montgomery reduction multiplier.
2069 * @param [out] y ECC point representing calculated value Y.
2070 * @return 0 on success.
2071 * @return MEMORY_E when dynamic memory allocation fails.
2072 * @return Other value when an an internal operation fails.
2073 */
eccsi_calc_y(EccsiKey * key,ecc_point * pvt,mp_digit mp,ecc_point * y)2074 static int eccsi_calc_y(EccsiKey* key, ecc_point* pvt, mp_digit mp,
2075 ecc_point* y)
2076 {
2077 int err;
2078 mp_int* hs = &key->ssk;
2079
2080 err = mp_read_unsigned_bin(hs, key->idHash, key->idHashSz);
2081 #ifndef WOLFSSL_HAVE_SP_ECC
2082 /* Need KPAK in montgomery form. */
2083 if (err == 0) {
2084 err = eccsi_kpak_to_mont(key);
2085 }
2086 #endif
2087 /* [HS]PVT + KPAK */
2088 if (err == 0) {
2089 ecc_point* kpak = &key->ecc.pubkey;
2090 err = eccsi_mulmod_point_add(key, hs, pvt, kpak, y, mp, 1);
2091 }
2092
2093 return err;
2094 }
2095
2096 /*
2097 * Calculate J point as part of verification process.
2098 *
2099 * J = [s]( [HE]G + [r]Y )
2100 *
2101 * @param [in] key ECCSI key.
2102 * @param [in] hem MP int representation of HE = Hash (hs, r and message).
2103 * @param [in] sig Signature of message.
2104 * @param [in] sigSz Length of signature in bytes.
2105 * @param [in] y ECC point representing [r]Y.
2106 * @param [in] mp Montgomery reduction multiplier.
2107 * @param [out] j ECC point representing calculated value J.
2108 * @return 0 on success.
2109 * @return MEMORY_E when dynamic memory allocation fails.
2110 * @return Other value when an an internal operation fails.
2111 */
eccsi_calc_j(EccsiKey * key,const mp_int * hem,const byte * sig,word32 sigSz,ecc_point * y,mp_digit mp,ecc_point * j)2112 static int eccsi_calc_j(EccsiKey* key, const mp_int* hem, const byte* sig,
2113 word32 sigSz, ecc_point* y, mp_digit mp, ecc_point* j)
2114 {
2115 int err;
2116 mp_int* s = &key->tmp;
2117
2118 /* [HE]G + [r]Y */
2119 err = eccsi_mulmod_base_add(key, hem, y, j, mp, 1);
2120 if (err == 0) {
2121 err = eccsi_decode_sig_s(key, sig, sigSz, s);
2122 }
2123 /* [s]( [HE]G + [r]Y ) */
2124 if (err == 0) {
2125 err = eccsi_mulmod_point(key, s, j, j, 1);
2126 }
2127
2128 return err;
2129 }
2130
2131 /**
2132 * Verify the ECCSI hash (of ID with the key).
2133 *
2134 * RFC 6507, Section 5.2.2
2135 *
2136 * Must have imported KPAK using wc_ImportEccsiPublicKey() before calling.\n
2137 * Use wc_HashEccsiId() to calculate the hash and wc_SetEccsiHash() to set
2138 * the identity hash to use.
2139 *
2140 * @param [in] key ECCSI key.
2141 * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256
2142 * @param [in] msg Message to verify.
2143 * @param [in] msgSz Length of message in bytes.
2144 * @param [in] sig Signature of message.
2145 * @param [in] sigSz Length of signature in bytes.
2146 * @param [out] verified 1 when the signature was verified and 0 otherwise.
2147 * @return 0 on success.
2148 * @return BAD_FUNC_ARG when key, hash, msg, sig or ret is NULL.
2149 * @return BAD_STATE_E when the curve or id hash has not been set (no key set).
2150 * @return MEMORY_E when dynamic memory allocation fails.
2151 * @return Other value when an an internal operation fails.
2152 */
wc_VerifyEccsiHash(EccsiKey * key,enum wc_HashType hashType,const byte * msg,word32 msgSz,const byte * sig,word32 sigSz,int * verified)2153 int wc_VerifyEccsiHash(EccsiKey* key, enum wc_HashType hashType,
2154 const byte* msg, word32 msgSz, const byte* sig, word32 sigSz,
2155 int* verified)
2156 {
2157 int err = 0;
2158 byte* he = NULL;
2159 word32 heSz = 0;
2160 mp_int* r = NULL;
2161 mp_int* jx = NULL;
2162 mp_int* hem = NULL;
2163 ecc_point* pvt = NULL;
2164 ecc_point* y = NULL;
2165 ecc_point* j = NULL;
2166 mp_digit mp = 0;
2167 EccsiKeyParams* params = NULL;
2168
2169 if ((key == NULL) || (msg == NULL) || (sig == NULL) || (verified == NULL)) {
2170 err = BAD_FUNC_ARG;
2171 }
2172 if ((err == 0) && (key->ecc.type != ECC_PRIVATEKEY) &&
2173 (key->ecc.type != ECC_PUBLICKEY)) {
2174 err = BAD_STATE_E;
2175 }
2176 if ((err == 0) && (key->idHashSz == 0)) {
2177 err = BAD_STATE_E;
2178 }
2179
2180 if (err != 0)
2181 return err;
2182
2183 SAVE_VECTOR_REGISTERS(return _svr_ret;);
2184
2185 /* Decode the signature into components. */
2186 r = &key->pubkey.k;
2187 pvt = &key->pubkey.pubkey;
2188 err = eccsi_decode_sig_r_pvt(key, sig, sigSz, r, pvt);
2189
2190 /* Load the curve parameters for operations */
2191 if (err == 0) {
2192 err = eccsi_load_base(key);
2193 }
2194 if (err == 0) {
2195 err = eccsi_load_ecc_params(key);
2196 }
2197 if (err == 0) {
2198 params = &key->params;
2199 err = mp_montgomery_setup(¶ms->prime, &mp);
2200 }
2201
2202 /* Step 1: Validate PVT is on curve */
2203 if (err == 0) {
2204 err = wc_ecc_is_point(pvt, ¶ms->a, ¶ms->b, ¶ms->prime);
2205 }
2206
2207 /* Step 2: Compute HS = hash( G | KPAK | ID | PVT )
2208 * HS is key->idHash, key->idHashSz */
2209
2210 /* Step 3: Compute HE = hash( HS | r | M ) */
2211 if (err == 0) {
2212 he = key->data;
2213 err = eccsi_compute_he(key, hashType, r, msg, msgSz, he, &heSz);
2214 }
2215
2216 /* Step 4: Y = [HS]PVT + KPAK */
2217 if (err == 0) {
2218 y = pvt;
2219 err = eccsi_calc_y(key, pvt, mp, y);
2220 }
2221
2222 /* Step 5: Compute J = [s]( [HE]G + [r]Y ) */
2223 /* [r]Y */
2224 if (err == 0) {
2225 hem = &key->tmp;
2226 err = mp_read_unsigned_bin(hem, he, heSz);
2227 }
2228 if (err == 0) {
2229 err = eccsi_mulmod_point(key, r, y, y, 0);
2230 }
2231 if (err == 0) {
2232 j = params->base;
2233 err = eccsi_calc_j(key, hem, sig, sigSz, y, mp, j);
2234 key->params.haveBase = 0;
2235 }
2236
2237 /* Step 6: Jx fitting, compare with r */
2238 if (err == 0) {
2239 jx = &key->tmp;
2240 err = eccsi_fit_to_octets(j->x, ¶ms->order, key->ecc.dp->size, jx);
2241 }
2242
2243 if (verified != NULL) {
2244 *verified = ((err == 0) && (mp_cmp(jx, r) == MP_EQ));
2245 }
2246
2247 RESTORE_VECTOR_REGISTERS();
2248
2249 return err;
2250 }
2251 #endif /* WOLFCRYPT_ECCSI_CLIENT */
2252
2253 #endif /* WOLFCRYPT_HAVE_ECCSI */
2254
2255