Make SHA512_Final actually only return one.

Rather than store md_len, factor out the common parts of SHA384_Final and
SHA512_Final and then extract the right state. Also add a missing
SHA384_Transform and be consistent about "1" vs "one" in comments.

This also removes the NULL output special-case which no other hash function
had.

Change-Id: If60008bae7d7d5b123046a46d8fd64139156a7c5
Reviewed-on: https://boringssl-review.googlesource.com/7720
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/sha/sha512.c b/crypto/sha/sha512.c
index 6ad8d40..9bfd96f 100644
--- a/crypto/sha/sha512.c
+++ b/crypto/sha/sha512.c
@@ -97,7 +97,6 @@
   sha->Nl = 0;
   sha->Nh = 0;
   sha->num = 0;
-  sha->md_len = SHA384_DIGEST_LENGTH;
   return 1;
 }
 
@@ -115,7 +114,6 @@
   sha->Nl = 0;
   sha->Nh = 0;
   sha->num = 0;
-  sha->md_len = SHA512_DIGEST_LENGTH;
   return 1;
 }
 
@@ -155,15 +153,36 @@
 #endif
 void sha512_block_data_order(uint64_t *state, const uint64_t *W, size_t num);
 
-
-int SHA384_Final(uint8_t *md, SHA512_CTX *sha) {
-  return SHA512_Final(md, sha);
-}
+static void sha512_finish(SHA512_CTX *sha);
 
 int SHA384_Update(SHA512_CTX *sha, const void *data, size_t len) {
   return SHA512_Update(sha, data, len);
 }
 
