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, 8 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

# Content
1 /* 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
23 #include "md5.h"
24
25 #include <cstring>
26
27 #define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
28
29 // 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 {
46 ctx->A = 0x67452301;
47 ctx->B = 0xefcdab89;
48 ctx->C = 0x98badcfe;
49 ctx->D = 0x10325476;
50
51 ctx->total[0] = ctx->total[1] = 0;
52 ctx->buflen = 0;
53 }
54
55 /* 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 {
63 ((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 }
70
71 /* 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 {
79 /* 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 }
101
102 /* 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 {
109 struct md5_ctx ctx;
110
111 /* Initialize the computation context. */
112 md5_init_ctx (&ctx);
113
114 /* 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 }
120
121
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 }