]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake2/qdata_heretic2/common/md4.c
uncrustify! now the code is only ugly on the *inside*
[xonotic/netradiant.git] / tools / quake2 / qdata_heretic2 / common / md4.c
1 /*
2    Copyright (C) 1999-2007 id Software, Inc. and contributors.
3    For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5    This file is part of GtkRadiant.
6
7    GtkRadiant is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    GtkRadiant is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GtkRadiant; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 /* GLOBAL.H - RSAREF types and constants */
23
24 #include <string.h>
25
26 /* POINTER defines a generic pointer type */
27 typedef unsigned char *POINTER;
28
29 /* UINT2 defines a two byte word */
30 typedef unsigned short int UINT2;
31
32 /* UINT4 defines a four byte word */
33 typedef unsigned long int UINT4;
34
35
36 /* MD4.H - header file for MD4C.C */
37
38 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991.
39
40    All rights reserved.
41
42    License to copy and use this software is granted provided that it is identified as the \93RSA Data Security, Inc. MD4 Message-Digest Algorithm\94 in all material mentioning or referencing this software or this function.
43    License is also granted to make and use derivative works provided that such works are identified as \93derived from the RSA Data Security, Inc. MD4 Message-Digest Algorithm\94 in all material mentioning or referencing the derived work.
44    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 \93as is\94 without express or implied warranty of any kind.
45
46    These notices must be retained in any copies of any part of this documentation and/or software. */
47
48 /* MD4 context. */
49 typedef struct {
50         UINT4 state[4];             /* state (ABCD) */
51         UINT4 count[2];             /* number of bits, modulo 2^64 (lsb first) */
52         unsigned char buffer[64];           /* input buffer */
53 } MD4_CTX;
54
55 void MD4Init( MD4_CTX * );
56 void MD4Update( MD4_CTX *, unsigned char *, unsigned int );
57 void MD4Final( unsigned char [16], MD4_CTX * );
58
59
60
61 /* MD4C.C - RSA Data Security, Inc., MD4 message-digest algorithm */
62 /* Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved.
63
64    License to copy and use this software is granted provided that it is identified as the
65    RSA Data Security, Inc. MD4 Message-Digest Algorithm
66    in all material mentioning or referencing this software or this function.
67    License is also granted to make and use derivative works provided that such works are identified as
68    derived from the RSA Data Security, Inc. MD4 Message-Digest Algorithm
69    in all material mentioning or referencing the derived work.
70    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
71    as is without express or implied warranty of any kind.
72
73    These notices must be retained in any copies of any part of this documentation and/or software. */
74
75 /* Constants for MD4Transform routine.  */
76 #define S11 3
77 #define S12 7
78 #define S13 11
79 #define S14 19
80 #define S21 3
81 #define S22 5
82 #define S23 9
83 #define S24 13
84 #define S31 3
85 #define S32 9
86 #define S33 11
87 #define S34 15
88
89 static void MD4Transform( UINT4 [4], unsigned char [64] );
90 static void Encode( unsigned char *, UINT4 *, unsigned int );
91 static void Decode( UINT4 *, unsigned char *, unsigned int );
92 static void MD4_memcpy( POINTER, POINTER, unsigned int );
93 static void MD4_memset( POINTER, int, 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 ) = \
114                                                                         ROTATE_LEFT( ( a ), ( s ) ); }
115
116
117 /* MD4 initialization. Begins an MD4 operation, writing a new context. */
118 void MD4Init( MD4_CTX *context ){
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         unsigned int i, index, partLen;
131
132         /* Compute number of bytes mod 64 */
133         index = (unsigned int)( ( context->count[0] >> 3 ) & 0x3F );
134
135         /* Update number of bits */
136         if ( ( context->count[0] += ( (UINT4)inputLen << 3 ) ) < ( (UINT4)inputLen << 3 ) ) {
137                 context->count[1]++;
138         }
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                 memcpy( (POINTER)&context->buffer[index], (POINTER)input, partLen );
147                 MD4Transform( context->state, context->buffer );
148
149                 for ( i = partLen; i + 63 < inputLen; i += 64 )
150                         MD4Transform( context->state, &input[i] );
151
152                 index = 0;
153         }
154         else{
155                 i = 0;
156         }
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         unsigned char bits[8];
166         unsigned int index, padLen;
167
168         /* Save number of bits */
169         Encode( bits, context->count, 8 );
170
171         /* Pad out to 56 mod 64.*/
172         index = (unsigned int)( ( context->count[0] >> 3 ) & 0x3f );
173         padLen = ( index < 56 ) ? ( 56 - index ) : ( 120 - index );
174         MD4Update( context, PADDING, padLen );
175
176         /* Append length (before padding) */
177         MD4Update( context, bits, 8 );
178
179         /* Store state in digest */
180         Encode( digest, context->state, 16 );
181
182         /* Zeroize sensitive information.*/
183         memset( (POINTER)context, 0, sizeof( *context ) );
184 }
185
186
187 /* MD4 basic transformation. Transforms state based on block. */
188 static void MD4Transform( UINT4 state[4], unsigned char block[64] ){
189         UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
190
191         Decode( x, block, 64 );
192
193 /* Round 1 */
194         FF( a, b, c, d, x[ 0], S11 );           /* 1 */
195         FF( d, a, b, c, x[ 1], S12 );           /* 2 */
196         FF( c, d, a, b, x[ 2], S13 );           /* 3 */
197         FF( b, c, d, a, x[ 3], S14 );           /* 4 */
198         FF( a, b, c, d, x[ 4], S11 );           /* 5 */
199         FF( d, a, b, c, x[ 5], S12 );           /* 6 */
200         FF( c, d, a, b, x[ 6], S13 );           /* 7 */
201         FF( b, c, d, a, x[ 7], S14 );           /* 8 */
202         FF( a, b, c, d, x[ 8], S11 );           /* 9 */
203         FF( d, a, b, c, x[ 9], S12 );           /* 10 */
204         FF( c, d, a, b, x[10], S13 );       /* 11 */
205         FF( b, c, d, a, x[11], S14 );       /* 12 */
206         FF( a, b, c, d, x[12], S11 );       /* 13 */
207         FF( d, a, b, c, x[13], S12 );       /* 14 */
208         FF( c, d, a, b, x[14], S13 );       /* 15 */
209         FF( b, c, d, a, x[15], S14 );       /* 16 */
210
211 /* Round 2 */
212         GG( a, b, c, d, x[ 0], S21 );       /* 17 */
213         GG( d, a, b, c, x[ 4], S22 );       /* 18 */
214         GG( c, d, a, b, x[ 8], S23 );       /* 19 */
215         GG( b, c, d, a, x[12], S24 );       /* 20 */
216         GG( a, b, c, d, x[ 1], S21 );       /* 21 */
217         GG( d, a, b, c, x[ 5], S22 );       /* 22 */
218         GG( c, d, a, b, x[ 9], S23 );       /* 23 */
219         GG( b, c, d, a, x[13], S24 );       /* 24 */
220         GG( a, b, c, d, x[ 2], S21 );       /* 25 */
221         GG( d, a, b, c, x[ 6], S22 );       /* 26 */
222         GG( c, d, a, b, x[10], S23 );       /* 27 */
223         GG( b, c, d, a, x[14], S24 );       /* 28 */
224         GG( a, b, c, d, x[ 3], S21 );       /* 29 */
225         GG( d, a, b, c, x[ 7], S22 );       /* 30 */
226         GG( c, d, a, b, x[11], S23 );       /* 31 */
227         GG( b, c, d, a, x[15], S24 );       /* 32 */
228
229 /* Round 3 */
230         HH( a, b, c, d, x[ 0], S31 );           /* 33 */
231         HH( d, a, b, c, x[ 8], S32 );       /* 34 */
232         HH( c, d, a, b, x[ 4], S33 );       /* 35 */
233         HH( b, c, d, a, x[12], S34 );       /* 36 */
234         HH( a, b, c, d, x[ 2], S31 );       /* 37 */
235         HH( d, a, b, c, x[10], S32 );       /* 38 */
236         HH( c, d, a, b, x[ 6], S33 );       /* 39 */
237         HH( b, c, d, a, x[14], S34 );       /* 40 */
238         HH( a, b, c, d, x[ 1], S31 );       /* 41 */
239         HH( d, a, b, c, x[ 9], S32 );       /* 42 */
240         HH( c, d, a, b, x[ 5], S33 );       /* 43 */
241         HH( b, c, d, a, x[13], S34 );       /* 44 */
242         HH( a, b, c, d, x[ 3], S31 );       /* 45 */
243         HH( d, a, b, c, x[11], S32 );       /* 46 */
244         HH( c, d, a, b, x[ 7], S33 );       /* 47 */
245         HH( b, c, d, a, x[15], S34 );       /* 48 */
246
247         state[0] += a;
248         state[1] += b;
249         state[2] += c;
250         state[3] += d;
251
252         /* Zeroize sensitive information.*/
253         memset( (POINTER)x, 0, sizeof( x ) );
254 }
255
256
257 /* Encodes input (UINT4) into output (unsigned char). Assumes len is a multiple of 4. */
258 static void Encode( unsigned char *output, UINT4 *input, unsigned int len ){
259         unsigned int i, j;
260
261         for ( i = 0, j = 0; j < len; i++, j += 4 ) {
262                 output[j] = (unsigned char)( input[i] & 0xff );
263                 output[j + 1] = (unsigned char)( ( input[i] >> 8 ) & 0xff );
264                 output[j + 2] = (unsigned char)( ( input[i] >> 16 ) & 0xff );
265                 output[j + 3] = (unsigned char)( ( input[i] >> 24 ) & 0xff );
266         }
267 }
268
269
270 /* Decodes input (unsigned char) into output (UINT4). Assumes len is a multiple of 4. */
271 static void Decode( UINT4 *output, unsigned char *input, unsigned int len ){
272         unsigned int i, j;
273
274         for ( i = 0, j = 0; j < len; i++, j += 4 )
275                 output[i] = ( (UINT4)input[j] ) | ( ( (UINT4)input[j + 1] ) << 8 ) | ( ( (UINT4)input[j + 2] ) << 16 ) | ( ( (UINT4)input[j + 3] ) << 24 );
276 }
277
278 //===================================================================
279
280 unsigned Com_BlockChecksum( void *buffer, int length ){
281         int digest[4];
282         unsigned val;
283         MD4_CTX ctx;
284
285         MD4Init( &ctx );
286         MD4Update( &ctx, (unsigned char *)buffer, length );
287         MD4Final( (unsigned char *)digest, &ctx );
288
289         val = digest[0] ^ digest[1] ^ digest[2] ^ digest[3];
290
291         return val;
292 }