Coverage Report

Created: 2022-08-24 06:37

/src/wolfssl-sp-math/wolfcrypt/src/ed25519.c
Line
Count
Source (jump to first uncovered line)
1
/* ed25519.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
23
 /* Based On Daniel J Bernstein's ed25519 Public Domain ref10 work. */
24
25
#ifdef HAVE_CONFIG_H
26
    #include <config.h>
27
#endif
28
29
/* in case user set HAVE_ED25519 there */
30
#include <wolfssl/wolfcrypt/settings.h>
31
32
#ifdef HAVE_ED25519
33
34
#include <wolfssl/wolfcrypt/ed25519.h>
35
#include <wolfssl/wolfcrypt/error-crypt.h>
36
#include <wolfssl/wolfcrypt/hash.h>
37
#ifdef NO_INLINE
38
    #include <wolfssl/wolfcrypt/misc.h>
39
#else
40
    #define WOLFSSL_MISC_INCLUDED
41
    #include <wolfcrypt/src/misc.c>
42
#endif
43
44
#ifdef FREESCALE_LTC_ECC
45
    #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
46
#endif
47
#ifdef WOLFSSL_SE050
48
    #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
49
#endif
50
51
#ifdef WOLF_CRYPTO_CB
52
    #include <wolfssl/wolfcrypt/cryptocb.h>
53
#endif
54
55
#if defined(HAVE_ED25519_SIGN) || defined(HAVE_ED25519_VERIFY)
56
0
#define ED25519CTX_SIZE    32
57
58
static const byte ed25519Ctx[ED25519CTX_SIZE+1] =
59
                                             "SigEd25519 no Ed25519 collisions";
60
#endif
61
62
static int ed25519_hash_init(ed25519_key* key, wc_Sha512 *sha)
63
7.54k
{
64
7.54k
    int ret;
65
66
7.54k
    ret = wc_InitSha512_ex(sha, key->heap,
67
7.54k
#if defined(WOLF_CRYPTO_CB)
68
7.54k
                           key->devId
69
#else
70
                           INVALID_DEVID
71
#endif
72
7.54k
        );
73
74
7.54k
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
75
7.54k
    if (ret == 0)
76
7.54k
        key->sha_clean_flag = 1;
77
7.54k
#endif
78
79
7.54k
    return ret;
80
7.54k
}
81
82
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
83
static int ed25519_hash_reset(ed25519_key* key)
84
11.0k
{
85
11.0k
    int ret;
86
11.0k
    if (key->sha_clean_flag)
87
11.0k
        ret = 0;
88
0
    else {
89
0
        wc_Sha512Free(&key->sha);
90
0
        ret = wc_InitSha512_ex(&key->sha, key->heap,
91
0
#if defined(WOLF_CRYPTO_CB)
92
0
                               key->devId
93
#else
94
                               INVALID_DEVID
95
#endif
96
0
            );
97
0
        if (ret == 0)
98
0
            key->sha_clean_flag = 1;
99
0
    }
100
11.0k
    return ret;
101
11.0k
}
102
#endif /* WOLFSSL_ED25519_PERSISTENT_SHA */
103
104
static int ed25519_hash_update(ed25519_key* key, wc_Sha512 *sha,
105
                               const byte* data, word32 len)
106
28.4k
{
107
28.4k
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
108
28.4k
    if (key->sha_clean_flag)
109
14.9k
        key->sha_clean_flag = 0;
110
#else
111
    (void)key;
112
#endif
113
28.4k
    return wc_Sha512Update(sha, data, len);
114
28.4k
}
115
116
static int ed25519_hash_final(ed25519_key* key, wc_Sha512 *sha, byte* hash)
117
14.3k
{
118
14.3k
    int ret = wc_Sha512Final(sha, hash);
119
14.3k
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
120
14.3k
    if (ret == 0)
121
13.5k
        key->sha_clean_flag = 1;
122
#else
123
    (void)key;
124
#endif
125
14.3k
    return ret;
126
14.3k
}
127
128
static void ed25519_hash_free(ed25519_key* key, wc_Sha512 *sha)
129
7.58k
{
130
7.58k
    wc_Sha512Free(sha);
131
7.58k
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
132
7.58k
    key->sha_clean_flag = 0;
133
#else
134
    (void)key;
135
#endif
136
7.58k
}
137
138
139
static int ed25519_hash(ed25519_key* key, const byte* in, word32 inLen,
140
    byte* hash)
141
7.76k
{
142
7.76k
    int ret;
143
#ifndef WOLFSSL_ED25519_PERSISTENT_SHA
144
    wc_Sha512 sha[1];
145
#else
146
7.76k
    wc_Sha512 *sha;
147
7.76k
#endif
148
149
7.76k
    if (key == NULL || (in == NULL && inLen > 0) || hash == NULL) {
150
0
        return BAD_FUNC_ARG;
151
0
    }
152
153
7.76k
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
154
7.76k
    sha = &key->sha;
155
7.76k
    ret = ed25519_hash_reset(key);
156
#else
157
    ret = ed25519_hash_init(key, sha);
158
#endif
159
7.76k
    if (ret < 0)
160
0
        return ret;
161
162
7.76k
    ret = ed25519_hash_update(key, sha, in, inLen);
163
7.76k
    if (ret == 0)
164
7.76k
        ret = ed25519_hash_final(key, sha, hash);
165
166
#ifndef WOLFSSL_ED25519_PERSISTENT_SHA
167
    ed25519_hash_free(key, sha);
168
#endif
169
170
7.76k
    return ret;
171
7.76k
}
172
173
int wc_ed25519_make_public(ed25519_key* key, unsigned char* pubKey,
174
                           word32 pubKeySz)
175
5.66k
{
176
5.66k
    int   ret = 0;
177
5.66k
    byte  az[ED25519_PRV_KEY_SIZE];
178
5.66k
#if !defined(FREESCALE_LTC_ECC)
179
5.66k
    ge_p3 A;
180
5.66k
#endif
181
182
5.66k
    if (key == NULL || pubKey == NULL || pubKeySz != ED25519_PUB_KEY_SIZE)
183
0
        ret = BAD_FUNC_ARG;
184
185
5.66k
    if (ret == 0)
186
5.66k
        ret = ed25519_hash(key, key->k, ED25519_KEY_SIZE, az);
187
5.66k
    if (ret == 0) {
188
        /* apply clamp */
189
5.16k
        az[0]  &= 248;
190
5.16k
        az[31] &= 63; /* same than az[31] &= 127 because of az[31] |= 64 */
191
5.16k
        az[31] |= 64;
192
193
    #ifdef FREESCALE_LTC_ECC
194
        ltc_pkha_ecc_point_t publicKey = {0};
195
        publicKey.X = key->pointX;
196
        publicKey.Y = key->pointY;
197
        LTC_PKHA_Ed25519_PointMul(LTC_PKHA_Ed25519_BasePoint(), az,
198
            ED25519_KEY_SIZE, &publicKey, kLTC_Ed25519 /* result on Ed25519 */);
199
        LTC_PKHA_Ed25519_Compress(&publicKey, pubKey);
200
    #else
201
5.16k
        ge_scalarmult_base(&A, az);
202
5.16k
        ge_p3_tobytes(pubKey, &A);
203
5.16k
    #endif
204
5.16k
    }
205
206
5.66k
    return ret;
207
5.66k
}
208
209
/* generate an ed25519 key pair.
210
 * returns 0 on success
211
 */
