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