Coverage Report

Created: 2026-08-15 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-openssl-api/src/pk_ec.c
Line
Count
Source
1
/* pk_ec.c
2
 *
3
 * Copyright (C) 2006-2026 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
23
24
#include <wolfssl/internal.h>
25
#ifndef WC_NO_RNG
26
    #include <wolfssl/wolfcrypt/random.h>
27
#endif
28
29
#ifdef HAVE_ECC
30
    #include <wolfssl/wolfcrypt/ecc.h>
31
    #ifdef HAVE_SELFTEST
32
        /* point compression types. */
33
        #define ECC_POINT_COMP_EVEN 0x02
34
        #define ECC_POINT_COMP_ODD  0x03
35
        #define ECC_POINT_UNCOMP    0x04
36
    #endif
37
#endif
38
#ifndef WOLFSSL_HAVE_ECC_KEY_GET_PRIV
39
    /* FIPS build has replaced ecc.h. */
40
    #define wc_ecc_key_get_priv(key) (&((key)->k))
41
    #define WOLFSSL_HAVE_ECC_KEY_GET_PRIV
42
#endif
43
44
#if !defined(WOLFSSL_PK_EC_INCLUDED)
45
    #ifndef WOLFSSL_IGNORE_FILE_WARN
46
        #warning pk_ec.c does not need to be compiled separately from ssl.c
47
    #endif
48
#else
49
50
/*******************************************************************************
51
 * START OF EC API
52
 ******************************************************************************/
53
54
#ifdef HAVE_ECC
55
56
#if defined(OPENSSL_EXTRA)
57
58
/* Start EC_curve */
59
60
/* Get the NIST name for the numeric ID.
61
 *
62
 * @param [in] nid  Numeric ID of an EC curve.
63
 * @return  String representing NIST name of EC curve on success.
64
 * @return  NULL on error.
65
 */
66
const char* wolfSSL_EC_curve_nid2nist(int nid)
67
0
{
68
0
    const char* name = NULL;
69
0
    const WOLF_EC_NIST_NAME* nist_name;
70
71
    /* Attempt to find the curve info matching the NID passed in. */
72
0
    for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) {
73
0
        if (nist_name->nid == nid) {
74
            /* NID found - return name. */
75
0
            name = nist_name->name;
76
0
            break;
77
0
        }
78
0
    }
79
80
0
    return name;
81
0
}
82
83
/* Get the numeric ID for the NIST name.
84
 *
85
 * @param [in] name  NIST name of EC curve.
86
 * @return  NID matching NIST name on success.
87
 * @return  0 on error.
88
 */
89
int wolfSSL_EC_curve_nist2nid(const char* name)
90
0
{
91
0
    int nid = 0;
92
0
    const WOLF_EC_NIST_NAME* nist_name;
93
94
    /* Attempt to find the curve info matching the NIST name passed in. */
95
0
    for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) {
96
0
        if (XSTRCMP(nist_name->name, name) == 0) {
97
            /* Name found - return NID. */
98
0
            nid = nist_name->nid;
99
0
            break;
100
0
        }
101
0
    }
102
103
0
    return nid;
104
0
}
105
106
#endif /* OPENSSL_EXTRA */
107
108
/* End EC_curve */
109
110
/* Start EC_METHOD */
111
112
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
113
/* Get the EC method of the EC group object.
114
 *
115
 * wolfSSL doesn't use method tables. Implementation used is dependent upon
116
 * the NID.
117
 *
118
 * @param [in] group  EC group object.
119
 * @return  EC method.
120
 */
121
const WOLFSSL_EC_METHOD* wolfSSL_EC_GROUP_method_of(
122
    const WOLFSSL_EC_GROUP *group)
123
0
{
124
    /* No method table used so just return the same object. */
125
0
    return group;
126
0
}
127
128
/* Get field type for method.
129
 *
130
 * Only prime fields are supported.
131
 *
132
 * @param [in] meth  EC method.
133
 * @return  X9.63 prime field NID on success.
134
 * @return  0 on error.
135
 */
136
int wolfSSL_EC_METHOD_get_field_type(const WOLFSSL_EC_METHOD *meth)
137
0
{
138
0
    int nid = 0;
139
140
0
    if (meth != NULL) {
141
        /* Only field type supported by code base. */
142
0
        nid = WC_NID_X9_62_prime_field;
143
0
    }
144
145
0
    return nid;
146
0
}
147
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
148
149
/* End EC_METHOD */
150
151
/* Start EC_GROUP */
152
153
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
154
/* Converts ECC curve enum values in ecc_curve_id to the associated OpenSSL NID
155
 * value.
156
 *
157
 * @param [in] n  ECC curve id.
158
 * @return  ECC curve NID (OpenSSL compatible value).
159
 */
160
int EccEnumToNID(int n)
161
2.46k
{
162
2.46k
    WOLFSSL_ENTER("EccEnumToNID");
163
164
2.46k
    switch(n) {
165
0
        case ECC_SECP192R1:
166
0
            return WC_NID_X9_62_prime192v1;
167
0
        case ECC_PRIME192V2:
168
0
            return WC_NID_X9_62_prime192v2;
169
0
        case ECC_PRIME192V3:
170
0
            return WC_NID_X9_62_prime192v3;
171
0
        case ECC_PRIME239V1:
172
0
            return WC_NID_X9_62_prime239v1;
173
0
        case ECC_PRIME239V2:
174
0
            return WC_NID_X9_62_prime239v2;
175
0
        case ECC_PRIME239V3:
176
0
            return WC_NID_X9_62_prime239v3;
177
0
        case ECC_SECP256R1:
178
0
            return WC_NID_X9_62_prime256v1;
179
0
        case ECC_SECP112R1:
180
0
            return WC_NID_secp112r1;
181
0
        case ECC_SECP112R2:
182
0
            return WC_NID_secp112r2;
183
0
        case ECC_SECP128R1:
184
0
            return WC_NID_secp128r1;
185
0
        case ECC_SECP128R2:
186
0
            return WC_NID_secp128r2;
187
0
        case ECC_SECP160R1:
188
0
            return WC_NID_secp160r1;
189
0
        case ECC_SECP160R2:
190
0
            return WC_NID_secp160r2;
191
0
        case ECC_SECP224R1:
192
0
            return WC_NID_secp224r1;
193
0
        case ECC_SECP384R1:
194
0
            return WC_NID_secp384r1;
195
0
        case ECC_SECP521R1:
196
0
            return WC_NID_secp521r1;
197
0
        case ECC_SECP160K1:
198
0
            return WC_NID_secp160k1;
199
0
        case ECC_SECP192K1:
200
0
            return WC_NID_secp192k1;
201
0
        case ECC_SECP224K1:
202
0
            return WC_NID_secp224k1;
203
0
        case ECC_SECP256K1:
204
0
            return WC_NID_secp256k1;
205
0
        case ECC_BRAINPOOLP160R1:
206
0
            return WC_NID_brainpoolP160r1;
207
0
        case ECC_BRAINPOOLP192R1:
208
0
            return WC_NID_brainpoolP192r1;
209
0
        case ECC_BRAINPOOLP224R1:
210
0
            return WC_NID_brainpoolP224r1;
211
0
        case ECC_BRAINPOOLP256R1:
212
0
            return WC_NID_brainpoolP256r1;
213
0
        case ECC_BRAINPOOLP320R1:
214
0
            return WC_NID_brainpoolP320r1;
215
0
        case ECC_BRAINPOOLP384R1:
216
0
            return WC_NID_brainpoolP384r1;
217
0
        case ECC_BRAINPOOLP512R1:
218
0
            return WC_NID_brainpoolP512r1;
219
0
    #ifdef WOLFSSL_SM2
220
0
        case ECC_SM2P256V1:
221
0
            return WC_NID_sm2;
222
0
    #endif
223
2.46k
        default:
224
2.46k
            WOLFSSL_MSG("NID not found");
225
2.46k
            return WOLFSSL_FATAL_ERROR;
226
2.46k
    }
227
2.46k
}
228
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
229
230
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
231
/* Converts OpenSSL NID of EC curve to the enum value in ecc_curve_id
232
 *
233
 * Used by ecc_sets[].
234
 *
235
 * @param [in] n  OpenSSL NID of EC curve.
236
 * @return  wolfCrypt EC curve id.
237
 * @return  -1 on error.
238
 */
239
int NIDToEccEnum(int nid)
240
2.71k
{
241
2.71k
    int id;
242
243
2.71k
    WOLFSSL_ENTER("NIDToEccEnum");
244
245
2.71k
    switch (nid) {
246
30
        case WC_NID_X9_62_prime192v1:
247
30
            id = ECC_SECP192R1;
248
30
            break;
249
101
        case WC_NID_X9_62_prime192v2:
250
101
            id = ECC_PRIME192V2;
251
101
            break;
252
29
        case WC_NID_X9_62_prime192v3:
253
29
            id = ECC_PRIME192V3;
254
29
            break;
255
27
        case WC_NID_X9_62_prime239v1:
256
27
            id = ECC_PRIME239V1;
257
27
            break;
258
55
        case WC_NID_X9_62_prime239v2:
259
55
            id = ECC_PRIME239V2;
260
55
            break;
261
10
        case WC_NID_X9_62_prime239v3:
262
10
            id = ECC_PRIME239V3;
263
10
            break;
264
123
        case WC_NID_X9_62_prime256v1:
265
123
            id = ECC_SECP256R1;
266
123
            break;
267
20
        case WC_NID_secp112r1:
268
20
            id = ECC_SECP112R1;
269
20
            break;
270
44
        case WC_NID_secp112r2:
271
44
            id = ECC_SECP112R2;
272
44
            break;
273
58
        case WC_NID_secp128r1:
274
58
            id = ECC_SECP128R1;
275
58
            break;
276
81
        case WC_NID_secp128r2:
277
81
            id = ECC_SECP128R2;
278
81
            break;
279
94
        case WC_NID_secp160r1:
280
94
            id = ECC_SECP160R1;
281
94
            break;
282
16
        case WC_NID_secp160r2:
283
16
            id = ECC_SECP160R2;
284
16
            break;
285
6
        case WC_NID_secp224r1:
286
6
            id = ECC_SECP224R1;
287
6
            break;
288
74
        case WC_NID_secp384r1:
289
74
            id = ECC_SECP384R1;
290
74
            break;
291
316
        case WC_NID_secp521r1:
292
316
            id = ECC_SECP521R1;
293
316
            break;
294
24
        case WC_NID_secp160k1:
295
24
            id = ECC_SECP160K1;
296
24
            break;
297
121
        case WC_NID_secp192k1:
298
121
            id = ECC_SECP192K1;
299
121
            break;
300
31
        case WC_NID_secp224k1:
301
31
            id = ECC_SECP224K1;
302
31
            break;
303
167
        case WC_NID_secp256k1:
304
167
            id = ECC_SECP256K1;
305
167
            break;
306
34
        case WC_NID_brainpoolP160r1:
307
34
            id = ECC_BRAINPOOLP160R1;
308
34
            break;
309
12
        case WC_NID_brainpoolP192r1:
310
12
            id = ECC_BRAINPOOLP192R1;
311
12
            break;
312
44
        case WC_NID_brainpoolP224r1:
313
44
            id = ECC_BRAINPOOLP224R1;
314
44
            break;
315
47
        case WC_NID_brainpoolP256r1:
316
47
            id = ECC_BRAINPOOLP256R1;
317
47
            break;
318
29
        case WC_NID_brainpoolP320r1:
319
29
            id = ECC_BRAINPOOLP320R1;
320
29
            break;
321
61
        case WC_NID_brainpoolP384r1:
322
61
            id = ECC_BRAINPOOLP384R1;
323
61
            break;
324
20
        case WC_NID_brainpoolP512r1:
325
20
            id = ECC_BRAINPOOLP512R1;
326
20
            break;
327
1.04k
        default:
328
1.04k
            WOLFSSL_MSG("NID not found");
329
            /* -1 on error. */
330
1.04k
            id = WOLFSSL_FATAL_ERROR;
331
2.71k
    }
332
333
2.71k
    return id;
334
2.71k
}
335
336
/* Set the fields of the EC group based on numeric ID.
337
 *
338
 * @param [in, out] group  EC group.
339
 * @param [in]      nid    Numeric ID of an EC curve.
340
 */
341
static void ec_group_set_nid(WOLFSSL_EC_GROUP* group, int nid)
342
2.71k
{
343
2.71k
    int eccEnum;
344
2.71k
    int realNid;
345
346
    /* Convert ecc_curve_id enum to NID. */
347
2.71k
    if ((realNid = EccEnumToNID(nid)) != -1) {
348
        /* ecc_curve_id enum passed in - have real NID value set. */
349
0
        eccEnum = nid;
350
0
    }
351
2.71k
    else {
352
        /* NID passed in is OpenSSL type. */
353
2.71k
        realNid = nid;
354
        /* Convert NID to ecc_curve_id enum. */
355
2.71k
        eccEnum = NIDToEccEnum(nid);
356
2.71k
    }
357
358
    /* Set the numeric ID of the curve */
359
2.71k
    group->curve_nid = realNid;
360
    /* Initialize index to -1 (i.e. wolfCrypt doesn't support curve). */
361
2.71k
    group->curve_idx = -1;
362
363
    /* Find index and OID sum for curve if wolfCrypt supports it. */
364
2.71k
    if (eccEnum != -1) {
365
1.67k
        int i;
366
367
        /* Find id and set the internal curve idx and OID sum. */
368
28.2k
        for (i = 0; ecc_sets[i].size != 0; i++) {
369
28.2k
            if (ecc_sets[i].id == eccEnum) {
370
                /* Found id in wolfCrypt supported EC curves. */
371
1.67k
                group->curve_idx = i;
372
1.67k
                group->curve_oid = (int)ecc_sets[i].oidSum;
373
1.67k
                break;
374
1.67k
            }
375
28.2k
        }
376
1.67k
    }
377
2.71k
}
378
379
/* Create a new EC group with the numeric ID for an EC curve.
380
 *
381
 * @param [in] nid  Numeric ID of an EC curve.
382
 * @return  New, allocated EC group on success.
383
 * @return  NULL on error.
384
 */
385
WOLFSSL_EC_GROUP* wolfSSL_EC_GROUP_new_by_curve_name(int nid)
386
2.71k
{
387
2.71k
    int err = 0;
388
2.71k
    WOLFSSL_EC_GROUP* group;
389
390
2.71k
    WOLFSSL_ENTER("wolfSSL_EC_GROUP_new_by_curve_name");
391
392
    /* Allocate EC group. */
393
2.71k
    group = (WOLFSSL_EC_GROUP*)XMALLOC(sizeof(WOLFSSL_EC_GROUP), NULL,
394
2.71k
        DYNAMIC_TYPE_ECC);
395
2.71k
    if (group == NULL) {
396
0
        WOLFSSL_MSG("wolfSSL_EC_GROUP_new_by_curve_name malloc failure");
397
0
        err = 1;
398
0
    }
399
400
2.71k
    if (!err) {
401
        /* Reset all fields. */
402
2.71k
        XMEMSET(group, 0, sizeof(WOLFSSL_EC_GROUP));
403
404
        /* Set the fields of group based on the numeric ID. */
405
2.71k
        ec_group_set_nid(group, nid);
406
2.71k
    }
407
408
2.71k
    return group;
409
2.71k
}
410
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
411
412
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
413
/* Dispose of the EC group.
414
 *
415
 * Cannot use group after this call.
416
 *
417
 * @param [in] group  EC group to free.
418
 */
419
void wolfSSL_EC_GROUP_free(WOLFSSL_EC_GROUP *group)
420
2.71k
{
421
2.71k
    WOLFSSL_ENTER("wolfSSL_EC_GROUP_free");
422
423
    /* Dispose of EC group. */
424
2.71k
    XFREE(group, NULL, DYNAMIC_TYPE_ECC);
425
2.71k
}
426
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
427
428
#ifdef OPENSSL_EXTRA
429
430
/* Creates an EC group from the DER encoding.
431
 *
432
 * Only named curves supported.
433
 *
434
 * @param [out] group  Reference to EC group object.
435
 * @param [in]  in     Buffer holding DER encoding of curve.
436
 * @param [in]  inSz   Length of data in buffer.
437
 * @return  EC group on success.
438
 * @return  NULL on error.
439
 */
440
static WOLFSSL_EC_GROUP* wolfssl_ec_group_d2i(WOLFSSL_EC_GROUP** group,
441
    const unsigned char** in_pp, long inSz)
442
0
{
443
0
    int err = 0;
444
0
    WOLFSSL_EC_GROUP* ret = NULL;
445
0
    word32 idx = 0;
446
0
    word32 oid = 0;
447
0
    int id = 0;
448
0
    const unsigned char* in;
449
450
0
    if (in_pp == NULL || *in_pp == NULL)
451
0
        return NULL;
452
0
    if (inSz <= 0)
453
0
        return NULL;
454
455
0
    in = *in_pp;
456
457
    /* Use the group passed in. */
458
0
    if ((group != NULL) && (*group != NULL)) {
459
0
        ret = *group;
460
0
    }
461
462
    /* Only support named curves. */
463
0
    if (in[0] != ASN_OBJECT_ID) {
464
0
        WOLFSSL_ERROR_MSG("Invalid or unsupported encoding");
465
0
        err = 1;
466
0
    }
467
    /* Decode the OBJECT ID - expecting an EC curve OID. */
468
0
    if ((!err) && (GetObjectId(in, &idx, &oid, oidCurveType, (word32)inSz) !=
469
0
            0)) {
470
0
        err = 1;
471
0
    }
472
0
    if (!err) {
473
        /* Get the internal ID for OID. */
474
0
        id = wc_ecc_get_oid(oid, NULL, NULL);
475
0
        if (id < 0) {
476
0
            err = 1;
477
0
        }
478
0
    }
479
0
    if (!err) {
480
        /* Get the NID for the internal ID. */
481
0
        int nid = EccEnumToNID(id);
482
0
        if (ret == NULL) {
483
            /* Create a new EC group with the numeric ID. */
484
0
            ret = wolfSSL_EC_GROUP_new_by_curve_name(nid);
485
0
            if (ret == NULL) {
486
0
                err = 1;
487
0
            }
488
0
        }
489
0
        else {
490
0
            ec_group_set_nid(ret, nid);
491
0
        }
492
0
    }
493
0
    if ((!err) && (group != NULL)) {
494
        /* Return the EC group through reference. */
495
0
        *group = ret;
496
0
    }
497
498
0
    if (err) {
499
0
        if ((ret != NULL) && (ret != *group)) {
500
0
            wolfSSL_EC_GROUP_free(ret);
501
0
        }
502
0
        ret = NULL;
503
0
    }
504
0
    else {
505
0
        *in_pp += idx;
506
0
    }
507
0
    return ret;
508
0
}
509
510
#ifndef NO_BIO
511
/* Creates a new EC group from the PEM encoding in the BIO.
512
 *
513
 * @param [in]  bio    BIO to read PEM encoding from.
514
 * @param [out] group  Reference to EC group object.
515
 * @param [in]  cb     Password callback when PEM encrypted.
516
 * @param [in]  pass   NUL terminated string for passphrase when PEM encrypted.
517
 * @return  EC group on success.
518
 * @return  NULL on error.
519
 */
520
WOLFSSL_EC_GROUP* wolfSSL_PEM_read_bio_ECPKParameters(WOLFSSL_BIO* bio,
521
    WOLFSSL_EC_GROUP** group, wc_pem_password_cb* cb, void* pass)
522
0
{
523
0
    int err = 0;
524
0
    WOLFSSL_EC_GROUP* ret = NULL;
525
0
    DerBuffer*        der = NULL;
526
0
    int               keyFormat = 0;
527
528
0
     if (bio == NULL) {
529
0
         err = 1;
530
0
     }
531
532
    /* Read parameters from BIO and convert PEM to DER. */
533
0
    if ((!err) && (pem_read_bio_key(bio, cb, pass, ECC_PARAM_TYPE,
534
0
            &keyFormat, &der) < 0)) {
535
0
        err = 1;
536
0
    }
537
0
    if (!err) {
538
        /* Create EC group from DER encoding. */
539
0
        const byte** p = (const byte**)&der->buffer;
540
0
        ret = wolfssl_ec_group_d2i(group, p, der->length);
541
0
        if (ret == NULL) {
542
0
            WOLFSSL_ERROR_MSG("Error loading DER buffer into WOLFSSL_EC_GROUP");
543
0
        }
544
0
    }
545
546
    /* Dispose of any allocated data. */
547
0
    FreeDer(&der);
548
0
    return ret;
549
0
}
550
#endif /* !NO_BIO */
551
552
WOLFSSL_EC_GROUP *wolfSSL_d2i_ECPKParameters(WOLFSSL_EC_GROUP **out,
553
        const unsigned char **in, long len)
554
0
{
555
0
    return wolfssl_ec_group_d2i(out, in, len);
556
0
}
557
558
int wolfSSL_i2d_ECPKParameters(const WOLFSSL_EC_GROUP* grp, unsigned char** pp)
559
0
{
560
0
    unsigned char* out = NULL;
561
0
    int len = 0;
562
0
    int idx;
563
0
    const byte* oid = NULL;
564
0
    word32 oidSz = 0;
565
566
0
    if (grp == NULL || !wc_ecc_is_valid_idx(grp->curve_idx) ||
567
0
            grp->curve_idx < 0)
568
0
        return WOLFSSL_FATAL_ERROR;
569
570
    /* Get the actual DER encoding of the OID. ecc_sets[grp->curve_idx].oid
571
     * is just the numerical representation. */
572
0
    if (wc_ecc_get_oid((word32)grp->curve_oid, &oid, &oidSz) < 0)
573
0
        return WOLFSSL_FATAL_ERROR;
574
575
0
    len = SetObjectId((int)oidSz, NULL) + (int)oidSz;
576
577
0
    if (pp == NULL)
578
0
        return len;
579
580
0
    if (*pp == NULL) {
581
0
        out = (unsigned char*)XMALLOC((size_t)len, NULL, DYNAMIC_TYPE_ASN1);
582
0
        if (out == NULL)
583
0
            return WOLFSSL_FATAL_ERROR;
584
0
    }
585
0
    else {
586
0
        out = *pp;
587
0
    }
588
589
0
    idx = SetObjectId((int)oidSz, out);
590
0
    XMEMCPY(out + idx, oid, oidSz);
591
0
    if (*pp == NULL)
592
0
        *pp = out;
593
0
    else
594
0
        *pp += len;
595
596
0
    return len;
597
0
}
598
599
#if defined(OPENSSL_ALL) && !defined(NO_CERTS)
600
/* Copy an EC group.
601
 *
602
 * Only used by wolfSSL_EC_KEY_dup at this time.
603
 *
604
 * @param [in, out] dst  Destination EC group.
605
 * @param [in]      src  Source EC group.
606
 * @return  0 on success.
607
 */
608
static int wolfssl_ec_group_copy(WOLFSSL_EC_GROUP* dst,
609
    const WOLFSSL_EC_GROUP* src)
610
0
{
611
    /* Copy the fields. */
612
0
    dst->curve_idx = src->curve_idx;
613
0
    dst->curve_nid = src->curve_nid;
614
0
    dst->curve_oid = src->curve_oid;
615
616
0
    return 0;
617
0
}
618
#endif /* OPENSSL_ALL && !NO_CERTS */
619
620
/* Copies ecc_key into new WOLFSSL_EC_GROUP object
621
 *
622
 * @param [in] src  EC group to duplicate.
623
 *
624
 * @return  EC group on success.
625
 * @return  NULL on error.
626
 */
627
WOLFSSL_EC_GROUP* wolfSSL_EC_GROUP_dup(const WOLFSSL_EC_GROUP *src)
628
778
{
629
778
    WOLFSSL_EC_GROUP* newGroup = NULL;
630
631
778
    if (src != NULL) {
632
        /* Create new group base on NID in original EC group. */
633
778
        newGroup = wolfSSL_EC_GROUP_new_by_curve_name(src->curve_nid);
634
778
     }
635
636
778
    return newGroup;
637
778
}
638
639
/* Compare two EC groups.
640
 *
641
 * Return code compliant with OpenSSL.
642
 *
643
 * @param [in] a    First EC group.
644
 * @param [in] b    Second EC group.
645
 * @param [in] ctx  Big number context to use when comparing fields. Unused.
646
 *
647
 * @return  0 if equal.
648
 * @return  1 if not equal.
649
 * @return  -1 on error.
650
 */
651
int wolfSSL_EC_GROUP_cmp(const WOLFSSL_EC_GROUP *a, const WOLFSSL_EC_GROUP *b,
652
                         WOLFSSL_BN_CTX *ctx)
653
0
{
654
0
    int ret;
655
656
    /* No BN operations performed. */
657
0
    (void)ctx;
658
659
0
    WOLFSSL_ENTER("wolfSSL_EC_GROUP_cmp");
660
661
    /* Validate parameters. */
662
0
    if ((a == NULL) || (b == NULL)) {
663
0
        WOLFSSL_MSG("wolfSSL_EC_GROUP_cmp Bad arguments");
664
        /* Return error value. */
665
0
        ret = WOLFSSL_FATAL_ERROR;
666
0
    }
667
    /* Compare NID and wolfSSL curve index. */
668
0
    else {
669
        /* 0 when same, 1 when not. */
670
0
        ret = ((a->curve_nid == b->curve_nid) &&
671
0
               (a->curve_idx == b->curve_idx)) ? 0 : 1;
672
0
    }
673
674
0
    return ret;
675
0
}
676
677
#ifndef NO_WOLFSSL_STUB
678
/* Set the ASN.1 flag that indicate encoding of curve.
679
 *
680
 * Stub function - flag not used elsewhere.
681
 * Always encoded as named curve.
682
 *
683
 * @param [in] group  EC group to modify.
684
 * @param [in] flag   ASN.1 flag to set. Valid values:
685
 *                    OPENSSL_EC_EXPLICIT_CURVE, OPENSSL_EC_NAMED_CURVE
686
 */
687
void wolfSSL_EC_GROUP_set_asn1_flag(WOLFSSL_EC_GROUP *group, int flag)
688
0
{
689
0
    (void)group;
690
0
    (void)flag;
691
692
0
    WOLFSSL_ENTER("wolfSSL_EC_GROUP_set_asn1_flag");
693
0
    WOLFSSL_STUB("EC_GROUP_set_asn1_flag");
694
0
}
695
#endif
696
697
/* Get the curve NID of the group.
698
 *
699
 * Return code compliant with OpenSSL.
700
 *
701
 * @param [in] group  EC group.
702
 * @return  Curve NID on success.
703
 * @return  0 on error.
704
 */
705
int wolfSSL_EC_GROUP_get_curve_name(const WOLFSSL_EC_GROUP *group)
706
0
{
707
0
    int nid = 0;
708
0
    WOLFSSL_ENTER("wolfSSL_EC_GROUP_get_curve_name");
709
710
0
    if (group == NULL) {
711
0
        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_curve_name Bad arguments");
712
0
    }
713
0
    else {
714
0
        nid = group->curve_nid;
715
0
    }
716
717
0
    return nid;
718
0
}
719
720
/* Get the degree (curve size in bits) of the EC group.
721
 *
722
 * Return code compliant with OpenSSL.
723
 *
724
 * @return  Degree of the curve on success.
725
 * @return  0 on error.
726
 */
727
int wolfSSL_EC_GROUP_get_degree(const WOLFSSL_EC_GROUP *group)
728
0
{
729
0
    int degree = 0;
730
731
0
    WOLFSSL_ENTER("wolfSSL_EC_GROUP_get_degree");
732
733
0
    if (group == NULL) {
734
0
        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_degree Bad arguments");
735
0
    }
736
0
    else {
737
0
        switch (group->curve_nid) {
738
0
            case WC_NID_secp112r1:
739
0
            case WC_NID_secp112r2:
740
0
                degree = 112;
741
0
                break;
742
0
            case WC_NID_secp128r1:
743
0
            case WC_NID_secp128r2:
744
0
                degree = 128;
745
0
                break;
746
0
            case WC_NID_secp160k1:
747
0
            case WC_NID_secp160r1:
748
0
            case WC_NID_secp160r2:
749
0
            case WC_NID_brainpoolP160r1:
750
0
                degree = 160;
751
0
                break;
752
0
            case WC_NID_secp192k1:
753
0
            case WC_NID_brainpoolP192r1:
754
0
            case WC_NID_X9_62_prime192v1:
755
0
            case WC_NID_X9_62_prime192v2:
756
0
            case WC_NID_X9_62_prime192v3:
757
0
                degree = 192;
758
0
                break;
759
0
            case WC_NID_secp224k1:
760
0
            case WC_NID_secp224r1:
761
0
            case WC_NID_brainpoolP224r1:
762
0
                degree = 224;
763
0
                break;
764
0
            case WC_NID_X9_62_prime239v1:
765
0
            case WC_NID_X9_62_prime239v2:
766
0
            case WC_NID_X9_62_prime239v3:
767
0
                degree = 239;
768
0
                break;
769
0
            case WC_NID_secp256k1:
770
0
            case WC_NID_brainpoolP256r1:
771
0
            case WC_NID_X9_62_prime256v1:
772
0
                degree = 256;
773
0
                break;
774
0
            case WC_NID_brainpoolP320r1:
775
0
                degree = 320;
776
0
                break;
777
0
            case WC_NID_secp384r1:
778
0
            case WC_NID_brainpoolP384r1:
779
0
                degree = 384;
780
0
                break;
781
0
            case WC_NID_brainpoolP512r1:
782
0
                degree = 512;
783
0
                break;
784
0
            case WC_NID_secp521r1:
785
0
                degree = 521;
786
0
                break;
787
0
        }
788
0
    }
789
790
0
    return degree;
791
0
}
792
#endif /* OPENSSL_EXTRA */
793
794
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
795
/* Get the length of the order in bits of the EC group.
796
 *
797
 * TODO: consider switch statement or calculating directly from hex string
798
 * array instead of using mp_int.
799
 *
800
 * @param [in] group  EC group.
801
 * @return  Length of order in bits on success.
802
 * @return  0 on error.
803
 */
