2 // This file is part of the aMule Project.
4 // Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )
6 // Any parts of this program derived from the xMule, lMule or eMule project,
7 // or contributed by third-party developers are copyrighted by their
10 // This program is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation; either version 2 of the License, or
13 // (at your option) any later version.
15 // This program is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include "StringFunctions.h"
28 #include "MD5Sum.h" // Interface declarations.
31 typedef unsigned char *POINTER
;
32 typedef uint16_t UINT2
;
33 typedef uint32_t UINT4
;
38 unsigned char buffer
[64];
41 void MD5Init (MD5_CTX
*);
42 void MD5Update (MD5_CTX
*, const unsigned char *, unsigned int);
43 void MD5Final (unsigned char [16], MD5_CTX
*);
49 MD5Sum::MD5Sum(const wxString
& sSource
)
54 MD5Sum::MD5Sum(const uint8
* buffer
, int len
)
56 Calculate(buffer
, len
);
59 wxString
MD5Sum::Calculate(const wxString
& sSource
)
62 (const uint8
*)(const char*)unicode2char(sSource
),
66 wxString
MD5Sum::Calculate(const uint8
* buffer
, int len
)
69 unsigned char digest
[16];
72 // Nothing we can do against this unicode2char
73 MD5Update (&context
, buffer
, len
);
74 MD5Final (digest
, &context
);
77 for (int i
= 0; i
< 16; ++i
)
80 sT
= wxString::Format(wxT("%02x"), digest
[i
]);
84 memcpy(m_rawhash
, digest
, 16);
89 wxString
MD5Sum::GetHash()
111 static void MD5Transform (UINT4
[4], const unsigned char [64]);
112 static void Encode (unsigned char *, UINT4
*, unsigned int);
113 static void Decode (UINT4
*, const unsigned char *, unsigned int);
114 static void MD5_memcpy (POINTER
, POINTER
, unsigned int);
115 static void MD5_memset (POINTER
, int, unsigned int);
117 static unsigned char PADDING
[64] = {
118 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
119 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
120 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
123 /* F, G, H and I are basic MD5 functions.
125 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
126 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
127 #define H(x, y, z) ((x) ^ (y) ^ (z))
128 #define I(x, y, z) ((y) ^ ((x) | (~z)))
130 /* ROTATE_LEFT rotates x left n bits.
131 15-April-2003 Sony: use _MSC_VER intrinsic to save some cycles
134 #pragma intrinsic(_rotl)
135 #define ROTATE_LEFT(x, n) _rotl((x), (n))
137 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
140 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
141 Rotation is separate from addition to prevent recomputation.
143 /* Defines must be on one line to work with GCC-2.95.3 */
144 #define FF(a, b, c, d, x, s, ac) { (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
145 #define GG(a, b, c, d, x, s, ac) { (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
146 #define HH(a, b, c, d, x, s, ac) { (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
147 #define II(a, b, c, d, x, s, ac) { (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
149 /* MD5 initialization. Begins an MD5 operation, writing a new context.
151 void MD5Init (MD5_CTX
*context
)
153 context
->count
[0] = context
->count
[1] = 0;
154 /* Load magic initialization constants.
156 context
->state
[0] = 0x67452301;
157 context
->state
[1] = 0xefcdab89;
158 context
->state
[2] = 0x98badcfe;
159 context
->state
[3] = 0x10325476;
162 /* MD5 block update operation. Continues an MD5 message-digest
163 operation, processing another message block, and updating the
166 void MD5Update (MD5_CTX
*context
, const unsigned char *input
, unsigned int inputLen
)
168 unsigned int i
, index
, partLen
;
170 /* Compute number of bytes mod 64 */
171 index
= (unsigned int)((context
->count
[0] >> 3) & 0x3F);
173 /* Update number of bits */
174 if ((context
->count
[0] += ((UINT4
)inputLen
<< 3)) < ((UINT4
)inputLen
<< 3)) {
177 context
->count
[1] += ((UINT4
)inputLen
>> 29);
178 partLen
= 64 - index
;
180 /* Transform as many times as possible. */
181 if (inputLen
>= partLen
) {
182 MD5_memcpy((POINTER
)&context
->buffer
[index
], (POINTER
)input
, partLen
);
183 MD5Transform (context
->state
, context
->buffer
);
185 for (i
= partLen
; i
+ 63 < inputLen
; i
+= 64) {
186 MD5Transform (context
->state
, &input
[i
]);
192 /* Buffer remaining input */
193 MD5_memcpy((POINTER
)&context
->buffer
[index
], (POINTER
)&input
[i
], inputLen
-i
);
196 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
197 * the message digest and zeroizing the context.
199 void MD5Final (unsigned char digest
[16], MD5_CTX
*context
)
201 unsigned char bits
[8];
202 unsigned int index
, padLen
;
204 /* Save number of bits */
205 Encode (bits
, context
->count
, 8);
207 /* Pad out to 56 mod 64. */
208 index
= (unsigned int)((context
->count
[0] >> 3) & 0x3f);
209 padLen
= (index
< 56) ? (56 - index
) : (120 - index
);
210 MD5Update (context
, PADDING
, padLen
);
212 /* Append length (before padding) */
213 MD5Update (context
, bits
, 8);
214 /* Store state in digest */
215 Encode (digest
, context
->state
, 16);
217 /* Zeroize sensitive information.*/
218 MD5_memset ((POINTER
)context
, 0, sizeof (*context
));
221 /* MD5 basic transformation. Transforms state based on block.
223 static void MD5Transform (UINT4 state
[4], const unsigned char block
[64])
225 UINT4 a
= state
[0], b
= state
[1], c
= state
[2], d
= state
[3], x
[16];
227 Decode (x
, block
, 64);
230 FF (a
, b
, c
, d
, x
[ 0], S11
, 0xd76aa478); /* 1 */
231 FF (d
, a
, b
, c
, x
[ 1], S12
, 0xe8c7b756); /* 2 */
232 FF (c
, d
, a
, b
, x
[ 2], S13
, 0x242070db); /* 3 */
233 FF (b
, c
, d
, a
, x
[ 3], S14
, 0xc1bdceee); /* 4 */
234 FF (a
, b
, c
, d
, x
[ 4], S11
, 0xf57c0faf); /* 5 */
235 FF (d
, a
, b
, c
, x
[ 5], S12
, 0x4787c62a); /* 6 */
236 FF (c
, d
, a
, b
, x
[ 6], S13
, 0xa8304613); /* 7 */
237 FF (b
, c
, d
, a
, x
[ 7], S14
, 0xfd469501); /* 8 */
238 FF (a
, b
, c
, d
, x
[ 8], S11
, 0x698098d8); /* 9 */
239 FF (d
, a
, b
, c
, x
[ 9], S12
, 0x8b44f7af); /* 10 */
240 FF (c
, d
, a
, b
, x
[10], S13
, 0xffff5bb1); /* 11 */
241 FF (b
, c
, d
, a
, x
[11], S14
, 0x895cd7be); /* 12 */
242 FF (a
, b
, c
, d
, x
[12], S11
, 0x6b901122); /* 13 */
243 FF (d
, a
, b
, c
, x
[13], S12
, 0xfd987193); /* 14 */
244 FF (c
, d
, a
, b
, x
[14], S13
, 0xa679438e); /* 15 */
245 FF (b
, c
, d
, a
, x
[15], S14
, 0x49b40821); /* 16 */
248 GG (a
, b
, c
, d
, x
[ 1], S21
, 0xf61e2562); /* 17 */
249 GG (d
, a
, b
, c
, x
[ 6], S22
, 0xc040b340); /* 18 */
250 GG (c
, d
, a
, b
, x
[11], S23
, 0x265e5a51); /* 19 */
251 GG (b
, c
, d
, a
, x
[ 0], S24
, 0xe9b6c7aa); /* 20 */
252 GG (a
, b
, c
, d
, x
[ 5], S21
, 0xd62f105d); /* 21 */
253 GG (d
, a
, b
, c
, x
[10], S22
, 0x2441453); /* 22 */
254 GG (c
, d
, a
, b
, x
[15], S23
, 0xd8a1e681); /* 23 */
255 GG (b
, c
, d
, a
, x
[ 4], S24
, 0xe7d3fbc8); /* 24 */
256 GG (a
, b
, c
, d
, x
[ 9], S21
, 0x21e1cde6); /* 25 */
257 GG (d
, a
, b
, c
, x
[14], S22
, 0xc33707d6); /* 26 */
258 GG (c
, d
, a
, b
, x
[ 3], S23
, 0xf4d50d87); /* 27 */
259 GG (b
, c
, d
, a
, x
[ 8], S24
, 0x455a14ed); /* 28 */
260 GG (a
, b
, c
, d
, x
[13], S21
, 0xa9e3e905); /* 29 */
261 GG (d
, a
, b
, c
, x
[ 2], S22
, 0xfcefa3f8); /* 30 */
262 GG (c
, d
, a
, b
, x
[ 7], S23
, 0x676f02d9); /* 31 */
263 GG (b
, c
, d
, a
, x
[12], S24
, 0x8d2a4c8a); /* 32 */
266 HH (a
, b
, c
, d
, x
[ 5], S31
, 0xfffa3942); /* 33 */
267 HH (d
, a
, b
, c
, x
[ 8], S32
, 0x8771f681); /* 34 */
268 HH (c
, d
, a
, b
, x
[11], S33
, 0x6d9d6122); /* 35 */
269 HH (b
, c
, d
, a
, x
[14], S34
, 0xfde5380c); /* 36 */
270 HH (a
, b
, c
, d
, x
[ 1], S31
, 0xa4beea44); /* 37 */
271 HH (d
, a
, b
, c
, x
[ 4], S32
, 0x4bdecfa9); /* 38 */
272 HH (c
, d
, a
, b
, x
[ 7], S33
, 0xf6bb4b60); /* 39 */
273 HH (b
, c
, d
, a
, x
[10], S34
, 0xbebfbc70); /* 40 */
274 HH (a
, b
, c
, d
, x
[13], S31
, 0x289b7ec6); /* 41 */
275 HH (d
, a
, b
, c
, x
[ 0], S32
, 0xeaa127fa); /* 42 */
276 HH (c
, d
, a
, b
, x
[ 3], S33
, 0xd4ef3085); /* 43 */
277 HH (b
, c
, d
, a
, x
[ 6], S34
, 0x4881d05); /* 44 */
278 HH (a
, b
, c
, d
, x
[ 9], S31
, 0xd9d4d039); /* 45 */
279 HH (d
, a
, b
, c
, x
[12], S32
, 0xe6db99e5); /* 46 */
280 HH (c
, d
, a
, b
, x
[15], S33
, 0x1fa27cf8); /* 47 */
281 HH (b
, c
, d
, a
, x
[ 2], S34
, 0xc4ac5665); /* 48 */
284 II (a
, b
, c
, d
, x
[ 0], S41
, 0xf4292244); /* 49 */
285 II (d
, a
, b
, c
, x
[ 7], S42
, 0x432aff97); /* 50 */
286 II (c
, d
, a
, b
, x
[14], S43
, 0xab9423a7); /* 51 */
287 II (b
, c
, d
, a
, x
[ 5], S44
, 0xfc93a039); /* 52 */
288 II (a
, b
, c
, d
, x
[12], S41
, 0x655b59c3); /* 53 */
289 II (d
, a
, b
, c
, x
[ 3], S42
, 0x8f0ccc92); /* 54 */
290 II (c
, d
, a
, b
, x
[10], S43
, 0xffeff47d); /* 55 */
291 II (b
, c
, d
, a
, x
[ 1], S44
, 0x85845dd1); /* 56 */
292 II (a
, b
, c
, d
, x
[ 8], S41
, 0x6fa87e4f); /* 57 */
293 II (d
, a
, b
, c
, x
[15], S42
, 0xfe2ce6e0); /* 58 */
294 II (c
, d
, a
, b
, x
[ 6], S43
, 0xa3014314); /* 59 */
295 II (b
, c
, d
, a
, x
[13], S44
, 0x4e0811a1); /* 60 */
296 II (a
, b
, c
, d
, x
[ 4], S41
, 0xf7537e82); /* 61 */
297 II (d
, a
, b
, c
, x
[11], S42
, 0xbd3af235); /* 62 */
298 II (c
, d
, a
, b
, x
[ 2], S43
, 0x2ad7d2bb); /* 63 */
299 II (b
, c
, d
, a
, x
[ 9], S44
, 0xeb86d391); /* 64 */
306 /* Zeroize sensitive information.
308 MD5_memset ((POINTER
)x
, 0, sizeof (x
));
311 /* Encodes input (UINT4) into output (unsigned char). Assumes len is
314 static void Encode (unsigned char *output
, UINT4
*input
, unsigned int len
)
318 for (i
= 0, j
= 0; j
< len
; i
++, j
+= 4) {
319 output
[j
] = (unsigned char)(input
[i
] & 0xff);
320 output
[j
+1] = (unsigned char)((input
[i
] >> 8) & 0xff);
321 output
[j
+2] = (unsigned char)((input
[i
] >> 16) & 0xff);
322 output
[j
+3] = (unsigned char)((input
[i
] >> 24) & 0xff);
326 /* Decodes input (unsigned char) into output (UINT4). Assumes len is
329 static void Decode (UINT4
*output
, const unsigned char *input
, unsigned int len
)
333 for (i
= 0, j
= 0; j
< len
; i
++, j
+= 4)
334 output
[i
] = ((UINT4
)input
[j
]) | (((UINT4
)input
[j
+1]) << 8) |
335 (((UINT4
)input
[j
+2]) << 16) | (((UINT4
)input
[j
+3]) << 24);
338 /* Note: Replace "for loop" with standard memcpy if possible.
341 static void MD5_memcpy (POINTER output
, POINTER input
, unsigned int len
)
345 for (i
= 0; i
< len
; i
++)
346 output
[i
] = input
[i
];
349 /* Note: Replace "for loop" with standard memset if possible.
351 static void MD5_memset (POINTER output
, int value
, unsigned int len
)
355 for (i
= 0; i
< len
; i
++)
356 ((char *)output
)[i
] = (char)value
;
358 // File_checked_for_headers