diff options
Diffstat (limited to 'providers')
-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) |