212
int wc_ed25519_make_key(WC_RNG* rng, int keySz, ed25519_key* key)
213
747
{
214
747
    int ret;
215
216
747
    if (rng == NULL || key == NULL)
217
0
        return BAD_FUNC_ARG;
218
219
    /* ed25519 has 32 byte key sizes */
220
747
    if (keySz != ED25519_KEY_SIZE)
221
0
        return BAD_FUNC_ARG;
222
223
747
#ifdef WOLF_CRYPTO_CB
224
747
    if (key->devId != INVALID_DEVID) {
225
0
        ret = wc_CryptoCb_Ed25519Gen(rng, keySz, key);
226
0
        if (ret != CRYPTOCB_UNAVAILABLE)
227
0
            return ret;
228
        /* fall-through when unavailable */
229
0
    }
230
747
#endif
231
232
747
    ret = wc_RNG_GenerateBlock(rng, key->k, ED25519_KEY_SIZE);
233
747
    if (ret != 0)
234
199
        return ret;
235
236
548
    ret = wc_ed25519_make_public(key, key->p, ED25519_PUB_KEY_SIZE);
237
548
    if (ret != 0) {
238
85
        ForceZero(key->k, ED25519_KEY_SIZE);
239
85
        return ret;
240
85
    }
241
242
    /* put public key after private key, on the same buffer */
243
463
    XMEMMOVE(key->k + ED25519_KEY_SIZE, key->p, ED25519_PUB_KEY_SIZE);
244
245
463
    key->privKeySet = 1;
246
463
    key->pubKeySet = 1;
247
248
463
    return ret;
249
548
}
250
251
252
#ifdef HAVE_ED25519_SIGN
253
/*
254
    in          contains the message to sign
255
    inLen       is the length of the message to sign
256
    out         is the buffer to write the signature
257
    outLen      [in/out] input size of out buf
258
                          output gets set as the final length of out
259
    key         is the ed25519 key to use when signing
260
    type        one of Ed25519, Ed25519ctx or Ed25519ph
261
    context     extra signing data
262
    contextLen  length of extra signing data
263
    return 0 on success
264
 */
265
int wc_ed25519_sign_msg_ex(const byte* in, word32 inLen, byte* out,
266
                            word32 *outLen, ed25519_key* key, byte type,
267
                            const byte* context, byte contextLen)
