md5.cpp
Go to the documentation of this file.
00001 /*
00002  *      This is the C++ implementation of the MD5 Message-Digest
00003  *      Algorithm desrcipted in RFC 1321.
00004  *      I translated the C code from this RFC to C++.
00005  *      There is now warranty.
00006  * 
00007  *      Feb. 12. 2005
00008  *      Benjamin Gr¨ądelbach
00009  */
00010 
00011 /*
00012  *      Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
00013  *      rights reserved.
00014  *
00015  *      License to copy and use this software is granted provided that it
00016  *      is identified as the "RSA Data Security, Inc. MD5 Message-Digest
00017  *      Algorithm" in all material mentioning or referencing this software
00018  *      or this function.
00019  *
00020  *      License is also granted to make and use derivative works provided
00021  *      that such works are identified as "derived from the RSA Data
00022  *      Security, Inc. MD5 Message-Digest Algorithm" in all material
00023  *      mentioning or referencing the derived work.
00024  *
00025  *      RSA Data Security, Inc. makes no representations concerning either
00026  *      the merchantability of this software or the suitability of this
00027  *      software for any particular purpose. It is provided "as is"
00028  *      without express or implied warranty of any kind.
00029  *
00030  *      These notices must be retained in any copies of any part of this
00031  *      documentation and/or software.
00032  */
00033 
00034 //md5 class include
00035 #include "md5.h"
00036 #include <string.h>
00037 
00038 // Constants for MD5Transform routine.
00039 #define S11 7
00040 #define S12 12
00041 #define S13 17
00042 #define S14 22
00043 #define S21 5
00044 #define S22 9
00045 #define S23 14
00046 #define S24 20
00047 #define S31 4
00048 #define S32 11
00049 #define S33 16
00050 #define S34 23
00051 #define S41 6
00052 #define S42 10
00053 #define S43 15
00054 #define S44 21
00055 
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,
00058   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00059   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00060 };
00061 
00062 /* F, G, H and I are basic MD5 functions. */
00063 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
00064 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
00065 #define H(x, y, z) ((x) ^ (y) ^ (z))
00066 #define I(x, y, z) ((y) ^ ((x) | (~z)))
00067 
00068 /* ROTATE_LEFT rotates x left n bits. */
00069 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
00070 
00071 /*
00072 FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
00073 Rotation is separate from addition to prevent recomputation.
00074 */
00075 #define FF(a, b, c, d, x, s, ac) { \
00076  (a) += F ((b), (c), (d)) + (x) + (unsigned long int)(ac); \
00077  (a) = ROTATE_LEFT ((a), (s)); \
00078  (a) += (b); \
00079   }
00080 
00081 #define GG(a, b, c, d, x, s, ac) { \
00082  (a) += G ((b), (c), (d)) + (x) + (unsigned long int)(ac); \
00083  (a) = ROTATE_LEFT ((a), (s)); \
00084  (a) += (b); \
00085   }
00086 #define HH(a, b, c, d, x, s, ac) { \
00087  (a) += H ((b), (c), (d)) + (x) + (unsigned long int)(ac); \
00088  (a) = ROTATE_LEFT ((a), (s)); \
00089  (a) += (b); \
00090   }
00091 #define II(a, b, c, d, x, s, ac) { \
00092  (a) += I ((b), (c), (d)) + (x) + (unsigned long int)(ac); \
00093  (a) = ROTATE_LEFT ((a), (s)); \
00094  (a) += (b); \
00095   }
00096 
00097 /* MD5 initialization. Begins an MD5 operation, writing a new context. */
00098 void MD5::MD5Init (MD5_CTX *context)
00099 {
00100           context->count[0] = context->count[1] = 0;
00101           context->state[0] = 0x67452301;
00102           context->state[1] = 0xefcdab89;
00103           context->state[2] = 0x98badcfe;
00104           context->state[3] = 0x10325476;
00105 }
00106 
00107 /*
00108          MD5 block update operation. Continues an MD5 message-digest
00109          operation, processing another message block, and updating the
00110          context.
00111 */
00112 void MD5::MD5Update (MD5_CTX *context, unsigned char *input, unsigned int inputLen)
00113 {
00114           unsigned int i, index, partLen;
00115 
00116           /* Compute number of bytes mod 64 */
00117           index = (unsigned int)((context->count[0] >> 3) & 0x3F);
00118 
00119           /* Update number of bits */
00120           if ( (context->count[0] += ((unsigned long int)inputLen << 3))
00121                < ((unsigned long int)inputLen << 3))
00122                 context->count[1]++;
00123 
00124           context->count[1] += ((unsigned long int)inputLen >> 29);
00125           partLen = 64 - index;
00126 
00127           /*
00128            * Transform as many times as possible.
00129            */
00130           if (inputLen >= partLen) 
00131           {
00132                  MD5_memcpy ((POINTER)&context->buffer[index], (POINTER)input, partLen);
00133                  MD5Transform (context->state, context->buffer);
00134 
00135                  for (i = partLen; i + 63 < inputLen; i += 64)
00136                    MD5Transform (context->state, &input[i]);
00137 
00138                  index = 0;
00139           }
00140           else 
00141                 i = 0;
00142 
00143           /* Buffer remaining input */
00144           MD5_memcpy ((POINTER)&context->buffer[index],
00145                       (POINTER)&input[i],
00146                       inputLen-i);
00147 }
00148 
00149 /*
00150  * MD5 finalization. Ends an MD5 message-digest operation, writing the
00151  * the message digest and zeroizing the context.
00152  */
00153 void MD5::MD5Final (unsigned char digest[16], MD5_CTX *context)
00154 {
00155         unsigned char bits[8];
00156         unsigned int index, padLen;
00157 
00158         /* Save number of bits */
00159         Encode (bits, context->count, 8);
00160 
00161         /* 
00162          * Pad out to 56 mod 64.
00163          */
00164         index = (unsigned int)((context->count[0] >> 3) & 0x3f);
00165         padLen = (index < 56) ? (56 - index) : (120 - index);
00166         MD5Update (context, PADDING, padLen);
00167 
00168         /* Append length (before padding) */
00169         MD5Update (context, bits, 8);
00170 
00171         /* Store state in digest */
00172         Encode (digest, context->state, 16);
00173 
00174         /*
00175          * Zeroize sensitive information.
00176          */
00177         MD5_memset ((POINTER)context, 0, sizeof (*context));
00178 }
00179 
00180 /*
00181  * MD5 basic transformation. Transforms state based on block.
00182  */
00183 void MD5::MD5Transform (unsigned long int state[4], unsigned char block[64])
00184 {
00185         unsigned long int a = state[0], b = state[1], c = state[2], d = state[3], x[16];
00186 
00187         Decode (x, block, 64);
00188 
00189         /* Round 1 */
00190         FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
00191         FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
00192         FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
00193         FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
00194         FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
00195         FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
00196         FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
00197         FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
00198         FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
00199         FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
00200         FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
00201         FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
00202         FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
00203         FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
00204         FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
00205         FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
00206 
00207         /* Round 2 */
00208         GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
00209         GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
00210         GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
00211         GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
00212         GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
00213         GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
00214         GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
00215         GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
00216         GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
00217         GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
00218         GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
00219 
00220         GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
00221         GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
00222         GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
00223         GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
00224         GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
00225 
00226         /* Round 3 */
00227         HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
00228         HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
00229         HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
00230         HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
00231         HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
00232         HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
00233         HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
00234         HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
00235         HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
00236         HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
00237         HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
00238         HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
00239         HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
00240         HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
00241         HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
00242         HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
00243 
00244         /* Round 4 */
00245         II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
00246         II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
00247         II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
00248         II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
00249         II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
00250         II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
00251         II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
00252         II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
00253         II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
00254         II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
00255         II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
00256         II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
00257         II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
00258         II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
00259         II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
00260         II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
00261 
00262         state[0] += a;
00263         state[1] += b;
00264         state[2] += c;
00265         state[3] += d;
00266 
00267         /* 
00268          * Zeroize sensitive information.
00269          */
00270         MD5_memset ((POINTER)x, 0, sizeof (x));
00271 }
00272 
00273 /* 
00274  * Encodes input (unsigned long int) into output (unsigned char). Assumes len is
00275  * a multiple of 4.
00276  */
00277 void MD5::Encode (unsigned char *output, unsigned long int *input, unsigned int len)
00278 {
00279         unsigned int i, j;
00280 
00281         for (i = 0, j = 0; j < len; i++, j += 4) {
00282                 output[j] = (unsigned char)(input[i] & 0xff);
00283                 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
00284                 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
00285                 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
00286         }
00287 }
00288 
00289 /*
00290  * Decodes input (unsigned char) into output (unsigned long int). Assumes len is
00291  * a multiple of 4.
00292  */
00293 void MD5::Decode (unsigned long int *output, unsigned char *input, unsigned int len)
00294 {
00295           unsigned int i, j;
00296 
00297           for (i = 0, j = 0; j < len; i++, j += 4)
00298                  output[i] = ((unsigned long int)input[j]) | 
00299                              (((unsigned long int)input[j+1]) << 8) |
00300                              (((unsigned long int)input[j+2]) << 16) |
00301                              (((unsigned long int)input[j+3]) << 24);
00302 }
00303 
00304 /*
00305  * Note: Replace "for loop" with standard memcpy if possible.
00306  */
00307 void MD5::MD5_memcpy (POINTER output, POINTER input, unsigned int len)
00308 {
00309         memcpy(output, input, len);
00310 
00311         /*
00312         unsigned int i;
00313         for (i = 0; i < len; i++)
00314                 output[i] = input[i];
00315                 */
00316 }
00317 
00318 /*
00319  * Note: Replace "for loop" with standard memset if possible.
00320  */
00321 void MD5::MD5_memset (POINTER output,int value,unsigned int len)
00322 {
00323         memset(output, value, len);
00324 
00325         /*
00326         unsigned int i;
00327         for (i = 0; i < len; i++)
00328                 ((char *)output)[i] = (char)value;
00329                 */
00330 }
00331 
00332 /*
00333  * EOF
00334  */
00335 


appl
Author(s): petercai
autogenerated on Tue Jan 7 2014 11:02:29