dh_ctrl.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. /*
  2. * Copyright 2020 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. #include <stdio.h>
  10. #include <string.h>
  11. #include <openssl/core_names.h>
  12. #include <openssl/params.h>
  13. #include <openssl/err.h>
  14. #include <openssl/dh.h>
  15. #include "crypto/dh.h"
  16. #include "crypto/evp.h"
  17. static int dh_paramgen_check(EVP_PKEY_CTX *ctx)
  18. {
  19. if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
  20. ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
  21. /* Uses the same return values as EVP_PKEY_CTX_ctrl */
  22. return -2;
  23. }
  24. /* If key type not DH return error */
  25. if (ctx->pmeth != NULL
  26. && ctx->pmeth->pkey_id != EVP_PKEY_DH
  27. && ctx->pmeth->pkey_id != EVP_PKEY_DHX)
  28. return -1;
  29. return 1;
  30. }
  31. static int dh_param_derive_check(EVP_PKEY_CTX *ctx)
  32. {
  33. if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) {
  34. ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
  35. /* Uses the same return values as EVP_PKEY_CTX_ctrl */
  36. return -2;
  37. }
  38. /* If key type not DH return error */
  39. if (ctx->pmeth != NULL
  40. && ctx->pmeth->pkey_id != EVP_PKEY_DH
  41. && ctx->pmeth->pkey_id != EVP_PKEY_DHX)
  42. return -1;
  43. return 1;
  44. }
  45. int EVP_PKEY_CTX_set_dh_paramgen_gindex(EVP_PKEY_CTX *ctx, int gindex)
  46. {
  47. int ret;
  48. OSSL_PARAM params[2], *p = params;
  49. if ((ret = dh_paramgen_check(ctx)) <= 0)
  50. return ret;
  51. *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_FFC_GINDEX, &gindex);
  52. *p = OSSL_PARAM_construct_end();
  53. return EVP_PKEY_CTX_set_params(ctx, params);
  54. }
  55. int EVP_PKEY_CTX_set_dh_paramgen_seed(EVP_PKEY_CTX *ctx,
  56. const unsigned char *seed,
  57. size_t seedlen)
  58. {
  59. int ret;
  60. OSSL_PARAM params[2], *p = params;
  61. if ((ret = dh_paramgen_check(ctx)) <= 0)
  62. return ret;
  63. *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_FFC_SEED,
  64. (void *)seed, seedlen);
  65. *p = OSSL_PARAM_construct_end();
  66. return EVP_PKEY_CTX_set_params(ctx, params);
  67. }
  68. int EVP_PKEY_CTX_set_dh_paramgen_type(EVP_PKEY_CTX *ctx, int typ)
  69. {
  70. int ret;
  71. OSSL_PARAM params[2], *p = params;
  72. const char *name;
  73. if ((ret = dh_paramgen_check(ctx)) <= 0)
  74. return ret;
  75. /* TODO(3.0): Remove this eventually when no more legacy */
  76. if (ctx->op.keymgmt.genctx == NULL)
  77. return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN,
  78. EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, typ, NULL);
  79. name = dh_gen_type_id2name(typ);
  80. if (name == NULL)
  81. return 0;
  82. *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_FFC_TYPE,
  83. (char *) name, 0);
  84. *p = OSSL_PARAM_construct_end();
  85. return EVP_PKEY_CTX_set_params(ctx, params);
  86. }
  87. int EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int pbits)
  88. {
  89. int ret;
  90. OSSL_PARAM params[2], *p = params;
  91. size_t bits = pbits;
  92. if ((ret = dh_paramgen_check(ctx)) <= 0)
  93. return ret;
  94. /* TODO(3.0): Remove this eventually when no more legacy */
  95. if (ctx->op.keymgmt.genctx == NULL)
  96. return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN,
  97. EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, pbits,
  98. NULL);
  99. *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_FFC_PBITS, &bits);
  100. *p = OSSL_PARAM_construct_end();
  101. return EVP_PKEY_CTX_set_params(ctx, params);
  102. }
  103. int EVP_PKEY_CTX_set_dh_paramgen_subprime_len(EVP_PKEY_CTX *ctx, int qbits)
  104. {
  105. int ret;
  106. OSSL_PARAM params[2], *p = params;
  107. size_t bits2 = qbits;
  108. if ((ret = dh_paramgen_check(ctx)) <= 0)
  109. return ret;
  110. /* TODO(3.0): Remove this eventually when no more legacy */
  111. if (ctx->op.keymgmt.genctx == NULL)
  112. return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN,
  113. EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN, qbits,
  114. NULL);
  115. *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_FFC_QBITS, &bits2);
  116. *p = OSSL_PARAM_construct_end();
  117. return EVP_PKEY_CTX_set_params(ctx, params);
  118. }
  119. int EVP_PKEY_CTX_set_dh_paramgen_generator(EVP_PKEY_CTX *ctx, int gen)
  120. {
  121. int ret;
  122. OSSL_PARAM params[2], *p = params;
  123. if ((ret = dh_paramgen_check(ctx)) <= 0)
  124. return ret;
  125. /* TODO(3.0): Remove this eventually when no more legacy */
  126. if (ctx->op.keymgmt.genctx == NULL)
  127. return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN,
  128. EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL);
  129. *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_DH_GENERATOR, &gen);
  130. *p = OSSL_PARAM_construct_end();
  131. return EVP_PKEY_CTX_set_params(ctx, params);
  132. }
  133. int EVP_PKEY_CTX_set_dh_rfc5114(EVP_PKEY_CTX *ctx, int gen)
  134. {
  135. int ret;
  136. OSSL_PARAM params[2], *p = params;
  137. const char *name;
  138. if ((ret = dh_paramgen_check(ctx)) <= 0)
  139. return ret;
  140. /* TODO(3.0): Remove this eventually when no more legacy */
  141. if (ctx->op.keymgmt.genctx == NULL)
  142. return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN,
  143. EVP_PKEY_CTRL_DH_RFC5114, gen, NULL);
  144. name = ossl_ffc_named_group_get_name(ossl_ffc_uid_to_dh_named_group(gen));
  145. if (name == NULL)
  146. return 0;
  147. *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
  148. (void *)name, 0);
  149. *p = OSSL_PARAM_construct_end();
  150. return EVP_PKEY_CTX_set_params(ctx, params);
  151. }
  152. int EVP_PKEY_CTX_set_dhx_rfc5114(EVP_PKEY_CTX *ctx, int gen)
  153. {
  154. return EVP_PKEY_CTX_set_dh_rfc5114(ctx, gen);
  155. }
  156. int EVP_PKEY_CTX_set_dh_nid(EVP_PKEY_CTX *ctx, int nid)
  157. {
  158. int ret;
  159. OSSL_PARAM params[2], *p = params;
  160. const char *name;
  161. if ((ret = dh_paramgen_check(ctx)) <= 0)
  162. return ret;
  163. /* TODO(3.0): Remove this eventually when no more legacy */
  164. if (ctx->op.keymgmt.genctx == NULL)
  165. return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH,
  166. EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN,
  167. EVP_PKEY_CTRL_DH_NID, nid, NULL);
  168. name = ossl_ffc_named_group_get_name(ossl_ffc_uid_to_dh_named_group(nid));
  169. if (name == NULL)
  170. return 0;
  171. *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
  172. (void *)name, 0);
  173. *p = OSSL_PARAM_construct_end();
  174. return EVP_PKEY_CTX_set_params(ctx, params);
  175. }
  176. int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad)
  177. {
  178. OSSL_PARAM dh_pad_params[2];
  179. unsigned int upad = pad;
  180. /* We use EVP_PKEY_CTX_ctrl return values */
  181. if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) {
  182. ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
  183. return -2;
  184. }
  185. /* TODO(3.0): Remove this eventually when no more legacy */
  186. if (ctx->op.kex.exchprovctx == NULL)
  187. return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_DERIVE,
  188. EVP_PKEY_CTRL_DH_PAD, pad, NULL);
  189. dh_pad_params[0] = OSSL_PARAM_construct_uint(OSSL_EXCHANGE_PARAM_PAD, &upad);
  190. dh_pad_params[1] = OSSL_PARAM_construct_end();
  191. return EVP_PKEY_CTX_set_params(ctx, dh_pad_params);
  192. }
  193. int EVP_PKEY_CTX_set_dh_kdf_type(EVP_PKEY_CTX *ctx, int kdf)
  194. {
  195. int ret;
  196. const char *kdf_type;
  197. OSSL_PARAM params[2], *p = params;
  198. ret = dh_param_derive_check(ctx);
  199. if (ret != 1)
  200. return ret;
  201. /* TODO(3.0): Remove this eventually when no more legacy */
  202. if (ctx->op.kex.exchprovctx == NULL)
  203. return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
  204. EVP_PKEY_CTRL_DH_KDF_TYPE, kdf, NULL);
  205. switch (kdf) {
  206. case EVP_PKEY_DH_KDF_NONE:
  207. kdf_type = "";
  208. break;
  209. case EVP_PKEY_DH_KDF_X9_42:
  210. kdf_type = OSSL_KDF_NAME_X942KDF_ASN1;
  211. break;
  212. default:
  213. return -2;
  214. }
  215. *p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE,
  216. /*
  217. * Cast away the const. This is read
  218. * only so should be safe
  219. */
  220. (char *)kdf_type, 0);
  221. *p = OSSL_PARAM_construct_end();
  222. ret = evp_pkey_ctx_set_params_strict(ctx, params);
  223. if (ret == -2) {
  224. ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
  225. /* Uses the same return values as EVP_PKEY_CTX_ctrl */
  226. return -2;
  227. }
  228. return ret;
  229. }
  230. int EVP_PKEY_CTX_get_dh_kdf_type(EVP_PKEY_CTX *ctx)
  231. {
  232. int ret;
  233. char kdf_type[80]; /* 80 should be big enough */
  234. OSSL_PARAM params[2], *p = params;
  235. ret = dh_param_derive_check(ctx);
  236. if (ret != 1)
  237. return ret;
  238. /* TODO(3.0): Remove this eventually when no more legacy */
  239. if (ctx->op.kex.exchprovctx == NULL)
  240. return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
  241. EVP_PKEY_CTRL_DH_KDF_TYPE, -2, NULL);
  242. *p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE,
  243. kdf_type, sizeof(kdf_type));
  244. *p = OSSL_PARAM_construct_end();
  245. ret = evp_pkey_ctx_get_params_strict(ctx, params);
  246. if (ret == -2) {
  247. ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
  248. /* Uses the same return values as EVP_PKEY_CTX_ctrl */
  249. return -2;
  250. } else if (ret != 1) {
  251. return -1;
  252. }
  253. if (kdf_type[0] == '\0')
  254. return EVP_PKEY_DH_KDF_NONE;
  255. else if (strcmp(kdf_type, OSSL_KDF_NAME_X942KDF_ASN1) == 0)
  256. return EVP_PKEY_DH_KDF_X9_42;
  257. return -1;
  258. }
  259. int EVP_PKEY_CTX_set0_dh_kdf_oid(EVP_PKEY_CTX *ctx, ASN1_OBJECT *oid)
  260. {
  261. int ret;
  262. OSSL_PARAM params[2], *p = params;
  263. const char *oid_name;
  264. ret = dh_param_derive_check(ctx);
  265. if (ret != 1)
  266. return ret;
  267. /* TODO(3.0): Remove this eventually when no more legacy */
  268. if (ctx->op.kex.exchprovctx == NULL)
  269. return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
  270. EVP_PKEY_CTRL_DH_KDF_OID, 0, (void *)(oid));
  271. oid_name = OBJ_nid2sn(OBJ_obj2nid(oid));
  272. *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CEK_ALG,
  273. (char *)oid_name, 0);
  274. *p = OSSL_PARAM_construct_end();
  275. ret = evp_pkey_ctx_set_params_strict(ctx, params);
  276. if (ret == -2) {
  277. ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
  278. /* Uses the same return values as EVP_PKEY_CTX_ctrl */
  279. return -2;
  280. }
  281. return ret;
  282. }
  283. int EVP_PKEY_CTX_get0_dh_kdf_oid(EVP_PKEY_CTX *ctx, ASN1_OBJECT **oid)
  284. {
  285. int ret, nid;
  286. OSSL_PARAM params[2], *p = params;
  287. char oid_name[80]; /* 80 should be big enough */
  288. ret = dh_param_derive_check(ctx);
  289. if (ret != 1)
  290. return ret;
  291. /* TODO(3.0): Remove this eventually when no more legacy */
  292. if (ctx->op.kex.exchprovctx == NULL)
  293. return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
  294. EVP_PKEY_CTRL_GET_DH_KDF_OID, 0, (void *)(oid));
  295. *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CEK_ALG,
  296. oid_name, sizeof(oid_name));
  297. *p = OSSL_PARAM_construct_end();
  298. ret = evp_pkey_ctx_get_params_strict(ctx, params);
  299. if (ret == -2) {
  300. ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
  301. /* Uses the same return values as EVP_PKEY_CTX_ctrl */
  302. return -2;
  303. } else if (ret != 1) {
  304. return -1;
  305. }
  306. nid = OBJ_sn2nid(oid_name);
  307. if (nid == NID_undef)
  308. nid = OBJ_ln2nid(oid_name);
  309. *oid = (nid == NID_undef ? NULL : OBJ_nid2obj(nid));
  310. return *oid != NULL;
  311. }
  312. int EVP_PKEY_CTX_set_dh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
  313. {
  314. int ret;
  315. OSSL_PARAM params[2], *p = params;
  316. const char *md_name = NULL;
  317. ret = dh_param_derive_check(ctx);
  318. if (ret != 1)
  319. return ret;
  320. /* TODO(3.0): Remove this eventually when no more legacy */
  321. if (ctx->op.kex.exchprovctx == NULL)
  322. return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
  323. EVP_PKEY_CTRL_DH_KDF_MD, 0, (void *)(md));
  324. md_name = (md == NULL) ? "" : EVP_MD_name(md);
  325. *p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST,
  326. /*
  327. * Cast away the const. This is read
  328. * only so should be safe
  329. */
  330. (char *)md_name, 0);
  331. *p = OSSL_PARAM_construct_end();
  332. ret = evp_pkey_ctx_set_params_strict(ctx, params);
  333. if (ret == -2) {
  334. ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
  335. /* Uses the same return values as EVP_PKEY_CTX_ctrl */
  336. return -2;
  337. }
  338. return ret;
  339. }
  340. int EVP_PKEY_CTX_get_dh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD **pmd)
  341. {
  342. int ret;
  343. char name[80] = ""; /* 80 should be big enough */
  344. OSSL_PARAM params[2], *p = params;
  345. ret = dh_param_derive_check(ctx);
  346. if (ret != 1)
  347. return ret;
  348. /* TODO(3.0): Remove this eventually when no more legacy */
  349. if (ctx->op.kex.exchprovctx == NULL)
  350. return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
  351. EVP_PKEY_CTRL_GET_DH_KDF_MD, 0, (void *)(pmd));
  352. *p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST,
  353. name, sizeof(name));
  354. *p = OSSL_PARAM_construct_end();
  355. ret = evp_pkey_ctx_get_params_strict(ctx, params);
  356. if (ret == -2) {
  357. ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
  358. /* Uses the same return values as EVP_PKEY_CTX_ctrl */
  359. return -2;
  360. } else if (ret != 1) {
  361. return -1;
  362. }
  363. /* May be NULL meaning "unknown" */
  364. *pmd = EVP_get_digestbyname(name);
  365. return 1;
  366. }
  367. int EVP_PKEY_CTX_set_dh_kdf_outlen(EVP_PKEY_CTX *ctx, int inlen)
  368. {
  369. int ret;
  370. size_t len = inlen;
  371. OSSL_PARAM params[2], *p = params;
  372. ret = dh_param_derive_check(ctx);
  373. if (ret != 1)
  374. return ret;
  375. /* TODO(3.0): Remove this eventually when no more legacy */
  376. if (ctx->op.kex.exchprovctx == NULL)
  377. return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
  378. EVP_PKEY_CTRL_DH_KDF_OUTLEN, inlen, NULL);
  379. if (inlen <= 0) {
  380. /*
  381. * This would ideally be -1 or 0, but we have to retain compatibility
  382. * with legacy behaviour of EVP_PKEY_CTX_ctrl() which returned -2 if
  383. * in <= 0
  384. */
  385. return -2;
  386. }
  387. *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN,
  388. &len);
  389. *p = OSSL_PARAM_construct_end();
  390. ret = evp_pkey_ctx_set_params_strict(ctx, params);
  391. if (ret == -2) {
  392. ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
  393. /* Uses the same return values as EVP_PKEY_CTX_ctrl */
  394. return -2;
  395. }
  396. return ret;
  397. }
  398. int EVP_PKEY_CTX_get_dh_kdf_outlen(EVP_PKEY_CTX *ctx, int *plen)
  399. {
  400. int ret;
  401. size_t len = UINT_MAX;
  402. OSSL_PARAM params[2], *p = params;
  403. ret = dh_param_derive_check(ctx);
  404. if (ret != 1)
  405. return ret;
  406. /* TODO(3.0): Remove this eventually when no more legacy */
  407. if (ctx->op.kex.exchprovctx == NULL)
  408. return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
  409. EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN, 0,
  410. (void *)(plen));
  411. *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN,
  412. &len);
  413. *p = OSSL_PARAM_construct_end();
  414. ret = evp_pkey_ctx_get_params_strict(ctx, params);
  415. if (ret == -2) {
  416. ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
  417. /* Uses the same return values as EVP_PKEY_CTX_ctrl */
  418. return -2;
  419. } else if (ret != 1) {
  420. return -1;
  421. }
  422. if (len > INT_MAX)
  423. return -1;
  424. *plen = (int)len;
  425. return 1;
  426. }
  427. int EVP_PKEY_CTX_set0_dh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char *ukm, int len)
  428. {
  429. int ret;
  430. OSSL_PARAM params[2], *p = params;
  431. if (len <= 0)
  432. return -1;
  433. ret = dh_param_derive_check(ctx);
  434. if (ret != 1)
  435. return ret;
  436. /* TODO(3.0): Remove this eventually when no more legacy */
  437. if (ctx->op.kex.exchprovctx == NULL)
  438. return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
  439. EVP_PKEY_CTRL_DH_KDF_UKM, len, (void *)(ukm));
  440. *p++ = OSSL_PARAM_construct_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM,
  441. /*
  442. * Cast away the const. This is read
  443. * only so should be safe
  444. */
  445. (void *)ukm,
  446. (size_t)len);
  447. *p = OSSL_PARAM_construct_end();
  448. ret = evp_pkey_ctx_set_params_strict(ctx, params);
  449. if (ret == -2) {
  450. ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
  451. /* Uses the same return values as EVP_PKEY_CTX_ctrl */
  452. return -2;
  453. }
  454. if (ret == 1)
  455. OPENSSL_free(ukm);
  456. return ret;
  457. }
  458. int EVP_PKEY_CTX_get0_dh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **pukm)
  459. {
  460. int ret;
  461. size_t ukmlen;
  462. OSSL_PARAM params[3], *p = params;
  463. ret = dh_param_derive_check(ctx);
  464. if (ret != 1)
  465. return ret;
  466. /* TODO(3.0): Remove this eventually when no more legacy */
  467. if (ctx->op.kex.exchprovctx == NULL)
  468. return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
  469. EVP_PKEY_CTRL_GET_DH_KDF_UKM, 0, (void *)(pukm));
  470. *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_EXCHANGE_PARAM_KDF_UKM,
  471. (void **)pukm, 0);
  472. *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_UKM_LEN,
  473. &ukmlen);
  474. *p = OSSL_PARAM_construct_end();
  475. ret = evp_pkey_ctx_get_params_strict(ctx, params);
  476. if (ret == -2) {
  477. ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
  478. /* Uses the same return values as EVP_PKEY_CTX_ctrl */
  479. return -2;
  480. } else if (ret != 1) {
  481. return -1;
  482. }
  483. if (ukmlen > INT_MAX)
  484. return -1;
  485. return (int)ukmlen;
  486. }