core/md5.cpp
author Matt Woodrow <pred@alliedmods.net>
Fri Aug 08 00:17:37 2008 +0000 (2008-08-08)
changeset 2224 676c3b826f13
parent 2142 d9d876e97a66
child 2471 194be299b700
permissions -rw-r--r--
Initial Import of beta structs extension.
     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 #include "md5.h"
    44 
    45 #include <assert.h>
    46 #include <string.h>
    47 
    48 // MD5 simple initialization method
    49 
    50 MD5::MD5(){
    51 
    52   init();
    53 
    54 }
    55 
    56 
    57 // MD5 block update operation. Continues an MD5 message-digest
    58 // operation, processing another message block, and updating the
    59 // context.
    60 
    61 void MD5::update (uint1 *input, uint4 input_length) {
    62 
    63   uint4 input_index, buffer_index;
    64   uint4 buffer_space;                // how much space is left in buffer
    65 
    66   if (finalized){  // so we can't update!
    67     /*cerr << "MD5::update:  Can't update a finalized digest!" << endl;*/
    68     return;
    69   }
    70 
    71   // Compute number of bytes mod 64
    72   buffer_index = (unsigned int)((count[0] >> 3) & 0x3F);
    73 
    74   // Update number of bits
    75   if (  (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) )
    76     count[1]++;
    77 
    78   count[1] += ((uint4)input_length >> 29);
    79 
    80 
    81   buffer_space = 64 - buffer_index;  // how much space is left in buffer
    82 
    83   // Transform as many times as possible.
    84   if (input_length >= buffer_space) { // ie. we have enough to fill the buffer
    85     // fill the rest of the buffer and transform
    86     memcpy (buffer + buffer_index, input, buffer_space);
    87     transform (buffer);
    88 
    89     // now, transform each 64-byte piece of the input, bypassing the buffer
    90     for (input_index = buffer_space; input_index + 63 < input_length; 
    91 	 input_index += 64)
    92       transform (input+input_index);
    93 
    94     buffer_index = 0;  // so we can buffer remaining
    95   }
    96   else
    97     input_index=0;     // so we can buffer the whole input
    98 
    99 
   100   // and here we do the buffering:
   101   memcpy(buffer+buffer_index, input+input_index, input_length-input_index);
   102 }
   103 
   104 
   105 
   106 // MD5 update for files.
   107 // Like above, except that it works on files (and uses above as a primitive.)
   108 
   109 void MD5::update(FILE *file){
   110 
   111   unsigned char buffer[1024];
   112   int len;
   113 
   114   while ((len=fread(buffer, 1, 1024, file)))
   115     update(buffer, len);
   116 
   117   fclose (file);
   118 
   119 }
   120 
   121 
   122 // MD5 finalization. Ends an MD5 message-digest operation, writing the
   123 // the message digest and zeroizing the context.
   124 
   125 
   126 void MD5::finalize (){
   127 
   128   unsigned char bits[8];
   129   unsigned int index, padLen;
   130   static uint1 PADDING[64]={
   131     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   132     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   133     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
   134     };
   135 
   136   if (finalized){
   137    /* cerr << "MD5::finalize:  Already finalized this digest!" << endl;*/
   138     return;
   139   }
   140 
   141   // Save number of bits
   142   encode (bits, count, 8);
   143 
   144   // Pad out to 56 mod 64.
   145   index = (uint4) ((count[0] >> 3) & 0x3f);
   146   padLen = (index < 56) ? (56 - index) : (120 - index);
   147   update (PADDING, padLen);
   148 
   149   // Append length (before padding)
   150   update (bits, 8);
   151 
   152   // Store state in digest
   153   encode (digest, state, 16);
   154 
   155   // Zeroize sensitive information
   156   memset (buffer, 0, sizeof(*buffer));
   157 
   158   finalized=1;
   159 
   160 }
   161 
   162 
   163 
   164 
   165 MD5::MD5(FILE *file){
   166 
   167   init();  // must be called be all constructors
   168   update(file);
   169   finalize ();
   170 }
   171 
   172 unsigned char *MD5::raw_digest(){
   173 
   174   uint1 *s = new uint1[16];
   175 
   176   if (!finalized){
   177 /*    cerr << "MD5::raw_digest:  Can't get digest if you haven't "<<
   178       "finalized the digest!" <<endl;*/
   179     return ( (unsigned char*) "");
   180   }
   181 
   182   memcpy(s, digest, 16);
   183   return s;
   184 }
   185 
   186 unsigned char *MD5::raw_digest(unsigned char buffer[16])
   187 {
   188 	if (!finalized)
   189 	{
   190 		return ( (unsigned char*) "");
   191 	}
   192 
   193 	 memcpy(buffer, digest, 16);
   194 	 return buffer;
   195 }
   196 
   197 
   198 
   199 char *MD5::hex_digest(){
   200 
   201   int i;
   202   char *s= new char[33];
   203 
   204   if (!finalized){
   205 /*    cerr << "MD5::hex_digest:  Can't get digest if you haven't "<<
   206       "finalized the digest!" <<endl;*/
   207     return "";
   208   }
   209 
   210   for (i=0; i<16; i++)
   211     sprintf(s+i*2, "%02x", digest[i]);
   212 
   213   s[32]='\0';
   214 
   215   return s;
   216 }
   217 
   218 
   219 char *MD5::hex_digest(char buffer[33]){
   220 
   221   int i;
   222 
   223   if (!finalized)
   224   {
   225 	 /* cerr << "MD5::hex_digest:  Can't get digest if you haven't "<<
   226       "finalized the digest!" <<endl;*/
   227     return "";
   228   }
   229 
   230   for (i=0; i<16; i++)
   231     sprintf(buffer+i*2, "%02x", digest[i]);
   232 
   233   buffer[32]='\0';
   234 
   235   return buffer;
   236 }
   237 
   238 
   239 // PRIVATE METHODS:
   240 
   241 
   242 
   243 void MD5::init(){
   244   finalized=0;  // we just started!
   245 
   246   // Nothing counted, so count=0
   247   count[0] = 0;
   248   count[1] = 0;
   249 
   250   // Load magic initialization constants.
   251   state[0] = 0x67452301;
   252   state[1] = 0xefcdab89;
   253   state[2] = 0x98badcfe;
   254   state[3] = 0x10325476;
   255 }
   256 
   257 
   258 
   259 // Constants for MD5Transform routine.
   260 // Although we could use C++ style constants, defines are actually better,
   261 // since they let us easily evade scope clashes.
   262 
   263 #define S11 7
   264 #define S12 12
   265 #define S13 17
   266 #define S14 22
   267 #define S21 5
   268 #define S22 9
   269 #define S23 14
   270 #define S24 20
   271 #define S31 4
   272 #define S32 11
   273 #define S33 16
   274 #define S34 23
   275 #define S41 6
   276 #define S42 10
   277 #define S43 15
   278 #define S44 21
   279 
   280 
   281 
   282 
   283 // MD5 basic transformation. Transforms state based on block.
   284 void MD5::transform (uint1 block[64]){
   285 
   286   uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
   287 
   288   decode (x, block, 64);
   289 
   290   assert(!finalized);  // not just a user error, since the method is private
   291 
   292   /* Round 1 */
   293   FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
   294   FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
   295   FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
   296   FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
   297   FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
   298   FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
   299   FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
   300   FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
   301   FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
   302   FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
   303   FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
   304   FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
   305   FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
   306   FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
   307   FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
   308   FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
   309 
   310  /* Round 2 */
   311   GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
   312   GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
   313   GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
   314   GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
   315   GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
   316   GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
   317   GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
   318   GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
   319   GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
   320   GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
   321   GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
   322   GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
   323   GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
   324   GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
   325   GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
   326   GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
   327 
   328   /* Round 3 */
   329   HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
   330   HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
   331   HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
   332   HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
   333   HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
   334   HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
   335   HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
   336   HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
   337   HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
   338   HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
   339   HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
   340   HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
   341   HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
   342   HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
   343   HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
   344   HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
   345 
   346   /* Round 4 */
   347   II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
   348   II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
   349   II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
   350   II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
   351   II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
   352   II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
   353   II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
   354   II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
   355   II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
   356   II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
   357   II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
   358   II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
   359   II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
   360   II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
   361   II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
   362   II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
   363 
   364   state[0] += a;
   365   state[1] += b;
   366   state[2] += c;
   367   state[3] += d;
   368 
   369   // Zeroize sensitive information.
   370   memset ( (uint1 *) x, 0, sizeof(x));
   371 
   372 }
   373 
   374 
   375 
   376 // Encodes input (UINT4) into output (unsigned char). Assumes len is
   377 // a multiple of 4.
   378 void MD5::encode (uint1 *output, uint4 *input, uint4 len) {
   379 
   380   unsigned int i, j;
   381 
   382   for (i = 0, j = 0; j < len; i++, j += 4) {
   383     output[j]   = (uint1)  (input[i] & 0xff);
   384     output[j+1] = (uint1) ((input[i] >> 8) & 0xff);
   385     output[j+2] = (uint1) ((input[i] >> 16) & 0xff);
   386     output[j+3] = (uint1) ((input[i] >> 24) & 0xff);
   387   }
   388 }
   389 
   390 
   391 
   392 
   393 // Decodes input (unsigned char) into output (UINT4). Assumes len is
   394 // a multiple of 4.
   395 void MD5::decode (uint4 *output, uint1 *input, uint4 len){
   396 
   397   unsigned int i, j;
   398 
   399   for (i = 0, j = 0; j < len; i++, j += 4)
   400     output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
   401       (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
   402 }
   403 
   404 
   405 
   406 
   407 
   408 // Note: Replace "for loop" with standard memcpy if possible.
   409 void MD5::memcpy (uint1 *output, uint1 *input, uint4 len){
   410 
   411   unsigned int i;
   412 
   413   for (i = 0; i < len; i++)
   414     output[i] = input[i];
   415 }
   416 
   417 
   418 
   419 // Note: Replace "for loop" with standard memset if possible.
   420 void MD5::memset (uint1 *output, uint1 value, uint4 len){
   421 
   422   unsigned int i;
   423 
   424   for (i = 0; i < len; i++)
   425     output[i] = value;
   426 }
   427 
   428 
   429 
   430 // ROTATE_LEFT rotates x left n bits.
   431 
   432 inline unsigned int MD5::rotate_left  (uint4 x, uint4 n){
   433   return (x << n) | (x >> (32-n))  ;
   434 }
   435 
   436 
   437 
   438 
   439 // F, G, H and I are basic MD5 functions.
   440 
   441 inline unsigned int MD5::F            (uint4 x, uint4 y, uint4 z){
   442   return (x & y) | (~x & z);
   443 }
   444 
   445 inline unsigned int MD5::G            (uint4 x, uint4 y, uint4 z){
   446   return (x & z) | (y & ~z);
   447 }
   448 
   449 inline unsigned int MD5::H            (uint4 x, uint4 y, uint4 z){
   450   return x ^ y ^ z;
   451 }
   452 
   453 inline unsigned int MD5::I            (uint4 x, uint4 y, uint4 z){
   454   return y ^ (x | ~z);
   455 }
   456 
   457 
   458 
   459 // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
   460 // Rotation is separate from addition to prevent recomputation.
   461 
   462 
   463 inline void MD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
   464 		    uint4  s, uint4 ac){
   465  a += F(b, c, d) + x + ac;
   466  a = rotate_left (a, s) +b;
   467 }
   468 
   469 inline void MD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
   470 		    uint4 s, uint4 ac){
   471  a += G(b, c, d) + x + ac;
   472  a = rotate_left (a, s) +b;
   473 }
   474 
   475 inline void MD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
   476 		    uint4 s, uint4 ac){
   477  a += H(b, c, d) + x + ac;
   478  a = rotate_left (a, s) +b;
   479 }
   480 
   481 inline void MD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
   482 			     uint4 s, uint4 ac){
   483  a += I(b, c, d) + x + ac;
   484  a = rotate_left (a, s) +b;
   485 }