00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00031 #include "stdinc.h"
00032
00033 #include "md5.h"
00034
00038 static inline void
00039 md5_encode(uint32_t dst[4], const uint32_t src[4])
00040 {
00041 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
00042 memcpy(dst, src, 16);
00043 #else
00044 size_t i;
00045
00046
00047 for (i = 0; i < 4; i++)
00048 dst[i] = GUINT32_TO_LE(src[i]);
00049 #endif
00050 }
00051
00055 static inline void
00056 md5_decode(uint32_t buf[16])
00057 {
00058 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
00059 size_t i;
00060
00061
00062 for (i = 0; i < 16; i++)
00063 buf[i] = GUINT32_FROM_LE(buf[i]);
00064 #endif
00065 }
00066
00070 #define md5_f(x, y, z) (z ^ (x & (y ^ z)))
00071
00074 #define md5_g(x, y, z) (y ^ (z & (x ^ y)))
00075
00078 #define md5_h(x, y, z) (x ^ y ^ z)
00079
00082 #define md5_i(x, y, z) (y ^ (x | ~z))
00083
00087 #define md5_step(f, w, x, y, z, d, s) do { \
00088 w += f(x, y, z) + d; \
00089 w = (w << s) | (w >> (32 - s)); \
00090 w += x; \
00091 } while(0)
00092
00096 static void
00097 md5_transform(uint32_t state[4], const uint32_t buf[16])
00098 {
00099 uint32_t a, b, c, d;
00100
00101 a = state[0];
00102 b = state[1];
00103 c = state[2];
00104 d = state[3];
00105
00106 md5_step(md5_f, a, b, c, d, buf[0] + 0xd76aa478, 7);
00107 md5_step(md5_f, d, a, b, c, buf[1] + 0xe8c7b756, 12);
00108 md5_step(md5_f, c, d, a, b, buf[2] + 0x242070db, 17);
00109 md5_step(md5_f, b, c, d, a, buf[3] + 0xc1bdceee, 22);
00110 md5_step(md5_f, a, b, c, d, buf[4] + 0xf57c0faf, 7);
00111 md5_step(md5_f, d, a, b, c, buf[5] + 0x4787c62a, 12);
00112 md5_step(md5_f, c, d, a, b, buf[6] + 0xa8304613, 17);
00113 md5_step(md5_f, b, c, d, a, buf[7] + 0xfd469501, 22);
00114 md5_step(md5_f, a, b, c, d, buf[8] + 0x698098d8, 7);
00115 md5_step(md5_f, d, a, b, c, buf[9] + 0x8b44f7af, 12);
00116 md5_step(md5_f, c, d, a, b, buf[10] + 0xffff5bb1, 17);
00117 md5_step(md5_f, b, c, d, a, buf[11] + 0x895cd7be, 22);
00118 md5_step(md5_f, a, b, c, d, buf[12] + 0x6b901122, 7);
00119 md5_step(md5_f, d, a, b, c, buf[13] + 0xfd987193, 12);
00120 md5_step(md5_f, c, d, a, b, buf[14] + 0xa679438e, 17);
00121 md5_step(md5_f, b, c, d, a, buf[15] + 0x49b40821, 22);
00122
00123 md5_step(md5_g, a, b, c, d, buf[1] + 0xf61e2562, 5);
00124 md5_step(md5_g, d, a, b, c, buf[6] + 0xc040b340, 9);
00125 md5_step(md5_g, c, d, a, b, buf[11] + 0x265e5a51, 14);
00126 md5_step(md5_g, b, c, d, a, buf[0] + 0xe9b6c7aa, 20);
00127 md5_step(md5_g, a, b, c, d, buf[5] + 0xd62f105d, 5);
00128 md5_step(md5_g, d, a, b, c, buf[10] + 0x02441453, 9);
00129 md5_step(md5_g, c, d, a, b, buf[15] + 0xd8a1e681, 14);
00130 md5_step(md5_g, b, c, d, a, buf[4] + 0xe7d3fbc8, 20);
00131 md5_step(md5_g, a, b, c, d, buf[9] + 0x21e1cde6, 5);
00132 md5_step(md5_g, d, a, b, c, buf[14] + 0xc33707d6, 9);
00133 md5_step(md5_g, c, d, a, b, buf[3] + 0xf4d50d87, 14);
00134 md5_step(md5_g, b, c, d, a, buf[8] + 0x455a14ed, 20);
00135 md5_step(md5_g, a, b, c, d, buf[13] + 0xa9e3e905, 5);
00136 md5_step(md5_g, d, a, b, c, buf[2] + 0xfcefa3f8, 9);
00137 md5_step(md5_g, c, d, a, b, buf[7] + 0x676f02d9, 14);
00138 md5_step(md5_g, b, c, d, a, buf[12] + 0x8d2a4c8a, 20);
00139
00140 md5_step(md5_h, a, b, c, d, buf[5] + 0xfffa3942, 4);
00141 md5_step(md5_h, d, a, b, c, buf[8] + 0x8771f681, 11);
00142 md5_step(md5_h, c, d, a, b, buf[11] + 0x6d9d6122, 16);
00143 md5_step(md5_h, b, c, d, a, buf[14] + 0xfde5380c, 23);
00144 md5_step(md5_h, a, b, c, d, buf[1] + 0xa4beea44, 4);
00145 md5_step(md5_h, d, a, b, c, buf[4] + 0x4bdecfa9, 11);
00146 md5_step(md5_h, c, d, a, b, buf[7] + 0xf6bb4b60, 16);
00147 md5_step(md5_h, b, c, d, a, buf[10] + 0xbebfbc70, 23);
00148 md5_step(md5_h, a, b, c, d, buf[13] + 0x289b7ec6, 4);
00149 md5_step(md5_h, d, a, b, c, buf[0] + 0xeaa127fa, 11);
00150 md5_step(md5_h, c, d, a, b, buf[3] + 0xd4ef3085, 16);
00151 md5_step(md5_h, b, c, d, a, buf[6] + 0x04881d05, 23);
00152 md5_step(md5_h, a, b, c, d, buf[9] + 0xd9d4d039, 4);
00153 md5_step(md5_h, d, a, b, c, buf[12] + 0xe6db99e5, 11);
00154 md5_step(md5_h, c, d, a, b, buf[15] + 0x1fa27cf8, 16);
00155 md5_step(md5_h, b, c, d, a, buf[2] + 0xc4ac5665, 23);
00156
00157 md5_step(md5_i, a, b, c, d, buf[0] + 0xf4292244, 6);
00158 md5_step(md5_i, d, a, b, c, buf[7] + 0x432aff97, 10);
00159 md5_step(md5_i, c, d, a, b, buf[14] + 0xab9423a7, 15);
00160 md5_step(md5_i, b, c, d, a, buf[5] + 0xfc93a039, 21);
00161 md5_step(md5_i, a, b, c, d, buf[12] + 0x655b59c3, 6);
00162 md5_step(md5_i, d, a, b, c, buf[3] + 0x8f0ccc92, 10);
00163 md5_step(md5_i, c, d, a, b, buf[10] + 0xffeff47d, 15);
00164 md5_step(md5_i, b, c, d, a, buf[1] + 0x85845dd1, 21);
00165 md5_step(md5_i, a, b, c, d, buf[8] + 0x6fa87e4f, 6);
00166 md5_step(md5_i, d, a, b, c, buf[15] + 0xfe2ce6e0, 10);
00167 md5_step(md5_i, c, d, a, b, buf[6] + 0xa3014314, 15);
00168 md5_step(md5_i, b, c, d, a, buf[13] + 0x4e0811a1, 21);
00169 md5_step(md5_i, a, b, c, d, buf[4] + 0xf7537e82, 6);
00170 md5_step(md5_i, d, a, b, c, buf[11] + 0xbd3af235, 10);
00171 md5_step(md5_i, c, d, a, b, buf[2] + 0x2ad7d2bb, 15);
00172 md5_step(md5_i, b, c, d, a, buf[9] + 0xeb86d391, 21);
00173
00174 state[0] += a;
00175 state[1] += b;
00176 state[2] += c;
00177 state[3] += d;
00178 }
00179
00180 void
00181 md5_update(struct md5_context *m, const void *buf, size_t len)
00182 {
00183 unsigned char *b, *ib;
00184 size_t blen, left, clen;
00185
00186
00187 b = (unsigned char *)m->buf;
00188 blen = m->count & 0x3f;
00189 m->count += len;
00190 ib = (unsigned char *)buf;
00191
00192
00193 if (blen != 0) {
00194
00195 left = 64 - blen;
00196
00197 clen = MIN(left, len);
00198
00199 memcpy(b + blen, ib, clen);
00200
00201 if (len < left)
00202 return;
00203
00204 md5_decode(m->buf);
00205 md5_transform(m->state, m->buf);
00206 ib += clen;
00207 len -= clen;
00208 }
00209
00210
00211 while (len >= 64) {
00212 memcpy(m->buf, ib, 64);
00213 md5_decode(m->buf);
00214 md5_transform(m->state, m->buf);
00215 ib += 64;
00216 len -= 64;
00217 }
00218
00219
00220 memcpy(m->buf, ib, len);
00221 }
00222
00223 void
00224 md5_final(struct md5_context *m, unsigned char out[16])
00225 {
00226 unsigned char *b;
00227 size_t blen;
00228
00229
00230 b = (unsigned char *)m->buf;
00231 blen = m->count & 0x3f;
00232 b[blen++] = 0x80;
00233
00234 if (blen > 56) {
00235
00236 memset(b + blen, 0, 64 - blen);
00237 md5_decode(m->buf);
00238 md5_transform(m->state, m->buf);
00239
00240
00241 memset(b, 0, 56);
00242 } else {
00243
00244 memset(b + blen, 0, 56 - blen);
00245 md5_decode(m->buf);
00246 }
00247
00248
00249 m->buf[14] = m->count << 3;
00250 m->buf[15] = m->count >> 29;
00251 md5_transform(m->state, m->buf);
00252
00253
00254 md5_encode((uint32_t *)out, m->state);
00255 memset(m, 0, sizeof(struct md5_context));
00256 }