00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00039 #include "blocxx/BLOCXX_config.h"
00040 #include "blocxx/MD5.hpp"
00041 #include "blocxx/String.hpp"
00042 #include "blocxx/ExceptionIds.hpp"
00043
00044 #include <string.h>
00045
00046 #ifdef BLOCXX_WIN32
00047 #pragma warning (push)
00048 #pragma warning (disable: 4355)
00049 #endif
00050
00051 namespace BLOCXX_NAMESPACE
00052 {
00053
00054 const int MD5HASHHEXLEN = 32;
00055
00056 BLOCXX_DEFINE_EXCEPTION_WITH_ID(MD5);
00058 MD5OStreamBase::MD5OStreamBase(MD5* md5): _buf(md5) {}
00060 MD5StreamBuffer::MD5StreamBuffer(MD5* md5): _md5(md5) {}
00062 int
00063 MD5StreamBuffer::overflow(int c)
00064 {
00065 unsigned char lc = c;
00066 MD5::MD5Update(&(_md5->m_ctx), &lc, 1);
00067 return c;
00068 }
00070 std::streamsize
00071 MD5StreamBuffer::xsputn(const char* s, std::streamsize num)
00072 {
00073 MD5::MD5Update(&(_md5->m_ctx),
00074 reinterpret_cast<const unsigned char*>(s), num);
00075 return num;
00076 }
00078 MD5::MD5()
00079 : MD5OStreamBase(this), std::ostream(&_buf), m_ctx(), m_finished(false)
00080 {
00081 MD5Init(&m_ctx);
00082 }
00084 void
00085 MD5::init(const String& input)
00086 {
00087 m_finished = false;
00088 MD5Init(&m_ctx);
00089 update(input);
00090 }
00092 MD5::MD5(const String& input)
00093 : MD5OStreamBase(this), std::ostream(&_buf), m_ctx(), m_finished(false)
00094 {
00095 MD5Init(&m_ctx);
00096 update(input);
00097 }
00099 void
00100 MD5::update(const String& input)
00101 {
00102 if (m_finished)
00103 {
00104 BLOCXX_THROW(MD5Exception, "Cannot update after a call to toString()");
00105 }
00106 MD5Update(&m_ctx, reinterpret_cast<const unsigned char*>(input.c_str()),
00107 input.length());
00108 }
00110 String
00111 MD5::toString()
00112 {
00113 return convertBinToHex(getDigest());
00114 }
00116 unsigned char*
00117 MD5::getDigest()
00118 {
00119 if (!m_finished)
00120 {
00121 MD5Final(m_digest, &m_ctx);
00122 m_finished = true;
00123 }
00124 return m_digest;
00125 }
00127 String
00128 MD5::convertBinToHex( const unsigned char* sBin)
00129 {
00130 unsigned short i;
00131 unsigned char j;
00132 char Hex[ MD5HASHHEXLEN + 1 ];
00133 for ( i = 0; i < MD5HASHLEN; i++ )
00134 {
00135 j = (sBin[i] >> 4) & 0xf;
00136 if ( j <= 9 )
00137 {
00138 Hex[i*2] = (j + '0');
00139 }
00140 else
00141 {
00142 Hex[i*2] = (j + 'a' - 10);
00143 }
00144 j = sBin[i] & 0xf;
00145 if ( j <= 9 )
00146 {
00147 Hex[i*2+1] = (j + '0');
00148 }
00149 else
00150 {
00151 Hex[i*2+1] = (j + 'a' - 10);
00152 }
00153 };
00154 Hex[MD5HASHHEXLEN] = '\0';
00155 return String(Hex);
00156 };
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 typedef unsigned char *POINTER;
00179
00180
00181 #define S11 7
00182 #define S12 12
00183 #define S13 17
00184 #define S14 22
00185 #define S21 5
00186 #define S22 9
00187 #define S23 14
00188 #define S24 20
00189 #define S31 4
00190 #define S32 11
00191 #define S33 16
00192 #define S34 23
00193 #define S41 6
00194 #define S42 10
00195 #define S43 15
00196 #define S44 21
00197 static void MD5Transform(UInt32*, const unsigned char*);
00198 static void Encode(unsigned char *, UInt32 *, UInt32);
00199 static void Decode(UInt32 *, const unsigned char *, UInt32);
00200
00201
00202 static unsigned char PADDING[64] = {
00203 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00204 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00205 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00206 };
00207
00208
00209 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
00210 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
00211 #define H(x, y, z) ((x) ^ (y) ^ (z))
00212 #define I(x, y, z) ((y) ^ ((x) | (~z)))
00213
00214
00215 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
00216
00217
00218
00219 #define FF(a, b, c, d, x, s, ac) { \
00220 (a) += F ((b), (c), (d)) + (x) + static_cast<UInt32>(ac); \
00221 (a) = ROTATE_LEFT ((a), (s)); \
00222 (a) += (b); \
00223 }
00224 #define GG(a, b, c, d, x, s, ac) { \
00225 (a) += G ((b), (c), (d)) + (x) + static_cast<UInt32>(ac); \
00226 (a) = ROTATE_LEFT ((a), (s)); \
00227 (a) += (b); \
00228 }
00229 #define HH(a, b, c, d, x, s, ac) { \
00230 (a) += H ((b), (c), (d)) + (x) + static_cast<UInt32>(ac); \
00231 (a) = ROTATE_LEFT ((a), (s)); \
00232 (a) += (b); \
00233 }
00234 #define II(a, b, c, d, x, s, ac) { \
00235 (a) += I ((b), (c), (d)) + (x) + static_cast<UInt32>(ac); \
00236 (a) = ROTATE_LEFT ((a), (s)); \
00237 (a) += (b); \
00238 }
00239
00240
00241 void
00242 MD5::MD5Init(MD5_CTX* context)
00243 {
00244 context->count[0] = context->count[1] = 0;
00245
00246
00247 context->state[0] = 0x67452301;
00248 context->state[1] = 0xefcdab89;
00249 context->state[2] = 0x98badcfe;
00250 context->state[3] = 0x10325476;
00251 }
00252
00253
00254
00255
00256 void
00257 MD5::MD5Update(MD5_CTX* context, const unsigned char* input,
00258 UInt32 inputLen)
00259 {
00260 UInt32 i, index, partLen;
00261
00262 index = ((context->count[0] >> 3) & 0x3F);
00263
00264 if ((context->count[0] += (inputLen << 3)) < (inputLen << 3))
00265 {
00266 context->count[1]++;
00267 }
00268 context->count[1] += (inputLen >> 29);
00269 partLen = 64 - index;
00270
00271
00272 if (inputLen >= partLen)
00273 {
00274 memcpy(static_cast<POINTER>(&context->buffer[index]),
00275 static_cast<const unsigned char*>(input), partLen);
00276 MD5Transform (context->state, context->buffer);
00277 for (i = partLen; i + 63 < inputLen; i += 64)
00278 MD5Transform (context->state, &input[i]);
00279 index = 0;
00280 }
00281 else
00282 i = 0;
00283
00284 memcpy
00285 (static_cast<POINTER>(&context->buffer[index]),
00286 static_cast<const unsigned char*>(&input[i]),
00287 inputLen-i);
00288 }
00289
00290
00291
00292 void
00293 MD5::MD5Final (unsigned char* digest, MD5_CTX* context)
00294 {
00295 unsigned char bits[8];
00296 UInt32 index, padLen;
00297
00298 Encode (bits, context->count, 8);
00299
00300
00301 index = ((context->count[0] >> 3) & 0x3f);
00302 padLen = (index < 56) ? (56 - index) : (120 - index);
00303 MD5Update (context, PADDING, padLen);
00304
00305 MD5Update (context, bits, 8);
00306
00307 Encode (digest, context->state, 16);
00308
00309
00310 memset (reinterpret_cast<POINTER>(context), 0, sizeof (*context));
00311 }
00312
00313
00314 static void MD5Transform (UInt32* state, const unsigned char* block)
00315 {
00316 UInt32 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
00317 Decode (x, block, 64);
00318
00319 FF (a, b, c, d, x[ 0], S11, 0xd76aa478);
00320 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756);
00321 FF (c, d, a, b, x[ 2], S13, 0x242070db);
00322 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee);
00323 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf);
00324 FF (d, a, b, c, x[ 5], S12, 0x4787c62a);
00325 FF (c, d, a, b, x[ 6], S13, 0xa8304613);
00326 FF (b, c, d, a, x[ 7], S14, 0xfd469501);
00327 FF (a, b, c, d, x[ 8], S11, 0x698098d8);
00328 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af);
00329 FF (c, d, a, b, x[10], S13, 0xffff5bb1);
00330 FF (b, c, d, a, x[11], S14, 0x895cd7be);
00331 FF (a, b, c, d, x[12], S11, 0x6b901122);
00332 FF (d, a, b, c, x[13], S12, 0xfd987193);
00333 FF (c, d, a, b, x[14], S13, 0xa679438e);
00334 FF (b, c, d, a, x[15], S14, 0x49b40821);
00335
00336 GG (a, b, c, d, x[ 1], S21, 0xf61e2562);
00337 GG (d, a, b, c, x[ 6], S22, 0xc040b340);
00338 GG (c, d, a, b, x[11], S23, 0x265e5a51);
00339 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa);
00340 GG (a, b, c, d, x[ 5], S21, 0xd62f105d);
00341 GG (d, a, b, c, x[10], S22, 0x2441453);
00342 GG (c, d, a, b, x[15], S23, 0xd8a1e681);
00343 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8);
00344 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6);
00345 GG (d, a, b, c, x[14], S22, 0xc33707d6);
00346 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87);
00347 GG (b, c, d, a, x[ 8], S24, 0x455a14ed);
00348 GG (a, b, c, d, x[13], S21, 0xa9e3e905);
00349 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8);
00350 GG (c, d, a, b, x[ 7], S23, 0x676f02d9);
00351 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a);
00352
00353 HH (a, b, c, d, x[ 5], S31, 0xfffa3942);
00354 HH (d, a, b, c, x[ 8], S32, 0x8771f681);
00355 HH (c, d, a, b, x[11], S33, 0x6d9d6122);
00356 HH (b, c, d, a, x[14], S34, 0xfde5380c);
00357 HH (a, b, c, d, x[ 1], S31, 0xa4beea44);
00358 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9);
00359 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60);
00360 HH (b, c, d, a, x[10], S34, 0xbebfbc70);
00361 HH (a, b, c, d, x[13], S31, 0x289b7ec6);
00362 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa);
00363 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085);
00364 HH (b, c, d, a, x[ 6], S34, 0x4881d05);
00365 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039);
00366 HH (d, a, b, c, x[12], S32, 0xe6db99e5);
00367 HH (c, d, a, b, x[15], S33, 0x1fa27cf8);
00368 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665);
00369
00370 II (a, b, c, d, x[ 0], S41, 0xf4292244);
00371 II (d, a, b, c, x[ 7], S42, 0x432aff97);
00372 II (c, d, a, b, x[14], S43, 0xab9423a7);
00373 II (b, c, d, a, x[ 5], S44, 0xfc93a039);
00374 II (a, b, c, d, x[12], S41, 0x655b59c3);
00375 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92);
00376 II (c, d, a, b, x[10], S43, 0xffeff47d);
00377 II (b, c, d, a, x[ 1], S44, 0x85845dd1);
00378 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f);
00379 II (d, a, b, c, x[15], S42, 0xfe2ce6e0);
00380 II (c, d, a, b, x[ 6], S43, 0xa3014314);
00381 II (b, c, d, a, x[13], S44, 0x4e0811a1);
00382 II (a, b, c, d, x[ 4], S41, 0xf7537e82);
00383 II (d, a, b, c, x[11], S42, 0xbd3af235);
00384 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb);
00385 II (b, c, d, a, x[ 9], S44, 0xeb86d391);
00386 state[0] += a;
00387 state[1] += b;
00388 state[2] += c;
00389 state[3] += d;
00390
00391 memset (reinterpret_cast<POINTER>(x), 0, sizeof (x));
00392 }
00393
00394
00395
00396 static void Encode (unsigned char* output, UInt32* input, UInt32 len)
00397 {
00398 UInt32 i, j;
00399 for (i = 0, j = 0; j < len; i++, j += 4)
00400 {
00401 output[j] = (input[i] & 0xff);
00402 output[j+1] = ((input[i] >> 8) & 0xff);
00403 output[j+2] = ((input[i] >> 16) & 0xff);
00404 output[j+3] = ((input[i] >> 24) & 0xff);
00405 }
00406 }
00407
00408
00409
00410 static void Decode (UInt32* output, const unsigned char* input, UInt32 len)
00411 {
00412 UInt32 i, j;
00413 for (i = 0, j = 0; j < len; i++, j += 4)
00414 output[i] = (static_cast<UInt32>(input[j])) | ((static_cast<UInt32>(input[j+1])) << 8) |
00415 ((static_cast<UInt32>(input[j+2])) << 16) | ((static_cast<UInt32>(input[j+3])) << 24);
00416 }
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433 }
00434
00435
00436 #ifdef BLOCXX_WIN32
00437 #pragma warning (pop)
00438 #endif
00439