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 }