Coverage Report

Created: 2026-05-18 06:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-openssl-api/wolfcrypt/src/ed448.c
Line
Count
Source
1
/* ed448.c
2
 *
3
 * Copyright (C) 2006-2026 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 3 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
/* Possible Ed448 enable options:
29
 *   WOLFSSL_EDDSA_CHECK_PRIV_ON_SIGN                               Default: OFF
30
 *     Check that the private key didn't change during the signing operations.
31
 */
32
33
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
34
35
#ifdef HAVE_ED448
36
#if FIPS_VERSION3_GE(6,0,0)
37
    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
38
    #define FIPS_NO_WRAPPERS
39
40
       #ifdef USE_WINDOWS_API
41
               #pragma code_seg(".fipsA$f")
42
               #pragma const_seg(".fipsB$f")
43
       #endif
44
#endif
45
46
#include <wolfssl/wolfcrypt/ed448.h>
47
#include <wolfssl/wolfcrypt/hash.h>
48
#ifdef NO_INLINE
49
    #include <wolfssl/wolfcrypt/misc.h>
50
#else
51
    #define WOLFSSL_MISC_INCLUDED
52
    #include <wolfcrypt/src/misc.c>
53
#endif
54
55
#if defined(HAVE_ED448_SIGN) || defined(HAVE_ED448_VERIFY)
56
/* Size of context bytes to use with hash when signing and verifying. */
57
1.09k
#define ED448CTX_SIZE    8
58
/* Context to pass to hash when signing and verifying. */
59
static const byte ed448Ctx[ED448CTX_SIZE+1] = "SigEd448";
60
#endif
61
62
#if FIPS_VERSION3_GE(6,0,0)
63
    const unsigned int wolfCrypt_FIPS_ed448_ro_sanity[2] =
64
                                                     { 0x1a2b3c4d, 0x00000007 };
65
    int wolfCrypt_FIPS_ED448_sanity(void)
66
    {
67
        return 0;
68
    }
69
#endif
70
71
static int ed448_hash_init(ed448_key* key, wc_Shake *sha)
72
2.30k
{
73
2.30k
    int ret;
74
75
2.30k
    ret = wc_InitShake256(sha, key->heap,
76
2.30k
#if defined(WOLF_CRYPTO_CB)
77
2.30k
                           key->devId
78
#else
79
                           INVALID_DEVID
80
#endif
81
2.30k
        );
82
83
2.30k
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
84
2.30k
    if (ret == 0)
85
2.30k
        key->sha_clean_flag = 1;
86
2.30k
#endif
87
88
2.30k
    return ret;
89
2.30k
}
90
91
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
92
static int ed448_hash_reset(ed448_key* key)
93
1.66k
{
94
1.66k
    int ret;
95
96
1.66k
    if (key->sha_clean_flag)
97
1.66k
        ret = 0;
98
0
    else {
99
0
        wc_Shake256_Free(&key->sha);
100
0
        ret = wc_InitShake256(&key->sha, key->heap,
101
0
#if defined(WOLF_CRYPTO_CB)
102
0
                              key->devId
103
#else
104
                              INVALID_DEVID
105
#endif
106
0
            );
107
0
        if (ret == 0)
108
0
            key->sha_clean_flag = 1;
109
0
    }
110
1.66k
    return ret;
111
1.66k
}
112
#endif /* WOLFSSL_ED448_PERSISTENT_SHA */
113
114
static int ed448_hash_update(ed448_key* key, wc_Shake *sha, const byte* data,
115
                             word32 len)
116
148k
{
117
148k
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
118
148k
    if (key->sha_clean_flag)
119
2.30k
        key->sha_clean_flag = 0;
120
#else
121
    (void)key;
122
#endif
123
148k
    return wc_Shake256_Update(sha, data, len);
124
148k
}
125
126
static int ed448_hash_final(ed448_key* key, wc_Shake *sha, byte* hash,
127
                            word32 hashLen)
128
2.26k
{
129
2.26k
    int ret = wc_Shake256_Final(sha, hash, hashLen);
130
2.26k
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
131
2.26k
    if (ret == 0)
132
2.26k
        key->sha_clean_flag = 1;
133
#else
134
    (void)key;
135
#endif
136
2.26k
    return ret;
137
2.26k
}
138
139
static void ed448_hash_free(ed448_key* key, wc_Shake *sha)
140
2.30k
{
141
2.30k
    wc_Shake256_Free(sha);
142
2.30k
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
143
2.30k
    key->sha_clean_flag = 0;
144
#else
145
    (void)key;
146
#endif
147
2.30k
}
148
149
150
static int ed448_hash(ed448_key* key, const byte* in, word32 inLen,
151
                      byte* hash, word32 hashLen)
152
1.20k
{
153
1.20k
    int ret;
154
#ifndef WOLFSSL_ED448_PERSISTENT_SHA
155
    WC_DECLARE_VAR(sha, wc_Shake, 1, key ? key->heap : NULL);
156
#else
157
1.20k
    wc_Shake *sha;
158
1.20k
#endif
159
160
1.20k
    if (key == NULL || (in == NULL && inLen > 0) || hash == NULL) {
161
0
        return BAD_FUNC_ARG;
162
0
    }
163
164
1.20k
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
165
1.20k
    sha = &key->sha;
166
1.20k
    ret = ed448_hash_reset(key);
167
#else
168
    WC_ALLOC_VAR_EX(sha, wc_Shake, 1, key->heap, DYNAMIC_TYPE_HASHES,
169
                    return MEMORY_E);
170
    ret = ed448_hash_init(key, sha);
171
#endif
172
1.20k
    if (ret < 0) {
173
    #ifndef WOLFSSL_ED448_PERSISTENT_SHA
174
        WC_FREE_VAR_EX(sha, key->heap, DYNAMIC_TYPE_HASHES);
175
    #endif
176
0
        return ret;
177
0
    }
178
179
1.20k
    ret = ed448_hash_update(key, sha, in, inLen);
180
1.20k
    if (ret == 0)
181
1.20k
        ret = ed448_hash_final(key, sha, hash, hashLen);
182
183
#ifndef WOLFSSL_ED448_PERSISTENT_SHA
184
    ed448_hash_free(key, sha);
185
    WC_FREE_VAR_EX(sha, key->heap, DYNAMIC_TYPE_HASHES);
186
#endif
187
188
1.20k
    return ret;
189
1.20k
}
190
191
#if FIPS_VERSION3_GE(6,0,0)
192
/* Performs a Pairwise Consistency Test on an Ed448 key pair.
193
 *
194
 * @param [in] key  Ed448 key to test.
195
 * @param [in] rng  Random number generator to use to create random digest.
196
 * @return  0 on success.
197
 * @return  ECC_PCT_E when signing or verification fail.
198
 * @return  Other -ve when random number generation fails.
199
 */
200
static int ed448_pairwise_consistency_test(ed448_key* key, WC_RNG* rng)
201
{
202
    int err = 0;
203
    byte digest[WC_SHA256_DIGEST_SIZE];
204
    word32 digestLen = WC_SHA256_DIGEST_SIZE;
205
    byte sig[ED448_SIG_SIZE];
206
    word32 sigLen = ED448_SIG_SIZE;
207
    int res = 0;
208
209
    /* Generate a random digest to sign. */
210
    err = wc_RNG_GenerateBlock(rng, digest, digestLen);
211
    if (err == 0) {
212
        /* Sign digest without context. */
213
        err = wc_ed448_sign_msg_ex(digest, digestLen, sig, &sigLen, key, Ed448,
214
            NULL, 0);
215
        if (err != 0) {
216
            /* Any sign failure means test failed. */
217
            err = ECC_PCT_E;
218
        }
219
    }
220
    if (err == 0) {
221
        /* Verify digest without context. */
222
        err = wc_ed448_verify_msg_ex(sig, sigLen, digest, digestLen, &res, key,
223
            Ed448, NULL, 0);
224
        if (err != 0) {
225
            /* Any verification operation failure means test failed. */
226
            err = ECC_PCT_E;
227
        }
228
        /* Check whether the signature verified. */
229
        else if (res == 0) {
230
            /* Test failed. */
231
            err = ECC_PCT_E;
232
        }
233
    }
234
235
    ForceZero(sig, sigLen);
236
237
    return err;
238
}
239
#endif
240
241
/* Derive the public key for the private key.
242
 *
243
 * key       [in]  Ed448 key object.
244
 * pubKey    [in]  Byte array to hold the public key.
245
 * pubKeySz  [in]  Size of the array in bytes.
246
 * returns BAD_FUNC_ARG when key is NULL or pubKeySz is not equal to
247
 *         ED448_PUB_KEY_SIZE,
248
 *         other -ve value on hash failure,
249
 *         0 otherwise.
250
 */
