PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
md5.c
Go to the documentation of this file.
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
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
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
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
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
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 }
#define Sa
Definition: md5.c:75
#define Sk
Definition: md5.c:87
#define Sp
Definition: md5.c:93
#define Sj
Definition: md5.c:86
unsigned char uint8
Definition: c.h:266
#define ROUND1(a, b, c, d, k, s, i)
Definition: md5.c:47
#define MD5_BUFLEN
Definition: md5.h:36
void md5_pad(md5_ctxt *ctxt)
Definition: md5.c:177
#define Sf
Definition: md5.c:81
#define Sh
Definition: md5.c:83
#define ROUND2(a, b, c, d, k, s, i)
Definition: md5.c:54
static const uint32 T[65]
Definition: md5.c:101
static const uint8 md5_paddat[MD5_BUFLEN]
Definition: md5.c:124
#define memmove(d, s, c)
Definition: c.h:1058
#define So
Definition: md5.c:92
void md5_init(md5_ctxt *ctxt)
Definition: md5.c:138
unsigned int uint32
Definition: c.h:268
#define Sl
Definition: md5.c:88
#define Sm
Definition: md5.c:90
#define Sb
Definition: md5.c:76
unsigned int md5_i
Definition: md5.h:60
#define Sg
Definition: md5.c:82
#define MD5_D0
Definition: md5.c:98
#define Sn
Definition: md5.c:91
#define Se
Definition: md5.c:80
#define MD5_A0
Definition: md5.c:95
#define Sc
Definition: md5.c:77
static void md5_calc(uint8 *, md5_ctxt *)
Definition: md5.c:245
#define Si
Definition: md5.c:85
#define Sd
Definition: md5.c:78
void md5_loop(md5_ctxt *ctxt, const uint8 *input, unsigned len)
Definition: md5.c:150
int i
#define ROUND4(a, b, c, d, k, s, i)
Definition: md5.c:68
#define MD5_B0
Definition: md5.c:96
uint8 md5_buf[MD5_BUFLEN]
Definition: md5.h:61
void md5_result(uint8 *digest, md5_ctxt *ctxt)
Definition: md5.c:215
#define ROUND3(a, b, c, d, k, s, i)
Definition: md5.c:61
#define MD5_C0
Definition: md5.c:97
Definition: md5.h:38