Coverage Report

Created: 2026-05-24 07:14

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