Coverage Report

Created: 2026-09-12 06:55

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-2026 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License 2.0 (the "License").  You may not use
5
 * this file except in compliance with the License.  You can obtain a copy
6
 * in the file LICENSE in the source distribution or at
7
 * https://www.openssl.org/source/license.html
8
 */
9
10
/*
11
 * ECDH/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
5
#define EC_DEFAULT_MD "SHA256"
76
#define EC_POSSIBLE_SELECTIONS \
77
187k
    (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
60.2k
{
82
60.2k
    switch (operation_id) {
83
4.01k
    case OSSL_OP_KEYEXCH:
84
4.01k
        return "ECDH";
85
56.2k
    case OSSL_OP_SIGNATURE:
86
56.2k
        return "ECDSA";
87
60.2k
    }
88
0
    return NULL;
89
60.2k
}
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
275k
{
115
275k
    BIGNUM *x = NULL, *y = NULL;
116
275k
    const BIGNUM *priv_key = NULL;
117
275k
    const EC_POINT *pub_point = NULL;
118
275k
    const EC_GROUP *ecg = NULL;
119
275k
    size_t pub_key_len = 0;
120
275k
    int ret = 0;
121
275k
    BN_CTX *bnctx = NULL;
122
123
275k
    if (eckey == NULL
124
275k
        || (ecg = EC_KEY_get0_group(eckey)) == NULL)
125
0
        return 0;
126
127
275k
    priv_key = EC_KEY_get0_private_key(eckey);
128
275k
    pub_point = EC_KEY_get0_public_key(eckey);
129
130
275k
    if (pub_point != NULL) {
131
269k
        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
269k
        bnctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(eckey));
137
269k
        if (bnctx == NULL)
138
0
            goto err;
139
140
        /* If we are doing a get then check first before decoding the point */
141
269k
        if (tmpl == NULL) {
142
236k
            p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PUB_KEY);
143
236k
            px = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_PUB_X);
144
236k
            py = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_PUB_Y);
145
236k
        }
146
147
269k
        if (p != NULL || tmpl != NULL) {
148
            /* convert pub_point to a octet string according to the SECG standard */
149
32.6k
            point_conversion_form_t format = EC_KEY_get_conv_form(eckey);
150
151
32.6k
            if ((pub_key_len = EC_POINT_point2buf(ecg, pub_point,
152
32.6k
                     format,
153
32.6k
                     pub_key, bnctx))
154
32.6k
                    == 0
155
32.6k
                || !ossl_param_build_set_octet_string(tmpl, p,
156
32.6k
                    OSSL_PKEY_PARAM_PUB_KEY,
157
32.6k
                    *pub_key, pub_key_len))
158
0
                goto err;
159
32.6k
        }
160
269k
        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
269k
    }
184
185
275k
    if (priv_key != NULL && include_private) {
186
89.9k
        size_t sz;
187
89.9k
        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
89.9k
        ecbits = EC_GROUP_order_bits(ecg);
223
89.9k
        if (ecbits <= 0)
224
0
            goto err;
225
89.9k
        sz = (ecbits + 7) / 8;
226
227
89.9k
        if (!ossl_param_build_set_bn_pad(tmpl, params,
228
89.9k
                OSSL_PKEY_PARAM_PRIV_KEY,
229
89.9k
                priv_key, sz))
230
0
            goto err;
231
89.9k
    }
232
275k
    ret = 1;
233
275k
err:
234
275k
    BN_CTX_free(bnctx);
235
275k
    return ret;
236
275k
}
237
238
static ossl_inline int otherparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl,
239
    OSSL_PARAM params[])
240
275k
{
241
275k
    int ecdh_cofactor_mode = 0, group_check = 0;
242
275k
    const char *name = NULL;
243
275k
    point_conversion_form_t format;
244
245
275k
    if (ec == NULL)
246
0
        return 0;
247
248
275k
    format = EC_KEY_get_conv_form(ec);
249
275k
    name = ossl_ec_pt_format_id2name((int)format);
250
275k
    if (name != NULL
251
258k
        && !ossl_param_build_set_utf8_string(tmpl, params,
252
258k
            OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT,
253
258k
            name))
254
0
        return 0;
255
256
275k
    group_check = EC_KEY_get_flags(ec) & EC_FLAG_CHECK_NAMED_GROUP_MASK;
257
275k
    name = ossl_ec_check_group_type_id2name(group_check);
258
275k
    if (name != NULL
259
275k
        && !ossl_param_build_set_utf8_string(tmpl, params,
260
275k
            OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE,
261
275k
            name))
262
0
        return 0;
263
264
275k
    if ((EC_KEY_get_enc_flags(ec) & EC_PKEY_NO_PUBKEY) != 0
265
5.65k
        && !ossl_param_build_set_int(tmpl, params,
266
5.65k
            OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC, 0))
267
0
        return 0;
268
269
275k
    ecdh_cofactor_mode = (EC_KEY_get_flags(ec) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0;
270
275k
    return ossl_param_build_set_int(tmpl, params,
271
275k
        OSSL_PKEY_PARAM_USE_COFACTOR_ECDH,
272
275k
        ecdh_cofactor_mode);
273
275k
}
274
275
static void *ec_newdata(void *provctx)
276
25.8k
{
277
25.8k
    if (!ossl_prov_is_running())
278
0
        return NULL;
279
25.8k
    return EC_KEY_new_ex(PROV_LIBCTX_OF(provctx), NULL);
280
25.8k
}
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
356k
{
295
356k
    EC_KEY_free(keydata);
296
356k
}
297
298
static int ec_has(const void *keydata, int selection)
299
161k
{
300
161k
    const EC_KEY *ec = keydata;
301
161k
    int ok = 1;
302
303
161k
    if (!ossl_prov_is_running() || ec == NULL)
304
3.61k
        return 0;
305
157k
    if ((selection & EC_POSSIBLE_SELECTIONS) == 0)
306
0
        return 1; /* the selection is not missing */
307
308
157k
    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
309
57.2k
        ok = ok && (EC_KEY_get0_public_key(ec) != NULL);
310
157k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
311
45.0k
        ok = ok && (EC_KEY_get0_private_key(ec) != NULL);
312
157k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
313
97.2k
        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
157k
    return ok;
320
157k
}
321
322
static int ec_match(const void *keydata1, const void *keydata2, int selection)
323
86.8k
{
324
86.8k
    const EC_KEY *ec1 = keydata1;
325
86.8k
    const EC_KEY *ec2 = keydata2;
326
86.8k
    const EC_GROUP *group_a = EC_KEY_get0_group(ec1);
327
86.8k
    const EC_GROUP *group_b = EC_KEY_get0_group(ec2);
328
86.8k
    BN_CTX *ctx = NULL;
329
86.8k
    int ok = 1;
330
331
86.8k
    if (!ossl_prov_is_running())
332
0
        return 0;
333
334
86.8k
    ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(ec1));
335
86.8k
    if (ctx == NULL)
336
0
        return 0;
337
338
86.8k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
339
86.8k
        ok = ok && group_a != NULL && group_b != NULL
340
86.8k
            && EC_GROUP_cmp(group_a, group_b, ctx) == 0;
341
86.8k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
342
45.2k
        int key_checked = 0;
343
344
45.2k
        if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
345
45.2k
            const EC_POINT *pa = EC_KEY_get0_public_key(ec1);
346
45.2k
            const EC_POINT *pb = EC_KEY_get0_public_key(ec2);
347
348
45.2k
            if (pa != NULL && pb != NULL) {
349
44.7k
                ok = ok && EC_POINT_cmp(group_b, pa, pb, ctx) == 0;
350
44.7k
                key_checked = 1;
351
44.7k
            }
352
45.2k
        }
353
45.2k
        if (!key_checked
354
495
            && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
355
495
            const BIGNUM *pa = EC_KEY_get0_private_key(ec1);
356
495
            const BIGNUM *pb = EC_KEY_get0_private_key(ec2);
357
358
495
            if (pa != NULL && pb != NULL) {
359
0
                ok = ok && BN_cmp(pa, pb) == 0;
360
0
                key_checked = 1;
361
0
            }
362
495
        }
363
45.2k
        ok = ok && key_checked;
364
45.2k
    }
365
86.8k
    BN_CTX_free(ctx);
366
86.8k
    return ok;
367
86.8k
}
368
369
static int common_check_sm2(const EC_KEY *ec, int sm2_wanted)
370
331k
{
371
331k
    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
331k
    if ((ecg = EC_KEY_get0_group(ec)) == NULL
378
331k
        || (sm2_wanted ^ (EC_GROUP_get_curve_name(ecg) == NID_sm2)))
379
12
        return 0;
380
331k
    return 1;
381
331k
}
382
383
static int common_import(void *keydata, int selection, const OSSL_PARAM params[],
384
    int sm2_wanted)
385
25.8k
{
386
25.8k
    EC_KEY *ec = keydata;
387
25.8k
    int ok = 1;
388
389
25.8k
    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
25.8k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0)
406
0
        return 0;
407
408
25.8k
    ok = ok && ossl_ec_group_fromdata(ec, params);
409
410
25.8k
    if (!common_check_sm2(ec, sm2_wanted))
411
0
        return 0;
412
413
25.8k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
414
25.8k
        int include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
415
416
25.8k
        ok = ok && ossl_ec_key_fromdata(ec, params, include_private);
417
25.8k
    }
418
25.8k
    if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
419
25.8k
        ok = ok && ossl_ec_key_otherparams_fromdata(ec, params);
420
421
25.8k
    return ok;
