summaryrefslogtreecommitdiffstats
path: root/crypto/dh
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2020-10-15 07:10:29 +0200
committerRichard Levitte <levitte@openssl.org>2020-10-19 12:14:11 +0200
commit0ba71d6a63add7efb244965c0f18502bd786a0f7 (patch)
tree95c205161b20599ac718a87645b9003c1832d579 /crypto/dh
parentChange markdown link style in README, INSTALL, SUPPORT and CONTRIBUTING (diff)
downloadopenssl-0ba71d6a63add7efb244965c0f18502bd786a0f7.tar.xz
openssl-0ba71d6a63add7efb244965c0f18502bd786a0f7.zip
DH: make the private key length importable / exportable
The DH private key length, which is an optional parameter, wasn't properly imported / exported between legacy and provider side implementations. Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from https://github.com/openssl/openssl/pull/13166)
Diffstat (limited to 'crypto/dh')
-rw-r--r--crypto/dh/dh_ameth.c8
-rw-r--r--crypto/dh/dh_backend.c66
-rw-r--r--crypto/dh/dh_lib.c19
3 files changed, 73 insertions, 20 deletions
diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c
index 69b166362a..49e65e4d6c 100644
--- a/crypto/dh/dh_ameth.c
+++ b/crypto/dh/dh_ameth.c
@@ -485,6 +485,7 @@ static int dh_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
DH *dh = from->pkey.dh;
OSSL_PARAM_BLD *tmpl;
const BIGNUM *p = DH_get0_p(dh), *g = DH_get0_g(dh), *q = DH_get0_q(dh);
+ long l = DH_get_length(dh);
const BIGNUM *pub_key = DH_get0_pub_key(dh);
const BIGNUM *priv_key = DH_get0_priv_key(dh);
OSSL_PARAM *params = NULL;
@@ -512,6 +513,11 @@ static int dh_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
goto err;
}
selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;
+ if (l > 0) {
+ if (!OSSL_PARAM_BLD_push_long(tmpl, OSSL_PKEY_PARAM_DH_PRIV_LEN, l))
+ goto err;
+ selection |= OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS;
+ }
if (pub_key != NULL) {
if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PUB_KEY, pub_key))
goto err;
@@ -550,7 +556,7 @@ static int dh_pkey_import_from_type(const OSSL_PARAM params[], void *vpctx,
DH_clear_flags(dh, DH_FLAG_TYPE_MASK);
DH_set_flags(dh, type == EVP_PKEY_DH ? DH_FLAG_TYPE_DH : DH_FLAG_TYPE_DHX);
- if (!dh_ffc_params_fromdata(dh, params)
+ if (!dh_params_fromdata(dh, params)
|| !dh_key_fromdata(dh, params)
|| !EVP_PKEY_assign(pkey, type, dh)) {
DH_free(dh);
diff --git a/crypto/dh/dh_backend.c b/crypto/dh/dh_backend.c
index 704f6efac1..1ce29e652d 100644
--- a/crypto/dh/dh_backend.c
+++ b/crypto/dh/dh_backend.c
@@ -8,6 +8,7 @@
*/
#include <openssl/core_names.h>
+#include "internal/param_build_set.h"
#include "crypto/dh.h"
/*
@@ -16,6 +17,41 @@
* implementations alike.
*/
+static int dh_ffc_params_fromdata(DH *dh, const OSSL_PARAM params[])
+{
+ int ret;
+ FFC_PARAMS *ffc;
+
+ if (dh == NULL)
+ return 0;
+ ffc = dh_get0_params(dh);
+ if (ffc == NULL)
+ return 0;
+
+ ret = ossl_ffc_params_fromdata(ffc, params);
+ if (ret)
+ dh_cache_named_group(dh); /* This increments dh->dirt_cnt */
+ return ret;
+}
+
+int dh_params_fromdata(DH *dh, const OSSL_PARAM params[])
+{
+ const OSSL_PARAM *param_priv_len;
+ long priv_len;
+
+ if (!dh_ffc_params_fromdata(dh, params))
+ return 0;
+
+ param_priv_len =
+ OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_PRIV_LEN);
+ if (param_priv_len != NULL
+ && (!OSSL_PARAM_get_long(param_priv_len, &priv_len)
+ || !DH_set_length(dh, priv_len)))
+ return 0;
+
+ return 1;
+}
+
int dh_key_fromdata(DH *dh, const OSSL_PARAM params[])
{
const OSSL_PARAM *param_priv_key, *param_pub_key;
@@ -52,3 +88,33 @@ int dh_key_fromdata(DH *dh, const OSSL_PARAM params[])
BN_free(pub_key);
return 0;
}
+
+int dh_params_todata(DH *dh, OSSL_PARAM_BLD *bld, OSSL_PARAM params[])
+{
+ long l = DH_get_length(dh);
+
+ if (!ossl_ffc_params_todata(dh_get0_params(dh), bld, params))
+ return 0;
+ if (l > 0
+ && !ossl_param_build_set_long(bld, params, OSSL_PKEY_PARAM_DH_PRIV_LEN, l))
+ return 0;
+ return 1;
+}
+
+int dh_key_todata(DH *dh, OSSL_PARAM_BLD *bld, OSSL_PARAM params[])
+{
+ const BIGNUM *priv = NULL, *pub = NULL;
+
+ if (dh == NULL)
+ return 0;
+
+ DH_get0_key(dh, &pub, &priv);
+ if (priv != NULL
+ && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_PRIV_KEY, priv))
+ return 0;
+ if (pub != NULL
+ && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_PUB_KEY, pub))
+ return 0;
+
+ return 1;
+}
diff --git a/crypto/dh/dh_lib.c b/crypto/dh/dh_lib.c
index 94978a2cb2..e6eba34ac9 100644
--- a/crypto/dh/dh_lib.c
+++ b/crypto/dh/dh_lib.c
@@ -325,22 +325,3 @@ int dh_get0_nid(const DH *dh)
{
return dh->params.nid;
}
-
-int dh_ffc_params_fromdata(DH *dh, const OSSL_PARAM params[])
-{
- int ret;
- FFC_PARAMS *ffc;
-
- if (dh == NULL)
- return 0;
- ffc = dh_get0_params(dh);
- if (ffc == NULL)
- return 0;
-
- ret = ossl_ffc_params_fromdata(ffc, params);
- if (ret) {
- dh_cache_named_group(dh);
- dh->dirty_cnt++;
- }
- return ret;
-}