Coverage Report

Created: 2026-04-01 06:39

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
163
#define EC_DEFAULT_MD "SHA256"
76
#define EC_POSSIBLE_SELECTIONS \
77
213k
    (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.6k
{
82
75.6k
    switch (operation_id) {
83
5.00k
    case OSSL_OP_KEYEXCH:
84
5.00k
        return "ECDH";
85
70.6k
    case OSSL_OP_SIGNATURE:
86
70.6k
        return "ECDSA";
87
75.6k
    }
88
0
    return NULL;
89
75.6k
}
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
560k
{
115
560k
    BIGNUM *x = NULL, *y = NULL;
116
560k
    const BIGNUM *priv_key = NULL;
117
560k
    const EC_POINT *pub_point = NULL;
118
560k
    const EC_GROUP *ecg = NULL;
119
560k
    size_t pub_key_len = 0;
120
560k
    int ret = 0;
121
560k
    BN_CTX *bnctx = NULL;
122
123
560k
    if (eckey == NULL
124
560k
        || (ecg = EC_KEY_get0_group(eckey)) == NULL)
125
0
        return 0;
126
127
560k
    priv_key = EC_KEY_get0_private_key(eckey);
128
560k
    pub_point = EC_KEY_get0_public_key(eckey);
129
130
560k
    if (pub_point != NULL) {
131
550k
        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
550k
        bnctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(eckey));
137
550k
        if (bnctx == NULL)
138
0
            goto err;
139
140
        /* If we are doing a get then check first before decoding the point */
141
550k
        if (tmpl == NULL) {
142
499k
            p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PUB_KEY);
143
499k
            px = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_PUB_X);
144
499k
            py = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_PUB_Y);
145
499k
        }
146
147
550k
        if (p != NULL || tmpl != NULL) {
148
            /* convert pub_point to a octet string according to the SECG standard */
149
51.1k
            point_conversion_form_t format = EC_KEY_get_conv_form(eckey);
150
151
51.1k
            if ((pub_key_len = EC_POINT_point2buf(ecg, pub_point,
152
51.1k
                     format,
153
51.1k
                     pub_key, bnctx))
154
51.1k
                    == 0
155
51.1k
                || !ossl_param_build_set_octet_string(tmpl, p,
156
51.1k
                    OSSL_PKEY_PARAM_PUB_KEY,
157
51.1k
                    *pub_key, pub_key_len))
158
0
                goto err;
159
51.1k
        }
160
550k
        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
550k
    }
184
185
560k
    if (priv_key != NULL && include_private) {
186
145k
        size_t sz;
187
145k
        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
145k
        ecbits = EC_GROUP_order_bits(ecg);
223
145k
        if (ecbits <= 0)
224
0
            goto err;
225
145k
        sz = (ecbits + 7) / 8;
226
227
145k
        if (!ossl_param_build_set_bn_pad(tmpl, params,
228
145k
                OSSL_PKEY_PARAM_PRIV_KEY,
229
145k
                priv_key, sz))
230
0
            goto err;
231
145k
    }
232
560k
    ret = 1;
233
560k
err:
234
560k
    BN_CTX_free(bnctx);
235
560k
    return ret;
236
560k
}
237
238
static ossl_inline int otherparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl,
239
    OSSL_PARAM params[])
