Updated addon repository URL and improved debug output on download
[supertux.git] / src / addon / md5.cpp
1 //
2 // MD5 message-digest algorithm
3 // Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved.
4 //
5 // C++/object oriented translation and modification:
6 // Copyright (C) 1995 Mordechai T. Abzug
7 //
8 // Further adaptations for SuperTux:
9 // Copyright (C) 2008 Christoph Sommer <christoph.sommer@2008.expires.deltadevelopment.de>
10 //
11 // This translation/modification is provided "as is," without express or
12 // implied warranty of any kind.
13 //
14 // The translators/modifiers do not claim:
15 // (1) that MD5 will do what you think it does;
16 // (2) that this translation/ modification is accurate; or
17 // (3) that this software is "merchantible."
18 //
19 // based on:
20 //
21 // MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
22 // MDDRIVER.C - test driver for MD2, MD4 and MD5
23 // Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved.
24 //
25 // License to copy and use this software is granted provided that it
26 // is identified as the "RSA Data Security, Inc. MD5 Message-Digest
27 // Algorithm" in all material mentioning or referencing this software
28 // or this function.
29 //
30 // License is also granted to make and use derivative works provided
31 // that such works are identified as "derived from the RSA Data
32 // Security, Inc. MD5 Message-Digest Algorithm" in all material
33 // mentioning or referencing the derived work.
34 //
35 // RSA Data Security, Inc. makes no representations concerning either
36 // the merchantability of this software or the suitability of this
37 // software for any particular purpose. It is provided "as is"
38 // without express or implied warranty of any kind.
39 //
40 // These notices must be retained in any copies of any part of this
41 // documentation and/or software.
42 //
43
44 #include "addon/md5.hpp"
45
46 #include <assert.h>
47 #include <stdexcept>
48
49 MD5::MD5() :
50   buffer(),
51   digest(),
52   finalized()
53 {
54   init();
55 }
56
57 void MD5::update (uint8_t* input, uint32_t input_length) {
58
59   uint32_t input_index, buffer_index;
60   uint32_t buffer_space; // how much space is left in buffer
61
62   if (finalized) throw std::runtime_error("MD5::update: Can't update a finalized digest!");
63
64   // Compute number of bytes mod 64
65   buffer_index = (unsigned int)((count[0] >> 3) & 0x3F);
66
67   // Update number of bits
68   if ( (count[0] += ((uint32_t) input_length << 3))<((uint32_t) input_length << 3) ) count[1]++;
69
70   count[1] += ((uint32_t)input_length >> 29);
71
72   buffer_space = 64 - buffer_index; // how much space is left in buffer
73
74   // Transform as many times as possible.
75   if (input_length >= buffer_space) { // ie. we have enough to fill the buffer
76     // fill the rest of the buffer and transform
77     memcpy (buffer + buffer_index, input, buffer_space);
78     transform (buffer);
79
80     // now, transform each 64-byte piece of the input, bypassing the buffer
81     for (input_index = buffer_space; input_index + 63 < input_length;
82          input_index += 64)
83       transform (input+input_index);
84
85     buffer_index = 0; // so we can buffer remaining
86   } else
87     input_index=0; // so we can buffer the whole input
88
89   // and here we do the buffering:
90   memcpy(buffer+buffer_index, input+input_index, input_length-input_index);
91 }
92
93 void MD5::update(FILE *file) {
94   uint8_t buffer_[1024];
95   int len;
96
97   while ((len=fread(buffer_, 1, 1024, file))) update(buffer_, len);
98
99   fclose (file);
100 }
101
102 void MD5::update(std::istream& stream) {
103   uint8_t buffer_[1024];
104
105   while (stream.good()) {
106     stream.read((char*)buffer_, 1024); // note that return value of read is unusable.
107     int len = stream.gcount();
108     update(buffer_, len);
109   }
110 }
111
112 void MD5::update(std::ifstream& stream) {
113   uint8_t buffer_[1024];
114
115   while (stream.good()) {
116     stream.read((char*)buffer_, 1024); // note that return value of read is unusable.
117     int len = stream.gcount();
118     update(buffer_, len);
119   }
120 }
121
122 MD5::MD5(FILE *file) :
123   finalized()
124 {
125   init(); // must be called be all constructors
126   update(file);
127   finalize ();
128 }
129
130 MD5::MD5(std::istream& stream) :
131   finalized()
132 {
133   init(); // must called by all constructors
134   update (stream);
135   finalize();
136 }
137
138 MD5::MD5(std::ifstream& stream) :
139   finalized()
140 {
141   init(); // must called by all constructors
142   update (stream);
143   finalize();
144 }
145
146 uint8_t* MD5::raw_digest() {
147   uint8_t* s = new uint8_t[16];
148
149   finalize();
150
151   memcpy(s, digest, 16);
152   return s;
153 }
154
155 std::string MD5::hex_digest() {
156   int i;
157   char* s= new char[33];
158
159   finalize();
160
161   for (i=0; i<16; i++) sprintf(s+i*2, "%02x", digest[i]);
162
163   s[32]='\0';
164
165   // Create string from 's'
166   std::string s_str = std::string(s);
167   delete[] s;
168
169   return s_str;
170 }
171
172 std::ostream& operator<<(std::ostream &stream, MD5 context) {
173   stream << context.hex_digest();
174   return stream;
175 }
176
177 // PRIVATE METHODS:
178
179 void MD5::init() {
180   finalized=false;
181
182   // Nothing counted, so count=0
183   count[0] = 0;
184   count[1] = 0;
185
186   // Load magic initialization constants.
187   state[0] = 0x67452301;
188   state[1] = 0xefcdab89;
189   state[2] = 0x98badcfe;
190   state[3] = 0x10325476;
191 }
192
193 void MD5::finalize() {
194   if (finalized) return;
195
196   uint8_t bits[8];
197   unsigned int index, padLen;
198   static uint8_t PADDING[64]={
199     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
201     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
202   };
203
204   // Save number of bits
205   encode (bits, count, 8);
206
207   // Pad out to 56 mod 64.
208   index = (uint32_t) ((count[0] >> 3) & 0x3f);
209   padLen = (index < 56) ? (56 - index) : (120 - index);
210   update (PADDING, padLen);
211
212   // Append length (before padding)
213   update (bits, 8);
214
215   // Store state in digest
216   encode (digest, state, 16);
217
218   // Zeroize sensitive information
219   memset (buffer, 0, sizeof(*buffer));
220
221   finalized=true;
222 }
223
224 // Constants for MD5Transform routine.
225 // Although we could use C++ style constants, defines are actually better,
226 // since they let us easily evade scope clashes.
227
228 #define S11 7
229 #define S12 12
230 #define S13 17
231 #define S14 22
232 #define S21 5
233 #define S22 9
234 #define S23 14
235 #define S24 20
236 #define S31 4
237 #define S32 11
238 #define S33 16
239 #define S34 23
240 #define S41 6
241 #define S42 10
242 #define S43 15
243 #define S44 21
244
245 void MD5::transform (uint8_t block[64]) {
246   uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
247
248   decode (x, block, 64);
249
250   assert(!finalized); // not just a user error, since the method is private
251
252   /* Round 1 */
253   FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
254   FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
255   FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
256   FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
257   FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
258   FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
259   FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
260   FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
261   FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
262   FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
263   FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
264   FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
265   FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
266   FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
267   FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
268   FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
269
270   /* Round 2 */
271   GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
272   GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
273   GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
274   GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
275   GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
276   GG (d, a, b, c, x[10], S22, 0x02441453); /* 22 */
277   GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
278   GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
279   GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
280   GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
281   GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
282   GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
283   GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
284   GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
285   GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
286   GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
287
288   /* Round 3 */
289   HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
290   HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
291   HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
292   HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
293   HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
294   HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
295   HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
296   HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
297   HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
298   HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
299   HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
300   HH (b, c, d, a, x[ 6], S34, 0x04881d05); /* 44 */
301   HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
302   HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
303   HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
304   HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
305
306   /* Round 4 */
307   II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
308   II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
309   II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
310   II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
311   II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
312   II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
313   II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
314   II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
315   II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
316   II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
317   II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
318   II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
319   II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
320   II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
321   II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
322   II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
323
324   state[0] += a;
325   state[1] += b;
326   state[2] += c;
327   state[3] += d;
328
329   // Zeroize sensitive information.
330   memset ( (uint8_t* ) x, 0, sizeof(x));
331 }
332
333 void MD5::encode (uint8_t* output, uint32_t* input, uint32_t len) {
334   unsigned int i, j;
335
336   for (i = 0, j = 0; j < len; i++, j += 4) {
337     output[j]   = (uint8_t) (input[i] & 0xff);
338     output[j+1] = (uint8_t) ((input[i] >> 8) & 0xff);
339     output[j+2] = (uint8_t) ((input[i] >> 16) & 0xff);
340     output[j+3] = (uint8_t) ((input[i] >> 24) & 0xff);
341   }
342 }
343
344 void MD5::decode (uint32_t* output, uint8_t* input, uint32_t len) {
345   unsigned int i, j;
346
347   for (i = 0, j = 0; j < len; i++, j += 4) {
348     output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) | (((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24);
349   }
350 }
351
352 // Note: Replace "for loop" with standard memcpy if possible.
353 void MD5::memcpy (uint8_t* output, uint8_t* input, uint32_t len) {
354   unsigned int i;
355
356   for (i = 0; i < len; i++) output[i] = input[i];
357 }
358
359 // Note: Replace "for loop" with standard memset if possible.
360 void MD5::memset (uint8_t* output, uint8_t value, uint32_t len) {
361   unsigned int i;
362
363   for (i = 0; i < len; i++) output[i] = value;
364 }
365
366 inline unsigned int MD5::rotate_left(uint32_t x, uint32_t n) {
367   return (x << n) | (x >> (32-n));
368 }
369
370 inline unsigned int MD5::F(uint32_t x, uint32_t y, uint32_t z) {
371   return (x & y) | (~x & z);
372 }
373
374 inline unsigned int MD5::G(uint32_t x, uint32_t y, uint32_t z) {
375   return (x & z) | (y & ~z);
376 }
377
378 inline unsigned int MD5::H(uint32_t x, uint32_t y, uint32_t z) {
379   return x ^ y ^ z;
380 }
381
382 inline unsigned int MD5::I(uint32_t x, uint32_t y, uint32_t z) {
383   return y ^ (x | ~z);
384 }
385
386 inline void MD5::FF(uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac) {
387   a += F(b, c, d) + x + ac;
388   a = rotate_left (a, s) +b;
389 }
390
391 inline void MD5::GG(uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac) {
392   a += G(b, c, d) + x + ac;
393   a = rotate_left (a, s) +b;
394 }
395
396 inline void MD5::HH(uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac) {
397   a += H(b, c, d) + x + ac;
398   a = rotate_left (a, s) +b;
399 }
400
401 inline void MD5::II(uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac) {
402   a += I(b, c, d) + x + ac;
403   a = rotate_left (a, s) +b;
404 }
405
406 /* EOF */