dh_exch.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. /*
  2. * Copyright 2019-2024 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. * DH 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/crypto.h>
  16. #include <openssl/core_dispatch.h>
  17. #include <openssl/core_names.h>
  18. #include <openssl/dh.h>
  19. #include <openssl/err.h>
  20. #include <openssl/proverr.h>
  21. #include <openssl/params.h>
  22. #include "prov/providercommon.h"
  23. #include "prov/implementations.h"
  24. #include "prov/provider_ctx.h"
  25. #include "prov/securitycheck.h"
  26. #include "crypto/dh.h"
  27. static OSSL_FUNC_keyexch_newctx_fn dh_newctx;
  28. static OSSL_FUNC_keyexch_init_fn dh_init;
  29. static OSSL_FUNC_keyexch_set_peer_fn dh_set_peer;
  30. static OSSL_FUNC_keyexch_derive_fn dh_derive;
  31. static OSSL_FUNC_keyexch_freectx_fn dh_freectx;
  32. static OSSL_FUNC_keyexch_dupctx_fn dh_dupctx;
  33. static OSSL_FUNC_keyexch_set_ctx_params_fn dh_set_ctx_params;
  34. static OSSL_FUNC_keyexch_settable_ctx_params_fn dh_settable_ctx_params;
  35. static OSSL_FUNC_keyexch_get_ctx_params_fn dh_get_ctx_params;
  36. static OSSL_FUNC_keyexch_gettable_ctx_params_fn dh_gettable_ctx_params;
  37. /*
  38. * This type is only really used to handle some legacy related functionality.
  39. * If you need to use other KDF's (such as SSKDF) just use PROV_DH_KDF_NONE
  40. * here and then create and run a KDF after the key is derived.
  41. * Note that X942 has 2 variants of key derivation:
  42. * (1) DH_KDF_X9_42_ASN1 - which contains an ANS1 encoded object that has
  43. * the counter embedded in it.
  44. * (2) DH_KDF_X941_CONCAT - which is the same as ECDH_X963_KDF (which can be
  45. * done by creating a "X963KDF".
  46. */
  47. enum kdf_type {
  48. PROV_DH_KDF_NONE = 0,
  49. PROV_DH_KDF_X9_42_ASN1
  50. };
  51. /*
  52. * What's passed as an actual key is defined by the KEYMGMT interface.
  53. * We happen to know that our KEYMGMT simply passes DH structures, so
  54. * we use that here too.
  55. */
  56. typedef struct {
  57. OSSL_LIB_CTX *libctx;
  58. DH *dh;
  59. DH *dhpeer;
  60. unsigned int pad : 1;
  61. /* DH KDF */
  62. /* KDF (if any) to use for DH */
  63. enum kdf_type kdf_type;
  64. /* Message digest to use for key derivation */
  65. EVP_MD *kdf_md;
  66. /* User key material */
  67. unsigned char *kdf_ukm;
  68. size_t kdf_ukmlen;
  69. /* KDF output length */
  70. size_t kdf_outlen;
  71. char *kdf_cekalg;
  72. OSSL_FIPS_IND_DECLARE
  73. } PROV_DH_CTX;
  74. static void *dh_newctx(void *provctx)
  75. {
  76. PROV_DH_CTX *pdhctx;
  77. if (!ossl_prov_is_running())
  78. return NULL;
  79. pdhctx = OPENSSL_zalloc(sizeof(PROV_DH_CTX));
  80. if (pdhctx == NULL)
  81. return NULL;
  82. OSSL_FIPS_IND_INIT(pdhctx)
  83. pdhctx->libctx = PROV_LIBCTX_OF(provctx);
  84. pdhctx->kdf_type = PROV_DH_KDF_NONE;
  85. return pdhctx;
  86. }
  87. #ifdef FIPS_MODULE
  88. static int dh_check_key(PROV_DH_CTX *ctx)
  89. {
  90. int key_approved = ossl_dh_check_key(ctx->dh);
  91. if (!key_approved) {
  92. if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
  93. ctx->libctx, "DH Init", "DH Key",
  94. ossl_fips_config_securitycheck_enabled)) {
  95. ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
  96. return 0;
  97. }
  98. }
  99. return 1;
  100. }
  101. static int digest_check(PROV_DH_CTX *ctx, const EVP_MD *md)
  102. {
  103. return ossl_fips_ind_digest_exch_check(OSSL_FIPS_IND_GET(ctx),
  104. OSSL_FIPS_IND_SETTABLE1, ctx->libctx,
  105. md, "DH Set Ctx");
  106. }
  107. #endif
  108. static int dh_init(void *vpdhctx, void *vdh, const OSSL_PARAM params[])
  109. {
  110. PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
  111. if (!ossl_prov_is_running()
  112. || pdhctx == NULL
  113. || vdh == NULL
  114. || !DH_up_ref(vdh))
  115. return 0;
  116. DH_free(pdhctx->dh);
  117. pdhctx->dh = vdh;
  118. pdhctx->kdf_type = PROV_DH_KDF_NONE;
  119. OSSL_FIPS_IND_SET_APPROVED(pdhctx)
  120. if (!dh_set_ctx_params(pdhctx, params))
  121. return 0;
  122. #ifdef FIPS_MODULE
  123. if (!dh_check_key(pdhctx))
  124. return 0;
  125. #endif
  126. return 1;
  127. }
  128. /* The 2 parties must share the same domain parameters */
  129. static int dh_match_params(DH *priv, DH *peer)
  130. {
  131. int ret;
  132. FFC_PARAMS *dhparams_priv = ossl_dh_get0_params(priv);
  133. FFC_PARAMS *dhparams_peer = ossl_dh_get0_params(peer);
  134. ret = dhparams_priv != NULL
  135. && dhparams_peer != NULL
  136. && ossl_ffc_params_cmp(dhparams_priv, dhparams_peer, 1);
  137. if (!ret)
  138. ERR_raise(ERR_LIB_PROV, PROV_R_MISMATCHING_DOMAIN_PARAMETERS);
  139. return ret;
  140. }
  141. static int dh_set_peer(void *vpdhctx, void *vdh)
  142. {
  143. PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
  144. if (!ossl_prov_is_running()
  145. || pdhctx == NULL
  146. || vdh == NULL
  147. || !dh_match_params(vdh, pdhctx->dh)
  148. || !DH_up_ref(vdh))
  149. return 0;
  150. DH_free(pdhctx->dhpeer);
  151. pdhctx->dhpeer = vdh;
  152. return 1;
  153. }
  154. static int dh_plain_derive(void *vpdhctx,
  155. unsigned char *secret, size_t *secretlen,
  156. size_t outlen, unsigned int pad)
  157. {
  158. PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
  159. int ret;
  160. size_t dhsize;
  161. const BIGNUM *pub_key = NULL;
  162. if (pdhctx->dh == NULL || pdhctx->dhpeer == NULL) {
  163. ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY);
  164. return 0;
  165. }
  166. dhsize = (size_t)DH_size(pdhctx->dh);
  167. if (secret == NULL) {
  168. *secretlen = dhsize;
  169. return 1;
  170. }
  171. if (outlen < dhsize) {
  172. ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
  173. return 0;
  174. }
  175. DH_get0_key(pdhctx->dhpeer, &pub_key, NULL);
  176. if (pad)
  177. ret = DH_compute_key_padded(secret, pub_key, pdhctx->dh);
  178. else
  179. ret = DH_compute_key(secret, pub_key, pdhctx->dh);
  180. if (ret <= 0)
  181. return 0;
  182. *secretlen = ret;
  183. return 1;
  184. }
  185. static int dh_X9_42_kdf_derive(void *vpdhctx, unsigned char *secret,
  186. size_t *secretlen, size_t outlen)
  187. {
  188. PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
  189. unsigned char *stmp = NULL;
  190. size_t stmplen;
  191. int ret = 0;
  192. if (secret == NULL) {
  193. *secretlen = pdhctx->kdf_outlen;
  194. return 1;
  195. }
  196. if (pdhctx->kdf_outlen > outlen) {
  197. ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
  198. return 0;
  199. }
  200. if (!dh_plain_derive(pdhctx, NULL, &stmplen, 0, 1))
  201. return 0;
  202. if ((stmp = OPENSSL_secure_malloc(stmplen)) == NULL)
  203. return 0;
  204. if (!dh_plain_derive(pdhctx, stmp, &stmplen, stmplen, 1))
  205. goto err;
  206. /* Do KDF stuff */
  207. if (pdhctx->kdf_type == PROV_DH_KDF_X9_42_ASN1) {
  208. if (!ossl_dh_kdf_X9_42_asn1(secret, pdhctx->kdf_outlen,
  209. stmp, stmplen,
  210. pdhctx->kdf_cekalg,
  211. pdhctx->kdf_ukm,
  212. pdhctx->kdf_ukmlen,
  213. pdhctx->kdf_md,
  214. pdhctx->libctx, NULL))
  215. goto err;
  216. }
  217. *secretlen = pdhctx->kdf_outlen;
  218. ret = 1;
  219. err:
  220. OPENSSL_secure_clear_free(stmp, stmplen);
  221. return ret;
  222. }
  223. static int dh_derive(void *vpdhctx, unsigned char *secret,
  224. size_t *psecretlen, size_t outlen)
  225. {
  226. PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
  227. if (!ossl_prov_is_running())
  228. return 0;
  229. switch (pdhctx->kdf_type) {
  230. case PROV_DH_KDF_NONE:
  231. return dh_plain_derive(pdhctx, secret, psecretlen, outlen,
  232. pdhctx->pad);
  233. case PROV_DH_KDF_X9_42_ASN1:
  234. return dh_X9_42_kdf_derive(pdhctx, secret, psecretlen, outlen);
  235. default:
  236. break;
  237. }
  238. return 0;
  239. }
  240. static void dh_freectx(void *vpdhctx)
  241. {
  242. PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
  243. OPENSSL_free(pdhctx->kdf_cekalg);
  244. DH_free(pdhctx->dh);
  245. DH_free(pdhctx->dhpeer);
  246. EVP_MD_free(pdhctx->kdf_md);
  247. OPENSSL_clear_free(pdhctx->kdf_ukm, pdhctx->kdf_ukmlen);
  248. OPENSSL_free(pdhctx);
  249. }
  250. static void *dh_dupctx(void *vpdhctx)
  251. {
  252. PROV_DH_CTX *srcctx = (PROV_DH_CTX *)vpdhctx;
  253. PROV_DH_CTX *dstctx;
  254. if (!ossl_prov_is_running())
  255. return NULL;
  256. dstctx = OPENSSL_zalloc(sizeof(*srcctx));
  257. if (dstctx == NULL)
  258. return NULL;
  259. *dstctx = *srcctx;
  260. dstctx->dh = NULL;
  261. dstctx->dhpeer = NULL;
  262. dstctx->kdf_md = NULL;
  263. dstctx->kdf_ukm = NULL;
  264. dstctx->kdf_cekalg = NULL;
  265. if (srcctx->dh != NULL && !DH_up_ref(srcctx->dh))
  266. goto err;
  267. else
  268. dstctx->dh = srcctx->dh;
  269. if (srcctx->dhpeer != NULL && !DH_up_ref(srcctx->dhpeer))
  270. goto err;
  271. else
  272. dstctx->dhpeer = srcctx->dhpeer;
  273. if (srcctx->kdf_md != NULL && !EVP_MD_up_ref(srcctx->kdf_md))
  274. goto err;
  275. else
  276. dstctx->kdf_md = srcctx->kdf_md;
  277. /* Duplicate UKM data if present */
  278. if (srcctx->kdf_ukm != NULL && srcctx->kdf_ukmlen > 0) {
  279. dstctx->kdf_ukm = OPENSSL_memdup(srcctx->kdf_ukm,
  280. srcctx->kdf_ukmlen);
  281. if (dstctx->kdf_ukm == NULL)
  282. goto err;
  283. }
  284. if (srcctx->kdf_cekalg != NULL) {
  285. dstctx->kdf_cekalg = OPENSSL_strdup(srcctx->kdf_cekalg);
  286. if (dstctx->kdf_cekalg == NULL)
  287. goto err;
  288. }
  289. return dstctx;
  290. err:
  291. dh_freectx(dstctx);
  292. return NULL;
  293. }
  294. static int dh_set_ctx_params(void *vpdhctx, const OSSL_PARAM params[])
  295. {
  296. PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
  297. const OSSL_PARAM *p;
  298. unsigned int pad;
  299. char name[80] = { '\0' }; /* should be big enough */
  300. char *str = NULL;
  301. if (pdhctx == NULL)
  302. return 0;
  303. if (ossl_param_is_empty(params))
  304. return 1;
  305. if (!OSSL_FIPS_IND_SET_CTX_PARAM(pdhctx, OSSL_FIPS_IND_SETTABLE0, params,
  306. OSSL_EXCHANGE_PARAM_FIPS_KEY_CHECK))
  307. return 0;
  308. if (!OSSL_FIPS_IND_SET_CTX_PARAM(pdhctx, OSSL_FIPS_IND_SETTABLE1, params,
  309. OSSL_EXCHANGE_PARAM_FIPS_DIGEST_CHECK))
  310. return 0;
  311. p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_TYPE);
  312. if (p != NULL) {
  313. str = name;
  314. if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(name)))
  315. return 0;
  316. if (name[0] == '\0')
  317. pdhctx->kdf_type = PROV_DH_KDF_NONE;
  318. else if (strcmp(name, OSSL_KDF_NAME_X942KDF_ASN1) == 0)
  319. pdhctx->kdf_type = PROV_DH_KDF_X9_42_ASN1;
  320. else
  321. return 0;
  322. }
  323. p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_DIGEST);
  324. if (p != NULL) {
  325. char mdprops[80] = { '\0' }; /* should be big enough */
  326. str = name;
  327. if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(name)))
  328. return 0;
  329. str = mdprops;
  330. p = OSSL_PARAM_locate_const(params,
  331. OSSL_EXCHANGE_PARAM_KDF_DIGEST_PROPS);
  332. if (p != NULL) {
  333. if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdprops)))
  334. return 0;
  335. }
  336. EVP_MD_free(pdhctx->kdf_md);
  337. pdhctx->kdf_md = EVP_MD_fetch(pdhctx->libctx, name, mdprops);
  338. if (pdhctx->kdf_md == NULL)
  339. return 0;
  340. /* XOF digests are not allowed */
  341. if (EVP_MD_xof(pdhctx->kdf_md)) {
  342. ERR_raise(ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED);
  343. return 0;
  344. }
  345. #ifdef FIPS_MODULE
  346. if (!digest_check(pdhctx, pdhctx->kdf_md)) {
  347. EVP_MD_free(pdhctx->kdf_md);
  348. pdhctx->kdf_md = NULL;
  349. return 0;
  350. }
  351. #endif
  352. }
  353. p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_OUTLEN);
  354. if (p != NULL) {
  355. size_t outlen;
  356. if (!OSSL_PARAM_get_size_t(p, &outlen))
  357. return 0;
  358. pdhctx->kdf_outlen = outlen;
  359. }
  360. p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_UKM);
  361. if (p != NULL) {
  362. void *tmp_ukm = NULL;
  363. size_t tmp_ukmlen;
  364. OPENSSL_free(pdhctx->kdf_ukm);
  365. pdhctx->kdf_ukm = NULL;
  366. pdhctx->kdf_ukmlen = 0;
  367. /* ukm is an optional field so it can be NULL */
  368. if (p->data != NULL && p->data_size != 0) {
  369. if (!OSSL_PARAM_get_octet_string(p, &tmp_ukm, 0, &tmp_ukmlen))
  370. return 0;
  371. pdhctx->kdf_ukm = tmp_ukm;
  372. pdhctx->kdf_ukmlen = tmp_ukmlen;
  373. }
  374. }
  375. p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_PAD);
  376. if (p != NULL) {
  377. if (!OSSL_PARAM_get_uint(p, &pad))
  378. return 0;
  379. pdhctx->pad = pad ? 1 : 0;
  380. }
  381. p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_CEK_ALG);
  382. if (p != NULL) {
  383. str = name;
  384. OPENSSL_free(pdhctx->kdf_cekalg);
  385. pdhctx->kdf_cekalg = NULL;
  386. if (p->data != NULL && p->data_size != 0) {
  387. if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(name)))
  388. return 0;
  389. pdhctx->kdf_cekalg = OPENSSL_strdup(name);
  390. if (pdhctx->kdf_cekalg == NULL)
  391. return 0;
  392. }
  393. }
  394. return 1;
  395. }
  396. static const OSSL_PARAM known_settable_ctx_params[] = {
  397. OSSL_PARAM_int(OSSL_EXCHANGE_PARAM_PAD, NULL),
  398. OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, NULL, 0),
  399. OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, NULL, 0),
  400. OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST_PROPS, NULL, 0),
  401. OSSL_PARAM_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, NULL),
  402. OSSL_PARAM_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM, NULL, 0),
  403. OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CEK_ALG, NULL, 0),
  404. OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_EXCHANGE_PARAM_FIPS_KEY_CHECK)
  405. OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_EXCHANGE_PARAM_FIPS_DIGEST_CHECK)
  406. OSSL_PARAM_END
  407. };
  408. static const OSSL_PARAM *dh_settable_ctx_params(ossl_unused void *vpdhctx,
  409. ossl_unused void *provctx)
  410. {
  411. return known_settable_ctx_params;
  412. }
  413. static const OSSL_PARAM known_gettable_ctx_params[] = {
  414. OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, NULL, 0),
  415. OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, NULL, 0),
  416. OSSL_PARAM_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, NULL),
  417. OSSL_PARAM_DEFN(OSSL_EXCHANGE_PARAM_KDF_UKM, OSSL_PARAM_OCTET_PTR,
  418. NULL, 0),
  419. OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CEK_ALG, NULL, 0),
  420. OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
  421. OSSL_PARAM_END
  422. };
  423. static const OSSL_PARAM *dh_gettable_ctx_params(ossl_unused void *vpdhctx,
  424. ossl_unused void *provctx)
  425. {
  426. return known_gettable_ctx_params;
  427. }
  428. static int dh_get_ctx_params(void *vpdhctx, OSSL_PARAM params[])
  429. {
  430. PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
  431. OSSL_PARAM *p;
  432. if (pdhctx == NULL)
  433. return 0;
  434. p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_TYPE);
  435. if (p != NULL) {
  436. const char *kdf_type = NULL;
  437. switch (pdhctx->kdf_type) {
  438. case PROV_DH_KDF_NONE:
  439. kdf_type = "";
  440. break;
  441. case PROV_DH_KDF_X9_42_ASN1:
  442. kdf_type = OSSL_KDF_NAME_X942KDF_ASN1;
  443. break;
  444. default:
  445. return 0;
  446. }
  447. if (!OSSL_PARAM_set_utf8_string(p, kdf_type))
  448. return 0;
  449. }
  450. p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_DIGEST);
  451. if (p != NULL
  452. && !OSSL_PARAM_set_utf8_string(p, pdhctx->kdf_md == NULL
  453. ? ""
  454. : EVP_MD_get0_name(pdhctx->kdf_md))) {
  455. return 0;
  456. }
  457. p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_OUTLEN);
  458. if (p != NULL && !OSSL_PARAM_set_size_t(p, pdhctx->kdf_outlen))
  459. return 0;
  460. p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_UKM);
  461. if (p != NULL
  462. && !OSSL_PARAM_set_octet_ptr(p, pdhctx->kdf_ukm, pdhctx->kdf_ukmlen))
  463. return 0;
  464. p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_CEK_ALG);
  465. if (p != NULL
  466. && !OSSL_PARAM_set_utf8_string(p, pdhctx->kdf_cekalg == NULL
  467. ? "" : pdhctx->kdf_cekalg))
  468. return 0;
  469. if (!OSSL_FIPS_IND_GET_CTX_PARAM(pdhctx, params))
  470. return 0;
  471. return 1;
  472. }
  473. const OSSL_DISPATCH ossl_dh_keyexch_functions[] = {
  474. { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))dh_newctx },
  475. { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))dh_init },
  476. { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))dh_derive },
  477. { OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))dh_set_peer },
  478. { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))dh_freectx },
  479. { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))dh_dupctx },
  480. { OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, (void (*)(void))dh_set_ctx_params },
  481. { OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS,
  482. (void (*)(void))dh_settable_ctx_params },
  483. { OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS, (void (*)(void))dh_get_ctx_params },
  484. { OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS,
  485. (void (*)(void))dh_gettable_ctx_params },
  486. OSSL_DISPATCH_END
  487. };