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
#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)