251
int wc_ed448_make_public(ed448_key* key, unsigned char* pubKey, word32 pubKeySz)
252
909
{
253
909
    int   ret = 0;
254
909
    byte  az[ED448_PRV_KEY_SIZE];
255
909
    ge448_p2 A;
256
257
909
    if ((key == NULL) || (pubKey == NULL) || (pubKeySz != ED448_PUB_KEY_SIZE)) {
258
0
        ret = BAD_FUNC_ARG;
259
0
    }
260
261
909
    if ((ret == 0) && (!key->privKeySet)) {
262
27
        ret = ECC_PRIV_KEY_E;
263
27
    }
264
265
909
    if (ret == 0)
266
882
        ret = ed448_hash(key, key->k, ED448_KEY_SIZE, az, sizeof(az));
267
268
909
    if (ret == 0) {
269
        /* apply clamp */
270
882
        az[0]  &= 0xfc;
271
882
        az[55] |= 0x80;
272
882
        az[56]  = 0x00;
273
274
882
        ret = ge448_scalarmult_base(&A, az);
275
882
    }
276
277
909
    if (ret == 0) {
278
769
        ge448_to_bytes(pubKey, &A);
279
280
769
        key->pubKeySet = 1;
281
769
    }
282
283
909
    return ret;
284
909
}
285
286
/* Make a new ed448 private/public key.
287
 *
288
 * rng      [in]  Random number generator.
289
 * keysize  [in]  Size of the key to generate.
290
 * key      [in]  Ed448 key object.
291
 * returns BAD_FUNC_ARG when rng or key is NULL or keySz is not equal to
292
 *         ED448_KEY_SIZE,
293
 *         other -ve value on random number or hash failure,
294
 *         0 otherwise.
295
 */
296
int wc_ed448_make_key(WC_RNG* rng, int keySz, ed448_key* key)
297
118
{
298
118
    int ret = 0;
299
300
118
    if ((rng == NULL) || (key == NULL)) {
301
0
        ret = BAD_FUNC_ARG;
302
0
    }
303
304
    /* ed448 has 57 byte key sizes */
305
118
    if ((ret == 0) && (keySz != ED448_KEY_SIZE)) {
306
0
        ret = BAD_FUNC_ARG;
307
0
    }
308
309
118
    if (ret == 0) {
310
118
        key->pubKeySet = 0;
311
118
        key->privKeySet = 0;
312
313
118
        ret = wc_RNG_GenerateBlock(rng, key->k, ED448_KEY_SIZE);
314
118
    }
315
118
    if (ret == 0) {
316
100
        key->privKeySet = 1;
317
100
        ret = wc_ed448_make_public(key, key->p, ED448_PUB_KEY_SIZE);
318
100
        if (ret != 0) {
319
22
            key->privKeySet = 0;
320
22
            ForceZero(key->k, ED448_KEY_SIZE);
321
22
        }
322
100
    }
323
118
    if (ret == 0) {
324
        /* put public key after private key, on the same buffer */
325
78
        XMEMMOVE(key->k + ED448_KEY_SIZE, key->p, ED448_PUB_KEY_SIZE);
326
327
    #if FIPS_VERSION3_GE(6,0,0)
328
        ret = wc_ed448_check_key(key);
329
        if (ret == 0) {
330
            ret = ed448_pairwise_consistency_test(key, rng);
331
        }
332
    #endif
333
78
    }
334
335
118
    return ret;
336
118
}
337
338
#ifdef HAVE_ED448_SIGN
339
/* Sign the message using the ed448 private key.
340
 *
341
 *  in          [in]      Message to sign.
342
 *  inLen       [in]      Length of the message in bytes.
343
 *  out         [in]      Buffer to write signature into.
344
 *  outLen      [in/out]  On in, size of buffer.
345
 *                        On out, the length of the signature in bytes.
346
 *  key         [in]      Ed448 key to use when signing
347
 *  type        [in]      Type of signature to perform: Ed448 or Ed448ph
348
 *  context     [in]      Context of signing.
349
 *  contextLen  [in]      Length of context in bytes.
350
 *  returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
351
 *          context is not NULL or public key not set,
352
 *          BUFFER_E when outLen is less than ED448_SIG_SIZE,
353
 *          other -ve values when hash fails,
354
 *          0 otherwise.
355
 */
356
int wc_ed448_sign_msg_ex(const byte* in, word32 inLen, byte* out,
357
                          word32 *outLen, ed448_key* key, byte type,
358
                          const byte* context, byte contextLen)
