1 /* ed448.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 /* Implemented to: RFC 8032 */
23
24 /* Based On Daniel J Bernstein's ed25519 Public Domain ref10 work.
25 * Reworked for curve448 by Sean Parkinson.
26 */
27
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31
32 /* in case user set HAVE_ED448 there */
33 #include <wolfssl/wolfcrypt/settings.h>
34
35 #ifdef HAVE_ED448
36
37 #include <wolfssl/wolfcrypt/ed448.h>
38 #include <wolfssl/wolfcrypt/error-crypt.h>
39 #include <wolfssl/wolfcrypt/hash.h>
40 #ifdef NO_INLINE
41 #include <wolfssl/wolfcrypt/misc.h>
42 #else
43 #define WOLFSSL_MISC_INCLUDED
44 #include <wolfcrypt/src/misc.c>
45 #endif
46
47 #if defined(HAVE_ED448_SIGN) || defined(HAVE_ED448_VERIFY)
48 /* Size of context bytes to use with hash when signing and verifying. */
49 #define ED448CTX_SIZE 8
50 /* Context to pass to hash when signing and verifying. */
51 static const byte ed448Ctx[ED448CTX_SIZE+1] = "SigEd448";
52 #endif
53
54
ed448_hash_init(ed448_key * key,wc_Shake * sha)55 static int ed448_hash_init(ed448_key* key, wc_Shake *sha)
56 {
57 int ret;
58
59 ret = wc_InitShake256(sha, key->heap,
60 #if defined(WOLF_CRYPTO_CB)
61 key->devId
62 #else
63 INVALID_DEVID
64 #endif
65 );
66
67 #ifdef WOLFSSL_ED448_PERSISTENT_SHA
68 if (ret == 0)
69 key->sha_clean_flag = 1;
70 #endif
71
72 return ret;
73 }
74
75 #ifdef WOLFSSL_ED448_PERSISTENT_SHA
ed448_hash_reset(ed448_key * key)76 static int ed448_hash_reset(ed448_key* key)
77 {
78 int ret;
79
80 if (key->sha_clean_flag)
81 ret = 0;
82 else {
83 wc_Shake256_Free(&key->sha);
84 ret = wc_InitShake256(&key->sha, key->heap,
85 #if defined(WOLF_CRYPTO_CB)
86 key->devId
87 #else
88 INVALID_DEVID
89 #endif
90 );
91 if (ret == 0)
92 key->sha_clean_flag = 1;
93 }
94 return ret;
95 }
96 #endif /* WOLFSSL_ED448_PERSISTENT_SHA */
97
ed448_hash_update(ed448_key * key,wc_Shake * sha,const byte * data,word32 len)98 static int ed448_hash_update(ed448_key* key, wc_Shake *sha, const byte* data,
99 word32 len)
100 {
101 #ifdef WOLFSSL_ED448_PERSISTENT_SHA
102 if (key->sha_clean_flag)
103 key->sha_clean_flag = 0;
104 #else
105 (void)key;
106 #endif
107 return wc_Shake256_Update(sha, data, len);
108 }
109
ed448_hash_final(ed448_key * key,wc_Shake * sha,byte * hash,word32 hashLen)110 static int ed448_hash_final(ed448_key* key, wc_Shake *sha, byte* hash,
111 word32 hashLen)
112 {
113 int ret = wc_Shake256_Final(sha, hash, hashLen);
114 #ifdef WOLFSSL_ED448_PERSISTENT_SHA
115 if (ret == 0)
116 key->sha_clean_flag = 1;
117 #else
118 (void)key;
119 #endif
120 return ret;
121 }
122
ed448_hash_free(ed448_key * key,wc_Shake * sha)123 static void ed448_hash_free(ed448_key* key, wc_Shake *sha)
124 {
125 wc_Shake256_Free(sha);
126 #ifdef WOLFSSL_ED448_PERSISTENT_SHA
127 key->sha_clean_flag = 0;
128 #else
129 (void)key;
130 #endif
131 }
132
133
ed448_hash(ed448_key * key,const byte * in,word32 inLen,byte * hash,word32 hashLen)134 static int ed448_hash(ed448_key* key, const byte* in, word32 inLen,
135 byte* hash, word32 hashLen)
136 {
137 int ret;
138 #ifndef WOLFSSL_ED448_PERSISTENT_SHA
139 wc_Shake sha[1];
140 #else
141 wc_Shake *sha;
142 #endif
143
144 if (key == NULL || (in == NULL && inLen > 0) || hash == NULL) {
145 return BAD_FUNC_ARG;
146 }
147
148 #ifdef WOLFSSL_ED448_PERSISTENT_SHA
149 sha = &key->sha;
150 ret = ed448_hash_reset(key);
151 #else
152 ret = ed448_hash_init(key, sha);
153 #endif
154 if (ret < 0)
155 return ret;
156
157 ret = ed448_hash_update(key, sha, in, inLen);
158 if (ret == 0)
159 ret = ed448_hash_final(key, sha, hash, hashLen);
160
161 #ifndef WOLFSSL_ED448_PERSISTENT_SHA
162 ed448_hash_free(key, sha);
163 #endif
164
165 return ret;
166 }
167
168 /* Derive the public key for the private key.
169 *
170 * key [in] Ed448 key object.
171 * pubKey [in] Byte array to hold te public key.
172 * pubKeySz [in] Size of the array in bytes.
173 * returns BAD_FUNC_ARG when key is NULL or pubKeySz is not equal to
174 * ED448_PUB_KEY_SIZE,
175 * other -ve value on hash failure,
176 * 0 otherwise.
177 */
wc_ed448_make_public(ed448_key * key,unsigned char * pubKey,word32 pubKeySz)178 int wc_ed448_make_public(ed448_key* key, unsigned char* pubKey, word32 pubKeySz)
179 {
180 int ret = 0;
181 byte az[ED448_PRV_KEY_SIZE];
182 ge448_p2 A;
183
184 if ((key == NULL) || (pubKey == NULL) || (pubKeySz != ED448_PUB_KEY_SIZE)) {
185 ret = BAD_FUNC_ARG;
186 }
187
188 if (ret == 0)
189 ret = ed448_hash(key, key->k, ED448_KEY_SIZE, az, sizeof(az));
190
191 if (ret == 0) {
192 /* apply clamp */
193 az[0] &= 0xfc;
194 az[55] |= 0x80;
195 az[56] = 0x00;
196
197 ge448_scalarmult_base(&A, az);
198 ge448_to_bytes(pubKey, &A);
199 }
200
201 return ret;
202 }
203
204 /* Make a new ed448 private/public key.
205 *
206 * rng [in] Random number generator.
207 * keysize [in] Size of the key to generate.
208 * key [in] Ed448 key object.
209 * returns BAD_FUNC_ARG when rng or key is NULL or keySz is not equal to
210 * ED448_KEY_SIZE,
211 * other -ve value on random number or hash failure,
212 * 0 otherwise.
213 */
wc_ed448_make_key(WC_RNG * rng,int keySz,ed448_key * key)214 int wc_ed448_make_key(WC_RNG* rng, int keySz, ed448_key* key)
215 {
216 int ret = 0;
217
218 if ((rng == NULL) || (key == NULL)) {
219 ret = BAD_FUNC_ARG;
220 }
221
222 /* ed448 has 57 byte key sizes */
223 if ((ret == 0) && (keySz != ED448_KEY_SIZE)) {
224 ret = BAD_FUNC_ARG;
225 }
226
227 if (ret == 0) {
228 ret = wc_RNG_GenerateBlock(rng, key->k, ED448_KEY_SIZE);
229 }
230 if (ret == 0) {
231 ret = wc_ed448_make_public(key, key->p, ED448_PUB_KEY_SIZE);
232 if (ret != 0) {
233 ForceZero(key->k, ED448_KEY_SIZE);
234 }
235 }
236 if (ret == 0) {
237 /* put public key after private key, on the same buffer */
238 XMEMMOVE(key->k + ED448_KEY_SIZE, key->p, ED448_PUB_KEY_SIZE);
239
240 key->pubKeySet = 1;
241 }
242
243 return ret;
244 }
245
246 #ifdef HAVE_ED448_SIGN
247 /* Sign the message using the ed448 private key.
248 *
249 * in [in] Message to sign.
250 * inLen [in] Length of the message in bytes.
251 * out [in] Buffer to write signature into.
252 * outLen [in/out] On in, size of buffer.
253 * On out, the length of the signature in bytes.
254 * key [in] Ed448 key to use when signing
255 * type [in] Type of signature to perform: Ed448 or Ed448ph
256 * context [in] Context of signing.
257 * contextLen [in] Length of context in bytes.
258 * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
259 * context is not NULL or public key not set,
260 * BUFFER_E when outLen is less than ED448_SIG_SIZE,
261 * other -ve values when hash fails,
262 * 0 otherwise.
263 */
wc_ed448_sign_msg_ex(const byte * in,word32 inLen,byte * out,word32 * outLen,ed448_key * key,byte type,const byte * context,byte contextLen)264 int wc_ed448_sign_msg_ex(const byte* in, word32 inLen, byte* out,
265 word32 *outLen, ed448_key* key, byte type,
266 const byte* context, byte contextLen)
267 {
268 ge448_p2 R;
269 byte nonce[ED448_SIG_SIZE];
270 byte hram[ED448_SIG_SIZE];
271 byte az[ED448_PRV_KEY_SIZE];
272 int ret = 0;
273
274 /* sanity check on arguments */
275 if ((in == NULL) || (out == NULL) || (outLen == NULL) || (key == NULL) ||
276 ((context == NULL) && (contextLen != 0))) {
277 ret = BAD_FUNC_ARG;
278 }
279 if ((ret == 0) && (!key->pubKeySet)) {
280 ret = BAD_FUNC_ARG;
281 }
282
283 /* check and set up out length */
284 if ((ret == 0) && (*outLen < ED448_SIG_SIZE)) {
285 *outLen = ED448_SIG_SIZE;
286 ret = BUFFER_E;
287 }
288
289 if (ret == 0) {
290 *outLen = ED448_SIG_SIZE;
291
292 /* step 1: create nonce to use where nonce is r in
293 r = H(h_b, ... ,h_2b-1,M) */
294 ret = ed448_hash(key, key->k, ED448_KEY_SIZE, az, sizeof(az));
295 }
296 if (ret == 0) {
297 #ifdef WOLFSSL_ED448_PERSISTENT_SHA
298 wc_Shake *sha = &key->sha;
299 #else
300 wc_Shake sha[1];
301 ret = ed448_hash_init(key, sha);
302 if (ret < 0)
303 return ret;
304 #endif
305 /* apply clamp */
306 az[0] &= 0xfc;
307 az[55] |= 0x80;
308 az[56] = 0x00;
309
310 ret = ed448_hash_update(key, sha, ed448Ctx, ED448CTX_SIZE);
311
312 if (ret == 0) {
313 ret = ed448_hash_update(key, sha, &type, sizeof(type));
314 }
315 if (ret == 0) {
316 ret = ed448_hash_update(key, sha, &contextLen, sizeof(contextLen));
317 }
318 if ((ret == 0) && (context != NULL)) {
319 ret = ed448_hash_update(key, sha, context, contextLen);
320 }
321 if (ret == 0) {
322 ret = ed448_hash_update(key, sha, az + ED448_KEY_SIZE, ED448_KEY_SIZE);
323 }
324 if (ret == 0) {
325 ret = ed448_hash_update(key, sha, in, inLen);
326 }
327 if (ret == 0) {
328 ret = ed448_hash_final(key, sha, nonce, sizeof(nonce));
329 }
330 #ifndef WOLFSSL_ED448_PERSISTENT_SHA
331 ed448_hash_free(key, sha);
332 #endif
333 }
334 if (ret == 0) {
335 #ifdef WOLFSSL_ED448_PERSISTENT_SHA
336 wc_Shake *sha = &key->sha;
337 #else
338 wc_Shake sha[1];
339 ret = ed448_hash_init(key, sha);
340 if (ret < 0)
341 return ret;
342 #endif
343 sc448_reduce(nonce);
344
345 /* step 2: computing R = rB where rB is the scalar multiplication of
346 r and B */
347 ge448_scalarmult_base(&R,nonce);
348 ge448_to_bytes(out,&R);
349
350 /* step 3: hash R + public key + message getting H(R,A,M) then
351 creating S = (r + H(R,A,M)a) mod l */
352
353 ret = ed448_hash_update(key, sha, ed448Ctx, ED448CTX_SIZE);
354 if (ret == 0) {
355 ret = ed448_hash_update(key, sha, &type, sizeof(type));
356 }
357 if (ret == 0) {
358 ret = ed448_hash_update(key, sha, &contextLen, sizeof(contextLen));
359 }
360 if ((ret == 0) && (context != NULL)) {
361 ret = ed448_hash_update(key, sha, context, contextLen);
362 }
363 if (ret == 0) {
364 ret = ed448_hash_update(key, sha, out, ED448_SIG_SIZE/2);
365 }
366 if (ret == 0) {
367 ret = ed448_hash_update(key, sha, key->p, ED448_PUB_KEY_SIZE);
368 }
369 if (ret == 0) {
370 ret = ed448_hash_update(key, sha, in, inLen);
371 }
372 if (ret == 0) {
373 ret = ed448_hash_final(key, sha, hram, sizeof(hram));
374 }
375 #ifndef WOLFSSL_ED448_PERSISTENT_SHA
376 ed448_hash_free(key, sha);
377 #endif
378 }
379
380 if (ret == 0) {
381 sc448_reduce(hram);
382 sc448_muladd(out + (ED448_SIG_SIZE/2), hram, az, nonce);
383 }
384
385 return ret;
386 }
387
388 /* Sign the message using the ed448 private key.
389 * Signature type is Ed448.
390 *
391 * in [in] Message to sign.
392 * inLen [in] Length of the message in bytes.
393 * out [in] Buffer to write signature into.
394 * outLen [in/out] On in, size of buffer.
395 * On out, the length of the signature in bytes.
396 * key [in] Ed448 key to use when signing
397 * context [in] Context of signing.
398 * contextLen [in] Length of context in bytes.
399 * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
400 * context is not NULL or public key not set,
401 * BUFFER_E when outLen is less than ED448_SIG_SIZE,
402 * other -ve values when hash fails,
403 * 0 otherwise.
404 */
wc_ed448_sign_msg(const byte * in,word32 inLen,byte * out,word32 * outLen,ed448_key * key,const byte * context,byte contextLen)405 int wc_ed448_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen,
406 ed448_key* key, const byte* context, byte contextLen)
407 {
408 return wc_ed448_sign_msg_ex(in, inLen, out, outLen, key, Ed448, context,
409 contextLen);
410 }
411
412 /* Sign the hash using the ed448 private key.
413 * Signature type is Ed448ph.
414 *
415 * hash [in] Hash of message to sign.
416 * hashLen [in] Length of hash of message in bytes.
417 * out [in] Buffer to write signature into.
418 * outLen [in/out] On in, size of buffer.
419 * On out, the length of the signature in bytes.
420 * key [in] Ed448 key to use when signing
421 * context [in] Context of signing.
422 * contextLen [in] Length of context in bytes.
423 * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
424 * context is not NULL or public key not set,
425 * BUFFER_E when outLen is less than ED448_SIG_SIZE,
426 * other -ve values when hash fails,
427 * 0 otherwise.
428 */
wc_ed448ph_sign_hash(const byte * hash,word32 hashLen,byte * out,word32 * outLen,ed448_key * key,const byte * context,byte contextLen)429 int wc_ed448ph_sign_hash(const byte* hash, word32 hashLen, byte* out,
430 word32 *outLen, ed448_key* key,
431 const byte* context, byte contextLen)
432 {
433 return wc_ed448_sign_msg_ex(hash, hashLen, out, outLen, key, Ed448ph,
434 context, contextLen);
435 }
436
437 /* Sign the message using the ed448 private key.
438 * Signature type is Ed448ph.
439 *
440 * in [in] Message to sign.
441 * inLen [in] Length of the message to sign in bytes.
442 * out [in] Buffer to write signature into.
443 * outLen [in/out] On in, size of buffer.
444 * On out, the length of the signature in bytes.
445 * key [in] Ed448 key to use when signing
446 * context [in] Context of signing.
447 * contextLen [in] Length of context in bytes.
448 * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
449 * context is not NULL or public key not set,
450 * BUFFER_E when outLen is less than ED448_SIG_SIZE,
451 * other -ve values when hash fails,
452 * 0 otherwise.
453 */
wc_ed448ph_sign_msg(const byte * in,word32 inLen,byte * out,word32 * outLen,ed448_key * key,const byte * context,byte contextLen)454 int wc_ed448ph_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen,
455 ed448_key* key, const byte* context, byte contextLen)
456 {
457 int ret;
458 byte hash[ED448_PREHASH_SIZE];
459
460 ret = ed448_hash(key, in, inLen, hash, sizeof(hash));
461
462 if (ret == 0) {
463 ret = wc_ed448ph_sign_hash(hash, sizeof(hash), out, outLen, key,
464 context, contextLen);
465 }
466
467 return ret;
468 }
469 #endif /* HAVE_ED448_SIGN */
470
471 #ifdef HAVE_ED448_VERIFY
472
473 /* Verify the message using the ed448 public key.
474 *
475 * sig [in] Signature to verify.
476 * sigLen [in] Size of signature in bytes.
477 * key [in] Ed448 key to use to verify.
478 * type [in] Type of signature to verify: Ed448 or Ed448ph
479 * context [in] Context of verification.
480 * contextLen [in] Length of context in bytes.
481 * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
482 * context is not NULL or public key not set,
483 * BUFFER_E when sigLen is less than ED448_SIG_SIZE,
484 * other -ve values when hash fails,
485 * 0 otherwise.
486 */
487
ed448_verify_msg_init_with_sha(const byte * sig,word32 sigLen,ed448_key * key,wc_Shake * sha,byte type,const byte * context,byte contextLen)488 static int ed448_verify_msg_init_with_sha(const byte* sig, word32 sigLen,
489 ed448_key* key, wc_Shake *sha, byte type,
490 const byte* context, byte contextLen)
491 {
492 int ret;
493
494 /* sanity check on arguments */
495 if ((sig == NULL) || (key == NULL) ||
496 ((context == NULL) && (contextLen != 0))) {
497 return BAD_FUNC_ARG;
498 }
499
500 /* check on basics needed to verify signature */
501 if (sigLen != ED448_SIG_SIZE) {
502 return BAD_FUNC_ARG;
503 }
504
505 /* find H(R,A,M) and store it as h */
506 #ifdef WOLFSSL_ED448_PERSISTENT_SHA
507 ret = ed448_hash_reset(key);
508 if (ret < 0)
509 return ret;
510 #endif
511
512 ret = ed448_hash_update(key, sha, ed448Ctx, ED448CTX_SIZE);
513 if (ret == 0) {
514 ret = ed448_hash_update(key, sha, &type, sizeof(type));
515 }
516 if (ret == 0) {
517 ret = ed448_hash_update(key, sha, &contextLen, sizeof(contextLen));
518 }
519 if ((ret == 0) && (context != NULL)) {
520 ret = ed448_hash_update(key, sha, context, contextLen);
521 }
522 if (ret == 0) {
523 ret = ed448_hash_update(key, sha, sig, ED448_SIG_SIZE/2);
524 }
525 if (ret == 0) {
526 ret = ed448_hash_update(key, sha, key->p, ED448_PUB_KEY_SIZE);
527 }
528
529 return ret;
530 }
531
532 /*
533 msgSegment an array of bytes containing a message segment
534 msgSegmentLen length of msgSegment
535 key Ed448 public key
536 return 0 on success
537 */
ed448_verify_msg_update_with_sha(const byte * msgSegment,word32 msgSegmentLen,ed448_key * key,wc_Shake * sha)538 static int ed448_verify_msg_update_with_sha(const byte* msgSegment,
539 word32 msgSegmentLen,
540 ed448_key* key,
541 wc_Shake *sha)
542 {
543 /* sanity check on arguments */
544 if (msgSegment == NULL || key == NULL)
545 return BAD_FUNC_ARG;
546
547 return ed448_hash_update(key, sha, msgSegment, msgSegmentLen);
548 }
549
550 /* Verify the message using the ed448 public key.
551 *
552 * sig [in] Signature to verify.
553 * sigLen [in] Size of signature in bytes.
554 * res [out] *res is set to 1 on successful verification.
555 * key [in] Ed448 key to use to verify.
556 * returns BAD_FUNC_ARG when a parameter is NULL or public key not set,
557 * BUFFER_E when sigLen is less than ED448_SIG_SIZE,
558 * other -ve values when hash fails,
559 * 0 otherwise.
560 */
ed448_verify_msg_final_with_sha(const byte * sig,word32 sigLen,int * res,ed448_key * key,wc_Shake * sha)561 static int ed448_verify_msg_final_with_sha(const byte* sig, word32 sigLen,
562 int* res, ed448_key* key, wc_Shake *sha)
563 {
564 byte rcheck[ED448_KEY_SIZE];
565 byte h[ED448_SIG_SIZE];
566 ge448_p2 A;
567 ge448_p2 R;
568 int ret;
569
570 /* sanity check on arguments */
571 if ((sig == NULL) || (res == NULL) || (key == NULL))
572 return BAD_FUNC_ARG;
573
574 /* set verification failed by default */
575 *res = 0;
576
577 /* check on basics needed to verify signature */
578 if (sigLen != ED448_SIG_SIZE)
579 return BAD_FUNC_ARG;
580
581 /* uncompress A (public key), test if valid, and negate it */
582 if (ge448_from_bytes_negate_vartime(&A, key->p) != 0)
583 return BAD_FUNC_ARG;
584
585 ret = ed448_hash_final(key, sha, h, sizeof(h));
586 if (ret != 0)
587 return ret;
588
589 sc448_reduce(h);
590
591 /* Uses a fast single-signature verification SB = R + H(R,A,M)A becomes
592 * SB - H(R,A,M)A saving decompression of R
593 */
594 ret = ge448_double_scalarmult_vartime(&R, h, &A,
595 sig + (ED448_SIG_SIZE/2));
596 if (ret != 0)
597 return ret;
598
599 ge448_to_bytes(rcheck, &R);
600
601 /* comparison of R created to R in sig */
602 if (ConstantCompare(rcheck, sig, ED448_SIG_SIZE/2) != 0) {
603 ret = SIG_VERIFY_E;
604 }
605 else {
606 /* set the verification status */
607 *res = 1;
608 }
609
610 return ret;
611 }
612
613 #ifdef WOLFSSL_ED448_STREAMING_VERIFY
wc_ed448_verify_msg_init(const byte * sig,word32 sigLen,ed448_key * key,byte type,const byte * context,byte contextLen)614 int wc_ed448_verify_msg_init(const byte* sig, word32 sigLen, ed448_key* key,
615 byte type, const byte* context, byte contextLen)
616 {
617 return ed448_verify_msg_init_with_sha(sig, sigLen, key, &key->sha, type,
618 context, contextLen);
619 }
620
wc_ed448_verify_msg_update(const byte * msgSegment,word32 msgSegmentLen,ed448_key * key)621 int wc_ed448_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen,
622 ed448_key* key)
623 {
624 return ed448_verify_msg_update_with_sha(msgSegment, msgSegmentLen, key,
625 &key->sha);
626 }
627
wc_ed448_verify_msg_final(const byte * sig,word32 sigLen,int * res,ed448_key * key)628 int wc_ed448_verify_msg_final(const byte* sig, word32 sigLen,
629 int* res, ed448_key* key)
630 {
631 return ed448_verify_msg_final_with_sha(sig, sigLen, res, key, &key->sha);
632 }
633 #endif
634
635 /* Verify the message using the ed448 public key.
636 *
637 * sig [in] Signature to verify.
638 * sigLen [in] Size of signature in bytes.
639 * msg [in] Message to verify.
640 * msgLen [in] Length of the message in bytes.
641 * res [out] *res is set to 1 on successful verification.
642 * key [in] Ed448 key to use to verify.
643 * type [in] Type of signature to verify: Ed448 or Ed448ph
644 * context [in] Context of verification.
645 * contextLen [in] Length of context in bytes.
646 * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
647 * context is not NULL or public key not set,
648 * BUFFER_E when sigLen is less than ED448_SIG_SIZE,
649 * other -ve values when hash fails,
650 * 0 otherwise.
651 */
wc_ed448_verify_msg_ex(const byte * sig,word32 sigLen,const byte * msg,word32 msgLen,int * res,ed448_key * key,byte type,const byte * context,byte contextLen)652 int wc_ed448_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg,
653 word32 msgLen, int* res, ed448_key* key,
654 byte type, const byte* context, byte contextLen)
655 {
656 int ret;
657 #ifdef WOLFSSL_ED448_PERSISTENT_SHA
658 wc_Shake *sha;
659 #else
660 wc_Shake sha[1];
661 #endif
662
663 if (key == NULL)
664 return BAD_FUNC_ARG;
665
666 #ifdef WOLFSSL_ED448_PERSISTENT_SHA
667 sha = &key->sha;
668 #else
669 ret = ed448_hash_init(key, sha);
670 if (ret < 0)
671 return ret;
672 #endif
673
674 ret = ed448_verify_msg_init_with_sha(sig, sigLen, key, sha,
675 type, context, contextLen);
676 if (ret == 0)
677 ret = ed448_verify_msg_update_with_sha(msg, msgLen, key, sha);
678 if (ret == 0)
679 ret = ed448_verify_msg_final_with_sha(sig, sigLen, res, key, sha);
680
681 #ifndef WOLFSSL_ED448_PERSISTENT_SHA
682 ed448_hash_free(key, sha);
683 #endif
684
685 return ret;
686 }
687
688 /* Verify the message using the ed448 public key.
689 * Signature type is Ed448.
690 *
691 * sig [in] Signature to verify.
692 * sigLen [in] Size of signature in bytes.
693 * msg [in] Message to verify.
694 * msgLen [in] Length of the message in bytes.
695 * key [in] Ed448 key to use to verify.
696 * context [in] Context of verification.
697 * contextLen [in] Length of context in bytes.
698 * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
699 * context is not NULL or public key not set,
700 * BUFFER_E when sigLen is less than ED448_SIG_SIZE,
701 * other -ve values when hash fails,
702 * 0 otherwise.
703 */
wc_ed448_verify_msg(const byte * sig,word32 sigLen,const byte * msg,word32 msgLen,int * res,ed448_key * key,const byte * context,byte contextLen)704 int wc_ed448_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
705 word32 msgLen, int* res, ed448_key* key,
706 const byte* context, byte contextLen)
707 {
708 return wc_ed448_verify_msg_ex(sig, sigLen, msg, msgLen, res, key, Ed448,
709 context, contextLen);
710 }
711
712 /* Verify the hash using the ed448 public key.
713 * Signature type is Ed448ph.
714 *
715 * sig [in] Signature to verify.
716 * sigLen [in] Size of signature in bytes.
717 * hash [in] Hash of message to verify.
718 * hashLen [in] Length of the hash in bytes.
719 * key [in] Ed448 key to use to verify.
720 * context [in] Context of verification.
721 * contextLen [in] Length of context in bytes.
722 * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
723 * context is not NULL or public key not set,
724 * BUFFER_E when sigLen is less than ED448_SIG_SIZE,
725 * other -ve values when hash fails,
726 * 0 otherwise.
727 */
wc_ed448ph_verify_hash(const byte * sig,word32 sigLen,const byte * hash,word32 hashLen,int * res,ed448_key * key,const byte * context,byte contextLen)728 int wc_ed448ph_verify_hash(const byte* sig, word32 sigLen, const byte* hash,
729 word32 hashLen, int* res, ed448_key* key,
730 const byte* context, byte contextLen)
731 {
732 return wc_ed448_verify_msg_ex(sig, sigLen, hash, hashLen, res, key, Ed448ph,
733 context, contextLen);
734 }
735
736 /* Verify the message using the ed448 public key.
737 * Signature type is Ed448ph.
738 *
739 * sig [in] Signature to verify.
740 * sigLen [in] Size of signature in bytes.
741 * msg [in] Message to verify.
742 * msgLen [in] Length of the message in bytes.
743 * key [in] Ed448 key to use to verify.
744 * context [in] Context of verification.
745 * contextLen [in] Length of context in bytes.
746 * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
747 * context is not NULL or public key not set,
748 * BUFFER_E when sigLen is less than ED448_SIG_SIZE,
749 * other -ve values when hash fails,
750 * 0 otherwise.
751 */
wc_ed448ph_verify_msg(const byte * sig,word32 sigLen,const byte * msg,word32 msgLen,int * res,ed448_key * key,const byte * context,byte contextLen)752 int wc_ed448ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
753 word32 msgLen, int* res, ed448_key* key,
754 const byte* context, byte contextLen)
755 {
756 int ret = 0;
757 byte hash[ED448_PREHASH_SIZE];
758
759 ret = ed448_hash(key, msg, msgLen, hash, sizeof(hash));
760
761 if (ret == 0) {
762 ret = wc_ed448ph_verify_hash(sig, sigLen, hash, sizeof(hash), res, key,
763 context, contextLen);
764 }
765
766 return ret;
767 }
768 #endif /* HAVE_ED448_VERIFY */
769
770 /* Initialize the ed448 private/public key.
771 *
772 * key [in] Ed448 key.
773 * heap [in] heap pointer to pass to wc_InitShake256().
774 * returns BAD_FUNC_ARG when key is NULL
775 */
wc_ed448_init_ex(ed448_key * key,void * heap,int devId)776 int wc_ed448_init_ex(ed448_key* key, void *heap, int devId)
777 {
778 if (key == NULL)
779 return BAD_FUNC_ARG;
780
781 XMEMSET(key, 0, sizeof(ed448_key));
782
783 #ifdef WOLF_CRYPTO_CB
784 key->devId = devId;
785 #else
786 (void)devId;
787 #endif
788 key->heap = heap;
789
790 fe448_init();
791
792 #ifdef WOLFSSL_ED448_PERSISTENT_SHA
793 return ed448_hash_init(key, &key->sha);
794 #else /* !WOLFSSL_ED448_PERSISTENT_SHA */
795 return 0;
796 #endif /* WOLFSSL_ED448_PERSISTENT_SHA */
797 }
798
799 /* Initialize the ed448 private/public key.
800 *
801 * key [in] Ed448 key.
802 * returns BAD_FUNC_ARG when key is NULL
803 */
wc_ed448_init(ed448_key * key)804 int wc_ed448_init(ed448_key* key) {
805 return wc_ed448_init_ex(key, NULL, INVALID_DEVID);
806 }
807
808 /* Clears the ed448 key data
809 *
810 * key [in] Ed448 key.
811 */
wc_ed448_free(ed448_key * key)812 void wc_ed448_free(ed448_key* key)
813 {
814 if (key != NULL) {
815 #ifdef WOLFSSL_ED448_PERSISTENT_SHA
816 ed448_hash_free(key, &key->sha);
817 #endif
818 ForceZero(key, sizeof(ed448_key));
819 }
820 }
821
822
823 #ifdef HAVE_ED448_KEY_EXPORT
824
825 /* Export the ed448 public key.
826 *
827 * key [in] Ed448 public key.
828 * out [in] Array to hold public key.
829 * outLen [in/out] On in, the number of bytes in array.
830 * On out, the number bytes put into array.
831 * returns BAD_FUNC_ARG when a parameter is NULL,
832 * ECC_BAD_ARG_E when outLen is less than ED448_PUB_KEY_SIZE,
833 * 0 otherwise.
834 */
wc_ed448_export_public(ed448_key * key,byte * out,word32 * outLen)835 int wc_ed448_export_public(ed448_key* key, byte* out, word32* outLen)
836 {
837 int ret = 0;
838
839 /* sanity check on arguments */
840 if ((key == NULL) || (out == NULL) || (outLen == NULL)) {
841 ret = BAD_FUNC_ARG;
842 }
843
844 if ((ret == 0) && (*outLen < ED448_PUB_KEY_SIZE)) {
845 *outLen = ED448_PUB_KEY_SIZE;
846 ret = BUFFER_E;
847 }
848
849 if (ret == 0) {
850 *outLen = ED448_PUB_KEY_SIZE;
851 XMEMCPY(out, key->p, ED448_PUB_KEY_SIZE);
852 }
853
854 return ret;
855 }
856
857 #endif /* HAVE_ED448_KEY_EXPORT */
858
859
860 #ifdef HAVE_ED448_KEY_IMPORT
861 /* Import a compressed or uncompressed ed448 public key from a byte array.
862 * Public key encoded in big-endian.
863 *
864 * in [in] Array holding public key.
865 * inLen [in] Number of bytes of data in array.
866 * key [in] Ed448 public key.
867 * returns BAD_FUNC_ARG when a parameter is NULL or key format is not supported,
868 * 0 otherwise.
869 */
wc_ed448_import_public(const byte * in,word32 inLen,ed448_key * key)870 int wc_ed448_import_public(const byte* in, word32 inLen, ed448_key* key)
871 {
872 int ret = 0;
873
874 /* sanity check on arguments */
875 if ((in == NULL) || (key == NULL)) {
876 ret = BAD_FUNC_ARG;
877 }
878
879 if (inLen < ED448_PUB_KEY_SIZE) {
880 ret = BAD_FUNC_ARG;
881 }
882
883 if (ret == 0) {
884 /* compressed prefix according to draft
885 * https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-06 */
886 if (in[0] == 0x40 && inLen > ED448_PUB_KEY_SIZE) {
887 /* key is stored in compressed format so just copy in */
888 XMEMCPY(key->p, (in + 1), ED448_PUB_KEY_SIZE);
889 key->pubKeySet = 1;
890 }
891 /* importing uncompressed public key */
892 else if (in[0] == 0x04 && inLen > 2*ED448_PUB_KEY_SIZE) {
893 /* pass in (x,y) and store compressed key */
894 ret = ge448_compress_key(key->p, in+1, in+1+ED448_PUB_KEY_SIZE);
895 if (ret == 0)
896 key->pubKeySet = 1;
897 }
898 else if (inLen == ED448_PUB_KEY_SIZE) {
899 /* if not specified compressed or uncompressed check key size
900 * if key size is equal to compressed key size copy in key */
901 XMEMCPY(key->p, in, ED448_PUB_KEY_SIZE);
902 key->pubKeySet = 1;
903 }
904 else {
905 /* bad public key format */
906 ret = BAD_FUNC_ARG;
907 }
908 }
909
910 return ret;
911 }
912
913
914 /* Import an ed448 private key from a byte array.
915 *
916 * priv [in] Array holding private key.
917 * privSz [in] Number of bytes of data in array.
918 * key [in] Ed448 private key.
919 * returns BAD_FUNC_ARG when a parameter is NULL or privSz is less than
920 * ED448_KEY_SIZE,
921 * 0 otherwise.
922 */
wc_ed448_import_private_only(const byte * priv,word32 privSz,ed448_key * key)923 int wc_ed448_import_private_only(const byte* priv, word32 privSz,
924 ed448_key* key)
925 {
926 int ret = 0;
927
928 /* sanity check on arguments */
929 if ((priv == NULL) || (key == NULL)) {
930 ret = BAD_FUNC_ARG;
931 }
932
933 /* key size check */
934 if ((ret == 0) && (privSz < ED448_KEY_SIZE)) {
935 ret = BAD_FUNC_ARG;
936 }
937
938 if (ret == 0) {
939 XMEMCPY(key->k, priv, ED448_KEY_SIZE);
940 }
941
942 return ret;
943 }
944
945
946 /* Import an ed448 private and public keys from byte array(s).
947 *
948 * priv [in] Array holding private key from wc_ed448_export_private_only(),
949 * or private+public keys from wc_ed448_export_private().
950 * privSz [in] Number of bytes of data in private key array.
951 * pub [in] Array holding public key (or NULL).
952 * pubSz [in] Number of bytes of data in public key array (or 0).
953 * key [in] Ed448 private/public key.
954 * returns BAD_FUNC_ARG when a required parameter is NULL or an invalid
955 * combination of keys/lengths is supplied, 0 otherwise.
956 */
wc_ed448_import_private_key(const byte * priv,word32 privSz,const byte * pub,word32 pubSz,ed448_key * key)957 int wc_ed448_import_private_key(const byte* priv, word32 privSz,
958 const byte* pub, word32 pubSz, ed448_key* key)
959 {
960 int ret;
961
962 /* sanity check on arguments */
963 if (priv == NULL || key == NULL)
964 return BAD_FUNC_ARG;
965
966 /* key size check */
967 if (privSz < ED448_KEY_SIZE)
968 return BAD_FUNC_ARG;
969
970 if (pub == NULL) {
971 if (pubSz != 0)
972 return BAD_FUNC_ARG;
973 if (privSz < ED448_PRV_KEY_SIZE)
974 return BAD_FUNC_ARG;
975 pub = priv + ED448_KEY_SIZE;
976 pubSz = ED448_PUB_KEY_SIZE;
977 } else if (pubSz < ED448_PUB_KEY_SIZE) {
978 return BAD_FUNC_ARG;
979 }
980
981 /* import public key */
982 ret = wc_ed448_import_public(pub, pubSz, key);
983 if (ret != 0)
984 return ret;
985
986 /* make the private key (priv + pub) */
987 XMEMCPY(key->k, priv, ED448_KEY_SIZE);
988 XMEMCPY(key->k + ED448_KEY_SIZE, key->p, ED448_PUB_KEY_SIZE);
989
990 return ret;
991 }
992
993
994 #endif /* HAVE_ED448_KEY_IMPORT */
995
996
997 #ifdef HAVE_ED448_KEY_EXPORT
998
999 /* Export the ed448 private key.
1000 *
1001 * key [in] Ed448 private key.
1002 * out [in] Array to hold private key.
1003 * outLen [in/out] On in, the number of bytes in array.
1004 * On out, the number bytes put into array.
1005 * returns BAD_FUNC_ARG when a parameter is NULL,
1006 * ECC_BAD_ARG_E when outLen is less than ED448_KEY_SIZE,
1007 * 0 otherwise.
1008 */
wc_ed448_export_private_only(ed448_key * key,byte * out,word32 * outLen)1009 int wc_ed448_export_private_only(ed448_key* key, byte* out, word32* outLen)
1010 {
1011 int ret = 0;
1012
1013 /* sanity checks on arguments */
1014 if ((key == NULL) || (out == NULL) || (outLen == NULL)) {
1015 ret = BAD_FUNC_ARG;
1016 }
1017
1018 if ((ret == 0) && (*outLen < ED448_KEY_SIZE)) {
1019 *outLen = ED448_KEY_SIZE;
1020 ret = BUFFER_E;
1021 }
1022
1023 if (ret == 0) {
1024 *outLen = ED448_KEY_SIZE;
1025 XMEMCPY(out, key->k, ED448_KEY_SIZE);
1026 }
1027
1028 return ret;
1029 }
1030
1031 /* Export the ed448 private and public key.
1032 *
1033 * key [in] Ed448 private/public key.
1034 * out [in] Array to hold private and public key.
1035 * outLen [in/out] On in, the number of bytes in array.
1036 * On out, the number bytes put into array.
1037 * returns BAD_FUNC_ARG when a parameter is NULL,
1038 * BUFFER_E when outLen is less than ED448_PRV_KEY_SIZE,
1039 * 0 otherwise.
1040 */
wc_ed448_export_private(ed448_key * key,byte * out,word32 * outLen)1041 int wc_ed448_export_private(ed448_key* key, byte* out, word32* outLen)
1042 {
1043 int ret = 0;
1044
1045 /* sanity checks on arguments */
1046 if ((key == NULL) || (out == NULL) || (outLen == NULL)) {
1047 ret = BAD_FUNC_ARG;
1048 }
1049
1050 if ((ret == 0) && (*outLen < ED448_PRV_KEY_SIZE)) {
1051 *outLen = ED448_PRV_KEY_SIZE;
1052 ret = BUFFER_E;
1053 }
1054
1055 if (ret == 0) {
1056 *outLen = ED448_PRV_KEY_SIZE;
1057 XMEMCPY(out, key->k, ED448_PRV_KEY_SIZE);
1058 }
1059
1060 return ret;
1061 }
1062
1063 /* Export the ed448 private and public key.
1064 *
1065 * key [in] Ed448 private/public key.
1066 * priv [in] Array to hold private key.
1067 * privSz [in/out] On in, the number of bytes in private key array.
1068 * pub [in] Array to hold public key.
1069 * pubSz [in/out] On in, the number of bytes in public key array.
1070 * On out, the number bytes put into array.
1071 * returns BAD_FUNC_ARG when a parameter is NULL,
1072 * BUFFER_E when privSz is less than ED448_PRV_KEY_SIZE or pubSz is less
1073 * than ED448_PUB_KEY_SIZE,
1074 * 0 otherwise.
1075 */
wc_ed448_export_key(ed448_key * key,byte * priv,word32 * privSz,byte * pub,word32 * pubSz)1076 int wc_ed448_export_key(ed448_key* key, byte* priv, word32 *privSz,
1077 byte* pub, word32 *pubSz)
1078 {
1079 int ret = 0;
1080
1081 /* export 'full' private part */
1082 ret = wc_ed448_export_private(key, priv, privSz);
1083 if (ret == 0) {
1084 /* export public part */
1085 ret = wc_ed448_export_public(key, pub, pubSz);
1086 }
1087
1088 return ret;
1089 }
1090
1091 #endif /* HAVE_ED448_KEY_EXPORT */
1092
1093 /* Check the public key of the ed448 key matches the private key.
1094 *
1095 * key [in] Ed448 private/public key.
1096 * returns BAD_FUNC_ARG when key is NULL,
1097 * PUBLIC_KEY_E when the public key is not set or doesn't match,
1098 * other -ve value on hash failure,
1099 * 0 otherwise.
1100 */
wc_ed448_check_key(ed448_key * key)1101 int wc_ed448_check_key(ed448_key* key)
1102 {
1103 int ret = 0;
1104 unsigned char pubKey[ED448_PUB_KEY_SIZE];
1105
1106 if (key == NULL) {
1107 ret = BAD_FUNC_ARG;
1108 }
1109
1110 if (ret == 0 && !key->pubKeySet) {
1111 ret = PUBLIC_KEY_E;
1112 }
1113 if (ret == 0) {
1114 ret = wc_ed448_make_public(key, pubKey, sizeof(pubKey));
1115 }
1116 if ((ret == 0) && (XMEMCMP(pubKey, key->p, ED448_PUB_KEY_SIZE) != 0)) {
1117 ret = PUBLIC_KEY_E;
1118 }
1119
1120 return ret;
1121 }
1122
1123 /* Returns the size of an ed448 private key.
1124 *
1125 * key [in] Ed448 private/public key.
1126 * returns BAD_FUNC_ARG when key is NULL,
1127 * ED448_KEY_SIZE otherwise.
1128 */
wc_ed448_size(ed448_key * key)1129 int wc_ed448_size(ed448_key* key)
1130 {
1131 int ret = ED448_KEY_SIZE;
1132
1133 if (key == NULL) {
1134 ret = BAD_FUNC_ARG;
1135 }
1136
1137 return ret;
1138 }
1139
1140 /* Returns the size of an ed448 private plus public key.
1141 *
1142 * key [in] Ed448 private/public key.
1143 * returns BAD_FUNC_ARG when key is NULL,
1144 * ED448_PRV_KEY_SIZE otherwise.
1145 */
wc_ed448_priv_size(ed448_key * key)1146 int wc_ed448_priv_size(ed448_key* key)
1147 {
1148 int ret = ED448_PRV_KEY_SIZE;
1149
1150 if (key == NULL) {
1151 ret = BAD_FUNC_ARG;
1152 }
1153
1154 return ret;
1155 }
1156
1157 /* Returns the size of an ed448 public key.
1158 *
1159 * key [in] Ed448 private/public key.
1160 * returns BAD_FUNC_ARG when key is NULL,
1161 * ED448_PUB_KEY_SIZE otherwise.
1162 */
wc_ed448_pub_size(ed448_key * key)1163 int wc_ed448_pub_size(ed448_key* key)
1164 {
1165 int ret = ED448_PUB_KEY_SIZE;
1166
1167 if (key == NULL) {
1168 ret = BAD_FUNC_ARG;
1169 }
1170
1171 return ret;
1172 }
1173
1174 /* Returns the size of an ed448 signature.
1175 *
1176 * key [in] Ed448 private/public key.
1177 * returns BAD_FUNC_ARG when key is NULL,
1178 * ED448_SIG_SIZE otherwise.
1179 */
wc_ed448_sig_size(ed448_key * key)1180 int wc_ed448_sig_size(ed448_key* key)
1181 {
1182 int ret = ED448_SIG_SIZE;
1183
1184 if (key == NULL) {
1185 ret = BAD_FUNC_ARG;
1186 }
1187
1188 return ret;
1189 }
1190
1191 #endif /* HAVE_ED448 */
1192
1193