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