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