From e906eab8d863ac7bdadc671e8d0686fead88c4bf Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Sat, 11 Jun 2022 07:40:40 +0200 Subject: 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 Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/18533) --- providers/implementations/exchange/kdf_exch.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'providers') 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 #include #include +#include +#include #include #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) -- cgit v1.2.3