Coverage Report

Created: 2026-11-12 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-sp-math-all/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
#define WC_FIPS_LL_CRYPTO
34
#define _WC_BUILDING_ED448_C
35
36
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
37
38
#ifdef HAVE_ED448
39
#if FIPS_VERSION3_GE(6,0,0)
40
       #if defined(USE_WINDOWS_API) && defined(_MSC_VER)
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 WOLF_CRYPTO_CB
49
    #include <wolfssl/wolfcrypt/cryptocb.h>
50
#endif
51
#ifdef NO_INLINE
52
    #include <wolfssl/wolfcrypt/misc.h>
53
#else
54
    #define WOLFSSL_MISC_INCLUDED
55
    #include <wolfcrypt/src/misc.c>
56
#endif
57
58
#if defined(HAVE_ED448_SIGN) || defined(HAVE_ED448_VERIFY)
59
/* Size of context bytes to use with hash when signing and verifying. */
60
7.24k
#define ED448CTX_SIZE    8
61
/* Context to pass to hash when signing and verifying. */
62
static const byte ed448Ctx[ED448CTX_SIZE+1] = "SigEd448";
63
#endif
64
65
#if FIPS_VERSION3_GE(6,0,0)
66
    const unsigned int wolfCrypt_FIPS_ed448_ro_sanity[2] =
67
                                                     { 0x1a2b3c4d, 0x00000007 };
68
    int wolfCrypt_FIPS_ED448_sanity(void)
69
    {
70
        return 0;
71
    }
72
#endif
73
74
static int ed448_hash_init(ed448_key* key, wc_Shake *sha)
75
6.83k
{
76
6.83k
    int ret;
77
78
6.83k
    ret = wc_InitShake256(sha, key->heap,
79
6.83k
#if defined(WOLF_CRYPTO_CB)
80
6.83k
                           key->devId
81
#else
82
                           INVALID_DEVID
83
#endif
84
6.83k
        );
85
86
6.83k
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
87
6.83k
    if (ret == 0)
88
6.83k
        key->sha_clean_flag = 1;
89
6.83k
#endif
90
91
6.83k
    return ret;
92
6.83k
}
93
94
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
95
static int ed448_hash_reset(ed448_key* key)
96
10.9k
{
97
10.9k
    int ret;
98
99
10.9k
    if (key->sha_clean_flag)
100
10.9k
        ret = 0;
101
0
    else {
102
0
        wc_Shake256_Free(&key->sha);
103
0
        ret = wc_InitShake256(&key->sha, key->heap,
104
0
#if defined(WOLF_CRYPTO_CB)
105
0
                              key->devId
106
#else
107
                              INVALID_DEVID
108
#endif
109
0
            );
110
0
        if (ret == 0)
111
0
            key->sha_clean_flag = 1;
112
0
    }
113
10.9k
    return ret;
114
10.9k
}
115
#endif /* WOLFSSL_ED448_PERSISTENT_SHA */
116
117
static int ed448_hash_update(ed448_key* key, wc_Shake *sha, const byte* data,
118
                             word32 len)
119
163k
{
120
163k
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
121
163k
    if (key->sha_clean_flag)
122
15.6k
        key->sha_clean_flag = 0;
123
#else
124
    (void)key;
125
#endif
126
163k
    return wc_Shake256_Update(sha, data, len);
127
163k
}
128
129
static int ed448_hash_final(ed448_key* key, wc_Shake *sha, byte* hash,
130
                            word32 hashLen)
131
15.5k
{
132
15.5k
    int ret = wc_Shake256_Final(sha, hash, hashLen);
133
15.5k
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
134
15.5k
    if (ret == 0)
135
15.5k
        key->sha_clean_flag = 1;
136
#else
137
    (void)key;
138
#endif
139
15.5k
    return ret;
140
15.5k
}
141
142
static void ed448_hash_free(ed448_key* key, wc_Shake *sha)
143
6.83k
{
144
6.83k
    wc_Shake256_Free(sha);
145
6.83k
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
146
6.83k
    key->sha_clean_flag = 0;
147
#else
148
    (void)key;
149
#endif
150
6.83k
}
151
152
153
static int ed448_hash(ed448_key* key, const byte* in, word32 inLen,
154
                      byte* hash, word32 hashLen)
155
8.38k
{
156
8.38k
    int ret;
157
#ifndef WOLFSSL_ED448_PERSISTENT_SHA
158
    WC_DECLARE_VAR(sha, wc_Shake, 1, key ? key->heap : NULL);
159
#else
160
8.38k
    wc_Shake *sha;
161
8.38k
#endif
162
163
8.38k
    if (key == NULL || (in == NULL && inLen > 0) || hash == NULL) {
164
0
        return BAD_FUNC_ARG;
165
0
    }
166
167
8.38k
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
168
8.38k
    sha = &key->sha;
169
8.38k
    ret = ed448_hash_reset(key);
170
#else
171
    WC_ALLOC_VAR_EX(sha, wc_Shake, 1, key->heap, DYNAMIC_TYPE_HASHES,
172
                    return MEMORY_E);
173
    ret = ed448_hash_init(key, sha);
174
#endif
175
8.38k
    if (ret < 0) {
176
    #ifndef WOLFSSL_ED448_PERSISTENT_SHA
177
        WC_FREE_VAR_EX(sha, key->heap, DYNAMIC_TYPE_HASHES);
178
    #endif
179
0
        return ret;
180
0
    }
181
182
8.38k
    ret = ed448_hash_update(key, sha, in, inLen);
183
8.38k
    if (ret == 0)
184
8.38k
        ret = ed448_hash_final(key, sha, hash, hashLen);
185
186
#ifndef WOLFSSL_ED448_PERSISTENT_SHA
187
    ed448_hash_free(key, sha);
188
    WC_FREE_VAR_EX(sha, key->heap, DYNAMIC_TYPE_HASHES);
189
#endif
190
191
8.38k
    return ret;
192
8.38k
}
193
194
#if FIPS_VERSION3_GE(6,0,0)
195
/* Performs a Pairwise Consistency Test on an Ed448 key pair.
196
 *
197
 * @param [in] key  Ed448 key to test.
198
 * @param [in] rng  Random number generator to use to create random digest.
199
 * @return  0 on success.
200
 * @return  ECC_PCT_E when signing or verification fail.
201
 * @return  Other -ve when random number generation fails.
202
 */
203
static int ed448_pairwise_consistency_test(ed448_key* key, WC_RNG* rng)
204
{
205
    int err = 0;
206
    byte digest[WC_SHA256_DIGEST_SIZE];
207
    word32 digestLen = WC_SHA256_DIGEST_SIZE;
208
    byte sig[ED448_SIG_SIZE];
209
    word32 sigLen = ED448_SIG_SIZE;
210
    int res = 0;
211
212
    /* Generate a random digest to sign. */
213
    err = wc_RNG_GenerateBlock(rng, digest, digestLen);
214
    if (err == 0) {
215
        /* Sign digest without context. */
216
        err = wc_ed448_sign_msg_ex(digest, digestLen, sig, &sigLen, key, Ed448,
217
            NULL, 0);
218
        if (err != 0) {
219
            /* Any sign failure means test failed. */
220
            err = ECC_PCT_E;
221
        }
222
    }
223
    if (err == 0) {
224
        /* Verify digest without context. */
225
        err = wc_ed448_verify_msg_ex(sig, sigLen, digest, digestLen, &res, key,
226
            Ed448, NULL, 0);
227
        if (err != 0) {
228
            /* Any verification operation failure means test failed. */
229
            err = ECC_PCT_E;
230
        }
231
        /* Check whether the signature verified. */
232
        else if (res == 0) {
233
            /* Test failed. */
234
            err = ECC_PCT_E;
235
        }
236
    }
237
238
    ForceZero(sig, sigLen);
239
240
    return err;
241
}
242
#endif
243
244
/* Reject small-order Ed448 public keys: h*A vanishes during verification
245
 * so any (R = [S]B, S) verifies for an arbitrary message. Cofactor is 4. */
246
static int ed448_is_small_order(const byte p[ED448_PUB_KEY_SIZE])
247
5.83k
{
248
    /* y-coordinates of every order-1/2/4 point plus the non-canonical
249
     * encodings y = p / y = p+1. Byte 56 is cleared in both table and
250
     * input before compare, masking the x-sign bit and the
251
     * spec-mandated-zero (but decoder-ignored) bits 0-6. The decoder
252
     * (fe448_from_bytes) reads bytes 0-55 modulo p with no canonical-form
253
     * check, so y = p decodes to 0 and y = p+1 decodes to 1; both must
254
     * be rejected here. Only {y, y + p} fits in 56 bytes (2p overflows),
255
     * so listing y and y + p exhausts the reachable encodings.
256
     * wc_ed448_check_key() depends on the y = p row: its Y-range test
257
     * accepts that encoding, so dropping the row would let a y outside
258
     * [0, p - 1] through. */
259
5.83k
    static const byte small_order_y[][ED448_PUB_KEY_SIZE] = {
260
        /* order 1: identity y = 1, x = 0 */
261
5.83k
        {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
262
5.83k
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
263
5.83k
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
264
5.83k
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
265
5.83k
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
266
5.83k
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
267
5.83k
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
268
5.83k
         0x00},
269
        /* order 4: y = 0 (x = +/-1; sign bit covered by mask) */
270
5.83k
        {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
271
5.83k
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
272
5.83k
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
273
5.83k
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
274
5.83k
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
275
5.83k
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
276
5.83k
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
277
5.83k
         0x00},
278
        /* order 2: y = p - 1, x = 0; p = 2^448 - 2^224 - 1 */
279
5.83k
        {0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
280
5.83k
         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
281
5.83k
         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
282
5.83k
         0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,
283
5.83k
         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
284
5.83k
         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
285
5.83k
         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
286
5.83k
         0x00},
287
        /* non-canonical y = p (decodes to y = 0) */
288
5.83k
        {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
289
5.83k
         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
290
5.83k
         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
291
5.83k
         0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,
292
5.83k
         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
293
5.83k
         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
294
5.83k
         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
295
5.83k
         0x00},
296
        /* non-canonical y = p + 1 (decodes to y = 1) */
297
5.83k
        {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
298
5.83k
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
299
5.83k
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
300
5.83k
         0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
301
5.83k
         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
302
5.83k
         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
303
5.83k
         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
304
5.83k
         0x00},
305
5.83k
    };
306
5.83k
    byte y[ED448_PUB_KEY_SIZE];
307
5.83k
    word32 i;
308
309
5.83k
    XMEMCPY(y, p, ED448_PUB_KEY_SIZE);
310
5.83k
    y[ED448_PUB_KEY_SIZE - 1] = 0;
311
34.5k
    for (i = 0; i < sizeof(small_order_y) / ED448_PUB_KEY_SIZE; i++) {
312
28.8k
        if (XMEMCMP(y, small_order_y[i], ED448_PUB_KEY_SIZE) == 0)
313
103
            return 1;
314
28.8k
    }
315
5.73k
    return 0;
316
5.83k
}
317
318
/* Check the y-coordinate of an encoded Ed448 public key is in [0, p - 1]
319
 * (RFC 8032 5.2.3). Only have y so check that ordinate.
320
 * p = 2^448-2^224-1 = 0xff..fe..ff
321
 *
322
 * The decoder (fe448_from_bytes) reads bytes 0-55 modulo p and ignores bits
323
 * 0-6 of byte 56, so an out of range y decodes to the same point as its
324
 * canonical encoding and must be rejected here.
325
 *
326
 * @param [in] p  Encoded public key.
327
 * @return  1 when y is in range.
328
 * @return  0 when y >= p.
329
 */