804
int wolfSSL_EC_GROUP_order_bits(const WOLFSSL_EC_GROUP *group)
805
0
{
806
0
    int ret = 0;
807
0
    WC_DECLARE_VAR(order, mp_int, 1, 0);
808
809
    /* Validate parameter. */
810
0
    if ((group == NULL) || (group->curve_idx < 0)) {
811
0
        WOLFSSL_MSG("wolfSSL_EC_GROUP_order_bits NULL error");
812
0
        ret = WOLFSSL_FATAL_ERROR;
813
0
    }
814
815
0
#ifdef WOLFSSL_SMALL_STACK
816
0
    if (ret == 0) {
817
        /* Allocate memory for mp_int that will hold order value. */
818
0
        order = (mp_int *)XMALLOC(sizeof(*order), NULL,
819
0
            DYNAMIC_TYPE_TMP_BUFFER);
820
0
        if (order == NULL) {
821
0
            ret = WOLFSSL_FATAL_ERROR;
822
0
        }
823
0
    }
824
0
#endif
825
826
0
    if (ret == 0) {
827
        /* Initialize mp_int. */
828
0
        ret = mp_init(order);
829
0
    }
830
831
0
    if (ret == 0) {
832
        /* Read hex string of order from wolfCrypt array of curves. */
833
0
        ret = mp_read_radix(order, ecc_sets[group->curve_idx].order,
834
0
            MP_RADIX_HEX);
835
0
        if (ret == 0) {
836
            /* Get bits of order. */
837
0
            ret = mp_count_bits(order);
838
0
        }
839
        /* Clear and free mp_int. */
840
0
        mp_clear(order);
841
0
    }
842
843
0
    WC_FREE_VAR_EX(order, NULL, DYNAMIC_TYPE_TMP_BUFFER);
844
845
    /* Convert error code to length of 0. */
846
0
    if (ret < 0) {
847
0
        ret = 0;
848
0
    }
849
850
0
    return ret;
851
0
}
852
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
853
854
#if defined(OPENSSL_EXTRA)
855
/* Get the order of the group as a BN.
856
 *
857
 * Return code compliant with OpenSSL.
858
 *
859
 * @param [in]      group  EC group.
860
 * @param [in, out] order  BN to hold order value.
861
 * @param [in]      ctx    Context to use for BN operations. Unused.
862
 * @return  1 on success.
863
 * @return  0 on error.
864
 */
865
int wolfSSL_EC_GROUP_get_order(const WOLFSSL_EC_GROUP *group,
866
    WOLFSSL_BIGNUM *order, WOLFSSL_BN_CTX *ctx)
867
0
{
868
0
    int ret = 1;
869
0
    mp_int* mp = NULL;
870
871
    /* No BN operations performed - done with mp_int in BN. */
872
0
    (void)ctx;
873
874
    /* Validate parameters. */
875
0
    if ((group == NULL) || (order == NULL) || (order->internal == NULL)) {
876
0
        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order NULL error");
877
0
        ret = 0;
878
0
    }
879
880
0
    if (ret == 1 &&
881
0
            (group->curve_idx < 0 || !wc_ecc_is_valid_idx(group->curve_idx))) {
882
0
        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order Bad group idx");
883
0
        ret = 0;
884
0
    }
885
886
0
    if (ret == 1) {
887
0
        mp = (mp_int*)order->internal;
888
0
    }
889
    /* Initialize */
890
0
    if ((ret == 1) && (mp_init(mp) != MP_OKAY)) {
891
0
        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order mp_init failure");
892
0
        ret = 0;
893
0
    }
894
    /* Read hex string of order from wolfCrypt array of curves. */
895
0
    if ((ret == 1) && (mp_read_radix(mp, ecc_sets[group->curve_idx].order,
896
0
            MP_RADIX_HEX) != MP_OKAY)) {
897
0
        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order mp_read order failure");
898
        /* Zero out any partial value but don't free. */
899
0
        mp_zero(mp);
900
0
        ret = 0;
901
0
    }
902
903
0
    return ret;
904
0
}
905
906
#endif /* OPENSSL_EXTRA */
907
908
/* End EC_GROUP */
909
910
/* Start EC_POINT */
911
912
#if defined(OPENSSL_EXTRA)
913
914
/* Set data of EC point into internal, wolfCrypt EC point object.
915
 *
916
 * EC_POINT Openssl -> WolfSSL
917
 *
918
 * @param [in, out] p  EC point to update.
919
 * @return  1 on success.
920
 * @return  -1 on failure.
921
 */
922
static int ec_point_internal_set(WOLFSSL_EC_POINT *p)
923
2.33k
{
924
2.33k
    int ret = 1;
925
926
2.33k
    WOLFSSL_ENTER("ec_point_internal_set");
927
928
    /* Validate parameter. */
929
2.33k
    if ((p == NULL) || (p->internal == NULL)) {
930
0
        WOLFSSL_MSG("ECPoint NULL error");
931
0
        ret = WOLFSSL_FATAL_ERROR;
932
0
    }
933
2.33k
    else {
934
        /* Get internal point as a wolfCrypt EC point. */
935
2.33k
        ecc_point* point = (ecc_point*)p->internal;
936
937
        /* Set X ordinate if available. */
938
2.33k
        if ((p->X != NULL) && (wolfssl_bn_get_value(p->X, point->x) != 1)) {
939
0
            WOLFSSL_MSG("ecc point X error");
940
0
            ret = WOLFSSL_FATAL_ERROR;
941
0
        }
942
        /* Set Y ordinate if available. */
943
2.33k
        if ((ret == 1) && (p->Y != NULL) && (wolfssl_bn_get_value(p->Y,
944
955
                point->y) != 1)) {
945
0
            WOLFSSL_MSG("ecc point Y error");
946
0
            ret = WOLFSSL_FATAL_ERROR;
947
0
        }
948
        /* Set Z ordinate if available. */
949
2.33k
        if ((ret == 1) && (p->Z != NULL) && (wolfssl_bn_get_value(p->Z,
950
955
                point->z) != 1)) {
951
0
            WOLFSSL_MSG("ecc point Z error");
952
0
            ret = WOLFSSL_FATAL_ERROR;
953
0
        }
954
        /* Internal values set when operations succeeded. */
955
2.33k
        p->inSet = (ret == 1);
956
2.33k
    }
957
958
2.33k
    return ret;
959
2.33k
}
960
961
/* Set data of internal, wolfCrypt EC point object into EC point.
962
 *
963
 * EC_POINT WolfSSL -> OpenSSL
964
 *
965
 * @param [in, out] p  EC point to update.
966
 * @return  1 on success.
967
 * @return  -1 on failure.
968
 */
969
static int ec_point_external_set(WOLFSSL_EC_POINT *p)
970
2.14k
{
971
2.14k
    int ret = 1;
972
973
2.14k
    WOLFSSL_ENTER("ec_point_external_set");
974
975
    /* Validate parameter. */
976
2.14k
    if ((p == NULL) || (p->internal == NULL)) {
977
0
        WOLFSSL_MSG("ECPoint NULL error");
978
0
        ret = WOLFSSL_FATAL_ERROR;
979
0
    }
980
2.14k
    else {
981
        /* Get internal point as a wolfCrypt EC point. */
982
2.14k
        ecc_point* point = (ecc_point*)p->internal;
983
984
        /* Set X ordinate. */
985
2.14k
        if (wolfssl_bn_set_value(&p->X, point->x) != 1) {
986
0
            WOLFSSL_MSG("ecc point X error");
987
0
            ret = WOLFSSL_FATAL_ERROR;
988
0
        }
989
        /* Set Y ordinate. */
990
2.14k
        if ((ret == 1) && (wolfssl_bn_set_value(&p->Y, point->y) != 1)) {
991
0
            WOLFSSL_MSG("ecc point Y error");
992
0
            ret = WOLFSSL_FATAL_ERROR;
993
0
        }
994
        /* Set Z ordinate. */
995
2.14k
        if ((ret == 1) && (wolfssl_bn_set_value(&p->Z, point->z) != 1)) {
996
0
            WOLFSSL_MSG("ecc point Z error");
997
0
            ret = WOLFSSL_FATAL_ERROR;
998
0
        }
999
        /* External values set when operations succeeded. */
1000
2.14k
        p->exSet = (ret == 1);
1001
2.14k
    }
1002
1003
2.14k
    return ret;
1004
2.14k
}
1005
1006
/* Setup internals of EC point.
1007
 *
1008
 * Assumes point is not NULL.
1009
 *
1010
 * @param [in, out] point  EC point to update.
1011
 * @return  1 on success.
1012
 * @return  0 on failure.
1013
 */
1014
2.46k
static int ec_point_setup(const WOLFSSL_EC_POINT *point) {
1015
2.46k
    int ret = 1;
1016
1017
    /* Check if internal values need setting. */
1018
2.46k
    if (!point->inSet) {
1019
654
        WOLFSSL_MSG("No ECPoint internal set, do it");
1020
1021
        /* Forcing to non-constant type to update internals. */
1022
654
        if (ec_point_internal_set((WOLFSSL_EC_POINT *)point) != 1) {
1023
0
            WOLFSSL_MSG("ec_point_internal_set failed");
1024
0
            ret = 0;
1025
0
        }
1026
654
    }
1027
1028
2.46k
    return ret;
1029
2.46k
}
1030
1031
/* Create a new EC point from the group.
1032
 *
1033
 * @param [in] group  EC group.
1034
 * @return  EC point on success.
1035
 * @return  NULL on error.
1036
 */
1037
WOLFSSL_EC_POINT* wolfSSL_EC_POINT_new(const WOLFSSL_EC_GROUP* group)
1038
3.26k
{
1039
3.26k
    int err = 0;
1040
3.26k
    WOLFSSL_EC_POINT* point = NULL;
1041
1042
3.26k
    WOLFSSL_ENTER("wolfSSL_EC_POINT_new");
1043
1044
    /* Validate parameter. */
1045
3.26k
    if (group == NULL) {
1046
0
        WOLFSSL_MSG("wolfSSL_EC_POINT_new NULL error");
1047
0
        err = 1;
1048
0
    }
1049
1050
3.26k
    if (!err) {
1051
        /* Allocate memory for new EC point. */
1052
3.26k
        point = (WOLFSSL_EC_POINT*)XMALLOC(sizeof(WOLFSSL_EC_POINT), NULL,
1053
3.26k
            DYNAMIC_TYPE_ECC);
1054
3.26k
        if (point == NULL) {
1055
0
            WOLFSSL_MSG("wolfSSL_EC_POINT_new malloc ecc point failure");
1056
0
            err = 1;
1057
0
        }
1058
3.26k
    }
1059
3.26k
    if (!err) {
1060
        /* Clear fields of EC point. */
1061
3.26k
        XMEMSET(point, 0, sizeof(WOLFSSL_EC_POINT));
1062
1063
        /* Allocate internal EC point. */
1064
3.26k
        point->internal = wc_ecc_new_point();
1065
3.26k
        if (point->internal == NULL) {
1066
0
            WOLFSSL_MSG("ecc_new_point failure");
1067
0
            err = 1;
1068
0
        }
1069
3.26k
    }
1070
1071
3.26k
    if (err) {
1072
0
        XFREE(point, NULL, DYNAMIC_TYPE_ECC);
1073
0
        point = NULL;
1074
0
    }
1075
3.26k
    return point;
1076
3.26k
}
1077
1078
#endif /* OPENSSL_EXTRA */
1079
1080
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
1081
/* Dispose of the EC point.
1082
 *
1083
 * Cannot use point after this call.
1084
 *
1085
 * @param [in, out] point  EC point to free.
1086
 */
1087
void wolfSSL_EC_POINT_free(WOLFSSL_EC_POINT *point)
1088
3.26k
{
1089
3.26k
    WOLFSSL_ENTER("wolfSSL_EC_POINT_free");
1090
1091
3.26k
    if (point != NULL) {
1092
3.26k
        if (point->internal != NULL) {
1093
3.26k
            wc_ecc_del_point((ecc_point*)point->internal);
1094
3.26k
            point->internal = NULL;
1095
3.26k
        }
1096
1097
        /* Free ordinates. */
1098
3.26k
        wolfSSL_BN_free(point->X);
1099
3.26k
        wolfSSL_BN_free(point->Y);
1100
3.26k
        wolfSSL_BN_free(point->Z);
1101
        /* Clear fields. */
1102
3.26k
        point->X = NULL;
1103
3.26k
        point->Y = NULL;
1104
3.26k
        point->Z = NULL;
1105
3.26k
        point->inSet = 0;
1106
3.26k
        point->exSet = 0;
1107
1108
        /* Dispose of EC point. */
1109
3.26k
        XFREE(point, NULL, DYNAMIC_TYPE_ECC);
1110
3.26k
    }
1111
3.26k
}
1112
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
1113
1114
#ifdef OPENSSL_EXTRA
1115
1116
/* Clear and dispose of the EC point.
1117
 *
1118
 * Cannot use point after this call.
1119
 *
1120
 * @param [in, out] point  EC point to free.
1121
 */
1122
void wolfSSL_EC_POINT_clear_free(WOLFSSL_EC_POINT *point)
1123
0
{
1124
0
    WOLFSSL_ENTER("wolfSSL_EC_POINT_clear_free");
1125
1126
0
    if (point != NULL) {
1127
0
        if (point->internal != NULL) {
1128
            /* Force internal point to be zeros. */
1129
0
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
1130
0
            wc_ecc_forcezero_point((ecc_point*)point->internal);
1131
    #else
1132
            ecc_point* p = (ecc_point*)point->internal;
1133
            mp_forcezero(p->x);
1134
            mp_forcezero(p->y);
1135
            mp_forcezero(p->z);
1136
    #endif
1137
0
            wc_ecc_del_point((ecc_point*)point->internal);
1138
0
            point->internal = NULL;
1139
0
        }
1140
1141
        /* Clear the ordinates before freeing. */
1142
0
        wolfSSL_BN_clear_free(point->X);
1143
0
        wolfSSL_BN_clear_free(point->Y);
1144
0
        wolfSSL_BN_clear_free(point->Z);
1145
        /* Clear fields. */
1146
0
        point->X = NULL;
1147
0
        point->Y = NULL;
1148
0
        point->Z = NULL;
1149
0
        point->inSet = 0;
1150
0
        point->exSet = 0;
1151
1152
        /* Dispose of EC point. */
1153
0
        XFREE(point, NULL, DYNAMIC_TYPE_ECC);
1154
0
    }
1155
0
}
1156
1157
/* Print out the internals of EC point in debug and when logging callback set.
1158
 *
1159
 * Not an OpenSSL API.
1160
 *
1161
 * TODO: Use WOLFSSL_MSG_EX()?
1162
 *
1163
 * @param [in] msg    Message to prepend.
1164
 * @param [in] point  EC point to print.
1165
 */
1166
void wolfSSL_EC_POINT_dump(const char *msg, const WOLFSSL_EC_POINT *point)
1167
784
{
1168
#if defined(DEBUG_WOLFSSL)
1169
    char *num;
1170
1171
    WOLFSSL_ENTER("wolfSSL_EC_POINT_dump");
1172
1173
    /* Only print when debugging on. */
1174
    if (WOLFSSL_IS_DEBUG_ON()) {
1175
        if (point == NULL) {
1176
            /* No point passed in so just put out "NULL". */
1177
            WOLFSSL_MSG_EX("%s = NULL\n", msg);
1178
        }
1179
        else {
1180
            /* Put out message and status of internal/external data set. */
1181
            WOLFSSL_MSG_EX("%s:\n\tinSet=%d, exSet=%d\n", msg, point->inSet,
1182
                point->exSet);
1183
            /* Get x-ordinate as a hex string and print. */
1184
            num = wolfSSL_BN_bn2hex(point->X);
1185
            WOLFSSL_MSG_EX("\tX = %s\n", num);
1186
            XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL);
1187
            /* Get x-ordinate as a hex string and print. */
1188
            num = wolfSSL_BN_bn2hex(point->Y);
1189
            WOLFSSL_MSG_EX("\tY = %s\n", num);
1190
            XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL);
1191
            /* Get z-ordinate as a hex string and print. */
1192
            num = wolfSSL_BN_bn2hex(point->Z);
1193
            WOLFSSL_MSG_EX("\tZ = %s\n", num);
1194
            XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL);
1195
        }
1196
    }
1197
#else
1198
784
    (void)msg;
1199
784
    (void)point;
1200
784
#endif
1201
784
}
1202
1203
/* Convert EC point to hex string that as either uncompressed or compressed.
1204
 *
1205
 * ECC point compression types were not included in selftest ecc.h
1206
 *
1207
 * @param [in] group  EC group for point.
1208
 * @param [in] point  EC point to encode.
1209
 * @param [in] form   Format of encoding. Valid values:
1210
 *                    POINT_CONVERSION_UNCOMPRESSED, POINT_CONVERSION_COMPRESSED
1211
 * @param [in] ctx    Context to use for BN operations. Unused.
1212
 * @return  Allocated hex string on success.
1213
 * @return  NULL on error.
1214
 */
1215
char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group,
1216
    const WOLFSSL_EC_POINT* point, int form, WOLFSSL_BN_CTX* ctx)
1217
0
{
1218
0
    static const char* hexDigit = "0123456789ABCDEF";
1219
0
    char* hex = NULL;
1220
0
    int i;
1221
0
    int sz = 0;
1222
0
    int len = 0;
1223
0
    int err = 0;
1224
1225
    /* No BN operations performed. */
1226
0
    (void)ctx;
1227
1228
    /* Validate parameters. */
1229
0
    if ((group == NULL) || (point == NULL)) {
1230
0
        err = 1;
1231
0
    }
1232
    /* Get curve id expects a positive index. */
1233
0
    if ((!err) && (group->curve_idx < 0)) {
1234
0
        err = 1;
1235
0
    }
1236
1237
0
    if (!err) {
1238
        /* Get curve id to look up ordinate size. */
1239
0
        int id = wc_ecc_get_curve_id(group->curve_idx);
1240
        /* Get size of ordinate. */
1241
0
        if ((sz = wc_ecc_get_curve_size_from_id(id)) < 0) {
1242
0
            err = 1;
1243
0
        }
1244
0
    }
1245
0
    if (!err) {
1246
        /* <format byte> <x-ordinate> [<y-ordinate>] */
1247
0
        len = sz + 1;
1248
0
        if (form == WC_POINT_CONVERSION_UNCOMPRESSED) {
1249
            /* Include y ordinate when uncompressed. */
1250
0
            len += sz;
1251
0
        }
1252
1253
        /* Hex string: allocate 2 bytes to represent each byte plus 1 for '\0'.
1254
         */
1255
0
        hex = (char*)XMALLOC((size_t)(2 * len + 1), NULL, DYNAMIC_TYPE_ECC);
1256
0
        if (hex == NULL) {
1257
0
            err = 1;
1258
0
        }
1259
0
    }
1260
0
    if (!err) {
1261
        /* Make bytes all zeros to allow for ordinate values less than max size.
1262
         */
1263
0
        XMEMSET(hex, 0, (size_t)(2 * len + 1));
1264
1265
        /* Calculate offset as leading zeros not encoded. */
1266
0
        i = sz - mp_unsigned_bin_size((mp_int*)point->X->internal) + 1;
1267
        /* Put in x-ordinate after format byte. */
1268
0
        if (mp_to_unsigned_bin((mp_int*)point->X->internal, (byte*)(hex + i)) <
1269
0
                0) {
1270
0
            err = 1;
1271
0
        }
1272
0
    }
1273
0
    if (!err) {
1274
0
        if (form == WC_POINT_CONVERSION_COMPRESSED) {
1275
            /* Compressed format byte value dependent on whether y-ordinate is
1276
             * odd.
1277
             */
1278
0
            hex[0] = mp_isodd((mp_int*)point->Y->internal) ?
1279
0
                ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN;
1280
            /* No y-ordinate. */
1281
0
        }
1282
0
        else {
1283
            /* Put in uncompressed format byte. */
1284
0
            hex[0] = ECC_POINT_UNCOMP;
1285
            /* Calculate offset as leading zeros not encoded. */
1286
0
            i = 1 + 2 * sz - mp_unsigned_bin_size((mp_int*)point->Y->internal);
1287
            /* Put in y-ordinate after x-ordinate. */
1288
0
            if (mp_to_unsigned_bin((mp_int*)point->Y->internal,
1289
0
                    (byte*)(hex + i)) < 0) {
1290
0
                err = 1;
1291
0
            }
1292
0
        }
1293
0
    }
1294
0
    if (!err) {
1295
        /* Convert binary encoding to hex string. */
1296
        /* Start at end so as not to overwrite. */
1297
0
        for (i = len-1; i >= 0; i--) {
1298
            /* Get byte value and store has hex string. */
1299
0
            byte b = (byte)hex[i];
1300
0
            hex[i * 2 + 1] = hexDigit[b  & 0xf];
1301
0
            hex[i * 2    ] = hexDigit[b >>   4];
1302
0
        }
1303
        /* Memset put trailing zero or '\0' on end of string. */
1304
0
    }
1305
1306
0
    if (err && (hex != NULL)) {
1307
        /* Dispose of allocated data not being returned. */
1308
0
        XFREE(hex,  NULL, DYNAMIC_TYPE_ECC);
1309
0
        hex = NULL;
1310
0
    }
1311
    /* Return hex string encoding. */
1312
0
    return hex;
1313
0
}
1314
1315
static size_t hex_to_bytes(const char *hex, unsigned char *output, size_t sz)
1316
0
{
1317
0
    word32 i;
1318
0
    for (i = 0; i < sz; i++) {
1319
0
        signed char ch1, ch2;
1320
0
        ch1 = HexCharToByte(hex[i * 2]);
1321
0
        ch2 = HexCharToByte(hex[i * 2 + 1]);
1322
0
        if ((ch1 < 0) || (ch2 < 0)) {
1323
0
            WOLFSSL_MSG("hex_to_bytes: syntax error");
1324
0
            return 0;
1325
0
        }
1326
0
        output[i] = (unsigned char)((ch1 << 4) + ch2);
1327
0
    }
1328
0
    return sz;
1329
0
}
1330
1331
WOLFSSL_EC_POINT* wolfSSL_EC_POINT_hex2point(const WOLFSSL_EC_GROUP *group,
1332
            const char *hex, WOLFSSL_EC_POINT*p, WOLFSSL_BN_CTX *ctx)
1333
0
{
1334
    /* for uncompressed mode */
1335
0
    size_t str_sz;
1336
0
    WOLFSSL_BIGNUM *Gx  = NULL;
1337
0
    WOLFSSL_BIGNUM *Gy  = NULL;
1338
0
    char   strGx[MAX_ECC_BYTES * 2 + 1];
1339
1340
    /* for compressed mode */
1341
0
    int    key_sz;
1342
0
    byte   *octGx = (byte *)strGx; /* octGx[MAX_ECC_BYTES] */
1343
1344
0
    int p_alloc = 0;
1345
0
    int ret;
1346
1347
0
    WOLFSSL_ENTER("wolfSSL_EC_POINT_hex2point");
1348
1349
0
    if (group == NULL || hex == NULL || ctx == NULL)
1350
0
        return NULL;
1351
1352
0
    if (p == NULL) {
1353
0
        if ((p = wolfSSL_EC_POINT_new(group)) == NULL) {
1354
0
            WOLFSSL_MSG("wolfSSL_EC_POINT_new");
1355
0
            goto err;
1356
0
        }
1357
0
        p_alloc = 1;
1358
0
    }
1359
1360
0
    key_sz = (wolfSSL_EC_GROUP_get_degree(group) + 7) / 8;
1361
0
    if (key_sz <= 0 || (size_t)key_sz > MAX_ECC_BYTES)
1362
0
        goto err;
1363
1364
0
    if (hex[0] ==  '0' && hex[1] == '4') { /* uncompressed mode */
1365
0
        str_sz = (size_t)key_sz * 2;
1366
1367
        /* The uncompressed encoding is exactly 2 + 4*key_sz hex chars
1368
         * ("04" prefix plus X and Y as 2*key_sz hex chars each). Reject
1369
         * any other length so XMEMCPY/BN_hex2bn cannot read past the end
1370
         * of the input and trailing garbage is not silently absorbed. */
1371
0
        if (XSTRLEN(hex + 2) != str_sz * 2)
1372
0
            goto err;
1373
1374
0
        XMEMSET(strGx, 0x0, str_sz + 1);
1375
0
        XMEMCPY(strGx, hex + 2, str_sz);
1376
1377
0
        if (wolfSSL_BN_hex2bn(&Gx, strGx) == 0)
1378
0
            goto err;
1379
1380
0
        if (wolfSSL_BN_hex2bn(&Gy, hex + 2 + str_sz) == 0)
1381
0
            goto err;
1382
1383
0
        ret = wolfSSL_EC_POINT_set_affine_coordinates_GFp
1384
0
                                            (group, p, Gx, Gy, ctx);
1385
1386
0
        if (ret != WOLFSSL_SUCCESS) {
1387
0
            WOLFSSL_MSG("wolfSSL_EC_POINT_set_affine_coordinates_GFp");
1388
0
            goto err;
1389
0
        }
1390
0
    }
1391
0
    else if (hex[0] == '0' && (hex[1] == '2' || hex[1] == '3')) {
1392
        /* The SEC 1 compressed encoding is exactly 1 + key_sz bytes, so
1393
         * the hex payload after the "02"/"03" prefix must be exactly
1394
         * 2*key_sz hex chars. Compare the input length directly (rather
1395
         * than XSTRLEN/2) so that odd-length inputs cannot slip past via
1396
         * integer truncation. The exact-match rejects oversized inputs
1397
         * (preventing a hex_to_bytes() write past strGx) and undersized
1398
         * inputs (preventing wolfSSL_ECPoint_d2i() from reading
1399
         * uninitialized stack bytes as the X coordinate). */
1400
0
        if (XSTRLEN(hex + 2) != (size_t)key_sz * 2)
1401
0
            goto err;
1402
0
        octGx[0] = (hex[1] == '2') ? ECC_POINT_COMP_EVEN
1403
0
                                   : ECC_POINT_COMP_ODD;
1404
0
        if (hex_to_bytes(hex + 2, octGx + 1, (size_t)key_sz)
1405
0
                                            != (size_t)key_sz) {
1406
0
            goto err;
1407
0
        }
1408
0
        if (wolfSSL_ECPoint_d2i(octGx, (word32)key_sz + 1, group, p)
1409
0
                                            != WOLFSSL_SUCCESS) {
1410
0
            goto err;
1411
0
        }
1412
0
    }
1413
0
    else
1414
0
        goto err;
1415
1416
0
    wolfSSL_BN_free(Gx);
1417
0
    wolfSSL_BN_free(Gy);
1418
0
    return p;
1419
1420
0
err:
1421
0
    wolfSSL_BN_free(Gx);
1422
0
    wolfSSL_BN_free(Gy);
1423
0
    if (p_alloc) {
1424
0
        wolfSSL_EC_POINT_free(p);
1425
0
    }
1426
0
    return NULL;
1427
1428
0
}
1429
1430
/* Encode the EC point as an uncompressed point in DER.
1431
 *
1432
 * Return code compliant with OpenSSL.
1433
 * Not OpenSSL API.
1434
 *
1435
 * @param [in]      group  EC group point belongs to.
1436
 * @param [in]      point  EC point to encode.
1437
 * @param [out]     out    Buffer to encode into. May be NULL.
1438
 * @param [in, out] len    On in, length of buffer in bytes.
1439
 *                         On out, length of encoding in bytes.
1440
 * @return  1 on success.
1441
 * @return  0 on error.
1442
 */
1443
int wolfSSL_ECPoint_i2d(const WOLFSSL_EC_GROUP *group,
1444
    const WOLFSSL_EC_POINT *point, unsigned char *out, unsigned int *len)
1445
0
{
1446
0
    int res = 1;
1447
1448
0
    WOLFSSL_ENTER("wolfSSL_ECPoint_i2d");
1449
1450
    /* Validate parameters. */
1451
0
    if ((group == NULL) || (point == NULL) || (len == NULL)) {
1452
0
        WOLFSSL_MSG("wolfSSL_ECPoint_i2d NULL error");
1453
0
        res = 0;
1454
0
    }
1455
1456
    /* Ensure points internals are set up. */
1457
0
    if ((res == 1) && (ec_point_setup(point) != 1)) {
1458
0
        res = 0;
1459
0
    }
1460
1461
    /* Dump the point if encoding. */
1462
0
    if ((res == 1) && (out != NULL)) {
1463
0
        wolfSSL_EC_POINT_dump("i2d p", point);
1464
0
    }
1465
1466
0
    if (res == 1) {
1467
        /* DER encode point in uncompressed format. */
1468
0
        int ret = wc_ecc_export_point_der(group->curve_idx,
1469
0
            (ecc_point*)point->internal, out, len);
1470
        /* Check return. When out is NULL, return will be length only error. */
1471
0
        if ((ret != MP_OKAY) && ((out != NULL) ||
1472
0
                                 (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E)))) {
1473
0
            WOLFSSL_MSG("wolfSSL_ECPoint_i2d wc_ecc_export_point_der failed");
1474
0
            res = 0;
1475
0
        }
1476
0
    }
1477
1478
0
    return res;
1479
0
}
1480
1481
/* Decode the uncompressed point in DER into EC point.
1482
 *
1483
 * Return code compliant with OpenSSL.
1484
 * Not OpenSSL API.
1485
 *
1486
 * @param [in]      in     Buffer containing DER encoded point.
1487
 * @param [in]      len    Length of data in bytes.
1488
 * @param [in]      group  EC group associated with point.
1489
 * @param [in, out] point  EC point to set data into.
1490
 * @return  1 on success.
1491
 * @return  0 on error.
1492
 */
1493
int wolfSSL_ECPoint_d2i(const unsigned char *in, unsigned int len,
1494
    const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *point)