268
2.19k
{
269
2.19k
    int    ret;
270
#ifdef WOLFSSL_SE050
271
    (void)context;
272
    (void)contextLen;
273
    (void)type;
274
    ret = se050_ed25519_sign_msg(in, inLen, out, outLen, key);
275
#else
276
#ifdef FREESCALE_LTC_ECC
277
    byte   tempBuf[ED25519_PRV_KEY_SIZE];
278
    ltc_pkha_ecc_point_t ltcPoint = {0};
279
#else
280
2.19k
    ge_p3  R;
281
2.19k
#endif
282
2.19k
    byte   nonce[WC_SHA512_DIGEST_SIZE];
283
2.19k
    byte   hram[WC_SHA512_DIGEST_SIZE];
284
2.19k
    byte   az[ED25519_PRV_KEY_SIZE];
285
286
    /* sanity check on arguments */
287
2.19k
    if (in == NULL || out == NULL || outLen == NULL || key == NULL ||
288
2.19k
                                         (context == NULL && contextLen != 0)) {
289
85
        return BAD_FUNC_ARG;
290
85
    }
291
292
2.10k
#ifdef WOLF_CRYPTO_CB
293
2.10k
    if (key->devId != INVALID_DEVID) {
294
0
        ret = wc_CryptoCb_Ed25519Sign(in, inLen, out, outLen, key, type,
295
0
            context, contextLen);
296
0
        if (ret != CRYPTOCB_UNAVAILABLE)
297
0
            return ret;
298
        /* fall-through when unavailable */
299
0
    }
300
2.10k
#endif
301
302
2.10k
    if (!key->pubKeySet)
303
0
        return BAD_FUNC_ARG;
304
305
    /* check and set up out length */
306
2.10k
    if (*outLen < ED25519_SIG_SIZE) {
307
0
        *outLen = ED25519_SIG_SIZE;
308
0
        return BUFFER_E;
309
0
    }
310
2.10k
    *outLen = ED25519_SIG_SIZE;
311
312
    /* step 1: create nonce to use where nonce is r in
313
       r = H(h_b, ... ,h_2b-1,M) */
314
2.10k
    ret = ed25519_hash(key, key->k, ED25519_KEY_SIZE, az);
315
2.10k
    if (ret != 0)
316
68
        return ret;
317
318
    /* apply clamp */
319
2.03k
    az[0]  &= 248;
320
2.03k
    az[31] &= 63; /* same than az[31] &= 127 because of az[31] |= 64 */
321
2.03k
    az[31] |= 64;
322
323
2.03k
    {
324
2.03k
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
325
2.03k
        wc_Sha512 *sha = &key->sha;
326
#else
327
        wc_Sha512 sha[1];
328
        ret = ed25519_hash_init(key, sha);
329
        if (ret < 0)
330
            return ret;
331
#endif
332
333
2.03k
        if (type == Ed25519ctx || type == Ed25519ph) {
334
0
            ret = ed25519_hash_update(key, sha, ed25519Ctx, ED25519CTX_SIZE);
335
0
            if (ret == 0)
336
0
                ret = ed25519_hash_update(key, sha, &type, sizeof(type));
337
0
            if (ret == 0)
338
0
                ret = ed25519_hash_update(key, sha, &contextLen,
339
0
                                          sizeof(contextLen));
340
0
            if (ret == 0 && context != NULL)
341
0
                ret = ed25519_hash_update(key, sha, context, contextLen);
342
0
        }
343
2.03k
        if (ret == 0)
344
2.03k
            ret = ed25519_hash_update(key, sha, az + ED25519_KEY_SIZE,
345
2.03k
                                      ED25519_KEY_SIZE);
346
2.03k
        if (ret == 0)
347
2.03k
            ret = ed25519_hash_update(key, sha, in, inLen);
348
2.03k
        if (ret == 0)
349
1.97k
            ret = ed25519_hash_final(key, sha, nonce);
350
#ifndef WOLFSSL_ED25519_PERSISTENT_SHA
351
        ed25519_hash_free(key, sha);
352
#endif
353
2.03k
    }
354
355
2.03k
    if (ret != 0)
356
132
        return ret;
357
358
#ifdef FREESCALE_LTC_ECC
359
    ltcPoint.X = &tempBuf[0];
360
    ltcPoint.Y = &tempBuf[32];
361
    LTC_PKHA_sc_reduce(nonce);
362
    LTC_PKHA_Ed25519_PointMul(LTC_PKHA_Ed25519_BasePoint(), nonce,
363
           ED25519_KEY_SIZE, &ltcPoint, kLTC_Ed25519 /* result on Ed25519 */);
364
    LTC_PKHA_Ed25519_Compress(&ltcPoint, out);
365
#else
366
1.90k
    sc_reduce(nonce);
367
368
    /* step 2: computing R = rB where rB is the scalar multiplication of
369
       r and B */
370
1.90k
    ge_scalarmult_base(&R,nonce);
371
1.90k
    ge_p3_tobytes(out,&R);
372
1.90k
#endif
373
374
    /* step 3: hash R + public key + message getting H(R,A,M) then
375
       creating S = (r + H(R,A,M)a) mod l */
376
1.90k
    {
377
1.90k
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
378
1.90k
        wc_Sha512 *sha = &key->sha;
379
#else
380
        wc_Sha512 sha[1];
381
        ret = ed25519_hash_init(key, sha);
382
        if (ret < 0)
383
            return ret;
384
#endif
385
386
1.90k
        if (type == Ed25519ctx || type == Ed25519ph) {
387
0
            ret = ed25519_hash_update(key, sha, ed25519Ctx, ED25519CTX_SIZE);
388
0
            if (ret == 0)
389
0
                ret = ed25519_hash_update(key, sha, &type, sizeof(type));
390
0
            if (ret == 0)
391
0
                ret = ed25519_hash_update(key, sha, &contextLen,
392
0
                                          sizeof(contextLen));
393
0
            if (ret == 0 && context != NULL)
394
0
                ret = ed25519_hash_update(key, sha, context, contextLen);
395
0
        }
396
1.90k
        if (ret == 0)
397
1.90k
            ret = ed25519_hash_update(key, sha, out, ED25519_SIG_SIZE/2);
398
1.90k
        if (ret == 0)
399
1.90k
            ret = ed25519_hash_update(key, sha, key->p, ED25519_PUB_KEY_SIZE);
400
1.90k
        if (ret == 0)
401
1.90k
            ret = ed25519_hash_update(key, sha, in, inLen);
402
1.90k
        if (ret == 0)
403
1.86k
            ret = ed25519_hash_final(key, sha, hram);
404
#ifndef WOLFSSL_ED25519_PERSISTENT_SHA
405
        ed25519_hash_free(key, sha);
406
#endif
407
1.90k
    }
408
409
1.90k
    if (ret != 0)
410
103
        return ret;
411
412
#ifdef FREESCALE_LTC_ECC
413
    LTC_PKHA_sc_reduce(hram);
414
    LTC_PKHA_sc_muladd(out + (ED25519_SIG_SIZE/2), hram, az, nonce);
415
#else
416
1.80k
    sc_reduce(hram);
417
1.80k
    sc_muladd(out + (ED25519_SIG_SIZE/2), hram, az, nonce);
418
1.80k
#endif
419
1.80k
#endif /* WOLFSSL_SE050 */
420
1.80k
    return ret;
421
1.90k
}
422
423
/*
424
    in     contains the message to sign
425
    inLen  is the length of the message to sign
426
    out    is the buffer to write the signature
427
    outLen [in/out] input size of out buf
428
                     output gets set as the final length of out
429
    key    is the ed25519 key to use when signing
430
    return 0 on success
431
 */
432
int wc_ed25519_sign_msg(const byte* in, word32 inLen, byte* out,
433
                        word32 *outLen, ed25519_key* key)
434
2.19k
{
435
2.19k
    return wc_ed25519_sign_msg_ex(in, inLen, out, outLen, key, (byte)Ed25519,
436
2.19k
        NULL, 0);
437
2.19k
}
438
439
/*
440
    in          contains the message to sign
441
    inLen       is the length of the message to sign
442
    out         is the buffer to write the signature
443
    outLen      [in/out] input size of out buf
444
                          output gets set as the final length of out
445
    key         is the ed25519 key to use when signing
446
    context     extra signing data
447
    contextLen  length of extra signing data
448
    return 0 on success
449
 */
450
int wc_ed25519ctx_sign_msg(const byte* in, word32 inLen, byte* out,
451
                           word32 *outLen, ed25519_key* key,
452
                           const byte* context, byte contextLen)
453
0
{
454
0
    return wc_ed25519_sign_msg_ex(in, inLen, out, outLen, key, Ed25519ctx,
455
0
                                                           context, contextLen);
456
0
}
457
458
/*
459
    hash        contains the SHA-512 hash of the message to sign
460
    hashLen     is the length of the SHA-512 hash of the message to sign
461
    out         is the buffer to write the signature
462
    outLen      [in/out] input size of out buf
463
                          output gets set as the final length of out
464
    key         is the ed25519 key to use when signing
465
    context     extra signing data
466
    contextLen  length of extra signing data
467
    return 0 on success
468
 */
469
int wc_ed25519ph_sign_hash(const byte* hash, word32 hashLen, byte* out,
470
                           word32 *outLen, ed25519_key* key,
471
                           const byte* context, byte contextLen)
472
0
{
473
0
    return wc_ed25519_sign_msg_ex(hash, hashLen, out, outLen, key, Ed25519ph,
474
0
                                                           context, contextLen);
475
0
}
476
477
/*
478
    in          contains the message to sign
479
    inLen       is the length of the message to sign
480
    out         is the buffer to write the signature
481
    outLen      [in/out] input size of out buf
482
                          output gets set as the final length of out
483
    key         is the ed25519 key to use when signing
484
    context     extra signing data
485
    contextLen  length of extra signing data
486
    return 0 on success
487
 */
