]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/dh/dh_pmeth.c
751428cb66c45ea7cc40e6aa933cc175f69bff16
[thirdparty/openssl.git] / crypto / dh / dh_pmeth.c
1 /*
2 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
3 * 2006.
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
13 * notice, this list of conditions and the following disclaimer.
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>
60 #include "internal/cryptlib.h"
61 #include <openssl/asn1t.h>
62 #include <openssl/x509.h>
63 #include <openssl/evp.h>
64 #include <openssl/dh.h>
65 #include <openssl/bn.h>
66 #ifndef OPENSSL_NO_DSA
67 # include <openssl/dsa.h>
68 #endif
69 #include <openssl/objects.h>
70 #include "internal/evp_int.h"
71
72 /* DH pkey context structure */
73
74 typedef 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;
97
98 static int pkey_dh_init(EVP_PKEY_CTX *ctx)
99 {
100 DH_PKEY_CTX *dctx;
101 dctx = OPENSSL_malloc(sizeof(*dctx));
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 }
124
125 static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
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 }
151
152 static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
153 {
154 DH_PKEY_CTX *dctx = ctx->data;
155 if (dctx) {
156 OPENSSL_free(dctx->kdf_ukm);
157 ASN1_OBJECT_free(dctx->kdf_oid);
158 OPENSSL_free(dctx);
159 }
160 }
161
162 static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
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:
185 #ifdef OPENSSL_NO_DSA
186 if (p1 != 0)
187 return -2;
188 #else
189 if (p1 < 0 || p1 > 2)
190 return -2;
191 #endif
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 #ifdef OPENSSL_NO_CMS
209 if (p1 != EVP_PKEY_DH_KDF_NONE)
210 #else
211 if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
212 #endif
213 return -2;
214 dctx->kdf_type = p1;
215 return 1;
216
217 case EVP_PKEY_CTRL_DH_KDF_MD:
218 dctx->kdf_md = p2;
219 return 1;
220
221 case EVP_PKEY_CTRL_GET_DH_KDF_MD:
222 *(const EVP_MD **)p2 = dctx->kdf_md;
223 return 1;
224
225 case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
226 if (p1 <= 0)
227 return -2;
228 dctx->kdf_outlen = (size_t)p1;
229 return 1;
230
231 case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
232 *(int *)p2 = dctx->kdf_outlen;
233 return 1;
234
235 case EVP_PKEY_CTRL_DH_KDF_UKM:
236 OPENSSL_free(dctx->kdf_ukm);
237 dctx->kdf_ukm = p2;
238 if (p2)
239 dctx->kdf_ukmlen = p1;
240 else
241 dctx->kdf_ukmlen = 0;
242 return 1;
243
244 case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
245 *(unsigned char **)p2 = dctx->kdf_ukm;
246 return dctx->kdf_ukmlen;
247
248 case EVP_PKEY_CTRL_DH_KDF_OID:
249 ASN1_OBJECT_free(dctx->kdf_oid);
250 dctx->kdf_oid = p2;
251 return 1;
252
253 case EVP_PKEY_CTRL_GET_DH_KDF_OID:
254 *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
255 return 1;
256
257 default:
258 return -2;
259
260 }
261 }
262
263 static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
264 const char *type, const char *value)
265 {
266 if (strcmp(type, "dh_paramgen_prime_len") == 0) {
267 int len;
268 len = atoi(value);
269 return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
270 }
271 if (strcmp(type, "dh_rfc5114") == 0) {
272 DH_PKEY_CTX *dctx = ctx->data;
273 int len;
274 len = atoi(value);
275 if (len < 0 || len > 3)
276 return -2;
277 dctx->rfc5114_param = len;
278 return 1;
279 }
280 if (strcmp(type, "dh_paramgen_generator") == 0) {
281 int len;
282 len = atoi(value);
283 return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
284 }
285 if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
286 int len;
287 len = atoi(value);
288 return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
289 }
290 if (strcmp(type, "dh_paramgen_type") == 0) {
291 int typ;
292 typ = atoi(value);
293 return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
294 }
295 return -2;
296 }
297
298 #ifndef OPENSSL_NO_DSA
299
300 extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
301 const EVP_MD *evpmd,
302 const unsigned char *seed_in, size_t seed_len,
303 unsigned char *seed_out, int *counter_ret,
304 unsigned long *h_ret, BN_GENCB *cb);
305
306 extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
307 const EVP_MD *evpmd,
308 const unsigned char *seed_in,
309 size_t seed_len, int idx,
310 unsigned char *seed_out, int *counter_ret,
311 unsigned long *h_ret, BN_GENCB *cb);
312
313 static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
314 {
315 DSA *ret;
316 int rv = 0;
317 int prime_len = dctx->prime_len;
318 int subprime_len = dctx->subprime_len;
319 const EVP_MD *md = dctx->md;
320 if (dctx->use_dsa > 2)
321 return NULL;
322 ret = DSA_new();
323 if (!ret)
324 return NULL;
325 if (subprime_len == -1) {
326 if (prime_len >= 2048)
327 subprime_len = 256;
328 else
329 subprime_len = 160;
330 }
331 if (md == NULL) {
332 if (prime_len >= 2048)
333 md = EVP_sha256();
334 else
335 md = EVP_sha1();
336 }
337 if (dctx->use_dsa == 1)
338 rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
339 NULL, 0, NULL, NULL, NULL, pcb);
340 else if (dctx->use_dsa == 2)
341 rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
342 NULL, 0, -1, NULL, NULL, NULL, pcb);
343 if (rv <= 0) {
344 DSA_free(ret);
345 return NULL;
346 }
347 return ret;
348 }
349
350 #endif
351
352 static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
353 {
354 DH *dh = NULL;
355 DH_PKEY_CTX *dctx = ctx->data;
356 BN_GENCB *pcb;
357 int ret;
358 if (dctx->rfc5114_param) {
359 switch (dctx->rfc5114_param) {
360 case 1:
361 dh = DH_get_1024_160();
362 break;
363
364 case 2:
365 dh = DH_get_2048_224();
366 break;
367
368 case 3:
369 dh = DH_get_2048_256();
370 break;
371
372 default:
373 return -2;
374 }
375 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
376 return 1;
377 }
378
379 if (ctx->pkey_gencb) {
380 pcb = BN_GENCB_new();
381 evp_pkey_set_cb_translate(pcb, ctx);
382 } else
383 pcb = NULL;
384 #ifndef OPENSSL_NO_DSA
385 if (dctx->use_dsa) {
386 DSA *dsa_dh;
387 dsa_dh = dsa_dh_generate(dctx, pcb);
388 BN_GENCB_free(pcb);
389 if (!dsa_dh)
390 return 0;
391 dh = DSA_dup_DH(dsa_dh);
392 DSA_free(dsa_dh);
393 if (!dh)
394 return 0;
395 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
396 return 1;
397 }
398 #endif
399 dh = DH_new();
400 if (!dh) {
401 BN_GENCB_free(pcb);
402 return 0;
403 }
404 ret = DH_generate_parameters_ex(dh,
405 dctx->prime_len, dctx->generator, pcb);
406 BN_GENCB_free(pcb);
407 if (ret)
408 EVP_PKEY_assign_DH(pkey, dh);
409 else
410 DH_free(dh);
411 return ret;
412 }
413
414 static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
415 {
416 DH *dh = NULL;
417 if (ctx->pkey == NULL) {
418 DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
419 return 0;
420 }
421 dh = DH_new();
422 if (!dh)
423 return 0;
424 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
425 /* Note: if error return, pkey is freed by parent routine */
426 if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
427 return 0;
428 return DH_generate_key(pkey->pkey.dh);
429 }
430
431 static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
432 size_t *keylen)
433 {
434 int ret;
435 DH *dh;
436 DH_PKEY_CTX *dctx = ctx->data;
437 BIGNUM *dhpub;
438 if (!ctx->pkey || !ctx->peerkey) {
439 DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
440 return 0;
441 }
442 dh = ctx->pkey->pkey.dh;
443 dhpub = ctx->peerkey->pkey.dh->pub_key;
444 if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
445 if (key == NULL) {
446 *keylen = DH_size(dh);
447 return 1;
448 }
449 ret = DH_compute_key(key, dhpub, dh);
450 if (ret < 0)
451 return ret;
452 *keylen = ret;
453 return 1;
454 }
455 #ifndef OPENSSL_NO_CMS
456 else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
457
458 unsigned char *Z = NULL;
459 size_t Zlen = 0;
460 if (!dctx->kdf_outlen || !dctx->kdf_oid)
461 return 0;
462 if (key == NULL) {
463 *keylen = dctx->kdf_outlen;
464 return 1;
465 }
466 if (*keylen != dctx->kdf_outlen)
467 return 0;
468 ret = 0;
469 Zlen = DH_size(dh);
470 Z = OPENSSL_malloc(Zlen);
471 if (!Z) {
472 goto err;
473 }
474 if (DH_compute_key_padded(Z, dhpub, dh) <= 0)
475 goto err;
476 if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
477 dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
478 goto err;
479 *keylen = dctx->kdf_outlen;
480 ret = 1;
481 err:
482 OPENSSL_clear_free(Z, Zlen);
483 return ret;
484 }
485 #endif
486 return 0;
487 }
488
489 const EVP_PKEY_METHOD dh_pkey_meth = {
490 EVP_PKEY_DH,
491 0,
492 pkey_dh_init,
493 pkey_dh_copy,
494 pkey_dh_cleanup,
495
496 0,
497 pkey_dh_paramgen,
498
499 0,
500 pkey_dh_keygen,
501
502 0,
503 0,
504
505 0,
506 0,
507
508 0, 0,
509
510 0, 0, 0, 0,
511
512 0, 0,
513
514 0, 0,
515
516 0,
517 pkey_dh_derive,
518
519 pkey_dh_ctrl,
520 pkey_dh_ctrl_str
521 };
522
523 const EVP_PKEY_METHOD dhx_pkey_meth = {
524 EVP_PKEY_DHX,
525 0,
526 pkey_dh_init,
527 pkey_dh_copy,
528 pkey_dh_cleanup,
529
530 0,
531 pkey_dh_paramgen,
532
533 0,
534 pkey_dh_keygen,
535
536 0,
537 0,
538
539 0,
540 0,
541
542 0, 0,
543
544 0, 0, 0, 0,
545
546 0, 0,
547
548 0, 0,
549
550 0,
551 pkey_dh_derive,
552
553 pkey_dh_ctrl,
554 pkey_dh_ctrl_str
555 };