hash_md5_sha: use common finalization routine for MD5 and sha1/256. -15 bytes
No binary (build failed)
—
(log yok)
| @@ -1515,35 +1515,14 @@ enum { | |
| }; | |
| void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags); | |
| - | typedef struct sha1_ctx_t { |
| - | uint32_t hash[8]; /* 5, +3 elements for sha256 */ |
| - | uint64_t total64; /* must be directly after hash[] */ |
| - | uint8_t wbuffer[64]; /* NB: always correctly aligned for uint64_t */ |
| - | void (*process_block)(struct sha1_ctx_t*) FAST_FUNC; |
| - | } sha1_ctx_t; |
| - | void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC; |
| - | void sha1_hash(sha1_ctx_t *ctx, const void *data, size_t length) FAST_FUNC; |
| - | void sha1_end(sha1_ctx_t *ctx, void *resbuf) FAST_FUNC; |
| - | typedef struct sha1_ctx_t sha256_ctx_t; |
| - | void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC; |
| - | #define sha256_hash sha1_hash |
| - | #define sha256_end sha1_end |
| - | typedef struct sha512_ctx_t { |
| - | uint64_t hash[8]; |
| - | uint64_t total64[2]; /* must be directly after hash[] */ |
| - | uint8_t wbuffer[128]; /* NB: always correctly aligned for uint64_t */ |
| - | } sha512_ctx_t; |
| - | void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; |
| - | void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; |
| - | void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; |
| #if 1 | |
| typedef struct md5_ctx_t { | |
| + | char wbuffer[64]; /* NB: always correctly aligned for uint64_t */ |
| + | uint64_t total64; |
| uint32_t A; | |
| uint32_t B; | |
| uint32_t C; | |
| uint32_t D; | |
| - | uint64_t total64; |
| - | char wbuffer[64]; /* NB: always correctly aligned for uint64_t */ |
| } md5_ctx_t; | |
| #else | |
| /* libbb/md5prime.c uses a bit different one: */ | |
| @@ -1556,6 +1535,27 @@ typedef struct md5_ctx_t { | |
| void md5_begin(md5_ctx_t *ctx) FAST_FUNC; | |
| void md5_hash(md5_ctx_t *ctx, const void *data, size_t length) FAST_FUNC; | |
| void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC; | |
| + | typedef struct sha1_ctx_t { |
| + | uint8_t wbuffer[64]; /* NB: always correctly aligned for uint64_t */ |
| + | uint64_t total64; /* must be directly before hash[] */ |
| + | uint32_t hash[8]; /* 5, +3 elements for sha256 */ |
| + | void (*process_block)(struct sha1_ctx_t*) FAST_FUNC; |
| + | } sha1_ctx_t; |
| + | void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC; |
| + | void sha1_hash(sha1_ctx_t *ctx, const void *data, size_t length) FAST_FUNC; |
| + | void sha1_end(sha1_ctx_t *ctx, void *resbuf) FAST_FUNC; |
| + | typedef struct sha1_ctx_t sha256_ctx_t; |
| + | void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC; |
| + | #define sha256_hash sha1_hash |
| + | #define sha256_end sha1_end |
| + | typedef struct sha512_ctx_t { |
| + | uint64_t total64[2]; /* must be directly before hash[] */ |
| + | uint64_t hash[8]; |
| + | uint8_t wbuffer[128]; /* NB: always correctly aligned for uint64_t */ |
| + | } sha512_ctx_t; |
| + | void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; |
| + | void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; |
| + | void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; |
| uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC; | |
| @@ -1,31 +1,10 @@ | |
| /* vi: set sw=4 ts=4: */ | |
| /* | |
| - | * Based on shasum from http://www.netsw.org/crypto/hash/ |
| - | * Majorly hacked up to use Dr Brian Gladman's sha1 code |
| + | * Utility routines. |
| * | |
| - | * Copyright (C) 2002 Dr Brian Gladman <[email protected]>, Worcester, UK. |
| - | * Copyright (C) 2003 Glenn L. McGrath |
| - | * Copyright (C) 2003 Erik Andersen |
| + | * Copyright (C) 2010 Denys Vlasenko |
| * | |
| * Licensed under GPLv2 or later, see file LICENSE in this source tree. | |
| - | * |
| - | * --------------------------------------------------------------------------- |
| - | * Issue Date: 10/11/2002 |
| - | * |
| - | * This is a byte oriented version of SHA1 that operates on arrays of bytes |
| - | * stored in memory. It runs at 22 cycles per byte on a Pentium P4 processor |
| - | * |
| - | * --------------------------------------------------------------------------- |
| - | * |
| - | * SHA256 and SHA512 parts are: |
| - | * Released into the Public Domain by Ulrich Drepper <[email protected]>. |
| - | * Shrank by Denys Vlasenko. |
| - | * |
| - | * --------------------------------------------------------------------------- |
| - | * |
| - | * The best way to test random blocksizes is to go to coreutils/md5_sha1_sum.c |
| - | * and replace "4096" with something like "2000 + time(NULL) % 2097", |
| - | * then rebuild and compare "shaNNNsum bigfile" results. |
| */ | |
| #include "libbb.h" | |
| @@ -53,6 +32,70 @@ static ALWAYS_INLINE uint64_t rotr64(uint64_t x, unsigned n) | |
| } | |
| + | typedef struct common64_ctx_t { |
| + | char wbuffer[64]; /* NB: always correctly aligned for uint64_t */ |
| + | uint64_t total64; |
| + | } common64_ctx_t; |
| + | |
| + | typedef void FAST_FUNC process_block64_func(void*); |
| + | |
| + | static void FAST_FUNC common64_end(void *vctx, process_block64_func process_block64, int swap_needed) |
| + | { |
| + | common64_ctx_t *ctx = vctx; |
| + | unsigned bufpos = ctx->total64 & 63; |
| + | /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */ |
| + | ctx->wbuffer[bufpos++] = 0x80; |
| + | |
| + | /* This loop iterates either once or twice, no more, no less */ |
| + | while (1) { |
| + | unsigned remaining = 64 - bufpos; |
| + | memset(ctx->wbuffer + bufpos, 0, remaining); |
| + | /* Do we have enough space for the length count? */ |
| + | if (remaining >= 8) { |
| + | /* Store the 64-bit counter of bits in the buffer */ |
| + | uint64_t t = ctx->total64 << 3; |
| + | if (swap_needed) |
| + | t = bb_bswap_64(t); |
| + | /* wbuffer is suitably aligned for this */ |
| + | *(uint64_t *) (&ctx->wbuffer[64 - 8]) = t; |
| + | } |
| + | process_block64(ctx); |
| + | if (remaining >= 8) |
| + | break; |
| + | bufpos = 0; |
| + | } |
| + | } |
| + | |
| + | |
| + | /* |
| + | * Based on shasum from http://www.netsw.org/crypto/hash/ |
| + | * Majorly hacked up to use Dr Brian Gladman's sha1 code |
| + | * |
| + | * Copyright (C) 2002 Dr Brian Gladman <[email protected]>, Worcester, UK. |
| + | * Copyright (C) 2003 Glenn L. McGrath |
| + | * Copyright (C) 2003 Erik Andersen |
| + | * |
| + | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
| + | * |
| + | * --------------------------------------------------------------------------- |
| + | * Issue Date: 10/11/2002 |
| + | * |
| + | * This is a byte oriented version of SHA1 that operates on arrays of bytes |
| + | * stored in memory. It runs at 22 cycles per byte on a Pentium P4 processor |
| + | * |
| + | * --------------------------------------------------------------------------- |
| + | * |
| + | * SHA256 and SHA512 parts are: |
| + | * Released into the Public Domain by Ulrich Drepper <[email protected]>. |
| + | * Shrank by Denys Vlasenko. |
| + | * |
| + | * --------------------------------------------------------------------------- |
| + | * |
| + | * The best way to test random blocksizes is to go to coreutils/md5_sha1_sum.c |
| + | * and replace "4096" with something like "2000 + time(NULL) % 2097", |
| + | * then rebuild and compare "shaNNNsum bigfile" results. |
| + | */ |
| + | |
| static void FAST_FUNC sha1_process_block64(sha1_ctx_t *ctx) | |
| { | |
| unsigned t; | |
| @@ -308,6 +351,8 @@ void FAST_FUNC sha1_begin(sha1_ctx_t *ctx) | |
| } | |
| static const uint32_t init256[] = { | |
| + | 0, |
| + | 0, |
| 0x6a09e667, | |
| 0xbb67ae85, | |
| 0x3c6ef372, | |
| @@ -316,10 +361,10 @@ static const uint32_t init256[] = { | |
| 0x9b05688c, | |
| 0x1f83d9ab, | |
| 0x5be0cd19, | |
| - | 0, |
| - | 0, |
| }; | |
| static const uint32_t init512_lo[] = { | |
| + | 0, |
| + | 0, |
| 0xf3bcc908, | |
| 0x84caa73b, | |
| 0xfe94f82b, | |
| @@ -328,16 +373,14 @@ static const uint32_t init512_lo[] = { | |
| 0x2b3e6c1f, | |
| 0xfb41bd6b, | |
| 0x137e2179, | |
| - | 0, |
| - | 0, |
| }; | |
| /* Initialize structure containing state of computation. | |
| (FIPS 180-2:5.3.2) */ | |
| void FAST_FUNC sha256_begin(sha256_ctx_t *ctx) | |
| { | |
| - | memcpy(ctx->hash, init256, sizeof(init256)); |
| - | /*ctx->total64 = 0; - done by extending init256 with two 32-bit zeros */ |
| + | memcpy(&ctx->total64, init256, sizeof(init256)); |
| + | /*ctx->total64 = 0; - done by prepending two 32-bit zeros to init256 */ |
| ctx->process_block = sha256_process_block64; | |
| } | |
| @@ -346,9 +389,10 @@ void FAST_FUNC sha256_begin(sha256_ctx_t *ctx) | |
| void FAST_FUNC sha512_begin(sha512_ctx_t *ctx) | |
| { | |
| int i; | |
| - | /* Two extra iterations zero out ctx->total64[] */ |
| - | for (i = 0; i < 8+2; i++) |
| - | ctx->hash[i] = ((uint64_t)(init256[i]) << 32) + init512_lo[i]; |
| + | /* Two extra iterations zero out ctx->total64[2] */ |
| + | uint64_t *tp = ctx->total64; |
| + | for (i = 0; i < 2+8; i++) |
| + | tp[i] = ((uint64_t)(init256[i]) << 32) + init512_lo[i]; |
| /*ctx->total64[0] = ctx->total64[1] = 0; - already done */ | |
| } | |
| @@ -448,37 +492,19 @@ void FAST_FUNC sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) | |
| /* Used also for sha256 */ | |
| void FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf) | |
| { | |
| - | unsigned bufpos = ctx->total64 & 63; |
| + | unsigned hash_size; |
| - | /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */ |
| - | ctx->wbuffer[bufpos++] = 0x80; |
| + | /* SHA stores total in BE, need to swap on LE arches: */ |
| + | common64_end(ctx, (process_block64_func*) ctx->process_block, /*swap_needed:*/ BB_LITTLE_ENDIAN); |
| - | /* This loop iterates either once or twice, no more, no less */ |
| - | while (1) { |
| - | unsigned remaining = 64 - bufpos; |
| - | memset(ctx->wbuffer + bufpos, 0, remaining); |
| - | /* Do we have enough space for the length count? */ |
| - | if (remaining >= 8) { |
| - | /* Store the 64-bit counter of bits in the buffer in BE format */ |
| - | uint64_t t = ctx->total64 << 3; |
| - | t = SWAP_BE64(t); |
| - | /* wbuffer is suitably aligned for this */ |
| - | *(uint64_t *) (&ctx->wbuffer[64 - 8]) = t; |
| - | } |
| - | ctx->process_block(ctx); |
| - | if (remaining >= 8) |
| - | break; |
| - | bufpos = 0; |
| - | } |
| - | |
| - | bufpos = (ctx->process_block == sha1_process_block64) ? 5 : 8; |
| + | hash_size = (ctx->process_block == sha1_process_block64) ? 5 : 8; |
| /* This way we do not impose alignment constraints on resbuf: */ | |
| if (BB_LITTLE_ENDIAN) { | |
| unsigned i; | |
| - | for (i = 0; i < bufpos; ++i) |
| + | for (i = 0; i < hash_size; ++i) |
| ctx->hash[i] = SWAP_BE32(ctx->hash[i]); | |
| } | |
| - | memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * bufpos); |
| + | memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * hash_size); |
| } | |
| void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf) | |
| @@ -566,7 +592,7 @@ void FAST_FUNC md5_begin(md5_ctx_t *ctx) | |
| #define FI(b, c, d) (c ^ (b | ~d)) | |
| /* Hash a single block, 64 bytes long and 4-byte aligned */ | |
| - | static void md5_process_block64(md5_ctx_t *ctx) |
| + | static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) |
| { | |
| #if MD5_SIZE_VS_SPEED > 0 | |
| /* Before we start, one word to the strange constants. | |
| @@ -927,27 +953,8 @@ void FAST_FUNC md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) | |
| */ | |
| void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf) | |
| { | |
| - | unsigned bufpos = ctx->total64 & 63; |
| - | /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */ |
| - | ctx->wbuffer[bufpos++] = 0x80; |
| - | |
| - | /* This loop iterates either once or twice, no more, no less */ |
| - | while (1) { |
| - | unsigned remaining = 64 - bufpos; |
| - | memset(ctx->wbuffer + bufpos, 0, remaining); |
| - | /* Do we have enough space for the length count? */ |
| - | if (remaining >= 8) { |
| - | /* Store the 64-bit counter of bits in the buffer in LE format */ |
| - | uint64_t t = ctx->total64 << 3; |
| - | t = SWAP_LE64(t); |
| - | /* wbuffer is suitably aligned for this */ |
| - | *(uint64_t *) (&ctx->wbuffer[64 - 8]) = t; |
| - | } |
| - | md5_process_block64(ctx); |
| - | if (remaining >= 8) |
| - | break; |
| - | bufpos = 0; |
| - | } |
| + | /* MD5 stores total in LE, need to swap on BE arches: */ |
| + | common64_end(ctx, (process_block64_func*) md5_process_block64, /*swap_needed:*/ BB_BIG_ENDIAN); |
| /* The MD5 result is in little endian byte order. | |
| * We (ab)use the fact that A-D are consecutive in memory. | |