MD5.cpp (10651B)
1 /* 2 =========================================================================== 3 4 Doom 3 BFG Edition GPL Source Code 5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 6 7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). 8 9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation, either version 3 of the License, or 12 (at your option) any later version. 13 14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>. 21 22 In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below. 23 24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. 25 26 =========================================================================== 27 */ 28 29 #pragma hdrstop 30 #include "../precompiled.h" 31 32 /* 33 ================================================================================================ 34 Contains the MD5BlockChecksum implementation. 35 ================================================================================================ 36 */ 37 38 // POINTER defines a generic pointer type 39 typedef unsigned char *POINTER; 40 41 // UINT2 defines a two byte word 42 typedef unsigned short int UINT2; 43 44 // UINT4 defines a four byte word 45 typedef unsigned int UINT4; 46 47 //------------------------ 48 // The four core functions - F1 is optimized somewhat 49 // JDC: I wouldn't have condoned the change in something as sensitive as a hash function, 50 // but it looks ok and a random test function checked it out. 51 //------------------------ 52 // #define F1(x, y, z) (x & y | ~x & z) 53 #define F1(x, y, z) (z ^ (x & (y ^ z))) 54 #define F2(x, y, z) F1(z, x, y) 55 #define F3(x, y, z) (x ^ y ^ z) 56 #define F4(x, y, z) (y ^ (x | ~z)) 57 58 // This is the central step in the MD5 algorithm. 59 #define MD5STEP(f, w, x, y, z, data, s) ( w += f(x, y, z) + (data), w = w<<s | w>>(32-s), w += x ) 60 61 static unsigned char PADDING[64] = { 62 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 63 }; 64 65 /* 66 ======================== 67 Encode 68 69 Encodes input (UINT4) into output (unsigned char). Assumes len is a multiple of 4. 70 ======================== 71 */ 72 static void Encode( unsigned char *output, UINT4 *input, unsigned int len ) { 73 unsigned int i, j; 74 75 for ( i = 0, j = 0; j < len; i++, j += 4 ) { 76 output[j] = (unsigned char)(input[i] & 0xff); 77 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); 78 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); 79 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); 80 } 81 } 82 83 /* 84 ======================== 85 Decode 86 87 Decodes input (unsigned char) into output (UINT4). Assumes len is a multiple of 4. 88 ======================== 89 */ 90 static void Decode( UINT4 *output, const unsigned char *input, unsigned int len ) { 91 unsigned int i, j; 92 93 for ( i = 0, j = 0; j < len; i++, j += 4 ) { 94 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); 95 } 96 } 97 98 /* 99 ======================== 100 MD5_Transform 101 102 The core of the MD5 algorithm, this alters an existing MD5 hash to reflect the addition of 16 103 longwords of new data. MD5Update blocks the data and converts bytes into longwords for this 104 routine. 105 ======================== 106 */ 107 void MD5_Transform( unsigned int state[4], const unsigned char block[64] ) { 108 unsigned int a, b, c, d, x[16]; 109 110 a = state[0]; 111 b = state[1]; 112 c = state[2]; 113 d = state[3]; 114 115 Decode( x, block, 64 ); 116 117 MD5STEP( F1, a, b, c, d, x[ 0] + 0xd76aa478, 7 ); 118 MD5STEP( F1, d, a, b, c, x[ 1] + 0xe8c7b756, 12 ); 119 MD5STEP( F1, c, d, a, b, x[ 2] + 0x242070db, 17 ); 120 MD5STEP( F1, b, c, d, a, x[ 3] + 0xc1bdceee, 22 ); 121 MD5STEP( F1, a, b, c, d, x[ 4] + 0xf57c0faf, 7 ); 122 MD5STEP( F1, d, a, b, c, x[ 5] + 0x4787c62a, 12 ); 123 MD5STEP( F1, c, d, a, b, x[ 6] + 0xa8304613, 17 ); 124 MD5STEP( F1, b, c, d, a, x[ 7] + 0xfd469501, 22 ); 125 MD5STEP( F1, a, b, c, d, x[ 8] + 0x698098d8, 7 ); 126 MD5STEP( F1, d, a, b, c, x[ 9] + 0x8b44f7af, 12 ); 127 MD5STEP( F1, c, d, a, b, x[10] + 0xffff5bb1, 17 ); 128 MD5STEP( F1, b, c, d, a, x[11] + 0x895cd7be, 22 ); 129 MD5STEP( F1, a, b, c, d, x[12] + 0x6b901122, 7 ); 130 MD5STEP( F1, d, a, b, c, x[13] + 0xfd987193, 12 ); 131 MD5STEP( F1, c, d, a, b, x[14] + 0xa679438e, 17 ); 132 MD5STEP( F1, b, c, d, a, x[15] + 0x49b40821, 22 ); 133 134 MD5STEP( F2, a, b, c, d, x[ 1] + 0xf61e2562, 5 ); 135 MD5STEP( F2, d, a, b, c, x[ 6] + 0xc040b340, 9 ); 136 MD5STEP( F2, c, d, a, b, x[11] + 0x265e5a51, 14 ); 137 MD5STEP( F2, b, c, d, a, x[ 0] + 0xe9b6c7aa, 20 ); 138 MD5STEP( F2, a, b, c, d, x[ 5] + 0xd62f105d, 5 ); 139 MD5STEP( F2, d, a, b, c, x[10] + 0x02441453, 9 ); 140 MD5STEP( F2, c, d, a, b, x[15] + 0xd8a1e681, 14 ); 141 MD5STEP( F2, b, c, d, a, x[ 4] + 0xe7d3fbc8, 20 ); 142 MD5STEP( F2, a, b, c, d, x[ 9] + 0x21e1cde6, 5 ); 143 MD5STEP( F2, d, a, b, c, x[14] + 0xc33707d6, 9 ); 144 MD5STEP( F2, c, d, a, b, x[ 3] + 0xf4d50d87, 14 ); 145 MD5STEP( F2, b, c, d, a, x[ 8] + 0x455a14ed, 20 ); 146 MD5STEP( F2, a, b, c, d, x[13] + 0xa9e3e905, 5 ); 147 MD5STEP( F2, d, a, b, c, x[ 2] + 0xfcefa3f8, 9 ); 148 MD5STEP( F2, c, d, a, b, x[ 7] + 0x676f02d9, 14 ); 149 MD5STEP( F2, b, c, d, a, x[12] + 0x8d2a4c8a, 20 ); 150 151 MD5STEP( F3, a, b, c, d, x[ 5] + 0xfffa3942, 4 ); 152 MD5STEP( F3, d, a, b, c, x[ 8] + 0x8771f681, 11 ); 153 MD5STEP( F3, c, d, a, b, x[11] + 0x6d9d6122, 16 ); 154 MD5STEP( F3, b, c, d, a, x[14] + 0xfde5380c, 23 ); 155 MD5STEP( F3, a, b, c, d, x[ 1] + 0xa4beea44, 4 ); 156 MD5STEP( F3, d, a, b, c, x[ 4] + 0x4bdecfa9, 11 ); 157 MD5STEP( F3, c, d, a, b, x[ 7] + 0xf6bb4b60, 16 ); 158 MD5STEP( F3, b, c, d, a, x[10] + 0xbebfbc70, 23 ); 159 MD5STEP( F3, a, b, c, d, x[13] + 0x289b7ec6, 4 ); 160 MD5STEP( F3, d, a, b, c, x[ 0] + 0xeaa127fa, 11 ); 161 MD5STEP( F3, c, d, a, b, x[ 3] + 0xd4ef3085, 16 ); 162 MD5STEP( F3, b, c, d, a, x[ 6] + 0x04881d05, 23 ); 163 MD5STEP( F3, a, b, c, d, x[ 9] + 0xd9d4d039, 4 ); 164 MD5STEP( F3, d, a, b, c, x[12] + 0xe6db99e5, 11 ); 165 MD5STEP( F3, c, d, a, b, x[15] + 0x1fa27cf8, 16 ); 166 MD5STEP( F3, b, c, d, a, x[ 2] + 0xc4ac5665, 23 ); 167 168 MD5STEP( F4, a, b, c, d, x[ 0] + 0xf4292244, 6 ); 169 MD5STEP( F4, d, a, b, c, x[ 7] + 0x432aff97, 10 ); 170 MD5STEP( F4, c, d, a, b, x[14] + 0xab9423a7, 15 ); 171 MD5STEP( F4, b, c, d, a, x[ 5] + 0xfc93a039, 21 ); 172 MD5STEP( F4, a, b, c, d, x[12] + 0x655b59c3, 6 ); 173 MD5STEP( F4, d, a, b, c, x[ 3] + 0x8f0ccc92, 10 ); 174 MD5STEP( F4, c, d, a, b, x[10] + 0xffeff47d, 15 ); 175 MD5STEP( F4, b, c, d, a, x[ 1] + 0x85845dd1, 21 ); 176 MD5STEP( F4, a, b, c, d, x[ 8] + 0x6fa87e4f, 6 ); 177 MD5STEP( F4, d, a, b, c, x[15] + 0xfe2ce6e0, 10 ); 178 MD5STEP( F4, c, d, a, b, x[ 6] + 0xa3014314, 15 ); 179 MD5STEP( F4, b, c, d, a, x[13] + 0x4e0811a1, 21 ); 180 MD5STEP( F4, a, b, c, d, x[ 4] + 0xf7537e82, 6 ); 181 MD5STEP( F4, d, a, b, c, x[11] + 0xbd3af235, 10 ); 182 MD5STEP( F4, c, d, a, b, x[ 2] + 0x2ad7d2bb, 15 ); 183 MD5STEP( F4, b, c, d, a, x[ 9] + 0xeb86d391, 21 ); 184 185 state[0] += a; 186 state[1] += b; 187 state[2] += c; 188 state[3] += d; 189 190 // Zeroize sensitive information. 191 memset( (POINTER)x, 0, sizeof( x ) ); 192 } 193 194 /* 195 ======================== 196 MD5_Init 197 198 MD5 initialization. Begins an MD5 operation, writing a new context. 199 ======================== 200 */ 201 void MD5_Init( MD5_CTX *ctx ) { 202 ctx->state[0] = 0x67452301; 203 ctx->state[1] = 0xefcdab89; 204 ctx->state[2] = 0x98badcfe; 205 ctx->state[3] = 0x10325476; 206 207 ctx->bits[0] = 0; 208 ctx->bits[1] = 0; 209 } 210 211 /* 212 ======================== 213 MD5_Update 214 215 MD5 block update operation. Continues an MD5 message-digest operation, processing another 216 message block, and updating the context. 217 ======================== 218 */ 219 void MD5_Update( MD5_CTX *context, unsigned char const *input, size_t inputLen ) { 220 unsigned int i, index, partLen; 221 222 // Compute number of bytes mod 64 223 index = (unsigned int)((context->bits[0] >> 3) & 0x3F); 224 225 // Update number of bits 226 if ((context->bits[0] += ((UINT4)inputLen << 3))< ((UINT4)inputLen << 3)) { 227 context->bits[1]++; 228 } 229 230 context->bits[1] += ((UINT4)inputLen >> 29); 231 232 partLen = 64 - index; 233 234 // Transform as many times as possible. 235 if ( inputLen >= partLen ) { 236 memcpy( (POINTER)&context->in[index], (POINTER)input, partLen ); 237 MD5_Transform( context->state, context->in ); 238 239 for ( i = partLen; i + 63 < inputLen; i += 64 ) { 240 MD5_Transform( context->state, &input[i] ); 241 } 242 243 index = 0; 244 } else { 245 i = 0; 246 } 247 248 // Buffer remaining input 249 memcpy( (POINTER)&context->in[index], (POINTER)&input[i], inputLen-i ); 250 } 251 252 /* 253 ======================== 254 MD5_Final 255 256 MD5 finalization. Ends an MD5 message-digest operation, writing the message digest and 257 zero-izing the context. 258 ======================== 259 */ 260 void MD5_Final( MD5_CTX *context, unsigned char digest[16] ) { 261 unsigned char bits[8]; 262 unsigned int index, padLen; 263 264 // Save number of bits 265 Encode( bits, context->bits, 8 ); 266 267 // Pad out to 56 mod 64. 268 index = (unsigned int)((context->bits[0] >> 3) & 0x3f); 269 padLen = (index < 56) ? (56 - index) : (120 - index); 270 MD5_Update( context, PADDING, padLen ); 271 272 // Append length (before padding) 273 MD5_Update( context, bits, 8 ); 274 275 // Store state in digest 276 Encode( digest, context->state, 16 ); 277 278 // Zeroize sensitive information. 279 memset( (POINTER)context, 0, sizeof( *context ) ); 280 } 281 282 /* 283 ======================== 284 MD5_BlockChecksum 285 ======================== 286 */ 287 288 unsigned int MD5_BlockChecksum( const void *data, size_t length ) { 289 unsigned char digest[16]; 290 unsigned int val; 291 MD5_CTX ctx; 292 293 MD5_Init( &ctx ); 294 MD5_Update( &ctx, (unsigned char *)data, length ); 295 MD5_Final( &ctx, (unsigned char *)digest ); 296 297 // Handle it manually to be endian-safe since we don't have access to idSwap. 298 val = ( digest[3] << 24 | digest[2] << 16 | digest[1] << 8 | digest[0] ) ^ 299 ( digest[7] << 24 | digest[6] << 16 | digest[5] << 8 | digest[4] ) ^ 300 ( digest[11] << 24 | digest[10] << 16 | digest[9] << 8 | digest[8] ) ^ 301 ( digest[15] << 24 | digest[14] << 16 | digest[13] << 8 | digest[12] ); 302 303 return val; 304 }