]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/dh/dh_pmeth.c
VMS perl: Fix glob output
[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>
0aeddcfa 64#include "dh_locl.h"
1e26a8ba 65#include <openssl/bn.h>
3c27208f 66#include <openssl/dsa.h>
bd59f2b9 67#include <openssl/objects.h>
27af42f9 68#include "internal/evp_int.h"
3ba0885a
DSH
69
70/* DH pkey context structure */
71
0f113f3e
MC
72typedef 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;
3ba0885a
DSH
95
96static int pkey_dh_init(EVP_PKEY_CTX *ctx)
0f113f3e
MC
97{
98 DH_PKEY_CTX *dctx;
64b25758
RS
99
100 dctx = OPENSSL_zalloc(sizeof(*dctx));
90945fa3 101 if (dctx == NULL)
0f113f3e
MC
102 return 0;
103 dctx->prime_len = 1024;
104 dctx->subprime_len = -1;
105 dctx->generator = 2;
0f113f3e 106 dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
0f113f3e
MC
107
108 ctx->data = dctx;
109 ctx->keygen_info = dctx->gentmp;
110 ctx->keygen_info_count = 2;
111
112 return 1;
113}
3ba0885a 114
8bdcef40 115static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
0f113f3e
MC
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) {
7644a9ae 135 dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
0f113f3e
MC
136 dctx->kdf_ukmlen = sctx->kdf_ukmlen;
137 }
138 dctx->kdf_outlen = sctx->kdf_outlen;
139 return 1;
140}
8bdcef40 141
3ba0885a 142static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
0f113f3e
MC
143{
144 DH_PKEY_CTX *dctx = ctx->data;
145 if (dctx) {
b548a1f1 146 OPENSSL_free(dctx->kdf_ukm);
0dfb9398 147 ASN1_OBJECT_free(dctx->kdf_oid);
0f113f3e
MC
148 OPENSSL_free(dctx);
149 }
150}
3ba0885a
DSH
151
152static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
0f113f3e
MC
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:
39090878 175#ifdef OPENSSL_NO_DSA
0f113f3e
MC
176 if (p1 != 0)
177 return -2;
39090878 178#else
0f113f3e
MC
179 if (p1 < 0 || p1 > 2)
180 return -2;
39090878 181#endif
0f113f3e
MC
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;
e968561d
DB
198#ifdef OPENSSL_NO_CMS
199 if (p1 != EVP_PKEY_DH_KDF_NONE)
200#else
0f113f3e 201 if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
e968561d 202#endif
0f113f3e
MC
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:
b548a1f1 226 OPENSSL_free(dctx->kdf_ukm);
0f113f3e
MC
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:
0dfb9398 239 ASN1_OBJECT_free(dctx->kdf_oid);
0f113f3e
MC
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}
39090878 252
3ba0885a 253static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
0f113f3e
MC
254 const char *type, const char *value)
255{
86885c28 256 if (strcmp(type, "dh_paramgen_prime_len") == 0) {
0f113f3e
MC
257 int len;
258 len = atoi(value);
259 return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
260 }
86885c28 261 if (strcmp(type, "dh_rfc5114") == 0) {
0f113f3e
MC
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 }
86885c28 270 if (strcmp(type, "dh_paramgen_generator") == 0) {
0f113f3e
MC
271 int len;
272 len = atoi(value);
273 return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
274 }
86885c28 275 if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
0f113f3e
MC
276 int len;
277 len = atoi(value);
278 return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
279 }
86885c28 280 if (strcmp(type, "dh_paramgen_type") == 0) {
0f113f3e
MC
281 int typ;
282 typ = atoi(value);
283 return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
284 }
285 return -2;
286}
3ba0885a 287
39090878
DSH
288#ifndef OPENSSL_NO_DSA
289
290extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
0f113f3e
MC
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);
39090878
DSH
295
296extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
0f113f3e
MC
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);
39090878
DSH
302
303static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
0f113f3e
MC
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();
90945fa3 313 if (ret == NULL)
0f113f3e
MC
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}
39090878
DSH
339
340#endif
341
3ba0885a 342static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
0f113f3e
MC
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();
90945fa3
MC
371 if (pcb == NULL)
372 return 0;
0f113f3e
MC
373 evp_pkey_set_cb_translate(pcb, ctx);
374 } else
375 pcb = NULL;
39090878 376#ifndef OPENSSL_NO_DSA
0f113f3e
MC
377 if (dctx->use_dsa) {
378 DSA *dsa_dh;
379 dsa_dh = dsa_dh_generate(dctx, pcb);
23a1d5e9 380 BN_GENCB_free(pcb);
90945fa3 381 if (dsa_dh == NULL)
0f113f3e
MC
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 }
39090878 390#endif
0f113f3e 391 dh = DH_new();
90945fa3 392 if (dh == NULL) {
23a1d5e9 393 BN_GENCB_free(pcb);
0f113f3e
MC
394 return 0;
395 }
396 ret = DH_generate_parameters_ex(dh,
397 dctx->prime_len, dctx->generator, pcb);
23a1d5e9 398 BN_GENCB_free(pcb);
0f113f3e
MC
399 if (ret)
400 EVP_PKEY_assign_DH(pkey, dh);
401 else
402 DH_free(dh);
403 return ret;
404}
3ba0885a
DSH
405
406static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
0f113f3e
MC
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();
90945fa3 414 if (dh == NULL)
0f113f3e
MC
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
423static 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;
e968561d
DB
446 }
447#ifndef OPENSSL_NO_CMS
448 else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
449
0f113f3e
MC
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);
90945fa3 463 if (Z == NULL) {
918bb865
MC
464 goto err;
465 }
0f113f3e
MC
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:
4b45c6e5 474 OPENSSL_clear_free(Z, Zlen);
0f113f3e
MC
475 return ret;
476 }
e968561d
DB
477#endif
478 return 0;
0f113f3e
MC
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};