1495
0
{
1496
0
    int ret = 1;
1497
0
    WOLFSSL_BIGNUM* x = NULL;
1498
0
    WOLFSSL_BIGNUM* y = NULL;
1499
1500
0
    WOLFSSL_ENTER("wolfSSL_ECPoint_d2i");
1501
1502
    /* Validate parameters. */
1503
0
    if ((in == NULL) || (group == NULL) || (point == NULL) ||
1504
0
            (point->internal == NULL)) {
1505
0
        WOLFSSL_MSG("wolfSSL_ECPoint_d2i NULL error");
1506
0
        ret = 0;
1507
0
    }
1508
1509
0
    if (ret == 1) {
1510
0
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
1511
        /* Import point into internal EC point. */
1512
0
        if (wc_ecc_import_point_der_ex(in, len, group->curve_idx,
1513
0
                (ecc_point*)point->internal, 0) != MP_OKAY) {
1514
0
            WOLFSSL_MSG("wc_ecc_import_point_der_ex failed");
1515
0
            ret = 0;
1516
0
        }
1517
    #else
1518
        /* ECC_POINT_UNCOMP is not defined CAVP self test so use magic number */
1519
        if (in[0] == 0x04) {
1520
            /* Import point into internal EC point. */
1521
            if (wc_ecc_import_point_der((unsigned char *)in, len,
1522
                    group->curve_idx, (ecc_point*)point->internal) != MP_OKAY) {
1523
                WOLFSSL_MSG("wc_ecc_import_point_der failed");
1524
                ret = 0;
1525
            }
1526
        }
1527
        else {
1528
            WOLFSSL_MSG("Only uncompressed points supported with "
1529
                        "HAVE_SELFTEST");
1530
            ret = 0;
1531
        }
1532
    #endif
1533
0
    }
1534
1535
0
    if (ret == 1)
1536
0
        point->inSet = 1;
1537
1538
    /* Set new external point. */
1539
0
    if (ret == 1 && ec_point_external_set(point) != 1) {
1540
0
        WOLFSSL_MSG("ec_point_external_set failed");
1541
0
        ret = 0;
1542
0
    }
1543
1544
0
    if (ret == 1 && !wolfSSL_BN_is_one(point->Z)) {
1545
0
#if !defined(WOLFSSL_SP_MATH) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
1546
0
        x = wolfSSL_BN_new();
1547
0
        y = wolfSSL_BN_new();
1548
0
        if (x == NULL || y == NULL)
1549
0
            ret = 0;
1550
1551
0
        if (ret == 1 && wolfSSL_EC_POINT_get_affine_coordinates_GFp(group,
1552
0
                point, x, y, NULL) != 1) {
1553
0
            WOLFSSL_MSG("wolfSSL_EC_POINT_get_affine_coordinates_GFp failed");
1554
0
            ret = 0;
1555
0
        }
1556
1557
        /* wolfSSL_EC_POINT_set_affine_coordinates_GFp checks that the point is
1558
         * on the curve. */
1559
0
        if (ret == 1 && wolfSSL_EC_POINT_set_affine_coordinates_GFp(group,
1560
0
                point, x, y, NULL) != 1) {
1561
0
            WOLFSSL_MSG("wolfSSL_EC_POINT_set_affine_coordinates_GFp failed");
1562
0
            ret = 0;
1563
0
        }
1564
#else
1565
        WOLFSSL_MSG("Importing non-affine point. This may cause issues in math "
1566
                    "operations later on.");
1567
#endif
1568
0
    }
1569
0
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
1570
    /* Validate that the imported point lies on the curve.  The Z!=1 path
1571
     * above validates via set_affine_coordinates_GFp, but for affine
1572
     * imports (Z==1), the common case for uncompressed points, that
1573
     * block is skipped.  Check unconditionally so no import path can
1574
     * bypass validation. */
1575
0
    if (ret == 1 && wolfSSL_EC_POINT_is_on_curve(group,
1576
0
            (WOLFSSL_EC_POINT *)point, NULL) != 1) {
1577
0
        WOLFSSL_MSG("wolfSSL_ECPoint_d2i: point not on curve");
1578
0
        ret = 0;
1579
0
    }
1580
0
#endif
1581
1582
0
    if (ret == 1) {
1583
        /* Dump new point. */
1584
0
        wolfSSL_EC_POINT_dump("d2i p", point);
1585
0
    }
1586
1587
0
    wolfSSL_BN_free(x);
1588
0
    wolfSSL_BN_free(y);
1589
1590
0
    return ret;
1591
0
}
1592
1593
/* Encode point as octet string.
1594
 *
1595
 * HYBRID not supported.
1596
 *
1597
 * @param [in]  group  EC group that point belongs to.
1598
 * @param [in]  point  EC point to encode.
1599
 * @param [in]  form   Format of encoding. Valid values:
1600
 *                     POINT_CONVERSION_UNCOMPRESSED,POINT_CONVERSION_COMPRESSED
1601
 * @param [out] buf    Buffer to write encoding into.
1602
 * @param [in]  len    Length of buffer.
1603
 * @param [in]  ctx    Context to use for BN operations. Unused.
1604
 * @return  Length of encoded data on success.
1605
 * @return  0 on error.
1606
 */
1607
size_t wolfSSL_EC_POINT_point2oct(const WOLFSSL_EC_GROUP *group,
1608
   const WOLFSSL_EC_POINT *point, int form, byte *buf, size_t len,
1609
   WOLFSSL_BN_CTX *ctx)
1610
0
{
1611
0
    int err = 0;
1612
0
    word32 enc_len = (word32)len;
1613
0
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
1614
0
    int compressed = ((form == WC_POINT_CONVERSION_COMPRESSED) ? 1 : 0);
1615
0
#endif /* !HAVE_SELFTEST */
1616
1617
0
    WOLFSSL_ENTER("wolfSSL_EC_POINT_point2oct");
1618
1619
    /* No BN operations performed. */
1620
0
    (void)ctx;
1621
1622
    /* Validate parameters. */
1623
0
    if ((group == NULL) || (point == NULL)) {
1624
0
        err = 1;
1625
0
    }
1626
1627
    /* Ensure points internals are set up. */
1628
0
    if ((!err) && (ec_point_setup(point) != 1)) {
1629
0
        err = 1;
1630
0
    }
1631
1632
    /* Special case when point is infinity. */
1633
0
    if ((!err) && wolfSSL_EC_POINT_is_at_infinity(group, point)) {
1634
        /* Encoding is a single octet: 0x00. */
1635
0
        enc_len = 1;
1636
0
        if (buf != NULL) {
1637
            /* Check whether buffer has space. */
1638
0
            if (len < 1) {
1639
0
                wolfSSL_ECerr(WOLFSSL_EC_F_EC_GFP_SIMPLE_POINT2OCT, BUFFER_E);
1640
0
                err = 1;
1641
0
            }
1642
0
            else {
1643
                /* Put in encoding of infinity. */
1644
0
                buf[0] = 0x00;
1645
0
            }
1646
0
        }
1647
0
    }
1648
    /* Not infinity. */
1649
0
    else if (!err) {
1650
        /* Validate format. */
1651
0
        if (form != WC_POINT_CONVERSION_UNCOMPRESSED
1652
0
        #ifndef HAVE_SELFTEST
1653
0
                && form != WC_POINT_CONVERSION_COMPRESSED
1654
0
        #endif /* !HAVE_SELFTEST */
1655
0
            ) {
1656
0
            WOLFSSL_MSG("Unsupported point form");
1657
0
            err = 1;
1658
0
        }
1659
1660
0
        if (!err) {
1661
0
            int ret;
1662
1663
0
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
1664
            /* Encode as compressed or uncompressed. */
1665
0
            ret = wc_ecc_export_point_der_ex(group->curve_idx,
1666
0
                (ecc_point*)point->internal, buf, &enc_len, compressed);
1667
    #else
1668
            /* Encode uncompressed point in DER format. */
1669
            ret = wc_ecc_export_point_der(group->curve_idx,
1670
                (ecc_point*)point->internal, buf, &enc_len);
1671
    #endif /* !HAVE_SELFTEST */
1672
            /* Check return. When buf is NULL, return will be length only
1673
             * error.
1674
             */
1675
0
            if (ret != ((buf != NULL) ? MP_OKAY :
1676
0
                                        WC_NO_ERR_TRACE(LENGTH_ONLY_E))) {
1677
0
                err = 1;
1678
0
            }
1679
0
        }
1680
0
    }
1681
1682
#if defined(DEBUG_WOLFSSL)
1683
    if (!err) {
1684
        wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_point2oct point", point);
1685
        WOLFSSL_MSG("\twolfSSL_EC_POINT_point2oct output:");
1686
        WOLFSSL_BUFFER(buf, enc_len);
1687
    }
1688
#endif
1689
1690
    /* On error, return encoding length of 0. */
1691
0
    if (err) {
1692
0
        enc_len = 0;
1693
0
    }
1694
0
    return (size_t)enc_len;
1695
0
}
1696
1697
1698
/* Convert octet string to EC point.
1699
 *
1700
 * @param [in]      group  EC group.
1701
 * @param [in, out] point  EC point to set data into.
1702
 * @param [in]      buf    Buffer holding octet string.
1703
 * @param [in]      len    Length of data in buffer in bytes.
1704
 * @param [in]      ctx    Context to use for BN operations. Unused.
1705
 */
1706
int wolfSSL_EC_POINT_oct2point(const WOLFSSL_EC_GROUP *group,
1707
    WOLFSSL_EC_POINT *point, const unsigned char *buf, size_t len,
1708
    WOLFSSL_BN_CTX *ctx)
1709
0
{
1710
0
    int ret;
1711
1712
0
    WOLFSSL_ENTER("wolfSSL_EC_POINT_oct2point");
1713
1714
    /* No BN operations performed. */
1715
0
    (void)ctx;
1716
1717
    /* Validate parameters. */
1718
0
    if ((group == NULL) || (point == NULL)) {
1719
0
        ret = 0;
1720
0
    }
1721
0
    else {
1722
        /* Decode DER encoding into EC point. */
1723
0
        ret = wolfSSL_ECPoint_d2i((unsigned char*)buf, (unsigned int)len, group,
1724
0
            point);
1725
0
    }
1726
1727
0
    return ret;
1728
0
}
1729
1730
/* Convert an EC point to a single BN.
1731
 *
1732
 * @param [in]      group  EC group.
1733
 * @param [in]      point  EC point.
1734
 * @param [in]      form   Format of encoding. Valid values:
1735
 *                         WC_POINT_CONVERSION_UNCOMPRESSED,
1736
 *                         WC_POINT_CONVERSION_COMPRESSED.
1737
 * @param [in, out] bn     BN to hold point value.
1738
 *                         When NULL a new BN is allocated otherwise this is
1739
 *                         returned on success.
1740
 * @param [in]      ctx    Context to use for BN operations. Unused.
1741
 * @return  BN object with point as a value on success.
1742
 * @return  NULL on error.
1743
 */
1744
WOLFSSL_BIGNUM *wolfSSL_EC_POINT_point2bn(const WOLFSSL_EC_GROUP* group,
1745
    const WOLFSSL_EC_POINT* point, int form, WOLFSSL_BIGNUM* bn,
1746
    WOLFSSL_BN_CTX* ctx)
1747
0
{
1748
0
    int err = 0;
1749
0
    size_t len = 0;
1750
0
    byte *buf = NULL;
1751
0
    WOLFSSL_BIGNUM *ret = NULL;
1752
1753
0
    WOLFSSL_ENTER("wolfSSL_EC_POINT_oct2point");
1754
1755
    /* Validate parameters. */
1756
0
    if ((group == NULL) || (point == NULL)) {
1757
0
        err = 1;
1758
0
    }
1759
1760
    /* Calculate length of octet encoding. */
1761
0
    if ((!err) && ((len = wolfSSL_EC_POINT_point2oct(group, point, form, NULL,
1762
0
            0, ctx)) == 0)) {
1763
0
        err = 1;
1764
0
    }
1765
    /* Allocate buffer to hold octet encoding. */
1766
0
    if ((!err) && ((buf = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER)) ==
1767
0
            NULL)) {
1768
0
        WOLFSSL_MSG("malloc failed");
1769
0
        err = 1;
1770
0
    }
1771
    /* Encode EC point as an octet string. */
1772
0
    if ((!err) && (wolfSSL_EC_POINT_point2oct(group, point, form, buf, len,
1773
0
            ctx) != len)) {
1774
0
        err = 1;
1775
0
    }
1776
    /* Load BN with octet string data. */
1777
0
    if (!err) {
1778
0
        ret = wolfSSL_BN_bin2bn(buf, (int)len, bn);
1779
0
    }
1780
1781
    /* Dispose of any allocated data. */
1782
0
    XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1783
1784
0
    return ret;
1785
0
}
1786
1787
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
1788
/* Check if EC point is on the the curve defined by the EC group.
1789
 *
1790
 * @param [in] group  EC group defining curve.
1791
 * @param [in] point  EC point to check.
1792
 * @param [in] ctx    Context to use for BN operations. Unused.
1793
 * @return  1 when point is on curve.
1794
 * @return  0 when point is not on curve or error.
1795
 */
1796
int wolfSSL_EC_POINT_is_on_curve(const WOLFSSL_EC_GROUP *group,
1797
    const WOLFSSL_EC_POINT *point, WOLFSSL_BN_CTX *ctx)
1798
573
{
1799
573
    int err = 0;
1800
1801
573
    WOLFSSL_ENTER("wolfSSL_EC_POINT_is_on_curve");
1802
1803
    /* No BN operations performed. */
1804
573
    (void)ctx;
1805
1806
    /* Validate parameters. */
1807
573
    if ((group == NULL) || (point == NULL)) {
1808
0
        WOLFSSL_MSG("Invalid arguments");
1809
0
        err = 1;
1810
0
    }
1811
1812
    /* Ensure internal EC point set. */
1813
573
    if ((!err) && (!point->inSet) && ec_point_internal_set(
1814
0
            (WOLFSSL_EC_POINT*)point) != 1) {
1815
0
        WOLFSSL_MSG("ec_point_internal_set error");
1816
0
        err = 1;
1817
0
    }
1818
1819
    /* Check point is on curve from group. */
1820
573
    if ((!err) && (wc_ecc_point_is_on_curve((ecc_point*)point->internal,
1821
573
            group->curve_idx) != MP_OKAY)) {
1822
78
        err = 1;
1823
78
    }
1824
1825
    /* Return boolean of on curve. No error means on curve. */
1826
573
    return !err;
1827
573
}
1828
#endif /* !HAVE_SELFTEST && !(HAVE_FIPS && FIPS_VERSION <= 2) */
1829
1830
#if !defined(WOLFSSL_SP_MATH) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
1831
/* Convert Jacobian ordinates to affine.
1832
 *
1833
 * @param [in]      group  EC group.
1834
 * @param [in]      point  EC point to get coordinates from.
1835
 * @return  1 on success.
1836
 * @return  0 on error.
1837
 */
1838
int ec_point_convert_to_affine(const WOLFSSL_EC_GROUP *group,
1839
    WOLFSSL_EC_POINT *point)
1840
0
{
1841
0
    int err = 0;
1842
0
    mp_digit mp = 0;
1843
0
    WC_DECLARE_VAR(modulus, mp_int, 1, 0);
1844
1845
    /* Allocate memory for curve's prime modulus. */
1846
0
    WC_ALLOC_VAR_EX(modulus, mp_int, 1, NULL, DYNAMIC_TYPE_BIGINT, err=1);
1847
    /* Initialize the MP integer. */
1848
0
    if ((!err) && (mp_init(modulus) != MP_OKAY)) {
1849
0
        WOLFSSL_MSG("mp_init failed");
1850
0
        err = 1;
1851
0
    }
1852
1853
0
    if (!err) {
1854
        /* Get the modulus from the hex string in the EC curve set. */
1855
0
        if (mp_read_radix(modulus, ecc_sets[group->curve_idx].prime,
1856
0
                MP_RADIX_HEX) != MP_OKAY) {
1857
0
            WOLFSSL_MSG("mp_read_radix failed");
1858
0
            err = 1;
1859
0
        }
1860
        /* Get Montgomery multiplier for the modulus as ordinates in
1861
         * Montgomery form.
1862
         */
1863
0
        if ((!err) && (mp_montgomery_setup(modulus, &mp) != MP_OKAY)) {
1864
0
            WOLFSSL_MSG("mp_montgomery_setup failed");
1865
0
            err = 1;
1866
0
        }
1867
        /* Map internal EC point from Jacobian to affine. */
1868
0
        if ((!err) && (ecc_map((ecc_point*)point->internal, modulus, mp) !=
1869
0
                MP_OKAY)) {
1870
0
            WOLFSSL_MSG("ecc_map failed");
1871
0
            err = 1;
1872
0
        }
1873
        /* Set new ordinates into external EC point. */
1874
0
        if ((!err) && (ec_point_external_set((WOLFSSL_EC_POINT *)point) != 1)) {
1875
0
            WOLFSSL_MSG("ec_point_external_set failed");
1876
0
            err = 1;
1877
0
        }
1878
1879
0
        point->exSet = !err;
1880
0
        mp_clear(modulus);
1881
0
    }
1882
1883
0
    WC_FREE_VAR_EX(modulus, NULL, DYNAMIC_TYPE_BIGINT);
1884
1885
0
    return err;
1886
0
}
1887
1888
/* Get the affine coordinates of the EC point on a Prime curve.
1889
 *
1890
 * When z-ordinate is not one then coordinates are Jacobian and need to be
1891
 * converted to affine before storing in BNs.
1892
 *
1893
 * Return code compliant with OpenSSL.
1894
 *
1895
 * TODO: OpenSSL doesn't change point when Jacobian. Do the same?
1896
 *
1897
 * @param [in]      group  EC group.
1898
 * @param [in]      point  EC point to get coordinates from.
1899
 * @param [in, out] x      BN to hold x-ordinate.
1900
 * @param [in, out] y      BN to hold y-ordinate.
1901
 * @param [in]      ctx    Context to use for BN operations. Unused.
1902
 * @return  1 on success.
1903
 * @return  0 on error.
1904
 */
1905
int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP* group,
1906
    const WOLFSSL_EC_POINT* point, WOLFSSL_BIGNUM* x, WOLFSSL_BIGNUM* y,
1907
    WOLFSSL_BN_CTX* ctx)
1908
358
{
1909
358
    int ret = 1;
1910
1911
    /* BN operations don't need context. */
1912
358
    (void)ctx;
1913
1914
358
    WOLFSSL_ENTER("wolfSSL_EC_POINT_get_affine_coordinates_GFp");
1915
1916
    /* Validate parameters. */
1917
358
    if ((group == NULL) || (point == NULL) || (point->internal == NULL) ||
1918
358
            (x == NULL) || (y == NULL)) {
1919
0
        WOLFSSL_MSG("wolfSSL_EC_POINT_get_affine_coordinates_GFp NULL error");
1920
0
        ret = 0;
1921
0
    }
1922
    /* Don't return point at infinity. */
1923
358
    if ((ret == 1) && wolfSSL_EC_POINT_is_at_infinity(group, point)) {
1924
7
        ret = 0;
1925
7
    }
1926
1927
    /* Ensure internal EC point has values of external EC point. */
1928
358
    if ((ret == 1) && (ec_point_setup(point) != 1)) {
1929
0
        ret = 0;
1930
0
    }
1931
1932
    /* Check whether ordinates are in Jacobian form. */
1933
358
    if ((ret == 1) && (!wolfSSL_BN_is_one(point->Z))) {
1934
        /* Convert from Jacobian to affine. */
1935
0
        if (ec_point_convert_to_affine(group, (WOLFSSL_EC_POINT*)point) == 1) {
1936
0
            ret = 0;
1937
0
        }
1938
0
    }
1939
1940
    /* Copy the externally set x and y ordinates. */
1941
358
    if ((ret == 1) && (wolfSSL_BN_copy(x, point->X) == NULL)) {
1942
0
        ret = 0;
1943
0
    }
1944
358
    if ((ret == 1) && (wolfSSL_BN_copy(y, point->Y) == NULL)) {
1945
0
        ret = 0;
1946
0
    }
1947
1948
358
    return ret;
1949
358
}
1950
#endif /* !WOLFSSL_SP_MATH && !WOLF_CRYPTO_CB_ONLY_ECC */
1951
1952
/* Sets the affine coordinates that belong on a prime curve.
1953
 *
1954
 * @param [in]      group  EC group.
1955
 * @param [in, out] point  EC point to set coordinates into.
1956
 * @param [in]      x      BN holding x-ordinate.
1957
 * @param [in]      y      BN holding y-ordinate.
1958
 * @param [in]      ctx    Context to use for BN operations. Unused.
1959
 * @return  1 on success.
1960
 * @return  0 on error.
1961
 */
1962
int wolfSSL_EC_POINT_set_affine_coordinates_GFp(const WOLFSSL_EC_GROUP* group,
1963
    WOLFSSL_EC_POINT* point, const WOLFSSL_BIGNUM* x, const WOLFSSL_BIGNUM* y,
1964
    WOLFSSL_BN_CTX* ctx)
1965
563
{
1966
563
    int ret = 1;
1967
1968
    /* BN operations don't need context. */
1969
563
    (void)ctx;
1970
1971
563
    WOLFSSL_ENTER("wolfSSL_EC_POINT_set_affine_coordinates_GFp");
1972
1973
    /* Validate parameters. */
1974
563
    if ((group == NULL) || (point == NULL) || (point->internal == NULL) ||
1975
563
            (x == NULL) || (y == NULL)) {
1976
0
        WOLFSSL_MSG("wolfSSL_EC_POINT_set_affine_coordinates_GFp NULL error");
1977
0
        ret = 0;
1978
0
    }
1979
1980
    /* Ensure we have a object for x-ordinate. */
1981
563
    if ((ret == 1) && (point->X == NULL) &&
1982
159
            ((point->X = wolfSSL_BN_new()) == NULL)) {
1983
0
        WOLFSSL_MSG("wolfSSL_BN_new failed");
1984
0
        ret = 0;
1985
0
    }
1986
    /* Ensure we have a object for y-ordinate. */
1987
563
    if ((ret == 1) && (point->Y == NULL) &&
1988
159
            ((point->Y = wolfSSL_BN_new()) == NULL)) {
1989
0
        WOLFSSL_MSG("wolfSSL_BN_new failed");
1990
0
        ret = 0;
1991
0
    }
1992
    /* Ensure we have a object for z-ordinate. */
1993
563
    if ((ret == 1) && (point->Z == NULL) &&
1994
159
            ((point->Z = wolfSSL_BN_new()) == NULL)) {
1995
0
        WOLFSSL_MSG("wolfSSL_BN_new failed");
1996
0
        ret = 0;
1997
0
    }
1998
1999
    /* Copy the x-ordinate. */
2000
563
    if ((ret == 1) && ((wolfSSL_BN_copy(point->X, x)) == NULL)) {
2001
0
        WOLFSSL_MSG("wolfSSL_BN_copy failed");
2002
0
        ret = 0;
2003
0
    }
2004
    /* Copy the y-ordinate. */
2005
563
    if ((ret == 1) && ((wolfSSL_BN_copy(point->Y, y)) == NULL)) {
2006
0
        WOLFSSL_MSG("wolfSSL_BN_copy failed");
2007
0
        ret = 0;
2008
0
    }
2009
    /* z-ordinate is one for affine coordinates. */
2010
563
    if ((ret == 1) && ((wolfSSL_BN_one(point->Z)) == 0)) {
2011
0
        WOLFSSL_MSG("wolfSSL_BN_one failed");
2012
0
        ret = 0;
2013
0
    }
2014
2015
    /* Copy the new point data to internal object. */
2016
563
    if ((ret == 1) && (ec_point_internal_set((WOLFSSL_EC_POINT *)point) != 1)) {
2017
0
        WOLFSSL_MSG("ec_point_internal_set failed");
2018
0
        ret = 0;
2019
0
    }
2020
2021
563
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
2022
    /* Check that the point is valid. */
2023
563
    if ((ret == 1) && (wolfSSL_EC_POINT_is_on_curve(group,
2024
563
            (WOLFSSL_EC_POINT *)point, ctx) != 1)) {
2025
78
        WOLFSSL_MSG("EC_POINT_is_on_curve failed");
2026
78
        ret = 0;
2027
78
    }
2028
563
#endif
2029
2030
563
    return ret;
2031
563
}
2032
2033
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
2034
    !defined(HAVE_SELFTEST) && !defined(WOLFSSL_SP_MATH) && \
2035
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
2036
/* Add two points on the same together.
2037
 *
2038
 * @param [in]  curveIdx  Index of curve in ecc_set.
2039
 * @param [out] r         Result point.
2040
 * @param [in]  p1        First point to add.
2041
 * @param [in]  p2        Second point to add.
2042
 * @return  1 on success.
2043
 * @return  0 on error.
2044
 */
2045
static int wolfssl_ec_point_add(int curveIdx, ecc_point* r, ecc_point* p1,
2046
    ecc_point* p2)
2047
29
{
2048
29
    int ret = 1;
2049
29
#ifdef WOLFSSL_SMALL_STACK
2050
29
    mp_int* a = NULL;
2051
29
    mp_int* prime = NULL;
2052
29
    mp_int* mu = NULL;
2053
#else
2054
    mp_int a[1];
2055
    mp_int prime[1];
2056
    mp_int mu[1];
2057
#endif
2058
29
    mp_digit mp = 0;
2059
29
    ecc_point* montP1 = NULL;
2060
29
    ecc_point* montP2 = NULL;
2061
2062
29
#ifdef WOLFSSL_SMALL_STACK
2063
29
    if (ret == 1) {
2064
        /* Allocate memory for curve parameter: a. */
2065
29
        a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
2066
29
        if (a == NULL) {
2067
0
            WOLFSSL_MSG("Failed to allocate memory for mp_int a");
2068
0
            ret = 0;
2069
0
        }
2070
29
    }
2071
29
    if (ret == 1) {
2072
        /* Allocate memory for curve parameter: prime. */
2073
29
        prime = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
2074
29
        if (prime == NULL) {
2075
0
            WOLFSSL_MSG("Failed to allocate memory for mp_int prime");
2076
0
            ret = 0;
2077
0
        }
2078
29
    }
2079
29
    if (ret == 1) {
2080
        /* Allocate memory for mu (Montgomery normalizer). */
2081
29
        mu = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
2082
29
        if (mu == NULL) {
2083
0
            WOLFSSL_MSG("Failed to allocate memory for mp_int mu");
2084
0
            ret = 0;
2085
0
        }
2086
29
    }
2087
29
    if (ret == 1) {
2088
        /* Zero out all MP int data in case initialization fails. */
2089
29
        XMEMSET(a, 0, sizeof(mp_int));
2090
29
        XMEMSET(prime, 0, sizeof(mp_int));
2091
29
        XMEMSET(mu, 0, sizeof(mp_int));
2092
29
    }
2093
29
#endif
2094
2095
    /* Initialize the MP ints. */
2096
29
    if ((ret == 1) && (mp_init_multi(prime, a, mu, NULL, NULL, NULL) !=
2097
29
            MP_OKAY)) {
2098
0
        WOLFSSL_MSG("mp_init_multi error");
2099
0
        ret = 0;
2100
0
    }
2101
2102
    /* Read the curve parameter: a. */
2103
29
    if ((ret == 1) && (mp_read_radix(a, ecc_sets[curveIdx].Af, MP_RADIX_HEX) !=
2104
29
            MP_OKAY)) {
2105
0
        WOLFSSL_MSG("mp_read_radix a error");
2106
0
        ret = 0;
2107
0
    }
2108
2109
    /* Read the curve parameter: prime. */
2110
29
    if ((ret == 1) && (mp_read_radix(prime, ecc_sets[curveIdx].prime,
2111
29
            MP_RADIX_HEX) != MP_OKAY)) {
2112
0
        WOLFSSL_MSG("mp_read_radix prime error");
2113
0
        ret = 0;
2114
0
    }
2115
2116
    /* Calculate the Montgomery product. */
2117
29
    if ((ret == 1) && (mp_montgomery_setup(prime, &mp) != MP_OKAY)) {
2118
0
        WOLFSSL_MSG("mp_montgomery_setup nqm error");
2119
0
        ret = 0;
2120
0
    }
2121
2122
    /* TODO: use the heap filed of one of the points? */
2123
    /* Allocate new points to hold the Montgomery form values. */
2124
29
    if ((ret == 1) && (((montP1 = wc_ecc_new_point_h(NULL)) == NULL) ||
2125
29
            ((montP2 = wc_ecc_new_point_h(NULL)) == NULL))) {
2126
0
        WOLFSSL_MSG("wc_ecc_new_point_h nqm error");
2127
0
        ret = 0;
2128
0
    }
2129
2130
    /* Calculate the Montgomery normalizer. */
2131
29
    if ((ret == 1) && (mp_montgomery_calc_normalization(mu, prime) !=
2132
29
            MP_OKAY)) {
2133
0
        WOLFSSL_MSG("mp_montgomery_calc_normalization error");
2134
0
        ret = 0;
2135
0
    }
2136
2137
    /* Convert to Montgomery form. */
2138
29
    if ((ret == 1) && (mp_cmp_d(mu, 1) == MP_EQ)) {
2139
        /* Copy the points if the normalizer is 1.  */
2140
10
        if ((wc_ecc_copy_point(p1, montP1) != MP_OKAY) ||
2141
10
                (wc_ecc_copy_point(p2, montP2) != MP_OKAY)) {
2142
0
            WOLFSSL_MSG("wc_ecc_copy_point error");
2143
0
            ret = 0;
2144
0
        }
2145
10
    }
2146
19
    else if (ret == 1) {
2147
        /* Multiply each ordinate by the Montgomery normalizer.  */
2148
19
        if ((mp_mulmod(p1->x, mu, prime, montP1->x) != MP_OKAY) ||
2149
19
                (mp_mulmod(p1->y, mu, prime, montP1->y) != MP_OKAY) ||
2150
19
                (mp_mulmod(p1->z, mu, prime, montP1->z) != MP_OKAY)) {
2151
0
            WOLFSSL_MSG("mp_mulmod error");
2152
0
            ret = 0;
2153
0
        }
2154
        /* Multiply each ordinate by the Montgomery normalizer.  */
2155
19
        if ((mp_mulmod(p2->x, mu, prime, montP2->x) != MP_OKAY) ||
2156
19
                (mp_mulmod(p2->y, mu, prime, montP2->y) != MP_OKAY) ||
2157
19
                (mp_mulmod(p2->z, mu, prime, montP2->z) != MP_OKAY)) {
2158
0
            WOLFSSL_MSG("mp_mulmod error");
2159
0
            ret = 0;
2160
0
        }
2161
19
    }
2162
2163
    /* Perform point addition with internal EC point objects - Jacobian form
2164
     * result.
2165
     */
2166
29
    if ((ret == 1) && (ecc_projective_add_point(montP1, montP2, r, a, prime,
2167
29
            mp) != MP_OKAY)) {
2168
0
        WOLFSSL_MSG("ecc_projective_add_point error");
2169
0
        ret = 0;
2170
0
    }
2171
2172
    /* Map point back to affine coordinates. Converts from Montogomery form. */
2173
29
    if ((ret == 1) && (ecc_map(r, prime, mp) != MP_OKAY)) {
2174
0
        WOLFSSL_MSG("ecc_map error");
2175
0
        ret = 0;
2176
0
    }
2177
2178
    /* Dispose of allocated memory. */
2179
29
    mp_clear(a);
2180
29
    mp_clear(prime);
2181
29
    mp_clear(mu);
2182
29
    wc_ecc_del_point_h(montP1, NULL);
2183
29
    wc_ecc_del_point_h(montP2, NULL);
2184
29
    WC_FREE_VAR_EX(a, NULL, DYNAMIC_TYPE_BIGINT);
2185
29
    WC_FREE_VAR_EX(prime, NULL, DYNAMIC_TYPE_BIGINT);
2186
29
    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_BIGINT);
