ARPDAS_QNX6 1.0
|
00001 /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm 00002 Obtained from RFC 1321 Reference Implementation 00003 */ 00004 00005 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All 00006 rights reserved. 00007 00008 License to copy and use this software is granted provided that it 00009 is identified as the "RSA Data Security, Inc. MD5 Message-Digest 00010 Algorithm" in all material mentioning or referencing this software 00011 or this function. 00012 00013 License is also granted to make and use derivative works provided 00014 that such works are identified as "derived from the RSA Data 00015 Security, Inc. MD5 Message-Digest Algorithm" in all material 00016 mentioning or referencing the derived work. 00017 00018 RSA Data Security, Inc. makes no representations concerning either 00019 the merchantability of this software or the suitability of this 00020 software for any particular purpose. It is provided "as is" 00021 without express or implied warranty of any kind. 00022 00023 These notices must be retained in any copies of any part of this 00024 documentation and/or software. 00025 */ 00026 #include <string.h> 00027 #include "md5.h" 00028 00029 /* Constants for MD5Transform routine. 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 #define MD5_memcpy memcpy 00056 #define MD5_memset memset 00057 00058 static unsigned char PADDING[64] = { 00059 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00060 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00061 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 00062 }; 00063 00064 /* F, G, H and I are basic MD5 functions. 00065 */ 00066 #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 00067 #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) 00068 #define H(x, y, z) ((x) ^ (y) ^ (z)) 00069 #define I(x, y, z) ((y) ^ ((x) | (~z))) 00070 00071 /* ROTATE_LEFT rotates x left n bits. 00072 */ 00073 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 00074 00075 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. 00076 Rotation is separate from addition to prevent recomputation. 00077 */ 00078 #define FF(a, b, c, d, x, s, ac) { \ 00079 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ 00080 (a) = ROTATE_LEFT ((a), (s)); \ 00081 (a) += (b); \ 00082 } 00083 #define GG(a, b, c, d, x, s, ac) { \ 00084 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ 00085 (a) = ROTATE_LEFT ((a), (s)); \ 00086 (a) += (b); \ 00087 } 00088 #define HH(a, b, c, d, x, s, ac) { \ 00089 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ 00090 (a) = ROTATE_LEFT ((a), (s)); \ 00091 (a) += (b); \ 00092 } 00093 #define II(a, b, c, d, x, s, ac) { \ 00094 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ 00095 (a) = ROTATE_LEFT ((a), (s)); \ 00096 (a) += (b); \ 00097 } 00098 00099 /* MD5 initialization. Begins an MD5 operation, writing a new context. 00100 */ 00101 void MD5Init (context) 00102 MD5_CTX *context; /* context */ 00103 { 00104 context->count[0] = context->count[1] = 0; 00105 /* Load magic initialization constants. 00106 */ 00107 context->state[0] = 0x67452301; 00108 context->state[1] = 0xefcdab89; 00109 context->state[2] = 0x98badcfe; 00110 context->state[3] = 0x10325476; 00111 } 00112 00113 /* MD5 block update operation. Continues an MD5 message-digest 00114 operation, processing another message block, and updating the 00115 context. 00116 */ 00117 void MD5Update (context, input, inputLen) 00118 MD5_CTX *context; /* context */ 00119 unsigned char *input; /* input block */ 00120 unsigned int inputLen; /* length of input block */ 00121 { 00122 unsigned int i, index, partLen; 00123 00124 /* Compute number of bytes mod 64 */ 00125 index = (unsigned int)((context->count[0] >> 3) & 0x3F); 00126 00127 /* Update number of bits */ 00128 if ((context->count[0] += ((UINT4)inputLen << 3)) 00129 < ((UINT4)inputLen << 3)) 00130 context->count[1]++; 00131 context->count[1] += ((UINT4)inputLen >> 29); 00132 00133 partLen = 64 - index; 00134 00135 /* Transform as many times as possible. 00136 */ 00137 if (inputLen >= partLen) { 00138 MD5_memcpy 00139 ((POINTER)&context->buffer[index], (POINTER)input, partLen); 00140 MD5Transform (context->state, context->buffer); 00141 00142 for (i = partLen; i + 63 < inputLen; i += 64) 00143 MD5Transform (context->state, &input[i]); 00144 00145 index = 0; 00146 } 00147 else 00148 i = 0; 00149 00150 /* Buffer remaining input */ 00151 MD5_memcpy 00152 ((POINTER)&context->buffer[index], (POINTER)&input[i], 00153 inputLen-i); 00154 } 00155 00156 /* MD5 finalization. Ends an MD5 message-digest operation, writing the 00157 the message digest and zeroizing the context. 00158 */ 00159 void MD5Final (digest, context) 00160 unsigned char digest[16]; /* message digest */ 00161 MD5_CTX *context; /* context */ 00162 { 00163 unsigned char bits[8]; 00164 unsigned int index, padLen; 00165 00166 /* Save number of bits */ 00167 Encode (bits, context->count, 8); 00168 00169 /* Pad out to 56 mod 64. 00170 */ 00171 index = (unsigned int)((context->count[0] >> 3) & 0x3f); 00172 padLen = (index < 56) ? (56 - index) : (120 - index); 00173 MD5Update (context, PADDING, padLen); 00174 00175 /* Append length (before padding) */ 00176 MD5Update (context, bits, 8); 00177 00178 /* Store state in digest */ 00179 Encode (digest, context->state, 16); 00180 00181 /* Zeroize sensitive information. 00182 */ 00183 MD5_memset ((POINTER)context, 0, sizeof (*context)); 00184 } 00185 00186 /* MD5 basic transformation. Transforms state based on block. 00187 */ 00188 static void MD5Transform (state, block) 00189 UINT4 state[4]; 00190 unsigned char block[64]; 00191 { 00192 UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; 00193 00194 Decode (x, block, 64); 00195 00196 /* Round 1 */ 00197 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ 00198 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ 00199 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ 00200 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ 00201 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ 00202 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ 00203 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ 00204 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ 00205 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ 00206 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ 00207 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ 00208 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ 00209 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ 00210 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ 00211 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ 00212 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ 00213 00214 /* Round 2 */ 00215 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ 00216 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ 00217 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ 00218 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ 00219 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ 00220 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ 00221 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ 00222 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ 00223 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ 00224 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ 00225 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ 00226 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ 00227 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ 00228 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ 00229 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ 00230 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ 00231 00232 /* Round 3 */ 00233 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ 00234 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ 00235 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ 00236 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ 00237 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ 00238 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ 00239 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ 00240 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ 00241 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ 00242 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ 00243 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ 00244 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ 00245 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ 00246 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ 00247 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ 00248 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ 00249 00250 /* Round 4 */ 00251 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ 00252 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ 00253 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ 00254 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ 00255 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ 00256 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ 00257 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ 00258 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ 00259 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ 00260 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ 00261 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ 00262 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ 00263 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ 00264 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ 00265 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ 00266 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ 00267 00268 state[0] += a; 00269 state[1] += b; 00270 state[2] += c; 00271 state[3] += d; 00272 00273 /* Zeroize sensitive information. */ 00274 MD5_memset ((POINTER)x, 0, sizeof (x)); 00275 } 00276 00277 /* Encodes input (UINT4) into output (unsigned char). Assumes len is 00278 a multiple of 4. 00279 */ 00280 static void Encode (output, input, len) 00281 unsigned char *output; 00282 UINT4 *input; 00283 unsigned int len; 00284 { 00285 unsigned int i, j; 00286 00287 for (i = 0, j = 0; j < len; i++, j += 4) { 00288 output[j] = (unsigned char)(input[i] & 0xff); 00289 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); 00290 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); 00291 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); 00292 } 00293 } 00294 00295 /* Decodes input (unsigned char) into output (UINT4). Assumes len is 00296 a multiple of 4. 00297 */ 00298 static void Decode (output, input, len) 00299 UINT4 *output; 00300 unsigned char *input; 00301 unsigned int len; 00302 { 00303 unsigned int i, j; 00304 00305 for (i = 0, j = 0; j < len; i++, j += 4) 00306 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | 00307 (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); 00308 } 00309 00310 /* Note: Replace "for loop" with standard memcpy if possible. 00311 */ 00312 00313 #ifndef MD5_memcpy 00314 static void MD5_memcpy (output, input, len) 00315 POINTER output; 00316 POINTER input; 00317 unsigned int len; 00318 { 00319 unsigned int i; 00320 00321 for (i = 0; i < len; i++) 00322 output[i] = input[i]; 00323 } 00324 #endif 00325 00326 /* Note: Replace "for loop" with standard memset if possible. 00327 */ 00328 #ifndef MD5_memset 00329 static void MD5_memset (output, value, len) 00330 POINTER output; 00331 int value; 00332 unsigned int len; 00333 { 00334 unsigned int i; 00335 00336 for (i = 0; i < len; i++) 00337 ((char *)output)[i] = (char)value; 00338 } 00339 #endif