G:/ScriptBasic/source/tools/md5.c

Go to the documentation of this file.
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 "global.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 
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   MD5_memset ((POINTER)x, 0, sizeof (x));
00273 }
00274 
00275 /* Encodes input (UINT4) into output (unsigned char). Assumes len is
00276   a multiple of 4.
00277  */
00278 static void Encode (output, input, len)
00279 unsigned char *output;
00280 UINT4 *input;
00281 unsigned int len;
00282 {
00283   unsigned int i, j;
00284 
00285   for (i = 0, j = 0; j < len; i++, j += 4) {
00286  output[j] = (unsigned char)(input[i] & 0xff);
00287  output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
00288  output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
00289  output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
00290   }
00291 }
00292 
00293 /* Decodes input (unsigned char) into output (UINT4). Assumes len is
00294   a multiple of 4.
00295  */
00296 static void Decode (output, input, len)
00297 UINT4 *output;
00298 unsigned char *input;
00299 unsigned int len;
00300 {
00301   unsigned int i, j;
00302 
00303   for (i = 0, j = 0; j < len; i++, j += 4)
00304  output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
00305    (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
00306 }
00307 
00308 /* Note: Replace "for loop" with standard memcpy if possible.
00309  */
00310 
00311 static void MD5_memcpy (output, input, len)
00312 POINTER output;
00313 POINTER input;
00314 unsigned int len;
00315 {
00316   unsigned int i;
00317 
00318   for (i = 0; i < len; i++)
00319  output[i] = input[i];
00320 }
00321 
00322 /* Note: Replace "for loop" with standard memset if possible.
00323  */
00324 static void MD5_memset (output, value, len)
00325 POINTER output;
00326 int value;
00327 unsigned int len;
00328 {
00329   unsigned int i;
00330 
00331   for (i = 0; i < len; i++)
00332  ((char *)output)[i] = (char)value;
00333 }

Generated on Sun Mar 12 23:56:31 2006 for ScriptBasic by  doxygen 1.4.6-NO