Coverage Report

Created: 2026-04-01 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl30/providers/implementations/keymgmt/ec_kmgmt.c
Line
Count
Source
1
/*
2
 * Copyright 2020-2023 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/ECDSA low level APIs are deprecated for public use, but still ok for
12
 * internal use.
13
 */
14
#include "internal/deprecated.h"
15
16
#include <string.h>
17
#include <openssl/core_dispatch.h>
18
#include <openssl/core_names.h>
19
#include <openssl/bn.h>
20
#include <openssl/err.h>
21
#include <openssl/objects.h>
22
#include <openssl/proverr.h>
23
#include "crypto/bn.h"
24
#include "crypto/ec.h"
25
#include "prov/implementations.h"
26
#include "prov/providercommon.h"
27
#include "prov/provider_ctx.h"
28
#include "internal/param_build_set.h"
29
30
#ifndef FIPS_MODULE
31
#ifndef OPENSSL_NO_SM2
32
#include "crypto/sm2.h"
33
#endif
34
#endif
35
36
static OSSL_FUNC_keymgmt_new_fn ec_newdata;
37
static OSSL_FUNC_keymgmt_gen_init_fn ec_gen_init;
38
static OSSL_FUNC_keymgmt_gen_set_template_fn ec_gen_set_template;
39
static OSSL_FUNC_keymgmt_gen_set_params_fn ec_gen_set_params;
40
static OSSL_FUNC_keymgmt_gen_settable_params_fn ec_gen_settable_params;
41
static OSSL_FUNC_keymgmt_gen_fn ec_gen;
42
static OSSL_FUNC_keymgmt_gen_cleanup_fn ec_gen_cleanup;
43
static OSSL_FUNC_keymgmt_load_fn ec_load;
44
static OSSL_FUNC_keymgmt_free_fn ec_freedata;
45
static OSSL_FUNC_keymgmt_get_params_fn ec_get_params;
46
static OSSL_FUNC_keymgmt_gettable_params_fn ec_gettable_params;
47
static OSSL_FUNC_keymgmt_set_params_fn ec_set_params;
48
static OSSL_FUNC_keymgmt_settable_params_fn ec_settable_params;
49
static OSSL_FUNC_keymgmt_has_fn ec_has;
50
static OSSL_FUNC_keymgmt_match_fn ec_match;
51
static OSSL_FUNC_keymgmt_validate_fn ec_validate;
52
static OSSL_FUNC_keymgmt_import_fn ec_import;
53
static OSSL_FUNC_keymgmt_import_types_fn ec_import_types;
54
static OSSL_FUNC_keymgmt_export_fn ec_export;
55
static OSSL_FUNC_keymgmt_export_types_fn ec_export_types;
56
static OSSL_FUNC_keymgmt_query_operation_name_fn ec_query_operation_name;
57
static OSSL_FUNC_keymgmt_dup_fn ec_dup;
58
#ifndef FIPS_MODULE
59
#ifndef OPENSSL_NO_SM2
60
static OSSL_FUNC_keymgmt_new_fn sm2_newdata;
61
static OSSL_FUNC_keymgmt_gen_init_fn sm2_gen_init;
62
static OSSL_FUNC_keymgmt_gen_fn sm2_gen;
63
static OSSL_FUNC_keymgmt_get_params_fn sm2_get_params;
64
static OSSL_FUNC_keymgmt_gettable_params_fn sm2_gettable_params;
65
static OSSL_FUNC_keymgmt_settable_params_fn sm2_settable_params;
66
static OSSL_FUNC_keymgmt_import_fn sm2_import;
67
static OSSL_FUNC_keymgmt_query_operation_name_fn sm2_query_operation_name;
68
static OSSL_FUNC_keymgmt_validate_fn sm2_validate;
69
#endif
70
#endif
71
72
163
#define EC_DEFAULT_MD "SHA256"
73
#define EC_POSSIBLE_SELECTIONS \
74
213k
    (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS)
75
0
#define SM2_DEFAULT_MD "SM3"
76
77
static const char *ec_query_operation_name(int operation_id)
78
75.6k
{
79
75.6k
    switch (operation_id) {
80
5.00k
    case OSSL_OP_KEYEXCH:
81
5.00k
        return "ECDH";
82
70.6k
    case OSSL_OP_SIGNATURE:
83
70.6k
        return "ECDSA";
84
75.6k
    }
85
0
    return NULL;
86
75.6k
}
87
88
#ifndef FIPS_MODULE
89
#ifndef OPENSSL_NO_SM2
90
static const char *sm2_query_operation_name(int operation_id)
91
0
{
92
0
    switch (operation_id) {
93
0
    case OSSL_OP_SIGNATURE:
94
0
        return "SM2";
95
0
    }
96
0
    return NULL;
97
0
}
98
#endif
99
#endif
100
101
/*
102
 * Callers of key_to_params MUST make sure that domparams_to_params is also
103
 * called!
104
 *
105
 * This function only exports the bare keypair, domain parameters and other
106
 * parameters are exported separately.
107
 */
108
static ossl_inline int key_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl,
109
    OSSL_PARAM params[], int include_private,
110
    unsigned char **pub_key)
111
560k
{
112
560k
    BIGNUM *x = NULL, *y = NULL;
113
560k
    const BIGNUM *priv_key = NULL;
114
560k
    const EC_POINT *pub_point = NULL;
115
560k
    const EC_GROUP *ecg = NULL;
116
560k
    size_t pub_key_len = 0;
117
560k
    int ret = 0;
118
560k
    BN_CTX *bnctx = NULL;
119
120
560k
    if (eckey == NULL
121
560k
        || (ecg = EC_KEY_get0_group(eckey)) == NULL)
122
0
        return 0;
123
124
560k
    priv_key = EC_KEY_get0_private_key(eckey);
125
560k
    pub_point = EC_KEY_get0_public_key(eckey);
126
127
560k
    if (pub_point != NULL) {
128
550k
        OSSL_PARAM *p = NULL, *px = NULL, *py = NULL;
129
        /*
130
         * EC_POINT_point2buf() can generate random numbers in some
131
         * implementations so we need to ensure we use the correct libctx.
132
         */
133
550k
        bnctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(eckey));
134
550k
        if (bnctx == NULL)
135
0
            goto err;
136
137
        /* If we are doing a get then check first before decoding the point */
138
550k
        if (tmpl == NULL) {
139
499k
            p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PUB_KEY);
140
499k
            px = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_PUB_X);
141
499k
            py = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_PUB_Y);
142
499k
        }
143
144
550k
        if (p != NULL || tmpl != NULL) {
145
            /* convert pub_point to a octet string according to the SECG standard */
146
51.1k
            point_conversion_form_t format = EC_KEY_get_conv_form(eckey);
147
148
51.1k
            if ((pub_key_len = EC_POINT_point2buf(ecg, pub_point,
149
51.1k
                     format,
150
51.1k
                     pub_key, bnctx))
151
51.1k
                    == 0
152
51.1k
                || !ossl_param_build_set_octet_string(tmpl, p,
153
51.1k
                    OSSL_PKEY_PARAM_PUB_KEY,
154
51.1k
                    *pub_key, pub_key_len))
155
0
                goto err;
156
51.1k
        }
