DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

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 }