Coverage Report

Created: 2025-07-23 06:59

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