157
550k
        if (px != NULL || py != NULL) {
158
0
            if (px != NULL) {
159
0
                x = BN_CTX_get(bnctx);
160
0
                if (x == NULL)
161
0
                    goto err;
162
0
            }
163
0
            if (py != NULL) {
164
0
                y = BN_CTX_get(bnctx);
165
0
                if (y == NULL)
166
0
                    goto err;
167
0
            }
168
169
0
            if (!EC_POINT_get_affine_coordinates(ecg, pub_point, x, y, bnctx))
170
0
                goto err;
171
0
            if (px != NULL
172
0
                && !ossl_param_build_set_bn(tmpl, px,
173
0
                    OSSL_PKEY_PARAM_EC_PUB_X, x))
174
0
                goto err;
175
0
            if (py != NULL
176
0
                && !ossl_param_build_set_bn(tmpl, py,
177
0
                    OSSL_PKEY_PARAM_EC_PUB_Y, y))
178
0
                goto err;
179
0
        }
180
550k
    }
181
182
560k
    if (priv_key != NULL && include_private) {
183
145k
        size_t sz;
184
145k
        int ecbits;
185
186
        /*
187
         * Key import/export should never leak the bit length of the secret
188
         * scalar in the key.
189
         *
190
         * For this reason, on export we use padded BIGNUMs with fixed length.
191
         *
192
         * When importing we also should make sure that, even if short lived,
193
         * the newly created BIGNUM is marked with the BN_FLG_CONSTTIME flag as
194
         * soon as possible, so that any processing of this BIGNUM might opt for
195
         * constant time implementations in the backend.
196
         *
197
         * Setting the BN_FLG_CONSTTIME flag alone is never enough, we also have
198
         * to preallocate the BIGNUM internal buffer to a fixed public size big
199
         * enough that operations performed during the processing never trigger
200
         * a realloc which would leak the size of the scalar through memory
201
         * accesses.
202
         *
203
         * Fixed Length
204
         * ------------
205
         *
206
         * The order of the large prime subgroup of the curve is our choice for
207
         * a fixed public size, as that is generally the upper bound for
208
         * generating a private key in EC cryptosystems and should fit all valid
209
         * secret scalars.
210
         *
211
         * For padding on export we just use the bit length of the order
212
         * converted to bytes (rounding up).
213
         *
214
         * For preallocating the BIGNUM storage we look at the number of "words"
215
         * required for the internal representation of the order, and we
216
         * preallocate 2 extra "words" in case any of the subsequent processing
217
         * might temporarily overflow the order length.
218
         */
219
145k
        ecbits = EC_GROUP_order_bits(ecg);
220
145k
        if (ecbits <= 0)
221
0
            goto err;
222
145k
        sz = (ecbits + 7) / 8;
223
224
145k
        if (!ossl_param_build_set_bn_pad(tmpl, params,
225
145k
                OSSL_PKEY_PARAM_PRIV_KEY,
226
145k
                priv_key, sz))
227
0
            goto err;
228
145k
    }
229
560k
    ret = 1;
230
560k
err:
231
560k
    BN_CTX_free(bnctx);
232
560k
    return ret;
233
560k
}
234
235
static ossl_inline int otherparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl,
236
    OSSL_PARAM params[])
237
560k
{
238
560k
    int ecdh_cofactor_mode = 0, group_check = 0;
239
560k
    const char *name = NULL;
240
560k
    point_conversion_form_t format;
241
242
560k
    if (ec == NULL)
243
0
        return 0;
244
245
560k
    format = EC_KEY_get_conv_form(ec);
246
560k
    name = ossl_ec_pt_format_id2name((int)format);
247
560k
    if (name != NULL
248
513k
        && !ossl_param_build_set_utf8_string(tmpl, params,
249
513k
            OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT,
250
513k
            name))
251
0
        return 0;
252
253
560k
    group_check = EC_KEY_get_flags(ec) & EC_FLAG_CHECK_NAMED_GROUP_MASK;
254
560k
    name = ossl_ec_check_group_type_id2name(group_check);
255
560k
    if (name != NULL
256
560k
        && !ossl_param_build_set_utf8_string(tmpl, params,
257
560k
            OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE,
258
560k
            name))
259
0
        return 0;
260
261
560k
    if ((EC_KEY_get_enc_flags(ec) & EC_PKEY_NO_PUBKEY) != 0
262
9.62k
        && !ossl_param_build_set_int(tmpl, params,
263
9.62k
            OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC, 0))
264
0
        return 0;
265
266
560k
    ecdh_cofactor_mode = (EC_KEY_get_flags(ec) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0;
267
560k
    return ossl_param_build_set_int(tmpl, params,
268
560k
        OSSL_PKEY_PARAM_USE_COFACTOR_ECDH,
269
560k
        ecdh_cofactor_mode);
270
560k
}
271
272
static void *ec_newdata(void *provctx)
273
41.5k
{
274
41.5k
    if (!ossl_prov_is_running())
275
0
        return NULL;
276
41.5k
    return EC_KEY_new_ex(PROV_LIBCTX_OF(provctx), NULL);
277
41.5k
}
278
279
#ifndef FIPS_MODULE
280
#ifndef OPENSSL_NO_SM2
281
static void *sm2_newdata(void *provctx)
282
0
{
283
0
    if (!ossl_prov_is_running())
284
0
        return NULL;
285
0
    return EC_KEY_new_by_curve_name_ex(PROV_LIBCTX_OF(provctx), NULL, NID_sm2);
286
0
}
287
#endif
288
#endif
289
290
static void ec_freedata(void *keydata)
291
483k
{
292
483k
    EC_KEY_free(keydata);
293
483k
}
294
295
static int ec_has(const void *keydata, int selection)
296
178k
{
297
178k
    const EC_KEY *ec = keydata;
298
178k
    int ok = 1;
299
300
178k
    if (!ossl_prov_is_running() || ec == NULL)
301
4.55k
        return 0;
302
174k
    if ((selection & EC_POSSIBLE_SELECTIONS) == 0)
303
0
        return 1; /* the selection is not missing */
304
305
174k
    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
306
60.4k
        ok = ok && (EC_KEY_get0_public_key(ec) != NULL);
307
174k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
308
55.7k
        ok = ok && (EC_KEY_get0_private_key(ec) != NULL);
309
174k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
310
109k
        ok = ok && (EC_KEY_get0_group(ec) != NULL);
311
    /*
312
     * We consider OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS to always be
313
     * available, so no extra check is needed other than the previous one
314
     * against EC_POSSIBLE_SELECTIONS.
315
     */
316
174k
    return ok;
317
174k
}
318
319
static int ec_match(const void *keydata1, const void *keydata2, int selection)
320
107k
{
321
107k
    const EC_KEY *ec1 = keydata1;
322
107k
    const EC_KEY *ec2 = keydata2;
323
107k
    const EC_GROUP *group_a = EC_KEY_get0_group(ec1);
324
107k
    const EC_GROUP *group_b = EC_KEY_get0_group(ec2);
325
107k
    BN_CTX *ctx = NULL;
326
107k
    int ok = 1;
327
328
107k
    if (!ossl_prov_is_running())
329
0
        return 0;
330
331
107k
    ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(ec1));
332
107k
    if (ctx == NULL)
333
0
        return 0;
334
335
107k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
336
107k
        ok = ok && group_a != NULL && group_b != NULL
337
107k
            && EC_GROUP_cmp(group_a, group_b, ctx) == 0;
338
107k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
339
56.1k
        int key_checked = 0;
340
341
56.1k
        if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
342
56.1k
            const EC_POINT *pa = EC_KEY_get0_public_key(ec1);
343
56.1k
            const EC_POINT *pb = EC_KEY_get0_public_key(ec2);
344
345
56.1k
            if (pa != NULL && pb != NULL) {
346
55.5k
                ok = ok && EC_POINT_cmp(group_b, pa, pb, ctx) == 0;
347
55.5k
                key_checked = 1;
348
55.5k
            }
349
56.1k
        }
