Coverage Report

Created: 2026-02-14 07:20

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
143
#define EC_DEFAULT_MD "SHA256"
76
#define EC_POSSIBLE_SELECTIONS \
77
208k
    (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
74.3k
{
82
74.3k
    switch (operation_id) {
83
4.73k
    case OSSL_OP_KEYEXCH:
84
4.73k
        return "ECDH";
85
69.6k
    case OSSL_OP_SIGNATURE:
86
69.6k
        return "ECDSA";
87
74.3k
    }
88
0
    return NULL;
89
74.3k
}
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
535k
{
115
535k
    BIGNUM *x = NULL, *y = NULL;
116
535k
    const BIGNUM *priv_key = NULL;
117
535k
    const EC_POINT *pub_point = NULL;
118
535k
    const EC_GROUP *ecg = NULL;
119
535k
    size_t pub_key_len = 0;
120
535k
    int ret = 0;
121
535k
    BN_CTX *bnctx = NULL;
122
123
535k
    if (eckey == NULL
124
535k
        || (ecg = EC_KEY_get0_group(eckey)) == NULL)
125
0
        return 0;
126
127
535k
    priv_key = EC_KEY_get0_private_key(eckey);
128
535k
    pub_point = EC_KEY_get0_public_key(eckey);
129
130
535k
    if (pub_point != NULL) {
131
525k
        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
525k
        bnctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(eckey));
137
525k
        if (bnctx == NULL)
138
0
            goto err;
139
140
        /* If we are doing a get then check first before decoding the point */
141
525k
        if (tmpl == NULL) {
142
475k
            p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PUB_KEY);
143
475k
            px = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_PUB_X);
144
475k
            py = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_PUB_Y);
145
475k
        }
146
147
525k
        if (p != NULL || tmpl != NULL) {
148
            /* convert pub_point to a octet string according to the SECG standard */
149
49.9k
            point_conversion_form_t format = EC_KEY_get_conv_form(eckey);
150
151
49.9k
            if ((pub_key_len = EC_POINT_point2buf(ecg, pub_point,
152
49.9k
                     format,
153
49.9k
                     pub_key, bnctx))
154
49.9k
                    == 0
155
49.9k
                || !ossl_param_build_set_octet_string(tmpl, p,
156
49.9k
                    OSSL_PKEY_PARAM_PUB_KEY,
157
49.9k
                    *pub_key, pub_key_len))
158
0
                goto err;
159
49.9k
        }
160
525k
        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
525k
    }
184
185
535k
    if (priv_key != NULL && include_private) {
186
141k
        size_t sz;
187
141k
        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
141k
        ecbits = EC_GROUP_order_bits(ecg);
223
141k
        if (ecbits <= 0)
224
0
            goto err;
225
141k
        sz = (ecbits + 7) / 8;
226
227
141k
        if (!ossl_param_build_set_bn_pad(tmpl, params,
228
141k
                OSSL_PKEY_PARAM_PRIV_KEY,
229
141k
                priv_key, sz))
230
0
            goto err;
231
141k
    }
232
535k
    ret = 1;
233
535k
err:
234
535k
    BN_CTX_free(bnctx);
235
535k
    return ret;
236
535k
}
237
238
static ossl_inline int otherparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl,
239
    OSSL_PARAM params[])
