1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24: #ifdef HAVE_CONFIG_H
25: # include <config.h>
26: #endif
27:
28: #include <sys/types.h>
29:
30: #if STDC_HEADERS || defined _LIBC
31: # include <stdlib.h>
32: # include <string.h>
33: #else
34: # ifndef HAVE_MEMCPY
35: # define memcpy(d, s, n) (bcopy ((s), (d), (n)), (d))
36: # endif
37: #endif
38:
39: #include "md5.h"
40:
41: #ifdef _LIBC
42: # include <endian.h>
43: # if __BYTE_ORDER == __BIG_ENDIAN
44: # define WORDS_BIGENDIAN 1
45: # endif
46:
47:
48: # define md5_init_ctx __md5_init_ctx
49: # define md5_process_block __md5_process_block
50: # define md5_process_bytes __md5_process_bytes
51: # define md5_finish_ctx __md5_finish_ctx
52: # define md5_read_ctx __md5_read_ctx
53: # define md5_stream __md5_stream
54: # define md5_buffer __md5_buffer
55: #endif
56:
57: #ifdef WORDS_BIGENDIAN
58: # define SWAP(n) \
59: (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
60: #else
61: # define SWAP(n) (n)
62: #endif
63:
64:
65:
66:
67: static const unsigned char fillbuf[64] = { 0x80, 0 };
68:
69:
70:
71:
72: void
73: md5_init_ctx (ctx)
74: struct md5_ctx *ctx;
75: {
76: ctx->A = 0x67452301;
77: ctx->B = 0xefcdab89;
78: ctx->C = 0x98badcfe;
79: ctx->D = 0x10325476;
80:
81: ctx->total[0] = ctx->total[1] = 0;
82: ctx->buflen = 0;
83: }
84:
85:
86:
87:
88:
89:
90: void *
91: md5_read_ctx (ctx, resbuf)
92: const struct md5_ctx *ctx;
93: void *resbuf;
94: {
95: ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
96: ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
97: ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
98: ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
99:
100: return resbuf;
101: }
102:
103:
104:
105:
106:
107:
108: void *
109: md5_finish_ctx (ctx, resbuf)
110: struct md5_ctx *ctx;
111: void *resbuf;
112: {
113:
114: md5_uint32 bytes = ctx->buflen;
115: size_t pad;
116:
117:
118: ctx->total[0] += bytes;
119: if (ctx->total[0] < bytes)
120: ++ctx->total[1];
121:
122: pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
123: memcpy (&ctx->buffer[bytes], fillbuf, pad);
124:
125:
126: *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3);
127: *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) |
128: (ctx->total[0] >> 29));
129:
130:
131: md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
132:
133: return md5_read_ctx (ctx, resbuf);
134: }
135:
136:
137:
138:
139: int
140: md5_stream (stream, resblock)
141: FILE *stream;
142: void *resblock;
143: {
144:
145: #define BLOCKSIZE 4096
146: struct md5_ctx ctx;
147: char buffer[BLOCKSIZE + 72];
148: size_t sum;
149:
150:
151: md5_init_ctx (&ctx);
152:
153:
154: while (1)
155: {
156:
157:
158:
159: size_t n;
160: sum = 0;
161:
162:
163: do
164: {
165: n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
166:
167: sum += n;
168: }
169: while (sum < BLOCKSIZE && n != 0);
170: if (n == 0 && ferror (stream))
171: return 1;
172:
173:
174: if (n == 0)
175: break;
176:
177:
178:
179:
180: md5_process_block (buffer, BLOCKSIZE, &ctx);
181: }
182:
183:
184: if (sum > 0)
185: md5_process_bytes (buffer, sum, &ctx);
186:
187:
188: md5_finish_ctx (&ctx, resblock);
189: return 0;
190: }
191:
192:
193:
194:
195:
196: void *
197: md5_buffer (buffer, len, resblock)
198: const char *buffer;
199: size_t len;
200: void *resblock;
201: {
202: struct md5_ctx ctx;
203:
204:
205: md5_init_ctx (&ctx);
206:
207:
208: md5_process_bytes (buffer, len, &ctx);
209:
210:
211: return md5_finish_ctx (&ctx, resblock);
212: }
213:
214:
215: void
216: md5_process_bytes (buffer, len, ctx)
217: const void *buffer;
218: size_t len;
219: struct md5_ctx *ctx;
220: {
221:
222:
223: if (ctx->buflen != 0)
224: {
225: size_t left_over = ctx->buflen;
226: size_t add = 128 - left_over > len ? len : 128 - left_over;
227:
228: memcpy (&ctx->buffer[left_over], buffer, add);
229: ctx->buflen += add;
230:
231: if (ctx->buflen > 64)
232: {
233: md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
234:
235: ctx->buflen &= 63;
236:
237: memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
238: ctx->buflen);
239: }
240:
241: buffer = (const char *) buffer + add;
242: len -= add;
243: }
244:
245:
246: if (len >= 64)
247: {
248: #if !_STRING_ARCH_unaligned
249:
250:
251: # if __GNUC__ >= 2
252: # define UNALIGNED_P(p) (((md5_uintptr) p) % __alignof__ (md5_uint32) != 0)
253: # else
254: # define UNALIGNED_P(p) (((md5_uintptr) p) % sizeof (md5_uint32) != 0)
255: # endif
256: if (UNALIGNED_P (buffer))
257: while (len > 64)
258: {
259: md5_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
260: buffer = (const char *) buffer + 64;
261: len -= 64;
262: }
263: else
264: #endif
265: {
266: md5_process_block (buffer, len & ~63, ctx);
267: buffer = (const char *) buffer + (len & ~63);
268: len &= 63;
269: }
270: }
271:
272:
273: if (len > 0)
274: {
275: size_t left_over = ctx->buflen;
276:
277: memcpy (&ctx->buffer[left_over], buffer, len);
278: left_over += len;
279: if (left_over >= 64)
280: {
281: md5_process_block (ctx->buffer, 64, ctx);
282: left_over -= 64;
283: memcpy (ctx->buffer, &ctx->buffer[64], left_over);
284: }
285: ctx->buflen = left_over;
286: }
287: }
288:
289:
290:
291:
292:
293:
294: #define FF(b, c, d) (d ^ (b & (c ^ d)))
295: #define FG(b, c, d) FF (d, b, c)
296: #define FH(b, c, d) (b ^ c ^ d)
297: #define FI(b, c, d) (c ^ (b | ~d))
298:
299:
300:
301:
302: void
303: md5_process_block (buffer, len, ctx)
304: const void *buffer;
305: size_t len;
306: struct md5_ctx *ctx;
307: {
308: md5_uint32 correct_words[16];
309: const md5_uint32 *words = buffer;
310: size_t nwords = len / sizeof (md5_uint32);
311: const md5_uint32 *endp = words + nwords;
312: md5_uint32 A = ctx->A;
313: md5_uint32 B = ctx->B;
314: md5_uint32 C = ctx->C;
315: md5_uint32 D = ctx->D;
316:
317:
318:
319:
320: ctx->total[0] += len;
321: if (ctx->total[0] < len)
322: ++ctx->total[1];
323:
324:
325:
326: while (words < endp)
327: {
328: md5_uint32 *cwp = correct_words;
329: md5_uint32 A_save = A;
330: md5_uint32 B_save = B;
331: md5_uint32 C_save = C;
332: md5_uint32 D_save = D;
333:
334:
335:
336:
337:
338:
339:
340:
341: #define OP(a, b, c, d, s, T) \
342: do \
343: { \
344: a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \
345: ++words; \
346: CYCLIC (a, s); \
347: a += b; \
348: } \
349: while (0)
350:
351:
352:
353: #define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
354:
355:
356:
357:
358:
359:
360:
361:
362: OP (A, B, C, D, 7, 0xd76aa478);
363: OP (D, A, B, C, 12, 0xe8c7b756);
364: OP (C, D, A, B, 17, 0x242070db);
365: OP (B, C, D, A, 22, 0xc1bdceee);
366: OP (A, B, C, D, 7, 0xf57c0faf);
367: OP (D, A, B, C, 12, 0x4787c62a);
368: OP (C, D, A, B, 17, 0xa8304613);
369: OP (B, C, D, A, 22, 0xfd469501);
370: OP (A, B, C, D, 7, 0x698098d8);
371: OP (D, A, B, C, 12, 0x8b44f7af);
372: OP (C, D, A, B, 17, 0xffff5bb1);
373: OP (B, C, D, A, 22, 0x895cd7be);
374: OP (A, B, C, D, 7, 0x6b901122);
375: OP (D, A, B, C, 12, 0xfd987193);
376: OP (C, D, A, B, 17, 0xa679438e);
377: OP (B, C, D, A, 22, 0x49b40821);
378:
379:
380:
381:
382: #undef OP
383: #define OP(f, a, b, c, d, k, s, T) \
384: do \
385: { \
386: a += f (b, c, d) + correct_words[k] + T; \
387: CYCLIC (a, s); \
388: a += b; \
389: } \
390: while (0)
391:
392:
393: OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
394: OP (FG, D, A, B, C, 6, 9, 0xc040b340);
395: OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
396: OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
397: OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
398: OP (FG, D, A, B, C, 10, 9, 0x02441453);
399: OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
400: OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
401: OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
402: OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
403: OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
404: OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
405: OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
406: OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
407: OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
408: OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
409:
410:
411: OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
412: OP (FH, D, A, B, C, 8, 11, 0x8771f681);
413: OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
414: OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
415: OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
416: OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
417: OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
418: OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
419: OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
420: OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
421: OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
422: OP (FH, B, C, D, A, 6, 23, 0x04881d05);
423: OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
424: OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
425: OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
426: OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
427:
428:
429: OP (FI, A, B, C, D, 0, 6, 0xf4292244);
430: OP (FI, D, A, B, C, 7, 10, 0x432aff97);
431: OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
432: OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
433: OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
434: OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
435: OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
436: OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
437: OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
438: OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
439: OP (FI, C, D, A, B, 6, 15, 0xa3014314);
440: OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
441: OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
442: OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
443: OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
444: OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
445:
446:
447: A += A_save;
448: B += B_save;
449: C += C_save;
450: D += D_save;
451: }
452:
453:
454: ctx->A = A;
455: ctx->B = B;
456: ctx->C = C;
457: ctx->D = D;
458: }