240
560k
{
241
560k
    int ecdh_cofactor_mode = 0, group_check = 0;
242
560k
    const char *name = NULL;
243
560k
    point_conversion_form_t format;
244
245
560k
    if (ec == NULL)
246
0
        return 0;
247
248
560k
    format = EC_KEY_get_conv_form(ec);
249
560k
    name = ossl_ec_pt_format_id2name((int)format);
250
560k
    if (name != NULL
251
513k
        && !ossl_param_build_set_utf8_string(tmpl, params,
252
513k
            OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT,
253
513k
            name))
254
0
        return 0;
255
256
560k
    group_check = EC_KEY_get_flags(ec) & EC_FLAG_CHECK_NAMED_GROUP_MASK;
257
560k
    name = ossl_ec_check_group_type_id2name(group_check);
258
560k
    if (name != NULL
259
560k
        && !ossl_param_build_set_utf8_string(tmpl, params,
260
560k
            OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE,
261
560k
            name))
262
0
        return 0;
263
264
560k
    if ((EC_KEY_get_enc_flags(ec) & EC_PKEY_NO_PUBKEY) != 0
265
9.62k
        && !ossl_param_build_set_int(tmpl, params,
266
9.62k
            OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC, 0))
267
0
        return 0;
268
269
560k
    ecdh_cofactor_mode = (EC_KEY_get_flags(ec) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0;
270
560k
    return ossl_param_build_set_int(tmpl, params,
271
560k
        OSSL_PKEY_PARAM_USE_COFACTOR_ECDH,
272
560k
        ecdh_cofactor_mode);
273
560k
}
274
275
static void *ec_newdata(void *provctx)
276
41.5k
{
277
41.5k
    if (!ossl_prov_is_running())
278
0
        return NULL;
279
41.5k
    return EC_KEY_new_ex(PROV_LIBCTX_OF(provctx), NULL);
280
41.5k
}
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
483k
{
295
483k
    EC_KEY_free(keydata);
296
483k
}
297
298
static int ec_has(const void *keydata, int selection)
299
178k
{
300
178k
    const EC_KEY *ec = keydata;
301
178k
    int ok = 1;
302
303
178k
    if (!ossl_prov_is_running() || ec == NULL)
304
4.55k
        return 0;
305
174k
    if ((selection & EC_POSSIBLE_SELECTIONS) == 0)
306
0
        return 1; /* the selection is not missing */
307
308
174k
    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
309
60.4k
        ok = ok && (EC_KEY_get0_public_key(ec) != NULL);
310
174k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
311
55.7k
        ok = ok && (EC_KEY_get0_private_key(ec) != NULL);
312
174k
    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
174k
    return ok;
320
174k
}
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.1k
        int key_checked = 0;
343
344
56.1k
        if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
345
56.1k
            const EC_POINT *pa = EC_KEY_get0_public_key(ec1);
346
56.1k
            const EC_POINT *pb = EC_KEY_get0_public_key(ec2);
347
348
56.1k
            if (pa != NULL && pb != NULL) {
349
55.5k
                ok = ok && EC_POINT_cmp(group_b, pa, pb, ctx) == 0;
350
55.5k
                key_checked = 1;
351
55.5k
            }
352
56.1k
        }
353
56.1k
        if (!key_checked
354
584
            && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
355
584
            const BIGNUM *pa = EC_KEY_get0_private_key(ec1);
356
584
            const BIGNUM *pb = EC_KEY_get0_private_key(ec2);
357
358
584
            if (pa != NULL && pb != NULL) {
359
0
                ok = ok && BN_cmp(pa, pb) == 0;
360
0
                key_checked = 1;
361
0
            }
362
584
        }
363
56.1k
        ok = ok && key_checked;
364
56.1k
    }
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
449k
{
371
449k
    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
449k
    if ((ecg = EC_KEY_get0_group(ec)) == NULL
378
449k
        || (sm2_wanted ^ (EC_GROUP_get_curve_name(ecg) == NID_sm2)))
379
10
        return 0;
380
449k
    return 1;
381
449k
}
382
383
static int common_import(void *keydata, int selection, const OSSL_PARAM params[],
384
    int sm2_wanted)
385
41.5k
{
386
41.5k
    EC_KEY *ec = keydata;
387
41.5k
    int ok = 1;
388
389
41.5k
    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
41.5k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0)
406
0
        return 0;
407
408
41.5k
    ok = ok && ossl_ec_group_fromdata(ec, params);
409
410
41.5k
    if (!common_check_sm2(ec, sm2_wanted))
411
0
        return 0;
412
413
41.5k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
414
41.5k
        int include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
415
416
41.5k
        ok = ok && ossl_ec_key_fromdata(ec, params, include_private);
417
41.5k
    }
418
41.5k
    if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
419
41.5k
        ok = ok && ossl_ec_key_otherparams_fromdata(ec, params);
420
421
41.5k
    return ok;
422
41.5k
}
423
424
static int ec_import(void *keydata, int selection, const OSSL_PARAM params[])
425
41.5k
{
426
41.5k
    return common_import(keydata, selection, params, 0);
427
41.5k
}
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.1k
{
441
51.1k
    EC_KEY *ec = keydata;
442
51.1k
    OSSL_PARAM_BLD *tmpl = NULL;
443
51.1k
    OSSL_PARAM *params = NULL;
444
51.1k
    unsigned char *pub_key = NULL, *genbuf = NULL;
445
51.1k
    BN_CTX *bnctx = NULL;
446
51.1k
    int ok = 1;
447
448
51.1k
    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.1k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0)
