summaryrefslogtreecommitdiffstats
path: root/crypto/dh
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2019-07-07 10:56:46 +0200
committerRichard Levitte <levitte@openssl.org>2019-07-23 19:43:09 +0200
commit8b84b075ff065554c0cdd1086950f1a8614d93a4 (patch)
tree504e19c43e2f8313665156f2220539830dece99d /crypto/dh
parent037439c46addc62130617bbba8c5e58e1548bfd8 (diff)
Adapt DH to use with KEYMGMT
The biggest part in this was to move the key->param builder from EVP to the DH ASN.1 method, and to implement the KEYMGMT support in the provider DH. Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/9394)
Diffstat (limited to 'crypto/dh')
-rw-r--r--crypto/dh/dh_ameth.c57
-rw-r--r--crypto/dh/dh_asn1.c2
-rw-r--r--crypto/dh/dh_gen.c1
-rw-r--r--crypto/dh/dh_key.c1
-rw-r--r--crypto/dh/dh_lib.c2
-rw-r--r--crypto/dh/dh_locl.h3
-rw-r--r--crypto/dh/dh_rfc7919.c1
7 files changed, 65 insertions, 2 deletions
diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c
index 524cac5bd8..6da4878200 100644
--- a/crypto/dh/dh_ameth.c
+++ b/crypto/dh/dh_ameth.c
@@ -16,6 +16,8 @@
#include "internal/asn1_int.h"
#include "internal/evp_int.h"
#include <openssl/cms.h>
+#include <openssl/core_names.h>
+#include "internal/param_build.h"
/*
* i2d/d2i like DH parameter functions which use the appropriate routine for
@@ -181,7 +183,7 @@ static int dh_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
DHerr(DH_F_DH_PRIV_DECODE, DH_R_BN_ERROR);
goto dherr;
}
- /* Calculate public key */
+ /* Calculate public key, increments dirty_cnt */
if (!DH_generate_key(dh))
goto dherr;
@@ -255,6 +257,7 @@ static int dh_param_decode(EVP_PKEY *pkey,
DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB);
return 0;
}
+ dh->dirty_cnt++;
EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
return 1;
}
@@ -415,6 +418,7 @@ static int int_dh_param_copy(DH *to, const DH *from, int is_x942)
}
} else
to->length = from->length;
+ to->dirty_cnt++;
return 1;
}
@@ -540,6 +544,50 @@ static int dh_pkey_param_check(const EVP_PKEY *pkey)
return DH_check_ex(dh);
}
+static size_t dh_pkey_dirty_cnt(const EVP_PKEY *pkey)
+{
+ return pkey->pkey.dh->dirty_cnt;
+}
+
+static void *dh_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
+{
+ DH *dh = pk->pkey.dh;
+ OSSL_PARAM_BLD tmpl;
+ const BIGNUM *p = DH_get0_p(dh), *g = DH_get0_g(dh), *q = DH_get0_q(dh);
+ const BIGNUM *pub_key = DH_get0_pub_key(dh);
+ const BIGNUM *priv_key = DH_get0_priv_key(dh);
+ OSSL_PARAM *params;
+ void *provkey = NULL;
+
+ if (p == NULL || g == NULL || pub_key == NULL)
+ return NULL;
+
+ ossl_param_bld_init(&tmpl);
+ if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_P, p)
+ || !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_G, g)
+ || !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_PUB_KEY, pub_key))
+ return NULL;
+
+ if (q != NULL) {
+ if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_Q, q))
+ return NULL;
+ }
+
+ if (priv_key != NULL) {
+ if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_PRIV_KEY,
+ priv_key))
+ return NULL;
+ }
+
+ params = ossl_param_bld_to_param(&tmpl);
+
+ /* We export, the provider imports */
+ provkey = evp_keymgmt_importkey(keymgmt, params);
+
+ ossl_param_bld_free(params);
+ return provkey;
+}
+
const EVP_PKEY_ASN1_METHOD dh_asn1_meth = {
EVP_PKEY_DH,
EVP_PKEY_DH,
@@ -576,7 +624,12 @@ const EVP_PKEY_ASN1_METHOD dh_asn1_meth = {
0,
dh_pkey_public_check,
- dh_pkey_param_check
+ dh_pkey_param_check,
+
+ 0, 0, 0, 0,
+
+ dh_pkey_dirty_cnt,
+ dh_pkey_export_to,
};
const EVP_PKEY_ASN1_METHOD dhx_asn1_meth = {
diff --git a/crypto/dh/dh_asn1.c b/crypto/dh/dh_asn1.c
index aabdfa8360..71379d73bb 100644
--- a/crypto/dh/dh_asn1.c
+++ b/crypto/dh/dh_asn1.c
@@ -27,6 +27,8 @@ static int dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
DH_free((DH *)*pval);
*pval = NULL;
return 2;
+ } else if (operation == ASN1_OP_D2I_POST) {
+ ((DH *)*pval)->dirty_cnt++;
}
return 1;
}
diff --git a/crypto/dh/dh_gen.c b/crypto/dh/dh_gen.c
index bbf774f138..6e98b59d85 100644
--- a/crypto/dh/dh_gen.c
+++ b/crypto/dh/dh_gen.c
@@ -111,6 +111,7 @@ static int dh_builtin_genparams(DH *ret, int prime_len, int generator,
goto err;
if (!BN_set_word(ret->g, g))
goto err;
+ ret->dirty_cnt++;
ok = 1;
err:
if (ok == -1) {
diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c
index 4df993e345..0d6b04de20 100644
--- a/crypto/dh/dh_key.c
+++ b/crypto/dh/dh_key.c
@@ -154,6 +154,7 @@ static int generate_key(DH *dh)
dh->pub_key = pub_key;
dh->priv_key = priv_key;
+ dh->dirty_cnt++;
ok = 1;
err:
if (ok != 1)
diff --git a/crypto/dh/dh_lib.c b/crypto/dh/dh_lib.c
index 70298edd08..df3166279e 100644
--- a/crypto/dh/dh_lib.c
+++ b/crypto/dh/dh_lib.c
@@ -209,6 +209,7 @@ int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
dh->length = BN_num_bits(q);
}
+ dh->dirty_cnt++;
return 1;
}
@@ -242,6 +243,7 @@ int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
dh->priv_key = priv_key;
}
+ dh->dirty_cnt++;
return 1;
}
diff --git a/crypto/dh/dh_locl.h b/crypto/dh/dh_locl.h
index bb64cde9f7..f0247b8d7d 100644
--- a/crypto/dh/dh_locl.h
+++ b/crypto/dh/dh_locl.h
@@ -35,6 +35,9 @@ struct dh_st {
const DH_METHOD *meth;
ENGINE *engine;
CRYPTO_RWLOCK *lock;
+
+ /* Provider data */
+ size_t dirty_cnt; /* If any key material changes, increment this */
};
struct dh_method {
diff --git a/crypto/dh/dh_rfc7919.c b/crypto/dh/dh_rfc7919.c
index e9f3eafb0e..4e676fd3d1 100644
--- a/crypto/dh/dh_rfc7919.c
+++ b/crypto/dh/dh_rfc7919.c
@@ -22,6 +22,7 @@ static DH *dh_param_init(const BIGNUM *p, int32_t nbits)
dh->p = (BIGNUM *)p;
dh->g = (BIGNUM *)&_bignum_const_2;
dh->length = nbits;
+ dh->dirty_cnt++;
return dh;
}