1 /*
2 * Copyright 2006-2021 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
83
pkey_dh_copy(EVP_PKEY_CTX * dst,const EVP_PKEY_CTX * src)84 static int pkey_dh_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
85 {
86 DH_PKEY_CTX *dctx, *sctx;
87
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;
95 dctx->paramgen_type = sctx->paramgen_type;
96 dctx->pad = sctx->pad;
97 dctx->md = sctx->md;
98 dctx->param_nid = sctx->param_nid;
99
100 dctx->kdf_type = sctx->kdf_type;
101 dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
102 if (dctx->kdf_oid == NULL)
103 return 0;
104 dctx->kdf_md = sctx->kdf_md;
105 if (sctx->kdf_ukm != NULL) {
106 dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
107 if (dctx->kdf_ukm == NULL)
108 return 0;
109 dctx->kdf_ukmlen = sctx->kdf_ukmlen;
110 }
111 dctx->kdf_outlen = sctx->kdf_outlen;
112 return 1;
113 }
114
pkey_dh_ctrl(EVP_PKEY_CTX * ctx,int type,int p1,void * p2)115 static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
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:
126 if (dctx->paramgen_type == DH_PARAMGEN_TYPE_GENERATOR)
127 return -2;
128 dctx->subprime_len = p1;
129 return 1;
130
131 case EVP_PKEY_CTRL_DH_PAD:
132 dctx->pad = p1;
133 return 1;
134
135 case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
136 if (dctx->paramgen_type != DH_PARAMGEN_TYPE_GENERATOR)
137 return -2;
138 dctx->generator = p1;
139 return 1;
140
141 case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
142 #ifdef OPENSSL_NO_DSA
143 if (p1 != DH_PARAMGEN_TYPE_GENERATOR)
144 return -2;
145 #else
146 if (p1 < 0 || p1 > 2)
147 return -2;
148 #endif
149 dctx->paramgen_type = p1;
150 return 1;
151
152 case EVP_PKEY_CTRL_DH_RFC5114:
153 if (p1 < 1 || p1 > 3 || dctx->param_nid != NID_undef)
154 return -2;
155 dctx->param_nid = p1;
156 return 1;
157
158 case EVP_PKEY_CTRL_DH_NID:
159 if (p1 <= 0 || dctx->param_nid != NID_undef)
160 return -2;
161 dctx->param_nid = p1;
162 return 1;
163
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:
195 OPENSSL_free(dctx->kdf_ukm);
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:
208 ASN1_OBJECT_free(dctx->kdf_oid);
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 }
221
pkey_dh_ctrl_str(EVP_PKEY_CTX * ctx,const char * type,const char * value)222 static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
223 const char *type, const char *value)
224 {
225 if (strcmp(type, "dh_paramgen_prime_len") == 0) {
226 int len;
227 len = atoi(value);
228 return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
229 }
230 if (strcmp(type, "dh_rfc5114") == 0) {
231 DH_PKEY_CTX *dctx = ctx->data;
232 int id;
233
234 id = atoi(value);
235 if (id < 0 || id > 3)
236 return -2;
237 dctx->param_nid = id;
238 return 1;
239 }
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 ERR_raise(ERR_LIB_DH, DH_R_INVALID_PARAMETER_NAME);
246 return -2;
247 }
248 dctx->param_nid = nid;
249 return 1;
250 }
251 if (strcmp(type, "dh_paramgen_generator") == 0) {
252 int len;
253 len = atoi(value);
254 return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
255 }
256 if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
257 int len;
258 len = atoi(value);
259 return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
260 }
261 if (strcmp(type, "dh_paramgen_type") == 0) {
262 int typ;
263 typ = atoi(value);
264 return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
265 }
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 }
271 return -2;
272 }
273
ffc_params_generate(OSSL_LIB_CTX * libctx,DH_PKEY_CTX * dctx,BN_GENCB * pcb)274 static DH *ffc_params_generate(OSSL_LIB_CTX *libctx, DH_PKEY_CTX *dctx,
275 BN_GENCB *pcb)
276 {
277 DH *ret;
278 int rv = 0;
279 int res;
280 int prime_len = dctx->prime_len;
281 int subprime_len = dctx->subprime_len;
282
283 if (dctx->paramgen_type > DH_PARAMGEN_TYPE_FIPS_186_4)
284 return NULL;
285 ret = DH_new();
286 if (ret == NULL)
287 return NULL;
288
289 if (subprime_len == -1) {
290 if (prime_len >= 2048)
291 subprime_len = 256;
292 else
293 subprime_len = 160;
294 }
295
296 if (dctx->md != NULL)
297 ossl_ffc_set_digest(&ret->params, EVP_MD_get0_name(dctx->md), NULL);
298
299 # ifndef FIPS_MODULE
300 if (dctx->paramgen_type == DH_PARAMGEN_TYPE_FIPS_186_2)
301 rv = ossl_ffc_params_FIPS186_2_generate(libctx, &ret->params,
302 FFC_PARAM_TYPE_DH,
303 prime_len, subprime_len, &res,
304 pcb);
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)
309 rv = ossl_ffc_params_FIPS186_4_generate(libctx, &ret->params,
310 FFC_PARAM_TYPE_DH,
311 prime_len, subprime_len, &res,
312 pcb);
313 if (rv <= 0) {
314 DH_free(ret);
315 return NULL;
316 }
317 return ret;
318 }
319
pkey_dh_paramgen(EVP_PKEY_CTX * ctx,EVP_PKEY * pkey)320 static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx,
321 EVP_PKEY *pkey)
322 {
323 DH *dh = NULL;
324 DH_PKEY_CTX *dctx = ctx->data;
325 BN_GENCB *pcb = NULL;
326 int ret;
327
328 /*
329 * Look for a safe prime group for key establishment. Which uses
330 * either RFC_3526 (modp_XXXX) or RFC_7919 (ffdheXXXX).
331 * RFC_5114 is also handled here for param_nid = (1..3)
332 */
333 if (dctx->param_nid != NID_undef) {
334 int type = dctx->param_nid <= 3 ? EVP_PKEY_DHX : EVP_PKEY_DH;
335
336 if ((dh = DH_new_by_nid(dctx->param_nid)) == NULL)
337 return 0;
338 EVP_PKEY_assign(pkey, type, dh);
339 return 1;
340 }
341
342 if (ctx->pkey_gencb != NULL) {
343 pcb = BN_GENCB_new();
344 if (pcb == NULL)
345 return 0;
346 evp_pkey_set_cb_translate(pcb, ctx);
347 }
348 # ifdef FIPS_MODULE
349 dctx->paramgen_type = DH_PARAMGEN_TYPE_FIPS_186_4;
350 # endif /* FIPS_MODULE */
351 if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2) {
352 dh = ffc_params_generate(NULL, dctx, pcb);
353 BN_GENCB_free(pcb);
354 if (dh == NULL)
355 return 0;
356 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
357 return 1;
358 }
359 dh = DH_new();
360 if (dh == NULL) {
361 BN_GENCB_free(pcb);
362 return 0;
363 }
364 ret = DH_generate_parameters_ex(dh,
365 dctx->prime_len, dctx->generator, pcb);
366 BN_GENCB_free(pcb);
367 if (ret)
368 EVP_PKEY_assign_DH(pkey, dh);
369 else
370 DH_free(dh);
371 return ret;
372 }
373
pkey_dh_keygen(EVP_PKEY_CTX * ctx,EVP_PKEY * pkey)374 static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
375 {
376 DH_PKEY_CTX *dctx = ctx->data;
377 DH *dh = NULL;
378
379 if (ctx->pkey == NULL && dctx->param_nid == NID_undef) {
380 ERR_raise(ERR_LIB_DH, DH_R_NO_PARAMETERS_SET);
381 return 0;
382 }
383 if (dctx->param_nid != NID_undef)
384 dh = DH_new_by_nid(dctx->param_nid);
385 else
386 dh = DH_new();
387 if (dh == NULL)
388 return 0;
389 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
390 /* Note: if error return, pkey is freed by parent routine */
391 if (ctx->pkey != NULL && !EVP_PKEY_copy_parameters(pkey, ctx->pkey))
392 return 0;
393 return DH_generate_key((DH *)EVP_PKEY_get0_DH(pkey));
394 }
395
pkey_dh_derive(EVP_PKEY_CTX * ctx,unsigned char * key,size_t * keylen)396 static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
397 size_t *keylen)
398 {
399 int ret;
400 DH *dh;
401 const DH *dhpub;
402 DH_PKEY_CTX *dctx = ctx->data;
403 BIGNUM *dhpubbn;
404
405 if (ctx->pkey == NULL || ctx->peerkey == NULL) {
406 ERR_raise(ERR_LIB_DH, DH_R_KEYS_NOT_SET);
407 return 0;
408 }
409 dh = (DH *)EVP_PKEY_get0_DH(ctx->pkey);
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;
416 if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
417 if (key == NULL) {
418 *keylen = DH_size(dh);
419 return 1;
420 }
421 if (dctx->pad)
422 ret = DH_compute_key_padded(key, dhpubbn, dh);
423 else
424 ret = DH_compute_key(key, dhpubbn, dh);
425 if (ret < 0)
426 return ret;
427 *keylen = ret;
428 return 1;
429 }
430 else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
431
432 unsigned char *Z = NULL;
433 int Zlen = 0;
434
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;
444 if ((Zlen = DH_size(dh)) <= 0)
445 return 0;
446 if ((Z = OPENSSL_malloc(Zlen)) == NULL)
447 return 0;
448 if (DH_compute_key_padded(Z, dhpubbn, dh) <= 0)
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:
456 OPENSSL_clear_free(Z, Zlen);
457 return ret;
458 }
459 return 0;
460 }
461
462 static const EVP_PKEY_METHOD dh_pkey_meth = {
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
ossl_dh_pkey_method(void)496 const EVP_PKEY_METHOD *ossl_dh_pkey_method(void)
497 {
498 return &dh_pkey_meth;
499 }
500
501 static const EVP_PKEY_METHOD dhx_pkey_meth = {
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 };
534
ossl_dhx_pkey_method(void)535 const EVP_PKEY_METHOD *ossl_dhx_pkey_method(void)
536 {
537 return &dhx_pkey_meth;
538 }
539