422
25.8k
}
423
424
static int ec_import(void *keydata, int selection, const OSSL_PARAM params[])
425
25.8k
{
426
25.8k
    return common_import(keydata, selection, params, 0);
427
25.8k
}
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
32.6k
{
441
32.6k
    EC_KEY *ec = keydata;
442
32.6k
    OSSL_PARAM_BLD *tmpl = NULL;
443
32.6k
    OSSL_PARAM *params = NULL;
444
32.6k
    unsigned char *pub_key = NULL, *genbuf = NULL;
445
32.6k
    BN_CTX *bnctx = NULL;
446
32.6k
    int ok = 1;
447
448
32.6k
    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
32.6k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0)
465
0
        return 0;
466
32.6k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0
467
32.6k
        && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) == 0)
468
0
        return 0;
469
470
32.6k
    tmpl = OSSL_PARAM_BLD_new();
471
32.6k
    if (tmpl == NULL)
472
0
        return 0;
473
474
32.6k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
475
32.6k
        bnctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(ec));
476
32.6k
        if (bnctx == NULL) {
477
0
            ok = 0;
478
0
            goto end;
479
0
        }
480
32.6k
        BN_CTX_start(bnctx);
481
32.6k
        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
32.6k
    }
483
484
32.6k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
485
32.6k
        int include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
486
487
32.6k
        ok = ok && key_to_params(ec, tmpl, NULL, include_private, &pub_key);
488
32.6k
    }
489
32.6k
    if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
490
32.6k
        ok = ok && otherparams_to_params(ec, tmpl, NULL);
491
492
32.6k
    if (!ok || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) {
493
0
        ok = 0;
494
0
        goto end;
495
0
    }
496
497
32.6k
    ok = param_cb(params, cbarg);
498
32.6k
    OSSL_PARAM_free(params);
499
32.6k
end:
500
32.6k
    OSSL_PARAM_BLD_free(tmpl);
501
32.6k
    OPENSSL_free(pub_key);
502
32.6k
    OPENSSL_free(genbuf);
503
32.6k
    BN_CTX_end(bnctx);
504
32.6k
    BN_CTX_free(bnctx);
505
32.6k
    return ok;
506
32.6k
}
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
363k
{
568
#ifdef OPENSSL_NO_EC2M
569
    return 1;
570
#else
571
363k
    int ret = 0, m;
572
363k
    unsigned int k1 = 0, k2 = 0, k3 = 0;
573
363k
    int basis_nid;
574
363k
    const char *basis_name = NULL;
575
363k
    int fid = EC_GROUP_get_field_type(group);
576
577
363k
    if (fid != NID_X9_62_characteristic_two_field)
578
243k
        return 1;
579
580
119k
    basis_nid = EC_GROUP_get_basis_type(group);
581
119k
    if (basis_nid == NID_X9_62_tpBasis)
582
26.4k
        basis_name = SN_X9_62_tpBasis;
583
92.6k
    else if (basis_nid == NID_X9_62_ppBasis)
584
92.6k
        basis_name = SN_X9_62_ppBasis;
585
0
    else
586
0
        goto err;
587
588
119k
    m = EC_GROUP_get_degree(group);
589
119k
    if (!ossl_param_build_set_int(NULL, params, OSSL_PKEY_PARAM_EC_CHAR2_M, m)
590
119k
        || !ossl_param_build_set_utf8_string(NULL, params,
591
119k
            OSSL_PKEY_PARAM_EC_CHAR2_TYPE,
592
119k
            basis_name))
593
0
        goto err;
594
595
119k
    if (basis_nid == NID_X9_62_tpBasis) {
596
26.4k
        if (!EC_GROUP_get_trinomial_basis(group, &k1)
597
26.4k
            || !ossl_param_build_set_int(NULL, params,
598
26.4k
                OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS,
599
26.4k
                (int)k1))
600
0
            goto err;
601
92.6k
    } else {
602
92.6k
        if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3)
603
92.6k
            || !ossl_param_build_set_int(NULL, params,
604
92.6k
                OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, (int)k1)
605
92.6k
            || !ossl_param_build_set_int(NULL, params,
606
92.6k
                OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, (int)k2)
607
92.6k
            || !ossl_param_build_set_int(NULL, params,
608
92.6k
                OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, (int)k3))
609
0
            goto err;
610
92.6k
    }
611
119k
    ret = 1;
612
119k
err:
613
119k
    return ret;
614
119k
#endif /* OPENSSL_NO_EC2M */
615
119k
}
616
617
static int common_get_params(void *key, OSSL_PARAM params[], int sm2)
618
139k
{
619
139k
    int ret = 0;
620
139k
    EC_KEY *eck = key;
621
139k
    const EC_GROUP *ecg = NULL;
622
139k
    OSSL_PARAM *p;
623
139k
    unsigned char *pub_key = NULL, *genbuf = NULL;
624
139k
    OSSL_LIB_CTX *libctx;
625
139k
    const char *propq;
626
139k
    BN_CTX *bnctx = NULL;
627
628
139k
    ecg = EC_KEY_get0_group(eck);
629
139k
    if (ecg == NULL) {
630
0
        ERR_raise(ERR_LIB_PROV, PROV_R_NO_PARAMETERS_SET);
631
0
        return 0;
632
0
    }
633
634
139k
    libctx = ossl_ec_key_get_libctx(eck);
635
139k
    propq = ossl_ec_key_get0_propq(eck);
636
637
139k
    bnctx = BN_CTX_new_ex(libctx);
638
139k
    if (bnctx == NULL)
639
0
        return 0;
640
139k
    BN_CTX_start(bnctx);
641
642
139k
    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
643
123k
        && !OSSL_PARAM_set_int(p, ECDSA_size(eck)))