350
56.1k
        if (!key_checked
351
584
            && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
352
584
            const BIGNUM *pa = EC_KEY_get0_private_key(ec1);
353
584
            const BIGNUM *pb = EC_KEY_get0_private_key(ec2);
354
355
584
            if (pa != NULL && pb != NULL) {
356
0
                ok = ok && BN_cmp(pa, pb) == 0;
357
0
                key_checked = 1;
358
0
            }
359
584
        }
360
56.1k
        ok = ok && key_checked;
361
56.1k
    }
362
107k
    BN_CTX_free(ctx);
363
107k
    return ok;
364
107k
}
365
366
static int common_check_sm2(const EC_KEY *ec, int sm2_wanted)
367
449k
{
368
449k
    const EC_GROUP *ecg = NULL;
369
370
    /*
371
     * sm2_wanted: import the keys or domparams only on SM2 Curve
372
     * !sm2_wanted: import the keys or domparams only not on SM2 Curve
373
     */
374
449k
    if ((ecg = EC_KEY_get0_group(ec)) == NULL
375
449k
        || (sm2_wanted ^ (EC_GROUP_get_curve_name(ecg) == NID_sm2)))
376
10
        return 0;
377
449k
    return 1;
378
449k
}
379
380
static int common_import(void *keydata, int selection, const OSSL_PARAM params[],
381
    int sm2_wanted)
382
41.5k
{
383
41.5k
    EC_KEY *ec = keydata;
384
41.5k
    int ok = 1;
385
386
41.5k
    if (!ossl_prov_is_running() || ec == NULL)
387
0
        return 0;
388
389
    /*
390
     * In this implementation, we can export/import only keydata in the
391
     * following combinations:
392
     *   - domain parameters (+optional other params)
393
     *   - public key with associated domain parameters (+optional other params)
394
     *   - private key with associated domain parameters and optional public key
395
     *         (+optional other params)
396
     *
397
     * This means:
398
     *   - domain parameters must always be requested
399
     *   - private key must be requested alongside public key
400
     *   - other parameters are always optional
401
     */
402
41.5k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0)
403
0
        return 0;
404
405
41.5k
    ok = ok && ossl_ec_group_fromdata(ec, params);
406
407
41.5k
    if (!common_check_sm2(ec, sm2_wanted))
408
0
        return 0;
409
410
41.5k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
411
41.5k
        int include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
412
413
41.5k
        ok = ok && ossl_ec_key_fromdata(ec, params, include_private);
414
41.5k
    }
415
41.5k
    if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
416
41.5k
        ok = ok && ossl_ec_key_otherparams_fromdata(ec, params);
417
418
41.5k
    return ok;
419
41.5k
}
420
421
static int ec_import(void *keydata, int selection, const OSSL_PARAM params[])
422
41.5k
{
423
41.5k
    return common_import(keydata, selection, params, 0);
424
41.5k
}
425
426
#ifndef FIPS_MODULE
427
#ifndef OPENSSL_NO_SM2
428
static int sm2_import(void *keydata, int selection, const OSSL_PARAM params[])
429
0
{
430
0
    return common_import(keydata, selection, params, 1);
431
0
}
432
#endif
433
#endif
434
435
static int ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
436
    void *cbarg)
437
51.1k
{
438
51.1k
    EC_KEY *ec = keydata;
439
51.1k
    OSSL_PARAM_BLD *tmpl = NULL;
440
51.1k
    OSSL_PARAM *params = NULL;
441
51.1k
    unsigned char *pub_key = NULL, *genbuf = NULL;
442
51.1k
    BN_CTX *bnctx = NULL;
443
51.1k
    int ok = 1;
444
445
51.1k
    if (!ossl_prov_is_running() || ec == NULL)
446
0
        return 0;
447
448
    /*
449
     * In this implementation, we can export/import only keydata in the
450
     * following combinations:
451
     *   - domain parameters (+optional other params)
452
     *   - public key with associated domain parameters (+optional other params)
453
     *   - private key with associated public key and domain parameters
454
     *         (+optional other params)
455
     *
456
     * This means:
457
     *   - domain parameters must always be requested
458
     *   - private key must be requested alongside public key
459
     *   - other parameters are always optional
460
     */
461
51.1k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0)
462
0
        return 0;
463
51.1k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0
464
51.1k
        && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) == 0)
465
0
        return 0;
466
467
51.1k
    tmpl = OSSL_PARAM_BLD_new();
468
51.1k
    if (tmpl == NULL)
469
0
        return 0;
470
471
51.1k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
472
51.1k
        bnctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(ec));
473
51.1k
        if (bnctx == NULL) {
474
0
            ok = 0;
475
0
            goto end;
476
0
        }
477
51.1k
        BN_CTX_start(bnctx);
478
51.1k
        ok = ok && ossl_ec_group_todata(EC_KEY_get0_group(ec), tmpl, NULL, ossl_ec_key_get_libctx(ec), ossl_ec_key_get0_propq(ec), bnctx, &genbuf);
479
51.1k
    }
480
481
51.1k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
482
51.1k
        int include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
483
484
51.1k
        ok = ok && key_to_params(ec, tmpl, NULL, include_private, &pub_key);
485
51.1k
    }
486
51.1k
    if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
487
51.1k
        ok = ok && otherparams_to_params(ec, tmpl, NULL);
488
489
51.1k
    if (!ok || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) {
490
0
        ok = 0;
491
0
        goto end;
492
0
    }
493
494
51.1k
    ok = param_cb(params, cbarg);
495
51.1k
    OSSL_PARAM_free(params);
496
51.1k
end:
497
51.1k
    OSSL_PARAM_BLD_free(tmpl);
498
51.1k
    OPENSSL_free(pub_key);
499
51.1k
    OPENSSL_free(genbuf);
500
51.1k
    BN_CTX_end(bnctx);
501
51.1k
    BN_CTX_free(bnctx);
502
51.1k
    return ok;
503
51.1k
}
504
505
/* IMEXPORT = IMPORT + EXPORT */
506
507
#define EC_IMEXPORTABLE_DOM_PARAMETERS                                               \
508
    OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0),                     \
509
        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, NULL, 0),                \
510
        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, NULL, 0), \
511
        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_FIELD_TYPE, NULL, 0),              \
512
        OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_P, NULL, 0),                                \
513
        OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_A, NULL, 0),                                \
514
        OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_B, NULL, 0),                                \
515
        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_GENERATOR, NULL, 0),              \
516
        OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_ORDER, NULL, 0),                            \
517
        OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_COFACTOR, NULL, 0),                         \
518
        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_SEED, NULL, 0),                   \
519
        OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS, NULL)
520
521
#define EC_IMEXPORTABLE_PUBLIC_KEY \
522
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0)
523
#define EC_IMEXPORTABLE_PRIVATE_KEY \
524
    OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)
525
#define EC_IMEXPORTABLE_OTHER_PARAMETERS                     \
526
    OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL), \
527
        OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC, NULL)
528
529
/*
530
 * Include all the possible combinations of OSSL_PARAM arrays for
531
 * ec_imexport_types().
532
 *
533
 * They are in a separate file as it is ~100 lines of unreadable and
534
 * uninteresting machine generated stuff.
535
 */
