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