]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/dh/dh_pmeth.c
Fix some errors in the mem leaks docs
[thirdparty/openssl.git] / crypto / dh / dh_pmeth.c
CommitLineData
0f113f3e 1/*
aa6bb135 2 * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
3ba0885a 3 *
aa6bb135
RS
4 * Licensed under the OpenSSL license (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
3ba0885a
DSH
8 */
9
10#include <stdio.h>
b39fc560 11#include "internal/cryptlib.h"
3ba0885a
DSH
12#include <openssl/asn1t.h>
13#include <openssl/x509.h>
3ba0885a 14#include <openssl/evp.h>
0aeddcfa 15#include "dh_locl.h"
1e26a8ba 16#include <openssl/bn.h>
3c27208f 17#include <openssl/dsa.h>
bd59f2b9 18#include <openssl/objects.h>
27af42f9 19#include "internal/evp_int.h"
3ba0885a
DSH
20
21/* DH pkey context structure */
22
0f113f3e
MC
23typedef struct {
24 /* Parameter gen parameters */
25 int prime_len;
26 int generator;
27 int use_dsa;
28 int subprime_len;
f4403a1f 29 int pad;
0f113f3e
MC
30 /* message digest used for parameter generation */
31 const EVP_MD *md;
32 int rfc5114_param;
d59d853a 33 int param_nid;
0f113f3e
MC
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;
3ba0885a
DSH
48
49static int pkey_dh_init(EVP_PKEY_CTX *ctx)
0f113f3e
MC
50{
51 DH_PKEY_CTX *dctx;
64b25758
RS
52
53 dctx = OPENSSL_zalloc(sizeof(*dctx));
90945fa3 54 if (dctx == NULL)
0f113f3e
MC
55 return 0;
56 dctx->prime_len = 1024;
57 dctx->subprime_len = -1;
58 dctx->generator = 2;
0f113f3e 59 dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
0f113f3e
MC
60
61 ctx->data = dctx;
62 ctx->keygen_info = dctx->gentmp;
63 ctx->keygen_info_count = 2;
64
65 return 1;
66}
3ba0885a 67
edeb3fd2
IY
68static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
69{
70 DH_PKEY_CTX *dctx = ctx->data;
71 if (dctx != NULL) {
72 OPENSSL_free(dctx->kdf_ukm);
73 ASN1_OBJECT_free(dctx->kdf_oid);
74 OPENSSL_free(dctx);
75 }
76}
77
78
8bdcef40 79static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
0f113f3e
MC
80{
81 DH_PKEY_CTX *dctx, *sctx;
82 if (!pkey_dh_init(dst))
83 return 0;
84 sctx = src->data;
85 dctx = dst->data;
86 dctx->prime_len = sctx->prime_len;
87 dctx->subprime_len = sctx->subprime_len;
88 dctx->generator = sctx->generator;
89 dctx->use_dsa = sctx->use_dsa;
f4403a1f 90 dctx->pad = sctx->pad;
0f113f3e
MC
91 dctx->md = sctx->md;
92 dctx->rfc5114_param = sctx->rfc5114_param;
d59d853a 93 dctx->param_nid = sctx->param_nid;
0f113f3e
MC
94
95 dctx->kdf_type = sctx->kdf_type;
96 dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
edeb3fd2 97 if (dctx->kdf_oid == NULL)
0f113f3e
MC
98 return 0;
99 dctx->kdf_md = sctx->kdf_md;
edeb3fd2 100 if (sctx->kdf_ukm != NULL) {
7644a9ae 101 dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
edeb3fd2
IY
102 if (dctx->kdf_ukm == NULL)
103 return 0;
0f113f3e
MC
104 dctx->kdf_ukmlen = sctx->kdf_ukmlen;
105 }
106 dctx->kdf_outlen = sctx->kdf_outlen;
107 return 1;
108}
8bdcef40 109
3ba0885a 110static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
0f113f3e
MC
111{
112 DH_PKEY_CTX *dctx = ctx->data;
113 switch (type) {
114 case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
115 if (p1 < 256)
116 return -2;
117 dctx->prime_len = p1;
118 return 1;
119
120 case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
121 if (dctx->use_dsa == 0)
122 return -2;
123 dctx->subprime_len = p1;
124 return 1;
125
f4403a1f
DSH
126 case EVP_PKEY_CTRL_DH_PAD:
127 dctx->pad = p1;
128 return 1;
129
0f113f3e
MC
130 case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
131 if (dctx->use_dsa)
132 return -2;
133 dctx->generator = p1;
134 return 1;
135
136 case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
39090878 137#ifdef OPENSSL_NO_DSA
0f113f3e
MC
138 if (p1 != 0)
139 return -2;
39090878 140#else
0f113f3e
MC
141 if (p1 < 0 || p1 > 2)
142 return -2;
39090878 143#endif
0f113f3e
MC
144 dctx->use_dsa = p1;
145 return 1;
146
147 case EVP_PKEY_CTRL_DH_RFC5114:
d59d853a 148 if (p1 < 1 || p1 > 3 || dctx->param_nid != NID_undef)
0f113f3e
MC
149 return -2;
150 dctx->rfc5114_param = p1;
151 return 1;
152
d59d853a
DSH
153 case EVP_PKEY_CTRL_DH_NID:
154 if (p1 <= 0 || dctx->rfc5114_param != 0)
155 return -2;
156 dctx->param_nid = p1;
157 return 1;
158
0f113f3e
MC
159 case EVP_PKEY_CTRL_PEER_KEY:
160 /* Default behaviour is OK */
161 return 1;
162
163 case EVP_PKEY_CTRL_DH_KDF_TYPE:
164 if (p1 == -2)
165 return dctx->kdf_type;
e968561d
DB
166#ifdef OPENSSL_NO_CMS
167 if (p1 != EVP_PKEY_DH_KDF_NONE)
168#else
0f113f3e 169 if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
e968561d 170#endif
0f113f3e
MC
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:
b548a1f1 194 OPENSSL_free(dctx->kdf_ukm);
0f113f3e
MC
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:
0dfb9398 207 ASN1_OBJECT_free(dctx->kdf_oid);
0f113f3e
MC
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}
39090878 220
3ba0885a 221static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
0f113f3e
MC
222 const char *type, const char *value)
223{
86885c28 224 if (strcmp(type, "dh_paramgen_prime_len") == 0) {
0f113f3e
MC
225 int len;
226 len = atoi(value);
227 return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
228 }
86885c28 229 if (strcmp(type, "dh_rfc5114") == 0) {
0f113f3e
MC
230 DH_PKEY_CTX *dctx = ctx->data;
231 int len;
232 len = atoi(value);
233 if (len < 0 || len > 3)
234 return -2;
235 dctx->rfc5114_param = len;
236 return 1;
237 }
d59d853a
DSH
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 DHerr(DH_F_PKEY_DH_CTRL_STR, DH_R_INVALID_PARAMETER_NAME);
244 return -2;
245 }
246 dctx->param_nid = nid;
247 return 1;
248 }
86885c28 249 if (strcmp(type, "dh_paramgen_generator") == 0) {
0f113f3e
MC
250 int len;
251 len = atoi(value);
252 return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
253 }
86885c28 254 if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
0f113f3e
MC
255 int len;
256 len = atoi(value);
257 return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
258 }
86885c28 259 if (strcmp(type, "dh_paramgen_type") == 0) {
0f113f3e
MC
260 int typ;
261 typ = atoi(value);
262 return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
263 }
f4403a1f
DSH
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 }
0f113f3e
MC
269 return -2;
270}
3ba0885a 271
39090878
DSH
272#ifndef OPENSSL_NO_DSA
273
274extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
0f113f3e
MC
275 const EVP_MD *evpmd,
276 const unsigned char *seed_in, size_t seed_len,
277 unsigned char *seed_out, int *counter_ret,
278 unsigned long *h_ret, BN_GENCB *cb);
39090878
DSH
279
280extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
0f113f3e
MC
281 const EVP_MD *evpmd,
282 const unsigned char *seed_in,
283 size_t seed_len, int idx,
284 unsigned char *seed_out, int *counter_ret,
285 unsigned long *h_ret, BN_GENCB *cb);
39090878
DSH
286
287static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
0f113f3e
MC
288{
289 DSA *ret;
290 int rv = 0;
291 int prime_len = dctx->prime_len;
292 int subprime_len = dctx->subprime_len;
293 const EVP_MD *md = dctx->md;
294 if (dctx->use_dsa > 2)
295 return NULL;
296 ret = DSA_new();
90945fa3 297 if (ret == NULL)
0f113f3e
MC
298 return NULL;
299 if (subprime_len == -1) {
300 if (prime_len >= 2048)
301 subprime_len = 256;
302 else
303 subprime_len = 160;
304 }
305 if (md == NULL) {
306 if (prime_len >= 2048)
307 md = EVP_sha256();
308 else
309 md = EVP_sha1();
310 }
311 if (dctx->use_dsa == 1)
312 rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
313 NULL, 0, NULL, NULL, NULL, pcb);
314 else if (dctx->use_dsa == 2)
315 rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
316 NULL, 0, -1, NULL, NULL, NULL, pcb);
317 if (rv <= 0) {
318 DSA_free(ret);
319 return NULL;
320 }
321 return ret;
322}
39090878
DSH
323
324#endif
325
3ba0885a 326static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
0f113f3e
MC
327{
328 DH *dh = NULL;
329 DH_PKEY_CTX *dctx = ctx->data;
330 BN_GENCB *pcb;
331 int ret;
332 if (dctx->rfc5114_param) {
333 switch (dctx->rfc5114_param) {
334 case 1:
335 dh = DH_get_1024_160();
336 break;
337
338 case 2:
339 dh = DH_get_2048_224();
340 break;
341
342 case 3:
343 dh = DH_get_2048_256();
344 break;
345
346 default:
347 return -2;
348 }
349 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
350 return 1;
351 }
352
d59d853a
DSH
353 if (dctx->param_nid != 0) {
354 if ((dh = DH_new_by_nid(dctx->param_nid)) == NULL)
355 return 0;
356 EVP_PKEY_assign(pkey, EVP_PKEY_DH, dh);
357 return 1;
358 }
359
0f113f3e
MC
360 if (ctx->pkey_gencb) {
361 pcb = BN_GENCB_new();
90945fa3
MC
362 if (pcb == NULL)
363 return 0;
0f113f3e
MC
364 evp_pkey_set_cb_translate(pcb, ctx);
365 } else
366 pcb = NULL;
39090878 367#ifndef OPENSSL_NO_DSA
0f113f3e
MC
368 if (dctx->use_dsa) {
369 DSA *dsa_dh;
370 dsa_dh = dsa_dh_generate(dctx, pcb);
23a1d5e9 371 BN_GENCB_free(pcb);
90945fa3 372 if (dsa_dh == NULL)
0f113f3e
MC
373 return 0;
374 dh = DSA_dup_DH(dsa_dh);
375 DSA_free(dsa_dh);
376 if (!dh)
377 return 0;
378 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
379 return 1;
380 }
39090878 381#endif
0f113f3e 382 dh = DH_new();
90945fa3 383 if (dh == NULL) {
23a1d5e9 384 BN_GENCB_free(pcb);
0f113f3e
MC
385 return 0;
386 }
387 ret = DH_generate_parameters_ex(dh,
388 dctx->prime_len, dctx->generator, pcb);
23a1d5e9 389 BN_GENCB_free(pcb);
0f113f3e
MC
390 if (ret)
391 EVP_PKEY_assign_DH(pkey, dh);
392 else
393 DH_free(dh);
394 return ret;
395}
3ba0885a
DSH
396
397static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
0f113f3e 398{
d59d853a 399 DH_PKEY_CTX *dctx = ctx->data;
0f113f3e 400 DH *dh = NULL;
d59d853a
DSH
401
402 if (ctx->pkey == NULL && dctx->param_nid == 0) {
0f113f3e
MC
403 DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
404 return 0;
405 }
d59d853a
DSH
406 if (dctx->param_nid != 0)
407 dh = DH_new_by_nid(dctx->param_nid);
408 else
409 dh = DH_new();
90945fa3 410 if (dh == NULL)
0f113f3e
MC
411 return 0;
412 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
413 /* Note: if error return, pkey is freed by parent routine */
d59d853a 414 if (ctx->pkey != NULL && !EVP_PKEY_copy_parameters(pkey, ctx->pkey))
0f113f3e
MC
415 return 0;
416 return DH_generate_key(pkey->pkey.dh);
417}
418
419static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
420 size_t *keylen)
421{
422 int ret;
423 DH *dh;
424 DH_PKEY_CTX *dctx = ctx->data;
425 BIGNUM *dhpub;
426 if (!ctx->pkey || !ctx->peerkey) {
427 DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
428 return 0;
429 }
430 dh = ctx->pkey->pkey.dh;
431 dhpub = ctx->peerkey->pkey.dh->pub_key;
432 if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
433 if (key == NULL) {
434 *keylen = DH_size(dh);
435 return 1;
436 }
f4403a1f
DSH
437 if (dctx->pad)
438 ret = DH_compute_key_padded(key, dhpub, dh);
439 else
440 ret = DH_compute_key(key, dhpub, dh);
0f113f3e
MC
441 if (ret < 0)
442 return ret;
443 *keylen = ret;
444 return 1;
e968561d
DB
445 }
446#ifndef OPENSSL_NO_CMS
447 else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
448
0f113f3e
MC
449 unsigned char *Z = NULL;
450 size_t Zlen = 0;
451 if (!dctx->kdf_outlen || !dctx->kdf_oid)
452 return 0;
453 if (key == NULL) {
454 *keylen = dctx->kdf_outlen;
455 return 1;
456 }
457 if (*keylen != dctx->kdf_outlen)
458 return 0;
459 ret = 0;
460 Zlen = DH_size(dh);
461 Z = OPENSSL_malloc(Zlen);
90945fa3 462 if (Z == NULL) {
918bb865
MC
463 goto err;
464 }
0f113f3e
MC
465 if (DH_compute_key_padded(Z, dhpub, dh) <= 0)
466 goto err;
467 if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
468 dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
469 goto err;
470 *keylen = dctx->kdf_outlen;
471 ret = 1;
472 err:
4b45c6e5 473 OPENSSL_clear_free(Z, Zlen);
0f113f3e
MC
474 return ret;
475 }
e968561d
DB
476#endif
477 return 0;
0f113f3e
MC
478}
479
480const EVP_PKEY_METHOD dh_pkey_meth = {
481 EVP_PKEY_DH,
482 0,
483 pkey_dh_init,
484 pkey_dh_copy,
485 pkey_dh_cleanup,
486
487 0,
488 pkey_dh_paramgen,
489
490 0,
491 pkey_dh_keygen,
492
493 0,
494 0,
495
496 0,
497 0,
498
499 0, 0,
500
501 0, 0, 0, 0,
502
503 0, 0,
504
505 0, 0,
506
507 0,
508 pkey_dh_derive,
509
510 pkey_dh_ctrl,
511 pkey_dh_ctrl_str
512};
513
514const EVP_PKEY_METHOD dhx_pkey_meth = {
515 EVP_PKEY_DHX,
516 0,
517 pkey_dh_init,
518 pkey_dh_copy,
519 pkey_dh_cleanup,
520
521 0,
522 pkey_dh_paramgen,
523
524 0,
525 pkey_dh_keygen,
526
527 0,
528 0,
529
530 0,
531 0,
532
533 0, 0,
534
535 0, 0, 0, 0,
536
537 0, 0,
538
539 0, 0,
540
541 0,
542 pkey_dh_derive,
543
544 pkey_dh_ctrl,
545 pkey_dh_ctrl_str
546};