aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-10-19 02:16:12 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2010-10-19 02:16:12 +0200
commit302ad1450e104460abd3aae60b7f40d8a88f43df (patch)
tree0558bb8533889fa16d820e4466d3b72da083b9f6
parentd982da79deb36185c420f94417b57e7b8a4af04c (diff)
downloadbusybox-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.h44
-rw-r--r--libbb/hash_md5_sha.c898
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};
1516void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags); 1516void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags);
1517 1517
1518#if 1
1519typedef struct md5_ctx_t { 1518typedef 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: */
1529typedef 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 1524typedef struct md5_ctx_t sha1_ctx_t;
1525typedef struct md5_ctx_t sha256_ctx_t;
1526typedef 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;
1535void md5_begin(md5_ctx_t *ctx) FAST_FUNC; 1531void md5_begin(md5_ctx_t *ctx) FAST_FUNC;
1536void md5_hash(md5_ctx_t *ctx, const void *data, size_t length) FAST_FUNC; 1532void md5_hash(md5_ctx_t *ctx, const void *data, size_t length) FAST_FUNC;
1537void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC; 1533void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC;
1538typedef 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;
1544void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC; 1534void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC;
1545void sha1_hash(sha1_ctx_t *ctx, const void *data, size_t length) FAST_FUNC; 1535#define sha1_hash md5_hash
1546void sha1_end(sha1_ctx_t *ctx, void *resbuf) FAST_FUNC; 1536void sha1_end(sha1_ctx_t *ctx, void *resbuf) FAST_FUNC;
1547typedef struct sha1_ctx_t sha256_ctx_t;
1548void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC; 1537void 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
1551typedef 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;
1556void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; 1540void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC;
1557void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; 1541void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
1558void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; 1542void 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
35typedef 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 */
39static void FAST_FUNC common64_hash(md5_ctx_t *ctx, const void *buffer, size_t len)
40{
41 unsigned bufpos = ctx->total64 & 63;
39 42
40typedef 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
42static void FAST_FUNC common64_end(void *vctx, process_block64_func process_block64, int swap_needed) 64/* Process the remaining bytes in the buffer */
65static 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 */
130static 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 */
438void 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 */
449void 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 */
459void 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 */
401void 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
444void FAST_FUNC sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) 806void 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 */
493void FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf) 854void 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 */
571void 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 */
595static 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. */
904void 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 */
954void 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}