240
535k
{
241
535k
    int ecdh_cofactor_mode = 0, group_check = 0;
242
535k
    const char *name = NULL;
243
535k
    point_conversion_form_t format;
244
245
535k
    if (ec == NULL)
246
0
        return 0;
247
248
535k
    format = EC_KEY_get_conv_form(ec);
249
535k
    name = ossl_ec_pt_format_id2name((int)format);
250
535k
    if (name != NULL
251
484k
        && !ossl_param_build_set_utf8_string(tmpl, params,
252
484k
            OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT,
253
484k
            name))
254
0
        return 0;
255
256
535k
    group_check = EC_KEY_get_flags(ec) & EC_FLAG_CHECK_NAMED_GROUP_MASK;
257
535k
    name = ossl_ec_check_group_type_id2name(group_check);
258
535k
    if (name != NULL
259
535k
        && !ossl_param_build_set_utf8_string(tmpl, params,
260
535k
            OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE,
261
535k
            name))
262
0
        return 0;
263
264
535k
    if ((EC_KEY_get_enc_flags(ec) & EC_PKEY_NO_PUBKEY) != 0
265
9.72k
        && !ossl_param_build_set_int(tmpl, params,
266
9.72k
            OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC, 0))
267
0
        return 0;
268
269
535k
    ecdh_cofactor_mode = (EC_KEY_get_flags(ec) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0;
270
535k
    return ossl_param_build_set_int(tmpl, params,
271
535k
        OSSL_PKEY_PARAM_USE_COFACTOR_ECDH,
272
535k
        ecdh_cofactor_mode);
273
535k
}
274
275
static void *ec_newdata(void *provctx)
276
41.4k
{
277
41.4k
    if (!ossl_prov_is_running())
278
0
        return NULL;
279
41.4k
    return EC_KEY_new_ex(PROV_LIBCTX_OF(provctx), NULL);
280
41.4k
}
281
282
#ifndef FIPS_MODULE
283
#ifndef OPENSSL_NO_SM2
284
static void *sm2_newdata(void *provctx)
285
0
{
286
0
    if (!ossl_prov_is_running())
287
0
        return NULL;
288
0
    return EC_KEY_new_by_curve_name_ex(PROV_LIBCTX_OF(provctx), NULL, NID_sm2);
289
0
}
290
#endif
291
#endif
292
293
static void ec_freedata(void *keydata)
294
459k
{
295
459k
    EC_KEY_free(keydata);
296
459k
}
297
298
static int ec_has(const void *keydata, int selection)
299
174k
{
300
174k
    const EC_KEY *ec = keydata;
301
174k
    int ok = 1;
302
303
174k
    if (!ossl_prov_is_running() || ec == NULL)
304
4.28k
        return 0;
305
170k
    if ((selection & EC_POSSIBLE_SELECTIONS) == 0)
306
0
        return 1; /* the selection is not missing */
307
308
170k
    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
309
59.0k
        ok = ok && (EC_KEY_get0_public_key(ec) != NULL);
310
170k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
311
54.7k
        ok = ok && (EC_KEY_get0_private_key(ec) != NULL);
312
170k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
313
106k
        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
170k
    return ok;
320
170k
}
321
322
static int ec_match(const void *keydata1, const void *keydata2, int selection)
323
104k
{
324
104k
    const EC_KEY *ec1 = keydata1;
325
104k
    const EC_KEY *ec2 = keydata2;
326
104k
    const EC_GROUP *group_a = EC_KEY_get0_group(ec1);
327
104k
    const EC_GROUP *group_b = EC_KEY_get0_group(ec2);
328
104k
    BN_CTX *ctx = NULL;
329
104k
    int ok = 1;
330
331
104k
    if (!ossl_prov_is_running())
332
0
        return 0;
333
334
104k
    ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(ec1));
335
104k
    if (ctx == NULL)
336
0
        return 0;
337
338
104k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
339
104k
        ok = ok && group_a != NULL && group_b != NULL
340
104k
            && EC_GROUP_cmp(group_a, group_b, ctx) == 0;
341
104k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
342
54.7k
        int key_checked = 0;
343
344
54.7k
        if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
345
54.7k
            const EC_POINT *pa = EC_KEY_get0_public_key(ec1);
346
54.7k
            const EC_POINT *pb = EC_KEY_get0_public_key(ec2);
347
348
54.7k
            if (pa != NULL && pb != NULL) {
349
54.2k
                ok = ok && EC_POINT_cmp(group_b, pa, pb, ctx) == 0;
350
54.2k
                key_checked = 1;
351
54.2k
            }
352
54.7k
        }
353
54.7k
        if (!key_checked
354
565
            && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
355
565
            const BIGNUM *pa = EC_KEY_get0_private_key(ec1);
356
565
            const BIGNUM *pb = EC_KEY_get0_private_key(ec2);
357
358
565
            if (pa != NULL && pb != NULL) {
359
0
                ok = ok && BN_cmp(pa, pb) == 0;
360
0
                key_checked = 1;
361
0
            }
362
565
        }
363
54.7k
        ok = ok && key_checked;
364
54.7k
    }
365
104k
    BN_CTX_free(ctx);
366
104k
    return ok;
367
104k
}
368
369
static int common_check_sm2(const EC_KEY *ec, int sm2_wanted)
370
428k
{
371
428k
    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
428k
    if ((ecg = EC_KEY_get0_group(ec)) == NULL
378
428k
        || (sm2_wanted ^ (EC_GROUP_get_curve_name(ecg) == NID_sm2)))
379
7
        return 0;
380
428k
    return 1;
381
428k
}
382
383
static int common_import(void *keydata, int selection, const OSSL_PARAM params[],
384
    int sm2_wanted)
385
41.4k
{
386
41.4k
    EC_KEY *ec = keydata;
387
41.4k
    int ok = 1;
388
389
41.4k
    if (!ossl_prov_is_running() || ec == NULL)
390
0
        return 0;
391
392
    /*
393
     * In this implementation, we can export/import only keydata in the
394
     * following combinations:
395
     *   - domain parameters (+optional other params)
396
     *   - public key with associated domain parameters (+optional other params)
397
     *   - private key with associated domain parameters and optional public key
398
     *         (+optional other params)
399
     *
400
     * This means:
401
     *   - domain parameters must always be requested
402
     *   - private key must be requested alongside public key
403
     *   - other parameters are always optional
404
     */
405
41.4k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0)
406
0
        return 0;
407
408
41.4k
    ok = ok && ossl_ec_group_fromdata(ec, params);
409
410
41.4k
    if (!common_check_sm2(ec, sm2_wanted))
411
0
        return 0;
412
413
41.4k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
414
41.4k
        int include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
415
416
41.4k
        ok = ok && ossl_ec_key_fromdata(ec, params, include_private);
417
41.4k
    }
418
41.4k
    if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
419
41.4k
        ok = ok && ossl_ec_key_otherparams_fromdata(ec, params);
420
421
41.4k
    return ok;
422
41.4k
}
423
424
static int ec_import(void *keydata, int selection, const OSSL_PARAM params[])
425
41.4k
{
426
41.4k
    return common_import(keydata, selection, params, 0);
427
41.4k
}
428
429
#ifndef FIPS_MODULE
430
#ifndef OPENSSL_NO_SM2
431
static int sm2_import(void *keydata, int selection, const OSSL_PARAM params[])
432
0
{
433
0
    return common_import(keydata, selection, params, 1);
434
0
}
435
#endif
436
#endif
437
438
static int ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
439
    void *cbarg)