2187
29
    return ret;
2188
29
}
2189
2190
/* Add two points on the same curve together.
2191
 *
2192
 * @param [in]  group  EC group.
2193
 * @param [out] r      EC point that is result of point addition.
2194
 * @param [in]  p1     First EC point to add.
2195
 * @param [in]  p2     Second EC point to add.
2196
 * @param [in]  ctx    Context to use for BN operations. Unused.
2197
 * @return  1 on success.
2198
 * @return  0 on error.
2199
 */
2200
int wolfSSL_EC_POINT_add(const WOLFSSL_EC_GROUP* group, WOLFSSL_EC_POINT* r,
2201
    const WOLFSSL_EC_POINT* p1, const WOLFSSL_EC_POINT* p2, WOLFSSL_BN_CTX* ctx)
2202
29
{
2203
29
    int ret = 1;
2204
2205
    /* No BN operations performed. */
2206
29
    (void)ctx;
2207
2208
    /* Validate parameters. */
2209
29
    if ((group == NULL) || (r == NULL) || (p1 == NULL) || (p2 == NULL)) {
2210
0
        WOLFSSL_MSG("wolfSSL_EC_POINT_add error");
2211
0
        ret = 0;
2212
0
    }
2213
2214
    /* Ensure the internal objects of the EC points are setup. */
2215
29
    if ((ret == 1) && ((ec_point_setup(r) != 1) || (ec_point_setup(p1) != 1) ||
2216
29
            (ec_point_setup(p2) != 1))) {
2217
0
        WOLFSSL_MSG("ec_point_setup error");
2218
0
        ret = 0;
2219
0
    }
2220
2221
#ifdef DEBUG_WOLFSSL
2222
    if (ret == 1) {
2223
        int nid = wolfSSL_EC_GROUP_get_curve_name(group);
2224
        const char* curve = wolfSSL_OBJ_nid2ln(nid);
2225
        const char* nistName = wolfSSL_EC_curve_nid2nist(nid);
2226
        wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_add p1", p1);
2227
        wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_add p2", p2);
2228
        if (curve != NULL)
2229
            WOLFSSL_MSG_EX("curve name: %s", curve);
2230
        if (nistName != NULL)
2231
            WOLFSSL_MSG_EX("nist curve name: %s", nistName);
2232
    }
2233
#endif
2234
2235
29
    if (ret == 1) {
2236
        /* Add points using wolfCrypt objects. */
2237
29
        ret = wolfssl_ec_point_add(group->curve_idx, (ecc_point*)r->internal,
2238
29
            (ecc_point*)p1->internal, (ecc_point*)p2->internal);
2239
29
    }
2240
2241
    /* Copy internal EC point values out to external EC point. */
2242
29
    if ((ret == 1) && (ec_point_external_set(r) != 1)) {
2243
0
        WOLFSSL_MSG("ec_point_external_set error");
2244
0
        ret = 0;
2245
0
    }
2246
2247
#ifdef DEBUG_WOLFSSL
2248
    if (ret == 1) {
2249
        wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_add result", r);
2250
    }
2251
#endif
2252
2253
29
    return ret;
2254
29
}
2255
2256
/* Sum the scalar multiplications of the base point and n, and q and m.
2257
 *
2258
 * r = base point * n + q * m
2259
 *
2260
 * @param [out] r      EC point that is result of operation.
2261
 * @param [in]  b      Base point of curve.
2262
 * @param [in]  n      Scalar to multiply by base point.
2263
 * @param [in]  q      EC point to be scalar multiplied.
2264
 * @param [in]  m      Scalar to multiply q by.
2265
 * @param [in]  a      Parameter A of curve.
2266
 * @param [in]  prime  Prime (modulus) of curve.
2267
 * @return  1 on success.
2268
 * @return  0 on error.
2269
 */
2270
static int ec_mul2add(ecc_point* r, ecc_point* b, mp_int* n, ecc_point* q,
2271
    mp_int* m, mp_int* a, mp_int* prime)
2272
0
{
2273
0
    int ret = 1;
2274
0
#if defined(ECC_SHAMIR) && !defined(WOLFSSL_KCAPI_ECC)
2275
0
    if (ecc_mul2add(b, n, q, m, r, a, prime, NULL) != MP_OKAY) {
2276
0
        WOLFSSL_MSG("ecc_mul2add error");
2277
0
        ret = 0;
2278
0
    }
2279
#else
2280
    ecc_point* tmp = NULL;
2281
    mp_digit mp = 0;
2282
2283
    /* Calculate Montgomery product. */
2284
    if (mp_montgomery_setup(prime, &mp) != MP_OKAY) {
2285
        WOLFSSL_MSG("mp_montgomery_setup nqm error");
2286
        ret = 0;
2287
    }
2288
    /* Create temporary point to hold: q * m */
2289
    if ((ret == 1) && ((tmp = wc_ecc_new_point()) == NULL)) {
2290
        WOLFSSL_MSG("wolfSSL_EC_POINT_new nqm error");
2291
        ret = 0;
2292
    }
2293
    /* r = base point * n */
2294
    if ((ret == 1) && (wc_ecc_mulmod(n, b, r, a, prime, 0) !=
2295
            MP_OKAY)) {
2296
        WOLFSSL_MSG("wc_ecc_mulmod nqm error");
2297
        ret = 0;
2298
    }
2299
    /* tmp = q * m */
2300
    if ((ret == 1) && (wc_ecc_mulmod(m, q, tmp, a, prime, 0) != MP_OKAY)) {
2301
        WOLFSSL_MSG("wc_ecc_mulmod nqm error");
2302
        ret = 0;
2303
    }
2304
    /* r = r + tmp */
2305
    if ((ret == 1) && (ecc_projective_add_point(tmp, r, r, a, prime, mp) !=
2306
            MP_OKAY)) {
2307
        WOLFSSL_MSG("wc_ecc_mulmod nqm error");
2308
        ret = 0;
2309
    }
2310
    /* Map point back to affine coordinates. Converts from Montogomery
2311
     * form. */
2312
    if ((ret == 1) && (ecc_map(r, prime, mp) != MP_OKAY)) {
2313
        WOLFSSL_MSG("ecc_map nqm error");
2314
        ret = 0;
2315
    }
2316
2317
    /* Dispose of allocated temporary point. */
2318
    wc_ecc_del_point(tmp);
2319
#endif
2320
2321
0
    return ret;
2322
0
}
2323
2324
/* Sum the scalar multiplications of the base point and n, and q and m.
2325
 *
2326
 * r = base point * n + q * m
2327
 *
2328
 * @param [in]  curveIdx  Index of curve in ecc_set.
2329
 * @param [out] r         EC point that is result of operation.
2330
 * @param [in]  n         Scalar to multiply by base point. May be NULL.
2331
 * @param [in]  q         EC point to be scalar multiplied. May be NULL.
2332
 * @param [in]  m         Scalar to multiply q by. May be NULL.
2333
 * @return  1 on success.
2334
 * @return  0 on error.
2335
 */
2336
static int wolfssl_ec_point_mul(int curveIdx, ecc_point* r, mp_int* n,
2337
    ecc_point* q, mp_int* m)
2338
351
{
2339
351
    int ret = 1;
2340
351
#ifdef WOLFSSL_SMALL_STACK
2341
351
    mp_int* a = NULL;
2342
351
    mp_int* prime = NULL;
2343
#else
2344
    mp_int a[1], prime[1];
2345
#endif
2346
2347
351
#ifdef WOLFSSL_SMALL_STACK
2348
    /* Allocate MP integer for curve parameter: a. */
2349
351
    a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
2350
351
    if (a == NULL) {
2351
0
        ret = 0;
2352
0
    }
2353
351
    if (ret == 1) {
2354
        /* Allocate MP integer for curve parameter: prime. */
2355
351
        prime = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
2356
351
        if (prime == NULL)  {
2357
0
            ret = 0;
2358
0
        }
2359
351
    }
2360
351
#endif
2361
2362
    /* Initialize the MP ints. */
2363
351
    if ((ret == 1) && (mp_init_multi(prime, a, NULL, NULL, NULL, NULL) !=
2364
351
             MP_OKAY)) {
2365
0
        WOLFSSL_MSG("mp_init_multi error");
2366
0
        ret = 0;
2367
0
    }
2368
2369
    /* Read the curve parameter: prime. */
2370
351
    if ((ret == 1) && (mp_read_radix(prime, ecc_sets[curveIdx].prime,
2371
351
            MP_RADIX_HEX) != MP_OKAY)) {
2372
0
        WOLFSSL_MSG("mp_read_radix prime error");
2373
0
        ret = 0;
2374
0
    }
2375
2376
    /* Read the curve parameter: a. */
2377
351
    if ((ret == 1) && (mp_read_radix(a, ecc_sets[curveIdx].Af,
2378
351
            MP_RADIX_HEX) != MP_OKAY)) {
2379
0
        WOLFSSL_MSG("mp_read_radix a error");
2380
0
        ret = 0;
2381
0
    }
2382
2383
351
    if ((ret == 1) && (n != NULL)) {
2384
        /* Get generator - base point. */
2385
337
    #if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)
2386
337
        if ((ret == 1) && (wc_ecc_get_generator(r, curveIdx) != MP_OKAY)) {
2387
0
            WOLFSSL_MSG("wc_ecc_get_generator error");
2388
0
            ret = 0;
2389
0
        }
2390
    #else
2391
        /* wc_ecc_get_generator is not defined in the FIPS v2 module. */
2392
        /* Read generator (base point) x-ordinate. */
2393
        if ((ret == 1) && (mp_read_radix(r->x, ecc_sets[curveIdx].Gx,
2394
                MP_RADIX_HEX) != MP_OKAY)) {
2395
            WOLFSSL_MSG("mp_read_radix Gx error");
2396
            ret = 0;
2397
        }
2398
        /* Read generator (base point) y-ordinate. */
2399
        if ((ret == 1) && (mp_read_radix(r->y, ecc_sets[curveIdx].Gy,
2400
                MP_RADIX_HEX) != MP_OKAY)) {
2401
            WOLFSSL_MSG("mp_read_radix Gy error");
2402
            ret = 0;
2403
        }
2404
        /* z-ordinate is one as point is affine. */
2405
        if ((ret == 1) && (mp_set(r->z, 1) != MP_OKAY)) {
2406
            WOLFSSL_MSG("mp_set Gz error");
2407
            ret = 0;
2408
        }
2409
    #endif /* NOPT_FIPS_VERSION == 2 */
2410
337
    }
2411
2412
351
    if ((ret == 1) && (n != NULL) && (q != NULL) && (m != NULL)) {
2413
        /* r = base point * n + q * m */
2414
0
        ret = ec_mul2add(r, r, n, q, m, a, prime);
2415
0
    }
2416
    /* Not all values present, see if we are only doing base point * n. */
2417
351
    else if ((ret == 1) && (n != NULL)) {
2418
        /* r = base point * n */
2419
337
        if (wc_ecc_mulmod(n, r, r, a, prime, 1) != MP_OKAY) {
2420
20
            WOLFSSL_MSG("wc_ecc_mulmod gn error");
2421
20
            ret = 0;
2422
20
        }
2423
337
    }
2424
    /* Not all values present, see if we are only doing q * m. */
2425
14
    else if ((ret == 1) && (q != NULL) && (m != NULL)) {
2426
        /* r = q * m */
2427
14
        if (wc_ecc_mulmod(m, q, r, a, prime, 1) != MP_OKAY) {
2428
4
            WOLFSSL_MSG("wc_ecc_mulmod qm error");
2429
4
            ret = 0;
2430
4
        }
2431
14
    }
2432
    /* No values to use. */
2433
0
    else if (ret == 1) {
2434
        /* Set result to infinity as no values passed in. */
2435
0
        mp_zero(r->x);
2436
0
        mp_zero(r->y);
2437
0
        mp_zero(r->z);
2438
0
    }
2439
2440
351
    mp_clear(a);
2441
351
    mp_clear(prime);
2442
351
    WC_FREE_VAR_EX(a, NULL, DYNAMIC_TYPE_BIGINT);
2443
351
    WC_FREE_VAR_EX(prime, NULL, DYNAMIC_TYPE_BIGINT);
2444
351
    return ret;
2445
351
}
2446
2447
/* Sum the scalar multiplications of the base point and n, and q and m.
2448
 *
2449
 * r = base point * n + q * m
2450
 *
2451
 * Return code compliant with OpenSSL.
2452
 *
2453
 * @param [in]  group  EC group.
2454
 * @param [out] r      EC point that is result of operation.
2455
 * @param [in]  n      Scalar to multiply by base point. May be NULL.
2456
 * @param [in]  q      EC point to be scalar multiplied. May be NULL.
2457
 * @param [in]  m      Scalar to multiply q by. May be NULL.
2458
 * @param [in]  ctx    Context to use for BN operations. Unused.
2459
 * @return  1 on success.
2460
 * @return  0 on error.
2461
 */
2462
int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r,
2463
    const WOLFSSL_BIGNUM *n, const WOLFSSL_EC_POINT *q, const WOLFSSL_BIGNUM *m,
2464
    WOLFSSL_BN_CTX *ctx)
2465
351
{
2466
351
    int ret = 1;
2467
2468
    /* No BN operations performed. */
2469
351
    (void)ctx;
2470
2471
351
    WOLFSSL_ENTER("wolfSSL_EC_POINT_mul");
2472
2473
    /* Validate parameters. */
2474
351
    if ((group == NULL) || (r == NULL)) {
2475
0
        WOLFSSL_MSG("wolfSSL_EC_POINT_mul NULL error");
2476
0
        ret = 0;
2477
0
    }
2478
2479
    /* Ensure the internal representation of the EC point q is setup. */
2480
351
    if ((ret == 1) && (q != NULL) && (ec_point_setup(q) != 1)) {
2481
0
        WOLFSSL_MSG("ec_point_setup error");
2482
0
        ret = 0;
2483
0
    }
2484
2485
#ifdef DEBUG_WOLFSSL
2486
    if (ret == 1) {
2487
        int nid = wolfSSL_EC_GROUP_get_curve_name(group);
2488
        const char* curve = wolfSSL_OBJ_nid2ln(nid);
2489
        const char* nistName = wolfSSL_EC_curve_nid2nist(nid);
2490
        char* num;
2491
        wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_mul input q", q);
2492
        num = wolfSSL_BN_bn2hex(n);
2493
        WOLFSSL_MSG_EX("\tn = %s", num);
2494
        XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL);
2495
        num = wolfSSL_BN_bn2hex(m);
2496
        WOLFSSL_MSG_EX("\tm = %s", num);
2497
        XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL);
2498
        if (curve != NULL)
2499
            WOLFSSL_MSG_EX("curve name: %s", curve);
2500
        if (nistName != NULL)
2501
            WOLFSSL_MSG_EX("nist curve name: %s", nistName);
2502
    }
2503
#endif
2504
2505
351
    if (ret == 1) {
2506
351
        mp_int* ni = (n != NULL) ? (mp_int*)n->internal : NULL;
2507
351
        ecc_point* qi = (q != NULL) ? (ecc_point*)q->internal : NULL;
2508
351
        mp_int* mi = (m != NULL) ? (mp_int*)m->internal : NULL;
2509
2510
        /* Perform multiplication with wolfCrypt objects. */
2511
351
        ret = wolfssl_ec_point_mul(group->curve_idx, (ecc_point*)r->internal,
2512
351
            ni, qi, mi);
2513
351
    }
2514
2515
    /* Only on success is the internal point guaranteed to be set. */
2516
351
    if (r != NULL) {
2517
351
        r->inSet = (ret == 1);
2518
351
    }
2519
    /* Copy internal EC point values out to external EC point. */
2520
351
    if ((ret == 1) && (ec_point_external_set(r) != 1)) {
2521
0
        WOLFSSL_MSG("ec_point_external_set error");
2522
0
        ret = 0;
2523
0
    }
2524
2525
#ifdef DEBUG_WOLFSSL
2526
    if (ret == 1) {
2527
        wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_mul result", r);
2528
    }
2529
#endif
2530
2531
351
    return ret;
2532
351
}
2533
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A && !HAVE_SELFTEST &&
2534
        * !WOLFSSL_SP_MATH */
2535
2536
/* Invert the point on the curve.
2537
 * (x, y) -> (x, -y) = (x, (prime - y) % prime)
2538
 *
2539
 * @param [in]      curveIdx  Index of curve in ecc_set.
2540
 * @param [in, out] point     EC point to invert.
2541
 * @return  1 on success.
2542
 * @return  0 on error.
2543
 */
2544
static int wolfssl_ec_point_invert(int curveIdx, ecc_point* point)
2545
2
{
2546
2
    int ret = 1;
2547
2
    WC_DECLARE_VAR(prime, mp_int, 1, 0);
2548
2549
    /* Allocate memory for an MP int to hold the prime of the curve. */
2550
2
    WC_ALLOC_VAR_EX(prime, mp_int, 1, NULL, DYNAMIC_TYPE_BIGINT, ret=0);
2551
2552
    /* Initialize MP int. */
2553
2
    if ((ret == 1) && (mp_init(prime) != MP_OKAY)) {
2554
0
        WOLFSSL_MSG("mp_init_multi error");
2555
0
        ret = 0;
2556
0
    }
2557
2558
    /* Read the curve parameter: prime. */
2559
2
    if ((ret == 1) && (mp_read_radix(prime, ecc_sets[curveIdx].prime,
2560
2
            MP_RADIX_HEX) != MP_OKAY)) {
2561
0
        WOLFSSL_MSG("mp_read_radix prime error");
2562
0
        ret = 0;
2563
0
    }
2564
2565
    /* y = (prime - y) mod prime. */
2566
2
    if ((ret == 1) && (!mp_iszero(point->y)) && (mp_sub(prime, point->y,
2567
0
            point->y) != MP_OKAY)) {
2568
0
        WOLFSSL_MSG("mp_sub error");
2569
0
        ret = 0;
2570
0
    }
2571
2572
    /* Dispose of memory associated with MP. */
2573
2
    mp_free(prime);
2574
2
    WC_FREE_VAR_EX(prime, NULL, DYNAMIC_TYPE_BIGINT);
2575
2
    return ret;
2576
2
}
2577
2578
/* Invert the point on the curve.
2579
 * (x, y) -> (x, -y) = (x, (prime - y) % prime)
2580
 *
2581
 * @param [in]      group  EC group.
2582
 * @param [in, out] point  EC point to invert.
2583
 * @param [in]      ctx    Context to use for BN operations. Unused.
2584
 * @return  1 on success.
2585
 * @return  0 on error.
2586
 */
2587
int wolfSSL_EC_POINT_invert(const WOLFSSL_EC_GROUP *group,
2588
    WOLFSSL_EC_POINT *point, WOLFSSL_BN_CTX *ctx)
2589
2
{
2590
2
    int ret = 1;
2591
2592
    /* No BN operations performed. */
2593
2
    (void)ctx;
2594
2595
2
    WOLFSSL_ENTER("wolfSSL_EC_POINT_invert");
2596
2597
    /* Validate parameters. */
2598
2
    if ((group == NULL) || (point == NULL) || (point->internal == NULL)) {
2599
0
        ret = 0;
2600
0
    }
2601
2602
    /* Ensure internal representation of point is setup. */
2603
2
    if ((ret == 1) && (ec_point_setup(point) != 1)) {
2604
0
        ret = 0;
2605
0
    }
2606
2607
#ifdef DEBUG_WOLFSSL
2608
    if (ret == 1) {
2609
        int nid = wolfSSL_EC_GROUP_get_curve_name(group);
2610
        const char* curve = wolfSSL_OBJ_nid2ln(nid);
2611
        const char* nistName = wolfSSL_EC_curve_nid2nist(nid);
2612
        wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_invert input", point);
2613
        if (curve != NULL)
2614
            WOLFSSL_MSG_EX("curve name: %s", curve);
2615
        if (nistName != NULL)
2616
            WOLFSSL_MSG_EX("nist curve name: %s", nistName);
2617
2618
    }
2619
#endif
2620
2621
2
    if (ret == 1 && !wolfSSL_BN_is_one(point->Z)) {
2622
0
#if !defined(WOLFSSL_SP_MATH) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
2623
0
        if (ec_point_convert_to_affine(group, point) != 0)
2624
0
            ret = 0;
2625
#else
2626
        WOLFSSL_MSG("wolfSSL_EC_POINT_invert called on non-affine point");
2627
        ret = 0;
2628
#endif
2629
0
    }
2630
2631
2
    if (ret == 1) {
2632
        /* Perform inversion using wolfCrypt objects. */
2633
2
        ret = wolfssl_ec_point_invert(group->curve_idx,
2634
2
            (ecc_point*)point->internal);
2635
2
    }
2636
2637
    /* Set the external EC point representation based on internal. */
2638
2
    if ((ret == 1) && (ec_point_external_set(point) != 1)) {
2639
0
        WOLFSSL_MSG("ec_point_external_set error");
2640
0
        ret = 0;
2641
0
    }
2642
2643
#ifdef DEBUG_WOLFSSL
2644
    if (ret == 1) {
2645
        wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_invert result", point);
2646
    }
2647
#endif
2648
2649
2
    return ret;
2650
2
}
2651
2652
#ifdef WOLFSSL_EC_POINT_CMP_JACOBIAN
2653
/* Compare two points on a the same curve.
2654
 *
2655
 * (Ax, Ay, Az) => (Ax / (Az ^ 2), Ay / (Az ^ 3))
2656
 * (Bx, By, Bz) => (Bx / (Bz ^ 2), By / (Bz ^ 3))
2657
 * When equal:
2658
 *      (Ax / (Az ^ 2), Ay / (Az ^ 3)) = (Bx / (Bz ^ 2), By / (Bz ^ 3))
2659
 *   => (Ax * (Bz ^ 2), Ay * (Bz ^ 3)) = (Bx * (Az ^ 2), By * (Az ^ 3))
2660
 *
2661
 * @param [in] group  EC group.
2662
 * @param [in] a      EC point to compare.
2663
 * @param [in] b      EC point to compare.
2664
 * @return  0 when equal.
2665
 * @return  1 when different.
2666
 * @return  -1 on error.
2667
 */
2668
static int ec_point_cmp_jacobian(const WOLFSSL_EC_GROUP* group,
2669
    const WOLFSSL_EC_POINT *a, const WOLFSSL_EC_POINT *b, WOLFSSL_BN_CTX *ctx)
2670
{
2671
    int ret = 0;
2672
    BIGNUM* at = BN_new();
2673
    BIGNUM* bt = BN_new();
2674
    BIGNUM* az = BN_new();
2675
    BIGNUM* bz = BN_new();
2676
    BIGNUM* mod = BN_new();
2677
2678
    /* Check that the big numbers were allocated. */
2679
    if ((at == NULL) || (bt == NULL) || (az == NULL) || (bz == NULL) ||
2680
            (mod == NULL)) {
2681
        ret = WOLFSSL_FATAL_ERROR;
2682
    }
2683
    /* Get the modulus for the curve. */
2684
    if ((ret == 0) &&
2685
            (BN_hex2bn(&mod, ecc_sets[group->curve_idx].prime) != 1)) {
2686
        ret = WOLFSSL_FATAL_ERROR;
2687
    }
2688
    if (ret == 0) {
2689
        /* bt = Bx * (Az ^ 2). When Az is one then just copy. */
2690
        if (BN_is_one(a->Z)) {
2691
            if (BN_copy(bt, b->X) == NULL) {
2692
                ret = WOLFSSL_FATAL_ERROR;
2693
            }
2694
        }
2695
        /* az = Az ^ 2 */
2696
        else if ((BN_mod_mul(az, a->Z, a->Z, mod, ctx) != 1)) {
2697
            ret = WOLFSSL_FATAL_ERROR;
2698
        }
2699
        /* bt = Bx * az = Bx * (Az ^ 2) */
2700
        else if (BN_mod_mul(bt, b->X, az, mod, ctx) != 1) {
2701
            ret = WOLFSSL_FATAL_ERROR;
2702
        }
2703
    }
2704
    if (ret == 0) {
2705
        /* at = Ax * (Bz ^ 2). When Bz is one then just copy. */
2706
        if (BN_is_one(b->Z)) {
2707
            if (BN_copy(at, a->X) == NULL) {
2708
                ret = WOLFSSL_FATAL_ERROR;
2709
            }
2710
        }
2711
        /* bz = Bz ^ 2 */
2712
        else if (BN_mod_mul(bz, b->Z, b->Z, mod, ctx) != 1) {
2713
            ret = WOLFSSL_FATAL_ERROR;
2714
        }
2715
        /* at = Ax * bz = Ax * (Bz ^ 2) */
2716
        else if (BN_mod_mul(at, a->X, bz, mod, ctx) != 1) {
2717
            ret = WOLFSSL_FATAL_ERROR;
2718
        }
2719
    }
2720
    /* Compare x-ordinates. */
2721
    if ((ret == 0) && (BN_cmp(at, bt) != 0)) {
2722
        ret = 1;
2723
    }
2724
    if (ret == 0) {
2725
        /* bt = By * (Az ^ 3). When Az is one then just copy. */
2726
        if (BN_is_one(a->Z)) {
2727
            if (BN_copy(bt, b->Y) == NULL) {
2728
                ret = WOLFSSL_FATAL_ERROR;
2729
            }
2730
        }
2731
        /* az = az * Az = Az ^ 3 */
2732
        else if ((BN_mod_mul(az, az, a->Z, mod, ctx) != 1)) {
2733
            ret = WOLFSSL_FATAL_ERROR;
2734
        }
2735
        /* bt = By * az = By * (Az ^ 3) */
2736
        else if (BN_mod_mul(bt, b->Y, az, mod, ctx) != 1) {
2737
            ret = WOLFSSL_FATAL_ERROR;
2738
        }
2739
    }
2740
    if (ret == 0) {
2741
        /* at = Ay * (Bz ^ 3). When Bz is one then just copy. */
2742
        if (BN_is_one(b->Z)) {
2743
            if (BN_copy(at, a->Y) == NULL) {
2744
                ret = WOLFSSL_FATAL_ERROR;
2745
            }
2746
        }
2747
        /* bz = bz * Bz = Bz ^ 3 */
2748
        else if (BN_mod_mul(bz, bz, b->Z, mod, ctx) != 1) {
2749
            ret = WOLFSSL_FATAL_ERROR;
2750
        }
2751
        /* at = Ay * bz = Ay * (Bz ^ 3) */
2752
        else if (BN_mod_mul(at, a->Y, bz, mod, ctx) != 1) {
2753
            ret = WOLFSSL_FATAL_ERROR;
2754
        }
2755
    }
2756
    /* Compare y-ordinates. */
2757
    if ((ret == 0) && (BN_cmp(at, bt) != 0)) {
2758
        ret = 1;
2759
    }
2760
2761
    BN_free(mod);
2762
    BN_free(bz);
2763
    BN_free(az);
2764
    BN_free(bt);
2765
    BN_free(at);
2766
    return ret;
2767
}
2768
#endif
2769
2770
/* Compare two points on a the same curve.
2771
 *
2772
 * Return code compliant with OpenSSL.
2773
 *
2774
 * @param [in] group  EC group.
2775
 * @param [in] a      EC point to compare.
2776
 * @param [in] b      EC point to compare.
2777
 * @param [in] ctx    Context to use for BN operations. Unused.
2778
 * @return  0 when equal.
2779
 * @return  1 when different.
2780
 * @return  -1 on error.
2781
 */
2782
int wolfSSL_EC_POINT_cmp(const WOLFSSL_EC_GROUP *group,
2783
    const WOLFSSL_EC_POINT *a, const WOLFSSL_EC_POINT *b, WOLFSSL_BN_CTX *ctx)
2784
7
{
2785
7
    int ret = 0;
2786
2787
7
    WOLFSSL_ENTER("wolfSSL_EC_POINT_cmp");
2788
2789
    /* Validate parameters. */
2790
7
    if ((group == NULL) || (a == NULL) || (a->internal == NULL) ||
2791
7
            (b == NULL) || (b->internal == NULL)) {
2792
0
        WOLFSSL_MSG("wolfSSL_EC_POINT_cmp Bad arguments");
2793
0
        ret = WOLFSSL_FATAL_ERROR;
2794
0
    }
2795
7
    if (ret != -1) {
2796
    #ifdef WOLFSSL_EC_POINT_CMP_JACOBIAN
2797
        /* If same Z ordinate then no need to convert to affine. */
2798
        if (BN_cmp(a->Z, b->Z) == 0) {
2799
            /* Compare */
2800
            ret = ((BN_cmp(a->X, b->X) != 0) || (BN_cmp(a->Y, b->Y) != 0));
2801
        }
2802
        else {
2803
            ret = ec_point_cmp_jacobian(group, a, b, ctx);
2804
        }
2805
    #else
2806
        /* No BN operations performed. */
2807
7
        (void)ctx;
2808
2809
7
        ret = (wc_ecc_cmp_point((ecc_point*)a->internal,
2810
7
            (ecc_point*)b->internal) != MP_EQ);
2811
7
    #endif
2812
7
    }
2813
2814
7
    return ret;
2815
7
}
2816
2817
/* Copy EC point.
2818
 *
2819
 * @param [out] dest  EC point to copy into.
2820
 * @param [in]  src   EC point to copy.
2821
 * @return  1 on success.
2822
 * @return  0 on error.
2823
 */
