diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-10-19 02:16:12 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-10-19 02:16:12 +0200 |
commit | 302ad1450e104460abd3aae60b7f40d8a88f43df (patch) | |
tree | 0558bb8533889fa16d820e4466d3b72da083b9f6 | |
parent | d982da79deb36185c420f94417b57e7b8a4af04c (diff) | |
download | busybox-w32-302ad1450e104460abd3aae60b7f40d8a88f43df.tar.gz busybox-w32-302ad1450e104460abd3aae60b7f40d8a88f43df.tar.bz2 busybox-w32-302ad1450e104460abd3aae60b7f40d8a88f43df.zip |
libbb/hash_md5_sha: use common ctx and code for md5 and sha1/256
function old new delta
sha256_process_block64 421 433 +12
md5_crypt 578 587 +9
md5_begin 43 50 +7
md5_hash 99 97 -2
sha1_end 85 82 -3
md5_end 36 31 -5
common64_end 93 86 -7
sha1_hash 97 - -97
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | include/libbb.h | 44 | ||||
-rw-r--r-- | libbb/hash_md5_sha.c | 898 |
2 files changed, 430 insertions, 512 deletions
diff --git a/include/libbb.h b/include/libbb.h index 3c8764b5c..01dc33e63 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -1515,44 +1515,28 @@ enum { | |||
1515 | }; | 1515 | }; |
1516 | void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags); | 1516 | void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags); |
1517 | 1517 | ||
1518 | #if 1 | ||
1519 | typedef struct md5_ctx_t { | 1518 | typedef struct md5_ctx_t { |
1520 | char wbuffer[64]; /* NB: always correctly aligned for uint64_t */ | 1519 | uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */ |
1521 | uint64_t total64; | 1520 | void (*process_block)(struct md5_ctx_t*) FAST_FUNC; |
1522 | uint32_t A; | 1521 | uint64_t total64; /* must be directly before hash[] */ |
1523 | uint32_t B; | 1522 | uint32_t hash[8]; /* 4 elements for md5, 5 for sha1, 8 for sha256 */ |
1524 | uint32_t C; | ||
1525 | uint32_t D; | ||
1526 | } md5_ctx_t; | ||
1527 | #else | ||
1528 | /* libbb/md5prime.c uses a bit different one: */ | ||
1529 | typedef struct md5_ctx_t { | ||
1530 | uint32_t state[4]; /* state (ABCD) */ | ||
1531 | uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */ | ||
1532 | unsigned char buffer[64]; /* input buffer */ | ||
1533 | } md5_ctx_t; | 1523 | } md5_ctx_t; |
1534 | #endif | 1524 | typedef struct md5_ctx_t sha1_ctx_t; |
1525 | typedef struct md5_ctx_t sha256_ctx_t; | ||
1526 | typedef struct sha512_ctx_t { | ||
1527 | uint64_t total64[2]; /* must be directly before hash[] */ | ||
1528 | uint64_t hash[8]; | ||
1529 | uint8_t wbuffer[128]; /* always correctly aligned for uint64_t */ | ||
1530 | } sha512_ctx_t; | ||
1535 | void md5_begin(md5_ctx_t *ctx) FAST_FUNC; | 1531 | void md5_begin(md5_ctx_t *ctx) FAST_FUNC; |
1536 | void md5_hash(md5_ctx_t *ctx, const void *data, size_t length) FAST_FUNC; | 1532 | void md5_hash(md5_ctx_t *ctx, const void *data, size_t length) FAST_FUNC; |
1537 | void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC; | 1533 | void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC; |
1538 | typedef struct sha1_ctx_t { | ||
1539 | uint8_t wbuffer[64]; /* NB: always correctly aligned for uint64_t */ | ||
1540 | uint64_t total64; /* must be directly before hash[] */ | ||
1541 | uint32_t hash[8]; /* 5, +3 elements for sha256 */ | ||
1542 | void (*process_block)(struct sha1_ctx_t*) FAST_FUNC; | ||
1543 | } sha1_ctx_t; | ||
1544 | void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC; | 1534 | void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC; |
1545 | void sha1_hash(sha1_ctx_t *ctx, const void *data, size_t length) FAST_FUNC; | 1535 | #define sha1_hash md5_hash |
1546 | void sha1_end(sha1_ctx_t *ctx, void *resbuf) FAST_FUNC; | 1536 | void sha1_end(sha1_ctx_t *ctx, void *resbuf) FAST_FUNC; |
1547 | typedef struct sha1_ctx_t sha256_ctx_t; | ||
1548 | void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC; | 1537 | void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC; |
1549 | #define sha256_hash sha1_hash | 1538 | #define sha256_hash md5_hash |
1550 | #define sha256_end sha1_end | 1539 | #define sha256_end sha1_end |
1551 | typedef struct sha512_ctx_t { | ||
1552 | uint64_t total64[2]; /* must be directly before hash[] */ | ||
1553 | uint64_t hash[8]; | ||
1554 | uint8_t wbuffer[128]; /* NB: always correctly aligned for uint64_t */ | ||
1555 | } sha512_ctx_t; | ||
1556 | void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; | 1540 | void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; |
1557 | void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; | 1541 | void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; |
1558 | void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; | 1542 | void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; |
diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c index b07ba55f7..f5f875a64 100644 --- a/libbb/hash_md5_sha.c +++ b/libbb/hash_md5_sha.c | |||
@@ -32,16 +32,38 @@ static ALWAYS_INLINE uint64_t rotr64(uint64_t x, unsigned n) | |||
32 | } | 32 | } |
33 | 33 | ||
34 | 34 | ||
35 | typedef struct common64_ctx_t { | 35 | /* Feed data through a temporary buffer. |
36 | char wbuffer[64]; /* NB: always correctly aligned for uint64_t */ | 36 | * The internal buffer remembers previous data until it has 64 |
37 | uint64_t total64; | 37 | * bytes worth to pass on. |
38 | } common64_ctx_t; | 38 | */ |
39 | static void FAST_FUNC common64_hash(md5_ctx_t *ctx, const void *buffer, size_t len) | ||
40 | { | ||
41 | unsigned bufpos = ctx->total64 & 63; | ||
39 | 42 | ||
40 | typedef void FAST_FUNC process_block64_func(void*); | 43 | ctx->total64 += len; |
44 | |||
45 | while (1) { | ||
46 | unsigned remaining = 64 - bufpos; | ||
47 | if (remaining > len) | ||
48 | remaining = len; | ||
49 | /* Copy data into aligned buffer */ | ||
50 | memcpy(ctx->wbuffer + bufpos, buffer, remaining); | ||
51 | len -= remaining; | ||
52 | buffer = (const char *)buffer + remaining; | ||
53 | bufpos += remaining; | ||
54 | /* clever way to do "if (bufpos != 64) break; ... ; bufpos = 0;" */ | ||
55 | bufpos -= 64; | ||
56 | if (bufpos != 0) | ||
57 | break; | ||
58 | /* Buffer is filled up, process it */ | ||
59 | ctx->process_block(ctx); | ||
60 | /*bufpos = 0; - already is */ | ||
61 | } | ||
62 | } | ||
41 | 63 | ||
42 | static void FAST_FUNC common64_end(void *vctx, process_block64_func process_block64, int swap_needed) | 64 | /* Process the remaining bytes in the buffer */ |
65 | static void FAST_FUNC common64_end(md5_ctx_t *ctx, int swap_needed) | ||
43 | { | 66 | { |
44 | common64_ctx_t *ctx = vctx; | ||
45 | unsigned bufpos = ctx->total64 & 63; | 67 | unsigned bufpos = ctx->total64 & 63; |
46 | /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */ | 68 | /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */ |
47 | ctx->wbuffer[bufpos++] = 0x80; | 69 | ctx->wbuffer[bufpos++] = 0x80; |
@@ -59,7 +81,7 @@ static void FAST_FUNC common64_end(void *vctx, process_block64_func process_bloc | |||
59 | /* wbuffer is suitably aligned for this */ | 81 | /* wbuffer is suitably aligned for this */ |
60 | *(uint64_t *) (&ctx->wbuffer[64 - 8]) = t; | 82 | *(uint64_t *) (&ctx->wbuffer[64 - 8]) = t; |
61 | } | 83 | } |
62 | process_block64(ctx); | 84 | ctx->process_block(ctx); |
63 | if (remaining >= 8) | 85 | if (remaining >= 8) |
64 | break; | 86 | break; |
65 | bufpos = 0; | 87 | bufpos = 0; |
@@ -68,6 +90,391 @@ static void FAST_FUNC common64_end(void *vctx, process_block64_func process_bloc | |||
68 | 90 | ||
69 | 91 | ||
70 | /* | 92 | /* |
93 | * Compute MD5 checksum of strings according to the | ||
94 | * definition of MD5 in RFC 1321 from April 1992. | ||
95 | * | ||
96 | * Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. | ||
97 | * | ||
98 | * Copyright (C) 1995-1999 Free Software Foundation, Inc. | ||
99 | * Copyright (C) 2001 Manuel Novoa III | ||
100 | * Copyright (C) 2003 Glenn L. McGrath | ||
101 | * Copyright (C) 2003 Erik Andersen | ||
102 | * | ||
103 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||
104 | */ | ||
105 | |||
106 | /* 0: fastest, 3: smallest */ | ||
107 | #if CONFIG_MD5_SIZE_VS_SPEED < 0 | ||
108 | # define MD5_SIZE_VS_SPEED 0 | ||
109 | #elif CONFIG_MD5_SIZE_VS_SPEED > 3 | ||
110 | # define MD5_SIZE_VS_SPEED 3 | ||
111 | #else | ||
112 | # define MD5_SIZE_VS_SPEED CONFIG_MD5_SIZE_VS_SPEED | ||
113 | #endif | ||
114 | |||
115 | /* These are the four functions used in the four steps of the MD5 algorithm | ||
116 | * and defined in the RFC 1321. The first function is a little bit optimized | ||
117 | * (as found in Colin Plumbs public domain implementation). | ||
118 | * #define FF(b, c, d) ((b & c) | (~b & d)) | ||
119 | */ | ||
120 | #undef FF | ||
121 | #undef FG | ||
122 | #undef FH | ||
123 | #undef FI | ||
124 | #define FF(b, c, d) (d ^ (b & (c ^ d))) | ||
125 | #define FG(b, c, d) FF(d, b, c) | ||
126 | #define FH(b, c, d) (b ^ c ^ d) | ||
127 | #define FI(b, c, d) (c ^ (b | ~d)) | ||
128 | |||
129 | /* Hash a single block, 64 bytes long and 4-byte aligned */ | ||
130 | static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) | ||
131 | { | ||
132 | #if MD5_SIZE_VS_SPEED > 0 | ||
133 | /* Before we start, one word to the strange constants. | ||
134 | They are defined in RFC 1321 as | ||
135 | T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64 | ||
136 | */ | ||
137 | static const uint32_t C_array[] = { | ||
138 | /* round 1 */ | ||
139 | 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, | ||
140 | 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, | ||
141 | 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, | ||
142 | 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, | ||
143 | /* round 2 */ | ||
144 | 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, | ||
145 | 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, | ||
146 | 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, | ||
147 | 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, | ||
148 | /* round 3 */ | ||
149 | 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, | ||
150 | 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, | ||
151 | 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05, | ||
152 | 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, | ||
153 | /* round 4 */ | ||
154 | 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, | ||
155 | 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, | ||
156 | 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, | ||
157 | 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 | ||
158 | }; | ||
159 | static const char P_array[] ALIGN1 = { | ||
160 | # if MD5_SIZE_VS_SPEED > 1 | ||
161 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */ | ||
162 | # endif | ||
163 | 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */ | ||
164 | 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */ | ||
165 | 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 /* 4 */ | ||
166 | }; | ||
167 | #endif | ||
168 | uint32_t *words = (void*) ctx->wbuffer; | ||
169 | uint32_t A = ctx->hash[0]; | ||
170 | uint32_t B = ctx->hash[1]; | ||
171 | uint32_t C = ctx->hash[2]; | ||
172 | uint32_t D = ctx->hash[3]; | ||
173 | |||
174 | #if MD5_SIZE_VS_SPEED >= 2 /* 2 or 3 */ | ||
175 | |||
176 | static const char S_array[] ALIGN1 = { | ||
177 | 7, 12, 17, 22, | ||
178 | 5, 9, 14, 20, | ||
179 | 4, 11, 16, 23, | ||
180 | 6, 10, 15, 21 | ||
181 | }; | ||
182 | const uint32_t *pc; | ||
183 | const char *pp; | ||
184 | const char *ps; | ||
185 | int i; | ||
186 | uint32_t temp; | ||
187 | |||
188 | # if BB_BIG_ENDIAN | ||
189 | for (i = 0; i < 16; i++) | ||
190 | words[i] = SWAP_LE32(words[i]); | ||
191 | # endif | ||
192 | |||
193 | # if MD5_SIZE_VS_SPEED == 3 | ||
194 | pc = C_array; | ||
195 | pp = P_array; | ||
196 | ps = S_array - 4; | ||
197 | |||
198 | for (i = 0; i < 64; i++) { | ||
199 | if ((i & 0x0f) == 0) | ||
200 | ps += 4; | ||
201 | temp = A; | ||
202 | switch (i >> 4) { | ||
203 | case 0: | ||
204 | temp += FF(B, C, D); | ||
205 | break; | ||
206 | case 1: | ||
207 | temp += FG(B, C, D); | ||
208 | break; | ||
209 | case 2: | ||
210 | temp += FH(B, C, D); | ||
211 | break; | ||
212 | case 3: | ||
213 | temp += FI(B, C, D); | ||
214 | } | ||
215 | temp += words[(int) (*pp++)] + *pc++; | ||
216 | temp = rotl32(temp, ps[i & 3]); | ||
217 | temp += B; | ||
218 | A = D; | ||
219 | D = C; | ||
220 | C = B; | ||
221 | B = temp; | ||
222 | } | ||
223 | # else /* MD5_SIZE_VS_SPEED == 2 */ | ||
224 | pc = C_array; | ||
225 | pp = P_array; | ||
226 | ps = S_array; | ||
227 | |||
228 | for (i = 0; i < 16; i++) { | ||
229 | temp = A + FF(B, C, D) + words[(int) (*pp++)] + *pc++; | ||
230 | temp = rotl32(temp, ps[i & 3]); | ||
231 | temp += B; | ||
232 | A = D; | ||
233 | D = C; | ||
234 | C = B; | ||
235 | B = temp; | ||
236 | } | ||
237 | ps += 4; | ||
238 | for (i = 0; i < 16; i++) { | ||
239 | temp = A + FG(B, C, D) + words[(int) (*pp++)] + *pc++; | ||
240 | temp = rotl32(temp, ps[i & 3]); | ||
241 | temp += B; | ||
242 | A = D; | ||
243 | D = C; | ||
244 | C = B; | ||
245 | B = temp; | ||
246 | } | ||
247 | ps += 4; | ||
248 | for (i = 0; i < 16; i++) { | ||
249 | temp = A + FH(B, C, D) + words[(int) (*pp++)] + *pc++; | ||
250 | temp = rotl32(temp, ps[i & 3]); | ||
251 | temp += B; | ||
252 | A = D; | ||
253 | D = C; | ||
254 | C = B; | ||
255 | B = temp; | ||
256 | } | ||
257 | ps += 4; | ||
258 | for (i = 0; i < 16; i++) { | ||
259 | temp = A + FI(B, C, D) + words[(int) (*pp++)] + *pc++; | ||
260 | temp = rotl32(temp, ps[i & 3]); | ||
261 | temp += B; | ||
262 | A = D; | ||
263 | D = C; | ||
264 | C = B; | ||
265 | B = temp; | ||
266 | } | ||
267 | # endif | ||
268 | /* Add checksum to the starting values */ | ||
269 | ctx->hash[0] += A; | ||
270 | ctx->hash[1] += B; | ||
271 | ctx->hash[2] += C; | ||
272 | ctx->hash[3] += D; | ||
273 | |||
274 | #else /* MD5_SIZE_VS_SPEED == 0 or 1 */ | ||
275 | |||
276 | uint32_t A_save = A; | ||
277 | uint32_t B_save = B; | ||
278 | uint32_t C_save = C; | ||
279 | uint32_t D_save = D; | ||
280 | # if MD5_SIZE_VS_SPEED == 1 | ||
281 | const uint32_t *pc; | ||
282 | const char *pp; | ||
283 | int i; | ||
284 | # endif | ||
285 | |||
286 | /* First round: using the given function, the context and a constant | ||
287 | the next context is computed. Because the algorithm's processing | ||
288 | unit is a 32-bit word and it is determined to work on words in | ||
289 | little endian byte order we perhaps have to change the byte order | ||
290 | before the computation. To reduce the work for the next steps | ||
291 | we save swapped words in WORDS array. */ | ||
292 | # undef OP | ||
293 | # define OP(a, b, c, d, s, T) \ | ||
294 | do { \ | ||
295 | a += FF(b, c, d) + (*words IF_BIG_ENDIAN(= SWAP_LE32(*words))) + T; \ | ||
296 | words++; \ | ||
297 | a = rotl32(a, s); \ | ||
298 | a += b; \ | ||
299 | } while (0) | ||
300 | |||
301 | /* Round 1 */ | ||
302 | # if MD5_SIZE_VS_SPEED == 1 | ||
303 | pc = C_array; | ||
304 | for (i = 0; i < 4; i++) { | ||
305 | OP(A, B, C, D, 7, *pc++); | ||
306 | OP(D, A, B, C, 12, *pc++); | ||
307 | OP(C, D, A, B, 17, *pc++); | ||
308 | OP(B, C, D, A, 22, *pc++); | ||
309 | } | ||
310 | # else | ||
311 | OP(A, B, C, D, 7, 0xd76aa478); | ||
312 | OP(D, A, B, C, 12, 0xe8c7b756); | ||
313 | OP(C, D, A, B, 17, 0x242070db); | ||
314 | OP(B, C, D, A, 22, 0xc1bdceee); | ||
315 | OP(A, B, C, D, 7, 0xf57c0faf); | ||
316 | OP(D, A, B, C, 12, 0x4787c62a); | ||
317 | OP(C, D, A, B, 17, 0xa8304613); | ||
318 | OP(B, C, D, A, 22, 0xfd469501); | ||
319 | OP(A, B, C, D, 7, 0x698098d8); | ||
320 | OP(D, A, B, C, 12, 0x8b44f7af); | ||
321 | OP(C, D, A, B, 17, 0xffff5bb1); | ||
322 | OP(B, C, D, A, 22, 0x895cd7be); | ||
323 | OP(A, B, C, D, 7, 0x6b901122); | ||
324 | OP(D, A, B, C, 12, 0xfd987193); | ||
325 | OP(C, D, A, B, 17, 0xa679438e); | ||
326 | OP(B, C, D, A, 22, 0x49b40821); | ||
327 | # endif | ||
328 | words -= 16; | ||
329 | |||
330 | /* For the second to fourth round we have the possibly swapped words | ||
331 | in WORDS. Redefine the macro to take an additional first | ||
332 | argument specifying the function to use. */ | ||
333 | # undef OP | ||
334 | # define OP(f, a, b, c, d, k, s, T) \ | ||
335 | do { \ | ||
336 | a += f(b, c, d) + words[k] + T; \ | ||
337 | a = rotl32(a, s); \ | ||
338 | a += b; \ | ||
339 | } while (0) | ||
340 | |||
341 | /* Round 2 */ | ||
342 | # if MD5_SIZE_VS_SPEED == 1 | ||
343 | pp = P_array; | ||
344 | for (i = 0; i < 4; i++) { | ||
345 | OP(FG, A, B, C, D, (int) (*pp++), 5, *pc++); | ||
346 | OP(FG, D, A, B, C, (int) (*pp++), 9, *pc++); | ||
347 | OP(FG, C, D, A, B, (int) (*pp++), 14, *pc++); | ||
348 | OP(FG, B, C, D, A, (int) (*pp++), 20, *pc++); | ||
349 | } | ||
350 | # else | ||
351 | OP(FG, A, B, C, D, 1, 5, 0xf61e2562); | ||
352 | OP(FG, D, A, B, C, 6, 9, 0xc040b340); | ||
353 | OP(FG, C, D, A, B, 11, 14, 0x265e5a51); | ||
354 | OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa); | ||
355 | OP(FG, A, B, C, D, 5, 5, 0xd62f105d); | ||
356 | OP(FG, D, A, B, C, 10, 9, 0x02441453); | ||
357 | OP(FG, C, D, A, B, 15, 14, 0xd8a1e681); | ||
358 | OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8); | ||
359 | OP(FG, A, B, C, D, 9, 5, 0x21e1cde6); | ||
360 | OP(FG, D, A, B, C, 14, 9, 0xc33707d6); | ||
361 | OP(FG, C, D, A, B, 3, 14, 0xf4d50d87); | ||
362 | OP(FG, B, C, D, A, 8, 20, 0x455a14ed); | ||
363 | OP(FG, A, B, C, D, 13, 5, 0xa9e3e905); | ||
364 | OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8); | ||
365 | OP(FG, C, D, A, B, 7, 14, 0x676f02d9); | ||
366 | OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a); | ||
367 | # endif | ||
368 | |||
369 | /* Round 3 */ | ||
370 | # if MD5_SIZE_VS_SPEED == 1 | ||
371 | for (i = 0; i < 4; i++) { | ||
372 | OP(FH, A, B, C, D, (int) (*pp++), 4, *pc++); | ||
373 | OP(FH, D, A, B, C, (int) (*pp++), 11, *pc++); | ||
374 | OP(FH, C, D, A, B, (int) (*pp++), 16, *pc++); | ||
375 | OP(FH, B, C, D, A, (int) (*pp++), 23, *pc++); | ||
376 | } | ||
377 | # else | ||
378 | OP(FH, A, B, C, D, 5, 4, 0xfffa3942); | ||
379 | OP(FH, D, A, B, C, 8, 11, 0x8771f681); | ||
380 | OP(FH, C, D, A, B, 11, 16, 0x6d9d6122); | ||
381 | OP(FH, B, C, D, A, 14, 23, 0xfde5380c); | ||
382 | OP(FH, A, B, C, D, 1, 4, 0xa4beea44); | ||
383 | OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9); | ||
384 | OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60); | ||
385 | OP(FH, B, C, D, A, 10, 23, 0xbebfbc70); | ||
386 | OP(FH, A, B, C, D, 13, 4, 0x289b7ec6); | ||
387 | OP(FH, D, A, B, C, 0, 11, 0xeaa127fa); | ||
388 | OP(FH, C, D, A, B, 3, 16, 0xd4ef3085); | ||
389 | OP(FH, B, C, D, A, 6, 23, 0x04881d05); | ||
390 | OP(FH, A, B, C, D, 9, 4, 0xd9d4d039); | ||
391 | OP(FH, D, A, B, C, 12, 11, 0xe6db99e5); | ||
392 | OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8); | ||
393 | OP(FH, B, C, D, A, 2, 23, 0xc4ac5665); | ||
394 | # endif | ||
395 | |||
396 | /* Round 4 */ | ||
397 | # if MD5_SIZE_VS_SPEED == 1 | ||
398 | for (i = 0; i < 4; i++) { | ||
399 | OP(FI, A, B, C, D, (int) (*pp++), 6, *pc++); | ||
400 | OP(FI, D, A, B, C, (int) (*pp++), 10, *pc++); | ||
401 | OP(FI, C, D, A, B, (int) (*pp++), 15, *pc++); | ||
402 | OP(FI, B, C, D, A, (int) (*pp++), 21, *pc++); | ||
403 | } | ||
404 | # else | ||
405 | OP(FI, A, B, C, D, 0, 6, 0xf4292244); | ||
406 | OP(FI, D, A, B, C, 7, 10, 0x432aff97); | ||
407 | OP(FI, C, D, A, B, 14, 15, 0xab9423a7); | ||
408 | OP(FI, B, C, D, A, 5, 21, 0xfc93a039); | ||
409 | OP(FI, A, B, C, D, 12, 6, 0x655b59c3); | ||
410 | OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92); | ||
411 | OP(FI, C, D, A, B, 10, 15, 0xffeff47d); | ||
412 | OP(FI, B, C, D, A, 1, 21, 0x85845dd1); | ||
413 | OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f); | ||
414 | OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0); | ||
415 | OP(FI, C, D, A, B, 6, 15, 0xa3014314); | ||
416 | OP(FI, B, C, D, A, 13, 21, 0x4e0811a1); | ||
417 | OP(FI, A, B, C, D, 4, 6, 0xf7537e82); | ||
418 | OP(FI, D, A, B, C, 11, 10, 0xbd3af235); | ||
419 | OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb); | ||
420 | OP(FI, B, C, D, A, 9, 21, 0xeb86d391); | ||
421 | # undef OP | ||
422 | # endif | ||
423 | /* Add checksum to the starting values */ | ||
424 | ctx->hash[0] = A_save + A; | ||
425 | ctx->hash[1] = B_save + B; | ||
426 | ctx->hash[2] = C_save + C; | ||
427 | ctx->hash[3] = D_save + D; | ||
428 | #endif | ||
429 | } | ||
430 | #undef FF | ||
431 | #undef FG | ||
432 | #undef FH | ||
433 | #undef FI | ||
434 | |||
435 | /* Initialize structure containing state of computation. | ||
436 | * (RFC 1321, 3.3: Step 3) | ||
437 | */ | ||
438 | void FAST_FUNC md5_begin(md5_ctx_t *ctx) | ||
439 | { | ||
440 | ctx->hash[0] = 0x67452301; | ||
441 | ctx->hash[1] = 0xefcdab89; | ||
442 | ctx->hash[2] = 0x98badcfe; | ||
443 | ctx->hash[3] = 0x10325476; | ||
444 | ctx->total64 = 0; | ||
445 | ctx->process_block = md5_process_block64; | ||
446 | } | ||
447 | |||
448 | /* Used also for sha1 and sha256 */ | ||
449 | void FAST_FUNC md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) | ||
450 | { | ||
451 | common64_hash(ctx, buffer, len); | ||
452 | } | ||
453 | |||
454 | /* Process the remaining bytes in the buffer and put result from CTX | ||
455 | * in first 16 bytes following RESBUF. The result is always in little | ||
456 | * endian byte order, so that a byte-wise output yields to the wanted | ||
457 | * ASCII representation of the message digest. | ||
458 | */ | ||
459 | void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf) | ||
460 | { | ||
461 | /* MD5 stores total in LE, need to swap on BE arches: */ | ||
462 | common64_end(ctx, /*swap_needed:*/ BB_BIG_ENDIAN); | ||
463 | |||
464 | /* The MD5 result is in little endian byte order. | ||
465 | * We (ab)use the fact that A-D are consecutive in memory. | ||
466 | */ | ||
467 | #if BB_BIG_ENDIAN | ||
468 | ctx->hash[0] = SWAP_LE32(ctx->hash[0]); | ||
469 | ctx->hash[1] = SWAP_LE32(ctx->hash[1]); | ||
470 | ctx->hash[2] = SWAP_LE32(ctx->hash[2]); | ||
471 | ctx->hash[3] = SWAP_LE32(ctx->hash[3]); | ||
472 | #endif | ||
473 | memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * 4); | ||
474 | } | ||
475 | |||
476 | |||
477 | /* | ||
71 | * Based on shasum from http://www.netsw.org/crypto/hash/ | 478 | * Based on shasum from http://www.netsw.org/crypto/hash/ |
72 | * Majorly hacked up to use Dr Brian Gladman's sha1 code | 479 | * Majorly hacked up to use Dr Brian Gladman's sha1 code |
73 | * | 480 | * |
@@ -396,51 +803,6 @@ void FAST_FUNC sha512_begin(sha512_ctx_t *ctx) | |||
396 | /*ctx->total64[0] = ctx->total64[1] = 0; - already done */ | 803 | /*ctx->total64[0] = ctx->total64[1] = 0; - already done */ |
397 | } | 804 | } |
398 | 805 | ||
399 | |||
400 | /* Used also for sha256 */ | ||
401 | void FAST_FUNC sha1_hash(sha1_ctx_t *ctx, const void *buffer, size_t len) | ||
402 | { | ||
403 | unsigned bufpos = ctx->total64 & 63; | ||
404 | unsigned remaining; | ||
405 | |||
406 | ctx->total64 += len; | ||
407 | #if 0 | ||
408 | remaining = 64 - bufpos; | ||
409 | |||
410 | /* Hash whole blocks */ | ||
411 | while (len >= remaining) { | ||
412 | memcpy(ctx->wbuffer + bufpos, buffer, remaining); | ||
413 | buffer = (const char *)buffer + remaining; | ||
414 | len -= remaining; | ||
415 | remaining = 64; | ||
416 | bufpos = 0; | ||
417 | ctx->process_block(ctx); | ||
418 | } | ||
419 | |||
420 | /* Save last, partial blosk */ | ||
421 | memcpy(ctx->wbuffer + bufpos, buffer, len); | ||
422 | #else | ||
423 | /* Tiny bit smaller code */ | ||
424 | while (1) { | ||
425 | remaining = 64 - bufpos; | ||
426 | if (remaining > len) | ||
427 | remaining = len; | ||
428 | /* Copy data into aligned buffer */ | ||
429 | memcpy(ctx->wbuffer + bufpos, buffer, remaining); | ||
430 | len -= remaining; | ||
431 | buffer = (const char *)buffer + remaining; | ||
432 | bufpos += remaining; | ||
433 | /* clever way to do "if (bufpos != 64) break; ... ; bufpos = 0;" */ | ||
434 | bufpos -= 64; | ||
435 | if (bufpos != 0) | ||
436 | break; | ||
437 | /* Buffer is filled up, process it */ | ||
438 | ctx->process_block(ctx); | ||
439 | /*bufpos = 0; - already is */ | ||
440 | } | ||
441 | #endif | ||
442 | } | ||
443 | |||
444 | void FAST_FUNC sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) | 806 | void FAST_FUNC sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) |
445 | { | 807 | { |
446 | unsigned bufpos = ctx->total64[0] & 127; | 808 | unsigned bufpos = ctx->total64[0] & 127; |
@@ -488,14 +850,13 @@ void FAST_FUNC sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) | |||
488 | #endif | 850 | #endif |
489 | } | 851 | } |
490 | 852 | ||
491 | |||
492 | /* Used also for sha256 */ | 853 | /* Used also for sha256 */ |
493 | void FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf) | 854 | void FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf) |
494 | { | 855 | { |
495 | unsigned hash_size; | 856 | unsigned hash_size; |
496 | 857 | ||
497 | /* SHA stores total in BE, need to swap on LE arches: */ | 858 | /* SHA stores total in BE, need to swap on LE arches: */ |
498 | common64_end(ctx, (process_block64_func*) ctx->process_block, /*swap_needed:*/ BB_LITTLE_ENDIAN); | 859 | common64_end(ctx, /*swap_needed:*/ BB_LITTLE_ENDIAN); |
499 | 860 | ||
500 | hash_size = (ctx->process_block == sha1_process_block64) ? 5 : 8; | 861 | hash_size = (ctx->process_block == sha1_process_block64) ? 5 : 8; |
501 | /* This way we do not impose alignment constraints on resbuf: */ | 862 | /* This way we do not impose alignment constraints on resbuf: */ |
@@ -540,430 +901,3 @@ void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf) | |||
540 | } | 901 | } |
541 | memcpy(resbuf, ctx->hash, sizeof(ctx->hash)); | 902 | memcpy(resbuf, ctx->hash, sizeof(ctx->hash)); |
542 | } | 903 | } |
543 | |||
544 | |||
545 | /* | ||
546 | * Compute MD5 checksum of strings according to the | ||
547 | * definition of MD5 in RFC 1321 from April 1992. | ||
548 | * | ||
549 | * Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. | ||
550 | * | ||
551 | * Copyright (C) 1995-1999 Free Software Foundation, Inc. | ||
552 | * Copyright (C) 2001 Manuel Novoa III | ||
553 | * Copyright (C) 2003 Glenn L. McGrath | ||
554 | * Copyright (C) 2003 Erik Andersen | ||
555 | * | ||
556 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||
557 | */ | ||
558 | |||
559 | /* 0: fastest, 3: smallest */ | ||
560 | #if CONFIG_MD5_SIZE_VS_SPEED < 0 | ||
561 | # define MD5_SIZE_VS_SPEED 0 | ||
562 | #elif CONFIG_MD5_SIZE_VS_SPEED > 3 | ||
563 | # define MD5_SIZE_VS_SPEED 3 | ||
564 | #else | ||
565 | # define MD5_SIZE_VS_SPEED CONFIG_MD5_SIZE_VS_SPEED | ||
566 | #endif | ||
567 | |||
568 | /* Initialize structure containing state of computation. | ||
569 | * (RFC 1321, 3.3: Step 3) | ||
570 | */ | ||
571 | void FAST_FUNC md5_begin(md5_ctx_t *ctx) | ||
572 | { | ||
573 | ctx->A = 0x67452301; | ||
574 | ctx->B = 0xefcdab89; | ||
575 | ctx->C = 0x98badcfe; | ||
576 | ctx->D = 0x10325476; | ||
577 | ctx->total64 = 0; | ||
578 | } | ||
579 | |||
580 | /* These are the four functions used in the four steps of the MD5 algorithm | ||
581 | * and defined in the RFC 1321. The first function is a little bit optimized | ||
582 | * (as found in Colin Plumbs public domain implementation). | ||
583 | * #define FF(b, c, d) ((b & c) | (~b & d)) | ||
584 | */ | ||
585 | #undef FF | ||
586 | #undef FG | ||
587 | #undef FH | ||
588 | #undef FI | ||
589 | #define FF(b, c, d) (d ^ (b & (c ^ d))) | ||
590 | #define FG(b, c, d) FF(d, b, c) | ||
591 | #define FH(b, c, d) (b ^ c ^ d) | ||
592 | #define FI(b, c, d) (c ^ (b | ~d)) | ||
593 | |||
594 | /* Hash a single block, 64 bytes long and 4-byte aligned */ | ||
595 | static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) | ||
596 | { | ||
597 | #if MD5_SIZE_VS_SPEED > 0 | ||
598 | /* Before we start, one word to the strange constants. | ||
599 | They are defined in RFC 1321 as | ||
600 | T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64 | ||
601 | */ | ||
602 | static const uint32_t C_array[] = { | ||
603 | /* round 1 */ | ||
604 | 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, | ||
605 | 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, | ||
606 | 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, | ||
607 | 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, | ||
608 | /* round 2 */ | ||
609 | 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, | ||
610 | 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, | ||
611 | 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, | ||
612 | 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, | ||
613 | /* round 3 */ | ||
614 | 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, | ||
615 | 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, | ||
616 | 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05, | ||
617 | 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, | ||
618 | /* round 4 */ | ||
619 | 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, | ||
620 | 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, | ||
621 | 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, | ||
622 | 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 | ||
623 | }; | ||
624 | static const char P_array[] ALIGN1 = { | ||
625 | # if MD5_SIZE_VS_SPEED > 1 | ||
626 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */ | ||
627 | # endif | ||
628 | 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */ | ||
629 | 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */ | ||
630 | 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 /* 4 */ | ||
631 | }; | ||
632 | #endif | ||
633 | uint32_t *words = (void*) ctx->wbuffer; | ||
634 | uint32_t A = ctx->A; | ||
635 | uint32_t B = ctx->B; | ||
636 | uint32_t C = ctx->C; | ||
637 | uint32_t D = ctx->D; | ||
638 | |||
639 | #if MD5_SIZE_VS_SPEED >= 2 /* 2 or 3 */ | ||
640 | |||
641 | static const char S_array[] ALIGN1 = { | ||
642 | 7, 12, 17, 22, | ||
643 | 5, 9, 14, 20, | ||
644 | 4, 11, 16, 23, | ||
645 | 6, 10, 15, 21 | ||
646 | }; | ||
647 | const uint32_t *pc; | ||
648 | const char *pp; | ||
649 | const char *ps; | ||
650 | int i; | ||
651 | uint32_t temp; | ||
652 | |||
653 | # if BB_BIG_ENDIAN | ||
654 | for (i = 0; i < 16; i++) | ||
655 | words[i] = SWAP_LE32(words[i]); | ||
656 | # endif | ||
657 | |||
658 | # if MD5_SIZE_VS_SPEED == 3 | ||
659 | pc = C_array; | ||
660 | pp = P_array; | ||
661 | ps = S_array - 4; | ||
662 | |||
663 | for (i = 0; i < 64; i++) { | ||
664 | if ((i & 0x0f) == 0) | ||
665 | ps += 4; | ||
666 | temp = A; | ||
667 | switch (i >> 4) { | ||
668 | case 0: | ||
669 | temp += FF(B, C, D); | ||
670 | break; | ||
671 | case 1: | ||
672 | temp += FG(B, C, D); | ||
673 | break; | ||
674 | case 2: | ||
675 | temp += FH(B, C, D); | ||
676 | break; | ||
677 | case 3: | ||
678 | temp += FI(B, C, D); | ||
679 | } | ||
680 | temp += words[(int) (*pp++)] + *pc++; | ||
681 | temp = rotl32(temp, ps[i & 3]); | ||
682 | temp += B; | ||
683 | A = D; | ||
684 | D = C; | ||
685 | C = B; | ||
686 | B = temp; | ||
687 | } | ||
688 | # else /* MD5_SIZE_VS_SPEED == 2 */ | ||
689 | pc = C_array; | ||
690 | pp = P_array; | ||
691 | ps = S_array; | ||
692 | |||
693 | for (i = 0; i < 16; i++) { | ||
694 | temp = A + FF(B, C, D) + words[(int) (*pp++)] + *pc++; | ||
695 | temp = rotl32(temp, ps[i & 3]); | ||
696 | temp += B; | ||
697 | A = D; | ||
698 | D = C; | ||
699 | C = B; | ||
700 | B = temp; | ||
701 | } | ||
702 | ps += 4; | ||
703 | for (i = 0; i < 16; i++) { | ||
704 | temp = A + FG(B, C, D) + words[(int) (*pp++)] + *pc++; | ||
705 | temp = rotl32(temp, ps[i & 3]); | ||
706 | temp += B; | ||
707 | A = D; | ||
708 | D = C; | ||
709 | C = B; | ||
710 | B = temp; | ||
711 | } | ||
712 | ps += 4; | ||
713 | for (i = 0; i < 16; i++) { | ||
714 | temp = A + FH(B, C, D) + words[(int) (*pp++)] + *pc++; | ||
715 | temp = rotl32(temp, ps[i & 3]); | ||
716 | temp += B; | ||
717 | A = D; | ||
718 | D = C; | ||
719 | C = B; | ||
720 | B = temp; | ||
721 | } | ||
722 | ps += 4; | ||
723 | for (i = 0; i < 16; i++) { | ||
724 | temp = A + FI(B, C, D) + words[(int) (*pp++)] + *pc++; | ||
725 | temp = rotl32(temp, ps[i & 3]); | ||
726 | temp += B; | ||
727 | A = D; | ||
728 | D = C; | ||
729 | C = B; | ||
730 | B = temp; | ||
731 | } | ||
732 | # endif | ||
733 | /* Add checksum to the starting values */ | ||
734 | ctx->A += A; | ||
735 | ctx->B += B; | ||
736 | ctx->C += C; | ||
737 | ctx->D += D; | ||
738 | |||
739 | #else /* MD5_SIZE_VS_SPEED == 0 or 1 */ | ||
740 | |||
741 | uint32_t A_save = A; | ||
742 | uint32_t B_save = B; | ||
743 | uint32_t C_save = C; | ||
744 | uint32_t D_save = D; | ||
745 | # if MD5_SIZE_VS_SPEED == 1 | ||
746 | const uint32_t *pc; | ||
747 | const char *pp; | ||
748 | int i; | ||
749 | # endif | ||
750 | |||
751 | /* First round: using the given function, the context and a constant | ||
752 | the next context is computed. Because the algorithm's processing | ||
753 | unit is a 32-bit word and it is determined to work on words in | ||
754 | little endian byte order we perhaps have to change the byte order | ||
755 | before the computation. To reduce the work for the next steps | ||
756 | we save swapped words in WORDS array. */ | ||
757 | # undef OP | ||
758 | # define OP(a, b, c, d, s, T) \ | ||
759 | do { \ | ||
760 | a += FF(b, c, d) + (*words IF_BIG_ENDIAN(= SWAP_LE32(*words))) + T; \ | ||
761 | words++; \ | ||
762 | a = rotl32(a, s); \ | ||
763 | a += b; \ | ||
764 | } while (0) | ||
765 | |||
766 | /* Round 1 */ | ||
767 | # if MD5_SIZE_VS_SPEED == 1 | ||
768 | pc = C_array; | ||
769 | for (i = 0; i < 4; i++) { | ||
770 | OP(A, B, C, D, 7, *pc++); | ||
771 | OP(D, A, B, C, 12, *pc++); | ||
772 | OP(C, D, A, B, 17, *pc++); | ||
773 | OP(B, C, D, A, 22, *pc++); | ||
774 | } | ||
775 | # else | ||
776 | OP(A, B, C, D, 7, 0xd76aa478); | ||
777 | OP(D, A, B, C, 12, 0xe8c7b756); | ||
778 | OP(C, D, A, B, 17, 0x242070db); | ||
779 | OP(B, C, D, A, 22, 0xc1bdceee); | ||
780 | OP(A, B, C, D, 7, 0xf57c0faf); | ||
781 | OP(D, A, B, C, 12, 0x4787c62a); | ||
782 | OP(C, D, A, B, 17, 0xa8304613); | ||
783 | OP(B, C, D, A, 22, 0xfd469501); | ||
784 | OP(A, B, C, D, 7, 0x698098d8); | ||
785 | OP(D, A, B, C, 12, 0x8b44f7af); | ||
786 | OP(C, D, A, B, 17, 0xffff5bb1); | ||
787 | OP(B, C, D, A, 22, 0x895cd7be); | ||
788 | OP(A, B, C, D, 7, 0x6b901122); | ||
789 | OP(D, A, B, C, 12, 0xfd987193); | ||
790 | OP(C, D, A, B, 17, 0xa679438e); | ||
791 | OP(B, C, D, A, 22, 0x49b40821); | ||
792 | # endif | ||
793 | words -= 16; | ||
794 | |||
795 | /* For the second to fourth round we have the possibly swapped words | ||
796 | in WORDS. Redefine the macro to take an additional first | ||
797 | argument specifying the function to use. */ | ||
798 | # undef OP | ||
799 | # define OP(f, a, b, c, d, k, s, T) \ | ||
800 | do { \ | ||
801 | a += f(b, c, d) + words[k] + T; \ | ||
802 | a = rotl32(a, s); \ | ||
803 | a += b; \ | ||
804 | } while (0) | ||
805 | |||
806 | /* Round 2 */ | ||
807 | # if MD5_SIZE_VS_SPEED == 1 | ||
808 | pp = P_array; | ||
809 | for (i = 0; i < 4; i++) { | ||
810 | OP(FG, A, B, C, D, (int) (*pp++), 5, *pc++); | ||
811 | OP(FG, D, A, B, C, (int) (*pp++), 9, *pc++); | ||
812 | OP(FG, C, D, A, B, (int) (*pp++), 14, *pc++); | ||
813 | OP(FG, B, C, D, A, (int) (*pp++), 20, *pc++); | ||
814 | } | ||
815 | # else | ||
816 | OP(FG, A, B, C, D, 1, 5, 0xf61e2562); | ||
817 | OP(FG, D, A, B, C, 6, 9, 0xc040b340); | ||
818 | OP(FG, C, D, A, B, 11, 14, 0x265e5a51); | ||
819 | OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa); | ||
820 | OP(FG, A, B, C, D, 5, 5, 0xd62f105d); | ||
821 | OP(FG, D, A, B, C, 10, 9, 0x02441453); | ||
822 | OP(FG, C, D, A, B, 15, 14, 0xd8a1e681); | ||
823 | OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8); | ||
824 | OP(FG, A, B, C, D, 9, 5, 0x21e1cde6); | ||
825 | OP(FG, D, A, B, C, 14, 9, 0xc33707d6); | ||
826 | OP(FG, C, D, A, B, 3, 14, 0xf4d50d87); | ||
827 | OP(FG, B, C, D, A, 8, 20, 0x455a14ed); | ||
828 | OP(FG, A, B, C, D, 13, 5, 0xa9e3e905); | ||
829 | OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8); | ||
830 | OP(FG, C, D, A, B, 7, 14, 0x676f02d9); | ||
831 | OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a); | ||
832 | # endif | ||
833 | |||
834 | /* Round 3 */ | ||
835 | # if MD5_SIZE_VS_SPEED == 1 | ||
836 | for (i = 0; i < 4; i++) { | ||
837 | OP(FH, A, B, C, D, (int) (*pp++), 4, *pc++); | ||
838 | OP(FH, D, A, B, C, (int) (*pp++), 11, *pc++); | ||
839 | OP(FH, C, D, A, B, (int) (*pp++), 16, *pc++); | ||
840 | OP(FH, B, C, D, A, (int) (*pp++), 23, *pc++); | ||
841 | } | ||
842 | # else | ||
843 | OP(FH, A, B, C, D, 5, 4, 0xfffa3942); | ||
844 | OP(FH, D, A, B, C, 8, 11, 0x8771f681); | ||
845 | OP(FH, C, D, A, B, 11, 16, 0x6d9d6122); | ||
846 | OP(FH, B, C, D, A, 14, 23, 0xfde5380c); | ||
847 | OP(FH, A, B, C, D, 1, 4, 0xa4beea44); | ||
848 | OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9); | ||
849 | OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60); | ||
850 | OP(FH, B, C, D, A, 10, 23, 0xbebfbc70); | ||
851 | OP(FH, A, B, C, D, 13, 4, 0x289b7ec6); | ||
852 | OP(FH, D, A, B, C, 0, 11, 0xeaa127fa); | ||
853 | OP(FH, C, D, A, B, 3, 16, 0xd4ef3085); | ||
854 | OP(FH, B, C, D, A, 6, 23, 0x04881d05); | ||
855 | OP(FH, A, B, C, D, 9, 4, 0xd9d4d039); | ||
856 | OP(FH, D, A, B, C, 12, 11, 0xe6db99e5); | ||
857 | OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8); | ||
858 | OP(FH, B, C, D, A, 2, 23, 0xc4ac5665); | ||
859 | # endif | ||
860 | |||
861 | /* Round 4 */ | ||
862 | # if MD5_SIZE_VS_SPEED == 1 | ||
863 | for (i = 0; i < 4; i++) { | ||
864 | OP(FI, A, B, C, D, (int) (*pp++), 6, *pc++); | ||
865 | OP(FI, D, A, B, C, (int) (*pp++), 10, *pc++); | ||
866 | OP(FI, C, D, A, B, (int) (*pp++), 15, *pc++); | ||
867 | OP(FI, B, C, D, A, (int) (*pp++), 21, *pc++); | ||
868 | } | ||
869 | # else | ||
870 | OP(FI, A, B, C, D, 0, 6, 0xf4292244); | ||
871 | OP(FI, D, A, B, C, 7, 10, 0x432aff97); | ||
872 | OP(FI, C, D, A, B, 14, 15, 0xab9423a7); | ||
873 | OP(FI, B, C, D, A, 5, 21, 0xfc93a039); | ||
874 | OP(FI, A, B, C, D, 12, 6, 0x655b59c3); | ||
875 | OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92); | ||
876 | OP(FI, C, D, A, B, 10, 15, 0xffeff47d); | ||
877 | OP(FI, B, C, D, A, 1, 21, 0x85845dd1); | ||
878 | OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f); | ||
879 | OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0); | ||
880 | OP(FI, C, D, A, B, 6, 15, 0xa3014314); | ||
881 | OP(FI, B, C, D, A, 13, 21, 0x4e0811a1); | ||
882 | OP(FI, A, B, C, D, 4, 6, 0xf7537e82); | ||
883 | OP(FI, D, A, B, C, 11, 10, 0xbd3af235); | ||
884 | OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb); | ||
885 | OP(FI, B, C, D, A, 9, 21, 0xeb86d391); | ||
886 | # undef OP | ||
887 | # endif | ||
888 | /* Add checksum to the starting values */ | ||
889 | ctx->A = A_save + A; | ||
890 | ctx->B = B_save + B; | ||
891 | ctx->C = C_save + C; | ||
892 | ctx->D = D_save + D; | ||
893 | #endif | ||
894 | } | ||
895 | #undef FF | ||
896 | #undef FG | ||
897 | #undef FH | ||
898 | #undef FI | ||
899 | |||
900 | /* Feed data through a temporary buffer to call md5_hash_aligned_block() | ||
901 | * with chunks of data that are 4-byte aligned and a multiple of 64 bytes. | ||
902 | * This function's internal buffer remembers previous data until it has 64 | ||
903 | * bytes worth to pass on. Call md5_end() to flush this buffer. */ | ||
904 | void FAST_FUNC md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) | ||
905 | { | ||
906 | unsigned bufpos = ctx->total64 & 63; | ||
907 | unsigned remaining; | ||
908 | |||
909 | /* RFC 1321 specifies the possible length of the file up to 2^64 bits. | ||
910 | * Here we only track the number of bytes. */ | ||
911 | ctx->total64 += len; | ||
912 | #if 0 | ||
913 | remaining = 64 - bufpos; | ||
914 | |||
915 | /* Hash whole blocks */ | ||
916 | while (len >= remaining) { | ||
917 | memcpy(ctx->wbuffer + bufpos, buffer, remaining); | ||
918 | buffer = (const char *)buffer + remaining; | ||
919 | len -= remaining; | ||
920 | remaining = 64; | ||
921 | bufpos = 0; | ||
922 | md5_process_block64(ctx); | ||
923 | } | ||
924 | |||
925 | /* Save last, partial blosk */ | ||
926 | memcpy(ctx->wbuffer + bufpos, buffer, len); | ||
927 | #else | ||
928 | /* Tiny bit smaller code */ | ||
929 | while (1) { | ||
930 | remaining = 64 - bufpos; | ||
931 | if (remaining > len) | ||
932 | remaining = len; | ||
933 | /* Copy data into aligned buffer */ | ||
934 | memcpy(ctx->wbuffer + bufpos, buffer, remaining); | ||
935 | len -= remaining; | ||
936 | buffer = (const char *)buffer + remaining; | ||
937 | bufpos += remaining; | ||
938 | /* clever way to do "if (bufpos != 64) break; ... ; bufpos = 0;" */ | ||
939 | bufpos -= 64; | ||
940 | if (bufpos != 0) | ||
941 | break; | ||
942 | /* Buffer is filled up, process it */ | ||
943 | md5_process_block64(ctx); | ||
944 | /*bufpos = 0; - already is */ | ||
945 | } | ||
946 | #endif | ||
947 | } | ||
948 | |||
949 | /* Process the remaining bytes in the buffer and put result from CTX | ||
950 | * in first 16 bytes following RESBUF. The result is always in little | ||
951 | * endian byte order, so that a byte-wise output yields to the wanted | ||
952 | * ASCII representation of the message digest. | ||
953 | */ | ||
954 | void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf) | ||
955 | { | ||
956 | /* MD5 stores total in LE, need to swap on BE arches: */ | ||
957 | common64_end(ctx, (process_block64_func*) md5_process_block64, /*swap_needed:*/ BB_BIG_ENDIAN); | ||
958 | |||
959 | /* The MD5 result is in little endian byte order. | ||
960 | * We (ab)use the fact that A-D are consecutive in memory. | ||
961 | */ | ||
962 | #if BB_BIG_ENDIAN | ||
963 | ctx->A = SWAP_LE32(ctx->A); | ||
964 | ctx->B = SWAP_LE32(ctx->B); | ||
965 | ctx->C = SWAP_LE32(ctx->C); | ||
966 | ctx->D = SWAP_LE32(ctx->D); | ||
967 | #endif | ||
968 | memcpy(resbuf, &ctx->A, sizeof(ctx->A) * 4); | ||
969 | } | ||