Coverage Report

Created: 2022-08-24 06:28

/src/wolfssl-disable-fastmath/wolfcrypt/src/curve25519.c
Line
Count
Source (jump to first uncovered line)
1
/* curve25519.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 curve25519 Public Domain ref10 work. */
24
25
26
#ifdef HAVE_CONFIG_H
27
    #include <config.h>
28
#endif
29
30
#include <wolfssl/wolfcrypt/settings.h>
31
32
#ifdef HAVE_CURVE25519
33
34
#include <wolfssl/wolfcrypt/curve25519.h>
35
#include <wolfssl/wolfcrypt/error-crypt.h>
36
#ifdef NO_INLINE
37
    #include <wolfssl/wolfcrypt/misc.h>
38
#else
39
    #define WOLFSSL_MISC_INCLUDED
40
    #include <wolfcrypt/src/misc.c>
41
#endif
42
43
#if defined(FREESCALE_LTC_ECC)
44
    #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
45
#endif
46
#ifdef WOLFSSL_SE050
47
    #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
48
#endif
49
50
#ifdef WOLF_CRYPTO_CB
51
    #include <wolfssl/wolfcrypt/cryptocb.h>
52
#endif
53
54
const curve25519_set_type curve25519_sets[] = {
55
    {
56
        CURVE25519_KEYSIZE,
57
        "CURVE25519",
58
    }
59
};
60
61
static const unsigned char kCurve25519BasePoint[CURVE25519_KEYSIZE] = {9};
62
63
/* Curve25519 private key must be less than order */
64
/* These functions clamp private k and check it */
65
static WC_INLINE int curve25519_priv_clamp(byte* priv)
66
145
{
67
145
    priv[0]  &= 248;
68
145
    priv[CURVE25519_KEYSIZE-1] &= 127;
69
145
    priv[CURVE25519_KEYSIZE-1] |= 64;
70
145
    return 0;
71
145
}
72
static WC_INLINE int curve25519_priv_clamp_check(const byte* priv)
73
246
{
74
    /* check that private part of key has been clamped */
75
246
    int ret = 0;
76
246
    if ((priv[0] & ~248) ||
77
246
        (priv[CURVE25519_KEYSIZE-1] & 128)) {
78
0
        ret = ECC_BAD_ARG_E;
79
0
    }
80
246
    return ret;
81
246
}
82
83
static WC_INLINE void curve25519_copy_point(byte* out, const byte* point,
84
    int endian)
85
126
{
86
126
    int i;
87
126
    if (endian == EC25519_BIG_ENDIAN) {
88
        /* put shared secret key in Big Endian format */
89
0
        for (i = 0; i < CURVE25519_KEYSIZE; i++) {
90
0
            out[i] = point[CURVE25519_KEYSIZE - i -1];
91
0
        }
92
0
    }
93
126
    else { /* put shared secret key in Little Endian format */
94
126
        XMEMCPY(out, point, CURVE25519_KEYSIZE);
95
126
    }
96
126
}
97
98
/* compute the public key from an existing private key, using bare vectors.
99
 *
100
 * return value is propagated from curve25519() (0 on success), or
101
 * ECC_BAD_ARG_E, and the byte vectors are little endian.
102
 */
103
int wc_curve25519_make_pub(int public_size, byte* pub, int private_size,
104
                           const byte* priv)
105
246
{
106
246
    int ret;
107
#ifdef FREESCALE_LTC_ECC
108
    const ECPoint* basepoint = nxp_ltc_curve25519_GetBasePoint();
109
    ECPoint wc_pub;
110
#endif
111
112
246
    if ( (public_size != CURVE25519_KEYSIZE) ||
113
246
        (private_size != CURVE25519_KEYSIZE)) {
114
0
        return ECC_BAD_ARG_E;
115
0
    }
116
246
    if ((pub == NULL) || (priv == NULL)) {
117
0
        return ECC_BAD_ARG_E;
118
0
    }
119
120
    /* check clamping */
121
246
    ret = curve25519_priv_clamp_check(priv);
122
246
    if (ret != 0)
123
0
        return ret;
124
125
#ifdef FREESCALE_LTC_ECC
126
    /* input basepoint on Weierstrass curve */
127
    ret = nxp_ltc_curve25519(&wc_pub, priv, basepoint, kLTC_Weierstrass);
128
    if (ret == 0) {
129
        XMEMCPY(pub, wc_pub.point, CURVE25519_KEYSIZE);
130
    }
131
#else
132
246
    fe_init();
133
134
246
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
135
136
246
    ret = curve25519(pub, priv, kCurve25519BasePoint);
137
138
246
    RESTORE_VECTOR_REGISTERS();
139
246
#endif
140
141
246
    return ret;
142
246
}
143
144
/* compute the public key from an existing private key, with supplied basepoint,
145
 * using bare vectors.
146
 *
147
 * return value is propagated from curve25519() (0 on success),
148
 * and the byte vectors are little endian.
149
 */