644
0
        goto err;
645
139k
    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
646
123k
        && !OSSL_PARAM_set_int(p, EC_GROUP_order_bits(ecg)))
647
0
        goto err;
648
139k
    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL) {
649
123k
        int ecbits, sec_bits;
650
651
123k
        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
123k
        if (ecbits >= 512)
670
4.21k
            sec_bits = 256;
671
119k
        else if (ecbits >= 384)
672
8.56k
            sec_bits = 192;
673
110k
        else if (ecbits >= 256)
674
46.2k
            sec_bits = 128;
675
64.6k
        else if (ecbits >= 224)
676
17.2k
            sec_bits = 112;
677
47.4k
        else if (ecbits >= 160)
678
18.4k
            sec_bits = 80;
679
28.9k
        else
680
28.9k
            sec_bits = ecbits / 2;
681
682
123k
        if (!OSSL_PARAM_set_int(p, sec_bits))
683
0
            goto err;
684
123k
    }
685
686
139k
    if ((p = OSSL_PARAM_locate(params,
687
139k
             OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS))
688
139k
        != NULL) {
689
1
        int explicitparams = EC_KEY_decoded_from_explicit_params(eck);
690
691
1
        if (explicitparams < 0
692
1
            || !OSSL_PARAM_set_int(p, explicitparams))
693
0
            goto err;
694
1
    }
695
696
139k
    if (!sm2) {
697
138k
        if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DEFAULT_DIGEST)) != NULL
698
5
            && !OSSL_PARAM_set_utf8_string(p, EC_DEFAULT_MD))
699
0
            goto err;
700
138k
    } else {
701
1.50k
        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
1.50k
    }
705
706
    /* SM2 doesn't support this PARAM */
707
139k
    if (!sm2) {
708
138k
        p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH);
709
138k
        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
138k
    }
718
139k
    if ((p = OSSL_PARAM_locate(params,
719
139k
             OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY))
720
139k
        != NULL) {
721
6.27k
        const EC_POINT *ecp = EC_KEY_get0_public_key(key);
722
723
6.27k
        if (ecp == NULL) {
724
0
            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
725
0
            goto err;
726
0
        }
727
6.27k
        p->return_size = EC_POINT_point2oct(ecg, ecp,
728
6.27k
            POINT_CONVERSION_UNCOMPRESSED,
729
6.27k
            p->data, p->data_size, bnctx);
730
6.27k
        if (p->return_size == 0)
731
0
            goto err;
732
6.27k
    }
733
734
139k
    ret = ec_get_ecm_params(ecg, params)
735
139k
        && ossl_ec_group_todata(ecg, NULL, params, libctx, propq, bnctx,
736
139k
            &genbuf)
737
139k
        && key_to_params(eck, NULL, params, 1, &pub_key)
738
139k
        && otherparams_to_params(eck, NULL, params);
739
139k
err:
740
139k
    OPENSSL_free(genbuf);
741
139k
    OPENSSL_free(pub_key);
742
139k
    BN_CTX_end(bnctx);
743
139k
    BN_CTX_free(bnctx);
744
139k
    return ret;
745
139k
}
746
747
static int ec_get_params(void *key, OSSL_PARAM params[])
748
358k
{
749
358k
    return common_get_params(key, params, 0);
750
358k
}
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
1.82k
{
804
1.82k
    EC_KEY *eck = key;
805
1.82k
    const OSSL_PARAM *p;
806
807
1.82k
    if (key == NULL)
808
0
        return 0;
809
1.82k
    if (params == NULL)
810
0
        return 1;
811
812
1.82k
    if (!ossl_ec_group_set_params((EC_GROUP *)EC_KEY_get0_group(key), params))
813
0
        return 0;
814
815
1.82k
    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY);
816
1.82k
    if (p != NULL) {
817
1.82k
        BN_CTX *ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(key));
818
1.82k
        int ret = 1;
819
820
1.82k
        if (ctx == NULL
821
1.82k
            || p->data_type != OSSL_PARAM_OCTET_STRING
822
1.82k
            || !EC_KEY_oct2key(key, p->data, p->data_size, ctx))
823
459
            ret = 0;
824
1.82k
        BN_CTX_free(ctx);
825
1.82k
        if (!ret)
826
459
            return 0;
827
1.82k
    }
828
829
1.36k
    return ossl_ec_key_otherparams_fromdata(eck, params);