2824
int wolfSSL_EC_POINT_copy(WOLFSSL_EC_POINT *dest, const WOLFSSL_EC_POINT *src)
2825
1.26k
{
2826
1.26k
    int ret = 1;
2827
2828
1.26k
    WOLFSSL_ENTER("wolfSSL_EC_POINT_copy");
2829
2830
    /* Validate parameters. */
2831
1.26k
    if ((dest == NULL) || (src == NULL)) {
2832
0
        ret = 0;
2833
0
    }
2834
2835
    /* Ensure internal EC point of src is setup. */
2836
1.26k
    if ((ret == 1) && (ec_point_setup(src) != 1)) {
2837
0
        ret = 0;
2838
0
    }
2839
2840
    /* Copy internal EC points. */
2841
1.26k
    if ((ret == 1) && (wc_ecc_copy_point((ecc_point*)src->internal,
2842
1.26k
            (ecc_point*)dest->internal) != MP_OKAY)) {
2843
0
        ret = 0;
2844
0
    }
2845
2846
1.26k
    if (ret == 1) {
2847
        /* Destinatation internal point is set. */
2848
1.26k
        dest->inSet = 1;
2849
2850
        /* Set the external EC point of dest based on internal. */
2851
1.26k
        if (ec_point_external_set(dest) != 1) {
2852
0
            ret = 0;
2853
0
        }
2854
1.26k
    }
2855
2856
1.26k
    return ret;
2857
1.26k
}
2858
2859
/* Duplicates an EC point.
2860
 *
2861
 * @param [in] src    EC point to duplicate.
2862
 * @param [in] group  EC group for the new point.
2863
 * @return  New EC point on success.
2864
 * @return  NULL on failure.
2865
 */
2866
WOLFSSL_EC_POINT *wolfSSL_EC_POINT_dup(const WOLFSSL_EC_POINT *src,
2867
    const WOLFSSL_EC_GROUP *group)
2868
0
{
2869
0
    WOLFSSL_EC_POINT *dest;
2870
2871
0
    WOLFSSL_ENTER("wolfSSL_EC_POINT_dup");
2872
2873
0
    if ((src == NULL) || (group == NULL)) {
2874
0
        return NULL;
2875
0
    }
2876
2877
0
    dest = wolfSSL_EC_POINT_new(group);
2878
0
    if (dest == NULL) {
2879
0
        return NULL;
2880
0
    }
2881
2882
0
    if (wolfSSL_EC_POINT_copy(dest, src) != 1) {
2883
0
        wolfSSL_EC_POINT_free(dest);
2884
0
        return NULL;
2885
0
    }
2886
2887
0
    return dest;
2888
0
}
2889
2890
/* Checks whether point is at infinity.
2891
 *
2892
 * Return code compliant with OpenSSL.
2893
 *
2894
 * @param [in] group  EC group.
2895
 * @param [in] point  EC point to check.
2896
 * @return  1 when at infinity.
2897
 * @return  0 when not at infinity.
2898
 */
2899
int wolfSSL_EC_POINT_is_at_infinity(const WOLFSSL_EC_GROUP *group,
2900
    const WOLFSSL_EC_POINT *point)
2901
358
{
2902
358
    int ret = 1;
2903
2904
358
    WOLFSSL_ENTER("wolfSSL_EC_POINT_is_at_infinity");
2905
2906
    /* Validate parameters. */
2907
358
    if ((group == NULL) || (point == NULL) || (point->internal == NULL)) {
2908
0
        WOLFSSL_MSG("wolfSSL_EC_POINT_is_at_infinity NULL error");
2909
0
        ret = 0;
2910
0
    }
2911
2912
    /* Ensure internal EC point is setup. */
2913
358
    if ((ret == 1) && (ec_point_setup(point) != 1)) {
2914
0
        ret = 0;
2915
0
    }
2916
358
    if (ret == 1) {
2917
358
    #ifndef WOLF_CRYPTO_CB_ONLY_ECC
2918
        /* Check for infinity. */
2919
358
        ret = wc_ecc_point_is_at_infinity((ecc_point*)point->internal);
2920
358
        if (ret < 0) {
2921
0
            WOLFSSL_MSG("ecc_point_is_at_infinity failure");
2922
            /* Error return is 0 by OpenSSL. */
2923
0
            ret = 0;
2924
0
        }
2925
    #else
2926
        WOLFSSL_MSG("ecc_point_is_at_infinitiy compiled out");
2927
        ret = 0;
2928
    #endif
2929
358
    }
2930
2931
358
    return ret;
2932
358
}
2933
2934
#endif /* OPENSSL_EXTRA */
2935
2936
/* End EC_POINT */
2937
2938
/* Start EC_KEY */
2939
2940
#ifdef OPENSSL_EXTRA
2941
2942
/*
2943
 * EC key constructor/deconstructor APIs
2944
 */
2945
2946
/* Allocate a new EC key.
2947
 *
2948
 * Not OpenSSL API.
2949
 *
2950
 * @param [in] heap   Heap hint for dynamic memory allocation.
2951
 * @param [in] devId  Device identifier value.
2952
 * @return  New, allocated EC key on success.
2953
 * @return  NULL on error.
2954
 */
2955
WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_ex(void* heap, int devId)
2956
1.04k
{
2957
1.04k
    WOLFSSL_EC_KEY *key = NULL;
2958
1.04k
    int err = 0;
2959
2960
1.04k
    WOLFSSL_ENTER("wolfSSL_EC_KEY_new");
2961
2962
    /* Allocate memory for EC key. */
2963
1.04k
    key = (WOLFSSL_EC_KEY*)XMALLOC(sizeof(WOLFSSL_EC_KEY), heap,
2964
1.04k
        DYNAMIC_TYPE_ECC);
2965
1.04k
    if (key == NULL) {
2966
0
        WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc WOLFSSL_EC_KEY failure");
2967
0
        err = 1;
2968
0
    }
2969
1.04k
    if (!err) {
2970
        /* Reset all fields to 0. */
2971
1.04k
        XMEMSET(key, 0, sizeof(WOLFSSL_EC_KEY));
2972
        /* Cache heap hint. */
2973
1.04k
        key->heap = heap;
2974
        /* Initialize fields to defaults. */
2975
1.04k
        key->form     = WC_POINT_CONVERSION_UNCOMPRESSED;
2976
2977
        /* Initialize reference count. */
2978
1.04k
        wolfSSL_RefInit(&key->ref, &err);
2979
#ifdef WOLFSSL_REFCNT_ERROR_RETURN
2980
    }
2981
    if (!err) {
2982
#endif
2983
        /* Allocate memory for internal EC key representation. */
2984
1.04k
        key->internal = (ecc_key*)XMALLOC(sizeof(ecc_key), heap,
2985
1.04k
            DYNAMIC_TYPE_ECC);
2986
1.04k
        if (key->internal == NULL) {
2987
0
            WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc ecc key failure");
2988
0
            err = 1;
2989
0
        }
2990
1.04k
    }
2991
1.04k
    if (!err) {
2992
        /* Initialize wolfCrypt EC key. */
2993
1.04k
        if (wc_ecc_init_ex((ecc_key*)key->internal, heap, devId) != 0) {
2994
0
            WOLFSSL_MSG("wolfSSL_EC_KEY_new init ecc key failure");
2995
0
            err = 1;
2996
0
        }
2997
1.04k
    }
2998
2999
1.04k
    if (!err) {
3000
        /* Group unknown at creation */
3001
1.04k
        key->group = wolfSSL_EC_GROUP_new_by_curve_name(WC_NID_undef);
3002
1.04k
        if (key->group == NULL) {
3003
0
            WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc WOLFSSL_EC_GROUP failure");
3004
0
            err = 1;
3005
0
        }
3006
1.04k
    }
3007
3008
1.04k
    if (!err) {
3009
        /* Allocate a point as public key. */
3010
1.04k
        key->pub_key = wolfSSL_EC_POINT_new(key->group);
3011
1.04k
        if (key->pub_key == NULL) {
3012
0
            WOLFSSL_MSG("wolfSSL_EC_POINT_new failure");
3013
0
            err = 1;
3014
0
        }
3015
1.04k
    }
3016
3017
1.04k
    if (!err) {
3018
        /* Allocate a BN as private key. */
3019
1.04k
        key->priv_key = wolfSSL_BN_new();
3020
1.04k
        if (key->priv_key == NULL) {
3021
0
            WOLFSSL_MSG("wolfSSL_BN_new failure");
3022
0
            err = 1;
3023
0
        }
3024
1.04k
    }
3025
3026
1.04k
    if (err) {
3027
        /* Dispose of EC key on error. */
3028
0
        wolfSSL_EC_KEY_free(key);
3029
0
        key = NULL;
3030
0
    }
3031
    /* Return new EC key object. */
3032
1.04k
    return key;
3033
1.04k
}
3034
3035
/* Allocate a new EC key.
3036
 *
3037
 * @return  New, allocated EC key on success.
3038
 * @return  NULL on error.
3039
 */
3040
WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new(void)
3041
1.04k
{
3042
1.04k
    return wolfSSL_EC_KEY_new_ex(NULL, INVALID_DEVID);
3043
1.04k
}
3044
3045
/* Create new EC key with the group having the specified numeric ID.
3046
 *
3047
 * @param [in] nid  Numeric ID.
3048
 * @return  New, allocated EC key on success.
3049
 * @return  NULL on error.
3050
 */
3051
WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_by_curve_name(int nid)
3052
0
{
3053
0
    WOLFSSL_EC_KEY *key;
3054
0
    int err = 0;
3055
3056
0
    WOLFSSL_ENTER("wolfSSL_EC_KEY_new_by_curve_name");
3057
3058
    /* Allocate empty, EC key. */
3059
0
    key = wolfSSL_EC_KEY_new();
3060
0
    if (key == NULL) {
3061
0
        WOLFSSL_MSG("wolfSSL_EC_KEY_new failure");
3062
0
        err = 1;
3063
0
    }
3064
3065
0
    if (!err) {
3066
        /* Set group to be nid. */
3067
0
        ec_group_set_nid(key->group, nid);
3068
0
        if (key->group->curve_idx == -1) {
3069
0
            wolfSSL_EC_KEY_free(key);
3070
0
            key = NULL;
3071
0
        }
3072
0
    }
3073
3074
    /* Return the new EC key object. */
3075
0
    return key;
3076
0
}
3077
3078
/* Dispose of the EC key and allocated data.
3079
 *
3080
 * Cannot use key after this call.
3081
 *
3082
 * @param [in] key  EC key to free.
3083
 */
3084
void wolfSSL_EC_KEY_free(WOLFSSL_EC_KEY *key)
3085
1.04k
{
3086
1.04k
    int doFree = 0;
3087
1.04k
    int err;
3088
3089
1.04k
    (void)err;
3090
3091
1.04k
    WOLFSSL_ENTER("wolfSSL_EC_KEY_free");
3092
3093
1.04k
    if (key != NULL) {
3094
1.04k
        void* heap = key->heap;
3095
3096
        /* Decrement reference count. */
3097
1.04k
        wolfSSL_RefDec(&key->ref, &doFree, &err);
3098
1.04k
        if (doFree) {
3099
            /* Dispose of allocated reference counting data. */
3100
1.04k
            wolfSSL_RefFree(&key->ref);
3101
3102
            /* Dispose of private key. */
3103
1.04k
            wolfSSL_BN_free(key->priv_key);
3104
1.04k
            wolfSSL_EC_POINT_free(key->pub_key);
3105
1.04k
            wolfSSL_EC_GROUP_free(key->group);
3106
1.04k
            if (key->internal != NULL) {
3107
                /* Dispose of wolfCrypt representation of EC key. */
3108
1.04k
                wc_ecc_free((ecc_key*)key->internal);
3109
1.04k
                XFREE(key->internal, heap, DYNAMIC_TYPE_ECC);
3110
1.04k
            }
3111
3112
            /* Set back to NULLs for safety. */
3113
1.04k
            ForceZero(key, sizeof(*key));
3114
3115
            /* Dispose of the memory associated with the EC key. */
3116
1.04k
            XFREE(key, heap, DYNAMIC_TYPE_ECC);
3117
1.04k
            (void)heap;
3118
1.04k
        }
3119
1.04k
    }
3120
1.04k
}
3121
3122
/* Increments ref count of EC key.
3123
 *
3124
 * @param [in, out] key  EC key.
3125
 * @return  1 on success
3126
 * @return  0 on error
3127
 */
3128
int wolfSSL_EC_KEY_up_ref(WOLFSSL_EC_KEY* key)
3129
0
{
3130
0
    int err = 1;
3131
3132
0
    if (key != NULL) {
3133
0
        wolfSSL_RefInc(&key->ref, &err);
3134
0
    }
3135
3136
0
    return !err;
3137
0
}
3138
3139
#ifndef NO_CERTS
3140
3141
#if defined(OPENSSL_ALL)
3142
/* Copy the internal, wolfCrypt EC key.
3143
 *
3144
 * @param [in, out] dst  Destination wolfCrypt EC key.
3145
 * @param [in]      src  Source wolfCrypt EC key.
3146
 * @return  0 on success.
3147
 * @return  Negative on error.
3148
 */
3149
static int wolfssl_ec_key_int_copy(ecc_key* dst, const ecc_key* src)
3150
0
{
3151
0
    int ret;
3152
3153
    /* Copy public key. */
3154
0
#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)
3155
0
    ret = wc_ecc_copy_point(&src->pubkey, &dst->pubkey);
3156
#else
3157
    ret = wc_ecc_copy_point((ecc_point*)&src->pubkey, &dst->pubkey);
3158
#endif
3159
0
    if (ret != MP_OKAY) {
3160
0
        WOLFSSL_MSG("wc_ecc_copy_point error");
3161
0
    }
3162
3163
0
    if (ret == 0) {
3164
        /* Copy private key. */
3165
0
        ret = mp_copy(wc_ecc_key_get_priv((ecc_key*)src),
3166
0
            wc_ecc_key_get_priv(dst));
3167
0
        if (ret != MP_OKAY) {
3168
0
            WOLFSSL_MSG("mp_copy error");
3169
0
        }
3170
0
    }
3171
3172
0
    if (ret == 0) {
3173
        /* Copy domain parameters. */
3174
0
        if (src->dp) {
3175
0
            ret = wc_ecc_set_curve(dst, 0, src->dp->id);
3176
0
            if (ret != 0) {
3177
0
                WOLFSSL_MSG("wc_ecc_set_curve error");
3178
0
            }
3179
0
        }
3180
0
    }
3181
3182
0
    if (ret == 0) {
3183
        /* Copy the other components. */
3184
0
        dst->type  = src->type;
3185
0
        dst->idx   = src->idx;
3186
0
        dst->state = src->state;
3187
0
        dst->flags = src->flags;
3188
0
    }
3189
3190
0
    return ret;
3191
0
}
3192
3193
/* Copies ecc_key into new WOLFSSL_EC_KEY object
3194
 *
3195
 * Copies the internal representation as well.
3196
 *
3197
 * @param [in] src  EC key to duplicate.
3198
 *
3199
 * @return  EC key on success.
3200
 * @return  NULL on error.
3201
 */
3202
WOLFSSL_EC_KEY *wolfSSL_EC_KEY_dup(const WOLFSSL_EC_KEY *src)
3203
0
{
3204
0
    int err = 0;
3205
0
    WOLFSSL_EC_KEY* newKey = NULL;
3206
3207
0
    WOLFSSL_ENTER("wolfSSL_EC_KEY_dup");
3208
3209
    /* Validate EC key. */
3210
0
    if ((src == NULL) || (src->internal == NULL) || (src->group == NULL) ||
3211
0
         (src->pub_key == NULL) || (src->priv_key == NULL)) {
3212
0
        WOLFSSL_MSG("src NULL error");
3213
0
        err = 1;
3214
0
    }
3215
3216
0
    if (!err) {
3217
        /* Create a new, empty key. */
3218
0
        newKey = wolfSSL_EC_KEY_new();
3219
0
        if (newKey == NULL) {
3220
0
            WOLFSSL_MSG("wolfSSL_EC_KEY_new error");
3221
0
            err = 1;
3222
0
        }
3223
0
    }
3224
3225
0
    if (!err) {
3226
        /* Copy internal EC key. */
3227
0
        if (wolfssl_ec_key_int_copy((ecc_key*)newKey->internal,
3228
0
                (ecc_key*)src->internal) != 0) {
3229
0
            WOLFSSL_MSG("Copying internal EC key error");
3230
0
            err = 1;
3231
0
        }
3232
0
    }
3233
0
    if (!err) {
3234
        /* Internal key set. */
3235
0
        newKey->inSet = 1;
3236
3237
        /* Copy group */
3238
0
        err = wolfssl_ec_group_copy(newKey->group, src->group);
3239
0
    }
3240
    /* Copy public key. */
3241
0
    if ((!err) && (wolfSSL_EC_POINT_copy(newKey->pub_key, src->pub_key) != 1)) {
3242
0
        WOLFSSL_MSG("Copying EC public key error");
3243
0
        err = 1;
3244
0
    }
3245
3246
0
    if (!err) {
3247
        /* Set header size of private key in PKCS#8 format.*/
3248
0
        newKey->pkcs8HeaderSz = src->pkcs8HeaderSz;
3249
3250
        /* Copy private key. */
3251
0
        if (wolfSSL_BN_copy(newKey->priv_key, src->priv_key) == NULL) {
3252
0
            WOLFSSL_MSG("Copying EC private key error");
3253
0
            err = 1;
3254
0
        }
3255
0
    }
3256
3257
0
    if (err) {
3258
        /* Dispose of EC key on error. */
3259
0
        wolfSSL_EC_KEY_free(newKey);
3260
0
        newKey = NULL;
3261
0
    }
3262
    /* Return the new EC key. */
3263
0
    return newKey;
3264
0
}
3265
3266
#endif /* OPENSSL_ALL */
3267
3268
#endif /* !NO_CERTS */
3269
3270
/*
3271
 * EC key to/from bin/octet APIs
3272
 */
3273
3274
/* Create an EC key from the octet encoded public key.
3275
 *
3276
 * Behaviour checked against OpenSSL.
3277
 *
3278
 * @param [out]     key  Reference to EC key. Must pass in a valid object with
3279
 *                       group set.
3280
 * @param [in, out] in   On in, reference to buffer that contains data.
3281
 *                       On out, reference to buffer after public key data.
3282
 * @param [in]      len  Length of data in the buffer. Must be length of the
3283
 *                       encoded public key.
3284
 * @return  Allocated EC key on success.
3285
 * @return  NULL on error.
3286
 */
3287
WOLFSSL_EC_KEY *wolfSSL_o2i_ECPublicKey(WOLFSSL_EC_KEY **key,
3288
   const unsigned char **in, long len)
3289
0
{
3290
0
    int err = 0;
3291
0
    WOLFSSL_EC_KEY* ret = NULL;
3292
3293
0
    WOLFSSL_ENTER("wolfSSL_o2i_ECPublicKey");
3294
3295
    /* Validate parameters: EC group needed to perform import. */
3296
0
    if ((key == NULL) || (*key == NULL) || ((*key)->group == NULL) ||
3297
0
            (in == NULL) || (*in == NULL) || (len <= 0)) {
3298
0
        WOLFSSL_MSG("wolfSSL_o2i_ECPublicKey Bad arguments");
3299
0
        err = 1;
3300
0
    }
3301
3302
0
    if (!err) {
3303
        /* Return the EC key object passed in. */
3304
0
        ret = *key;
3305
3306
        /* Import point into public key field. */
3307
0
        if (wolfSSL_EC_POINT_oct2point(ret->group, ret->pub_key, *in,
3308
0
                (size_t)len, NULL) != 1) {
3309
0
            WOLFSSL_MSG("wolfSSL_EC_POINT_oct2point error");
3310
0
            ret = NULL;
3311
0
            err = 1;
3312
0
        }
3313
0
    }
3314
0
    if (!err) {
3315
        /* Assumed length passed in is all the data. */
3316
0
        *in += len;
3317
0
    }
3318
3319
0
    return ret;
3320
0
}
3321
3322
/* Puts the encoded public key into out.
3323
 *
3324
 * Passing in NULL for out returns length only.
3325
 * Passing in NULL for *out has buffer allocated, encoded into and passed back.
3326
 * Passing non-NULL for *out has it encoded into and pointer moved past.
3327
 *
3328
 * @param [in]      key  EC key to encode.
3329
 * @param [in, out] out  Reference to buffer to encode into. May be NULL or
3330
 *                       point to NULL.
3331
 * @return  Length of encoding in bytes on success.
3332
 * @return  0 on error.
3333
 */
3334
int wolfSSL_i2o_ECPublicKey(const WOLFSSL_EC_KEY *key, unsigned char **out)
3335
0
{
3336
0
    int ret = 1;
3337
0
    size_t len = 0;
3338
0
    int form = WC_POINT_CONVERSION_UNCOMPRESSED;
3339
3340
0
    WOLFSSL_ENTER("wolfSSL_i2o_ECPublicKey");
3341
3342
    /* Validate parameters. */
3343
0
    if (key == NULL) {
3344
0
        WOLFSSL_MSG("wolfSSL_i2o_ECPublicKey Bad arguments");
3345
0
        ret = 0;
3346
0
    }
3347
3348
    /* Ensure the external key data is set from the internal EC key. */
3349
0
    if ((ret == 1) && (!key->exSet) && (SetECKeyExternal((WOLFSSL_EC_KEY*)
3350
0
            key) != 1)) {
3351
0
        WOLFSSL_MSG("SetECKeyExternal failure");
3352
0
        ret = 0;
3353
0
    }
3354
3355
0
    if (ret == 1) {
3356
0
    #ifdef HAVE_COMP_KEY
3357
        /* Default to compressed form if not set */
3358
0
        form = (key->form == WC_POINT_CONVERSION_UNCOMPRESSED) ?
3359
0
               WC_POINT_CONVERSION_UNCOMPRESSED :
3360
0
               WC_POINT_CONVERSION_COMPRESSED;
3361
0
    #endif
3362
3363
        /* Calculate length of point encoding. */
3364
0
        len = wolfSSL_EC_POINT_point2oct(key->group, key->pub_key, form, NULL,
3365
0
            0, NULL);
3366
0
    }
3367
    /* Encode if length calculated and pointer supplied to update. */
3368
0
    if ((ret == 1) && (len != 0) && (out != NULL)) {
3369
0
        unsigned char *tmp = NULL;
3370
3371
        /* Allocate buffer for encoding if no buffer supplied. */
3372
0
        if (*out == NULL) {
3373
0
            tmp = (unsigned char*)XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL);
3374
0
            if (tmp == NULL) {
3375
0
                WOLFSSL_MSG("malloc failed");
3376
0
                ret = 0;
3377
0
            }
3378
0
        }
3379
0
        else {
3380
            /* Get buffer to encode into. */
3381
0
            tmp = *out;
3382
0
        }
3383
3384
        /* Encode public key into buffer. */
3385
0
        if ((ret == 1) && (wolfSSL_EC_POINT_point2oct(key->group, key->pub_key,
3386
0
                form, tmp, len, NULL) == 0)) {
3387
0
            ret = 0;
3388
0
        }
3389
3390
0
        if (ret == 1) {
3391
            /* Return buffer if allocated. */
3392
0
            if (*out == NULL) {
3393
0
                *out = tmp;
3394
0
            }
3395
0
            else {
3396
                /* Step over encoded data if not allocated. */
3397
0
                *out += len;
3398
0
            }
3399
0
        }
3400
0
        else if (*out == NULL) {
3401
            /* Dispose of allocated buffer. */
3402
0
            XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL);
3403
0
        }
3404
0
    }
3405
3406
0
    if (ret == 1) {
3407
        /* Return length on success. */
3408
0
        ret = (int)len;
3409
0
    }
3410
0
    return ret;
3411
0
}
3412
3413
#ifdef HAVE_ECC_KEY_IMPORT
3414
/* Create a EC key from the DER encoded private key.
3415
 *
3416
 * @param [out]     key   Reference to EC key.
3417
 * @param [in, out] in    On in, reference to buffer that contains DER data.
3418
 *                        On out, reference to buffer after private key data.
3419
 * @param [in]      long  Length of data in the buffer. May be larger than the
3420
 *                        length of the encoded private key.
3421
 * @return  Allocated EC key on success.
3422
 * @return  NULL on error.
3423
 */
3424
WOLFSSL_EC_KEY* wolfSSL_d2i_ECPrivateKey(WOLFSSL_EC_KEY** key,
3425
    const unsigned char** in, long len)
3426
0
{
3427
0
    int err = 0;
3428
0
    word32 idx = 0;
3429
0
    WOLFSSL_EC_KEY* ret = NULL;
3430
3431
0
    WOLFSSL_ENTER("wolfSSL_d2i_ECPrivateKey");
3432
3433
    /* Validate parameters. */
3434
0
    if ((in == NULL) || (*in == NULL) || (len <= 0)) {
3435
0
        WOLFSSL_MSG("wolfSSL_d2i_ECPrivateKey Bad arguments");
3436
0
        err = 1;
3437
0
    }
3438
3439
    /* Create a new, empty EC key.  */
3440
0
    if ((!err) && ((ret = wolfSSL_EC_KEY_new()) == NULL)) {
3441
0
        WOLFSSL_MSG("wolfSSL_EC_KEY_new error");
3442
0
        err = 1;
3443
0
    }
3444
3445
    /* Decode the private key DER data into internal EC key. */
3446
0
    if ((!err) && (wc_EccPrivateKeyDecode(*in, &idx, (ecc_key*)ret->internal,
3447
0
            (word32)len) != 0)) {
3448
0
        WOLFSSL_MSG("wc_EccPrivateKeyDecode error");
3449
0
        err = 1;
3450
0
    }
3451
3452
0
    if (!err) {
3453
        /* Internal EC key setup. */
3454
0
        ret->inSet = 1;
3455
3456
        /* Set the EC key from the internal values. */
3457
0
        if (SetECKeyExternal(ret) != 1) {
3458
0
            WOLFSSL_MSG("SetECKeyExternal error");
3459
0
            err = 1;
3460
0
        }
3461
0
    }
3462
3463
0
    if (!err) {
3464
        /* Move buffer on to next byte after data used. */
3465
0
        *in += idx;
3466
0
        if (key) {
3467
            /* Return new EC key through reference. */
3468
0
            *key = ret;
3469
0
        }
3470
0
    }
3471
3472
0
    if (err && (ret != NULL)) {
3473
        /* Dispose of allocated EC key. */
3474
0
        wolfSSL_EC_KEY_free(ret);
3475
0
        ret = NULL;
3476
0
    }
3477
0
    return ret;
3478
0
}
3479
#endif /* HAVE_ECC_KEY_IMPORT */
3480
3481
/* Enecode the private key of the EC key into the buffer as DER.
3482
 *
3483
 * @param [in]      key  EC key to encode.
3484
 * @param [in, out] out  On in, reference to buffer to place DER encoding into.
3485
 *                       On out, reference to buffer after the encoding.
3486
 *                       May be NULL.
3487
 * @return  Length of DER encoding on success.
3488
 * @return  0 on error.
3489
 */
3490
int wolfSSL_i2d_ECPrivateKey(const WOLFSSL_EC_KEY *key, unsigned char **out)
3491
0
{
3492
0
    int err = 0;
3493
0
    word32 len = 0;
3494
3495
0
    WOLFSSL_ENTER("wolfSSL_i2d_ECPrivateKey");
3496
3497
    /* Validate parameters. */
3498
0
    if (key == NULL) {
3499
0
        WOLFSSL_MSG("wolfSSL_i2d_ECPrivateKey Bad arguments");
3500
0
        err = 1;
3501
0
    }
3502
3503
    /* Update the internal EC key if not set. */
3504
0
    if ((!err) && (!key->inSet) && (SetECKeyInternal((WOLFSSL_EC_KEY*)key) !=
3505
0
            1)) {
3506
0
        WOLFSSL_MSG("SetECKeyInternal error");
3507
0
        err = 1;
3508
0
    }
3509
3510
    /* Calculate the length of the private key DER encoding using internal EC
3511
     * key. */
3512
0
    if ((!err) && ((int)(len = (word32)wc_EccKeyDerSize((ecc_key*)key->internal,
3513
0
           0)) <= 0)) {
3514
0
        WOLFSSL_MSG("wc_EccKeyDerSize error");
3515
0
        err = 1;
3516
0
    }
3517
3518
    /* Only return length when out is NULL. */
3519
0
    if ((!err) && (out != NULL)) {
3520
0
        unsigned char* buf = NULL;
3521
3522
        /* Must have a buffer to encode into. */
3523
0
        if (*out == NULL) {
3524
            /* Allocate a new buffer of appropriate length. */
3525
0
            buf = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3526
0
            if (buf == NULL) {
3527
                /* Error and return 0. */
3528
0
                err = 1;
3529
0
                len = 0;
3530
0
            }
3531
0
            else {
3532
                /* Return the allocated buffer. */
3533
0
                *out = buf;
3534
0
            }
3535
0
        }
3536
        /* Encode the internal EC key as a private key in DER format. */
3537
0
        if ((!err) && wc_EccPrivateKeyToDer((ecc_key*)key->internal, *out,
3538
0
                len) < 0) {
3539
0
            WOLFSSL_MSG("wc_EccPrivateKeyToDer error");
3540
0
            err = 1;
3541
0
        }
3542
0
        else if (buf != *out) {
3543
            /* Move the reference to byte past encoded private key. */
3544
0
            *out += len;
3545
0
        }
3546
3547
        /* Dispose of any allocated buffer on error. */
3548
0
        if (err && (*out == buf)) {
3549
0
            if (buf != NULL) {
3550
0
                ForceZero(buf, len);
3551
0
            }
3552
0
            XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3553
0
            *out = NULL;
3554
0
        }
3555
0
    }
3556
3557
0
    return (int)len;
3558
0
}
3559
3560
/* Load private key into EC key from DER encoding.
3561
 *
3562
 * Not an OpenSSL compatibility API.
3563
 *
3564
 * @param [in, out] key     EC key to put private key values into.
3565
 * @param [in]      derBuf  Buffer holding DER encoding.
3566
 * @param [in]      derSz   Size of DER encoding in bytes.
3567
 * @return  1 on success.
3568
 * @return  -1 on error.
3569
 */
