ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/libcpjit/md5.C
Revision: 1.2
Committed: Fri Oct 14 01:29:45 2005 UTC (18 years, 9 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +336 -298 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.2 /* md5.c - Functions to compute MD5 message digest of files or memory blocks
2     according to the definition of MD5 in RFC 1321 from April 1992.
3     Copyright (C) 1995, 1996, 2001, 2003 Free Software Foundation, Inc.
4     NOTE: The canonical source of this file is maintained with the GNU C
5     Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
6    
7     This program is free software; you can redistribute it and/or modify it
8     under the terms of the GNU General Public License as published by the
9     Free Software Foundation; either version 2, or (at your option) any
10     later version.
11    
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software Foundation,
19     Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20    
21     /* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */
22 root 1.1
23     #include "md5.h"
24    
25 root 1.2 #include <cstring>
26    
27     #define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
28 root 1.1
29 root 1.2 // endianness doesn't matter, as we don't share files between architectures
30     #ifdef WORDS_BIGENDIAN
31     # define SWAP(n) \
32     (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
33     #else
34     # define SWAP(n) (n)
35     #endif
36    
37     /* This array contains the bytes used to pad the buffer to the next
38     64-byte boundary. (RFC 1321, 3.1: Step 1) */
39     static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
40    
41     /* Initialize structure containing state of computation.
42     (RFC 1321, 3.3: Step 3) */
43     void
44     md5_init_ctx (struct md5_ctx *ctx)
45 root 1.1 {
46 root 1.2 ctx->A = 0x67452301;
47     ctx->B = 0xefcdab89;
48     ctx->C = 0x98badcfe;
49     ctx->D = 0x10325476;
50 root 1.1
51 root 1.2 ctx->total[0] = ctx->total[1] = 0;
52     ctx->buflen = 0;
53 root 1.1 }
54    
55 root 1.2 /* Put result from CTX in first 16 bytes following RESBUF. The result
56     must be in little endian byte order.
57    
58     IMPORTANT: On some systems it is required that RESBUF is correctly
59     aligned for a 32 bits value. */
60     void *
61     md5_read_ctx (const struct md5_ctx *ctx, void *resbuf)
62 root 1.1 {
63 root 1.2 ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
64     ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
65     ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
66     ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
67    
68     return resbuf;
69 root 1.1 }
70    
71 root 1.2 /* Process the remaining bytes in the internal buffer and the usual
72     prolog according to the standard and write the result to RESBUF.
73    
74     IMPORTANT: On some systems it is required that RESBUF is correctly
75     aligned for a 32 bits value. */
76     void *
77     md5_finish_ctx (struct md5_ctx *ctx, void *resbuf)
78 root 1.1 {
79 root 1.2 /* Take yet unprocessed bytes into account. */
80     md5_uint32 bytes = ctx->buflen;
81     int pad;
82    
83     /* Now count remaining bytes. */
84     ctx->total[0] += bytes;
85     if (ctx->total[0] < bytes)
86     ++ctx->total[1];
87    
88     pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
89     memcpy (&ctx->buffer[bytes], fillbuf, pad);
90    
91     /* Put the 64-bit file length in *bits* at the end of the buffer. */
92     *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3);
93     *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) |
94     (ctx->total[0] >> 29));
95    
96     /* Process last bytes. */
97     md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
98    
99     return md5_read_ctx (ctx, resbuf);
100 root 1.1 }
101    
102 root 1.2 /* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
103     result is always in little endian byte order, so that a byte-wise
104     output yields to the wanted ASCII representation of the message
105     digest. */
106     void *
107     md5_buffer (const char *buffer, int len, void *resblock)
108 root 1.1 {
109 root 1.2 struct md5_ctx ctx;
110    
111     /* Initialize the computation context. */
112     md5_init_ctx (&ctx);
113 root 1.1
114 root 1.2 /* Process whole buffer but last len % 64 bytes. */
115     md5_process_bytes (buffer, len, &ctx);
116    
117     /* Put result in desired memory area. */
118     return md5_finish_ctx (&ctx, resblock);
119 root 1.1 }
120    
121 root 1.2
122     void
123     md5_process_bytes (const void *buffer, int len, struct md5_ctx *ctx)
124     {
125     /* When we already have some bits in our internal buffer concatenate
126     both inputs first. */
127     if (ctx->buflen != 0)
128     {
129     int left_over = ctx->buflen;
130     int add = 128 - left_over > len ? len : 128 - left_over;
131    
132     memcpy (&ctx->buffer[left_over], buffer, add);
133     ctx->buflen += add;
134    
135     if (ctx->buflen > 64)
136     {
137     md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
138    
139     ctx->buflen &= 63;
140     /* The regions in the following copy operation cannot overlap. */
141     memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
142     ctx->buflen);
143     }
144    
145     buffer = (const char *) buffer + add;
146     len -= add;
147     }
148    
149     /* Process available complete blocks. */
150     if (len >= 64)
151     {
152     /* To check alignment gcc has an appropriate operator. Other
153     compilers don't. */
154     # if __GNUC__ >= 2
155     # define UNALIGNED_P(p) (((md5_uintptr) p) % __alignof__ (md5_uint32) != 0)
156     # else
157     # define UNALIGNED_P(p) (((md5_uintptr) p) % sizeof (md5_uint32) != 0)
158     # endif
159     if (UNALIGNED_P (buffer))
160     while (len > 64)
161     {
162     md5_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
163     buffer = (const char *) buffer + 64;
164     len -= 64;
165     }
166     else
167     {
168     md5_process_block (buffer, len & ~63, ctx);
169     buffer = (const char *) buffer + (len & ~63);
170     len &= 63;
171     }
172     }
173    
174     /* Move remaining bytes in internal buffer. */
175     if (len > 0)
176     {
177     int left_over = ctx->buflen;
178    
179     memcpy (&ctx->buffer[left_over], buffer, len);
180     left_over += len;
181     if (left_over >= 64)
182     {
183     md5_process_block (ctx->buffer, 64, ctx);
184     left_over -= 64;
185     memcpy (ctx->buffer, &ctx->buffer[64], left_over);
186     }
187     ctx->buflen = left_over;
188     }
189     }
190    
191    
192     /* These are the four functions used in the four steps of the MD5 algorithm
193     and defined in the RFC 1321. The first function is a little bit optimized
194     (as found in Colin Plumbs public domain implementation). */
195     /* #define FF(b, c, d) ((b & c) | (~b & d)) */
196     #define FF(b, c, d) (d ^ (b & (c ^ d)))
197     #define FG(b, c, d) FF (d, b, c)
198     #define FH(b, c, d) (b ^ c ^ d)
199     #define FI(b, c, d) (c ^ (b | ~d))
200    
201     /* Process LEN bytes of BUFFER, accumulating context into CTX.
202     It is assumed that LEN % 64 == 0. */
203    
204     void
205     md5_process_block (const void *buffer, int len, struct md5_ctx *ctx)
206     {
207     md5_uint32 correct_words[16];
208     const md5_uint32 *words = (const md5_uint32 *)buffer;
209     int nwords = len / sizeof (md5_uint32);
210     const md5_uint32 *endp = words + nwords;
211     md5_uint32 A = ctx->A;
212     md5_uint32 B = ctx->B;
213     md5_uint32 C = ctx->C;
214     md5_uint32 D = ctx->D;
215    
216     /* First increment the byte count. RFC 1321 specifies the possible
217     length of the file up to 2^64 bits. Here we only compute the
218     number of bytes. Do a double word increment. */
219     ctx->total[0] += len;
220     if (ctx->total[0] < len)
221     ++ctx->total[1];
222    
223     /* Process all bytes in the buffer with 64 bytes in each round of
224     the loop. */
225     while (words < endp)
226     {
227     md5_uint32 *cwp = correct_words;
228     md5_uint32 A_save = A;
229     md5_uint32 B_save = B;
230     md5_uint32 C_save = C;
231     md5_uint32 D_save = D;
232    
233     /* First round: using the given function, the context and a constant
234     the next context is computed. Because the algorithms processing
235     unit is a 32-bit word and it is determined to work on words in
236     little endian byte order we perhaps have to change the byte order
237     before the computation. To reduce the work for the next steps
238     we store the swapped words in the array CORRECT_WORDS. */
239    
240     #define OP(a, b, c, d, s, T) \
241     do \
242     { \
243     a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \
244     ++words; \
245     a = rol (a, s); \
246     a += b; \
247     } \
248     while (0)
249    
250     /* Before we start, one word to the strange constants.
251     They are defined in RFC 1321 as
252    
253     T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64, or
254     perl -e 'foreach(1..64){printf "0x%08x\n", int (4294967296 * abs (sin $_))}'
255     */
256    
257     /* Round 1. */
258     OP (A, B, C, D, 7, 0xd76aa478);
259     OP (D, A, B, C, 12, 0xe8c7b756);
260     OP (C, D, A, B, 17, 0x242070db);
261     OP (B, C, D, A, 22, 0xc1bdceee);
262     OP (A, B, C, D, 7, 0xf57c0faf);
263     OP (D, A, B, C, 12, 0x4787c62a);
264     OP (C, D, A, B, 17, 0xa8304613);
265     OP (B, C, D, A, 22, 0xfd469501);
266     OP (A, B, C, D, 7, 0x698098d8);
267     OP (D, A, B, C, 12, 0x8b44f7af);
268     OP (C, D, A, B, 17, 0xffff5bb1);
269     OP (B, C, D, A, 22, 0x895cd7be);
270     OP (A, B, C, D, 7, 0x6b901122);
271     OP (D, A, B, C, 12, 0xfd987193);
272     OP (C, D, A, B, 17, 0xa679438e);
273     OP (B, C, D, A, 22, 0x49b40821);
274    
275     /* For the second to fourth round we have the possibly swapped words
276     in CORRECT_WORDS. Redefine the macro to take an additional first
277     argument specifying the function to use. */
278     #undef OP
279     #define OP(f, a, b, c, d, k, s, T) \
280     do \
281     { \
282     a += f (b, c, d) + correct_words[k] + T; \
283     a = rol (a, s); \
284     a += b; \
285     } \
286     while (0)
287    
288     /* Round 2. */
289     OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
290     OP (FG, D, A, B, C, 6, 9, 0xc040b340);
291     OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
292     OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
293     OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
294     OP (FG, D, A, B, C, 10, 9, 0x02441453);
295     OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
296     OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
297     OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
298     OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
299     OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
300     OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
301     OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
302     OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
303     OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
304     OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
305    
306     /* Round 3. */
307     OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
308     OP (FH, D, A, B, C, 8, 11, 0x8771f681);
309     OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
310     OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
311     OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
312     OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
313     OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
314     OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
315     OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
316     OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
317     OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
318     OP (FH, B, C, D, A, 6, 23, 0x04881d05);
319     OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
320     OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
321     OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
322     OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
323    
324     /* Round 4. */
325     OP (FI, A, B, C, D, 0, 6, 0xf4292244);
326     OP (FI, D, A, B, C, 7, 10, 0x432aff97);
327     OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
328     OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
329     OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
330     OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
331     OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
332     OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
333     OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
334     OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
335     OP (FI, C, D, A, B, 6, 15, 0xa3014314);
336     OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
337     OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
338     OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
339     OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
340     OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
341    
342     /* Add the starting values of the context. */
343     A += A_save;
344     B += B_save;
345     C += C_save;
346     D += D_save;
347     }
348    
349     /* Put checksum in context given as argument. */
350     ctx->A = A;
351     ctx->B = B;
352     ctx->C = C;
353     ctx->D = D;
354     }