• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • Directories
  • File List
  • Globals

md5.c

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

Generated on Tue May 22 2012 13:10:11 for SIP Router by  doxygen 1.7.1