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