Coverage Report

Created: 2022-08-24 06:37

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