536
#include "ec_kmgmt_imexport.inc"
537
538
static ossl_inline const OSSL_PARAM *ec_imexport_types(int selection)
539
0
{
540
0
    int type_select = 0;
541
542
0
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
543
0
        type_select += 1;
544
0
    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
545
0
        type_select += 2;
546
0
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
547
0
        type_select += 4;
548
0
    if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
549
0
        type_select += 8;
550
0
    return ec_types[type_select];
551
0
}
552
553
static const OSSL_PARAM *ec_import_types(int selection)
554
0
{
555
0
    return ec_imexport_types(selection);
556
0
}
557
558
static const OSSL_PARAM *ec_export_types(int selection)
559
0
{
560
0
    return ec_imexport_types(selection);
561
0
}
562
563
static int ec_get_ecm_params(const EC_GROUP *group, OSSL_PARAM params[])
564
509k
{
565
#ifdef OPENSSL_NO_EC2M
566
    return 1;
567
#else
568
509k
    int ret = 0, m;
569
509k
    unsigned int k1 = 0, k2 = 0, k3 = 0;
570
509k
    int basis_nid;
571
509k
    const char *basis_name = NULL;
572
509k
    int fid = EC_GROUP_get_field_type(group);
573
574
509k
    if (fid != NID_X9_62_characteristic_two_field)
575
340k
        return 1;
576
577
168k
    basis_nid = EC_GROUP_get_basis_type(group);
578
168k
    if (basis_nid == NID_X9_62_tpBasis)
579
44.5k
        basis_name = SN_X9_62_tpBasis;
580
124k
    else if (basis_nid == NID_X9_62_ppBasis)
581
124k
        basis_name = SN_X9_62_ppBasis;
582
0
    else
583
0
        goto err;
584
585
168k
    m = EC_GROUP_get_degree(group);
586
168k
    if (!ossl_param_build_set_int(NULL, params, OSSL_PKEY_PARAM_EC_CHAR2_M, m)
587
168k
        || !ossl_param_build_set_utf8_string(NULL, params,
588
168k
            OSSL_PKEY_PARAM_EC_CHAR2_TYPE,
589
168k
            basis_name))
590
0
        goto err;
591
592
168k
    if (basis_nid == NID_X9_62_tpBasis) {
593
44.5k
        if (!EC_GROUP_get_trinomial_basis(group, &k1)
594
44.5k
            || !ossl_param_build_set_int(NULL, params,
595
44.5k
                OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS,
596
44.5k
                (int)k1))
597
0
            goto err;
598
124k
    } else {
599
124k
        if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3)
600
124k
            || !ossl_param_build_set_int(NULL, params,
601
124k
                OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, (int)k1)
602
124k
            || !ossl_param_build_set_int(NULL, params,
603
124k
                OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, (int)k2)
604
124k
            || !ossl_param_build_set_int(NULL, params,
605
124k
                OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, (int)k3))
606
0
            goto err;
607
124k
    }
608
168k
    ret = 1;
609
168k
err:
610
168k
    return ret;
611
168k
#endif /* OPENSSL_NO_EC2M */
612
168k
}
613
614
static int common_get_params(void *key, OSSL_PARAM params[], int sm2)
615
323k
{
616
323k
    int ret = 0;
617
323k
    EC_KEY *eck = key;
618
323k
    const EC_GROUP *ecg = NULL;
619
323k
    OSSL_PARAM *p;
620
323k
    unsigned char *pub_key = NULL, *genbuf = NULL;
621
323k
    OSSL_LIB_CTX *libctx;
622
323k
    const char *propq;
623
323k
    BN_CTX *bnctx = NULL;
624
625
323k
    ecg = EC_KEY_get0_group(eck);
626
323k
    if (ecg == NULL) {
627
0
        ERR_raise(ERR_LIB_PROV, PROV_R_NO_PARAMETERS_SET);
628
0
        return 0;
629
0
    }
630
631
323k
    libctx = ossl_ec_key_get_libctx(eck);
632
323k
    propq = ossl_ec_key_get0_propq(eck);
633
634
323k
    bnctx = BN_CTX_new_ex(libctx);
635
323k
    if (bnctx == NULL)
636
0
        return 0;
637
323k
    BN_CTX_start(bnctx);
638
639
323k
    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
640
275k
        && !OSSL_PARAM_set_int(p, ECDSA_size(eck)))
641
0
        goto err;
642
323k
    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
643
275k
        && !OSSL_PARAM_set_int(p, EC_GROUP_order_bits(ecg)))
644
0
        goto err;
645
323k
    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL) {
646
275k
        int ecbits, sec_bits;
647
648
275k
        ecbits = EC_GROUP_order_bits(ecg);
649
650
        /*
651
         * The following estimates are based on the values published
652
         * in Table 2 of "NIST Special Publication 800-57 Part 1 Revision 4"
653
         * at http://dx.doi.org/10.6028/NIST.SP.800-57pt1r4 .
654
         *
655
         * Note that the above reference explicitly categorizes algorithms in a
656
         * discrete set of values {80, 112, 128, 192, 256}, and that it is
657
         * relevant only for NIST approved Elliptic Curves, while OpenSSL
658
         * applies the same logic also to other curves.
659
         *
660
         * Classifications produced by other standardazing bodies might differ,
661
         * so the results provided for "bits of security" by this provider are
662
         * to be considered merely indicative, and it is the users'
663
         * responsibility to compare these values against the normative
664
         * references that may be relevant for their intent and purposes.
665
         */
666
275k
        if (ecbits >= 512)
667
12.2k
            sec_bits = 256;
668
262k
        else if (ecbits >= 384)
669
14.8k
            sec_bits = 192;
670
248k
        else if (ecbits >= 256)
671
90.4k
            sec_bits = 128;
672
157k
        else if (ecbits >= 224)
673
48.3k
            sec_bits = 112;
674
109k
        else if (ecbits >= 160)
675
47.5k
            sec_bits = 80;
676
61.9k
        else
677
61.9k
            sec_bits = ecbits / 2;
678
679
275k
        if (!OSSL_PARAM_set_int(p, sec_bits))
680
0
            goto err;
681
275k
    }
682
683
323k
    if ((p = OSSL_PARAM_locate(params,
684
323k
             OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS))
685
323k
        != NULL) {
686
3
        int explicitparams = EC_KEY_decoded_from_explicit_params(eck);
687
688
3
        if (explicitparams < 0
689
3
            || !OSSL_PARAM_set_int(p, explicitparams))
690
0
            goto err;
691
3
    }
692
693
323k
    if (!sm2) {
694
321k
        if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DEFAULT_DIGEST)) != NULL
695
163
            && !OSSL_PARAM_set_utf8_string(p, EC_DEFAULT_MD))
696
0
            goto err;
697
321k
    } else {
698
2.37k
        if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DEFAULT_DIGEST)) != NULL
699
0
            && !OSSL_PARAM_set_utf8_string(p, SM2_DEFAULT_MD))
700
0
            goto err;
701
2.37k
    }
702
703
    /* SM2 doesn't support this PARAM */
704
323k
    if (!sm2) {
705
321k
        p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH);
706
321k
        if (p != NULL) {
707
0
            int ecdh_cofactor_mode = 0;
708
709
0
            ecdh_cofactor_mode = (EC_KEY_get_flags(eck) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0;
710
711
0
            if (!OSSL_PARAM_set_int(p, ecdh_cofactor_mode))
712
0
                goto err;
713
0
        }
714
321k
    }
