ARPDAS_QNX6 1.0
md5c.c
Go to the documentation of this file.
00001 /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
00002    Obtained from RFC 1321 Reference Implementation
00003  */
00004 
00005 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
00006 rights reserved.
00007 
00008 License to copy and use this software is granted provided that it
00009 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
00010 Algorithm" in all material mentioning or referencing this software
00011 or this function.
00012 
00013 License is also granted to make and use derivative works provided
00014 that such works are identified as "derived from the RSA Data
00015 Security, Inc. MD5 Message-Digest Algorithm" in all material
00016 mentioning or referencing the derived work.
00017 
00018 RSA Data Security, Inc. makes no representations concerning either
00019 the merchantability of this software or the suitability of this
00020 software for any particular purpose. It is provided "as is"
00021 without express or implied warranty of any kind.
00022 
00023 These notices must be retained in any copies of any part of this
00024 documentation and/or software.
00025  */
00026 #include <string.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 #define MD5_memcpy memcpy
00056 #define MD5_memset memset
00057 
00058 static unsigned char PADDING[64] = {
00059   0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00060   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00061   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00062 };
00063 
00064 /* F, G, H and I are basic MD5 functions.
00065  */
00066 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
00067 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
00068 #define H(x, y, z) ((x) ^ (y) ^ (z))
00069 #define I(x, y, z) ((y) ^ ((x) | (~z)))
00070 
00071 /* ROTATE_LEFT rotates x left n bits.
00072  */
00073 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
00074 
00075 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
00076 Rotation is separate from addition to prevent recomputation.
00077  */
00078 #define FF(a, b, c, d, x, s, ac) { \
00079  (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
00080  (a) = ROTATE_LEFT ((a), (s)); \
00081  (a) += (b); \
00082   }
00083 #define GG(a, b, c, d, x, s, ac) { \
00084  (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
00085  (a) = ROTATE_LEFT ((a), (s)); \
00086  (a) += (b); \
00087   }
00088 #define HH(a, b, c, d, x, s, ac) { \
00089  (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
00090  (a) = ROTATE_LEFT ((a), (s)); \
00091  (a) += (b); \
00092   }
00093 #define II(a, b, c, d, x, s, ac) { \
00094  (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
00095  (a) = ROTATE_LEFT ((a), (s)); \
00096  (a) += (b); \
00097   }
00098 
00099 /* MD5 initialization. Begins an MD5 operation, writing a new context.
00100  */
00101 void MD5Init (context)
00102 MD5_CTX *context;                                        /* context */
00103 {
00104   context->count[0] = context->count[1] = 0;
00105   /* Load magic initialization constants.
00106 */
00107   context->state[0] = 0x67452301;
00108   context->state[1] = 0xefcdab89;
00109   context->state[2] = 0x98badcfe;
00110   context->state[3] = 0x10325476;
00111 }
00112 
00113 /* MD5 block update operation. Continues an MD5 message-digest
00114   operation, processing another message block, and updating the
00115   context.
00116  */
00117 void MD5Update (context, input, inputLen)
00118 MD5_CTX *context;                                        /* context */
00119 unsigned char *input;                                /* input block */
00120 unsigned int inputLen;                     /* length of input block */
00121 {
00122   unsigned int i, index, partLen;
00123 
00124   /* Compute number of bytes mod 64 */
00125   index = (unsigned int)((context->count[0] >> 3) & 0x3F);
00126 
00127   /* Update number of bits */
00128   if ((context->count[0] += ((UINT4)inputLen << 3))
00129    < ((UINT4)inputLen << 3))
00130  context->count[1]++;
00131   context->count[1] += ((UINT4)inputLen >> 29);
00132 
00133   partLen = 64 - index;
00134 
00135   /* Transform as many times as possible.
00136 */
00137   if (inputLen >= partLen) {
00138  MD5_memcpy
00139    ((POINTER)&context->buffer[index], (POINTER)input, partLen);
00140  MD5Transform (context->state, context->buffer);
00141 
00142  for (i = partLen; i + 63 < inputLen; i += 64)
00143    MD5Transform (context->state, &input[i]);
00144 
00145  index = 0;
00146   }
00147   else
00148  i = 0;
00149 
00150   /* Buffer remaining input */
00151   MD5_memcpy
00152  ((POINTER)&context->buffer[index], (POINTER)&input[i],
00153   inputLen-i);
00154 }
00155 
00156 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
00157   the message digest and zeroizing the context.
00158  */
00159 void MD5Final (digest, context)
00160 unsigned char digest[16];                         /* message digest */
00161 MD5_CTX *context;                                       /* context */
00162 {
00163   unsigned char bits[8];
00164   unsigned int index, padLen;
00165 
00166   /* Save number of bits */
00167   Encode (bits, context->count, 8);
00168 
00169   /* Pad out to 56 mod 64.
00170 */
00171   index = (unsigned int)((context->count[0] >> 3) & 0x3f);
00172   padLen = (index < 56) ? (56 - index) : (120 - index);
00173   MD5Update (context, PADDING, padLen);
00174 
00175   /* Append length (before padding) */
00176   MD5Update (context, bits, 8);
00177 
00178   /* Store state in digest */
00179   Encode (digest, context->state, 16);
00180 
00181   /* Zeroize sensitive information.
00182 */
00183   MD5_memset ((POINTER)context, 0, sizeof (*context));
00184 }
00185 
00186 /* MD5 basic transformation. Transforms state based on block.
00187  */
00188 static void MD5Transform (state, block)
00189 UINT4 state[4];
00190 unsigned char block[64];
00191 {
00192   UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
00193 
00194   Decode (x, block, 64);
00195 
00196   /* Round 1 */
00197   FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
00198   FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
00199   FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
00200   FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
00201   FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
00202   FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
00203   FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
00204   FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
00205   FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
00206   FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
00207   FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
00208   FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
00209   FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
00210   FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
00211   FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
00212   FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
00213 
00214  /* Round 2 */
00215   GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
00216   GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
00217   GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
00218   GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
00219   GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
00220   GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
00221   GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
00222   GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
00223   GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
00224   GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
00225   GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
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   MD5_memset ((POINTER)x, 0, sizeof (x));
00275 }
00276 
00277 /* Encodes input (UINT4) into output (unsigned char). Assumes len is
00278   a multiple of 4.
00279  */
00280 static void Encode (output, input, len)
00281 unsigned char *output;
00282 UINT4 *input;
00283 unsigned int len;
00284 {
00285   unsigned int i, j;
00286 
00287   for (i = 0, j = 0; j < len; i++, j += 4) {
00288  output[j] = (unsigned char)(input[i] & 0xff);
00289  output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
00290  output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
00291  output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
00292   }
00293 }
00294 
00295 /* Decodes input (unsigned char) into output (UINT4). Assumes len is
00296   a multiple of 4.
00297  */
00298 static void Decode (output, input, len)
00299 UINT4 *output;
00300 unsigned char *input;
00301 unsigned int len;
00302 {
00303   unsigned int i, j;
00304 
00305   for (i = 0, j = 0; j < len; i++, j += 4)
00306  output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
00307    (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
00308 }
00309 
00310 /* Note: Replace "for loop" with standard memcpy if possible.
00311  */
00312 
00313 #ifndef MD5_memcpy
00314 static void MD5_memcpy (output, input, len)
00315 POINTER output;
00316 POINTER input;
00317 unsigned int len;
00318 {
00319   unsigned int i;
00320 
00321   for (i = 0; i < len; i++)
00322   output[i] = input[i];
00323 }
00324 #endif
00325 
00326 /* Note: Replace "for loop" with standard memset if possible.
00327  */
00328 #ifndef MD5_memset
00329 static void MD5_memset (output, value, len)
00330 POINTER output;
00331 int value;
00332 unsigned int len;
00333 {
00334   unsigned int i;
00335 
00336   for (i = 0; i < len; i++)
00337  ((char *)output)[i] = (char)value;
00338 }
00339 #endif
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines