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 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
00028 #define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
00029 #define H(x, y, z) ((x) ^ (y) ^ (z))
00030 #define I(x, y, z) ((y) ^ ((x) | ~(z)))
00031
00032
00033
00034
00035 #define STEP(f, a, b, c, d, x, t, s) \
00036 (a) += f((b), (c), (d)) + (x) + (t); \
00037 (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
00038 (a) += (b);
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #if defined(__i386__) || defined(__vax__)
00049 #define SET(n) \
00050 (*(MD5_u32plus *)&ptr[(n) * 4])
00051 #define GET(n) \
00052 SET(n)
00053 #else
00054 #define SET(n) \
00055 (ctx->block[(n)] = \
00056 (MD5_u32plus)ptr[(n) * 4] | \
00057 ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
00058 ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
00059 ((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
00060 #define GET(n) \
00061 (ctx->block[(n)])
00062 #endif
00063
00064
00065
00066
00067
00068 static void *body(MD5_CTX *ctx, void *data, unsigned long size)
00069 {
00070 unsigned char *ptr;
00071 MD5_u32plus a, b, c, d;
00072 MD5_u32plus saved_a, saved_b, saved_c, saved_d;
00073
00074 ptr = data;
00075
00076 a = ctx->a;
00077 b = ctx->b;
00078 c = ctx->c;
00079 d = ctx->d;
00080
00081 do {
00082 saved_a = a;
00083 saved_b = b;
00084 saved_c = c;
00085 saved_d = d;
00086
00087
00088 STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
00089 STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
00090 STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
00091 STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
00092 STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
00093 STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
00094 STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
00095 STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
00096 STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
00097 STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
00098 STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
00099 STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
00100 STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
00101 STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
00102 STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
00103 STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
00104
00105
00106 STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
00107 STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
00108 STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
00109 STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
00110 STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
00111 STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
00112 STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
00113 STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
00114 STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
00115 STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
00116 STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
00117 STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
00118 STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
00119 STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
00120 STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
00121 STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
00122
00123
00124 STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
00125 STEP(H, d, a, b, c, GET(8), 0x8771f681, 11)
00126 STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
00127 STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23)
00128 STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
00129 STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11)
00130 STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
00131 STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23)
00132 STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
00133 STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11)
00134 STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
00135 STEP(H, b, c, d, a, GET(6), 0x04881d05, 23)
00136 STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
00137 STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11)
00138 STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
00139 STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23)
00140
00141
00142 STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
00143 STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
00144 STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
00145 STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
00146 STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
00147 STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
00148 STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
00149 STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
00150 STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
00151 STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
00152 STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
00153 STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
00154 STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
00155 STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
00156 STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
00157 STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
00158
00159 a += saved_a;
00160 b += saved_b;
00161 c += saved_c;
00162 d += saved_d;
00163
00164 ptr += 64;
00165 } while (size -= 64);
00166
00167 ctx->a = a;
00168 ctx->b = b;
00169 ctx->c = c;
00170 ctx->d = d;
00171
00172 return ptr;
00173 }
00174
00175 void MD5_Init(MD5_CTX *ctx)
00176 {
00177 ctx->a = 0x67452301;
00178 ctx->b = 0xefcdab89;
00179 ctx->c = 0x98badcfe;
00180 ctx->d = 0x10325476;
00181
00182 ctx->lo = 0;
00183 ctx->hi = 0;
00184 }
00185
00186 void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size)
00187 {
00188 MD5_u32plus saved_lo;
00189 unsigned long used, free;
00190
00191 saved_lo = ctx->lo;
00192 if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
00193 ctx->hi++;
00194 ctx->hi += size >> 29;
00195
00196 used = saved_lo & 0x3f;
00197
00198 if (used) {
00199 free = 64 - used;
00200
00201 if (size < free) {
00202 memcpy(&ctx->buffer[used], data, size);
00203 return;
00204 }
00205
00206 memcpy(&ctx->buffer[used], data, free);
00207 data = (unsigned char *)data + free;
00208 size -= free;
00209 body(ctx, ctx->buffer, 64);
00210 }
00211
00212 if (size >= 64) {
00213 data = body(ctx, data, size & ~(unsigned long)0x3f);
00214 size &= 0x3f;
00215 }
00216
00217 memcpy(ctx->buffer, data, size);
00218 }
00219
00220 void MD5_Final(unsigned char *result, MD5_CTX *ctx)
00221 {
00222 unsigned long used, free;
00223
00224 used = ctx->lo & 0x3f;
00225
00226 ctx->buffer[used++] = 0x80;
00227
00228 free = 64 - used;
00229
00230 if (free < 8) {
00231 memset(&ctx->buffer[used], 0, free);
00232 body(ctx, ctx->buffer, 64);
00233 used = 0;
00234 free = 64;
00235 }
00236
00237 memset(&ctx->buffer[used], 0, free - 8);
00238
00239 ctx->lo <<= 3;
00240 ctx->buffer[56] = ctx->lo;
00241 ctx->buffer[57] = ctx->lo >> 8;
00242 ctx->buffer[58] = ctx->lo >> 16;
00243 ctx->buffer[59] = ctx->lo >> 24;
00244 ctx->buffer[60] = ctx->hi;
00245 ctx->buffer[61] = ctx->hi >> 8;
00246 ctx->buffer[62] = ctx->hi >> 16;
00247 ctx->buffer[63] = ctx->hi >> 24;
00248
00249 body(ctx, ctx->buffer, 64);
00250
00251 result[0] = ctx->a;
00252 result[1] = ctx->a >> 8;
00253 result[2] = ctx->a >> 16;
00254 result[3] = ctx->a >> 24;
00255 result[4] = ctx->b;
00256 result[5] = ctx->b >> 8;
00257 result[6] = ctx->b >> 16;
00258 result[7] = ctx->b >> 24;
00259 result[8] = ctx->c;
00260 result[9] = ctx->c >> 8;
00261 result[10] = ctx->c >> 16;
00262 result[11] = ctx->c >> 24;
00263 result[12] = ctx->d;
00264 result[13] = ctx->d >> 8;
00265 result[14] = ctx->d >> 16;
00266 result[15] = ctx->d >> 24;
00267
00268 memset(ctx, 0, sizeof(ctx));
00269 }
00270
00271
00272
00273
00274
00275
00276
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295