440
49.9k
{
441
49.9k
    EC_KEY *ec = keydata;
442
49.9k
    OSSL_PARAM_BLD *tmpl = NULL;
443
49.9k
    OSSL_PARAM *params = NULL;
444
49.9k
    unsigned char *pub_key = NULL, *genbuf = NULL;
445
49.9k
    BN_CTX *bnctx = NULL;
446
49.9k
    int ok = 1;
447
448
49.9k
    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
49.9k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0)
465
0
        return 0;
466
49.9k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0
467
49.9k
        && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) == 0)
468
0
        return 0;
469
470
49.9k
    tmpl = OSSL_PARAM_BLD_new();
471
49.9k
    if (tmpl == NULL)
472
0
        return 0;
473
474
49.9k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
475
49.9k
        bnctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(ec));
476
49.9k
        if (bnctx == NULL) {
477
0
            ok = 0;
478
0
            goto end;
479
0
        }
480
49.9k
        BN_CTX_start(bnctx);
481
49.9k
        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
49.9k
    }
483
484
49.9k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
485
49.9k
        int include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
486
487
49.9k
        ok = ok && key_to_params(ec, tmpl, NULL, include_private, &pub_key);
488
49.9k
    }
489
49.9k
    if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
490
49.9k
        ok = ok && otherparams_to_params(ec, tmpl, NULL);
491
492
49.9k
    if (!ok || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) {
493
0
        ok = 0;
494
0
        goto end;
495
0
    }
496
497
49.9k
    ok = param_cb(params, cbarg);
498
49.9k
    OSSL_PARAM_free(params);
499
49.9k
end:
500
49.9k
    OSSL_PARAM_BLD_free(tmpl);
501
49.9k
    OPENSSL_free(pub_key);
502
49.9k
    OPENSSL_free(genbuf);
503
49.9k
    BN_CTX_end(bnctx);
504
49.9k
    BN_CTX_free(bnctx);
505
49.9k
    return ok;
506
49.9k
}
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
485k
{
568
#ifdef OPENSSL_NO_EC2M
569
    return 1;
570
#else
571
485k
    int ret = 0, m;
572
485k
    unsigned int k1 = 0, k2 = 0, k3 = 0;
573
485k
    int basis_nid;
574
485k
    const char *basis_name = NULL;
575
485k
    int fid = EC_GROUP_get_field_type(group);
576
577
485k
    if (fid != NID_X9_62_characteristic_two_field)
578
331k
        return 1;
579
580
154k
    basis_nid = EC_GROUP_get_basis_type(group);
581
154k
    if (basis_nid == NID_X9_62_tpBasis)
582
43.7k
        basis_name = SN_X9_62_tpBasis;
583
110k
    else if (basis_nid == NID_X9_62_ppBasis)
584
110k
        basis_name = SN_X9_62_ppBasis;
585
0
    else
586
0
        goto err;
587
588
154k
    m = EC_GROUP_get_degree(group);
589
154k
    if (!ossl_param_build_set_int(NULL, params, OSSL_PKEY_PARAM_EC_CHAR2_M, m)
590
154k
        || !ossl_param_build_set_utf8_string(NULL, params,
591
154k
            OSSL_PKEY_PARAM_EC_CHAR2_TYPE,
592
154k
            basis_name))
593
0
        goto err;
594
595
154k
    if (basis_nid == NID_X9_62_tpBasis) {
596
43.7k
        if (!EC_GROUP_get_trinomial_basis(group, &k1)
597
43.7k
            || !ossl_param_build_set_int(NULL, params,
598
43.7k
                OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS,
599
43.7k
                (int)k1))
600
0
            goto err;
601
110k
    } else {
602
110k
        if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3)
603
110k
            || !ossl_param_build_set_int(NULL, params,
604
110k
                OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, (int)k1)
605
110k
            || !ossl_param_build_set_int(NULL, params,
606
110k
                OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, (int)k2)
607
110k
            || !ossl_param_build_set_int(NULL, params,
608
110k
                OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, (int)k3))
609
0
            goto err;
610
110k
    }
611
154k
    ret = 1;
612
154k
err:
613
154k
    return ret;
614
154k
#endif /* OPENSSL_NO_EC2M */
615
154k
}
616
617
static int common_get_params(void *key, OSSL_PARAM params[], int sm2)
618
321k
{
619
321k
    int ret = 0;
620
321k
    EC_KEY *eck = key;
621
321k
    const EC_GROUP *ecg = NULL;
622
321k
    OSSL_PARAM *p;
623
321k
    unsigned char *pub_key = NULL, *genbuf = NULL;
624
321k
    OSSL_LIB_CTX *libctx;
625
321k
    const char *propq;
626
321k
    BN_CTX *bnctx = NULL;
627
628
321k
    ecg = EC_KEY_get0_group(eck);
629
321k
    if (ecg == NULL) {
630
0
        ERR_raise(ERR_LIB_PROV, PROV_R_NO_PARAMETERS_SET);
631
0
        return 0;
632
0
    }
633
634
321k
    libctx = ossl_ec_key_get_libctx(eck);
635
321k
    propq = ossl_ec_key_get0_propq(eck);
636
637
321k
    bnctx = BN_CTX_new_ex(libctx);
638
321k
    if (bnctx == NULL)
639
0
        return 0;
640
321k
    BN_CTX_start(bnctx);
641
642
321k
    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
643
273k
        && !OSSL_PARAM_set_int(p, ECDSA_size(eck)))