150
int wc_curve25519_generic(int public_size, byte* pub,
151
                          int private_size, const byte* priv,
152
                          int basepoint_size, const byte* basepoint)
153
0
{
154
#ifdef FREESCALE_LTC_ECC
155
    /* unsupported with NXP LTC, only supports single basepoint with
156
     * nxp_ltc_curve25519_GetBasePoint() */
157
    return WC_HW_E;
158
#else
159
0
    int ret;
160
161
0
    if ((public_size != CURVE25519_KEYSIZE) ||
162
0
        (private_size != CURVE25519_KEYSIZE) ||
163
0
        (basepoint_size != CURVE25519_KEYSIZE)) {
164
0
        return ECC_BAD_ARG_E;
165
0
    }
166
0
    if ((pub == NULL) || (priv == NULL) || (basepoint == NULL))
167
0
        return ECC_BAD_ARG_E;
168
169
    /* check clamping */
170
0
    ret = curve25519_priv_clamp_check(priv);
171
0
    if (ret != 0)
172
0
        return ret;
173
174
0
    fe_init();
175
176
0
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
177
178
0
    ret = curve25519(pub, priv, basepoint);
179
180
0
    RESTORE_VECTOR_REGISTERS();
181
182
0
    return ret;
183
0
#endif /* FREESCALE_LTC_ECC */
184
0
}
185
186
/* generate a new private key, as a bare vector.
187
 *
188
 * return value is propagated from wc_RNG_GenerateBlock(() (0 on success),
189
 * or BAD_FUNC_ARG/ECC_BAD_ARG_E, and the byte vector is little endian.
190
 */
191
int wc_curve25519_make_priv(WC_RNG* rng, int keysize, byte* key)
192
165
{
193
165
    int ret;
194
195
165
    if (key == NULL || rng == NULL)
196
0
        return BAD_FUNC_ARG;
197
198
    /* currently only a key size of 32 bytes is used */
199
165
    if (keysize != CURVE25519_KEYSIZE)
200
0
        return ECC_BAD_ARG_E;
201
202
    /* random number for private key */
203
165
    ret = wc_RNG_GenerateBlock(rng, key, keysize);
204
165
    if (ret == 0) {
205
        /* Clamp the private key */
206
145
        ret = curve25519_priv_clamp(key);
207
145
    }
208
209
165
    return ret;
210
165
}
211
212
/* generate a new keypair.
213
 *
214
 * return value is propagated from wc_curve25519_make_private() or
215
 * wc_curve25519_make_pub() (0 on success).
216
 */
217
int wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key)
218
165
{
219
165
    int ret;
220
221
165
    if (key == NULL || rng == NULL)
222
0
        return BAD_FUNC_ARG;
223
224
165
#ifdef WOLF_CRYPTO_CB
225
165
    if (key->devId != INVALID_DEVID) {
226
0
        ret = wc_CryptoCb_Curve25519Gen(rng, keysize, key);
227
0
        if (ret != CRYPTOCB_UNAVAILABLE)
228
0
            return ret;
229
        /* fall-through when unavailable */
230
0
    }
231
165
#endif
232
233
#ifdef WOLFSSL_SE050
234
    ret = se050_curve25519_create_key(key, keysize);
235
#else
236
165
    ret = wc_curve25519_make_priv(rng, keysize, key->k);
237
165
    if (ret == 0) {
238
145
        key->privSet = 1;
239
145
        ret = wc_curve25519_make_pub((int)sizeof(key->p.point), key->p.point,
240
145
                                     (int)sizeof(key->k), key->k);
241
145
        key->pubSet = (ret == 0);
242
145
    }
243
165
#endif
244
165
    return ret;
245
165
}
246
247
#ifdef HAVE_CURVE25519_SHARED_SECRET
248
249
int wc_curve25519_shared_secret(curve25519_key* private_key,
250
                                curve25519_key* public_key,
251
                                byte* out, word32* outlen)
