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
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "postgres.h"
00035
00036 #include <sys/param.h>
00037
00038 #include "md5.h"
00039
00040 #define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))
00041
00042 #define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
00043 #define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))
00044 #define H(X, Y, Z) ((X) ^ (Y) ^ (Z))
00045 #define I(X, Y, Z) ((Y) ^ ((X) | (~Z)))
00046
00047 #define ROUND1(a, b, c, d, k, s, i) \
00048 do { \
00049 (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \
00050 (a) = SHIFT((a), (s)); \
00051 (a) = (b) + (a); \
00052 } while (0)
00053
00054 #define ROUND2(a, b, c, d, k, s, i) \
00055 do { \
00056 (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \
00057 (a) = SHIFT((a), (s)); \
00058 (a) = (b) + (a); \
00059 } while (0)
00060
00061 #define ROUND3(a, b, c, d, k, s, i) \
00062 do { \
00063 (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \
00064 (a) = SHIFT((a), (s)); \
00065 (a) = (b) + (a); \
00066 } while (0)
00067
00068 #define ROUND4(a, b, c, d, k, s, i) \
00069 do { \
00070 (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \
00071 (a) = SHIFT((a), (s)); \
00072 (a) = (b) + (a); \
00073 } while (0)
00074
00075 #define Sa 7
00076 #define Sb 12
00077 #define Sc 17
00078 #define Sd 22
00079
00080 #define Se 5
00081 #define Sf 9
00082 #define Sg 14
00083 #define Sh 20
00084
00085 #define Si 4
00086 #define Sj 11
00087 #define Sk 16
00088 #define Sl 23
00089
00090 #define Sm 6
00091 #define Sn 10
00092 #define So 15
00093 #define Sp 21
00094
00095 #define MD5_A0 0x67452301
00096 #define MD5_B0 0xefcdab89
00097 #define MD5_C0 0x98badcfe
00098 #define MD5_D0 0x10325476
00099
00100
00101 static const uint32 T[65] = {
00102 0,
00103 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
00104 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
00105 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
00106 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
00107
00108 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
00109 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
00110 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
00111 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
00112
00113 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
00114 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
00115 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
00116 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
00117
00118 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
00119 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
00120 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
00121 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
00122 };
00123
00124 static const uint8 md5_paddat[MD5_BUFLEN] = {
00125 0x80, 0, 0, 0, 0, 0, 0, 0,
00126 0, 0, 0, 0, 0, 0, 0, 0,
00127 0, 0, 0, 0, 0, 0, 0, 0,
00128 0, 0, 0, 0, 0, 0, 0, 0,
00129 0, 0, 0, 0, 0, 0, 0, 0,
00130 0, 0, 0, 0, 0, 0, 0, 0,
00131 0, 0, 0, 0, 0, 0, 0, 0,
00132 0, 0, 0, 0, 0, 0, 0, 0,
00133 };
00134
00135 static void md5_calc(uint8 *, md5_ctxt *);
00136
00137 void
00138 md5_init(md5_ctxt *ctxt)
00139 {
00140 ctxt->md5_n = 0;
00141 ctxt->md5_i = 0;
00142 ctxt->md5_sta = MD5_A0;
00143 ctxt->md5_stb = MD5_B0;
00144 ctxt->md5_stc = MD5_C0;
00145 ctxt->md5_std = MD5_D0;
00146 memset(ctxt->md5_buf, 0, sizeof(ctxt->md5_buf));
00147 }
00148
00149 void
00150 md5_loop(md5_ctxt *ctxt, const uint8 *input, unsigned len)
00151 {
00152 unsigned int gap,
00153 i;
00154
00155 ctxt->md5_n += len * 8;
00156 gap = MD5_BUFLEN - ctxt->md5_i;
00157
00158 if (len >= gap)
00159 {
00160 memmove(ctxt->md5_buf + ctxt->md5_i, input, gap);
00161 md5_calc(ctxt->md5_buf, ctxt);
00162
00163 for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN)
00164 md5_calc((uint8 *) (input + i), ctxt);
00165
00166 ctxt->md5_i = len - i;
00167 memmove(ctxt->md5_buf, input + i, ctxt->md5_i);
00168 }
00169 else
00170 {
00171 memmove(ctxt->md5_buf + ctxt->md5_i, input, len);
00172 ctxt->md5_i += len;
00173 }
00174 }
00175
00176 void
00177 md5_pad(md5_ctxt *ctxt)
00178 {
00179 unsigned int gap;
00180
00181
00182 gap = MD5_BUFLEN - ctxt->md5_i;
00183 if (gap > 8)
00184 {
00185 memmove(ctxt->md5_buf + ctxt->md5_i, md5_paddat,
00186 gap - sizeof(ctxt->md5_n));
00187 }
00188 else
00189 {
00190
00191 memmove(ctxt->md5_buf + ctxt->md5_i, md5_paddat, gap);
00192 md5_calc(ctxt->md5_buf, ctxt);
00193 memmove(ctxt->md5_buf, md5_paddat + gap,
00194 MD5_BUFLEN - sizeof(ctxt->md5_n));
00195 }
00196
00197
00198 #ifndef WORDS_BIGENDIAN
00199 memmove(&ctxt->md5_buf[56], &ctxt->md5_n8[0], 8);
00200 #else
00201 ctxt->md5_buf[56] = ctxt->md5_n8[7];
00202 ctxt->md5_buf[57] = ctxt->md5_n8[6];
00203 ctxt->md5_buf[58] = ctxt->md5_n8[5];
00204 ctxt->md5_buf[59] = ctxt->md5_n8[4];
00205 ctxt->md5_buf[60] = ctxt->md5_n8[3];
00206 ctxt->md5_buf[61] = ctxt->md5_n8[2];
00207 ctxt->md5_buf[62] = ctxt->md5_n8[1];
00208 ctxt->md5_buf[63] = ctxt->md5_n8[0];
00209 #endif
00210
00211 md5_calc(ctxt->md5_buf, ctxt);
00212 }
00213
00214 void
00215 md5_result(uint8 *digest, md5_ctxt *ctxt)
00216 {
00217
00218 #ifndef WORDS_BIGENDIAN
00219 memmove(digest, &ctxt->md5_st8[0], 16);
00220 #else
00221 digest[0] = ctxt->md5_st8[3];
00222 digest[1] = ctxt->md5_st8[2];
00223 digest[2] = ctxt->md5_st8[1];
00224 digest[3] = ctxt->md5_st8[0];
00225 digest[4] = ctxt->md5_st8[7];
00226 digest[5] = ctxt->md5_st8[6];
00227 digest[6] = ctxt->md5_st8[5];
00228 digest[7] = ctxt->md5_st8[4];
00229 digest[8] = ctxt->md5_st8[11];
00230 digest[9] = ctxt->md5_st8[10];
00231 digest[10] = ctxt->md5_st8[9];
00232 digest[11] = ctxt->md5_st8[8];
00233 digest[12] = ctxt->md5_st8[15];
00234 digest[13] = ctxt->md5_st8[14];
00235 digest[14] = ctxt->md5_st8[13];
00236 digest[15] = ctxt->md5_st8[12];
00237 #endif
00238 }
00239
00240 #ifdef WORDS_BIGENDIAN
00241 static uint32 X[16];
00242 #endif
00243
00244 static void
00245 md5_calc(uint8 *b64, md5_ctxt *ctxt)
00246 {
00247 uint32 A = ctxt->md5_sta;
00248 uint32 B = ctxt->md5_stb;
00249 uint32 C = ctxt->md5_stc;
00250 uint32 D = ctxt->md5_std;
00251
00252 #ifndef WORDS_BIGENDIAN
00253 uint32 *X = (uint32 *) b64;
00254 #else
00255
00256
00257 uint8 *y = (uint8 *) X;
00258
00259 y[0] = b64[3];
00260 y[1] = b64[2];
00261 y[2] = b64[1];
00262 y[3] = b64[0];
00263 y[4] = b64[7];
00264 y[5] = b64[6];
00265 y[6] = b64[5];
00266 y[7] = b64[4];
00267 y[8] = b64[11];
00268 y[9] = b64[10];
00269 y[10] = b64[9];
00270 y[11] = b64[8];
00271 y[12] = b64[15];
00272 y[13] = b64[14];
00273 y[14] = b64[13];
00274 y[15] = b64[12];
00275 y[16] = b64[19];
00276 y[17] = b64[18];
00277 y[18] = b64[17];
00278 y[19] = b64[16];
00279 y[20] = b64[23];
00280 y[21] = b64[22];
00281 y[22] = b64[21];
00282 y[23] = b64[20];
00283 y[24] = b64[27];
00284 y[25] = b64[26];
00285 y[26] = b64[25];
00286 y[27] = b64[24];
00287 y[28] = b64[31];
00288 y[29] = b64[30];
00289 y[30] = b64[29];
00290 y[31] = b64[28];
00291 y[32] = b64[35];
00292 y[33] = b64[34];
00293 y[34] = b64[33];
00294 y[35] = b64[32];
00295 y[36] = b64[39];
00296 y[37] = b64[38];
00297 y[38] = b64[37];
00298 y[39] = b64[36];
00299 y[40] = b64[43];
00300 y[41] = b64[42];
00301 y[42] = b64[41];
00302 y[43] = b64[40];
00303 y[44] = b64[47];
00304 y[45] = b64[46];
00305 y[46] = b64[45];
00306 y[47] = b64[44];
00307 y[48] = b64[51];
00308 y[49] = b64[50];
00309 y[50] = b64[49];
00310 y[51] = b64[48];
00311 y[52] = b64[55];
00312 y[53] = b64[54];
00313 y[54] = b64[53];
00314 y[55] = b64[52];
00315 y[56] = b64[59];
00316 y[57] = b64[58];
00317 y[58] = b64[57];
00318 y[59] = b64[56];
00319 y[60] = b64[63];
00320 y[61] = b64[62];
00321 y[62] = b64[61];
00322 y[63] = b64[60];
00323 #endif
00324
00325 ROUND1(A, B, C, D, 0, Sa, 1);
00326 ROUND1(D, A, B, C, 1, Sb, 2);
00327 ROUND1(C, D, A, B, 2, Sc, 3);
00328 ROUND1(B, C, D, A, 3, Sd, 4);
00329 ROUND1(A, B, C, D, 4, Sa, 5);
00330 ROUND1(D, A, B, C, 5, Sb, 6);
00331 ROUND1(C, D, A, B, 6, Sc, 7);
00332 ROUND1(B, C, D, A, 7, Sd, 8);
00333 ROUND1(A, B, C, D, 8, Sa, 9);
00334 ROUND1(D, A, B, C, 9, Sb, 10);
00335 ROUND1(C, D, A, B, 10, Sc, 11);
00336 ROUND1(B, C, D, A, 11, Sd, 12);
00337 ROUND1(A, B, C, D, 12, Sa, 13);
00338 ROUND1(D, A, B, C, 13, Sb, 14);
00339 ROUND1(C, D, A, B, 14, Sc, 15);
00340 ROUND1(B, C, D, A, 15, Sd, 16);
00341
00342 ROUND2(A, B, C, D, 1, Se, 17);
00343 ROUND2(D, A, B, C, 6, Sf, 18);
00344 ROUND2(C, D, A, B, 11, Sg, 19);
00345 ROUND2(B, C, D, A, 0, Sh, 20);
00346 ROUND2(A, B, C, D, 5, Se, 21);
00347 ROUND2(D, A, B, C, 10, Sf, 22);
00348 ROUND2(C, D, A, B, 15, Sg, 23);
00349 ROUND2(B, C, D, A, 4, Sh, 24);
00350 ROUND2(A, B, C, D, 9, Se, 25);
00351 ROUND2(D, A, B, C, 14, Sf, 26);
00352 ROUND2(C, D, A, B, 3, Sg, 27);
00353 ROUND2(B, C, D, A, 8, Sh, 28);
00354 ROUND2(A, B, C, D, 13, Se, 29);
00355 ROUND2(D, A, B, C, 2, Sf, 30);
00356 ROUND2(C, D, A, B, 7, Sg, 31);
00357 ROUND2(B, C, D, A, 12, Sh, 32);
00358
00359 ROUND3(A, B, C, D, 5, Si, 33);
00360 ROUND3(D, A, B, C, 8, Sj, 34);
00361 ROUND3(C, D, A, B, 11, Sk, 35);
00362 ROUND3(B, C, D, A, 14, Sl, 36);
00363 ROUND3(A, B, C, D, 1, Si, 37);
00364 ROUND3(D, A, B, C, 4, Sj, 38);
00365 ROUND3(C, D, A, B, 7, Sk, 39);
00366 ROUND3(B, C, D, A, 10, Sl, 40);
00367 ROUND3(A, B, C, D, 13, Si, 41);
00368 ROUND3(D, A, B, C, 0, Sj, 42);
00369 ROUND3(C, D, A, B, 3, Sk, 43);
00370 ROUND3(B, C, D, A, 6, Sl, 44);
00371 ROUND3(A, B, C, D, 9, Si, 45);
00372 ROUND3(D, A, B, C, 12, Sj, 46);
00373 ROUND3(C, D, A, B, 15, Sk, 47);
00374 ROUND3(B, C, D, A, 2, Sl, 48);
00375
00376 ROUND4(A, B, C, D, 0, Sm, 49);
00377 ROUND4(D, A, B, C, 7, Sn, 50);
00378 ROUND4(C, D, A, B, 14, So, 51);
00379 ROUND4(B, C, D, A, 5, Sp, 52);
00380 ROUND4(A, B, C, D, 12, Sm, 53);
00381 ROUND4(D, A, B, C, 3, Sn, 54);
00382 ROUND4(C, D, A, B, 10, So, 55);
00383 ROUND4(B, C, D, A, 1, Sp, 56);
00384 ROUND4(A, B, C, D, 8, Sm, 57);
00385 ROUND4(D, A, B, C, 15, Sn, 58);
00386 ROUND4(C, D, A, B, 6, So, 59);
00387 ROUND4(B, C, D, A, 13, Sp, 60);
00388 ROUND4(A, B, C, D, 4, Sm, 61);
00389 ROUND4(D, A, B, C, 11, Sn, 62);
00390 ROUND4(C, D, A, B, 2, So, 63);
00391 ROUND4(B, C, D, A, 9, Sp, 64);
00392
00393 ctxt->md5_sta += A;
00394 ctxt->md5_stb += B;
00395 ctxt->md5_stc += C;
00396 ctxt->md5_std += D;
00397 }