465
0
        return 0;
466
51.1k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0
467
51.1k
        && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) == 0)
468
0
        return 0;
469
470
51.1k
    tmpl = OSSL_PARAM_BLD_new();
471
51.1k
    if (tmpl == NULL)
472
0
        return 0;
473
474
51.1k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
475
51.1k
        bnctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(ec));
476
51.1k
        if (bnctx == NULL) {
477
0
            ok = 0;
478
0
            goto end;
479
0
        }
480
51.1k
        BN_CTX_start(bnctx);
481
51.1k
        ok = ok && ossl_ec_group_todata(EC_KEY_get0_group(ec), tmpl, NULL, ossl_ec_key_get_libctx(ec), ossl_ec_key_get0_propq(ec), bnctx, &genbuf);
482
51.1k
    }
483
484
51.1k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
485
51.1k
        int include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
486
487
51.1k
        ok = ok && key_to_params(ec, tmpl, NULL, include_private, &pub_key);
488
51.1k
    }
489
51.1k
    if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
490
51.1k
        ok = ok && otherparams_to_params(ec, tmpl, NULL);
491
492
51.1k
    if (!ok || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) {
493
0
        ok = 0;
494
0
        goto end;
495
0
    }
496
497
51.1k
    ok = param_cb(params, cbarg);
498
51.1k
    OSSL_PARAM_free(params);
499
51.1k
end:
500
51.1k
    OSSL_PARAM_BLD_free(tmpl);
501
51.1k
    OPENSSL_free(pub_key);
502
51.1k
    OPENSSL_free(genbuf);
503
51.1k
    BN_CTX_end(bnctx);
504
51.1k
    BN_CTX_free(bnctx);
505
51.1k
    return ok;
506
51.1k
}
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
509k
{
568
#ifdef OPENSSL_NO_EC2M
569
    return 1;
570
#else
571
509k
    int ret = 0, m;
572
509k
    unsigned int k1 = 0, k2 = 0, k3 = 0;
573
509k
    int basis_nid;
574
509k
    const char *basis_name = NULL;
575
509k
    int fid = EC_GROUP_get_field_type(group);
576
577
509k
    if (fid != NID_X9_62_characteristic_two_field)
578
340k
        return 1;
579
580
168k
    basis_nid = EC_GROUP_get_basis_type(group);
581
168k
    if (basis_nid == NID_X9_62_tpBasis)
582
44.5k
        basis_name = SN_X9_62_tpBasis;
583
124k
    else if (basis_nid == NID_X9_62_ppBasis)
584
124k
        basis_name = SN_X9_62_ppBasis;
585
0
    else
586
0
        goto err;
587
588
168k
    m = EC_GROUP_get_degree(group);
589
168k
    if (!ossl_param_build_set_int(NULL, params, OSSL_PKEY_PARAM_EC_CHAR2_M, m)
590
168k
        || !ossl_param_build_set_utf8_string(NULL, params,
591
168k
            OSSL_PKEY_PARAM_EC_CHAR2_TYPE,
592
168k
            basis_name))
593
0
        goto err;
594
595
168k
    if (basis_nid == NID_X9_62_tpBasis) {
596
44.5k
        if (!EC_GROUP_get_trinomial_basis(group, &k1)
597
44.5k
            || !ossl_param_build_set_int(NULL, params,
598
44.5k
                OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS,
599
44.5k
                (int)k1))
600
0
            goto err;
601
124k
    } else {
602
124k
        if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3)
603
124k
            || !ossl_param_build_set_int(NULL, params,
604
124k
                OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, (int)k1)
605
124k
            || !ossl_param_build_set_int(NULL, params,
606
124k
                OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, (int)k2)
607
124k
            || !ossl_param_build_set_int(NULL, params,
608
124k
                OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, (int)k3))
609
0
            goto err;
610
124k
    }
611
168k
    ret = 1;
612
168k
err:
613
168k
    return ret;