359
339
{
360
339
    ge448_p2 R;
361
339
    byte     nonce[ED448_SIG_SIZE];
362
339
    byte     hram[ED448_SIG_SIZE];
363
339
    byte     az[ED448_PRV_KEY_SIZE];
364
339
    int      ret = 0;
365
#ifdef WOLFSSL_EDDSA_CHECK_PRIV_ON_SIGN
366
    byte     orig_k[ED448_KEY_SIZE];
367
#endif
368
#ifndef WOLFSSL_ED448_PERSISTENT_SHA
369
    WC_DECLARE_VAR(sha, wc_Shake, 1, key ? key->heap : NULL);
370
#endif
371
372
    /* sanity check on arguments */
373
339
    if ((in == NULL) || (out == NULL) || (outLen == NULL) || (key == NULL) ||
374
323
                                     ((context == NULL) && (contextLen != 0))) {
375
16
        ret = BAD_FUNC_ARG;
376
16
    }
377
339
    if ((ret == 0) && (!key->pubKeySet)) {
378
0
        ret = BAD_FUNC_ARG;
379
0
    }
380
339
    if ((ret == 0) && (!key->privKeySet)) {
381
0
        ret = BAD_FUNC_ARG;
382
0
    }
383
384
339
    if ((ret == 0) && (type == Ed448ph) && (inLen != ED448_PREHASH_SIZE))
385
0
    {
386
0
        ret = BAD_LENGTH_E;
387
0
    }
388
389
    /* check and set up out length */
390
339
    if ((ret == 0) && (*outLen < ED448_SIG_SIZE)) {
391
0
        *outLen = ED448_SIG_SIZE;
392
0
        ret = BUFFER_E;
393
0
    }
394
395
339
    if (ret == 0) {
396
323
        *outLen = ED448_SIG_SIZE;
397
398
#ifdef WOLFSSL_EDDSA_CHECK_PRIV_ON_SIGN
399
        XMEMCPY(orig_k, key->k, ED448_KEY_SIZE);
400
#endif
401
402
        /* step 1: create nonce to use where nonce is r in
403
           r = H(h_b, ... ,h_2b-1,M) */
404
323
        ret = ed448_hash(key, key->k, ED448_KEY_SIZE, az, sizeof(az));
405
323
    }
406
339
    if (ret == 0) {
407
323
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
408
323
        wc_Shake *sha = &key->sha;
409
#else
410
        WC_ALLOC_VAR_EX(sha, wc_Shake, 1, key->heap, DYNAMIC_TYPE_HASHES,
411
                        ret = MEMORY_E);
412
        if (ret == 0)
413
            ret = ed448_hash_init(key, sha);
414
#endif
415
        /* apply clamp */
416
323
        az[0]  &= 0xfc;
417
323
        az[55] |= 0x80;
418
323
        az[56]  = 0x00;
419
420
323
        if (ret == 0) {
421
323
            ret = ed448_hash_update(key, sha, ed448Ctx, ED448CTX_SIZE);
422
323
        }
423
323
        if (ret == 0) {
424
323
            ret = ed448_hash_update(key, sha, &type, sizeof(type));
425
323
        }
426
323
        if (ret == 0) {
427
323
            ret = ed448_hash_update(key, sha, &contextLen, sizeof(contextLen));
428
323
        }
429
323
        if ((ret == 0) && (context != NULL)) {
430
0
            ret = ed448_hash_update(key, sha, context, contextLen);
431
0
        }
432
323
        if (ret == 0) {
433
323
            ret = ed448_hash_update(key, sha, az + ED448_KEY_SIZE, ED448_KEY_SIZE);
434
323
        }
435
323
        if (ret == 0) {
436
323
            ret = ed448_hash_update(key, sha, in, inLen);
437
323
        }
438
323
        if (ret == 0) {
439
323
            ret = ed448_hash_final(key, sha, nonce, sizeof(nonce));
440
323
        }
441
#ifndef WOLFSSL_ED448_PERSISTENT_SHA
442
        ed448_hash_free(key, sha);
443
#endif
444
323
    }
445
339
    if (ret == 0) {
446
323
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
447
323
        wc_Shake *sha = &key->sha;
448
#else
449
        ret = ed448_hash_init(key, sha);
450
#endif
451
323
        if (ret == 0)
452
323
            sc448_reduce(nonce);
453
        /* step 2: computing R = rB where rB is the scalar multiplication of
454
           r and B */
455
323
        if (ret == 0) {
456
323
            ret = ge448_scalarmult_base(&R,nonce);
457
323
        }
458
        /* step 3: hash R + public key + message getting H(R,A,M) then
459
           creating S = (r + H(R,A,M)a) mod l */
460
323
        if (ret == 0) {
461
314
            ge448_to_bytes(out,&R);
462
463
314
            ret = ed448_hash_update(key, sha, ed448Ctx, ED448CTX_SIZE);
464
314
        }
465
323
        if (ret == 0) {
466
314
            ret = ed448_hash_update(key, sha, &type, sizeof(type));
467
314
        }
468
323
        if (ret == 0) {
469
314
            ret = ed448_hash_update(key, sha, &contextLen, sizeof(contextLen));
470
314
        }
471
323
        if ((ret == 0) && (context != NULL)) {
472
0
            ret = ed448_hash_update(key, sha, context, contextLen);
473
0
        }
474
323
        if (ret == 0) {
475
314
            ret = ed448_hash_update(key, sha, out, ED448_SIG_SIZE/2);
476
314
        }
477
323
        if (ret == 0) {
478
314
            ret = ed448_hash_update(key, sha, key->p, ED448_PUB_KEY_SIZE);
479
314
        }
480
323
        if (ret == 0) {
481
314
            ret = ed448_hash_update(key, sha, in, inLen);
482
314
        }
483
323
        if (ret == 0) {
484
314
            ret = ed448_hash_final(key, sha, hram, sizeof(hram));
485
314
        }
486
#ifndef WOLFSSL_ED448_PERSISTENT_SHA
487
        ed448_hash_free(key, sha);
488
#endif
489
323
    }
490
#ifndef WOLFSSL_ED448_PERSISTENT_SHA
491
    WC_FREE_VAR_EX(sha, key->heap, DYNAMIC_TYPE_HASHES);
492
#endif
493
494
339
    if (ret == 0) {
495
314
        sc448_reduce(hram);
496
314
        sc448_muladd(out + (ED448_SIG_SIZE/2), hram, az, nonce);
497
314
    }
498
499
#ifdef WOLFSSL_EDDSA_CHECK_PRIV_ON_SIGN
500
    if (ret == 0) {
501
        int  i;
502
        byte c = 0;
503
        for (i = 0; i < ED448_KEY_SIZE; i++) {
504
            c |= key->k[i] ^ orig_k[i];
505
        }
506
        ret = ctMaskGT(c, 0) & SIG_VERIFY_E;
507
    }
508
    ForceZero(orig_k, sizeof(orig_k));
509
#endif
510
511
339
    ForceZero(az, sizeof(az));
512
339
    ForceZero(nonce, sizeof(nonce));
513
339
    return ret;
514
339
}
515
516
/* Sign the message using the ed448 private key.
517
 * Signature type is Ed448.
518
 *
519
 *  in          [in]      Message to sign.
520
 *  inLen       [in]      Length of the message in bytes.
521
 *  out         [in]      Buffer to write signature into.
522
 *  outLen      [in/out]  On in, size of buffer.
523
 *                        On out, the length of the signature in bytes.
524
 *  key         [in]      Ed448 key to use when signing
525
 *  context     [in]      Context of signing.
526
 *  contextLen  [in]      Length of context in bytes.
527
 *  returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
528
 *          context is not NULL or public key not set,
529
 *          BUFFER_E when outLen is less than ED448_SIG_SIZE,
530
 *          other -ve values when hash fails,
531
 *          0 otherwise.
532
 */
533
int wc_ed448_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen,
534
                      ed448_key* key, const byte* context, byte contextLen)
535
339
{
536
339
    return wc_ed448_sign_msg_ex(in, inLen, out, outLen, key, Ed448, context,
537
339
                                                                    contextLen);
538
339
}
539
540
/* Sign the hash using the ed448 private key.
541
 * Signature type is Ed448ph.
542
 *
543
 *  hash        [in]      Hash of message to sign.
544
 *  hashLen     [in]      Length of hash of message in bytes.
545
 *  out         [in]      Buffer to write signature into.
546
 *  outLen      [in/out]  On in, size of buffer.
547
 *                        On out, the length of the signature in bytes.
548
 *  key         [in]      Ed448 key to use when signing
549
 *  context     [in]      Context of signing.
550
 *  contextLen  [in]      Length of context in bytes.
551
 *  returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
552
 *          context is not NULL or public key not set,
553
 *          BUFFER_E when outLen is less than ED448_SIG_SIZE,
554
 *          other -ve values when hash fails,
555
 *          0 otherwise.
556
 */
557
int wc_ed448ph_sign_hash(const byte* hash, word32 hashLen, byte* out,
558
                         word32 *outLen, ed448_key* key,
559
                         const byte* context, byte contextLen)
560
0
{
561
0
    return wc_ed448_sign_msg_ex(hash, hashLen, out, outLen, key, Ed448ph,
562
0
                                context, contextLen);
563
0
}
564
565
/* Sign the message using the ed448 private key.
566
 * Signature type is Ed448ph.
567
 *
568
 *  in          [in]      Message to sign.
569
 *  inLen       [in]      Length of the message to sign in bytes.
570
 *  out         [in]      Buffer to write signature into.
571
 *  outLen      [in/out]  On in, size of buffer.
572
 *                        On out, the length of the signature in bytes.
573
 *  key         [in]      Ed448 key to use when signing
574
 *  context     [in]      Context of signing.
575
 *  contextLen  [in]      Length of context in bytes.
576
 *  returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
577
 *          context is not NULL or public key not set,
578
 *          BUFFER_E when outLen is less than ED448_SIG_SIZE,
579
 *          other -ve values when hash fails,
580
 *          0 otherwise.
581
 */
582
int wc_ed448ph_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen,
583
                        ed448_key* key, const byte* context, byte contextLen)
584
0
{
585
0
    int  ret;
586
0
    byte hash[ED448_PREHASH_SIZE];
587
588
0
    ret = ed448_hash(key, in, inLen, hash, sizeof(hash));
589
590
0
    if (ret == 0) {
591
0
        ret = wc_ed448ph_sign_hash(hash, sizeof(hash), out, outLen, key,
592
0
                                                           context, contextLen);
593
0
    }
594
595
0
    return ret;
596
0
}
597
#endif /* HAVE_ED448_SIGN */
598
599
#ifdef HAVE_ED448_VERIFY
600
601
/* Verify the message using the ed448 public key.
602
 *
603
 *  sig         [in]  Signature to verify.
604
 *  sigLen      [in]  Size of signature in bytes.
605
 *  key         [in]  Ed448 key to use to verify.
606
 *  type        [in]  Type of signature to verify: Ed448 or Ed448ph
607
 *  context     [in]  Context of verification.
608
 *  contextLen  [in]  Length of context in bytes.
609
 *  returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
610
 *          context is not NULL or public key not set,
611
 *          BUFFER_E when sigLen is less than ED448_SIG_SIZE,
612
 *          other -ve values when hash fails,
613
 *          0 otherwise.
614
 */
