]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/dh/dh_pmeth.c
Convert all {NAME}err() in crypto/ to their corresponding ERR_raise() call
[thirdparty/openssl.git] / crypto / dh / dh_pmeth.c
CommitLineData
0f113f3e 1/*
33388b44 2 * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved.
3ba0885a 3 *
e38873f5 4 * Licensed under the Apache License 2.0 (the "License"). You may not use
aa6bb135
RS
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
3ba0885a
DSH
8 */
9
f41ac0ee 10/*
ada66e78 11 * DH & DSA low level APIs are deprecated for public use, but still ok for
f41ac0ee
P
12 * internal use.
13 */
14#include "internal/deprecated.h"
15
3ba0885a 16#include <stdio.h>
b39fc560 17#include "internal/cryptlib.h"
3ba0885a
DSH
18#include <openssl/asn1t.h>
19#include <openssl/x509.h>
3ba0885a 20#include <openssl/evp.h>
706457b7 21#include "dh_local.h"
1e26a8ba 22#include <openssl/bn.h>
3c27208f 23#include <openssl/dsa.h>
bd59f2b9 24#include <openssl/objects.h>
25f2138b 25#include "crypto/evp.h"
3ba0885a
DSH
26
27/* DH pkey context structure */
28
0f113f3e
MC
29typedef struct {
30 /* Parameter gen parameters */
31 int prime_len;
32 int generator;
f11f86f6 33 int paramgen_type;
0f113f3e 34 int subprime_len;
f4403a1f 35 int pad;
0f113f3e
MC
36 /* message digest used for parameter generation */
37 const EVP_MD *md;
38 int rfc5114_param;
d59d853a 39 int param_nid;
0f113f3e
MC
40 /* Keygen callback info */
41 int gentmp[2];
42 /* KDF (if any) to use for DH */
43 char kdf_type;
44 /* OID to use for KDF */
45 ASN1_OBJECT *kdf_oid;
46 /* Message digest to use for key derivation */
47 const EVP_MD *kdf_md;
48 /* User key material */
49 unsigned char *kdf_ukm;
50 size_t kdf_ukmlen;
51 /* KDF output length */
52 size_t kdf_outlen;
53} DH_PKEY_CTX;
3ba0885a
DSH
54
55static int pkey_dh_init(EVP_PKEY_CTX *ctx)
0f113f3e
MC
56{
57 DH_PKEY_CTX *dctx;
64b25758 58
cdb10bae 59 if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL) {
9311d0c4 60 ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
0f113f3e 61 return 0;
cdb10bae 62 }
70b0b977 63 dctx->prime_len = 2048;
0f113f3e
MC
64 dctx->subprime_len = -1;
65 dctx->generator = 2;
0f113f3e 66 dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
0f113f3e
MC
67
68 ctx->data = dctx;
69 ctx->keygen_info = dctx->gentmp;
70 ctx->keygen_info_count = 2;
71
72 return 1;
73}
3ba0885a 74
edeb3fd2
IY
75static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
76{
77 DH_PKEY_CTX *dctx = ctx->data;
f11f86f6 78
edeb3fd2
IY
79 if (dctx != NULL) {
80 OPENSSL_free(dctx->kdf_ukm);
81 ASN1_OBJECT_free(dctx->kdf_oid);
82 OPENSSL_free(dctx);
83 }
84}
85
86
9fdcc21f 87static int pkey_dh_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
0f113f3e
MC
88{
89 DH_PKEY_CTX *dctx, *sctx;
12a765a5 90
0f113f3e
MC
91 if (!pkey_dh_init(dst))
92 return 0;
93 sctx = src->data;
94 dctx = dst->data;
95 dctx->prime_len = sctx->prime_len;
96 dctx->subprime_len = sctx->subprime_len;
97 dctx->generator = sctx->generator;
f11f86f6 98 dctx->paramgen_type = sctx->paramgen_type;
f4403a1f 99 dctx->pad = sctx->pad;
0f113f3e
MC
100 dctx->md = sctx->md;
101 dctx->rfc5114_param = sctx->rfc5114_param;
d59d853a 102 dctx->param_nid = sctx->param_nid;
0f113f3e
MC
103
104 dctx->kdf_type = sctx->kdf_type;
105 dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
edeb3fd2 106 if (dctx->kdf_oid == NULL)
0f113f3e
MC
107 return 0;
108 dctx->kdf_md = sctx->kdf_md;
edeb3fd2 109 if (sctx->kdf_ukm != NULL) {
7644a9ae 110 dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
edeb3fd2
IY
111 if (dctx->kdf_ukm == NULL)
112 return 0;
0f113f3e
MC
113 dctx->kdf_ukmlen = sctx->kdf_ukmlen;
114 }
115 dctx->kdf_outlen = sctx->kdf_outlen;
116 return 1;
117}
8bdcef40 118
3ba0885a 119static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
0f113f3e
MC
120{
121 DH_PKEY_CTX *dctx = ctx->data;
122 switch (type) {
123 case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
124 if (p1 < 256)
125 return -2;
126 dctx->prime_len = p1;
127 return 1;
128
129 case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
f11f86f6 130 if (dctx->paramgen_type == DH_PARAMGEN_TYPE_GENERATOR)
0f113f3e
MC
131 return -2;
132 dctx->subprime_len = p1;
133 return 1;
134
f4403a1f
DSH
135 case EVP_PKEY_CTRL_DH_PAD:
136 dctx->pad = p1;
137 return 1;
138
0f113f3e 139 case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
f11f86f6 140 if (dctx->paramgen_type != DH_PARAMGEN_TYPE_GENERATOR)
0f113f3e
MC
141 return -2;
142 dctx->generator = p1;
143 return 1;
144
145 case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
39090878 146#ifdef OPENSSL_NO_DSA
f11f86f6 147 if (p1 != DH_PARAMGEN_TYPE_GENERATOR)
0f113f3e 148 return -2;
39090878 149#else
0f113f3e
MC
150 if (p1 < 0 || p1 > 2)
151 return -2;
39090878 152#endif
f11f86f6 153 dctx->paramgen_type = p1;
0f113f3e
MC
154 return 1;
155
156 case EVP_PKEY_CTRL_DH_RFC5114:
d59d853a 157 if (p1 < 1 || p1 > 3 || dctx->param_nid != NID_undef)
0f113f3e
MC
158 return -2;
159 dctx->rfc5114_param = p1;
160 return 1;
161
d59d853a
DSH
162 case EVP_PKEY_CTRL_DH_NID:
163 if (p1 <= 0 || dctx->rfc5114_param != 0)
164 return -2;
165 dctx->param_nid = p1;
166 return 1;
167
0f113f3e
MC
168 case EVP_PKEY_CTRL_PEER_KEY:
169 /* Default behaviour is OK */
170 return 1;
171
172 case EVP_PKEY_CTRL_DH_KDF_TYPE:
173 if (p1 == -2)
174 return dctx->kdf_type;
175 if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
176 return -2;
177 dctx->kdf_type = p1;
178 return 1;
179
180 case EVP_PKEY_CTRL_DH_KDF_MD:
181 dctx->kdf_md = p2;
182 return 1;
183
184 case EVP_PKEY_CTRL_GET_DH_KDF_MD:
185 *(const EVP_MD **)p2 = dctx->kdf_md;
186 return 1;
187
188 case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
189 if (p1 <= 0)
190 return -2;
191 dctx->kdf_outlen = (size_t)p1;
192 return 1;
193
194 case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
195 *(int *)p2 = dctx->kdf_outlen;
196 return 1;
197
198 case EVP_PKEY_CTRL_DH_KDF_UKM:
b548a1f1 199 OPENSSL_free(dctx->kdf_ukm);
0f113f3e
MC
200 dctx->kdf_ukm = p2;
201 if (p2)
202 dctx->kdf_ukmlen = p1;
203 else
204 dctx->kdf_ukmlen = 0;
205 return 1;
206
207 case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
208 *(unsigned char **)p2 = dctx->kdf_ukm;
209 return dctx->kdf_ukmlen;
210
211 case EVP_PKEY_CTRL_DH_KDF_OID:
0dfb9398 212 ASN1_OBJECT_free(dctx->kdf_oid);
0f113f3e
MC
213 dctx->kdf_oid = p2;
214 return 1;
215
216 case EVP_PKEY_CTRL_GET_DH_KDF_OID:
217 *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
218 return 1;
219
220 default:
221 return -2;
222
223 }
224}
39090878 225
3ba0885a 226static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
0f113f3e
MC
227 const char *type, const char *value)
228{
86885c28 229 if (strcmp(type, "dh_paramgen_prime_len") == 0) {
0f113f3e
MC
230 int len;
231 len = atoi(value);
232 return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
233 }
86885c28 234 if (strcmp(type, "dh_rfc5114") == 0) {
0f113f3e
MC
235 DH_PKEY_CTX *dctx = ctx->data;
236 int len;
237 len = atoi(value);
238 if (len < 0 || len > 3)
239 return -2;
240 dctx->rfc5114_param = len;
241 return 1;
242 }
d59d853a
DSH
243 if (strcmp(type, "dh_param") == 0) {
244 DH_PKEY_CTX *dctx = ctx->data;
245 int nid = OBJ_sn2nid(value);
246
247 if (nid == NID_undef) {
9311d0c4 248 ERR_raise(ERR_LIB_DH, DH_R_INVALID_PARAMETER_NAME);
d59d853a
DSH
249 return -2;
250 }
251 dctx->param_nid = nid;
252 return 1;
253 }
86885c28 254 if (strcmp(type, "dh_paramgen_generator") == 0) {
0f113f3e
MC
255 int len;
256 len = atoi(value);
257 return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
258 }
86885c28 259 if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
0f113f3e
MC
260 int len;
261 len = atoi(value);
262 return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
263 }
86885c28 264 if (strcmp(type, "dh_paramgen_type") == 0) {
0f113f3e
MC
265 int typ;
266 typ = atoi(value);
267 return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
268 }
f4403a1f
DSH
269 if (strcmp(type, "dh_pad") == 0) {
270 int pad;
271 pad = atoi(value);
272 return EVP_PKEY_CTX_set_dh_pad(ctx, pad);
273 }
0f113f3e
MC
274 return -2;
275}
3ba0885a 276
b4250010 277static DH *ffc_params_generate(OSSL_LIB_CTX *libctx, DH_PKEY_CTX *dctx,
f11f86f6 278 BN_GENCB *pcb)
0f113f3e 279{
f11f86f6 280 DH *ret;
0f113f3e 281 int rv = 0;
f11f86f6 282 int res;
0f113f3e
MC
283 int prime_len = dctx->prime_len;
284 int subprime_len = dctx->subprime_len;
f11f86f6
SL
285
286 if (dctx->paramgen_type > DH_PARAMGEN_TYPE_FIPS_186_4)
0f113f3e 287 return NULL;
f11f86f6 288 ret = DH_new();
90945fa3 289 if (ret == NULL)
0f113f3e 290 return NULL;
f11f86f6 291
0f113f3e
MC
292 if (subprime_len == -1) {
293 if (prime_len >= 2048)
294 subprime_len = 256;
295 else
296 subprime_len = 160;
297 }
4f2271d5
SL
298
299 if (dctx->md != NULL)
5357c106 300 ossl_ffc_set_digest(&ret->params, EVP_MD_name(dctx->md), NULL);
4f2271d5 301
f844f9eb 302# ifndef FIPS_MODULE
f11f86f6 303 if (dctx->paramgen_type == DH_PARAMGEN_TYPE_FIPS_186_2)
5357c106
P
304 rv = ossl_ffc_params_FIPS186_2_generate(libctx, &ret->params,
305 FFC_PARAM_TYPE_DH,
306 prime_len, subprime_len, &res,
307 pcb);
f11f86f6
SL
308 else
309# endif
310 /* For FIPS we always use the DH_PARAMGEN_TYPE_FIPS_186_4 generator */
311 if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2)
5357c106
P
312 rv = ossl_ffc_params_FIPS186_4_generate(libctx, &ret->params,
313 FFC_PARAM_TYPE_DH,
314 prime_len, subprime_len, &res,
315 pcb);
0f113f3e 316 if (rv <= 0) {
f11f86f6 317 DH_free(ret);
0f113f3e
MC
318 return NULL;
319 }
320 return ret;
321}
39090878 322
f11f86f6
SL
323static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx,
324 EVP_PKEY *pkey)
0f113f3e
MC
325{
326 DH *dh = NULL;
327 DH_PKEY_CTX *dctx = ctx->data;
ca2bf555 328 BN_GENCB *pcb = NULL;
0f113f3e 329 int ret;
ca2bf555
SL
330
331 /*
332 * Look for a safe prime group for key establishment. Which uses
333 * either RFC_3526 (modp_XXXX) or RFC_7919 (ffdheXXXX).
334 */
335 if (dctx->param_nid != NID_undef) {
336 if ((dh = DH_new_by_nid(dctx->param_nid)) == NULL)
337 return 0;
338 EVP_PKEY_assign(pkey, EVP_PKEY_DH, dh);
339 return 1;
340 }
341
f844f9eb 342#ifndef FIPS_MODULE
0f113f3e
MC
343 if (dctx->rfc5114_param) {
344 switch (dctx->rfc5114_param) {
345 case 1:
346 dh = DH_get_1024_160();
347 break;
348
349 case 2:
350 dh = DH_get_2048_224();
351 break;
352
353 case 3:
354 dh = DH_get_2048_256();
355 break;
356
357 default:
358 return -2;
359 }
360 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
361 return 1;
362 }
f844f9eb 363#endif /* FIPS_MODULE */
0f113f3e 364
ca2bf555 365 if (ctx->pkey_gencb != NULL) {
0f113f3e 366 pcb = BN_GENCB_new();
90945fa3
MC
367 if (pcb == NULL)
368 return 0;
0f113f3e 369 evp_pkey_set_cb_translate(pcb, ctx);
ca2bf555 370 }
f844f9eb 371# ifdef FIPS_MODULE
f11f86f6 372 dctx->paramgen_type = DH_PARAMGEN_TYPE_FIPS_186_4;
f844f9eb 373# endif /* FIPS_MODULE */
f11f86f6
SL
374 if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2) {
375 dh = ffc_params_generate(NULL, dctx, pcb);
23a1d5e9 376 BN_GENCB_free(pcb);
f11f86f6 377 if (dh == NULL)
0f113f3e
MC
378 return 0;
379 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
380 return 1;
381 }
0f113f3e 382 dh = DH_new();
90945fa3 383 if (dh == NULL) {
23a1d5e9 384 BN_GENCB_free(pcb);
0f113f3e
MC
385 return 0;
386 }
387 ret = DH_generate_parameters_ex(dh,
388 dctx->prime_len, dctx->generator, pcb);
23a1d5e9 389 BN_GENCB_free(pcb);
0f113f3e
MC
390 if (ret)
391 EVP_PKEY_assign_DH(pkey, dh);
392 else
393 DH_free(dh);
394 return ret;
395}
3ba0885a
DSH
396
397static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
0f113f3e 398{
d59d853a 399 DH_PKEY_CTX *dctx = ctx->data;
0f113f3e 400 DH *dh = NULL;
d59d853a 401
ca2bf555 402 if (ctx->pkey == NULL && dctx->param_nid == NID_undef) {
9311d0c4 403 ERR_raise(ERR_LIB_DH, DH_R_NO_PARAMETERS_SET);
0f113f3e
MC
404 return 0;
405 }
ca2bf555 406 if (dctx->param_nid != NID_undef)
d59d853a
DSH
407 dh = DH_new_by_nid(dctx->param_nid);
408 else
409 dh = DH_new();
90945fa3 410 if (dh == NULL)
0f113f3e
MC
411 return 0;
412 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
413 /* Note: if error return, pkey is freed by parent routine */
d59d853a 414 if (ctx->pkey != NULL && !EVP_PKEY_copy_parameters(pkey, ctx->pkey))
0f113f3e
MC
415 return 0;
416 return DH_generate_key(pkey->pkey.dh);
417}
418
419static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
420 size_t *keylen)
421{
422 int ret;
423 DH *dh;
424 DH_PKEY_CTX *dctx = ctx->data;
425 BIGNUM *dhpub;
426 if (!ctx->pkey || !ctx->peerkey) {
9311d0c4 427 ERR_raise(ERR_LIB_DH, DH_R_KEYS_NOT_SET);
0f113f3e
MC
428 return 0;
429 }
430 dh = ctx->pkey->pkey.dh;
431 dhpub = ctx->peerkey->pkey.dh->pub_key;
432 if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
433 if (key == NULL) {
434 *keylen = DH_size(dh);
435 return 1;
436 }
f4403a1f
DSH
437 if (dctx->pad)
438 ret = DH_compute_key_padded(key, dhpub, dh);
439 else
440 ret = DH_compute_key(key, dhpub, dh);
0f113f3e
MC
441 if (ret < 0)
442 return ret;
443 *keylen = ret;
444 return 1;
e968561d 445 }
e968561d
DB
446 else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
447
0f113f3e
MC
448 unsigned char *Z = NULL;
449 size_t Zlen = 0;
450 if (!dctx->kdf_outlen || !dctx->kdf_oid)
451 return 0;
452 if (key == NULL) {
453 *keylen = dctx->kdf_outlen;
454 return 1;
455 }
456 if (*keylen != dctx->kdf_outlen)
457 return 0;
458 ret = 0;
459 Zlen = DH_size(dh);
460 Z = OPENSSL_malloc(Zlen);
90945fa3 461 if (Z == NULL) {
918bb865
MC
462 goto err;
463 }
0f113f3e
MC
464 if (DH_compute_key_padded(Z, dhpub, dh) <= 0)
465 goto err;
466 if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
467 dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
468 goto err;
469 *keylen = dctx->kdf_outlen;
470 ret = 1;
471 err:
4b45c6e5 472 OPENSSL_clear_free(Z, Zlen);
0f113f3e
MC
473 return ret;
474 }
e968561d 475 return 0;
0f113f3e
MC
476}
477
19bd1fa1 478static const EVP_PKEY_METHOD dh_pkey_meth = {
0f113f3e
MC
479 EVP_PKEY_DH,
480 0,
481 pkey_dh_init,
482 pkey_dh_copy,
483 pkey_dh_cleanup,
484
485 0,
486 pkey_dh_paramgen,
487
488 0,
489 pkey_dh_keygen,
490
491 0,
492 0,
493
494 0,
495 0,
496
497 0, 0,
498
499 0, 0, 0, 0,
500
501 0, 0,
502
503 0, 0,
504
505 0,
506 pkey_dh_derive,
507
508 pkey_dh_ctrl,
509 pkey_dh_ctrl_str
510};
511
19bd1fa1
PS
512const EVP_PKEY_METHOD *dh_pkey_method(void)
513{
514 return &dh_pkey_meth;
515}
516
517static const EVP_PKEY_METHOD dhx_pkey_meth = {
0f113f3e
MC
518 EVP_PKEY_DHX,
519 0,
520 pkey_dh_init,
521 pkey_dh_copy,
522 pkey_dh_cleanup,
523
524 0,
525 pkey_dh_paramgen,
526
527 0,
528 pkey_dh_keygen,
529
530 0,
531 0,
532
533 0,
534 0,
535
536 0, 0,
537
538 0, 0, 0, 0,
539
540 0, 0,
541
542 0, 0,
543
544 0,
545 pkey_dh_derive,
546
547 pkey_dh_ctrl,
548 pkey_dh_ctrl_str
549};
19bd1fa1
PS
550
551const EVP_PKEY_METHOD *dhx_pkey_method(void)
552{
553 return &dhx_pkey_meth;
554}