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