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