252
0
{
253
0
    return wc_curve25519_shared_secret_ex(private_key, public_key,
254
0
                                          out, outlen, EC25519_BIG_ENDIAN);
255
0
}
256
257
int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
258
                                   curve25519_key* public_key,
259
                                   byte* out, word32* outlen, int endian)
260
0
{
261
0
    int ret;
262
0
    ECPoint o;
263
264
    /* sanity check */
265
0
    if (private_key == NULL || public_key == NULL ||
266
0
        out == NULL || outlen == NULL || *outlen < CURVE25519_KEYSIZE) {
267
0
        return BAD_FUNC_ARG;
268
0
    }
269
270
    /* make sure we have a populated private and public key */
271
0
    if (!public_key->pubSet
272
0
    #ifndef WOLFSSL_SE050
273
0
        || !private_key->privSet
274
0
    #endif
275
0
    ) {
276
0
        return ECC_BAD_ARG_E;
277
0
    }
278
279
    /* avoid implementation fingerprinting - make sure signed bit is not set */
280
0
    if (public_key->p.point[CURVE25519_KEYSIZE-1] & 0x80) {
281
0
        return ECC_BAD_ARG_E;
282
0
    }
283
284
0
#ifdef WOLF_CRYPTO_CB
285
0
    if (private_key->devId != INVALID_DEVID) {
286
0
        ret = wc_CryptoCb_Curve25519(private_key, public_key, out, outlen,
287
0
            endian);
288
0
        if (ret != CRYPTOCB_UNAVAILABLE)
289
0
            return ret;
290
        /* fall-through when unavailable */
291
0
    }
292
0
#endif
293
294
0
    XMEMSET(&o, 0, sizeof(o));
295
296
#ifdef FREESCALE_LTC_ECC
297
    /* input point P on Curve25519 */
298
    ret = nxp_ltc_curve25519(&o, private_key->k, &public_key->p,
299
        kLTC_Curve25519);
300
#else
301
    #ifdef WOLFSSL_SE050
302
    if (!private_key->privSet) {
303
        /* use NXP SE050: "privSet" is not set */
304
        ret = se050_curve25519_shared_secret(private_key, public_key, &o);
305
    }
306
    else
307
    #endif
308
0
    {
309
0
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
310
311
0
    ret = curve25519(o.point, private_key->k, public_key->p.point);
312
313
0
    RESTORE_VECTOR_REGISTERS();
314
0
    }
315
0
#endif
316
#ifdef WOLFSSL_ECDHX_SHARED_NOT_ZERO
317
    if (ret == 0) {
318
        int i;
319
        byte t = 0;
320
        for (i = 0; i < CURVE25519_KEYSIZE; i++) {
321
            t |= o.point[i];
322
        }
323
        if (t == 0) {
324
            ret = ECC_OUT_OF_RANGE_E;
325
        }
326
    }
327
#endif
328
0
    if (ret != 0) {
329
0
        ForceZero(&o, sizeof(o));
330
0
        return ret;
331
0
    }
332
333
0
    curve25519_copy_point(out, o.point, endian);
334
0
    *outlen = CURVE25519_KEYSIZE;
335
336
0
    ForceZero(&o, sizeof(o));
337
338
0
    return ret;
339
0
}
340
341
#endif /* HAVE_CURVE25519_SHARED_SECRET */
342
343
#ifdef HAVE_CURVE25519_KEY_EXPORT
344
345
/* export curve25519 public key (Big endian)
346
 * return 0 on success */
347
int wc_curve25519_export_public(curve25519_key* key, byte* out, word32* outLen)
348
0
{
349
0
    return wc_curve25519_export_public_ex(key, out, outLen, EC25519_BIG_ENDIAN);
350
0
}
351
352
/* export curve25519 public key (Big or Little endian)
353
 * return 0 on success */
354
int wc_curve25519_export_public_ex(curve25519_key* key, byte* out,
355
                                   word32* outLen, int endian)