615
616
static int ed448_verify_msg_init_with_sha(const byte* sig, word32 sigLen,
617
                                      ed448_key* key, wc_Shake *sha, byte type,
618
                                      const byte* context, byte contextLen)
619
458
{
620
458
    int ret;
621
622
    /* sanity check on arguments */
623
458
    if ((sig == NULL) || (key == NULL) ||
624
458
        ((context == NULL) && (contextLen != 0))) {
625
0
        return BAD_FUNC_ARG;
626
0
    }
627
628
    /* check on basics needed to verify signature */
629
458
    if (sigLen != ED448_SIG_SIZE) {
630
0
        return BAD_FUNC_ARG;
631
0
    }
632
633
    /* find H(R,A,M) and store it as h */
634
458
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
635
458
    ret = ed448_hash_reset(key);
636
458
    if (ret < 0)
637
0
        return ret;
638
458
#endif
639
640
458
    ret = ed448_hash_update(key, sha, ed448Ctx, ED448CTX_SIZE);
641
458
    if (ret == 0) {
642
458
        ret = ed448_hash_update(key, sha, &type, sizeof(type));
643
458
    }
644
458
    if (ret == 0) {
645
458
        ret = ed448_hash_update(key, sha, &contextLen, sizeof(contextLen));
646
458
    }
647
458
    if ((ret == 0) && (context != NULL)) {
648
0
        ret = ed448_hash_update(key, sha, context, contextLen);
649
0
    }
650
458
    if (ret == 0) {
651
458
        ret = ed448_hash_update(key, sha, sig, ED448_SIG_SIZE/2);
652
458
    }
653
458
    if (ret == 0) {
654
458
        ret = ed448_hash_update(key, sha, key->p, ED448_PUB_KEY_SIZE);
655
458
    }
656
657
458
    return ret;
658
458
}
659
660
/*
661
   msgSegment     an array of bytes containing a message segment
662
   msgSegmentLen  length of msgSegment
663
   key            Ed448 public key
664
   return         0 on success
665
*/
666
static int ed448_verify_msg_update_with_sha(const byte* msgSegment,
667
                                        word32 msgSegmentLen,
668
                                        ed448_key* key,
669
                                        wc_Shake *sha)
670
141k
{
671
    /* sanity check on arguments */
672
141k
    if (msgSegment == NULL || key == NULL)
673
12
        return BAD_FUNC_ARG;
674
675
141k
    return ed448_hash_update(key, sha, msgSegment, msgSegmentLen);
676
141k
}
677
678
/* Order of the ed448 curve - little endian. */
679
static const byte ed448_order[] = {
680
    0xf3, 0x44, 0x58, 0xab, 0x92, 0xc2, 0x78, 0x23,
681
    0x55, 0x8f, 0xc5, 0x8d, 0x72, 0xc2, 0x6c, 0x21,
682
    0x90, 0x36, 0xd6, 0xae, 0x49, 0xdb, 0x4e, 0xc4,
683
    0xe9, 0x23, 0xca, 0x7c, 0xff, 0xff, 0xff, 0xff,
684
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
685
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
686
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f,
687
    0x00
688
};
689
690
/* Verify the message using the ed448 public key.
691
 *
692
 *  sig         [in]  Signature to verify.
693
 *  sigLen      [in]  Size of signature in bytes.
694
 *  res         [out] *res is set to 1 on successful verification.
695
 *  key         [in]  Ed448 key to use to verify.
696
 *  returns BAD_FUNC_ARG when a parameter is NULL or public key not set,
697
 *          BUFFER_E when sigLen is less than ED448_SIG_SIZE,
698
 *          other -ve values when hash fails,
699
 *          0 otherwise.
700
 */
701
static int ed448_verify_msg_final_with_sha(const byte* sig, word32 sigLen,
702
                                     int* res, ed448_key* key, wc_Shake *sha)
703
446
{
704
446
    byte     rcheck[ED448_KEY_SIZE];
705
446
    byte     h[ED448_SIG_SIZE];
706
446
    ge448_p2 A;
707
446
    ge448_p2 R;
708
446
    int      ret;
709
446
    int      i;
710
711
    /* sanity check on arguments */
712
446
    if ((sig == NULL) || (res == NULL) || (key == NULL))
713
0
        return BAD_FUNC_ARG;
714
715
    /* set verification failed by default */
716
446
    *res = 0;
717
718
    /* check on basics needed to verify signature */
719
446
    if (sigLen != ED448_SIG_SIZE)
720
0
        return BAD_FUNC_ARG;
721
    /* Check S is not larger than or equal to order. */
722
889
    for (i = (int)sizeof(ed448_order) - 1; i >= 0; i--) {
723
        /* Bigger than order. */
724
889
        if (sig[ED448_SIG_SIZE/2 + i] > ed448_order[i])
725
23
            return BAD_FUNC_ARG;
726
        /* Less than order. */
727
866
        if (sig[ED448_SIG_SIZE/2 + i] < ed448_order[i])
728
423
            break;
729
866
    }
730
    /* Same value as order. */
731
423
    if (i == -1)
732
0
        return BAD_FUNC_ARG;
733
734
    /* Reject identity public key (0,1): 0x01 followed by 56 zero bytes. */
735
423
    {
736
423
        int isIdentity = (key->p[0] == 0x01);
737
423
        int j;
738
423
        for (j = 1; j < ED448_PUB_KEY_SIZE && isIdentity; j++) {
739
0
            if (key->p[j] != 0x00)
740
0
                isIdentity = 0;
741
0
        }
742
423
        if (isIdentity)
743
0
            return BAD_FUNC_ARG;
744
423
    }
745
746
    /* uncompress A (public key), test if valid, and negate it */
747
423
    if (ge448_from_bytes_negate_vartime(&A, key->p) != 0)
748
0
        return BAD_FUNC_ARG;
749
750
423
    ret = ed448_hash_final(key, sha, h, sizeof(h));
751
423
    if (ret != 0)
752
0
        return ret;
753
754
423
    sc448_reduce(h);
755
756
    /* Uses a fast single-signature verification SB = R + H(R,A,M)A becomes
757
     * SB - H(R,A,M)A saving decompression of R
758
     */
759
423
    ret = ge448_double_scalarmult_vartime(&R, h, &A,
760
423
                                          sig + (ED448_SIG_SIZE/2));
761
423
    if (ret != 0)
762
64
        return ret;
763
764
359
    ge448_to_bytes(rcheck, &R);
765
766
    /* comparison of R created to R in sig */
767
359
    if (ConstantCompare(rcheck, sig, ED448_SIG_SIZE/2) != 0) {
768
101
        ret = SIG_VERIFY_E;
769
101
    }
770
258
    else {
771
        /* set the verification status */
772
258
        *res = 1;
773
258
    }
774
775
359
    return ret;
776
423
}
777
778
#ifdef WOLFSSL_ED448_STREAMING_VERIFY
779
int wc_ed448_verify_msg_init(const byte* sig, word32 sigLen, ed448_key* key,
780
                        byte type, const byte* context, byte contextLen)
781
144
{
782
144
    return ed448_verify_msg_init_with_sha(sig, sigLen, key, &key->sha, type,
783
144
                                      context, contextLen);
784
144
}
785
786
int wc_ed448_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen,
787
                             ed448_key* key)
788
141k
{
789
141k
    return ed448_verify_msg_update_with_sha(msgSegment, msgSegmentLen, key,
790
141k
                                        &key->sha);
791
141k
}
792
793
int wc_ed448_verify_msg_final(const byte* sig, word32 sigLen,
794
                              int* res, ed448_key* key)