644
0
        goto err;
645
321k
    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
646
273k
        && !OSSL_PARAM_set_int(p, EC_GROUP_order_bits(ecg)))
647
0
        goto err;
648
321k
    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL) {
649
273k
        int ecbits, sec_bits;
650
651
273k
        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
273k
        if (ecbits >= 512)
670
12.0k
            sec_bits = 256;
671
261k
        else if (ecbits >= 384)
672
13.5k
            sec_bits = 192;
673
247k
        else if (ecbits >= 256)
674
89.3k
            sec_bits = 128;
675
158k
        else if (ecbits >= 224)
676
51.5k
            sec_bits = 112;
677
107k
        else if (ecbits >= 160)
678
46.9k
            sec_bits = 80;
679
60.1k
        else
680
60.1k
            sec_bits = ecbits / 2;
681
682
273k
        if (!OSSL_PARAM_set_int(p, sec_bits))
683
0
            goto err;
684
273k
    }
685
686
321k
    if ((p = OSSL_PARAM_locate(params,
687
321k
             OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS))
688
321k
        != 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
321k
    if (!sm2) {
697
319k
        if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DEFAULT_DIGEST)) != NULL
698
143
            && !OSSL_PARAM_set_utf8_string(p, EC_DEFAULT_MD))
699
0
            goto err;
700
319k
    } else {
701
2.41k
        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.41k
    }
705
706
    /* SM2 doesn't support this PARAM */
707
321k
    if (!sm2) {
708
319k
        p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH);
709
319k
        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
319k
    }
718
321k
    if ((p = OSSL_PARAM_locate(params,
719
321k
             OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY))
720
321k
        != NULL) {
721
11.9k
        const EC_POINT *ecp = EC_KEY_get0_public_key(key);
722
723
11.9k
        if (ecp == NULL) {
724
0
            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
725
0
            goto err;
726
0
        }
727
11.9k
        p->return_size = EC_POINT_point2oct(ecg, ecp,
728
11.9k
            POINT_CONVERSION_UNCOMPRESSED,
729
11.9k
            p->data, p->data_size, bnctx);
730
11.9k
        if (p->return_size == 0)
731
0
            goto err;
732
11.9k
    }
733
734
321k
    ret = ec_get_ecm_params(ecg, params)
735
321k
        && ossl_ec_group_todata(ecg, NULL, params, libctx, propq, bnctx,
736
321k
            &genbuf)
737
321k
        && key_to_params(eck, NULL, params, 1, &pub_key)
738
321k
        && otherparams_to_params(eck, NULL, params);
739
321k
err:
740
321k
    OPENSSL_free(genbuf);
741
321k
    OPENSSL_free(pub_key);
742
321k
    BN_CTX_end(bnctx);
743
321k
    BN_CTX_free(bnctx);
744
321k
    return ret;
745
321k
}
746
747
static int ec_get_params(void *key, OSSL_PARAM params[])
748
481k
{
749
481k
    return common_get_params(key, params, 0);
750
481k
}
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
3.97k
{
804
3.97k
    EC_KEY *eck = key;
805
3.97k
    const OSSL_PARAM *p;
806
807
3.97k
    if (key == NULL)
808
0
        return 0;
809
3.97k
    if (params == NULL)
810
0
        return 1;
811
812
3.97k
    if (!ossl_ec_group_set_params((EC_GROUP *)EC_KEY_get0_group(key), params))
813
0
        return 0;
814
815
3.97k
    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY);
816
3.97k
    if (p != NULL) {
817
3.97k
        BN_CTX *ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(key));
818
3.97k
        int ret = 1;
819
820
3.97k
        if (ctx == NULL
821
3.97k
            || p->data_type != OSSL_PARAM_OCTET_STRING
822
3.97k
            || !EC_KEY_oct2key(key, p->data, p->data_size, ctx))
823
1.14k
            ret = 0;
824
3.97k
        BN_CTX_free(ctx);
825
3.97k
        if (!ret)
826
1.14k
            return 0;
827
3.97k
    }
828
829
2.83k
    return ossl_ec_key_otherparams_fromdata(eck, params);
830
3.97k
}
831
832
#ifndef FIPS_MODULE
833
#ifndef OPENSSL_NO_SM2
834
static int sm2_get_params(void *key, OSSL_PARAM params[])
835
3.50k
{
836
3.50k
    return common_get_params(key, params, 1);
837
3.50k
}
838
839
static const OSSL_PARAM sm2_known_gettable_params[] = {
840
    OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
841
    OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
842
    OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
843
    OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST, NULL, 0),
844
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
845
    OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS, NULL),
846
    EC_IMEXPORTABLE_DOM_PARAMETERS,
847
    EC_IMEXPORTABLE_PUBLIC_KEY,
848
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_PUB_X, NULL, 0),
849
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_PUB_Y, NULL, 0),
850
    EC_IMEXPORTABLE_PRIVATE_KEY,
