]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/dh/dh_pmeth.c
Fix no-tls1_3
[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>
706457b7 15#include "dh_local.h"
1e26a8ba 16#include <openssl/bn.h>
3c27208f 17#include <openssl/dsa.h>
bd59f2b9 18#include <openssl/objects.h>
25f2138b 19#include "crypto/evp.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 }
70b0b977 57 dctx->prime_len = 2048;
0f113f3e
MC
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;
12a765a5 83
0f113f3e
MC
84 if (!pkey_dh_init(dst))
85 return 0;
86 sctx = src->data;
87 dctx = dst->data;
88 dctx->prime_len = sctx->prime_len;
89 dctx->subprime_len = sctx->subprime_len;
90 dctx->generator = sctx->generator;
91 dctx->use_dsa = sctx->use_dsa;
f4403a1f 92 dctx->pad = sctx->pad;
0f113f3e
MC
93 dctx->md = sctx->md;
94 dctx->rfc5114_param = sctx->rfc5114_param;
d59d853a 95 dctx->param_nid = sctx->param_nid;
0f113f3e
MC
96
97 dctx->kdf_type = sctx->kdf_type;
98 dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
edeb3fd2 99 if (dctx->kdf_oid == NULL)
0f113f3e
MC
100 return 0;
101 dctx->kdf_md = sctx->kdf_md;
edeb3fd2 102 if (sctx->kdf_ukm != NULL) {
7644a9ae 103 dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
edeb3fd2
IY
104 if (dctx->kdf_ukm == NULL)
105 return 0;
0f113f3e
MC
106 dctx->kdf_ukmlen = sctx->kdf_ukmlen;
107 }
108 dctx->kdf_outlen = sctx->kdf_outlen;
109 return 1;
110}
8bdcef40 111
3ba0885a 112static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
0f113f3e
MC
113{
114 DH_PKEY_CTX *dctx = ctx->data;
115 switch (type) {
116 case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
117 if (p1 < 256)
118 return -2;
119 dctx->prime_len = p1;
120 return 1;
121
122 case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
123 if (dctx->use_dsa == 0)
124 return -2;
125 dctx->subprime_len = p1;
126 return 1;
127
f4403a1f
DSH
128 case EVP_PKEY_CTRL_DH_PAD:
129 dctx->pad = p1;
130 return 1;
131
0f113f3e
MC
132 case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
133 if (dctx->use_dsa)
134 return -2;
135 dctx->generator = p1;
136 return 1;
137
138 case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
39090878 139#ifdef OPENSSL_NO_DSA
0f113f3e
MC
140 if (p1 != 0)
141 return -2;
39090878 142#else
0f113f3e
MC
143 if (p1 < 0 || p1 > 2)
144 return -2;
39090878 145#endif
0f113f3e
MC
146 dctx->use_dsa = p1;
147 return 1;
148
149 case EVP_PKEY_CTRL_DH_RFC5114:
d59d853a 150 if (p1 < 1 || p1 > 3 || dctx->param_nid != NID_undef)
0f113f3e
MC
151 return -2;
152 dctx->rfc5114_param = p1;
153 return 1;
154
d59d853a
DSH
155 case EVP_PKEY_CTRL_DH_NID:
156 if (p1 <= 0 || dctx->rfc5114_param != 0)
157 return -2;
158 dctx->param_nid = p1;
159 return 1;
160
0f113f3e
MC
161 case EVP_PKEY_CTRL_PEER_KEY:
162 /* Default behaviour is OK */
163 return 1;
164
165 case EVP_PKEY_CTRL_DH_KDF_TYPE:
166 if (p1 == -2)
167 return dctx->kdf_type;
e968561d
DB
168#ifdef OPENSSL_NO_CMS
169 if (p1 != EVP_PKEY_DH_KDF_NONE)
170#else
0f113f3e 171 if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
e968561d 172#endif
0f113f3e
MC
173 return -2;
174 dctx->kdf_type = p1;
175 return 1;
176
177 case EVP_PKEY_CTRL_DH_KDF_MD:
178 dctx->kdf_md = p2;
179 return 1;
180
181 case EVP_PKEY_CTRL_GET_DH_KDF_MD:
182 *(const EVP_MD **)p2 = dctx->kdf_md;
183 return 1;
184
185 case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
186 if (p1 <= 0)
187 return -2;
188 dctx->kdf_outlen = (size_t)p1;
189 return 1;
190
191 case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
192 *(int *)p2 = dctx->kdf_outlen;
193 return 1;
194
195 case EVP_PKEY_CTRL_DH_KDF_UKM:
b548a1f1 196 OPENSSL_free(dctx->kdf_ukm);
0f113f3e
MC
197 dctx->kdf_ukm = p2;
198 if (p2)
199 dctx->kdf_ukmlen = p1;
200 else
201 dctx->kdf_ukmlen = 0;
202 return 1;
203
204 case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
205 *(unsigned char **)p2 = dctx->kdf_ukm;
206 return dctx->kdf_ukmlen;
207
208 case EVP_PKEY_CTRL_DH_KDF_OID:
0dfb9398 209 ASN1_OBJECT_free(dctx->kdf_oid);
0f113f3e
MC
210 dctx->kdf_oid = p2;
211 return 1;
212
213 case EVP_PKEY_CTRL_GET_DH_KDF_OID:
214 *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
215 return 1;
216
217 default:
218 return -2;
219
220 }
221}
39090878 222
3ba0885a 223static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
0f113f3e
MC
224 const char *type, const char *value)
225{
86885c28 226 if (strcmp(type, "dh_paramgen_prime_len") == 0) {
0f113f3e
MC
227 int len;
228 len = atoi(value);
229 return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
230 }
86885c28 231 if (strcmp(type, "dh_rfc5114") == 0) {
0f113f3e
MC
232 DH_PKEY_CTX *dctx = ctx->data;
233 int len;
234 len = atoi(value);
235 if (len < 0 || len > 3)
236 return -2;
237 dctx->rfc5114_param = len;
238 return 1;
239 }
d59d853a
DSH
240 if (strcmp(type, "dh_param") == 0) {
241 DH_PKEY_CTX *dctx = ctx->data;
242 int nid = OBJ_sn2nid(value);
243
244 if (nid == NID_undef) {
245 DHerr(DH_F_PKEY_DH_CTRL_STR, DH_R_INVALID_PARAMETER_NAME);
246 return -2;
247 }
248 dctx->param_nid = nid;
249 return 1;
250 }
86885c28 251 if (strcmp(type, "dh_paramgen_generator") == 0) {
0f113f3e
MC
252 int len;
253 len = atoi(value);
254 return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
255 }
86885c28 256 if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
0f113f3e
MC
257 int len;
258 len = atoi(value);
259 return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
260 }
86885c28 261 if (strcmp(type, "dh_paramgen_type") == 0) {
0f113f3e
MC
262 int typ;
263 typ = atoi(value);
264 return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
265 }
f4403a1f
DSH
266 if (strcmp(type, "dh_pad") == 0) {
267 int pad;
268 pad = atoi(value);
269 return EVP_PKEY_CTX_set_dh_pad(ctx, pad);
270 }
0f113f3e
MC
271 return -2;
272}
3ba0885a 273
39090878
DSH
274#ifndef OPENSSL_NO_DSA
275
276extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
0f113f3e
MC
277 const EVP_MD *evpmd,
278 const unsigned char *seed_in, size_t seed_len,
279 unsigned char *seed_out, int *counter_ret,
280 unsigned long *h_ret, BN_GENCB *cb);
39090878
DSH
281
282extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
0f113f3e
MC
283 const EVP_MD *evpmd,
284 const unsigned char *seed_in,
285 size_t seed_len, int idx,
286 unsigned char *seed_out, int *counter_ret,
287 unsigned long *h_ret, BN_GENCB *cb);
39090878
DSH
288
289static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
0f113f3e
MC
290{
291 DSA *ret;
292 int rv = 0;
293 int prime_len = dctx->prime_len;
294 int subprime_len = dctx->subprime_len;
295 const EVP_MD *md = dctx->md;
296 if (dctx->use_dsa > 2)
297 return NULL;
298 ret = DSA_new();
90945fa3 299 if (ret == NULL)
0f113f3e
MC
300 return NULL;
301 if (subprime_len == -1) {
302 if (prime_len >= 2048)
303 subprime_len = 256;
304 else
305 subprime_len = 160;
306 }
307 if (md == NULL) {
308 if (prime_len >= 2048)
309 md = EVP_sha256();
310 else
311 md = EVP_sha1();
312 }
313 if (dctx->use_dsa == 1)
314 rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
315 NULL, 0, NULL, NULL, NULL, pcb);
316 else if (dctx->use_dsa == 2)
317 rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
318 NULL, 0, -1, NULL, NULL, NULL, pcb);
319 if (rv <= 0) {
320 DSA_free(ret);
321 return NULL;
322 }
323 return ret;
324}
39090878
DSH
325
326#endif
327
3ba0885a 328static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
0f113f3e
MC
329{
330 DH *dh = NULL;
331 DH_PKEY_CTX *dctx = ctx->data;
ca2bf555 332 BN_GENCB *pcb = NULL;
0f113f3e 333 int ret;
ca2bf555
SL
334
335 /*
336 * Look for a safe prime group for key establishment. Which uses
337 * either RFC_3526 (modp_XXXX) or RFC_7919 (ffdheXXXX).
338 */
339 if (dctx->param_nid != NID_undef) {
340 if ((dh = DH_new_by_nid(dctx->param_nid)) == NULL)
341 return 0;
342 EVP_PKEY_assign(pkey, EVP_PKEY_DH, dh);
343 return 1;
344 }
345
346#ifndef FIPS_MODE
0f113f3e
MC
347 if (dctx->rfc5114_param) {
348 switch (dctx->rfc5114_param) {
349 case 1:
350 dh = DH_get_1024_160();
351 break;
352
353 case 2:
354 dh = DH_get_2048_224();
355 break;
356
357 case 3:
358 dh = DH_get_2048_256();
359 break;
360
361 default:
362 return -2;
363 }
364 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
365 return 1;
366 }
ca2bf555 367#endif /* FIPS_MODE */
0f113f3e 368
ca2bf555 369 if (ctx->pkey_gencb != NULL) {
0f113f3e 370 pcb = BN_GENCB_new();
90945fa3
MC
371 if (pcb == NULL)
372 return 0;
0f113f3e 373 evp_pkey_set_cb_translate(pcb, ctx);
ca2bf555 374 }
39090878 375#ifndef OPENSSL_NO_DSA
0f113f3e
MC
376 if (dctx->use_dsa) {
377 DSA *dsa_dh;
ca2bf555 378
0f113f3e 379 dsa_dh = dsa_dh_generate(dctx, pcb);
23a1d5e9 380 BN_GENCB_free(pcb);
90945fa3 381 if (dsa_dh == NULL)
0f113f3e
MC
382 return 0;
383 dh = DSA_dup_DH(dsa_dh);
384 DSA_free(dsa_dh);
385 if (!dh)
386 return 0;
387 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
388 return 1;
389 }
39090878 390#endif
0f113f3e 391 dh = DH_new();
90945fa3 392 if (dh == NULL) {
23a1d5e9 393 BN_GENCB_free(pcb);
0f113f3e
MC
394 return 0;
395 }
396 ret = DH_generate_parameters_ex(dh,
397 dctx->prime_len, dctx->generator, pcb);
23a1d5e9 398 BN_GENCB_free(pcb);
0f113f3e
MC
399 if (ret)
400 EVP_PKEY_assign_DH(pkey, dh);
401 else
402 DH_free(dh);
403 return ret;
404}
3ba0885a
DSH
405
406static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
0f113f3e 407{
d59d853a 408 DH_PKEY_CTX *dctx = ctx->data;
0f113f3e 409 DH *dh = NULL;
d59d853a 410
ca2bf555 411 if (ctx->pkey == NULL && dctx->param_nid == NID_undef) {
0f113f3e
MC
412 DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
413 return 0;
414 }
ca2bf555 415 if (dctx->param_nid != NID_undef)
d59d853a
DSH
416 dh = DH_new_by_nid(dctx->param_nid);
417 else
418 dh = DH_new();
90945fa3 419 if (dh == NULL)
0f113f3e
MC
420 return 0;
421 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
422 /* Note: if error return, pkey is freed by parent routine */
d59d853a 423 if (ctx->pkey != NULL && !EVP_PKEY_copy_parameters(pkey, ctx->pkey))
0f113f3e
MC
424 return 0;
425 return DH_generate_key(pkey->pkey.dh);
426}
427
428static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
429 size_t *keylen)
430{
431 int ret;
432 DH *dh;
433 DH_PKEY_CTX *dctx = ctx->data;
434 BIGNUM *dhpub;
435 if (!ctx->pkey || !ctx->peerkey) {
436 DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
437 return 0;
438 }
439 dh = ctx->pkey->pkey.dh;
440 dhpub = ctx->peerkey->pkey.dh->pub_key;
441 if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
442 if (key == NULL) {
443 *keylen = DH_size(dh);
444 return 1;
445 }
f4403a1f
DSH
446 if (dctx->pad)
447 ret = DH_compute_key_padded(key, dhpub, dh);
448 else
449 ret = DH_compute_key(key, dhpub, dh);
0f113f3e
MC
450 if (ret < 0)
451 return ret;
452 *keylen = ret;
453 return 1;
e968561d
DB
454 }
455#ifndef OPENSSL_NO_CMS
456 else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
457
0f113f3e
MC
458 unsigned char *Z = NULL;
459 size_t Zlen = 0;
460 if (!dctx->kdf_outlen || !dctx->kdf_oid)
461 return 0;
462 if (key == NULL) {
463 *keylen = dctx->kdf_outlen;
464 return 1;
465 }
466 if (*keylen != dctx->kdf_outlen)
467 return 0;
468 ret = 0;
469 Zlen = DH_size(dh);
470 Z = OPENSSL_malloc(Zlen);
90945fa3 471 if (Z == NULL) {
918bb865
MC
472 goto err;
473 }
0f113f3e
MC
474 if (DH_compute_key_padded(Z, dhpub, dh) <= 0)
475 goto err;
476 if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
477 dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
478 goto err;
479 *keylen = dctx->kdf_outlen;
480 ret = 1;
481 err:
4b45c6e5 482 OPENSSL_clear_free(Z, Zlen);
0f113f3e
MC
483 return ret;
484 }
e968561d
DB
485#endif
486 return 0;
0f113f3e
MC
487}
488
19bd1fa1 489static const EVP_PKEY_METHOD dh_pkey_meth = {
0f113f3e
MC
490 EVP_PKEY_DH,
491 0,
492 pkey_dh_init,
493 pkey_dh_copy,
494 pkey_dh_cleanup,
495
496 0,
497 pkey_dh_paramgen,
498
499 0,
500 pkey_dh_keygen,
501
502 0,
503 0,
504
505 0,
506 0,
507
508 0, 0,
509
510 0, 0, 0, 0,
511
512 0, 0,
513
514 0, 0,
515
516 0,
517 pkey_dh_derive,
518
519 pkey_dh_ctrl,
520 pkey_dh_ctrl_str
521};
522
19bd1fa1
PS
523const EVP_PKEY_METHOD *dh_pkey_method(void)
524{
525 return &dh_pkey_meth;
526}
527
528static const EVP_PKEY_METHOD dhx_pkey_meth = {
0f113f3e
MC
529 EVP_PKEY_DHX,
530 0,
531 pkey_dh_init,
532 pkey_dh_copy,
533 pkey_dh_cleanup,
534
535 0,
536 pkey_dh_paramgen,
537
538 0,
539 pkey_dh_keygen,
540
541 0,
542 0,
543
544 0,
545 0,
546
547 0, 0,
548
549 0, 0, 0, 0,
550
551 0, 0,
552
553 0, 0,
554
555 0,
556 pkey_dh_derive,
557
558 pkey_dh_ctrl,
559 pkey_dh_ctrl_str
560};
19bd1fa1
PS
561
562const EVP_PKEY_METHOD *dhx_pkey_method(void)
563{
564 return &dhx_pkey_meth;
565}