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>
This commit is contained in:
David Benjamin 2016-04-19 17:39:28 -04:00 committed by Adam Langley
parent 3baee2a495
commit c0d8b83b44
2 changed files with 47 additions and 53 deletions

View File

@ -97,7 +97,6 @@ int SHA384_Init(SHA512_CTX *sha) {
sha->Nl = 0;
sha->Nh = 0;
sha->num = 0;
sha->md_len = SHA384_DIGEST_LENGTH;
return 1;
}
@ -115,7 +114,6 @@ int SHA512_Init(SHA512_CTX *sha) {
sha->Nl = 0;
sha->Nh = 0;
sha->num = 0;
sha->md_len = SHA512_DIGEST_LENGTH;
return 1;
}
@ -155,15 +153,36 @@ static
#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 @@ int SHA512_Update(SHA512_CTX *c, const void *in_data, size_t len) {
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 @@ int SHA512_Final(uint8_t *md, SHA512_CTX *sha) {
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;

View File

@ -189,15 +189,15 @@ struct sha256_state_st {
/* 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 @@ OPENSSL_EXPORT void SHA384_Transform(SHA512_CTX *sha, const uint8_t *data);
/* 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 @@ struct sha512_state_st {
uint64_t d[16];
uint8_t p[128];
} u;
unsigned num, md_len;
unsigned num;
};