Coverage Report

Created: 2026-09-12 06:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl41/crypto/ec/ec_ameth.c
Line
Count
Source
1
/*
2
 * Copyright 2006-2026 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License 2.0 (the "License").  You may not use
5
 * this file except in compliance with the License.  You can obtain a copy
6
 * in the file LICENSE in the source distribution or at
7
 * https://www.openssl.org/source/license.html
8
 */
9
10
/*
11
 * ECDH and ECDSA low level APIs are deprecated for public use, but still ok
12
 * for internal use.
13
 */
14
#include "internal/deprecated.h"
15
16
#include <stdio.h>
17
#include "internal/cryptlib.h"
18
#include <openssl/x509.h>
19
#include <openssl/ec.h>
20
#include <openssl/bn.h>
21
#include <openssl/asn1t.h>
22
#include "crypto/asn1.h"
23
#include "crypto/evp.h"
24
#include "crypto/ec_params.h"
25
#include "crypto/x509.h"
26
#include <openssl/core_names.h>
27
#include <openssl/param_build.h>
28
#include "ec_local.h"
29
30
static int eckey_param2type(int *pptype, void **ppval, const EC_KEY *ec_key)
31
0
{
32
0
    const EC_GROUP *group;
33
0
    int nid;
34
35
0
    if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) {
36
0
        ERR_raise(ERR_LIB_EC, EC_R_MISSING_PARAMETERS);
37
0
        return 0;
38
0
    }
39
0
    if (EC_GROUP_get_asn1_flag(group)
40
0
        && (nid = EC_GROUP_get_curve_name(group)))
41
    /* we have a 'named curve' => just set the OID */
42
0
    {
43
0
        ASN1_OBJECT *asn1obj = OBJ_nid2obj(nid);
44
45
0
        if (asn1obj == NULL || OBJ_length(asn1obj) == 0) {
46
0
            ERR_raise(ERR_LIB_EC, EC_R_MISSING_OID);
47
0
            return 0;
48
0
        }
49
0
        *ppval = asn1obj;
50
0
        *pptype = V_ASN1_OBJECT;
51
0
    } else { /* explicit parameters */
52
53
0
        ASN1_STRING *pstr = NULL;
54
0
        pstr = ASN1_STRING_new();
55
0
        if (pstr == NULL)
56
0
            return 0;
57
0
        pstr->length = i2d_ECParameters(ec_key, &pstr->data);
58
0
        if (pstr->length <= 0) {
59
0
            ASN1_STRING_free(pstr);
60
0
            ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
61
0
            return 0;
62
0
        }
63
0
        *ppval = pstr;
64
0
        *pptype = V_ASN1_SEQUENCE;
65
0
    }
66
0
    return 1;
67
0
}
68
69
static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
70
0
{
71
0
    const EC_KEY *ec_key = pkey->pkey.ec;
72
0
    void *pval = NULL;
73
0
    int ptype;
74
0
    unsigned char *penc = NULL, *p;
75
0
    int penclen;
76
77
0
    if (!eckey_param2type(&ptype, &pval, ec_key)) {
78
0
        ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
79
0
        return 0;
80
0
    }
81
0
    penclen = i2o_ECPublicKey(ec_key, NULL);
82
0
    if (penclen <= 0)
83
0
        goto err;
84
0
    penc = OPENSSL_malloc(penclen);
85
0
    if (penc == NULL)
86
0
        goto err;
87
0
    p = penc;
88
0
    penclen = i2o_ECPublicKey(ec_key, &p);
89
0
    if (penclen <= 0)
90
0
        goto err;
91
0
    if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC),
92
0
            ptype, pval, penc, penclen))
93
0
        return 1;
94
0
err:
95
0
    if (ptype == V_ASN1_SEQUENCE)
96
0
        ASN1_STRING_free(pval);
97
0
    OPENSSL_free(penc);
98
0
    return 0;