330
static int ed448_pub_y_in_range(const byte p[ED448_PUB_KEY_SIZE])
331
5.29k
{
332
5.29k
    int i;
333
334
    /* Last byte: bit 7 is the sign of x, bits 0-6 are the top bits of y and
335
     * must be zero; when set y >= 2^448 > p. */
336
5.29k
    if ((p[ED448_PUB_KEY_SIZE - 1] & 0x7f) != 0)
337
106
        return 0;
338
339
    /* Check top part before 0xFE - skipping the sign byte. */
340
5.55k
    for (i = ED448_PUB_KEY_SIZE - 2; i > ED448_PUB_KEY_SIZE/2; i--) {
341
5.54k
        if (p[i] < 0xff)
342
5.18k
            return 1;
343
5.54k
    }
344
    /* Every byte above this one is 0xff here, so y > p whenever this byte is
345
     * 0xff, and y == p is then the only remaining encoding outside
346
     * [0, p - 1]. It is rejected by ed448_is_small_order(), whose table
347
     * carries y == p as a non-canonical encoding, so the low bytes need no
348
     * check. */
349
3
    return p[ED448_PUB_KEY_SIZE/2] <= 0xfe;
350
5.18k
}
351
352
/* Mirror a derived public key into the key object, in the layout
353
 * wc_ed448_make_key() leaves: key->p, and a copy after the private key in
354
 * key->k.  Only ever called for a key with no public half yet - deriving into
355
 * scratch and comparing against key->p is how wc_ed448_check_key() works.
356
 */
357
static void ed448_store_public(ed448_key* key, const byte* pubKey)
358
3.13k
{
359
3.13k
    if (pubKey != key->p) {
360
2.69k
        XMEMCPY(key->p, pubKey, ED448_PUB_KEY_SIZE);
361
2.69k
    }
362
    /* put public key after private key, on the same buffer */
363
3.13k
    XMEMMOVE(key->k + ED448_KEY_SIZE, key->p, ED448_PUB_KEY_SIZE);
364
3.13k
}
365
366
/* Derive the public key for the private key.
367
 *
368
 * Also stores the derived key in the key object when it did not already carry
369
 * a public half.
370
 *
371
 * key       [in]  Ed448 key object.
372
 * pubKey    [in]  Byte array to hold the public key.
373
 * pubKeySz  [in]  Size of the array in bytes.
374
 * returns BAD_FUNC_ARG when key is NULL or pubKeySz is not equal to
375
 *         ED448_PUB_KEY_SIZE,
376
 *         other -ve value on hash failure,
377
 *         0 otherwise.
378
 */
379
int wc_ed448_make_public(ed448_key* key, unsigned char* pubKey, word32 pubKeySz)
380
6.02k
{
381
6.02k
    int   ret = 0;
382
6.02k
    int   storePub = 0;
383
6.02k
    byte  az[ED448_PRV_KEY_SIZE];
384
6.02k
    ge448_p2 A;
385
386
6.02k
    if ((key == NULL) || (pubKey == NULL) || (pubKeySz != ED448_PUB_KEY_SIZE)) {
387
0
        ret = BAD_FUNC_ARG;
388
0
    }
389
390
6.02k
    if ((ret == 0) && (!key->privKeySet)
391
17
    #ifdef WOLF_PRIVATE_KEY_ID
392
17
        && (key->idLen == 0) && (key->labelLen == 0)
393
6.02k
    #endif
394
6.02k
        ) {
395
17
        ret = ECC_PRIV_KEY_E;
396
17
    }
397
398
6.02k
    if (ret == 0) {
399
        /* The key doesn't carry its public half yet (e.g. it was decoded from
400
         * a PKCS#8 v1 PrivateKeyInfo, which holds only the seed): fill it in
401
         * as well, so pubKeySet below doesn't end up set on a key whose p/k
402
         * are still empty. */
403
6.00k
        storePub = !key->pubKeySet;
404
6.00k
    }
405
406
6.02k
#ifdef WOLF_CRYPTO_CB
407
6.02k
    #ifndef WOLF_CRYPTO_CB_FIND
408
6.02k
    if ((ret == 0) && (key->devId != INVALID_DEVID))
409
    #else
410
    if (ret == 0)
411
    #endif
412
0
    {
413
0
        ret = wc_CryptoCb_Ed448MakePub(key, pubKey, pubKeySz);
414
0
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
415
0
            if (ret == 0) {
416
0
                if (storePub)
417
0
                    ed448_store_public(key, pubKey);
418
0
                key->pubKeySet = 1;
419
0
            }
420
0
            return ret;
421
0
        }
422
0
        ret = 0;
423
0
    }
424
6.02k
#endif
425
426
    /* A key named by id or label has no private key for software to use. */
427
6.02k
    if ((ret == 0) && (!key->privKeySet)) {
428
0
        ret = ECC_PRIV_KEY_E;
429
0
    }
430
431
#ifdef WOLFSSL_CHECK_MEM_ZERO
432
    wc_MemZero_Add("wc_ed448_make_public az", az, sizeof(az));
433
    wc_MemZero_Add("wc_ed448_make_public A", &A, sizeof(A));
434
#endif
435
6.02k
    if (ret == 0)
436
6.00k
        ret = ed448_hash(key, key->k, ED448_KEY_SIZE, az, sizeof(az));
437
438
6.02k
    if (ret == 0) {
439
        /* apply clamp */
440
6.00k
        az[0]  &= 0xfc;
441
6.00k
        az[55] |= 0x80;
442
6.00k
        az[56]  = 0x00;
443
444
6.00k
        ret = ge448_scalarmult_base(&A, az);
445
6.00k
    }
446
447
6.02k
    if (ret == 0) {
448
5.49k
        ge448_to_bytes(pubKey, &A);
449
450
5.49k
        if (storePub)
451
3.13k
            ed448_store_public(key, pubKey);
452
5.49k
        key->pubKeySet = 1;
453
5.49k
    }
454
455
    /* az holds the clamped secret scalar (ISO/IEC 19790:2012 7.9.7). */
456
    /* Projective A leaks bits of the private scalar. */
457
6.02k
    ForceZero(&A, sizeof(A));
458
6.02k
    ForceZero(az, sizeof(az));
459
#ifdef WOLFSSL_CHECK_MEM_ZERO
460
    wc_MemZero_Check(&A, sizeof(A));
461
    wc_MemZero_Check(az, sizeof(az));
462
#endif
463
464
6.02k
    return ret;
465
6.02k
}
466
467
/* Make a new ed448 private/public key.
468
 *
469
 * rng      [in]  Random number generator.
470
 * keysize  [in]  Size of the key to generate.
471
 * key      [in]  Ed448 key object.
472
 * returns BAD_FUNC_ARG when rng or key is NULL or keySz is not equal to
473
 *         ED448_KEY_SIZE,
474
 *         other -ve value on device, random number or hash failure,
475
 *         0 otherwise.
476
 */
477
int wc_ed448_make_key(WC_RNG* rng, int keySz, ed448_key* key)
478
710
{
479
710
    int ret = 0;
480
710
#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK
481
710
    int idKey = 0;
482
710
    int idDevId = INVALID_DEVID;
483
710
#endif
484
485
710
    if ((rng == NULL) || (key == NULL)) {
486
0
        ret = BAD_FUNC_ARG;
487
0
    }
488
489
    /* ed448 has 57 byte key sizes */
490
710
    if ((ret == 0) && (keySz != ED448_KEY_SIZE)) {
491
0
        ret = BAD_FUNC_ARG;
492
0
    }
493
494
710
    if (ret == 0) {
495
710
        key->pubKeySet = 0;
496
710
        key->privKeySet = 0;
497
710
    }
498
499
710
#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK
500
710
    if (ret == 0) {
501
710
        idKey = WC_CRYPTOCB_HAS_ID(key);
502
710
        idDevId = key->devId;
503
710
    }
504
710
#endif
505
710
#ifdef WOLF_CRYPTO_CB
506
710
    #ifndef WOLF_CRYPTO_CB_FIND
507
710
    if ((ret == 0) && (key->devId != INVALID_DEVID))
508
    #else
509
    if (ret == 0)
510
    #endif
511
0
    {
512
0
        ret = wc_CryptoCb_Ed448Gen(rng, keySz, key);
513
0
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
514
0
            return ret;
515
        /* fall-through when unavailable */
516
0
        ret = 0;
517
0
    }
518
710
    #ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK
519
710
    if ((ret == 0) && idKey && wc_CryptoCb_HasPkDevice(idDevId))
520
0
        ret = NO_VALID_DEVID;
521
710
    #endif
522
710
#endif
523
524
710
    if (ret == 0) {
525
710
        ret = wc_RNG_GenerateBlock(rng, key->k, ED448_KEY_SIZE);
526
710
    }
527
710
    if (ret == 0) {
528
515
        key->privKeySet = 1;
529
        /* pubKeySet was just cleared, so this also stores the public key in
530
         * key->p and after the private key in key->k */
531
515
        ret = wc_ed448_make_public(key, key->p, ED448_PUB_KEY_SIZE);
532
515
        if (ret != 0) {
533
74
            key->privKeySet = 0;
534
74
            ForceZero(key->k, ED448_KEY_SIZE);
535
74
        }
536
515
    }
537
#if FIPS_VERSION3_GE(6,0,0)
538
    if (ret == 0) {
539
        ret = wc_ed448_check_key(key);
540
        if (ret == 0) {
541
            ret = ed448_pairwise_consistency_test(key, rng);
542
        }
543
        if (ret != 0) {
544
            /* Do not hand back a key that failed its check or PCT. */
545
            key->privKeySet = 0;
546
            key->pubKeySet = 0;
547
            ForceZero(key->k, ED448_PRV_KEY_SIZE);
548
            ForceZero(key->p, ED448_PUB_KEY_SIZE);
549
        }
550
    }
551
#endif
552
553
710
    return ret;
554
710
}
555
556
#ifdef HAVE_ED448_SIGN
557
/* Sign the message using the ed448 private key.
558
 *
559
 *  in          [in]      Message to sign.
560
 *  inLen       [in]      Length of the message in bytes.
561
 *  out         [in]      Buffer to write signature into.
562
 *  outLen      [in/out]  On in, size of buffer.
563
 *                        On out, the length of the signature in bytes.
564
 *  key         [in]      Ed448 key to use when signing
565
 *  type        [in]      Type of signature to perform: Ed448 or Ed448ph
566
 *  context     [in]      Context of signing.
567
 *  contextLen  [in]      Length of context in bytes.
568
 *  returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
569
 *          context is not NULL or public key not set,
570
 *          BUFFER_E when outLen is less than ED448_SIG_SIZE,
571
 *          other -ve values when hash fails,
572
 *          0 otherwise.
573
 */
