md5c.cpp

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 /* $Id: md5c.cpp 71526 2006-03-14 06:14:35Z jtc $ */
00027 
00028 #include "orbsvcs/AV/global.h"
00029 #include "orbsvcs/AV/md5.h"
00030 
00031 /* Constants for MD5Transform routine.
00032  */
00033 
00034 #define S11 7
00035 #define S12 12
00036 #define S13 17
00037 #define S14 22
00038 #define S21 5
00039 #define S22 9
00040 #define S23 14
00041 #define S24 20
00042 #define S31 4
00043 #define S32 11
00044 #define S33 16
00045 #define S34 23
00046 #define S41 6
00047 #define S42 10
00048 #define S43 15
00049 #define S44 21
00050 
00051 /*static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
00052 static void Encode PROTO_LIST
00053   ((unsigned char *, UINT4 *, unsigned int));
00054 static void Decode PROTO_LIST
00055   ((UINT4 *, unsigned char *, unsigned int));
00056 static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
00057 static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));*/
00058 static void MD5Transform (UINT4 [4], unsigned char [64]);
00059 static void Encode (unsigned char *, UINT4 *, unsigned int);
00060 static void Decode (UINT4 *, unsigned char *, unsigned int);
00061 static void MD5_memcpy (POINTER, POINTER, unsigned int);
00062 static void MD5_memset (POINTER, int, unsigned int);
00063 
00064 static unsigned char PADDING[64] = {
00065   0x80, 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, 0, 0, 0, 0,
00067   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00068 };
00069 
00070 /* F, G, H and I are basic MD5 functions.
00071  */
00072 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
00073 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
00074 #define H(x, y, z) ((x) ^ (y) ^ (z))
00075 #define I(x, y, z) ((y) ^ ((x) | (~z)))
00076 
00077 /* ROTATE_LEFT rotates x left n bits.
00078  */
00079 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
00080 
00081 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
00082 Rotation is separate from addition to prevent recomputation.
00083  */
00084 #define FF(a, b, c, d, x, s, ac) { \
00085  (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
00086  (a) = ROTATE_LEFT ((a), (s)); \
00087  (a) += (b); \
00088   }
00089 #define GG(a, b, c, d, x, s, ac) { \
00090  (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
00091  (a) = ROTATE_LEFT ((a), (s)); \
00092  (a) += (b); \
00093   }
00094 #define HH(a, b, c, d, x, s, ac) { \
00095  (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
00096  (a) = ROTATE_LEFT ((a), (s)); \
00097  (a) += (b); \
00098   }
00099 #define II(a, b, c, d, x, s, ac) { \
00100  (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
00101  (a) = ROTATE_LEFT ((a), (s)); \
00102  (a) += (b); \
00103   }
00104 
00105 /* MD5 initialization. Begins an MD5 operation, writing a new context.
00106  */
00107 void MD5Init (MD5_CTX *context)
00108 {
00109   context->count[0] = context->count[1] = 0;
00110   /* Load magic initialization constants.
00111 */
00112   context->state[0] = 0x67452301;
00113   context->state[1] = 0xefcdab89;
00114   context->state[2] = 0x98badcfe;
00115   context->state[3] = 0x10325476;
00116 }
00117 
00118 /* MD5 block update operation. Continues an MD5 message-digest
00119   operation, processing another message block, and updating the
00120   context.
00121  */
00122 void MD5Update (MD5_CTX *context, unsigned char *input, unsigned int inputLen)
00123 {
00124   unsigned int i, index, partLen;
00125 
00126   /* Compute number of bytes mod 64 */
00127   index = (unsigned int)((context->count[0] >> 3) & 0x3F);
00128 
00129   /* Update number of bits */
00130   if ((context->count[0] += ((UINT4)inputLen << 3))
00131 
00132    < ((UINT4)inputLen << 3))
00133  context->count[1]++;
00134   context->count[1] += ((UINT4)inputLen >> 29);
00135 
00136   partLen = 64 - index;
00137 
00138   /* Transform as many times as possible.
00139 */
00140   if (inputLen >= partLen) {
00141  MD5_memcpy
00142    ((POINTER)&context->buffer[index], (POINTER)input, partLen);
00143  MD5Transform (context->state, context->buffer);
00144 
00145  for (i = partLen; i + 63 < inputLen; i += 64)
00146    MD5Transform (context->state, &input[i]);
00147 
00148  index = 0;
00149   }
00150   else
00151  i = 0;
00152 
00153   /* Buffer remaining input */
00154   MD5_memcpy
00155  ((POINTER)&context->buffer[index], (POINTER)&input[i],
00156   inputLen-i);
00157 }
00158 
00159 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
00160   the message digest and zeroizing the context.
00161  */
00162 void MD5Final (unsigned char digest[16], MD5_CTX *context)
00163 {
00164   unsigned char bits[8];
00165   unsigned int index, padLen;
00166 
00167   /* Save number of bits */
00168   Encode (bits, context->count, 8);
00169 
00170   /* Pad out to 56 mod 64.
00171 */
00172   index = (unsigned int)((context->count[0] >> 3) & 0x3f);
00173   padLen = (index < 56) ? (56 - index) : (120 - index);
00174   MD5Update (context, PADDING, padLen);
00175 
00176   /* Append length (before padding) */
00177   MD5Update (context, bits, 8);
00178 
00179   /* Store state in digest */
00180   Encode (digest, context->state, 16);
00181 
00182   /* Zeroize sensitive information.
00183 */
00184   MD5_memset ((POINTER)context, 0, sizeof (*context));
00185 }
00186 
00187 /* MD5 basic transformation. Transforms state based on block.
00188  */
00189 static void MD5Transform (UINT4 state[4], unsigned char block[64])
00190 {
00191   UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
00192 
00193   Decode (x, block, 64);
00194 
00195   /* Round 1 */
00196   FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
00197   FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
00198   FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
00199   FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
00200   FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
00201   FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
00202   FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
00203   FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
00204   FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
00205   FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
00206   FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
00207   FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
00208   FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
00209   FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
00210   FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
00211   FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
00212 
00213  /* Round 2 */
00214   GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
00215   GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
00216   GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
00217   GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
00218   GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
00219   GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
00220   GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
00221   GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
00222   GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
00223   GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
00224   GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
00225 
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 
00275 */
00276   MD5_memset ((POINTER)x, 0, sizeof (x));
00277 }
00278 
00279 /* Encodes input (UINT4) into output (unsigned char). Assumes len is
00280   a multiple of 4.
00281  */
00282 static void Encode (unsigned char *output, UINT4 *input, unsigned int len)
00283 {
00284   unsigned int i, j;
00285 
00286   for (i = 0, j = 0; j < len; i++, j += 4) {
00287  output[j] = (unsigned char)(input[i] & 0xff);
00288  output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
00289  output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
00290  output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
00291   }
00292 }
00293 
00294 /* Decodes input (unsigned char) into output (UINT4). Assumes len is
00295   a multiple of 4.
00296  */
00297 static void Decode (UINT4 *output, unsigned char *input, unsigned int len)
00298 {
00299   unsigned int i, j;
00300 
00301   for (i = 0, j = 0; j < len; i++, j += 4)
00302  output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
00303    (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
00304 }
00305 
00306 /* Note: Replace "for loop" with standard memcpy if possible.
00307  */
00308 
00309 static void MD5_memcpy (POINTER output, POINTER input, unsigned int len)
00310 {
00311   unsigned int i;
00312 
00313   for (i = 0; i < len; i++)
00314 
00315  output[i] = input[i];
00316 }
00317 
00318 /* Note: Replace "for loop" with standard memset if possible.
00319  */
00320 static void MD5_memset (POINTER output, int value, unsigned int len)
00321 {
00322   unsigned int i;
00323 
00324   for (i = 0; i < len; i++)
00325  ((char *)output)[i] = (char)value;
00326 }

Generated on Tue Feb 2 17:47:49 2010 for TAO_AV by  doxygen 1.4.7