]> git.proxmox.com Git - efi-boot-shim.git/blame - Cryptlib/OpenSSL/crypto/dh/dh_pmeth.c
New upstream version 15.3
[efi-boot-shim.git] / Cryptlib / OpenSSL / crypto / dh / dh_pmeth.c
CommitLineData
d3819813 1/*
031e5cce
SM
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).
d3819813
MTL
56 *
57 */
58
59#include <stdio.h>
031e5cce 60#include "cryptlib.h"
d3819813
MTL
61#include <openssl/asn1t.h>
62#include <openssl/x509.h>
63#include <openssl/evp.h>
031e5cce 64#include <openssl/dh.h>
d3819813 65#include <openssl/bn.h>
031e5cce
SM
66#ifndef OPENSSL_NO_DSA
67# include <openssl/dsa.h>
68#endif
d3819813 69#include <openssl/objects.h>
031e5cce 70#include "evp_locl.h"
d3819813
MTL
71
72/* DH pkey context structure */
73
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;
97
98static int pkey_dh_init(EVP_PKEY_CTX *ctx)
99{
100 DH_PKEY_CTX *dctx;
031e5cce
SM
101 dctx = OPENSSL_malloc(sizeof(DH_PKEY_CTX));
102 if (!dctx)
d3819813
MTL
103 return 0;
104 dctx->prime_len = 1024;
105 dctx->subprime_len = -1;
106 dctx->generator = 2;
031e5cce
SM
107 dctx->use_dsa = 0;
108 dctx->md = NULL;
109 dctx->rfc5114_param = 0;
110
d3819813 111 dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
031e5cce
SM
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;
d3819813
MTL
117
118 ctx->data = dctx;
119 ctx->keygen_info = dctx->gentmp;
120 ctx->keygen_info_count = 2;
121
122 return 1;
123}
124
125static 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);
031e5cce 141 if (!dctx->kdf_oid)
d3819813
MTL
142 return 0;
143 dctx->kdf_md = sctx->kdf_md;
031e5cce
SM
144 if (dctx->kdf_ukm) {
145 dctx->kdf_ukm = BUF_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
d3819813
MTL
146 dctx->kdf_ukmlen = sctx->kdf_ukmlen;
147 }
148 dctx->kdf_outlen = sctx->kdf_outlen;
149 return 1;
150}
151
031e5cce
SM
152static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
153{
154 DH_PKEY_CTX *dctx = ctx->data;
155 if (dctx) {
156 if (dctx->kdf_ukm)
157 OPENSSL_free(dctx->kdf_ukm);
158 if (dctx->kdf_oid)
159 ASN1_OBJECT_free(dctx->kdf_oid);
160 OPENSSL_free(dctx);
161 }
162}
163
d3819813
MTL
164static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
165{
166 DH_PKEY_CTX *dctx = ctx->data;
167 switch (type) {
168 case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
169 if (p1 < 256)
170 return -2;
171 dctx->prime_len = p1;
172 return 1;
173
174 case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
175 if (dctx->use_dsa == 0)
176 return -2;
177 dctx->subprime_len = p1;
178 return 1;
179
180 case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
181 if (dctx->use_dsa)
182 return -2;
183 dctx->generator = p1;
184 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 if (p1 < 0 || p1 > 2)
192 return -2;
193#endif
194 dctx->use_dsa = p1;
195 return 1;
196
197 case EVP_PKEY_CTRL_DH_RFC5114:
198 if (p1 < 1 || p1 > 3)
199 return -2;
200 dctx->rfc5114_param = p1;
201 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 if (p1 == -2)
209 return dctx->kdf_type;
62f0afa2
MTL
210#ifdef OPENSSL_NO_CMS
211 if (p1 != EVP_PKEY_DH_KDF_NONE)
212#else
d3819813 213 if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
62f0afa2 214#endif
d3819813
MTL
215 return -2;
216 dctx->kdf_type = p1;
217 return 1;
218
219 case EVP_PKEY_CTRL_DH_KDF_MD:
220 dctx->kdf_md = p2;
221 return 1;
222
223 case EVP_PKEY_CTRL_GET_DH_KDF_MD:
224 *(const EVP_MD **)p2 = dctx->kdf_md;
225 return 1;
226
227 case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
228 if (p1 <= 0)
229 return -2;
230 dctx->kdf_outlen = (size_t)p1;
231 return 1;
232
233 case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
234 *(int *)p2 = dctx->kdf_outlen;
235 return 1;
236
237 case EVP_PKEY_CTRL_DH_KDF_UKM:
031e5cce
SM
238 if (dctx->kdf_ukm)
239 OPENSSL_free(dctx->kdf_ukm);
d3819813
MTL
240 dctx->kdf_ukm = p2;
241 if (p2)
242 dctx->kdf_ukmlen = p1;
243 else
244 dctx->kdf_ukmlen = 0;
245 return 1;
246
247 case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
248 *(unsigned char **)p2 = dctx->kdf_ukm;
249 return dctx->kdf_ukmlen;
250
251 case EVP_PKEY_CTRL_DH_KDF_OID:
031e5cce
SM
252 if (dctx->kdf_oid)
253 ASN1_OBJECT_free(dctx->kdf_oid);
d3819813
MTL
254 dctx->kdf_oid = p2;
255 return 1;
256
257 case EVP_PKEY_CTRL_GET_DH_KDF_OID:
258 *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
259 return 1;
260
261 default:
262 return -2;
263
264 }
265}
266
267static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
268 const char *type, const char *value)
269{
031e5cce 270 if (!strcmp(type, "dh_paramgen_prime_len")) {
d3819813
MTL
271 int len;
272 len = atoi(value);
273 return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
274 }
031e5cce 275 if (!strcmp(type, "dh_rfc5114")) {
d3819813
MTL
276 DH_PKEY_CTX *dctx = ctx->data;
277 int len;
278 len = atoi(value);
279 if (len < 0 || len > 3)
280 return -2;
281 dctx->rfc5114_param = len;
282 return 1;
283 }
031e5cce 284 if (!strcmp(type, "dh_paramgen_generator")) {
d3819813
MTL
285 int len;
286 len = atoi(value);
287 return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
288 }
031e5cce 289 if (!strcmp(type, "dh_paramgen_subprime_len")) {
d3819813
MTL
290 int len;
291 len = atoi(value);
292 return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
293 }
031e5cce 294 if (!strcmp(type, "dh_paramgen_type")) {
d3819813
MTL
295 int typ;
296 typ = atoi(value);
297 return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
298 }
299 return -2;
300}
301
302#ifndef OPENSSL_NO_DSA
303
304extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
305 const EVP_MD *evpmd,
306 const unsigned char *seed_in, size_t seed_len,
307 unsigned char *seed_out, int *counter_ret,
308 unsigned long *h_ret, BN_GENCB *cb);
309
310extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
311 const EVP_MD *evpmd,
312 const unsigned char *seed_in,
313 size_t seed_len, int idx,
314 unsigned char *seed_out, int *counter_ret,
315 unsigned long *h_ret, BN_GENCB *cb);
316
317static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
318{
319 DSA *ret;
320 int rv = 0;
321 int prime_len = dctx->prime_len;
322 int subprime_len = dctx->subprime_len;
323 const EVP_MD *md = dctx->md;
324 if (dctx->use_dsa > 2)
325 return NULL;
326 ret = DSA_new();
031e5cce 327 if (!ret)
d3819813
MTL
328 return NULL;
329 if (subprime_len == -1) {
330 if (prime_len >= 2048)
331 subprime_len = 256;
332 else
333 subprime_len = 160;
334 }
335 if (md == NULL) {
336 if (prime_len >= 2048)
337 md = EVP_sha256();
338 else
339 md = EVP_sha1();
340 }
341 if (dctx->use_dsa == 1)
342 rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
343 NULL, 0, NULL, NULL, NULL, pcb);
344 else if (dctx->use_dsa == 2)
345 rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
346 NULL, 0, -1, NULL, NULL, NULL, pcb);
347 if (rv <= 0) {
348 DSA_free(ret);
349 return NULL;
350 }
351 return ret;
352}
353
354#endif
355
356static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
357{
358 DH *dh = NULL;
359 DH_PKEY_CTX *dctx = ctx->data;
031e5cce 360 BN_GENCB *pcb, cb;
d3819813
MTL
361 int ret;
362 if (dctx->rfc5114_param) {
363 switch (dctx->rfc5114_param) {
364 case 1:
365 dh = DH_get_1024_160();
366 break;
367
368 case 2:
369 dh = DH_get_2048_224();
370 break;
371
372 case 3:
373 dh = DH_get_2048_256();
374 break;
375
376 default:
377 return -2;
378 }
379 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
380 return 1;
381 }
382
383 if (ctx->pkey_gencb) {
031e5cce 384 pcb = &cb;
d3819813
MTL
385 evp_pkey_set_cb_translate(pcb, ctx);
386 } else
387 pcb = NULL;
388#ifndef OPENSSL_NO_DSA
389 if (dctx->use_dsa) {
390 DSA *dsa_dh;
391 dsa_dh = dsa_dh_generate(dctx, pcb);
031e5cce 392 if (!dsa_dh)
d3819813
MTL
393 return 0;
394 dh = DSA_dup_DH(dsa_dh);
395 DSA_free(dsa_dh);
396 if (!dh)
397 return 0;
398 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
399 return 1;
400 }
401#endif
402 dh = DH_new();
031e5cce 403 if (!dh)
d3819813
MTL
404 return 0;
405 ret = DH_generate_parameters_ex(dh,
406 dctx->prime_len, dctx->generator, pcb);
031e5cce 407
d3819813
MTL
408 if (ret)
409 EVP_PKEY_assign_DH(pkey, dh);
410 else
411 DH_free(dh);
412 return ret;
413}
414
415static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
416{
417 DH *dh = NULL;
418 if (ctx->pkey == NULL) {
419 DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
420 return 0;
421 }
422 dh = DH_new();
031e5cce 423 if (!dh)
d3819813
MTL
424 return 0;
425 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
426 /* Note: if error return, pkey is freed by parent routine */
427 if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
428 return 0;
429 return DH_generate_key(pkey->pkey.dh);
430}
431
432static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
433 size_t *keylen)
434{
435 int ret;
436 DH *dh;
437 DH_PKEY_CTX *dctx = ctx->data;
438 BIGNUM *dhpub;
439 if (!ctx->pkey || !ctx->peerkey) {
440 DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
441 return 0;
442 }
443 dh = ctx->pkey->pkey.dh;
444 dhpub = ctx->peerkey->pkey.dh->pub_key;
445 if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
446 if (key == NULL) {
447 *keylen = DH_size(dh);
448 return 1;
449 }
450 ret = DH_compute_key(key, dhpub, dh);
451 if (ret < 0)
452 return ret;
453 *keylen = ret;
454 return 1;
62f0afa2
MTL
455 }
456#ifndef OPENSSL_NO_CMS
457 else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
d3819813
MTL
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);
031e5cce 471 if (!Z) {
d3819813
MTL
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:
031e5cce
SM
482 if (Z) {
483 OPENSSL_cleanse(Z, Zlen);
484 OPENSSL_free(Z);
485 }
d3819813 486 return ret;
d3819813 487 }
62f0afa2
MTL
488#endif
489 return 0;
d3819813
MTL
490}
491
492const EVP_PKEY_METHOD dh_pkey_meth = {
493 EVP_PKEY_DH,
494 0,
495 pkey_dh_init,
496 pkey_dh_copy,
497 pkey_dh_cleanup,
498
499 0,
500 pkey_dh_paramgen,
501
502 0,
503 pkey_dh_keygen,
504
505 0,
506 0,
507
508 0,
509 0,
510
511 0, 0,
512
513 0, 0, 0, 0,
514
515 0, 0,
516
517 0, 0,
518
519 0,
520 pkey_dh_derive,
521
522 pkey_dh_ctrl,
523 pkey_dh_ctrl_str
524};
525
526const EVP_PKEY_METHOD dhx_pkey_meth = {
527 EVP_PKEY_DHX,
528 0,
529 pkey_dh_init,
530 pkey_dh_copy,
531 pkey_dh_cleanup,
532
533 0,
534 pkey_dh_paramgen,
535
536 0,
537 pkey_dh_keygen,
538
539 0,
540 0,
541
542 0,
543 0,
544
545 0, 0,
546
547 0, 0, 0, 0,
548
549 0, 0,
550
551 0, 0,
552
553 0,
554 pkey_dh_derive,
555
556 pkey_dh_ctrl,
557 pkey_dh_ctrl_str
558};