795
142
{
796
142
    return ed448_verify_msg_final_with_sha(sig, sigLen, res, key, &key->sha);
797
142
}
798
#endif
799
800
/* Verify the message using the ed448 public key.
801
 *
802
 *  sig         [in]  Signature to verify.
803
 *  sigLen      [in]  Size of signature in bytes.
804
 *  msg         [in]  Message to verify.
805
 *  msgLen      [in]  Length of the message in bytes.
806
 *  res         [out] *res is set to 1 on successful verification.
807
 *  key         [in]  Ed448 key to use to verify.
808
 *  type        [in]  Type of signature to verify: Ed448 or Ed448ph
809
 *  context     [in]  Context of verification.
810
 *  contextLen  [in]  Length of context in bytes.
811
 *  returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
812
 *          context is not NULL or public key not set,
813
 *          BUFFER_E when sigLen is less than ED448_SIG_SIZE,
814
 *          other -ve values when hash fails,
815
 *          0 otherwise.
816
 */
817
int wc_ed448_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg,
818
                            word32 msgLen, int* res, ed448_key* key,
819
                            byte type, const byte* context, byte contextLen)
820
314
{
821
314
    int ret;
822
314
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
823
314
    wc_Shake *sha;
824
#else
825
    WC_DECLARE_VAR(sha, wc_Shake, 1, key ? key->heap : NULL);
826
#endif
827
828
314
    if (key == NULL)
829
0
        return BAD_FUNC_ARG;
830
831
314
    if ((type == Ed448ph) &&
832
0
        (msgLen != ED448_PREHASH_SIZE))
833
0
    {
834
0
        return BAD_LENGTH_E;
835
0
    }
836
837
314
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
838
314
    sha = &key->sha;
839
#else
840
    WC_ALLOC_VAR_EX(sha, wc_Shake, 1, key->heap, DYNAMIC_TYPE_HASHES,
841
                    return MEMORY_E);
842
    ret = ed448_hash_init(key, sha);
843
    if (ret < 0) {
844
        WC_FREE_VAR_EX(sha, key->heap, DYNAMIC_TYPE_HASHES);
845
        return ret;
846
    }
847
#endif
848
849
314
    ret = ed448_verify_msg_init_with_sha(sig, sigLen, key, sha,
850
314
                                   type, context, contextLen);
851
314
    if (ret == 0)
852
314
        ret = ed448_verify_msg_update_with_sha(msg, msgLen, key, sha);
853
314
    if (ret == 0)
854
304
        ret = ed448_verify_msg_final_with_sha(sig, sigLen, res, key, sha);
855
856
#ifndef WOLFSSL_ED448_PERSISTENT_SHA
857
    ed448_hash_free(key, sha);
858
    WC_FREE_VAR_EX(sha, key->heap, DYNAMIC_TYPE_HASHES);
859
#endif
860
861
314
    return ret;
862
314
}
863
864
/* Verify the message using the ed448 public key.
865
 * Signature type is Ed448.
866
 *
867
 *  sig         [in]  Signature to verify.
868
 *  sigLen      [in]  Size of signature in bytes.
869
 *  msg         [in]  Message to verify.
870
 *  msgLen      [in]  Length of the message in bytes.
871
 *  key         [in]  Ed448 key to use to verify.
872
 *  context     [in]  Context of verification.
873
 *  contextLen  [in]  Length of context in bytes.
874
 *  returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
875
 *          context is not NULL or public key not set,
876
 *          BUFFER_E when sigLen is less than ED448_SIG_SIZE,
877
 *          other -ve values when hash fails,
878
 *          0 otherwise.
879
 */
880
int wc_ed448_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
881
                        word32 msgLen, int* res, ed448_key* key,
882
                        const byte* context, byte contextLen)
883
314
{
884
314
    return wc_ed448_verify_msg_ex(sig, sigLen, msg, msgLen, res, key, Ed448,
885
314
                                                           context, contextLen);
886
314
}
887
888
/* Verify the hash using the ed448 public key.
889
 * Signature type is Ed448ph.
890
 *
891
 *  sig         [in]  Signature to verify.
892
 *  sigLen      [in]  Size of signature in bytes.
893
 *  hash        [in]  Hash of message to verify.
894
 *  hashLen     [in]  Length of the hash in bytes.
895
 *  key         [in]  Ed448 key to use to verify.
896
 *  context     [in]  Context of verification.
897
 *  contextLen  [in]  Length of context in bytes.
898
 *  returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
899
 *          context is not NULL or public key not set,
900
 *          BUFFER_E when sigLen is less than ED448_SIG_SIZE,
901
 *          other -ve values when hash fails,
902
 *          0 otherwise.
903
 */
904
int wc_ed448ph_verify_hash(const byte* sig, word32 sigLen, const byte* hash,
905
                           word32 hashLen, int* res, ed448_key* key,
906
                           const byte* context, byte contextLen)
907
0
{
908
0
    return wc_ed448_verify_msg_ex(sig, sigLen, hash, hashLen, res, key, Ed448ph,
909
0
                                                           context, contextLen);
910
0
}
911
912
/* Verify the message using the ed448 public key.
913
 * Signature type is Ed448ph.
914
 *
915
 *  sig         [in]  Signature to verify.
916
 *  sigLen      [in]  Size of signature in bytes.
917
 *  msg         [in]  Message to verify.
918
 *  msgLen      [in]  Length of the message in bytes.
919
 *  key         [in]  Ed448 key to use to verify.
920
 *  context     [in]  Context of verification.
921
 *  contextLen  [in]  Length of context in bytes.
922
 *  returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
923
 *          context is not NULL or public key not set,
924
 *          BUFFER_E when sigLen is less than ED448_SIG_SIZE,
925
 *          other -ve values when hash fails,
926
 *          0 otherwise.
927
 */
928
int wc_ed448ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
929
                          word32 msgLen, int* res, ed448_key* key,
930
                          const byte* context, byte contextLen)
931
0
{
932
0
    int  ret = 0;
933
0
    byte hash[ED448_PREHASH_SIZE];
934
935
0
    ret = ed448_hash(key, msg, msgLen, hash, sizeof(hash));
936
937
0
    if (ret == 0) {
938
0
        ret = wc_ed448ph_verify_hash(sig, sigLen, hash, sizeof(hash), res, key,
939
0
                                                           context, contextLen);
940
0
    }
941
942
0
    return ret;
943
0
}
944
#endif /* HAVE_ED448_VERIFY */
945
946
/* Initialize the ed448 private/public key.
947
 *
948
 * key  [in]  Ed448 key.
949
 * heap [in]  heap pointer to pass to wc_InitShake256().
950
 * returns BAD_FUNC_ARG when key is NULL
951
 */
952
int wc_ed448_init_ex(ed448_key* key, void *heap, int devId)
953
2.30k
{
954
2.30k
    if (key == NULL)
955
0
        return BAD_FUNC_ARG;
956
957
2.30k
    XMEMSET(key, 0, sizeof(ed448_key));
958
959
2.30k
#ifdef WOLF_CRYPTO_CB
960
2.30k
    key->devId = devId;
961
#else
962
    (void)devId;
963
#endif
964
2.30k
    key->heap = heap;
965
966
2.30k
    fe448_init();
967
968
#ifdef WOLFSSL_CHECK_MEM_ZERO
969
    wc_MemZero_Add("wc_ed448_init_ex key->k", &key->k, sizeof(key->k));
970
#endif
971
972
2.30k
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
973
2.30k
    return ed448_hash_init(key, &key->sha);
974
#else /* !WOLFSSL_ED448_PERSISTENT_SHA */
975
    return 0;
976
#endif /* WOLFSSL_ED448_PERSISTENT_SHA */
977
2.30k
}
978
979
/* Initialize the ed448 private/public key.
980
 *
981
 * key  [in]  Ed448 key.
982
 * returns BAD_FUNC_ARG when key is NULL
983
 */
984
1.20k
int wc_ed448_init(ed448_key* key) {
985
1.20k
    return wc_ed448_init_ex(key, NULL, INVALID_DEVID);
986
1.20k
}
987
988
/* Clears the ed448 key data
989
 *
990
 * key  [in]  Ed448 key.
991
 */
