Coverage Report

Created: 2026-08-15 06:21

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