614
168k
#endif /* OPENSSL_NO_EC2M */
615
168k
}
616
617
static int common_get_params(void *key, OSSL_PARAM params[], int sm2)
618
323k
{
619
323k
    int ret = 0;
620
323k
    EC_KEY *eck = key;
621
323k
    const EC_GROUP *ecg = NULL;
622
323k
    OSSL_PARAM *p;
623
323k
    unsigned char *pub_key = NULL, *genbuf = NULL;
624
323k
    OSSL_LIB_CTX *libctx;
625
323k
    const char *propq;
626
323k
    BN_CTX *bnctx = NULL;
627
628
323k
    ecg = EC_KEY_get0_group(eck);
629
323k
    if (ecg == NULL) {
630
0
        ERR_raise(ERR_LIB_PROV, PROV_R_NO_PARAMETERS_SET);
631
0
        return 0;
632
0
    }
633
634
323k
    libctx = ossl_ec_key_get_libctx(eck);
635
323k
    propq = ossl_ec_key_get0_propq(eck);
636
637
323k
    bnctx = BN_CTX_new_ex(libctx);
638
323k
    if (bnctx == NULL)
639
0
        return 0;
640
323k
    BN_CTX_start(bnctx);
641
642
323k
    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
643
275k
        && !OSSL_PARAM_set_int(p, ECDSA_size(eck)))
644
0
        goto err;
645
323k
    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
646
275k
        && !OSSL_PARAM_set_int(p, EC_GROUP_order_bits(ecg)))
647
0
        goto err;
648
323k
    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL) {
649
275k
        int ecbits, sec_bits;
650
651
275k
        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
275k
        if (ecbits >= 512)
670
12.2k
            sec_bits = 256;
671
262k
        else if (ecbits >= 384)
672
14.8k
            sec_bits = 192;
673
248k
        else if (ecbits >= 256)
674
90.4k
            sec_bits = 128;
675
157k
        else if (ecbits >= 224)
676
48.3k
            sec_bits = 112;
677
109k
        else if (ecbits >= 160)
678
47.5k
            sec_bits = 80;
679
61.9k
        else
680
61.9k
            sec_bits = ecbits / 2;
681
682
275k
        if (!OSSL_PARAM_set_int(p, sec_bits))
683
0
            goto err;
684
275k
    }
685
686
323k
    if ((p = OSSL_PARAM_locate(params,
687
323k
             OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS))
688
323k
        != NULL) {
689
3
        int explicitparams = EC_KEY_decoded_from_explicit_params(eck);
690
691
3
        if (explicitparams < 0
692
3
            || !OSSL_PARAM_set_int(p, explicitparams))
693
0
            goto err;
694
3
    }
695
696
323k
    if (!sm2) {
697
321k
        if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DEFAULT_DIGEST)) != NULL
698
163
            && !OSSL_PARAM_set_utf8_string(p, EC_DEFAULT_MD))
699
0
            goto err;
700
321k
    } else {
701
2.37k
        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.37k
    }
705
706
    /* SM2 doesn't support this PARAM */
707
323k
    if (!sm2) {
708
321k
        p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH);
709
321k
        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
321k
    }
718
323k
    if ((p = OSSL_PARAM_locate(params,
719
323k
             OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY))
720
323k
        != 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
323k
    ret = ec_get_ecm_params(ecg, params)
735
323k
        && ossl_ec_group_todata(ecg, NULL, params, libctx, propq, bnctx,
736
323k
            &genbuf)
737
323k
        && key_to_params(eck, NULL, params, 1, &pub_key)
738
323k
        && otherparams_to_params(eck, NULL, params);
739
323k
err:
740
323k
    OPENSSL_free(genbuf);
741
323k
    OPENSSL_free(pub_key);
742
323k
    BN_CTX_end(bnctx);
743
323k
    BN_CTX_free(bnctx);
744
323k
    return ret;
745
323k
}
746
747
static int ec_get_params(void *key, OSSL_PARAM params[])
748
505k
{
749
505k
    return common_get_params(key, params, 0);
750
505k
}
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.21k
{
804
4.21k
    EC_KEY *eck = key;
805
4.21k
    const OSSL_PARAM *p;
806
807
4.21k
    if (key == NULL)
808
0
        return 0;
809
4.21k
    if (params == NULL)
810
0
        return 1;
811
812
4.21k
    if (!ossl_ec_group_set_params((EC_GROUP *)EC_KEY_get0_group(key), params))
813
0
        return 0;
814
815
4.21k
    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY);
