core/md5.cpp
author David Anderson <dvander@alliedmods.net>
Tue Dec 23 01:33:37 2008 -0500 (2008-12-23)
changeset 2471 194be299b700
parent 2142 d9d876e97a66
permissions -rw-r--r--
SourceMod can now be somewhat compiled on OS X for patch sanity testing (bug 3516, r=ds).
This adds the ability for us to change the GCC version we use more flexibly.
     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   assert(finalized);
   205 
   206   for (i=0; i<16; i++)
   207     sprintf(s+i*2, "%02x", digest[i]);
   208 
   209   s[32]='\0';
   210 
   211   return s;
   212 }
   213 
   214 
   215 char *MD5::hex_digest(char buffer[33]){
   216 
   217   int i;
   218 
   219   assert(finalized);
   220 
   221   for (i=0; i<16; i++)
   222     sprintf(buffer+i*2, "%02x", digest[i]);
   223 
   224   buffer[32]='\0';
   225 
   226   return buffer;
   227 }
   228 
   229 
   230 // PRIVATE METHODS:
   231 
   232 
   233 
   234 void MD5::init(){
   235   finalized=0;  // we just started!
   236 
   237   // Nothing counted, so count=0
   238   count[0] = 0;
   239   count[1] = 0;
   240 
   241   // Load magic initialization constants.
   242   state[0] = 0x67452301;
   243   state[1] = 0xefcdab89;
   244   state[2] = 0x98badcfe;
   245   state[3] = 0x10325476;
   246 }
   247 
   248 
   249 
   250 // Constants for MD5Transform routine.
   251 // Although we could use C++ style constants, defines are actually better,
   252 // since they let us easily evade scope clashes.
   253 
   254 #define S11 7
   255 #define S12 12
   256 #define S13 17
   257 #define S14 22
   258 #define S21 5
   259 #define S22 9
   260 #define S23 14
   261 #define S24 20
   262 #define S31 4
   263 #define S32 11
   264 #define S33 16
   265 #define S34 23
   266 #define S41 6
   267 #define S42 10
   268 #define S43 15
   269 #define S44 21
   270 
   271 
   272 
   273 
   274 // MD5 basic transformation. Transforms state based on block.
   275 void MD5::transform (uint1 block[64]){
   276 
   277   uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
   278 
   279   decode (x, block, 64);
   280 
   281   assert(!finalized);  // not just a user error, since the method is private
   282 
   283   /* Round 1 */
   284   FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
   285   FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
   286   FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
   287   FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
   288   FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
   289   FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
   290   FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
   291   FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
   292   FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
   293   FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
   294   FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
   295   FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
   296   FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
   297   FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
   298   FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
   299   FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
   300 
   301  /* Round 2 */
   302   GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
   303   GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
   304   GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
   305   GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
   306   GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
   307   GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
   308   GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
   309   GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
   310   GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
   311   GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
   312   GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
   313   GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
   314   GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
   315   GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
   316   GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
   317   GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
   318 
   319   /* Round 3 */
   320   HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
   321   HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
   322   HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
   323   HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
   324   HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
   325   HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
   326   HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
   327   HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
   328   HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
   329   HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
   330   HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
   331   HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
   332   HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
   333   HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
   334   HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
   335   HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
   336 
   337   /* Round 4 */
   338   II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
   339   II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
   340   II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
   341   II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
   342   II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
   343   II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
   344   II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
   345   II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
   346   II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
   347   II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
   348   II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
   349   II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
   350   II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
   351   II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
   352   II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
   353   II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
   354 
   355   state[0] += a;
   356   state[1] += b;
   357   state[2] += c;
   358   state[3] += d;
   359 
   360   // Zeroize sensitive information.
   361   memset ( (uint1 *) x, 0, sizeof(x));
   362 
   363 }
   364 
   365 
   366 
   367 // Encodes input (UINT4) into output (unsigned char). Assumes len is
   368 // a multiple of 4.
   369 void MD5::encode (uint1 *output, uint4 *input, uint4 len) {
   370 
   371   unsigned int i, j;
   372 
   373   for (i = 0, j = 0; j < len; i++, j += 4) {
   374     output[j]   = (uint1)  (input[i] & 0xff);
   375     output[j+1] = (uint1) ((input[i] >> 8) & 0xff);
   376     output[j+2] = (uint1) ((input[i] >> 16) & 0xff);
   377     output[j+3] = (uint1) ((input[i] >> 24) & 0xff);
   378   }
   379 }
   380 
   381 
   382 
   383 
   384 // Decodes input (unsigned char) into output (UINT4). Assumes len is
   385 // a multiple of 4.
   386 void MD5::decode (uint4 *output, uint1 *input, uint4 len){
   387 
   388   unsigned int i, j;
   389 
   390   for (i = 0, j = 0; j < len; i++, j += 4)
   391     output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
   392       (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
   393 }
   394 
   395 
   396 
   397 
   398 
   399 // Note: Replace "for loop" with standard memcpy if possible.
   400 void MD5::memcpy (uint1 *output, uint1 *input, uint4 len){
   401 
   402   unsigned int i;
   403 
   404   for (i = 0; i < len; i++)
   405     output[i] = input[i];
   406 }
   407 
   408 
   409 
   410 // Note: Replace "for loop" with standard memset if possible.
   411 void MD5::memset (uint1 *output, uint1 value, uint4 len){
   412 
   413   unsigned int i;
   414 
   415   for (i = 0; i < len; i++)
   416     output[i] = value;
   417 }
   418 
   419 
   420 
   421 // ROTATE_LEFT rotates x left n bits.
   422 
   423 inline unsigned int MD5::rotate_left  (uint4 x, uint4 n){
   424   return (x << n) | (x >> (32-n))  ;
   425 }
   426 
   427 
   428 
   429 
   430 // F, G, H and I are basic MD5 functions.
   431 
   432 inline unsigned int MD5::F            (uint4 x, uint4 y, uint4 z){
   433   return (x & y) | (~x & z);
   434 }
   435 
   436 inline unsigned int MD5::G            (uint4 x, uint4 y, uint4 z){
   437   return (x & z) | (y & ~z);
   438 }
   439 
   440 inline unsigned int MD5::H            (uint4 x, uint4 y, uint4 z){
   441   return x ^ y ^ z;
   442 }
   443 
   444 inline unsigned int MD5::I            (uint4 x, uint4 y, uint4 z){
   445   return y ^ (x | ~z);
   446 }
   447 
   448 
   449 
   450 // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
   451 // Rotation is separate from addition to prevent recomputation.
   452 
   453 
   454 inline void MD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
   455 		    uint4  s, uint4 ac){
   456  a += F(b, c, d) + x + ac;
   457  a = rotate_left (a, s) +b;
   458 }
   459 
   460 inline void MD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
   461 		    uint4 s, uint4 ac){
   462  a += G(b, c, d) + x + ac;
   463  a = rotate_left (a, s) +b;
   464 }
   465 
   466 inline void MD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
   467 		    uint4 s, uint4 ac){
   468  a += H(b, c, d) + x + ac;
   469  a = rotate_left (a, s) +b;
   470 }
   471 
   472 inline void MD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, 
   473 			     uint4 s, uint4 ac){
   474  a += I(b, c, d) + x + ac;
   475  a = rotate_left (a, s) +b;
   476 }