khanat-opennel-code/code/nelns/login_system/nel_launcher_windows_ext/Md5.cpp
2015-03-01 18:41:16 +02:00

487 lines
13 KiB
C++

// Md5.cpp: implementation of the CMd5 class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Md5.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
#define MD5_PAD_FIRST_BYTE 0x80 // The first byte of padding.
#define MD5_PAD_SIZE 56 // The padding function pads out to 56 bytes.
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
#define T1 0xd76aa478
#define T2 0xe8c7b756
#define T3 0x242070db
#define T4 0xc1bdceee
#define T5 0xf57c0faf
#define T6 0x4787c62a
#define T7 0xa8304613
#define T8 0xfd469501
#define T9 0x698098d8
#define T10 0x8b44f7af
#define T11 0xffff5bb1
#define T12 0x895cd7be
#define T13 0x6b901122
#define T14 0xfd987193
#define T15 0xa679438e
#define T16 0x49b40821
#define T17 0xf61e2562
#define T18 0xc040b340
#define T19 0x265e5a51
#define T20 0xe9b6c7aa
#define T21 0xd62f105d
#define T22 0x02441453
#define T23 0xd8a1e681
#define T24 0xe7d3fbc8
#define T25 0x21e1cde6
#define T26 0xc33707d6
#define T27 0xf4d50d87
#define T28 0x455a14ed
#define T29 0xa9e3e905
#define T30 0xfcefa3f8
#define T31 0x676f02d9
#define T32 0x8d2a4c8a
#define T33 0xfffa3942
#define T34 0x8771f681
#define T35 0x6d9d6122
#define T36 0xfde5380c
#define T37 0xa4beea44
#define T38 0x4bdecfa9
#define T39 0xf6bb4b60
#define T40 0xbebfbc70
#define T41 0x289b7ec6
#define T42 0xeaa127fa
#define T43 0xd4ef3085
#define T44 0x04881d05
#define T45 0xd9d4d039
#define T46 0xe6db99e5
#define T47 0x1fa27cf8
#define T48 0xc4ac5665
#define T49 0xf4292244
#define T50 0x432aff97
#define T51 0xab9423a7
#define T52 0xfc93a039
#define T53 0x655b59c3
#define T54 0x8f0ccc92
#define T55 0xffeff47d
#define T56 0x85845dd1
#define T57 0x6fa87e4f
#define T58 0xfe2ce6e0
#define T59 0xa3014314
#define T60 0x4e0811a1
#define T61 0xf7537e82
#define T62 0xbd3af235
#define T63 0x2ad7d2bb
#define T64 0xeb86d391
#define A_INIT 0x67452301
#define B_INIT 0xefcdab89
#define C_INIT 0x98badcfe
#define D_INIT 0x10325476
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMD5::CMD5()
{
}
CMD5::CMD5(CFile& InputFile)
{
// Initialize the digest.
a = A_INIT;
b = B_INIT;
c = C_INIT;
d = D_INIT;
// Now init the bit length of the input.
count[0] = 0;
count[1] = 0;
// Now perform transformation on every block of input.
do
{
// Read a block from the input.
block_idx = InputFile.Read( manip_block, MD5_BLOCK_SIZE);
if (block_idx == MD5_BLOCK_SIZE)
{
// A full block is ready to be transformed. Do so.
MD5_IncCount( MD5_BLOCK_SIZE );
MD5_Xform();
}
else
{
MD5_IncCount( block_idx );
// If the count of bytes read is not a full block,
// the end of the file has been found, and the ending should be prepared.
if (block_idx < (MD5_PAD_SIZE) )
{
// There is enough room in the block, to pad up to the correct size.
// Pad and then transform.
MD5_Pad( normal );
MD5_Xform();
}
else
{
// The block is already up to or beyond the pad size. Pad to the
// end and of the current block, and then transform it.
MD5_Pad( to_end );
MD5_Xform();
// Now create another block that is empty and pad all the way.
block_idx = 0;
MD5_Pad( finish );
MD5_Xform();
}
}
} while (block_idx == MD5_BLOCK_SIZE);
}
void CMD5::SetContent(CString csContent)
{
int iOffset = 0;
// Initialize the digest.
a = A_INIT;
b = B_INIT;
c = C_INIT;
d = D_INIT;
// Now init the bit length of the input.
count[0] = 0;
count[1] = 0;
// Now perform transformation on every block of input.
do
{
strcpy((char*)manip_block, csContent.Mid(iOffset, MD5_BLOCK_SIZE));
block_idx = strlen((const char*)manip_block);
if (block_idx == MD5_BLOCK_SIZE)
{
// A full block is ready to be transformed. Do so.
MD5_IncCount(MD5_BLOCK_SIZE);
MD5_Xform();
}
else
{
MD5_IncCount( block_idx );
// If the count of bytes read is not a full block,
// the end of the file has been found, and the ending should be prepared.
if (block_idx < (MD5_PAD_SIZE) )
{
// There is enough room in the block, to pad up to the correct size.
// Pad and then transform.
MD5_Pad( normal );
MD5_Xform();
}
else
{
// The block is already up to or beyond the pad size. Pad to the
// end and of the current block, and then transform it.
MD5_Pad( to_end );
MD5_Xform();
// Now create another block that is empty and pad all the way.
block_idx = 0;
MD5_Pad( finish );
MD5_Xform();
}
}
}
while (block_idx == MD5_BLOCK_SIZE);
}
void CMD5::MD5_Pad( MD5_PadMode PadMode )
{
switch( PadMode )
{
case normal:
// Perform normal padding.
manip_block[block_idx++] = MD5_PAD_FIRST_BYTE;
while (block_idx < MD5_PAD_SIZE)
manip_block[block_idx++] = 0;
// Now store count in this last block.
MD5_StoreCnt();
break;
case to_end:
// Pad until the end of the block.
manip_block[block_idx++] = MD5_PAD_FIRST_BYTE;
while (block_idx < MD5_BLOCK_SIZE)
manip_block[block_idx++] = 0;
break;
case finish:
// Finish padding.
while (block_idx < MD5_PAD_SIZE)
manip_block[block_idx++] = 0;
// Now store count in this last block.
MD5_StoreCnt();
break;
}
}
void CMD5::MD5_Xform()
{
// Save orig values of a,b,c,d.
UINT4 a_orig = a;
UINT4 b_orig = b;
UINT4 c_orig = c;
UINT4 d_orig = d;
// Now decode the manip_block into xform_buf;
MD5_Decode();
// Round 1.
// Let [abcd k s i] denote the operation
// a = b + ((a + F(b,c,d) + xform_buf[k] + T[i]) <<< s).
// Do the following 16 operations.
// [ABCD 0 7 1] [DABC 1 12 2] [CDAB 2 17 3] [BCDA 3 22 4]
// [ABCD 4 7 5] [DABC 5 12 6] [CDAB 6 17 7] [BCDA 7 22 8]
// [ABCD 8 7 9] [DABC 9 12 10] [CDAB 10 17 11] [BCDA 11 22 12]
// [ABCD 12 7 13] [DABC 13 12 14] [CDAB 14 17 15] [BCDA 15 22 16]
FF (a, b, c, d, xform_buf[ 0], S11, T1);
FF (d, a, b, c, xform_buf[ 1], S12, T2);
FF (c, d, a, b, xform_buf[ 2], S13, T3);
FF (b, c, d, a, xform_buf[ 3], S14, T4);
FF (a, b, c, d, xform_buf[ 4], S11, T5);
FF (d, a, b, c, xform_buf[ 5], S12, T6);
FF (c, d, a, b, xform_buf[ 6], S13, T7);
FF (b, c, d, a, xform_buf[ 7], S14, T8);
FF (a, b, c, d, xform_buf[ 8], S11, T9);
FF (d, a, b, c, xform_buf[ 9], S12, T10);
FF (c, d, a, b, xform_buf[10], S13, T11);
FF (b, c, d, a, xform_buf[11], S14, T12);
FF (a, b, c, d, xform_buf[12], S11, T13);
FF (d, a, b, c, xform_buf[13], S12, T14);
FF (c, d, a, b, xform_buf[14], S13, T15);
FF (b, c, d, a, xform_buf[15], S14, T16);
// Round 2.
// Let [abcd k s i] denote the operation
// a = b + ((a + G(b,c,d) + xform_buf[k] + T[i]) <<< s).
// Do the following 16 operations.
// [ABCD 1 5 17] [DABC 6 9 18] [CDAB 11 14 19] [BCDA 0 20 20]
// [ABCD 5 5 21] [DABC 10 9 22] [CDAB 15 14 23] [BCDA 4 20 24]
// [ABCD 9 5 25] [DABC 14 9 26] [CDAB 3 14 27] [BCDA 8 20 28]
// [ABCD 13 5 29] [DABC 2 9 30] [CDAB 7 14 31] [BCDA 12 20 32]
GG (a, b, c, d, xform_buf[ 1], S21, T17);
GG (d, a, b, c, xform_buf[ 6], S22, T18);
GG (c, d, a, b, xform_buf[11], S23, T19);
GG (b, c, d, a, xform_buf[ 0], S24, T20);
GG (a, b, c, d, xform_buf[ 5], S21, T21);
GG (d, a, b, c, xform_buf[10], S22, T22);
GG (c, d, a, b, xform_buf[15], S23, T23);
GG (b, c, d, a, xform_buf[ 4], S24, T24);
GG (a, b, c, d, xform_buf[ 9], S21, T25);
GG (d, a, b, c, xform_buf[14], S22, T26);
GG (c, d, a, b, xform_buf[ 3], S23, T27);
GG (b, c, d, a, xform_buf[ 8], S24, T28);
GG (a, b, c, d, xform_buf[13], S21, T29);
GG (d, a, b, c, xform_buf[ 2], S22, T30);
GG (c, d, a, b, xform_buf[ 7], S23, T31);
GG (b, c, d, a, xform_buf[12], S24, T32);
// Round 3.
// Let [abcd k s t] denote the operation
// a = b + ((a + H(b,c,d) + xform_buf[k] + T[i]) <<< s).
// Do the following 16 operations.
// [ABCD 5 4 33] [DABC 8 11 34] [CDAB 11 16 35] [BCDA 14 23 36]
// [ABCD 1 4 37] [DABC 4 11 38] [CDAB 7 16 39] [BCDA 10 23 40]
// [ABCD 13 4 41] [DABC 0 11 42] [CDAB 3 16 43] [BCDA 6 23 44]
// [ABCD 9 4 45] [DABC 12 11 46] [CDAB 15 16 47] [BCDA 2 23 48]
HH (a, b, c, d, xform_buf[ 5], S31, T33);
HH (d, a, b, c, xform_buf[ 8], S32, T34);
HH (c, d, a, b, xform_buf[11], S33, T35);
HH (b, c, d, a, xform_buf[14], S34, T36);
HH (a, b, c, d, xform_buf[ 1], S31, T37);
HH (d, a, b, c, xform_buf[ 4], S32, T38);
HH (c, d, a, b, xform_buf[ 7], S33, T39);
HH (b, c, d, a, xform_buf[10], S34, T40);
HH (a, b, c, d, xform_buf[13], S31, T41);
HH (d, a, b, c, xform_buf[ 0], S32, T42);
HH (c, d, a, b, xform_buf[ 3], S33, T43);
HH (b, c, d, a, xform_buf[ 6], S34, T44);
HH (a, b, c, d, xform_buf[ 9], S31, T45);
HH (d, a, b, c, xform_buf[12], S32, T46);
HH (c, d, a, b, xform_buf[15], S33, T47);
HH (b, c, d, a, xform_buf[ 2], S34, T48);
// Round 4.
// Let [abcd k s t] denote the operation
// a = b + ((a + I(b,c,d) + xform_buf[k] + T[i]) <<< s).
// Do the following 16 operations.
// [ABCD 0 6 49] [DABC 7 10 50] [CDAB 14 15 51] [BCDA 5 21 52]
// [ABCD 12 6 53] [DABC 3 10 54] [CDAB 10 15 55] [BCDA 1 21 56]
// [ABCD 8 6 57] [DABC 15 10 58] [CDAB 6 15 59] [BCDA 13 21 60]
// [ABCD 4 6 61] [DABC 11 10 62] [CDAB 2 15 63] [BCDA 9 21 64]
II (a, b, c, d, xform_buf[ 0], S41, T49);
II (d, a, b, c, xform_buf[ 7], S42, T50);
II (c, d, a, b, xform_buf[14], S43, T51);
II (b, c, d, a, xform_buf[ 5], S44, T52);
II (a, b, c, d, xform_buf[12], S41, T53);
II (d, a, b, c, xform_buf[ 3], S42, T54);
II (c, d, a, b, xform_buf[10], S43, T55);
II (b, c, d, a, xform_buf[ 1], S44, T56);
II (a, b, c, d, xform_buf[ 8], S41, T57);
II (d, a, b, c, xform_buf[15], S42, T58);
II (c, d, a, b, xform_buf[ 6], S43, T59);
II (b, c, d, a, xform_buf[13], S44, T60);
II (a, b, c, d, xform_buf[ 4], S41, T61);
II (d, a, b, c, xform_buf[11], S42, T62);
II (c, d, a, b, xform_buf[ 2], S43, T63);
II (b, c, d, a, xform_buf[ 9], S44, T64);
// Now perform the following additions. (That is increment each
// of the four registers by the value it had before this block
// was started.)
a += a_orig;
b += b_orig;
c += c_orig;
d += d_orig;
}
void CMD5::MD5_IncCount( int IncAmt)
{
UINT4 old_cnt0 = count[0];
count[0] += IncAmt*8;
if(count[0] < old_cnt0)
count[1]++; // Carry detection.
}
void CMD5::MD5_Decode()
{
unsigned int i, j;
for (i = 0, j = 0; j < MD5_BLOCK_SIZE; i++, j += sizeof(UINT4))
xform_buf[i] = ((UINT4)manip_block[j]) | (((UINT4)manip_block[j+1]) << 8) |
(((UINT4)manip_block[j+2]) << 16) | (((UINT4)manip_block[j+3]) << 24);
}
void CMD5::MD5_StoreCnt()
{
manip_block[MD5_PAD_SIZE+0]= unsigned int( count[0] & 0xff);
manip_block[MD5_PAD_SIZE+1]= unsigned int((count[0] >> 8) & 0xff);
manip_block[MD5_PAD_SIZE+2]= unsigned int((count[0] >> 16) & 0xff);
manip_block[MD5_PAD_SIZE+3]= unsigned int((count[0] >> 24) & 0xff);
manip_block[MD5_PAD_SIZE+4]= unsigned int(count[1] & 0xff);
manip_block[MD5_PAD_SIZE+5]= unsigned int((count[1] >> 8) & 0xff);
manip_block[MD5_PAD_SIZE+6]= unsigned int((count[1] >> 16) & 0xff);
manip_block[MD5_PAD_SIZE+7]= unsigned int((count[1] >> 24) & 0xff);
}
void CMD5::GetDigest( unsigned char* Dest)
{
Dest[0] = unsigned int(a & 0xff);
Dest[1] = unsigned int((a >> 8) & 0xff);
Dest[2] = unsigned int((a >> 16) & 0xff);
Dest[3] = unsigned int((a >> 24) & 0xff);
Dest[4] = unsigned int(b & 0xff);
Dest[5] = unsigned int((b >> 8) & 0xff);
Dest[6] = unsigned int((b >> 16) & 0xff);
Dest[7] = unsigned int((b >> 24) & 0xff);
Dest[8] = unsigned int(c & 0xff);
Dest[9] = unsigned int((c >> 8) & 0xff);
Dest[10] = unsigned int((c >> 16) & 0xff);
Dest[11] = unsigned int((c >> 24) & 0xff);
Dest[12] = unsigned int(d & 0xff);
Dest[13] = unsigned int((d >> 8) & 0xff);
Dest[14] = unsigned int((d >> 16) & 0xff);
Dest[15] = unsigned int((d >> 24) & 0xff);
}
CString CMD5::ConvertToAscii(unsigned char* lpszBuff)
{
CString csRet;
CString csHex = "0123456789abcdef";
int i, j;
unsigned long num;
unsigned long* plBuff = (unsigned long*)lpszBuff;
for(i = 0; i < 4; i++)
{
num = plBuff[i];
for(j = 0; j < 4; j++)
{
csRet += csHex[int((num >> (j * 8 + 4)) & 0x0F)];
csRet += csHex[int((num >> (j * 8)) & 0x0F)];
}
}
return csRet;
}