+void SHA384_Transform(SHA512_CTX *c, const uint8_t *data) {
+  return SHA512_Transform(c, data);
+}
+
+int SHA384_Final(uint8_t *md, SHA512_CTX *sha) {
+  sha512_finish(sha);
+
+  size_t n;
+  for (n = 0; n < SHA384_DIGEST_LENGTH / 8; n++) {
+    uint64_t t = sha->h[n];
+
+    *(md++) = (uint8_t)(t >> 56);
+    *(md++) = (uint8_t)(t >> 48);
+    *(md++) = (uint8_t)(t >> 40);
+    *(md++) = (uint8_t)(t >> 32);
+    *(md++) = (uint8_t)(t >> 24);
+    *(md++) = (uint8_t)(t >> 16);
+    *(md++) = (uint8_t)(t >> 8);
+    *(md++) = (uint8_t)(t);
+  }
+
+  return 1;
+}
+
 void SHA512_Transform(SHA512_CTX *c, const uint8_t *data) {
 #ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
   if ((size_t)data % sizeof(c->u.d[0]) != 0) {
@@ -234,7 +253,7 @@
   return 1;
 }
 
-int SHA512_Final(uint8_t *md, SHA512_CTX *sha) {
+static void sha512_finish(SHA512_CTX *sha) {
   uint8_t *p = (uint8_t *)sha->u.p;
   size_t n = sha->num;
 
@@ -265,48 +284,23 @@
   p[sizeof(sha->u) - 16] = (uint8_t)(sha->Nh >> 56);
 
   sha512_block_data_order(sha->h, (uint64_t *)p, 1);
+}
 
-  if (md == NULL) {
-    /* TODO(davidben): This NULL check is absent in other low-level hash 'final'
-     * functions and is one of the few places one can fail. */
-    return 0;
-  }
+int SHA512_Final(uint8_t *md, SHA512_CTX *sha) {
+  sha512_finish(sha);
 
-  switch (sha->md_len) {
-    /* Let compiler decide if it's appropriate to unroll... */
-    case SHA384_DIGEST_LENGTH:
-      for (n = 0; n < SHA384_DIGEST_LENGTH / 8; n++) {
-        uint64_t t = sha->h[n];
+  size_t n;
+  for (n = 0; n < SHA512_DIGEST_LENGTH / 8; n++) {
+    uint64_t t = sha->h[n];
 
-        *(md++) = (uint8_t)(t >> 56);
-        *(md++) = (uint8_t)(t >> 48);
-        *(md++) = (uint8_t)(t >> 40);
-        *(md++) = (uint8_t)(t >> 32);
-        *(md++) = (uint8_t)(t >> 24);
-        *(md++) = (uint8_t)(t >> 16);
-        *(md++) = (uint8_t)(t >> 8);
-        *(md++) = (uint8_t)(t);
-      }
-      break;
-    case SHA512_DIGEST_LENGTH:
-      for (n = 0; n < SHA512_DIGEST_LENGTH / 8; n++) {
-        uint64_t t = sha->h[n];
-
-        *(md++) = (uint8_t)(t >> 56);
-        *(md++) = (uint8_t)(t >> 48);
-        *(md++) = (uint8_t)(t >> 40);
-        *(md++) = (uint8_t)(t >> 32);
-        *(md++) = (uint8_t)(t >> 24);
-        *(md++) = (uint8_t)(t >> 16);
-        *(md++) = (uint8_t)(t >> 8);
-        *(md++) = (uint8_t)(t);
-      }
-      break;
-    /* ... as well as make sure md_len is not abused. */
-    default:
-      /* TODO(davidben): This bad |md_len| case is one of the few places a
-       * low-level hash 'final' function can fail. This should never happen. */
-      return 0;
+    *(md++) = (uint8_t)(t >> 56);
+    *(md++) = (uint8_t)(t >> 48);
+    *(md++) = (uint8_t)(t >> 40);
+    *(md++) = (uint8_t)(t >> 32);
+    *(md++) = (uint8_t)(t >> 24);
+    *(md++) = (uint8_t)(t >> 16);
+    *(md++) = (uint8_t)(t >> 8);
+    *(md++) = (uint8_t)(t);
   }
 
   return 1;
diff --git a/include/openssl/sha.h b/include/openssl/sha.h
index 48a52e8..a1f360b 100644
--- a/include/openssl/sha.h
+++ b/include/openssl/sha.h
@@ -189,15 +189,15 @@
 /* SHA384_DIGEST_LENGTH is the length of a SHA-384 digest. */
 #define SHA384_DIGEST_LENGTH 48
 
-/* SHA384_Init initialises |sha| and returns 1. */
+/* SHA384_Init initialises |sha| and returns one. */
 OPENSSL_EXPORT int SHA384_Init(SHA512_CTX *sha);
 
-/* SHA384_Update adds |len| bytes from |data| to |sha| and returns 1. */
+/* SHA384_Update adds |len| bytes from |data| to |sha| and returns one. */
 OPENSSL_EXPORT int SHA384_Update(SHA512_CTX *sha, const void *data, size_t len);
 
 /* SHA384_Final adds the final padding to |sha| and writes the resulting digest
  * to |md|, which must have at least |SHA384_DIGEST_LENGTH| bytes of space. It
- * returns one on success and zero on programmer error. */
+ * returns one. */
 OPENSSL_EXPORT int SHA384_Final(uint8_t *md, SHA512_CTX *sha);
 
 /* SHA384 writes the digest of |len| bytes from |data| to |out| and returns
@@ -218,15 +218,15 @@
 /* SHA512_DIGEST_LENGTH is the length of a SHA-512 digest. */
 #define SHA512_DIGEST_LENGTH 64
 
-/* SHA512_Init initialises |sha| and returns 1. */
+/* SHA512_Init initialises |sha| and returns one. */
 OPENSSL_EXPORT int SHA512_Init(SHA512_CTX *sha);
 
-/* SHA512_Update adds |len| bytes from |data| to |sha| and returns 1. */
+/* SHA512_Update adds |len| bytes from |data| to |sha| and returns one. */
 OPENSSL_EXPORT int SHA512_Update(SHA512_CTX *sha, const void *data, size_t len);
 
 /* SHA512_Final adds the final padding to |sha| and writes the resulting digest
  * to |md|, which must have at least |SHA512_DIGEST_LENGTH| bytes of space. It
- * returns one on success and zero on programmer error. */
+ * returns one. */
 OPENSSL_EXPORT int SHA512_Final(uint8_t *md, SHA512_CTX *sha);
 
 /* SHA512 writes the digest of |len| bytes from |data| to |out| and returns
@@ -245,7 +245,7 @@
     uint64_t d[16];
     uint8_t p[128];
   } u;
-  unsigned num, md_len;
+  unsigned num;
 };