VirtualBox

source: vbox/trunk/src/libs/openssl-1.1.1f/crypto/dh/dh_pmeth.c@ 83531

Last change on this file since 83531 was 83531, checked in by vboxsync, 5 years ago

setting svn:sync-process=export for openssl-1.1.1f, all files except tests

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