715
323k
    if ((p = OSSL_PARAM_locate(params,
716
323k
             OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY))
717
323k
        != NULL) {
718
12.0k
        const EC_POINT *ecp = EC_KEY_get0_public_key(key);
719
720
12.0k
        if (ecp == NULL) {
721
0
            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
722
0
            goto err;
723
0
        }
724
12.0k
        p->return_size = EC_POINT_point2oct(ecg, ecp,
725
12.0k
            POINT_CONVERSION_UNCOMPRESSED,
726
12.0k
            p->data, p->data_size, bnctx);
727
12.0k
        if (p->return_size == 0)
728
0
            goto err;
729
12.0k
    }
730
731
323k
    ret = ec_get_ecm_params(ecg, params)
732
323k
        && ossl_ec_group_todata(ecg, NULL, params, libctx, propq, bnctx,
733
323k
            &genbuf)
734
323k
        && key_to_params(eck, NULL, params, 1, &pub_key)
735
323k
        && otherparams_to_params(eck, NULL, params);
736
323k
err:
737
323k
    OPENSSL_free(genbuf);
738
323k
    OPENSSL_free(pub_key);
739
323k
    BN_CTX_end(bnctx);
740
323k
    BN_CTX_free(bnctx);
741
323k
    return ret;
742
323k
}
743
744
static int ec_get_params(void *key, OSSL_PARAM params[])
745
505k
{
746
505k
    return common_get_params(key, params, 0);
747
505k
}
748
749
#ifndef OPENSSL_NO_EC2M
750
#define EC2M_GETTABLE_DOM_PARAMS                                        \
751
    OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_M, NULL),                   \
752
        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_CHAR2_TYPE, NULL, 0), \
753
        OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS, NULL),        \
754
        OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, NULL),           \
755
        OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, NULL),           \
756
        OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, NULL),
757
#else
758
#define EC2M_GETTABLE_DOM_PARAMS
759
#endif
760
761
static const OSSL_PARAM ec_known_gettable_params[] = {
762
    OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
763
    OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
764
    OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
765
    OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST, NULL, 0),
766
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
767
    OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS, NULL),
768
    EC_IMEXPORTABLE_DOM_PARAMETERS,
769
    EC2M_GETTABLE_DOM_PARAMS
770
        EC_IMEXPORTABLE_PUBLIC_KEY,
771
    OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_PUB_X, NULL, 0),
772
    OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_PUB_Y, NULL, 0),
773
    EC_IMEXPORTABLE_PRIVATE_KEY,
774
    EC_IMEXPORTABLE_OTHER_PARAMETERS,
775
    OSSL_PARAM_END
776
};
777
778
static const OSSL_PARAM *ec_gettable_params(void *provctx)
779
0
{
780
0
    return ec_known_gettable_params;
781
0
}
782
783
static const OSSL_PARAM ec_known_settable_params[] = {
784
    OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL),
785
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
786
    OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, NULL, 0),
787
    OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, NULL, 0),
788
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_SEED, NULL, 0),
789
    OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC, NULL),
790
    OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE, NULL, 0),
791
    OSSL_PARAM_END
792
};
793
794
static const OSSL_PARAM *ec_settable_params(void *provctx)
795
0
{
796
0
    return ec_known_settable_params;
797
0
}
798
799
static int ec_set_params(void *key, const OSSL_PARAM params[])
800
4.21k
{
801
4.21k
    EC_KEY *eck = key;
802
4.21k
    const OSSL_PARAM *p;
803
804
4.21k
    if (key == NULL)
805
0
        return 0;
806
4.21k
    if (params == NULL)
807
0
        return 1;
808
809
4.21k
    if (!ossl_ec_group_set_params((EC_GROUP *)EC_KEY_get0_group(key), params))
810
0
        return 0;
811
812
4.21k
    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY);
813
4.21k
    if (p != NULL) {
814
4.21k
        BN_CTX *ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(key));
815
4.21k
        int ret = 1;
816
817
4.21k
        if (ctx == NULL
818
4.21k
            || p->data_type != OSSL_PARAM_OCTET_STRING
819
4.21k
            || !EC_KEY_oct2key(key, p->data, p->data_size, ctx))
820
1.18k
            ret = 0;
821
4.21k
        BN_CTX_free(ctx);
822
4.21k
        if (!ret)
823
1.18k
            return 0;
824
4.21k
    }
825
826
3.03k
    return ossl_ec_key_otherparams_fromdata(eck, params);
827
4.21k
}
828
829
#ifndef FIPS_MODULE
830
#ifndef OPENSSL_NO_SM2
831
static int sm2_get_params(void *key, OSSL_PARAM params[])
832
4.12k
{
833
4.12k
    return common_get_params(key, params, 1);
834
4.12k
}
835
836
static const OSSL_PARAM sm2_known_gettable_params[] = {
837
    OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
838
    OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
839
    OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
840
    OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST, NULL, 0),
841
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
842
    OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS, NULL),
843
    EC_IMEXPORTABLE_DOM_PARAMETERS,
844
    EC_IMEXPORTABLE_PUBLIC_KEY,
845
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_PUB_X, NULL, 0),
846
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_PUB_Y, NULL, 0),
847
    EC_IMEXPORTABLE_PRIVATE_KEY,
848
    OSSL_PARAM_END
849
};
850
851
static const OSSL_PARAM *sm2_gettable_params(ossl_unused void *provctx)
852
0
{
853
0
    return sm2_known_gettable_params;
854
0
}
855
856
static const OSSL_PARAM sm2_known_settable_params[] = {
857
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
858
    OSSL_PARAM_END
859
};
860
861
static const OSSL_PARAM *sm2_settable_params(ossl_unused void *provctx)
862
0
{
863
0
    return sm2_known_settable_params;
864
0
}
865
866
static int sm2_validate(const void *keydata, int selection, int checktype)
867
277
{
868
277
    const EC_KEY *eck = keydata;
869
277
    int ok = 1;
870
277
    BN_CTX *ctx = NULL;
871
872
277
    if (!ossl_prov_is_running())
873
0
        return 0;
874
875
277
    if ((selection & EC_POSSIBLE_SELECTIONS) == 0)
876
0
        return 1; /* nothing to validate */
877
878
277
    ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(eck));
879
277
    if (ctx == NULL)
880
0
        return 0;
881
882
277
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
883
45
        ok = ok && EC_GROUP_check(EC_KEY_get0_group(eck), ctx);
884
885
277
    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
886
187
        if (checktype == OSSL_KEYMGMT_VALIDATE_QUICK_CHECK)
887
0
            ok = ok && ossl_ec_key_public_check_quick(eck, ctx);
888
187
        else
889
187
            ok = ok && ossl_ec_key_public_check(eck, ctx);
890
187
    }
891
892
277
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
893
90
        ok = ok && ossl_sm2_key_private_check(eck);
894
895
277
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == OSSL_KEYMGMT_SELECT_KEYPAIR)
896
45
        ok = ok && ossl_ec_key_pairwise_check(eck, ctx);
897
898
277
    BN_CTX_free(ctx);
899
277
    return ok;
900
277
}
901
#endif
902
#endif
903
904
static int ec_validate(const void *keydata, int selection, int checktype)
905
24.5k
{
906
24.5k
    const EC_KEY *eck = keydata;
907
24.5k
    int ok = 1;
908
24.5k
    BN_CTX *ctx = NULL;
909
910
24.5k
    if (!ossl_prov_is_running())
911
0
        return 0;
912
913
24.5k
    if ((selection & EC_POSSIBLE_SELECTIONS) == 0)
914
0
        return 1; /* nothing to validate */
915
916
24.5k
    ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(eck));