851
    OSSL_PARAM_END
852
};
853
854
static const OSSL_PARAM *sm2_gettable_params(ossl_unused void *provctx)
855
0
{
856
0
    return sm2_known_gettable_params;
857
0
}
858
859
static const OSSL_PARAM sm2_known_settable_params[] = {
860
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
861
    OSSL_PARAM_END
862
};
863
864
static const OSSL_PARAM *sm2_settable_params(ossl_unused void *provctx)
865
0
{
866
0
    return sm2_known_settable_params;
867
0
}
868
869
static int sm2_validate(const void *keydata, int selection, int checktype)
870
172
{
871
172
    const EC_KEY *eck = keydata;
872
172
    int ok = 1;
873
172
    BN_CTX *ctx = NULL;
874
875
172
    if (!ossl_prov_is_running())
876
0
        return 0;
877
878
172
    if ((selection & EC_POSSIBLE_SELECTIONS) == 0)
879
0
        return 1; /* nothing to validate */
880
881
172
    ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(eck));
882
172
    if (ctx == NULL)
883
0
        return 0;
884
885
172
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
886
43
        ok = ok && EC_GROUP_check(EC_KEY_get0_group(eck), ctx);
887
888
172
    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
889
86
        if (checktype == OSSL_KEYMGMT_VALIDATE_QUICK_CHECK)
890
0
            ok = ok && ossl_ec_key_public_check_quick(eck, ctx);
891
86
        else
892
86
            ok = ok && ossl_ec_key_public_check(eck, ctx);
893
86
    }
894
895
172
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
896
86
        ok = ok && ossl_sm2_key_private_check(eck);
897
898
172
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == OSSL_KEYMGMT_SELECT_KEYPAIR)
899
43
        ok = ok && ossl_ec_key_pairwise_check(eck, ctx);
900
901
172
    BN_CTX_free(ctx);
902
172
    return ok;
903
172
}
904
#endif
905
#endif
906
907
static int ec_validate(const void *keydata, int selection, int checktype)
908
23.9k
{
909
23.9k
    const EC_KEY *eck = keydata;
910
23.9k
    int ok = 1;
911
23.9k
    BN_CTX *ctx = NULL;
912
913
23.9k
    if (!ossl_prov_is_running())
914
0
        return 0;
915
916
23.9k
    if ((selection & EC_POSSIBLE_SELECTIONS) == 0)
917
0
        return 1; /* nothing to validate */
918
919
23.9k
    ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(eck));
920
23.9k
    if (ctx == NULL)
921
0
        return 0;
922
923
23.9k
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
924
4.80k
        int flags = EC_KEY_get_flags(eck);
925
926
4.80k
        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.80k
        else
929
4.80k
            ok = ok && EC_GROUP_check(EC_KEY_get0_group(eck), ctx);
930
4.80k
    }
931
932
23.9k
    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
933
14.3k
        if (checktype == OSSL_KEYMGMT_VALIDATE_QUICK_CHECK)
934
0
            ok = ok && ossl_ec_key_public_check_quick(eck, ctx);
935
14.3k
        else
936
14.3k
            ok = ok && ossl_ec_key_public_check(eck, ctx);
937
14.3k
    }
938
939
23.9k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
940
9.61k
        ok = ok && ossl_ec_key_private_check(eck);
941
942
23.9k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == OSSL_KEYMGMT_SELECT_KEYPAIR)
943
4.80k
        ok = ok && ossl_ec_key_pairwise_check(eck, ctx);
944
945
23.9k
    BN_CTX_free(ctx);
946
23.9k
    return ok;
947
23.9k
}
948
949
struct ec_gen_ctx {
950
    OSSL_LIB_CTX *libctx;
951
    char *group_name;
952
    char *encoding;
953
    char *pt_format;
954
    char *group_check;
955
    char *field_type;
956
    BIGNUM *p, *a, *b, *order, *cofactor;
957
    unsigned char *gen, *seed;
958
    size_t gen_len, seed_len;
959
    int selection;
960
    int ecdh_mode;
961
    EC_GROUP *gen_group;
962
    unsigned char *dhkem_ikm;
963
    size_t dhkem_ikmlen;
964
    OSSL_FIPS_IND_DECLARE
965
};
966
967
static void *ec_gen_init(void *provctx, int selection,
968
    const OSSL_PARAM params[])
969
13.9k
{
970
13.9k
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx);
971
13.9k
    struct ec_gen_ctx *gctx = NULL;
972
973
13.9k
    if (!ossl_prov_is_running() || (selection & (EC_POSSIBLE_SELECTIONS)) == 0)
974
0
        return NULL;
975
976
13.9k
    if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {
977
13.9k
        gctx->libctx = libctx;
978
13.9k
        gctx->selection = selection;
979
13.9k
        gctx->ecdh_mode = 0;
980
13.9k
        OSSL_FIPS_IND_INIT(gctx)
981
13.9k
        if (!ec_gen_set_params(gctx, params)) {
982
0
            ec_gen_cleanup(gctx);
983
0
            gctx = NULL;
984
0
        }
985
13.9k
    }
986
13.9k
    return gctx;
987
13.9k
}
988
989
#ifndef FIPS_MODULE
990
#ifndef OPENSSL_NO_SM2
991
static void *sm2_gen_init(void *provctx, int selection,
992
    const OSSL_PARAM params[])
