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
49MD5::MD5() :
50 buffer(),
51 digest(),
52 finalized()
53{
54 init();
55}
56
57void 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 = static_cast<unsigned int>((count[0] >> 3) & 0x3F);
66
67 // Update number of bits
68 if ( (count[0] += (static_cast<uint32_t>(input_length) << 3))<(static_cast<uint32_t>(input_length) << 3) ) count[1]++;
69
70 count[1] += (static_cast<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
93void MD5::update(FILE *file) {
94 uint8_t buffer_[1024];
95 size_t len;
96
97 while ((len = fread(buffer_, 1, 1024, file))) update(buffer_, static_cast<int>(len));
98
99 fclose (file);
100}
101
102void MD5::update(std::istream& stream) {
103 uint8_t buffer_[1024];
104
105 while (stream.good()) {
106 stream.read(reinterpret_cast<char*>(buffer_), 1024); // note that return value of read is unusable.
107 size_t len = stream.gcount();
108 update(buffer_, static_cast<unsigned int>(len));
109 }
110}
111
112void MD5::update(std::ifstream& stream) {
113 uint8_t buffer_[1024];
114
115 while (stream.good()) {
116 stream.read(reinterpret_cast<char*>(buffer_), 1024); // note that return value of read is unusable.
117 size_t len = stream.gcount();
118 update(buffer_, static_cast<unsigned int>(len));
119 }
120}
121
122MD5::MD5(FILE *file) :
123 finalized()
124{
125 init(); // must be called be all constructors
126 update(file);
127 finalize ();
128}
129
130MD5::MD5(std::istream& stream) :
131 finalized()
132{
133 init(); // must called by all constructors
134 update (stream);
135 finalize();
136}
137
138MD5::MD5(std::ifstream& stream) :
139 finalized()
140{
141 init(); // must called by all constructors
142 update (stream);
143 finalize();
144}
145
146uint8_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
155std::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
172std::ostream& operator<<(std::ostream &stream, MD5 context) {
173 stream << context.hex_digest().c_str();
174 return stream;
175}
176
177// PRIVATE METHODS:
178
179void 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
193void 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 = static_cast<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
245void 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 ( reinterpret_cast<uint8_t*>(x), 0, sizeof(x));
331}
332
333void 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] = static_cast<uint8_t>(input[i] & 0xff);
338 output[j+1] = static_cast<uint8_t>((input[i] >> 8) & 0xff);
339 output[j+2] = static_cast<uint8_t>((input[i] >> 16) & 0xff);
340 output[j+3] = static_cast<uint8_t>((input[i] >> 24) & 0xff);
341 }
342}
343
344void 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] = (static_cast<uint32_t>(input[j])) | ((static_cast<uint32_t>(input[j+1])) << 8) | ((static_cast<uint32_t>(input[j+2])) << 16) | ((static_cast<uint32_t>(input[j+3])) << 24);
349 }
350}
351
352// Note: Replace "for loop" with standard memcpy if possible.
353void 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.
360void 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
366inline unsigned int MD5::rotate_left(uint32_t x, uint32_t n) {
367 return (x << n) | (x >> (32-n));
368}
369
370inline unsigned int MD5::F(uint32_t x, uint32_t y, uint32_t z) {
371 return (x & y) | (~x & z);
372}
373
374inline unsigned int MD5::G(uint32_t x, uint32_t y, uint32_t z) {
375 return (x & z) | (y & ~z);
376}
377
378inline unsigned int MD5::H(uint32_t x, uint32_t y, uint32_t z) {
379 return x ^ y ^ z;
380}
381
382inline unsigned int MD5::I(uint32_t x, uint32_t y, uint32_t z) {
383 return y ^ (x | ~z);
384}
385
386inline 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
391inline 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
396inline 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
401inline 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 */
407