574
int wc_ed448_sign_msg_ex(const byte* in, word32 inLen, byte* out,
575
                          word32 *outLen, ed448_key* key, byte type,
576
                          const byte* context, byte contextLen)
577
2.38k
{
578
2.38k
    ge448_p2 R;
579
2.38k
    byte     nonce[ED448_SIG_SIZE];
580
2.38k
    byte     hram[ED448_SIG_SIZE];
581
2.38k
    byte     az[ED448_PRV_KEY_SIZE];
582
2.38k
    int      ret = 0;
583
#ifdef WOLFSSL_EDDSA_CHECK_PRIV_ON_SIGN
584
    byte     orig_k[ED448_KEY_SIZE];
585
#endif
586
#ifndef WOLFSSL_ED448_PERSISTENT_SHA
587
    WC_DECLARE_VAR(sha, wc_Shake, 1, key ? key->heap : NULL);
588
#endif
589
590
    /* sanity check on arguments */
591
2.38k
    if (((in == NULL) && (inLen != 0)) || (out == NULL) || (outLen == NULL) ||
592
2.38k
            (key == NULL) || ((context == NULL) && (contextLen != 0))) {
593
0
        ret = BAD_FUNC_ARG;
594
0
    }
595
    /* An empty message may be passed as (NULL, 0); canonicalize it to a
596
     * readable stand-in so that downstream consumers -- hash updates and
597
     * crypto callbacks -- never see a NULL pointer. */
598
2.38k
    if ((ret == 0) && (in == NULL)) {
599
110
        static const byte ed448_empty_msg[] = {0};
600
110
        in = ed448_empty_msg;
601
110
    }
602
603
2.38k
    if ((ret == 0) && (type == Ed448ph) && (inLen != ED448_PREHASH_SIZE)) {
604
0
        ret = BAD_LENGTH_E;
605
0
    }
606
607
2.38k
#ifdef WOLF_CRYPTO_CB
608
2.38k
    if (ret == 0) {
609
2.38k
    #ifndef WOLF_CRYPTO_CB_FIND
610
2.38k
        if (key->devId != INVALID_DEVID)
611
0
    #endif
612
0
        {
613
0
            ret = wc_CryptoCb_Ed448Sign(in, inLen, out, outLen, key, type,
614
0
                context, contextLen);
615
0
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
616
0
                return ret;
617
0
            ret = 0; /* fall-through when unavailable */
618
0
        }
619
2.38k
    }
620
2.38k
#endif
621
622
#ifdef WOLFSSL_CHECK_MEM_ZERO
623
    /* Register the secret nonce/expanded-key buffers up front so that any exit
624
     * path from here to the ForceZero below is checked for proper zeroization.
625
     * XMEMSET gives them a defined value before the hash steps fill them. */
626
    XMEMSET(az, 0, sizeof(az));
627
    XMEMSET(nonce, 0, sizeof(nonce));
628
    wc_MemZero_Add("wc_ed448_sign_msg_ex az", az, sizeof(az));
629
    wc_MemZero_Add("wc_ed448_sign_msg_ex nonce", nonce, sizeof(nonce));
630
    wc_MemZero_Add("wc_ed448_sign_msg_ex R", &R, sizeof(R));
631
#ifdef WOLFSSL_EDDSA_CHECK_PRIV_ON_SIGN
632
    XMEMSET(orig_k, 0, sizeof(orig_k));
633
    wc_MemZero_Add("wc_ed448_sign_msg_ex orig_k", orig_k, sizeof(orig_k));
634
#endif
635
#endif
636
637
2.38k
    if ((ret == 0) && (!key->pubKeySet)) {
638
0
        ret = BAD_FUNC_ARG;
639
0
    }
640
2.38k
    if ((ret == 0) && (!key->privKeySet)) {
641
0
        ret = BAD_FUNC_ARG;
642
0
    }
643
644
    /* check and set up out length */
645
2.38k
    if ((ret == 0) && (*outLen < ED448_SIG_SIZE)) {
646
0
        *outLen = ED448_SIG_SIZE;
647
0
        ret = BUFFER_E;
648
0
    }
649
650
2.38k
    if (ret == 0) {
651
2.38k
        *outLen = ED448_SIG_SIZE;
652
653
#ifdef WOLFSSL_EDDSA_CHECK_PRIV_ON_SIGN
654
        XMEMCPY(orig_k, key->k, ED448_KEY_SIZE);
655
#endif
656
657
        /* step 1: create nonce to use where nonce is r in
658
           r = H(h_b, ... ,h_2b-1,M) */
659
2.38k
        ret = ed448_hash(key, key->k, ED448_KEY_SIZE, az, sizeof(az));
660
2.38k
    }
661
2.38k
    if (ret == 0) {
662
2.38k
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
663
2.38k
        wc_Shake *sha = &key->sha;
664
#else
665
        WC_ALLOC_VAR_EX(sha, wc_Shake, 1, key->heap, DYNAMIC_TYPE_HASHES,
666
                        ret = MEMORY_E);
667
        if (ret == 0)
668
            ret = ed448_hash_init(key, sha);
669
#endif
670
        /* apply clamp */
671
2.38k
        az[0]  &= 0xfc;
672
2.38k
        az[55] |= 0x80;
673
2.38k
        az[56]  = 0x00;
674
675
2.38k
        if (ret == 0) {
676
2.38k
            ret = ed448_hash_update(key, sha, ed448Ctx, ED448CTX_SIZE);
677
2.38k
        }
678
2.38k
        if (ret == 0) {
679
2.38k
            ret = ed448_hash_update(key, sha, &type, sizeof(type));
680
2.38k
        }
681
2.38k
        if (ret == 0) {
682
2.38k
            ret = ed448_hash_update(key, sha, &contextLen, sizeof(contextLen));
683
2.38k
        }
684
2.38k
        if ((ret == 0) && (context != NULL)) {
685
0
            ret = ed448_hash_update(key, sha, context, contextLen);
686
0
        }
687
2.38k
        if (ret == 0) {
688
2.38k
            ret = ed448_hash_update(key, sha, az + ED448_KEY_SIZE, ED448_KEY_SIZE);
689
2.38k
        }
690
2.38k
        if (ret == 0) {
691
2.38k
            ret = ed448_hash_update(key, sha, in, inLen);
692
2.38k
        }
693
2.38k
        if (ret == 0) {
694
2.38k
            ret = ed448_hash_final(key, sha, nonce, sizeof(nonce));
695
2.38k
        }
696
#ifndef WOLFSSL_ED448_PERSISTENT_SHA
697
        ed448_hash_free(key, sha);
698
#else
699
        /* On failure the absorbed prefix must not stay in the key's hash. */
700
2.38k
        if (ret != 0) {
701
0
            ed448_hash_free(key, sha);
702
0
        }
703
2.38k
#endif
704
2.38k
    }
705
2.38k
    if (ret == 0) {
706
2.38k
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
707
2.38k
        wc_Shake *sha = &key->sha;
708
#else
709
        ret = ed448_hash_init(key, sha);
710
#endif
711
2.38k
        if (ret == 0)
712
2.38k
            sc448_reduce(nonce);
713
        /* step 2: computing R = rB where rB is the scalar multiplication of
714
           r and B */
715
2.38k
        if (ret == 0) {
716
2.38k
            ret = ge448_scalarmult_base(&R,nonce);
717
2.38k
        }
718
        /* step 3: hash R + public key + message getting H(R,A,M) then
719
           creating S = (r + H(R,A,M)a) mod l */
720
2.38k
        if (ret == 0) {
721
2.28k
            ge448_to_bytes(out,&R);
722
723
2.28k
            ret = ed448_hash_update(key, sha, ed448Ctx, ED448CTX_SIZE);
724
2.28k
        }
725
2.38k
        if (ret == 0) {
726
2.28k
            ret = ed448_hash_update(key, sha, &type, sizeof(type));
727
2.28k
        }
728
2.38k
        if (ret == 0) {
729
2.28k
            ret = ed448_hash_update(key, sha, &contextLen, sizeof(contextLen));
730
2.28k
        }
731
2.38k
        if ((ret == 0) && (context != NULL)) {
732
0
            ret = ed448_hash_update(key, sha, context, contextLen);
733
0
        }
734
2.38k
        if (ret == 0) {
735
2.28k
            ret = ed448_hash_update(key, sha, out, ED448_SIG_SIZE/2);
736
2.28k
        }
737
2.38k
        if (ret == 0) {
738
2.28k
            ret = ed448_hash_update(key, sha, key->p, ED448_PUB_KEY_SIZE);
739
2.28k
        }
740
2.38k
        if (ret == 0) {
741
2.28k
            ret = ed448_hash_update(key, sha, in, inLen);
742
2.28k
        }
743
2.38k
        if (ret == 0) {
744
2.28k
            ret = ed448_hash_final(key, sha, hram, sizeof(hram));
745
2.28k
        }
746
#ifndef WOLFSSL_ED448_PERSISTENT_SHA
747
        ed448_hash_free(key, sha);
748
#endif
749
2.38k
    }
750
#ifndef WOLFSSL_ED448_PERSISTENT_SHA
751
    /* key may be NULL here and XFREE evaluates its heap argument. */
752
    WC_FREE_VAR_EX(sha, key ? key->heap : NULL, DYNAMIC_TYPE_HASHES);
753
#endif
754
755
2.38k
    if (ret == 0) {
756
2.28k
        sc448_reduce(hram);
757
2.28k
        sc448_muladd(out + (ED448_SIG_SIZE/2), hram, az, nonce);
758
2.28k
    }
759
760
#ifdef WOLFSSL_EDDSA_CHECK_PRIV_ON_SIGN
761
    if (ret == 0) {
762
        int  i;
763
        byte c = 0;
764
        for (i = 0; i < ED448_KEY_SIZE; i++) {
765
            c |= key->k[i] ^ orig_k[i];
766
        }
767
        ret = ctMaskGT(c, 0) & SIG_VERIFY_E;
768
    }
769
    ForceZero(orig_k, sizeof(orig_k));
770
#ifdef WOLFSSL_CHECK_MEM_ZERO
771
    wc_MemZero_Check(orig_k, sizeof(orig_k));
772
#endif
773
#endif
774
775
2.38k
    ForceZero(az, sizeof(az));
776
2.38k
    ForceZero(nonce, sizeof(nonce));
777
    /* Projective R leaks bits of the nonce. */
778
2.38k
    ForceZero(&R, sizeof(R));
779
#ifdef WOLFSSL_CHECK_MEM_ZERO
780
    wc_MemZero_Check(&R, sizeof(R));
781
    wc_MemZero_Check(nonce, sizeof(nonce));
782
    wc_MemZero_Check(az, sizeof(az));
783
#endif
784
2.38k
    return ret;
785
2.38k
}
786
787
/* Sign the message using the ed448 private key.
788
 * Signature type is Ed448.
789
 *
790
 *  in          [in]      Message to sign.
791
 *  inLen       [in]      Length of the message in bytes.
792
 *  out         [in]      Buffer to write signature into.
793
 *  outLen      [in/out]  On in, size of buffer.
794
 *                        On out, the length of the signature in bytes.
795
 *  key         [in]      Ed448 key to use when signing
796
 *  context     [in]      Context of signing.
797
 *  contextLen  [in]      Length of context in bytes.
798
 *  returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
799
 *          context is not NULL or public key not set,
800
 *          BUFFER_E when outLen is less than ED448_SIG_SIZE,
801
 *          other -ve values when hash fails,
802
 *          0 otherwise.
803
 */
