Pull HASH_MAKE_STRING out of md32_common.h.
This is in preparation for taking md_len out of SHA256_CTX by allowing us to do something similar to SHA512_CTX. md32_common.h now emits a static "finish" function which Final composes with the extraction step. Change-Id: I314fb31e2482af642fd280500cc0e4716aef1ac6 Reviewed-on: https://boringssl-review.googlesource.com/7721 Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
parent
e3118b8dc4
commit
a90aa64302
@ -90,7 +90,7 @@ extern "C" {
|
||||
* |HASH_TRANSFORM| must be defined as the the name of the "Transform"
|
||||
* function to generate.
|
||||
*
|
||||
* |HASH_FINAL| must be defined as the name of "Final" function to generate.
|
||||
* |HASH_FINISH| must be defined as the name of "finish" function to generate.
|
||||
*
|
||||
* |HASH_BLOCK_DATA_ORDER| must be defined as the name of the "Block" function.
|
||||
* That function must be implemented manually. It must be capable of operating
|
||||
@ -103,11 +103,7 @@ extern "C" {
|
||||
* It must update the hash state |state| with |num| blocks of data from |data|,
|
||||
* where each block is |HASH_CBLOCK| bytes; i.e. |data| points to a array of
|
||||
* |HASH_CBLOCK * num| bytes. |state| points to the |h| member of a |HASH_CTX|,
|
||||
* and so will have |<chaining length> / sizeof(uint32_t)| elements.
|
||||
*
|
||||
* |HASH_MAKE_STRING(c, s)| must be defined as a block statement that converts
|
||||
* the hash state |c->h| into the output byte order, storing the result in |s|.
|
||||
*/
|
||||
* and so will have |<chaining length> / sizeof(uint32_t)| elements. */
|
||||
|
||||
#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
|
||||
#error "DATA_ORDER must be defined!"
|
||||
@ -126,18 +122,14 @@ extern "C" {
|
||||
#ifndef HASH_TRANSFORM
|
||||
#error "HASH_TRANSFORM must be defined!"
|
||||
#endif
|
||||
#ifndef HASH_FINAL
|
||||
#error "HASH_FINAL must be defined!"
|
||||
#ifndef HASH_FINISH
|
||||
#error "HASH_FINISH must be defined!"
|
||||
#endif
|
||||
|
||||
#ifndef HASH_BLOCK_DATA_ORDER
|
||||
#error "HASH_BLOCK_DATA_ORDER must be defined!"
|
||||
#endif
|
||||
|
||||
#ifndef HASH_MAKE_STRING
|
||||
#error "HASH_MAKE_STRING must be defined!"
|
||||
#endif
|
||||
|
||||
#if defined(DATA_ORDER_IS_BIG_ENDIAN)
|
||||
|
||||
#define HOST_c2l(c, l) \
|
||||
@ -220,7 +212,7 @@ void HASH_TRANSFORM(HASH_CTX *c, const uint8_t *data) {
|
||||
}
|
||||
|
||||
|
||||
int HASH_FINAL(uint8_t *md, HASH_CTX *c) {
|
||||
static void HASH_FINISH(HASH_CTX *c) {
|
||||
/* |c->data| always has room for at least one byte. A full block would have
|
||||
* been consumed. */
|
||||
size_t n = c->num;
|
||||
@ -249,9 +241,6 @@ int HASH_FINAL(uint8_t *md, HASH_CTX *c) {
|
||||
HASH_BLOCK_DATA_ORDER(c->h, c->data, 1);
|
||||
c->num = 0;
|
||||
memset(c->data, 0, HASH_CBLOCK);
|
||||
|
||||
HASH_MAKE_STRING(c, md);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -88,23 +88,27 @@ void md4_block_data_order(uint32_t *state, const uint8_t *data, size_t num);
|
||||
#define HASH_CBLOCK 64
|
||||
#define HASH_UPDATE MD4_Update
|
||||
#define HASH_TRANSFORM MD4_Transform
|
||||
#define HASH_FINAL MD4_Final
|
||||
#define HASH_MAKE_STRING(c, s) \
|
||||
do { \
|
||||
uint32_t ll; \
|
||||
ll = (c)->h[0]; \
|
||||
HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[1]; \
|
||||
HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[2]; \
|
||||
HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[3]; \
|
||||
HOST_l2c(ll, (s)); \
|
||||
} while (0)
|
||||
#define HASH_FINISH md4_finish
|
||||
#define HASH_BLOCK_DATA_ORDER md4_block_data_order
|
||||
|
||||
#include "../digest/md32_common.h"
|
||||
|
||||
int MD4_Final(uint8_t *md, MD4_CTX *md4) {
|
||||
md4_finish(md4);
|
||||
|
||||
uint32_t ll;
|
||||
ll = md4->h[0];
|
||||
HOST_l2c(ll, md);
|
||||
ll = md4->h[1];
|
||||
HOST_l2c(ll, md);
|
||||
ll = md4->h[2];
|
||||
HOST_l2c(ll, md);
|
||||
ll = md4->h[3];
|
||||
HOST_l2c(ll, md);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* As pointed out by Wei Dai <weidai@eskimo.com>, the above can be
|
||||
* simplified to the code below. Wei attributes these optimizations
|
||||
* to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel. */
|
||||
|
@ -101,23 +101,27 @@ void md5_block_data_order(uint32_t *state, const uint8_t *data, size_t num);
|
||||
#define HASH_CBLOCK 64
|
||||
#define HASH_UPDATE MD5_Update
|
||||
#define HASH_TRANSFORM MD5_Transform
|
||||
#define HASH_FINAL MD5_Final
|
||||
#define HASH_MAKE_STRING(c, s) \
|
||||
do { \
|
||||
uint32_t ll; \
|
||||
ll = (c)->h[0]; \
|
||||
HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[1]; \
|
||||
HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[2]; \
|
||||
HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[3]; \
|
||||
HOST_l2c(ll, (s)); \
|
||||
} while (0)
|
||||
#define HASH_FINISH md5_finish
|
||||
#define HASH_BLOCK_DATA_ORDER md5_block_data_order
|
||||
|
||||
#include "../digest/md32_common.h"
|
||||
|
||||
int MD5_Final(uint8_t *md, MD5_CTX *md5) {
|
||||
md5_finish(md5);
|
||||
|
||||
uint32_t ll;
|
||||
ll = md5->h[0];
|
||||
HOST_l2c(ll, md);
|
||||
ll = md5->h[1];
|
||||
HOST_l2c(ll, md);
|
||||
ll = md5->h[2];
|
||||
HOST_l2c(ll, md);
|
||||
ll = md5->h[3];
|
||||
HOST_l2c(ll, md);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* As pointed out by Wei Dai <weidai@eskimo.com>, the above can be
|
||||
* simplified to the code below. Wei attributes these optimizations
|
||||
* to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
|
||||
|
@ -98,24 +98,10 @@ uint8_t *SHA1(const uint8_t *data, size_t len, uint8_t *out) {
|
||||
|
||||
#define HASH_CTX SHA_CTX
|
||||
#define HASH_CBLOCK 64
|
||||
#define HASH_MAKE_STRING(c, s) \
|
||||
do { \
|
||||
uint32_t ll; \
|
||||
ll = (c)->h[0]; \
|
||||
HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[1]; \
|
||||
HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[2]; \
|
||||
HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[3]; \
|
||||
HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[4]; \
|
||||
HOST_l2c(ll, (s)); \
|
||||
} while (0)
|
||||
|
||||
#define HASH_UPDATE SHA1_Update
|
||||
#define HASH_TRANSFORM SHA1_Transform
|
||||
#define HASH_FINAL SHA1_Final
|
||||
#define HASH_FINISH sha1_finish
|
||||
#define HASH_BLOCK_DATA_ORDER sha1_block_data_order
|
||||
#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n))))
|
||||
#define Xupdate(a, ix, ia, ib, ic, id) \
|
||||
@ -128,6 +114,24 @@ void sha1_block_data_order(uint32_t *state, const uint8_t *data, size_t num);
|
||||
|
||||
#include "../digest/md32_common.h"
|
||||
|
||||
int SHA1_Final(uint8_t *md, SHA_CTX *sha) {
|
||||
sha1_finish(sha);
|
||||
|
||||
uint32_t ll;
|
||||
ll = sha->h[0];
|
||||
HOST_l2c(ll, md);
|
||||
ll = sha->h[1];
|
||||
HOST_l2c(ll, md);
|
||||
ll = sha->h[2];
|
||||
HOST_l2c(ll, md);
|
||||
ll = sha->h[3];
|
||||
HOST_l2c(ll, md);
|
||||
ll = sha->h[4];
|
||||
HOST_l2c(ll, md);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define K_00_19 0x5a827999UL
|
||||
#define K_20_39 0x6ed9eba1UL
|
||||
#define K_40_59 0x8f1bbcdcUL
|
||||
|
@ -138,48 +138,9 @@ int SHA224_Final(uint8_t *md, SHA256_CTX *ctx) {
|
||||
#define HASH_CTX SHA256_CTX
|
||||
#define HASH_CBLOCK 64
|
||||
|
||||
/* Note that FIPS180-2 discusses "Truncation of the Hash Function Output."
|
||||
* default: case below covers for it. It's not clear however if it's permitted
|
||||
* to truncate to amount of bytes not divisible by 4. I bet not, but if it is,
|
||||
* then default: case shall be extended. For reference. Idea behind separate
|
||||
* cases for pre-defined lenghts is to let the compiler decide if it's
|
||||
* appropriate to unroll small loops.
|
||||
*
|
||||
* TODO(davidben): The small |md_len| case is one of the few places a low-level
|
||||
* hash 'final' function can fail. This should never happen. */
|
||||
#define HASH_MAKE_STRING(c, s) \
|
||||
do { \
|
||||
uint32_t ll; \
|
||||
unsigned int nn; \
|
||||
switch ((c)->md_len) { \
|
||||
case SHA224_DIGEST_LENGTH: \
|
||||
for (nn = 0; nn < SHA224_DIGEST_LENGTH / 4; nn++) { \
|
||||
ll = (c)->h[nn]; \
|
||||
HOST_l2c(ll, (s)); \
|
||||
} \
|
||||
break; \
|
||||
case SHA256_DIGEST_LENGTH: \
|
||||
for (nn = 0; nn < SHA256_DIGEST_LENGTH / 4; nn++) { \
|
||||
ll = (c)->h[nn]; \
|
||||
HOST_l2c(ll, (s)); \
|
||||
} \
|
||||
break; \
|
||||
default: \
|
||||
if ((c)->md_len > SHA256_DIGEST_LENGTH) { \
|
||||
return 0; \
|
||||
} \
|
||||
for (nn = 0; nn < (c)->md_len / 4; nn++) { \
|
||||
ll = (c)->h[nn]; \
|
||||
HOST_l2c(ll, (s)); \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define HASH_UPDATE SHA256_Update
|
||||
#define HASH_TRANSFORM SHA256_Transform
|
||||
#define HASH_FINAL SHA256_Final
|
||||
#define HASH_FINISH sha256_finish
|
||||
#define HASH_BLOCK_DATA_ORDER sha256_block_data_order
|
||||
#ifndef SHA256_ASM
|
||||
static
|
||||
@ -188,6 +149,40 @@ void sha256_block_data_order(uint32_t *state, const uint8_t *in, size_t num);
|
||||
|
||||
#include "../digest/md32_common.h"
|
||||
|
||||
int SHA256_Final(uint8_t *md, SHA256_CTX *sha) {
|
||||
sha256_finish(sha);
|
||||
|
||||
/* TODO(davidben): Replace this with different versions of SHA256_Final
|
||||
* and SHA224_Final. */
|
||||
uint32_t ll;
|
||||
unsigned int nn;
|
||||
switch (sha->md_len) {
|
||||
case SHA224_DIGEST_LENGTH:
|
||||
for (nn = 0; nn < SHA224_DIGEST_LENGTH / 4; nn++) {
|
||||
ll = sha->h[nn];
|
||||
HOST_l2c(ll, md);
|
||||
}
|
||||
break;
|
||||
case SHA256_DIGEST_LENGTH:
|
||||
for (nn = 0; nn < SHA256_DIGEST_LENGTH / 4; nn++) {
|
||||
ll = sha->h[nn];
|
||||
HOST_l2c(ll, md);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (sha->md_len > SHA256_DIGEST_LENGTH) {
|
||||
return 0;
|
||||
}
|
||||
for (nn = 0; nn < sha->md_len / 4; nn++) {
|
||||
ll = sha->h[nn];
|
||||
HOST_l2c(ll, md);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef SHA256_ASM
|
||||
static const uint32_t K256[64] = {
|
||||
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
|
||||
|
@ -74,21 +74,7 @@ static void ripemd160_block_data_order(uint32_t h[5], const uint8_t *data,
|
||||
#define HASH_CBLOCK RIPEMD160_CBLOCK
|
||||
#define HASH_UPDATE RIPEMD160_Update
|
||||
#define HASH_TRANSFORM RIPEMD160_Transform
|
||||
#define HASH_FINAL RIPEMD160_Final
|
||||
#define HASH_MAKE_STRING(c, s) \
|
||||
do { \
|
||||
unsigned long ll; \
|
||||
ll = (c)->h[0]; \
|
||||
(void)HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[1]; \
|
||||
(void)HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[2]; \
|
||||
(void)HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[3]; \
|
||||
(void)HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[4]; \
|
||||
(void)HOST_l2c(ll, (s)); \
|
||||
} while (0)
|
||||
#define HASH_FINISH ripemd160_finish
|
||||
#define HASH_BLOCK_DATA_ORDER ripemd160_block_data_order
|
||||
|
||||
#include "../../crypto/digest/md32_common.h"
|
||||
|
@ -71,6 +71,24 @@ int RIPEMD160_Init(RIPEMD160_CTX *ctx) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int RIPEMD160_Final(uint8_t *md, RIPEMD160_CTX *ctx) {
|
||||
ripemd160_finish(ctx);
|
||||
|
||||
unsigned long ll;
|
||||
ll = ctx->h[0];
|
||||
(void)HOST_l2c(ll, md);
|
||||
ll = ctx->h[1];
|
||||
(void)HOST_l2c(ll, md);
|
||||
ll = ctx->h[2];
|
||||
(void)HOST_l2c(ll, md);
|
||||
ll = ctx->h[3];
|
||||
(void)HOST_l2c(ll, md);
|
||||
ll = ctx->h[4];
|
||||
(void)HOST_l2c(ll, md);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void ripemd160_block_data_order(uint32_t h[5], const uint8_t *data,
|
||||
size_t num) {
|
||||
uint32_t A, B, C, D, E;
|
||||
|
Loading…
Reference in New Issue
Block a user