summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2019-04-15 09:37:51 +0200
committerRichard Levitte <levitte@openssl.org>2019-04-15 10:46:09 +0200
commit0ad50b4dee36d4b576473ccbf744284d66fbffd6 (patch)
treebd36098c772345c31c023eef2e7b8399b773cd84
parent15972296af6b98ae495ada9d4695f2a0e71f891c (diff)
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 <paul.dale@oracle.com> (Merged from https://github.com/openssl/openssl/pull/8747)
-rw-r--r--crypto/evp/digest.c7
-rw-r--r--include/openssl/core_numbers.h4
-rw-r--r--providers/common/digests/sha2.c8
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 <openssl/crypto.h>
#include <openssl/core_numbers.h>
-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;
}