1 /*-------------------------------------------------------------------------
4 * Implements the SHA1 Secure Hash Algorithm
6 * Fallback implementation of SHA1, as specified in RFC 3174.
8 * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
14 *-------------------------------------------------------------------------
17 /* $KAME: sha1.c,v 1.3 2000/02/22 14:01:18 itojun Exp $ */
20 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
21 * All rights reserved.
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
26 * 1. Redistributions of source code must retain the above copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. Neither the name of the project nor the names of its contributors
32 * may be used to endorse or promote products derived from this software
33 * without specific prior written permission.
35 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
36 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
39 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
41 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
43 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
49 * based on: http://www.itl.nist.gov/fipspubs/fip180-1.htm
50 * implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
56 #include "postgres_fe.h"
59 #include <sys/param.h>
64 static const uint32 _K
[] = {0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6};
66 #define K(t) _K[(t) / 20]
68 #define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d)))
69 #define F1(b, c, d) (((b) ^ (c)) ^ (d))
70 #define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
71 #define F3(b, c, d) (((b) ^ (c)) ^ (d))
73 #define S(n, x) (((x) << (n)) | ((x) >> (32 - (n))))
75 #define H(n) (ctx->h.b32[(n)])
76 #define COUNT (ctx->count)
77 #define BCOUNT (ctx->c.b64[0] / 8)
78 #define W(n) (ctx->m.b32[(n)])
82 ctx->m.b8[(COUNT % 64)] = (x); \
85 if (COUNT % 64 == 0) \
90 sha1_step(pg_sha1_ctx
*ctx
)
101 #ifndef WORDS_BIGENDIAN
104 memmove(&tctx
.m
.b8
[0], &ctx
->m
.b8
[0], 64);
105 ctx
->m
.b8
[0] = tctx
.m
.b8
[3];
106 ctx
->m
.b8
[1] = tctx
.m
.b8
[2];
107 ctx
->m
.b8
[2] = tctx
.m
.b8
[1];
108 ctx
->m
.b8
[3] = tctx
.m
.b8
[0];
109 ctx
->m
.b8
[4] = tctx
.m
.b8
[7];
110 ctx
->m
.b8
[5] = tctx
.m
.b8
[6];
111 ctx
->m
.b8
[6] = tctx
.m
.b8
[5];
112 ctx
->m
.b8
[7] = tctx
.m
.b8
[4];
113 ctx
->m
.b8
[8] = tctx
.m
.b8
[11];
114 ctx
->m
.b8
[9] = tctx
.m
.b8
[10];
115 ctx
->m
.b8
[10] = tctx
.m
.b8
[9];
116 ctx
->m
.b8
[11] = tctx
.m
.b8
[8];
117 ctx
->m
.b8
[12] = tctx
.m
.b8
[15];
118 ctx
->m
.b8
[13] = tctx
.m
.b8
[14];
119 ctx
->m
.b8
[14] = tctx
.m
.b8
[13];
120 ctx
->m
.b8
[15] = tctx
.m
.b8
[12];
121 ctx
->m
.b8
[16] = tctx
.m
.b8
[19];
122 ctx
->m
.b8
[17] = tctx
.m
.b8
[18];
123 ctx
->m
.b8
[18] = tctx
.m
.b8
[17];
124 ctx
->m
.b8
[19] = tctx
.m
.b8
[16];
125 ctx
->m
.b8
[20] = tctx
.m
.b8
[23];
126 ctx
->m
.b8
[21] = tctx
.m
.b8
[22];
127 ctx
->m
.b8
[22] = tctx
.m
.b8
[21];
128 ctx
->m
.b8
[23] = tctx
.m
.b8
[20];
129 ctx
->m
.b8
[24] = tctx
.m
.b8
[27];
130 ctx
->m
.b8
[25] = tctx
.m
.b8
[26];
131 ctx
->m
.b8
[26] = tctx
.m
.b8
[25];
132 ctx
->m
.b8
[27] = tctx
.m
.b8
[24];
133 ctx
->m
.b8
[28] = tctx
.m
.b8
[31];
134 ctx
->m
.b8
[29] = tctx
.m
.b8
[30];
135 ctx
->m
.b8
[30] = tctx
.m
.b8
[29];
136 ctx
->m
.b8
[31] = tctx
.m
.b8
[28];
137 ctx
->m
.b8
[32] = tctx
.m
.b8
[35];
138 ctx
->m
.b8
[33] = tctx
.m
.b8
[34];
139 ctx
->m
.b8
[34] = tctx
.m
.b8
[33];
140 ctx
->m
.b8
[35] = tctx
.m
.b8
[32];
141 ctx
->m
.b8
[36] = tctx
.m
.b8
[39];
142 ctx
->m
.b8
[37] = tctx
.m
.b8
[38];
143 ctx
->m
.b8
[38] = tctx
.m
.b8
[37];
144 ctx
->m
.b8
[39] = tctx
.m
.b8
[36];
145 ctx
->m
.b8
[40] = tctx
.m
.b8
[43];
146 ctx
->m
.b8
[41] = tctx
.m
.b8
[42];
147 ctx
->m
.b8
[42] = tctx
.m
.b8
[41];
148 ctx
->m
.b8
[43] = tctx
.m
.b8
[40];
149 ctx
->m
.b8
[44] = tctx
.m
.b8
[47];
150 ctx
->m
.b8
[45] = tctx
.m
.b8
[46];
151 ctx
->m
.b8
[46] = tctx
.m
.b8
[45];
152 ctx
->m
.b8
[47] = tctx
.m
.b8
[44];
153 ctx
->m
.b8
[48] = tctx
.m
.b8
[51];
154 ctx
->m
.b8
[49] = tctx
.m
.b8
[50];
155 ctx
->m
.b8
[50] = tctx
.m
.b8
[49];
156 ctx
->m
.b8
[51] = tctx
.m
.b8
[48];
157 ctx
->m
.b8
[52] = tctx
.m
.b8
[55];
158 ctx
->m
.b8
[53] = tctx
.m
.b8
[54];
159 ctx
->m
.b8
[54] = tctx
.m
.b8
[53];
160 ctx
->m
.b8
[55] = tctx
.m
.b8
[52];
161 ctx
->m
.b8
[56] = tctx
.m
.b8
[59];
162 ctx
->m
.b8
[57] = tctx
.m
.b8
[58];
163 ctx
->m
.b8
[58] = tctx
.m
.b8
[57];
164 ctx
->m
.b8
[59] = tctx
.m
.b8
[56];
165 ctx
->m
.b8
[60] = tctx
.m
.b8
[63];
166 ctx
->m
.b8
[61] = tctx
.m
.b8
[62];
167 ctx
->m
.b8
[62] = tctx
.m
.b8
[61];
168 ctx
->m
.b8
[63] = tctx
.m
.b8
[60];
177 for (t
= 0; t
< 20; t
++)
181 W(s
) = S(1, W((s
+ 13) & 0x0f) ^ W((s
+ 8) & 0x0f) ^ W((s
+ 2) & 0x0f) ^ W(s
));
182 tmp
= S(5, a
) + F0(b
, c
, d
) + e
+ W(s
) + K(t
);
189 for (t
= 20; t
< 40; t
++)
192 W(s
) = S(1, W((s
+ 13) & 0x0f) ^ W((s
+ 8) & 0x0f) ^ W((s
+ 2) & 0x0f) ^ W(s
));
193 tmp
= S(5, a
) + F1(b
, c
, d
) + e
+ W(s
) + K(t
);
200 for (t
= 40; t
< 60; t
++)
203 W(s
) = S(1, W((s
+ 13) & 0x0f) ^ W((s
+ 8) & 0x0f) ^ W((s
+ 2) & 0x0f) ^ W(s
));
204 tmp
= S(5, a
) + F2(b
, c
, d
) + e
+ W(s
) + K(t
);
211 for (t
= 60; t
< 80; t
++)
214 W(s
) = S(1, W((s
+ 13) & 0x0f) ^ W((s
+ 8) & 0x0f) ^ W((s
+ 2) & 0x0f) ^ W(s
));
215 tmp
= S(5, a
) + F3(b
, c
, d
) + e
+ W(s
) + K(t
);
229 memset(&ctx
->m
.b8
[0], 0, 64);
233 sha1_pad(pg_sha1_ctx
*ctx
)
235 size_t padlen
; /* pad length in bytes */
240 padstart
= COUNT
% 64;
241 padlen
= 64 - padstart
;
244 memset(&ctx
->m
.b8
[padstart
], 0, padlen
);
248 padstart
= COUNT
% 64; /* should be 0 */
249 padlen
= 64 - padstart
; /* should be 64 */
251 memset(&ctx
->m
.b8
[padstart
], 0, padlen
- 8);
252 COUNT
+= (padlen
- 8);
254 #ifdef WORDS_BIGENDIAN
255 PUTPAD(ctx
->c
.b8
[0]);
256 PUTPAD(ctx
->c
.b8
[1]);
257 PUTPAD(ctx
->c
.b8
[2]);
258 PUTPAD(ctx
->c
.b8
[3]);
259 PUTPAD(ctx
->c
.b8
[4]);
260 PUTPAD(ctx
->c
.b8
[5]);
261 PUTPAD(ctx
->c
.b8
[6]);
262 PUTPAD(ctx
->c
.b8
[7]);
264 PUTPAD(ctx
->c
.b8
[7]);
265 PUTPAD(ctx
->c
.b8
[6]);
266 PUTPAD(ctx
->c
.b8
[5]);
267 PUTPAD(ctx
->c
.b8
[4]);
268 PUTPAD(ctx
->c
.b8
[3]);
269 PUTPAD(ctx
->c
.b8
[2]);
270 PUTPAD(ctx
->c
.b8
[1]);
271 PUTPAD(ctx
->c
.b8
[0]);
276 sha1_result(uint8
*digest0
, pg_sha1_ctx
*ctx
)
280 digest
= (uint8
*) digest0
;
282 #ifdef WORDS_BIGENDIAN
283 memmove(digest
, &ctx
->h
.b8
[0], 20);
285 digest
[0] = ctx
->h
.b8
[3];
286 digest
[1] = ctx
->h
.b8
[2];
287 digest
[2] = ctx
->h
.b8
[1];
288 digest
[3] = ctx
->h
.b8
[0];
289 digest
[4] = ctx
->h
.b8
[7];
290 digest
[5] = ctx
->h
.b8
[6];
291 digest
[6] = ctx
->h
.b8
[5];
292 digest
[7] = ctx
->h
.b8
[4];
293 digest
[8] = ctx
->h
.b8
[11];
294 digest
[9] = ctx
->h
.b8
[10];
295 digest
[10] = ctx
->h
.b8
[9];
296 digest
[11] = ctx
->h
.b8
[8];
297 digest
[12] = ctx
->h
.b8
[15];
298 digest
[13] = ctx
->h
.b8
[14];
299 digest
[14] = ctx
->h
.b8
[13];
300 digest
[15] = ctx
->h
.b8
[12];
301 digest
[16] = ctx
->h
.b8
[19];
302 digest
[17] = ctx
->h
.b8
[18];
303 digest
[18] = ctx
->h
.b8
[17];
304 digest
[19] = ctx
->h
.b8
[16];
308 /* External routines for this SHA1 implementation */
313 * Initialize a SHA1 context.
316 pg_sha1_init(pg_sha1_ctx
*ctx
)
318 memset(ctx
, 0, sizeof(pg_sha1_ctx
));
329 * Update a SHA1 context.
332 pg_sha1_update(pg_sha1_ctx
*ctx
, const uint8
*data
, size_t len
)
340 input
= (const uint8
*) data
;
345 gapstart
= COUNT
% 64;
346 gaplen
= 64 - gapstart
;
348 copysiz
= (gaplen
< len
- off
) ? gaplen
: len
- off
;
349 memmove(&ctx
->m
.b8
[gapstart
], &input
[off
], copysiz
);
352 ctx
->c
.b64
[0] += copysiz
* 8;
362 * Finalize a SHA1 context.
365 pg_sha1_final(pg_sha1_ctx
*ctx
, uint8
*dest
)
368 sha1_result(dest
, ctx
);