ec_kmgmt.c 48 KB

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