1/*
2Copyright (C) 1996-1997 Id Software, Inc.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, 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 */
25typedef unsigned char *POINTER;
26
27/* UINT2 defines a two byte word */
28typedef unsigned short int UINT2;
29
30/* UINT4 defines a four byte word */
31#ifdef __alpha__
32typedef unsigned int UINT4;
33#else
34typedef 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
42All rights reserved.
43
44License 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.
45License 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.
46RSA 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
48These notices must be retained in any copies of any part of this documentation and/or software. */
49
50/* MD4 context. */
51typedef 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
57void MD4Init (MD4_CTX *);
58void MD4Update (MD4_CTX *, unsigned char *, unsigned int);
59void 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
66License to copy and use this software is granted provided that it is identified as the
67RSA Data Security, Inc. MD4 Message-Digest Algorithm
68 in all material mentioning or referencing this software or this function.
69License is also granted to make and use derivative works provided that such works are identified as
70derived from the RSA Data Security, Inc. MD4 Message-Digest Algorithm
71in all material mentioning or referencing the derived work.
72RSA 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
73as is without express or implied warranty of any kind.
74
75These 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
91static void MD4Transform (UINT4 [4], unsigned char [64]);
92static void Encode (unsigned char *, UINT4 *, unsigned int);
93static void Decode (UINT4 *, unsigned char *, unsigned int);
94
95static unsigned char PADDING[64] = {
960x80, 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. */
117void MD4Init (MD4_CTX *context)
118{
119	context->count[0] = context->count[1] = 0;
120
121/* Load magic initialization constants.*/
122context->state[0] = 0x67452301;
123context->state[1] = 0xefcdab89;
124context->state[2] = 0x98badcfe;
125context->state[3] = 0x10325476;
126}
127
128/* MD4 block update operation. Continues an MD4 message-digest operation, processing another message block, and updating the context. */
129void 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. */
164void 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. */
189static 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 */
196FF (a, b, c, d, x[ 0], S11); 				/* 1 */
197FF (d, a, b, c, x[ 1], S12); 				/* 2 */
198FF (c, d, a, b, x[ 2], S13); 				/* 3 */
199FF (b, c, d, a, x[ 3], S14); 				/* 4 */
200FF (a, b, c, d, x[ 4], S11); 				/* 5 */
201FF (d, a, b, c, x[ 5], S12); 				/* 6 */
202FF (c, d, a, b, x[ 6], S13); 				/* 7 */
203FF (b, c, d, a, x[ 7], S14); 				/* 8 */
204FF (a, b, c, d, x[ 8], S11); 				/* 9 */
205FF (d, a, b, c, x[ 9], S12); 				/* 10 */
206FF (c, d, a, b, x[10], S13); 			/* 11 */
207FF (b, c, d, a, x[11], S14); 			/* 12 */
208FF (a, b, c, d, x[12], S11); 			/* 13 */
209FF (d, a, b, c, x[13], S12); 			/* 14 */
210FF (c, d, a, b, x[14], S13); 			/* 15 */
211FF (b, c, d, a, x[15], S14); 			/* 16 */
212
213/* Round 2 */
214GG (a, b, c, d, x[ 0], S21); 			/* 17 */
215GG (d, a, b, c, x[ 4], S22); 			/* 18 */
216GG (c, d, a, b, x[ 8], S23); 			/* 19 */
217GG (b, c, d, a, x[12], S24); 			/* 20 */
218GG (a, b, c, d, x[ 1], S21); 			/* 21 */
219GG (d, a, b, c, x[ 5], S22); 			/* 22 */
220GG (c, d, a, b, x[ 9], S23); 			/* 23 */
221GG (b, c, d, a, x[13], S24); 			/* 24 */
222GG (a, b, c, d, x[ 2], S21); 			/* 25 */
223GG (d, a, b, c, x[ 6], S22); 			/* 26 */
224GG (c, d, a, b, x[10], S23); 			/* 27 */
225GG (b, c, d, a, x[14], S24); 			/* 28 */
226GG (a, b, c, d, x[ 3], S21); 			/* 29 */
227GG (d, a, b, c, x[ 7], S22); 			/* 30 */
228GG (c, d, a, b, x[11], S23); 			/* 31 */
229GG (b, c, d, a, x[15], S24); 			/* 32 */
230
231/* Round 3 */
232HH (a, b, c, d, x[ 0], S31);				/* 33 */
233HH (d, a, b, c, x[ 8], S32); 			/* 34 */
234HH (c, d, a, b, x[ 4], S33); 			/* 35 */
235HH (b, c, d, a, x[12], S34); 			/* 36 */
236HH (a, b, c, d, x[ 2], S31); 			/* 37 */
237HH (d, a, b, c, x[10], S32); 			/* 38 */
238HH (c, d, a, b, x[ 6], S33); 			/* 39 */
239HH (b, c, d, a, x[14], S34); 			/* 40 */
240HH (a, b, c, d, x[ 1], S31); 			/* 41 */
241HH (d, a, b, c, x[ 9], S32); 			/* 42 */
242HH (c, d, a, b, x[ 5], S33); 			/* 43 */
243HH (b, c, d, a, x[13], S34); 			/* 44 */
244HH (a, b, c, d, x[ 3], S31); 			/* 45 */
245HH (d, a, b, c, x[11], S32); 			/* 46 */
246HH (c, d, a, b, x[ 7], S33); 			/* 47 */
247HH (b, c, d, a, x[15], S34);			/* 48 */
248
249state[0] += a;
250state[1] += b;
251state[2] += c;
252state[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. */
260static 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. */
274static void Decode (UINT4 *output, unsigned char *input, unsigned int len)
275{
276unsigned int i, j;
277
278for (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
284unsigned 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
299void 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