830
1.82k
}
831
832
#ifndef FIPS_MODULE
833
#ifndef OPENSSL_NO_SM2
834
static int sm2_get_params(void *key, OSSL_PARAM params[])
835
4.32k
{
836
4.32k
    return common_get_params(key, params, 1);
837
4.32k
}
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
312
{
871
312
    const EC_KEY *eck = keydata;
872
312
    int ok = 1;
873
312
    BN_CTX *ctx = NULL;
874
875
312
    if (!ossl_prov_is_running())
876
0
        return 0;
877
878
312
    if ((selection & EC_POSSIBLE_SELECTIONS) == 0)
879
0
        return 1; /* nothing to validate */
880
881
312
    ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(eck));
882
312
    if (ctx == NULL)
883
0
        return 0;
884
885
312
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
886
40
        ok = ok && EC_GROUP_check(EC_KEY_get0_group(eck), ctx);
887
888
312
    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
889
232
        if (checktype == OSSL_KEYMGMT_VALIDATE_QUICK_CHECK)
890
0
            ok = ok && ossl_ec_key_public_check_quick(eck, ctx);
891
232
        else
892
232
            ok = ok && ossl_ec_key_public_check(eck, ctx);
893
232
    }
894
895
312
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
896
80
        ok = ok && ossl_sm2_key_private_check(eck);
897
898
312
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == OSSL_KEYMGMT_SELECT_KEYPAIR)
899
40
        ok = ok && ossl_ec_key_pairwise_check(eck, ctx);
900
901
312
    BN_CTX_free(ctx);
902
312
    return ok;
903
312
}
904
#endif
905
#endif
906
907
static int ec_validate(const void *keydata, int selection, int checktype)
908
18.1k
{
909
18.1k
    const EC_KEY *eck = keydata;
910
18.1k
    int ok = 1;
911
18.1k
    BN_CTX *ctx = NULL;
912
913
18.1k
    if (!ossl_prov_is_running())
914
0
        return 0;
915
916
18.1k
    if ((selection & EC_POSSIBLE_SELECTIONS) == 0)
917
0
        return 1; /* nothing to validate */
918
919
18.1k
    ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(eck));
920
18.1k
    if (ctx == NULL)
921
0
        return 0;
922
923
18.1k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
924
3.52k
        int flags = EC_KEY_get_flags(eck);
925
926
3.52k
        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
3.52k
        else
929
3.52k
            ok = ok && EC_GROUP_check(EC_KEY_get0_group(eck), ctx);
930
3.52k
    }
931
932
18.1k
    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
933
11.0k
        if (checktype == OSSL_KEYMGMT_VALIDATE_QUICK_CHECK)
934
0
            ok = ok && ossl_ec_key_public_check_quick(eck, ctx);
935
11.0k
        else
936
11.0k
            ok = ok && ossl_ec_key_public_check(eck, ctx);
937
11.0k
    }
938
939
18.1k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
940
7.05k
        ok = ok && ossl_ec_key_private_check(eck);
941
942
18.1k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == OSSL_KEYMGMT_SELECT_KEYPAIR)
943
3.52k
        ok = ok && ossl_ec_key_pairwise_check(eck, ctx);
944
945
18.1k
    BN_CTX_free(ctx);
946
18.1k
    return ok;
947
18.1k
}
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
11.5k
{
970
11.5k
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx);
971
11.5k
    struct ec_gen_ctx *gctx = NULL;
972
973
11.5k
    if (!ossl_prov_is_running() || (selection & (EC_POSSIBLE_SELECTIONS)) == 0)
974
0
        return NULL;
975
976
11.5k
    if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {
977
11.5k
        gctx->libctx = libctx;
978
11.5k
        gctx->selection = selection;
979
11.5k
        gctx->ecdh_mode = 0;
980
11.5k
        OSSL_FIPS_IND_INIT(gctx)
981
11.5k
        if (!ec_gen_set_params(gctx, params)) {
982
0
            ec_gen_cleanup(gctx);
983
0
            gctx = NULL;
984
0
        }
985
11.5k
    }
986
11.5k
    return gctx;
987
11.5k
}
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
202
{
994
202
    struct ec_gen_ctx *gctx = ec_gen_init(provctx, selection, params);
995
996
202
    if (gctx != NULL) {
997
202
        if (gctx->group_name != NULL)
998
0
            return gctx;
999
202
        if ((gctx->group_name = OPENSSL_strdup("sm2")) != NULL)
1000
202
            return gctx;
1001
0
        ec_gen_cleanup(gctx);
1002
0
    }
1003
0
    return NULL;
1004
202
}
1005
#endif
1006
#endif
1007
1008
static int ec_gen_set_group(void *genctx, const EC_GROUP *src)
1009
1.77k
{
1010
1.77k
    struct ec_gen_ctx *gctx = genctx;
1011
1.77k
    EC_GROUP *group;
1012
1013
1.77k
    group = EC_GROUP_dup(src);
1014
1.77k
    if (group == NULL) {
1015
0
        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE);
1016
0
        return 0;
1017
0
    }
1018
1.77k
    EC_GROUP_free(gctx->gen_group);