917
24.5k
    if (ctx == NULL)
918
0
        return 0;
919
920
24.5k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
921
4.87k
        int flags = EC_KEY_get_flags(eck);
922
923
4.87k
        if ((flags & EC_FLAG_CHECK_NAMED_GROUP) != 0)
924
0
            ok = ok && EC_GROUP_check_named_curve(EC_KEY_get0_group(eck), (flags & EC_FLAG_CHECK_NAMED_GROUP_NIST) != 0, ctx) > 0;
925
4.87k
        else
926
4.87k
            ok = ok && EC_GROUP_check(EC_KEY_get0_group(eck), ctx);
927
4.87k
    }
928
929
24.5k
    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
930
14.7k
        if (checktype == OSSL_KEYMGMT_VALIDATE_QUICK_CHECK)
931
0
            ok = ok && ossl_ec_key_public_check_quick(eck, ctx);
932
14.7k
        else
933
14.7k
            ok = ok && ossl_ec_key_public_check(eck, ctx);
934
14.7k
    }
935
936
24.5k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
937
9.75k
        ok = ok && ossl_ec_key_private_check(eck);
938
939
24.5k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == OSSL_KEYMGMT_SELECT_KEYPAIR)
940
4.87k
        ok = ok && ossl_ec_key_pairwise_check(eck, ctx);
941
942
24.5k
    BN_CTX_free(ctx);
943
24.5k
    return ok;
944
24.5k
}
945
946
struct ec_gen_ctx {
947
    OSSL_LIB_CTX *libctx;
948
    char *group_name;
949
    char *encoding;
950
    char *pt_format;
951
    char *group_check;
952
    char *field_type;
953
    BIGNUM *p, *a, *b, *order, *cofactor;
954
    unsigned char *gen, *seed;
955
    size_t gen_len, seed_len;
956
    int selection;
957
    int ecdh_mode;
958
    EC_GROUP *gen_group;
959
};
960
961
static void *ec_gen_init(void *provctx, int selection,
962
    const OSSL_PARAM params[])
963
14.8k
{
964
14.8k
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx);
965
14.8k
    struct ec_gen_ctx *gctx = NULL;
966
967
14.8k
    if (!ossl_prov_is_running() || (selection & (EC_POSSIBLE_SELECTIONS)) == 0)
968
0
        return NULL;
969
970
14.8k
    if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {
971
14.8k
        gctx->libctx = libctx;
972
14.8k
        gctx->selection = selection;
973
14.8k
        gctx->ecdh_mode = 0;
974
14.8k
        if (!ec_gen_set_params(gctx, params)) {
975
0
            OPENSSL_free(gctx);
976
0
            gctx = NULL;
977
0
        }
978
14.8k
    }
979
14.8k
    return gctx;
980
14.8k
}
981
982
#ifndef FIPS_MODULE
983
#ifndef OPENSSL_NO_SM2
984
static void *sm2_gen_init(void *provctx, int selection,
985
    const OSSL_PARAM params[])
986
253
{
987
253
    struct ec_gen_ctx *gctx = ec_gen_init(provctx, selection, params);
988
989
253
    if (gctx != NULL) {
990
253
        if (gctx->group_name != NULL)
991
0
            return gctx;
992
253
        if ((gctx->group_name = OPENSSL_strdup("sm2")) != NULL)
993
253
            return gctx;
994
253
        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
995
0
        ec_gen_cleanup(gctx);
996
0
    }
997
0
    return NULL;
998
253
}
999
#endif
1000
#endif
1001
1002
static int ec_gen_set_group(void *genctx, const EC_GROUP *src)
1003
2.02k
{
1004
2.02k
    struct ec_gen_ctx *gctx = genctx;
1005
2.02k
    EC_GROUP *group;
1006
1007
2.02k
    group = EC_GROUP_dup(src);
1008
2.02k
    if (group == NULL) {
1009
0
        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE);
1010
0
        return 0;
1011
0
    }
1012
2.02k
    EC_GROUP_free(gctx->gen_group);
1013
2.02k
    gctx->gen_group = group;
1014
2.02k
    return 1;
1015
2.02k
}
1016
1017
static int ec_gen_set_template(void *genctx, void *templ)
1018
2.02k
{
1019
2.02k
    struct ec_gen_ctx *gctx = genctx;
1020
2.02k
    EC_KEY *ec = templ;
1021
2.02k
    const EC_GROUP *ec_group;
1022
1023
2.02k
    if (!ossl_prov_is_running() || gctx == NULL || ec == NULL)
1024
0
        return 0;
1025
2.02k
    if ((ec_group = EC_KEY_get0_group(ec)) == NULL)
1026
0
        return 0;
1027
2.02k
    return ec_gen_set_group(gctx, ec_group);
1028
2.02k
}
1029
1030
#define COPY_INT_PARAM(params, key, val)           \
1031
2.55k
    p = OSSL_PARAM_locate_const(params, key);      \
1032
2.55k
    if (p != NULL && !OSSL_PARAM_get_int(p, &val)) \
1033
2.55k
        goto err;
1034
1035
#define COPY_UTF8_PARAM(params, key, val)           \
1036
12.7k
    p = OSSL_PARAM_locate_const(params, key);       \
1037
12.7k
    if (p != NULL) {                                \
1038
1.21k
        if (p->data_type != OSSL_PARAM_UTF8_STRING) \
1039
1.21k
            goto err;                               \
1040
1.21k
        OPENSSL_free(val);                          \
1041
1.21k
        val = OPENSSL_strdup(p->data);              \
1042
1.21k
        if (val == NULL)                            \
1043
1.21k
            goto err;                               \
1044
1.21k
    }
1045
1046
#define COPY_OCTET_PARAM(params, key, val, len)      \
1047
5.10k
    p = OSSL_PARAM_locate_const(params, key);        \
1048
5.10k
    if (p != NULL) {                                 \
1049
0
        if (p->data_type != OSSL_PARAM_OCTET_STRING) \
1050
0
            goto err;                                \
1051
0
        OPENSSL_free(val);                           \
1052
0
        len = p->data_size;                          \
1053
0
        val = OPENSSL_memdup(p->data, p->data_size); \
1054
0
        if (val == NULL)                             \
1055
0
            goto err;                                \
1056
0
    }
1057
1058
#define COPY_BN_PARAM(params, key, bn)                \
1059
12.7k
    p = OSSL_PARAM_locate_const(params, key);         \
1060
12.7k
    if (p != NULL) {                                  \
1061
0
        if (bn == NULL)                               \
1062
0
            bn = BN_new();                            \
1063
0
        if (bn == NULL || !OSSL_PARAM_get_BN(p, &bn)) \
1064
0
            goto err;                                 \
1065
0
    }
1066
1067
static int ec_gen_set_params(void *genctx, const OSSL_PARAM params[])
1068
2.55k
{
1069
2.55k
    int ret = 0;
1070
2.55k
    struct ec_gen_ctx *gctx = genctx;
1071
2.55k
    const OSSL_PARAM *p;
1072
2.55k
    EC_GROUP *group = NULL;
1073
1074
2.55k
    COPY_INT_PARAM(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, gctx->ecdh_mode);
1075
1076
2.55k
    COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_GROUP_NAME, gctx->group_name);
