2 * $Id: md5.c,v 1.2 2002/02/27 15:51:20 dfs Exp $
5 /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
8 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
11 License to copy and use this software is granted provided that it
12 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
13 Algorithm" in all material mentioning or referencing this software
16 License is also granted to make and use derivative works provided
17 that such works are identified as "derived from the RSA Data
18 Security, Inc. MD5 Message-Digest Algorithm" in all material
19 mentioning or referencing the derived work.
21 RSA Data Security, Inc. makes no representations concerning either
22 the merchantability of this software or the suitability of this
23 software for any particular purpose. It is provided "as is"
24 without express or implied warranty of any kind.
26 These notices must be retained in any copies of any part of this
27 documentation and/or software.
34 #include <radiusclient.h>
36 typedef unsigned char *POINTER;
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 */
46 static void MD5Init (MD5_CTX *);
47 static void MD5Update (MD5_CTX *, unsigned char *, unsigned int);
48 static void MD5Final (unsigned char[16], MD5_CTX *);
50 /* Constants for MD5Transform routine.
69 static void MD5Transform (UINT4[4], unsigned char[64]);
70 static void Encode (unsigned char *, UINT4 *, unsigned int);
71 static void Decode (UINT4 *, unsigned char *, unsigned int);
72 static void MD5_memcpy (POINTER, POINTER, unsigned int);
73 static void MD5_memset (POINTER, int, unsigned int);
75 static 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
81 /* F, G, H and I are basic MD5 functions.
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)))
88 /* ROTATE_LEFT rotates x left n bits.
90 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
92 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
93 Rotation is separate from addition to prevent recomputation.
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)); \
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)); \
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)); \
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)); \
116 void rc_md5_calc (unsigned char *output, unsigned char *input, unsigned int inlen)
121 MD5Update (&context, input, inlen);
122 MD5Final (output, &context);
125 /* MD5 initialization. Begins an MD5 operation, writing a new context.
127 static void MD5Init (MD5_CTX *context)
129 context->count[0] = context->count[1] = 0;
132 * Load magic initialization constants.
134 context->state[0] = 0x67452301;
135 context->state[1] = 0xefcdab89;
136 context->state[2] = 0x98badcfe;
137 context->state[3] = 0x10325476;
140 /* MD5 block update operation. Continues an MD5 message-digest
141 operation, processing another message block, and updating the
144 static void MD5Update (MD5_CTX *context, unsigned char *input, unsigned int inputLen)
150 /* Compute number of bytes mod 64 */
151 index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
153 /* Update number of bits */
154 if ((context->count[0] += ((UINT4) inputLen << 3))
155 < ((UINT4) inputLen << 3))
157 context->count[1] += ((UINT4) inputLen >> 29);
159 partLen = 64 - index;
162 * Transform as many times as possible.
164 if (inputLen >= partLen)
167 ((POINTER) & context->buffer[index], (POINTER) input, partLen);
168 MD5Transform (context->state, context->buffer);
170 for (i = partLen; i + 63 < inputLen; i += 64)
171 MD5Transform (context->state, &input[i]);
178 /* Buffer remaining input */
180 ((POINTER) & context->buffer[index], (POINTER) & input[i],
184 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
185 the message digest and zeroizing the context.
187 static void MD5Final (unsigned char *digest, MD5_CTX *context)
189 unsigned char bits[8];
193 /* Save number of bits */
194 Encode (bits, context->count, 8);
197 * Pad out to 56 mod 64.
199 index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
200 padLen = (index < 56) ? (56 - index) : (120 - index);
201 MD5Update (context, PADDING, padLen);
203 /* Append length (before padding) */
204 MD5Update (context, bits, 8);
206 /* Store state in digest */
207 Encode (digest, context->state, 16);
210 * Zeroize sensitive information.
212 MD5_memset ((POINTER) context, 0, sizeof (*context));
215 /* MD5 basic transformation. Transforms state based on block.
217 static void MD5Transform (UINT4 *state, unsigned char *block)
225 Decode (x, block, 64);
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 */
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 */
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 */
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 */
305 * Zeroize sensitive information.
307 MD5_memset ((POINTER) x, 0, sizeof (x));
310 /* Encodes input (UINT4) into output (unsigned char). Assumes len is
313 static void Encode (unsigned char *output, UINT4 *input, unsigned int len)
318 for (i = 0, j = 0; j < len; i++, j += 4)
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);
327 /* Decodes input (unsigned char) into output (UINT4). Assumes len is
330 static void Decode (UINT4 *output, unsigned char *input, unsigned int len)
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);
340 static void MD5_memcpy (POINTER output, POINTER input, unsigned int len)
342 memcpy(output, input, len);
345 static void MD5_memset (POINTER output, int value, unsigned int len)
347 memset(output, value, len);