816
4.21k
    if (p != NULL) {
817
4.21k
        BN_CTX *ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(key));
818
4.21k
        int ret = 1;
819
820
4.21k
        if (ctx == NULL
821
4.21k
            || p->data_type != OSSL_PARAM_OCTET_STRING
822
4.21k
            || !EC_KEY_oct2key(key, p->data, p->data_size, ctx))
823
1.18k
            ret = 0;
824
4.21k
        BN_CTX_free(ctx);
825
4.21k
        if (!ret)
826
1.18k
            return 0;
827
4.21k
    }
828
829
3.03k
    return ossl_ec_key_otherparams_fromdata(eck, params);
830
4.21k
}
831
832
#ifndef FIPS_MODULE
833
#ifndef OPENSSL_NO_SM2
834
static int sm2_get_params(void *key, OSSL_PARAM params[])
835
4.12k
{
836
4.12k
    return common_get_params(key, params, 1);
837
4.12k
}
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
277
{
871
277
    const EC_KEY *eck = keydata;
872
277
    int ok = 1;
873
277
    BN_CTX *ctx = NULL;
874
875
277
    if (!ossl_prov_is_running())
876
0
        return 0;
877
878
277
    if ((selection & EC_POSSIBLE_SELECTIONS) == 0)
879
0
        return 1; /* nothing to validate */
880
881
277
    ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(eck));
882
277
    if (ctx == NULL)
883
0
        return 0;
884
885
277
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
886
45
        ok = ok && EC_GROUP_check(EC_KEY_get0_group(eck), ctx);
887
888
277
    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
889
187
        if (checktype == OSSL_KEYMGMT_VALIDATE_QUICK_CHECK)
890
0
            ok = ok && ossl_ec_key_public_check_quick(eck, ctx);
891
187
        else
892
187
            ok = ok && ossl_ec_key_public_check(eck, ctx);
893
187
    }
894
895
277
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
896
90
        ok = ok && ossl_sm2_key_private_check(eck);
897
898
277
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == OSSL_KEYMGMT_SELECT_KEYPAIR)
899
45
        ok = ok && ossl_ec_key_pairwise_check(eck, ctx);
900
901
277
    BN_CTX_free(ctx);
902
277
    return ok;
903
277
}
904
#endif
905
#endif
906
907
static int ec_validate(const void *keydata, int selection, int checktype)
908
24.5k
{
909
24.5k
    const EC_KEY *eck = keydata;
910
24.5k
    int ok = 1;
911
24.5k
    BN_CTX *ctx = NULL;
912
913
24.5k
    if (!ossl_prov_is_running())
914
0
        return 0;
915
916
24.5k
    if ((selection & EC_POSSIBLE_SELECTIONS) == 0)
917
0
        return 1; /* nothing to validate */
918
919
24.5k
    ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(eck));
920
24.5k
    if (ctx == NULL)
921
0
        return 0;
922
923
24.5k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
924
4.87k
        int flags = EC_KEY_get_flags(eck);
925
926
4.87k
        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.87k
        else
929
4.87k
            ok = ok && EC_GROUP_check(EC_KEY_get0_group(eck), ctx);
930
4.87k
    }
931
932
24.5k
    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
933
14.7k
        if (checktype == OSSL_KEYMGMT_VALIDATE_QUICK_CHECK)
934
0
            ok = ok && ossl_ec_key_public_check_quick(eck, ctx);
935
14.7k
        else
936
14.7k
            ok = ok && ossl_ec_key_public_check(eck, ctx);
937
14.7k
    }
938
939
24.5k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
940
9.75k
        ok = ok && ossl_ec_key_private_check(eck);
941
942
24.5k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == OSSL_KEYMGMT_SELECT_KEYPAIR)
943
4.87k
        ok = ok && ossl_ec_key_pairwise_check(eck, ctx);
944
945
24.5k
    BN_CTX_free(ctx);
946
24.5k
    return ok;
947
24.5k
}
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
14.8k
{
970
14.8k
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx);
971
14.8k
    struct ec_gen_ctx *gctx = NULL;
972
973
14.8k
    if (!ossl_prov_is_running() || (selection & (EC_POSSIBLE_SELECTIONS)) == 0)
