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