#include #include #include #include "md5.h" // This is a fun macro that tells us where the length char goes after the data // section in the padded data segment. It's short for OBfuscation LOCaction. #define OBLOC(len) ((((len + 64) >> 9) << 4) + 14) // This performs a wrapping bitwise shift, kinda' fun! #define bit_roll( num, cnt ) \ (((num) << (cnt)) | (((num) >> (32 - (cnt))) & ~(-1<<(cnt)))) //#define md5_cmn( q, a, b, x, s, t ) (bit_roll((a + q + x + t), s) + b) // The following are handy wrappers for the cmn function #define md5_ff( a, b, c, d, x, s, t ) \ (md5_cmn((b & c) | ((~b) & d), a, b, x, s, t)) #define md5_gg( a, b, c, d, x, s, t ) \ (md5_cmn((b & d) | (c & (~d)), a, b, x, s, t)) #define md5_hh( a, b, c, d, x, s, t ) \ (md5_cmn(b ^ c ^ d, a, b, x, s, t)) #define md5_ii( a, b, c, d, x, s, t ) \ (md5_cmn(c ^ (b | (~d)), a, b, x, s, t)) inline long md5_cmn( long q, long a, long b, long x, long s, long t ) { return bit_roll((a + q + x + t), s) + b; } md5::md5() { } md5::~md5() { } /* * Calculate the MD5 of an array of little-endian words, and a bit length */ void md5::core_md5( long *x, long len, md5sum *output ) { long a = 1732584193, olda; long b = -271733879, oldb; long c = -1732584194, oldc; long d = 271733878, oldd; for( long i = 0; i < len; i += 16 ) { olda = a; oldb = b; oldc = c; oldd = d; a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819); b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426); c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416); d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); c = md5_ff(c, d, a, b, x[i+10], 17, -42063); b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682); d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329); a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); c = md5_gg(c, d, a, b, x[i+11], 14, 643717713); b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083); c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438); d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501); a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473); b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562); b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353); c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174); d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189); a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); c = md5_hh(c, d, a, b, x[i+15], 16, 530742520); b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415); c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571); d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359); d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649); a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259); b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); a = a + olda; b = b + oldb; c = c + oldc; d = d + oldd; } output->data[0] = a; output->data[1] = b; output->data[2] = c; output->data[3] = d; delete[] x; } long *md5::c2l( const char *str, long len, long *nNewLen ) { long len8 = len*8; long mlen = OBLOC( len8 ); long flen = (((mlen/16)+((mlen%16)?(1):(0))))*16; long *aBin = new long[flen]; memset( aBin, 0, flen*4 ); for( long i = 0; i < len8; i+=8 ) { aBin[i>>5] |= ((long)str[i/8]) << (i%32); } aBin[len8 >> 5] |= 0x80 << ((len8) % 32); aBin[OBLOC( len8 )] = len8; (*nNewLen) = flen; return aBin; } void md5::l2hexstr( long *binarray, char *str ) { static const char hex_tab[] = {"0123456789abcdef"}; //static char str[33]; int k = 0; for( int i = 0; i < 16; i++) { str[k++] = hex_tab[(binarray[i>>2] >> ((i%4)*8+4)) & 0xF]; str[k++] = hex_tab[(binarray[i>>2] >> ((i%4)*8 )) & 0xF]; } } void md5::sumString( md5sum *pSum, const char *sStr ) { sumData( pSum, sStr, strlen( sStr ) ); } void md5::sumData( md5sum *pSum, const char *aData, long nLen ) { long nNewLen; long *aOb = c2l( aData, nLen, &nNewLen ); core_md5( aOb, nNewLen, pSum ); } void md5::sumToHex( md5sum *pSum, char *sHex ) { l2hexstr( pSum->data, sHex ); }