488
int wc_ed25519ph_sign_msg(const byte* in, word32 inLen, byte* out,
489
                          word32 *outLen, ed25519_key* key,
490
                          const byte* context, byte contextLen)
491
0
{
492
0
    int  ret;
493
0
    byte hash[WC_SHA512_DIGEST_SIZE];
494
495
0
    ret = ed25519_hash(key, in, inLen, hash);
496
0
    if (ret != 0)
497
0
        return ret;
498
499
0
    return wc_ed25519_sign_msg_ex(hash, sizeof(hash), out, outLen, key,
500
0
                                                Ed25519ph, context, contextLen);
501
0
}
502
#endif /* HAVE_ED25519_SIGN */
503
504
#ifdef HAVE_ED25519_VERIFY
505
#ifndef WOLFSSL_SE050
506
/*
507
   sig        is array of bytes containing the signature
508
   sigLen     is the length of sig byte array
509
   key        Ed25519 public key
510
   return     0 on success
511
   type       variant to use -- Ed25519, Ed25519ctx, or Ed25519ph
512
   context    extra signing data
513
   contextLen length of extra signing data
514
*/
515
static int ed25519_verify_msg_init_with_sha(const byte* sig, word32 sigLen,
516
                                            ed25519_key* key, wc_Sha512 *sha,
517
                                            byte type, const byte* context,
518
                                            byte contextLen)
519
3.40k
{
520
3.40k
    int ret;
521
522
    /* sanity check on arguments */
523
3.40k
    if (sig == NULL || key == NULL ||
524
3.40k
        (context == NULL && contextLen != 0)) {
525
0
        return BAD_FUNC_ARG;
526
0
    }
527
528
    /* check on basics needed to verify signature */
529
3.40k
    if (sigLen != ED25519_SIG_SIZE || (sig[ED25519_SIG_SIZE-1] & 224))
530
121
        return BAD_FUNC_ARG;
531
532
    /* find H(R,A,M) and store it as h */
533
534
3.28k
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
535
3.28k
    ret = ed25519_hash_reset(key);
536
3.28k
    if (ret != 0)
537
0
        return ret;
538
#else
539
    ret = 0;
540
#endif
541
542
3.28k
    if (type == Ed25519ctx || type == Ed25519ph) {
543
0
        ret = ed25519_hash_update(key, sha, ed25519Ctx, ED25519CTX_SIZE);
544
0
        if (ret == 0)
545
0
            ret = ed25519_hash_update(key, sha, &type, sizeof(type));
546
0
        if (ret == 0)
547
0
            ret = ed25519_hash_update(key, sha, &contextLen, sizeof(contextLen));
548
0
        if (ret == 0 && context != NULL)
549
0
            ret = ed25519_hash_update(key, sha, context, contextLen);
550
0
    }
551
3.28k
    if (ret == 0)
552
3.28k
        ret = ed25519_hash_update(key, sha, sig, ED25519_SIG_SIZE/2);
553
3.28k
    if (ret == 0)
554
3.28k
        ret = ed25519_hash_update(key, sha, key->p, ED25519_PUB_KEY_SIZE);
555
556
3.28k
    return ret;
557
3.28k
}
558
559
/*
560
   msgSegment     an array of bytes containing a message segment
561
   msgSegmentLen  length of msgSegment
562
   key            Ed25519 public key
563
   return         0 on success
564
*/
565
static int ed25519_verify_msg_update_with_sha(const byte* msgSegment,
566
                                              word32 msgSegmentLen,
567
                                              ed25519_key* key,
568
4.49k
                                              wc_Sha512 *sha) {
569
    /* sanity check on arguments */
570
4.49k
    if (msgSegment == NULL || key == NULL)
571
160
        return BAD_FUNC_ARG;
572
573
4.33k
    return ed25519_hash_update(key, sha, msgSegment, msgSegmentLen);
574
4.49k
}
575
576
/* Low part of order in big endian. */
577
static const byte ed25519_low_order[] = {
578
    0x14, 0xde, 0xf9, 0xde, 0xa2, 0xf7, 0x9c, 0xd6,
579
    0x58, 0x12, 0x63, 0x1a, 0x5c, 0xf5, 0xd3, 0xed
580
};
581
582
#define ED25519_SIG_LOW_ORDER_IDX \
583
1.03k
    ((int)(ED25519_SIG_SIZE/2 + sizeof(ed25519_low_order) - 1))
584
585
/*
586
   sig     is array of bytes containing the signature
587
   sigLen  is the length of sig byte array
588
   res     will be 1 on successful verify and 0 on unsuccessful
589
   key     Ed25519 public key
590
   return  0 and res of 1 on success
591
*/
592
static int ed25519_verify_msg_final_with_sha(const byte* sig, word32 sigLen,
593
                                             int* res, ed25519_key* key,
594
                                             wc_Sha512 *sha)