3570
int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key, const unsigned char* derBuf,
3571
                           int derSz)
3572
0
{
3573
0
    return wolfSSL_EC_KEY_LoadDer_ex(key, derBuf, derSz,
3574
0
        WOLFSSL_EC_KEY_LOAD_PRIVATE);
3575
0
}
3576
3577
/* Load private/public key into EC key from DER encoding.
3578
 *
3579
 * Not an OpenSSL compatibility API.
3580
 *
3581
 * @param [in, out] key     EC key to put private/public key values into.
3582
 * @param [in]      derBuf  Buffer holding DER encoding.
3583
 * @param [in]      derSz   Size of DER encoding in bytes.
3584
 * @param [in]      opt     Key type option. Valid values:
3585
 *                            WOLFSSL_EC_KEY_LOAD_PRIVATE,
3586
 *                            WOLFSSL_EC_KEY_LOAD_PUBLIC.
3587
 * @return  1 on success.
3588
 * @return  -1 on error.
3589
 */
3590
int wolfSSL_EC_KEY_LoadDer_ex(WOLFSSL_EC_KEY* key, const unsigned char* derBuf,
3591
                              int derSz, int opt)
3592
253
{
3593
253
    int res = 1;
3594
253
    int ret;
3595
253
    word32 idx = 0;
3596
253
    word32 algId;
3597
3598
253
    WOLFSSL_ENTER("wolfSSL_EC_KEY_LoadDer");
3599
3600
    /* Validate parameters. */
3601
253
    if ((key == NULL) || (key->internal == NULL) || (derBuf == NULL) ||
3602
253
            (derSz <= 0)) {
3603
0
        WOLFSSL_MSG("Bad function arguments");
3604
0
        res = WOLFSSL_FATAL_ERROR;
3605
0
    }
3606
253
    if ((res == 1) && (opt != WOLFSSL_EC_KEY_LOAD_PRIVATE) &&
3607
253
            (opt != WOLFSSL_EC_KEY_LOAD_PUBLIC)) {
3608
0
        res = WOLFSSL_FATAL_ERROR;
3609
0
    }
3610
3611
253
    if (res == 1) {
3612
        /* Assume no PKCS#8 header. */
3613
253
        key->pkcs8HeaderSz = 0;
3614
3615
        /* Check if input buffer has PKCS8 header. In the case that it does not
3616
         * have a PKCS8 header then do not error out.
3617
         */
3618
253
        if ((ret = ToTraditionalInline_ex((const byte*)derBuf, &idx,
3619
253
                (word32)derSz, &algId)) >= 0) {
3620
0
            WOLFSSL_MSG("Found PKCS8 header");
3621
0
            key->pkcs8HeaderSz = (word16)idx;
3622
0
            res = 1;
3623
0
        }
3624
        /* Error out on parsing error. */
3625
253
        else if (ret != WC_NO_ERR_TRACE(ASN_PARSE_E)) {
3626
0
            WOLFSSL_MSG("Unexpected error with trying to remove PKCS8 header");
3627
0
            res = WOLFSSL_FATAL_ERROR;
3628
0
        }
3629
253
    }
3630
3631
253
    if (res == 1) {
3632
        /* Load into internal EC key based on key type option. */
3633
253
        if (opt == WOLFSSL_EC_KEY_LOAD_PRIVATE) {
3634
0
            ret = wc_EccPrivateKeyDecode(derBuf, &idx, (ecc_key*)key->internal,
3635
0
                (word32)derSz);
3636
0
        }
3637
253
        else {
3638
253
            ret = wc_EccPublicKeyDecode(derBuf, &idx, (ecc_key*)key->internal,
3639
253
                (word32)derSz);
3640
253
            if (ret < 0) {
3641
125
                ecc_key *tmp = (ecc_key*)XMALLOC(sizeof(ecc_key),
3642
125
                    ((ecc_key*)key->internal)->heap, DYNAMIC_TYPE_ECC);
3643
125
                if (tmp == NULL) {
3644
0
                    ret = WOLFSSL_FATAL_ERROR;
3645
0
                }
3646
125
                else {
3647
                    /* We now try again as x.963 [point type][x][opt y]. */
3648
125
                    ret = wc_ecc_init_ex(tmp, ((ecc_key*)key->internal)->heap,
3649
125
                                         INVALID_DEVID);
3650
125
                    if (ret == 0) {
3651
125
                        ret = wc_ecc_import_x963(derBuf, (word32)derSz, tmp);
3652
125
                        if (ret == 0) {
3653
                            /* Take ownership of new key - set tmp to the old
3654
                             * key which will then be freed below. */
3655
0
                            ecc_key *old = (ecc_key *)key->internal;
3656
0
                            key->internal = tmp;
3657
0
                            tmp = old;
3658
3659
0
                            idx = (word32)derSz;
3660
0
                        }
3661
125
                        wc_ecc_free(tmp);
3662
125
                    }
3663
125
                    XFREE(tmp, ((ecc_key*)key->internal)->heap,
3664
125
                          DYNAMIC_TYPE_ECC);
3665
125
                }
3666
125
            }
3667
253
        }
3668
253
        if (ret < 0) {
3669
            /* Error returned from wolfSSL. */
3670
125
            if (opt == WOLFSSL_EC_KEY_LOAD_PRIVATE) {
3671
0
                WOLFSSL_MSG("wc_EccPrivateKeyDecode failed");
3672
0
            }
3673
125
            else {
3674
125
                WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
3675
125
            }
3676
125
            res = WOLFSSL_FATAL_ERROR;
3677
125
        }
3678
3679
        /* Internal key updated - update whether it is a valid key. */
3680
253
        key->inSet = (res == 1);
3681
253
    }
3682
3683
    /* Set the external EC key based on value in internal. */
3684
253
    if ((res == 1) && (SetECKeyExternal(key) != 1)) {
3685
0
        WOLFSSL_MSG("SetECKeyExternal failed");
3686
0
        res = WOLFSSL_FATAL_ERROR;
3687
0
    }
3688
3689
253
    return res;
3690
253
}
3691
3692
3693
#ifndef NO_BIO
3694
3695
WOLFSSL_EC_KEY *wolfSSL_d2i_EC_PUBKEY_bio(WOLFSSL_BIO *bio,
3696
        WOLFSSL_EC_KEY **out)
3697
0
{
3698
0
    char* data = NULL;
3699
0
    int dataSz = 0;
3700
0
    int memAlloced = 0;
3701
0
    WOLFSSL_EC_KEY* ec = NULL;
3702
0
    int err = 0;
3703
3704
0
    WOLFSSL_ENTER("wolfSSL_d2i_EC_PUBKEY_bio");
3705
3706
0
    if (bio == NULL)
3707
0
        return NULL;
3708
3709
0
    if (err == 0 && wolfssl_read_bio(bio, &data, &dataSz, &memAlloced) != 0) {
3710
0
        WOLFSSL_ERROR_MSG("wolfssl_read_bio failed");
3711
0
        err = 1;
3712
0
    }
3713
3714
0
    if (err == 0 && (ec = wolfSSL_EC_KEY_new()) == NULL) {
3715
0
        WOLFSSL_ERROR_MSG("wolfSSL_EC_KEY_new failed");
3716
0
        err = 1;
3717
0
    }
3718
3719
    /* Load the EC key with the public key from the DER encoding. */
3720
0
    if (err == 0 && wolfSSL_EC_KEY_LoadDer_ex(ec, (const unsigned char*)data,
3721
0
            dataSz, WOLFSSL_EC_KEY_LOAD_PUBLIC) != 1) {
3722
0
        WOLFSSL_ERROR_MSG("wolfSSL_EC_KEY_LoadDer_ex failed");
3723
0
        err = 1;
3724
0
    }
3725
3726
0
    if (memAlloced)
3727
0
        XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3728
0
    if (err) { /* on error */
3729
0
        wolfSSL_EC_KEY_free(ec);
3730
0
        ec = NULL;
3731
0
    }
3732
0
    else { /* on success */
3733
0
        if (out != NULL)
3734
0
            *out = ec;
3735
0
    }
3736
3737
0
    return ec;
3738
0
}
3739
3740
#endif /* !NO_BIO */
3741
3742
/*
3743
 * EC key PEM APIs
3744
 */
3745
3746
#ifdef HAVE_ECC_KEY_EXPORT
3747
#if defined(WOLFSSL_KEY_GEN) && (!defined(NO_FILESYSTEM) || !defined(NO_BIO))
3748
/* Encode the EC public key as DER.
3749
 *
3750
 * @param [in]  key   EC key to encode.
3751
 * @param [out] der   Pointer through which buffer is returned.
3752
 * @param [in]  heap  Heap hint.
3753
 * @return  Size of encoding on success.
3754
 * @return  0 on error.
3755
 */
3756
static int wolfssl_ec_key_to_pubkey_der(WOLFSSL_EC_KEY* key,
3757
    unsigned char** der, void* heap)
3758
0
{
3759
0
    int sz;
3760
0
    unsigned char* buf = NULL;
3761
3762
0
    (void)heap;
3763
3764
    /* Calculate encoded size to allocate. */
3765
0
    sz = wc_EccPublicKeyDerSize((ecc_key*)key->internal, 1);
3766
0
    if (sz <= 0) {
3767
0
        WOLFSSL_MSG("wc_EccPublicKeyDerSize failed");
3768
0
        sz = 0;
3769
0
    }
3770
0
    if (sz > 0) {
3771
        /* Allocate memory to hold encoding. */
3772
0
        buf = (byte*)XMALLOC((size_t)sz, heap, DYNAMIC_TYPE_TMP_BUFFER);
3773
0
        if (buf == NULL) {
3774
0
            WOLFSSL_MSG("malloc failed");
3775
0
            sz = 0;
3776
0
        }
3777
0
    }
3778
0
    if (sz > 0) {
3779
        /* Encode public key to DER using wolfSSL.  */
3780
0
        sz = wc_EccPublicKeyToDer((ecc_key*)key->internal, buf, (word32)sz, 1);
3781
0
        if (sz < 0) {
3782
0
            WOLFSSL_MSG("wc_EccPublicKeyToDer failed");
3783
0
            sz = 0;
3784
0
        }
3785
0
    }
3786
3787
    /* Return buffer on success. */
3788
0
    if (sz > 0) {
3789
0
        *der = buf;
3790
0
    }
3791
0
    else {
3792
        /* Dispose of any dynamically allocated data not returned. */
3793
0
        XFREE(buf, heap, DYNAMIC_TYPE_TMP_BUFFER);
3794
0
    }
3795
3796
0
    return sz;
3797
0
}
3798
#endif
3799
3800
#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_KEY_GEN)
3801
/*
3802
 * Return code compliant with OpenSSL.
3803
 *
3804
 * @param [in] fp   File pointer to write PEM encoding to.
3805
 * @param [in] key  EC key to encode and write.
3806
 * @return  1 on success.
3807
 * @return  0 on error.
3808
 */
3809
int wolfSSL_PEM_write_EC_PUBKEY(XFILE fp, WOLFSSL_EC_KEY* key)
3810
0
{
3811
0
    int ret = 1;
3812
0
    unsigned char* derBuf = NULL;
3813
0
    int derSz = 0;
3814
3815
0
    WOLFSSL_ENTER("wolfSSL_PEM_write_EC_PUBKEY");
3816
3817
    /* Validate parameters. */
3818
0
    if ((fp == XBADFILE) || (key == NULL)) {
3819
0
        WOLFSSL_MSG("Bad argument.");
3820
0
        return 0;
3821
0
    }
3822
3823
    /* Encode public key in EC key as DER. */
3824
0
    derSz = wolfssl_ec_key_to_pubkey_der(key, &derBuf, key->heap);
3825
0
    if (derSz == 0) {
3826
0
        ret = 0;
3827
0
    }
3828
3829
    /* Write out to file the PEM encoding of the DER. */
3830
0
    if ((ret == 1) && (der_write_to_file_as_pem(derBuf, derSz, fp,
3831
0
            ECC_PUBLICKEY_TYPE, key->heap) != 1)) {
3832
0
        ret = 0;
3833
0
    }
3834
3835
    /* Dispose of any dynamically allocated data. */
3836
0
    XFREE(derBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
3837
3838
0
    WOLFSSL_LEAVE("wolfSSL_PEM_write_EC_PUBKEY", ret);
3839
3840
0
    return ret;
3841
0
}
3842
#endif
3843
#endif
3844
3845
#ifndef NO_BIO
3846
/* Read a PEM encoded EC public key from a BIO.
3847
 *
3848
 * @param [in]  bio   BIO to read EC public key from.
3849
 * @param [out] out   Pointer to return EC key object through. May be NULL.
3850
 * @param [in]  cb    Password callback when PEM encrypted.
3851
 * @param [in]  pass  NUL terminated string for passphrase when PEM
3852
 *                    encrypted.
3853
 * @return  New EC key object on success.
3854
 * @return  NULL on error.
3855
 */
3856
WOLFSSL_EC_KEY* wolfSSL_PEM_read_bio_EC_PUBKEY(WOLFSSL_BIO* bio,
3857
    WOLFSSL_EC_KEY** out, wc_pem_password_cb* cb, void *pass)
3858
0
{
3859
0
    int             err = 0;
3860
0
    WOLFSSL_EC_KEY* ec = NULL;
3861
0
    DerBuffer*      der = NULL;
3862
0
    int             keyFormat = 0;
3863
3864
0
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_EC_PUBKEY");
3865
3866
    /* Validate parameters. */
3867
0
    if (bio == NULL) {
3868
0
        err = 1;
3869
0
    }
3870
3871
0
    if (!err) {
3872
        /* Create an empty EC key. */
3873
0
        ec = wolfSSL_EC_KEY_new();
3874
0
        if (ec == NULL) {
3875
0
            err = 1;
3876
0
        }
3877
0
    }
3878
    /* Read a PEM key in to a new DER buffer. */
3879
0
    if ((!err) && (pem_read_bio_key(bio, cb, pass, ECC_PUBLICKEY_TYPE,
3880
0
            &keyFormat, &der) <= 0)) {
3881
0
        err = 1;
3882
0
    }
3883
    /* Load the EC key with the public key from the DER encoding. */
3884
0
    if ((!err) && (wolfSSL_EC_KEY_LoadDer_ex(ec, der->buffer, (int)der->length,
3885
0
            WOLFSSL_EC_KEY_LOAD_PUBLIC) != 1)) {
3886
0
        WOLFSSL_ERROR_MSG("Error loading DER buffer into WOLFSSL_EC_KEY");
3887
0
        err = 1;
3888
0
    }
3889
3890
    /* Dispose of dynamically allocated data not needed anymore. */
3891
0
    FreeDer(&der);
3892
0
    if (err) {
3893
0
        wolfSSL_EC_KEY_free(ec);
3894
0
        ec = NULL;
3895
0
    }
3896
3897
    /* Return EC key through out if required. */
3898
0
    if ((out != NULL) && (ec != NULL)) {
3899
0
        *out = ec;
3900
0
    }
3901
0
    return ec;
3902
0
}
3903
3904
/* Read a PEM encoded EC private key from a BIO.
3905
 *
3906
 * @param [in]  bio   BIO to read EC private key from.
3907
 * @param [out] out   Pointer to return EC key object through. May be NULL.
3908
 * @param [in]  cb    Password callback when PEM encrypted.
3909
 * @param [in]  pass  NUL terminated string for passphrase when PEM
3910
 *                    encrypted.
3911
 * @return  New EC key object on success.
3912
 * @return  NULL on error.
3913
 */
3914
WOLFSSL_EC_KEY* wolfSSL_PEM_read_bio_ECPrivateKey(WOLFSSL_BIO* bio,
3915
   WOLFSSL_EC_KEY** out, wc_pem_password_cb* cb, void *pass)
3916
0
{
3917
0
    int             err = 0;
3918
0
    WOLFSSL_EC_KEY* ec = NULL;
3919
0
    DerBuffer*      der = NULL;
3920
0
    int             keyFormat = 0;
3921
3922
0
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_ECPrivateKey");
3923
3924
    /* Validate parameters. */
3925
0
    if (bio == NULL) {
3926
0
        err = 1;
3927
0
    }
3928
3929
0
    if (!err) {
3930
        /* Create an empty EC key. */
3931
0
        ec = wolfSSL_EC_KEY_new();
3932
0
        if (ec == NULL) {
3933
0
            err = 1;
3934
0
        }
3935
0
    }
3936
    /* Read a PEM key in to a new DER buffer.
3937
     * To check ENC EC PRIVATE KEY, it uses PRIVATEKEY_TYPE to call
3938
     * pem_read_bio_key(), and then check key format if it is EC.
3939
     */
3940
0
    if ((!err) && (pem_read_bio_key(bio, cb, pass, PRIVATEKEY_TYPE,
3941
0
            &keyFormat, &der) <= 0)) {
3942
0
        err = 1;
3943
0
    }
3944
0
    if (keyFormat != ECDSAk) {
3945
0
        WOLFSSL_ERROR_MSG("Error not EC key format");
3946
0
        err = 1;
3947
0
    }
3948
    /* Load the EC key with the private key from the DER encoding. */
3949
0
    if ((!err) && (wolfSSL_EC_KEY_LoadDer_ex(ec, der->buffer, (int)der->length,
3950
0
            WOLFSSL_EC_KEY_LOAD_PRIVATE) != 1)) {
3951
0
        WOLFSSL_ERROR_MSG("Error loading DER buffer into WOLFSSL_EC_KEY");
3952
0
        err = 1;
3953
0
    }
3954
3955
    /* Dispose of dynamically allocated data not needed anymore. */
3956
0
    FreeDer(&der);
3957
0
    if (err) {
3958
0
        wolfSSL_EC_KEY_free(ec);
3959
0
        ec = NULL;
3960
0
    }
3961
3962
    /* Return EC key through out if required. */
3963
0
    if ((out != NULL) && (ec != NULL)) {
3964
0
        *out = ec;
3965
0
    }
3966
0
    return ec;
3967
0
}
3968
#endif /* !NO_BIO */
3969
3970
#if defined(WOLFSSL_KEY_GEN) && defined(HAVE_ECC_KEY_EXPORT)
3971
#ifndef NO_BIO
3972
/* Write out the EC public key as PEM to the BIO.
3973
 *
3974
 * @param [in] bio  BIO to write PEM encoding to.
3975
 * @param [in] ec   EC public key to encode.
3976
 * @return  1 on success.
3977
 * @return  0 on error.
3978
 */
3979
int wolfSSL_PEM_write_bio_EC_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ec)
3980
0
{
3981
0
    int ret = 1;
3982
0
    unsigned char* derBuf = NULL;
3983
0
    int derSz = 0;
3984
3985
0
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_EC_PUBKEY");
3986
3987
    /* Validate parameters. */
3988
0
    if ((bio == NULL) || (ec == NULL)) {
3989
0
        WOLFSSL_MSG("Bad Function Arguments");
3990
0
        return 0;
3991
0
    }
3992
3993
    /* Encode public key in EC key as DER. */
3994
0
    derSz = wolfssl_ec_key_to_pubkey_der(ec, &derBuf, ec->heap);
3995
0
    if (derSz == 0) {
3996
0
        ret = 0;
3997
0
    }
3998
3999
    /* Write out to BIO the PEM encoding of the EC public key. */
4000
0
    if ((ret == 1) && (der_write_to_bio_as_pem(derBuf, derSz, bio,
4001
0
            ECC_PUBLICKEY_TYPE) != 1)) {
4002
0
        ret = 0;
4003
0
    }
4004
4005
    /* Dispose of any dynamically allocated data. */
4006
0
    XFREE(derBuf, ec->heap, DYNAMIC_TYPE_TMP_BUFFER);
4007
4008
0
    return ret;
4009
0
}
4010
4011
/* Write out the EC private key as PEM to the BIO.
4012
 *
4013
 * Return code compliant with OpenSSL.
4014
 *
4015
 * @param [in] bio       BIO to write PEM encoding to.
4016
 * @param [in] ec        EC private key to encode.
4017
 * @param [in] cipher    Cipher to use when PEM encrypted. May be NULL.
4018
 * @param [in] passwd    Password string when PEM encrypted. May be NULL.
4019
 * @param [in] passwdSz  Length of password string when PEM encrypted.
4020
 * @param [in] cb        Password callback when PEM encrypted. Unused.
4021
 * @param [in] pass      NUL terminated string for passphrase when PEM
4022
 *                       encrypted. Unused.
4023
 * @return  1 on success.
4024
 * @return  0 on error.
4025
 */
4026
int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ec,
4027
    const WOLFSSL_EVP_CIPHER* cipher, unsigned char* passwd, int passwdSz,
4028
    wc_pem_password_cb* cb, void* arg)
4029
0
{
4030
0
    int ret = 1;
4031
0
    unsigned char* pem = NULL;
4032
0
    int pLen = 0;
4033
4034
0
    (void)cb;
4035
0
    (void)arg;
4036
4037
    /* Validate parameters. */
4038
0
    if ((bio == NULL) || (ec == NULL)) {
4039
0
        ret = 0;
4040
0
    }
4041
4042
    /* Write EC private key to PEM. */
4043
0
    if ((ret == 1) && (wolfSSL_PEM_write_mem_ECPrivateKey(ec, cipher, passwd,
4044
0
            passwdSz, &pem, &pLen) != 1)) {
4045
0
       ret = 0;
4046
0
    }
4047
    /* Write PEM to BIO. */
4048
0
    if ((ret == 1) && (wolfSSL_BIO_write(bio, pem, pLen) != pLen)) {
4049
0
        WOLFSSL_ERROR_MSG("EC private key BIO write failed");
4050
0
        ret = 0;
4051
0
    }
4052
4053
0
    XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
4054
4055
0
    return ret;
4056
0
}
4057
4058
#endif /* !NO_BIO */
4059
4060
/* Encode the EC private key as PEM into buffer.
4061
 *
4062
 * Return code compliant with OpenSSL.
4063
 * Not an OpenSSL API.
4064
 *
4065
 * @param [in]  ec        EC private key to encode.
4066
 * @param [in]  cipher    Cipher to use when PEM encrypted. May be NULL.
4067
 * @param [in]  passwd    Password string when PEM encrypted. May be NULL.
4068
 * @param [in]  passwdSz  Length of password string when PEM encrypted.
4069
 * @param [out] pem       Newly allocated buffer holding PEM encoding.
4070
 * @param [out] pLen      Length of PEM encoding in bytes.
4071
 * @return  1 on success.
4072
 * @return  0 on error.
4073
 */
4074
int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* ec,
4075
    const WOLFSSL_EVP_CIPHER* cipher, unsigned char* passwd, int passwdSz,
4076
    unsigned char **pem, int *pLen)
4077
0
{
4078
0
#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
4079
0
    int ret = 1;
4080
0
    byte* derBuf = NULL;
4081
0
    word32 der_max_len = 0;
4082
0
    int derSz = 0;
4083
4084
0
    WOLFSSL_MSG("wolfSSL_PEM_write_mem_ECPrivateKey");
4085
4086
    /* Validate parameters. */
4087
0
    if ((pem == NULL) || (pLen == NULL) || (ec == NULL) ||
4088
0
            (ec->internal == NULL)) {
4089
0
        WOLFSSL_MSG("Bad function arguments");
4090
0
        ret = 0;
4091
0
    }
4092
4093
    /* Ensure internal EC key is set from external. */
4094
0
    if ((ret == 1) && (ec->inSet == 0)) {
4095
0
        WOLFSSL_MSG("No ECC internal set, do it");
4096
4097
0
        if (SetECKeyInternal(ec) != 1) {
4098
0
            WOLFSSL_MSG("SetECKeyInternal failed");
4099
0
            ret = 0;
4100
0
        }
4101
0
    }
4102
4103
0
    if (ret == 1) {
4104
        /* Calculate maximum size of DER encoding.
4105
         * 4 > size of pub, priv + ASN.1 additional information */
4106
0
        der_max_len = 4 * (word32)wc_ecc_size((ecc_key*)ec->internal) +
4107
0
                      WC_AES_BLOCK_SIZE;
4108
4109
        /* Allocate buffer big enough to hold encoding. */
4110
0
        derBuf = (byte*)XMALLOC((size_t)der_max_len, NULL,
4111
0
            DYNAMIC_TYPE_TMP_BUFFER);
4112
0
        if (derBuf == NULL) {
4113
0
            WOLFSSL_MSG("malloc failed");
4114
0
            ret = 0;
4115
0
        }
4116
0
    }
4117
4118
0
    if (ret == 1) {
4119
        /* Encode EC private key as DER. */
4120
0
        derSz = wc_EccKeyToDer((ecc_key*)ec->internal, derBuf, der_max_len);
4121
0
        if (derSz < 0) {
4122
0
            WOLFSSL_MSG("wc_EccKeyToDer failed");
4123
0
            ForceZero(derBuf, der_max_len);
4124
0
            XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
4125
0
            ret = 0;
4126
0
        }
4127
0
    }
4128
4129
    /* Convert DER to PEM - possibly encrypting. */
4130
0
    if ((ret == 1) && (der_to_enc_pem_alloc(derBuf, derSz, cipher, passwd,
4131
0
            passwdSz, ECC_PRIVATEKEY_TYPE, NULL, pem, pLen) != 1)) {
4132
0
        WOLFSSL_ERROR_MSG("der_to_enc_pem_alloc failed");
4133
0
        ret = 0;
4134
0
    }
4135
4136
0
    return ret;
4137
#else
4138
    (void)ec;
4139
    (void)cipher;
4140
    (void)passwd;
4141
    (void)passwdSz;
4142
    (void)pem;
4143
    (void)pLen;
4144
    return 0;
4145
#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
4146
0
}
4147
4148
#ifndef NO_FILESYSTEM
4149
/* Write out the EC private key as PEM to file.
4150
 *
4151
 * Return code compliant with OpenSSL.
4152
 *
4153
 * @param [in] fp        File pointer to write PEM encoding to.
4154
 * @param [in] ec        EC private key to encode.
4155
 * @param [in] cipher    Cipher to use when PEM encrypted. May be NULL.
4156
 * @param [in] passwd    Password string when PEM encrypted. May be NULL.
4157
 * @param [in] passwdSz  Length of password string when PEM encrypted.
4158
 * @param [in] cb        Password callback when PEM encrypted. Unused.
4159
 * @param [in] pass      NUL terminated string for passphrase when PEM
4160
 *                       encrypted. Unused.
4161
 * @return  1 on success.
4162
 * @return  0 on error.
4163
 */
4164
int wolfSSL_PEM_write_ECPrivateKey(XFILE fp, WOLFSSL_EC_KEY *ec,
4165
    const WOLFSSL_EVP_CIPHER *cipher, unsigned char *passwd, int passwdSz,
4166
    wc_pem_password_cb *cb, void *pass)
4167
0
{
4168
0
    int ret = 1;
4169
0
    byte *pem = NULL;
4170
0
    int pLen = 0;
4171
4172
0
    (void)cb;
4173
0
    (void)pass;
4174
4175
0
    WOLFSSL_MSG("wolfSSL_PEM_write_ECPrivateKey");
4176
4177
    /* Validate parameters. */
4178
0
    if ((fp == XBADFILE) || (ec == NULL) || (ec->internal == NULL)) {
4179
0
        WOLFSSL_MSG("Bad function arguments");
4180
0
        ret = 0;
4181
0
    }
4182
4183
    /* Write EC private key to PEM. */
4184
0
    if ((ret == 1) && (wolfSSL_PEM_write_mem_ECPrivateKey(ec, cipher, passwd,
4185
0
            passwdSz, &pem, &pLen) != 1)) {
4186
0
        WOLFSSL_MSG("wolfSSL_PEM_write_mem_ECPrivateKey failed");
4187
0
        ret = 0;
4188
0
    }
4189
4190
    /* Write out to file the PEM encoding of the EC private key. */
4191
0
    if ((ret == 1) && ((int)XFWRITE(pem, 1, (size_t)pLen, fp) != pLen)) {
4192
0
        WOLFSSL_MSG("ECC private key file write failed");
4193
0
        ret = 0;
4194
0
    }
4195
4196
    /* Dispose of any dynamically allocated data. */
4197
0
    XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
4198
4199
0
    return ret;
4200
0
}
4201
4202
#endif /* NO_FILESYSTEM */
4203
#endif /* WOLFSSL_KEY_GEN && HAVE_ECC_KEY_EXPORT */
4204
4205
/*
4206
 * EC key print APIs
4207
 */
4208
4209
#ifndef NO_CERTS
4210
4211
#if defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \
4212
    !defined(NO_STDIO_FILESYSTEM)
4213
/* Print the EC key to a file pointer as text.
4214
 *
4215
 * @param [in] fp      File pointer.
4216
 * @param [in] key     EC key to print.
4217
 * @param [in] indent  Number of spaces to place before each line printed.
4218
 * @return  1 on success.
4219
 * @return  0 on failure.
4220
 */
