]> git.jsancho.org Git - lugaru.git/blob - Source/MD5.CC
Added GPL license and headers.
[lugaru.git] / Source / MD5.CC
1 /*
2 Copyright (C) 2003, 2010 - Wolfire Games
3
4 This file is part of Lugaru.
5
6 Lugaru is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
14
15 See the GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 */
21
22 // MD5.CC - source code for the C++/object oriented translation and 
23 //          modification of MD5.
24
25 // Translation and modification (c) 1995 by Mordechai T. Abzug 
26
27 // This translation/ modification is provided "as is," without express or 
28 // implied warranty of any kind.
29
30 // The translator/ modifier does not claim (1) that MD5 will do what you think 
31 // it does; (2) that this translation/ modification is accurate; or (3) that 
32 // this software is "merchantible."  (Language for this disclaimer partially 
33 // copied from the disclaimer below).
34
35 /* based on:
36
37 MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
38 MDDRIVER.C - test driver for MD2, MD4 and MD5
39
40
41 Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
42 rights reserved.
43
44 License to copy and use this software is granted provided that it
45 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
46 Algorithm" in all material mentioning or referencing this software
47 or this function.
48
49 License is also granted to make and use derivative works provided
50 that such works are identified as "derived from the RSA Data
51 Security, Inc. MD5 Message-Digest Algorithm" in all material
52 mentioning or referencing the derived work.
53
54 RSA Data Security, Inc. makes no representations concerning either
55 the merchantability of this software or the suitability of this
56 software for any particular purpose. It is provided "as is"
57 without express or implied warranty of any kind.
58
59 These notices must be retained in any copies of any part of this
60 documentation and/or software.
61
62 */
63
64
65
66
67
68
69 #include "md5.h"
70
71 #include <assert.h>
72 //#include <strings.h>
73 #include <iostream>
74
75
76
77
78 // MD5 simple initialization method
79
80 MD5::MD5(){
81
82         init();
83
84 }
85
86
87
88
89 // MD5 block update operation. Continues an MD5 message-digest
90 // operation, processing another message block, and updating the
91 // context.
92
93 void MD5::update (uint1 *input, uint4 input_length) {
94
95         uint4 input_index, buffer_index;
96         uint4 buffer_space;                // how much space is left in buffer
97
98         if (finalized){  // so we can't update!
99                 cerr << "MD5::update:  Can't update a finalized digest!" << endl;
100                 return;
101         }
102
103         // Compute number of bytes mod 64
104         buffer_index = (unsigned int)((count[0] >> 3) & 0x3F);
105
106         // Update number of bits
107         if (  (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) )
108                 count[1]++;
109
110         count[1] += ((uint4)input_length >> 29);
111
112
113         buffer_space = 64 - buffer_index;  // how much space is left in buffer
114
115         // Transform as many times as possible.
116         if (input_length >= buffer_space) { // ie. we have enough to fill the buffer
117                 // fill the rest of the buffer and transform
118                 memcpy (buffer + buffer_index, input, buffer_space);
119                 transform (buffer);
120
121                 // now, transform each 64-byte piece of the input, bypassing the buffer
122                 for (input_index = buffer_space; input_index + 63 < input_length; 
123                         input_index += 64)
124                         transform (input+input_index);
125
126                 buffer_index = 0;  // so we can buffer remaining
127         }
128         else
129                 input_index=0;     // so we can buffer the whole input
130
131
132         // and here we do the buffering:
133         memcpy(buffer+buffer_index, input+input_index, input_length-input_index);
134 }
135
136
137
138 // MD5 update for files.
139 // Like above, except that it works on files (and uses above as a primitive.)
140
141 void MD5::update(FILE *file){
142
143         unsigned char buffer[1024];
144         int len;
145
146         while (len=fread(buffer, 1, 1024, file))
147                 update(buffer, len);
148
149         fclose (file);
150
151 }
152
153
154
155
156
157
158 // MD5 update for istreams.
159 // Like update for files; see above.
160
161 void MD5::update(istream& stream){
162
163         unsigned char buffer[1024];
164         int len;
165
166         while (stream.good()){
167                 stream.read((char *)buffer, (long)1024); // note that return value of read is unusable.
168                 len=stream.gcount();
169                 update(buffer, len);
170         }
171
172 }
173
174
175
176
177
178
179 // MD5 update for ifstreams.
180 // Like update for files; see above.
181
182 void MD5::update(ifstream& stream){
183
184         unsigned char buffer[1024];
185         int len;
186
187         while (stream.good()){
188                 stream.read((char *)buffer, (long)1024); // note that return value of read is unusable.
189                 len=stream.gcount();
190                 update(buffer, len);
191         }
192
193 }
194
195
196
197
198
199
200 // MD5 finalization. Ends an MD5 message-digest operation, writing the
201 // the message digest and zeroizing the context.
202
203
204 void MD5::finalize (){
205
206         unsigned char bits[8];
207         unsigned int index, padLen;
208         static uint1 PADDING[64]={
209                 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
210                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
211                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
212         };
213
214         if (finalized){
215                 cerr << "MD5::finalize:  Already finalized this digest!" << endl;
216                 return;
217         }
218
219         // Save number of bits
220         encode (bits, count, 8);
221
222         // Pad out to 56 mod 64.
223         index = (uint4) ((count[0] >> 3) & 0x3f);
224         padLen = (index < 56) ? (56 - index) : (120 - index);
225         update (PADDING, padLen);
226
227         // Append length (before padding)
228         update (bits, 8);
229
230         // Store state in digest
231         encode (digest, state, 16);
232
233         // Zeroize sensitive information
234         memset (buffer, 0, sizeof(*buffer));
235
236         finalized=1;
237
238 }
239
240
241
242
243 MD5::MD5(FILE *file){
244
245         init();  // must be called be all constructors
246         update(file);
247         finalize ();
248 }
249
250
251
252
253 MD5::MD5(istream& stream){
254
255         init();  // must called by all constructors
256         update (stream);
257         finalize();
258 }
259
260
261
262 MD5::MD5(ifstream& stream){
263
264         init();  // must called by all constructors
265         update (stream);
266         finalize();
267 }
268
269
270
271 unsigned char *MD5::raw_digest(){
272
273         uint1 *s = new uint1[16];
274
275         if (!finalized){
276                 cerr << "MD5::raw_digest:  Can't get digest if you haven't "<<
277                         "finalized the digest!" <<endl;
278                 return ( (unsigned char*) "");
279         }
280
281         memcpy(s, digest, 16);
282         return s;
283 }
284
285
286
287 char *MD5::hex_digest(){
288
289         int i;
290         char *s= new char[33];
291
292         if (!finalized){
293                 cerr << "MD5::hex_digest:  Can't get digest if you haven't "<<
294                         "finalized the digest!" <<endl;
295                 return "";
296         }
297
298         for (i=0; i<16; i++)
299                 sprintf(s+i*2, "%02x", digest[i]);
300
301         s[32]='\0';
302
303         return s;
304 }
305
306
307
308
309
310 ostream& operator<<(ostream &stream, MD5 context){
311
312         stream << context.hex_digest();
313         return stream;
314 }
315
316
317
318
319 // PRIVATE METHODS:
320
321
322
323 void MD5::init(){
324         finalized=0;  // we just started!
325
326         // Nothing counted, so count=0
327         count[0] = 0;
328         count[1] = 0;
329
330         // Load magic initialization constants.
331         state[0] = 0x67452301;
332         state[1] = 0xefcdab89;
333         state[2] = 0x98badcfe;
334         state[3] = 0x10325476;
335 }
336
337
338
339 // Constants for MD5Transform routine.
340 // Although we could use C++ style constants, defines are actually better,
341 // since they let us easily evade scope clashes.
342
343 #define S11 7
344 #define S12 12
345 #define S13 17
346 #define S14 22
347 #define S21 5
348 #define S22 9
349 #define S23 14
350 #define S24 20
351 #define S31 4
352 #define S32 11
353 #define S33 16
354 #define S34 23
355 #define S41 6
356 #define S42 10
357 #define S43 15
358 #define S44 21
359
360
361
362
363 // MD5 basic transformation. Transforms state based on block.
364 void MD5::transform (uint1 block[64]){
365
366         uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
367
368         decode (x, block, 64);
369
370         assert(!finalized);  // not just a user error, since the method is private
371
372         /* Round 1 */
373         FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
374         FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
375         FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
376         FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
377         FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
378         FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
379         FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
380         FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
381         FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
382         FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
383         FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
384         FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
385         FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
386         FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
387         FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
388         FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
389
390         /* Round 2 */
391         GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
392         GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
393         GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
394         GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
395         GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
396         GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
397         GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
398         GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
399         GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
400         GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
401         GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
402         GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
403         GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
404         GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
405         GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
406         GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
407
408         /* Round 3 */
409         HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
410         HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
411         HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
412         HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
413         HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
414         HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
415         HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
416         HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
417         HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
418         HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
419         HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
420         HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
421         HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
422         HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
423         HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
424         HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
425
426         /* Round 4 */
427         II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
428         II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
429         II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
430         II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
431         II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
432         II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
433         II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
434         II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
435         II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
436         II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
437         II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
438         II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
439         II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
440         II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
441         II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
442         II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
443
444         state[0] += a;
445         state[1] += b;
446         state[2] += c;
447         state[3] += d;
448
449         // Zeroize sensitive information.
450         memset ( (uint1 *) x, 0, sizeof(x));
451
452 }
453
454
455
456 // Encodes input (UINT4) into output (unsigned char). Assumes len is
457 // a multiple of 4.
458 void MD5::encode (uint1 *output, uint4 *input, uint4 len) {
459
460         unsigned int i, j;
461
462         for (i = 0, j = 0; j < len; i++, j += 4) {
463                 output[j]   = (uint1)  (input[i] & 0xff);
464                 output[j+1] = (uint1) ((input[i] >> 8) & 0xff);
465                 output[j+2] = (uint1) ((input[i] >> 16) & 0xff);
466                 output[j+3] = (uint1) ((input[i] >> 24) & 0xff);
467         }
468 }
469
470
471
472
473 // Decodes input (unsigned char) into output (UINT4). Assumes len is
474 // a multiple of 4.
475 void MD5::decode (uint4 *output, uint1 *input, uint4 len){
476
477         unsigned int i, j;
478
479         for (i = 0, j = 0; j < len; i++, j += 4)
480                 output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
481                 (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
482 }
483
484
485
486
487
488 // Note: Replace "for loop" with standard memcpy if possible.
489 void MD5::memcpy (uint1 *output, uint1 *input, uint4 len){
490
491         unsigned int i;
492
493         for (i = 0; i < len; i++)
494                 output[i] = input[i];
495 }
496
497
498
499 // Note: Replace "for loop" with standard memset if possible.
500 void MD5::memset (uint1 *output, uint1 value, uint4 len){
501
502         unsigned int i;
503
504         for (i = 0; i < len; i++)
505                 output[i] = value;
506 }
507
508
509
510 // ROTATE_LEFT rotates x left n bits.
511
512 inline unsigned int MD5::rotate_left  (uint4 x, uint4 n){
513         return (x << n) | (x >> (32-n))  ;
514 }
515
516
517
518
519 // F, G, H and I are basic MD5 functions.
520
521 inline unsigned int MD5::F            (uint4 x, uint4 y, uint4 z){
522         return (x & y) | (~x & z);
523 }
524
525 inline unsigned int MD5::G            (uint4 x, uint4 y, uint4 z){
526         return (x & z) | (y & ~z);
527 }
528
529 inline unsigned int MD5::H            (uint4 x, uint4 y, uint4 z){
530         return x ^ y ^ z;
531 }
532
533 inline unsigned int MD5::I            (uint4 x, uint4 y, uint4 z){
534         return y ^ (x | ~z);
535 }
536
537
538
539 // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
540 // Rotation is separate from addition to prevent recomputation.
541
542
543 inline void MD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
544                                         uint4  s, uint4 ac){
545                                                 a += F(b, c, d) + x + ac;
546                                                 a = rotate_left (a, s) +b;
547                                         }
548
549                                         inline void MD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
550                                                 uint4 s, uint4 ac){
551                                                         a += G(b, c, d) + x + ac;
552                                                         a = rotate_left (a, s) +b;
553                                                 }
554
555                                                 inline void MD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
556                                                         uint4 s, uint4 ac){
557                                                                 a += H(b, c, d) + x + ac;
558                                                                 a = rotate_left (a, s) +b;
559                                                         }
560
561                                                         inline void MD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
562                                                                 uint4 s, uint4 ac){
563                                                                         a += I(b, c, d) + x + ac;
564                                                                         a = rotate_left (a, s) +b;
565                                                                 }
566