1 /* $KAME: md5.c,v 1.3 2000/02/22 14:01:17 itojun Exp $ */
2
3 /*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
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.
18 *
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.
30 *
31 * contrib/pgcrypto/md5.c
32 */
33
34 #include "postgres.h"
35
36 #include <sys/param.h>
37
38 #include "md5.h"
39
40 #define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))
41
42 #define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
43 #define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))
44 #define H(X, Y, Z) ((X) ^ (Y) ^ (Z))
45 #define I(X, Y, Z) ((Y) ^ ((X) | (~Z)))
46
47 #define ROUND1(a, b, c, d, k, s, i) \
48 do { \
49 (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \
50 (a) = SHIFT((a), (s)); \
51 (a) = (b) + (a); \
52 } while (0)
53
54 #define ROUND2(a, b, c, d, k, s, i) \
55 do { \
56 (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \
57 (a) = SHIFT((a), (s)); \
58 (a) = (b) + (a); \
59 } while (0)
60
61 #define ROUND3(a, b, c, d, k, s, i) \
62 do { \
63 (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \
64 (a) = SHIFT((a), (s)); \
65 (a) = (b) + (a); \
66 } while (0)
67
68 #define ROUND4(a, b, c, d, k, s, i) \
69 do { \
70 (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \
71 (a) = SHIFT((a), (s)); \
72 (a) = (b) + (a); \
73 } while (0)
74
75 #define Sa 7
76 #define Sb 12
77 #define Sc 17
78 #define Sd 22
79
80 #define Se 5
81 #define Sf 9
82 #define Sg 14
83 #define Sh 20
84
85 #define Si 4
86 #define Sj 11
87 #define Sk 16
88 #define Sl 23
89
90 #define Sm 6
91 #define Sn 10
92 #define So 15
93 #define Sp 21
94
95 #define MD5_A0 0x67452301
96 #define MD5_B0 0xefcdab89
97 #define MD5_C0 0x98badcfe
98 #define MD5_D0 0x10325476
99
100 /* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */
101 static const uint32 T[65] = {
102 0,
103 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
104 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
105 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
106 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
107
108 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
109 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
110 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
111 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
112
113 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
114 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
115 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
116 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
117
118 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
119 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
120 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
121 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
122 };
123
124 static const uint8 md5_paddat[MD5_BUFLEN] = {
125 0x80, 0, 0, 0, 0, 0, 0, 0,
126 0, 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 };
134
135 static void md5_calc(const uint8 *, md5_ctxt *);
136
137 void
md5_init(md5_ctxt * ctxt)138 md5_init(md5_ctxt *ctxt)
139 {
140 ctxt->md5_n = 0;
141 ctxt->md5_i = 0;
142 ctxt->md5_sta = MD5_A0;
143 ctxt->md5_stb = MD5_B0;
144 ctxt->md5_stc = MD5_C0;
145 ctxt->md5_std = MD5_D0;
146 memset(ctxt->md5_buf, 0, sizeof(ctxt->md5_buf));
147 }
148
149 void
md5_loop(md5_ctxt * ctxt,const uint8 * input,unsigned len)150 md5_loop(md5_ctxt *ctxt, const uint8 *input, unsigned len)
151 {
152 unsigned int gap,
153 i;
154
155 ctxt->md5_n += len * 8; /* byte to bit */
156 gap = MD5_BUFLEN - ctxt->md5_i;
157
158 if (len >= gap)
159 {
160 memmove(ctxt->md5_buf + ctxt->md5_i, input, gap);
161 md5_calc(ctxt->md5_buf, ctxt);
162
163 for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN)
164 md5_calc(input + i, ctxt);
165
166 ctxt->md5_i = len - i;
167 memmove(ctxt->md5_buf, input + i, ctxt->md5_i);
168 }
169 else
170 {
171 memmove(ctxt->md5_buf + ctxt->md5_i, input, len);
172 ctxt->md5_i += len;
173 }
174 }
175
176 void
md5_pad(md5_ctxt * ctxt)177 md5_pad(md5_ctxt *ctxt)
178 {
179 unsigned int gap;
180
181 /* Don't count up padding. Keep md5_n. */
182 gap = MD5_BUFLEN - ctxt->md5_i;
183 if (gap > 8)
184 {
185 memmove(ctxt->md5_buf + ctxt->md5_i, md5_paddat,
186 gap - sizeof(ctxt->md5_n));
187 }
188 else
189 {
190 /* including gap == 8 */
191 memmove(ctxt->md5_buf + ctxt->md5_i, md5_paddat, gap);
192 md5_calc(ctxt->md5_buf, ctxt);
193 memmove(ctxt->md5_buf, md5_paddat + gap,
194 MD5_BUFLEN - sizeof(ctxt->md5_n));
195 }
196
197 /* 8 byte word */
198 #ifndef WORDS_BIGENDIAN
199 memmove(&ctxt->md5_buf[56], &ctxt->md5_n8[0], 8);
200 #else
201 ctxt->md5_buf[56] = ctxt->md5_n8[7];
202 ctxt->md5_buf[57] = ctxt->md5_n8[6];
203 ctxt->md5_buf[58] = ctxt->md5_n8[5];
204 ctxt->md5_buf[59] = ctxt->md5_n8[4];
205 ctxt->md5_buf[60] = ctxt->md5_n8[3];
206 ctxt->md5_buf[61] = ctxt->md5_n8[2];
207 ctxt->md5_buf[62] = ctxt->md5_n8[1];
208 ctxt->md5_buf[63] = ctxt->md5_n8[0];
209 #endif
210
211 md5_calc(ctxt->md5_buf, ctxt);
212 }
213
214 void
md5_result(uint8 * digest,md5_ctxt * ctxt)215 md5_result(uint8 *digest, md5_ctxt *ctxt)
216 {
217 /* 4 byte words */
218 #ifndef WORDS_BIGENDIAN
219 memmove(digest, &ctxt->md5_st8[0], 16);
220 #else
221 digest[0] = ctxt->md5_st8[3];
222 digest[1] = ctxt->md5_st8[2];
223 digest[2] = ctxt->md5_st8[1];
224 digest[3] = ctxt->md5_st8[0];
225 digest[4] = ctxt->md5_st8[7];
226 digest[5] = ctxt->md5_st8[6];
227 digest[6] = ctxt->md5_st8[5];
228 digest[7] = ctxt->md5_st8[4];
229 digest[8] = ctxt->md5_st8[11];
230 digest[9] = ctxt->md5_st8[10];
231 digest[10] = ctxt->md5_st8[9];
232 digest[11] = ctxt->md5_st8[8];
233 digest[12] = ctxt->md5_st8[15];
234 digest[13] = ctxt->md5_st8[14];
235 digest[14] = ctxt->md5_st8[13];
236 digest[15] = ctxt->md5_st8[12];
237 #endif
238 }
239
240 #ifdef WORDS_BIGENDIAN
241 static uint32 X[16];
242 #endif
243
244 static void
md5_calc(const uint8 * b64,md5_ctxt * ctxt)245 md5_calc(const uint8 *b64, md5_ctxt *ctxt)
246 {
247 uint32 A = ctxt->md5_sta;
248 uint32 B = ctxt->md5_stb;
249 uint32 C = ctxt->md5_stc;
250 uint32 D = ctxt->md5_std;
251
252 #ifndef WORDS_BIGENDIAN
253 const uint32 *X = (const uint32 *) b64;
254 #else
255 /* 4 byte words */
256 /* what a brute force but fast! */
257 uint8 *y = (uint8 *) X;
258
259 y[0] = b64[3];
260 y[1] = b64[2];
261 y[2] = b64[1];
262 y[3] = b64[0];
263 y[4] = b64[7];
264 y[5] = b64[6];
265 y[6] = b64[5];
266 y[7] = b64[4];
267 y[8] = b64[11];
268 y[9] = b64[10];
269 y[10] = b64[9];
270 y[11] = b64[8];
271 y[12] = b64[15];
272 y[13] = b64[14];
273 y[14] = b64[13];
274 y[15] = b64[12];
275 y[16] = b64[19];
276 y[17] = b64[18];
277 y[18] = b64[17];
278 y[19] = b64[16];
279 y[20] = b64[23];
280 y[21] = b64[22];
281 y[22] = b64[21];
282 y[23] = b64[20];
283 y[24] = b64[27];
284 y[25] = b64[26];
285 y[26] = b64[25];
286 y[27] = b64[24];
287 y[28] = b64[31];
288 y[29] = b64[30];
289 y[30] = b64[29];
290 y[31] = b64[28];
291 y[32] = b64[35];
292 y[33] = b64[34];
293 y[34] = b64[33];
294 y[35] = b64[32];
295 y[36] = b64[39];
296 y[37] = b64[38];
297 y[38] = b64[37];
298 y[39] = b64[36];
299 y[40] = b64[43];
300 y[41] = b64[42];
301 y[42] = b64[41];
302 y[43] = b64[40];
303 y[44] = b64[47];
304 y[45] = b64[46];
305 y[46] = b64[45];
306 y[47] = b64[44];
307 y[48] = b64[51];
308 y[49] = b64[50];
309 y[50] = b64[49];
310 y[51] = b64[48];
311 y[52] = b64[55];
312 y[53] = b64[54];
313 y[54] = b64[53];
314 y[55] = b64[52];
315 y[56] = b64[59];
316 y[57] = b64[58];
317 y[58] = b64[57];
318 y[59] = b64[56];
319 y[60] = b64[63];
320 y[61] = b64[62];
321 y[62] = b64[61];
322 y[63] = b64[60];
323 #endif
324
325 ROUND1(A, B, C, D, 0, Sa, 1);
326 ROUND1(D, A, B, C, 1, Sb, 2);
327 ROUND1(C, D, A, B, 2, Sc, 3);
328 ROUND1(B, C, D, A, 3, Sd, 4);
329 ROUND1(A, B, C, D, 4, Sa, 5);
330 ROUND1(D, A, B, C, 5, Sb, 6);
331 ROUND1(C, D, A, B, 6, Sc, 7);
332 ROUND1(B, C, D, A, 7, Sd, 8);
333 ROUND1(A, B, C, D, 8, Sa, 9);
334 ROUND1(D, A, B, C, 9, Sb, 10);
335 ROUND1(C, D, A, B, 10, Sc, 11);
336 ROUND1(B, C, D, A, 11, Sd, 12);
337 ROUND1(A, B, C, D, 12, Sa, 13);
338 ROUND1(D, A, B, C, 13, Sb, 14);
339 ROUND1(C, D, A, B, 14, Sc, 15);
340 ROUND1(B, C, D, A, 15, Sd, 16);
341
342 ROUND2(A, B, C, D, 1, Se, 17);
343 ROUND2(D, A, B, C, 6, Sf, 18);
344 ROUND2(C, D, A, B, 11, Sg, 19);
345 ROUND2(B, C, D, A, 0, Sh, 20);
346 ROUND2(A, B, C, D, 5, Se, 21);
347 ROUND2(D, A, B, C, 10, Sf, 22);
348 ROUND2(C, D, A, B, 15, Sg, 23);
349 ROUND2(B, C, D, A, 4, Sh, 24);
350 ROUND2(A, B, C, D, 9, Se, 25);
351 ROUND2(D, A, B, C, 14, Sf, 26);
352 ROUND2(C, D, A, B, 3, Sg, 27);
353 ROUND2(B, C, D, A, 8, Sh, 28);
354 ROUND2(A, B, C, D, 13, Se, 29);
355 ROUND2(D, A, B, C, 2, Sf, 30);
356 ROUND2(C, D, A, B, 7, Sg, 31);
357 ROUND2(B, C, D, A, 12, Sh, 32);
358
359 ROUND3(A, B, C, D, 5, Si, 33);
360 ROUND3(D, A, B, C, 8, Sj, 34);
361 ROUND3(C, D, A, B, 11, Sk, 35);
362 ROUND3(B, C, D, A, 14, Sl, 36);
363 ROUND3(A, B, C, D, 1, Si, 37);
364 ROUND3(D, A, B, C, 4, Sj, 38);
365 ROUND3(C, D, A, B, 7, Sk, 39);
366 ROUND3(B, C, D, A, 10, Sl, 40);
367 ROUND3(A, B, C, D, 13, Si, 41);
368 ROUND3(D, A, B, C, 0, Sj, 42);
369 ROUND3(C, D, A, B, 3, Sk, 43);
370 ROUND3(B, C, D, A, 6, Sl, 44);
371 ROUND3(A, B, C, D, 9, Si, 45);
372 ROUND3(D, A, B, C, 12, Sj, 46);
373 ROUND3(C, D, A, B, 15, Sk, 47);
374 ROUND3(B, C, D, A, 2, Sl, 48);
375
376 ROUND4(A, B, C, D, 0, Sm, 49);
377 ROUND4(D, A, B, C, 7, Sn, 50);
378 ROUND4(C, D, A, B, 14, So, 51);
379 ROUND4(B, C, D, A, 5, Sp, 52);
380 ROUND4(A, B, C, D, 12, Sm, 53);
381 ROUND4(D, A, B, C, 3, Sn, 54);
382 ROUND4(C, D, A, B, 10, So, 55);
383 ROUND4(B, C, D, A, 1, Sp, 56);
384 ROUND4(A, B, C, D, 8, Sm, 57);
385 ROUND4(D, A, B, C, 15, Sn, 58);
386 ROUND4(C, D, A, B, 6, So, 59);
387 ROUND4(B, C, D, A, 13, Sp, 60);
388 ROUND4(A, B, C, D, 4, Sm, 61);
389 ROUND4(D, A, B, C, 11, Sn, 62);
390 ROUND4(C, D, A, B, 2, So, 63);
391 ROUND4(B, C, D, A, 9, Sp, 64);
392
393 ctxt->md5_sta += A;
394 ctxt->md5_stb += B;
395 ctxt->md5_stc += C;
396 ctxt->md5_std += D;
397 }
398