1077
2.55k
    COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_FIELD_TYPE, gctx->field_type);
1078
2.55k
    COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_ENCODING, gctx->encoding);
1079
2.55k
    COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, gctx->pt_format);
1080
2.55k
    COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE, gctx->group_check);
1081
1082
2.55k
    COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_P, gctx->p);
1083
2.55k
    COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_A, gctx->a);
1084
2.55k
    COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_B, gctx->b);
1085
2.55k
    COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_ORDER, gctx->order);
1086
2.55k
    COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_COFACTOR, gctx->cofactor);
1087
1088
2.55k
    COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_EC_SEED, gctx->seed, gctx->seed_len);
1089
2.55k
    COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_EC_GENERATOR, gctx->gen,
1090
2.55k
        gctx->gen_len);
1091
1092
2.55k
    ret = 1;
1093
2.55k
err:
1094
2.55k
    EC_GROUP_free(group);
1095
2.55k
    return ret;
1096
2.55k
}
1097
1098
static int ec_gen_set_group_from_params(struct ec_gen_ctx *gctx)
1099
12.7k
{
1100
12.7k
    int ret = 0;
1101
12.7k
    OSSL_PARAM_BLD *bld;
1102
12.7k
    OSSL_PARAM *params = NULL;
1103
12.7k
    EC_GROUP *group = NULL;
1104
1105
12.7k
    bld = OSSL_PARAM_BLD_new();
1106
12.7k
    if (bld == NULL)
1107
0
        return 0;
1108
1109
12.7k
    if (gctx->encoding != NULL
1110
0
        && !OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_EC_ENCODING,
1111
0
            gctx->encoding, 0))
1112
0
        goto err;
1113
1114
12.7k
    if (gctx->pt_format != NULL
1115
0
        && !OSSL_PARAM_BLD_push_utf8_string(bld,
1116
0
            OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT,
1117
0
            gctx->pt_format, 0))
1118
0
        goto err;
1119
1120
12.7k
    if (gctx->group_name != NULL) {
1121
12.7k
        if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME,
1122
12.7k
                gctx->group_name, 0))
1123
0
            goto err;
1124
        /* Ignore any other parameters if there is a group name */
1125
12.7k
        goto build;
1126
12.7k
    } else if (gctx->field_type != NULL) {
1127
0
        if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_EC_FIELD_TYPE,
1128
0
                gctx->field_type, 0))
1129
0
            goto err;
1130
0
    } else {
1131
0
        goto err;
1132
0
    }
1133
0
    if (gctx->p == NULL
1134
0
        || gctx->a == NULL
1135
0
        || gctx->b == NULL
1136
0
        || gctx->order == NULL
1137
0
        || !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_P, gctx->p)
1138
0
        || !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_A, gctx->a)
1139
0
        || !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_B, gctx->b)
1140
0
        || !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_ORDER, gctx->order))
1141
0
        goto err;
1142
1143
0
    if (gctx->cofactor != NULL
1144
0
        && !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_COFACTOR,
1145
0
            gctx->cofactor))
1146
0
        goto err;
1147
1148
0
    if (gctx->seed != NULL
1149
0
        && !OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_EC_SEED,
1150
0
            gctx->seed, gctx->seed_len))
1151
0
        goto err;
1152
1153
0
    if (gctx->gen == NULL
1154
0
        || !OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_EC_GENERATOR,
1155
0
            gctx->gen, gctx->gen_len))
1156
0
        goto err;
1157
12.7k
build:
1158
12.7k
    params = OSSL_PARAM_BLD_to_param(bld);
1159
12.7k
    if (params == NULL)
1160
0
        goto err;
1161
12.7k
    group = EC_GROUP_new_from_params(params, gctx->libctx, NULL);
1162
12.7k
    if (group == NULL)
1163
0
        goto err;
1164
1165
12.7k
    EC_GROUP_free(gctx->gen_group);
1166
12.7k
    gctx->gen_group = group;
1167
1168
12.7k
    ret = 1;
1169
12.7k
err:
1170
12.7k
    OSSL_PARAM_free(params);
1171
12.7k
    OSSL_PARAM_BLD_free(bld);
1172
12.7k
    return ret;
1173
12.7k
}
1174
1175
static const OSSL_PARAM *ec_gen_settable_params(ossl_unused void *genctx,
1176
    ossl_unused void *provctx)
1177
0
{
1178
0
    static OSSL_PARAM settable[] = {
1179
0
        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0),
1180
0
        OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL),
1181
0
        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, NULL, 0),
1182
0
        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, NULL, 0),
1183
0
        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_FIELD_TYPE, NULL, 0),
1184
0
        OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_P, NULL, 0),
1185
0
        OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_A, NULL, 0),
1186
0
        OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_B, NULL, 0),
1187
0
        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_GENERATOR, NULL, 0),
1188
0
        OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_ORDER, NULL, 0),
1189
0
        OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_COFACTOR, NULL, 0),
1190
0
        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_SEED, NULL, 0),
1191
0
        OSSL_PARAM_END
1192
0
    };
1193
1194
0
    return settable;
1195
0
}
1196
1197
static int ec_gen_assign_group(EC_KEY *ec, EC_GROUP *group)
1198
14.8k
{
1199
14.8k
    if (group == NULL) {
1200
0
        ERR_raise(ERR_LIB_PROV, PROV_R_NO_PARAMETERS_SET);
1201
0
        return 0;
1202
0
    }
1203
14.8k
    return EC_KEY_set_group(ec, group) > 0;
1204
14.8k
}
1205
1206
/*
1207
 * The callback arguments (osslcb & cbarg) are not used by EC_KEY generation
1208
 */
1209
static void *ec_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
1210
1.34k
{
1211
1.34k
    struct ec_gen_ctx *gctx = genctx;
1212
1.34k
    EC_KEY *ec = NULL;
1213
1.34k
    int ret = 0;
1214
1215
1.34k
    if (!ossl_prov_is_running()
1216
1.34k
        || gctx == NULL
1217
1.34k
        || (ec = EC_KEY_new_ex(gctx->libctx, NULL)) == NULL)
1218
0
        return NULL;
1219
1220
1.34k
    if (gctx->gen_group == NULL) {
1221
1.21k
        if (!ec_gen_set_group_from_params(gctx))
1222
0
            goto err;
1223
1.21k
    } else {
1224
127
        if (gctx->encoding != NULL) {
1225
0
            int flags = ossl_ec_encoding_name2id(gctx->encoding);
1226
1227
0
            if (flags < 0)
1228
0
                goto err;
1229
0
            EC_GROUP_set_asn1_flag(gctx->gen_group, flags);
1230
0
        }
1231
127
        if (gctx->pt_format != NULL) {
1232
0
            int format = ossl_ec_pt_format_name2id(gctx->pt_format);
1233
1234
0
            if (format < 0)
1235
0
                goto err;
1236
0
            EC_GROUP_set_point_conversion_form(gctx->gen_group, format);
1237
0
        }
1238
127
    }
1239
1240
    /* We must always assign a group, no matter what */
1241
1.34k
    ret = ec_gen_assign_group(ec, gctx->gen_group);
1242
1243
    /* Whether you want it or not, you get a keypair, not just one half */
1244
1.34k
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
1245
989
        ret = ret && EC_KEY_generate_key(ec);
1246
1247
1.34k
    if (gctx->ecdh_mode != -1)
1248
1.34k
        ret = ret && ossl_ec_set_ecdh_cofactor_mode(ec, gctx->ecdh_mode);
1249
1250
1.34k
    if (gctx->group_check != NULL)
1251
0
        ret = ret && ossl_ec_set_check_group_type_from_name(ec, gctx->group_check);
1252
1.34k
    if (ret)
1253
1.34k
        return ec;
1254
0
err:
1255
    /* Something went wrong, throw the key away */
1256
0
    EC_KEY_free(ec);
1257
0
    return NULL;
1258
1.34k
}
1259
1260
#ifndef FIPS_MODULE
1261
#ifndef OPENSSL_NO_SM2
1262
/*
1263
 * The callback arguments (osslcb & cbarg) are not used by EC_KEY generation
1264
 */