804
int wc_ed448_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen,
805
                      ed448_key* key, const byte* context, byte contextLen)
806
2.38k
{
807
2.38k
    return wc_ed448_sign_msg_ex(in, inLen, out, outLen, key, Ed448, context,
808
2.38k
                                                                    contextLen);
809
2.38k
}
810
811
/* Sign the hash using the ed448 private key.
812
 * Signature type is Ed448ph.
813
 *
814
 *  hash        [in]      Hash of message to sign.
815
 *  hashLen     [in]      Length of hash of message in bytes.
816
 *  out         [in]      Buffer to write signature into.
817
 *  outLen      [in/out]  On in, size of buffer.
818
 *                        On out, the length of the signature in bytes.
819
 *  key         [in]      Ed448 key to use when signing
820
 *  context     [in]      Context of signing.
821
 *  contextLen  [in]      Length of context in bytes.
822
 *  returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
823
 *          context is not NULL or public key not set,
824
 *          BUFFER_E when outLen is less than ED448_SIG_SIZE,
825
 *          other -ve values when hash fails,
826
 *          0 otherwise.
827
 */
828
int wc_ed448ph_sign_hash(const byte* hash, word32 hashLen, byte* out,
829
                         word32 *outLen, ed448_key* key,
830
                         const byte* context, byte contextLen)
831
0
{
832
0
    return wc_ed448_sign_msg_ex(hash, hashLen, out, outLen, key, Ed448ph,
833
0
                                context, contextLen);
834
0
}
835
836
/* Sign the message using the ed448 private key.
837
 * Signature type is Ed448ph.
838
 *
839
 *  in          [in]      Message to sign.
840
 *  inLen       [in]      Length of the message to sign in bytes.
841
 *  out         [in]      Buffer to write signature into.
842
 *  outLen      [in/out]  On in, size of buffer.
843
 *                        On out, the length of the signature in bytes.
844
 *  key         [in]      Ed448 key to use when signing
845
 *  context     [in]      Context of signing.
846
 *  contextLen  [in]      Length of context in bytes.
847
 *  returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
848
 *          context is not NULL or public key not set,
849
 *          BUFFER_E when outLen is less than ED448_SIG_SIZE,
850
 *          other -ve values when hash fails,
851
 *          0 otherwise.
852
 */
853
int wc_ed448ph_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen,
854
                        ed448_key* key, const byte* context, byte contextLen)
855
0
{
856
0
    int  ret;
857
0
    byte hash[ED448_PREHASH_SIZE];
858
859
0
    ret = ed448_hash(key, in, inLen, hash, sizeof(hash));
860
861
0
    if (ret == 0) {
862
0
        ret = wc_ed448ph_sign_hash(hash, sizeof(hash), out, outLen, key,
863
0
                                                           context, contextLen);
864
0
    }
865
866
0
    return ret;
867
0
}
868
#endif /* HAVE_ED448_SIGN */
869
870
#ifdef HAVE_ED448_VERIFY
871
872
/* Verify the message using the ed448 public key.
873
 *
874
 *  sig         [in]  Signature to verify.
875
 *  sigLen      [in]  Size of signature in bytes.
876
 *  key         [in]  Ed448 key to use to verify.
877
 *  type        [in]  Type of signature to verify: Ed448 or Ed448ph
878
 *  context     [in]  Context of verification.
879
 *  contextLen  [in]  Length of context in bytes.
880
 *  returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
881
 *          context is not NULL or public key not set,
882
 *          BUFFER_E when sigLen is less than ED448_SIG_SIZE,
883
 *          other -ve values when hash fails,
884
 *          0 otherwise.
885
 */
886
887
static int ed448_verify_msg_init_with_sha(const byte* sig, word32 sigLen,
888
                                      ed448_key* key, wc_Shake *sha, byte type,
889
                                      const byte* context, byte contextLen)
890
2.58k
{
891
2.58k
    int ret;
892
893
    /* sanity check on arguments */
894
2.58k
    if ((sig == NULL) || (key == NULL) ||
895
2.58k
        ((context == NULL) && (contextLen != 0))) {
896
0
        return BAD_FUNC_ARG;
897
0
    }
898
899
    /* check on basics needed to verify signature */
900
2.58k
    if (sigLen != ED448_SIG_SIZE) {
901
0
        return BAD_FUNC_ARG;
902
0
    }
903
904
    /* find H(R,A,M) and store it as h */
905
2.58k
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
906
2.58k
    ret = ed448_hash_reset(key);
907
2.58k
    if (ret < 0)
908
0
        return ret;
909
2.58k
#endif
910
911
2.58k
    ret = ed448_hash_update(key, sha, ed448Ctx, ED448CTX_SIZE);
912
2.58k
    if (ret == 0) {
913
2.58k
        ret = ed448_hash_update(key, sha, &type, sizeof(type));
914
2.58k
    }
915
2.58k
    if (ret == 0) {
916
2.58k
        ret = ed448_hash_update(key, sha, &contextLen, sizeof(contextLen));
917
2.58k
    }
918
2.58k
    if ((ret == 0) && (context != NULL)) {
919
0
        ret = ed448_hash_update(key, sha, context, contextLen);
920
0
    }
921
2.58k
    if (ret == 0) {
922
2.58k
        ret = ed448_hash_update(key, sha, sig, ED448_SIG_SIZE/2);
923
2.58k
    }
924
2.58k
    if (ret == 0) {
925
2.58k
        ret = ed448_hash_update(key, sha, key->p, ED448_PUB_KEY_SIZE);
926
2.58k
    }
927
928
2.58k
    return ret;
929
2.58k
}
930
931
/*
932
   msgSegment     an array of bytes containing a message segment
933
   msgSegmentLen  length of msgSegment
934
   key            Ed448 public key
935
   return         0 on success
936
*/
937
static int ed448_verify_msg_update_with_sha(const byte* msgSegment,
938
                                        word32 msgSegmentLen,
939
                                        ed448_key* key,
940
                                        wc_Shake *sha)
941
116k
{
942
    /* sanity check on arguments */
943
116k
    if (msgSegment == NULL || key == NULL)
944
27
        return BAD_FUNC_ARG;
945
946
116k
    return ed448_hash_update(key, sha, msgSegment, msgSegmentLen);
947
116k
}
948
949
/* Order of the ed448 curve - little endian. */
950
static const byte ed448_order[] = {
951
    0xf3, 0x44, 0x58, 0xab, 0x92, 0xc2, 0x78, 0x23,
952
    0x55, 0x8f, 0xc5, 0x8d, 0x72, 0xc2, 0x6c, 0x21,
953
    0x90, 0x36, 0xd6, 0xae, 0x49, 0xdb, 0x4e, 0xc4,
954
    0xe9, 0x23, 0xca, 0x7c, 0xff, 0xff, 0xff, 0xff,
955
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
956
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
957
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f,
958
    0x00
959
};
960
961
/* Verify the message using the ed448 public key.
962
 *
963
 *  sig         [in]  Signature to verify.
964
 *  sigLen      [in]  Size of signature in bytes.
965
 *  res         [out] *res is set to 1 on successful verification.
966
 *  key         [in]  Ed448 key to use to verify.
967
 *  returns BAD_FUNC_ARG when a parameter is NULL or public key not set,
968
 *          BUFFER_E when sigLen is less than ED448_SIG_SIZE,
969
 *          other -ve values when hash fails,
970
 *          0 otherwise.
971
 */
972
static int ed448_verify_msg_final_with_sha(const byte* sig, word32 sigLen,
973
                                     int* res, ed448_key* key, wc_Shake *sha)