993
0
{
994
0
    struct ec_gen_ctx *gctx = ec_gen_init(provctx, selection, params);
995
996
0
    if (gctx != NULL) {
997
0
        if (gctx->group_name != NULL)
998
0
            return gctx;
999
0
        if ((gctx->group_name = OPENSSL_strdup("sm2")) != NULL)
1000
0
            return gctx;
1001
0
        ec_gen_cleanup(gctx);
1002
0
    }
1003
0
    return NULL;
1004
0
}
1005
#endif
1006
#endif
1007
1008
static int ec_gen_set_group(void *genctx, const EC_GROUP *src)
1009
1.86k
{
1010
1.86k
    struct ec_gen_ctx *gctx = genctx;
1011
1.86k
    EC_GROUP *group;
1012
1013
1.86k
    group = EC_GROUP_dup(src);
1014
1.86k
    if (group == NULL) {
1015
0
        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE);
1016
0
        return 0;
1017
0
    }
1018
1.86k
    EC_GROUP_free(gctx->gen_group);
1019
1.86k
    gctx->gen_group = group;
1020
1.86k
    return 1;
1021
1.86k
}
1022
1023
static int ec_gen_set_template(void *genctx, void *templ)
1024
1.86k
{
1025
1.86k
    struct ec_gen_ctx *gctx = genctx;
1026
1.86k
    EC_KEY *ec = templ;
1027
1.86k
    const EC_GROUP *ec_group;
1028
1029
1.86k
    if (!ossl_prov_is_running() || gctx == NULL || ec == NULL)
1030
0
        return 0;
1031
1.86k
    if ((ec_group = EC_KEY_get0_group(ec)) == NULL)
1032
0
        return 0;
1033
1.86k
    return ec_gen_set_group(gctx, ec_group);
1034
1.86k
}
1035
1036
#define COPY_INT_PARAM(params, key, val)           \
1037
19.4k
    p = OSSL_PARAM_locate_const(params, key);      \
1038
19.4k
    if (p != NULL && !OSSL_PARAM_get_int(p, &val)) \
1039
19.4k
        goto err;
1040
1041
#define COPY_UTF8_PARAM(params, key, val)           \
1042
97.2k
    p = OSSL_PARAM_locate_const(params, key);       \
1043
97.2k
    if (p != NULL) {                                \
1044
8.97k
        if (p->data_type != OSSL_PARAM_UTF8_STRING) \
1045
8.97k
            goto err;                               \
1046
8.97k
        OPENSSL_free(val);                          \
1047
8.97k
        val = OPENSSL_strdup(p->data);              \
1048
8.97k
        if (val == NULL)                            \
1049
8.97k
            goto err;                               \
1050
8.97k
    }
1051
1052
#define COPY_OCTET_PARAM(params, key, val, len)      \
1053
58.3k
    p = OSSL_PARAM_locate_const(params, key);        \
1054
58.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
97.2k
    p = OSSL_PARAM_locate_const(params, key);         \
1066
97.2k
    if (p != NULL) {                                  \
1067
0
        if (bn == NULL)                               \
1068
0
            bn = BN_new();                            \
1069
0
        if (bn == NULL || !OSSL_PARAM_get_BN(p, &bn)) \
1070
0
            goto err;                                 \
1071
0
    }
1072
1073
static int ec_gen_set_params(void *genctx, const OSSL_PARAM params[])
1074
19.4k
{
1075
19.4k
    int ret = 0;
1076
19.4k
    struct ec_gen_ctx *gctx = genctx;
1077
19.4k
    const OSSL_PARAM *p;
1078
19.4k
    EC_GROUP *group = NULL;
1079
1080
19.4k
    if (!OSSL_FIPS_IND_SET_CTX_PARAM(gctx, OSSL_FIPS_IND_SETTABLE0, params,
1081
19.4k
            OSSL_PKEY_PARAM_FIPS_KEY_CHECK))
1082
0
        goto err;
1083
1084
19.4k
    COPY_INT_PARAM(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, gctx->ecdh_mode);
1085
1086
19.4k
    COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_GROUP_NAME, gctx->group_name);
1087
19.4k
    COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_FIELD_TYPE, gctx->field_type);
1088
19.4k
    COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_ENCODING, gctx->encoding);
1089
19.4k
    COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, gctx->pt_format);
1090
19.4k
    COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE, gctx->group_check);
1091
1092
19.4k
    COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_P, gctx->p);
1093
19.4k
    COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_A, gctx->a);
1094
19.4k
    COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_B, gctx->b);
1095
19.4k
    COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_ORDER, gctx->order);
1096
19.4k
    COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_COFACTOR, gctx->cofactor);
1097
1098
19.4k
    COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_EC_SEED, gctx->seed, gctx->seed_len);
1099
19.4k
    COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_EC_GENERATOR, gctx->gen,
1100
19.4k
        gctx->gen_len);
1101
1102
19.4k
    COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_DHKEM_IKM, gctx->dhkem_ikm,
1103
19.4k
        gctx->dhkem_ikmlen);
1104
1105
19.4k
    ret = 1;
1106
19.4k
err:
1107
19.4k
    EC_GROUP_free(group);
1108
19.4k
    return ret;
