1.1 --- a/core/md5.cpp Fri Jul 11 06:51:21 2008 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,485 +0,0 @@
1.4 -// MD5.CC - source code for the C++/object oriented translation and
1.5 -// modification of MD5.
1.6 -
1.7 -// Translation and modification (c) 1995 by Mordechai T. Abzug
1.8 -
1.9 -// This translation/ modification is provided "as is," without express or
1.10 -// implied warranty of any kind.
1.11 -
1.12 -// The translator/ modifier does not claim (1) that MD5 will do what you think
1.13 -// it does; (2) that this translation/ modification is accurate; or (3) that
1.14 -// this software is "merchantible." (Language for this disclaimer partially
1.15 -// copied from the disclaimer below).
1.16 -
1.17 -/* based on:
1.18 -
1.19 - MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
1.20 - MDDRIVER.C - test driver for MD2, MD4 and MD5
1.21 -
1.22 -
1.23 - Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
1.24 -rights reserved.
1.25 -
1.26 -License to copy and use this software is granted provided that it
1.27 -is identified as the "RSA Data Security, Inc. MD5 Message-Digest
1.28 -Algorithm" in all material mentioning or referencing this software
1.29 -or this function.
1.30 -
1.31 -License is also granted to make and use derivative works provided
1.32 -that such works are identified as "derived from the RSA Data
1.33 -Security, Inc. MD5 Message-Digest Algorithm" in all material
1.34 -mentioning or referencing the derived work.
1.35 -
1.36 -RSA Data Security, Inc. makes no representations concerning either
1.37 -the merchantability of this software or the suitability of this
1.38 -software for any particular purpose. It is provided "as is"
1.39 -without express or implied warranty of any kind.
1.40 -
1.41 -These notices must be retained in any copies of any part of this
1.42 -documentation and/or software.
1.43 -
1.44 - */
1.45 -
1.46 -#include "md5.h"
1.47 -
1.48 -#include <assert.h>
1.49 -#include <string.h>
1.50 -
1.51 -// MD5 simple initialization method
1.52 -
1.53 -MD5::MD5(){
1.54 -
1.55 - init();
1.56 -
1.57 -}
1.58 -
1.59 -
1.60 -// MD5 block update operation. Continues an MD5 message-digest
1.61 -// operation, processing another message block, and updating the
1.62 -// context.
1.63 -
1.64 -void MD5::update (uint1 *input, uint4 input_length) {
1.65 -
1.66 - uint4 input_index, buffer_index;
1.67 - uint4 buffer_space; // how much space is left in buffer
1.68 -
1.69 - if (finalized){ // so we can't update!
1.70 - /*cerr << "MD5::update: Can't update a finalized digest!" << endl;*/
1.71 - return;
1.72 - }
1.73 -
1.74 - // Compute number of bytes mod 64
1.75 - buffer_index = (unsigned int)((count[0] >> 3) & 0x3F);
1.76 -
1.77 - // Update number of bits
1.78 - if ( (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) )
1.79 - count[1]++;
1.80 -
1.81 - count[1] += ((uint4)input_length >> 29);
1.82 -
1.83 -
1.84 - buffer_space = 64 - buffer_index; // how much space is left in buffer
1.85 -
1.86 - // Transform as many times as possible.
1.87 - if (input_length >= buffer_space) { // ie. we have enough to fill the buffer
1.88 - // fill the rest of the buffer and transform
1.89 - memcpy (buffer + buffer_index, input, buffer_space);
1.90 - transform (buffer);
1.91 -
1.92 - // now, transform each 64-byte piece of the input, bypassing the buffer
1.93 - for (input_index = buffer_space; input_index + 63 < input_length;
1.94 - input_index += 64)
1.95 - transform (input+input_index);
1.96 -
1.97 - buffer_index = 0; // so we can buffer remaining
1.98 - }
1.99 - else
1.100 - input_index=0; // so we can buffer the whole input
1.101 -
1.102 -
1.103 - // and here we do the buffering:
1.104 - memcpy(buffer+buffer_index, input+input_index, input_length-input_index);
1.105 -}
1.106 -
1.107 -
1.108 -
1.109 -// MD5 update for files.
1.110 -// Like above, except that it works on files (and uses above as a primitive.)
1.111 -
1.112 -void MD5::update(FILE *file){
1.113 -
1.114 - unsigned char buffer[1024];
1.115 - int len;
1.116 -
1.117 - while ((len=fread(buffer, 1, 1024, file)))
1.118 - update(buffer, len);
1.119 -
1.120 - fclose (file);
1.121 -
1.122 -}
1.123 -
1.124 -
1.125 -// MD5 finalization. Ends an MD5 message-digest operation, writing the
1.126 -// the message digest and zeroizing the context.
1.127 -
1.128 -
1.129 -void MD5::finalize (){
1.130 -
1.131 - unsigned char bits[8];
1.132 - unsigned int index, padLen;
1.133 - static uint1 PADDING[64]={
1.134 - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.135 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.136 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1.137 - };
1.138 -
1.139 - if (finalized){
1.140 - /* cerr << "MD5::finalize: Already finalized this digest!" << endl;*/
1.141 - return;
1.142 - }
1.143 -
1.144 - // Save number of bits
1.145 - encode (bits, count, 8);
1.146 -
1.147 - // Pad out to 56 mod 64.
1.148 - index = (uint4) ((count[0] >> 3) & 0x3f);
1.149 - padLen = (index < 56) ? (56 - index) : (120 - index);
1.150 - update (PADDING, padLen);
1.151 -
1.152 - // Append length (before padding)
1.153 - update (bits, 8);
1.154 -
1.155 - // Store state in digest
1.156 - encode (digest, state, 16);
1.157 -
1.158 - // Zeroize sensitive information
1.159 - memset (buffer, 0, sizeof(*buffer));
1.160 -
1.161 - finalized=1;
1.162 -
1.163 -}
1.164 -
1.165 -
1.166 -
1.167 -
1.168 -MD5::MD5(FILE *file){
1.169 -
1.170 - init(); // must be called be all constructors
1.171 - update(file);
1.172 - finalize ();
1.173 -}
1.174 -
1.175 -unsigned char *MD5::raw_digest(){
1.176 -
1.177 - uint1 *s = new uint1[16];
1.178 -
1.179 - if (!finalized){
1.180 -/* cerr << "MD5::raw_digest: Can't get digest if you haven't "<<
1.181 - "finalized the digest!" <<endl;*/
1.182 - return ( (unsigned char*) "");
1.183 - }
1.184 -
1.185 - memcpy(s, digest, 16);
1.186 - return s;
1.187 -}
1.188 -
1.189 -unsigned char *MD5::raw_digest(unsigned char buffer[16])
1.190 -{
1.191 - if (!finalized)
1.192 - {
1.193 - return ( (unsigned char*) "");
1.194 - }
1.195 -
1.196 - memcpy(buffer, digest, 16);
1.197 - return buffer;
1.198 -}
1.199 -
1.200 -
1.201 -
1.202 -char *MD5::hex_digest(){
1.203 -
1.204 - int i;
1.205 - char *s= new char[33];
1.206 -
1.207 - if (!finalized){
1.208 -/* cerr << "MD5::hex_digest: Can't get digest if you haven't "<<
1.209 - "finalized the digest!" <<endl;*/
1.210 - return "";
1.211 - }
1.212 -
1.213 - for (i=0; i<16; i++)
1.214 - sprintf(s+i*2, "%02x", digest[i]);
1.215 -
1.216 - s[32]='\0';
1.217 -
1.218 - return s;
1.219 -}
1.220 -
1.221 -
1.222 -char *MD5::hex_digest(char buffer[33]){
1.223 -
1.224 - int i;
1.225 -
1.226 - if (!finalized)
1.227 - {
1.228 - /* cerr << "MD5::hex_digest: Can't get digest if you haven't "<<
1.229 - "finalized the digest!" <<endl;*/
1.230 - return "";
1.231 - }
1.232 -
1.233 - for (i=0; i<16; i++)
1.234 - sprintf(buffer+i*2, "%02x", digest[i]);
1.235 -
1.236 - buffer[32]='\0';
1.237 -
1.238 - return buffer;
1.239 -}
1.240 -
1.241 -
1.242 -// PRIVATE METHODS:
1.243 -
1.244 -
1.245 -
1.246 -void MD5::init(){
1.247 - finalized=0; // we just started!
1.248 -
1.249 - // Nothing counted, so count=0
1.250 - count[0] = 0;
1.251 - count[1] = 0;
1.252 -
1.253 - // Load magic initialization constants.
1.254 - state[0] = 0x67452301;
1.255 - state[1] = 0xefcdab89;
1.256 - state[2] = 0x98badcfe;
1.257 - state[3] = 0x10325476;
1.258 -}
1.259 -
1.260 -
1.261 -
1.262 -// Constants for MD5Transform routine.
1.263 -// Although we could use C++ style constants, defines are actually better,
1.264 -// since they let us easily evade scope clashes.
1.265 -
1.266 -#define S11 7
1.267 -#define S12 12
1.268 -#define S13 17
1.269 -#define S14 22
1.270 -#define S21 5
1.271 -#define S22 9
1.272 -#define S23 14
1.273 -#define S24 20
1.274 -#define S31 4
1.275 -#define S32 11
1.276 -#define S33 16
1.277 -#define S34 23
1.278 -#define S41 6
1.279 -#define S42 10
1.280 -#define S43 15
1.281 -#define S44 21
1.282 -
1.283 -
1.284 -
1.285 -
1.286 -// MD5 basic transformation. Transforms state based on block.
1.287 -void MD5::transform (uint1 block[64]){
1.288 -
1.289 - uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
1.290 -
1.291 - decode (x, block, 64);
1.292 -
1.293 - assert(!finalized); // not just a user error, since the method is private
1.294 -
1.295 - /* Round 1 */
1.296 - FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
1.297 - FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
1.298 - FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
1.299 - FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
1.300 - FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
1.301 - FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
1.302 - FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
1.303 - FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
1.304 - FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
1.305 - FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
1.306 - FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
1.307 - FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
1.308 - FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
1.309 - FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
1.310 - FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
1.311 - FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
1.312 -
1.313 - /* Round 2 */
1.314 - GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
1.315 - GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
1.316 - GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
1.317 - GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
1.318 - GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
1.319 - GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
1.320 - GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
1.321 - GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
1.322 - GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
1.323 - GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
1.324 - GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
1.325 - GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
1.326 - GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
1.327 - GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
1.328 - GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
1.329 - GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
1.330 -
1.331 - /* Round 3 */
1.332 - HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
1.333 - HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
1.334 - HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
1.335 - HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
1.336 - HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
1.337 - HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
1.338 - HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
1.339 - HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
1.340 - HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
1.341 - HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
1.342 - HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
1.343 - HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
1.344 - HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
1.345 - HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
1.346 - HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
1.347 - HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
1.348 -
1.349 - /* Round 4 */
1.350 - II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
1.351 - II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
1.352 - II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
1.353 - II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
1.354 - II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
1.355 - II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
1.356 - II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
1.357 - II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
1.358 - II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
1.359 - II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
1.360 - II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
1.361 - II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
1.362 - II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
1.363 - II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
1.364 - II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
1.365 - II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
1.366 -
1.367 - state[0] += a;
1.368 - state[1] += b;
1.369 - state[2] += c;
1.370 - state[3] += d;
1.371 -
1.372 - // Zeroize sensitive information.
1.373 - memset ( (uint1 *) x, 0, sizeof(x));
1.374 -
1.375 -}
1.376 -
1.377 -
1.378 -
1.379 -// Encodes input (UINT4) into output (unsigned char). Assumes len is
1.380 -// a multiple of 4.
1.381 -void MD5::encode (uint1 *output, uint4 *input, uint4 len) {
1.382 -
1.383 - unsigned int i, j;
1.384 -
1.385 - for (i = 0, j = 0; j < len; i++, j += 4) {
1.386 - output[j] = (uint1) (input[i] & 0xff);
1.387 - output[j+1] = (uint1) ((input[i] >> 8) & 0xff);
1.388 - output[j+2] = (uint1) ((input[i] >> 16) & 0xff);
1.389 - output[j+3] = (uint1) ((input[i] >> 24) & 0xff);
1.390 - }
1.391 -}
1.392 -
1.393 -
1.394 -
1.395 -
1.396 -// Decodes input (unsigned char) into output (UINT4). Assumes len is
1.397 -// a multiple of 4.
1.398 -void MD5::decode (uint4 *output, uint1 *input, uint4 len){
1.399 -
1.400 - unsigned int i, j;
1.401 -
1.402 - for (i = 0, j = 0; j < len; i++, j += 4)
1.403 - output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
1.404 - (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
1.405 -}
1.406 -
1.407 -
1.408 -
1.409 -
1.410 -
1.411 -// Note: Replace "for loop" with standard memcpy if possible.
1.412 -void MD5::memcpy (uint1 *output, uint1 *input, uint4 len){
1.413 -
1.414 - unsigned int i;
1.415 -
1.416 - for (i = 0; i < len; i++)
1.417 - output[i] = input[i];
1.418 -}
1.419 -
1.420 -
1.421 -
1.422 -// Note: Replace "for loop" with standard memset if possible.
1.423 -void MD5::memset (uint1 *output, uint1 value, uint4 len){
1.424 -
1.425 - unsigned int i;
1.426 -
1.427 - for (i = 0; i < len; i++)
1.428 - output[i] = value;
1.429 -}
1.430 -
1.431 -
1.432 -
1.433 -// ROTATE_LEFT rotates x left n bits.
1.434 -
1.435 -inline unsigned int MD5::rotate_left (uint4 x, uint4 n){
1.436 - return (x << n) | (x >> (32-n)) ;
1.437 -}
1.438 -
1.439 -
1.440 -
1.441 -
1.442 -// F, G, H and I are basic MD5 functions.
1.443 -
1.444 -inline unsigned int MD5::F (uint4 x, uint4 y, uint4 z){
1.445 - return (x & y) | (~x & z);
1.446 -}
1.447 -
1.448 -inline unsigned int MD5::G (uint4 x, uint4 y, uint4 z){
1.449 - return (x & z) | (y & ~z);
1.450 -}
1.451 -
1.452 -inline unsigned int MD5::H (uint4 x, uint4 y, uint4 z){
1.453 - return x ^ y ^ z;
1.454 -}
1.455 -
1.456 -inline unsigned int MD5::I (uint4 x, uint4 y, uint4 z){
1.457 - return y ^ (x | ~z);
1.458 -}
1.459 -
1.460 -
1.461 -
1.462 -// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
1.463 -// Rotation is separate from addition to prevent recomputation.
1.464 -
1.465 -
1.466 -inline void MD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
1.467 - uint4 s, uint4 ac){
1.468 - a += F(b, c, d) + x + ac;
1.469 - a = rotate_left (a, s) +b;
1.470 -}
1.471 -
1.472 -inline void MD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
1.473 - uint4 s, uint4 ac){
1.474 - a += G(b, c, d) + x + ac;
1.475 - a = rotate_left (a, s) +b;
1.476 -}
1.477 -
1.478 -inline void MD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
1.479 - uint4 s, uint4 ac){
1.480 - a += H(b, c, d) + x + ac;
1.481 - a = rotate_left (a, s) +b;
1.482 -}
1.483 -
1.484 -inline void MD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
1.485 - uint4 s, uint4 ac){
1.486 - a += I(b, c, d) + x + ac;
1.487 - a = rotate_left (a, s) +b;
1.488 -}