974
2.55k
{
975
2.55k
    byte     rcheck[ED448_KEY_SIZE];
976
2.55k
    byte     h[ED448_SIG_SIZE];
977
2.55k
    ge448_p2 A;
978
2.55k
    ge448_p2 R;
979
2.55k
    int      ret;
980
2.55k
    int      i;
981
982
    /* sanity check on arguments */
983
2.55k
    if ((sig == NULL) || (res == NULL) || (key == NULL))
984
0
        return BAD_FUNC_ARG;
985
986
    /* set verification failed by default */
987
2.55k
    *res = 0;
988
989
    /* check on basics needed to verify signature */
990
2.55k
    if (sigLen != ED448_SIG_SIZE)
991
0
        return BAD_FUNC_ARG;
992
    /* Check S is not larger than or equal to order. */
993
5.16k
    for (i = (int)sizeof(ed448_order) - 1; i >= 0; i--) {
994
        /* Bigger than order. */
995
5.16k
        if (sig[ED448_SIG_SIZE/2 + i] > ed448_order[i])
996
98
            return BAD_FUNC_ARG;
997
        /* Less than order. */
998
5.06k
        if (sig[ED448_SIG_SIZE/2 + i] < ed448_order[i])
999
2.45k
            break;
1000
5.06k
    }
1001
    /* Same value as order. */
1002
2.45k
    if (i == -1)
1003
0
        return BAD_FUNC_ARG;
1004
1005
    /* Defence in depth: also catch small-order and non-canonical keys
1006
     * imported with trusted=1. */
1007
2.45k
    if (ed448_is_small_order(key->p)) {
1008
0
        WOLFSSL_MSG("Ed448 small-order public key rejected during "
1009
0
                    "signature verification");
1010
0
        return BAD_FUNC_ARG;
1011
0
    }
1012
2.45k
    if (!ed448_pub_y_in_range(key->p)) {
1013
0
        WOLFSSL_MSG("Ed448 public key with y >= p rejected during "
1014
0
                    "signature verification");
1015
0
        return BAD_FUNC_ARG;
1016
0
    }
1017
1018
1019
    /* uncompress A (public key), test if valid, and negate it */
1020
2.45k
    if (ge448_from_bytes_negate_vartime(&A, key->p) != 0)
1021
0
        return BAD_FUNC_ARG;
1022
1023
2.45k
    ret = ed448_hash_final(key, sha, h, sizeof(h));
1024
2.45k
    if (ret != 0)
1025
0
        return ret;
1026
1027
2.45k
    sc448_reduce(h);
1028
1029
    /* Uses a fast single-signature verification SB = R + H(R,A,M)A becomes
1030
     * SB - H(R,A,M)A saving decompression of R
1031
     */
1032
2.45k
    ret = ge448_double_scalarmult_vartime(&R, h, &A,
1033
2.45k
                                          sig + (ED448_SIG_SIZE/2));
1034
2.45k
    if (ret != 0)
1035
336
        return ret;
1036
1037
2.11k
    ge448_to_bytes(rcheck, &R);
1038
1039
    /* comparison of R created to R in sig */
1040
2.11k
    if (ConstantCompare(rcheck, sig, ED448_SIG_SIZE/2) != 0) {
1041
218
        ret = SIG_VERIFY_E;
1042
218
    }
1043
1.90k
    else {
1044
        /* set the verification status */
1045
1.90k
        *res = 1;
1046
1.90k
    }
1047
1048
2.11k
    return ret;
1049
2.45k
}
1050
1051
#ifdef WOLFSSL_ED448_STREAMING_VERIFY
1052
int wc_ed448_verify_msg_init(const byte* sig, word32 sigLen, ed448_key* key,
1053
                        byte type, const byte* context, byte contextLen)
1054
790
{
1055
790
    return ed448_verify_msg_init_with_sha(sig, sigLen, key, &key->sha, type,
1056
790
                                      context, contextLen);
1057
790
}
1058
1059
int wc_ed448_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen,
1060
                             ed448_key* key)
1061
114k
{
1062
114k
    return ed448_verify_msg_update_with_sha(msgSegment, msgSegmentLen, key,
1063
114k
                                        &key->sha);
1064
114k
}
1065
1066
int wc_ed448_verify_msg_final(const byte* sig, word32 sigLen,
1067
                              int* res, ed448_key* key)
1068
763
{
1069
763
    return ed448_verify_msg_final_with_sha(sig, sigLen, res, key, &key->sha);
1070
763
}
1071
#endif
1072
1073
/* Verify the message using the ed448 public key.
1074
 *
1075
 *  sig         [in]  Signature to verify.
1076
 *  sigLen      [in]  Size of signature in bytes.
1077
 *  msg         [in]  Message to verify.
1078
 *  msgLen      [in]  Length of the message in bytes.
1079
 *  res         [out] *res is set to 1 on successful verification.
1080
 *  key         [in]  Ed448 key to use to verify.
1081
 *  type        [in]  Type of signature to verify: Ed448 or Ed448ph
1082
 *  context     [in]  Context of verification.
1083
 *  contextLen  [in]  Length of context in bytes.
1084
 *  returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
1085
 *          context is not NULL or public key not set,
1086
 *          BUFFER_E when sigLen is less than ED448_SIG_SIZE,
1087
 *          other -ve values when hash fails,
1088
 *          0 otherwise.
1089
 */
1090
int wc_ed448_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg,
1091
                            word32 msgLen, int* res, ed448_key* key,
1092
                            byte type, const byte* context, byte contextLen)
1093
1.79k
{
1094
1.79k
    int ret;
1095
1.79k
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
1096
1.79k
    wc_Shake *sha;
1097
#else
1098
    WC_DECLARE_VAR(sha, wc_Shake, 1, key ? key->heap : NULL);
1099
#endif
1100
1101
1.79k
    if (key == NULL)
1102
0
        return BAD_FUNC_ARG;
1103
1104
    /* A NULL msg is valid for the empty message (msgLen == 0). */
1105
1.79k
    if ((sig == NULL) || (res == NULL) || ((msg == NULL) && (msgLen != 0)))
1106
0
        return BAD_FUNC_ARG;
1107
1108
    /* An empty message may be passed as (NULL, 0); canonicalize it to a
1109
     * readable stand-in so that downstream consumers -- hash updates and
1110
     * crypto callbacks -- never see a NULL pointer. */
1111
1.79k
    if (msg == NULL) {
1112
104
        static const byte ed448_empty_msg[] = {0};
1113
104
        msg = ed448_empty_msg;
1114
104
    }
1115
1116
1.79k
    if ((type == Ed448ph) &&
1117
0
        (msgLen != ED448_PREHASH_SIZE))
1118
0
    {
1119
0
        return BAD_LENGTH_E;
1120
0
    }
1121
1122
1.79k
#ifdef WOLF_CRYPTO_CB
1123
1.79k
    #ifndef WOLF_CRYPTO_CB_FIND
1124
1.79k
    if (key->devId != INVALID_DEVID)
1125
0
    #endif
1126
0
    {
1127
0
        if (res != NULL)
1128
0
            *res = 0;
1129
0
        ret = wc_CryptoCb_Ed448Verify(sig, sigLen, msg, msgLen, res, key, type,
1130
0
            context, contextLen);
1131
0
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
1132
0
            return ret;
1133
        /* fall-through when unavailable */
1134
0
    }
1135
1.79k
#endif
1136
1137
1.79k
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
1138
1.79k
    sha = &key->sha;
1139
#else
1140
    WC_ALLOC_VAR_EX(sha, wc_Shake, 1, key->heap, DYNAMIC_TYPE_HASHES,
1141
                    return MEMORY_E);
1142
    ret = ed448_hash_init(key, sha);
1143
    if (ret < 0) {
1144
        WC_FREE_VAR_EX(sha, key->heap, DYNAMIC_TYPE_HASHES);
1145
        return ret;
1146
    }
1147
#endif
1148
1149
1.79k
    ret = ed448_verify_msg_init_with_sha(sig, sigLen, key, sha,
1150
1.79k
                                   type, context, contextLen);
1151
1.79k
    if (ret == 0)
1152
1.79k
        ret = ed448_verify_msg_update_with_sha(msg, msgLen, key, sha);
1153
1.79k
    if (ret == 0)
1154
1.79k
        ret = ed448_verify_msg_final_with_sha(sig, sigLen, res, key, sha);
1155
1156
#ifndef WOLFSSL_ED448_PERSISTENT_SHA
1157
    ed448_hash_free(key, sha);
1158
    WC_FREE_VAR_EX(sha, key->heap, DYNAMIC_TYPE_HASHES);
1159
#endif
1160
1161
1.79k
    return ret;
1162
1.79k
}
1163
1164
/* Verify the message using the ed448 public key.
1165
 * Signature type is Ed448.
1166
 *
1167
 *  sig         [in]  Signature to verify.
1168
 *  sigLen      [in]  Size of signature in bytes.
1169
 *  msg         [in]  Message to verify.
1170
 *  msgLen      [in]  Length of the message in bytes.
1171
 *  key         [in]  Ed448 key to use to verify.
1172
 *  context     [in]  Context of verification.
1173
 *  contextLen  [in]  Length of context in bytes.
1174
 *  returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
1175
 *          context is not NULL or public key not set,
1176
 *          BUFFER_E when sigLen is less than ED448_SIG_SIZE,
1177
 *          other -ve values when hash fails,
1178
 *          0 otherwise.
1179
 */
1180
int wc_ed448_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
1181
                        word32 msgLen, int* res, ed448_key* key,
1182
                        const byte* context, byte contextLen)
1183
1.79k
{
1184
1.79k
    return wc_ed448_verify_msg_ex(sig, sigLen, msg, msgLen, res, key, Ed448,
1185
1.79k
                                                           context, contextLen);
1186
1.79k
}
1187
1188
/* Verify the hash using the ed448 public key.
1189
 * Signature type is Ed448ph.
1190
 *
1191
 *  sig         [in]  Signature to verify.
1192
 *  sigLen      [in]  Size of signature in bytes.
1193
 *  hash        [in]  Hash of message to verify.
1194
 *  hashLen     [in]  Length of the hash in bytes.
1195
 *  key         [in]  Ed448 key to use to verify.
1196
 *  context     [in]  Context of verification.
1197
 *  contextLen  [in]  Length of context in bytes.
1198
 *  returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
1199
 *          context is not NULL or public key not set,
1200
 *          BUFFER_E when sigLen is less than ED448_SIG_SIZE,
1201
 *          other -ve values when hash fails,
1202
 *          0 otherwise.
1203
 */
