Maintain EVP_MD_CTX invariants.

Thanks to Lennart Beringer for pointing that that malloc failures could
lead to invalid EVP_MD_CTX states. This change cleans up the code in
general so that fallible operations are all performed before mutating
objects. Thus failures should leave objects in a valid state.

Also, |ctx_size| is never zero and a hash with no context is not
sensible, so stop handling that case and simply assert that it doesn't
occur.

Change-Id: Ia60c3796dcf2f772f55e12e49431af6475f64d52
Reviewed-on: https://boringssl-review.googlesource.com/20544
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
diff --git a/crypto/fipsmodule/digest/digest.c b/crypto/fipsmodule/digest/digest.c
index 886c910..8afd1e1 100644
--- a/crypto/fipsmodule/digest/digest.c
+++ b/crypto/fipsmodule/digest/digest.c
@@ -90,9 +90,7 @@
 }
 
 int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) {
-  if (ctx->digest && ctx->digest->ctx_size && ctx->md_data) {
-    OPENSSL_free(ctx->md_data);
-  }
+  OPENSSL_free(ctx->md_data);
 
   assert(ctx->pctx == NULL || ctx->pctx_ops != NULL);
   if (ctx->pctx_ops) {
@@ -114,17 +112,35 @@
 }
 
 int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) {
-  uint8_t *tmp_buf = NULL;
-
   if (in == NULL || in->digest == NULL) {
     OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_INPUT_NOT_INITIALIZED);
     return 0;
   }
 
-  if (out->digest == in->digest) {
-    // |md_data| will be the correct size in this case so it's removed from
-    // |out| at this point so that |EVP_MD_CTX_cleanup| doesn't free it and
-    // then it's reused.
+  EVP_PKEY_CTX *pctx = NULL;
+  assert(in->pctx == NULL || in->pctx_ops != NULL);
+  if (in->pctx) {
+    pctx = in->pctx_ops->dup(in->pctx);
+    if (!pctx) {
+      OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE);
+      return 0;
+    }
+  }
+
+  uint8_t *tmp_buf;
+  if (out->digest != in->digest) {
+    assert(in->digest->ctx_size != 0);
+    tmp_buf = OPENSSL_malloc(in->digest->ctx_size);
+    if (tmp_buf == NULL) {
+      if (pctx) {
+        in->pctx_ops->free(pctx);
+      }
+      OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE);
+      return 0;
+    }
+  } else {
+    // |md_data| will be the correct size in this case. It's removed from |out|
+    // so that |EVP_MD_CTX_cleanup| doesn't free it, and then it's reused.
     tmp_buf = out->md_data;
     out->md_data = NULL;
   }
@@ -132,28 +148,11 @@
   EVP_MD_CTX_cleanup(out);
 
   out->digest = in->digest;
-  if (in->md_data && in->digest->ctx_size) {
-    if (tmp_buf) {
-      out->md_data = tmp_buf;
-    } else {
-      out->md_data = OPENSSL_malloc(in->digest->ctx_size);
-      if (!out->md_data) {
-        OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE);
-        return 0;
-      }
-    }
-    OPENSSL_memcpy(out->md_data, in->md_data, in->digest->ctx_size);
-  }
-
-  assert(in->pctx == NULL || in->pctx_ops != NULL);
+  out->md_data = tmp_buf;
+  OPENSSL_memcpy(out->md_data, in->md_data, in->digest->ctx_size);
+  out->pctx = pctx;
   out->pctx_ops = in->pctx_ops;
-  if (in->pctx && in->pctx_ops) {
-    out->pctx = in->pctx_ops->dup(in->pctx);
-    if (!out->pctx) {
-      EVP_MD_CTX_cleanup(out);
-      return 0;
-    }
-  }
+  assert(out->pctx == NULL || out->pctx_ops != NULL);
 
   return 1;
 }
@@ -165,18 +164,16 @@
 
 int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *engine) {
   if (ctx->digest != type) {
-    if (ctx->digest && ctx->digest->ctx_size > 0) {
-      OPENSSL_free(ctx->md_data);
-      ctx->md_data = NULL;
+    assert(type->ctx_size != 0);
+    uint8_t *md_data = OPENSSL_malloc(type->ctx_size);
+    if (md_data == NULL) {
+      OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE);
+      return 0;
     }
+
+    OPENSSL_free(ctx->md_data);
+    ctx->md_data = md_data;
     ctx->digest = type;
-    if (type->ctx_size > 0) {
-      ctx->md_data = OPENSSL_malloc(type->ctx_size);
-      if (ctx->md_data == NULL) {
-        OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE);
-        return 0;
-      }
-    }
   }
 
   assert(ctx->pctx == NULL || ctx->pctx_ops != NULL);