md5.c

Go to the documentation of this file.
00001 /*
00002  * This is an OpenSSL-compatible implementation of the RSA Data Security,
00003  * Inc. MD5 Message-Digest Algorithm.
00004  *
00005  * Written by Solar Designer <solar@openwall.com> in 2001, and placed in
00006  * the public domain.
00007  *
00008  * This differs from Colin Plumb's older public domain implementation in
00009  * that no 32-bit integer data type is required, there's no compile-time
00010  * endianness configuration, and the function prototypes match OpenSSL's.
00011  * The primary goals are portability and ease of use.
00012  *
00013  * This implementation is meant to be fast, but not as fast as possible.
00014  * Some known optimizations are not included to reduce source code size
00015  * and avoid compile-time configuration.
00016  */
00017 
00018 #include <string.h>
00019 #include "md5.h"
00020 
00021 
00022 /*
00023  * The basic MD5 functions.
00024  *
00025  * F is optimized compared to its RFC 1321 definition just like in Colin
00026  * Plumb's implementation.
00027  */
00028 #define F(x, y, z)                      ((z) ^ ((x) & ((y) ^ (z))))
00029 #define G(x, y, z)                      ((y) ^ ((z) & ((x) ^ (y))))
00030 #define H(x, y, z)                      ((x) ^ (y) ^ (z))
00031 #define I(x, y, z)                      ((y) ^ ((x) | ~(z)))
00032 
00033 /*
00034  * The MD5 transformation for all four rounds.
00035  */
00036 #define STEP(f, a, b, c, d, x, t, s) \
00037         (a) += f((b), (c), (d)) + (x) + (t); \
00038         (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
00039         (a) += (b);
00040 
00041 /*
00042  * SET reads 4 input bytes in little-endian byte order and stores them
00043  * in a properly aligned word in host byte order.
00044  *
00045  * The check for little-endian architectures which tolerate unaligned
00046  * memory accesses is just an optimization.  Nothing will break if it
00047  * doesn't work.
00048  */
00049 #if defined(__i386__) || defined(__vax__)
00050 #define SET(n) \
00051         (*(MD5_u32plus *)&ptr[(n) * 4])
00052 #define GET(n) \
00053         SET(n)
00054 #else
00055 #define SET(n) \
00056         (ctx->block[(n)] = \
00057         (MD5_u32plus)ptr[(n) * 4] | \
00058         ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
00059         ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
00060         ((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
00061 #define GET(n) \
00062         (ctx->block[(n)])
00063 #endif
00064 
00065 /*
00066  * This processes one or more 64-byte data blocks, but does NOT update
00067  * the bit counters.  There're no alignment requirements.
00068  */
00069 static void *body(MD5_CTX *ctx, void *data, unsigned long size)
00070 {
00071         unsigned char *ptr;
00072         MD5_u32plus a, b, c, d;
00073         MD5_u32plus saved_a, saved_b, saved_c, saved_d;
00074 
00075         ptr = data;
00076 
00077         a = ctx->a;
00078         b = ctx->b;
00079         c = ctx->c;
00080         d = ctx->d;
00081 
00082         do {
00083                 saved_a = a;
00084                 saved_b = b;
00085                 saved_c = c;
00086                 saved_d = d;
00087 
00088 /* Round 1 */
00089                 STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
00090                 STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
00091                 STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
00092                 STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
00093                 STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
00094                 STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
00095                 STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
00096                 STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
00097                 STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
00098                 STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
00099                 STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
00100                 STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
00101                 STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
00102                 STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
00103                 STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
00104                 STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
00105 
00106 /* Round 2 */
00107                 STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
00108                 STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
00109                 STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
00110                 STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
00111                 STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
00112                 STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
00113                 STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
00114                 STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
00115                 STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
00116                 STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
00117                 STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
00118                 STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
00119                 STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
00120                 STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
00121                 STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
00122                 STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
00123 
00124 /* Round 3 */
00125                 STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
00126                 STEP(H, d, a, b, c, GET(8), 0x8771f681, 11)
00127                 STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
00128                 STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23)
00129                 STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
00130                 STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11)
00131                 STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
00132                 STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23)
00133                 STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
00134                 STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11)
00135                 STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
00136                 STEP(H, b, c, d, a, GET(6), 0x04881d05, 23)
00137                 STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
00138                 STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11)
00139                 STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
00140                 STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23)
00141 
00142 /* Round 4 */
00143                 STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
00144                 STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
00145                 STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
00146                 STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
00147                 STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
00148                 STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
00149                 STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
00150                 STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
00151                 STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
00152                 STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
00153                 STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
00154                 STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
00155                 STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
00156                 STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
00157                 STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
00158                 STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
00159 
00160                 a += saved_a;
00161                 b += saved_b;
00162                 c += saved_c;
00163                 d += saved_d;
00164 
00165                 ptr += 64;
00166         } while (size -= 64);
00167 
00168         ctx->a = a;
00169         ctx->b = b;
00170         ctx->c = c;
00171         ctx->d = d;
00172 
00173         return ptr;
00174 }
00175 
00176 void sat_MD5_Init(MD5_CTX *ctx)
00177 {
00178         ctx->a = 0x67452301;
00179         ctx->b = 0xefcdab89;
00180         ctx->c = 0x98badcfe;
00181         ctx->d = 0x10325476;
00182 
00183         ctx->lo = 0;
00184         ctx->hi = 0;
00185 }
00186 
00187 void sat_MD5_Update(MD5_CTX *ctx, void *data, unsigned long size)
00188 {
00189         MD5_u32plus saved_lo;
00190         unsigned long used, free;
00191 
00192         saved_lo = ctx->lo;
00193         if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
00194                 ctx->hi++;
00195         ctx->hi += size >> 29;
00196 
00197         used = saved_lo & 0x3f;
00198 
00199         if (used) {
00200                 free = 64 - used;
00201 
00202                 if (size < free) {
00203                         memcpy(&ctx->buffer[used], data, size);
00204                         return;
00205                 }
00206 
00207                 memcpy(&ctx->buffer[used], data, free);
00208                 data = (unsigned char *)data + free;
00209                 size -= free;
00210                 body(ctx, ctx->buffer, 64);
00211         }
00212 
00213         if (size >= 64) {
00214                 data = body(ctx, data, size & ~(unsigned long)0x3f);
00215                 size &= 0x3f;
00216         }
00217 
00218         memcpy(ctx->buffer, data, size);
00219 }
00220 
00221 void sat_MD5_Final(unsigned char *result, MD5_CTX *ctx)
00222 {
00223         unsigned long used, free;
00224 
00225         used = ctx->lo & 0x3f;
00226 
00227         ctx->buffer[used++] = 0x80;
00228 
00229         free = 64 - used;
00230 
00231         if (free < 8) {
00232                 memset(&ctx->buffer[used], 0, free);
00233                 body(ctx, ctx->buffer, 64);
00234                 used = 0;
00235                 free = 64;
00236         }
00237 
00238         memset(&ctx->buffer[used], 0, free - 8);
00239 
00240         ctx->lo <<= 3;
00241         ctx->buffer[56] = ctx->lo;
00242         ctx->buffer[57] = ctx->lo >> 8;
00243         ctx->buffer[58] = ctx->lo >> 16;
00244         ctx->buffer[59] = ctx->lo >> 24;
00245         ctx->buffer[60] = ctx->hi;
00246         ctx->buffer[61] = ctx->hi >> 8;
00247         ctx->buffer[62] = ctx->hi >> 16;
00248         ctx->buffer[63] = ctx->hi >> 24;
00249 
00250         body(ctx, ctx->buffer, 64);
00251 
00252         result[0] = ctx->a;
00253         result[1] = ctx->a >> 8;
00254         result[2] = ctx->a >> 16;
00255         result[3] = ctx->a >> 24;
00256         result[4] = ctx->b;
00257         result[5] = ctx->b >> 8;
00258         result[6] = ctx->b >> 16;
00259         result[7] = ctx->b >> 24;
00260         result[8] = ctx->c;
00261         result[9] = ctx->c >> 8;
00262         result[10] = ctx->c >> 16;
00263         result[11] = ctx->c >> 24;
00264         result[12] = ctx->d;
00265         result[13] = ctx->d >> 8;
00266         result[14] = ctx->d >> 16;
00267         result[15] = ctx->d >> 24;
00268 
00269         memset(ctx, 0, sizeof(ctx));
00270 }
Generated on Mon Dec 12 11:44:12 2011 for satsolver by  doxygen 1.6.3