595
2.99k
{
596
2.99k
    byte   rcheck[ED25519_KEY_SIZE];
597
2.99k
    byte   h[WC_SHA512_DIGEST_SIZE];
598
2.99k
#ifndef FREESCALE_LTC_ECC
599
2.99k
    ge_p3  A;
600
2.99k
    ge_p2  R;
601
2.99k
#endif
602
2.99k
    int    ret;
603
604
    /* sanity check on arguments */
605
2.99k
    if (sig == NULL || res == NULL || key == NULL)
606
0
        return BAD_FUNC_ARG;
607
608
    /* set verification failed by default */
609
2.99k
    *res = 0;
610
611
    /* check on basics needed to verify signature */
612
2.99k
    if (sigLen != ED25519_SIG_SIZE)
613
0
        return BAD_FUNC_ARG;
614
    /* S is not larger or equal to the order:
615
     *     2^252 + 0x14def9dea2f79cd65812631a5cf5d3ed
616
     *   = 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed
617
     */
618
2.99k
    if (sig[ED25519_SIG_SIZE-1] > 0x10)
619
98
        return BAD_FUNC_ARG;
620
2.89k
    if (sig[ED25519_SIG_SIZE-1] == 0x10) {
621
153
        int i = ED25519_SIG_SIZE-1;
622
153
        int j;
623
624
        /* Check high zeros. */
625
878
        for (--i; i > ED25519_SIG_LOW_ORDER_IDX; i--) {
626
832
            if (sig[i] > 0x00)
627
107
                break;
628
832
        }
629
        /* Did we see all zeros up to lower order index? */
630
153
        if (i == ED25519_SIG_LOW_ORDER_IDX) {
631
            /* Check lower part. */
632
46
            for (j = 0; j < (int)sizeof(ed25519_low_order); j++, i--) {
633
                /* Check smaller. */
634
46
                if (sig[i] < ed25519_low_order[j])
635
46
                    break;
636
                /* Check bigger. */
637
0
                if (sig[i] > ed25519_low_order[j])
638
0
                    return BAD_FUNC_ARG;
639
0
            }
640
            /* Check equal - all bytes match. */
641
46
            if (i == ED25519_SIG_SIZE/2 - 1)
642
0
                return BAD_FUNC_ARG;
643
46
        }
644
153
    }
645
646
    /* uncompress A (public key), test if valid, and negate it */
647
2.89k
#ifndef FREESCALE_LTC_ECC
648
2.89k
    if (ge_frombytes_negate_vartime(&A, key->p) != 0)
649
86
        return BAD_FUNC_ARG;
650
2.81k
#endif
651
652
    /* find H(R,A,M) and store it as h */
653
654
2.81k
    ret = ed25519_hash_final(key, sha, h);
655
2.81k
    if (ret != 0)
656
161
        return ret;
657
658
#ifdef FREESCALE_LTC_ECC
659
    ret = LTC_PKHA_sc_reduce(h);
660
    if (ret != kStatus_Success)
661
        return ret;
662
    ret = LTC_PKHA_SignatureForVerify(rcheck, h, sig + (ED25519_SIG_SIZE/2), key);
663
    if (ret != kStatus_Success)
664
        return ret;
665
#else
666
2.64k
    sc_reduce(h);
667
668
    /*
669
       Uses a fast single-signature verification SB = R + H(R,A,M)A becomes
670
       SB - H(R,A,M)A saving decompression of R
671
    */
672
2.64k
    ret = ge_double_scalarmult_vartime(&R, h, &A, sig + (ED25519_SIG_SIZE/2));
673
2.64k
    if (ret != 0)
674
356
        return ret;
675
676
2.29k
    ge_tobytes(rcheck, &R);
677
2.29k
#endif /* FREESCALE_LTC_ECC */
678
679
    /* comparison of R created to R in sig */
680
2.29k
    ret = ConstantCompare(rcheck, sig, ED25519_SIG_SIZE/2);
681
2.29k
    if (ret != 0) {
682
663
        ret = SIG_VERIFY_E;
683
1.63k
    } else {
684
        /* set the verification status */
685
1.63k
        *res = 1;
686
1.63k
    }
687
688
2.29k
    return ret;
689
2.64k
}
690
#endif /* WOLFSSL_SE050 */
691
692
#ifdef WOLFSSL_ED25519_STREAMING_VERIFY
693
694
int wc_ed25519_verify_msg_init(const byte* sig, word32 sigLen, ed25519_key* key,
695
713
                               byte type, const byte* context, byte contextLen) {
696
713
    return ed25519_verify_msg_init_with_sha(sig, sigLen, key, &key->sha,
697
713
                                        type, context, contextLen);
698
713
}
699
700
int wc_ed25519_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen,
701
1.86k
                                        ed25519_key* key) {
702
1.86k
    return ed25519_verify_msg_update_with_sha(msgSegment, msgSegmentLen,
703
1.86k
                                          key, &key->sha);
704
1.86k
}
705
706
int wc_ed25519_verify_msg_final(const byte* sig, word32 sigLen, int* res,
707
409
                                ed25519_key* key) {
708
409
    return ed25519_verify_msg_final_with_sha(sig, sigLen, res,
709
409
                                         key, &key->sha);
710
409
}
711
712
#endif /* WOLFSSL_ED25519_STREAMING_VERIFY */
713
714
/*
715
   sig     is array of bytes containing the signature
716
   sigLen  is the length of sig byte array
717
   msg     the array of bytes containing the message
718
   msgLen  length of msg array
719
   res     will be 1 on successful verify and 0 on unsuccessful
720
   key     Ed25519 public key
721
   return  0 and res of 1 on success
722
*/
723
int wc_ed25519_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg,
724
                              word32 msgLen, int* res, ed25519_key* key,
725
                              byte type, const byte* context, byte contextLen)
726
2.74k
{
727
2.74k
    int ret;
728
#ifdef WOLFSSL_SE050
729
    (void)type;
730
    (void)context;
731
    (void)contextLen;
732
    (void)ed25519Ctx;
733
    ret = se050_ed25519_verify_msg(sig, sigLen, msg, msgLen, key, res);
734
#else
735
2.74k
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
736
2.74k
    wc_Sha512 *sha;
737
#else
738
    wc_Sha512 sha[1];
739
#endif
740
741
    /* sanity check on arguments */
742
2.74k
    if (sig == NULL || msg == NULL || res == NULL || key == NULL ||
743
2.74k
                                         (context == NULL && contextLen != 0))
744
55
        return BAD_FUNC_ARG;
745
746
2.69k
#ifdef WOLF_CRYPTO_CB
747
2.69k
    if (key->devId != INVALID_DEVID) {
748
0
        ret = wc_CryptoCb_Ed25519Verify(sig, sigLen, msg, msgLen, res, key,
749
0
            type, context, contextLen);
750
0
        if (ret != CRYPTOCB_UNAVAILABLE)
751
0
            return ret;
752
        /* fall-through when unavailable */
753
0
    }
754
2.69k
#endif
755
756
2.69k
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
757
2.69k
    sha = &key->sha;
758
#else
759
    ret = ed25519_hash_init(key, sha);
760
    if (ret < 0)
761
        return ret;
762
#endif
763
764
2.69k
    ret = ed25519_verify_msg_init_with_sha(sig, sigLen, key, sha, type, context,
765
2.69k
        contextLen);
766
2.69k
    if (ret == 0)
767
2.63k
        ret = ed25519_verify_msg_update_with_sha(msg, msgLen, key, sha);
768
2.69k
    if (ret == 0)
769
2.58k
        ret = ed25519_verify_msg_final_with_sha(sig, sigLen, res, key, sha);
770
771
#ifndef WOLFSSL_ED25519_PERSISTENT_SHA
772
    ed25519_hash_free(key, sha);
773
#endif
774
2.69k
#endif /* WOLFSSL_SE050 */
775
2.69k
    return ret;
776
2.69k
}
777
778
/*
779
   sig     is array of bytes containing the signature
780
   sigLen  is the length of sig byte array
781
   msg     the array of bytes containing the message
782
   msgLen  length of msg array
783
   res     will be 1 on successful verify and 0 on unsuccessful
784
   key     Ed25519 public key
785
   return  0 and res of 1 on success
786
*/
787
int wc_ed25519_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
788
                          word32 msgLen, int* res, ed25519_key* key)