992
void wc_ed448_free(ed448_key* key)
993
2.30k
{
994
2.30k
    if (key != NULL) {
995
2.30k
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
996
2.30k
        ed448_hash_free(key, &key->sha);
997
2.30k
#endif
998
2.30k
        ForceZero(key, sizeof(ed448_key));
999
    #ifdef WOLFSSL_CHECK_MEM_ZERO
1000
        wc_MemZero_Check(key, sizeof(ed448_key));
1001
    #endif
1002
2.30k
    }
1003
2.30k
}
1004
1005
#ifndef WC_NO_CONSTRUCTORS
1006
ed448_key* wc_ed448_new(void* heap, int devId, int *result_code)
1007
1.10k
{
1008
1.10k
    int ret;
1009
1.10k
    ed448_key* key = (ed448_key*)XMALLOC(sizeof(ed448_key), heap,
1010
1.10k
                        DYNAMIC_TYPE_ED448);
1011
1.10k
    if (key == NULL) {
1012
0
        ret = MEMORY_E;
1013
0
    }
1014
1.10k
    else {
1015
1.10k
        ret = wc_ed448_init_ex(key, heap, devId);
1016
1.10k
        if (ret != 0) {
1017
0
            XFREE(key, heap, DYNAMIC_TYPE_ED448);
1018
0
            key = NULL;
1019
0
        }
1020
1.10k
    }
1021
1022
1.10k
    if (result_code != NULL)
1023
0
        *result_code = ret;
1024
1025
1.10k
    return key;
1026
1.10k
}
1027
1028
1.10k
int wc_ed448_delete(ed448_key* key, ed448_key** key_p) {
1029
1.10k
    void* heap;
1030
1.10k
    if (key == NULL)
1031
0
        return BAD_FUNC_ARG;
1032
1.10k
    heap = key->heap;
1033
1.10k
    wc_ed448_free(key);
1034
1.10k
    XFREE(key, heap, DYNAMIC_TYPE_ED448);
1035
1.10k
    if (key_p != NULL)
1036
0
        *key_p = NULL;
1037
1.10k
    return 0;
1038
1.10k
}
1039
#endif /* !WC_NO_CONSTRUCTORS */
1040
1041
#ifdef HAVE_ED448_KEY_EXPORT
1042
1043
/* Export the ed448 public key.
1044
 *
1045
 * key     [in]      Ed448 public key.
1046
 * out     [in]      Array to hold public key.
1047
 * outLen  [in/out]  On in, the number of bytes in array.
1048
 *                   On out, the number bytes put into array.
1049
 * returns BAD_FUNC_ARG when a parameter is NULL,
1050
 *         ECC_BAD_ARG_E when outLen is less than ED448_PUB_KEY_SIZE,
1051
 *         0 otherwise.
1052
 */
1053
int wc_ed448_export_public(const ed448_key* key, byte* out, word32* outLen)
1054
38
{
1055
38
    int ret = 0;
1056
1057
    /* sanity check on arguments */
1058
38
    if ((key == NULL) || (out == NULL) || (outLen == NULL)) {
1059
10
        ret = BAD_FUNC_ARG;
1060
10
    }
1061
1062
38
    if ((ret == 0) && (*outLen < ED448_PUB_KEY_SIZE)) {
1063
1
        *outLen = ED448_PUB_KEY_SIZE;
1064
1
        ret = BUFFER_E;
1065
1
    }
1066
1067
38
    if (ret == 0) {
1068
27
        *outLen = ED448_PUB_KEY_SIZE;
1069
27
        XMEMCPY(out, key->p, ED448_PUB_KEY_SIZE);
1070
27
    }
1071
1072
38
    return ret;
1073
38
}
1074
1075
#endif /* HAVE_ED448_KEY_EXPORT */
1076
1077
1078
#ifdef HAVE_ED448_KEY_IMPORT
1079
/* Import a compressed or uncompressed ed448 public key from a byte array.
1080
 * Public key encoded in big-endian.
1081
 *
1082
 * in       [in]  Array holding public key.
1083
 * inLen    [in]  Number of bytes of data in array.
1084
 * key      [in]  Ed448 public key.
1085
 * trusted  [in]  Indicates whether the public key data is trusted.
1086
 *                When 0, checks public key matches private key.
1087
 *                When 1, doesn't check public key matches private key.
1088
 * returns BAD_FUNC_ARG when a parameter is NULL or key format is not supported,
1089
 *         0 otherwise.
1090
 */
1091
int wc_ed448_import_public_ex(const byte* in, word32 inLen, ed448_key* key,
1092
    int trusted)
1093
602
{
1094
602
    int ret = 0;
1095
1096
    /* sanity check on arguments */
1097
602
    if ((in == NULL) || (key == NULL)) {
1098
0
        ret = BAD_FUNC_ARG;
1099
0
    }
1100
1101
602
    if ((inLen != ED448_PUB_KEY_SIZE) &&
1102
44
        (inLen != ED448_PUB_KEY_SIZE + 1) &&
1103
42
        (inLen != 2 * ED448_PUB_KEY_SIZE + 1)) {
1104
39
        ret = BAD_FUNC_ARG;
1105
39
    }
1106
1107
602
    if (ret == 0) {
1108
        /* compressed prefix according to draft
1109
         * https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-06 */
1110
563
        if (in[0] == 0x40 && inLen > ED448_PUB_KEY_SIZE) {
1111
            /* key is stored in compressed format so just copy in */
1112
2
            XMEMCPY(key->p, (in + 1), ED448_PUB_KEY_SIZE);
1113
2
        }
1114
        /* importing uncompressed public key */
1115
561
        else if (in[0] == 0x04 && inLen > 2*ED448_PUB_KEY_SIZE) {
1116
            /* pass in (x,y) and store compressed key */
1117
2
            ret = ge448_compress_key(key->p, in+1, in+1+ED448_PUB_KEY_SIZE);
1118
2
        }
1119
559
        else if (inLen == ED448_PUB_KEY_SIZE) {
1120
            /* if not specified compressed or uncompressed check key size
1121
             * if key size is equal to compressed key size copy in key */
1122
558
            XMEMCPY(key->p, in, ED448_PUB_KEY_SIZE);
1123
558
        }
1124
1
        else {
1125
            /* bad public key format */
1126
1
            ret = BAD_FUNC_ARG;
1127
1
        }
1128
563
    }
1129
1130
602
    if (ret == 0) {
1131
562
        key->pubKeySet = 1;
1132
562
        if (!trusted) {
1133
            /* Check untrusted public key data matches private key. */
1134
562
            ret = wc_ed448_check_key(key);
1135
562
        }
1136
562
    }
1137
1138
602
    if ((ret != 0) && (key != NULL)) {
1139
        /* No public key set on failure. */
1140
92
        key->pubKeySet = 0;
1141
92
    }
1142
1143
602
    return ret;
1144
602
}
1145
1146
/* Import a compressed or uncompressed ed448 public key from a byte array.
1147
 *
1148
 * Public key encoded in big-endian.
1149
 * Public key is not trusted and is checked against private key if set.
1150
 *
1151
 * in      [in]  Array holding public key.
1152
 * inLen   [in]  Number of bytes of data in array.
1153
 * key     [in]  Ed448 public key.
1154
 * returns BAD_FUNC_ARG when a parameter is NULL or key format is not supported,
1155
 *         0 otherwise.
1156
 */
1157
int wc_ed448_import_public(const byte* in, word32 inLen, ed448_key* key)
1158
602
{
1159
602
    return wc_ed448_import_public_ex(in, inLen, key, 0);
1160
602
}
1161
1162
/* Import an ed448 private key from a byte array.
1163
 *
1164
 * priv    [in]  Array holding private key.
1165
 * privSz  [in]  Number of bytes of data in array.
1166
 * key     [in]  Ed448 private key.
1167
 * returns BAD_FUNC_ARG when a parameter is NULL or privSz is less than
1168
 *         ED448_KEY_SIZE,
1169
 *         0 otherwise.
1170
 */
1171
int wc_ed448_import_private_only(const byte* priv, word32 privSz,
1172
                                 ed448_key* key)
