diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-10-16 20:46:35 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-10-16 20:46:35 +0200 |
| commit | bcccad35318004922cc04487e1df4eade4545966 (patch) | |
| tree | d65ad2822b4baf2b4c8e0c3ac02cf74879b03573 | |
| parent | c0683acce88efc1fe15d9a4332428b5a9fdc6c2e (diff) | |
| download | busybox-w32-bcccad35318004922cc04487e1df4eade4545966.tar.gz busybox-w32-bcccad35318004922cc04487e1df4eade4545966.tar.bz2 busybox-w32-bcccad35318004922cc04487e1df4eade4545966.zip | |
md5: code shrink; and use 64-byte temp buf, not 128-byte.
function old new delta
md5_hash 111 108 -3
md5_end 129 125 -4
md5_hash_block 459 454 -5
filter_rename_config 250 244 -6
md5_crypt 587 578 -9
popmaildir_main 828 816 -12
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/6 up/down: 0/-39) Total: -39 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
| -rw-r--r-- | include/libbb.h | 2 | ||||
| -rw-r--r-- | include/platform.h | 4 | ||||
| -rw-r--r-- | libbb/md5.c | 51 |
3 files changed, 30 insertions, 27 deletions
diff --git a/include/libbb.h b/include/libbb.h index 1031cad8b..f406fc6f1 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
| @@ -1540,7 +1540,7 @@ typedef struct md5_ctx_t { | |||
| 1540 | uint32_t C; | 1540 | uint32_t C; |
| 1541 | uint32_t D; | 1541 | uint32_t D; |
| 1542 | uint64_t total; | 1542 | uint64_t total; |
| 1543 | char buffer[128]; | 1543 | char buffer[64]; |
| 1544 | } md5_ctx_t; | 1544 | } md5_ctx_t; |
| 1545 | #else | 1545 | #else |
| 1546 | /* libbb/md5prime.c uses a bit different one: */ | 1546 | /* libbb/md5prime.c uses a bit different one: */ |
diff --git a/include/platform.h b/include/platform.h index 85efa53cd..c255a17ce 100644 --- a/include/platform.h +++ b/include/platform.h | |||
| @@ -197,6 +197,8 @@ | |||
| 197 | # define SWAP_LE16(x) bswap_16(x) | 197 | # define SWAP_LE16(x) bswap_16(x) |
| 198 | # define SWAP_LE32(x) bswap_32(x) | 198 | # define SWAP_LE32(x) bswap_32(x) |
| 199 | # define SWAP_LE64(x) bswap_64(x) | 199 | # define SWAP_LE64(x) bswap_64(x) |
| 200 | # define IF_BIG_ENDIAN(...) __VA_ARGS__ | ||
| 201 | # define IF_LITTLE_ENDIAN(...) | ||
| 200 | #else | 202 | #else |
| 201 | # define SWAP_BE16(x) bswap_16(x) | 203 | # define SWAP_BE16(x) bswap_16(x) |
| 202 | # define SWAP_BE32(x) bswap_32(x) | 204 | # define SWAP_BE32(x) bswap_32(x) |
| @@ -204,6 +206,8 @@ | |||
| 204 | # define SWAP_LE16(x) (x) | 206 | # define SWAP_LE16(x) (x) |
| 205 | # define SWAP_LE32(x) (x) | 207 | # define SWAP_LE32(x) (x) |
| 206 | # define SWAP_LE64(x) (x) | 208 | # define SWAP_LE64(x) (x) |
| 209 | # define IF_BIG_ENDIAN(...) | ||
| 210 | # define IF_LITTLE_ENDIAN(...) __VA_ARGS__ | ||
| 207 | #endif | 211 | #endif |
| 208 | 212 | ||
| 209 | /* ---- Unaligned access ------------------------------------ */ | 213 | /* ---- Unaligned access ------------------------------------ */ |
diff --git a/libbb/md5.c b/libbb/md5.c index 47f5fc6f8..3c24bc60b 100644 --- a/libbb/md5.c +++ b/libbb/md5.c | |||
| @@ -49,11 +49,8 @@ void FAST_FUNC md5_begin(md5_ctx_t *ctx) | |||
| 49 | #define rotl32(w, s) (((w) << (s)) | ((w) >> (32 - (s)))) | 49 | #define rotl32(w, s) (((w) << (s)) | ((w) >> (32 - (s)))) |
| 50 | 50 | ||
| 51 | /* Hash a single block, 64 bytes long and 4-byte aligned. */ | 51 | /* Hash a single block, 64 bytes long and 4-byte aligned. */ |
| 52 | static void md5_hash_block(md5_ctx_t *ctx, const void *buffer) | 52 | static void md5_hash_block(md5_ctx_t *ctx) |
| 53 | { | 53 | { |
| 54 | uint32_t correct_words[16]; | ||
| 55 | const uint32_t *words = buffer; | ||
| 56 | |||
| 57 | #if MD5_SIZE_VS_SPEED > 0 | 54 | #if MD5_SIZE_VS_SPEED > 0 |
| 58 | /* Before we start, one word to the strange constants. | 55 | /* Before we start, one word to the strange constants. |
| 59 | They are defined in RFC 1321 as | 56 | They are defined in RFC 1321 as |
| @@ -98,12 +95,13 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer) | |||
| 98 | }; | 95 | }; |
| 99 | # endif | 96 | # endif |
| 100 | #endif | 97 | #endif |
| 98 | const uint32_t *words = (const void*) ctx->buffer; | ||
| 99 | |||
| 101 | uint32_t A = ctx->A; | 100 | uint32_t A = ctx->A; |
| 102 | uint32_t B = ctx->B; | 101 | uint32_t B = ctx->B; |
| 103 | uint32_t C = ctx->C; | 102 | uint32_t C = ctx->C; |
| 104 | uint32_t D = ctx->D; | 103 | uint32_t D = ctx->D; |
| 105 | 104 | ||
| 106 | uint32_t *cwp = correct_words; | ||
| 107 | uint32_t A_save = A; | 105 | uint32_t A_save = A; |
| 108 | uint32_t B_save = B; | 106 | uint32_t B_save = B; |
| 109 | uint32_t C_save = C; | 107 | uint32_t C_save = C; |
| @@ -116,9 +114,10 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer) | |||
| 116 | int i; | 114 | int i; |
| 117 | uint32_t temp; | 115 | uint32_t temp; |
| 118 | 116 | ||
| 117 | # if BB_BIG_ENDIAN | ||
| 119 | for (i = 0; i < 16; i++) | 118 | for (i = 0; i < 16; i++) |
| 120 | cwp[i] = SWAP_LE32(words[i]); | 119 | words[i] = SWAP_LE32(words[i]); |
| 121 | words += 16; | 120 | # endif |
| 122 | 121 | ||
| 123 | # if MD5_SIZE_VS_SPEED > 2 | 122 | # if MD5_SIZE_VS_SPEED > 2 |
| 124 | pc = C_array; | 123 | pc = C_array; |
| @@ -142,7 +141,7 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer) | |||
| 142 | case 3: | 141 | case 3: |
| 143 | temp += FI(B, C, D); | 142 | temp += FI(B, C, D); |
| 144 | } | 143 | } |
| 145 | temp += cwp[(int) (*pp++)] + *pc++; | 144 | temp += words[(int) (*pp++)] + *pc++; |
| 146 | temp = rotl32(temp, ps[i & 3]); | 145 | temp = rotl32(temp, ps[i & 3]); |
| 147 | temp += B; | 146 | temp += B; |
| 148 | A = D; | 147 | A = D; |
| @@ -156,7 +155,7 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer) | |||
| 156 | ps = S_array; | 155 | ps = S_array; |
| 157 | 156 | ||
| 158 | for (i = 0; i < 16; i++) { | 157 | for (i = 0; i < 16; i++) { |
| 159 | temp = A + FF(B, C, D) + cwp[(int) (*pp++)] + *pc++; | 158 | temp = A + FF(B, C, D) + words[(int) (*pp++)] + *pc++; |
| 160 | temp = rotl32(temp, ps[i & 3]); | 159 | temp = rotl32(temp, ps[i & 3]); |
| 161 | temp += B; | 160 | temp += B; |
| 162 | A = D; | 161 | A = D; |
| @@ -166,7 +165,7 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer) | |||
| 166 | } | 165 | } |
| 167 | ps += 4; | 166 | ps += 4; |
| 168 | for (i = 0; i < 16; i++) { | 167 | for (i = 0; i < 16; i++) { |
| 169 | temp = A + FG(B, C, D) + cwp[(int) (*pp++)] + *pc++; | 168 | temp = A + FG(B, C, D) + words[(int) (*pp++)] + *pc++; |
| 170 | temp = rotl32(temp, ps[i & 3]); | 169 | temp = rotl32(temp, ps[i & 3]); |
| 171 | temp += B; | 170 | temp += B; |
| 172 | A = D; | 171 | A = D; |
| @@ -176,7 +175,7 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer) | |||
| 176 | } | 175 | } |
| 177 | ps += 4; | 176 | ps += 4; |
| 178 | for (i = 0; i < 16; i++) { | 177 | for (i = 0; i < 16; i++) { |
| 179 | temp = A + FH(B, C, D) + cwp[(int) (*pp++)] + *pc++; | 178 | temp = A + FH(B, C, D) + words[(int) (*pp++)] + *pc++; |
| 180 | temp = rotl32(temp, ps[i & 3]); | 179 | temp = rotl32(temp, ps[i & 3]); |
| 181 | temp += B; | 180 | temp += B; |
| 182 | A = D; | 181 | A = D; |
| @@ -186,7 +185,7 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer) | |||
| 186 | } | 185 | } |
| 187 | ps += 4; | 186 | ps += 4; |
| 188 | for (i = 0; i < 16; i++) { | 187 | for (i = 0; i < 16; i++) { |
| 189 | temp = A + FI(B, C, D) + cwp[(int) (*pp++)] + *pc++; | 188 | temp = A + FI(B, C, D) + words[(int) (*pp++)] + *pc++; |
| 190 | temp = rotl32(temp, ps[i & 3]); | 189 | temp = rotl32(temp, ps[i & 3]); |
| 191 | temp += B; | 190 | temp += B; |
| 192 | A = D; | 191 | A = D; |
| @@ -203,12 +202,12 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer) | |||
| 203 | unit is a 32-bit word and it is determined to work on words in | 202 | unit is a 32-bit word and it is determined to work on words in |
| 204 | little endian byte order we perhaps have to change the byte order | 203 | little endian byte order we perhaps have to change the byte order |
| 205 | before the computation. To reduce the work for the next steps | 204 | before the computation. To reduce the work for the next steps |
| 206 | we store the swapped words in the array CORRECT_WORDS. */ | 205 | we save swapped words in WORDS array. */ |
| 207 | # undef OP | 206 | # undef OP |
| 208 | # define OP(a, b, c, d, s, T) \ | 207 | # define OP(a, b, c, d, s, T) \ |
| 209 | do { \ | 208 | do { \ |
| 210 | a += FF(b, c, d) + (*cwp++ = SWAP_LE32(*words)) + T; \ | 209 | a += FF(b, c, d) + (*words IF_BIG_ENDIAN(= SWAP_LE32(*words))) + T; \ |
| 211 | ++words; \ | 210 | words++; \ |
| 212 | a = rotl32(a, s); \ | 211 | a = rotl32(a, s); \ |
| 213 | a += b; \ | 212 | a += b; \ |
| 214 | } while (0) | 213 | } while (0) |
| @@ -248,7 +247,7 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer) | |||
| 248 | # endif | 247 | # endif |
| 249 | 248 | ||
| 250 | /* For the second to fourth round we have the possibly swapped words | 249 | /* For the second to fourth round we have the possibly swapped words |
| 251 | in CORRECT_WORDS. Redefine the macro to take an additional first | 250 | in WORDS. Redefine the macro to take an additional first |
| 252 | argument specifying the function to use. */ | 251 | argument specifying the function to use. */ |
| 253 | # undef OP | 252 | # undef OP |
| 254 | # define OP(f, a, b, c, d, k, s, T) \ | 253 | # define OP(f, a, b, c, d, k, s, T) \ |
| @@ -385,7 +384,7 @@ void FAST_FUNC md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) | |||
| 385 | if (buflen != 0) | 384 | if (buflen != 0) |
| 386 | break; | 385 | break; |
| 387 | /* Buffer is filled up, process it. */ | 386 | /* Buffer is filled up, process it. */ |
| 388 | md5_hash_block(ctx, ctx->buffer); | 387 | md5_hash_block(ctx); |
| 389 | /*buflen = 0; - already is */ | 388 | /*buflen = 0; - already is */ |
| 390 | } | 389 | } |
| 391 | } | 390 | } |
| @@ -398,29 +397,29 @@ void FAST_FUNC md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) | |||
| 398 | void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf) | 397 | void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf) |
| 399 | { | 398 | { |
| 400 | uint64_t total; | 399 | uint64_t total; |
| 401 | char *buf = ctx->buffer; | ||
| 402 | unsigned i; | 400 | unsigned i; |
| 403 | unsigned buflen = BUFLEN(ctx); | 401 | unsigned buflen = BUFLEN(ctx); |
| 404 | 402 | ||
| 405 | /* Pad data to block size. */ | 403 | /* Pad data to block size. */ |
| 406 | buf[buflen++] = 0x80; | 404 | ctx->buffer[buflen++] = 0x80; |
| 407 | memset(buf + buflen, 0, 128 - buflen); | 405 | memset(ctx->buffer + buflen, 0, 64 - buflen); |
| 406 | |||
| 407 | if (buflen > 56) { | ||
| 408 | md5_hash_block(ctx); | ||
| 409 | memset(ctx->buffer, 0, 64); | ||
| 410 | } | ||
| 408 | 411 | ||
| 409 | /* Put the 64-bit file length, expressed in *bits*, | 412 | /* Put the 64-bit file length, expressed in *bits*, |
| 410 | * at the end of the buffer. | 413 | * at the end of the buffer. |
| 411 | */ | 414 | */ |
| 412 | /* clever way to do "if (buflen > 56) buf += 64": */ | ||
| 413 | buf += ((buflen + 7) & 64); | ||
| 414 | total = ctx->total << 3; | 415 | total = ctx->total << 3; |
| 415 | for (i = 0; i < 8; i++) { | 416 | for (i = 0; i < 8; i++) { |
| 416 | buf[56 + i] = total; | 417 | ctx->buffer[56 + i] = total; |
| 417 | total >>= 8; | 418 | total >>= 8; |
| 418 | } | 419 | } |
| 419 | 420 | ||
| 420 | /* Process last bytes. */ | 421 | /* Process last bytes. */ |
| 421 | if (buf != ctx->buffer) | 422 | md5_hash_block(ctx); |
| 422 | md5_hash_block(ctx, ctx->buffer); | ||
| 423 | md5_hash_block(ctx, buf); | ||
| 424 | 423 | ||
| 425 | /* The MD5 result is in little endian byte order. | 424 | /* The MD5 result is in little endian byte order. |
| 426 | * We (ab)use the fact that A-D are consecutive in memory. | 425 | * We (ab)use the fact that A-D are consecutive in memory. |
