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