aboutsummaryrefslogtreecommitdiff
path: root/libbb/md5.c
diff options
context:
space:
mode:
authorDenys Vlasenko <dvlasenk@redhat.com>2010-10-18 10:38:18 +0200
committerDenys Vlasenko <dvlasenk@redhat.com>2010-10-18 10:38:18 +0200
commit06f719fd79fe15ce6fd5431bc58fcb22851de24d (patch)
tree2fc468c9a73e7a83440bbff24fb636a671ccb1cd /libbb/md5.c
parent5fe2f863b9cee5ab0e7ac873538bce48846dbad8 (diff)
downloadbusybox-w32-06f719fd79fe15ce6fd5431bc58fcb22851de24d.tar.gz
busybox-w32-06f719fd79fe15ce6fd5431bc58fcb22851de24d.tar.bz2
busybox-w32-06f719fd79fe15ce6fd5431bc58fcb22851de24d.zip
libbb: rename hash source files. no code changes
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Diffstat (limited to 'libbb/md5.c')
-rw-r--r--libbb/md5.c442
1 files changed, 0 insertions, 442 deletions
diff --git a/libbb/md5.c b/libbb/md5.c
deleted file mode 100644
index 051c8ede4..000000000
--- a/libbb/md5.c
+++ /dev/null
@@ -1,442 +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 BE format */
419 uint64_t t = ctx->total64 << 3;
420 unsigned i;
421 for (i = 0; i < 8; i++) {
422 ctx->wbuffer[56 + i] = t;
423 t >>= 8;
424 }
425 }
426 md5_process_block64(ctx);
427 if (remaining >= 8)
428 break;
429 bufpos = 0;
430 }
431
432 /* The MD5 result is in little endian byte order.
433 * We (ab)use the fact that A-D are consecutive in memory.
434 */
435#if BB_BIG_ENDIAN
436 ctx->A = SWAP_LE32(ctx->A);
437 ctx->B = SWAP_LE32(ctx->B);
438 ctx->C = SWAP_LE32(ctx->C);
439 ctx->D = SWAP_LE32(ctx->D);
440#endif
441 memcpy(resbuf, &ctx->A, sizeof(ctx->A) * 4);
442}