1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the qmake application of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
30
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
33
RSA Data Security, Inc. makes no representations concerning either
34
the merchantability of this software or the suitability of this
35
software for any particular purpose. It is provided "as is"
36
without express or implied warranty of any kind.
38
License to copy and use this software is granted provided that it
39
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
40
Algorithm" in all material mentioning or referencing this software
43
License is also granted to make and use derivative works provided
44
that such works are identified as "derived from the RSA Data
45
Security, Inc. MD5 Message-Digest Algorithm" in all material
46
mentioning or referencing the derived work.
48
These notices must be retained in any copies of any part of this
49
documentation and/or software.
54
typedef unsigned char *POINTER;
55
typedef unsigned short int UINT2;
56
typedef unsigned long int UINT4;
59
UINT4 state[4]; // state(ABCD)
60
UINT4 count[2]; // number of bits, modulo 2^64(lsb first)
61
unsigned char buffer[64]; // input buffer
64
static void MD5Init(MD5_CTX *);
65
static void MD5Update(MD5_CTX *, unsigned char *, unsigned int);
66
static void MD5Final(unsigned char [16], MD5_CTX *);
67
static void MD5Transform(UINT4[4], unsigned char[64]);
68
static void Encode(unsigned char *, UINT4 *, unsigned int);
69
static void Decode(UINT4 *, unsigned char *, unsigned int);
70
static void MD5_memset(POINTER, int, unsigned int);
71
static void MD5_memcpy(POINTER output,POINTER input,unsigned int len);
73
// Constants for MD5Transform routine.
75
S11 = 7, S12 = 12, S13 = 17, S14 = 22, S21 = 5, S22 = 9, S23 = 14, S24 = 20,
76
S31 = 4, S32 = 11, S33 = 16, S34 = 23, S41 = 6, S42 = 10, S43 = 15, S44 = 21
79
static unsigned char PADDING[64] = {
80
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
81
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
82
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
85
// F, G, H and I are basic MD5 functions.
86
static inline UINT4 F(UINT4 x, UINT4 y, UINT4 z)
88
return (x & y) |((~x) & z);
91
static inline UINT4 G(UINT4 x, UINT4 y, UINT4 z)
93
return (x & z) |(y &(~z));
96
static inline UINT4 H(UINT4 x, UINT4 y, UINT4 z)
101
static inline UINT4 I(UINT4 x, UINT4 y, UINT4 z)
106
static inline UINT4 rotateLeft(UINT4 x, UINT4 n)
108
return (x << n) |(x >>(32-(n)));
111
// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
112
// Rotation is separate from addition to prevent recomputation.
113
static inline void FF(UINT4 &a, UINT4 b, UINT4 c, UINT4 d, UINT4 x, UINT4 s, UINT4 ac)
115
a += F(b, c, d) + x + ac;
116
a = rotateLeft(a, s);
120
static inline void GG(UINT4 &a, UINT4 b, UINT4 c, UINT4 d, UINT4 x, UINT4 s, UINT4 ac)
122
a += G(b, c, d) + x +(UINT4)(ac);
123
a = rotateLeft(a, s);
127
static inline void HH(UINT4 &a, UINT4 b, UINT4 c, UINT4 d, UINT4 x, UINT4 s, UINT4 ac)
129
a += H(b, c, d) + x +(UINT4)(ac);
130
a = rotateLeft(a, s);
134
static inline void II(UINT4 &a, UINT4 b, UINT4 c, UINT4 d, UINT4 x, UINT4 s, UINT4 ac)
136
a += I(b, c, d) + x +(UINT4)(ac);
137
a = rotateLeft(a, s);
141
// MD5 initialization. Begins an MD5 operation, writing a new context.
142
static void MD5Init(MD5_CTX *context)
144
context->count[0] = context->count[1] = 0;
146
// 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
156
static void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputLen)
158
unsigned int i, index, partLen;
159
// Compute number of bytes mod 64
160
index =(unsigned int)((context->count[0] >> 3) & 0x3F);
162
// Update number of bits
163
if ((context->count[0] +=((UINT4)inputLen << 3)) <((UINT4)inputLen << 3))
166
context->count[1] +=((UINT4)inputLen >> 29);
167
partLen = 64 - index;
169
// Transform as many times as possible.
170
if (inputLen >= partLen) {
171
MD5_memcpy((POINTER)&context->buffer[index],(POINTER)input, partLen);
172
MD5Transform(context->state, context->buffer);
173
for (i = partLen; i + 63 < inputLen; i += 64)
174
MD5Transform(context->state, &input[i]);
180
// Buffer remaining input
181
MD5_memcpy((POINTER)&context->buffer[index],(POINTER)&input[i],
185
// MD5 finalization. Ends an MD5 message-digest operation, writing the
186
// the message digest and zeroizing the context.
187
static void MD5Final(unsigned char digest[16], MD5_CTX *context)
189
unsigned char bits[8];
190
unsigned int index, padLen;
192
// Save number of bits
193
Encode(bits, context->count, 8);
195
// Pad out to 56 mod 64.
196
index =(unsigned int)((context->count[0] >> 3) & 0x3f);
197
padLen =(index < 56) ?(56 - index) :(120 - index);
198
MD5Update(context, PADDING, padLen);
200
// Append length(before padding)
201
MD5Update(context, bits, 8);
203
// Store state in digest
204
Encode(digest, context->state, 16);
206
// Zeroize sensitive information.
207
MD5_memset((POINTER)context, 0, sizeof(*context));
210
// MD5 basic transformation. Transforms state based on block.
211
static void MD5Transform(UINT4 state[4], unsigned char block[64])
213
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
214
Decode(x, block, 64);
217
FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
218
FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
219
FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
220
FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
221
FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
222
FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
223
FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
224
FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
225
FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
226
FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
227
FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
228
FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
229
FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
230
FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
231
FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
232
FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
235
GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
236
GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
237
GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
238
GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
239
GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
240
GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
241
GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
242
GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
243
GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
244
GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
245
GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
246
GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
247
GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
248
GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
249
GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
250
GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
253
HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
254
HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
255
HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
256
HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
257
HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
258
HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
259
HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
260
HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
261
HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
262
HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
263
HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
264
HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
265
HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
266
HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
267
HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
268
HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
271
II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
272
II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
273
II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
274
II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
275
II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
276
II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
277
II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
278
II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
279
II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
280
II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
281
II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
282
II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
283
II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
284
II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
285
II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
286
II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
292
// Zeroize sensitive information.
293
MD5_memset((POINTER)x, 0, sizeof(x));
296
// Encodes input(UINT4) into output(unsigned char). Assumes len is a
298
static void Encode(unsigned char *output, UINT4 *input, unsigned int len)
301
for (i = 0, j = 0; j < len; i++, j += 4) {
302
output[j] = (unsigned char) (input[i] & 0xff);
303
output[j+1] = (unsigned char) ((input[i] >> 8) & 0xff);
304
output[j+2] = (unsigned char) ((input[i] >> 16) & 0xff);
305
output[j+3] = (unsigned char) ((input[i] >> 24) & 0xff);
309
// Decodes input(unsigned char) into output(UINT4). Assumes len is a
311
static void Decode(UINT4 *output, unsigned char *input, unsigned int len)
314
for (i = 0, j = 0; j < len; i++, j += 4)
315
output[i] =((UINT4)input[j]) |(((UINT4)input[j+1]) << 8) |
316
(((UINT4)input[j+2]) << 16) |(((UINT4)input[j+3]) << 24);
319
// Note: Replace "for loop" with standard memset if possible.
320
static void MD5_memset(POINTER output, int value, unsigned int len)
323
for (i = 0; i < len; i++)
324
((char *)output)[i] =(char)value;
327
// Note: Replace "for loop" with standard memcpy if possible.
328
static void MD5_memcpy(POINTER output,POINTER input,unsigned int len)
331
for (i = 0; i < len; i++)
332
output[i] = input[i];
335
void qtMD5(const QByteArray &src, unsigned char *digest)
340
MD5Update(&context, (unsigned char *) src.data(), src.size());
341
MD5Final(digest, &context);
344
QString qtMD5(const QByteArray &src)
346
unsigned char digest[16];
350
for (int i = 0; i < 16; ++i)
351
output += tmp.sprintf("%02x", digest[i]);