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