1173
437
{
1174
437
    int ret = 0;
1175
1176
    /* sanity check on arguments */
1177
437
    if ((priv == NULL) || (key == NULL)) {
1178
0
        ret = BAD_FUNC_ARG;
1179
0
    }
1180
1181
    /* key size check */
1182
437
    if ((ret == 0) && (privSz != ED448_KEY_SIZE)) {
1183
18
        ret = BAD_FUNC_ARG;
1184
18
    }
1185
1186
437
    if (ret == 0) {
1187
419
        XMEMCPY(key->k, priv, ED448_KEY_SIZE);
1188
419
        key->privKeySet = 1;
1189
419
    }
1190
1191
437
    if ((ret == 0) && key->pubKeySet) {
1192
        /* Validate loaded public key */
1193
0
        ret = wc_ed448_check_key(key);
1194
0
    }
1195
1196
437
    if ((ret != 0) && (key != NULL)) {
1197
        /* No private key set on error. */
1198
18
        key->privKeySet = 0;
1199
18
        ForceZero(key->k, ED448_KEY_SIZE);
1200
18
    }
1201
1202
437
    return ret;
1203
437
}
1204
1205
1206
/* Import an ed448 private and public keys from byte array(s).
1207
 *
1208
 * priv     [in]  Array holding private key from wc_ed448_export_private_only(),
1209
 *                or private+public keys from wc_ed448_export_private().
1210
 * privSz   [in]  Number of bytes of data in private key array.
1211
 * pub      [in]  Array holding public key (or NULL).
1212
 * pubSz    [in]  Number of bytes of data in public key array (or 0).
1213
 * key      [in]  Ed448 private/public key.
1214
 * trusted  [in]  Indicates whether the public key data is trusted.
1215
 *                When 0, checks public key matches private key.
1216
 *                When 1, doesn't check public key matches private key.
1217
 * returns BAD_FUNC_ARG when a required parameter is NULL or an invalid
1218
 *         combination of keys/lengths is supplied, 0 otherwise.
1219
 */
1220
int wc_ed448_import_private_key_ex(const byte* priv, word32 privSz,
1221
    const byte* pub, word32 pubSz, ed448_key* key, int trusted)
1222
0
{
1223
0
    int ret;
1224
1225
    /* sanity check on arguments */
1226
0
    if (priv == NULL || key == NULL)
1227
0
        return BAD_FUNC_ARG;
1228
1229
    /* key size check */
1230
0
    if (privSz != ED448_KEY_SIZE && privSz != ED448_PRV_KEY_SIZE)
1231
0
        return BAD_FUNC_ARG;
1232
1233
0
    if (pub == NULL) {
1234
0
        if (pubSz != 0)
1235
0
            return BAD_FUNC_ARG;
1236
0
        if (privSz != ED448_PRV_KEY_SIZE)
1237
0
            return BAD_FUNC_ARG;
1238
0
        pub = priv + ED448_KEY_SIZE;
1239
0
        pubSz = ED448_PUB_KEY_SIZE;
1240
0
    }
1241
0
    else if (pubSz < ED448_PUB_KEY_SIZE) {
1242
0
        return BAD_FUNC_ARG;
1243
0
    }
1244
1245
0
    XMEMCPY(key->k, priv, ED448_KEY_SIZE);
1246
0
    key->privKeySet = 1;
1247
1248
    /* import public key */
1249
0
    ret = wc_ed448_import_public_ex(pub, pubSz, key, trusted);
1250
0
    if (ret != 0) {
1251
0
        key->privKeySet = 0;
1252
0
        ForceZero(key->k, ED448_KEY_SIZE);
1253
0
        return ret;
1254
0
    }
1255
1256
    /* make the private key (priv + pub) */
1257
0
    XMEMCPY(key->k + ED448_KEY_SIZE, key->p, ED448_PUB_KEY_SIZE);
1258
1259
0
    return ret;
1260
0
}
1261
1262
/* Import an ed448 private and public keys from byte array(s).
1263
 *
1264
 * Public key is not trusted and is checked against private key.
1265
 *
1266
 * priv    [in]  Array holding private key from wc_ed448_export_private_only(),
1267
 *               or private+public keys from wc_ed448_export_private().
1268
 * privSz  [in]  Number of bytes of data in private key array.
1269
 * pub     [in]  Array holding public key (or NULL).
1270
 * pubSz   [in]  Number of bytes of data in public key array (or 0).
1271
 * key     [in]  Ed448 private/public key.
1272
 * returns BAD_FUNC_ARG when a required parameter is NULL or an invalid
1273
 *         combination of keys/lengths is supplied, 0 otherwise.
1274
 */
1275
int wc_ed448_import_private_key(const byte* priv, word32 privSz,
1276
                                const byte* pub, word32 pubSz, ed448_key* key)
1277
0
{
1278
0
    return wc_ed448_import_private_key_ex(priv, privSz, pub, pubSz, key, 0);
1279
0
}
1280
1281
#endif /* HAVE_ED448_KEY_IMPORT */
1282
1283
1284
#ifdef HAVE_ED448_KEY_EXPORT
1285
1286
/* Export the ed448 private key.
1287
 *
1288
 * key     [in]      Ed448 private key.
1289
 * out     [in]      Array to hold private key.
1290
 * outLen  [in/out]  On in, the number of bytes in array.
1291
 *                   On out, the number bytes put into array.
1292
 * returns BAD_FUNC_ARG when a parameter is NULL,
1293
 *         ECC_BAD_ARG_E when outLen is less than ED448_KEY_SIZE,
1294
 *         0 otherwise.
1295
 */
1296
int wc_ed448_export_private_only(const ed448_key* key, byte* out, word32* outLen)
1297
78
{
1298
78
    int ret = 0;
1299
1300
    /* sanity checks on arguments */
1301
78
    if ((key == NULL) || (out == NULL) || (outLen == NULL)) {
1302
19
        ret = BAD_FUNC_ARG;
1303
19
    }
1304
1305
78
    if ((ret == 0) && (!key->privKeySet)) {
1306
0
        ret = BAD_FUNC_ARG;
1307
0
    }
1308
1309
78
    if ((ret == 0) && (*outLen < ED448_KEY_SIZE)) {
1310
6
        *outLen = ED448_KEY_SIZE;
1311
6
        ret = BUFFER_E;
1312
6
    }
1313
1314
78
    if (ret == 0) {
1315
53
        *outLen = ED448_KEY_SIZE;
1316
53
        XMEMCPY(out, key->k, ED448_KEY_SIZE);
1317
53
    }
1318
1319
78
    return ret;
1320
78
}
1321
1322
/* Export the ed448 private and public key.
1323
 *
1324
 * key     [in]      Ed448 private/public key.
1325
 * out     [in]      Array to hold private and public key.
1326
 * outLen  [in/out]  On in, the number of bytes in array.
1327
 *                   On out, the number bytes put into array.
1328
 * returns BAD_FUNC_ARG when a parameter is NULL,
1329
 *         BUFFER_E when outLen is less than ED448_PRV_KEY_SIZE,
1330
 *         0 otherwise.
1331
 */
1332
int wc_ed448_export_private(const ed448_key* key, byte* out, word32* outLen)
1333
0
{
1334
0
    int ret = 0;
1335
1336
    /* sanity checks on arguments */
1337
0
    if ((key == NULL) || (out == NULL) || (outLen == NULL)) {
1338
0
        ret = BAD_FUNC_ARG;
1339
0
    }
1340
1341
0
    if ((ret == 0) && (!key->privKeySet)) {
1342
0
        ret = BAD_FUNC_ARG;
1343
0
    }
1344
1345
0
    if ((ret == 0) && (*outLen < ED448_PRV_KEY_SIZE)) {
1346
0
        *outLen = ED448_PRV_KEY_SIZE;
1347
0
        ret = BUFFER_E;
1348
0
    }
1349
1350
0
    if (ret == 0) {
1351
0
        *outLen = ED448_PRV_KEY_SIZE;
1352
0
        XMEMCPY(out, key->k, ED448_PRV_KEY_SIZE);
1353
0
     }
1354
1355
0
    return ret;
1356
0
}
1357
1358
/* Export the ed448 private and public key.
1359
 *
1360
 * key     [in]      Ed448 private/public key.
1361
 * priv    [in]      Array to hold private key.
1362
 * privSz  [in/out]  On in, the number of bytes in private key array.
1363
 * pub     [in]      Array to hold  public key.
1364
 * pubSz   [in/out]  On in, the number of bytes in public key array.
1365
 *                   On out, the number bytes put into array.
1366
 * returns BAD_FUNC_ARG when a parameter is NULL,
1367
 *         BUFFER_E when privSz is less than ED448_PRV_KEY_SIZE or pubSz is less
1368
 *         than ED448_PUB_KEY_SIZE,
1369
 *         0 otherwise.
1370
 */