789
2.74k
{
790
2.74k
    return wc_ed25519_verify_msg_ex(sig, sigLen, msg, msgLen, res, key,
791
2.74k
                                    (byte)Ed25519, NULL, 0);
792
2.74k
}
793
794
/*
795
   sig         is array of bytes containing the signature
796
   sigLen      is the length of sig byte array
797
   msg         the array of bytes containing the message
798
   msgLen      length of msg array
799
   res         will be 1 on successful verify and 0 on unsuccessful
800
   key         Ed25519 public key
801
   context     extra signing data
802
   contextLen  length of extra signing data
803
   return  0 and res of 1 on success
804
*/
805
int wc_ed25519ctx_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
806
                             word32 msgLen, int* res, ed25519_key* key,
807
                             const byte* context, byte contextLen)
808
0
{
809
0
    return wc_ed25519_verify_msg_ex(sig, sigLen, msg, msgLen, res, key,
810
0
                                    Ed25519ctx, context, contextLen);
811
0
}
812
813
/*
814
   sig         is array of bytes containing the signature
815
   sigLen      is the length of sig byte array
816
   hash        the array of bytes containing the SHA-512 hash of the message
817
   hashLen     length of hash array
818
   res         will be 1 on successful verify and 0 on unsuccessful
819
   key         Ed25519 public key
820
   context     extra signing data
821
   contextLen  length of extra signing data
822
   return  0 and res of 1 on success
823
*/
824
int wc_ed25519ph_verify_hash(const byte* sig, word32 sigLen, const byte* hash,
825
                             word32 hashLen, int* res, ed25519_key* key,
826
                             const byte* context, byte contextLen)
827
0
{
828
0
    return wc_ed25519_verify_msg_ex(sig, sigLen, hash, hashLen, res, key,
829
0
                                    Ed25519ph, context, contextLen);
830
0
}
831
832
/*
833
   sig         is array of bytes containing the signature
834
   sigLen      is the length of sig byte array
835
   msg         the array of bytes containing the message
836
   msgLen      length of msg array
837
   res         will be 1 on successful verify and 0 on unsuccessful
838
   key         Ed25519 public key
839
   context     extra signing data
840
   contextLen  length of extra signing data
841
   return  0 and res of 1 on success
842
*/
843
int wc_ed25519ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
844
                            word32 msgLen, int* res, ed25519_key* key,
845
                            const byte* context, byte contextLen)
846
0
{
847
0
    int  ret;
848
0
    byte hash[WC_SHA512_DIGEST_SIZE];
849
850
0
    ret = ed25519_hash(key, msg, msgLen, hash);
851
0
    if (ret != 0)
852
0
        return ret;
853
854
0
    return wc_ed25519_verify_msg_ex(sig, sigLen, hash, sizeof(hash), res, key,
855
0
                                    Ed25519ph, context, contextLen);
856
0
}
857
#endif /* HAVE_ED25519_VERIFY */
858
859
860
/* initialize information and memory for key */
861
int wc_ed25519_init_ex(ed25519_key* key, void* heap, int devId)
862
7.65k
{
863
7.65k
    if (key == NULL)
864
0
        return BAD_FUNC_ARG;
865
866
7.65k
    XMEMSET(key, 0, sizeof(ed25519_key));
867
7.65k
#ifdef WOLF_CRYPTO_CB
868
7.65k
    key->devId = devId;
869
#else
870
    (void)devId;
871
#endif
872
7.65k
    key->heap = heap;
873
874
7.65k
#ifndef FREESCALE_LTC_ECC
875
7.65k
    fe_init();
876
7.65k
#endif
877
878
#ifdef WOLFSSL_CHECK_MEM_ZERO
879
    wc_MemZero_Add("wc_ed25519_init_ex key->k", &key->k, sizeof(key->k));
880
#endif
881
882
7.65k
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
883
7.65k
    return ed25519_hash_init(key, &key->sha);
884
#else /* !WOLFSSL_ED25519_PERSISTENT_SHA */
885
    return 0;
886
#endif /* WOLFSSL_ED25519_PERSISTENT_SHA */
887
7.65k
}
888
889
int wc_ed25519_init(ed25519_key* key)
890
7.65k
{
891
7.65k
    return wc_ed25519_init_ex(key, NULL, INVALID_DEVID);
892
7.65k
}
893
894
/* clear memory of key */
895
void wc_ed25519_free(ed25519_key* key)
896
7.65k
{
897
7.65k
    if (key == NULL)
898
0
        return;
899
900
7.65k
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
901
7.65k
    ed25519_hash_free(key, &key->sha);
902
7.65k
#endif
903
904
#ifdef WOLFSSL_SE050
905
    se050_ed25519_free_key(key);
906
#endif
907
908
7.65k
    ForceZero(key, sizeof(ed25519_key));
909
#ifdef WOLFSSL_CHECK_MEM_ZERO
910
    wc_MemZero_Check(key, sizeof(ed25519_key));
911
#endif
912
7.65k
}
913
914
915
#ifdef HAVE_ED25519_KEY_EXPORT
916
917
/*
918
    outLen should contain the size of out buffer when input. outLen is than set
919
    to the final output length.
920
    returns 0 on success
921
 */
922
int wc_ed25519_export_public(ed25519_key* key, byte* out, word32* outLen)
923
233
{
924
    /* sanity check on arguments */
925
233
    if (key == NULL || out == NULL || outLen == NULL)
926
88
        return BAD_FUNC_ARG;
927
928
145
    if (*outLen < ED25519_PUB_KEY_SIZE) {
929
17
        *outLen = ED25519_PUB_KEY_SIZE;
930
17
        return BUFFER_E;
931
17
    }
932
933
128
    *outLen = ED25519_PUB_KEY_SIZE;
934
128
    XMEMCPY(out, key->p, ED25519_PUB_KEY_SIZE);
935
936
128
    return 0;
937
145
}
938
939
#endif /* HAVE_ED25519_KEY_EXPORT */
940
941
942
#ifdef HAVE_ED25519_KEY_IMPORT
943
/*
944
    Imports a compressed/uncompressed public key.
945
    in       the byte array containing the public key
946
    inLen    the length of the byte array being passed in
947
    key      ed25519 key struct to put the public key in
948
    trusted  whether the public key is trusted to match private key if set
949
 */
950
int wc_ed25519_import_public_ex(const byte* in, word32 inLen, ed25519_key* key,
951
    int trusted)
