Coverage Report

Created: 2025-12-31 06:58

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