974
0
        return NULL;
975
976
14.8k
    if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {
977
14.8k
        gctx->libctx = libctx;
978
14.8k
        gctx->selection = selection;
979
14.8k
        gctx->ecdh_mode = 0;
980
14.8k
        OSSL_FIPS_IND_INIT(gctx)
981
14.8k
        if (!ec_gen_set_params(gctx, params)) {
982
0
            ec_gen_cleanup(gctx);
983
0
            gctx = NULL;
984
0
        }
985
14.8k
    }
986
14.8k
    return gctx;
987
14.8k
}
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
253
{
994
253
    struct ec_gen_ctx *gctx = ec_gen_init(provctx, selection, params);
995
996
253
    if (gctx != NULL) {
997
253
        if (gctx->group_name != NULL)
998
0
            return gctx;
999
253
        if ((gctx->group_name = OPENSSL_strdup("sm2")) != NULL)
1000
253
            return gctx;
1001
0
        ec_gen_cleanup(gctx);
1002
0
    }
1003
0
    return NULL;
1004
253
}
1005
#endif
1006
#endif
1007
1008
static int ec_gen_set_group(void *genctx, const EC_GROUP *src)
1009
2.02k
{
1010
2.02k
    struct ec_gen_ctx *gctx = genctx;
1011
2.02k
    EC_GROUP *group;
1012
1013
2.02k
    group = EC_GROUP_dup(src);
1014
2.02k
    if (group == NULL) {
1015
0
        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE);
1016
0
        return 0;
1017
0
    }
1018
2.02k
    EC_GROUP_free(gctx->gen_group);
1019
2.02k
    gctx->gen_group = group;
1020
2.02k
    return 1;
1021
2.02k
}
1022
1023
static int ec_gen_set_template(void *genctx, void *templ)
1024
2.02k
{
1025
2.02k
    struct ec_gen_ctx *gctx = genctx;
1026
2.02k
    EC_KEY *ec = templ;
1027
2.02k
    const EC_GROUP *ec_group;
1028
1029
2.02k
    if (!ossl_prov_is_running() || gctx == NULL || ec == NULL)
1030
0
        return 0;
1031
2.02k
    if ((ec_group = EC_KEY_get0_group(ec)) == NULL)
1032
0
        return 0;
1033
2.02k
    return ec_gen_set_group(gctx, ec_group);
1034
2.02k
}
1035
1036
#define COPY_INT_PARAM(params, key, val)           \
1037
20.7k
    p = OSSL_PARAM_locate_const(params, key);      \
1038
20.7k
    if (p != NULL && !OSSL_PARAM_get_int(p, &val)) \
1039
20.7k
        goto err;
1040
1041
#define COPY_UTF8_PARAM(params, key, val)           \
1042
103k
    p = OSSL_PARAM_locate_const(params, key);       \
1043
103k
    if (p != NULL) {                                \
1044
9.56k
        if (p->data_type != OSSL_PARAM_UTF8_STRING) \
1045
9.56k
            goto err;                               \
1046
9.56k
        OPENSSL_free(val);                          \
1047
9.56k
        val = OPENSSL_strdup(p->data);              \
1048
9.56k
        if (val == NULL)                            \
1049
9.56k
            goto err;                               \
1050
9.56k
    }
1051
1052
#define COPY_OCTET_PARAM(params, key, val, len)      \
1053
62.3k
    p = OSSL_PARAM_locate_const(params, key);        \
1054
62.3k
    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
103k
    p = OSSL_PARAM_locate_const(params, key);         \
1066
103k
    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
20.7k
{
1075
20.7k
    int ret = 0;
1076
20.7k
    struct ec_gen_ctx *gctx = genctx;
1077
20.7k
    const OSSL_PARAM *p;
1078
20.7k
    EC_GROUP *group = NULL;
1079
1080
20.7k
    if (!OSSL_FIPS_IND_SET_CTX_PARAM(gctx, OSSL_FIPS_IND_SETTABLE0, params,
1081
20.7k
            OSSL_PKEY_PARAM_FIPS_KEY_CHECK))
1082
0
        goto err;
1083
1084
20.7k
    COPY_INT_PARAM(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, gctx->ecdh_mode);
1085
1086
20.7k
    COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_GROUP_NAME, gctx->group_name);
