aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-10-16 20:46:35 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2010-10-16 20:46:35 +0200
commitbcccad35318004922cc04487e1df4eade4545966 (patch)
treed65ad2822b4baf2b4c8e0c3ac02cf74879b03573
parentc0683acce88efc1fe15d9a4332428b5a9fdc6c2e (diff)
downloadbusybox-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.h2
-rw-r--r--include/platform.h4
-rw-r--r--libbb/md5.c51
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. */
52static void md5_hash_block(md5_ctx_t *ctx, const void *buffer) 52static 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)
398void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf) 397void 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.