1/*
2 * Copyright 2006-2018 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#include <stdio.h>
11#include "internal/cryptlib.h"
12#include <openssl/asn1t.h>
13#include <openssl/x509.h>
14#include <openssl/evp.h>
15#include "dh_local.h"
16#include <openssl/bn.h>
17#include <openssl/dsa.h>
18#include <openssl/objects.h>
19#include "crypto/evp.h"
20
21/* DH pkey context structure */
22
23typedef struct {
24 /* Parameter gen parameters */
25 int prime_len;
26 int generator;
27 int use_dsa;
28 int subprime_len;
29 int pad;
30 /* message digest used for parameter generation */
31 const EVP_MD *md;
32 int rfc5114_param;
33 int param_nid;
34 /* Keygen callback info */
35 int gentmp[2];
36 /* KDF (if any) to use for DH */
37 char kdf_type;
38 /* OID to use for KDF */
39 ASN1_OBJECT *kdf_oid;
40 /* Message digest to use for key derivation */
41 const EVP_MD *kdf_md;
42 /* User key material */
43 unsigned char *kdf_ukm;
44 size_t kdf_ukmlen;
45 /* KDF output length */
46 size_t kdf_outlen;
47} DH_PKEY_CTX;
48
49static int pkey_dh_init(EVP_PKEY_CTX *ctx)
50{
51 DH_PKEY_CTX *dctx;
52
53 if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL) {
54 DHerr(DH_F_PKEY_DH_INIT, ERR_R_MALLOC_FAILURE);
55 return 0;
56 }
57 dctx->prime_len = 2048;
58 dctx->subprime_len = -1;
59 dctx->generator = 2;
60 dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
61
62 ctx->data = dctx;
63 ctx->keygen_info = dctx->gentmp;
64 ctx->keygen_info_count = 2;
65
66 return 1;
67}
68
69static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
70{
71 DH_PKEY_CTX *dctx = ctx->data;
72 if (dctx != NULL) {
73 OPENSSL_free(dctx->kdf_ukm);
74 ASN1_OBJECT_free(dctx->kdf_oid);
75 OPENSSL_free(dctx);
76 }
77}
78
79
80static int pkey_dh_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
81{
82 DH_PKEY_CTX *dctx, *sctx;
83
84 if (!pkey_dh_init(dst))
85 return 0;
86 sctx = src->data;
87 dctx = dst->data;
88 dctx->prime_len = sctx->prime_len;
89 dctx->subprime_len = sctx->subprime_len;
90 dctx->generator = sctx->generator;
91 dctx->use_dsa = sctx->use_dsa;
92 dctx->pad = sctx->pad;
93 dctx->md = sctx->md;
94 dctx->rfc5114_param = sctx->rfc5114_param;
95 dctx->param_nid = sctx->param_nid;
96
97 dctx->kdf_type = sctx->kdf_type;
98 dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
99 if (dctx->kdf_oid == NULL)
100 return 0;
101 dctx->kdf_md = sctx->kdf_md;
102 if (sctx->kdf_ukm != NULL) {
103 dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
104 if (dctx->kdf_ukm == NULL)
105 return 0;
106 dctx->kdf_ukmlen = sctx->kdf_ukmlen;
107 }
108 dctx->kdf_outlen = sctx->kdf_outlen;
109 return 1;
110}
111
112static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
113{
114 DH_PKEY_CTX *dctx = ctx->data;
115 switch (type) {
116 case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
117 if (p1 < 256)
118 return -2;
119 dctx->prime_len = p1;
120 return 1;
121
122 case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
123 if (dctx->use_dsa == 0)
124 return -2;
125 dctx->subprime_len = p1;
126 return 1;
127
128 case EVP_PKEY_CTRL_DH_PAD:
129 dctx->pad = p1;
130 return 1;
131
132 case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
133 if (dctx->use_dsa)
134 return -2;
135 dctx->generator = p1;
136 return 1;
137
138 case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
139#ifdef OPENSSL_NO_DSA
140 if (p1 != 0)
141 return -2;
142#else
143 if (p1 < 0 || p1 > 2)
144 return -2;
145#endif
146 dctx->use_dsa = p1;
147 return 1;
148
149 case EVP_PKEY_CTRL_DH_RFC5114:
150 if (p1 < 1 || p1 > 3 || dctx->param_nid != NID_undef)
151 return -2;
152 dctx->rfc5114_param = p1;
153 return 1;
154
155 case EVP_PKEY_CTRL_DH_NID:
156 if (p1 <= 0 || dctx->rfc5114_param != 0)
157 return -2;
158 dctx->param_nid = p1;
159 return 1;
160
161 case EVP_PKEY_CTRL_PEER_KEY:
162 /* Default behaviour is OK */
163 return 1;
164
165 case EVP_PKEY_CTRL_DH_KDF_TYPE:
166 if (p1 == -2)
167 return dctx->kdf_type;
168#ifdef OPENSSL_NO_CMS
169 if (p1 != EVP_PKEY_DH_KDF_NONE)
170#else
171 if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
172#endif
173 return -2;
174 dctx->kdf_type = p1;
175 return 1;
176
177 case EVP_PKEY_CTRL_DH_KDF_MD:
178 dctx->kdf_md = p2;
179 return 1;
180
181 case EVP_PKEY_CTRL_GET_DH_KDF_MD:
182 *(const EVP_MD **)p2 = dctx->kdf_md;
183 return 1;
184
185 case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
186 if (p1 <= 0)
187 return -2;
188 dctx->kdf_outlen = (size_t)p1;
189 return 1;
190
191 case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
192 *(int *)p2 = dctx->kdf_outlen;
193 return 1;
194
195 case EVP_PKEY_CTRL_DH_KDF_UKM:
196 OPENSSL_free(dctx->kdf_ukm);
197 dctx->kdf_ukm = p2;
198 if (p2)
199 dctx->kdf_ukmlen = p1;
200 else
201 dctx->kdf_ukmlen = 0;
202 return 1;
203
204 case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
205 *(unsigned char **)p2 = dctx->kdf_ukm;
206 return dctx->kdf_ukmlen;
207
208 case EVP_PKEY_CTRL_DH_KDF_OID:
209 ASN1_OBJECT_free(dctx->kdf_oid);
210 dctx->kdf_oid = p2;
211 return 1;
212
213 case EVP_PKEY_CTRL_GET_DH_KDF_OID:
214 *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
215 return 1;
216
217 default:
218 return -2;
219
220 }
221}
222
223static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
224 const char *type, const char *value)
225{
226 if (strcmp(type, "dh_paramgen_prime_len") == 0) {
227 int len;
228 len = atoi(value);
229 return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
230 }
231 if (strcmp(type, "dh_rfc5114") == 0) {
232 DH_PKEY_CTX *dctx = ctx->data;
233 int len;
234 len = atoi(value);
235 if (len < 0 || len > 3)
236 return -2;
237 dctx->rfc5114_param = len;
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 DHerr(DH_F_PKEY_DH_CTRL_STR, 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
274#ifndef OPENSSL_NO_DSA
275
276extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
277 const EVP_MD *evpmd,
278 const unsigned char *seed_in, size_t seed_len,
279 unsigned char *seed_out, int *counter_ret,
280 unsigned long *h_ret, BN_GENCB *cb);
281
282extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
283 const EVP_MD *evpmd,
284 const unsigned char *seed_in,
285 size_t seed_len, int idx,
286 unsigned char *seed_out, int *counter_ret,
287 unsigned long *h_ret, BN_GENCB *cb);
288
289static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
290{
291 DSA *ret;
292 int rv = 0;
293 int prime_len = dctx->prime_len;
294 int subprime_len = dctx->subprime_len;
295 const EVP_MD *md = dctx->md;
296 if (dctx->use_dsa > 2)
297 return NULL;
298 ret = DSA_new();
299 if (ret == NULL)
300 return NULL;
301 if (subprime_len == -1) {
302 if (prime_len >= 2048)
303 subprime_len = 256;
304 else
305 subprime_len = 160;
306 }
307 if (md == NULL) {
308 if (prime_len >= 2048)
309 md = EVP_sha256();
310 else
311 md = EVP_sha1();
312 }
313 if (dctx->use_dsa == 1)
314 rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
315 NULL, 0, NULL, NULL, NULL, pcb);
316 else if (dctx->use_dsa == 2)
317 rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
318 NULL, 0, -1, NULL, NULL, NULL, pcb);
319 if (rv <= 0) {
320 DSA_free(ret);
321 return NULL;
322 }
323 return ret;
324}
325
326#endif
327
328static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
329{
330 DH *dh = NULL;
331 DH_PKEY_CTX *dctx = ctx->data;
332 BN_GENCB *pcb;
333 int ret;
334 if (dctx->rfc5114_param) {
335 switch (dctx->rfc5114_param) {
336 case 1:
337 dh = DH_get_1024_160();
338 break;
339
340 case 2:
341 dh = DH_get_2048_224();
342 break;
343
344 case 3:
345 dh = DH_get_2048_256();
346 break;
347
348 default:
349 return -2;
350 }
351 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
352 return 1;
353 }
354
355 if (dctx->param_nid != 0) {
356 if ((dh = DH_new_by_nid(dctx->param_nid)) == NULL)
357 return 0;
358 EVP_PKEY_assign(pkey, EVP_PKEY_DH, dh);
359 return 1;
360 }
361
362 if (ctx->pkey_gencb) {
363 pcb = BN_GENCB_new();
364 if (pcb == NULL)
365 return 0;
366 evp_pkey_set_cb_translate(pcb, ctx);
367 } else
368 pcb = NULL;
369#ifndef OPENSSL_NO_DSA
370 if (dctx->use_dsa) {
371 DSA *dsa_dh;
372 dsa_dh = dsa_dh_generate(dctx, pcb);
373 BN_GENCB_free(pcb);
374 if (dsa_dh == NULL)
375 return 0;
376 dh = DSA_dup_DH(dsa_dh);
377 DSA_free(dsa_dh);
378 if (!dh)
379 return 0;
380 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
381 return 1;
382 }
383#endif
384 dh = DH_new();
385 if (dh == NULL) {
386 BN_GENCB_free(pcb);
387 return 0;
388 }
389 ret = DH_generate_parameters_ex(dh,
390 dctx->prime_len, dctx->generator, pcb);
391 BN_GENCB_free(pcb);
392 if (ret)
393 EVP_PKEY_assign_DH(pkey, dh);
394 else
395 DH_free(dh);
396 return ret;
397}
398
399static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
400{
401 DH_PKEY_CTX *dctx = ctx->data;
402 DH *dh = NULL;
403
404 if (ctx->pkey == NULL && dctx->param_nid == 0) {
405 DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
406 return 0;
407 }
408 if (dctx->param_nid != 0)
409 dh = DH_new_by_nid(dctx->param_nid);
410 else
411 dh = DH_new();
412 if (dh == NULL)
413 return 0;
414 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
415 /* Note: if error return, pkey is freed by parent routine */
416 if (ctx->pkey != NULL && !EVP_PKEY_copy_parameters(pkey, ctx->pkey))
417 return 0;
418 return DH_generate_key(pkey->pkey.dh);
419}
420
421static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
422 size_t *keylen)
423{
424 int ret;
425 DH *dh;
426 DH_PKEY_CTX *dctx = ctx->data;
427 BIGNUM *dhpub;
428 if (!ctx->pkey || !ctx->peerkey) {
429 DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
430 return 0;
431 }
432 dh = ctx->pkey->pkey.dh;
433 dhpub = ctx->peerkey->pkey.dh->pub_key;
434 if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
435 if (key == NULL) {
436 *keylen = DH_size(dh);
437 return 1;
438 }
439 if (dctx->pad)
440 ret = DH_compute_key_padded(key, dhpub, dh);
441 else
442 ret = DH_compute_key(key, dhpub, dh);
443 if (ret < 0)
444 return ret;
445 *keylen = ret;
446 return 1;
447 }
448#ifndef OPENSSL_NO_CMS
449 else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
450
451 unsigned char *Z = NULL;
452 size_t Zlen = 0;
453 if (!dctx->kdf_outlen || !dctx->kdf_oid)
454 return 0;
455 if (key == NULL) {
456 *keylen = dctx->kdf_outlen;
457 return 1;
458 }
459 if (*keylen != dctx->kdf_outlen)
460 return 0;
461 ret = 0;
462 Zlen = DH_size(dh);
463 Z = OPENSSL_malloc(Zlen);
464 if (Z == NULL) {
465 goto err;
466 }
467 if (DH_compute_key_padded(Z, dhpub, dh) <= 0)
468 goto err;
469 if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
470 dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
471 goto err;
472 *keylen = dctx->kdf_outlen;
473 ret = 1;
474 err:
475 OPENSSL_clear_free(Z, Zlen);
476 return ret;
477 }
478#endif
479 return 0;
480}
481
482static const EVP_PKEY_METHOD dh_pkey_meth = {
483 EVP_PKEY_DH,
484 0,
485 pkey_dh_init,
486 pkey_dh_copy,
487 pkey_dh_cleanup,
488
489 0,
490 pkey_dh_paramgen,
491
492 0,
493 pkey_dh_keygen,
494
495 0,
496 0,
497
498 0,
499 0,
500
501 0, 0,
502
503 0, 0, 0, 0,
504
505 0, 0,
506
507 0, 0,
508
509 0,
510 pkey_dh_derive,
511
512 pkey_dh_ctrl,
513 pkey_dh_ctrl_str
514};
515
516const EVP_PKEY_METHOD *dh_pkey_method(void)
517{
518 return &dh_pkey_meth;
519}
520
521static const EVP_PKEY_METHOD dhx_pkey_meth = {
522 EVP_PKEY_DHX,
523 0,
524 pkey_dh_init,
525 pkey_dh_copy,
526 pkey_dh_cleanup,
527
528 0,
529 pkey_dh_paramgen,
530
531 0,
532 pkey_dh_keygen,
533
534 0,
535 0,
536
537 0,
538 0,
539
540 0, 0,
541
542 0, 0, 0, 0,
543
544 0, 0,
545
546 0, 0,
547
548 0,
549 pkey_dh_derive,
550
551 pkey_dh_ctrl,
552 pkey_dh_ctrl_str
553};
554
555const EVP_PKEY_METHOD *dhx_pkey_method(void)
556{
557 return &dhx_pkey_meth;
558}
559