]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/dh/dh_pmeth.c
threads_pthread.c: change inline to ossl_inline
[thirdparty/openssl.git] / crypto / dh / dh_pmeth.c
CommitLineData
0f113f3e 1/*
8020d79b 2 * Copyright 2006-2021 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;
d59d853a 38 int param_nid;
0f113f3e
MC
39 /* Keygen callback info */
40 int gentmp[2];
41 /* KDF (if any) to use for DH */
42 char kdf_type;
43 /* OID to use for KDF */
44 ASN1_OBJECT *kdf_oid;
45 /* Message digest to use for key derivation */
46 const EVP_MD *kdf_md;
47 /* User key material */
48 unsigned char *kdf_ukm;
49 size_t kdf_ukmlen;
50 /* KDF output length */
51 size_t kdf_outlen;
52} DH_PKEY_CTX;
3ba0885a
DSH
53
54static int pkey_dh_init(EVP_PKEY_CTX *ctx)
0f113f3e
MC
55{
56 DH_PKEY_CTX *dctx;
64b25758 57
e077455e 58 if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL)
0f113f3e 59 return 0;
70b0b977 60 dctx->prime_len = 2048;
0f113f3e
MC
61 dctx->subprime_len = -1;
62 dctx->generator = 2;
0f113f3e 63 dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
0f113f3e
MC
64
65 ctx->data = dctx;
66 ctx->keygen_info = dctx->gentmp;
67 ctx->keygen_info_count = 2;
68
69 return 1;
70}
3ba0885a 71
edeb3fd2
IY
72static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
73{
74 DH_PKEY_CTX *dctx = ctx->data;
f11f86f6 75
edeb3fd2
IY
76 if (dctx != NULL) {
77 OPENSSL_free(dctx->kdf_ukm);
78 ASN1_OBJECT_free(dctx->kdf_oid);
79 OPENSSL_free(dctx);
80 }
81}
82
83
9fdcc21f 84static int pkey_dh_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
0f113f3e
MC
85{
86 DH_PKEY_CTX *dctx, *sctx;
12a765a5 87
0f113f3e
MC
88 if (!pkey_dh_init(dst))
89 return 0;
90 sctx = src->data;
91 dctx = dst->data;
92 dctx->prime_len = sctx->prime_len;
93 dctx->subprime_len = sctx->subprime_len;
94 dctx->generator = sctx->generator;
f11f86f6 95 dctx->paramgen_type = sctx->paramgen_type;
f4403a1f 96 dctx->pad = sctx->pad;
0f113f3e 97 dctx->md = sctx->md;
d59d853a 98 dctx->param_nid = sctx->param_nid;
0f113f3e
MC
99
100 dctx->kdf_type = sctx->kdf_type;
101 dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
edeb3fd2 102 if (dctx->kdf_oid == NULL)
0f113f3e
MC
103 return 0;
104 dctx->kdf_md = sctx->kdf_md;
edeb3fd2 105 if (sctx->kdf_ukm != NULL) {
7644a9ae 106 dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
edeb3fd2
IY
107 if (dctx->kdf_ukm == NULL)
108 return 0;
0f113f3e
MC
109 dctx->kdf_ukmlen = sctx->kdf_ukmlen;
110 }
111 dctx->kdf_outlen = sctx->kdf_outlen;
112 return 1;
113}
8bdcef40 114
3ba0885a 115static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
0f113f3e
MC
116{
117 DH_PKEY_CTX *dctx = ctx->data;
118 switch (type) {
119 case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
120 if (p1 < 256)
121 return -2;
122 dctx->prime_len = p1;
123 return 1;
124
125 case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
f11f86f6 126 if (dctx->paramgen_type == DH_PARAMGEN_TYPE_GENERATOR)
0f113f3e
MC
127 return -2;
128 dctx->subprime_len = p1;
129 return 1;
130
f4403a1f
DSH
131 case EVP_PKEY_CTRL_DH_PAD:
132 dctx->pad = p1;
133 return 1;
134
0f113f3e 135 case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
f11f86f6 136 if (dctx->paramgen_type != DH_PARAMGEN_TYPE_GENERATOR)
0f113f3e
MC
137 return -2;
138 dctx->generator = p1;
139 return 1;
140
141 case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
39090878 142#ifdef OPENSSL_NO_DSA
f11f86f6 143 if (p1 != DH_PARAMGEN_TYPE_GENERATOR)
0f113f3e 144 return -2;
39090878 145#else
0f113f3e
MC
146 if (p1 < 0 || p1 > 2)
147 return -2;
39090878 148#endif
f11f86f6 149 dctx->paramgen_type = p1;
0f113f3e
MC
150 return 1;
151
152 case EVP_PKEY_CTRL_DH_RFC5114:
d59d853a 153 if (p1 < 1 || p1 > 3 || dctx->param_nid != NID_undef)
0f113f3e 154 return -2;
f1ffaaee 155 dctx->param_nid = p1;
0f113f3e
MC
156 return 1;
157
d59d853a 158 case EVP_PKEY_CTRL_DH_NID:
f1ffaaee 159 if (p1 <= 0 || dctx->param_nid != NID_undef)
d59d853a
DSH
160 return -2;
161 dctx->param_nid = p1;
162 return 1;
163
0f113f3e
MC
164 case EVP_PKEY_CTRL_PEER_KEY:
165 /* Default behaviour is OK */
166 return 1;
167
168 case EVP_PKEY_CTRL_DH_KDF_TYPE:
169 if (p1 == -2)
170 return dctx->kdf_type;
171 if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
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 231 DH_PKEY_CTX *dctx = ctx->data;
f1ffaaee
SL
232 int id;
233
234 id = atoi(value);
235 if (id < 0 || id > 3)
0f113f3e 236 return -2;
f1ffaaee 237 dctx->param_nid = id;
0f113f3e
MC
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) {
9311d0c4 245 ERR_raise(ERR_LIB_DH, DH_R_INVALID_PARAMETER_NAME);
d59d853a
DSH
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
b4250010 274static DH *ffc_params_generate(OSSL_LIB_CTX *libctx, DH_PKEY_CTX *dctx,
f11f86f6 275 BN_GENCB *pcb)
0f113f3e 276{
f11f86f6 277 DH *ret;
0f113f3e 278 int rv = 0;
f11f86f6 279 int res;
0f113f3e
MC
280 int prime_len = dctx->prime_len;
281 int subprime_len = dctx->subprime_len;
f11f86f6
SL
282
283 if (dctx->paramgen_type > DH_PARAMGEN_TYPE_FIPS_186_4)
0f113f3e 284 return NULL;
f11f86f6 285 ret = DH_new();
90945fa3 286 if (ret == NULL)
0f113f3e 287 return NULL;
f11f86f6 288
0f113f3e
MC
289 if (subprime_len == -1) {
290 if (prime_len >= 2048)
291 subprime_len = 256;
292 else
293 subprime_len = 160;
294 }
4f2271d5
SL
295
296 if (dctx->md != NULL)
ed576acd 297 ossl_ffc_set_digest(&ret->params, EVP_MD_get0_name(dctx->md), NULL);
4f2271d5 298
f844f9eb 299# ifndef FIPS_MODULE
f11f86f6 300 if (dctx->paramgen_type == DH_PARAMGEN_TYPE_FIPS_186_2)
5357c106
P
301 rv = ossl_ffc_params_FIPS186_2_generate(libctx, &ret->params,
302 FFC_PARAM_TYPE_DH,
303 prime_len, subprime_len, &res,
304 pcb);
f11f86f6
SL
305 else
306# endif
307 /* For FIPS we always use the DH_PARAMGEN_TYPE_FIPS_186_4 generator */
308 if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2)
5357c106
P
309 rv = ossl_ffc_params_FIPS186_4_generate(libctx, &ret->params,
310 FFC_PARAM_TYPE_DH,
311 prime_len, subprime_len, &res,
312 pcb);
0f113f3e 313 if (rv <= 0) {
f11f86f6 314 DH_free(ret);
0f113f3e
MC
315 return NULL;
316 }
317 return ret;
318}
39090878 319
f11f86f6
SL
320static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx,
321 EVP_PKEY *pkey)
0f113f3e
MC
322{
323 DH *dh = NULL;
324 DH_PKEY_CTX *dctx = ctx->data;
ca2bf555 325 BN_GENCB *pcb = NULL;
0f113f3e 326 int ret;
ca2bf555
SL
327
328 /*
329 * Look for a safe prime group for key establishment. Which uses
330 * either RFC_3526 (modp_XXXX) or RFC_7919 (ffdheXXXX).
f1ffaaee 331 * RFC_5114 is also handled here for param_nid = (1..3)
ca2bf555
SL
332 */
333 if (dctx->param_nid != NID_undef) {
f1ffaaee
SL
334 int type = dctx->param_nid <= 3 ? EVP_PKEY_DHX : EVP_PKEY_DH;
335
ca2bf555
SL
336 if ((dh = DH_new_by_nid(dctx->param_nid)) == NULL)
337 return 0;
f1ffaaee 338 EVP_PKEY_assign(pkey, type, dh);
0f113f3e
MC
339 return 1;
340 }
341
ca2bf555 342 if (ctx->pkey_gencb != NULL) {
0f113f3e 343 pcb = BN_GENCB_new();
90945fa3
MC
344 if (pcb == NULL)
345 return 0;
0f113f3e 346 evp_pkey_set_cb_translate(pcb, ctx);
ca2bf555 347 }
f844f9eb 348# ifdef FIPS_MODULE
f11f86f6 349 dctx->paramgen_type = DH_PARAMGEN_TYPE_FIPS_186_4;
f844f9eb 350# endif /* FIPS_MODULE */
f11f86f6
SL
351 if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2) {
352 dh = ffc_params_generate(NULL, dctx, pcb);
23a1d5e9 353 BN_GENCB_free(pcb);
f11f86f6 354 if (dh == NULL)
0f113f3e
MC
355 return 0;
356 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
357 return 1;
358 }
0f113f3e 359 dh = DH_new();
90945fa3 360 if (dh == NULL) {
23a1d5e9 361 BN_GENCB_free(pcb);
0f113f3e
MC
362 return 0;
363 }
364 ret = DH_generate_parameters_ex(dh,
365 dctx->prime_len, dctx->generator, pcb);
23a1d5e9 366 BN_GENCB_free(pcb);
0f113f3e
MC
367 if (ret)
368 EVP_PKEY_assign_DH(pkey, dh);
369 else
370 DH_free(dh);
371 return ret;
372}
3ba0885a
DSH
373
374static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
0f113f3e 375{
d59d853a 376 DH_PKEY_CTX *dctx = ctx->data;
0f113f3e 377 DH *dh = NULL;
d59d853a 378
ca2bf555 379 if (ctx->pkey == NULL && dctx->param_nid == NID_undef) {
9311d0c4 380 ERR_raise(ERR_LIB_DH, DH_R_NO_PARAMETERS_SET);
0f113f3e
MC
381 return 0;
382 }
ca2bf555 383 if (dctx->param_nid != NID_undef)
d59d853a
DSH
384 dh = DH_new_by_nid(dctx->param_nid);
385 else
386 dh = DH_new();
90945fa3 387 if (dh == NULL)
0f113f3e
MC
388 return 0;
389 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
390 /* Note: if error return, pkey is freed by parent routine */
d59d853a 391 if (ctx->pkey != NULL && !EVP_PKEY_copy_parameters(pkey, ctx->pkey))
0f113f3e 392 return 0;
5dc6489b 393 return DH_generate_key((DH *)EVP_PKEY_get0_DH(pkey));
0f113f3e
MC
394}
395
396static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
397 size_t *keylen)
398{
399 int ret;
400 DH *dh;
19ad1e9d 401 const DH *dhpub;
0f113f3e 402 DH_PKEY_CTX *dctx = ctx->data;
19ad1e9d
MC
403 BIGNUM *dhpubbn;
404
405 if (ctx->pkey == NULL || ctx->peerkey == NULL) {
9311d0c4 406 ERR_raise(ERR_LIB_DH, DH_R_KEYS_NOT_SET);
0f113f3e
MC
407 return 0;
408 }
5dc6489b 409 dh = (DH *)EVP_PKEY_get0_DH(ctx->pkey);
19ad1e9d
MC
410 dhpub = EVP_PKEY_get0_DH(ctx->peerkey);
411 if (dhpub == NULL) {
412 ERR_raise(ERR_LIB_DH, DH_R_KEYS_NOT_SET);
413 return 0;
414 }
415 dhpubbn = dhpub->pub_key;
0f113f3e
MC
416 if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
417 if (key == NULL) {
418 *keylen = DH_size(dh);
419 return 1;
420 }
f4403a1f 421 if (dctx->pad)
19ad1e9d 422 ret = DH_compute_key_padded(key, dhpubbn, dh);
f4403a1f 423 else
19ad1e9d 424 ret = DH_compute_key(key, dhpubbn, dh);
0f113f3e
MC
425 if (ret < 0)
426 return ret;
427 *keylen = ret;
428 return 1;
e968561d 429 }
e968561d
DB
430 else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
431
0f113f3e 432 unsigned char *Z = NULL;
eb7a5cc3
P
433 int Zlen = 0;
434
0f113f3e
MC
435 if (!dctx->kdf_outlen || !dctx->kdf_oid)
436 return 0;
437 if (key == NULL) {
438 *keylen = dctx->kdf_outlen;
439 return 1;
440 }
441 if (*keylen != dctx->kdf_outlen)
442 return 0;
443 ret = 0;
fd0a9ff7
P
444 if ((Zlen = DH_size(dh)) <= 0)
445 return 0;
e077455e 446 if ((Z = OPENSSL_malloc(Zlen)) == NULL)
fd0a9ff7 447 return 0;
19ad1e9d 448 if (DH_compute_key_padded(Z, dhpubbn, dh) <= 0)
0f113f3e
MC
449 goto err;
450 if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
451 dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
452 goto err;
453 *keylen = dctx->kdf_outlen;
454 ret = 1;
455 err:
4b45c6e5 456 OPENSSL_clear_free(Z, Zlen);
0f113f3e
MC
457 return ret;
458 }
e968561d 459 return 0;
0f113f3e
MC
460}
461
19bd1fa1 462static const EVP_PKEY_METHOD dh_pkey_meth = {
0f113f3e
MC
463 EVP_PKEY_DH,
464 0,
465 pkey_dh_init,
466 pkey_dh_copy,
467 pkey_dh_cleanup,
468
469 0,
470 pkey_dh_paramgen,
471
472 0,
473 pkey_dh_keygen,
474
475 0,
476 0,
477
478 0,
479 0,
480
481 0, 0,
482
483 0, 0, 0, 0,
484
485 0, 0,
486
487 0, 0,
488
489 0,
490 pkey_dh_derive,
491
492 pkey_dh_ctrl,
493 pkey_dh_ctrl_str
494};
495
19dbb742 496const EVP_PKEY_METHOD *ossl_dh_pkey_method(void)
19bd1fa1
PS
497{
498 return &dh_pkey_meth;
499}
500
501static const EVP_PKEY_METHOD dhx_pkey_meth = {
0f113f3e
MC
502 EVP_PKEY_DHX,
503 0,
504 pkey_dh_init,
505 pkey_dh_copy,
506 pkey_dh_cleanup,
507
508 0,
509 pkey_dh_paramgen,
510
511 0,
512 pkey_dh_keygen,
513
514 0,
515 0,
516
517 0,
518 0,
519
520 0, 0,
521
522 0, 0, 0, 0,
523
524 0, 0,
525
526 0, 0,
527
528 0,
529 pkey_dh_derive,
530
531 pkey_dh_ctrl,
532 pkey_dh_ctrl_str
533};
19bd1fa1 534
19dbb742 535const EVP_PKEY_METHOD *ossl_dhx_pkey_method(void)
19bd1fa1
PS
536{
537 return &dhx_pkey_meth;
538}