From 0ad50b4dee36d4b576473ccbf744284d66fbffd6 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Mon, 15 Apr 2019 09:37:51 +0200 Subject: Providers: for the digest_final operation, pass a output buffer size This allows the provider digest_final operation to check that it doesn't over-run the output buffer. The EVP_DigestFinal_ex function doesn't take that same parameter, so it will have to assume that the user provided a properly sized buffer, but this leaves better room for future enhancements of the public API. Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/8747) --- crypto/evp/digest.c | 7 ++++--- include/openssl/core_numbers.h | 4 ++-- providers/common/digests/sha2.c | 8 +++++--- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c index 527c5d66b0..e4787e6256 100644 --- a/crypto/evp/digest.c +++ b/crypto/evp/digest.c @@ -295,6 +295,7 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize) { int ret; size_t size = 0; + size_t mdsize = EVP_MD_size(ctx->digest); if (ctx->digest == NULL || ctx->digest->prov == NULL) goto legacy; @@ -304,7 +305,7 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize) return 0; } - ret = ctx->digest->dfinal(ctx->provctx, md, &size); + ret = ctx->digest->dfinal(ctx->provctx, md, &size, mdsize); if (isize != NULL) { if (size <= UINT_MAX) { @@ -321,10 +322,10 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize) /* TODO(3.0): Remove legacy code below */ legacy: - OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE); + OPENSSL_assert(mdsize <= EVP_MAX_MD_SIZE); ret = ctx->digest->final(ctx, md); if (isize != NULL) - *isize = ctx->digest->md_size; + *isize = mdsize; if (ctx->digest->cleanup) { ctx->digest->cleanup(ctx); EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); diff --git a/include/openssl/core_numbers.h b/include/openssl/core_numbers.h index 1e53627706..20543812f4 100644 --- a/include/openssl/core_numbers.h +++ b/include/openssl/core_numbers.h @@ -91,10 +91,10 @@ OSSL_CORE_MAKE_FUNC(int, OP_digest_init, (void *vctx)) OSSL_CORE_MAKE_FUNC(int, OP_digest_update, (void *, const unsigned char *in, size_t inl)) OSSL_CORE_MAKE_FUNC(int, OP_digest_final, - (void *, unsigned char *out, size_t *outl)) + (void *, unsigned char *out, size_t *outl, size_t outsz)) OSSL_CORE_MAKE_FUNC(int, OP_digest_digest, (const unsigned char *in, size_t inl, unsigned char *out, - size_t *out_l)) + size_t *out_l, size_t outsz)) OSSL_CORE_MAKE_FUNC(void, OP_digest_cleanctx, (void *vctx)) OSSL_CORE_MAKE_FUNC(void, OP_digest_freectx, (void *vctx)) OSSL_CORE_MAKE_FUNC(void *, OP_digest_dupctx, (void *vctx)) diff --git a/providers/common/digests/sha2.c b/providers/common/digests/sha2.c index 4332e9818e..fb2bd95f52 100644 --- a/providers/common/digests/sha2.c +++ b/providers/common/digests/sha2.c @@ -11,10 +11,12 @@ #include #include -static int sha256_final(void *ctx, unsigned char *md, size_t *size) +static int sha256_final(void *ctx, + unsigned char *md, size_t *mdl, size_t mdsz) { - if (SHA256_Final(md, ctx)) { - *size = SHA256_DIGEST_LENGTH; + if (mdsz >= SHA256_DIGEST_LENGTH + && SHA256_Final(md, ctx)) { + *mdl = SHA256_DIGEST_LENGTH; return 1; } -- cgit v1.2.3