satsolver 0.16.3
|
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 }