1109
19.4k
}
1110
1111
static int ec_gen_set_group_from_params(struct ec_gen_ctx *gctx)
1112
12.1k
{
1113
12.1k
    int ret = 0;
1114
12.1k
    OSSL_PARAM_BLD *bld;
1115
12.1k
    OSSL_PARAM *params = NULL;
1116
12.1k
    EC_GROUP *group = NULL;
1117
1118
12.1k
    bld = OSSL_PARAM_BLD_new();
1119
12.1k
    if (bld == NULL)
1120
0
        return 0;
1121
1122
12.1k
    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.1k
    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.1k
    if (gctx->group_name != NULL) {
1134
12.1k
        if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME,
1135
12.1k
                gctx->group_name, 0))
1136
0
            goto err;
1137
        /* Ignore any other parameters if there is a group name */
1138
12.1k
        goto build;
1139
12.1k
    } 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.1k
build:
1171
12.1k
    params = OSSL_PARAM_BLD_to_param(bld);
1172
12.1k
    if (params == NULL)
1173
0
        goto err;
1174
12.1k
    group = EC_GROUP_new_from_params(params, gctx->libctx, NULL);
1175
12.1k
    if (group == NULL)
1176
0
        goto err;
1177
1178
12.1k
    EC_GROUP_free(gctx->gen_group);
1179
12.1k
    gctx->gen_group = group;
1180
1181
12.1k
    ret = 1;
1182
12.1k
err:
1183
12.1k
    OSSL_PARAM_free(params);
1184
12.1k
    OSSL_PARAM_BLD_free(bld);
1185
12.1k
    return ret;
1186
12.1k
}
1187
1188
static const OSSL_PARAM *ec_gen_settable_params(ossl_unused void *genctx,
1189
    ossl_unused void *provctx)
1190
0
{
1191
0
    static OSSL_PARAM settable[] = {
1192
0
        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0),
1193
0
        OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL),
1194
0
        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, NULL, 0),
1195
0
        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, NULL, 0),
1196
0
        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_FIELD_TYPE, NULL, 0),
1197
0
        OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_P, NULL, 0),
1198
0
        OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_A, NULL, 0),
1199
0
        OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_B, NULL, 0),
1200
0
        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_GENERATOR, NULL, 0),
1201
0
        OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_ORDER, NULL, 0),
1202
0
        OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_COFACTOR, NULL, 0),
1203
0
        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_SEED, NULL, 0),
1204
0
        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_DHKEM_IKM, NULL, 0),
1205
0
        OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_PKEY_PARAM_FIPS_KEY_CHECK)
1206
0
            OSSL_PARAM_END
1207
0
    };
1208
0
    return settable;
1209
0
}
1210
1211
static const OSSL_PARAM *ec_gen_gettable_params(ossl_unused void *genctx,
1212
    ossl_unused void *provctx)
1213
0
{
1214
0
    static const OSSL_PARAM known_ec_gen_gettable_ctx_params[] = {
1215
0
        OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
1216
0
            OSSL_PARAM_END
1217
0
    };
1218
0
    return known_ec_gen_gettable_ctx_params;
1219
0
}
1220
1221
static int ec_gen_get_params(void *genctx, OSSL_PARAM *params)
1222
0
{
1223
0
    struct ec_gen_ctx *gctx = genctx;
1224
1225
0
    if (gctx == NULL)
1226
0
        return 0;
1227
1228
0
    if (!OSSL_FIPS_IND_GET_CTX_PARAM(gctx, params))
1229
0
        return 0;
1230
1231
0
    return 1;
1232
0
}
1233
1234
static int ec_gen_assign_group(EC_KEY *ec, EC_GROUP *group)
1235
13.9k
{
1236
13.9k
    if (group == NULL) {
1237
0
        ERR_raise(ERR_LIB_PROV, PROV_R_NO_PARAMETERS_SET);
1238
0
        return 0;
1239
0
    }
1240
13.9k
    return EC_KEY_set_group(ec, group) > 0;
1241
13.9k
}
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
12.6k
{
1248
12.6k
    struct ec_gen_ctx *gctx = genctx;
1249
12.6k
    EC_KEY *ec = NULL;
1250
12.6k
    int ret = 0;
1251
1252
12.6k
    if (!ossl_prov_is_running()
1253
12.6k
        || gctx == NULL
1254
12.6k
        || (ec = EC_KEY_new_ex(gctx->libctx, NULL)) == NULL)
1255
0
        return NULL;
1256
1257
12.6k
    if (gctx->gen_group == NULL) {
1258
10.8k
        if (!ec_gen_set_group_from_params(gctx))
1259
0
            goto err;
1260
10.8k
    } else {
1261
1.73k
        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.73k
        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.73k
    }
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
12.6k
    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
12.6k
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
1292
8.78k
#ifndef FIPS_MODULE
1293
8.78k
        if (gctx->dhkem_ikm != NULL && gctx->dhkem_ikmlen != 0)
1294
0
            ret = ret && ossl_ec_generate_key_dhkem(ec, gctx->dhkem_ikm, gctx->dhkem_ikmlen);
1295
8.78k
        else
1296
8.78k
#endif
1297
8.78k
            ret = ret && EC_KEY_generate_key(ec);
1298
8.78k
    }
1299
1300
12.6k
    if (gctx->ecdh_mode != -1)