1019
1.77k
    gctx->gen_group = group;
1020
1.77k
    return 1;
1021
1.77k
}
1022
1023
static int ec_gen_set_template(void *genctx, void *templ)
1024
1.77k
{
1025
1.77k
    struct ec_gen_ctx *gctx = genctx;
1026
1.77k
    EC_KEY *ec = templ;
1027
1.77k
    const EC_GROUP *ec_group;
1028
1029
1.77k
    if (!ossl_prov_is_running() || gctx == NULL || ec == NULL)
1030
0
        return 0;
1031
1.77k
    if ((ec_group = EC_KEY_get0_group(ec)) == NULL)
1032
0
        return 0;
1033
1.77k
    return ec_gen_set_group(gctx, ec_group);
1034
1.77k
}
1035
1036
#define COPY_INT_PARAM(params, key, val)           \
1037
15.9k
    p = OSSL_PARAM_locate_const(params, key);      \
1038
15.9k
    if (p != NULL && !OSSL_PARAM_get_int(p, &val)) \
1039
15.9k
        goto err;
1040
1041
#define COPY_UTF8_PARAM(params, key, val)           \
1042
79.9k
    p = OSSL_PARAM_locate_const(params, key);       \
1043
79.9k
    if (p != NULL) {                                \
1044
7.32k
        if (p->data_type != OSSL_PARAM_UTF8_STRING) \
1045
7.32k
            goto err;                               \
1046
7.32k
        OPENSSL_free(val);                          \
1047
7.32k
        val = OPENSSL_strdup(p->data);              \
1048
7.32k
        if (val == NULL)                            \
1049
7.32k
            goto err;                               \
1050
7.32k
    }
1051
1052
#define COPY_OCTET_PARAM(params, key, val, len)      \
1053
47.9k
    p = OSSL_PARAM_locate_const(params, key);        \
1054
47.9k
    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
79.9k
    p = OSSL_PARAM_locate_const(params, key);         \
1066
79.9k
    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
15.9k
{
1075
15.9k
    int ret = 0;
1076
15.9k
    struct ec_gen_ctx *gctx = genctx;
1077
15.9k
    const OSSL_PARAM *p;
1078
15.9k
    EC_GROUP *group = NULL;
1079
1080
15.9k
    if (!OSSL_FIPS_IND_SET_CTX_PARAM(gctx, OSSL_FIPS_IND_SETTABLE0, params,
1081
15.9k
            OSSL_PKEY_PARAM_FIPS_KEY_CHECK))
1082
0
        goto err;
1083
1084
15.9k
    COPY_INT_PARAM(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, gctx->ecdh_mode);
1085
1086
15.9k
    COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_GROUP_NAME, gctx->group_name);
1087
15.9k
    COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_FIELD_TYPE, gctx->field_type);
1088
15.9k
    COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_ENCODING, gctx->encoding);
1089
15.9k
    COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, gctx->pt_format);
1090
15.9k
    COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE, gctx->group_check);
1091
1092
15.9k
    COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_P, gctx->p);
1093
15.9k
    COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_A, gctx->a);
1094
15.9k
    COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_B, gctx->b);
1095
15.9k
    COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_ORDER, gctx->order);
1096
15.9k
    COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_COFACTOR, gctx->cofactor);
1097
1098
15.9k
    COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_EC_SEED, gctx->seed, gctx->seed_len);
1099
15.9k
    COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_EC_GENERATOR, gctx->gen,
1100
15.9k
        gctx->gen_len);
1101
1102
15.9k
    COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_DHKEM_IKM, gctx->dhkem_ikm,
1103
15.9k
        gctx->dhkem_ikmlen);
1104
1105
15.9k
    ret = 1;
1106
15.9k
err:
1107
15.9k
    EC_GROUP_free(group);
1108
15.9k
    return ret;
1109
15.9k
}
1110
1111
static int ec_gen_set_group_from_params(struct ec_gen_ctx *gctx)
1112
9.75k
{
1113
9.75k
    int ret = 0;
1114
9.75k
    OSSL_PARAM_BLD *bld;
1115
9.75k
    OSSL_PARAM *params = NULL;
1116
9.75k
    EC_GROUP *group = NULL;
1117
1118
9.75k
    bld = OSSL_PARAM_BLD_new();
1119
9.75k
    if (bld == NULL)
1120
0
        return 0;
1121
1122
9.75k
    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
9.75k
    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
9.75k
    if (gctx->group_name != NULL) {
1134
9.75k
        if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME,
1135
9.75k
                gctx->group_name, 0))
1136
0
            goto err;
1137
        /* Ignore any other parameters if there is a group name */
1138
9.75k
        goto build;
1139
9.75k
    } 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
9.75k
build:
1171
9.75k
    params = OSSL_PARAM_BLD_to_param(bld);
1172
9.75k
    if (params == NULL)
1173
0
        goto err;
1174
9.75k
    group = EC_GROUP_new_from_params(params, gctx->libctx, NULL);
