]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/dh/dh_pmeth.c
Update copyright year
[thirdparty/openssl.git] / crypto / dh / dh_pmeth.c
1 /*
2 * Copyright 2006-2020 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 DHerr(DH_F_PKEY_DH_INIT, 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 #ifdef OPENSSL_NO_CMS
176 if (p1 != EVP_PKEY_DH_KDF_NONE)
177 #else
178 if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
179 #endif
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:
203 OPENSSL_free(dctx->kdf_ukm);
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:
216 ASN1_OBJECT_free(dctx->kdf_oid);
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 }
229
230 static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
231 const char *type, const char *value)
232 {
233 if (strcmp(type, "dh_paramgen_prime_len") == 0) {
234 int len;
235 len = atoi(value);
236 return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
237 }
238 if (strcmp(type, "dh_rfc5114") == 0) {
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 }
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 }
258 if (strcmp(type, "dh_paramgen_generator") == 0) {
259 int len;
260 len = atoi(value);
261 return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
262 }
263 if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
264 int len;
265 len = atoi(value);
266 return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
267 }
268 if (strcmp(type, "dh_paramgen_type") == 0) {
269 int typ;
270 typ = atoi(value);
271 return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
272 }
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 }
278 return -2;
279 }
280
281 static DH *ffc_params_generate(OPENSSL_CTX *libctx, DH_PKEY_CTX *dctx,
282 BN_GENCB *pcb)
283 {
284 DH *ret;
285 int rv = 0;
286 int res;
287 int prime_len = dctx->prime_len;
288 int subprime_len = dctx->subprime_len;
289 const EVP_MD *md = dctx->md;
290
291 if (dctx->paramgen_type > DH_PARAMGEN_TYPE_FIPS_186_4)
292 return NULL;
293 ret = DH_new();
294 if (ret == NULL)
295 return NULL;
296
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 }
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);
323 if (rv <= 0) {
324 DH_free(ret);
325 return NULL;
326 }
327 return ret;
328 }
329
330 static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx,
331 EVP_PKEY *pkey)
332 {
333 DH *dh = NULL;
334 DH_PKEY_CTX *dctx = ctx->data;
335 BN_GENCB *pcb = NULL;
336 int ret;
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
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 }
370 #endif /* FIPS_MODE */
371
372 if (ctx->pkey_gencb != NULL) {
373 pcb = BN_GENCB_new();
374 if (pcb == NULL)
375 return 0;
376 evp_pkey_set_cb_translate(pcb, ctx);
377 }
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);
383 BN_GENCB_free(pcb);
384 if (dh == NULL)
385 return 0;
386 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
387 return 1;
388 }
389 dh = DH_new();
390 if (dh == NULL) {
391 BN_GENCB_free(pcb);
392 return 0;
393 }
394 ret = DH_generate_parameters_ex(dh,
395 dctx->prime_len, dctx->generator, pcb);
396 BN_GENCB_free(pcb);
397 if (ret)
398 EVP_PKEY_assign_DH(pkey, dh);
399 else
400 DH_free(dh);
401 return ret;
402 }
403
404 static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
405 {
406 DH_PKEY_CTX *dctx = ctx->data;
407 DH *dh = NULL;
408
409 if (ctx->pkey == NULL && dctx->param_nid == NID_undef) {
410 DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
411 return 0;
412 }
413 if (dctx->param_nid != NID_undef)
414 dh = DH_new_by_nid(dctx->param_nid);
415 else
416 dh = DH_new();
417 if (dh == NULL)
418 return 0;
419 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
420 /* Note: if error return, pkey is freed by parent routine */
421 if (ctx->pkey != NULL && !EVP_PKEY_copy_parameters(pkey, ctx->pkey))
422 return 0;
423 return DH_generate_key(pkey->pkey.dh);
424 }
425
426 static 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 }
444 if (dctx->pad)
445 ret = DH_compute_key_padded(key, dhpub, dh);
446 else
447 ret = DH_compute_key(key, dhpub, dh);
448 if (ret < 0)
449 return ret;
450 *keylen = ret;
451 return 1;
452 }
453 #ifndef OPENSSL_NO_CMS
454 else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
455
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);
469 if (Z == NULL) {
470 goto err;
471 }
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:
480 OPENSSL_clear_free(Z, Zlen);
481 return ret;
482 }
483 #endif
484 return 0;
485 }
486
487 static const EVP_PKEY_METHOD dh_pkey_meth = {
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
521 const EVP_PKEY_METHOD *dh_pkey_method(void)
522 {
523 return &dh_pkey_meth;
524 }
525
526 static const EVP_PKEY_METHOD dhx_pkey_meth = {
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 };
559
560 const EVP_PKEY_METHOD *dhx_pkey_method(void)
561 {
562 return &dhx_pkey_meth;
563 }