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