OTES: Four BYTES from the input array are transferred to each DWORD entry
of the output array. The first BYTE is transferred to the bits (0-7)
of the output DWORD, the second BYTE to bits 8-15 etc.
The algorithm assumes that the input array is a multiple of 4 bytes long
so that there is a perfect fit into the array of 32 bit words.
*****************************************************************************************/
void CMD5Checksum::ByteToDWord(DWORD* Output, BYTE* Input, UINT nLength)
{
//entry invariants
ASSERT( nLength % 4 == 0 );
ASSERT( AfxIsValidAddress(Output, nLength/4, TRUE) );
ASSERT( AfxIsValidAddress(Input, nLength, FALSE) );
//initialisations
UINT i=0; //index to Output array
UINT j=0; //index to Input array
//transfer the data by shifting and copying
for ( ; j < nLength; i++, j += 4)
{
Output[i] = (ULONG)Input[j] |
(ULONG)Input[j+1] << 8 |
(ULONG)Input[j+2] << 16 |
(ULONG)Input[j+3] << 24;
}
}
/*****************************************************************************************
FUNCTION: CMD5Checksum::Transform
DETAILS: protected
DESCRIPTION: MD5 basic transformation algorithm; transforms ''''m_lMD5''''
RETURNS: void
ARGUMENTS: BYTE Block[64]
NOTES: An MD5 checksum is calculated by four rounds of ''''Transformation''''.
The MD5 checksum currently held in m_lMD5 is merged by the
transformation process with data passed in ''''Block''''.
*****************************************************************************************/
void CMD5Checksum::Transform(BYTE Block[64])
{
//initialise local data with current checksum
ULONG a = m_lMD5[0];
ULONG b = m_lMD5;
ULONG c = m_lMD5;
ULONG d = m_lMD5;
//copy BYTES from input ''''Block'''' to an array of ULONGS ''''X''''
ULONG X[16];
ByteToDWord( X, Block, 64 );
//Perform Round 1 of the transformation
FF (a, b, c, d, X[ 0], MD5_S11, MD5_T01);
FF (d, a, b, c, X[ 1], MD5_S12, MD5_T02);
FF (c, d, a, b, X[ 2], MD5_S13, MD5_T03);
FF (b, c, d, a, X[ 3], MD5_S14, MD5_T04);
FF (a, b, c, d, X[ 4], MD5_S11, MD5_T05);
FF (d, a, b, c, X[ 5], MD5_S12, MD5_T06);
FF (c, d, a, b, X[ 6], MD5_S13, MD5_T07);
FF (b, c, d, a, X[ 7], MD5_S14, MD5_T08);
FF (a, b, c, d, X[ 8], MD5_S11, MD5_T09);
FF (d, a, b, c, X[ 9], MD5_S12, MD5_T10);
FF (c, d, a, b, X, MD5_S13, MD5_T11);
FF (b, c, d, a, X, MD5_S14, MD5_T12);
FF (a, b, c, d, X, MD5_S11, MD5_T13);
FF (d, a, b, c, X, MD5_S12, MD5_T14);
FF (c, d, a, b, X, MD5_S13, MD5_T15);
FF (b, c, d, a, X[15], MD5_S14, MD5_T16);
//Perform Round 2 of the transformation
GG (a, b, c, d, X[ 1], MD5_S21, MD5_T17);
GG (d, a, b, c, X[ 6], MD5_S22, MD5_T18);
GG (c, d, a, b, X, MD5_S23, MD5_T19);
GG (b,