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;
};