[cppcheck] Part 2: Some further style fixes etc.
[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   return s;
166 }
167
168 std::ostream& operator<<(std::ostream &stream, MD5 context) {
169   stream << context.hex_digest();
170   return stream;
171 }
172
173 // PRIVATE METHODS:
174
175 void MD5::init() {
176   finalized=false;
177
178   // Nothing counted, so count=0
179   count[0] = 0;
180   count[1] = 0;
181
182   // Load magic initialization constants.
183   state[0] = 0x67452301;
184   state[1] = 0xefcdab89;
185   state[2] = 0x98badcfe;
186   state[3] = 0x10325476;
187 }
188
189 void MD5::finalize() {
190   if (finalized) return;
191
192   uint8_t bits[8];
193   unsigned int index, padLen;
194   static uint8_t PADDING[64]={
195     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
196     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
197     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
198   };
199
200   // Save number of bits
201   encode (bits, count, 8);
202
203   // Pad out to 56 mod 64.
204   index = (uint32_t) ((count[0] >> 3) & 0x3f);
205   padLen = (index < 56) ? (56 - index) : (120 - index);
206   update (PADDING, padLen);
207
208   // Append length (before padding)
209   update (bits, 8);
210
211   // Store state in digest
212   encode (digest, state, 16);
213
214   // Zeroize sensitive information
215   memset (buffer, 0, sizeof(*buffer));
216
217   finalized=true;
218 }
219
220 // Constants for MD5Transform routine.
221 // Although we could use C++ style constants, defines are actually better,
222 // since they let us easily evade scope clashes.
223
224 #define S11 7
225 #define S12 12
226 #define S13 17
227 #define S14 22
228 #define S21 5
229 #define S22 9
230 #define S23 14
231 #define S24 20
232 #define S31 4
233 #define S32 11
234 #define S33 16
235 #define S34 23
236 #define S41 6
237 #define S42 10
238 #define S43 15
239 #define S44 21
240
241 void MD5::transform (uint8_t block[64]) {
242   uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
243
244   decode (x, block, 64);
245
246   assert(!finalized); // not just a user error, since the method is private
247
248   /* Round 1 */
249   FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
250   FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
251   FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
252   FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
253   FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
254   FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
255   FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
256   FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
257   FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
258   FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
259   FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
260   FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
261   FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
262   FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
263   FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
264   FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
265
266   /* Round 2 */
267   GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
268   GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
269   GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
270   GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
271   GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
272   GG (d, a, b, c, x[10], S22, 0x02441453); /* 22 */
273   GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
274   GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
275   GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
276   GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
277   GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
278   GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
279   GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
280   GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
281   GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
282   GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
283
284   /* Round 3 */
285   HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
286   HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
287   HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
288   HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
289   HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
290   HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
291   HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
292   HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
293   HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
294   HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
295   HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
296   HH (b, c, d, a, x[ 6], S34, 0x04881d05); /* 44 */
297   HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
298   HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
299   HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
300   HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
301
302   /* Round 4 */
303   II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
304   II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
305   II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
306   II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
307   II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
308   II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
309   II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
310   II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
311   II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
312   II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
313   II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
314   II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
315   II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
316   II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
317   II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
318   II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
319
320   state[0] += a;
321   state[1] += b;
322   state[2] += c;
323   state[3] += d;
324
325   // Zeroize sensitive information.
326   memset ( (uint8_t* ) x, 0, sizeof(x));
327 }
328
329 void MD5::encode (uint8_t* output, uint32_t* input, uint32_t len) {
330   unsigned int i, j;
331
332   for (i = 0, j = 0; j < len; i++, j += 4) {
333     output[j]   = (uint8_t) (input[i] & 0xff);
334     output[j+1] = (uint8_t) ((input[i] >> 8) & 0xff);
335     output[j+2] = (uint8_t) ((input[i] >> 16) & 0xff);
336     output[j+3] = (uint8_t) ((input[i] >> 24) & 0xff);
337   }
338 }
339
340 void MD5::decode (uint32_t* output, uint8_t* input, uint32_t len) {
341   unsigned int i, j;
342
343   for (i = 0, j = 0; j < len; i++, j += 4) {
344     output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) | (((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24);
345   }
346 }
347
348 // Note: Replace "for loop" with standard memcpy if possible.
349 void MD5::memcpy (uint8_t* output, uint8_t* input, uint32_t len) {
350   unsigned int i;
351
352   for (i = 0; i < len; i++) output[i] = input[i];
353 }
354
355 // Note: Replace "for loop" with standard memset if possible.
356 void MD5::memset (uint8_t* output, uint8_t value, uint32_t len) {
357   unsigned int i;
358
359   for (i = 0; i < len; i++) output[i] = value;
360 }
361
362 inline unsigned int MD5::rotate_left(uint32_t x, uint32_t n) {
363   return (x << n) | (x >> (32-n));
364 }
365
366 inline unsigned int MD5::F(uint32_t x, uint32_t y, uint32_t z) {
367   return (x & y) | (~x & z);
368 }
369
370 inline unsigned int MD5::G(uint32_t x, uint32_t y, uint32_t z) {
371   return (x & z) | (y & ~z);
372 }
373
374 inline unsigned int MD5::H(uint32_t x, uint32_t y, uint32_t z) {
375   return x ^ y ^ z;
376 }
377
378 inline unsigned int MD5::I(uint32_t x, uint32_t y, uint32_t z) {
379   return y ^ (x | ~z);
380 }
381
382 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) {
383   a += F(b, c, d) + x + ac;
384   a = rotate_left (a, s) +b;
385 }
386
387 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) {
388   a += G(b, c, d) + x + ac;
389   a = rotate_left (a, s) +b;
390 }
391
392 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) {
393   a += H(b, c, d) + x + ac;
394   a = rotate_left (a, s) +b;
395 }
396
397 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) {
398   a += I(b, c, d) + x + ac;
399   a = rotate_left (a, s) +b;
400 }
401
402 /* EOF */