Main Page | Namespace List | Class Hierarchy | Compound List | File List | Namespace Members | Compound Members | File Members

md5.cxx

Go to the documentation of this file.
00001 //Copyright notice:
00002 // The following software is derived from the RSA Data
00003 // Security, Inc. MD5 Message-Digest Algorithm.  Accordingly,
00004 // the following copyright notice is reproduced, and applies to
00005 // such parts of this file which are copied from RSA's source code.
00006 // All other parts of the file are copyright 1998 ABKGroup and
00007 // the Regents of the University of California.
00008 
00009 
00010 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
00011 rights reserved.
00012 
00013 License to copy and use this software is granted provided that it
00014 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
00015 Algorithm" in all material mentioning or referencing this software
00016 or this function.
00017 
00018 License is also granted to make and use derivative works provided
00019 that such works are identified as "derived from the RSA Data
00020 Security, Inc. MD5 Message-Digest Algorithm" in all material
00021 mentioning or referencing the derived work.
00022 
00023 RSA Data Security, Inc. makes no representations concerning either
00024 the merchantability of this software or the suitability of this
00025 software for any particular purpose. It is provided "as is"
00026 without express or implied warranty of any kind.
00027 
00028 These notices must be retained in any copies of any part of this
00029 documentation and/or software.
00030 
00031 */
00032 
00033 #ifdef _MSC_VER
00034 #pragma warning(disable:4786)
00035 #endif
00036 
00037 
00038 #include <vector>
00039 #include "abkMD5.h"
00040 #define S11 7
00041 #define S12 12
00042 #define S13 17
00043 #define S14 22
00044 #define S21 5
00045 #define S22 9
00046 #define S23 14
00047 #define S24 20
00048 #define S31 4
00049 #define S32 11
00050 #define S33 16
00051 #define S34 23
00052 #define S41 6
00053 #define S42 10
00054 #define S43 15
00055 #define S44 21
00056 static unsigned char PADDING[64] = {
00057      0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
00058 };
00059 
00060 /* F, G, H and I are basic MD5 functions.
00061 
00062       */
00063 
00064 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
00065 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
00066 #define H(x, y, z) ((x) ^ (y) ^ (z))
00067 #define I(x, y, z) ((y) ^ ((x) | (~z)))
00068 
00069 /* ROTATE_LEFT rotates x left n bits.
00070 
00071       */
00072 
00073 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
00074 
00075 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
00076 Rotation is separate from addition to prevent recomputation.
00077 
00078       */
00079 
00080 #define FF(a, b, c, d, x, s, ac) { \
00081      (a) += F ((b), (c), (d)) + (x) + (unsigned)(ac); \
00082      (a) = ROTATE_LEFT ((a), (s)); \
00083      (a) += (b); \
00084      } 
00085 #define GG(a, b, c, d, x, s, ac) { \
00086      (a) += G ((b), (c), (d)) + (x) + (unsigned)(ac); \
00087      (a) = ROTATE_LEFT ((a), (s)); \
00088      (a) += (b); \
00089      } 
00090 #define HH(a, b, c, d, x, s, ac) { \
00091      (a) += H ((b), (c), (d)) + (x) + (unsigned)(ac); \
00092      (a) = ROTATE_LEFT ((a), (s)); \
00093      (a) += (b); \
00094      } 
00095 #define II(a, b, c, d, x, s, ac) { \
00096      (a) += I ((b), (c), (d)) + (x) + (unsigned)(ac); \
00097      (a) = ROTATE_LEFT ((a), (s)); \
00098      (a) += (b); \
00099      } 
00100 
00101 MD5::MD5():_isFinalized(false)
00102     {
00103     _initState();
00104     }
00105 
00106 
00107 MD5::MD5(const char *input, unsigned length, bool lastUpdate):_isFinalized(false)
00108     {
00109     _initState();
00110     update(input,length,lastUpdate);
00111     }
00112 
00113 MD5::MD5(const char *input, bool lastUpdate):_isFinalized(false)
00114     {
00115     _initState();
00116     update(input,lastUpdate);
00117     }
00118 
00119 void MD5::_initState()
00120     {
00121     _state[0] = 0x67452301;
00122     _state[1] = 0xefcdab89;
00123     _state[2] = 0x98badcfe;
00124     _state[3] = 0x10325476;
00125     _count[0]=0;
00126     _count[1]=0;
00127     }
00128 
00129 
00130 void MD5::encode (unsigned char *output, const unsigned *input, unsigned len)
00131     {
00132     unsigned int i, j; 
00133     
00134     for (i = 0, j = 0; j < len; i++, j += 4) 
00135         { 
00136         output[j] = (unsigned char)(input[i] & 0xff); 
00137         output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); 
00138         output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); 
00139         output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); 
00140         } 
00141     }
00142 
00143 void MD5::decode (unsigned *output, const unsigned char *input, unsigned len)
00144     {
00145     unsigned int i, j; 
00146     
00147     for (i = 0, j = 0; j < len; i++, j += 4) 
00148         output[i] = ((unsigned)input[j]) | 
00149         (((unsigned)input[j+1]) << 8) | 
00150         (((unsigned)input[j+2]) << 16) | 
00151         (((unsigned)input[j+3]) << 24); 
00152     }
00153 
00154 void MD5::update(const char *input, bool lastUpdate)
00155     {
00156     abkfatal(!_isFinalized,"Can't update MD5 after final update");
00157     _update((const unsigned char*)input,strlen(input));
00158     if (lastUpdate)
00159         _finalize();
00160     }
00161 
00162 void MD5::update(const char *input,unsigned inputLen, bool lastUpdate)
00163     {
00164     abkfatal(!_isFinalized,"Can't update MD5 after final update");
00165     _update((const unsigned char*)input,inputLen);
00166     if (lastUpdate)
00167         _finalize();
00168     }
00169 
00170 void MD5::finalize()
00171     {
00172     abkfatal(!_isFinalized,"Can't finalize twice");
00173     _finalize();
00174     }
00175 
00176 void MD5::_update(const unsigned char *input,unsigned inputLen)
00177     {
00178     unsigned  i, index, partLen; 
00179     
00180     /* Compute number of bytes mod 64 */
00181     index = (unsigned)((_count[0] >> 3) & 0x3F);
00182     
00183     /* Update number of bits */
00184     if ((_count[0] += ((unsigned)inputLen << 3))
00185         < ((unsigned)inputLen << 3))
00186         _count[1]++;
00187     _count[1] += ((unsigned)inputLen >> 29);
00188     
00189     partLen = 64 - index; 
00190     
00191     //Transform as many times as possible.
00192     
00193     
00194     if (inputLen >= partLen)
00195         { 
00196         memcpy(&_buffer[index],input, partLen);
00197         _transform (&_buffer[0]); 
00198         
00199         for (i = partLen; i + 63 < inputLen; i += 64) 
00200             _transform (&input[i]); 
00201         
00202         index = 0; 
00203         } 
00204     else 
00205         i = 0; 
00206     
00207     /* Buffer remaining input */
00208     memcpy(&_buffer[index],&input[i],inputLen-i);
00209     
00210     }
00211 
00212 void MD5::_finalize()
00213     {
00214      unsigned char bits[8]; 
00215      unsigned int index, padLen; 
00216 
00217        /* Save number of bits */
00218        encode (bits,_count, 8);
00219 
00220        /* Pad out to 56 mod 64.
00221 
00222 */
00223      index = (unsigned int)((_count[0] >> 3) & 0x3f); 
00224      padLen = (index < 56) ? (56 - index) : (120 - index); 
00225      _update (PADDING, padLen); 
00226 
00227        /* Append length (before padding) */
00228      _update (bits, 8);
00229 
00230        /* Store state in digest */
00231        //encode (digest, _state, 16);
00232 
00233        /* Zeroize sensitive information.
00234 
00235 */
00236      //MD5_memset ((POINTER)context, 0, sizeof (*context)); //we'll do in dtor
00237     _isFinalized=true;
00238     }
00239 
00240 void MD5::_transform(const unsigned char *block)
00241     {
00242      unsigned a = _state[0], b = _state[1], c = _state[2], d = _state[3], x[16]; 
00243 
00244      decode (x, block, 64); 
00245 
00246        /* Round 1 */
00247        FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
00248        FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
00249        FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
00250        FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
00251        FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
00252        FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
00253        FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
00254        FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
00255        FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
00256        FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
00257        FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
00258        FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
00259        FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
00260        FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
00261        FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
00262        FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
00263 
00264       /* Round 2 */
00265        GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
00266        GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
00267        GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
00268        GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
00269        GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
00270        GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
00271        GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
00272        GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
00273        GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
00274        GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
00275        GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
00276 
00277 
00278 
00279      GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ 
00280      GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ 
00281      GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ 
00282      GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ 
00283      GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ 
00284 
00285        /* Round 3 */
00286        HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
00287        HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
00288        HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
00289        HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
00290        HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
00291        HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
00292        HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
00293        HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
00294        HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
00295        HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
00296        HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
00297        HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
00298        HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
00299        HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
00300        HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
00301        HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
00302 
00303        /* Round 4 */
00304        II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
00305        II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
00306        II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
00307        II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
00308        II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
00309        II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
00310        II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
00311        II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
00312        II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
00313        II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
00314        II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
00315        II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
00316        II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
00317        II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
00318        II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
00319        II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
00320 
00321      _state[0] += a; 
00322      _state[1] += b; 
00323      _state[2] += c; 
00324      _state[3] += d; 
00325 
00326        /* Zeroize sensitive information.
00327 
00328 
00329 
00330 */
00331      memset (x, 0, sizeof (x)); 
00332     }
00333 
00334 
00335 
00336 MD5::operator unsigned() const
00337     {
00338     abkfatal(_isFinalized,"Can't read values from non-finalized MD5");
00339     return _state[0];
00340     }
00341 
00342 
00343 MD5::operator MD5::Wrap128() const
00344     {
00345     abkfatal(_isFinalized,"Can't read values from non-finalized MD5");
00346     Wrap128 w128;
00347     w128.meat[0] = _state[0];
00348     w128.meat[1] = _state[1];
00349     w128.meat[2] = _state[2];
00350     w128.meat[3] = _state[3];
00351     return w128;
00352     }
00353 
00354 MD5::~MD5()
00355     {
00356     //zeroize sensitive info
00357     memset(_state,0,16);
00358     }
00359 
00360 unsigned MD5:: getWord(unsigned idx) const
00361     {
00362     abkassert(idx < 4, "Index out of range");
00363     return _state[idx];
00364 
00365     }
00366 
00367 
00368 ostream& operator<<(ostream& os, const MD5& md5)
00369     {
00370     abkfatal(md5._isFinalized,"Can't output state of MD5 before finalization");
00371     int i;
00372     unsigned char digest[16];
00373     char buf[3];
00374     MD5::encode(&digest[0],md5._state,16);
00375     for (i=0;i<16;i++)
00376         {
00377         sprintf(buf,"%02x",digest[i]);
00378         os << buf;
00379         }
00380     return os;
00381     }
00382 

Generated on Mon Apr 25 01:09:24 2005 for Parquete by doxygen 1.3.2