]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/dh/dh_pmeth.c
Make DH opaque
[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 "dh_locl.h"
65 #include <openssl/bn.h>
66 #include <openssl/dsa.h>
67 #include <openssl/objects.h>
68 #include "internal/evp_int.h"
69
70 /* DH pkey context structure */
71
72 typedef struct {
73 /* Parameter gen parameters */
74 int prime_len;
75 int generator;
76 int use_dsa;
77 int subprime_len;
78 /* message digest used for parameter generation */
79 const EVP_MD *md;
80 int rfc5114_param;
81 /* Keygen callback info */
82 int gentmp[2];
83 /* KDF (if any) to use for DH */
84 char kdf_type;
85 /* OID to use for KDF */
86 ASN1_OBJECT *kdf_oid;
87 /* Message digest to use for key derivation */
88 const EVP_MD *kdf_md;
89 /* User key material */
90 unsigned char *kdf_ukm;
91 size_t kdf_ukmlen;
92 /* KDF output length */
93 size_t kdf_outlen;
94 } DH_PKEY_CTX;
95
96 static int pkey_dh_init(EVP_PKEY_CTX *ctx)
97 {
98 DH_PKEY_CTX *dctx;
99
100 dctx = OPENSSL_zalloc(sizeof(*dctx));
101 if (dctx == NULL)
102 return 0;
103 dctx->prime_len = 1024;
104 dctx->subprime_len = -1;
105 dctx->generator = 2;
106 dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
107
108 ctx->data = dctx;
109 ctx->keygen_info = dctx->gentmp;
110 ctx->keygen_info_count = 2;
111
112 return 1;
113 }
114
115 static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
116 {
117 DH_PKEY_CTX *dctx, *sctx;
118 if (!pkey_dh_init(dst))
119 return 0;
120 sctx = src->data;
121 dctx = dst->data;
122 dctx->prime_len = sctx->prime_len;
123 dctx->subprime_len = sctx->subprime_len;
124 dctx->generator = sctx->generator;
125 dctx->use_dsa = sctx->use_dsa;
126 dctx->md = sctx->md;
127 dctx->rfc5114_param = sctx->rfc5114_param;
128
129 dctx->kdf_type = sctx->kdf_type;
130 dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
131 if (!dctx->kdf_oid)
132 return 0;
133 dctx->kdf_md = sctx->kdf_md;
134 if (dctx->kdf_ukm) {
135 dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
136 dctx->kdf_ukmlen = sctx->kdf_ukmlen;
137 }
138 dctx->kdf_outlen = sctx->kdf_outlen;
139 return 1;
140 }
141
142 static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
143 {
144 DH_PKEY_CTX *dctx = ctx->data;
145 if (dctx) {
146 OPENSSL_free(dctx->kdf_ukm);
147 ASN1_OBJECT_free(dctx->kdf_oid);
148 OPENSSL_free(dctx);
149 }
150 }
151
152 static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
153 {
154 DH_PKEY_CTX *dctx = ctx->data;
155 switch (type) {
156 case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
157 if (p1 < 256)
158 return -2;
159 dctx->prime_len = p1;
160 return 1;
161
162 case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
163 if (dctx->use_dsa == 0)
164 return -2;
165 dctx->subprime_len = p1;
166 return 1;
167
168 case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
169 if (dctx->use_dsa)
170 return -2;
171 dctx->generator = p1;
172 return 1;
173
174 case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
175 #ifdef OPENSSL_NO_DSA
176 if (p1 != 0)
177 return -2;
178 #else
179 if (p1 < 0 || p1 > 2)
180 return -2;
181 #endif
182 dctx->use_dsa = p1;
183 return 1;
184
185 case EVP_PKEY_CTRL_DH_RFC5114:
186 if (p1 < 1 || p1 > 3)
187 return -2;
188 dctx->rfc5114_param = p1;
189 return 1;
190
191 case EVP_PKEY_CTRL_PEER_KEY:
192 /* Default behaviour is OK */
193 return 1;
194
195 case EVP_PKEY_CTRL_DH_KDF_TYPE:
196 if (p1 == -2)
197 return dctx->kdf_type;
198 #ifdef OPENSSL_NO_CMS
199 if (p1 != EVP_PKEY_DH_KDF_NONE)
200 #else
201 if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
202 #endif
203 return -2;
204 dctx->kdf_type = p1;
205 return 1;
206
207 case EVP_PKEY_CTRL_DH_KDF_MD:
208 dctx->kdf_md = p2;
209 return 1;
210
211 case EVP_PKEY_CTRL_GET_DH_KDF_MD:
212 *(const EVP_MD **)p2 = dctx->kdf_md;
213 return 1;
214
215 case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
216 if (p1 <= 0)
217 return -2;
218 dctx->kdf_outlen = (size_t)p1;
219 return 1;
220
221 case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
222 *(int *)p2 = dctx->kdf_outlen;
223 return 1;
224
225 case EVP_PKEY_CTRL_DH_KDF_UKM:
226 OPENSSL_free(dctx->kdf_ukm);
227 dctx->kdf_ukm = p2;
228 if (p2)
229 dctx->kdf_ukmlen = p1;
230 else
231 dctx->kdf_ukmlen = 0;
232 return 1;
233
234 case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
235 *(unsigned char **)p2 = dctx->kdf_ukm;
236 return dctx->kdf_ukmlen;
237
238 case EVP_PKEY_CTRL_DH_KDF_OID:
239 ASN1_OBJECT_free(dctx->kdf_oid);
240 dctx->kdf_oid = p2;
241 return 1;
242
243 case EVP_PKEY_CTRL_GET_DH_KDF_OID:
244 *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
245 return 1;
246
247 default:
248 return -2;
249
250 }
251 }
252
253 static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
254 const char *type, const char *value)
255 {
256 if (strcmp(type, "dh_paramgen_prime_len") == 0) {
257 int len;
258 len = atoi(value);
259 return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
260 }
261 if (strcmp(type, "dh_rfc5114") == 0) {
262 DH_PKEY_CTX *dctx = ctx->data;
263 int len;
264 len = atoi(value);
265 if (len < 0 || len > 3)
266 return -2;
267 dctx->rfc5114_param = len;
268 return 1;
269 }
270 if (strcmp(type, "dh_paramgen_generator") == 0) {
271 int len;
272 len = atoi(value);
273 return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
274 }
275 if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
276 int len;
277 len = atoi(value);
278 return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
279 }
280 if (strcmp(type, "dh_paramgen_type") == 0) {
281 int typ;
282 typ = atoi(value);
283 return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
284 }
285 return -2;
286 }
287
288 #ifndef OPENSSL_NO_DSA
289
290 extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
291 const EVP_MD *evpmd,
292 const unsigned char *seed_in, size_t seed_len,
293 unsigned char *seed_out, int *counter_ret,
294 unsigned long *h_ret, BN_GENCB *cb);
295
296 extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
297 const EVP_MD *evpmd,
298 const unsigned char *seed_in,
299 size_t seed_len, int idx,
300 unsigned char *seed_out, int *counter_ret,
301 unsigned long *h_ret, BN_GENCB *cb);
302
303 static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
304 {
305 DSA *ret;
306 int rv = 0;
307 int prime_len = dctx->prime_len;
308 int subprime_len = dctx->subprime_len;
309 const EVP_MD *md = dctx->md;
310 if (dctx->use_dsa > 2)
311 return NULL;
312 ret = DSA_new();
313 if (ret == NULL)
314 return NULL;
315 if (subprime_len == -1) {
316 if (prime_len >= 2048)
317 subprime_len = 256;
318 else
319 subprime_len = 160;
320 }
321 if (md == NULL) {
322 if (prime_len >= 2048)
323 md = EVP_sha256();
324 else
325 md = EVP_sha1();
326 }
327 if (dctx->use_dsa == 1)
328 rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
329 NULL, 0, NULL, NULL, NULL, pcb);
330 else if (dctx->use_dsa == 2)
331 rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
332 NULL, 0, -1, NULL, NULL, NULL, pcb);
333 if (rv <= 0) {
334 DSA_free(ret);
335 return NULL;
336 }
337 return ret;
338 }
339
340 #endif
341
342 static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
343 {
344 DH *dh = NULL;
345 DH_PKEY_CTX *dctx = ctx->data;
346 BN_GENCB *pcb;
347 int ret;
348 if (dctx->rfc5114_param) {
349 switch (dctx->rfc5114_param) {
350 case 1:
351 dh = DH_get_1024_160();
352 break;
353
354 case 2:
355 dh = DH_get_2048_224();
356 break;
357
358 case 3:
359 dh = DH_get_2048_256();
360 break;
361
362 default:
363 return -2;
364 }
365 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
366 return 1;
367 }
368
369 if (ctx->pkey_gencb) {
370 pcb = BN_GENCB_new();
371 if (pcb == NULL)
372 return 0;
373 evp_pkey_set_cb_translate(pcb, ctx);
374 } else
375 pcb = NULL;
376 #ifndef OPENSSL_NO_DSA
377 if (dctx->use_dsa) {
378 DSA *dsa_dh;
379 dsa_dh = dsa_dh_generate(dctx, pcb);
380 BN_GENCB_free(pcb);
381 if (dsa_dh == NULL)
382 return 0;
383 dh = DSA_dup_DH(dsa_dh);
384 DSA_free(dsa_dh);
385 if (!dh)
386 return 0;
387 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
388 return 1;
389 }
390 #endif
391 dh = DH_new();
392 if (dh == NULL) {
393 BN_GENCB_free(pcb);
394 return 0;
395 }
396 ret = DH_generate_parameters_ex(dh,
397 dctx->prime_len, dctx->generator, pcb);
398 BN_GENCB_free(pcb);
399 if (ret)
400 EVP_PKEY_assign_DH(pkey, dh);
401 else
402 DH_free(dh);
403 return ret;
404 }
405
406 static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
407 {
408 DH *dh = NULL;
409 if (ctx->pkey == NULL) {
410 DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
411 return 0;
412 }
413 dh = DH_new();
414 if (dh == NULL)
415 return 0;
416 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
417 /* Note: if error return, pkey is freed by parent routine */
418 if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
419 return 0;
420 return DH_generate_key(pkey->pkey.dh);
421 }
422
423 static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
424 size_t *keylen)
425 {
426 int ret;
427 DH *dh;
428 DH_PKEY_CTX *dctx = ctx->data;
429 BIGNUM *dhpub;
430 if (!ctx->pkey || !ctx->peerkey) {
431 DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
432 return 0;
433 }
434 dh = ctx->pkey->pkey.dh;
435 dhpub = ctx->peerkey->pkey.dh->pub_key;
436 if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
437 if (key == NULL) {
438 *keylen = DH_size(dh);
439 return 1;
440 }
441 ret = DH_compute_key(key, dhpub, dh);
442 if (ret < 0)
443 return ret;
444 *keylen = ret;
445 return 1;
446 }
447 #ifndef OPENSSL_NO_CMS
448 else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
449
450 unsigned char *Z = NULL;
451 size_t Zlen = 0;
452 if (!dctx->kdf_outlen || !dctx->kdf_oid)
453 return 0;
454 if (key == NULL) {
455 *keylen = dctx->kdf_outlen;
456 return 1;
457 }
458 if (*keylen != dctx->kdf_outlen)
459 return 0;
460 ret = 0;
461 Zlen = DH_size(dh);
462 Z = OPENSSL_malloc(Zlen);
463 if (Z == NULL) {
464 goto err;
465 }
466 if (DH_compute_key_padded(Z, dhpub, dh) <= 0)
467 goto err;
468 if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
469 dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
470 goto err;
471 *keylen = dctx->kdf_outlen;
472 ret = 1;
473 err:
474 OPENSSL_clear_free(Z, Zlen);
475 return ret;
476 }
477 #endif
478 return 0;
479 }
480
481 const 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
515 const 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 };