1204
int wc_ed448ph_verify_hash(const byte* sig, word32 sigLen, const byte* hash,
1205
                           word32 hashLen, int* res, ed448_key* key,
1206
                           const byte* context, byte contextLen)
1207
0
{
1208
0
    return wc_ed448_verify_msg_ex(sig, sigLen, hash, hashLen, res, key, Ed448ph,
1209
0
                                                           context, contextLen);
1210
0
}
1211
1212
/* Verify the message using the ed448 public key.
1213
 * Signature type is Ed448ph.
1214
 *
1215
 *  sig         [in]  Signature to verify.
1216
 *  sigLen      [in]  Size of signature in bytes.
1217
 *  msg         [in]  Message to verify.
1218
 *  msgLen      [in]  Length of the message in bytes.
1219
 *  key         [in]  Ed448 key to use to verify.
1220
 *  context     [in]  Context of verification.
1221
 *  contextLen  [in]  Length of context in bytes.
1222
 *  returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
1223
 *          context is not NULL or public key not set,
1224
 *          BUFFER_E when sigLen is less than ED448_SIG_SIZE,
1225
 *          other -ve values when hash fails,
1226
 *          0 otherwise.
1227
 */
1228
int wc_ed448ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
1229
                          word32 msgLen, int* res, ed448_key* key,
1230
                          const byte* context, byte contextLen)
1231
0
{
1232
0
    int  ret = 0;
1233
0
    byte hash[ED448_PREHASH_SIZE];
1234
1235
0
    ret = ed448_hash(key, msg, msgLen, hash, sizeof(hash));
1236
1237
0
    if (ret == 0) {
1238
0
        ret = wc_ed448ph_verify_hash(sig, sigLen, hash, sizeof(hash), res, key,
1239
0
                                                           context, contextLen);
1240
0
    }
1241
1242
0
    return ret;
1243
0
}
1244
#endif /* HAVE_ED448_VERIFY */
1245
1246
/* Initialize the ed448 private/public key.
1247
 *
1248
 * key  [in]  Ed448 key.
1249
 * heap [in]  heap pointer to pass to wc_InitShake256().
1250
 * returns BAD_FUNC_ARG when key is NULL
1251
 */
1252
int wc_ed448_init_ex(ed448_key* key, void *heap, int devId)
1253
6.83k
{
1254
6.83k
    if (key == NULL)
1255
0
        return BAD_FUNC_ARG;
1256
1257
6.83k
    XMEMSET(key, 0, sizeof(ed448_key));
1258
1259
6.83k
#ifdef WOLF_CRYPTO_CB
1260
6.83k
    key->devId = devId;
1261
#else
1262
    (void)devId;
1263
#endif
1264
6.83k
    key->heap = heap;
1265
1266
6.83k
    fe448_init();
1267
1268
#ifdef WOLFSSL_CHECK_MEM_ZERO
1269
    wc_MemZero_Add("wc_ed448_init_ex key->k", &key->k, sizeof(key->k));
1270
#endif
1271
1272
6.83k
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
1273
6.83k
    return ed448_hash_init(key, &key->sha);
1274
#else /* !WOLFSSL_ED448_PERSISTENT_SHA */
1275
    return 0;
1276
#endif /* WOLFSSL_ED448_PERSISTENT_SHA */
1277
6.83k
}
1278
1279
/* Initialize the ed448 private/public key.
1280
 *
1281
 * key  [in]  Ed448 key.
1282
 * returns BAD_FUNC_ARG when key is NULL
1283
 */
1284
6.83k
int wc_ed448_init(ed448_key* key) {
1285
6.83k
    return wc_ed448_init_ex(key, NULL, INVALID_DEVID);
1286
6.83k
}
1287
1288
#ifdef WOLF_PRIVATE_KEY_ID
1289
/* Initialize an Ed448 key that references a device key by id.
1290
 *
1291
 * key   [in]  Ed448 key.
1292
 * id    [in]  Identifier of the device key.
1293
 * len   [in]  Length of the identifier in bytes.
1294
 * heap  [in]  Heap hint.
1295
 * devId [in]  Device identifier.
1296
 * returns BAD_FUNC_ARG when key is NULL or id is NULL with a positive len,
1297
 *         BUFFER_E when len is negative or more than ED448_MAX_ID_LEN,
1298
 *         0 otherwise.
1299
 */
1300
int wc_ed448_init_id(ed448_key* key, const unsigned char* id, int len,
1301
                     void* heap, int devId)
1302
0
{
1303
0
    int ret = 0;
1304
1305
0
    if ((key == NULL) || ((id == NULL) && (len > 0))) {
1306
0
        ret = BAD_FUNC_ARG;
1307
0
    }
1308
0
    if ((ret == 0) && ((len < 0) || (len > ED448_MAX_ID_LEN))) {
1309
0
        ret = BUFFER_E;
1310
0
    }
1311
0
    if (ret == 0) {
1312
0
        ret = wc_ed448_init_ex(key, heap, devId);
1313
0
    }
1314
0
    if ((ret == 0) && (id != NULL) && (len != 0)) {
1315
0
        XMEMCPY(key->id, id, (size_t)len);
1316
0
        key->idLen = len;
1317
0
    }
1318
1319
0
    return ret;
1320
0
}
1321
1322
/* Initialize an Ed448 key that references a device key by label.
1323
 *
1324
 * key   [in]  Ed448 key.
1325
 * label [in]  NUL terminated label of the device key.
1326
 * heap  [in]  Heap hint.
1327
 * devId [in]  Device identifier.
1328
 * returns BAD_FUNC_ARG when key or label is NULL,
1329
 *         BUFFER_E when label is empty or longer than ED448_MAX_LABEL_LEN,
1330
 *         0 otherwise.
1331
 */
1332
int wc_ed448_init_label(ed448_key* key, const char* label, void* heap,
1333
                        int devId)
1334
0
{
1335
0
    int ret = 0;
1336
0
    int labelLen = 0;
1337
1338
0
    if ((key == NULL) || (label == NULL)) {
1339
0
        ret = BAD_FUNC_ARG;
1340
0
    }
1341
0
    if (ret == 0) {
1342
0
        labelLen = (int)XSTRLEN(label);
1343
0
        if ((labelLen == 0) || (labelLen > ED448_MAX_LABEL_LEN)) {
1344
0
            ret = BUFFER_E;
1345
0
        }
1346
0
    }
1347
0
    if (ret == 0) {
1348
0
        ret = wc_ed448_init_ex(key, heap, devId);
1349
0
    }
1350
0
    if (ret == 0) {
1351
0
        XMEMCPY(key->label, label, (size_t)labelLen);
1352
0
        key->labelLen = labelLen;
1353
0
    }
1354
1355
0
    return ret;
1356
0
}
1357
#endif /* WOLF_PRIVATE_KEY_ID */
1358
1359
/* Clears the ed448 key data
1360
 *
1361
 * key  [in]  Ed448 key.
1362
 */
1363
void wc_ed448_free(ed448_key* key)
1364
6.83k
{
1365
6.83k
    if (key != NULL) {
1366
6.83k
#ifdef WOLFSSL_ED448_PERSISTENT_SHA
1367
6.83k
        ed448_hash_free(key, &key->sha);
1368
6.83k
#endif
1369
6.83k
        ForceZero(key, sizeof(ed448_key));
1370
    #ifdef WOLFSSL_CHECK_MEM_ZERO
1371
        wc_MemZero_Check(key, sizeof(ed448_key));
1372
    #endif
1373
6.83k
    }
1374
6.83k
}
1375
1376
#ifndef WC_NO_CONSTRUCTORS
1377
ed448_key* wc_ed448_new(void* heap, int devId, int *result_code)
1378
0
{
1379
0
    int ret;
1380
0
    ed448_key* key = (ed448_key*)XMALLOC(sizeof(ed448_key), heap,
1381
0
                        DYNAMIC_TYPE_ED448);
1382
0
    if (key == NULL) {
1383
0
        ret = MEMORY_E;
1384
0
    }
1385
0
    else {
1386
0
        ret = wc_ed448_init_ex(key, heap, devId);
1387
0
        if (ret != 0) {
1388
0
            XFREE(key, heap, DYNAMIC_TYPE_ED448);
1389
0
            key = NULL;
1390
0
        }
1391
0
    }
1392
1393
0
    if (result_code != NULL)
1394
0
        *result_code = ret;
1395
1396
0
    return key;
1397
0
}
1398
1399
0
int wc_ed448_delete(ed448_key* key, ed448_key** key_p) {
1400
0
    void* heap;
1401
0
    if (key == NULL)
1402
0
        return BAD_FUNC_ARG;
1403
0
    heap = key->heap;
1404
0
    wc_ed448_free(key);
1405
0
    XFREE(key, heap, DYNAMIC_TYPE_ED448);
1406
0
    if (key_p != NULL)
1407
0
        *key_p = NULL;
1408
0
    return 0;
1409
0
}
1410
#endif /* !WC_NO_CONSTRUCTORS */
1411
1412
#ifdef HAVE_ED448_KEY_EXPORT
1413
1414
/* Export the ed448 public key.
1415
 *
1416
 * key     [in]      Ed448 public key.
1417
 * out     [in]      Array to hold public key.
1418
 * outLen  [in/out]  On in, the number of bytes in array.
1419
 *                   On out, the number bytes put into array.
1420
 * returns PUBLIC_KEY_E the given key only has a private key present,
1421
 *         BAD_FUNC_ARG when a parameter is NULL,
1422
 *         ECC_BAD_ARG_E when outLen is less than ED448_PUB_KEY_SIZE,
1423
 *         0 otherwise.
1424
 */