4221
int wolfSSL_EC_KEY_print_fp(XFILE fp, WOLFSSL_EC_KEY* key, int indent)
4222
0
{
4223
0
    int ret = 1;
4224
0
    int bits = 0;
4225
0
    int priv = 0;
4226
4227
0
    WOLFSSL_ENTER("wolfSSL_EC_KEY_print_fp");
4228
4229
    /* Validate parameters. */
4230
0
    if ((fp == XBADFILE) || (key == NULL) || (key->group == NULL) ||
4231
0
            (indent < 0)) {
4232
0
        ret = 0;
4233
0
    }
4234
4235
0
    if (ret == 1) {
4236
        /* Get EC groups order size in bits. */
4237
0
        bits = wolfSSL_EC_GROUP_order_bits(key->group);
4238
0
        if (bits <= 0) {
4239
0
            WOLFSSL_MSG("Failed to get group order bits.");
4240
0
            ret = 0;
4241
0
        }
4242
0
    }
4243
0
    if (ret == 1) {
4244
0
        const char* keyType;
4245
4246
        /* Determine whether this is a private or public key. */
4247
0
        if ((key->priv_key != NULL) && (!wolfSSL_BN_is_zero(key->priv_key))) {
4248
0
            keyType = "Private-Key";
4249
0
            priv = 1;
4250
0
        }
4251
0
        else {
4252
0
            keyType = "Public-Key";
4253
0
        }
4254
4255
        /* Print key header. */
4256
0
        if (XFPRINTF(fp, "%*s%s: (%d bit)\n", indent, "", keyType, bits) < 0) {
4257
0
            ret = 0;
4258
0
        }
4259
0
    }
4260
0
    if ((ret == 1) && priv) {
4261
        /* Print the private key BN. */
4262
0
        ret = pk_bn_field_print_fp(fp, indent, "priv", key->priv_key);
4263
0
    }
4264
    /* Check for public key data in EC key. */
4265
0
    if ((ret == 1) && (key->pub_key != NULL) && (key->pub_key->exSet)) {
4266
        /* Get the public key point as one BN. */
4267
0
        WOLFSSL_BIGNUM* pubBn = wolfSSL_EC_POINT_point2bn(key->group,
4268
0
            key->pub_key, WC_POINT_CONVERSION_UNCOMPRESSED, NULL, NULL);
4269
0
        if (pubBn == NULL) {
4270
0
            WOLFSSL_MSG("wolfSSL_EC_POINT_point2bn failed.");
4271
0
            ret = 0;
4272
0
        }
4273
0
        else {
4274
            /* Print the public key in a BN. */
4275
0
            ret = pk_bn_field_print_fp(fp, indent, "pub", pubBn);
4276
0
            wolfSSL_BN_free(pubBn);
4277
0
        }
4278
0
    }
4279
0
    if (ret == 1) {
4280
        /* Get the NID of the group. */
4281
0
        int nid = wolfSSL_EC_GROUP_get_curve_name(key->group);
4282
0
        if (nid > 0) {
4283
            /* Convert the NID into a long name and NIST name. */
4284
0
            const char* curve = wolfSSL_OBJ_nid2ln(nid);
4285
0
            const char* nistName = wolfSSL_EC_curve_nid2nist(nid);
4286
4287
            /* Print OID name if known. */
4288
0
            if ((curve != NULL) &&
4289
0
                (XFPRINTF(fp, "%*sASN1 OID: %s\n", indent, "", curve) < 0)) {
4290
0
                ret = 0;
4291
0
            }
4292
            /* Print NIST curve name if known. */
4293
0
            if ((nistName != NULL) &&
4294
0
                (XFPRINTF(fp, "%*sNIST CURVE: %s\n", indent, "",
4295
0
                    nistName) < 0)) {
4296
0
                ret = 0;
4297
0
            }
4298
0
        }
4299
0
    }
4300
4301
4302
0
    WOLFSSL_LEAVE("wolfSSL_EC_KEY_print_fp", ret);
4303
4304
0
    return ret;
4305
0
}
4306
#endif /* XFPRINTF && !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */
4307
4308
#endif /* !NO_CERTS */
4309
4310
/*
4311
 * EC_KEY get/set/test APIs
4312
 */
4313
4314
/* Set data of internal, wolfCrypt EC key object into EC key.
4315
 *
4316
 * EC_KEY wolfSSL -> OpenSSL
4317
 *
4318
 * @param [in, out] p  EC key to update.
4319
 * @return  1 on success.
4320
 * @return  -1 on failure.
4321
 */
4322
int SetECKeyExternal(WOLFSSL_EC_KEY* eckey)
4323
128
{
4324
128
    int ret = 1;
4325
4326
128
    WOLFSSL_ENTER("SetECKeyExternal");
4327
4328
    /* Validate parameter. */
4329
128
    if ((eckey == NULL) || (eckey->internal == NULL)) {
4330
0
        WOLFSSL_MSG("ec key NULL error");
4331
0
        ret = WOLFSSL_FATAL_ERROR;
4332
0
    }
4333
128
    else {
4334
128
        ecc_key* key = (ecc_key*)eckey->internal;
4335
4336
        /* Set group (OID, nid and idx) from wolfCrypt EC key. */
4337
128
        eckey->group->curve_oid = (int)key->dp->oidSum;
4338
128
        eckey->group->curve_nid = EccEnumToNID(key->dp->id);
4339
128
        eckey->group->curve_idx = key->idx;
4340
4341
128
        if (eckey->pub_key->internal != NULL) {
4342
            /* Copy internal public point from internal key's public point. */
4343
128
            if (wc_ecc_copy_point(&key->pubkey,
4344
128
                    (ecc_point*)eckey->pub_key->internal) != MP_OKAY) {
4345
0
                WOLFSSL_MSG("SetECKeyExternal ecc_copy_point failed");
4346
0
                ret = WOLFSSL_FATAL_ERROR;
4347
0
            }
4348
4349
            /* Set external public key from internal wolfCrypt, public key. */
4350
128
            if ((ret == 1) && (ec_point_external_set(eckey->pub_key) != 1)) {
4351
0
                WOLFSSL_MSG("SetECKeyExternal ec_point_external_set failed");
4352
0
                ret = WOLFSSL_FATAL_ERROR;
4353
0
            }
4354
128
        }
4355
4356
        /* set the external privkey */
4357
128
        if ((ret == 1) && (key->type == ECC_PRIVATEKEY) &&
4358
0
                (wolfssl_bn_set_value(&eckey->priv_key,
4359
0
                wc_ecc_key_get_priv(key)) != 1)) {
4360
0
            WOLFSSL_MSG("ec priv key error");
4361
0
            ret = WOLFSSL_FATAL_ERROR;
4362
0
        }
4363
4364
        /* External values set when operations succeeded. */
4365
128
        eckey->exSet = (ret == 1);
4366
128
    }
4367
4368
128
    return ret;
4369
128
}
4370
4371
/* Set data of EC key into internal, wolfCrypt EC key object.
4372
 *
4373
 * EC_KEY Openssl -> WolfSSL
4374
 *
4375
 * @param [in, out] p  EC key to update.
4376
 * @return  1 on success.
4377
 * @return  -1 on failure.
4378
 */
4379
int SetECKeyInternal(WOLFSSL_EC_KEY* eckey)
4380
1.12k
{
4381
1.12k
    int ret = 1;
4382
4383
1.12k
    WOLFSSL_ENTER("SetECKeyInternal");
4384
4385
    /* Validate parameter. */
4386
1.12k
    if ((eckey == NULL) || (eckey->internal == NULL) ||
4387
1.12k
            (eckey->group == NULL)) {
4388
0
        WOLFSSL_MSG("ec key NULL error");
4389
0
        ret = WOLFSSL_FATAL_ERROR;
4390
0
    }
4391
1.12k
    else {
4392
1.12k
        ecc_key* key = (ecc_key*)eckey->internal;
4393
1.12k
        int pubSet = 0;
4394
4395
        /* Validate group. */
4396
1.12k
        if ((eckey->group->curve_idx < 0) ||
4397
1.12k
            (wc_ecc_is_valid_idx(eckey->group->curve_idx) == 0)) {
4398
0
            WOLFSSL_MSG("invalid curve idx");
4399
0
            ret = WOLFSSL_FATAL_ERROR;
4400
0
        }
4401
4402
1.12k
        if (ret == 1) {
4403
            /* Set group (idx of curve and corresponding domain parameters). */
4404
1.12k
            key->idx = eckey->group->curve_idx;
4405
1.12k
            key->dp = &ecc_sets[key->idx];
4406
1.12k
            pubSet = (eckey->pub_key != NULL);
4407
1.12k
        }
4408
        /* Set public key (point). */
4409
1.12k
        if ((ret == 1) && pubSet) {
4410
1.12k
            if (ec_point_internal_set(eckey->pub_key) != 1) {
4411
0
                WOLFSSL_MSG("ec key pub error");
4412
0
                ret = WOLFSSL_FATAL_ERROR;
4413
0
            }
4414
            /* Copy public point to key. */
4415
1.12k
            if ((ret == 1) && (wc_ecc_copy_point(
4416
1.12k
                    (ecc_point*)eckey->pub_key->internal, &key->pubkey) !=
4417
1.12k
                    MP_OKAY)) {
4418
0
                WOLFSSL_MSG("wc_ecc_copy_point error");
4419
0
                ret = WOLFSSL_FATAL_ERROR;
4420
0
            }
4421
4422
1.12k
            if (ret == 1) {
4423
                /* Set that the internal key is a public key */
4424
1.12k
                key->type = ECC_PUBLICKEY;
4425
1.12k
            }
4426
1.12k
        }
4427
4428
        /* set privkey */
4429
1.12k
        if ((ret == 1) && (eckey->priv_key != NULL)) {
4430
1.12k
            if (wolfssl_bn_get_value(eckey->priv_key,
4431
1.12k
                    wc_ecc_key_get_priv(key)) != 1) {
4432
0
                WOLFSSL_MSG("ec key priv error");
4433
0
                ret = WOLFSSL_FATAL_ERROR;
4434
0
            }
4435
            /* private key */
4436
1.12k
            if ((ret == 1) && (!mp_iszero(wc_ecc_key_get_priv(key)))) {
4437
337
                if (pubSet) {
4438
337
                    key->type = ECC_PRIVATEKEY;
4439
337
                }
4440
0
                else {
4441
0
                    key->type = ECC_PRIVATEKEY_ONLY;
4442
0
                }
4443
337
            }
4444
1.12k
        }
4445
4446
        /* Internal values set when operations succeeded. */
4447
1.12k
        eckey->inSet = (ret == 1);
4448
1.12k
    }
4449
4450
1.12k
    return ret;
4451
1.12k
}
4452
4453
/* Get point conversion format of EC key.
4454
 *
4455
 * @param [in] key  EC key.
4456
 * @return  Point conversion format on success.
4457
 * @return  -1 on error.
4458
 */
4459
wc_point_conversion_form_t wolfSSL_EC_KEY_get_conv_form(
4460
    const WOLFSSL_EC_KEY* key)
4461
0
{
4462
0
    if (key == NULL)
4463
0
        return WOLFSSL_FATAL_ERROR;
4464
0
    return key->form;
4465
0
}
4466
4467
/* Set point conversion format into EC key.
4468
 *
4469
 * @param [in, out] key   EC key to set format into.
4470
 * @param [in]      form  Point conversion format. Valid values:
4471
 *                          WC_POINT_CONVERSION_UNCOMPRESSED,
4472
 *                          WC_POINT_CONVERSION_COMPRESSED (when HAVE_COMP_KEY)
4473
 */
4474
void wolfSSL_EC_KEY_set_conv_form(WOLFSSL_EC_KEY *key, int form)
4475
0
{
4476
0
    if (key == NULL) {
4477
0
        WOLFSSL_MSG("Key passed in NULL");
4478
0
    }
4479
0
    else if (form == WC_POINT_CONVERSION_UNCOMPRESSED
4480
0
#ifdef HAVE_COMP_KEY
4481
0
          || form == WC_POINT_CONVERSION_COMPRESSED
4482
0
#endif
4483
0
             ) {
4484
0
        key->form = (unsigned char)form;
4485
0
    }
4486
0
    else {
4487
0
        WOLFSSL_MSG("Incorrect form or HAVE_COMP_KEY not compiled in");
4488
0
    }
4489
0
}
4490
4491
/* Get the EC group object that is in EC key.
4492
 *
4493
 * @param [in] key  EC key.
4494
 * @return  EC group object on success.
4495
 * @return  NULL when key is NULL.
4496
 */
4497
const WOLFSSL_EC_GROUP *wolfSSL_EC_KEY_get0_group(const WOLFSSL_EC_KEY *key)
4498
0
{
4499
0
    WOLFSSL_EC_GROUP* group = NULL;
4500
4501
0
    WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_group");
4502
4503
0
    if (key != NULL) {
4504
0
        group = key->group;
4505
0
    }
4506
4507
0
    return group;
4508
0
}
4509
4510
/* Set the group in WOLFSSL_EC_KEY
4511
 *
4512
 * @param [in, out] key    EC key to update.
4513
 * @param [in]      group  EC group to copy.
4514
 * @return  1 on success
4515
 * @return  0 on failure.
4516
 */
4517
int wolfSSL_EC_KEY_set_group(WOLFSSL_EC_KEY *key, WOLFSSL_EC_GROUP *group)
4518
778
{
4519
778
    int ret = 1;
4520
4521
778
    WOLFSSL_ENTER("wolfSSL_EC_KEY_set_group");
4522
4523
    /* Validate parameters. */
4524
778
    if ((key == NULL) || (group == NULL)) {
4525
0
        ret = 0;
4526
0
    }
4527
4528
778
    if (ret == 1) {
4529
        /* Dispose of the current group. */
4530
778
        if (key->group != NULL) {
4531
778
            wolfSSL_EC_GROUP_free(key->group);
4532
778
        }
4533
        /* Duplicate the passed in group into EC key. */
4534
778
        key->group = wolfSSL_EC_GROUP_dup(group);
4535
778
        if (key->group == NULL) {
4536
0
            ret = 0;
4537
0
        }
4538
778
    }
4539
4540
778
    return ret;
4541
778
}
4542
4543
/* Get the BN object that is the private key in the EC key.
4544
 *
4545
 * @param [in] key  EC key.
4546
 * @return  BN object on success.
4547
 * @return  NULL when key is NULL or private key is not set.
4548
 */
4549
WOLFSSL_BIGNUM *wolfSSL_EC_KEY_get0_private_key(const WOLFSSL_EC_KEY *key)
4550
0
{
4551
0
    WOLFSSL_BIGNUM* priv_key = NULL;
4552
4553
0
    WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_private_key");
4554
4555
    /* Validate parameter. */
4556
0
    if (key == NULL) {
4557
0
        WOLFSSL_MSG("wolfSSL_EC_KEY_get0_private_key Bad arguments");
4558
0
    }
4559
    /* Only return private key if it is not 0. */
4560
0
    else if (!wolfSSL_BN_is_zero(key->priv_key)) {
4561
0
        priv_key = key->priv_key;
4562
0
    }
4563
4564
0
    return priv_key;
4565
0
}
4566
4567
/* Sets the private key value into EC key.
4568
 *
4569
 * Return code compliant with OpenSSL.
4570
 *
4571
 * @param [in, out] key       EC key to set.
4572
 * @param [in]      priv_key  Private key value in a BN.
4573
 * @return  1 on success
4574
 * @return  0 on failure.
4575
 */
4576
int wolfSSL_EC_KEY_set_private_key(WOLFSSL_EC_KEY *key,
4577
    const WOLFSSL_BIGNUM *priv_key)
4578
342
{
4579
342
    int ret = 1;
4580
4581
342
    WOLFSSL_ENTER("wolfSSL_EC_KEY_set_private_key");
4582
4583
    /* Validate parameters. */
4584
342
    if ((key == NULL) || (priv_key == NULL)) {
4585
0
        WOLFSSL_MSG("Bad arguments");
4586
0
        ret = 0;
4587
0
    }
4588
4589
    /* Check for obvious invalid values. */
4590
342
    if (wolfSSL_BN_is_negative(priv_key) || wolfSSL_BN_is_zero(priv_key) ||
4591
337
            wolfSSL_BN_is_one(priv_key)) {
4592
5
        WOLFSSL_MSG("Invalid private key value");
4593
5
        ret = 0;
4594
5
    }
4595
4596
342
    if (ret == 1) {
4597
        /* Free key if previously set. */
4598
337
        if (key->priv_key != NULL) {
4599
337
            wolfSSL_BN_free(key->priv_key);
4600
337
        }
4601
4602
        /* Duplicate the BN passed in. */
4603
337
        key->priv_key = wolfSSL_BN_dup(priv_key);
4604
337
        if (key->priv_key == NULL) {
4605
0
            WOLFSSL_MSG("key ecc priv key NULL");
4606
0
            ret = 0;
4607
0
        }
4608
337
    }
4609
    /* Set the external values into internal EC key. */
4610
342
    if ((ret == 1) && (SetECKeyInternal(key) != 1)) {
4611
0
        WOLFSSL_MSG("SetECKeyInternal failed");
4612
        /* Dispose of new private key on error. */
4613
0
        wolfSSL_BN_free(key->priv_key);
4614
0
        key->priv_key = NULL;
4615
0
        ret = 0;
4616
0
    }
4617
4618
342
    return ret;
4619
342
}
4620
4621
/* Get the public key EC point object that is in EC key.
4622
 *
4623
 * @param [in] key  EC key.
4624
 * @return  EC point object that is the public key on success.
4625
 * @return  NULL when key is NULL.
4626
 */
4627
WOLFSSL_EC_POINT* wolfSSL_EC_KEY_get0_public_key(const WOLFSSL_EC_KEY *key)
4628
0
{
4629
0
    WOLFSSL_EC_POINT* pub_key = NULL;
4630
4631
0
    WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_public_key");
4632
4633
0
    if (key != NULL) {
4634
0
        pub_key = key->pub_key;
4635
0
    }
4636
4637
0
    return pub_key;
4638
0
}
4639
4640
/*
4641
 * Return code compliant with OpenSSL.
4642
 *
4643
 * @param [in, out] key  EC key.
4644
 * @param [in]      pub  Public key as an EC point.
4645
 * @return  1 on success
4646
 * @return  0 on failure.
4647
 */
4648
int wolfSSL_EC_KEY_set_public_key(WOLFSSL_EC_KEY *key,
4649
    const WOLFSSL_EC_POINT *pub)
4650
392
{
4651
392
    int ret = 1;
4652
392
    ecc_point *pub_p = NULL;
4653
392
    ecc_point *key_p = NULL;
4654
4655
392
    WOLFSSL_ENTER("wolfSSL_EC_KEY_set_public_key");
4656
4657
    /* Validate parameters. */
4658
392
    if ((key == NULL) || (key->internal == NULL) || (pub == NULL) ||
4659
392
            (pub->internal == NULL)) {
4660
0
        WOLFSSL_MSG("wolfSSL_EC_KEY_set_public_key Bad arguments");
4661
0
        ret = 0;
4662
0
    }
4663
4664
    /* Ensure the internal EC key is set. */
4665
392
    if ((ret == 1) && (key->inSet == 0) && (SetECKeyInternal(key) != 1)) {
4666
0
        WOLFSSL_MSG("SetECKeyInternal failed");
4667
0
        ret = 0;
4668
0
    }
4669
4670
    /* Ensure the internal EC point of pub is setup. */
4671
392
    if ((ret == 1) && (ec_point_setup(pub) != 1)) {
4672
0
        ret = 0;
4673
0
    }
4674
4675
392
    if (ret == 1) {
4676
        /* Get the internal point of pub and the public key in key. */
4677
392
        pub_p = (ecc_point*)pub->internal;
4678
392
        key_p = (ecc_point*)key->pub_key->internal;
4679
4680
        /* Create new point if required. */
4681
392
        if (key_p == NULL) {
4682
0
            key_p = wc_ecc_new_point();
4683
0
            key->pub_key->internal = (void*)key_p;
4684
0
        }
4685
        /* Check point available. */
4686
392
        if (key_p == NULL) {
4687
0
            WOLFSSL_MSG("key ecc point NULL");
4688
0
            ret = 0;
4689
0
        }
4690
392
    }
4691
4692
    /* Copy the internal pub point into internal key point. */
4693
392
    if ((ret == 1) && (wc_ecc_copy_point(pub_p, key_p) != MP_OKAY)) {
4694
0
        WOLFSSL_MSG("ecc_copy_point failure");
4695
0
        ret = 0;
4696
0
    }
4697
4698
    /* Copy the internal point data into external. */
4699
392
    if ((ret == 1) && (ec_point_external_set(key->pub_key) != 1)) {
4700
0
        WOLFSSL_MSG("SetECKeyInternal failed");
4701
0
        ret = 0;
4702
0
    }
4703
4704
    /* Copy the internal key into external. */
4705
392
    if ((ret == 1) && (SetECKeyInternal(key) != 1)) {
4706
0
        WOLFSSL_MSG("SetECKeyInternal failed");
4707
0
        ret = 0;
4708
0
    }
4709
4710
392
    if (ret == 1) {
4711
        /* Dump out the point and the key's public key for debug. */
4712
392
        wolfSSL_EC_POINT_dump("pub", pub);
4713
392
        wolfSSL_EC_POINT_dump("key->pub_key", key->pub_key);
4714
392
    }
4715
4716
392
    return ret;
4717
392
}
4718
4719
#ifndef NO_WOLFSSL_STUB
4720
/* Set the ASN.1 encoding flag against the EC key.
4721
 *
4722
 * No implementation as only named curves supported for encoding.
4723
 *
4724
 * @param [in, out] key   EC key.
4725
 * @param [in]      flag  ASN.1 flag to set. Valid values:
4726
 *                        OPENSSL_EC_EXPLICIT_CURVE, OPENSSL_EC_NAMED_CURVE
4727
 */
4728
void wolfSSL_EC_KEY_set_asn1_flag(WOLFSSL_EC_KEY *key, int asn1_flag)
4729
0
{
4730
0
    (void)key;
4731
0
    (void)asn1_flag;
4732
4733
0
    WOLFSSL_ENTER("wolfSSL_EC_KEY_set_asn1_flag");
4734
0
    WOLFSSL_STUB("EC_KEY_set_asn1_flag");
4735
0
}
4736
#endif
4737
4738
/*
4739
 * EC key generate key APIs
4740
 */
4741
4742
/* Generate an EC key.
4743
 *
4744
 * Uses the internal curve index set in the EC key or the default.
4745
 *
4746
 * @param [in, out] key  EC key.
4747
 * @return  1 on success
4748
 * @return  0 on failure.
4749
 */
4750
int wolfSSL_EC_KEY_generate_key(WOLFSSL_EC_KEY *key)
4751
0
{
4752
0
    int res = 1;
4753
0
    int initTmpRng = 0;
4754
0
    WC_RNG* rng = NULL;
4755
0
    WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
4756
4757
0
    WOLFSSL_ENTER("wolfSSL_EC_KEY_generate_key");
4758
4759
    /* Validate parameters. */
4760
0
    if ((key == NULL) || (key->internal == NULL) || (key->group == NULL)) {
4761
0
        WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key Bad arguments");
4762
0
        res = 0;
4763
0
    }
4764
0
    if (res == 1) {
4765
        /* Check if we know which internal curve index to use. */
4766
0
        if (key->group->curve_idx < 0) {
4767
            /* Generate key using the default curve. */
4768
#if FIPS_VERSION3_GE(6,0,0)
4769
            key->group->curve_idx = ECC_SECP256R1; /* FIPS default to 256 */
4770
#else
4771
0
            key->group->curve_idx = ECC_CURVE_DEF;
4772
0
#endif
4773
0
        }
4774
4775
        /* Create a random number generator. */
4776
0
        rng = wolfssl_make_rng(tmpRng, &initTmpRng);
4777
0
        if (rng == NULL) {
4778
0
            WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to make RNG");
4779
0
            res = 0;
4780
0
        }
4781
0
    }
4782
0
    if (res == 1) {
4783
        /* NIDToEccEnum returns -1 for invalid NID so if key->group->curve_nid
4784
         * is 0 then pass ECC_CURVE_DEF as arg */
4785
0
        int eccEnum = key->group->curve_nid ?
4786
#if FIPS_VERSION3_GE(6,0,0)
4787
            NIDToEccEnum(key->group->curve_nid) : ECC_SECP256R1;
4788
#else
4789
0
            NIDToEccEnum(key->group->curve_nid) : ECC_CURVE_DEF;
4790
0
#endif
4791
        /* Get the internal EC key. */
4792
0
        ecc_key* ecKey = (ecc_key*)key->internal;
4793
        /* Make the key using internal API. */
4794
0
        int ret = 0;
4795
4796
#if FIPS_VERSION3_GE(6,0,0)
4797
        /* In the case of FIPS only allow key generation with approved curves */
4798
        if (eccEnum != ECC_SECP256R1 && eccEnum != ECC_SECP224R1 &&
4799
            eccEnum != ECC_SECP384R1 && eccEnum != ECC_SECP521R1) {
4800
            WOLFSSL_MSG("Unsupported curve selected in FIPS mode");
4801
            res = 0;
4802
        }
4803
        if (res == 1) {
4804
#endif
4805
0
        ret  = wc_ecc_make_key_ex(rng, 0, ecKey, eccEnum);
4806
#if FIPS_VERSION3_GE(6,0,0)
4807
        }
4808
#endif
4809
4810
    #if defined(WOLFSSL_ASYNC_CRYPT)
4811
        /* Wait on asynchronouse operation. */
4812
        ret = wc_AsyncWait(ret, &ecKey->asyncDev, WC_ASYNC_FLAG_NONE);
4813
    #endif
4814
0
        if (ret != 0) {
4815
0
            WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key wc_ecc_make_key failed");
4816
0
            res = 0;
4817
0
        }
4818
0
    }
4819
4820
    /* Dispose of local random number generator if initialized. */
4821
0
    if (initTmpRng) {
4822
0
        wc_FreeRng(rng);
4823
0
        WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_RNG);
4824
0
    }
4825
4826
    /* Set the external key from new internal key values. */
4827
0
    if ((res == 1) && (SetECKeyExternal(key) != 1)) {
4828
0
        WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key SetECKeyExternal failed");
4829
0
        res = 0;
4830
0
    }
4831
4832
0
    return res;
4833
0
}
4834
4835
/*
4836
 * EC key check key APIs
4837
 */
4838
4839
/* Check that the EC key is valid.
4840
 *
4841
 * @param [in] key  EC key.
4842
 * @return  1 on valid.
4843
 * @return  0 on invalid or error.
4844
 */
4845
int wolfSSL_EC_KEY_check_key(const WOLFSSL_EC_KEY *key)
4846
0
{
4847
0
    int ret = 1;
4848
4849
0
    WOLFSSL_ENTER("wolfSSL_EC_KEY_check_key");
4850
4851
    /* Validate parameter. */
4852
0
    if ((key == NULL) || (key->internal == NULL)) {
4853
0
        WOLFSSL_MSG("Bad parameter");
4854
0
        ret = 0;
4855
0
    }
4856
4857
    /* Set the external EC key values into internal if not already. */
4858
0
    if ((ret == 1) && (key->inSet == 0) && (SetECKeyInternal(
4859
0
            (WOLFSSL_EC_KEY*)key) != 1)) {
4860
0
        WOLFSSL_MSG("SetECKeyInternal failed");
4861
0
        ret = 0;
4862
0
    }
4863
4864
0
    if (ret == 1) {
4865
        /* Have internal EC implementation check key. */
4866
0
        ret = wc_ecc_check_key((ecc_key*)key->internal) == 0;
4867
0
    }
4868
4869
0
    return ret;
4870
0
}
4871
4872
/* End EC_KEY */
4873
4874
#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)
4875
/* Get the supported, built-in EC curves
4876
 *
4877
 * @param [in, out] curves  Pre-allocated list to put supported curves into.
4878
 * @param [in]      len     Maximum number of items to place in list.
4879
 * @return  Number of built-in EC curves when curves is NULL or len is 0.
4880
 * @return  Number of items placed in list otherwise.
4881
 */
4882
size_t wolfSSL_EC_get_builtin_curves(WOLFSSL_EC_BUILTIN_CURVE *curves,
4883
    size_t len)
4884
0
{
4885
0
    size_t i;
4886
0
    size_t cnt;
4887
#ifdef HAVE_SELFTEST
4888
    /* Defined in ecc.h when available. */
4889
    size_t ecc_sets_count;
4890
4891
    /* Count the pre-defined curves since global not available. */
4892
    for (i = 0; ecc_sets[i].size != 0 && ecc_sets[i].name != NULL; i++) {
4893
        /* Do nothing. */
4894
    }
4895
    ecc_sets_count = i;
4896
#endif
4897
4898
    /* Assume we are going to return total count. */
4899
0
    cnt = ecc_sets_count;
4900
    /* Check we have a list that can hold data. */
4901
0
    if ((curves != NULL) && (len != 0)) {
4902
        /* Limit count to length of list. */
4903
0
        if (cnt > len) {
4904
0
            cnt = len;
4905
0
        }
4906
4907
        /* Put in built-in EC curve nid and short name. */
4908
0
        for (i = 0; i < cnt; i++) {
4909
0
            curves[i].nid = EccEnumToNID(ecc_sets[i].id);
4910
0
            curves[i].comment = wolfSSL_OBJ_nid2sn(curves[i].nid);
4911
0
        }
4912
0
    }
4913
4914
0
    return cnt;
4915
0
}
4916
#endif /* !HAVE_FIPS || FIPS_VERSION_GT(2,0) */
4917
4918
/* Start ECDSA_SIG */
4919
4920
/* Allocate a new ECDSA signature object.
4921
 *
4922
 * @return  New, allocated ECDSA signature object on success.
4923
 * @return  NULL on error.
4924
 */
