Coverage Report

Created: 2025-12-31 06:58

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