xref: /freebsd-src/crypto/openssl/crypto/evp/dh_ctrl.c (revision b077aed33b7b6aefca7b17ddb250cf521f938613)
1*b077aed3SPierre Pronchery /*
2*b077aed3SPierre Pronchery  * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
3*b077aed3SPierre Pronchery  *
4*b077aed3SPierre Pronchery  * Licensed under the Apache License 2.0 (the "License").  You may not use
5*b077aed3SPierre Pronchery  * this file except in compliance with the License.  You can obtain a copy
6*b077aed3SPierre Pronchery  * in the file LICENSE in the source distribution or at
7*b077aed3SPierre Pronchery  * https://www.openssl.org/source/license.html
8*b077aed3SPierre Pronchery  */
9*b077aed3SPierre Pronchery 
10*b077aed3SPierre Pronchery #include "internal/deprecated.h"
11*b077aed3SPierre Pronchery 
12*b077aed3SPierre Pronchery #include <openssl/core_names.h>
13*b077aed3SPierre Pronchery #include <openssl/params.h>
14*b077aed3SPierre Pronchery #include <openssl/err.h>
15*b077aed3SPierre Pronchery #include <openssl/dh.h>
16*b077aed3SPierre Pronchery #include "crypto/dh.h"
17*b077aed3SPierre Pronchery #include "crypto/evp.h"
18*b077aed3SPierre Pronchery 
dh_paramgen_check(EVP_PKEY_CTX * ctx)19*b077aed3SPierre Pronchery static int dh_paramgen_check(EVP_PKEY_CTX *ctx)
20*b077aed3SPierre Pronchery {
21*b077aed3SPierre Pronchery     if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
22*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
23*b077aed3SPierre Pronchery         /* Uses the same return values as EVP_PKEY_CTX_ctrl */
24*b077aed3SPierre Pronchery         return -2;
25*b077aed3SPierre Pronchery     }
26*b077aed3SPierre Pronchery     /* If key type not DH return error */
27*b077aed3SPierre Pronchery     if (evp_pkey_ctx_is_legacy(ctx)
28*b077aed3SPierre Pronchery         && ctx->pmeth->pkey_id != EVP_PKEY_DH
29*b077aed3SPierre Pronchery         && ctx->pmeth->pkey_id != EVP_PKEY_DHX)
30*b077aed3SPierre Pronchery         return -1;
31*b077aed3SPierre Pronchery     return 1;
32*b077aed3SPierre Pronchery }
33*b077aed3SPierre Pronchery 
dh_param_derive_check(EVP_PKEY_CTX * ctx)34*b077aed3SPierre Pronchery static int dh_param_derive_check(EVP_PKEY_CTX *ctx)
35*b077aed3SPierre Pronchery {
36*b077aed3SPierre Pronchery     if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) {
37*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
38*b077aed3SPierre Pronchery         /* Uses the same return values as EVP_PKEY_CTX_ctrl */
39*b077aed3SPierre Pronchery         return -2;
40*b077aed3SPierre Pronchery     }
41*b077aed3SPierre Pronchery     /* If key type not DH return error */
42*b077aed3SPierre Pronchery     if (evp_pkey_ctx_is_legacy(ctx)
43*b077aed3SPierre Pronchery         && ctx->pmeth->pkey_id != EVP_PKEY_DH
44*b077aed3SPierre Pronchery         && ctx->pmeth->pkey_id != EVP_PKEY_DHX)
45*b077aed3SPierre Pronchery         return -1;
46*b077aed3SPierre Pronchery     return 1;
47*b077aed3SPierre Pronchery }
48*b077aed3SPierre Pronchery 
EVP_PKEY_CTX_set_dh_paramgen_gindex(EVP_PKEY_CTX * ctx,int gindex)49*b077aed3SPierre Pronchery int EVP_PKEY_CTX_set_dh_paramgen_gindex(EVP_PKEY_CTX *ctx, int gindex)
50*b077aed3SPierre Pronchery {
51*b077aed3SPierre Pronchery     int ret;
52*b077aed3SPierre Pronchery     OSSL_PARAM params[2], *p = params;
53*b077aed3SPierre Pronchery 
54*b077aed3SPierre Pronchery     if ((ret = dh_paramgen_check(ctx)) <= 0)
55*b077aed3SPierre Pronchery         return ret;
56*b077aed3SPierre Pronchery 
57*b077aed3SPierre Pronchery     *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_FFC_GINDEX, &gindex);
58*b077aed3SPierre Pronchery     *p = OSSL_PARAM_construct_end();
59*b077aed3SPierre Pronchery 
60*b077aed3SPierre Pronchery     return evp_pkey_ctx_set_params_strict(ctx, params);
61*b077aed3SPierre Pronchery }
62*b077aed3SPierre Pronchery 
EVP_PKEY_CTX_set_dh_paramgen_seed(EVP_PKEY_CTX * ctx,const unsigned char * seed,size_t seedlen)63*b077aed3SPierre Pronchery int EVP_PKEY_CTX_set_dh_paramgen_seed(EVP_PKEY_CTX *ctx,
64*b077aed3SPierre Pronchery                                       const unsigned char *seed,
65*b077aed3SPierre Pronchery                                       size_t seedlen)
66*b077aed3SPierre Pronchery {
67*b077aed3SPierre Pronchery     int ret;
68*b077aed3SPierre Pronchery     OSSL_PARAM params[2], *p = params;
69*b077aed3SPierre Pronchery 
70*b077aed3SPierre Pronchery     if ((ret = dh_paramgen_check(ctx)) <= 0)
71*b077aed3SPierre Pronchery         return ret;
72*b077aed3SPierre Pronchery 
73*b077aed3SPierre Pronchery     *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_FFC_SEED,
74*b077aed3SPierre Pronchery                                              (void *)seed, seedlen);
75*b077aed3SPierre Pronchery     *p = OSSL_PARAM_construct_end();
76*b077aed3SPierre Pronchery 
77*b077aed3SPierre Pronchery     return evp_pkey_ctx_set_params_strict(ctx, params);
78*b077aed3SPierre Pronchery }
79*b077aed3SPierre Pronchery 
80*b077aed3SPierre Pronchery /*
81*b077aed3SPierre Pronchery  * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
82*b077aed3SPierre Pronchery  * simply because that's easier.
83*b077aed3SPierre Pronchery  */
EVP_PKEY_CTX_set_dh_paramgen_type(EVP_PKEY_CTX * ctx,int typ)84*b077aed3SPierre Pronchery int EVP_PKEY_CTX_set_dh_paramgen_type(EVP_PKEY_CTX *ctx, int typ)
85*b077aed3SPierre Pronchery {
86*b077aed3SPierre Pronchery     return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN,
87*b077aed3SPierre Pronchery                              EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, typ, NULL);
88*b077aed3SPierre Pronchery }
89*b077aed3SPierre Pronchery 
EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX * ctx,int pbits)90*b077aed3SPierre Pronchery int EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int pbits)
91*b077aed3SPierre Pronchery {
92*b077aed3SPierre Pronchery     int ret;
93*b077aed3SPierre Pronchery     OSSL_PARAM params[2], *p = params;
94*b077aed3SPierre Pronchery     size_t bits = pbits;
95*b077aed3SPierre Pronchery 
96*b077aed3SPierre Pronchery     if ((ret = dh_paramgen_check(ctx)) <= 0)
97*b077aed3SPierre Pronchery         return ret;
98*b077aed3SPierre Pronchery 
99*b077aed3SPierre Pronchery     *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_FFC_PBITS, &bits);
100*b077aed3SPierre Pronchery     *p = OSSL_PARAM_construct_end();
101*b077aed3SPierre Pronchery     return evp_pkey_ctx_set_params_strict(ctx, params);
102*b077aed3SPierre Pronchery }
103*b077aed3SPierre Pronchery 
EVP_PKEY_CTX_set_dh_paramgen_subprime_len(EVP_PKEY_CTX * ctx,int qbits)104*b077aed3SPierre Pronchery int EVP_PKEY_CTX_set_dh_paramgen_subprime_len(EVP_PKEY_CTX *ctx, int qbits)
105*b077aed3SPierre Pronchery {
106*b077aed3SPierre Pronchery     int ret;
107*b077aed3SPierre Pronchery     OSSL_PARAM params[2], *p = params;
108*b077aed3SPierre Pronchery     size_t bits2 = qbits;
109*b077aed3SPierre Pronchery 
110*b077aed3SPierre Pronchery     if ((ret = dh_paramgen_check(ctx)) <= 0)
111*b077aed3SPierre Pronchery         return ret;
112*b077aed3SPierre Pronchery 
113*b077aed3SPierre Pronchery     *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_FFC_QBITS, &bits2);
114*b077aed3SPierre Pronchery     *p = OSSL_PARAM_construct_end();
115*b077aed3SPierre Pronchery 
116*b077aed3SPierre Pronchery     return evp_pkey_ctx_set_params_strict(ctx, params);
117*b077aed3SPierre Pronchery }
118*b077aed3SPierre Pronchery 
EVP_PKEY_CTX_set_dh_paramgen_generator(EVP_PKEY_CTX * ctx,int gen)119*b077aed3SPierre Pronchery int EVP_PKEY_CTX_set_dh_paramgen_generator(EVP_PKEY_CTX *ctx, int gen)
120*b077aed3SPierre Pronchery {
121*b077aed3SPierre Pronchery     int ret;
122*b077aed3SPierre Pronchery     OSSL_PARAM params[2], *p = params;
123*b077aed3SPierre Pronchery 
124*b077aed3SPierre Pronchery     if ((ret = dh_paramgen_check(ctx)) <= 0)
125*b077aed3SPierre Pronchery         return ret;
126*b077aed3SPierre Pronchery 
127*b077aed3SPierre Pronchery     *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_DH_GENERATOR, &gen);
128*b077aed3SPierre Pronchery     *p = OSSL_PARAM_construct_end();
129*b077aed3SPierre Pronchery 
130*b077aed3SPierre Pronchery     return evp_pkey_ctx_set_params_strict(ctx, params);
131*b077aed3SPierre Pronchery }
132*b077aed3SPierre Pronchery 
133*b077aed3SPierre Pronchery /*
134*b077aed3SPierre Pronchery  * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
135*b077aed3SPierre Pronchery  * simply because that's easier.
136*b077aed3SPierre Pronchery  */
EVP_PKEY_CTX_set_dh_rfc5114(EVP_PKEY_CTX * ctx,int gen)137*b077aed3SPierre Pronchery int EVP_PKEY_CTX_set_dh_rfc5114(EVP_PKEY_CTX *ctx, int gen)
138*b077aed3SPierre Pronchery {
139*b077aed3SPierre Pronchery     return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN,
140*b077aed3SPierre Pronchery                              EVP_PKEY_CTRL_DH_RFC5114, gen, NULL);
141*b077aed3SPierre Pronchery }
142*b077aed3SPierre Pronchery 
EVP_PKEY_CTX_set_dhx_rfc5114(EVP_PKEY_CTX * ctx,int gen)143*b077aed3SPierre Pronchery int EVP_PKEY_CTX_set_dhx_rfc5114(EVP_PKEY_CTX *ctx, int gen)
144*b077aed3SPierre Pronchery {
145*b077aed3SPierre Pronchery     return EVP_PKEY_CTX_set_dh_rfc5114(ctx, gen);
146*b077aed3SPierre Pronchery }
147*b077aed3SPierre Pronchery 
148*b077aed3SPierre Pronchery /*
149*b077aed3SPierre Pronchery  * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
150*b077aed3SPierre Pronchery  * simply because that's easier.
151*b077aed3SPierre Pronchery  */
EVP_PKEY_CTX_set_dh_nid(EVP_PKEY_CTX * ctx,int nid)152*b077aed3SPierre Pronchery int EVP_PKEY_CTX_set_dh_nid(EVP_PKEY_CTX *ctx, int nid)
153*b077aed3SPierre Pronchery {
154*b077aed3SPierre Pronchery     return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH,
155*b077aed3SPierre Pronchery                              EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN,
156*b077aed3SPierre Pronchery                              EVP_PKEY_CTRL_DH_NID, nid, NULL);
157*b077aed3SPierre Pronchery }
158*b077aed3SPierre Pronchery 
EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX * ctx,int pad)159*b077aed3SPierre Pronchery int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad)
160*b077aed3SPierre Pronchery {
161*b077aed3SPierre Pronchery     OSSL_PARAM dh_pad_params[2];
162*b077aed3SPierre Pronchery     unsigned int upad = pad;
163*b077aed3SPierre Pronchery 
164*b077aed3SPierre Pronchery     /* We use EVP_PKEY_CTX_ctrl return values */
165*b077aed3SPierre Pronchery     if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) {
166*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
167*b077aed3SPierre Pronchery         return -2;
168*b077aed3SPierre Pronchery     }
169*b077aed3SPierre Pronchery 
170*b077aed3SPierre Pronchery     dh_pad_params[0] = OSSL_PARAM_construct_uint(OSSL_EXCHANGE_PARAM_PAD, &upad);
171*b077aed3SPierre Pronchery     dh_pad_params[1] = OSSL_PARAM_construct_end();
172*b077aed3SPierre Pronchery 
173*b077aed3SPierre Pronchery     return evp_pkey_ctx_set_params_strict(ctx, dh_pad_params);
174*b077aed3SPierre Pronchery }
175*b077aed3SPierre Pronchery 
176*b077aed3SPierre Pronchery /*
177*b077aed3SPierre Pronchery  * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
178*b077aed3SPierre Pronchery  * simply because that's easier.
179*b077aed3SPierre Pronchery  */
EVP_PKEY_CTX_set_dh_kdf_type(EVP_PKEY_CTX * ctx,int kdf)180*b077aed3SPierre Pronchery int EVP_PKEY_CTX_set_dh_kdf_type(EVP_PKEY_CTX *ctx, int kdf)
181*b077aed3SPierre Pronchery {
182*b077aed3SPierre Pronchery     return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
183*b077aed3SPierre Pronchery                              EVP_PKEY_CTRL_DH_KDF_TYPE, kdf, NULL);
184*b077aed3SPierre Pronchery }
185*b077aed3SPierre Pronchery 
186*b077aed3SPierre Pronchery /*
187*b077aed3SPierre Pronchery  * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
188*b077aed3SPierre Pronchery  * simply because that's easier.
189*b077aed3SPierre Pronchery  */
EVP_PKEY_CTX_get_dh_kdf_type(EVP_PKEY_CTX * ctx)190*b077aed3SPierre Pronchery int EVP_PKEY_CTX_get_dh_kdf_type(EVP_PKEY_CTX *ctx)
191*b077aed3SPierre Pronchery {
192*b077aed3SPierre Pronchery     return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
193*b077aed3SPierre Pronchery                              EVP_PKEY_CTRL_DH_KDF_TYPE, -2, NULL);
194*b077aed3SPierre Pronchery }
195*b077aed3SPierre Pronchery 
196*b077aed3SPierre Pronchery /*
197*b077aed3SPierre Pronchery  * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
198*b077aed3SPierre Pronchery  * simply because that's easier.
199*b077aed3SPierre Pronchery  */
EVP_PKEY_CTX_set0_dh_kdf_oid(EVP_PKEY_CTX * ctx,ASN1_OBJECT * oid)200*b077aed3SPierre Pronchery int EVP_PKEY_CTX_set0_dh_kdf_oid(EVP_PKEY_CTX *ctx, ASN1_OBJECT *oid)
201*b077aed3SPierre Pronchery {
202*b077aed3SPierre Pronchery     return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
203*b077aed3SPierre Pronchery                              EVP_PKEY_CTRL_DH_KDF_OID, 0, (void *)(oid));
204*b077aed3SPierre Pronchery }
205*b077aed3SPierre Pronchery 
206*b077aed3SPierre Pronchery /*
207*b077aed3SPierre Pronchery  * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
208*b077aed3SPierre Pronchery  * simply because that's easier.
209*b077aed3SPierre Pronchery  */
EVP_PKEY_CTX_get0_dh_kdf_oid(EVP_PKEY_CTX * ctx,ASN1_OBJECT ** oid)210*b077aed3SPierre Pronchery int EVP_PKEY_CTX_get0_dh_kdf_oid(EVP_PKEY_CTX *ctx, ASN1_OBJECT **oid)
211*b077aed3SPierre Pronchery {
212*b077aed3SPierre Pronchery     return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
213*b077aed3SPierre Pronchery                              EVP_PKEY_CTRL_GET_DH_KDF_OID, 0, (void *)(oid));
214*b077aed3SPierre Pronchery }
215*b077aed3SPierre Pronchery 
216*b077aed3SPierre Pronchery /*
217*b077aed3SPierre Pronchery  * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
218*b077aed3SPierre Pronchery  * simply because that's easier.
219*b077aed3SPierre Pronchery  */
EVP_PKEY_CTX_set_dh_kdf_md(EVP_PKEY_CTX * ctx,const EVP_MD * md)220*b077aed3SPierre Pronchery int EVP_PKEY_CTX_set_dh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
221*b077aed3SPierre Pronchery {
222*b077aed3SPierre Pronchery     return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
223*b077aed3SPierre Pronchery                              EVP_PKEY_CTRL_DH_KDF_MD, 0, (void *)(md));
224*b077aed3SPierre Pronchery }
225*b077aed3SPierre Pronchery 
226*b077aed3SPierre Pronchery /*
227*b077aed3SPierre Pronchery  * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
228*b077aed3SPierre Pronchery  * simply because that's easier.
229*b077aed3SPierre Pronchery  */
EVP_PKEY_CTX_get_dh_kdf_md(EVP_PKEY_CTX * ctx,const EVP_MD ** pmd)230*b077aed3SPierre Pronchery int EVP_PKEY_CTX_get_dh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD **pmd)
231*b077aed3SPierre Pronchery {
232*b077aed3SPierre Pronchery         return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
233*b077aed3SPierre Pronchery                                  EVP_PKEY_CTRL_GET_DH_KDF_MD, 0, (void *)(pmd));
234*b077aed3SPierre Pronchery }
235*b077aed3SPierre Pronchery 
EVP_PKEY_CTX_set_dh_kdf_outlen(EVP_PKEY_CTX * ctx,int outlen)236*b077aed3SPierre Pronchery int EVP_PKEY_CTX_set_dh_kdf_outlen(EVP_PKEY_CTX *ctx, int outlen)
237*b077aed3SPierre Pronchery {
238*b077aed3SPierre Pronchery     int ret;
239*b077aed3SPierre Pronchery     size_t len = outlen;
240*b077aed3SPierre Pronchery     OSSL_PARAM params[2], *p = params;
241*b077aed3SPierre Pronchery 
242*b077aed3SPierre Pronchery     ret = dh_param_derive_check(ctx);
243*b077aed3SPierre Pronchery     if (ret != 1)
244*b077aed3SPierre Pronchery         return ret;
245*b077aed3SPierre Pronchery 
246*b077aed3SPierre Pronchery     if (outlen <= 0) {
247*b077aed3SPierre Pronchery         /*
248*b077aed3SPierre Pronchery          * This would ideally be -1 or 0, but we have to retain compatibility
249*b077aed3SPierre Pronchery          * with legacy behaviour of EVP_PKEY_CTX_ctrl() which returned -2 if
250*b077aed3SPierre Pronchery          * inlen <= 0
251*b077aed3SPierre Pronchery          */
252*b077aed3SPierre Pronchery         return -2;
253*b077aed3SPierre Pronchery     }
254*b077aed3SPierre Pronchery 
255*b077aed3SPierre Pronchery     *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN,
256*b077aed3SPierre Pronchery                                        &len);
257*b077aed3SPierre Pronchery     *p = OSSL_PARAM_construct_end();
258*b077aed3SPierre Pronchery 
259*b077aed3SPierre Pronchery     ret = evp_pkey_ctx_set_params_strict(ctx, params);
260*b077aed3SPierre Pronchery     if (ret == -2)
261*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
262*b077aed3SPierre Pronchery     return ret;
263*b077aed3SPierre Pronchery }
264*b077aed3SPierre Pronchery 
EVP_PKEY_CTX_get_dh_kdf_outlen(EVP_PKEY_CTX * ctx,int * plen)265*b077aed3SPierre Pronchery int EVP_PKEY_CTX_get_dh_kdf_outlen(EVP_PKEY_CTX *ctx, int *plen)
266*b077aed3SPierre Pronchery {
267*b077aed3SPierre Pronchery     int ret;
268*b077aed3SPierre Pronchery     size_t len = UINT_MAX;
269*b077aed3SPierre Pronchery     OSSL_PARAM params[2], *p = params;
270*b077aed3SPierre Pronchery 
271*b077aed3SPierre Pronchery     ret = dh_param_derive_check(ctx);
272*b077aed3SPierre Pronchery     if (ret != 1)
273*b077aed3SPierre Pronchery         return ret;
274*b077aed3SPierre Pronchery 
275*b077aed3SPierre Pronchery     *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN,
276*b077aed3SPierre Pronchery                                        &len);
277*b077aed3SPierre Pronchery     *p = OSSL_PARAM_construct_end();
278*b077aed3SPierre Pronchery 
279*b077aed3SPierre Pronchery     ret = evp_pkey_ctx_get_params_strict(ctx, params);
280*b077aed3SPierre Pronchery     if (ret == -2)
281*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
282*b077aed3SPierre Pronchery     if (ret != 1 || len > INT_MAX)
283*b077aed3SPierre Pronchery         return -1;
284*b077aed3SPierre Pronchery 
285*b077aed3SPierre Pronchery     *plen = (int)len;
286*b077aed3SPierre Pronchery 
287*b077aed3SPierre Pronchery     return 1;
288*b077aed3SPierre Pronchery }
289*b077aed3SPierre Pronchery 
EVP_PKEY_CTX_set0_dh_kdf_ukm(EVP_PKEY_CTX * ctx,unsigned char * ukm,int len)290*b077aed3SPierre Pronchery int EVP_PKEY_CTX_set0_dh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char *ukm, int len)
291*b077aed3SPierre Pronchery {
292*b077aed3SPierre Pronchery     int ret;
293*b077aed3SPierre Pronchery     OSSL_PARAM params[2], *p = params;
294*b077aed3SPierre Pronchery 
295*b077aed3SPierre Pronchery     if (len < 0)
296*b077aed3SPierre Pronchery         return -1;
297*b077aed3SPierre Pronchery 
298*b077aed3SPierre Pronchery     ret = dh_param_derive_check(ctx);
299*b077aed3SPierre Pronchery     if (ret != 1)
300*b077aed3SPierre Pronchery         return ret;
301*b077aed3SPierre Pronchery 
302*b077aed3SPierre Pronchery     *p++ = OSSL_PARAM_construct_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM,
303*b077aed3SPierre Pronchery                                             /*
304*b077aed3SPierre Pronchery                                              * Cast away the const. This is read
305*b077aed3SPierre Pronchery                                              * only so should be safe
306*b077aed3SPierre Pronchery                                              */
307*b077aed3SPierre Pronchery                                             (void *)ukm,
308*b077aed3SPierre Pronchery                                             (size_t)len);
309*b077aed3SPierre Pronchery     *p = OSSL_PARAM_construct_end();
310*b077aed3SPierre Pronchery 
311*b077aed3SPierre Pronchery     ret = evp_pkey_ctx_set_params_strict(ctx, params);
312*b077aed3SPierre Pronchery     if (ret == -2)
313*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
314*b077aed3SPierre Pronchery     if (ret == 1)
315*b077aed3SPierre Pronchery         OPENSSL_free(ukm);
316*b077aed3SPierre Pronchery     return ret;
317*b077aed3SPierre Pronchery }
318*b077aed3SPierre Pronchery 
319*b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DEPRECATED_3_0
EVP_PKEY_CTX_get0_dh_kdf_ukm(EVP_PKEY_CTX * ctx,unsigned char ** pukm)320*b077aed3SPierre Pronchery int EVP_PKEY_CTX_get0_dh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **pukm)
321*b077aed3SPierre Pronchery {
322*b077aed3SPierre Pronchery     int ret;
323*b077aed3SPierre Pronchery     size_t ukmlen;
324*b077aed3SPierre Pronchery     OSSL_PARAM params[2], *p = params;
325*b077aed3SPierre Pronchery 
326*b077aed3SPierre Pronchery     ret = dh_param_derive_check(ctx);
327*b077aed3SPierre Pronchery     if (ret != 1)
328*b077aed3SPierre Pronchery         return ret;
329*b077aed3SPierre Pronchery 
330*b077aed3SPierre Pronchery     *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_EXCHANGE_PARAM_KDF_UKM,
331*b077aed3SPierre Pronchery                                           (void **)pukm, 0);
332*b077aed3SPierre Pronchery     *p = OSSL_PARAM_construct_end();
333*b077aed3SPierre Pronchery 
334*b077aed3SPierre Pronchery     ret = evp_pkey_ctx_get_params_strict(ctx, params);
335*b077aed3SPierre Pronchery     if (ret == -2)
336*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
337*b077aed3SPierre Pronchery     if (ret != 1)
338*b077aed3SPierre Pronchery         return -1;
339*b077aed3SPierre Pronchery 
340*b077aed3SPierre Pronchery     ukmlen = params[0].return_size;
341*b077aed3SPierre Pronchery     if (ukmlen > INT_MAX)
342*b077aed3SPierre Pronchery         return -1;
343*b077aed3SPierre Pronchery 
344*b077aed3SPierre Pronchery     return (int)ukmlen;
345*b077aed3SPierre Pronchery }
346*b077aed3SPierre Pronchery #endif
347