1175
9.75k
    if (group == NULL)
1176
0
        goto err;
1177
1178
9.75k
    EC_GROUP_free(gctx->gen_group);
1179
9.75k
    gctx->gen_group = group;
1180
1181
9.75k
    ret = 1;
1182
9.75k
err:
1183
9.75k
    OSSL_PARAM_free(params);
1184
9.75k
    OSSL_PARAM_BLD_free(bld);
1185
9.75k
    return ret;
1186
9.75k
}
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
11.5k
{
1236
11.5k
    if (group == NULL) {
1237
0
        ERR_raise(ERR_LIB_PROV, PROV_R_NO_PARAMETERS_SET);
1238
0
        return 0;
1239
0
    }
1240
11.5k
    return EC_KEY_set_group(ec, group) > 0;
1241
11.5k
}
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
7.14k
{
1248
7.14k
    struct ec_gen_ctx *gctx = genctx;
1249
7.14k
    EC_KEY *ec = NULL;
1250
7.14k
    int ret = 0;
1251
1252
7.14k
    if (!ossl_prov_is_running()
1253
7.14k
        || gctx == NULL
1254
7.14k
        || (ec = EC_KEY_new_ex(gctx->libctx, NULL)) == NULL)
1255
0
        return NULL;
1256
1257
7.14k
    if (gctx->gen_group == NULL) {
1258
5.98k
        if (!ec_gen_set_group_from_params(gctx))
1259
0
            goto err;
1260
5.98k
    } else {
1261
1.15k
        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.15k
        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.15k
    }
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
7.14k
    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
7.14k
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
1292
4.72k
#ifndef FIPS_MODULE
1293
4.72k
        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
4.72k
        else
1296
4.72k
#endif
1297
4.72k
            ret = ret && EC_KEY_generate_key(ec);
1298
4.72k
    }
1299
1300
7.14k
    if (gctx->ecdh_mode != -1)
1301
7.14k
        ret = ret && ossl_ec_set_ecdh_cofactor_mode(ec, gctx->ecdh_mode);
1302
1303
7.14k
    if (gctx->group_check != NULL)
1304
0
        ret = ret && ossl_ec_set_check_group_type_from_name(ec, gctx->group_check);
1305
1306
7.14k
    if (ret)
1307
7.14k
        return ec;
1308
0
err:
1309
    /* Something went wrong, throw the key away */
1310
0
    EC_KEY_free(ec);
1311
0
    return NULL;
1312
7.14k
}
1313
1314
#ifndef FIPS_MODULE
1315
#ifndef OPENSSL_NO_SM2
1316
/*
1317
 * The callback arguments (osslcb & cbarg) are not used by EC_KEY generation
1318
 */
1319
static void *sm2_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
1320
440
{
1321
440
    struct ec_gen_ctx *gctx = genctx;
1322
440
    EC_KEY *ec = NULL;
1323
440
    int ret = 1;
1324
1325
440
    if (gctx == NULL
1326
440
        || (ec = EC_KEY_new_ex(gctx->libctx, NULL)) == NULL)
1327
0
        return NULL;
1328
1329
440
    if (gctx->gen_group == NULL) {
1330
288
        if (!ec_gen_set_group_from_params(gctx))
1331
0
            goto err;
1332
288
    } else {
1333
152
        if (gctx->encoding) {
1334
0
            int flags = ossl_ec_encoding_name2id(gctx->encoding);
1335
1336
0
            if (flags < 0)
1337
0
                goto err;
1338
0
            EC_GROUP_set_asn1_flag(gctx->gen_group, flags);
1339
0
        }
1340
152
        if (gctx->pt_format != NULL) {
1341
0
            int format = ossl_ec_pt_format_name2id(gctx->pt_format);
1342
1343
0
            if (format < 0)
1344
0
                goto err;
1345
0
            EC_GROUP_set_point_conversion_form(gctx->gen_group, format);
1346
0
        }
1347
152
    }
1348
1349
    /* We must always assign a group, no matter what */
1350
440
    ret = ec_gen_assign_group(ec, gctx->gen_group);
1351
1352
    /* Whether you want it or not, you get a keypair, not just one half */
1353
440
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
1354
155
        ret = ret && EC_KEY_generate_key(ec);
1355
1356
440
    if (ret)
1357
440
        return ec;
1358
0
err:
1359
    /* Something went wrong, throw the key away */
1360
0
    EC_KEY_free(ec);
1361
0
    return NULL;
1362
440
}
1363
#endif
1364
#endif
1365
1366
static void ec_gen_cleanup(void *genctx)
1367
11.5k
{
1368
11.5k
    struct ec_gen_ctx *gctx = genctx;
1369
1370
11.5k
    if (gctx == NULL)
1371
0
        return;
1372
1373
11.5k
    OPENSSL_clear_free(gctx->dhkem_ikm, gctx->dhkem_ikmlen);
1374
11.5k
    EC_GROUP_free(gctx->gen_group);
1375
11.5k
    BN_free(gctx->p);
1376
11.5k
    BN_free(gctx->a);
1377
11.5k
    BN_free(gctx->b);
1378
11.5k
    BN_free(gctx->order);
1379
11.5k
    BN_free(gctx->cofactor);
1380
11.5k
    OPENSSL_free(gctx->group_name);
1381
11.5k
    OPENSSL_free(gctx->field_type);
1382
11.5k
    OPENSSL_free(gctx->pt_format);
1383
11.5k
    OPENSSL_free(gctx->encoding);
1384
11.5k
    OPENSSL_free(gctx->seed);
1385
11.5k
    OPENSSL_free(gctx->gen);
1386
11.5k
    OPENSSL_free(gctx);
1387
11.5k
}
1388
1389
static void *common_load(const void *reference, size_t reference_sz,
1390
    int sm2_wanted)
