md5.c

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

Generated on Wed May 31 18:19:54 2006 for frontierkernel 10.1.10a by  doxygen 1.4.6