1 /*
2
3 $Id$
4
5 MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
6
7 Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
8 rights reserved.
9
10 License to copy and use this software is granted provided that it
11 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
12 Algorithm" in all material mentioning or referencing this software
13 or this function.
14
15 License is also granted to make and use derivative works provided
16 that such works are identified as "derived from the RSA Data
17 Security, Inc. MD5 Message-Digest Algorithm" in all material
18 mentioning or referencing the derived work.
19
20 RSA Data Security, Inc. makes no representations concerning either
21 the merchantability of this software or the suitability of this
22 software for any particular purpose. It is provided "as is"
23 without express or implied warranty of any kind.
24
25 These notices must be retained in any copies of any part of this
26 documentation and/or software.
27 */
28
29
30 #include <string.h>
31 #include "md5global.h"
32 #include "md5.h"
33
34
35 #define USE_MEM
36
37 /* Constants for MD5Transform routine.
38 */
39
40
41
42
43 #define S11 7
44 #define S12 12
45 #define S13 17
46 #define S14 22
47 #define S21 5
48 #define S22 9
49 #define S23 14
50 #define S24 20
51 #define S31 4
52 #define S32 11
53 #define S33 16
54 #define S34 23
55 #define S41 6
56 #define S42 10
57 #define S43 15
58 #define S44 21
59
60 static void MD5Transform(UINT4 [4], unsigned char [64]);
61 static void Encode(unsigned char *, UINT4 *, unsigned int);
62 static void Decode(UINT4 *, unsigned char *, unsigned int);
63 static void MD5_memcpy(POINTER, POINTER, unsigned int);
64 static void MD5_memset(POINTER, int, unsigned int);
65
66 static unsigned char PADDING[64] = {
67 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
68 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
69 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
70 };
71
72 /* F, G, H and I are basic MD5 functions.
73 */
74 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
75 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
76 #define H(x, y, z) ((x) ^ (y) ^ (z))
77 #define I(x, y, z) ((y) ^ ((x) | (~z)))
78
79 /* ROTATE_LEFT rotates x left n bits.
80 */
81 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
82
83 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
84 Rotation is separate from addition to prevent recomputation.
85 */
86 #define FF(a, b, c, d, x, s, ac) { \
87 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
88 (a) = ROTATE_LEFT ((a), (s)); \
89 (a) += (b); \
90 }
91 #define GG(a, b, c, d, x, s, ac) { \
92 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
93 (a) = ROTATE_LEFT ((a), (s)); \
94 (a) += (b); \
95 }
96 #define HH(a, b, c, d, x, s, ac) { \
97 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
98 (a) = ROTATE_LEFT ((a), (s)); \
99 (a) += (b); \
100 }
101 #define II(a, b, c, d, x, s, ac) { \
102 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
103 (a) = ROTATE_LEFT ((a), (s)); \
104 (a) += (b); \
105 }
106
107 /* MD5 initialization. Begins an MD5 operation, writing a new context.
108 */
MD5Init(MD5_CTX * context)109 void MD5Init (MD5_CTX *context)
110 {
111 context->count[0] = context->count[1] = 0;
112 /* Load magic initialization constants.
113 */
114 context->state[0] = 0x67452301;
115 context->state[1] = 0xefcdab89;
116 context->state[2] = 0x98badcfe;
117 context->state[3] = 0x10325476;
118 }
119
120 /* MD5 block update operation. Continues an MD5 message-digest
121 operation, processing another message block, and updating the
122 context.
123 */
MD5Update(MD5_CTX * context,unsigned char * input,unsigned int inputLen)124 void MD5Update (MD5_CTX *context, /* context */
125 unsigned char *input, /* input block */
126 unsigned int inputLen /* length of input block */
127 )
128 {
129 unsigned int i, index, partLen;
130
131 /* Compute number of bytes mod 64 */
132 index = (unsigned int)((context->count[0] >> 3) & 0x3F);
133
134 /* Update number of bits */
135 if ((context->count[0] += ((UINT4)inputLen << 3))
136
137 < ((UINT4)inputLen << 3))
138 context->count[1]++;
139 context->count[1] += ((UINT4)inputLen >> 29);
140
141 partLen = 64 - index;
142
143 /* Transform as many times as possible.
144 */
145 if (inputLen >= partLen) {
146 MD5_memcpy
147 ((POINTER)&context->buffer[index], (POINTER)input, partLen);
148 MD5Transform (context->state, context->buffer);
149
150 for (i = partLen; i + 63 < inputLen; i += 64)
151 MD5Transform (context->state, &input[i]);
152
153 index = 0;
154 }
155 else
156 i = 0;
157
158 /* Buffer remaining input */
159 MD5_memcpy
160 ((POINTER)&context->buffer[index], (POINTER)&input[i],
161 inputLen-i);
162 }
163
164 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
165 the message digest and zeroizing the context.
166 */
MD5Final(unsigned char digest[16],MD5_CTX * context)167 void MD5Final (unsigned char digest[16], MD5_CTX *context)
168 {
169 unsigned char bits[8];
170 unsigned int index, padLen;
171
172 /* Save number of bits */
173 Encode (bits, context->count, 8);
174
175 /* Pad out to 56 mod 64.
176 */
177 index = (unsigned int)((context->count[0] >> 3) & 0x3f);
178 padLen = (index < 56) ? (56 - index) : (120 - index);
179 MD5Update (context, PADDING, padLen);
180
181 /* Append length (before padding) */
182 MD5Update (context, bits, 8);
183
184 /* Store state in digest */
185 Encode (digest, context->state, 16);
186
187 /* Zeroize sensitive information.
188 */
189 MD5_memset ((POINTER)context, 0, sizeof (*context));
190 }
191
192 /* MD5 basic transformation. Transforms state based on block.
193 */
MD5Transform(UINT4 state[4],unsigned char block[64])194 static void MD5Transform (UINT4 state[4], unsigned char block[64])
195 {
196 UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
197
198 Decode (x, block, 64);
199
200 /* Round 1 */
201 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
202 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
203 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
204 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
205 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
206 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
207 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
208 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
209 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
210 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
211 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
212 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
213 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
214 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
215 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
216 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
217
218 /* Round 2 */
219 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
220 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
221 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
222 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
223 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
224 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
225 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
226 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
227 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
228 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
229 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
230 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
231 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
232 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
233 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
234 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
235
236 /* Round 3 */
237 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
238 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
239 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
240 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
241 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
242 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
243 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
244 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
245 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
246 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
247 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
248 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
249 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
250 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
251 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
252 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
253
254 /* Round 4 */
255 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
256 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
257 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
258 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
259 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
260 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
261 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
262 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
263 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
264 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
265 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
266 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
267 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
268 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
269 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
270 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
271
272 state[0] += a;
273 state[1] += b;
274 state[2] += c;
275 state[3] += d;
276
277 /* Zeroize sensitive information.
278 */
279 MD5_memset ((POINTER)x, 0, sizeof (x));
280 }
281
282 /* Encodes input (UINT4) into output (unsigned char). Assumes len is
283 a multiple of 4.
284 */
Encode(unsigned char * output,UINT4 * input,unsigned int len)285 static void Encode (unsigned char *output, UINT4 *input, unsigned int len)
286 {
287 unsigned int i, j;
288
289 for (i = 0, j = 0; j < len; i++, j += 4) {
290 output[j] = (unsigned char)(input[i] & 0xff);
291 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
292 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
293 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
294 }
295 }
296
297 /* Decodes input (unsigned char) into output (UINT4). Assumes len is
298 a multiple of 4.
299 */
Decode(UINT4 * output,unsigned char * input,unsigned int len)300 static void Decode (UINT4 *output, unsigned char *input, unsigned int len)
301 {
302 unsigned int i, j;
303
304 for (i = 0, j = 0; j < len; i++, j += 4)
305 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
306 (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
307 }
308
309 /* Note: Replace "for loop" with standard memcpy if possible.
310 */
311
MD5_memcpy(POINTER output,POINTER input,unsigned int len)312 static void MD5_memcpy (POINTER output, POINTER input, unsigned int len)
313 {
314
315 // #ifndef USE_MEM
316 // unsigned int i;
317
318 // for (i = 0; i < len; i++)
319 // output[i] = input[i];
320 // #else
321 memcpy( output, input, len );
322 // #endif
323 }
324
325 /* Note: Replace "for loop" with standard memset if possible.
326 */
MD5_memset(POINTER output,int value,unsigned int len)327 static void MD5_memset (POINTER output, int value, unsigned int len)
328 {
329
330 // #ifndef USE_MEM
331 // unsigned int i;
332 // for (i = 0; i < len; i++)
333 // ((char *)output)[i] = (char)value;
334 // #else
335 memset( output, value, len );
336 // #endif
337 }
338
339