From: Nicolas Pitre - avoids shifting the count left and right needlessly (can be done once at the end) - avoids always memcpy()ing the first block each time sha1_update() is called (can be skipped if we don't have any partial block pending) - logically groups code in sha1_final() - avoids successively shifting a long long to append the final length (which generated awful assembly on some 32 bits archs) - plus a few other minor changes to prettify the code and/or the assembly. Signed-off-by: Nicolas Pitre Cc: Herbert Xu Signed-off-by: Andrew Morton --- crypto/sha1.c | 63 ++++++++++++++++++++++++++++++---------------------------- 1 files changed, 33 insertions(+), 30 deletions(-) diff -puN crypto/sha1.c~clean-crypto-sha1c-up-a-bit crypto/sha1.c --- devel/crypto/sha1.c~clean-crypto-sha1c-up-a-bit 2005-10-23 13:03:26.000000000 -0700 +++ devel-akpm/crypto/sha1.c 2005-10-23 13:03:26.000000000 -0700 @@ -48,23 +48,26 @@ static void sha1_init(void *ctx) static void sha1_update(void *ctx, const u8 *data, unsigned int len) { struct sha1_ctx *sctx = ctx; - unsigned int i, j; + unsigned int partial, done; u32 temp[SHA_WORKSPACE_WORDS]; - j = (sctx->count >> 3) & 0x3f; - sctx->count += len << 3; - - if ((j + len) > 63) { - memcpy(&sctx->buffer[j], data, (i = 64-j)); - sha_transform(sctx->state, sctx->buffer, temp); - for ( ; i + 63 < len; i += 64) { - sha_transform(sctx->state, &data[i], temp); + partial = sctx->count & 0x3f; + sctx->count += len; + done = 0; + + if ((partial + len) > 63) { + if (partial) { + done = 64 - partial; + memcpy(sctx->buffer + partial, data, done); + sha_transform(sctx->state, sctx->buffer, temp); + partial = 0; } - j = 0; + for ( ; done + 63 < len; done += 64) + sha_transform(sctx->state, data + done, temp); } - else i = 0; + if (len - done) + memcpy(sctx->buffer + partial, data + done, len - done); memset(temp, 0, sizeof(temp)); - memcpy(&sctx->buffer[j], &data[i], len - i); } @@ -72,36 +75,36 @@ static void sha1_update(void *ctx, const static void sha1_final(void* ctx, u8 *out) { struct sha1_ctx *sctx = ctx; - u32 i, j, index, padlen; - u64 t; - u8 bits[8] = { 0, }; + u32 i, t, index, padlen; + u8 bits[8]; static const u8 padding[64] = { 0x80, }; - t = sctx->count; + /* Pad out to 56 mod 64 */ + index = sctx->count & 0x3f; + padlen = ((index < 56) ? 56 : (64 + 56)) - index; + sha1_update(sctx, padding, padlen); + + /* Append length */ + t = sctx->count << 3; bits[7] = 0xff & t; t>>=8; bits[6] = 0xff & t; t>>=8; bits[5] = 0xff & t; t>>=8; - bits[4] = 0xff & t; t>>=8; + bits[4] = 0xff & t; + t = sctx->count >> (32 - 3); bits[3] = 0xff & t; t>>=8; bits[2] = 0xff & t; t>>=8; bits[1] = 0xff & t; t>>=8; bits[0] = 0xff & t; - - /* Pad out to 56 mod 64 */ - index = (sctx->count >> 3) & 0x3f; - padlen = (index < 56) ? (56 - index) : ((64+56) - index); - sha1_update(sctx, padding, padlen); - - /* Append length */ sha1_update(sctx, bits, sizeof bits); /* Store state in digest */ - for (i = j = 0; i < 5; i++, j += 4) { - u32 t2 = sctx->state[i]; - out[j+3] = t2 & 0xff; t2>>=8; - out[j+2] = t2 & 0xff; t2>>=8; - out[j+1] = t2 & 0xff; t2>>=8; - out[j ] = t2 & 0xff; + for (i = 0; i < 5; i++) { + t = sctx->state[i]; + out[3] = t & 0xff; t>>=8; + out[2] = t & 0xff; t>>=8; + out[1] = t & 0xff; t>>=8; + out[0] = t & 0xff; + out += 4; } /* Wipe context */ _