1301
12.6k
        ret = ret && ossl_ec_set_ecdh_cofactor_mode(ec, gctx->ecdh_mode);
1302
1303
12.6k
    if (gctx->group_check != NULL)
1304
0
        ret = ret && ossl_ec_set_check_group_type_from_name(ec, gctx->group_check);
1305
12.6k
    if (ret)
1306
12.6k
        return ec;
1307
0
err:
1308
    /* Something went wrong, throw the key away */
1309
0
    EC_KEY_free(ec);
1310
0
    return NULL;
1311
12.6k
}
1312
1313
#ifndef FIPS_MODULE
1314
#ifndef OPENSSL_NO_SM2
1315
/*
1316
 * The callback arguments (osslcb & cbarg) are not used by EC_KEY generation
1317
 */
1318
static void *sm2_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
1319
0
{
1320
0
    struct ec_gen_ctx *gctx = genctx;
1321
0
    EC_KEY *ec = NULL;
1322
0
    int ret = 1;
1323
1324
0
    if (gctx == NULL
1325
0
        || (ec = EC_KEY_new_ex(gctx->libctx, NULL)) == NULL)
1326
0
        return NULL;
1327
1328
0
    if (gctx->gen_group == NULL) {
1329
0
        if (!ec_gen_set_group_from_params(gctx))
1330
0
            goto err;
1331
0
    } else {
1332
0
        if (gctx->encoding) {
1333
0
            int flags = ossl_ec_encoding_name2id(gctx->encoding);
1334
1335
0
            if (flags < 0)
1336
0
                goto err;
1337
0
            EC_GROUP_set_asn1_flag(gctx->gen_group, flags);
1338
0
        }
1339
0
        if (gctx->pt_format != NULL) {
1340
0
            int format = ossl_ec_pt_format_name2id(gctx->pt_format);
1341
1342
0
            if (format < 0)
1343
0
                goto err;
1344
0
            EC_GROUP_set_point_conversion_form(gctx->gen_group, format);
1345
0
        }
1346
0
    }
1347
1348
    /* We must always assign a group, no matter what */
1349
0
    ret = ec_gen_assign_group(ec, gctx->gen_group);
1350
1351
    /* Whether you want it or not, you get a keypair, not just one half */
1352
0
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
1353
0
        ret = ret && EC_KEY_generate_key(ec);
1354
1355
0
    if (ret)
1356
0
        return ec;
1357
0
err:
1358
    /* Something went wrong, throw the key away */
1359
0
    EC_KEY_free(ec);
1360
0
    return NULL;
1361
0
}
1362
#endif
1363
#endif
1364
1365
static void ec_gen_cleanup(void *genctx)
1366
13.9k
{
1367
13.9k
    struct ec_gen_ctx *gctx = genctx;
1368
1369
13.9k
    if (gctx == NULL)
1370
0
        return;
1371
1372
13.9k
    OPENSSL_clear_free(gctx->dhkem_ikm, gctx->dhkem_ikmlen);
1373
13.9k
    EC_GROUP_free(gctx->gen_group);
1374
13.9k
    BN_free(gctx->p);
1375
13.9k
    BN_free(gctx->a);
1376
13.9k
    BN_free(gctx->b);
1377
13.9k
    BN_free(gctx->order);
1378
13.9k
    BN_free(gctx->cofactor);
1379
13.9k
    OPENSSL_free(gctx->group_name);
1380
13.9k
    OPENSSL_free(gctx->field_type);
1381
13.9k
    OPENSSL_free(gctx->pt_format);
1382
13.9k
    OPENSSL_free(gctx->encoding);
1383
13.9k
    OPENSSL_free(gctx->seed);
1384
13.9k
    OPENSSL_free(gctx->gen);
1385
13.9k
    OPENSSL_free(gctx);
1386
13.9k
}
1387
1388
static void *common_load(const void *reference, size_t reference_sz,
1389
    int sm2_wanted)
1390
386k
{
1391
386k
    EC_KEY *ec = NULL;
1392
1393
386k
    if (ossl_prov_is_running() && reference_sz == sizeof(ec)) {
1394
        /* The contents of the reference is the address to our object */
1395
386k
        ec = *(EC_KEY **)reference;
1396
1397
386k
        if (!common_check_sm2(ec, sm2_wanted))
1398
7
            return NULL;
1399
1400
        /* We grabbed, so we detach it */
1401
386k
        *(EC_KEY **)reference = NULL;
1402
386k
        return ec;
1403
386k
    }
1404
0
    return NULL;
1405
386k
}
1406
1407
static void *ec_load(const void *reference, size_t reference_sz)
1408
383k
{
1409
383k
    return common_load(reference, reference_sz, 0);
1410
383k
}
1411
1412
#ifndef FIPS_MODULE
1413
#ifndef OPENSSL_NO_SM2
1414
static void *sm2_load(const void *reference, size_t reference_sz)
1415
3.47k
{
1416
3.47k
    return common_load(reference, reference_sz, 1);
1417
3.47k
}
1418
#endif
1419
#endif
1420
1421
static void *ec_dup(const void *keydata_from, int selection)
1422
9.13k
{
1423
9.13k
    if (ossl_prov_is_running())
1424
9.13k
        return ossl_ec_key_dup(keydata_from, selection);
1425
0
    return NULL;
1426
9.13k
}
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