G:/ScriptBasic/source/md5.c

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

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