99
0
}
100
101
static int eckey_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey)
102
552k
{
103
552k
    const unsigned char *p = NULL;
104
552k
    int pklen;
105
552k
    EC_KEY *eckey = NULL;
106
552k
    X509_ALGOR *palg;
107
552k
    OSSL_LIB_CTX *libctx = NULL;
108
552k
    const char *propq = NULL;
109
110
552k
    if (!ossl_x509_PUBKEY_get0_libctx(&libctx, &propq, pubkey)
111
552k
        || !X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
112
0
        return 0;
113
552k
    eckey = ossl_ec_key_param_from_x509_algor(palg, libctx, propq);
114
115
552k
    if (!eckey)
116
64.5k
        return 0;
117
118
    /* We have parameters now set public key */
119
487k
    if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
120
230k
        ERR_raise(ERR_LIB_EC, EC_R_DECODE_ERROR);
121
230k
        goto ecerr;
122
230k
    }
123
124
257k
    EVP_PKEY_assign_EC_KEY(pkey, eckey);
125
257k
    return 1;
126
127
230k
ecerr:
128
230k
    EC_KEY_free(eckey);
129
230k
    return 0;
130
487k
}
131
132
static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
133
0
{
134
0
    int r;
135
0
    const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
136
0
    const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec),
137
0
                   *pb = EC_KEY_get0_public_key(b->pkey.ec);
138
139
0
    if (group == NULL || pa == NULL || pb == NULL)
140
0
        return -2;
141
0
    r = EC_POINT_cmp(group, pa, pb, NULL);
142
0
    if (r == 0)
143
0
        return 1;
144
0
    if (r == 1)
145
0
        return 0;
146
0
    return -2;
147
0
}
148
149
static int eckey_priv_decode_ex(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8,
150
    OSSL_LIB_CTX *libctx, const char *propq)
151
252
{
152
252
    int ret = 0;
153
252
    EC_KEY *eckey = ossl_ec_key_from_pkcs8(p8, libctx, propq);
154
155
252
    if (eckey != NULL) {
156
41
        ret = 1;
157
41
        EVP_PKEY_assign_EC_KEY(pkey, eckey);
158
41
    }
159
160
252
    return ret;
161
252
}
162
163
static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
164
0
{
165
0
    EC_KEY ec_key = *(pkey->pkey.ec);
166
0
    unsigned char *ep = NULL;
167
0
    int eplen, ptype;
168
0
    void *pval;
169
0
    unsigned int old_flags;
170
171
0
    if (!eckey_param2type(&ptype, &pval, &ec_key)) {
172
0
        ERR_raise(ERR_LIB_EC, EC_R_DECODE_ERROR);
173
0
        return 0;
174
0
    }
175
176
    /* set the private key */
177
178
    /*
179
     * do not include the parameters in the SEC1 private key see PKCS#11
180
     * 12.11
181
     */
182
0
    old_flags = EC_KEY_get_enc_flags(&ec_key);
183
0
    EC_KEY_set_enc_flags(&ec_key, old_flags | EC_PKEY_NO_PARAMETERS);
184
185
0
    eplen = i2d_ECPrivateKey(&ec_key, &ep);
186
0
    if (eplen <= 0) {
187
0
        ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
188
0
        goto err;
189
0
    }
190
191
0
    if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
192
0
            ptype, pval, ep, eplen)) {
193
0
        ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB);
194
0
        OPENSSL_clear_free(ep, eplen);
195
0
        goto err;
196
0
    }
197
198
0
    return 1;
199
200
0
err:
201
0
    if (ptype == V_ASN1_SEQUENCE)
202
0
        ASN1_STRING_free(pval);
203
0
    return 0;
