Upstream tarball 9882
[amule.git] / src / libs / common / MD5Sum.cpp
blob90a67ad00d5c65ce9a8cb63e511019103da01d65
1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )
5 //
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
8 // respective authors.
9 //
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.
19 //
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.
30 typedef struct {
31 uint32_t state[4];
32 uint32_t count[2];
33 unsigned char buffer[64];
34 } MD5_CTX;
36 void MD5Init (MD5_CTX *);
37 void MD5Update (MD5_CTX *, const unsigned char *, size_t);
38 void MD5Final (unsigned char [16], MD5_CTX *);
40 MD5Sum::MD5Sum()
44 MD5Sum::MD5Sum(const wxString& sSource)
46 Calculate(sSource);
49 MD5Sum::MD5Sum(const uint8* buffer, size_t len)
51 Calculate(buffer, len);
54 wxString MD5Sum::Calculate(const wxString& sSource)
56 // Nothing we can do against this unicode2char
57 return Calculate( (const uint8*)(const char*)unicode2char(sSource), sSource.Length());
60 wxString MD5Sum::Calculate(const uint8* buffer, size_t len)
62 MD5_CTX context;
63 unsigned char digest[16];
65 MD5Init (&context);
66 MD5Update (&context, buffer, len);
67 MD5Final (digest, &context);
69 m_sHash.Clear();
70 for (int i = 0; i < 16; ++i) {
71 wxString sT;
72 sT = wxString::Format(wxT("%02x"), digest[i]);
73 m_sHash += sT;
76 memcpy(m_rawhash, digest, 16);
78 return m_sHash;
81 wxString MD5Sum::GetHash()
83 return m_sHash;
86 #define S11 7
87 #define S12 12
88 #define S13 17
89 #define S14 22
90 #define S21 5
91 #define S22 9
92 #define S23 14
93 #define S24 20
94 #define S31 4
95 #define S32 11
96 #define S33 16
97 #define S34 23
98 #define S41 6
99 #define S42 10
100 #define S43 15
101 #define S44 21
103 static void MD5Transform (uint32_t [4], const unsigned char [64]);
104 static void Encode (unsigned char *, uint32_t *, size_t);
105 static void Decode (uint32_t *, const unsigned char *, size_t);
107 static unsigned char PADDING[64] = {
108 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
109 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
113 /* F, G, H and I are basic MD5 functions.
115 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
116 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
117 #define H(x, y, z) ((x) ^ (y) ^ (z))
118 #define I(x, y, z) ((y) ^ ((x) | (~z)))
120 /* ROTATE_LEFT rotates x left n bits.
121 15-April-2003 Sony: use _MSC_VER intrinsic to save some cycles
123 #ifdef _MSC_VER
124 #pragma intrinsic(_rotl)
125 #define ROTATE_LEFT(x, n) _rotl((x), (n))
126 #else
127 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
128 #endif
130 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
131 Rotation is separate from addition to prevent recomputation.
133 /* Defines must be on one line to work with GCC-2.95.3 */
134 #define FF(a, b, c, d, x, s, ac) { (a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
135 #define GG(a, b, c, d, x, s, ac) { (a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
136 #define HH(a, b, c, d, x, s, ac) { (a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
137 #define II(a, b, c, d, x, s, ac) { (a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
139 /* MD5 initialization. Begins an MD5 operation, writing a new context.
141 void MD5Init (MD5_CTX *context)
143 context->count[0] = context->count[1] = 0;
144 /* Load magic initialization constants.
146 context->state[0] = 0x67452301;
147 context->state[1] = 0xefcdab89;
148 context->state[2] = 0x98badcfe;
149 context->state[3] = 0x10325476;
152 /* MD5 block update operation. Continues an MD5 message-digest
153 operation, processing another message block, and updating the
154 context.
156 void MD5Update (MD5_CTX *context, const unsigned char *input, size_t inputLen)
158 off_t index;
159 size_t i, partLen;
161 /* Compute number of bytes mod 64 */
162 index = (context->count[0] >> 3) & 0x3F;
164 /* Update number of bits */
165 if ((context->count[0] += ((uint32_t)inputLen << 3)) < ((uint32_t)inputLen << 3)) {
166 context->count[1]++;
169 context->count[1] += ((uint32_t)inputLen >> 29);
170 partLen = 64 - index;
172 /* Transform as many times as possible. */
173 if (inputLen >= partLen) {
174 memcpy((unsigned char*)&context->buffer[index], (unsigned char*)input, partLen);
175 MD5Transform (context->state, context->buffer);
177 for (i = partLen; i + 63 < inputLen; i += 64) {
178 MD5Transform (context->state, &input[i]);
180 index = 0;
181 } else {
182 i = 0;
185 /* Buffer remaining input */
186 memcpy((unsigned char*)&context->buffer[index], (unsigned char*)&input[i], inputLen-i);
189 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
190 * the message digest and zeroizing the context.
192 void MD5Final (unsigned char digest[16], MD5_CTX *context)
194 unsigned char bits[8];
195 off_t index;
196 size_t padLen;
198 /* Save number of bits */
199 Encode (bits, context->count, 8);
201 /* Pad out to 56 mod 64. */
202 index = (context->count[0] >> 3) & 0x3f;
204 padLen = (index < 56) ? (56 - index) : (120 - index);
206 MD5Update (context, PADDING, padLen);
208 /* Append length (before padding) */
209 MD5Update (context, bits, 8);
211 /* Store state in digest */
212 Encode (digest, context->state, 16);
214 /* Zeroize sensitive information.*/
215 memset((unsigned char*)context, 0, sizeof (*context));
218 /* MD5 basic transformation. Transforms state based on block.
220 static void MD5Transform (uint32_t state[4], const unsigned char block[64])
222 uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
224 Decode (x, block, 64);
226 /* Round 1 */
227 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
228 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
229 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
230 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
231 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
232 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
233 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
234 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
235 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
236 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
237 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
238 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
239 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
240 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
241 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
242 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
244 /* Round 2 */
245 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
246 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
247 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
248 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
249 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
250 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
251 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
252 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
253 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
254 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
255 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
256 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
257 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
258 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
259 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
260 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
262 /* Round 3 */
263 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
264 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
265 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
266 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
267 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
268 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
269 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
270 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
271 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
272 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
273 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
274 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
275 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
276 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
277 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
278 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
280 /* Round 4 */
281 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
282 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
283 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
284 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
285 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
286 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
287 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
288 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
289 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
290 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
291 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
292 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
293 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
294 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
295 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
296 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
298 state[0] += a;
299 state[1] += b;
300 state[2] += c;
301 state[3] += d;
303 /* Zeroize sensitive information.
305 memset((unsigned char*)x, 0, sizeof (x));
308 /* Encodes input (uint32_t) into output (unsigned char). Assumes len is
309 a multiple of 4.
311 static void Encode (unsigned char *output, uint32_t *input, size_t len)
313 size_t i, j;
315 for (i = 0, j = 0; j < len; i++, j += 4) {
316 output[j] = (unsigned char)(input[i] & 0xff);
317 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
318 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
319 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
323 /* Decodes input (unsigned char) into output (uint32_t). Assumes len is
324 a multiple of 4.
326 static void Decode (uint32_t *output, const unsigned char *input, size_t len)
328 wxASSERT( !(len & 3) );
329 size_t i, j;
331 for (i = 0, j = 0; j < len; i++, j += 4) {
332 output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) | (((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24);
336 // File_checked_for_headers