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