ec_kmgmt.c 49 KB

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