]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/dh/dh_pmeth.c
affe40a53c6dc35d6b35c81f0dfe0119cae9b8c6
[thirdparty/openssl.git] / crypto / dh / dh_pmeth.c
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 rfc5114_param;
39 int param_nid;
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;
54
55 static int pkey_dh_init(EVP_PKEY_CTX *ctx)
56 {
57 DH_PKEY_CTX *dctx;
58
59 if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL) {
60 ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
61 return 0;
62 }
63 dctx->prime_len = 2048;
64 dctx->subprime_len = -1;
65 dctx->generator = 2;
66 dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
67
68 ctx->data = dctx;
69 ctx->keygen_info = dctx->gentmp;
70 ctx->keygen_info_count = 2;
71
72 return 1;
73 }
74
75 static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
76 {
77 DH_PKEY_CTX *dctx = ctx->data;
78
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
87 static int pkey_dh_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
88 {
89 DH_PKEY_CTX *dctx, *sctx;
90
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;
98 dctx->paramgen_type = sctx->paramgen_type;
99 dctx->pad = sctx->pad;
100 dctx->md = sctx->md;
101 dctx->rfc5114_param = sctx->rfc5114_param;
102 dctx->param_nid = sctx->param_nid;
103
104 dctx->kdf_type = sctx->kdf_type;
105 dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
106 if (dctx->kdf_oid == NULL)
107 return 0;
108 dctx->kdf_md = sctx->kdf_md;
109 if (sctx->kdf_ukm != NULL) {
110 dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
111 if (dctx->kdf_ukm == NULL)
112 return 0;
113 dctx->kdf_ukmlen = sctx->kdf_ukmlen;
114 }
115 dctx->kdf_outlen = sctx->kdf_outlen;
116 return 1;
117 }
118
119 static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
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:
130 if (dctx->paramgen_type == DH_PARAMGEN_TYPE_GENERATOR)
131 return -2;
132 dctx->subprime_len = p1;
133 return 1;
134
135 case EVP_PKEY_CTRL_DH_PAD:
136 dctx->pad = p1;
137 return 1;
138
139 case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
140 if (dctx->paramgen_type != DH_PARAMGEN_TYPE_GENERATOR)
141 return -2;
142 dctx->generator = p1;
143 return 1;
144
145 case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
146 #ifdef OPENSSL_NO_DSA
147 if (p1 != DH_PARAMGEN_TYPE_GENERATOR)
148 return -2;
149 #else
150 if (p1 < 0 || p1 > 2)
151 return -2;
152 #endif
153 dctx->paramgen_type = p1;
154 return 1;
155
156 case EVP_PKEY_CTRL_DH_RFC5114:
157 if (p1 < 1 || p1 > 3 || dctx->param_nid != NID_undef)
158 return -2;
159 dctx->rfc5114_param = p1;
160 return 1;
161
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
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;
175 if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
176 return -2;
177 dctx->kdf_type = p1;
178 return 1;
179
180 case EVP_PKEY_CTRL_DH_KDF_MD:
181 dctx->kdf_md = p2;
182 return 1;
183
184 case EVP_PKEY_CTRL_GET_DH_KDF_MD:
185 *(const EVP_MD **)p2 = dctx->kdf_md;
186 return 1;
187
188 case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
189 if (p1 <= 0)
190 return -2;
191 dctx->kdf_outlen = (size_t)p1;
192 return 1;
193
194 case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
195 *(int *)p2 = dctx->kdf_outlen;
196 return 1;
197
198 case EVP_PKEY_CTRL_DH_KDF_UKM:
199 OPENSSL_free(dctx->kdf_ukm);
200 dctx->kdf_ukm = p2;
201 if (p2)
202 dctx->kdf_ukmlen = p1;
203 else
204 dctx->kdf_ukmlen = 0;
205 return 1;
206
207 case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
208 *(unsigned char **)p2 = dctx->kdf_ukm;
209 return dctx->kdf_ukmlen;
210
211 case EVP_PKEY_CTRL_DH_KDF_OID:
212 ASN1_OBJECT_free(dctx->kdf_oid);
213 dctx->kdf_oid = p2;
214 return 1;
215
216 case EVP_PKEY_CTRL_GET_DH_KDF_OID:
217 *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
218 return 1;
219
220 default:
221 return -2;
222
223 }
224 }
225
226 static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
227 const char *type, const char *value)
228 {
229 if (strcmp(type, "dh_paramgen_prime_len") == 0) {
230 int len;
231 len = atoi(value);
232 return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
233 }
234 if (strcmp(type, "dh_rfc5114") == 0) {
235 DH_PKEY_CTX *dctx = ctx->data;
236 int len;
237 len = atoi(value);
238 if (len < 0 || len > 3)
239 return -2;
240 dctx->rfc5114_param = len;
241 return 1;
242 }
243 if (strcmp(type, "dh_param") == 0) {
244 DH_PKEY_CTX *dctx = ctx->data;
245 int nid = OBJ_sn2nid(value);
246
247 if (nid == NID_undef) {
248 ERR_raise(ERR_LIB_DH, DH_R_INVALID_PARAMETER_NAME);
249 return -2;
250 }
251 dctx->param_nid = nid;
252 return 1;
253 }
254 if (strcmp(type, "dh_paramgen_generator") == 0) {
255 int len;
256 len = atoi(value);
257 return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
258 }
259 if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
260 int len;
261 len = atoi(value);
262 return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
263 }
264 if (strcmp(type, "dh_paramgen_type") == 0) {
265 int typ;
266 typ = atoi(value);
267 return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
268 }
269 if (strcmp(type, "dh_pad") == 0) {
270 int pad;
271 pad = atoi(value);
272 return EVP_PKEY_CTX_set_dh_pad(ctx, pad);
273 }
274 return -2;
275 }
276
277 static DH *ffc_params_generate(OSSL_LIB_CTX *libctx, DH_PKEY_CTX *dctx,
278 BN_GENCB *pcb)
279 {
280 DH *ret;
281 int rv = 0;
282 int res;
283 int prime_len = dctx->prime_len;
284 int subprime_len = dctx->subprime_len;
285
286 if (dctx->paramgen_type > DH_PARAMGEN_TYPE_FIPS_186_4)
287 return NULL;
288 ret = DH_new();
289 if (ret == NULL)
290 return NULL;
291
292 if (subprime_len == -1) {
293 if (prime_len >= 2048)
294 subprime_len = 256;
295 else
296 subprime_len = 160;
297 }
298
299 if (dctx->md != NULL)
300 ossl_ffc_set_digest(&ret->params, EVP_MD_name(dctx->md), NULL);
301
302 # ifndef FIPS_MODULE
303 if (dctx->paramgen_type == DH_PARAMGEN_TYPE_FIPS_186_2)
304 rv = ossl_ffc_params_FIPS186_2_generate(libctx, &ret->params,
305 FFC_PARAM_TYPE_DH,
306 prime_len, subprime_len, &res,
307 pcb);
308 else
309 # endif
310 /* For FIPS we always use the DH_PARAMGEN_TYPE_FIPS_186_4 generator */
311 if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2)
312 rv = ossl_ffc_params_FIPS186_4_generate(libctx, &ret->params,
313 FFC_PARAM_TYPE_DH,
314 prime_len, subprime_len, &res,
315 pcb);
316 if (rv <= 0) {
317 DH_free(ret);
318 return NULL;
319 }
320 return ret;
321 }
322
323 static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx,
324 EVP_PKEY *pkey)
325 {
326 DH *dh = NULL;
327 DH_PKEY_CTX *dctx = ctx->data;
328 BN_GENCB *pcb = NULL;
329 int ret;
330
331 /*
332 * Look for a safe prime group for key establishment. Which uses
333 * either RFC_3526 (modp_XXXX) or RFC_7919 (ffdheXXXX).
334 */
335 if (dctx->param_nid != NID_undef) {
336 if ((dh = DH_new_by_nid(dctx->param_nid)) == NULL)
337 return 0;
338 EVP_PKEY_assign(pkey, EVP_PKEY_DH, dh);
339 return 1;
340 }
341
342 #ifndef FIPS_MODULE
343 if (dctx->rfc5114_param) {
344 switch (dctx->rfc5114_param) {
345 case 1:
346 dh = DH_get_1024_160();
347 break;
348
349 case 2:
350 dh = DH_get_2048_224();
351 break;
352
353 case 3:
354 dh = DH_get_2048_256();
355 break;
356
357 default:
358 return -2;
359 }
360 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
361 return 1;
362 }
363 #endif /* FIPS_MODULE */
364
365 if (ctx->pkey_gencb != NULL) {
366 pcb = BN_GENCB_new();
367 if (pcb == NULL)
368 return 0;
369 evp_pkey_set_cb_translate(pcb, ctx);
370 }
371 # ifdef FIPS_MODULE
372 dctx->paramgen_type = DH_PARAMGEN_TYPE_FIPS_186_4;
373 # endif /* FIPS_MODULE */
374 if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2) {
375 dh = ffc_params_generate(NULL, dctx, pcb);
376 BN_GENCB_free(pcb);
377 if (dh == NULL)
378 return 0;
379 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
380 return 1;
381 }
382 dh = DH_new();
383 if (dh == NULL) {
384 BN_GENCB_free(pcb);
385 return 0;
386 }
387 ret = DH_generate_parameters_ex(dh,
388 dctx->prime_len, dctx->generator, pcb);
389 BN_GENCB_free(pcb);
390 if (ret)
391 EVP_PKEY_assign_DH(pkey, dh);
392 else
393 DH_free(dh);
394 return ret;
395 }
396
397 static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
398 {
399 DH_PKEY_CTX *dctx = ctx->data;
400 DH *dh = NULL;
401
402 if (ctx->pkey == NULL && dctx->param_nid == NID_undef) {
403 ERR_raise(ERR_LIB_DH, DH_R_NO_PARAMETERS_SET);
404 return 0;
405 }
406 if (dctx->param_nid != NID_undef)
407 dh = DH_new_by_nid(dctx->param_nid);
408 else
409 dh = DH_new();
410 if (dh == NULL)
411 return 0;
412 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
413 /* Note: if error return, pkey is freed by parent routine */
414 if (ctx->pkey != NULL && !EVP_PKEY_copy_parameters(pkey, ctx->pkey))
415 return 0;
416 return DH_generate_key(pkey->pkey.dh);
417 }
418
419 static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
420 size_t *keylen)
421 {
422 int ret;
423 DH *dh;
424 const DH *dhpub;
425 DH_PKEY_CTX *dctx = ctx->data;
426 BIGNUM *dhpubbn;
427
428 if (ctx->pkey == NULL || ctx->peerkey == NULL) {
429 ERR_raise(ERR_LIB_DH, DH_R_KEYS_NOT_SET);
430 return 0;
431 }
432 dh = ctx->pkey->pkey.dh;
433 dhpub = EVP_PKEY_get0_DH(ctx->peerkey);
434 if (dhpub == NULL) {
435 ERR_raise(ERR_LIB_DH, DH_R_KEYS_NOT_SET);
436 return 0;
437 }
438 dhpubbn = dhpub->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 }
444 if (dctx->pad)
445 ret = DH_compute_key_padded(key, dhpubbn, dh);
446 else
447 ret = DH_compute_key(key, dhpubbn, dh);
448 if (ret < 0)
449 return ret;
450 *keylen = ret;
451 return 1;
452 }
453 else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
454
455 unsigned char *Z = NULL;
456 size_t Zlen = 0;
457 if (!dctx->kdf_outlen || !dctx->kdf_oid)
458 return 0;
459 if (key == NULL) {
460 *keylen = dctx->kdf_outlen;
461 return 1;
462 }
463 if (*keylen != dctx->kdf_outlen)
464 return 0;
465 ret = 0;
466 if ((Zlen = DH_size(dh)) <= 0)
467 return 0;
468 if ((Z = OPENSSL_malloc(Zlen)) == NULL) {
469 ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
470 return 0;
471 }
472 if (DH_compute_key_padded(Z, dhpubbn, 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:
480 OPENSSL_clear_free(Z, Zlen);
481 return ret;
482 }
483 return 0;
484 }
485
486 static const EVP_PKEY_METHOD dh_pkey_meth = {
487 EVP_PKEY_DH,
488 0,
489 pkey_dh_init,
490 pkey_dh_copy,
491 pkey_dh_cleanup,
492
493 0,
494 pkey_dh_paramgen,
495
496 0,
497 pkey_dh_keygen,
498
499 0,
500 0,
501
502 0,
503 0,
504
505 0, 0,
506
507 0, 0, 0, 0,
508
509 0, 0,
510
511 0, 0,
512
513 0,
514 pkey_dh_derive,
515
516 pkey_dh_ctrl,
517 pkey_dh_ctrl_str
518 };
519
520 const EVP_PKEY_METHOD *ossl_dh_pkey_method(void)
521 {
522 return &dh_pkey_meth;
523 }
524
525 static const EVP_PKEY_METHOD dhx_pkey_meth = {
526 EVP_PKEY_DHX,
527 0,
528 pkey_dh_init,
529 pkey_dh_copy,
530 pkey_dh_cleanup,
531
532 0,
533 pkey_dh_paramgen,
534
535 0,
536 pkey_dh_keygen,
537
538 0,
539 0,
540
541 0,
542 0,
543
544 0, 0,
545
546 0, 0, 0, 0,
547
548 0, 0,
549
550 0, 0,
551
552 0,
553 pkey_dh_derive,
554
555 pkey_dh_ctrl,
556 pkey_dh_ctrl_str
557 };
558
559 const EVP_PKEY_METHOD *ossl_dhx_pkey_method(void)
560 {
561 return &dhx_pkey_meth;
562 }