356
77
{
357
77
    int ret = 0;
358
359
77
    if (key == NULL || out == NULL || outLen == NULL) {
360
38
        return BAD_FUNC_ARG;
361
38
    }
362
363
    /* check and set outgoing key size */
364
39
    if (*outLen < CURVE25519_KEYSIZE) {
365
1
        *outLen = CURVE25519_KEYSIZE;
366
1
        return ECC_BAD_ARG_E;
367
1
    }
368
369
    /* calculate public if missing */
370
38
    if (!key->pubSet) {
371
0
        ret = wc_curve25519_make_pub((int)sizeof(key->p.point), key->p.point,
372
0
                                     (int)sizeof(key->k), key->k);
373
0
        key->pubSet = (ret == 0);
374
0
    }
375
    /* export public point with endianess */
376
38
    curve25519_copy_point(out, key->p.point, endian);
377
38
    *outLen = CURVE25519_KEYSIZE;
378
379
38
    return ret;
380
39
}
381
382
#endif /* HAVE_CURVE25519_KEY_EXPORT */
383
384
#ifdef HAVE_CURVE25519_KEY_IMPORT
385
386
/* import curve25519 public key (Big endian)
387
 *  return 0 on success */
388
int wc_curve25519_import_public(const byte* in, word32 inLen,
389
                                curve25519_key* key)
390
0
{
391
0
    return wc_curve25519_import_public_ex(in, inLen, key, EC25519_BIG_ENDIAN);
392
0
}
393
394
/* import curve25519 public key (Big or Little endian)
395
 * return 0 on success */
396
int wc_curve25519_import_public_ex(const byte* in, word32 inLen,
397
                                curve25519_key* key, int endian)
398
0
{
399
#ifdef FREESCALE_LTC_ECC
400
    ltc_pkha_ecc_point_t ltcPoint;
401
#endif
402
403
    /* sanity check */
404
0
    if (key == NULL || in == NULL) {
405
0
        return BAD_FUNC_ARG;
406
0
    }
407
408
    /* check size of incoming keys */
409
0
    if (inLen != CURVE25519_KEYSIZE) {
410
0
       return ECC_BAD_ARG_E;
411
0
    }
412
413
    /* import public point with endianess */
414
0
    curve25519_copy_point(key->p.point, in, endian);
415
0
    key->pubSet = 1;
416
417
0
    key->dp = &curve25519_sets[0];
418
419
    /* LTC needs also Y coordinate - let's compute it */
420
#ifdef FREESCALE_LTC_ECC
421
    ltcPoint.X = &key->p.point[0];
422
    ltcPoint.Y = &key->p.pointY[0];
423
    LTC_PKHA_Curve25519ComputeY(&ltcPoint);
424
#endif
425
426
0
    return 0;
427
0
}
428
429
/* Check the public key value (big or little endian)
430
 *
431
 * pub     Public key bytes.
432
 * pubSz   Size of public key in bytes.
433
 * endian  Public key bytes passed in as big-endian or little-endian.
434
 * returns BAD_FUNC_ARGS when pub is NULL,
435
 *         BUFFER_E when size of public key is zero;
436
 *         ECC_OUT_OF_RANGE_E if the high bit is set;
437
 *         ECC_BAD_ARG_E if key length is not 32 bytes, public key value is
438
 *         zero or one; and
439
 *         0 otherwise.
440
 */
