Initialize HMAC keys to zero.

In an attempt to assign a zero-length HMAC key, consumers might
incorrectly call:

   HMAC_Init_ex(key=NULL, key_len=0)

This does not work as expected since |key==NULL| has special semantics.
This bug may consequently result in uninitialized memory being used for
the HMAC key data.

This workaround doesn't fix all the problems associated with this
pattern, however by defaulting to a zero key the results are more
predictable than before.

BUG=http://crbug.com/449409

Change-Id: I777276d57c61f1c0cce80b18e28a9b063784733f
Reviewed-on: https://boringssl-review.googlesource.com/3040
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/hmac/hmac.c b/crypto/hmac/hmac.c
index 9c1e77a..de00aae 100644
--- a/crypto/hmac/hmac.c
+++ b/crypto/hmac/hmac.c
@@ -93,6 +93,8 @@
 }
 
 void HMAC_CTX_init(HMAC_CTX *ctx) {
+  ctx->md = NULL;
+  ctx->key_length = 0;
   EVP_MD_CTX_init(&ctx->i_ctx);
   EVP_MD_CTX_init(&ctx->o_ctx);
   EVP_MD_CTX_init(&ctx->md_ctx);
@@ -111,6 +113,15 @@
   uint8_t pad[HMAC_MAX_MD_CBLOCK];
 
   if (md != NULL) {
+    if (ctx->md == NULL && key == NULL && ctx->key_length == 0) {
+      /* TODO(eroman): Change the API instead of this hack.
+       * If a key hasn't yet been assigned to the context, then default to using
+       * an all-zero key. This is to work around callers of
+       * HMAC_Init_ex(key=NULL, key_len=0) intending to set a zero-length key.
+       * Rather than resulting in uninitialized memory reads, it will
+       * predictably use a zero key. */
+      memset(ctx->key, 0, sizeof(ctx->key));
+    }
     reset = 1;
     ctx->md = md;
   } else {