OSDN Git Service

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