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(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((uint8 *) (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(uint8 * b64,md5_ctxt * ctxt)245 md5_calc(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 	uint32	   *X = (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