1425
int wc_ed448_export_public(const ed448_key* key, byte* out, word32* outLen)
1426
173
{
1427
173
    int ret = 0;
1428
1429
    /* sanity check on arguments */
1430
173
    if ((key == NULL) || (out == NULL) || (outLen == NULL)) {
1431
45
        ret = BAD_FUNC_ARG;
1432
45
    }
1433
1434
173
    if ((ret == 0) && (*outLen < ED448_PUB_KEY_SIZE)) {
1435
12
        *outLen = ED448_PUB_KEY_SIZE;
1436
12
        ret = BUFFER_E;
1437
12
    }
1438
1439
173
    if ((ret == 0) && (!key->pubKeySet)) {
1440
0
        ret = PUBLIC_KEY_E;
1441
0
    }
1442
1443
173
    if (ret == 0) {
1444
116
        *outLen = ED448_PUB_KEY_SIZE;
1445
116
        XMEMCPY(out, key->p, ED448_PUB_KEY_SIZE);
1446
116
    }
1447
1448
173
    return ret;
1449
173
}
1450
1451
#endif /* HAVE_ED448_KEY_EXPORT */
1452
1453
1454
#ifdef HAVE_ED448_KEY_IMPORT
1455
/* Import a compressed or uncompressed ed448 public key from a byte array.
1456
 * Public key encoded in big-endian.
1457
 *
1458
 * in       [in]  Array holding public key.
1459
 * inLen    [in]  Number of bytes of data in array.
1460
 * key      [in]  Ed448 public key.
1461
 * trusted  [in]  Indicates whether the public key data is trusted.
1462
 *                When 0, checks public key matches private key.
1463
 *                When 1, doesn't check public key matches private key.
1464
 * returns BAD_FUNC_ARG when a parameter is NULL or key format is not supported,
1465
 *         0 otherwise.
1466
 */
1467
int wc_ed448_import_public_ex(const byte* in, word32 inLen, ed448_key* key,
1468
    int trusted)
1469
2.98k
{
1470
2.98k
    int ret = 0;
1471
1472
    /* sanity check on arguments */
1473
2.98k
    if ((in == NULL) || (key == NULL)) {
1474
0
        ret = BAD_FUNC_ARG;
1475
0
    }
1476
1477
2.98k
    if ((inLen != ED448_PUB_KEY_SIZE) &&
1478
52
        (inLen != ED448_PUB_KEY_SIZE + 1) &&
1479
50
        (inLen != 2 * ED448_PUB_KEY_SIZE + 1)) {
1480
48
        ret = BAD_FUNC_ARG;
1481
48
    }
1482
1483
2.98k
    if (ret == 0) {
1484
        /* compressed prefix according to draft
1485
         * https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-06 */
1486
2.93k
        if (in[0] == 0x40 && inLen > ED448_PUB_KEY_SIZE) {
1487
            /* key is stored in compressed format so just copy in */
1488
1
            XMEMCPY(key->p, (in + 1), ED448_PUB_KEY_SIZE);
1489
1
        }
1490
        /* importing uncompressed public key */
1491
2.93k
        else if (in[0] == 0x04 && inLen > 2*ED448_PUB_KEY_SIZE) {
1492
            /* pass in (x,y) and store compressed key */
1493
2
            ret = ge448_compress_key(key->p, in+1, in+1+ED448_PUB_KEY_SIZE);
1494
2
        }
1495
2.93k
        else if (inLen == ED448_PUB_KEY_SIZE) {
1496
            /* if not specified compressed or uncompressed check key size
1497
             * if key size is equal to compressed key size copy in key */
1498
2.93k
            XMEMCPY(key->p, in, ED448_PUB_KEY_SIZE);
1499
2.93k
        }
1500
1
        else {
1501
            /* bad public key format */
1502
1
            ret = BAD_FUNC_ARG;
1503
1
        }
1504
2.93k
    }
1505
1506
2.98k
    if (ret == 0) {
1507
2.93k
        key->pubKeySet = 1;
1508
2.93k
        if (!trusted) {
1509
            /* Check untrusted public key data matches private key. */
1510
2.93k
            ret = wc_ed448_check_key(key);
1511
2.93k
        }
1512
2.93k
    }
1513
2.98k
    if (ret == 0) {
1514
        /* Keep the public key copy synchronized. */
1515
2.66k
        XMEMCPY(key->k + ED448_KEY_SIZE,
1516
2.66k
                key->p, ED448_PUB_KEY_SIZE);
1517
2.66k
    }
1518
1519
2.98k
    if ((ret != 0) && (key != NULL)) {
1520
        /* No public key set on failure. */
1521
322
        key->pubKeySet = 0;
1522
322
    }
1523
1524
2.98k
    return ret;
1525
2.98k
}
1526
1527
/* Import a compressed or uncompressed ed448 public key from a byte array.
1528
 *
1529
 * Public key encoded in big-endian.
1530
 * Public key is not trusted and is checked against private key if set.
1531
 *
1532
 * in      [in]  Array holding public key.
1533
 * inLen   [in]  Number of bytes of data in array.
1534
 * key     [in]  Ed448 public key.
1535
 * returns BAD_FUNC_ARG when a parameter is NULL or key format is not supported,
1536
 *         0 otherwise.
1537
 */
1538
int wc_ed448_import_public(const byte* in, word32 inLen, ed448_key* key)
1539
2.98k
{
1540
2.98k
    return wc_ed448_import_public_ex(in, inLen, key, 0);
1541
2.98k
}
1542
1543
/* Import an ed448 private key from a byte array.
1544
 *
1545
 * priv    [in]  Array holding private key.
1546
 * privSz  [in]  Number of bytes of data in array.
1547
 * key     [in]  Ed448 private key.
1548
 * returns BAD_FUNC_ARG when a parameter is NULL or privSz is less than
1549
 *         ED448_KEY_SIZE,
1550
 *         0 otherwise.
1551
 */
1552
int wc_ed448_import_private_only(const byte* priv, word32 privSz,
1553
                                 ed448_key* key)
1554
2.89k
{
1555
2.89k
    int ret = 0;
1556
1557
    /* sanity check on arguments */
1558
2.89k
    if ((priv == NULL) || (key == NULL)) {
1559
0
        ret = BAD_FUNC_ARG;
1560
0
    }
1561
1562
    /* key size check */
1563
2.89k
    if ((ret == 0) && (privSz != ED448_KEY_SIZE)) {
1564
20
        ret = BAD_FUNC_ARG;
1565
20
    }
1566
1567
2.89k
    if (ret == 0) {
1568
2.87k
        XMEMCPY(key->k, priv, ED448_KEY_SIZE);
1569
2.87k
        key->privKeySet = 1;
1570
2.87k
    }
1571
1572
2.89k
    if ((ret == 0) && key->pubKeySet) {
1573
        /* Validate loaded public key */
1574
0
        ret = wc_ed448_check_key(key);
1575
0
    }
1576
1577
2.89k
    if ((ret != 0) && (key != NULL)) {
1578
        /* No private key set on error. */
1579
20
        key->privKeySet = 0;
1580
20
        ForceZero(key->k, ED448_KEY_SIZE);
1581
20
    }
1582
1583
2.89k
    return ret;
1584
2.89k
}
1585
1586
1587
/* Import an ed448 private and public keys from byte array(s).
1588
 *
1589
 * priv     [in]  Array holding private key from wc_ed448_export_private_only(),
1590
 *                or private+public keys from wc_ed448_export_private().
1591
 * privSz   [in]  Number of bytes of data in private key array.
1592
 * pub      [in]  Array holding public key (or NULL).
1593
 * pubSz    [in]  Number of bytes of data in public key array (or 0).
1594
 * key      [in]  Ed448 private/public key.
1595
 * trusted  [in]  Indicates whether the public key data is trusted.
1596
 *                When 0, checks public key matches private key.
1597
 *                When 1, doesn't check public key matches private key.
1598
 * returns BAD_FUNC_ARG when a required parameter is NULL or an invalid
1599
 *         combination of keys/lengths is supplied, 0 otherwise.
1600
 */
1601
int wc_ed448_import_private_key_ex(const byte* priv, word32 privSz,
1602
    const byte* pub, word32 pubSz, ed448_key* key, int trusted)
1603
0
{
1604
0
    int ret;
1605
1606
    /* sanity check on arguments */
1607
0
    if (priv == NULL || key == NULL)
1608
0
        return BAD_FUNC_ARG;
1609
1610
    /* key size check */
1611
0
    if (privSz != ED448_KEY_SIZE && privSz != ED448_PRV_KEY_SIZE)
1612
0
        return BAD_FUNC_ARG;
1613
1614
0
    if (pub == NULL) {
1615
0
        if (pubSz != 0)
1616
0
            return BAD_FUNC_ARG;
1617
0
        if (privSz != ED448_PRV_KEY_SIZE)
1618
0
            return BAD_FUNC_ARG;
1619
0
        pub = priv + ED448_KEY_SIZE;
1620
0
        pubSz = ED448_PUB_KEY_SIZE;
1621
0
    }
1622
0
    else if (pubSz < ED448_PUB_KEY_SIZE) {
1623
0
        return BAD_FUNC_ARG;
1624
0
    }
1625
1626
0
    XMEMCPY(key->k, priv, ED448_KEY_SIZE);
1627
0
    key->privKeySet = 1;
1628
1629
    /* import public key */
1630
0
    ret = wc_ed448_import_public_ex(pub, pubSz, key, trusted);
1631
0
    if (ret != 0) {
1632
0
        key->privKeySet = 0;
1633
0
        ForceZero(key->k, ED448_KEY_SIZE);
1634
0
        return ret;
1635
0
    }
1636
1637
    /* make the private key (priv + pub) */
1638
0
    ed448_store_public(key, key->p);
1639
1640
0
    return ret;
1641
0
}
1642
1643
/* Import an ed448 private and public keys from byte array(s).
1644
 *
1645
 * Public key is not trusted and is checked against private key.
1646
 *
1647
 * priv    [in]  Array holding private key from wc_ed448_export_private_only(),
1648
 *               or private+public keys from wc_ed448_export_private().
1649
 * privSz  [in]  Number of bytes of data in private key array.
1650
 * pub     [in]  Array holding public key (or NULL).
1651
 * pubSz   [in]  Number of bytes of data in public key array (or 0).
1652
 * key     [in]  Ed448 private/public key.
1653
 * returns BAD_FUNC_ARG when a required parameter is NULL or an invalid
1654
 *         combination of keys/lengths is supplied, 0 otherwise.
1655
 */
1656
int wc_ed448_import_private_key(const byte* priv, word32 privSz,
1657
                                const byte* pub, word32 pubSz, ed448_key* key)
1658
0
{
1659
0
    return wc_ed448_import_private_key_ex(priv, privSz, pub, pubSz, key, 0);
1660
0
}
1661
1662
#endif /* HAVE_ED448_KEY_IMPORT */
1663
1664
1665
#ifdef HAVE_ED448_KEY_EXPORT
1666
1667
/* Export the ed448 private key.
1668
 *
1669
 * key     [in]      Ed448 private key.
1670
 * out     [in]      Array to hold private key.
1671
 * outLen  [in/out]  On in, the number of bytes in array.
1672
 *                   On out, the number bytes put into array.
1673
 * returns BAD_FUNC_ARG when a parameter is NULL,
1674
 *         ECC_BAD_ARG_E when outLen is less than ED448_KEY_SIZE,
1675
 *         0 otherwise.
1676
 */