204
0
}
205
206
static int int_ec_size(const EVP_PKEY *pkey)
207
0
{
208
0
    return ECDSA_size(pkey->pkey.ec);
209
0
}
210
211
static int ec_bits(const EVP_PKEY *pkey)
212
0
{
213
0
    return EC_GROUP_order_bits(EC_KEY_get0_group(pkey->pkey.ec));
214
0
}
215
216
static int ec_security_bits(const EVP_PKEY *pkey)
217
0
{
218
0
    return EC_GROUP_security_bits(EC_KEY_get0_group(pkey->pkey.ec));
219
0
}
220
221
static int ec_missing_parameters(const EVP_PKEY *pkey)
222
32.6k
{
223
32.6k
    if (pkey->pkey.ec == NULL || EC_KEY_get0_group(pkey->pkey.ec) == NULL)
224
0
        return 1;
225
32.6k
    return 0;
226
32.6k
}
227
228
static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
229
0
{
230
0
    EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));
231
232
0
    if (group == NULL)
233
0
        return 0;
234
0
    if (to->pkey.ec == NULL) {
235
0
        to->pkey.ec = EC_KEY_new();
236
0
        if (to->pkey.ec == NULL)
237
0
            goto err;
238
0
    }
239
0
    if (EC_KEY_set_group(to->pkey.ec, group) == 0)
240
0
        goto err;
241
0
    EC_GROUP_free(group);
242
0
    return 1;
243
0
err:
244
0
    EC_GROUP_free(group);
245
0
    return 0;
246
0
}
247
248
static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
249
0
{
250
0
    const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
251
0
                   *group_b = EC_KEY_get0_group(b->pkey.ec);
252
253
0
    if (group_a == NULL || group_b == NULL)
254
0
        return -2;
255
0
    if (EC_GROUP_cmp(group_a, group_b, NULL))
256
0
        return 0;
257
0
    else
258
0
        return 1;
259
0
}
260
261
static void int_ec_free(EVP_PKEY *pkey)
262
653k
{
263
653k
    EC_KEY_free(pkey->pkey.ec);
264
653k
}
265
266
typedef enum {
267
    EC_KEY_PRINT_PRIVATE,
268
    EC_KEY_PRINT_PUBLIC,
269
    EC_KEY_PRINT_PARAM
270
} ec_print_t;
271
272
static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, ec_print_t ktype)
273
3.82k
{
274
3.82k
    const char *ecstr;
275
3.82k
    unsigned char *priv = NULL, *pub = NULL;
276
3.82k
    size_t privlen = 0, publen = 0;
277
3.82k
    int ret = 0;
278
3.82k
    const EC_GROUP *group;
279
280
3.82k
    if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
281
0
        ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
282
0
        return 0;
283
0
    }
284
285
3.82k
    if (ktype != EC_KEY_PRINT_PARAM && EC_KEY_get0_public_key(x) != NULL) {
286
3.45k
        publen = EC_KEY_key2buf(x, EC_KEY_get_conv_form(x), &pub, NULL);
287
3.45k
        if (publen == 0)
288
38
            goto err;
289
3.45k
    }
290
291
3.78k
    if (ktype == EC_KEY_PRINT_PRIVATE && EC_KEY_get0_private_key(x) != NULL) {
292
3.42k
        privlen = EC_KEY_priv2buf(x, &priv);
293
3.42k
        if (privlen == 0)
294
846
            goto err;
295
3.42k
    }
296
297
2.93k
    if (ktype == EC_KEY_PRINT_PRIVATE)
298
2.57k
        ecstr = "Private-Key";
299
364
    else if (ktype == EC_KEY_PRINT_PUBLIC)
300
0
        ecstr = "Public-Key";
301
364
    else
302
364
        ecstr = "ECDSA-Parameters";
303
304
2.93k
    if (!BIO_indent(bp, off, 128))
305
0
        goto err;
306
2.93k
    if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
307
2.93k
            EC_GROUP_order_bits(group))
308
2.93k
        <= 0)
309
0
        goto err;
310
311
2.93k
    if (privlen != 0) {
312
2.57k
        if (BIO_printf(bp, "%*spriv:\n", off, "") <= 0)
313
0
            goto err;
314
2.57k
        if (ASN1_buf_print(bp, priv, privlen, off + 4) == 0)
315
0
            goto err;
316
2.57k
    }
