liveMedia/our_md5.c

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

Generated on Mon Apr 29 13:28:03 2013 for live by  doxygen 1.5.2