4925
WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_SIG_new(void)
4926
622
{
4927
622
    int err = 0;
4928
622
    WOLFSSL_ECDSA_SIG *sig;
4929
4930
622
    WOLFSSL_ENTER("wolfSSL_ECDSA_SIG_new");
4931
4932
    /* Allocate memory for ECDSA signature object. */
4933
622
    sig = (WOLFSSL_ECDSA_SIG*)XMALLOC(sizeof(WOLFSSL_ECDSA_SIG), NULL,
4934
622
        DYNAMIC_TYPE_ECC);
4935
622
    if (sig == NULL) {
4936
0
        WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA signature failure");
4937
0
        return NULL;
4938
0
    }
4939
4940
    /* Set s to NULL in case of error. */
4941
622
    sig->s = NULL;
4942
    /* Allocate BN into r. */
4943
622
    sig->r = wolfSSL_BN_new();
4944
622
    if (sig->r == NULL) {
4945
0
        WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA r failure");
4946
0
        err = 1;
4947
0
    }
4948
622
    if (!err) {
4949
        /* Allocate BN into s. */
4950
622
        sig->s = wolfSSL_BN_new();
4951
622
        if (sig->s == NULL) {
4952
0
            WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA s failure");
4953
0
            err = 1;
4954
0
        }
4955
622
    }
4956
4957
622
    if (err) {
4958
        /* Dispose of allocated memory. */
4959
0
        wolfSSL_ECDSA_SIG_free(sig);
4960
0
        sig = NULL;
4961
0
    }
4962
622
    return sig;
4963
622
}
4964
4965
/* Dispose of ECDSA signature object.
4966
 *
4967
 * Cannot use object after this call.
4968
 *
4969
 * @param [in] sig  ECDSA signature object to free.
4970
 */
4971
void wolfSSL_ECDSA_SIG_free(WOLFSSL_ECDSA_SIG *sig)
4972
622
{
4973
622
    WOLFSSL_ENTER("wolfSSL_ECDSA_SIG_free");
4974
4975
622
    if (sig != NULL) {
4976
        /* Dispose of BNs allocated for r and s. */
4977
622
        wolfSSL_BN_free(sig->r);
4978
622
        wolfSSL_BN_free(sig->s);
4979
4980
        /* Dispose of memory associated with ECDSA signature object. */
4981
622
        XFREE(sig, NULL, DYNAMIC_TYPE_ECC);
4982
622
    }
4983
622
}
4984
4985
/* Create an ECDSA signature from the DER encoding.
4986
 *
4987
 * @param [in, out] sig  Reference to ECDSA signature object. May be NULL.
4988
 * @param [in, out] pp   On in, reference to buffer containing DER encoding.
4989
 *                       On out, reference to buffer after signature data.
4990
 * @param [in]      len  Length of the data in the buffer. May be more than
4991
 *                       the length of the signature.
4992
 * @return  ECDSA signature object on success.
4993
 * @return  NULL on error.
4994
 */
4995
WOLFSSL_ECDSA_SIG* wolfSSL_d2i_ECDSA_SIG(WOLFSSL_ECDSA_SIG** sig,
4996
    const unsigned char** pp, long len)
4997
227
{
4998
227
    int err = 0;
4999
    /* ECDSA signature object to return. */
5000
227
    WOLFSSL_ECDSA_SIG *s = NULL;
5001
5002
    /* Validate parameter. */
5003
227
    if (pp == NULL || *pp == NULL) {
5004
0
        err = 1;
5005
0
    }
5006
227
    if ((!err) && (len <= 0)) {
5007
0
        err = 1;
5008
0
    }
5009
227
    if (!err) {
5010
227
        if (sig != NULL) {
5011
            /* Use the ECDSA signature object passed in. */
5012
0
            s = *sig;
5013
0
        }
5014
227
        if (s == NULL) {
5015
            /* No ECDSA signature object passed in - create a new one. */
5016
227
            s = wolfSSL_ECDSA_SIG_new();
5017
227
            if (s == NULL) {
5018
0
                err = 1;
5019
0
            }
5020
227
        }
5021
227
    }
5022
227
    if (!err) {
5023
        /* DecodeECC_DSA_Sig calls mp_init, so free these. */
5024
227
        mp_free((mp_int*)s->r->internal);
5025
227
        mp_free((mp_int*)s->s->internal);
5026
5027
        /* Decode the signature into internal r and s fields. */
5028
227
        if (DecodeECC_DSA_Sig(*pp, (word32)len, (mp_int*)s->r->internal,
5029
227
                (mp_int*)s->s->internal) != MP_OKAY) {
5030
0
            err = 1;
5031
0
        }
5032
227
    }
5033
5034
227
    if (!err) {
5035
        /* Move pointer passed signature data successfully decoded. */
5036
227
        *pp += wolfssl_der_length(*pp, (int)len);
5037
227
        if (sig != NULL) {
5038
            /* Update reference to ECDSA signature object. */
5039
0
            *sig = s;
5040
0
        }
5041
227
    }
5042
5043
    /* Dispose of newly allocated object on error. */
5044
227
    if (err) {
5045
0
        if ((s != NULL) && ((sig == NULL) || (*sig != s))) {
5046
0
            wolfSSL_ECDSA_SIG_free(s);
5047
0
        }
5048
        /* Return NULL for object on error. */
5049
0
        s = NULL;
5050
0
    }
5051
227
    return s;
5052
227
}
5053
5054
/* Encode the ECDSA signature as DER.
5055
 *
5056
 * @param [in]      sig  ECDSA signature object.
5057
 * @param [in, out] pp   On in, reference to buffer in which to place encoding.
5058
 *                       On out, reference to buffer after encoding.
5059
 *                       May be NULL or point to NULL in which case no encoding
5060
 *                       is done.
5061
 * @return  Length of encoding on success.
5062
 * @return  0 on error.
5063
 */
5064
int wolfSSL_i2d_ECDSA_SIG(const WOLFSSL_ECDSA_SIG *sig, unsigned char **pp)
5065
0
{
5066
0
    word32 len = 0;
5067
0
    int    update_p = 1;
5068
5069
    /* Validate parameter. */
5070
0
    if (sig != NULL) {
5071
        /* ASN.1: SEQ + INT + INT
5072
         *   ASN.1 Integer must be a positive value - prepend zero if number has
5073
         *   top bit set.
5074
         */
5075
        /* Get total length of r including any prepended zero. */
5076
0
        word32 rLen = (word32)(mp_leading_bit((mp_int*)sig->r->internal) +
5077
0
               mp_unsigned_bin_size((mp_int*)sig->r->internal));
5078
        /* Get total length of s including any prepended zero. */
5079
0
        word32 sLen = (word32)(mp_leading_bit((mp_int*)sig->s->internal) +
5080
0
               mp_unsigned_bin_size((mp_int*)sig->s->internal));
5081
        /* Calculate length of data in sequence. */
5082
0
        len = (word32)1 + ASN_LEN_SIZE(rLen) + rLen +
5083
0
              (word32)1 + ASN_LEN_SIZE(sLen) + sLen;
5084
        /* Add in the length of the SEQUENCE. */
5085
0
        len += (word32)1 + ASN_LEN_SIZE(len);
5086
5087
        #ifdef WOLFSSL_I2D_ECDSA_SIG_ALLOC
5088
        if ((pp != NULL) && (*pp == NULL)) {
5089
            *pp = (unsigned char *)XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL);
5090
            if (*pp == NULL) {
5091
                WOLFSSL_MSG("malloc error");
5092
                return 0;
5093
            }
5094
            update_p = 0;
5095
        }
5096
        #endif
5097
5098
        /* Encode only if there is a buffer to encode into. */
5099
0
        if ((pp != NULL) && (*pp != NULL)) {
5100
            /* Encode using the internal representations of r and s. */
5101
0
            if (StoreECC_DSA_Sig(*pp, &len, (mp_int*)sig->r->internal,
5102
0
                    (mp_int*)sig->s->internal) != MP_OKAY) {
5103
                /* No bytes encoded. */
5104
0
                len = 0;
5105
0
            }
5106
0
            else if (update_p) {
5107
                /* Update pointer to after encoding. */
5108
0
                *pp += len;
5109
0
            }
5110
0
        }
5111
0
    }
5112
5113
0
    return (int)len;
5114
0
}
5115
5116
/* Get the pointer to the fields of the ECDSA signature.
5117
 *
5118
 * r and s untouched when sig is NULL.
5119
 *
5120
 * @param [in]  sig  ECDSA signature object.
5121
 * @param [out] r    R field of ECDSA signature as a BN. May be NULL.
5122
 * @param [out] s    S field of ECDSA signature as a BN. May be NULL.
5123
 */
5124
void wolfSSL_ECDSA_SIG_get0(const WOLFSSL_ECDSA_SIG* sig,
5125
    const WOLFSSL_BIGNUM** r, const WOLFSSL_BIGNUM** s)
5126
227
{
5127
    /* Validate parameter. */
5128
227
    if (sig != NULL) {
5129
        /* Return the r BN when pointer to return through. */
5130
227
        if (r != NULL) {
5131
227
            *r = sig->r;
5132
227
        }
5133
        /* Return the s BN when pointer to return through. */
5134
227
        if (s != NULL) {
5135
227
            *s = sig->s;
5136
227
        }
5137
227
    }
5138
227
}
5139
5140
/* Set the pointers to the fields of the ECDSA signature.
5141
 *
5142
 * @param [in, out] sig  ECDSA signature object to update.
5143
 * @param [in]      r    R field of ECDSA signature as a BN.
5144
 * @param [in]      s    S field of ECDSA signature as a BN.
5145
 * @return  1 on success.
5146
 * @return  0 on error.
5147
 */
5148
int wolfSSL_ECDSA_SIG_set0(WOLFSSL_ECDSA_SIG* sig, WOLFSSL_BIGNUM* r,
5149
    WOLFSSL_BIGNUM* s)
5150
395
{
5151
395
    int ret = 1;
5152
5153
    /* Validate parameters. */
5154
395
    if ((sig == NULL) || (r == NULL) || (s == NULL)) {
5155
0
        ret = 0;
5156
0
    }
5157
5158
395
    if (ret == 1) {
5159
        /* Dispose of old BN objects. */
5160
395
        wolfSSL_BN_free(sig->r);
5161
395
        wolfSSL_BN_free(sig->s);
5162
5163
        /* Assign new BN objects. */
5164
395
        sig->r = r;
5165
395
        sig->s = s;
5166
395
    }
5167
5168
395
    return ret;
5169
395
}
5170
5171
/* End ECDSA_SIG */
5172
5173
/* Start ECDSA */
5174
5175
/* Calculate maximum size of the DER encoded ECDSA signature for the curve.
5176
 *
5177
 * @param [in] key  EC key.
5178
 * @return  Size of DER encoded signature on success.
5179
 * @return  0 on error.
5180
 */
5181
int wolfSSL_ECDSA_size(const WOLFSSL_EC_KEY *key)
5182
0
{
5183
0
    int err = 0;
5184
0
    int len = 0;
5185
0
    const WOLFSSL_EC_GROUP *group = NULL;
5186
0
    int bits = 0;
5187
5188
    /* Validate parameter. */
5189
0
    if (key == NULL) {
5190
0
        err = 1;
5191
0
    }
5192
5193
    /* Get group from key to get order bits. */
5194
0
    if ((!err) && ((group = wolfSSL_EC_KEY_get0_group(key)) == NULL)) {
5195
0
        err = 1;
5196
0
    }
5197
    /* Get order bits of group. */
5198
0
    if ((!err) && ((bits = wolfSSL_EC_GROUP_order_bits(group)) == 0)) {
5199
        /* Group is not set. */
5200
0
        err = 1;
5201
0
    }
5202
5203
0
    if (!err) {
5204
        /* r and s are mod order. */
5205
0
        int bytes = (bits + 7) / 8;  /* Bytes needed to hold bits. */
5206
0
        len = SIG_HEADER_SZ + /* 2*ASN_TAG + 2*LEN(ENUM) */
5207
0
            ECC_MAX_PAD_SZ +  /* possible leading zeroes in r and s */
5208
0
            bytes + bytes;    /* max r and s in bytes */
5209
0
    }
5210
5211
0
    return len;
5212
0
}
5213
5214
/* Create ECDSA signature by signing digest with key.
5215
 *
5216
 * @param [in] dgst  Digest to sign.
5217
 * @param [in] dLen  Length of digest in bytes.
5218
 * @param [in] key   EC key to sign with.
5219
 * @return  ECDSA signature object on success.
5220
 * @return  NULL on error.
5221
 */
5222
WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_do_sign(const unsigned char *dgst, int dLen,
5223
    WOLFSSL_EC_KEY *key)
5224
283
{
5225
283
    int err = 0;
5226
283
    WOLFSSL_ECDSA_SIG *sig = NULL;
5227
283
    WC_DECLARE_VAR(out, byte, ECC_BUFSIZE, 0);
5228
283
    unsigned int outLen = ECC_BUFSIZE;
5229
5230
283
    WOLFSSL_ENTER("wolfSSL_ECDSA_do_sign");
5231
5232
    /* Validate parameters. */
5233
283
    if ((dgst == NULL) || (key == NULL) || (key->internal == NULL)) {
5234
10
        WOLFSSL_MSG("wolfSSL_ECDSA_do_sign Bad arguments");
5235
10
        err = 1;
5236
10
    }
5237
5238
    /* Ensure internal EC key is set from external. */
5239
283
    if ((!err) && (key->inSet == 0)) {
5240
0
        WOLFSSL_MSG("wolfSSL_ECDSA_do_sign No EC key internal set, do it");
5241
5242
0
        if (SetECKeyInternal(key) != 1) {
5243
0
            WOLFSSL_MSG("wolfSSL_ECDSA_do_sign SetECKeyInternal failed");
5244
0
            err = 1;
5245
0
        }
5246
0
    }
5247
5248
283
#ifdef WOLFSSL_SMALL_STACK
5249
283
    if (!err) {
5250
        /* Allocate buffer to hold encoded signature. */
5251
273
        out = (byte*)XMALLOC(outLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5252
273
        if (out == NULL) {
5253
0
            err = 1;
5254
0
        }
5255
273
    }
5256
283
#endif
5257
5258
    /* Sign the digest with the key to create encoded ECDSA signature. */
5259
283
    if ((!err) && (wolfSSL_ECDSA_sign(0, dgst, dLen, out, &outLen, key) != 1)) {
5260
46
        err = 1;
5261
46
    }
5262
5263
283
    if (!err) {
5264
227
        const byte* p = out;
5265
        /* Decode the ECDSA signature into a new object. */
5266
227
        sig = wolfSSL_d2i_ECDSA_SIG(NULL, &p, outLen);
5267
227
    }
5268
5269
283
    WC_FREE_VAR_EX(out, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5270
5271
283
    return sig;
5272
283
}
5273
5274
/* Verify ECDSA signature in the object using digest and key.
5275
 *
5276
 * Return code compliant with OpenSSL.
5277
 *
5278
 * @param [in] dgst  Digest to verify.
5279
 * @param [in] dLen  Length of the digest in bytes.
5280
 * @param [in] sig   ECDSA signature object.
5281
 * @param [in] key   EC key containing public key.
5282
 * @return  1 when signature is valid.
5283
 * @return  0 when signature is invalid.
5284
 * @return  -1 on error.
5285
 */
5286
int wolfSSL_ECDSA_do_verify(const unsigned char *dgst, int dLen,
5287
    const WOLFSSL_ECDSA_SIG *sig, WOLFSSL_EC_KEY *key)
5288
356
{
5289
356
    int ret = 1;
5290
356
    int verified = 0;
5291
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
5292
    byte signature[ECC_MAX_SIG_SIZE];
5293
    int signatureLen;
5294
    byte* p = signature;
5295
#endif
5296
5297
356
    WOLFSSL_ENTER("wolfSSL_ECDSA_do_verify");
5298
5299
    /* Validate parameters. */
5300
356
    if ((dgst == NULL) || (sig == NULL) || (key == NULL) ||
5301
341
            (key->internal == NULL)) {
5302
15
        WOLFSSL_MSG("wolfSSL_ECDSA_do_verify Bad arguments");
5303
15
        ret = WOLFSSL_FATAL_ERROR;
5304
15
    }
5305
5306
    /* Check hash length */
5307
356
    if ((ret == 1) &&
5308
341
        ((dLen > WC_MAX_DIGEST_SIZE) ||
5309
329
         (dLen < WC_MIN_DIGEST_SIZE_FOR_VERIFY))) {
5310
18
        WOLFSSL_MSG("wolfSSL_ECDSA_do_verify Bad digest size");
5311
18
        ret = WOLFSSL_FATAL_ERROR;
5312
18
    }
5313
5314
    /* Ensure internal EC key is set from external. */
5315
356
    if ((ret == 1) && (key->inSet == 0)) {
5316
0
        WOLFSSL_MSG("No EC key internal set, do it");
5317
5318
0
        if (SetECKeyInternal(key) != 1) {
5319
0
            WOLFSSL_MSG("SetECKeyInternal failed");
5320
0
            ret = WOLFSSL_FATAL_ERROR;
5321
0
        }
5322
0
    }
5323
5324
356
    if (ret == 1) {
5325
323
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
5326
        /* Verify hash using digest, r and s as MP ints and internal EC key. */
5327
323
        if (wc_ecc_verify_hash_ex((mp_int*)sig->r->internal,
5328
323
                (mp_int*)sig->s->internal, dgst, (word32)dLen, &verified,
5329
323
                (ecc_key *)key->internal) != MP_OKAY) {
5330
53
            WOLFSSL_MSG("wc_ecc_verify_hash failed");
5331
53
            ret = WOLFSSL_FATAL_ERROR;
5332
53
        }
5333
270
        else if (verified == 0) {
5334
64
            WOLFSSL_MSG("wc_ecc_verify_hash incorrect signature detected");
5335
64
            ret = 0;
5336
64
        }
5337
#else
5338
        signatureLen = i2d_ECDSA_SIG(sig, &p);
5339
        if (signatureLen > 0) {
5340
            /* verify hash. expects to call wc_CryptoCb_EccVerify internally */
5341
            ret = wc_ecc_verify_hash(signature, signatureLen, dgst,
5342
                (word32)dLen, &verified, (ecc_key*)key->internal);
5343
            if (ret != MP_OKAY) {
5344
                WOLFSSL_MSG("wc_ecc_verify_hash failed");
5345
                ret = WOLFSSL_FATAL_ERROR;
5346
            }
5347
            else if (verified == 0) {
5348
                WOLFSSL_MSG("wc_ecc_verify_hash incorrect signature detected");
5349
                ret = 0;
5350
            }
5351
        }
5352
        else {
5353
            WOLFSSL_MSG("i2d_ECDSA_SIG failed");
5354
            ret = WOLFSSL_FATAL_ERROR;
5355
        }
5356
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
5357
323
    }
5358
5359
356
    return ret;
5360
356
}
5361
5362
/* Sign the digest with the key to produce a DER encode signature.
5363
 *
5364
 * @param [in]      type      Digest algorithm used to create digest. Unused.
5365
 * @param [in]      digest    Digest of the message to sign.
5366
 * @param [in]      digestSz  Size of the digest in bytes.
5367
 * @param [out]     sig       Buffer to hold signature.
5368
 * @param [in, out] sigSz     On in, size of buffer in bytes.
5369
 *                            On out, size of signatre in bytes.
5370
 * @param [in]      key       EC key containing private key.
5371
 * @return  1 on success.
5372
 * @return  0 on error.
5373
 */
5374
int wolfSSL_ECDSA_sign(int type, const unsigned char *digest, int digestSz,
5375
    unsigned char *sig, unsigned int *sigSz, WOLFSSL_EC_KEY *key)
5376
273
{
5377
273
    int ret = 1;
5378
273
    WC_RNG* rng = NULL;
5379
273
    WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
5380
273
    int initTmpRng = 0;
5381
5382
273
    WOLFSSL_ENTER("wolfSSL_ECDSA_sign");
5383
5384
    /* Digest algorithm not used in DER encoding. */
5385
273
    (void)type;
5386
5387
    /* Validate parameters. */
5388
273
    if (key == NULL) {
5389
0
        ret = 0;
5390
0
    }
5391
5392
273
    if (ret == 1) {
5393
        /* Make an RNG - create local or get global. */
5394
273
        rng = wolfssl_make_rng(tmpRng, &initTmpRng);
5395
273
        if (rng == NULL) {
5396
0
            ret = 0;
5397
0
        }
5398
273
    }
5399
    /* Sign the digest with the key using the RNG and put signature into buffer
5400
     * update sigSz to be actual length.
5401
     */
5402
273
    if ((ret == 1) && (wc_ecc_sign_hash(digest, (word32)digestSz, sig, sigSz,
5403
273
            rng, (ecc_key*)key->internal) != 0)) {
5404
46
        ret = 0;
5405
46
    }
5406
5407
273
    if (initTmpRng) {
5408
273
        wc_FreeRng(rng);
5409
273
        WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_RNG);
5410
273
    }
5411
5412
273
    return ret;
5413
273
}
5414
5415
/* Verify the signature with the digest and key.
5416
 *
5417
 * @param [in] type      Digest algorithm used to create digest. Unused.
5418
 * @param [in] digest    Digest of the message to verify.
5419
 * @param [in] digestSz  Size of the digest in bytes.
5420
 * @param [in] sig       Buffer holding signature.
5421
 * @param [in] sigSz     Size of signature data in bytes.
5422
 * @param [in] key       EC key containing public key.
5423
 * @return  1 when signature is valid.
5424
 * @return  0 when signature is invalid or error.
5425
 */
5426
int wolfSSL_ECDSA_verify(int type, const unsigned char *digest, int digestSz,
5427
    const unsigned char *sig, int sigSz, WOLFSSL_EC_KEY *key)
5428
0
{
5429
0
    int ret = 1;
5430
0
    int verify = 0;
5431
5432
0
    WOLFSSL_ENTER("wolfSSL_ECDSA_verify");
5433
5434
    /* Digest algorithm not used in DER encoding. */
5435
0
    (void)type;
5436
5437
    /* Validate parameters. */
5438
0
    if (key == NULL) {
5439
0
        ret = 0;
5440
0
    }
5441
5442
    /* Check hash length */
5443
0
    if ((ret == 1) &&
5444
0
        ((digestSz > WC_MAX_DIGEST_SIZE) ||
5445
0
         (digestSz < WC_MIN_DIGEST_SIZE_FOR_VERIFY))) {
5446
0
        WOLFSSL_MSG("wolfSSL_ECDSA_verify Bad digest size");
5447
0
        ret = 0;
5448
0
    }
5449
5450
    /* Verify signature using digest and key. */
5451
0
    if ((ret == 1) && (wc_ecc_verify_hash(sig, (word32)sigSz, digest,
5452
0
            (word32)digestSz, &verify, (ecc_key*)key->internal) != 0)) {
5453
0
        ret = 0;
5454
0
    }
5455
    /* When no error, verification may still have failed - check now. */
5456
0
    if ((ret == 1) && (verify != 1)) {
5457
0
        WOLFSSL_MSG("wolfSSL_ECDSA_verify failed");
5458
0
        ret = 0;
5459
0
    }
5460
5461
0
    return ret;
5462
0
}
5463
5464
/* End ECDSA */
5465
5466
/* Start ECDH */
5467
5468
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
5469
/* Compute the shared secret (key) using ECDH.
5470
 *
5471
 * KDF not supported.
5472
 *
5473
 * Return code compliant with OpenSSL.
5474
 *
5475
 * @param [out] out      Buffer to hold key.
5476
 * @param [in]  outLen   Length of buffer in bytes.
5477
 * @param [in]  pubKey   Public key as an EC point.
5478
 * @param [in]  privKey  EC key holding a private key.
5479
 * @param [in]  kdf      Key derivation function to apply to secret.
5480
 * @return  Length of computed key on success
5481
 * @return  0 on error.
5482
 */
5483
int wolfSSL_ECDH_compute_key(void *out, size_t outLen,
5484
    const WOLFSSL_EC_POINT *pubKey, WOLFSSL_EC_KEY *privKey,
5485
    void *(*kdf) (const void *in, size_t inlen, void *out, size_t *outLen))
5486
0
{
5487
0
    int err = 0;
5488
0
    word32 len = 0;
5489
0
    ecc_key* key = NULL;
5490
0
#if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_SELFTEST) && \
5491
0
    (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,0))
5492
0
    WC_RNG* rng = NULL;
5493
0
    WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
5494
0
    int initTmpRng = 0;
5495
0
    int setKeyRng = 0;
5496
0
#endif
5497
5498
    /* TODO: support using the KDF. */
5499
0
    (void)kdf;
5500
5501
0
    WOLFSSL_ENTER("wolfSSL_ECDH_compute_key");
5502
5503
    /* Validate parameters. */
5504
0
    if ((out == NULL) || (pubKey == NULL) || (pubKey->internal == NULL) ||
5505
0
        (privKey == NULL) || (privKey->internal == NULL)) {
5506
0
        WOLFSSL_MSG("Bad function arguments");
5507
0
        err = 1;
5508
0
    }
5509
5510
    /* Ensure internal EC key is set from external. */
5511
0
    if ((!err) && (privKey->inSet == 0)) {
5512
0
        WOLFSSL_MSG("No EC key internal set, do it");
5513
5514
0
        if (SetECKeyInternal(privKey) != 1) {
5515
0
            WOLFSSL_MSG("SetECKeyInternal failed");
5516
0
            err = 1;
5517
0
        }
5518
0
    }
5519
5520
0
    if (!err) {
5521
0
        int ret;
5522
5523
        /* Get the internal key. */
5524
0
        key = (ecc_key*)privKey->internal;
5525
        /* Set length into variable of type suitable for wolfSSL API. */
5526
0
        len = (word32)outLen;
5527
5528
0
    #if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_SELFTEST) && \
5529
0
        (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,0))
5530
        /* An RNG is needed - create local or get global. */
5531
0
        if (key->rng == NULL) {
5532
0
            rng = wolfssl_make_rng(tmpRng, &initTmpRng);
5533
0
            if (rng == NULL) {
5534
0
                WOLFSSL_MSG("wolfSSL_ECDH_compute_key failed to make RNG");
5535
0
                err = 1;
5536
0
            }
5537
0
            else {
5538
0
                key->rng = rng;
5539
                /* RNG set and needs to be unset. */
5540
0
                setKeyRng = 1;
5541
0
            }
5542
0
        }
5543
0
    #endif
5544
5545
0
        if (!err) {
5546
0
            PRIVATE_KEY_UNLOCK();
5547
            /* Create secret using wolfSSL. */
5548
0
            ret = wc_ecc_shared_secret_ex(key, (ecc_point*)pubKey->internal,
5549
0
                (byte *)out, &len);
5550
0
            PRIVATE_KEY_LOCK();
5551
0
            if (ret != MP_OKAY) {
5552
0
                WOLFSSL_MSG("wc_ecc_shared_secret failed");
5553
0
                err = 1;
5554
0
            }
5555
0
        }
5556
0
    }
5557
5558
0
#if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_SELFTEST) && \
5559
0
    (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,0))
5560
    /* Clear before the RNG is disposed of - key must not keep a dangling
5561
     * reference to a local RNG. */
5562
0
    if (setKeyRng) {
5563
0
        key->rng = NULL;
5564
0
    }
5565
0
    if (initTmpRng) {
5566
0
        wc_FreeRng(rng);
5567
0
        WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_RNG);
5568
0
    }
5569
0
#endif
5570
5571
0
    if (err) {
5572
        /* Make returned value zero. */
5573
0
        len = 0;
5574
0
    }
5575
0
    return (int)len;
5576
0
}
5577
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
5578
5579
/* End ECDH */
5580
5581
#ifndef NO_WOLFSSL_STUB
5582
const WOLFSSL_EC_KEY_METHOD *wolfSSL_EC_KEY_OpenSSL(void)
5583
0
{
5584
0
    WOLFSSL_STUB("wolfSSL_EC_KEY_OpenSSL");
5585
5586
0
    return NULL;
5587
0
}
5588
5589
WOLFSSL_EC_KEY_METHOD *wolfSSL_EC_KEY_METHOD_new(
5590
        const WOLFSSL_EC_KEY_METHOD *meth)
5591
0
{
5592
0
    WOLFSSL_STUB("wolfSSL_EC_KEY_METHOD_new");
5593
5594
0
    (void)meth;
5595
5596
0
    return NULL;
5597
0
}
5598
5599
void wolfSSL_EC_KEY_METHOD_free(WOLFSSL_EC_KEY_METHOD *meth)
5600
0
{
5601
0
    WOLFSSL_STUB("wolfSSL_EC_KEY_METHOD_free");
5602
5603
0
    (void)meth;
5604
0
}
5605
5606
void wolfSSL_EC_KEY_METHOD_set_init(WOLFSSL_EC_KEY_METHOD *meth,
5607
        void* a1, void* a2, void* a3, void* a4, void* a5, void* a6)
5608
0
{
5609
0
    WOLFSSL_STUB("wolfSSL_EC_KEY_METHOD_set_init");
5610
5611
0
    (void)meth;
5612
0
    (void)a1;
5613
0
    (void)a2;
5614
0
    (void)a3;
5615
0
    (void)a4;
5616
0
    (void)a5;
5617
0
    (void)a6;
5618
0
}
5619
5620
void wolfSSL_EC_KEY_METHOD_set_sign(WOLFSSL_EC_KEY_METHOD *meth,
5621
        void* a1, void* a2, void* a3)
5622
0
{
5623
0
    WOLFSSL_STUB("wolfSSL_EC_KEY_METHOD_set_sign");
5624
5625
0
    (void)meth;
5626
0
    (void)a1;
5627
0
    (void)a2;
5628
0
    (void)a3;
5629
0
}
5630
5631
const WOLFSSL_EC_KEY_METHOD *wolfSSL_EC_KEY_get_method(
5632
        const WOLFSSL_EC_KEY *key)
5633
0
{
5634
0
    WOLFSSL_STUB("wolfSSL_EC_KEY_get_method");
5635
5636
0
    (void)key;
5637
5638
0
    return NULL;
5639
0
}
5640
5641
int wolfSSL_EC_KEY_set_method(WOLFSSL_EC_KEY *key,
5642
        const WOLFSSL_EC_KEY_METHOD *meth)
5643
0
{
5644
0
    WOLFSSL_STUB("wolfSSL_EC_KEY_set_method");
5645
5646
0
    (void)key;
5647
0
    (void)meth;
5648
5649
0
    return 0;
5650
0
}
5651
5652
#endif /* !NO_WOLFSSL_STUB */
5653
5654
#endif /* OPENSSL_EXTRA */
5655
5656
#endif /* HAVE_ECC */
5657
5658
/*******************************************************************************
5659
 * END OF EC API
5660
 ******************************************************************************/
5661
5662
#endif /* !WOLFSSL_PK_EC_INCLUDED */
5663