Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

md4.c (10144B)


      1 /* GLOBAL.H - RSAREF types and constants */
      2 
      3 #include <string.h>
      4 #if defined(_WIN32)
      5 #pragma warning(disable : 4711)		// selected for automatic inline expansion
      6 #endif
      7 
      8 /* POINTER defines a generic pointer type */
      9 typedef unsigned char *POINTER;
     10 
     11 /* UINT2 defines a two byte word */
     12 typedef unsigned short int UINT2;
     13 
     14 /* UINT4 defines a four byte word */
     15 typedef unsigned long int UINT4;
     16 
     17   
     18 /* MD4.H - header file for MD4C.C */
     19 
     20 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. 
     21 
     22 All rights reserved.
     23   
     24 License to copy and use this software is granted provided that it is identified as the “RSA Data Security, Inc. MD4 Message-Digest Algorithm” in all material mentioning or referencing this software or this function.
     25 License is also granted to make and use derivative works provided that such works are identified as “derived from the RSA Data Security, Inc. MD4 Message-Digest Algorithm” in all material mentioning or referencing the derived work.
     26 RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided “as is” without express or implied warranty of any kind.
     27   
     28 These notices must be retained in any copies of any part of this documentation and/or software. */
     29 
     30 /* MD4 context. */
     31 typedef struct {
     32 	UINT4 state[4];				/* state (ABCD) */
     33 	UINT4 count[2];				/* number of bits, modulo 2^64 (lsb first) */
     34 	unsigned char buffer[64]; 			/* input buffer */
     35 } MD4_CTX;
     36 
     37 void MD4Init (MD4_CTX *);
     38 void MD4Update (MD4_CTX *, const unsigned char *, unsigned int);
     39 void MD4Final (unsigned char [16], MD4_CTX *);
     40 
     41 #ifndef __VECTORC  
     42 void Com_Memset (void* dest, const int val, const size_t count);
     43 void Com_Memcpy (void* dest, const void* src, const size_t count);
     44 #else
     45 #define Com_Memset memset
     46 #define Com_Memcpy memcpy
     47 #endif
     48 
     49 /* MD4C.C - RSA Data Security, Inc., MD4 message-digest algorithm */
     50 /* Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved.
     51   
     52 License to copy and use this software is granted provided that it is identified as the
     53 RSA Data Security, Inc. MD4 Message-Digest Algorithm
     54  in all material mentioning or referencing this software or this function.
     55 License is also granted to make and use derivative works provided that such works are identified as 
     56 derived from the RSA Data Security, Inc. MD4 Message-Digest Algorithm
     57 in all material mentioning or referencing the derived work.
     58 RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided
     59 as is without express or implied warranty of any kind.
     60   
     61 These notices must be retained in any copies of any part of this documentation and/or software. */
     62 
     63 /* Constants for MD4Transform routine.  */
     64 #define S11 3
     65 #define S12 7
     66 #define S13 11
     67 #define S14 19
     68 #define S21 3
     69 #define S22 5
     70 #define S23 9
     71 #define S24 13
     72 #define S31 3
     73 #define S32 9
     74 #define S33 11
     75 #define S34 15
     76 
     77 static void MD4Transform (UINT4 [4], const unsigned char [64]);
     78 static void Encode (unsigned char *, UINT4 *, unsigned int);
     79 static void Decode (UINT4 *, const unsigned char *, unsigned int);
     80 
     81 static unsigned char PADDING[64] = {
     82 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
     83 };
     84 
     85 /* F, G and H are basic MD4 functions. */
     86 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
     87 #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
     88 #define H(x, y, z) ((x) ^ (y) ^ (z))
     89 
     90 /* ROTATE_LEFT rotates x left n bits. */
     91 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
     92 
     93 /* FF, GG and HH are transformations for rounds 1, 2 and 3 */
     94 /* Rotation is separate from addition to prevent recomputation */
     95 #define FF(a, b, c, d, x, s) {(a) += F ((b), (c), (d)) + (x); (a) = ROTATE_LEFT ((a), (s));}
     96 
     97 #define GG(a, b, c, d, x, s) {(a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; (a) = ROTATE_LEFT ((a), (s));}
     98 
     99 #define HH(a, b, c, d, x, s) {(a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; (a) = ROTATE_LEFT ((a), (s));}
    100 
    101 
    102 /* MD4 initialization. Begins an MD4 operation, writing a new context. */
    103 void MD4Init (MD4_CTX *context)
    104 {
    105 	context->count[0] = context->count[1] = 0;
    106 
    107 /* Load magic initialization constants.*/
    108 context->state[0] = 0x67452301;
    109 context->state[1] = 0xefcdab89;
    110 context->state[2] = 0x98badcfe;
    111 context->state[3] = 0x10325476;
    112 }
    113 
    114 /* MD4 block update operation. Continues an MD4 message-digest operation, processing another message block, and updating the context. */
    115 void MD4Update (MD4_CTX *context, const unsigned char *input, unsigned int inputLen)
    116 {
    117 	unsigned int i, index, partLen;
    118 
    119 	/* Compute number of bytes mod 64 */
    120 	index = (unsigned int)((context->count[0] >> 3) & 0x3F);
    121 
    122 	/* Update number of bits */
    123 	if ((context->count[0] += ((UINT4)inputLen << 3))< ((UINT4)inputLen << 3))
    124 		context->count[1]++;
    125 
    126 	context->count[1] += ((UINT4)inputLen >> 29);
    127 
    128 	partLen = 64 - index;
    129 
    130 	/* Transform as many times as possible.*/
    131 	if (inputLen >= partLen)
    132 	{
    133  		Com_Memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen);
    134  		MD4Transform (context->state, context->buffer);
    135 
    136  		for (i = partLen; i + 63 < inputLen; i += 64)
    137  			MD4Transform (context->state, &input[i]);
    138 
    139  		index = 0;
    140 	}
    141 	else
    142  		i = 0;
    143 
    144 	/* Buffer remaining input */
    145 	Com_Memcpy ((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i);
    146 }
    147 
    148 
    149 /* MD4 finalization. Ends an MD4 message-digest operation, writing the the message digest and zeroizing the context. */
    150 void MD4Final (unsigned char digest[16], MD4_CTX *context)
    151 {
    152 	unsigned char bits[8];
    153 	unsigned int index, padLen;
    154 
    155 	/* Save number of bits */
    156 	Encode (bits, context->count, 8);
    157 
    158 	/* Pad out to 56 mod 64.*/
    159 	index = (unsigned int)((context->count[0] >> 3) & 0x3f);
    160 	padLen = (index < 56) ? (56 - index) : (120 - index);
    161 	MD4Update (context, PADDING, padLen);
    162 
    163 	/* Append length (before padding) */
    164 	MD4Update (context, bits, 8);
    165 	
    166 	/* Store state in digest */
    167 	Encode (digest, context->state, 16);
    168 
    169 	/* Zeroize sensitive information.*/
    170 	Com_Memset ((POINTER)context, 0, sizeof (*context));
    171 }
    172 
    173 
    174 /* MD4 basic transformation. Transforms state based on block. */
    175 static void MD4Transform (UINT4 state[4], const unsigned char block[64])
    176 {
    177 	UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
    178 
    179 	Decode (x, block, 64);
    180 
    181 /* Round 1 */
    182 FF (a, b, c, d, x[ 0], S11); 				/* 1 */
    183 FF (d, a, b, c, x[ 1], S12); 				/* 2 */
    184 FF (c, d, a, b, x[ 2], S13); 				/* 3 */
    185 FF (b, c, d, a, x[ 3], S14); 				/* 4 */
    186 FF (a, b, c, d, x[ 4], S11); 				/* 5 */
    187 FF (d, a, b, c, x[ 5], S12); 				/* 6 */
    188 FF (c, d, a, b, x[ 6], S13); 				/* 7 */
    189 FF (b, c, d, a, x[ 7], S14); 				/* 8 */
    190 FF (a, b, c, d, x[ 8], S11); 				/* 9 */
    191 FF (d, a, b, c, x[ 9], S12); 				/* 10 */
    192 FF (c, d, a, b, x[10], S13); 			/* 11 */
    193 FF (b, c, d, a, x[11], S14); 			/* 12 */
    194 FF (a, b, c, d, x[12], S11); 			/* 13 */
    195 FF (d, a, b, c, x[13], S12); 			/* 14 */
    196 FF (c, d, a, b, x[14], S13); 			/* 15 */
    197 FF (b, c, d, a, x[15], S14); 			/* 16 */
    198 
    199 /* Round 2 */
    200 GG (a, b, c, d, x[ 0], S21); 			/* 17 */
    201 GG (d, a, b, c, x[ 4], S22); 			/* 18 */
    202 GG (c, d, a, b, x[ 8], S23); 			/* 19 */
    203 GG (b, c, d, a, x[12], S24); 			/* 20 */
    204 GG (a, b, c, d, x[ 1], S21); 			/* 21 */
    205 GG (d, a, b, c, x[ 5], S22); 			/* 22 */
    206 GG (c, d, a, b, x[ 9], S23); 			/* 23 */
    207 GG (b, c, d, a, x[13], S24); 			/* 24 */
    208 GG (a, b, c, d, x[ 2], S21); 			/* 25 */
    209 GG (d, a, b, c, x[ 6], S22); 			/* 26 */
    210 GG (c, d, a, b, x[10], S23); 			/* 27 */
    211 GG (b, c, d, a, x[14], S24); 			/* 28 */
    212 GG (a, b, c, d, x[ 3], S21); 			/* 29 */
    213 GG (d, a, b, c, x[ 7], S22); 			/* 30 */
    214 GG (c, d, a, b, x[11], S23); 			/* 31 */
    215 GG (b, c, d, a, x[15], S24); 			/* 32 */
    216 
    217 /* Round 3 */
    218 HH (a, b, c, d, x[ 0], S31);				/* 33 */
    219 HH (d, a, b, c, x[ 8], S32); 			/* 34 */
    220 HH (c, d, a, b, x[ 4], S33); 			/* 35 */
    221 HH (b, c, d, a, x[12], S34); 			/* 36 */
    222 HH (a, b, c, d, x[ 2], S31); 			/* 37 */
    223 HH (d, a, b, c, x[10], S32); 			/* 38 */
    224 HH (c, d, a, b, x[ 6], S33); 			/* 39 */
    225 HH (b, c, d, a, x[14], S34); 			/* 40 */
    226 HH (a, b, c, d, x[ 1], S31); 			/* 41 */
    227 HH (d, a, b, c, x[ 9], S32); 			/* 42 */
    228 HH (c, d, a, b, x[ 5], S33); 			/* 43 */
    229 HH (b, c, d, a, x[13], S34); 			/* 44 */
    230 HH (a, b, c, d, x[ 3], S31); 			/* 45 */
    231 HH (d, a, b, c, x[11], S32); 			/* 46 */
    232 HH (c, d, a, b, x[ 7], S33); 			/* 47 */
    233 HH (b, c, d, a, x[15], S34);			/* 48 */
    234 
    235 state[0] += a;
    236 state[1] += b;
    237 state[2] += c;
    238 state[3] += d;
    239 
    240 	/* Zeroize sensitive information.*/
    241 	Com_Memset ((POINTER)x, 0, sizeof (x));
    242 }
    243 
    244 
    245 /* Encodes input (UINT4) into output (unsigned char). Assumes len is a multiple of 4. */
    246 static void Encode (unsigned char *output, UINT4 *input, unsigned int len)
    247 {
    248 	unsigned int i, j;
    249 
    250 	for (i = 0, j = 0; j < len; i++, j += 4) {
    251  		output[j] = (unsigned char)(input[i] & 0xff);
    252  		output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
    253  		output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
    254  		output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
    255 	}
    256 }
    257 
    258 
    259 /* Decodes input (unsigned char) into output (UINT4). Assumes len is a multiple of 4. */
    260 static void Decode (UINT4 *output, const unsigned char *input, unsigned int len)
    261 {
    262 unsigned int i, j;
    263 
    264 for (i = 0, j = 0; j < len; i++, j += 4)
    265  	output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
    266 }
    267 
    268 //===================================================================
    269 
    270 unsigned Com_BlockChecksum (void *buffer, int length)
    271 {
    272 	int			digest[4];
    273 	unsigned	val;
    274 	MD4_CTX		ctx;
    275 
    276 	MD4Init (&ctx);
    277 	MD4Update (&ctx, (unsigned char *)buffer, length);
    278 	MD4Final ( (unsigned char *)digest, &ctx);
    279 	
    280 	val = digest[0] ^ digest[1] ^ digest[2] ^ digest[3];
    281 
    282 	return val;
    283 }
    284 
    285 unsigned Com_BlockChecksumKey (void *buffer, int length, int key)
    286 {
    287 	int			digest[4];
    288 	unsigned	val;
    289 	MD4_CTX		ctx;
    290 
    291 	MD4Init (&ctx);
    292 	MD4Update (&ctx, (unsigned char *)&key, 4);
    293 	MD4Update (&ctx, (unsigned char *)buffer, length);
    294 	MD4Final ( (unsigned char *)digest, &ctx);
    295 	
    296 	val = digest[0] ^ digest[1] ^ digest[2] ^ digest[3];
    297 
    298 	return val;
    299 }