1265
static void *sm2_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
1266
253
{
1267
253
    struct ec_gen_ctx *gctx = genctx;
1268
253
    EC_KEY *ec = NULL;
1269
253
    int ret = 1;
1270
1271
253
    if (gctx == NULL
1272
253
        || (ec = EC_KEY_new_ex(gctx->libctx, NULL)) == NULL)
1273
0
        return NULL;
1274
1275
253
    if (gctx->gen_group == NULL) {
1276
156
        if (!ec_gen_set_group_from_params(gctx))
1277
0
            goto err;
1278
156
    } else {
1279
97
        if (gctx->encoding) {
1280
0
            int flags = ossl_ec_encoding_name2id(gctx->encoding);
1281
1282
0
            if (flags < 0)
1283
0
                goto err;
1284
0
            EC_GROUP_set_asn1_flag(gctx->gen_group, flags);
1285
0
        }
1286
97
        if (gctx->pt_format != NULL) {
1287
0
            int format = ossl_ec_pt_format_name2id(gctx->pt_format);
1288
1289
0
            if (format < 0)
1290
0
                goto err;
1291
0
            EC_GROUP_set_point_conversion_form(gctx->gen_group, format);
1292
0
        }
1293
97
    }
1294
1295
    /* We must always assign a group, no matter what */
1296
253
    ret = ec_gen_assign_group(ec, gctx->gen_group);
1297
1298
    /* Whether you want it or not, you get a keypair, not just one half */
1299
253
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
1300
98
        ret = ret && EC_KEY_generate_key(ec);
1301
1302
253
    if (ret)
1303
253
        return ec;
1304
0
err:
1305
    /* Something went wrong, throw the key away */
1306
0
    EC_KEY_free(ec);
1307
0
    return NULL;
1308
253
}
1309
#endif
1310
#endif
1311
1312
static void ec_gen_cleanup(void *genctx)
1313
14.8k
{
1314
14.8k
    struct ec_gen_ctx *gctx = genctx;
1315
1316
14.8k
    if (gctx == NULL)
1317
0
        return;
1318
1319
14.8k
    EC_GROUP_free(gctx->gen_group);
1320
14.8k
    BN_free(gctx->p);
1321
14.8k
    BN_free(gctx->a);
1322
14.8k
    BN_free(gctx->b);
1323
14.8k
    BN_free(gctx->order);
1324
14.8k
    BN_free(gctx->cofactor);
1325
14.8k
    OPENSSL_free(gctx->group_name);
1326
14.8k
    OPENSSL_free(gctx->field_type);
1327
14.8k
    OPENSSL_free(gctx->pt_format);
1328
14.8k
    OPENSSL_free(gctx->encoding);
1329
14.8k
    OPENSSL_free(gctx->seed);
1330
14.8k
    OPENSSL_free(gctx->gen);
1331
14.8k
    OPENSSL_free(gctx);
1332
14.8k
}
1333
1334
static void *common_load(const void *reference, size_t reference_sz,
1335
    int sm2_wanted)
1336
407k
{
1337
407k
    EC_KEY *ec = NULL;
1338
1339
407k
    if (ossl_prov_is_running() && reference_sz == sizeof(ec)) {
1340
        /* The contents of the reference is the address to our object */
1341
407k
        ec = *(EC_KEY **)reference;
1342
1343
407k
        if (!common_check_sm2(ec, sm2_wanted))
1344
10
            return NULL;
1345
1346
        /* We grabbed, so we detach it */
1347
407k
        *(EC_KEY **)reference = NULL;
1348
407k
        return ec;
1349
407k
    }
1350
0
    return NULL;
1351
407k
}
1352
1353
static void *ec_load(const void *reference, size_t reference_sz)
1354
403k
{
1355
403k
    return common_load(reference, reference_sz, 0);
1356
403k
}
1357
1358
#ifndef FIPS_MODULE
1359
#ifndef OPENSSL_NO_SM2
1360
static void *sm2_load(const void *reference, size_t reference_sz)
1361
3.63k
{
1362
3.63k
    return common_load(reference, reference_sz, 1);
1363
3.63k
}
1364
#endif
1365
#endif
1366
1367
static void *ec_dup(const void *keydata_from, int selection)
1368
9.47k
{
1369
9.47k
    if (ossl_prov_is_running())
1370
9.47k
        return ossl_ec_key_dup(keydata_from, selection);
1371
0
    return NULL;
1372
9.47k
}
1373
1374
const OSSL_DISPATCH ossl_ec_keymgmt_functions[] = {
1375
    { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))ec_newdata },
1376
    { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))ec_gen_init },
1377
    { OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE,
1378
        (void (*)(void))ec_gen_set_template },
1379
    { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))ec_gen_set_params },
1380
    { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,
1381
        (void (*)(void))ec_gen_settable_params },
1382
    { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))ec_gen },
1383
    { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ec_gen_cleanup },
1384
    { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))ec_load },
1385
    { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ec_freedata },
1386
    { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))ec_get_params },
1387
    { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))ec_gettable_params },
1388
    { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*)(void))ec_set_params },
1389
    { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*)(void))ec_settable_params },
1390
    { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ec_has },
1391
    { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ec_match },
1392
    { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))ec_validate },
1393
    { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ec_import },
1394
    { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ec_import_types },
1395
    { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ec_export },
1396
    { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ec_export_types },
1397
    { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME,
1398
        (void (*)(void))ec_query_operation_name },
1399
    { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ec_dup },
1400
    { 0, NULL }
1401
};
1402
1403
#ifndef FIPS_MODULE
1404
#ifndef OPENSSL_NO_SM2
1405
const OSSL_DISPATCH ossl_sm2_keymgmt_functions[] = {
1406
    { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))sm2_newdata },
1407
    { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))sm2_gen_init },
1408
    { OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE,
1409
        (void (*)(void))ec_gen_set_template },
1410
    { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))ec_gen_set_params },
1411
    { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,
1412
        (void (*)(void))ec_gen_settable_params },
1413
    { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))sm2_gen },
1414
    { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ec_gen_cleanup },
1415
    { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))sm2_load },
1416
    { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ec_freedata },
1417
    { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))sm2_get_params },
1418
    { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))sm2_gettable_params },
1419
    { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*)(void))ec_set_params },
1420
    { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*)(void))sm2_settable_params },
1421
    { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ec_has },
1422
    { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ec_match },
1423
    { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))sm2_validate },
1424
    { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))sm2_import },
1425
    { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ec_import_types },
1426
    { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ec_export },
1427
    { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ec_export_types },
1428
    { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME,
1429
        (void (*)(void))sm2_query_operation_name },
1430
    { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ec_dup },
1431
    { 0, NULL }
1432
};
1433
#endif
1434
#endif