]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/dh/dh_pmeth.c
fix for no-ec
[thirdparty/openssl.git] / crypto / dh / dh_pmeth.c
CommitLineData
0f113f3e
MC
1/*
2 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
3 * 2006.
3ba0885a
DSH
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
0f113f3e 13 * notice, this list of conditions and the following disclaimer.
3ba0885a
DSH
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
b39fc560 60#include "internal/cryptlib.h"
3ba0885a
DSH
61#include <openssl/asn1t.h>
62#include <openssl/x509.h>
3ba0885a 63#include <openssl/evp.h>
1e26a8ba
GT
64#include <openssl/dh.h>
65#include <openssl/bn.h>
39090878 66#ifndef OPENSSL_NO_DSA
0f113f3e 67# include <openssl/dsa.h>
39090878 68#endif
bd59f2b9 69#include <openssl/objects.h>
27af42f9 70#include "internal/evp_int.h"
3ba0885a
DSH
71
72/* DH pkey context structure */
73
0f113f3e
MC
74typedef struct {
75 /* Parameter gen parameters */
76 int prime_len;
77 int generator;
78 int use_dsa;
79 int subprime_len;
80 /* message digest used for parameter generation */
81 const EVP_MD *md;
82 int rfc5114_param;
83 /* Keygen callback info */
84 int gentmp[2];
85 /* KDF (if any) to use for DH */
86 char kdf_type;
87 /* OID to use for KDF */
88 ASN1_OBJECT *kdf_oid;
89 /* Message digest to use for key derivation */
90 const EVP_MD *kdf_md;
91 /* User key material */
92 unsigned char *kdf_ukm;
93 size_t kdf_ukmlen;
94 /* KDF output length */
95 size_t kdf_outlen;
96} DH_PKEY_CTX;
3ba0885a
DSH
97
98static int pkey_dh_init(EVP_PKEY_CTX *ctx)
0f113f3e
MC
99{
100 DH_PKEY_CTX *dctx;
64b25758
RS
101
102 dctx = OPENSSL_zalloc(sizeof(*dctx));
90945fa3 103 if (dctx == NULL)
0f113f3e
MC
104 return 0;
105 dctx->prime_len = 1024;
106 dctx->subprime_len = -1;
107 dctx->generator = 2;
0f113f3e 108 dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
0f113f3e
MC
109
110 ctx->data = dctx;
111 ctx->keygen_info = dctx->gentmp;
112 ctx->keygen_info_count = 2;
113
114 return 1;
115}
3ba0885a 116
8bdcef40 117static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
0f113f3e
MC
118{
119 DH_PKEY_CTX *dctx, *sctx;
120 if (!pkey_dh_init(dst))
121 return 0;
122 sctx = src->data;
123 dctx = dst->data;
124 dctx->prime_len = sctx->prime_len;
125 dctx->subprime_len = sctx->subprime_len;
126 dctx->generator = sctx->generator;
127 dctx->use_dsa = sctx->use_dsa;
128 dctx->md = sctx->md;
129 dctx->rfc5114_param = sctx->rfc5114_param;
130
131 dctx->kdf_type = sctx->kdf_type;
132 dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
133 if (!dctx->kdf_oid)
134 return 0;
135 dctx->kdf_md = sctx->kdf_md;
136 if (dctx->kdf_ukm) {
137 dctx->kdf_ukm = BUF_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
138 dctx->kdf_ukmlen = sctx->kdf_ukmlen;
139 }
140 dctx->kdf_outlen = sctx->kdf_outlen;
141 return 1;
142}
8bdcef40 143
3ba0885a 144static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
0f113f3e
MC
145{
146 DH_PKEY_CTX *dctx = ctx->data;
147 if (dctx) {
b548a1f1 148 OPENSSL_free(dctx->kdf_ukm);
0dfb9398 149 ASN1_OBJECT_free(dctx->kdf_oid);
0f113f3e
MC
150 OPENSSL_free(dctx);
151 }
152}
3ba0885a
DSH
153
154static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
0f113f3e
MC
155{
156 DH_PKEY_CTX *dctx = ctx->data;
157 switch (type) {
158 case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
159 if (p1 < 256)
160 return -2;
161 dctx->prime_len = p1;
162 return 1;
163
164 case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
165 if (dctx->use_dsa == 0)
166 return -2;
167 dctx->subprime_len = p1;
168 return 1;
169
170 case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
171 if (dctx->use_dsa)
172 return -2;
173 dctx->generator = p1;
174 return 1;
175
176 case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
39090878 177#ifdef OPENSSL_NO_DSA
0f113f3e
MC
178 if (p1 != 0)
179 return -2;
39090878 180#else
0f113f3e
MC
181 if (p1 < 0 || p1 > 2)
182 return -2;
39090878 183#endif
0f113f3e
MC
184 dctx->use_dsa = p1;
185 return 1;
186
187 case EVP_PKEY_CTRL_DH_RFC5114:
188 if (p1 < 1 || p1 > 3)
189 return -2;
190 dctx->rfc5114_param = p1;
191 return 1;
192
193 case EVP_PKEY_CTRL_PEER_KEY:
194 /* Default behaviour is OK */
195 return 1;
196
197 case EVP_PKEY_CTRL_DH_KDF_TYPE:
198 if (p1 == -2)
199 return dctx->kdf_type;
e968561d
DB
200#ifdef OPENSSL_NO_CMS
201 if (p1 != EVP_PKEY_DH_KDF_NONE)
202#else
0f113f3e 203 if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
e968561d 204#endif
0f113f3e
MC
205 return -2;
206 dctx->kdf_type = p1;
207 return 1;
208
209 case EVP_PKEY_CTRL_DH_KDF_MD:
210 dctx->kdf_md = p2;
211 return 1;
212
213 case EVP_PKEY_CTRL_GET_DH_KDF_MD:
214 *(const EVP_MD **)p2 = dctx->kdf_md;
215 return 1;
216
217 case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
218 if (p1 <= 0)
219 return -2;
220 dctx->kdf_outlen = (size_t)p1;
221 return 1;
222
223 case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
224 *(int *)p2 = dctx->kdf_outlen;
225 return 1;
226
227 case EVP_PKEY_CTRL_DH_KDF_UKM:
b548a1f1 228 OPENSSL_free(dctx->kdf_ukm);
0f113f3e
MC
229 dctx->kdf_ukm = p2;
230 if (p2)
231 dctx->kdf_ukmlen = p1;
232 else
233 dctx->kdf_ukmlen = 0;
234 return 1;
235
236 case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
237 *(unsigned char **)p2 = dctx->kdf_ukm;
238 return dctx->kdf_ukmlen;
239
240 case EVP_PKEY_CTRL_DH_KDF_OID:
0dfb9398 241 ASN1_OBJECT_free(dctx->kdf_oid);
0f113f3e
MC
242 dctx->kdf_oid = p2;
243 return 1;
244
245 case EVP_PKEY_CTRL_GET_DH_KDF_OID:
246 *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
247 return 1;
248
249 default:
250 return -2;
251
252 }
253}
39090878 254
3ba0885a 255static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
0f113f3e
MC
256 const char *type, const char *value)
257{
86885c28 258 if (strcmp(type, "dh_paramgen_prime_len") == 0) {
0f113f3e
MC
259 int len;
260 len = atoi(value);
261 return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
262 }
86885c28 263 if (strcmp(type, "dh_rfc5114") == 0) {
0f113f3e
MC
264 DH_PKEY_CTX *dctx = ctx->data;
265 int len;
266 len = atoi(value);
267 if (len < 0 || len > 3)
268 return -2;
269 dctx->rfc5114_param = len;
270 return 1;
271 }
86885c28 272 if (strcmp(type, "dh_paramgen_generator") == 0) {
0f113f3e
MC
273 int len;
274 len = atoi(value);
275 return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
276 }
86885c28 277 if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
0f113f3e
MC
278 int len;
279 len = atoi(value);
280 return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
281 }
86885c28 282 if (strcmp(type, "dh_paramgen_type") == 0) {
0f113f3e
MC
283 int typ;
284 typ = atoi(value);
285 return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
286 }
287 return -2;
288}
3ba0885a 289
39090878
DSH
290#ifndef OPENSSL_NO_DSA
291
292extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
0f113f3e
MC
293 const EVP_MD *evpmd,
294 const unsigned char *seed_in, size_t seed_len,
295 unsigned char *seed_out, int *counter_ret,
296 unsigned long *h_ret, BN_GENCB *cb);
39090878
DSH
297
298extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
0f113f3e
MC
299 const EVP_MD *evpmd,
300 const unsigned char *seed_in,
301 size_t seed_len, int idx,
302 unsigned char *seed_out, int *counter_ret,
303 unsigned long *h_ret, BN_GENCB *cb);
39090878
DSH
304
305static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
0f113f3e
MC
306{
307 DSA *ret;
308 int rv = 0;
309 int prime_len = dctx->prime_len;
310 int subprime_len = dctx->subprime_len;
311 const EVP_MD *md = dctx->md;
312 if (dctx->use_dsa > 2)
313 return NULL;
314 ret = DSA_new();
90945fa3 315 if (ret == NULL)
0f113f3e
MC
316 return NULL;
317 if (subprime_len == -1) {
318 if (prime_len >= 2048)
319 subprime_len = 256;
320 else
321 subprime_len = 160;
322 }
323 if (md == NULL) {
324 if (prime_len >= 2048)
325 md = EVP_sha256();
326 else
327 md = EVP_sha1();
328 }
329 if (dctx->use_dsa == 1)
330 rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
331 NULL, 0, NULL, NULL, NULL, pcb);
332 else if (dctx->use_dsa == 2)
333 rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
334 NULL, 0, -1, NULL, NULL, NULL, pcb);
335 if (rv <= 0) {
336 DSA_free(ret);
337 return NULL;
338 }
339 return ret;
340}
39090878
DSH
341
342#endif
343
3ba0885a 344static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
0f113f3e
MC
345{
346 DH *dh = NULL;
347 DH_PKEY_CTX *dctx = ctx->data;
348 BN_GENCB *pcb;
349 int ret;
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
371 if (ctx->pkey_gencb) {
372 pcb = BN_GENCB_new();
90945fa3
MC
373 if (pcb == NULL)
374 return 0;
0f113f3e
MC
375 evp_pkey_set_cb_translate(pcb, ctx);
376 } else
377 pcb = NULL;
39090878 378#ifndef OPENSSL_NO_DSA
0f113f3e
MC
379 if (dctx->use_dsa) {
380 DSA *dsa_dh;
381 dsa_dh = dsa_dh_generate(dctx, pcb);
23a1d5e9 382 BN_GENCB_free(pcb);
90945fa3 383 if (dsa_dh == NULL)
0f113f3e
MC
384 return 0;
385 dh = DSA_dup_DH(dsa_dh);
386 DSA_free(dsa_dh);
387 if (!dh)
388 return 0;
389 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
390 return 1;
391 }
39090878 392#endif
0f113f3e 393 dh = DH_new();
90945fa3 394 if (dh == NULL) {
23a1d5e9 395 BN_GENCB_free(pcb);
0f113f3e
MC
396 return 0;
397 }
398 ret = DH_generate_parameters_ex(dh,
399 dctx->prime_len, dctx->generator, pcb);
23a1d5e9 400 BN_GENCB_free(pcb);
0f113f3e
MC
401 if (ret)
402 EVP_PKEY_assign_DH(pkey, dh);
403 else
404 DH_free(dh);
405 return ret;
406}
3ba0885a
DSH
407
408static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
0f113f3e
MC
409{
410 DH *dh = NULL;
411 if (ctx->pkey == NULL) {
412 DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
413 return 0;
414 }
415 dh = DH_new();
90945fa3 416 if (dh == NULL)
0f113f3e
MC
417 return 0;
418 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
419 /* Note: if error return, pkey is freed by parent routine */
420 if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
421 return 0;
422 return DH_generate_key(pkey->pkey.dh);
423}
424
425static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
426 size_t *keylen)
427{
428 int ret;
429 DH *dh;
430 DH_PKEY_CTX *dctx = ctx->data;
431 BIGNUM *dhpub;
432 if (!ctx->pkey || !ctx->peerkey) {
433 DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
434 return 0;
435 }
436 dh = ctx->pkey->pkey.dh;
437 dhpub = ctx->peerkey->pkey.dh->pub_key;
438 if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
439 if (key == NULL) {
440 *keylen = DH_size(dh);
441 return 1;
442 }
443 ret = DH_compute_key(key, dhpub, dh);
444 if (ret < 0)
445 return ret;
446 *keylen = ret;
447 return 1;
e968561d
DB
448 }
449#ifndef OPENSSL_NO_CMS
450 else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
451
0f113f3e
MC
452 unsigned char *Z = NULL;
453 size_t Zlen = 0;
454 if (!dctx->kdf_outlen || !dctx->kdf_oid)
455 return 0;
456 if (key == NULL) {
457 *keylen = dctx->kdf_outlen;
458 return 1;
459 }
460 if (*keylen != dctx->kdf_outlen)
461 return 0;
462 ret = 0;
463 Zlen = DH_size(dh);
464 Z = OPENSSL_malloc(Zlen);
90945fa3 465 if (Z == NULL) {
918bb865
MC
466 goto err;
467 }
0f113f3e
MC
468 if (DH_compute_key_padded(Z, dhpub, dh) <= 0)
469 goto err;
470 if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
471 dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
472 goto err;
473 *keylen = dctx->kdf_outlen;
474 ret = 1;
475 err:
4b45c6e5 476 OPENSSL_clear_free(Z, Zlen);
0f113f3e
MC
477 return ret;
478 }
e968561d
DB
479#endif
480 return 0;
0f113f3e
MC
481}
482
483const EVP_PKEY_METHOD dh_pkey_meth = {
484 EVP_PKEY_DH,
485 0,
486 pkey_dh_init,
487 pkey_dh_copy,
488 pkey_dh_cleanup,
489
490 0,
491 pkey_dh_paramgen,
492
493 0,
494 pkey_dh_keygen,
495
496 0,
497 0,
498
499 0,
500 0,
501
502 0, 0,
503
504 0, 0, 0, 0,
505
506 0, 0,
507
508 0, 0,
509
510 0,
511 pkey_dh_derive,
512
513 pkey_dh_ctrl,
514 pkey_dh_ctrl_str
515};
516
517const EVP_PKEY_METHOD dhx_pkey_meth = {
518 EVP_PKEY_DHX,
519 0,
520 pkey_dh_init,
521 pkey_dh_copy,
522 pkey_dh_cleanup,
523
524 0,
525 pkey_dh_paramgen,
526
527 0,
528 pkey_dh_keygen,
529
530 0,
531 0,
532
533 0,
534 0,
535
536 0, 0,
537
538 0, 0, 0, 0,
539
540 0, 0,
541
542 0, 0,
543
544 0,
545 pkey_dh_derive,
546
547 pkey_dh_ctrl,
548 pkey_dh_ctrl_str
549};