]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/dh/dh_pmeth.c
make update
[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;
b4faea50 101 dctx = OPENSSL_malloc(sizeof(*dctx));
0f113f3e
MC
102 if (!dctx)
103 return 0;
104 dctx->prime_len = 1024;
105 dctx->subprime_len = -1;
106 dctx->generator = 2;
107 dctx->use_dsa = 0;
108 dctx->md = NULL;
109 dctx->rfc5114_param = 0;
110
111 dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
112 dctx->kdf_oid = NULL;
113 dctx->kdf_md = NULL;
114 dctx->kdf_ukm = NULL;
115 dctx->kdf_ukmlen = 0;
116 dctx->kdf_outlen = 0;
117
118 ctx->data = dctx;
119 ctx->keygen_info = dctx->gentmp;
120 ctx->keygen_info_count = 2;
121
122 return 1;
123}
3ba0885a 124
8bdcef40 125static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
0f113f3e
MC
126{
127 DH_PKEY_CTX *dctx, *sctx;
128 if (!pkey_dh_init(dst))
129 return 0;
130 sctx = src->data;
131 dctx = dst->data;
132 dctx->prime_len = sctx->prime_len;
133 dctx->subprime_len = sctx->subprime_len;
134 dctx->generator = sctx->generator;
135 dctx->use_dsa = sctx->use_dsa;
136 dctx->md = sctx->md;
137 dctx->rfc5114_param = sctx->rfc5114_param;
138
139 dctx->kdf_type = sctx->kdf_type;
140 dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
141 if (!dctx->kdf_oid)
142 return 0;
143 dctx->kdf_md = sctx->kdf_md;
144 if (dctx->kdf_ukm) {
145 dctx->kdf_ukm = BUF_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
146 dctx->kdf_ukmlen = sctx->kdf_ukmlen;
147 }
148 dctx->kdf_outlen = sctx->kdf_outlen;
149 return 1;
150}
8bdcef40 151
3ba0885a 152static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
0f113f3e
MC
153{
154 DH_PKEY_CTX *dctx = ctx->data;
155 if (dctx) {
b548a1f1 156 OPENSSL_free(dctx->kdf_ukm);
0dfb9398 157 ASN1_OBJECT_free(dctx->kdf_oid);
0f113f3e
MC
158 OPENSSL_free(dctx);
159 }
160}
3ba0885a
DSH
161
162static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
0f113f3e
MC
163{
164 DH_PKEY_CTX *dctx = ctx->data;
165 switch (type) {
166 case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
167 if (p1 < 256)
168 return -2;
169 dctx->prime_len = p1;
170 return 1;
171
172 case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
173 if (dctx->use_dsa == 0)
174 return -2;
175 dctx->subprime_len = p1;
176 return 1;
177
178 case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
179 if (dctx->use_dsa)
180 return -2;
181 dctx->generator = p1;
182 return 1;
183
184 case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
39090878 185#ifdef OPENSSL_NO_DSA
0f113f3e
MC
186 if (p1 != 0)
187 return -2;
39090878 188#else
0f113f3e
MC
189 if (p1 < 0 || p1 > 2)
190 return -2;
39090878 191#endif
0f113f3e
MC
192 dctx->use_dsa = p1;
193 return 1;
194
195 case EVP_PKEY_CTRL_DH_RFC5114:
196 if (p1 < 1 || p1 > 3)
197 return -2;
198 dctx->rfc5114_param = p1;
199 return 1;
200
201 case EVP_PKEY_CTRL_PEER_KEY:
202 /* Default behaviour is OK */
203 return 1;
204
205 case EVP_PKEY_CTRL_DH_KDF_TYPE:
206 if (p1 == -2)
207 return dctx->kdf_type;
208 if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
209 return -2;
210 dctx->kdf_type = p1;
211 return 1;
212
213 case EVP_PKEY_CTRL_DH_KDF_MD:
214 dctx->kdf_md = p2;
215 return 1;
216
217 case EVP_PKEY_CTRL_GET_DH_KDF_MD:
218 *(const EVP_MD **)p2 = dctx->kdf_md;
219 return 1;
220
221 case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
222 if (p1 <= 0)
223 return -2;
224 dctx->kdf_outlen = (size_t)p1;
225 return 1;
226
227 case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
228 *(int *)p2 = dctx->kdf_outlen;
229 return 1;
230
231 case EVP_PKEY_CTRL_DH_KDF_UKM:
b548a1f1 232 OPENSSL_free(dctx->kdf_ukm);
0f113f3e
MC
233 dctx->kdf_ukm = p2;
234 if (p2)
235 dctx->kdf_ukmlen = p1;
236 else
237 dctx->kdf_ukmlen = 0;
238 return 1;
239
240 case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
241 *(unsigned char **)p2 = dctx->kdf_ukm;
242 return dctx->kdf_ukmlen;
243
244 case EVP_PKEY_CTRL_DH_KDF_OID:
0dfb9398 245 ASN1_OBJECT_free(dctx->kdf_oid);
0f113f3e
MC
246 dctx->kdf_oid = p2;
247 return 1;
248
249 case EVP_PKEY_CTRL_GET_DH_KDF_OID:
250 *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
251 return 1;
252
253 default:
254 return -2;
255
256 }
257}
39090878 258
3ba0885a 259static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
0f113f3e
MC
260 const char *type, const char *value)
261{
86885c28 262 if (strcmp(type, "dh_paramgen_prime_len") == 0) {
0f113f3e
MC
263 int len;
264 len = atoi(value);
265 return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
266 }
86885c28 267 if (strcmp(type, "dh_rfc5114") == 0) {
0f113f3e
MC
268 DH_PKEY_CTX *dctx = ctx->data;
269 int len;
270 len = atoi(value);
271 if (len < 0 || len > 3)
272 return -2;
273 dctx->rfc5114_param = len;
274 return 1;
275 }
86885c28 276 if (strcmp(type, "dh_paramgen_generator") == 0) {
0f113f3e
MC
277 int len;
278 len = atoi(value);
279 return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
280 }
86885c28 281 if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
0f113f3e
MC
282 int len;
283 len = atoi(value);
284 return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
285 }
86885c28 286 if (strcmp(type, "dh_paramgen_type") == 0) {
0f113f3e
MC
287 int typ;
288 typ = atoi(value);
289 return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
290 }
291 return -2;
292}
3ba0885a 293
39090878
DSH
294#ifndef OPENSSL_NO_DSA
295
296extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
0f113f3e
MC
297 const EVP_MD *evpmd,
298 const unsigned char *seed_in, size_t seed_len,
299 unsigned char *seed_out, int *counter_ret,
300 unsigned long *h_ret, BN_GENCB *cb);
39090878
DSH
301
302extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
0f113f3e
MC
303 const EVP_MD *evpmd,
304 const unsigned char *seed_in,
305 size_t seed_len, int idx,
306 unsigned char *seed_out, int *counter_ret,
307 unsigned long *h_ret, BN_GENCB *cb);
39090878
DSH
308
309static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
0f113f3e
MC
310{
311 DSA *ret;
312 int rv = 0;
313 int prime_len = dctx->prime_len;
314 int subprime_len = dctx->subprime_len;
315 const EVP_MD *md = dctx->md;
316 if (dctx->use_dsa > 2)
317 return NULL;
318 ret = DSA_new();
319 if (!ret)
320 return NULL;
321 if (subprime_len == -1) {
322 if (prime_len >= 2048)
323 subprime_len = 256;
324 else
325 subprime_len = 160;
326 }
327 if (md == NULL) {
328 if (prime_len >= 2048)
329 md = EVP_sha256();
330 else
331 md = EVP_sha1();
332 }
333 if (dctx->use_dsa == 1)
334 rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
335 NULL, 0, NULL, NULL, NULL, pcb);
336 else if (dctx->use_dsa == 2)
337 rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
338 NULL, 0, -1, NULL, NULL, NULL, pcb);
339 if (rv <= 0) {
340 DSA_free(ret);
341 return NULL;
342 }
343 return ret;
344}
39090878
DSH
345
346#endif
347
3ba0885a 348static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
0f113f3e
MC
349{
350 DH *dh = NULL;
351 DH_PKEY_CTX *dctx = ctx->data;
352 BN_GENCB *pcb;
353 int ret;
354 if (dctx->rfc5114_param) {
355 switch (dctx->rfc5114_param) {
356 case 1:
357 dh = DH_get_1024_160();
358 break;
359
360 case 2:
361 dh = DH_get_2048_224();
362 break;
363
364 case 3:
365 dh = DH_get_2048_256();
366 break;
367
368 default:
369 return -2;
370 }
371 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
372 return 1;
373 }
374
375 if (ctx->pkey_gencb) {
376 pcb = BN_GENCB_new();
377 evp_pkey_set_cb_translate(pcb, ctx);
378 } else
379 pcb = NULL;
39090878 380#ifndef OPENSSL_NO_DSA
0f113f3e
MC
381 if (dctx->use_dsa) {
382 DSA *dsa_dh;
383 dsa_dh = dsa_dh_generate(dctx, pcb);
23a1d5e9 384 BN_GENCB_free(pcb);
0f113f3e
MC
385 if (!dsa_dh)
386 return 0;
387 dh = DSA_dup_DH(dsa_dh);
388 DSA_free(dsa_dh);
389 if (!dh)
390 return 0;
391 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
392 return 1;
393 }
39090878 394#endif
0f113f3e
MC
395 dh = DH_new();
396 if (!dh) {
23a1d5e9 397 BN_GENCB_free(pcb);
0f113f3e
MC
398 return 0;
399 }
400 ret = DH_generate_parameters_ex(dh,
401 dctx->prime_len, dctx->generator, pcb);
23a1d5e9 402 BN_GENCB_free(pcb);
0f113f3e
MC
403 if (ret)
404 EVP_PKEY_assign_DH(pkey, dh);
405 else
406 DH_free(dh);
407 return ret;
408}
3ba0885a
DSH
409
410static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
0f113f3e
MC
411{
412 DH *dh = NULL;
413 if (ctx->pkey == NULL) {
414 DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
415 return 0;
416 }
417 dh = DH_new();
418 if (!dh)
419 return 0;
420 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
421 /* Note: if error return, pkey is freed by parent routine */
422 if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
423 return 0;
424 return DH_generate_key(pkey->pkey.dh);
425}
426
427static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
428 size_t *keylen)
429{
430 int ret;
431 DH *dh;
432 DH_PKEY_CTX *dctx = ctx->data;
433 BIGNUM *dhpub;
434 if (!ctx->pkey || !ctx->peerkey) {
435 DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
436 return 0;
437 }
438 dh = ctx->pkey->pkey.dh;
439 dhpub = ctx->peerkey->pkey.dh->pub_key;
440 if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
441 if (key == NULL) {
442 *keylen = DH_size(dh);
443 return 1;
444 }
445 ret = DH_compute_key(key, dhpub, dh);
446 if (ret < 0)
447 return ret;
448 *keylen = ret;
449 return 1;
450 } else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
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);
61986d32 464 if (!Z) {
918bb865
MC
465 goto err;
466 }
0f113f3e
MC
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:
4b45c6e5 475 OPENSSL_clear_free(Z, Zlen);
0f113f3e
MC
476 return ret;
477 }
478 return 1;
479}
480
481const EVP_PKEY_METHOD dh_pkey_meth = {
482 EVP_PKEY_DH,
483 0,
484 pkey_dh_init,
485 pkey_dh_copy,
486 pkey_dh_cleanup,
487
488 0,
489 pkey_dh_paramgen,
490
491 0,
492 pkey_dh_keygen,
493
494 0,
495 0,
496
497 0,
498 0,
499
500 0, 0,
501
502 0, 0, 0, 0,
503
504 0, 0,
505
506 0, 0,
507
508 0,
509 pkey_dh_derive,
510
511 pkey_dh_ctrl,
512 pkey_dh_ctrl_str
513};
514
515const EVP_PKEY_METHOD dhx_pkey_meth = {
516 EVP_PKEY_DHX,
517 0,
518 pkey_dh_init,
519 pkey_dh_copy,
520 pkey_dh_cleanup,
521
522 0,
523 pkey_dh_paramgen,
524
525 0,
526 pkey_dh_keygen,
527
528 0,
529 0,
530
531 0,
532 0,
533
534 0, 0,
535
536 0, 0, 0, 0,
537
538 0, 0,
539
540 0, 0,
541
542 0,
543 pkey_dh_derive,
544
545 pkey_dh_ctrl,
546 pkey_dh_ctrl_str
547};