diff --git a/include/sha.h b/include/sha.h index 35677517c509698a773f5cb65dbc6787b03e26e7..9f15ea06705dc842a4f204c6e7e362dbb0f7b062 100644 --- a/include/sha.h +++ b/include/sha.h @@ -16,7 +16,7 @@ struct sha_ctx { UINT32 digest[SHA_DIGESTLEN]; /* Message digest */ UINT32 count_l, count_h; /* 64-bit block count */ UINT8 block[SHA_DATASIZE]; /* SHA data buffer */ - int index; /* index into buffer */ + int index; /* index into buffer */ }; void sha_init(struct sha_ctx *ctx); @@ -24,3 +24,7 @@ void sha_update(struct sha_ctx *ctx, const UINT8 *buffer, UINT32 len); void sha_final(struct sha_ctx *ctx); void sha_digest(struct sha_ctx *ctx, UINT8 *s); void sha_copy(struct sha_ctx *dest, struct sha_ctx *src); + +/* The core compression function, mapping 5 + 16 32-bit words to 5 + * words. Destroys the data in the process. */ +void sha_transform(UINT32 *state, UINT32 *data); diff --git a/sha.c b/sha.c index da4177a5b9d67486f6a13897c90f4c98e84b5335..f7b19338dbe420afc6f3aec4974c9e3327c2333d 100644 --- a/sha.c +++ b/sha.c @@ -37,6 +37,26 @@ effort (for example the reengineering of a great many Capstone chips). #include <string.h> +/* Also defined in lsh_types.h */ +#ifndef READ_UINT32 +/* Reads a 32-bit integer, in network byte order */ +#define READ_UINT32(p) \ +((((UINT32) (p)[0]) << 24) \ + | (((UINT32) (p)[1]) << 16) \ + | (((UINT32) (p)[2]) << 8) \ + | ((UINT32) (p)[3])) +#endif + +#ifndef WRITE_UINT32 +#define WRITE_UINT32(p, i) \ +do { \ + (p)[0] = ((i) >> 24) & 0xff; \ + (p)[1] = ((i) >> 16) & 0xff; \ + (p)[2] = ((i) >> 8) & 0xff; \ + (p)[3] = (i) & 0xff; \ +} while(0) +#endif + void sha_copy(struct sha_ctx *dest, struct sha_ctx *src) { int i; @@ -141,16 +161,16 @@ void sha_init(struct sha_ctx *ctx) Note that this function destroys the data area */ -static void sha_transform(struct sha_ctx *ctx, UINT32 *data ) +void sha_transform(UINT32 *state, UINT32 *data) { UINT32 A, B, C, D, E; /* Local vars */ /* Set up first buffer and local data buffer */ - A = ctx->digest[0]; - B = ctx->digest[1]; - C = ctx->digest[2]; - D = ctx->digest[3]; - E = ctx->digest[4]; + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + E = state[4]; /* Heavy mangling, in 4 sub-rounds of 20 interations each. */ subRound( A, B, C, D, E, f1, K1, data[ 0] ); @@ -238,50 +258,28 @@ static void sha_transform(struct sha_ctx *ctx, UINT32 *data ) subRound( B, C, D, E, A, f4, K4, expand( data, 79 ) ); /* Build message digest */ - ctx->digest[0] += A; - ctx->digest[1] += B; - ctx->digest[2] += C; - ctx->digest[3] += D; - ctx->digest[4] += E; + state[0] += A; + state[1] += B; + state[2] += C; + state[3] += D; + state[4] += E; } -#if 1 - -#ifndef EXTRACT_UCHAR -#define EXTRACT_UCHAR(p) (*(unsigned char *)(p)) -#endif - -#define STRING2INT(s) ((((((EXTRACT_UCHAR(s) << 8) \ - | EXTRACT_UCHAR(s+1)) << 8) \ - | EXTRACT_UCHAR(s+2)) << 8) \ - | EXTRACT_UCHAR(s+3)) -#else -UINT32 STRING2INT(UINT8 *s) -{ - UINT32 r; - int i; - - for (i = 0, r = 0; i < 4; i++, s++) - r = (r << 8) | *s; - return r; -} -#endif - static void sha_block(struct sha_ctx *ctx, const UINT8 *block) { UINT32 data[SHA_DATALEN]; int i; - + /* Update block count */ if (!++ctx->count_l) ++ctx->count_h; /* Endian independent conversion */ for (i = 0; i<SHA_DATALEN; i++, block += 4) - data[i] = STRING2INT(block); + data[i] = READ_UINT32(block); - sha_transform(ctx, data); + sha_transform(ctx->digest, data); } void @@ -338,14 +336,14 @@ sha_final(struct sha_ctx *ctx) /* i is now a multiple of the word size 4 */ words = i >> 2; for (i = 0; i < words; i++) - data[i] = STRING2INT(ctx->block + 4*i); + data[i] = READ_UINT32(ctx->block + 4*i); if (words > (SHA_DATALEN-2)) { /* No room for length in this block. Process it and * pad with another one */ for (i = words ; i < SHA_DATALEN; i++) data[i] = 0; - sha_transform(ctx, data); + sha_transform(ctx->digest, data); for (i = 0; i < (SHA_DATALEN-2); i++) data[i] = 0; } @@ -355,7 +353,7 @@ sha_final(struct sha_ctx *ctx) /* Theres 512 = 2^9 bits in one block */ data[SHA_DATALEN-2] = (ctx->count_h << 9) | (ctx->count_l >> 23); data[SHA_DATALEN-1] = (ctx->count_l << 9) | (ctx->index << 3); - sha_transform(ctx, data); + sha_transform(ctx->digest, data); } void @@ -363,11 +361,6 @@ sha_digest(struct sha_ctx *ctx, UINT8 *s) { int i; - for (i = 0; i < SHA_DIGESTLEN; i++) - { - *s++ = ctx->digest[i] >> 24; - *s++ = 0xff & (ctx->digest[i] >> 16); - *s++ = 0xff & (ctx->digest[i] >> 8); - *s++ = 0xff & ctx->digest[i]; - } + for (i = 0; i < SHA_DIGESTLEN; i++, s+= 4) + WRITE_UINT32(s, ctx->digest[i]); }