PostgreSQL Source Code  git master
sha1.c
Go to the documentation of this file.
1 /* $KAME: sha1.c,v 1.3 2000/02/22 14:01:18 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/sha1.c
32  */
33 /*
34  * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
35  * based on: http://www.itl.nist.gov/fipspubs/fip180-1.htm
36  * implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
37  */
38 
39 #include "postgres.h"
40 
41 #include <sys/param.h>
42 
43 #include "sha1.h"
44 
45 /* constant table */
46 static uint32 _K[] = {0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6};
47 
48 #define K(t) _K[(t) / 20]
49 
50 #define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d)))
51 #define F1(b, c, d) (((b) ^ (c)) ^ (d))
52 #define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
53 #define F3(b, c, d) (((b) ^ (c)) ^ (d))
54 
55 #define S(n, x) (((x) << (n)) | ((x) >> (32 - (n))))
56 
57 #define H(n) (ctxt->h.b32[(n)])
58 #define COUNT (ctxt->count)
59 #define BCOUNT (ctxt->c.b64[0] / 8)
60 #define W(n) (ctxt->m.b32[(n)])
61 
62 #define PUTPAD(x) \
63 do { \
64  ctxt->m.b8[(COUNT % 64)] = (x); \
65  COUNT++; \
66  COUNT %= 64; \
67  if (COUNT % 64 == 0) \
68  sha1_step(ctxt); \
69 } while (0)
70 
71 static void sha1_step(struct sha1_ctxt *);
72 
73 static void
74 sha1_step(struct sha1_ctxt *ctxt)
75 {
76  uint32 a,
77  b,
78  c,
79  d,
80  e;
81  size_t t,
82  s;
83  uint32 tmp;
84 
85 #ifndef WORDS_BIGENDIAN
86  struct sha1_ctxt tctxt;
87 
88  memmove(&tctxt.m.b8[0], &ctxt->m.b8[0], 64);
89  ctxt->m.b8[0] = tctxt.m.b8[3];
90  ctxt->m.b8[1] = tctxt.m.b8[2];
91  ctxt->m.b8[2] = tctxt.m.b8[1];
92  ctxt->m.b8[3] = tctxt.m.b8[0];
93  ctxt->m.b8[4] = tctxt.m.b8[7];
94  ctxt->m.b8[5] = tctxt.m.b8[6];
95  ctxt->m.b8[6] = tctxt.m.b8[5];
96  ctxt->m.b8[7] = tctxt.m.b8[4];
97  ctxt->m.b8[8] = tctxt.m.b8[11];
98  ctxt->m.b8[9] = tctxt.m.b8[10];
99  ctxt->m.b8[10] = tctxt.m.b8[9];
100  ctxt->m.b8[11] = tctxt.m.b8[8];
101  ctxt->m.b8[12] = tctxt.m.b8[15];
102  ctxt->m.b8[13] = tctxt.m.b8[14];
103  ctxt->m.b8[14] = tctxt.m.b8[13];
104  ctxt->m.b8[15] = tctxt.m.b8[12];
105  ctxt->m.b8[16] = tctxt.m.b8[19];
106  ctxt->m.b8[17] = tctxt.m.b8[18];
107  ctxt->m.b8[18] = tctxt.m.b8[17];
108  ctxt->m.b8[19] = tctxt.m.b8[16];
109  ctxt->m.b8[20] = tctxt.m.b8[23];
110  ctxt->m.b8[21] = tctxt.m.b8[22];
111  ctxt->m.b8[22] = tctxt.m.b8[21];
112  ctxt->m.b8[23] = tctxt.m.b8[20];
113  ctxt->m.b8[24] = tctxt.m.b8[27];
114  ctxt->m.b8[25] = tctxt.m.b8[26];
115  ctxt->m.b8[26] = tctxt.m.b8[25];
116  ctxt->m.b8[27] = tctxt.m.b8[24];
117  ctxt->m.b8[28] = tctxt.m.b8[31];
118  ctxt->m.b8[29] = tctxt.m.b8[30];
119  ctxt->m.b8[30] = tctxt.m.b8[29];
120  ctxt->m.b8[31] = tctxt.m.b8[28];
121  ctxt->m.b8[32] = tctxt.m.b8[35];
122  ctxt->m.b8[33] = tctxt.m.b8[34];
123  ctxt->m.b8[34] = tctxt.m.b8[33];
124  ctxt->m.b8[35] = tctxt.m.b8[32];
125  ctxt->m.b8[36] = tctxt.m.b8[39];
126  ctxt->m.b8[37] = tctxt.m.b8[38];
127  ctxt->m.b8[38] = tctxt.m.b8[37];
128  ctxt->m.b8[39] = tctxt.m.b8[36];
129  ctxt->m.b8[40] = tctxt.m.b8[43];
130  ctxt->m.b8[41] = tctxt.m.b8[42];
131  ctxt->m.b8[42] = tctxt.m.b8[41];
132  ctxt->m.b8[43] = tctxt.m.b8[40];
133  ctxt->m.b8[44] = tctxt.m.b8[47];
134  ctxt->m.b8[45] = tctxt.m.b8[46];
135  ctxt->m.b8[46] = tctxt.m.b8[45];
136  ctxt->m.b8[47] = tctxt.m.b8[44];
137  ctxt->m.b8[48] = tctxt.m.b8[51];
138  ctxt->m.b8[49] = tctxt.m.b8[50];
139  ctxt->m.b8[50] = tctxt.m.b8[49];
140  ctxt->m.b8[51] = tctxt.m.b8[48];
141  ctxt->m.b8[52] = tctxt.m.b8[55];
142  ctxt->m.b8[53] = tctxt.m.b8[54];
143  ctxt->m.b8[54] = tctxt.m.b8[53];
144  ctxt->m.b8[55] = tctxt.m.b8[52];
145  ctxt->m.b8[56] = tctxt.m.b8[59];
146  ctxt->m.b8[57] = tctxt.m.b8[58];
147  ctxt->m.b8[58] = tctxt.m.b8[57];
148  ctxt->m.b8[59] = tctxt.m.b8[56];
149  ctxt->m.b8[60] = tctxt.m.b8[63];
150  ctxt->m.b8[61] = tctxt.m.b8[62];
151  ctxt->m.b8[62] = tctxt.m.b8[61];
152  ctxt->m.b8[63] = tctxt.m.b8[60];
153 #endif
154 
155  a = H(0);
156  b = H(1);
157  c = H(2);
158  d = H(3);
159  e = H(4);
160 
161  for (t = 0; t < 20; t++)
162  {
163  s = t & 0x0f;
164  if (t >= 16)
165  W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s));
166  tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t);
167  e = d;
168  d = c;
169  c = S(30, b);
170  b = a;
171  a = tmp;
172  }
173  for (t = 20; t < 40; t++)
174  {
175  s = t & 0x0f;
176  W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s));
177  tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t);
178  e = d;
179  d = c;
180  c = S(30, b);
181  b = a;
182  a = tmp;
183  }
184  for (t = 40; t < 60; t++)
185  {
186  s = t & 0x0f;
187  W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s));
188  tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t);
189  e = d;
190  d = c;
191  c = S(30, b);
192  b = a;
193  a = tmp;
194  }
195  for (t = 60; t < 80; t++)
196  {
197  s = t & 0x0f;
198  W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s));
199  tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t);
200  e = d;
201  d = c;
202  c = S(30, b);
203  b = a;
204  a = tmp;
205  }
206 
207  H(0) = H(0) + a;
208  H(1) = H(1) + b;
209  H(2) = H(2) + c;
210  H(3) = H(3) + d;
211  H(4) = H(4) + e;
212 
213  memset(&ctxt->m.b8[0], 0, 64);
214 }
215 
216 /*------------------------------------------------------------*/
217 
218 void
219 sha1_init(struct sha1_ctxt *ctxt)
220 {
221  memset(ctxt, 0, sizeof(struct sha1_ctxt));
222  H(0) = 0x67452301;
223  H(1) = 0xefcdab89;
224  H(2) = 0x98badcfe;
225  H(3) = 0x10325476;
226  H(4) = 0xc3d2e1f0;
227 }
228 
229 void
230 sha1_pad(struct sha1_ctxt *ctxt)
231 {
232  size_t padlen; /* pad length in bytes */
233  size_t padstart;
234 
235  PUTPAD(0x80);
236 
237  padstart = COUNT % 64;
238  padlen = 64 - padstart;
239  if (padlen < 8)
240  {
241  memset(&ctxt->m.b8[padstart], 0, padlen);
242  COUNT += padlen;
243  COUNT %= 64;
244  sha1_step(ctxt);
245  padstart = COUNT % 64; /* should be 0 */
246  padlen = 64 - padstart; /* should be 64 */
247  }
248  memset(&ctxt->m.b8[padstart], 0, padlen - 8);
249  COUNT += (padlen - 8);
250  COUNT %= 64;
251 #ifdef WORDS_BIGENDIAN
252  PUTPAD(ctxt->c.b8[0]);
253  PUTPAD(ctxt->c.b8[1]);
254  PUTPAD(ctxt->c.b8[2]);
255  PUTPAD(ctxt->c.b8[3]);
256  PUTPAD(ctxt->c.b8[4]);
257  PUTPAD(ctxt->c.b8[5]);
258  PUTPAD(ctxt->c.b8[6]);
259  PUTPAD(ctxt->c.b8[7]);
260 #else
261  PUTPAD(ctxt->c.b8[7]);
262  PUTPAD(ctxt->c.b8[6]);
263  PUTPAD(ctxt->c.b8[5]);
264  PUTPAD(ctxt->c.b8[4]);
265  PUTPAD(ctxt->c.b8[3]);
266  PUTPAD(ctxt->c.b8[2]);
267  PUTPAD(ctxt->c.b8[1]);
268  PUTPAD(ctxt->c.b8[0]);
269 #endif
270 }
271 
272 void
273 sha1_loop(struct sha1_ctxt *ctxt, const uint8 *input0, size_t len)
274 {
275  const uint8 *input;
276  size_t gaplen;
277  size_t gapstart;
278  size_t off;
279  size_t copysiz;
280 
281  input = (const uint8 *) input0;
282  off = 0;
283 
284  while (off < len)
285  {
286  gapstart = COUNT % 64;
287  gaplen = 64 - gapstart;
288 
289  copysiz = (gaplen < len - off) ? gaplen : len - off;
290  memmove(&ctxt->m.b8[gapstart], &input[off], copysiz);
291  COUNT += copysiz;
292  COUNT %= 64;
293  ctxt->c.b64[0] += copysiz * 8;
294  if (COUNT % 64 == 0)
295  sha1_step(ctxt);
296  off += copysiz;
297  }
298 }
299 
300 void
301 sha1_result(struct sha1_ctxt *ctxt, uint8 *digest0)
302 {
303  uint8 *digest;
304 
305  digest = (uint8 *) digest0;
306  sha1_pad(ctxt);
307 #ifdef WORDS_BIGENDIAN
308  memmove(digest, &ctxt->h.b8[0], 20);
309 #else
310  digest[0] = ctxt->h.b8[3];
311  digest[1] = ctxt->h.b8[2];
312  digest[2] = ctxt->h.b8[1];
313  digest[3] = ctxt->h.b8[0];
314  digest[4] = ctxt->h.b8[7];
315  digest[5] = ctxt->h.b8[6];
316  digest[6] = ctxt->h.b8[5];
317  digest[7] = ctxt->h.b8[4];
318  digest[8] = ctxt->h.b8[11];
319  digest[9] = ctxt->h.b8[10];
320  digest[10] = ctxt->h.b8[9];
321  digest[11] = ctxt->h.b8[8];
322  digest[12] = ctxt->h.b8[15];
323  digest[13] = ctxt->h.b8[14];
324  digest[14] = ctxt->h.b8[13];
325  digest[15] = ctxt->h.b8[12];
326  digest[16] = ctxt->h.b8[19];
327  digest[17] = ctxt->h.b8[18];
328  digest[18] = ctxt->h.b8[17];
329  digest[19] = ctxt->h.b8[16];
330 #endif
331 }
union sha1_ctxt::@15 h
#define COUNT
Definition: sha1.c:58
#define PUTPAD(x)
Definition: sha1.c:62
void sha1_loop(struct sha1_ctxt *ctxt, const uint8 *input0, size_t len)
Definition: sha1.c:273
unsigned char uint8
Definition: c.h:357
static uint32 _K[]
Definition: sha1.c:46
void sha1_result(struct sha1_ctxt *ctxt, uint8 *digest0)
Definition: sha1.c:301
Definition: sha1.h:41
#define W(n)
Definition: sha1.c:60
char * c
#define memmove(d, s, c)
Definition: c.h:1267
#define F3(b, c, d)
Definition: sha1.c:53
#define F2(b, c, d)
Definition: sha1.c:52
unsigned int uint32
Definition: c.h:359
uint8 b8[20]
Definition: sha1.h:45
#define S(n, x)
Definition: sha1.c:55
void sha1_init(struct sha1_ctxt *ctxt)
Definition: sha1.c:219
#define K(t)
Definition: sha1.c:48
static void sha1_step(struct sha1_ctxt *)
Definition: sha1.c:74
#define F1(b, c, d)
Definition: sha1.c:51
void sha1_pad(struct sha1_ctxt *ctxt)
Definition: sha1.c:230
e
Definition: preproc-init.c:82
union sha1_ctxt::@16 c
#define F0(b, c, d)
Definition: sha1.c:50
uint64 b64[1]
Definition: sha1.h:51
union sha1_ctxt::@17 m
#define H(n)
Definition: sha1.c:57