952
85
{
953
85
    int ret = 0;
954
955
    /* sanity check on arguments */
956
85
    if (in == NULL || key == NULL)
957
0
        return BAD_FUNC_ARG;
958
959
85
    if (inLen < ED25519_PUB_KEY_SIZE)
960
9
        return BAD_FUNC_ARG;
961
962
    /* compressed prefix according to draft
963
       http://www.ietf.org/id/draft-koch-eddsa-for-openpgp-02.txt */
964
76
    if (in[0] == 0x40 && inLen == ED25519_PUB_KEY_SIZE + 1) {
965
        /* key is stored in compressed format so just copy in */
966
1
        XMEMCPY(key->p, (in + 1), ED25519_PUB_KEY_SIZE);
967
#ifdef FREESCALE_LTC_ECC
968
        /* recover X coordinate */
969
        ltc_pkha_ecc_point_t pubKey;
970
        pubKey.X = key->pointX;
971
        pubKey.Y = key->pointY;
972
        LTC_PKHA_Ed25519_PointDecompress(key->p, ED25519_PUB_KEY_SIZE, &pubKey);
973
#endif
974
1
    }
975
    /* importing uncompressed public key */
976
75
    else if (in[0] == 0x04 && inLen > 2*ED25519_PUB_KEY_SIZE) {
977
#ifdef FREESCALE_LTC_ECC
978
        /* reverse bytes for little endian byte order */
979
        for (int i = 0; i < ED25519_KEY_SIZE; i++)
980
        {
981
            key->pointX[i] = *(in + ED25519_KEY_SIZE - i);
982
            key->pointY[i] = *(in + 2*ED25519_KEY_SIZE - i);
983
        }
984
        XMEMCPY(key->p, key->pointY, ED25519_KEY_SIZE);
985
#else
986
        /* pass in (x,y) and store compressed key */
987
14
        ret = ge_compress_key(key->p, in+1,
988
14
                              in+1+ED25519_PUB_KEY_SIZE, ED25519_PUB_KEY_SIZE);
989
14
#endif /* FREESCALE_LTC_ECC */
990
14
    }
991
    /* if not specified compressed or uncompressed check key size
992
       if key size is equal to compressed key size copy in key */
993
61
    else if (inLen == ED25519_PUB_KEY_SIZE) {
994
16
        XMEMCPY(key->p, in, ED25519_PUB_KEY_SIZE);
995
#ifdef FREESCALE_LTC_ECC
996
        /* recover X coordinate */
997
        ltc_pkha_ecc_point_t pubKey;
998
        pubKey.X = key->pointX;
999
        pubKey.Y = key->pointY;
1000
        LTC_PKHA_Ed25519_PointDecompress(key->p, ED25519_PUB_KEY_SIZE, &pubKey);
1001
#endif
1002
16
    }
1003
45
    else {
1004
45
        ret = BAD_FUNC_ARG;
1005
45
    }
1006
1007
76
    if (ret == 0) {
1008
31
        key->pubKeySet = 1;
1009
31
        if (key->privKeySet && (!trusted)) {
1010
0
            ret = wc_ed25519_check_key(key);
1011
0
        }
1012
31
    }
1013
76
    if (ret != 0) {
1014
45
        key->pubKeySet = 0;
1015
45
    }
1016
1017
    /* bad public key format */
1018
76
    return ret;
1019
85
}
1020
1021
/*
1022
    Imports a compressed/uncompressed public key.
1023
    in    the byte array containing the public key
1024
    inLen the length of the byte array being passed in
1025
    key   ed25519 key struct to put the public key in
1026
 */
1027
int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key)
1028
85
{
1029
85
    return wc_ed25519_import_public_ex(in, inLen, key, 0);
1030
85
}
1031
1032
/*
1033
    For importing a private key.
1034
 */
1035
int wc_ed25519_import_private_only(const byte* priv, word32 privSz,
1036
                                                               ed25519_key* key)
1037
25
{
1038
25
    int ret = 0;
1039
1040
    /* sanity check on arguments */
1041
25
    if (priv == NULL || key == NULL)
1042
0
        return BAD_FUNC_ARG;
1043
1044
    /* key size check */
1045
25
    if (privSz != ED25519_KEY_SIZE)
1046
24
        return BAD_FUNC_ARG;
1047
1048
1
    XMEMCPY(key->k, priv, ED25519_KEY_SIZE);
1049
1
    key->privKeySet = 1;
1050
1051
1
    if (key->pubKeySet) {
1052
        /* Validate loaded public key */
1053
0
        ret = wc_ed25519_check_key(key);
1054
0
    }
1055
1
    if (ret != 0) {
1056
0
        key->privKeySet = 0;
1057
0
        ForceZero(key->k, ED25519_KEY_SIZE);
1058
0
    }
1059
1060
1
    return ret;
1061
25
}
1062
1063
1064
/* Import an ed25519 private and public keys from byte array(s).
1065
 *
1066
 * priv     [in]  Array holding private key from
1067
 *                wc_ed25519_export_private_only(), or private+public keys from
1068
 *                wc_ed25519_export_private().
1069
 * privSz   [in]  Number of bytes of data in private key array.
1070
 * pub      [in]  Array holding public key (or NULL).
1071
 * pubSz    [in]  Number of bytes of data in public key array (or 0).
1072
 * key      [in]  Ed25519 private/public key.
1073
 * trusted  [in]  Indicates whether the public key data is trusted.
1074
 *                When 0, checks public key matches private key.
1075
 *                When 1, doesn't check public key matches private key.
1076
 * returns BAD_FUNC_ARG when a required parameter is NULL or an invalid
1077
 *         combination of keys/lengths is supplied, 0 otherwise.
1078
 */
1079
int wc_ed25519_import_private_key_ex(const byte* priv, word32 privSz,
1080
    const byte* pub, word32 pubSz, ed25519_key* key, int trusted)
