00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 #include <string.h>
00019 #include "md5.h"
00020 
00021 
00022 
00023 
00024 
00025 
00026 
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 
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 
00043 
00044 
00045 
00046 
00047 
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 
00067 
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 
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 
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 
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 
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 }