00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 #include "md5.hh"
00049 
00050 #include <assert.h>
00051 #include <string>
00052 #include <iostream>
00053 
00054 
00055 
00056 
00057 
00058 
00059 _MD5::_MD5(){
00060 
00061   init();
00062 
00063 }
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 void _MD5::update (uint1 *input, uint4 input_length) {
00073 
00074   uint4 input_index, buffer_index;
00075   uint4 buffer_space;                
00076 
00077   if (finalized){  
00078     cerr << "_MD5::update:  Can't update a finalized digest!" << endl;
00079     return;
00080   }
00081 
00082   
00083   buffer_index = (unsigned int)((count[0] >> 3) & 0x3F);
00084 
00085   
00086   if (  (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) )
00087     count[1]++;
00088 
00089   count[1] += ((uint4)input_length >> 29);
00090 
00091 
00092   buffer_space = 64 - buffer_index;  
00093 
00094   
00095   if (input_length >= buffer_space) { 
00096     
00097     memcpy (buffer + buffer_index, input, buffer_space);
00098     transform (buffer);
00099 
00100     
00101     for (input_index = buffer_space; input_index + 63 < input_length;
00102      input_index += 64)
00103       transform (input+input_index);
00104 
00105     buffer_index = 0;  
00106   }
00107   else
00108     input_index=0;     
00109 
00110 
00111   
00112   memcpy(buffer+buffer_index, input+input_index, input_length-input_index);
00113 }
00114 
00115 
00116 
00117 
00118 
00119 
00120 void _MD5::update(FILE *file){
00121 
00122   unsigned char buffer[1024];
00123   int len;
00124 
00125   while (len=fread(buffer, 1, 1024, file))
00126     update(buffer, len);
00127 
00128   fclose (file);
00129 
00130 }
00131 
00132 
00133 
00134 
00135 
00136 
00137 
00138 
00139 
00140 void _MD5::update(istream& stream){
00141 
00142   unsigned char buffer[1024];
00143   int len;
00144 
00145   while (stream.good()){
00146     stream.read((char*)buffer, 1024); 
00147     len=stream.gcount();
00148     update(buffer, len);
00149   }
00150 
00151 }
00152 
00153 
00154 
00155 
00156 
00157 
00158 
00159 
00160 
00161 void _MD5::update(ifstream& stream){
00162 
00163   unsigned char buffer[1024];
00164   int len;
00165 
00166   while (stream.good()){
00167     stream.read((char*)buffer, 1024); 
00168     len=stream.gcount();
00169     update(buffer, len);
00170   }
00171 
00172 }
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 void _MD5::finalize (){
00184 
00185   unsigned char bits[8];
00186   unsigned int index, padLen;
00187   static uint1 PADDING[64]={
00188     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00189     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00190     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00191     };
00192 
00193   if (finalized){
00194     cerr << "_MD5::finalize:  Already finalized this digest!" << endl;
00195     return;
00196   }
00197 
00198   
00199   encode (bits, count, 8);
00200 
00201   
00202   index = (uint4) ((count[0] >> 3) & 0x3f);
00203   padLen = (index < 56) ? (56 - index) : (120 - index);
00204   update (PADDING, padLen);
00205 
00206   
00207   update (bits, 8);
00208 
00209   
00210   encode (digest, state, 16);
00211 
00212   
00213   memset (buffer, 0, sizeof(*buffer));
00214 
00215   finalized=1;
00216 
00217 }
00218 
00219 
00220 
00221 
00222 _MD5::_MD5(FILE *file){
00223 
00224   init();  
00225   update(file);
00226   finalize ();
00227 }
00228 
00229 
00230 
00231 
00232 _MD5::_MD5(istream& stream){
00233 
00234   init();  
00235   update (stream);
00236   finalize();
00237 }
00238 
00239 
00240 
00241 _MD5::_MD5(ifstream& stream){
00242 
00243   init();  
00244   update (stream);
00245   finalize();
00246 }
00247 
00248 
00249 
00250 unsigned char *_MD5::raw_digest(){
00251 
00252   uint1 *s = new uint1[16];
00253 
00254   if (!finalized){
00255     cerr << "_MD5::raw_digest:  Can't get digest if you haven't "<<
00256       "finalized the digest!" <<endl;
00257     return ( (unsigned char*) "");
00258   }
00259 
00260   memcpy(s, digest, 16);
00261   return s;
00262 }
00263 
00264 
00265 
00266 char *_MD5::hex_digest(){
00267 
00268   int i;
00269   char *s= new char[33];
00270 
00271   if (!finalized){
00272     cerr << "_MD5::hex_digest:  Can't get digest if you haven't "<<
00273       "finalized the digest!" <<endl;
00274     return "";
00275   }
00276 
00277   for (i=0; i<16; i++)
00278     sprintf(s+i*2, "%02x", digest[i]);
00279 
00280   s[32]='\0';
00281 
00282   return s;
00283 }
00284 
00285 
00286 
00287 
00288 
00289 ostream& operator<<(ostream &stream, _MD5 context){
00290 
00291   stream << context.hex_digest();
00292   return stream;
00293 }
00294 
00295 
00296 
00297 
00298 
00299 
00300 
00301 
00302 void _MD5::init(){
00303   finalized=0;  
00304 
00305   
00306   count[0] = 0;
00307   count[1] = 0;
00308 
00309   
00310   state[0] = 0x67452301;
00311   state[1] = 0xefcdab89;
00312   state[2] = 0x98badcfe;
00313   state[3] = 0x10325476;
00314 }
00315 
00316 
00317 
00318 
00319 
00320 
00321 
00322 #define S11 7
00323 #define S12 12
00324 #define S13 17
00325 #define S14 22
00326 #define S21 5
00327 #define S22 9
00328 #define S23 14
00329 #define S24 20
00330 #define S31 4
00331 #define S32 11
00332 #define S33 16
00333 #define S34 23
00334 #define S41 6
00335 #define S42 10
00336 #define S43 15
00337 #define S44 21
00338 
00339 
00340 
00341 
00342 
00343 void _MD5::transform (uint1 block[64]){
00344 
00345   uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
00346 
00347   decode (x, block, 64);
00348 
00349   assert(!finalized);  
00350 
00351   
00352   FF (a, b, c, d, x[ 0], S11, 0xd76aa478); 
00353   FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); 
00354   FF (c, d, a, b, x[ 2], S13, 0x242070db); 
00355   FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); 
00356   FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); 
00357   FF (d, a, b, c, x[ 5], S12, 0x4787c62a); 
00358   FF (c, d, a, b, x[ 6], S13, 0xa8304613); 
00359   FF (b, c, d, a, x[ 7], S14, 0xfd469501); 
00360   FF (a, b, c, d, x[ 8], S11, 0x698098d8); 
00361   FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); 
00362   FF (c, d, a, b, x[10], S13, 0xffff5bb1); 
00363   FF (b, c, d, a, x[11], S14, 0x895cd7be); 
00364   FF (a, b, c, d, x[12], S11, 0x6b901122); 
00365   FF (d, a, b, c, x[13], S12, 0xfd987193); 
00366   FF (c, d, a, b, x[14], S13, 0xa679438e); 
00367   FF (b, c, d, a, x[15], S14, 0x49b40821); 
00368 
00369  
00370   GG (a, b, c, d, x[ 1], S21, 0xf61e2562); 
00371   GG (d, a, b, c, x[ 6], S22, 0xc040b340); 
00372   GG (c, d, a, b, x[11], S23, 0x265e5a51); 
00373   GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); 
00374   GG (a, b, c, d, x[ 5], S21, 0xd62f105d); 
00375   GG (d, a, b, c, x[10], S22,  0x2441453); 
00376   GG (c, d, a, b, x[15], S23, 0xd8a1e681); 
00377   GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); 
00378   GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); 
00379   GG (d, a, b, c, x[14], S22, 0xc33707d6); 
00380   GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); 
00381   GG (b, c, d, a, x[ 8], S24, 0x455a14ed); 
00382   GG (a, b, c, d, x[13], S21, 0xa9e3e905); 
00383   GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); 
00384   GG (c, d, a, b, x[ 7], S23, 0x676f02d9); 
00385   GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); 
00386 
00387   
00388   HH (a, b, c, d, x[ 5], S31, 0xfffa3942); 
00389   HH (d, a, b, c, x[ 8], S32, 0x8771f681); 
00390   HH (c, d, a, b, x[11], S33, 0x6d9d6122); 
00391   HH (b, c, d, a, x[14], S34, 0xfde5380c); 
00392   HH (a, b, c, d, x[ 1], S31, 0xa4beea44); 
00393   HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); 
00394   HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); 
00395   HH (b, c, d, a, x[10], S34, 0xbebfbc70); 
00396   HH (a, b, c, d, x[13], S31, 0x289b7ec6); 
00397   HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); 
00398   HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); 
00399   HH (b, c, d, a, x[ 6], S34,  0x4881d05); 
00400   HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); 
00401   HH (d, a, b, c, x[12], S32, 0xe6db99e5); 
00402   HH (c, d, a, b, x[15], S33, 0x1fa27cf8); 
00403   HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); 
00404 
00405   
00406   II (a, b, c, d, x[ 0], S41, 0xf4292244); 
00407   II (d, a, b, c, x[ 7], S42, 0x432aff97); 
00408   II (c, d, a, b, x[14], S43, 0xab9423a7); 
00409   II (b, c, d, a, x[ 5], S44, 0xfc93a039); 
00410   II (a, b, c, d, x[12], S41, 0x655b59c3); 
00411   II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); 
00412   II (c, d, a, b, x[10], S43, 0xffeff47d); 
00413   II (b, c, d, a, x[ 1], S44, 0x85845dd1); 
00414   II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); 
00415   II (d, a, b, c, x[15], S42, 0xfe2ce6e0); 
00416   II (c, d, a, b, x[ 6], S43, 0xa3014314); 
00417   II (b, c, d, a, x[13], S44, 0x4e0811a1); 
00418   II (a, b, c, d, x[ 4], S41, 0xf7537e82); 
00419   II (d, a, b, c, x[11], S42, 0xbd3af235); 
00420   II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); 
00421   II (b, c, d, a, x[ 9], S44, 0xeb86d391); 
00422 
00423   state[0] += a;
00424   state[1] += b;
00425   state[2] += c;
00426   state[3] += d;
00427 
00428   
00429   memset ( (uint1 *) x, 0, sizeof(x));
00430 
00431 }
00432 
00433 
00434 
00435 
00436 
00437 void _MD5::encode (uint1 *output, uint4 *input, uint4 len) {
00438 
00439   unsigned int i, j;
00440 
00441   for (i = 0, j = 0; j < len; i++, j += 4) {
00442     output[j]   = (uint1)  (input[i] & 0xff);
00443     output[j+1] = (uint1) ((input[i] >> 8) & 0xff);
00444     output[j+2] = (uint1) ((input[i] >> 16) & 0xff);
00445     output[j+3] = (uint1) ((input[i] >> 24) & 0xff);
00446   }
00447 }
00448 
00449 
00450 
00451 
00452 
00453 
00454 void _MD5::decode (uint4 *output, uint1 *input, uint4 len){
00455 
00456   unsigned int i, j;
00457 
00458   for (i = 0, j = 0; j < len; i++, j += 4)
00459     output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
00460       (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
00461 }
00462 
00463 
00464 
00465 
00466 
00467 
00468 void _MD5::memcpy (uint1 *output, uint1 *input, uint4 len){
00469 
00470   unsigned int i;
00471 
00472   for (i = 0; i < len; i++)
00473     output[i] = input[i];
00474 }
00475 
00476 
00477 
00478 
00479 void _MD5::memset (uint1 *output, uint1 value, uint4 len){
00480 
00481   unsigned int i;
00482 
00483   for (i = 0; i < len; i++)
00484     output[i] = value;
00485 }
00486 
00487 
00488 
00489 
00490 
00491 inline unsigned int _MD5::rotate_left  (uint4 x, uint4 n){
00492   return (x << n) | (x >> (32-n))  ;
00493 }
00494 
00495 
00496 
00497 
00498 
00499 
00500 inline unsigned int _MD5::F            (uint4 x, uint4 y, uint4 z){
00501   return (x & y) | (~x & z);
00502 }
00503 
00504 inline unsigned int _MD5::G            (uint4 x, uint4 y, uint4 z){
00505   return (x & z) | (y & ~z);
00506 }
00507 
00508 inline unsigned int _MD5::H            (uint4 x, uint4 y, uint4 z){
00509   return x ^ y ^ z;
00510 }
00511 
00512 inline unsigned int _MD5::I            (uint4 x, uint4 y, uint4 z){
00513   return y ^ (x | ~z);
00514 }
00515 
00516 
00517 
00518 
00519 
00520 
00521 
00522 inline void _MD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
00523             uint4  s, uint4 ac){
00524  a += F(b, c, d) + x + ac;
00525  a = rotate_left (a, s) +b;
00526 }
00527 
00528 inline void _MD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
00529             uint4 s, uint4 ac){
00530  a += G(b, c, d) + x + ac;
00531  a = rotate_left (a, s) +b;
00532 }
00533 
00534 inline void _MD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
00535             uint4 s, uint4 ac){
00536  a += H(b, c, d) + x + ac;
00537  a = rotate_left (a, s) +b;
00538 }
00539 
00540 inline void _MD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
00541                  uint4 s, uint4 ac){
00542  a += I(b, c, d) + x + ac;
00543  a = rotate_left (a, s) +b;
00544 }