2 * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (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
11 * DH & DSA low level APIs are deprecated for public use, but still ok for
14 #include "internal/deprecated.h"
17 #include "internal/cryptlib.h"
18 #include <openssl/asn1t.h>
19 #include <openssl/x509.h>
20 #include <openssl/evp.h>
22 #include <openssl/bn.h>
23 #include <openssl/dsa.h>
24 #include <openssl/objects.h>
25 #include "crypto/evp.h"
27 /* DH pkey context structure */
30 /* Parameter gen parameters */
36 /* message digest used for parameter generation */
39 /* Keygen callback info */
41 /* KDF (if any) to use for DH */
43 /* OID to use for KDF */
45 /* Message digest to use for key derivation */
47 /* User key material */
48 unsigned char *kdf_ukm;
50 /* KDF output length */
54 static int pkey_dh_init(EVP_PKEY_CTX *ctx)
58 if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL)
60 dctx->prime_len = 2048;
61 dctx->subprime_len = -1;
63 dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
66 ctx->keygen_info = dctx->gentmp;
67 ctx->keygen_info_count = 2;
72 static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
74 DH_PKEY_CTX *dctx = ctx->data;
77 OPENSSL_free(dctx->kdf_ukm);
78 ASN1_OBJECT_free(dctx->kdf_oid);
84 static int pkey_dh_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
86 DH_PKEY_CTX *dctx, *sctx;
88 if (!pkey_dh_init(dst))
92 dctx->prime_len = sctx->prime_len;
93 dctx->subprime_len = sctx->subprime_len;
94 dctx->generator = sctx->generator;
95 dctx->paramgen_type = sctx->paramgen_type;
96 dctx->pad = sctx->pad;
98 dctx->param_nid = sctx->param_nid;
100 dctx->kdf_type = sctx->kdf_type;
101 dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
102 if (dctx->kdf_oid == NULL)
104 dctx->kdf_md = sctx->kdf_md;
105 if (sctx->kdf_ukm != NULL) {
106 dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
107 if (dctx->kdf_ukm == NULL)
109 dctx->kdf_ukmlen = sctx->kdf_ukmlen;
111 dctx->kdf_outlen = sctx->kdf_outlen;
115 static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
117 DH_PKEY_CTX *dctx = ctx->data;
119 case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
122 dctx->prime_len = p1;
125 case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
126 if (dctx->paramgen_type == DH_PARAMGEN_TYPE_GENERATOR)
128 dctx->subprime_len = p1;
131 case EVP_PKEY_CTRL_DH_PAD:
135 case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
136 if (dctx->paramgen_type != DH_PARAMGEN_TYPE_GENERATOR)
138 dctx->generator = p1;
141 case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
142 #ifdef OPENSSL_NO_DSA
143 if (p1 != DH_PARAMGEN_TYPE_GENERATOR)
146 if (p1 < 0 || p1 > 2)
149 dctx->paramgen_type = p1;
152 case EVP_PKEY_CTRL_DH_RFC5114:
153 if (p1 < 1 || p1 > 3 || dctx->param_nid != NID_undef)
155 dctx->param_nid = p1;
158 case EVP_PKEY_CTRL_DH_NID:
159 if (p1 <= 0 || dctx->param_nid != NID_undef)
161 dctx->param_nid = p1;
164 case EVP_PKEY_CTRL_PEER_KEY:
165 /* Default behaviour is OK */
168 case EVP_PKEY_CTRL_DH_KDF_TYPE:
170 return dctx->kdf_type;
171 if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
176 case EVP_PKEY_CTRL_DH_KDF_MD:
180 case EVP_PKEY_CTRL_GET_DH_KDF_MD:
181 *(const EVP_MD **)p2 = dctx->kdf_md;
184 case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
187 dctx->kdf_outlen = (size_t)p1;
190 case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
191 *(int *)p2 = dctx->kdf_outlen;
194 case EVP_PKEY_CTRL_DH_KDF_UKM:
195 OPENSSL_free(dctx->kdf_ukm);
198 dctx->kdf_ukmlen = p1;
200 dctx->kdf_ukmlen = 0;
203 case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
204 *(unsigned char **)p2 = dctx->kdf_ukm;
205 return dctx->kdf_ukmlen;
207 case EVP_PKEY_CTRL_DH_KDF_OID:
208 ASN1_OBJECT_free(dctx->kdf_oid);
212 case EVP_PKEY_CTRL_GET_DH_KDF_OID:
213 *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
222 static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
223 const char *type, const char *value)
225 if (strcmp(type, "dh_paramgen_prime_len") == 0) {
228 return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
230 if (strcmp(type, "dh_rfc5114") == 0) {
231 DH_PKEY_CTX *dctx = ctx->data;
235 if (id < 0 || id > 3)
237 dctx->param_nid = id;
240 if (strcmp(type, "dh_param") == 0) {
241 DH_PKEY_CTX *dctx = ctx->data;
242 int nid = OBJ_sn2nid(value);
244 if (nid == NID_undef) {
245 ERR_raise(ERR_LIB_DH, DH_R_INVALID_PARAMETER_NAME);
248 dctx->param_nid = nid;
251 if (strcmp(type, "dh_paramgen_generator") == 0) {
254 return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
256 if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
259 return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
261 if (strcmp(type, "dh_paramgen_type") == 0) {
264 return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
266 if (strcmp(type, "dh_pad") == 0) {
269 return EVP_PKEY_CTX_set_dh_pad(ctx, pad);
274 static DH *ffc_params_generate(OSSL_LIB_CTX *libctx, DH_PKEY_CTX *dctx,
280 int prime_len = dctx->prime_len;
281 int subprime_len = dctx->subprime_len;
283 if (dctx->paramgen_type > DH_PARAMGEN_TYPE_FIPS_186_4)
289 if (subprime_len == -1) {
290 if (prime_len >= 2048)
296 if (dctx->md != NULL)
297 ossl_ffc_set_digest(&ret->params, EVP_MD_get0_name(dctx->md), NULL);
300 if (dctx->paramgen_type == DH_PARAMGEN_TYPE_FIPS_186_2)
301 rv = ossl_ffc_params_FIPS186_2_generate(libctx, &ret->params,
303 prime_len, subprime_len, &res,
307 /* For FIPS we always use the DH_PARAMGEN_TYPE_FIPS_186_4 generator */
308 if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2)
309 rv = ossl_ffc_params_FIPS186_4_generate(libctx, &ret->params,
311 prime_len, subprime_len, &res,
320 static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx,
324 DH_PKEY_CTX *dctx = ctx->data;
325 BN_GENCB *pcb = NULL;
329 * Look for a safe prime group for key establishment. Which uses
330 * either RFC_3526 (modp_XXXX) or RFC_7919 (ffdheXXXX).
331 * RFC_5114 is also handled here for param_nid = (1..3)
333 if (dctx->param_nid != NID_undef) {
334 int type = dctx->param_nid <= 3 ? EVP_PKEY_DHX : EVP_PKEY_DH;
336 if ((dh = DH_new_by_nid(dctx->param_nid)) == NULL)
338 EVP_PKEY_assign(pkey, type, dh);
342 if (ctx->pkey_gencb != NULL) {
343 pcb = BN_GENCB_new();
346 evp_pkey_set_cb_translate(pcb, ctx);
349 dctx->paramgen_type = DH_PARAMGEN_TYPE_FIPS_186_4;
350 # endif /* FIPS_MODULE */
351 if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2) {
352 dh = ffc_params_generate(NULL, dctx, pcb);
356 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
364 ret = DH_generate_parameters_ex(dh,
365 dctx->prime_len, dctx->generator, pcb);
368 EVP_PKEY_assign_DH(pkey, dh);
374 static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
376 DH_PKEY_CTX *dctx = ctx->data;
379 if (ctx->pkey == NULL && dctx->param_nid == NID_undef) {
380 ERR_raise(ERR_LIB_DH, DH_R_NO_PARAMETERS_SET);
383 if (dctx->param_nid != NID_undef)
384 dh = DH_new_by_nid(dctx->param_nid);
389 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
390 /* Note: if error return, pkey is freed by parent routine */
391 if (ctx->pkey != NULL && !EVP_PKEY_copy_parameters(pkey, ctx->pkey))
393 return DH_generate_key((DH *)EVP_PKEY_get0_DH(pkey));
396 static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
402 DH_PKEY_CTX *dctx = ctx->data;
405 if (ctx->pkey == NULL || ctx->peerkey == NULL) {
406 ERR_raise(ERR_LIB_DH, DH_R_KEYS_NOT_SET);
409 dh = (DH *)EVP_PKEY_get0_DH(ctx->pkey);
410 dhpub = EVP_PKEY_get0_DH(ctx->peerkey);
412 ERR_raise(ERR_LIB_DH, DH_R_KEYS_NOT_SET);
415 dhpubbn = dhpub->pub_key;
416 if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
418 *keylen = DH_size(dh);
422 ret = DH_compute_key_padded(key, dhpubbn, dh);
424 ret = DH_compute_key(key, dhpubbn, dh);
430 else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
432 unsigned char *Z = NULL;
435 if (!dctx->kdf_outlen || !dctx->kdf_oid)
438 *keylen = dctx->kdf_outlen;
441 if (*keylen != dctx->kdf_outlen)
444 if ((Zlen = DH_size(dh)) <= 0)
446 if ((Z = OPENSSL_malloc(Zlen)) == NULL)
448 if (DH_compute_key_padded(Z, dhpubbn, dh) <= 0)
450 if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
451 dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
453 *keylen = dctx->kdf_outlen;
456 OPENSSL_clear_free(Z, Zlen);
462 static const EVP_PKEY_METHOD dh_pkey_meth = {
496 const EVP_PKEY_METHOD *ossl_dh_pkey_method(void)
498 return &dh_pkey_meth;
501 static const EVP_PKEY_METHOD dhx_pkey_meth = {
535 const EVP_PKEY_METHOD *ossl_dhx_pkey_method(void)
537 return &dhx_pkey_meth;