Regenerated man pages
[amule.git] / src / libs / common / MD5Sum.cpp
blobcfc103ae0cfaa0b3b78985c1713d29e8c32d9075
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 // 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.
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"
27 #include "Format.h" // Needed for CFormat
29 #include "MD5Sum.h" // Interface declarations.
31 typedef struct {
32 uint32_t state[4];
33 uint32_t count[2];
34 unsigned char buffer[64];
35 } MD5_CTX;
37 void MD5Init (MD5_CTX *);
38 void MD5Update (MD5_CTX *, const unsigned char *, size_t);
39 void MD5Final (unsigned char [16], MD5_CTX *);
41 MD5Sum::MD5Sum()
45 MD5Sum::MD5Sum(const wxString& sSource)
47 Calculate(sSource);
50 MD5Sum::MD5Sum(const uint8* buffer, size_t len)
52 Calculate(buffer, len);
55 void MD5Sum::Calculate(const wxString& sSource)
57 // Nothing we can do against this unicode2char
58 Calculate( (const uint8*)(const char*)unicode2char(sSource), sSource.Length());
61 void MD5Sum::Calculate(const uint8* buffer, size_t len)
63 MD5_CTX context;
64 unsigned char digest[16];
66 MD5Init (&context);
67 MD5Update (&context, buffer, len);
68 MD5Final (digest, &context);
70 memcpy(m_rawhash, digest, 16);
71 m_sHash.Clear();
74 wxString MD5Sum::GetHash()
76 if (m_sHash.empty()) {
77 // That's still far from optimal, but called much less often.
78 for (int i = 0; i < 16; ++i) {
79 wxString sT;
80 sT = CFormat(wxT("%02x")) % m_rawhash[i];
81 m_sHash += sT;
84 return m_sHash;
87 #define S11 7
88 #define S12 12
89 #define S13 17
90 #define S14 22
91 #define S21 5
92 #define S22 9
93 #define S23 14
94 #define S24 20
95 #define S31 4
96 #define S32 11
97 #define S33 16
98 #define S34 23
99 #define S41 6
100 #define S42 10
101 #define S43 15
102 #define S44 21
104 static void MD5Transform (uint32_t [4], const unsigned char [64]);
105 static void Encode (unsigned char *, uint32_t *, size_t);
106 static void Decode (uint32_t *, const unsigned char *, size_t);
108 static const unsigned char PADDING[64] = {
109 0x80, 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, 0, 0, 0, 0,
111 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
114 /* F, G, H and I are basic MD5 functions.
116 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
117 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
118 #define H(x, y, z) ((x) ^ (y) ^ (z))
119 #define I(x, y, z) ((y) ^ ((x) | (~z)))
121 /* ROTATE_LEFT rotates x left n bits.
122 15-April-2003 Sony: use _MSC_VER intrinsic to save some cycles
124 #ifdef _MSC_VER
125 #pragma intrinsic(_rotl)
126 #define ROTATE_LEFT(x, n) _rotl((x), (n))
127 #else
128 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
129 #endif
131 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
132 Rotation is separate from addition to prevent recomputation.
134 /* Defines must be on one line to work with GCC-2.95.3 */
135 #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); }
136 #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); }
137 #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); }
138 #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); }
140 /* MD5 initialization. Begins an MD5 operation, writing a new context.
142 void MD5Init (MD5_CTX *context)
144 context->count[0] = context->count[1] = 0;
145 /* Load magic initialization constants.
147 context->state[0] = 0x67452301;
148 context->state[1] = 0xefcdab89;
149 context->state[2] = 0x98badcfe;
150 context->state[3] = 0x10325476;
153 /* MD5 block update operation. Continues an MD5 message-digest
154 operation, processing another message block, and updating the
155 context.
157 void MD5Update (MD5_CTX *context, const unsigned char *input, size_t inputLen)
159 off_t index;
160 size_t i, partLen;
162 /* Compute number of bytes mod 64 */
163 index = (context->count[0] >> 3) & 0x3F;
165 /* Update number of bits */
166 if ((context->count[0] += ((uint32_t)inputLen << 3)) < ((uint32_t)inputLen << 3)) {
167 context->count[1]++;
170 context->count[1] += ((uint32_t)inputLen >> 29);
171 partLen = 64 - index;
173 /* Transform as many times as possible. */
174 if (inputLen >= partLen) {
175 memcpy((unsigned char*)&context->buffer[index], (unsigned char*)input, partLen);
176 MD5Transform (context->state, context->buffer);
178 for (i = partLen; i + 63 < inputLen; i += 64) {
179 MD5Transform (context->state, &input[i]);
181 index = 0;
182 } else {
183 i = 0;
186 /* Buffer remaining input */
187 memcpy((unsigned char*)&context->buffer[index], (unsigned char*)&input[i], inputLen-i);
190 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
191 * the message digest and zeroizing the context.
193 void MD5Final (unsigned char digest[16], MD5_CTX *context)
195 unsigned char bits[8];
196 off_t index;
197 size_t padLen;
199 /* Save number of bits */
200 Encode (bits, context->count, 8);
202 /* Pad out to 56 mod 64. */
203 index = (context->count[0] >> 3) & 0x3f;
205 padLen = (index < 56) ? (56 - index) : (120 - index);
207 MD5Update (context, PADDING, padLen);
209 /* Append length (before padding) */
210 MD5Update (context, bits, 8);
212 /* Store state in digest */
213 Encode (digest, context->state, 16);
215 /* Zeroize sensitive information.*/
216 memset((unsigned char*)context, 0, sizeof (*context));
219 /* MD5 basic transformation. Transforms state based on block.
221 static void MD5Transform (uint32_t state[4], const unsigned char block[64])
223 uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
225 Decode (x, block, 64);
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 */
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 */
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 */
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 */
299 state[0] += a;
300 state[1] += b;
301 state[2] += c;
302 state[3] += d;
304 /* Zeroize sensitive information.
306 memset((unsigned char*)x, 0, sizeof (x));
309 /* Encodes input (uint32_t) into output (unsigned char). Assumes len is
310 a multiple of 4.
312 static void Encode (unsigned char *output, uint32_t *input, size_t len)
314 size_t i, j;
316 for (i = 0, j = 0; j < len; i++, j += 4) {
317 output[j] = (unsigned char)(input[i] & 0xff);
318 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
319 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
320 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
324 /* Decodes input (unsigned char) into output (uint32_t). Assumes len is
325 a multiple of 4.
327 static void Decode (uint32_t *output, const unsigned char *input, size_t len)
329 wxASSERT( !(len & 3) );
330 size_t i, j;
332 for (i = 0, j = 0; j < len; i++, j += 4) {
333 output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) | (((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24);
337 // File_checked_for_headers