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