1087
20.7k
    COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_FIELD_TYPE, gctx->field_type);
1088
20.7k
    COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_ENCODING, gctx->encoding);
1089
20.7k
    COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, gctx->pt_format);
1090
20.7k
    COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE, gctx->group_check);
1091
1092
20.7k
    COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_P, gctx->p);
1093
20.7k
    COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_A, gctx->a);
1094
20.7k
    COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_B, gctx->b);
1095
20.7k
    COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_ORDER, gctx->order);
1096
20.7k
    COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_COFACTOR, gctx->cofactor);
1097
1098
20.7k
    COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_EC_SEED, gctx->seed, gctx->seed_len);
1099
20.7k
    COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_EC_GENERATOR, gctx->gen,
1100
20.7k
        gctx->gen_len);
1101
1102
20.7k
    COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_DHKEM_IKM, gctx->dhkem_ikm,
1103
20.7k
        gctx->dhkem_ikmlen);
1104
1105
20.7k
    ret = 1;
1106
20.7k
err:
1107
20.7k
    EC_GROUP_free(group);
1108
20.7k
    return ret;
1109
20.7k
}
1110
1111
static int ec_gen_set_group_from_params(struct ec_gen_ctx *gctx)
1112
12.7k
{
1113
12.7k
    int ret = 0;
1114
12.7k
    OSSL_PARAM_BLD *bld;
1115
12.7k
    OSSL_PARAM *params = NULL;
1116
12.7k
    EC_GROUP *group = NULL;
1117
1118
12.7k
    bld = OSSL_PARAM_BLD_new();
1119
12.7k
    if (bld == NULL)
1120
0
        return 0;
1121
1122
12.7k
    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
12.7k
    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
12.7k
    if (gctx->group_name != NULL) {
1134
12.7k
        if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME,
1135
12.7k
                gctx->group_name, 0))
1136
0
            goto err;
1137
        /* Ignore any other parameters if there is a group name */
1138
12.7k
        goto build;
1139
12.7k
    } 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
12.7k
build:
1171
12.7k
    params = OSSL_PARAM_BLD_to_param(bld);
1172
12.7k
    if (params == NULL)
1173
0
        goto err;
1174
12.7k
    group = EC_GROUP_new_from_params(params, gctx->libctx, NULL);
1175
12.7k
    if (group == NULL)
1176
0
        goto err;
1177
1178
12.7k
    EC_GROUP_free(gctx->gen_group);
1179
12.7k
    gctx->gen_group = group;
1180
1181
12.7k
    ret = 1;
1182
12.7k
err:
1183
12.7k
    OSSL_PARAM_free(params);
1184
12.7k
    OSSL_PARAM_BLD_free(bld);
1185
12.7k
    return ret;
1186
12.7k
}
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
14.8k
{
1236
14.8k
    if (group == NULL) {
1237
0
        ERR_raise(ERR_LIB_PROV, PROV_R_NO_PARAMETERS_SET);
1238
0
        return 0;
1239
0
    }
1240
14.8k
    return EC_KEY_set_group(ec, group) > 0;
1241
14.8k
}
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
13.2k
{
1248
13.2k
    struct ec_gen_ctx *gctx = genctx;
1249
13.2k
    EC_KEY *ec = NULL;
1250
13.2k
    int ret = 0;
1251
1252
13.2k
    if (!ossl_prov_is_running()
1253
13.2k
        || gctx == NULL
1254
13.2k
        || (ec = EC_KEY_new_ex(gctx->libctx, NULL)) == NULL)
1255
0
        return NULL;
1256
1257
13.2k
    if (gctx->gen_group == NULL) {
1258
11.4k
        if (!ec_gen_set_group_from_params(gctx))
1259
0
            goto err;
1260
11.4k
    } else {
1261
1.79k
        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.79k
        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.79k
    }
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
13.2k
    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
13.2k
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
1292
9.16k
#ifndef FIPS_MODULE
1293
9.16k
        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
9.16k
        else
1296
9.16k
#endif
1297
9.16k
            ret = ret && EC_KEY_generate_key(ec);
1298
9.16k
    }
1299
1300
13.2k
    if (gctx->ecdh_mode != -1)