441
int wc_curve25519_check_public(const byte* pub, word32 pubSz, int endian)
442
231
{
443
231
    word32 i;
444
445
231
    if (pub == NULL)
446
0
        return BAD_FUNC_ARG;
447
448
    /* Check for empty key data */
449
231
    if (pubSz == 0)
450
0
        return BUFFER_E;
451
452
    /* Check key length */
453
231
    if (pubSz != CURVE25519_KEYSIZE)
454
0
        return ECC_BAD_ARG_E;
455
456
457
231
    if (endian == EC25519_LITTLE_ENDIAN) {
458
        /* Check for value of zero or one */
459
169
        for (i = CURVE25519_KEYSIZE - 1; i > 0; i--) {
460
169
            if (pub[i] != 0)
461
145
                break;
462
169
        }
463
145
        if (i == 0 && (pub[0] == 0 || pub[0] == 1))
464
0
            return ECC_BAD_ARG_E;
465
466
        /* Check high bit set */
467
145
        if (pub[CURVE25519_KEYSIZE - 1] & 0x80)
468
0
            return ECC_OUT_OF_RANGE_E;
469
470
        /* Check for order-1 or higher. */
471
145
        if (pub[CURVE25519_KEYSIZE - 1] == 0x7f) {
472
9
            for (i = CURVE25519_KEYSIZE - 2; i > 0; i--) {
473
9
                if (pub[i] != 0xff)
474
8
                    break;
475
9
            }
476
8
            if (i == 0 && (pub[0] >= 0xec))
477
0
                return ECC_BAD_ARG_E;
478
8
         }
479
145
    }
480
86
    else {
481
        /* Check for value of zero or one */
482
1.79k
        for (i = 0; i < CURVE25519_KEYSIZE - 1; i++) {
483
1.75k
            if (pub[i] != 0)
484
46
                break;
485
1.75k
        }
486
86
        if (i == CURVE25519_KEYSIZE - 1 && (pub[i] == 0 || pub[i] == 1))
487
25
            return ECC_BAD_ARG_E;
488
489
        /* Check high bit set */
490
61
        if (pub[0] & 0x80)
491
10
            return ECC_OUT_OF_RANGE_E;
492
493
        /* Check for order-1 or higher. */
494
51
        if (pub[0] == 0x7f) {
495
26
            for (i = 1; i < CURVE25519_KEYSIZE - 1; i++) {
496
26
                if (pub[i] != 0)
497
16
                    break;
498
26
            }
499
16
            if (i == CURVE25519_KEYSIZE - 1 && (pub[i] >= 0xec))
500
0
                return ECC_BAD_ARG_E;
501
16
         }
502
51
    }
503
504
196
    return 0;
505
231
}
506
507
#endif /* HAVE_CURVE25519_KEY_IMPORT */
508
509
510
#ifdef HAVE_CURVE25519_KEY_EXPORT
511
512
/* export curve25519 private key only raw (Big endian)
513
 * outLen is in/out size
514
 * return 0 on success */
515
int wc_curve25519_export_private_raw(curve25519_key* key, byte* out,
516
                                     word32* outLen)
517
0
{
518
0
    return wc_curve25519_export_private_raw_ex(key, out, outLen,
519
0
                                               EC25519_BIG_ENDIAN);
520
0
}
521
522
/* export curve25519 private key only raw (Big or Little endian)
523
 * outLen is in/out size
524
 * return 0 on success */
525
int wc_curve25519_export_private_raw_ex(curve25519_key* key, byte* out,
526
                                        word32* outLen, int endian)
527
145
{
528
    /* sanity check */
529
145
    if (key == NULL || out == NULL || outLen == NULL)
530
43
        return BAD_FUNC_ARG;
531
532
    /* check size of outgoing buffer */
533
102
    if (*outLen < CURVE25519_KEYSIZE) {
534
14
        *outLen = CURVE25519_KEYSIZE;
535
14
        return ECC_BAD_ARG_E;
536
14
    }
537
538
    /* export private scalar with endianess */
539
88
    curve25519_copy_point(out, key->k, endian);
540
88
    *outLen = CURVE25519_KEYSIZE;
541
542
88
    return 0;
543
102
}
544
545
/* curve25519 key pair export (Big or Little endian)
546
 * return 0 on success */
547
int wc_curve25519_export_key_raw(curve25519_key* key,
548
                                 byte* priv, word32 *privSz,
549
                                 byte* pub, word32 *pubSz)
550
0
{
551
0
    return wc_curve25519_export_key_raw_ex(key, priv, privSz,
552
0
                                           pub, pubSz, EC25519_BIG_ENDIAN);
553
0
}
554
555
/* curve25519 key pair export (Big or Little endian)
556
 * return 0 on success */
557
int wc_curve25519_export_key_raw_ex(curve25519_key* key,
558
                                    byte* priv, word32 *privSz,
559
                                    byte* pub, word32 *pubSz,
560
                                    int endian)
561
0
{
562
0
    int ret;
563
564
    /* export private part */
565
0
    ret = wc_curve25519_export_private_raw_ex(key, priv, privSz, endian);
566
0
    if (ret != 0)
567
0
        return ret;
568
569
    /* export public part */
570
0
    return wc_curve25519_export_public_ex(key, pub, pubSz, endian);
571
0
}
572
573
#endif /* HAVE_CURVE25519_KEY_EXPORT */
574
575
#ifdef HAVE_CURVE25519_KEY_IMPORT
576
577
/* curve25519 private key import (Big endian)
578
 * Public key to match private key needs to be imported too
579
 * return 0 on success */
580
int wc_curve25519_import_private_raw(const byte* priv, word32 privSz,
581
                                     const byte* pub, word32 pubSz,
582
                                     curve25519_key* key)
