summaryrefslogtreecommitdiffstats
path: root/crypto/evp
diff options
context:
space:
mode:
authorShane Lontis <shane.lontis@oracle.com>2021-03-29 13:38:00 +1000
committerShane Lontis <shane.lontis@oracle.com>2021-04-01 09:07:08 +1000
commite454a3934c287aede194cac49c8934f04bf6a04f (patch)
treec43916f0a50c5e2d1a9aa1caa00539c0629f1175 /crypto/evp
parent9e6f30e683fd0f243cf15d2bac2cdef2bcbbac12 (diff)
Add a range check (from SP800-56Ar3) to DH key derivation.
Fixes #14401 Note that this moves the public key check out of DH compute_key() since key validation does not belong inside this primitive.. The check has been moved to the EVP_PKEY_derive_set_peer() function so that it generally applies to all exchange operations.. Use EVP_PKEY_derive_set_peer_ex() to disable this behaviour. Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/14717)
Diffstat (limited to 'crypto/evp')
-rw-r--r--crypto/evp/exchange.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/crypto/evp/exchange.c b/crypto/evp/exchange.c
index 5e098f0c3f..5bb038f118 100644
--- a/crypto/evp/exchange.c
+++ b/crypto/evp/exchange.c
@@ -317,10 +317,12 @@ int EVP_PKEY_derive_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[])
#endif
}
-int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
+int EVP_PKEY_derive_set_peer_ex(EVP_PKEY_CTX *ctx, EVP_PKEY *peer,
+ int validate_peer)
{
- int ret = 0;
+ int ret = 0, check;
void *provkey = NULL;
+ EVP_PKEY_CTX *check_ctx = NULL;
if (ctx == NULL) {
ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
@@ -335,6 +337,16 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
return -2;
}
+ if (validate_peer) {
+ check_ctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, peer, ctx->propquery);
+ if (check_ctx == NULL)
+ return -1;
+ check = EVP_PKEY_public_check(check_ctx);
+ EVP_PKEY_CTX_free(check_ctx);
+ if (check <= 0)
+ return -1;
+ }
+
provkey = evp_pkey_export_to_provider(peer, ctx->libctx, &ctx->keymgmt,
ctx->propquery);
/*
@@ -410,6 +422,11 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
#endif
}
+int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
+{
+ return EVP_PKEY_derive_set_peer_ex(ctx, peer, 1);
+}
+
int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
{
int ret;