|
reSIProcate/stack
9694
|
00001 /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm 00002 */ 00003 00004 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All 00005 rights reserved. 00006 00007 License to copy and use this software is granted provided that it 00008 is identified as the "RSA Data Security, Inc. MD5 Message-Digest 00009 Algorithm" in all material mentioning or referencing this software 00010 or this function. 00011 00012 License is also granted to make and use derivative works provided 00013 that such works are identified as "derived from the RSA Data 00014 Security, Inc. MD5 Message-Digest Algorithm" in all material 00015 mentioning or referencing the derived work. 00016 00017 RSA Data Security, Inc. makes no representations concerning either 00018 the merchantability of this software or the suitability of this 00019 software for any particular purpose. It is provided "as is" 00020 without express or implied warranty of any kind. 00021 00022 These notices must be retained in any copies of any part of this 00023 documentation and/or software. 00024 */ 00025 00026 #include "md5.hxx" 00027 00028 /* Constants for MD5Transform routine. 00029 */ 00030 00031 #define S11 7 00032 #define S12 12 00033 #define S13 17 00034 #define S14 22 00035 #define S21 5 00036 #define S22 9 00037 #define S23 14 00038 #define S24 20 00039 #define S31 4 00040 #define S32 11 00041 #define S33 16 00042 #define S34 23 00043 #define S41 6 00044 #define S42 10 00045 #define S43 15 00046 #define S44 21 00047 00048 static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64])); 00049 static void Encode PROTO_LIST 00050 ((unsigned char *, UINT4 *, unsigned int)); 00051 static void Decode PROTO_LIST 00052 ((UINT4 *, unsigned char *, unsigned int)); 00053 static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int)); 00054 static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int)); 00055 00056 static unsigned char PADDING[64] = { 00057 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00058 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00059 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 00060 }; 00061 00062 /* F, G, H and I are basic MD5 functions. 00063 */ 00064 #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 00065 #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) 00066 #define H(x, y, z) ((x) ^ (y) ^ (z)) 00067 #define I(x, y, z) ((y) ^ ((x) | (~z))) 00068 00069 /* ROTATE_LEFT rotates x left n bits. 00070 */ 00071 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 00072 00073 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. 00074 Rotation is separate from addition to prevent recomputation. 00075 */ 00076 #define FF(a, b, c, d, x, s, ac) { \ 00077 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ 00078 (a) = ROTATE_LEFT ((a), (s)); \ 00079 (a) += (b); \ 00080 } 00081 #define GG(a, b, c, d, x, s, ac) { \ 00082 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ 00083 (a) = ROTATE_LEFT ((a), (s)); \ 00084 (a) += (b); \ 00085 } 00086 #define HH(a, b, c, d, x, s, ac) { \ 00087 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ 00088 (a) = ROTATE_LEFT ((a), (s)); \ 00089 (a) += (b); \ 00090 } 00091 #define II(a, b, c, d, x, s, ac) { \ 00092 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ 00093 (a) = ROTATE_LEFT ((a), (s)); \ 00094 (a) += (b); \ 00095 } 00096 00097 /* MD5 initialization. Begins an MD5 operation, writing a new context. 00098 */ 00099 void MD5Init (context) 00100 MD5_CTX *context; /* context */ 00101 { 00102 context->count[0] = context->count[1] = 0; 00103 /* Load magic initialization constants. 00104 */ 00105 context->state[0] = 0x67452301; 00106 context->state[1] = 0xefcdab89; 00107 context->state[2] = 0x98badcfe; 00108 context->state[3] = 0x10325476; 00109 } 00110 00111 /* MD5 block update operation. Continues an MD5 message-digest 00112 operation, processing another message block, and updating the 00113 context. 00114 */ 00115 void MD5Update (context, input, inputLen) 00116 MD5_CTX *context; /* context */ 00117 unsigned char *input; /* input block */ 00118 unsigned int inputLen; /* length of input block */ 00119 { 00120 unsigned int i, index, partLen; 00121 00122 /* Compute number of bytes mod 64 */ 00123 index = (unsigned int)((context->count[0] >> 3) & 0x3F); 00124 00125 /* Update number of bits */ 00126 if ((context->count[0] += ((UINT4)inputLen << 3)) 00127 < ((UINT4)inputLen << 3)) 00128 context->count[1]++; 00129 context->count[1] += ((UINT4)inputLen >> 29); 00130 00131 partLen = 64 - index; 00132 00133 /* Transform as many times as possible. 00134 */ 00135 if (inputLen >= partLen) { 00136 MD5_memcpy 00137 ((POINTER)&context->buffer[index], (POINTER)input, partLen); 00138 MD5Transform (context->state, context->buffer); 00139 00140 for (i = partLen; i + 63 < inputLen; i += 64) 00141 MD5Transform (context->state, &input[i]); 00142 00143 index = 0; 00144 } 00145 else 00146 i = 0; 00147 00148 /* Buffer remaining input */ 00149 MD5_memcpy 00150 ((POINTER)&context->buffer[index], (POINTER)&input[i], 00151 inputLen-i); 00152 } 00153 00154 /* MD5 finalization. Ends an MD5 message-digest operation, writing the 00155 the message digest and zeroizing the context. 00156 */ 00157 void MD5Final (digest, context) 00158 unsigned char digest[16]; /* message digest */ 00159 MD5_CTX *context; /* context */ 00160 { 00161 unsigned char bits[8]; 00162 unsigned int index, padLen; 00163 00164 /* Save number of bits */ 00165 Encode (bits, context->count, 8); 00166 00167 /* Pad out to 56 mod 64. 00168 */ 00169 index = (unsigned int)((context->count[0] >> 3) & 0x3f); 00170 padLen = (index < 56) ? (56 - index) : (120 - index); 00171 MD5Update (context, PADDING, padLen); 00172 00173 /* Append length (before padding) */ 00174 MD5Update (context, bits, 8); 00175 /* Store state in digest */ 00176 Encode (digest, context->state, 16); 00177 00178 /* Zeroize sensitive information. 00179 */ 00180 MD5_memset ((POINTER)context, 0, sizeof (*context)); 00181 } 00182 00183 /* MD5 basic transformation. Transforms state based on block. 00184 */ 00185 static void MD5Transform (state, block) 00186 UINT4 state[4]; 00187 unsigned char block[64]; 00188 { 00189 UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; 00190 00191 Decode (x, block, 64); 00192 00193 /* Round 1 */ 00194 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ 00195 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ 00196 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ 00197 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ 00198 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ 00199 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ 00200 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ 00201 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ 00202 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ 00203 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ 00204 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ 00205 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ 00206 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ 00207 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ 00208 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ 00209 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ 00210 00211 /* Round 2 */ 00212 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ 00213 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ 00214 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ 00215 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ 00216 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ 00217 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ 00218 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ 00219 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ 00220 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ 00221 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ 00222 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ 00223 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ 00224 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ 00225 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ 00226 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ 00227 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ 00228 00229 /* Round 3 */ 00230 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ 00231 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ 00232 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ 00233 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ 00234 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ 00235 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ 00236 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ 00237 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ 00238 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ 00239 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ 00240 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ 00241 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ 00242 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ 00243 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ 00244 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ 00245 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ 00246 00247 /* Round 4 */ 00248 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ 00249 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ 00250 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ 00251 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ 00252 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ 00253 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ 00254 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ 00255 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ 00256 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ 00257 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ 00258 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ 00259 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ 00260 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ 00261 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ 00262 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ 00263 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ 00264 00265 state[0] += a; 00266 state[1] += b; 00267 state[2] += c; 00268 state[3] += d; 00269 00270 /* Zeroize sensitive information. 00271 00272 */ 00273 MD5_memset ((POINTER)x, 0, sizeof (x)); 00274 } 00275 00276 /* Encodes input (UINT4) into output (unsigned char). Assumes len is 00277 a multiple of 4. 00278 */ 00279 static void Encode (output, input, len) 00280 unsigned char *output; 00281 UINT4 *input; 00282 unsigned int len; 00283 { 00284 unsigned int i, j; 00285 00286 for (i = 0, j = 0; j < len; i++, j += 4) { 00287 output[j] = (unsigned char)(input[i] & 0xff); 00288 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); 00289 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); 00290 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); 00291 } 00292 } 00293 00294 /* Decodes input (unsigned char) into output (UINT4). Assumes len is 00295 a multiple of 4. 00296 */ 00297 static void Decode (output, input, len) 00298 UINT4 *output; 00299 unsigned char *input; 00300 unsigned int len; 00301 { 00302 unsigned int i, j; 00303 00304 for (i = 0, j = 0; j < len; i++, j += 4) 00305 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | 00306 (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); 00307 } 00308 00309 /* Note: Replace "for loop" with standard memcpy if possible. 00310 */ 00311 00312 static void MD5_memcpy (output, input, len) 00313 POINTER output; 00314 POINTER input; 00315 unsigned int len; 00316 { 00317 unsigned int i; 00318 00319 for (i = 0; i < len; i++) 00320 output[i] = input[i]; 00321 } 00322 00323 /* Note: Replace "for loop" with standard memset if possible. 00324 */ 00325 static void MD5_memset (output, value, len) 00326 POINTER output; 00327 int value; 00328 unsigned int len; 00329 { 00330 unsigned int i; 00331 00332 for (i = 0; i < len; i++) 00333 ((char *)output)[i] = (char)value; 00334 } 00335 00336 00337 /* ==================================================================== 00338 * The Vovida Software License, Version 1.0 00339 * 00340 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 00341 * 00342 * Redistribution and use in source and binary forms, with or without 00343 * modification, are permitted provided that the following conditions 00344 * are met: 00345 * 00346 * 1. Redistributions of source code must retain the above copyright 00347 * notice, this list of conditions and the following disclaimer. 00348 * 00349 * 2. Redistributions in binary form must reproduce the above copyright 00350 * notice, this list of conditions and the following disclaimer in 00351 * the documentation and/or other materials provided with the 00352 * distribution. 00353 * 00354 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00355 * and "Vovida Open Communication Application Library (VOCAL)" must 00356 * not be used to endorse or promote products derived from this 00357 * software without prior written permission. For written 00358 * permission, please contact vocal@vovida.org. 00359 * 00360 * 4. Products derived from this software may not be called "VOCAL", nor 00361 * may "VOCAL" appear in their name, without prior written 00362 * permission of Vovida Networks, Inc. 00363 * 00364 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00365 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00366 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00367 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00368 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00369 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00370 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00371 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00372 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00373 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00374 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00375 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00376 * DAMAGE. 00377 * 00378 * ==================================================================== 00379 * 00380 * This software consists of voluntary contributions made by Vovida 00381 * Networks, Inc. and many individuals on behalf of Vovida Networks, 00382 * Inc. For more information on Vovida Networks, Inc., please see 00383 * <http://www.vovida.org/>. 00384 * 00385 */
1.7.5.1