1/* 2 * This file is part of the aMule project. 3 * 4 * Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org ) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21/* 22 * This program generates an md5sum from a C/C++ source file. 23 * Basic preprocessing is applied to the source (comment removal, 24 * whitespace normalization), so only real code change will result 25 * in md5sum change. 26 * 27 * Preprocessor code is written by D�vai Tam�s (gonosztopi@amule.org) 28 * md5 code is taken from src/MD5Sum.cpp 29 * 30 * Usage: the program takes input from stdin and places output to stdout. 31 * This behaviour cannot be altered. 32 */ 33 34#include <inttypes.h> 35#include <stdio.h> 36 37typedef unsigned char *POINTER; 38typedef uint16_t UINT2; 39typedef uint32_t UINT4; 40 41typedef struct { 42 UINT4 state[4]; 43 UINT4 count[2]; 44 unsigned char buffer[64]; 45} MD5_CTX; 46 47void MD5Init(MD5_CTX *); 48void MD5Update(MD5_CTX *, const unsigned char *, unsigned int); 49void MD5Final(unsigned char [16], MD5_CTX *); 50 51 52const int table[][9] = { 53 { 0x0206, 0x0206, 0x0008, 0x0100, 0x0101, 0x0102, 0x000e, 0x0100, 0x00ff }, 54 { 0x0101, 0x0101, 0x0101, 0x0101, 0x0100, 0x0101, 0x010b, 0x0101, 0x00ff }, 55 { 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0100, 0x010c, 0x0102, 0x00ff }, 56 { 0x0003, 0x0003, 0x0003, 0x0009, 0x0003, 0x0003, 0x0003, 0x0003, 0x00ff }, 57 { 0x0006, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x00ff }, 58 { 0x0206, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x00ff }, 59 { 0x0006, 0x0006, 0x0007, 0x0100, 0x0101, 0x0102, 0x000d, 0x0100, 0x00ff }, 60 { 0x0606, 0x0606, 0x0004, 0x000f, 0x0401, 0x0402, 0x050a, 0x0400, 0x04ff }, 61 { 0x0606, 0x0606, 0x0005, 0x0003, 0x0401, 0x0402, 0x050a, 0x0400, 0x04ff }, 62 { 0x0003, 0x0003, 0x0000, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x00ff }, 63 { 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x00ff }, 64 { 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x00ff }, 65 { 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x00ff }, 66 { 0x0006, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x00ff }, 67 { 0x0206, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x00ff }, 68 { 0x000f, 0x000f, 0x000f, 0x0010, 0x000f, 0x000f, 0x000f, 0x000f, 0x00ff }, 69 { 0x000f, 0x000f, 0x0006, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x00ff } 70}; 71 72int GetCharCode(int c) 73{ 74 if (c == '\r' || c == '\n') return 0; 75 if (c == ' ' || c == '\t') return 1; 76 if (c == '/') return 2; 77 if (c == '*') return 3; 78 if (c == '\"') return 4; 79 if (c == '\'') return 5; 80 if (c == '\\') return 6; 81 if (c == EOF) return 8; 82 return 7; 83} 84 85int main() 86{ 87 int c; 88 int state = 0; 89 MD5_CTX context; 90 unsigned char digest[16]; 91 unsigned char buffer[1024]; 92 int count = 0; 93 94 MD5Init(&context); 95 96 while (state != 0x00ff) { 97 c = getchar(); 98 state = table[state][GetCharCode(c)]; 99 if (state & 0x0800) { 100 buffer[count++] = '\\'; 101 } 102 if (state & 0x0400) { 103 buffer[count++] = '/'; 104 } 105 if (state & 0x0200) { 106 buffer[count++] = ' '; 107 } 108 if (state & 0x0100) { 109 buffer[count++] = c; 110 } 111 state &= 0x00ff; 112 if (count > 1020) { 113 MD5Update(&context, buffer, count); 114 count = 0; 115 } 116 } 117 MD5Update(&context, buffer, count); 118 MD5Final(digest, &context); 119 for (count = 0; count < 16; count++) printf("%02x", digest[count]); 120 putchar('\n'); 121 return 0; 122} 123 124 125#define S11 7 126#define S12 12 127#define S13 17 128#define S14 22 129#define S21 5 130#define S22 9 131#define S23 14 132#define S24 20 133#define S31 4 134#define S32 11 135#define S33 16 136#define S34 23 137#define S41 6 138#define S42 10 139#define S43 15 140#define S44 21 141 142static void MD5Transform (UINT4 [4], const unsigned char [64]); 143static void Encode (unsigned char *, UINT4 *, unsigned int); 144static void Decode (UINT4 *, const unsigned char *, unsigned int); 145static void MD5_memcpy (POINTER, POINTER, unsigned int); 146static void MD5_memset (POINTER, int, unsigned int); 147 148static unsigned char PADDING[64] = { 149 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 151 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 152}; 153 154/* F, G, H and I are basic MD5 functions. 155 */ 156#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 157#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) 158#define H(x, y, z) ((x) ^ (y) ^ (z)) 159#define I(x, y, z) ((y) ^ ((x) | (~z))) 160 161/* ROTATE_LEFT rotates x left n bits. 162 15-April-2003 Sony: use MSVC intrinsic to save some cycles 163 */ 164#ifdef _MSC_VER 165#pragma intrinsic(_rotl) 166#define ROTATE_LEFT(x, n) _rotl((x), (n)) 167#else 168#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 169#endif 170 171/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. 172Rotation is separate from addition to prevent recomputation. 173*/ 174/* Defines must be on one line to work with GCC-2.95.3 */ 175#define FF(a, b, c, d, x, s, ac) { (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); } 176#define GG(a, b, c, d, x, s, ac) { (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); } 177#define HH(a, b, c, d, x, s, ac) { (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); } 178#define II(a, b, c, d, x, s, ac) { (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); } 179 180/* MD5 initialization. Begins an MD5 operation, writing a new context. 181 */ 182void MD5Init (MD5_CTX *context) 183{ 184 context->count[0] = context->count[1] = 0; 185 /* Load magic initialization constants. 186*/ 187 context->state[0] = 0x67452301; 188 context->state[1] = 0xefcdab89; 189 context->state[2] = 0x98badcfe; 190 context->state[3] = 0x10325476; 191} 192 193/* MD5 block update operation. Continues an MD5 message-digest 194 operation, processing another message block, and updating the 195 context. 196 */ 197void MD5Update (MD5_CTX *context, const unsigned char *input, unsigned int inputLen) 198{ 199 unsigned int i, index, partLen; 200 201 /* Compute number of bytes mod 64 */ 202 index = (unsigned int)((context->count[0] >> 3) & 0x3F); 203 204 /* Update number of bits */ 205 if ((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3)) { 206 context->count[1]++; 207 } 208 context->count[1] += ((UINT4)inputLen >> 29); 209 partLen = 64 - index; 210 211 /* Transform as many times as possible. */ 212 if (inputLen >= partLen) { 213 MD5_memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen); 214 MD5Transform (context->state, context->buffer); 215 216 for (i = partLen; i + 63 < inputLen; i += 64) { 217 MD5Transform (context->state, &input[i]); 218 } 219 index = 0; 220 } else { 221 i = 0; 222 } 223 /* Buffer remaining input */ 224 MD5_memcpy((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i); 225} 226 227/* MD5 finalization. Ends an MD5 message-digest operation, writing the 228 * the message digest and zeroizing the context. 229 */ 230void MD5Final (unsigned char digest[16], MD5_CTX *context) 231{ 232 unsigned char bits[8]; 233 unsigned int index, padLen; 234 235 /* Save number of bits */ 236 Encode (bits, context->count, 8); 237 238 /* Pad out to 56 mod 64. */ 239 index = (unsigned int)((context->count[0] >> 3) & 0x3f); 240 padLen = (index < 56) ? (56 - index) : (120 - index); 241 MD5Update (context, PADDING, padLen); 242 243 /* Append length (before padding) */ 244 MD5Update (context, bits, 8); 245 /* Store state in digest */ 246 Encode (digest, context->state, 16); 247 248 /* Zeroize sensitive information.*/ 249 MD5_memset ((POINTER)context, 0, sizeof (*context)); 250} 251 252/* MD5 basic transformation. Transforms state based on block. 253 */ 254static void MD5Transform (UINT4 state[4], const unsigned char block[64]) 255{ 256 UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; 257 258 Decode (x, block, 64); 259 260 /* Round 1 */ 261 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ 262 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ 263 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ 264 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ 265 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ 266 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ 267 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ 268 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ 269 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ 270 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ 271 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ 272 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ 273 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ 274 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ 275 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ 276 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ 277 278 /* Round 2 */ 279 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ 280 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ 281 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ 282 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ 283 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ 284 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ 285 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ 286 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ 287 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ 288 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ 289 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ 290 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ 291 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ 292 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ 293 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ 294 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ 295 296 /* Round 3 */ 297 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ 298 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ 299 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ 300 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ 301 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ 302 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ 303 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ 304 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ 305 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ 306 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ 307 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ 308 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ 309 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ 310 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ 311 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ 312 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ 313 314 /* Round 4 */ 315 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ 316 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ 317 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ 318 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ 319 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ 320 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ 321 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ 322 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ 323 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ 324 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ 325 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ 326 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ 327 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ 328 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ 329 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ 330 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ 331 332 state[0] += a; 333 state[1] += b; 334 state[2] += c; 335 state[3] += d; 336 337 /* Zeroize sensitive information. 338 */ 339 MD5_memset ((POINTER)x, 0, sizeof (x)); 340} 341 342/* Encodes input (UINT4) into output (unsigned char). Assumes len is 343 a multiple of 4. 344 */ 345static void Encode (unsigned char *output, UINT4 *input, unsigned int len) 346{ 347 unsigned int i, j; 348 349 for (i = 0, j = 0; j < len; i++, j += 4) { 350 output[j] = (unsigned char)(input[i] & 0xff); 351 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); 352 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); 353 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); 354 } 355} 356 357/* Decodes input (unsigned char) into output (UINT4). Assumes len is 358 a multiple of 4. 359 */ 360static void Decode (UINT4 *output, const unsigned char *input, unsigned int len) 361{ 362 unsigned int i, j; 363 364 for (i = 0, j = 0; j < len; i++, j += 4) 365 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | 366 (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); 367} 368 369/* Note: Replace "for loop" with standard memcpy if possible. 370 */ 371 372static void MD5_memcpy (POINTER output, POINTER input, unsigned int len) 373{ 374 unsigned int i; 375 376 for (i = 0; i < len; i++) 377 output[i] = input[i]; 378} 379 380/* Note: Replace "for loop" with standard memset if possible. 381 */ 382static void MD5_memset (POINTER output, int value, unsigned int len) 383{ 384 unsigned int i; 385 386 for (i = 0; i < len; i++) 387 ((char *)output)[i] = (char)value; 388} 389