583
0
{
584
0
    return wc_curve25519_import_private_raw_ex(priv, privSz, pub, pubSz,
585
0
                                               key, EC25519_BIG_ENDIAN);
586
0
}
587
588
/* curve25519 private key import (Big or Little endian)
589
 * Public key to match private key needs to be imported too
590
 * return 0 on success */
591
int wc_curve25519_import_private_raw_ex(const byte* priv, word32 privSz,
592
                                        const byte* pub, word32 pubSz,
593
                                        curve25519_key* key, int endian)
594
0
{
595
0
    int ret;
596
597
    /* import private part */
598
0
    ret = wc_curve25519_import_private_ex(priv, privSz, key, endian);
599
0
    if (ret != 0)
600
0
        return ret;
601
602
    /* import public part */
603
0
    return wc_curve25519_import_public_ex(pub, pubSz, key, endian);
604
0
}
605
606
/* curve25519 private key import only. (Big endian)
607
 * return 0 on success */
608
int wc_curve25519_import_private(const byte* priv, word32 privSz,
609
                                 curve25519_key* key)
610
0
{
611
0
    return wc_curve25519_import_private_ex(priv, privSz,
612
0
                                           key, EC25519_BIG_ENDIAN);
613
0
}
614
615
/* curve25519 private key import only. (Big or Little endian)
616
 * return 0 on success */
617
int wc_curve25519_import_private_ex(const byte* priv, word32 privSz,
618
                                    curve25519_key* key, int endian)
619
0
{
620
    /* sanity check */
621
0
    if (key == NULL || priv == NULL) {
622
0
        return BAD_FUNC_ARG;
623
0
    }
624
625
    /* check size of incoming keys */
626
0
    if ((int)privSz != CURVE25519_KEYSIZE) {
627
0
        return ECC_BAD_ARG_E;
628
0
    }
629
630
#ifdef WOLFSSL_SE050
631
    /* release NXP resources if set */
632
    se050_curve25519_free_key(key);
633
#endif
634
635
    /* import private scalar with endianess */
636
0
    curve25519_copy_point(key->k, priv, endian);
637
0
    key->privSet = 1;
638
639
0
    key->dp = &curve25519_sets[0];
640
641
    /* Clamp the key */
642
0
    return curve25519_priv_clamp(key->k);
643
0
}
644
645
#endif /* HAVE_CURVE25519_KEY_IMPORT */
646
647
int wc_curve25519_init_ex(curve25519_key* key, void* heap, int devId)
648
165
{
649
165
    if (key == NULL)
650
0
       return BAD_FUNC_ARG;
651
652
165
    XMEMSET(key, 0, sizeof(*key));
653
654
    /* currently the format for curve25519 */
655
165
    key->dp = &curve25519_sets[0];
656
657
165
#ifdef WOLF_CRYPTO_CB
658
165
    key->devId = devId;
659
#else
660
    (void)devId;
661
#endif
662
165
    (void)heap; /* if needed for XMALLOC/XFREE in future */
663
664
165
#ifndef FREESCALE_LTC_ECC
665
165
    fe_init();
666
165
#endif
667
668
#ifdef WOLFSSL_CHECK_MEM_ZERO
669
    wc_MemZero_Add("wc_curve25519_init_ex key->k", key->k, CURVE25519_KEYSIZE);
670
#endif
671
672
165
    return 0;
673
165
}
674
675
int wc_curve25519_init(curve25519_key* key)
676
165
{
677
165
    return wc_curve25519_init_ex(key, NULL, INVALID_DEVID);
678
165
}
679
680
/* Clean the memory of a key */
681
void wc_curve25519_free(curve25519_key* key)
682
165
{
683
165
    if (key == NULL)
684
0
       return;
685
686
#ifdef WOLFSSL_SE050
687
    se050_curve25519_free_key(key);
688
#endif
689
690
165
    key->dp = NULL;
691
165
    ForceZero(key->k, sizeof(key->k));
692
165
    XMEMSET(&key->p, 0, sizeof(key->p));
693
165
    key->pubSet = 0;
694
165
    key->privSet = 0;
695
#ifdef WOLFSSL_CHECK_MEM_ZERO
696
    wc_MemZero_Check(key, sizeof(curve25519_key));
697
#endif
698
165
}
699
700
/* get key size */
701
int wc_curve25519_size(curve25519_key* key)
702
0
{
703
0
    if (key == NULL)
704
0
        return 0;
705
706
0
    return key->dp->size;
707
0
}
708
709
#endif /*HAVE_CURVE25519*/