1301
13.2k
        ret = ret && ossl_ec_set_ecdh_cofactor_mode(ec, gctx->ecdh_mode);
1302
1303
13.2k
    if (gctx->group_check != NULL)
1304
0
        ret = ret && ossl_ec_set_check_group_type_from_name(ec, gctx->group_check);
1305
13.2k
    if (ret)
1306
13.2k
        return ec;
1307
0
err:
1308
    /* Something went wrong, throw the key away */
1309
0
    EC_KEY_free(ec);
1310
0
    return NULL;
1311
13.2k
}
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
253
{
1320
253
    struct ec_gen_ctx *gctx = genctx;
1321
253
    EC_KEY *ec = NULL;
1322
253
    int ret = 1;
1323
1324
253
    if (gctx == NULL
1325
253
        || (ec = EC_KEY_new_ex(gctx->libctx, NULL)) == NULL)
1326
0
        return NULL;
1327
1328
253
    if (gctx->gen_group == NULL) {
1329
156
        if (!ec_gen_set_group_from_params(gctx))
1330
0
            goto err;
1331
156
    } else {
1332
97
        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
97
        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
97
    }
1347
1348
    /* We must always assign a group, no matter what */
1349
253
    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
253
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
1353
98
        ret = ret && EC_KEY_generate_key(ec);
1354
1355
253
    if (ret)
1356
253
        return ec;
1357
0
err:
1358
    /* Something went wrong, throw the key away */
1359
0
    EC_KEY_free(ec);
1360
0
    return NULL;
1361
253
}
1362
#endif
1363
#endif
1364
1365
static void ec_gen_cleanup(void *genctx)
1366
14.8k
{
1367
14.8k
    struct ec_gen_ctx *gctx = genctx;
1368
1369
14.8k
    if (gctx == NULL)
1370
0
        return;
1371
1372
14.8k
    OPENSSL_clear_free(gctx->dhkem_ikm, gctx->dhkem_ikmlen);
1373
14.8k
    EC_GROUP_free(gctx->gen_group);
1374
14.8k
    BN_free(gctx->p);
1375
14.8k
    BN_free(gctx->a);
1376
14.8k
    BN_free(gctx->b);
1377
14.8k
    BN_free(gctx->order);
1378
14.8k
    BN_free(gctx->cofactor);
1379
14.8k
    OPENSSL_free(gctx->group_name);
1380
14.8k
    OPENSSL_free(gctx->field_type);
1381
14.8k
    OPENSSL_free(gctx->pt_format);
1382
14.8k
    OPENSSL_free(gctx->encoding);
1383
14.8k
    OPENSSL_free(gctx->seed);
1384
14.8k
    OPENSSL_free(gctx->gen);
1385
14.8k
    OPENSSL_free(gctx);
1386
14.8k
}
1387
1388
static void *common_load(const void *reference, size_t reference_sz,
1389
    int sm2_wanted)
1390
407k
{
1391
407k
    EC_KEY *ec = NULL;
1392
1393
407k
    if (ossl_prov_is_running() && reference_sz == sizeof(ec)) {
1394
        /* The contents of the reference is the address to our object */
1395
407k
        ec = *(EC_KEY **)reference;
1396
1397
407k
        if (!common_check_sm2(ec, sm2_wanted))
1398
10
            return NULL;
1399
1400
        /* We grabbed, so we detach it */
1401
407k
        *(EC_KEY **)reference = NULL;
1402
407k
        return ec;
1403
407k
    }
1404
0
    return NULL;
1405
407k
}
1406
1407
static void *ec_load(const void *reference, size_t reference_sz)
1408
403k
{
1409
403k
    return common_load(reference, reference_sz, 0);
1410
403k
}
1411
1412
#ifndef FIPS_MODULE
1413
#ifndef OPENSSL_NO_SM2
1414
static void *sm2_load(const void *reference, size_t reference_sz)
1415
3.63k
{
1416
3.63k
    return common_load(reference, reference_sz, 1);
1417
3.63k
}
1418
#endif
1419
#endif
1420
1421
static void *ec_dup(const void *keydata_from, int selection)
1422
9.47k
{
1423
9.47k
    if (ossl_prov_is_running())
1424
9.47k
        return ossl_ec_key_dup(keydata_from, selection);
1425
0
    return NULL;
1426
9.47k
}
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