1// md5.cpp : Defines the entry point for the DLL application. 2// 3 4 5#include "md5.h" 6 7/* MD5 initialization. Begins an MD5 operation, writing a new context. */ 8void MD5Init(MD5_CTX *context) /* context */ 9{ 10 context->count[0] = context->count[1] = 0; 11 /* Load magic initialization constants.*/ 12 context->state[0] = 0x67452301; 13 context->state[1] = 0xefcdab89; 14 context->state[2] = 0x98badcfe; 15 context->state[3] = 0x10325476; 16} 17/* MD5 block update operation. Continues an MD5 message-digest 18 operation, processing another message block, and updating the context. */ 19 20void MD5Update (MD5_CTX *context, unsigned char *input, unsigned int inputLen) 21 { 22 unsigned int i, index, partLen; /* Compute number of bytes mod 64 */ 23 index = (unsigned int)((context->count[0] >> 3) & 0x3F); 24 /* Update number of bits */ 25 if ((context->count[0] += ((unsigned int)inputLen << 3)) 26 < ((unsigned int)inputLen << 3)) context->count[1]++; 27 28 context->count[1] += ((unsigned int)inputLen >> 29); 29 partLen = 64 - index; 30 /* Transform as many times as possible.*/ 31 if (inputLen >= partLen) 32 { 33 MD5_memcpy((unsigned char *)&context->buffer[index], (unsigned char *)input, partLen); 34 MD5Transform(context->state, context->buffer); 35 36 for (i = partLen; i + 63 < inputLen; i += 64) 37 MD5Transform (context->state, &input[i]); 38 index = 0; 39 } 40 else i = 0; 41 /* Buffer remaining input */ 42 MD5_memcpy((unsigned char *)&context->buffer[index], (unsigned char *)&input[i], inputLen-i); 43 } 44/* MD5 finalization. Ends an MD5 message-digest operation, writing the 45 the message digest and zeroizing the context. */ 46void MD5Final (unsigned char* digest, MD5_CTX *context) 47 { 48 unsigned char bits[8]; 49 unsigned int index, padLen; /* Save number of bits */ 50 Encode (bits, context->count, 8); /* Pad out to 56 mod 64.*/ 51 index = (unsigned int)((context->count[0] >> 3) & 0x3f); 52 padLen = (index < 56) ? (56 - index) : (120 - index); 53 MD5Update (context, PADDING, padLen); /* Append length (before padding) */ 54 MD5Update (context, bits, 8); 55 /* Store state in digest */ 56 Encode (digest, context->state, 16); 57 /* Zeroize sensitive information.*/ 58 MD5_memset ((unsigned char *)context, 0, sizeof (*context)); 59 } 60 61/* MD5 basic transformation. Transforms state based on block. */ 62static void MD5Transform (unsigned int state[4], unsigned char block[64]) 63 { 64 unsigned int a = state[0], b = state[1], c = state[2], d = state[3], x[16]; 65 Decode (x, block, 64); 66 /* Round 1 */ 67 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ 68 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ 69 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ 70 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ 71 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ 72 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ 73 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ 74 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ 75 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ 76 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ 77 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ 78 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ 79 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ 80 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ 81 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ 82 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ 83 /* Round 2 */ 84 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ 85 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ 86 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ 87 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ 88 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ 89 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ 90 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ 91 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ 92 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ 93 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ 94 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ 95 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ 96 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ 97 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ 98 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ 99 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ 100 /* Round 3 */ 101 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ 102 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ 103 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ 104 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ 105 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ 106 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ 107 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ 108 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ 109 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ 110 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ 111 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ 112 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ 113 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ 114 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ 115 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ 116 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ 117 /* Round 4 */ 118 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ 119 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ 120 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ 121 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ 122 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ 123 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ 124 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ 125 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ 126 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ 127 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ 128 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ 129 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ 130 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ 131 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ 132 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ 133 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ 134 state[0] += a; 135 state[1] += b; 136 state[2] += c; 137 state[3] += d; 138 /* Zeroize sensitive information. 139 */ 140 MD5_memset ((unsigned char *)x, 0, sizeof (x)); 141 } 142 143/* Encodes input (unsigned int) into output (unsigned char). Assumes len is 144 a multiple of 4. */ 145 static void Encode (unsigned char *output, unsigned int *input, unsigned int len) 146 { 147 unsigned int i, j; 148 for (i = 0, j = 0; j < len; i++, j += 4) 149 { 150 output[j] = (char)(input[i] & 0xff); 151 output[j+1] = (char)((input[i] >> 8) & 0xff); 152 output[j+2] = (char)((input[i] >> 16) & 0xff); 153 output[j+3] = (char)((input[i] >> 24) & 0xff); 154 } 155 } 156 157/* Decodes input (unsigned char) into output (unsigned int). Assumes len is 158 a multiple of 4. */ 159 static void Decode (unsigned int *output, unsigned char *input, unsigned int len) 160 { 161 unsigned int i, j; 162 for (i = 0, j = 0; j < len; i++, j += 4) 163 output[i] = ((unsigned int)input[j]) | (((unsigned int)input[j+1]) << 8) | 164 (((unsigned int)input[j+2]) << 16) | (((unsigned int)input[j+3]) << 24); 165 } 166 167/* Note: Replace "for loop" with standard memcpy if possible. */ 168 static void MD5_memcpy (unsigned char * output, unsigned char * input, unsigned int len) 169 { 170 unsigned int i; for (i = 0; i < len; i++) 171 output[i] = input[i]; 172 } 173 174/* Note: Replace "for loop" with standard memset if possible. */ 175 176static void MD5_memset (unsigned char * output, int value, unsigned int len) 177 { 178 unsigned int i; 179 for (i = 0; i < len; i++) 180 ((char *)output)[i] = (char)value; 181 } 182 183 184int MDString (unsigned char* string, unsigned int nLen, unsigned char* digest) 185 186{ 187 MD_CTX context; 188 //char digest[16]; 189 MDInit (&context); 190 MDUpdate (&context, string, nLen); 191 MDFinal (digest, &context); 192 //digest[0] ='a'; 193 194 return 1; 195} 196 197 198#define PADLEN 64 199#define MAXMD5SOURCESTRINGLEN 1024 200unsigned int KeyMD5Encode(unsigned char* szEncoded, const unsigned char* szData, unsigned int nSize, unsigned char* szKey, unsigned int nKeyLen) 201{ 202 //See rfc2104 203 unsigned char ipad[PADLEN] = {0}, opad[PADLEN] = {0}; 204 unsigned char K[PADLEN] = {0}; 205 unsigned char firstPad[PADLEN + MAXMD5SOURCESTRINGLEN + 1] = {0}; 206 unsigned char midResult[PADLEN + 16] = {0}; 207 int i; 208 209 memset(ipad, 0x36, PADLEN); 210 memset(opad, 0x5c, PADLEN); 211 212 213 memcpy(K, szKey, nKeyLen); 214 215 for(i = 0; i < PADLEN; i++) 216 { 217 ipad[i] ^= K[i]; 218 opad[i] ^= K[i]; 219 } 220 221 222 memcpy(firstPad, ipad, PADLEN); 223 memcpy(firstPad + PADLEN, szData, nSize); 224 firstPad[PADLEN + nSize] = '\x0'; 225 MDString(firstPad, PADLEN + nSize, midResult + PADLEN); 226 227 memcpy(midResult, opad, PADLEN); 228 MDString(midResult, PADLEN + 16, szEncoded); 229 230 return 16; 231}