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