1677
int wc_ed448_export_private_only(const ed448_key* key, byte* out, word32* outLen)
1678
441
{
1679
441
    int ret = 0;
1680
1681
    /* sanity checks on arguments */
1682
441
    if ((key == NULL) || (out == NULL) || (outLen == NULL)) {
1683
194
        ret = BAD_FUNC_ARG;
1684
194
    }
1685
1686
441
    if ((ret == 0) && (!key->privKeySet)) {
1687
0
        ret = BAD_FUNC_ARG;
1688
0
    }
1689
1690
441
    if ((ret == 0) && (*outLen < ED448_KEY_SIZE)) {
1691
23
        *outLen = ED448_KEY_SIZE;
1692
23
        ret = BUFFER_E;
1693
23
    }
1694
1695
441
    if (ret == 0) {
1696
224
        *outLen = ED448_KEY_SIZE;
1697
224
        XMEMCPY(out, key->k, ED448_KEY_SIZE);
1698
224
    }
1699
1700
441
    return ret;
1701
441
}
1702
1703
/* Export the ed448 private and public key.
1704
 *
1705
 * key     [in]      Ed448 private/public key.
1706
 * out     [in]      Array to hold private and public key.
1707
 * outLen  [in/out]  On in, the number of bytes in array.
1708
 *                   On out, the number bytes put into array.
1709
 * returns BAD_FUNC_ARG when a parameter is NULL,
1710
 *         BUFFER_E when outLen is less than ED448_PRV_KEY_SIZE,
1711
 *         0 otherwise.
1712
 */
1713
int wc_ed448_export_private(const ed448_key* key, byte* out, word32* outLen)
1714
0
{
1715
0
    int ret = 0;
1716
1717
    /* sanity checks on arguments */
1718
0
    if ((key == NULL) || (out == NULL) || (outLen == NULL)) {
1719
0
        ret = BAD_FUNC_ARG;
1720
0
    }
1721
1722
0
    if ((ret == 0) && (!key->privKeySet)) {
1723
0
        ret = BAD_FUNC_ARG;
1724
0
    }
1725
1726
0
    if ((ret == 0) && (*outLen < ED448_PRV_KEY_SIZE)) {
1727
0
        *outLen = ED448_PRV_KEY_SIZE;
1728
0
        ret = BUFFER_E;
1729
0
    }
1730
1731
0
    if (ret == 0) {
1732
0
        *outLen = ED448_PRV_KEY_SIZE;
1733
0
        XMEMCPY(out, key->k, ED448_PRV_KEY_SIZE);
1734
0
     }
1735
1736
0
    return ret;
1737
0
}
1738
1739
/* Export the ed448 private and public key.
1740
 *
1741
 * key     [in]      Ed448 private/public key.
1742
 * priv    [in]      Array to hold private key.
1743
 * privSz  [in/out]  On in, the number of bytes in private key array.
1744
 * pub     [in]      Array to hold  public key.
1745
 * pubSz   [in/out]  On in, the number of bytes in public key array.
1746
 *                   On out, the number bytes put into array.
1747
 * returns BAD_FUNC_ARG when a parameter is NULL,
1748
 *         BUFFER_E when privSz is less than ED448_PRV_KEY_SIZE or pubSz is less
1749
 *         than ED448_PUB_KEY_SIZE,
1750
 *         0 otherwise.
1751
 */
1752
int wc_ed448_export_key(const ed448_key* key, byte* priv, word32 *privSz,
1753
                        byte* pub, word32 *pubSz)
1754
0
{
1755
0
    int ret = 0;
1756
1757
    /* export 'full' private part */
1758
    /* Check the public arguments before anything is written to priv. */
1759
0
    if ((pub == NULL) || (pubSz == NULL)) {
1760
0
        return BAD_FUNC_ARG;
1761
0
    }
1762
0
    ret = wc_ed448_export_private(key, priv, privSz);
1763
0
    if (ret == 0) {
1764
        /* export public part */
1765
0
        ret = wc_ed448_export_public(key, pub, pubSz);
1766
0
        if (ret != 0) {
1767
            /* Public export failed: do not hand back the private key. */
1768
0
            ForceZero(priv, *privSz);
1769
0
        }
1770
0
    }
1771
1772
0
    return ret;
1773
0
}
1774
1775
#endif /* HAVE_ED448_KEY_EXPORT */
1776
1777
/* Check the public key is valid.
1778
 *
1779
 * When private key available, check the calculated public key matches.
1780
 * When no private key, check Y is in range and an X is able to be calculated.
1781
 *
1782
 * @param [in] key  Ed448 private/public key.
1783
 * @return  0 otherwise.
1784
 * @return  BAD_FUNC_ARG when key is NULL.
1785
 * @return  PUBLIC_KEY_E when the public key is not set, doesn't match or is
1786
 *          invalid.
1787
 * @return  other -ve value on hash failure.
1788
 */
1789
int wc_ed448_check_key(ed448_key* key)
1790
3.37k
{
1791
3.37k
    int ret = 0;
1792
3.37k
    unsigned char pubKey[ED448_PUB_KEY_SIZE];
1793
1794
    /* Validate parameter. */
1795
3.37k
    if (key == NULL) {
1796
0
        ret = BAD_FUNC_ARG;
1797
0
    }
1798
1799
    /* Check we have a public key to check. */
1800
3.37k
    if (ret == 0 && !key->pubKeySet) {
1801
0
        ret = PUBLIC_KEY_E;
1802
0
    }
1803
1804
3.37k
#ifdef WOLF_CRYPTO_CB
1805
3.37k
    #ifndef WOLF_CRYPTO_CB_FIND
1806
3.37k
    if ((ret == 0) && (key->devId != INVALID_DEVID))
1807
    #else
1808
    if (ret == 0)
1809
    #endif
1810
0
    {
1811
0
        ret = wc_CryptoCb_Ed448CheckKey(key);
1812
0
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
1813
0
            return ret;
1814
0
        ret = 0;
1815
0
    }
1816
3.37k
#endif
1817
1818
    /* Reject small-order pub key before the priv-vs-pub compare so the
1819
     * diagnostic isn't masked by a "mismatch" error. */
1820
3.37k
    if ((ret == 0) && ed448_is_small_order(key->p)) {
1821
103
        WOLFSSL_MSG("Ed448 small-order public key rejected during key check");
1822
103
        ret = PUBLIC_KEY_E;
1823
103
    }
1824
1825
    /* If we have a private key just make the public key and compare. */
1826
3.37k
    if ((ret == 0) && key->privKeySet) {
1827
441
        ret = wc_ed448_make_public(key, pubKey, sizeof(pubKey));
1828
441
        if ((ret == 0) && (XMEMCMP(pubKey, key->p, ED448_PUB_KEY_SIZE) != 0)) {
1829
0
            ret = PUBLIC_KEY_E;
1830
0
        }
1831
441
    }
1832
    /* No private key, check Y is valid. */
1833
2.93k
    else if (ret == 0) {
1834
        /* Verify that xQ and yQ are integers in the interval [0, p - 1]. */
1835
2.83k
        if (!ed448_pub_y_in_range(key->p)) {
1836
106
            ret = PUBLIC_KEY_E;
1837
106
        }
1838
1839
2.83k
        if (ret == 0) {
1840
            /* Verify that Q is on the curve.
1841
             * Uncompressing the public key will validate yQ. */
1842
2.72k
            ge448_p2 A;
1843
1844
2.72k
            if (ge448_from_bytes_negate_vartime(&A, key->p) != 0) {
1845
64
                ret = PUBLIC_KEY_E;
1846
64
            }
1847
2.72k
        }
1848
2.83k
    }
1849
1850
3.37k
    return ret;
1851
3.37k
}
1852
1853
/* Returns the size of an ed448 private key.
1854
 *
1855
 * key     [in]      Ed448 private/public key.
1856
 * returns BAD_FUNC_ARG when key is NULL,
1857
 *         ED448_KEY_SIZE otherwise.
1858
 */
1859
int wc_ed448_size(const ed448_key* key)
1860
0
{
1861
0
    int ret = ED448_KEY_SIZE;
1862
1863
0
    if (key == NULL) {
1864
0
        ret = BAD_FUNC_ARG;
1865
0
    }
1866
1867
0
    return ret;
1868
0
}
1869
1870
/* Returns the size of an ed448 private plus public key.
1871
 *
1872
 * key     [in]      Ed448 private/public key.
1873
 * returns BAD_FUNC_ARG when key is NULL,
1874
 *         ED448_PRV_KEY_SIZE otherwise.
1875
 */
1876
int wc_ed448_priv_size(const ed448_key* key)
1877
0
{
1878
0
    int ret = ED448_PRV_KEY_SIZE;
1879
1880
0
    if (key == NULL) {
1881
0
        ret = BAD_FUNC_ARG;
1882
0
    }
1883
1884
0
    return ret;
1885
0
}
1886
1887
/* Returns the size of an ed448 public key.
1888
 *
1889
 * key     [in]      Ed448 private/public key.
1890
 * returns BAD_FUNC_ARG when key is NULL,
1891
 *         ED448_PUB_KEY_SIZE otherwise.
1892
 */
1893
int wc_ed448_pub_size(const ed448_key* key)
1894
0
{
1895
0
    int ret = ED448_PUB_KEY_SIZE;
1896
1897
0
    if (key == NULL) {
1898
0
        ret = BAD_FUNC_ARG;
1899
0
    }
1900
1901
0
    return ret;
1902
0
}
1903
1904
/* Returns the size of an ed448 signature.
1905
 *
1906
 * key     [in]      Ed448 private/public key.
1907
 * returns BAD_FUNC_ARG when key is NULL,
1908
 *         ED448_SIG_SIZE otherwise.
1909
 */
1910
int wc_ed448_sig_size(const ed448_key* key)
1911
0
{
1912
0
    int ret = ED448_SIG_SIZE;
1913
1914
0
    if (key == NULL) {
1915
0
        ret = BAD_FUNC_ARG;
1916
0
    }
1917
1918
0
    return ret;
1919
0
}
1920
1921
#endif /* HAVE_ED448 */
1922