Providers: for the digest_final operation, pass a output buffer size
authorRichard Levitte <levitte@openssl.org>
Mon, 15 Apr 2019 07:37:51 +0000 (09:37 +0200)
committerRichard Levitte <levitte@openssl.org>
Mon, 15 Apr 2019 08:46:09 +0000 (10:46 +0200)
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)

crypto/evp/digest.c
include/openssl/core_numbers.h
providers/common/digests/sha2.c

index 527c5d66b053930bc4b8db3d1044f3d4d3157d9b..e4787e6256ebb8acfa8836e9b368d7d6a4996360 100644 (file)
@@ -295,6 +295,7 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize)
 {
     int ret;
     size_t size = 0;
 {
     int ret;
     size_t size = 0;
+    size_t mdsize = EVP_MD_size(ctx->digest);
 
     if (ctx->digest == NULL || ctx->digest->prov == NULL)
         goto legacy;
 
     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;
     }
 
         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) {
 
     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:
 
     /* 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)
     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);
     if (ctx->digest->cleanup) {
         ctx->digest->cleanup(ctx);
         EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
index 1e53627706bccdf4ed7012445814682055b4d265..20543812f4eec72d8a3afb44e2a8c45c26ef8f49 100644 (file)
@@ -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,
 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,
 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))
 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))
index 4332e9818eae9adffbb02b09fac8763306589445..fb2bd95f5235a5af8d484f9d0c88ee5c7209304c 100644 (file)
 #include <openssl/crypto.h>
 #include <openssl/core_numbers.h>
 
 #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;
     }
 
         return 1;
     }