317
318
2.93k
    if (publen != 0) {
319
2.57k
        if (BIO_printf(bp, "%*spub:\n", off, "") <= 0)
320
0
            goto err;
321
2.57k
        if (ASN1_buf_print(bp, pub, publen, off + 4) == 0)
322
0
            goto err;
323
2.57k
    }
324
325
2.93k
    if (!ECPKParameters_print(bp, group, off))
326
0
        goto err;
327
2.93k
    ret = 1;
328
3.82k
err:
329
3.82k
    if (!ret)
330
3.82k
        ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
331
3.82k
    OPENSSL_clear_free(priv, privlen);
332
3.82k
    OPENSSL_free(pub);
333
3.82k
    return ret;
334
2.93k
}
335
336
static int eckey_param_decode(EVP_PKEY *pkey,
337
    const unsigned char **pder, int derlen)
338
0
{
339
0
    EC_KEY *eckey;
340
341
0
    if ((eckey = d2i_ECParameters(NULL, pder, derlen)) == NULL)
342
0
        return 0;
343
0
    EVP_PKEY_assign_EC_KEY(pkey, eckey);
344
0
    return 1;
345
0
}
346
347
static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
348
0
{
349
0
    return i2d_ECParameters(pkey->pkey.ec, pder);
350
0
}
351
352
static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
353
    ASN1_PCTX *ctx)
354
0
{
355
0
    return do_EC_KEY_print(bp, pkey->pkey.ec, indent, EC_KEY_PRINT_PARAM);
356
0
}
357
358
static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
359
    ASN1_PCTX *ctx)
360
0
{
361
0
    return do_EC_KEY_print(bp, pkey->pkey.ec, indent, EC_KEY_PRINT_PUBLIC);
362
0
}
363
364
static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
365
    ASN1_PCTX *ctx)
366
58
{
367
58
    return do_EC_KEY_print(bp, pkey->pkey.ec, indent, EC_KEY_PRINT_PRIVATE);
368
58
}
369
370
static int old_ec_priv_decode(EVP_PKEY *pkey,
371
    const unsigned char **pder, int derlen)
372
2.74k
{
373
2.74k
    EC_KEY *ec;
374
375
2.74k
    if ((ec = d2i_ECPrivateKey(NULL, pder, derlen)) == NULL)
376
2.73k
        return 0;
377
17
    EVP_PKEY_assign_EC_KEY(pkey, ec);
378
17
    return 1;
379
2.74k
}
380
381
static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
382
58
{
383
58
    return i2d_ECPrivateKey(pkey->pkey.ec, pder);
384
58
}
385
386
static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
387
0
{
388
0
    switch (op) {
389
0
    case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
390
0
        if (EVP_PKEY_get_id(pkey) == EVP_PKEY_SM2) {
391
            /* For SM2, the only valid digest-alg is SM3 */
392
0
            *(int *)arg2 = NID_sm3;
393
0
            return 2; /* Make it mandatory */
394
0
        }
395
0
        *(int *)arg2 = NID_sha256;
396
0
        return 1;
397
398
0
    case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
399
        /* We should only be here if we have a legacy key */
400
0
        if (!ossl_assert(evp_pkey_is_legacy(pkey)))
401
0
            return 0;
402
0
        return EC_KEY_oct2key(evp_pkey_get0_EC_KEY_int(pkey), arg2, arg1, NULL);
403
404
0
    case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
405
0
        return (int)EC_KEY_key2buf(EVP_PKEY_get0_EC_KEY(pkey),
406
0
            POINT_CONVERSION_UNCOMPRESSED, arg2, NULL);
407
408
0
    default:
409
0
        return -2;
410
0
    }
411
0
}
412
413
static int ec_pkey_check(const EVP_PKEY *pkey)
414
0
{
415
0
    EC_KEY *eckey = pkey->pkey.ec;
416
417
    /* stay consistent to what EVP_PKEY_check demands */
418
0
    if (eckey->priv_key == NULL) {
419
0
        ERR_raise(ERR_LIB_EC, EC_R_MISSING_PRIVATE_KEY);
420
0
        return 0;
421
0
    }
422
423
0
    return EC_KEY_check_key(eckey);
424
0
}
425
426
static int ec_pkey_public_check(const EVP_PKEY *pkey)
427
0
{
428
0
    EC_KEY *eckey = pkey->pkey.ec;
429
430
    /*
431
     * Note: it unnecessary to check eckey->pub_key here since
432
     * it will be checked in EC_KEY_check_key(). In fact, the
433
     * EC_KEY_check_key() mainly checks the public key, and checks
434
     * the private key optionally (only if there is one). So if
435
     * someone passes a whole EC key (public + private), this
436
     * will also work...
437
     */
438
439
0
    return EC_KEY_check_key(eckey);
440
0
}
441
442
static int ec_pkey_param_check(const EVP_PKEY *pkey)
443
0
{
444
0
    EC_KEY *eckey = pkey->pkey.ec;
445
446
    /* stay consistent to what EVP_PKEY_check demands */
447
0
    if (eckey->group == NULL) {
448
0
        ERR_raise(ERR_LIB_EC, EC_R_MISSING_PARAMETERS);
449
0
        return 0;
450
0
    }
451
452
0
    return EC_GROUP_check(eckey->group, NULL);
453
0
}
454
455
static size_t ec_pkey_dirty_cnt(const EVP_PKEY *pkey)
456
172k
{
457
172k
    return pkey->pkey.ec->dirty_cnt;
458
172k
}
459
460
static int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
461
    OSSL_FUNC_keymgmt_import_fn *importer,