1391
305k
{
1392
305k
    EC_KEY *ec = NULL;
1393
1394
305k
    if (ossl_prov_is_running() && reference_sz == sizeof(ec)) {
1395
        /* The contents of the reference is the address to our object */
1396
305k
        ec = *(EC_KEY **)reference;
1397
1398
305k
        if (!common_check_sm2(ec, sm2_wanted))
1399
12
            return NULL;
1400
1401
        /* We grabbed, so we detach it */
1402
305k
        *(EC_KEY **)reference = NULL;
1403
305k
        return ec;
1404
305k
    }
1405
0
    return NULL;
1406
305k
}
1407
1408
static void *ec_load(const void *reference, size_t reference_sz)
1409
301k
{
1410
301k
    return common_load(reference, reference_sz, 0);
1411
301k
}
1412
1413
#ifndef FIPS_MODULE
1414
#ifndef OPENSSL_NO_SM2
1415
static void *sm2_load(const void *reference, size_t reference_sz)
1416
3.55k
{
1417
3.55k
    return common_load(reference, reference_sz, 1);
1418
3.55k
}
1419
#endif
1420
#endif
1421
1422
static void *ec_dup(const void *keydata_from, int selection)
1423
7.17k
{
1424
7.17k
    if (ossl_prov_is_running())
1425
7.17k
        return ossl_ec_key_dup(keydata_from, selection);
1426
0
    return NULL;
1427
7.17k
}
1428
1429
const OSSL_DISPATCH ossl_ec_keymgmt_functions[] = {
1430
    { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))ec_newdata },
1431
    { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))ec_gen_init },
1432
    { OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE,
1433
        (void (*)(void))ec_gen_set_template },
1434
    { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))ec_gen_set_params },
1435
    { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,
1436
        (void (*)(void))ec_gen_settable_params },
1437
    { OSSL_FUNC_KEYMGMT_GEN_GET_PARAMS, (void (*)(void))ec_gen_get_params },
1438
    { OSSL_FUNC_KEYMGMT_GEN_GETTABLE_PARAMS,
1439
        (void (*)(void))ec_gen_gettable_params },
1440
    { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))ec_gen },
1441
    { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ec_gen_cleanup },
1442
    { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))ec_load },
1443
    { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ec_freedata },
1444
    { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))ec_get_params },
1445
    { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))ec_gettable_params },
1446
    { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*)(void))ec_set_params },
1447
    { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*)(void))ec_settable_params },
1448
    { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ec_has },
1449
    { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ec_match },
1450
    { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))ec_validate },
1451
    { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ec_import },
1452
    { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ec_import_types },
1453
    { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ec_export },
1454
    { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ec_export_types },
1455
    { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME,
1456
        (void (*)(void))ec_query_operation_name },
1457
    { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ec_dup },
1458
    OSSL_DISPATCH_END
1459
};
1460
1461
#ifndef FIPS_MODULE
1462
#ifndef OPENSSL_NO_SM2
1463
const OSSL_DISPATCH ossl_sm2_keymgmt_functions[] = {
1464
    { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))sm2_newdata },
1465
    { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))sm2_gen_init },
1466
    { OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE,
1467
        (void (*)(void))ec_gen_set_template },
1468
    { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))ec_gen_set_params },
1469
    { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,
1470
        (void (*)(void))ec_gen_settable_params },
1471
    { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))sm2_gen },
1472
    { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ec_gen_cleanup },
1473
    { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))sm2_load },
1474
    { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ec_freedata },
1475
    { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))sm2_get_params },
1476
    { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))sm2_gettable_params },
1477
    { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*)(void))ec_set_params },
1478
    { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*)(void))sm2_settable_params },
1479
    { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ec_has },
1480
    { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ec_match },
1481
    { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))sm2_validate },
1482
    { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))sm2_import },
1483
    { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ec_import_types },
1484
    { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ec_export },
1485
    { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ec_export_types },
1486
    { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME,
1487
        (void (*)(void))sm2_query_operation_name },
1488
    { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ec_dup },
1489
    OSSL_DISPATCH_END
1490
};
1491
#endif
1492
#endif