]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/dh/dh_pmeth.c
Revert "EVP_*Update: ensure that input NULL with length 0 isn't passed"
[thirdparty/openssl.git] / crypto / dh / dh_pmeth.c
CommitLineData
0f113f3e 1/*
28428130 2 * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
3ba0885a 3 *
e38873f5 4 * Licensed under the Apache License 2.0 (the "License"). You may not use
aa6bb135
RS
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
3ba0885a
DSH
8 */
9
10#include <stdio.h>
b39fc560 11#include "internal/cryptlib.h"
3ba0885a
DSH
12#include <openssl/asn1t.h>
13#include <openssl/x509.h>
3ba0885a 14#include <openssl/evp.h>
0aeddcfa 15#include "dh_locl.h"
1e26a8ba 16#include <openssl/bn.h>
3c27208f 17#include <openssl/dsa.h>
bd59f2b9 18#include <openssl/objects.h>
27af42f9 19#include "internal/evp_int.h"
3ba0885a
DSH
20
21/* DH pkey context structure */
22
0f113f3e
MC
23typedef struct {
24 /* Parameter gen parameters */
25 int prime_len;
26 int generator;
27 int use_dsa;
28 int subprime_len;
f4403a1f 29 int pad;
0f113f3e
MC
30 /* message digest used for parameter generation */
31 const EVP_MD *md;
32 int rfc5114_param;
d59d853a 33 int param_nid;
0f113f3e
MC
34 /* Keygen callback info */
35 int gentmp[2];
36 /* KDF (if any) to use for DH */
37 char kdf_type;
38 /* OID to use for KDF */
39 ASN1_OBJECT *kdf_oid;
40 /* Message digest to use for key derivation */
41 const EVP_MD *kdf_md;
42 /* User key material */
43 unsigned char *kdf_ukm;
44 size_t kdf_ukmlen;
45 /* KDF output length */
46 size_t kdf_outlen;
47} DH_PKEY_CTX;
3ba0885a
DSH
48
49static int pkey_dh_init(EVP_PKEY_CTX *ctx)
0f113f3e
MC
50{
51 DH_PKEY_CTX *dctx;
64b25758 52
cdb10bae
RS
53 if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL) {
54 DHerr(DH_F_PKEY_DH_INIT, ERR_R_MALLOC_FAILURE);
0f113f3e 55 return 0;
cdb10bae 56 }
0f113f3e
MC
57 dctx->prime_len = 1024;
58 dctx->subprime_len = -1;
59 dctx->generator = 2;
0f113f3e 60 dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
0f113f3e
MC
61
62 ctx->data = dctx;
63 ctx->keygen_info = dctx->gentmp;
64 ctx->keygen_info_count = 2;
65
66 return 1;
67}
3ba0885a 68
edeb3fd2
IY
69static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
70{
71 DH_PKEY_CTX *dctx = ctx->data;
72 if (dctx != NULL) {
73 OPENSSL_free(dctx->kdf_ukm);
74 ASN1_OBJECT_free(dctx->kdf_oid);
75 OPENSSL_free(dctx);
76 }
77}
78
79
9fdcc21f 80static int pkey_dh_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
0f113f3e
MC
81{
82 DH_PKEY_CTX *dctx, *sctx;
83 if (!pkey_dh_init(dst))
84 return 0;
85 sctx = src->data;
86 dctx = dst->data;
87 dctx->prime_len = sctx->prime_len;
88 dctx->subprime_len = sctx->subprime_len;
89 dctx->generator = sctx->generator;
90 dctx->use_dsa = sctx->use_dsa;
f4403a1f 91 dctx->pad = sctx->pad;
0f113f3e
MC
92 dctx->md = sctx->md;
93 dctx->rfc5114_param = sctx->rfc5114_param;
d59d853a 94 dctx->param_nid = sctx->param_nid;
0f113f3e
MC
95
96 dctx->kdf_type = sctx->kdf_type;
97 dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
edeb3fd2 98 if (dctx->kdf_oid == NULL)
0f113f3e
MC
99 return 0;
100 dctx->kdf_md = sctx->kdf_md;
edeb3fd2 101 if (sctx->kdf_ukm != NULL) {
7644a9ae 102 dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
edeb3fd2
IY
103 if (dctx->kdf_ukm == NULL)
104 return 0;
0f113f3e
MC
105 dctx->kdf_ukmlen = sctx->kdf_ukmlen;
106 }
107 dctx->kdf_outlen = sctx->kdf_outlen;
108 return 1;
109}
8bdcef40 110
3ba0885a 111static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
0f113f3e
MC
112{
113 DH_PKEY_CTX *dctx = ctx->data;
114 switch (type) {
115 case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
116 if (p1 < 256)
117 return -2;
118 dctx->prime_len = p1;
119 return 1;
120
121 case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
122 if (dctx->use_dsa == 0)
123 return -2;
124 dctx->subprime_len = p1;
125 return 1;
126
f4403a1f
DSH
127 case EVP_PKEY_CTRL_DH_PAD:
128 dctx->pad = p1;
129 return 1;
130
0f113f3e
MC
131 case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
132 if (dctx->use_dsa)
133 return -2;
134 dctx->generator = p1;
135 return 1;
136
137 case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
39090878 138#ifdef OPENSSL_NO_DSA
0f113f3e
MC
139 if (p1 != 0)
140 return -2;
39090878 141#else
0f113f3e
MC
142 if (p1 < 0 || p1 > 2)
143 return -2;
39090878 144#endif
0f113f3e
MC
145 dctx->use_dsa = p1;
146 return 1;
147
148 case EVP_PKEY_CTRL_DH_RFC5114:
d59d853a 149 if (p1 < 1 || p1 > 3 || dctx->param_nid != NID_undef)
0f113f3e
MC
150 return -2;
151 dctx->rfc5114_param = p1;
152 return 1;
153
d59d853a
DSH
154 case EVP_PKEY_CTRL_DH_NID:
155 if (p1 <= 0 || dctx->rfc5114_param != 0)
156 return -2;
157 dctx->param_nid = p1;
158 return 1;
159
0f113f3e
MC
160 case EVP_PKEY_CTRL_PEER_KEY:
161 /* Default behaviour is OK */
162 return 1;
163
164 case EVP_PKEY_CTRL_DH_KDF_TYPE:
165 if (p1 == -2)
166 return dctx->kdf_type;
e968561d
DB
167#ifdef OPENSSL_NO_CMS
168 if (p1 != EVP_PKEY_DH_KDF_NONE)
169#else
0f113f3e 170 if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
e968561d 171#endif
0f113f3e
MC
172 return -2;
173 dctx->kdf_type = p1;
174 return 1;
175
176 case EVP_PKEY_CTRL_DH_KDF_MD:
177 dctx->kdf_md = p2;
178 return 1;
179
180 case EVP_PKEY_CTRL_GET_DH_KDF_MD:
181 *(const EVP_MD **)p2 = dctx->kdf_md;
182 return 1;
183
184 case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
185 if (p1 <= 0)
186 return -2;
187 dctx->kdf_outlen = (size_t)p1;
188 return 1;
189
190 case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
191 *(int *)p2 = dctx->kdf_outlen;
192 return 1;
193
194 case EVP_PKEY_CTRL_DH_KDF_UKM:
b548a1f1 195 OPENSSL_free(dctx->kdf_ukm);
0f113f3e
MC
196 dctx->kdf_ukm = p2;
197 if (p2)
198 dctx->kdf_ukmlen = p1;
199 else
200 dctx->kdf_ukmlen = 0;
201 return 1;
202
203 case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
204 *(unsigned char **)p2 = dctx->kdf_ukm;
205 return dctx->kdf_ukmlen;
206
207 case EVP_PKEY_CTRL_DH_KDF_OID:
0dfb9398 208 ASN1_OBJECT_free(dctx->kdf_oid);
0f113f3e
MC
209 dctx->kdf_oid = p2;
210 return 1;
211
212 case EVP_PKEY_CTRL_GET_DH_KDF_OID:
213 *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
214 return 1;
215
216 default:
217 return -2;
218
219 }
220}
39090878 221
3ba0885a 222static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
0f113f3e
MC
223 const char *type, const char *value)
224{
86885c28 225 if (strcmp(type, "dh_paramgen_prime_len") == 0) {
0f113f3e
MC
226 int len;
227 len = atoi(value);
228 return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
229 }
86885c28 230 if (strcmp(type, "dh_rfc5114") == 0) {
0f113f3e
MC
231 DH_PKEY_CTX *dctx = ctx->data;
232 int len;
233 len = atoi(value);
234 if (len < 0 || len > 3)
235 return -2;
236 dctx->rfc5114_param = len;
237 return 1;
238 }
d59d853a
DSH
239 if (strcmp(type, "dh_param") == 0) {
240 DH_PKEY_CTX *dctx = ctx->data;
241 int nid = OBJ_sn2nid(value);
242
243 if (nid == NID_undef) {
244 DHerr(DH_F_PKEY_DH_CTRL_STR, DH_R_INVALID_PARAMETER_NAME);
245 return -2;
246 }
247 dctx->param_nid = nid;
248 return 1;
249 }
86885c28 250 if (strcmp(type, "dh_paramgen_generator") == 0) {
0f113f3e
MC
251 int len;
252 len = atoi(value);
253 return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
254 }
86885c28 255 if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
0f113f3e
MC
256 int len;
257 len = atoi(value);
258 return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
259 }
86885c28 260 if (strcmp(type, "dh_paramgen_type") == 0) {
0f113f3e
MC
261 int typ;
262 typ = atoi(value);
263 return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
264 }
f4403a1f
DSH
265 if (strcmp(type, "dh_pad") == 0) {
266 int pad;
267 pad = atoi(value);
268 return EVP_PKEY_CTX_set_dh_pad(ctx, pad);
269 }
0f113f3e
MC
270 return -2;
271}
3ba0885a 272
39090878
DSH
273#ifndef OPENSSL_NO_DSA
274
275extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
0f113f3e
MC
276 const EVP_MD *evpmd,
277 const unsigned char *seed_in, size_t seed_len,
278 unsigned char *seed_out, int *counter_ret,
279 unsigned long *h_ret, BN_GENCB *cb);
39090878
DSH
280
281extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
0f113f3e
MC
282 const EVP_MD *evpmd,
283 const unsigned char *seed_in,
284 size_t seed_len, int idx,
285 unsigned char *seed_out, int *counter_ret,
286 unsigned long *h_ret, BN_GENCB *cb);
39090878
DSH
287
288static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
0f113f3e
MC
289{
290 DSA *ret;
291 int rv = 0;
292 int prime_len = dctx->prime_len;
293 int subprime_len = dctx->subprime_len;
294 const EVP_MD *md = dctx->md;
295 if (dctx->use_dsa > 2)
296 return NULL;
297 ret = DSA_new();
90945fa3 298 if (ret == NULL)
0f113f3e
MC
299 return NULL;
300 if (subprime_len == -1) {
301 if (prime_len >= 2048)
302 subprime_len = 256;
303 else
304 subprime_len = 160;
305 }
306 if (md == NULL) {
307 if (prime_len >= 2048)
308 md = EVP_sha256();
309 else
310 md = EVP_sha1();
311 }
312 if (dctx->use_dsa == 1)
313 rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
314 NULL, 0, NULL, NULL, NULL, pcb);
315 else if (dctx->use_dsa == 2)
316 rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
317 NULL, 0, -1, NULL, NULL, NULL, pcb);
318 if (rv <= 0) {
319 DSA_free(ret);
320 return NULL;
321 }
322 return ret;
323}
39090878
DSH
324
325#endif
326
3ba0885a 327static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
0f113f3e
MC
328{
329 DH *dh = NULL;
330 DH_PKEY_CTX *dctx = ctx->data;
331 BN_GENCB *pcb;
332 int ret;
333 if (dctx->rfc5114_param) {
334 switch (dctx->rfc5114_param) {
335 case 1:
336 dh = DH_get_1024_160();
337 break;
338
339 case 2:
340 dh = DH_get_2048_224();
341 break;
342
343 case 3:
344 dh = DH_get_2048_256();
345 break;
346
347 default:
348 return -2;
349 }
350 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
351 return 1;
352 }
353
d59d853a
DSH
354 if (dctx->param_nid != 0) {
355 if ((dh = DH_new_by_nid(dctx->param_nid)) == NULL)
356 return 0;
357 EVP_PKEY_assign(pkey, EVP_PKEY_DH, dh);
358 return 1;
359 }
360
0f113f3e
MC
361 if (ctx->pkey_gencb) {
362 pcb = BN_GENCB_new();
90945fa3
MC
363 if (pcb == NULL)
364 return 0;
0f113f3e
MC
365 evp_pkey_set_cb_translate(pcb, ctx);
366 } else
367 pcb = NULL;
39090878 368#ifndef OPENSSL_NO_DSA
0f113f3e
MC
369 if (dctx->use_dsa) {
370 DSA *dsa_dh;
371 dsa_dh = dsa_dh_generate(dctx, pcb);
23a1d5e9 372 BN_GENCB_free(pcb);
90945fa3 373 if (dsa_dh == NULL)
0f113f3e
MC
374 return 0;
375 dh = DSA_dup_DH(dsa_dh);
376 DSA_free(dsa_dh);
377 if (!dh)
378 return 0;
379 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
380 return 1;
381 }
39090878 382#endif
0f113f3e 383 dh = DH_new();
90945fa3 384 if (dh == NULL) {
23a1d5e9 385 BN_GENCB_free(pcb);
0f113f3e
MC
386 return 0;
387 }
388 ret = DH_generate_parameters_ex(dh,
389 dctx->prime_len, dctx->generator, pcb);
23a1d5e9 390 BN_GENCB_free(pcb);
0f113f3e
MC
391 if (ret)
392 EVP_PKEY_assign_DH(pkey, dh);
393 else
394 DH_free(dh);
395 return ret;
396}
3ba0885a
DSH
397
398static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
0f113f3e 399{
d59d853a 400 DH_PKEY_CTX *dctx = ctx->data;
0f113f3e 401 DH *dh = NULL;
d59d853a
DSH
402
403 if (ctx->pkey == NULL && dctx->param_nid == 0) {
0f113f3e
MC
404 DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
405 return 0;
406 }
d59d853a
DSH
407 if (dctx->param_nid != 0)
408 dh = DH_new_by_nid(dctx->param_nid);
409 else
410 dh = DH_new();
90945fa3 411 if (dh == NULL)
0f113f3e
MC
412 return 0;
413 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
414 /* Note: if error return, pkey is freed by parent routine */
d59d853a 415 if (ctx->pkey != NULL && !EVP_PKEY_copy_parameters(pkey, ctx->pkey))
0f113f3e
MC
416 return 0;
417 return DH_generate_key(pkey->pkey.dh);
418}
419
420static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
421 size_t *keylen)
422{
423 int ret;
424 DH *dh;
425 DH_PKEY_CTX *dctx = ctx->data;
426 BIGNUM *dhpub;
427 if (!ctx->pkey || !ctx->peerkey) {
428 DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
429 return 0;
430 }
431 dh = ctx->pkey->pkey.dh;
432 dhpub = ctx->peerkey->pkey.dh->pub_key;
433 if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
434 if (key == NULL) {
435 *keylen = DH_size(dh);
436 return 1;
437 }
f4403a1f
DSH
438 if (dctx->pad)
439 ret = DH_compute_key_padded(key, dhpub, dh);
440 else
441 ret = DH_compute_key(key, dhpub, dh);
0f113f3e
MC
442 if (ret < 0)
443 return ret;
444 *keylen = ret;
445 return 1;
e968561d
DB
446 }
447#ifndef OPENSSL_NO_CMS
448 else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
449
0f113f3e
MC
450 unsigned char *Z = NULL;
451 size_t Zlen = 0;
452 if (!dctx->kdf_outlen || !dctx->kdf_oid)
453 return 0;
454 if (key == NULL) {
455 *keylen = dctx->kdf_outlen;
456 return 1;
457 }
458 if (*keylen != dctx->kdf_outlen)
459 return 0;
460 ret = 0;
461 Zlen = DH_size(dh);
462 Z = OPENSSL_malloc(Zlen);
90945fa3 463 if (Z == NULL) {
918bb865
MC
464 goto err;
465 }
0f113f3e
MC
466 if (DH_compute_key_padded(Z, dhpub, dh) <= 0)
467 goto err;
468 if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
469 dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
470 goto err;
471 *keylen = dctx->kdf_outlen;
472 ret = 1;
473 err:
4b45c6e5 474 OPENSSL_clear_free(Z, Zlen);
0f113f3e
MC
475 return ret;
476 }
e968561d
DB
477#endif
478 return 0;
0f113f3e
MC
479}
480
481const EVP_PKEY_METHOD dh_pkey_meth = {
482 EVP_PKEY_DH,
483 0,
484 pkey_dh_init,
485 pkey_dh_copy,
486 pkey_dh_cleanup,
487
488 0,
489 pkey_dh_paramgen,
490
491 0,
492 pkey_dh_keygen,
493
494 0,
495 0,
496
497 0,
498 0,
499
500 0, 0,
501
502 0, 0, 0, 0,
503
504 0, 0,
505
506 0, 0,
507
508 0,
509 pkey_dh_derive,
510
511 pkey_dh_ctrl,
512 pkey_dh_ctrl_str
513};
514
515const EVP_PKEY_METHOD dhx_pkey_meth = {
516 EVP_PKEY_DHX,
517 0,
518 pkey_dh_init,
519 pkey_dh_copy,
520 pkey_dh_cleanup,
521
522 0,
523 pkey_dh_paramgen,
524
525 0,
526 pkey_dh_keygen,
527
528 0,
529 0,
530
531 0,
532 0,
533
534 0, 0,
535
536 0, 0, 0, 0,
537
538 0, 0,
539
540 0, 0,
541
542 0,
543 pkey_dh_derive,
544
545 pkey_dh_ctrl,
546 pkey_dh_ctrl_str
547};