src/md5.c

00001 /* 
00002  * md5.c - Copyright 1997 Lachlan Roche 
00003  */
00004 #include <stdio.h>
00005 #include <string.h>
00006 #include "md5.h"
00007 
00008 /*
00009  * The remaining code is the reference MD5 code (md5c.c) from rfc1321
00010  */
00011 /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
00012  */
00013 
00014 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
00015    rights reserved.
00016 
00017    License to copy and use this software is granted provided that it
00018    is identified as the "RSA Data Security, Inc. MD5 Message-Digest
00019    Algorithm" in all material mentioning or referencing this software
00020    or this function.
00021 
00022    License is also granted to make and use derivative works provided
00023    that such works are identified as "derived from the RSA Data
00024    Security, Inc. MD5 Message-Digest Algorithm" in all material
00025    mentioning or referencing the derived work.
00026 
00027    RSA Data Security, Inc. makes no representations concerning either
00028    the merchantability of this software or the suitability of this
00029    software for any particular purpose. It is provided "as is"
00030    without express or implied warranty of any kind.
00031 
00032    These notices must be retained in any copies of any part of this
00033    documentation and/or software.
00034  */
00035 
00036 /* Constants for MD5Transform routine.
00037  */
00038 
00039 
00040 #define S11 7
00041 #define S12 12
00042 #define S13 17
00043 #define S14 22
00044 #define S21 5
00045 #define S22 9
00046 #define S23 14
00047 #define S24 20
00048 #define S31 4
00049 #define S32 11
00050 #define S33 16
00051 #define S34 23
00052 #define S41 6
00053 #define S42 10
00054 #define S43 15
00055 #define S44 21
00056 
00057 static void MD5Transform(unsigned int[4], const unsigned char[64]);
00058 static void Encode(unsigned char *, unsigned int *, unsigned int);
00059 static void Decode(unsigned int *, const unsigned char *, unsigned int);
00060 static void MD5_memcpy(void *, void *, unsigned int);
00061 static void MD5_memset(void *, int, 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 
00069 /* F, G, H and I are basic MD5 functions.
00070  */
00071 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
00072 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
00073 #define H(x, y, z) ((x) ^ (y) ^ (z))
00074 #define I(x, y, z) ((y) ^ ((x) | (~z)))
00075 
00076 /* ROTATE_LEFT rotates x left n bits.
00077  */
00078 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
00079 
00080 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
00081    Rotation is separate from addition to prevent recomputation.
00082  */
00083 #define FF(a, b, c, d, x, s, ac) { \
00084  (a) += F ((b), (c), (d)) + (x) + (unsigned int)(ac); \
00085  (a) = ROTATE_LEFT ((a), (s)); \
00086  (a) += (b); \
00087   }
00088 #define GG(a, b, c, d, x, s, ac) { \
00089  (a) += G ((b), (c), (d)) + (x) + (unsigned int)(ac); \
00090  (a) = ROTATE_LEFT ((a), (s)); \
00091  (a) += (b); \
00092   }
00093 #define HH(a, b, c, d, x, s, ac) { \
00094  (a) += H ((b), (c), (d)) + (x) + (unsigned int)(ac); \
00095  (a) = ROTATE_LEFT ((a), (s)); \
00096  (a) += (b); \
00097   }
00098 #define II(a, b, c, d, x, s, ac) { \
00099  (a) += I ((b), (c), (d)) + (x) + (unsigned int)(ac); \
00100  (a) = ROTATE_LEFT ((a), (s)); \
00101  (a) += (b); \
00102   }
00103 
00104 /* MD5 initialization. Begins an MD5 operation, writing a new context.
00105  */
00106 void MD5Init(MD5_CTX * context)
00107 {
00108         context->count[0] = context->count[1] = 0;
00109         /* Load magic initialization constants.
00110          */
00111         context->state[0] = 0x67452301;
00112         context->state[1] = 0xefcdab89;
00113         context->state[2] = 0x98badcfe;
00114         context->state[3] = 0x10325476;
00115 }
00116 
00117 /* MD5 block update operation. Continues an MD5 message-digest
00118    operation, processing another message block, and updating the
00119    context.
00120  */
00121 void MD5Update(MD5_CTX * context, const unsigned char *input,
00122                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] += ((unsigned int) inputLen << 3))
00131             < ((unsigned int) inputLen << 3))
00132                 context->count[1]++;
00133         context->count[1] += ((unsigned int) inputLen >> 29);
00134 
00135         partLen = 64 - index;
00136 
00137         /* Transform as many times as possible.
00138          */
00139         if (inputLen >= partLen) {
00140                 MD5_memcpy
00141                    ((void *) &context->buffer[index], (void *) input, partLen);
00142                 MD5Transform(context->state, context->buffer);
00143 
00144                 for (i = partLen; i + 63 < inputLen; i += 64)
00145                         MD5Transform(context->state, &input[i]);
00146 
00147                 index = 0;
00148         }
00149         else
00150                 i = 0;
00151 
00152         /* Buffer remaining input */
00153         MD5_memcpy
00154            ((void *) &context->buffer[index], (void *) &input[i], inputLen - i);
00155 }
00156 
00157 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
00158    the message digest and zeroizing the context.
00159  */
00160 void MD5Final(unsigned char digest[16], MD5_CTX * context)
00161 {
00162         unsigned char bits[8];
00163         unsigned int index, padLen;
00164 
00165         /* Save number of bits */
00166         Encode(bits, context->count, 8);
00167 
00168         /* Pad out to 56 mod 64.
00169          */
00170         index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
00171         padLen = (index < 56) ? (56 - index) : (120 - index);
00172         MD5Update(context, PADDING, padLen);
00173 
00174         /* Append length (before padding) */
00175         MD5Update(context, bits, 8);
00176 
00177         /* Store state in digest */
00178         Encode(digest, context->state, 16);
00179 
00180         /* Zeroize sensitive information.
00181          */
00182         MD5_memset((void *) context, 0, sizeof (*context));
00183 }
00184 
00185 /* MD5 basic transformation. Transforms state based on block.
00186  */
00187 static void MD5Transform(state, block)
00188      unsigned int state[4];
00189      const unsigned char block[64];
00190 {
00191         unsigned int a = state[0], b = state[1], c = state[2], d =
00192            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((void *) x, 0, sizeof (x));
00275 }
00276 
00277 /* Encodes input (unsigned int) 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      unsigned int *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 (unsigned int). Assumes len is
00296    a multiple of 4.
00297  */
00298 static void Decode(output, input, len)
00299      unsigned int *output;
00300      const 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] =
00307                    ((unsigned int) input[j]) | (((unsigned int) input[j + 1]) <<
00308                                                 8) |
00309                    (((unsigned int) input[j + 2]) << 16) |
00310                    (((unsigned int) input[j + 3]) << 24);
00311 }
00312 
00313 /* Note: Replace "for loop" with standard memcpy if possible.
00314  */
00315 
00316 static void MD5_memcpy(output, input, len)
00317      void *output;
00318      void *input;
00319      unsigned int len;
00320 {
00321 /*      unsigned int i; */
00322 
00323         memmove(output, input, len * sizeof (void));
00324         /* for (i = 0; i < len; i++)
00325            output[i] = input[i]; */
00326 }
00327 
00328 /* Note: Replace "for loop" with standard memset if possible.
00329  */
00330 static void MD5_memset(output, value, len)
00331      void *output;
00332      int value;
00333      unsigned int len;
00334 {
00335         memset(output, (char) value, len);
00336 /*      
00337         unsigned int i;
00338 
00339         for (i = 0; i < len; i++)
00340                 ((char *) output)[i] = (char) value;
00341 */
00342 }

Generated on Thu Feb 22 06:15:14 2007 for midgard-core by  doxygen 1.4.6