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