diff options
author | Richard Levitte <levitte@openssl.org> | 2022-06-11 07:40:40 +0200 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2022-06-15 15:17:39 +0200 |
commit | e906eab8d863ac7bdadc671e8d0686fead88c4bf (patch) | |
tree | ddca414b4dc003654087b465d228083b14cda551 /providers/implementations | |
parent | a0587aaeff7391b8cf4ee4c6a233d0f4dca7d62f (diff) |
providers/implementations/exchange/kdf_exch.c: Fix kdf_derive()
kdf_derive() calls EVP_KDF_derive(), but didn't do enough to adapt its input
buffer length arguments to fit the requirements to call EVP_KDF_derive().
Fixes #18517
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/18533)
Diffstat (limited to 'providers/implementations')
-rw-r--r-- | providers/implementations/exchange/kdf_exch.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/providers/implementations/exchange/kdf_exch.c b/providers/implementations/exchange/kdf_exch.c index 38631b45d1..bb18da9eba 100644 --- a/providers/implementations/exchange/kdf_exch.c +++ b/providers/implementations/exchange/kdf_exch.c @@ -11,6 +11,8 @@ #include <openssl/kdf.h> #include <openssl/core_dispatch.h> #include <openssl/core_names.h> +#include <openssl/err.h> +#include <openssl/proverr.h> #include <openssl/params.h> #include "prov/implementations.h" #include "prov/provider_ctx.h" @@ -92,16 +94,33 @@ static int kdf_derive(void *vpkdfctx, unsigned char *secret, size_t *secretlen, size_t outlen) { PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx; + size_t kdfsize; + int ret; if (!ossl_prov_is_running()) return 0; + kdfsize = EVP_KDF_CTX_get_kdf_size(pkdfctx->kdfctx); + if (secret == NULL) { - *secretlen = EVP_KDF_CTX_get_kdf_size(pkdfctx->kdfctx); + *secretlen = kdfsize; return 1; } - return EVP_KDF_derive(pkdfctx->kdfctx, secret, outlen, NULL); + if (kdfsize != SIZE_MAX) { + if (outlen < kdfsize) { + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + outlen = kdfsize; + } + + ret = EVP_KDF_derive(pkdfctx->kdfctx, secret, outlen, NULL); + if (ret <= 0) + return 0; + + *secretlen = outlen; + return 1; } static void kdf_freectx(void *vpkdfctx) |