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