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