Only skip pages marked as clean in the visibility map, if the last 32
[PostgreSQL.git] / contrib / pgcrypto / md5.c
blobf69cd05b234416356c2c17dbe4bca70beb4f8890
1 /* $KAME$ */
3 /*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
31 * $PostgreSQL$
34 #include "postgres.h"
36 #include <sys/param.h>
38 #include "px.h"
39 #include "md5.h"
41 #define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))
43 #define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
44 #define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))
45 #define H(X, Y, Z) ((X) ^ (Y) ^ (Z))
46 #define I(X, Y, Z) ((Y) ^ ((X) | (~Z)))
48 #define ROUND1(a, b, c, d, k, s, i) \
49 do { \
50 (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \
51 (a) = SHIFT((a), (s)); \
52 (a) = (b) + (a); \
53 } while (0)
55 #define ROUND2(a, b, c, d, k, s, i) \
56 do { \
57 (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \
58 (a) = SHIFT((a), (s)); \
59 (a) = (b) + (a); \
60 } while (0)
62 #define ROUND3(a, b, c, d, k, s, i) \
63 do { \
64 (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \
65 (a) = SHIFT((a), (s)); \
66 (a) = (b) + (a); \
67 } while (0)
69 #define ROUND4(a, b, c, d, k, s, i) \
70 do { \
71 (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \
72 (a) = SHIFT((a), (s)); \
73 (a) = (b) + (a); \
74 } while (0)
76 #define Sa 7
77 #define Sb 12
78 #define Sc 17
79 #define Sd 22
81 #define Se 5
82 #define Sf 9
83 #define Sg 14
84 #define Sh 20
86 #define Si 4
87 #define Sj 11
88 #define Sk 16
89 #define Sl 23
91 #define Sm 6
92 #define Sn 10
93 #define So 15
94 #define Sp 21
96 #define MD5_A0 0x67452301
97 #define MD5_B0 0xefcdab89
98 #define MD5_C0 0x98badcfe
99 #define MD5_D0 0x10325476
101 /* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */
102 static const uint32 T[65] = {
104 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
105 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
106 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
107 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
109 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
110 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
111 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
112 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
114 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
115 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
116 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
117 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
119 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
120 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
121 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
122 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
125 static const uint8 md5_paddat[MD5_BUFLEN] = {
126 0x80, 0, 0, 0, 0, 0, 0, 0,
127 0, 0, 0, 0, 0, 0, 0, 0,
128 0, 0, 0, 0, 0, 0, 0, 0,
129 0, 0, 0, 0, 0, 0, 0, 0,
130 0, 0, 0, 0, 0, 0, 0, 0,
131 0, 0, 0, 0, 0, 0, 0, 0,
132 0, 0, 0, 0, 0, 0, 0, 0,
133 0, 0, 0, 0, 0, 0, 0, 0,
136 static void md5_calc(uint8 *, md5_ctxt *);
138 void
139 md5_init(md5_ctxt * ctxt)
141 ctxt->md5_n = 0;
142 ctxt->md5_i = 0;
143 ctxt->md5_sta = MD5_A0;
144 ctxt->md5_stb = MD5_B0;
145 ctxt->md5_stc = MD5_C0;
146 ctxt->md5_std = MD5_D0;
147 memset(ctxt->md5_buf, 0, sizeof(ctxt->md5_buf));
150 void
151 md5_loop(md5_ctxt * ctxt, const uint8 *input, unsigned len)
153 unsigned int gap,
156 ctxt->md5_n += len * 8; /* byte to bit */
157 gap = MD5_BUFLEN - ctxt->md5_i;
159 if (len >= gap)
161 memmove(ctxt->md5_buf + ctxt->md5_i, input, gap);
162 md5_calc(ctxt->md5_buf, ctxt);
164 for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN)
165 md5_calc((uint8 *) (input + i), ctxt);
167 ctxt->md5_i = len - i;
168 memmove(ctxt->md5_buf, input + i, ctxt->md5_i);
170 else
172 memmove(ctxt->md5_buf + ctxt->md5_i, input, len);
173 ctxt->md5_i += len;
177 void
178 md5_pad(md5_ctxt * ctxt)
180 unsigned int gap;
182 /* Don't count up padding. Keep md5_n. */
183 gap = MD5_BUFLEN - ctxt->md5_i;
184 if (gap > 8)
186 memmove(ctxt->md5_buf + ctxt->md5_i, md5_paddat,
187 gap - sizeof(ctxt->md5_n));
189 else
191 /* including gap == 8 */
192 memmove(ctxt->md5_buf + ctxt->md5_i, md5_paddat, gap);
193 md5_calc(ctxt->md5_buf, ctxt);
194 memmove(ctxt->md5_buf, md5_paddat + gap,
195 MD5_BUFLEN - sizeof(ctxt->md5_n));
198 /* 8 byte word */
199 #ifndef WORDS_BIGENDIAN
200 memmove(&ctxt->md5_buf[56], &ctxt->md5_n8[0], 8);
201 #else
202 ctxt->md5_buf[56] = ctxt->md5_n8[7];
203 ctxt->md5_buf[57] = ctxt->md5_n8[6];
204 ctxt->md5_buf[58] = ctxt->md5_n8[5];
205 ctxt->md5_buf[59] = ctxt->md5_n8[4];
206 ctxt->md5_buf[60] = ctxt->md5_n8[3];
207 ctxt->md5_buf[61] = ctxt->md5_n8[2];
208 ctxt->md5_buf[62] = ctxt->md5_n8[1];
209 ctxt->md5_buf[63] = ctxt->md5_n8[0];
210 #endif
212 md5_calc(ctxt->md5_buf, ctxt);
215 void
216 md5_result(uint8 *digest, md5_ctxt * ctxt)
218 /* 4 byte words */
219 #ifndef WORDS_BIGENDIAN
220 memmove(digest, &ctxt->md5_st8[0], 16);
221 #else
222 digest[0] = ctxt->md5_st8[3];
223 digest[1] = ctxt->md5_st8[2];
224 digest[2] = ctxt->md5_st8[1];
225 digest[3] = ctxt->md5_st8[0];
226 digest[4] = ctxt->md5_st8[7];
227 digest[5] = ctxt->md5_st8[6];
228 digest[6] = ctxt->md5_st8[5];
229 digest[7] = ctxt->md5_st8[4];
230 digest[8] = ctxt->md5_st8[11];
231 digest[9] = ctxt->md5_st8[10];
232 digest[10] = ctxt->md5_st8[9];
233 digest[11] = ctxt->md5_st8[8];
234 digest[12] = ctxt->md5_st8[15];
235 digest[13] = ctxt->md5_st8[14];
236 digest[14] = ctxt->md5_st8[13];
237 digest[15] = ctxt->md5_st8[12];
238 #endif
241 #ifdef WORDS_BIGENDIAN
242 static uint32 X[16];
243 #endif
245 static void
246 md5_calc(uint8 *b64, md5_ctxt * ctxt)
248 uint32 A = ctxt->md5_sta;
249 uint32 B = ctxt->md5_stb;
250 uint32 C = ctxt->md5_stc;
251 uint32 D = ctxt->md5_std;
253 #ifndef WORDS_BIGENDIAN
254 uint32 *X = (uint32 *) b64;
255 #else
256 /* 4 byte words */
257 /* what a brute force but fast! */
258 uint8 *y = (uint8 *) X;
260 y[0] = b64[3];
261 y[1] = b64[2];
262 y[2] = b64[1];
263 y[3] = b64[0];
264 y[4] = b64[7];
265 y[5] = b64[6];
266 y[6] = b64[5];
267 y[7] = b64[4];
268 y[8] = b64[11];
269 y[9] = b64[10];
270 y[10] = b64[9];
271 y[11] = b64[8];
272 y[12] = b64[15];
273 y[13] = b64[14];
274 y[14] = b64[13];
275 y[15] = b64[12];
276 y[16] = b64[19];
277 y[17] = b64[18];
278 y[18] = b64[17];
279 y[19] = b64[16];
280 y[20] = b64[23];
281 y[21] = b64[22];
282 y[22] = b64[21];
283 y[23] = b64[20];
284 y[24] = b64[27];
285 y[25] = b64[26];
286 y[26] = b64[25];
287 y[27] = b64[24];
288 y[28] = b64[31];
289 y[29] = b64[30];
290 y[30] = b64[29];
291 y[31] = b64[28];
292 y[32] = b64[35];
293 y[33] = b64[34];
294 y[34] = b64[33];
295 y[35] = b64[32];
296 y[36] = b64[39];
297 y[37] = b64[38];
298 y[38] = b64[37];
299 y[39] = b64[36];
300 y[40] = b64[43];
301 y[41] = b64[42];
302 y[42] = b64[41];
303 y[43] = b64[40];
304 y[44] = b64[47];
305 y[45] = b64[46];
306 y[46] = b64[45];
307 y[47] = b64[44];
308 y[48] = b64[51];
309 y[49] = b64[50];
310 y[50] = b64[49];
311 y[51] = b64[48];
312 y[52] = b64[55];
313 y[53] = b64[54];
314 y[54] = b64[53];
315 y[55] = b64[52];
316 y[56] = b64[59];
317 y[57] = b64[58];
318 y[58] = b64[57];
319 y[59] = b64[56];
320 y[60] = b64[63];
321 y[61] = b64[62];
322 y[62] = b64[61];
323 y[63] = b64[60];
324 #endif
326 ROUND1(A, B, C, D, 0, Sa, 1);
327 ROUND1(D, A, B, C, 1, Sb, 2);
328 ROUND1(C, D, A, B, 2, Sc, 3);
329 ROUND1(B, C, D, A, 3, Sd, 4);
330 ROUND1(A, B, C, D, 4, Sa, 5);
331 ROUND1(D, A, B, C, 5, Sb, 6);
332 ROUND1(C, D, A, B, 6, Sc, 7);
333 ROUND1(B, C, D, A, 7, Sd, 8);
334 ROUND1(A, B, C, D, 8, Sa, 9);
335 ROUND1(D, A, B, C, 9, Sb, 10);
336 ROUND1(C, D, A, B, 10, Sc, 11);
337 ROUND1(B, C, D, A, 11, Sd, 12);
338 ROUND1(A, B, C, D, 12, Sa, 13);
339 ROUND1(D, A, B, C, 13, Sb, 14);
340 ROUND1(C, D, A, B, 14, Sc, 15);
341 ROUND1(B, C, D, A, 15, Sd, 16);
343 ROUND2(A, B, C, D, 1, Se, 17);
344 ROUND2(D, A, B, C, 6, Sf, 18);
345 ROUND2(C, D, A, B, 11, Sg, 19);
346 ROUND2(B, C, D, A, 0, Sh, 20);
347 ROUND2(A, B, C, D, 5, Se, 21);
348 ROUND2(D, A, B, C, 10, Sf, 22);
349 ROUND2(C, D, A, B, 15, Sg, 23);
350 ROUND2(B, C, D, A, 4, Sh, 24);
351 ROUND2(A, B, C, D, 9, Se, 25);
352 ROUND2(D, A, B, C, 14, Sf, 26);
353 ROUND2(C, D, A, B, 3, Sg, 27);
354 ROUND2(B, C, D, A, 8, Sh, 28);
355 ROUND2(A, B, C, D, 13, Se, 29);
356 ROUND2(D, A, B, C, 2, Sf, 30);
357 ROUND2(C, D, A, B, 7, Sg, 31);
358 ROUND2(B, C, D, A, 12, Sh, 32);
360 ROUND3(A, B, C, D, 5, Si, 33);
361 ROUND3(D, A, B, C, 8, Sj, 34);
362 ROUND3(C, D, A, B, 11, Sk, 35);
363 ROUND3(B, C, D, A, 14, Sl, 36);
364 ROUND3(A, B, C, D, 1, Si, 37);
365 ROUND3(D, A, B, C, 4, Sj, 38);
366 ROUND3(C, D, A, B, 7, Sk, 39);
367 ROUND3(B, C, D, A, 10, Sl, 40);
368 ROUND3(A, B, C, D, 13, Si, 41);
369 ROUND3(D, A, B, C, 0, Sj, 42);
370 ROUND3(C, D, A, B, 3, Sk, 43);
371 ROUND3(B, C, D, A, 6, Sl, 44);
372 ROUND3(A, B, C, D, 9, Si, 45);
373 ROUND3(D, A, B, C, 12, Sj, 46);
374 ROUND3(C, D, A, B, 15, Sk, 47);
375 ROUND3(B, C, D, A, 2, Sl, 48);
377 ROUND4(A, B, C, D, 0, Sm, 49);
378 ROUND4(D, A, B, C, 7, Sn, 50);
379 ROUND4(C, D, A, B, 14, So, 51);
380 ROUND4(B, C, D, A, 5, Sp, 52);
381 ROUND4(A, B, C, D, 12, Sm, 53);
382 ROUND4(D, A, B, C, 3, Sn, 54);
383 ROUND4(C, D, A, B, 10, So, 55);
384 ROUND4(B, C, D, A, 1, Sp, 56);
385 ROUND4(A, B, C, D, 8, Sm, 57);
386 ROUND4(D, A, B, C, 15, Sn, 58);
387 ROUND4(C, D, A, B, 6, So, 59);
388 ROUND4(B, C, D, A, 13, Sp, 60);
389 ROUND4(A, B, C, D, 4, Sm, 61);
390 ROUND4(D, A, B, C, 11, Sn, 62);
391 ROUND4(C, D, A, B, 2, So, 63);
392 ROUND4(B, C, D, A, 9, Sp, 64);
394 ctxt->md5_sta += A;
395 ctxt->md5_stb += B;
396 ctxt->md5_stc += C;
397 ctxt->md5_std += D;