462
    OSSL_LIB_CTX *libctx, const char *propq)
463
25.8k
{
464
25.8k
    const EC_KEY *eckey = NULL;
465
25.8k
    const EC_GROUP *ecg = NULL;
466
25.8k
    unsigned char *pub_key_buf = NULL, *gen_buf = NULL;
467
25.8k
    size_t pub_key_buflen;
468
25.8k
    OSSL_PARAM_BLD *tmpl;
469
25.8k
    OSSL_PARAM *params = NULL;
470
25.8k
    const BIGNUM *priv_key = NULL;
471
25.8k
    const EC_POINT *pub_point = NULL;
472
25.8k
    int selection = 0;
473
25.8k
    int rv = 0;
474
25.8k
    BN_CTX *bnctx = NULL;
475
476
25.8k
    if (from == NULL
477
25.8k
        || (eckey = from->pkey.ec) == NULL
478
25.8k
        || (ecg = EC_KEY_get0_group(eckey)) == NULL)
479
0
        return 0;
480
481
25.8k
    tmpl = OSSL_PARAM_BLD_new();
482
25.8k
    if (tmpl == NULL)
483
0
        return 0;
484
485
    /*
486
     * EC_POINT_point2buf() can generate random numbers in some
487
     * implementations so we need to ensure we use the correct libctx.
488
     */
489
25.8k
    bnctx = BN_CTX_new_ex(libctx);
490
25.8k
    if (bnctx == NULL)
491
0
        goto err;
492
25.8k
    BN_CTX_start(bnctx);
493
494
    /* export the domain parameters */
495
25.8k
    if (!ossl_ec_group_todata(ecg, tmpl, NULL, libctx, propq, bnctx, &gen_buf))
496
0
        goto err;
497
25.8k
    selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;
498
499
25.8k
    priv_key = EC_KEY_get0_private_key(eckey);
500
25.8k
    pub_point = EC_KEY_get0_public_key(eckey);
501
502
25.8k
    if (pub_point != NULL) {
503
        /* convert pub_point to a octet string according to the SECG standard */
504
25.8k
        point_conversion_form_t format = EC_KEY_get_conv_form(eckey);
505
506
25.8k
        if ((pub_key_buflen = EC_POINT_point2buf(ecg, pub_point,
507
25.8k
                 format,
508
25.8k
                 &pub_key_buf, bnctx))
509
25.8k
                == 0
510
25.8k
            || !OSSL_PARAM_BLD_push_octet_string(tmpl,
511
25.8k
                OSSL_PKEY_PARAM_PUB_KEY,
512
25.8k
                pub_key_buf,
513
25.8k
                pub_key_buflen))
514
0
            goto err;
515
25.8k
        selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
516
25.8k
    }
517
518
25.8k
    if (priv_key != NULL) {
519
25.8k
        size_t sz;
520
25.8k
        int ecbits;
521
25.8k
        int ecdh_cofactor_mode;
522
523
        /*
524
         * Key import/export should never leak the bit length of the secret
525
         * scalar in the key.
526
         *
527
         * For this reason, on export we use padded BIGNUMs with fixed length.
528
         *
529
         * When importing we also should make sure that, even if short lived,
530
         * the newly created BIGNUM is marked with the BN_FLG_CONSTTIME flag as
531
         * soon as possible, so that any processing of this BIGNUM might opt for
532
         * constant time implementations in the backend.
533
         *
534
         * Setting the BN_FLG_CONSTTIME flag alone is never enough, we also have
535
         * to preallocate the BIGNUM internal buffer to a fixed public size big
536
         * enough that operations performed during the processing never trigger
537
         * a realloc which would leak the size of the scalar through memory
538
         * accesses.
539
         *
540
         * Fixed Length
541
         * ------------
542
         *
543
         * The order of the large prime subgroup of the curve is our choice for
544
         * a fixed public size, as that is generally the upper bound for
545
         * generating a private key in EC cryptosystems and should fit all valid
546
         * secret scalars.
547
         *
548
         * For padding on export we just use the bit length of the order
549
         * converted to bytes (rounding up).
550
         *
551
         * For preallocating the BIGNUM storage we look at the number of "words"
552
         * required for the internal representation of the order, and we
553
         * preallocate 2 extra "words" in case any of the subsequent processing
554
         * might temporarily overflow the order length.
555
         */
556
25.8k
        ecbits = EC_GROUP_order_bits(ecg);
557
25.8k
        if (ecbits <= 0)
558
0
            goto err;
559
560
25.8k
        sz = (ecbits + 7) / 8;
561
25.8k
        if (!OSSL_PARAM_BLD_push_BN_pad(tmpl,
562
25.8k
                OSSL_PKEY_PARAM_PRIV_KEY,
563
25.8k
                priv_key, sz))
564
0
            goto err;
565
25.8k
        selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
566
567
        /*
568
         * The ECDH Cofactor Mode is defined only if the EC_KEY actually
569
         * contains a private key, so we check for the flag and export it only
570
         * in this case.
571
         */
572
25.8k
        ecdh_cofactor_mode = (EC_KEY_get_flags(eckey) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0;
573
574
        /* Export the ECDH_COFACTOR_MODE parameter */
575
25.8k
        if (!OSSL_PARAM_BLD_push_int(tmpl,
576
25.8k
                OSSL_PKEY_PARAM_USE_COFACTOR_ECDH,
577
25.8k
                ecdh_cofactor_mode))
578
0
            goto err;
579
25.8k
        selection |= OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS;
580
25.8k
    }
581
582
25.8k
    params = OSSL_PARAM_BLD_to_param(tmpl);
583
584
    /* We export, the provider imports */
585
25.8k
    rv = importer(to_keydata, selection, params);
586
587
25.8k
err:
588
25.8k
    OSSL_PARAM_BLD_free(tmpl);
589
25.8k
    OSSL_PARAM_free(params);
590
25.8k
    OPENSSL_free(pub_key_buf);
591
25.8k
    OPENSSL_free(gen_buf);
592
25.8k
    BN_CTX_end(bnctx);
593
25.8k
    BN_CTX_free(bnctx);
594
25.8k
    return rv;
595
25.8k
}
596
597
static int ec_pkey_import_from(const OSSL_PARAM params[], void *vpctx)
598
0
{
599
0
    EVP_PKEY_CTX *pctx = vpctx;
600
0
    EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
601
0
    EC_KEY *ec = EC_KEY_new_ex(pctx->libctx, pctx->propquery);
602
0
    EC_PARAMS p;
603
604
0
    if (ec == NULL) {
605
0
        ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
606
0
        return 0;
607
0
    }
608
0
    if (!ec_pkey_import_from_decoder(params, &p)) {
609
0
        EC_KEY_free(ec);
610
0
        return 0;
611
0
    }
612
613
0
    if (!ossl_ec_group_fromdata_parsed(ec, &p)
614
0
        || !ossl_ec_key_otherparams_fromdata_parsed(ec, &p)
615
0
        || !ossl_ec_key_fromdata_parsed(ec, &p, 1)
616
0
        || !EVP_PKEY_assign_EC_KEY(pkey, ec)) {
617
0
        EC_KEY_free(ec);
618
0
        return 0;
619
0
    }
620
0
    return 1;
621
0
}
622
623
static int ec_pkey_copy(EVP_PKEY *to, EVP_PKEY *from)
624
0
{
625
0
    EC_KEY *eckey = from->pkey.ec;
626
0
    EC_KEY *dupkey = NULL;
627
0
    int ret;
628
629
0
    if (eckey != NULL) {
630
0
        dupkey = EC_KEY_dup(eckey);
631
0
        if (dupkey == NULL)
632
0
            return 0;
633
0
    } else {
634
        /* necessary to properly copy empty SM2 keys */
635
0
        return EVP_PKEY_set_type(to, from->type);
636
0
    }
637
638
0
    ret = EVP_PKEY_assign_EC_KEY(to, dupkey);
639
0
    if (!ret)
640
0
        EC_KEY_free(dupkey);
641
0
    return ret;
642
0
}
643
644
const EVP_PKEY_ASN1_METHOD ossl_eckey_asn1_meth = {
645
    EVP_PKEY_EC,
646
    EVP_PKEY_EC,
647
    0,
648
    "EC",
649
    "OpenSSL EC algorithm",
650
651
    eckey_pub_decode,
652
    eckey_pub_encode,
653
    eckey_pub_cmp,
654
    eckey_pub_print,
655
656
    NULL,
657
    eckey_priv_encode,
658
    eckey_priv_print,
659
660
    int_ec_size,
661
    ec_bits,
662
    ec_security_bits,
663
664
    eckey_param_decode,
665
    eckey_param_encode,
666
    ec_missing_parameters,
667
    ec_copy_parameters,
668
    ec_cmp_parameters,
669
    eckey_param_print,
670
    0,
671
672
    int_ec_free,
673
    ec_pkey_ctrl,
674
    old_ec_priv_decode,
675
    old_ec_priv_encode,
676
677
    0, 0, 0,
678
679
    ec_pkey_check,
680
    ec_pkey_public_check,
681
    ec_pkey_param_check,
682
683
    0, /* set_priv_key */
684
    0, /* set_pub_key */
685
    0, /* get_priv_key */
686
    0, /* get_pub_key */
687
688
    ec_pkey_dirty_cnt,
689
    ec_pkey_export_to,
690
    ec_pkey_import_from,
691
    ec_pkey_copy,
692
    eckey_priv_decode_ex
693
};
694
695
#if !defined(OPENSSL_NO_SM2)
696
const EVP_PKEY_ASN1_METHOD ossl_sm2_asn1_meth = {
697
    EVP_PKEY_SM2,
698
    EVP_PKEY_EC,
699
    ASN1_PKEY_ALIAS
700
};
701
#endif
702
703
int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
704
3.40k
{
705
3.40k
    int private = EC_KEY_get0_private_key(x) != NULL;
706
707
3.40k
    return do_EC_KEY_print(bp, x, off,
708
3.40k
        private ? EC_KEY_PRINT_PRIVATE : EC_KEY_PRINT_PUBLIC);
709
3.40k
}
710
711
int ECParameters_print(BIO *bp, const EC_KEY *x)
712
364
{
713
364
    return do_EC_KEY_print(bp, x, 4, EC_KEY_PRINT_PARAM);
714
364
}