1 /* Part of the ht://Dig package <http://www.htdig.org/> */
2 /* Copyright (c) 1999-2004 The ht://Dig Group */
3 /* For copyright details, see the file COPYING in your distribution */
4 /* or the GNU Library General Public License (LGPL) version 2 or later */
5 /* <http://www.gnu.org/copyleft/lgpl.html> */
6
7
8 /*
9 Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
10 rights reserved.
11
12 License to copy and use this software is granted provided that it
13 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
14 Algorithm" in all material mentioning or referencing this software
15 or this function.
16
17 License is also granted to make and use derivative works provided
18 that such works are identified as "derived from the RSA Data
19 Security, Inc. MD5 Message-Digest Algorithm" in all material
20 mentioning or referencing the derived work.
21
22 RSA Data Security, Inc. makes no representations concerning either
23 the merchantability of this software or the suitability of this
24 software for any particular purpose. It is provided "as is"
25 without express or implied warranty of any kind.
26
27 These notices must be retained in any copies of any part of this
28 documentation and/or software.
29 */
30
31 /*
32 This is a slightly modified version
33 */
34
35 #include "mhash_md5.h"
36
37 /*
38 Constants for MD5Transform routine.
39 */
40
41
42 #define S11 7
43 #define S12 12
44 #define S13 17
45 #define S14 22
46 #define S21 5
47 #define S22 9
48 #define S23 14
49 #define S24 20
50 #define S31 4
51 #define S32 11
52 #define S33 16
53 #define S34 23
54 #define S41 6
55 #define S42 10
56 #define S43 15
57 #define S44 21
58
59 static void MD5Transform PROTO_LIST((word32[4], unsigned char[64]));
60 static void Encode PROTO_LIST
61 ((unsigned char *, word32 *, unsigned int));
62 static void Decode PROTO_LIST
63 ((word32 *, unsigned char *, unsigned int));
64 static void MD5_memcpy PROTO_LIST((POINTER, POINTER, unsigned int));
65 static void MD5_memset PROTO_LIST((POINTER, int, unsigned int));
66
67 static unsigned char PADDING[64] =
68 {
69 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
70 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
71 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
72 };
73
74 /*
75 F, G, H and I are basic MD5 functions.
76 */
77 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
78 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
79 #define H(x, y, z) ((x) ^ (y) ^ (z))
80 #define I(x, y, z) ((y) ^ ((x) | (~z)))
81
82 /*
83 ROTATE_LEFT rotates x left n bits.
84 */
85 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
86
87 /*
88 FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
89 Rotation is separate from addition to prevent recomputation.
90 */
91 #define FF(a, b, c, d, x, s, ac) { \
92 (a) += F ((b), (c), (d)) + (x) + (word32)(ac); \
93 (a) = ROTATE_LEFT ((a), (s)); \
94 (a) += (b); \
95 }
96 #define GG(a, b, c, d, x, s, ac) { \
97 (a) += G ((b), (c), (d)) + (x) + (word32)(ac); \
98 (a) = ROTATE_LEFT ((a), (s)); \
99 (a) += (b); \
100 }
101 #define HH(a, b, c, d, x, s, ac) { \
102 (a) += H ((b), (c), (d)) + (x) + (word32)(ac); \
103 (a) = ROTATE_LEFT ((a), (s)); \
104 (a) += (b); \
105 }
106 #define II(a, b, c, d, x, s, ac) { \
107 (a) += I ((b), (c), (d)) + (x) + (word32)(ac); \
108 (a) = ROTATE_LEFT ((a), (s)); \
109 (a) += (b); \
110 }
111
112 /*
113 MD5 initialization. Begins an MD5 operation, writing a new context.
114 */
115 void
MD5Init(context)116 MD5Init(context)
117 MD5_CTX *context; /*
118 context
119 */
120 {
121 context->count[0] = context->count[1] = 0;
122 /*
123 Load magic initialization constants.
124 */
125 context->state[0] = 0x67452301;
126 context->state[1] = 0xefcdab89;
127 context->state[2] = 0x98badcfe;
128 context->state[3] = 0x10325476;
129 }
130
131 /*
132 MD5 block update operation. Continues an MD5 message-digest
133 operation, processing another message block, and updating the
134 context.
135 */
136 void
MD5Update(context,input,inputLen)137 MD5Update(context, input, inputLen)
138 MD5_CTX *context; /*
139 context
140 */
141 const unsigned char *input; /*
142 input block
143 */
144 unsigned int inputLen; /*
145 length of input block
146 */
147 {
148 unsigned int i, index, partLen;
149
150 /*
151 Compute number of bytes mod 64
152 */
153 index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
154
155 /*
156 Update number of bits
157 */
158 if ((context->count[0] += ((word32) inputLen << 3)) < ((word32) inputLen << 3))
159 context->count[1]++;
160 context->count[1] += ((word32) inputLen >> 29);
161
162 partLen = 64 - index;
163
164 /*
165 Transform as many times as possible.
166 */
167 if (inputLen >= partLen) {
168 MD5_memcpy
169 ((POINTER) & context->buffer[index], (POINTER) input, partLen);
170 MD5Transform(context->state, context->buffer);
171
172 for (i = partLen; i + 63 < inputLen; i += 64)
173 MD5Transform(context->state, (unsigned char *) &input[i]);
174
175 index = 0;
176 }
177 else
178 i = 0;
179
180 /*
181 Buffer remaining input
182 */
183 MD5_memcpy
184 ((POINTER) & context->buffer[index], (POINTER) & input[i],
185 inputLen - i);
186 }
187
188 /*
189 MD5 finalization. Ends an MD5 message-digest operation, writing the
190 the message digest and zeroizing the context.
191 */
192 void *
MD5Final(context)193 MD5Final(context)
194 MD5_CTX *context; /*
195 context
196 */
197 {
198 unsigned char bits[8];
199 unsigned int index, padLen;
200 unsigned char *digest = malloc(16);
201
202 /*
203 Save number of bits
204 */
205 Encode(bits, context->count, 8);
206
207 /*
208 Pad out to 56 mod 64.
209 */
210 index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
211 padLen = (index < 56) ? (56 - index) : (120 - index);
212 MD5Update(context, PADDING, padLen);
213
214 /*
215 Append length (before padding)
216 */
217 MD5Update(context, bits, 8);
218
219
220
221 /*
222 Store state in digest
223 */
224 Encode(digest, context->state, 16);
225
226 /*
227 Zeroize sensitive information.
228 */
229 MD5_memset((POINTER) context, 0, sizeof(*context));
230
231 return digest;
232 }
233
234 /*
235 MD5 basic transformation. Transforms state based on block.
236 */
237 static void
MD5Transform(state,block)238 MD5Transform(state, block)
239 word32 state[4];
240 unsigned char block[64];
241 {
242 word32 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
243
244 Decode(x, block, 64);
245
246 /*
247 Round 1
248 */
249 FF(a, b, c, d, x[0], S11, 0xd76aa478); /*
250 1
251 */
252 FF(d, a, b, c, x[1], S12, 0xe8c7b756); /*
253 2
254 */
255 FF(c, d, a, b, x[2], S13, 0x242070db); /*
256 3
257 */
258 FF(b, c, d, a, x[3], S14, 0xc1bdceee); /*
259 4
260 */
261 FF(a, b, c, d, x[4], S11, 0xf57c0faf); /*
262 5
263 */
264 FF(d, a, b, c, x[5], S12, 0x4787c62a); /*
265 6
266 */
267 FF(c, d, a, b, x[6], S13, 0xa8304613); /*
268 7
269 */
270 FF(b, c, d, a, x[7], S14, 0xfd469501); /*
271 8
272 */
273 FF(a, b, c, d, x[8], S11, 0x698098d8); /*
274 9
275 */
276 FF(d, a, b, c, x[9], S12, 0x8b44f7af); /*
277 10
278 */
279 FF(c, d, a, b, x[10], S13, 0xffff5bb1); /*
280 11
281 */
282 FF(b, c, d, a, x[11], S14, 0x895cd7be); /*
283 12
284 */
285 FF(a, b, c, d, x[12], S11, 0x6b901122); /*
286 13
287 */
288 FF(d, a, b, c, x[13], S12, 0xfd987193); /*
289 14
290 */
291 FF(c, d, a, b, x[14], S13, 0xa679438e); /*
292 15
293 */
294 FF(b, c, d, a, x[15], S14, 0x49b40821); /*
295 16
296 */
297
298 /*
299 Round 2
300 */
301 GG(a, b, c, d, x[1], S21, 0xf61e2562); /*
302 17
303 */
304 GG(d, a, b, c, x[6], S22, 0xc040b340); /*
305 18
306 */
307 GG(c, d, a, b, x[11], S23, 0x265e5a51); /*
308 19
309 */
310 GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /*
311 20
312 */
313 GG(a, b, c, d, x[5], S21, 0xd62f105d); /*
314 21
315 */
316 GG(d, a, b, c, x[10], S22, 0x2441453); /*
317 22
318 */
319 GG(c, d, a, b, x[15], S23, 0xd8a1e681); /*
320 23
321 */
322 GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /*
323 24
324 */
325 GG(a, b, c, d, x[9], S21, 0x21e1cde6); /*
326 25
327 */
328 GG(d, a, b, c, x[14], S22, 0xc33707d6); /*
329 26
330 */
331 GG(c, d, a, b, x[3], S23, 0xf4d50d87); /*
332 27
333 */
334 GG(b, c, d, a, x[8], S24, 0x455a14ed); /*
335 28
336 */
337 GG(a, b, c, d, x[13], S21, 0xa9e3e905); /*
338 29
339 */
340 GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /*
341 30
342 */
343 GG(c, d, a, b, x[7], S23, 0x676f02d9); /*
344 31
345 */
346 GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /*
347 32
348 */
349
350 /*
351 Round 3
352 */
353 HH(a, b, c, d, x[5], S31, 0xfffa3942); /*
354 33
355 */
356 HH(d, a, b, c, x[8], S32, 0x8771f681); /*
357 34
358 */
359 HH(c, d, a, b, x[11], S33, 0x6d9d6122); /*
360 35
361 */
362 HH(b, c, d, a, x[14], S34, 0xfde5380c); /*
363 36
364 */
365 HH(a, b, c, d, x[1], S31, 0xa4beea44); /*
366 37
367 */
368 HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /*
369 38
370 */
371 HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /*
372 39
373 */
374 HH(b, c, d, a, x[10], S34, 0xbebfbc70); /*
375 40
376 */
377 HH(a, b, c, d, x[13], S31, 0x289b7ec6); /*
378 41
379 */
380 HH(d, a, b, c, x[0], S32, 0xeaa127fa); /*
381 42
382 */
383 HH(c, d, a, b, x[3], S33, 0xd4ef3085); /*
384 43
385 */
386 HH(b, c, d, a, x[6], S34, 0x4881d05); /*
387 44
388 */
389 HH(a, b, c, d, x[9], S31, 0xd9d4d039); /*
390 45
391 */
392 HH(d, a, b, c, x[12], S32, 0xe6db99e5); /*
393 46
394 */
395 HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /*
396 47
397 */
398 HH(b, c, d, a, x[2], S34, 0xc4ac5665); /*
399 48
400 */
401
402 /*
403 Round 4
404 */
405 II(a, b, c, d, x[0], S41, 0xf4292244); /*
406 49
407 */
408 II(d, a, b, c, x[7], S42, 0x432aff97); /*
409 50
410 */
411 II(c, d, a, b, x[14], S43, 0xab9423a7); /*
412 51
413 */
414 II(b, c, d, a, x[5], S44, 0xfc93a039); /*
415 52
416 */
417 II(a, b, c, d, x[12], S41, 0x655b59c3); /*
418 53
419 */
420 II(d, a, b, c, x[3], S42, 0x8f0ccc92); /*
421 54
422 */
423 II(c, d, a, b, x[10], S43, 0xffeff47d); /*
424 55
425 */
426 II(b, c, d, a, x[1], S44, 0x85845dd1); /*
427 56
428 */
429 II(a, b, c, d, x[8], S41, 0x6fa87e4f); /*
430 57
431 */
432 II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /*
433 58
434 */
435 II(c, d, a, b, x[6], S43, 0xa3014314); /*
436 59
437 */
438 II(b, c, d, a, x[13], S44, 0x4e0811a1); /*
439 60
440 */
441 II(a, b, c, d, x[4], S41, 0xf7537e82); /*
442 61
443 */
444 II(d, a, b, c, x[11], S42, 0xbd3af235); /*
445 62
446 */
447 II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /*
448 63
449 */
450 II(b, c, d, a, x[9], S44, 0xeb86d391); /*
451 64
452 */
453
454 state[0] += a;
455 state[1] += b;
456 state[2] += c;
457 state[3] += d;
458
459 /*
460 Zeroize sensitive information.
461
462
463
464 */
465 MD5_memset((POINTER) x, 0, sizeof(x));
466 }
467
468 /*
469 Encodes input (word32) into output (unsigned char). Assumes len is
470 a multiple of 4.
471 */
472 static void
Encode(output,input,len)473 Encode(output, input, len)
474 unsigned char *output;
475 word32 *input;
476 unsigned int len;
477 {
478 unsigned int i, j;
479
480 for (i = 0, j = 0; j < len; i++, j += 4) {
481 output[j] = (unsigned char) (input[i] & 0xff);
482 output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff);
483 output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff);
484 output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff);
485 }
486 }
487
488 /*
489 Decodes input (unsigned char) into output (word32). Assumes len is
490 a multiple of 4.
491 */
492 static void
Decode(output,input,len)493 Decode(output, input, len)
494 word32 *output;
495 unsigned char *input;
496 unsigned int len;
497 {
498 unsigned int i, j;
499
500 for (i = 0, j = 0; j < len; i++, j += 4)
501 output[i] = ((word32) input[j]) | (((word32) input[j + 1]) << 8) |
502 (((word32) input[j + 2]) << 16) | (((word32) input[j + 3]) << 24);
503 }
504
505 /*
506 Note: Replace "for loop" with standard memcpy if possible.
507 */
508
509 static void
MD5_memcpy(output,input,len)510 MD5_memcpy(output, input, len)
511 POINTER output;
512 POINTER input;
513 unsigned int len;
514 {
515 unsigned int i;
516
517 for (i = 0; i < len; i++)
518 output[i] = input[i];
519 }
520
521 /*
522 Note: Replace "for loop" with standard memset if possible.
523 */
524 static void
MD5_memset(output,value,len)525 MD5_memset(output, value, len)
526 POINTER output;
527 int value;
528 unsigned int len;
529 {
530 unsigned int i;
531
532 for (i = 0; i < len; i++)
533 ((char *) output)[i] = (char) value;
534 }
535