1371
int wc_ed448_export_key(const ed448_key* key, byte* priv, word32 *privSz,
1372
                        byte* pub, word32 *pubSz)
1373
0
{
1374
0
    int ret = 0;
1375
1376
    /* export 'full' private part */
1377
0
    ret = wc_ed448_export_private(key, priv, privSz);
1378
0
    if (ret == 0) {
1379
        /* export public part */
1380
0
        ret = wc_ed448_export_public(key, pub, pubSz);
1381
0
    }
1382
1383
0
    return ret;
1384
0
}
1385
1386
#endif /* HAVE_ED448_KEY_EXPORT */
1387
1388
/* Check the public key is valid.
1389
 *
1390
 * When private key available, check the calculated public key matches.
1391
 * When no private key, check Y is in range and an X is able to be calculated.
1392
 *
1393
 * @param [in] key  Ed448 private/public key.
1394
 * @return  0 otherwise.
1395
 * @return  BAD_FUNC_ARG when key is NULL.
1396
 * @return  PUBLIC_KEY_E when the public key is not set, doesn't match or is
1397
 *          invalid.
1398
 * @return  other -ve value on hash failure.
1399
 */
1400
int wc_ed448_check_key(ed448_key* key)
1401
640
{
1402
640
    int ret = 0;
1403
640
    unsigned char pubKey[ED448_PUB_KEY_SIZE];
1404
1405
    /* Validate parameter. */
1406
640
    if (key == NULL) {
1407
0
        ret = BAD_FUNC_ARG;
1408
0
    }
1409
1410
    /* Check we have a public key to check. */
1411
640
    if (ret == 0 && !key->pubKeySet) {
1412
0
        ret = PUBLIC_KEY_E;
1413
0
    }
1414
1415
    /* If we have a private key just make the public key and compare. */
1416
640
    if ((ret == 0) && key->privKeySet) {
1417
78
        ret = wc_ed448_make_public(key, pubKey, sizeof(pubKey));
1418
78
        if ((ret == 0) && (XMEMCMP(pubKey, key->p, ED448_PUB_KEY_SIZE) != 0)) {
1419
0
            ret = PUBLIC_KEY_E;
1420
0
        }
1421
78
    }
1422
    /* No private key, check Y is valid. */
1423
562
    else if ((ret == 0) && (!key->privKeySet)) {
1424
        /* Reject the identity element (0, 1).
1425
         * Encoding: 0x01 followed by 56 zero bytes. */
1426
562
        {
1427
562
            int isIdentity = 1;
1428
562
            int i;
1429
562
            if (key->p[0] != 0x01)
1430
553
                isIdentity = 0;
1431
687
            for (i = 1; i < ED448_PUB_KEY_SIZE && isIdentity; i++) {
1432
125
                if (key->p[i] != 0x00)
1433
8
                    isIdentity = 0;
1434
125
            }
1435
562
            if (isIdentity) {
1436
1
                WOLFSSL_MSG("Ed448 public key is the identity element");
1437
1
                ret = PUBLIC_KEY_E;
1438
1
            }
1439
562
        }
1440
1441
        /* Verify that xQ and yQ are integers in the interval [0, p - 1].
1442
         * Only have yQ so check that ordinate.
1443
         * p = 2^448-2^224-1 = 0xff..fe..ff
1444
         */
1445
562
        if (ret == 0) {
1446
561
            int i;
1447
561
            ret = PUBLIC_KEY_E;
1448
1449
            /* Check top part before 0xFE. */
1450
2.07k
            for (i = ED448_PUB_KEY_SIZE - 1; i > ED448_PUB_KEY_SIZE/2; i--) {
1451
2.03k
                if (key->p[i] < 0xff) {
1452
513
                    ret = 0;
1453
513
                    break;
1454
513
                }
1455
2.03k
            }
1456
561
            if (ret == WC_NO_ERR_TRACE(PUBLIC_KEY_E)) {
1457
                /* Check against 0xFE. */
1458
48
                if (key->p[ED448_PUB_KEY_SIZE/2] < 0xfe) {
1459
17
                    ret = 0;
1460
17
                }
1461
31
                else if (key->p[ED448_PUB_KEY_SIZE/2] == 0xfe) {
1462
                    /* Check bottom part before last byte. */
1463
417
                    for (i = ED448_PUB_KEY_SIZE/2 - 1; i > 0; i--) {
1464
405
                        if (key->p[i] != 0xff) {
1465
15
                            ret = 0;
1466
15
                            break;
1467
15
                        }
1468
405
                    }
1469
                    /* Check last byte. */
1470
27
                    if ((ret == WC_NO_ERR_TRACE(PUBLIC_KEY_E)) &&
1471
12
                        (key->p[0] < 0xff)) {
1472
11
                        ret = 0;
1473
11
                    }
1474
27
                }
1475
48
            }
1476
561
        }
1477
1478
562
        if (ret == 0) {
1479
            /* Verify that Q is on the curve.
1480
             * Uncompressing the public key will validate yQ. */
1481
556
            ge448_p2 A;
1482
1483
556
            if (ge448_from_bytes_negate_vartime(&A, key->p) != 0) {
1484
46
                ret = PUBLIC_KEY_E;
1485
46
            }
1486
556
        }
1487
562
    }
1488
1489
640
    return ret;
1490
640
}
1491
1492
/* Returns the size of an ed448 private key.
1493
 *
1494
 * key     [in]      Ed448 private/public key.
1495
 * returns BAD_FUNC_ARG when key is NULL,
1496
 *         ED448_KEY_SIZE otherwise.
1497
 */
1498
int wc_ed448_size(const ed448_key* key)
1499
0
{
1500
0
    int ret = ED448_KEY_SIZE;
1501
1502
0
    if (key == NULL) {
1503
0
        ret = BAD_FUNC_ARG;
1504
0
    }
1505
1506
0
    return ret;
1507
0
}
1508
1509
/* Returns the size of an ed448 private plus public key.
1510
 *
1511
 * key     [in]      Ed448 private/public key.
1512
 * returns BAD_FUNC_ARG when key is NULL,
1513
 *         ED448_PRV_KEY_SIZE otherwise.
1514
 */
1515
int wc_ed448_priv_size(const ed448_key* key)
1516
0
{
1517
0
    int ret = ED448_PRV_KEY_SIZE;
1518
1519
0
    if (key == NULL) {
1520
0
        ret = BAD_FUNC_ARG;
1521
0
    }
1522
1523
0
    return ret;
1524
0
}
1525
1526
/* Returns the size of an ed448 public key.
1527
 *
1528
 * key     [in]      Ed448 private/public key.
1529
 * returns BAD_FUNC_ARG when key is NULL,
1530
 *         ED448_PUB_KEY_SIZE otherwise.
1531
 */
1532
int wc_ed448_pub_size(const ed448_key* key)
1533
0
{
1534
0
    int ret = ED448_PUB_KEY_SIZE;
1535
1536
0
    if (key == NULL) {
1537
0
        ret = BAD_FUNC_ARG;
1538
0
    }
1539
1540
0
    return ret;
1541
0
}
1542
1543
/* Returns the size of an ed448 signature.
1544
 *
1545
 * key     [in]      Ed448 private/public key.
1546
 * returns BAD_FUNC_ARG when key is NULL,
1547
 *         ED448_SIG_SIZE otherwise.
1548
 */
1549
int wc_ed448_sig_size(const ed448_key* key)
1550
0
{
1551
0
    int ret = ED448_SIG_SIZE;
1552
1553
0
    if (key == NULL) {
1554
0
        ret = BAD_FUNC_ARG;
1555
0
    }
1556
1557
0
    return ret;
1558
0
}
1559
1560
#endif /* HAVE_ED448 */
1561