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