1081
0
{
1082
0
    int ret;
1083
1084
    /* sanity check on arguments */
1085
0
    if (priv == NULL || key == NULL)
1086
0
        return BAD_FUNC_ARG;
1087
1088
    /* key size check */
1089
0
    if (privSz != ED25519_KEY_SIZE && privSz != ED25519_PRV_KEY_SIZE)
1090
0
        return BAD_FUNC_ARG;
1091
1092
0
    if (pub == NULL) {
1093
0
        if (pubSz != 0)
1094
0
            return BAD_FUNC_ARG;
1095
0
        if (privSz != ED25519_PRV_KEY_SIZE)
1096
0
            return BAD_FUNC_ARG;
1097
0
        pub = priv + ED25519_KEY_SIZE;
1098
0
        pubSz = ED25519_PUB_KEY_SIZE;
1099
0
    }
1100
0
    else if (pubSz < ED25519_PUB_KEY_SIZE) {
1101
0
        return BAD_FUNC_ARG;
1102
0
    }
1103
1104
0
    XMEMCPY(key->k, priv, ED25519_KEY_SIZE);
1105
0
    key->privKeySet = 1;
1106
1107
    /* import public key */
1108
0
    ret = wc_ed25519_import_public_ex(pub, pubSz, key, trusted);
1109
0
    if (ret != 0) {
1110
0
        key->privKeySet = 0;
1111
0
        ForceZero(key->k, ED25519_KEY_SIZE);
1112
0
        return ret;
1113
0
    }
1114
1115
    /* make the private key (priv + pub) */
1116
0
    XMEMCPY(key->k + ED25519_KEY_SIZE, key->p, ED25519_PUB_KEY_SIZE);
1117
1118
0
    return ret;
1119
0
}
1120
1121
/* Import an ed25519 private and public keys from byte array(s).
1122
 *
1123
 * priv    [in]  Array holding private key from wc_ed25519_export_private_only(),
1124
 *               or private+public keys from wc_ed25519_export_private().
1125
 * privSz  [in]  Number of bytes of data in private key array.
1126
 * pub     [in]  Array holding public key (or NULL).
1127
 * pubSz   [in]  Number of bytes of data in public key array (or 0).
1128
 * key     [in]  Ed25519 private/public key.
1129
 * returns BAD_FUNC_ARG when a required parameter is NULL or an invalid
1130
 *         combination of keys/lengths is supplied, 0 otherwise.
1131
 */
1132
int wc_ed25519_import_private_key(const byte* priv, word32 privSz,
1133
    const byte* pub, word32 pubSz, ed25519_key* key)
1134
0
{
1135
0
    return wc_ed25519_import_private_key_ex(priv, privSz, pub, pubSz, key, 0);
1136
0
}
1137
#endif /* HAVE_ED25519_KEY_IMPORT */
1138
1139
1140
#ifdef HAVE_ED25519_KEY_EXPORT
1141
1142
/*
1143
 export private key only (secret part so 32 bytes)
1144
 outLen should contain the size of out buffer when input. outLen is than set
1145
 to the final output length.
1146
 returns 0 on success
1147
 */
1148
int wc_ed25519_export_private_only(ed25519_key* key, byte* out, word32* outLen)
1149
463
{
1150
    /* sanity checks on arguments */
1151
463
    if (key == NULL || out == NULL || outLen == NULL)
1152
123
        return BAD_FUNC_ARG;
1153
1154
340
    if (*outLen < ED25519_KEY_SIZE) {
1155
58
        *outLen = ED25519_KEY_SIZE;
1156
58
        return BUFFER_E;
1157
58
    }
1158
1159
282
    *outLen = ED25519_KEY_SIZE;
1160
282
    XMEMCPY(out, key->k, ED25519_KEY_SIZE);
1161
1162
282
    return 0;
1163
340
}
1164
1165
/*
1166
 export private key, including public part
1167
 outLen should contain the size of out buffer when input. outLen is than set
1168
 to the final output length.
1169
 returns 0 on success
1170
 */
1171
int wc_ed25519_export_private(ed25519_key* key, byte* out, word32* outLen)
1172
0
{
1173
    /* sanity checks on arguments */
1174
0
    if (key == NULL || out == NULL || outLen == NULL)
1175
0
        return BAD_FUNC_ARG;
1176
1177
0
    if (*outLen < ED25519_PRV_KEY_SIZE) {
1178
0
        *outLen = ED25519_PRV_KEY_SIZE;
1179
0
        return BUFFER_E;
1180
0
    }
1181
1182
0
    *outLen = ED25519_PRV_KEY_SIZE;
1183
0
    XMEMCPY(out, key->k, ED25519_PRV_KEY_SIZE);
1184
1185
0
    return 0;
1186
0
}
1187
1188
/* export full private key and public key
1189
   return 0 on success
1190
 */
1191
int wc_ed25519_export_key(ed25519_key* key,
1192
                          byte* priv, word32 *privSz,
1193
                          byte* pub, word32 *pubSz)
1194
0
{
1195
0
    int ret;
1196
1197
    /* export 'full' private part */
1198
0
    ret = wc_ed25519_export_private(key, priv, privSz);
1199
0
    if (ret != 0)
1200
0
        return ret;
1201
1202
    /* export public part */
1203
0
    ret = wc_ed25519_export_public(key, pub, pubSz);
1204
1205
0
    return ret;
1206
0
}
1207
1208
#endif /* HAVE_ED25519_KEY_EXPORT */
1209
1210
/* check the private and public keys match */
1211
int wc_ed25519_check_key(ed25519_key* key)
1212
775
{
1213
775
    int ret = 0;
1214
775
    unsigned char pubKey[ED25519_PUB_KEY_SIZE];
1215
1216
775
    if (!key->pubKeySet)
1217
0
        ret = PUBLIC_KEY_E;
1218
775
    if (ret == 0)
1219
775
        ret = wc_ed25519_make_public(key, pubKey, sizeof(pubKey));
1220
775
    if (ret == 0 && XMEMCMP(pubKey, key->p, ED25519_PUB_KEY_SIZE) != 0)
1221
204
        ret = PUBLIC_KEY_E;
1222
1223
775
    return ret;
1224
775
}
1225
1226
/* returns the private key size (secret only) in bytes */
1227
int wc_ed25519_size(ed25519_key* key)
1228
0
{
1229
0
    if (key == NULL)
1230
0
        return BAD_FUNC_ARG;
1231
1232
0
    return ED25519_KEY_SIZE;
1233
0
}
1234
1235
/* returns the private key size (secret + public) in bytes */
1236
int wc_ed25519_priv_size(ed25519_key* key)
1237
0
{
1238
0
    if (key == NULL)
1239
0
        return BAD_FUNC_ARG;
1240
1241
0
    return ED25519_PRV_KEY_SIZE;
1242
0
}
1243
1244
/* returns the compressed key size in bytes (public key) */
1245
int wc_ed25519_pub_size(ed25519_key* key)
1246
0
{
1247
0
    if (key == NULL)
1248
0
        return BAD_FUNC_ARG;
1249
1250
0
    return ED25519_PUB_KEY_SIZE;
1251
0
}
1252
1253
/* returns the size of signature in bytes */
1254
int wc_ed25519_sig_size(ed25519_key* key)
1255
0
{
1256
0
    if (key == NULL)
1257
0
        return BAD_FUNC_ARG;
1258
1259
0
    return ED25519_SIG_SIZE;
1260
0
}
1261
1262
#endif /* HAVE_ED25519 */