VirtualBox

source: vbox/trunk/src/libs/openssl-1.1.0g/crypto/dh/dh_pmeth.c@ 69890

Last change on this file since 69890 was 69890, checked in by vboxsync, 7 years ago

Added OpenSSL 1.1.0g with unneeded files removed, otherwise unmodified.
bugref:8070: src/libs maintenance

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette