]> git.proxmox.com Git - ceph.git/blob - ceph/src/civetweb/src/sha1.inl
buildsys: switch source download to quincy
[ceph.git] / ceph / src / civetweb / src / sha1.inl
1 /*
2 SHA-1 in C
3 By Steve Reid <sreid@sea-to-sky.net>
4 100% Public Domain
5
6 -----------------
7 Modified 7/98
8 By James H. Brown <jbrown@burgoyne.com>
9 Still 100% Public Domain
10
11 Corrected a problem which generated improper hash values on 16 bit machines
12 Routine SHA1Update changed from
13 void SHA1Update(SHA_CTX* context, unsigned char* data, unsigned int
14 len)
15 to
16 void SHA1Update(SHA_CTX* context, unsigned char* data, unsigned
17 long len)
18
19 The 'len' parameter was declared an int which works fine on 32 bit machines.
20 However, on 16 bit machines an int is too small for the shifts being done
21 against
22 it. This caused the hash function to generate incorrect values if len was
23 greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
24
25 Since the file IO in main() reads 16K at a time, any file 8K or larger would
26 be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
27 "a"s).
28
29 I also changed the declaration of variables i & j in SHA1Update to
30 unsigned long from unsigned int for the same reason.
31
32 These changes should make no difference to any 32 bit implementations since
33 an
34 int and a long are the same size in those environments.
35
36 --
37 I also corrected a few compiler warnings generated by Borland C.
38 1. Added #include <process.h> for exit() prototype
39 2. Removed unused variable 'j' in SHA1Final
40 3. Changed exit(0) to return(0) at end of main.
41
42 ALL changes I made can be located by searching for comments containing 'JHB'
43 -----------------
44 Modified 8/98
45 By Steve Reid <sreid@sea-to-sky.net>
46 Still 100% public domain
47
48 1- Removed #include <process.h> and used return() instead of exit()
49 2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
50 3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net
51
52 -----------------
53 Modified 4/01
54 By Saul Kravitz <Saul.Kravitz@celera.com>
55 Still 100% PD
56 Modified to run on Compaq Alpha hardware.
57
58 -----------------
59 Modified 07/2002
60 By Ralph Giles <giles@ghostscript.com>
61 Still 100% public domain
62 modified for use with stdint types, autoconf
63 code cleanup, removed attribution comments
64 switched SHA1Final() argument order for consistency
65 use SHA1_ prefix for public api
66 move public api to sha1.h
67 */
68
69 /*
70 11/2016 adapted for CivetWeb:
71 include sha1.h in sha1.c,
72 rename to sha1.inl
73 remove unused #ifdef sections
74 make endian independent
75 align buffer to 4 bytes
76 remove unused variable assignments
77 */
78
79 /*
80 Test Vectors (from FIPS PUB 180-1)
81 "abc"
82 A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
83 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
84 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
85 A million repetitions of "a"
86 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
87 */
88
89 #include <string.h>
90 #include <stdint.h>
91
92 typedef struct {
93 uint32_t state[5];
94 uint32_t count[2];
95 uint8_t buffer[64];
96 } SHA_CTX;
97
98 #define SHA1_DIGEST_SIZE 20
99
100 #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
101
102 /* blk0() and blk() perform the initial expand. */
103 /* I got the idea of expanding during the round function from SSLeay */
104
105
106 typedef union {
107 uint8_t c[64];
108 uint32_t l[16];
109 } CHAR64LONG16;
110
111
112 static uint32_t
113 blk0(CHAR64LONG16 *block, int i)
114 {
115 static const uint32_t n = 1u;
116 if ((*((uint8_t *)(&n))) == 1) {
117 /* little endian / intel byte order */
118 block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00)
119 | (rol(block->l[i], 8) & 0x00FF00FF);
120 }
121 return block->l[i];
122 }
123
124 #define blk(block, i) \
125 (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ block->l[(i + 8) & 15] \
126 ^ block->l[(i + 2) & 15] ^ block->l[i & 15], \
127 1))
128
129 /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
130 #define R0(v, w, x, y, z, i) \
131 z += ((w & (x ^ y)) ^ y) + blk0(block, i) + 0x5A827999 + rol(v, 5); \
132 w = rol(w, 30);
133 #define R1(v, w, x, y, z, i) \
134 z += ((w & (x ^ y)) ^ y) + blk(block, i) + 0x5A827999 + rol(v, 5); \
135 w = rol(w, 30);
136 #define R2(v, w, x, y, z, i) \
137 z += (w ^ x ^ y) + blk(block, i) + 0x6ED9EBA1 + rol(v, 5); \
138 w = rol(w, 30);
139 #define R3(v, w, x, y, z, i) \
140 z += (((w | x) & y) | (w & x)) + blk(block, i) + 0x8F1BBCDC + rol(v, 5); \
141 w = rol(w, 30);
142 #define R4(v, w, x, y, z, i) \
143 z += (w ^ x ^ y) + blk(block, i) + 0xCA62C1D6 + rol(v, 5); \
144 w = rol(w, 30);
145
146
147 /* Hash a single 512-bit block. This is the core of the algorithm. */
148 static void
149 SHA1_Transform(uint32_t state[5], const uint8_t buffer[64])
150 {
151 uint32_t a, b, c, d, e;
152
153 /* Must use an aligned, read/write buffer */
154 CHAR64LONG16 block[1];
155 memcpy(block, buffer, sizeof(block));
156
157 /* Copy context->state[] to working vars */
158 a = state[0];
159 b = state[1];
160 c = state[2];
161 d = state[3];
162 e = state[4];
163
164 /* 4 rounds of 20 operations each. Loop unrolled. */
165 R0(a, b, c, d, e, 0);
166 R0(e, a, b, c, d, 1);
167 R0(d, e, a, b, c, 2);
168 R0(c, d, e, a, b, 3);
169 R0(b, c, d, e, a, 4);
170 R0(a, b, c, d, e, 5);
171 R0(e, a, b, c, d, 6);
172 R0(d, e, a, b, c, 7);
173 R0(c, d, e, a, b, 8);
174 R0(b, c, d, e, a, 9);
175 R0(a, b, c, d, e, 10);
176 R0(e, a, b, c, d, 11);
177 R0(d, e, a, b, c, 12);
178 R0(c, d, e, a, b, 13);
179 R0(b, c, d, e, a, 14);
180 R0(a, b, c, d, e, 15);
181 R1(e, a, b, c, d, 16);
182 R1(d, e, a, b, c, 17);
183 R1(c, d, e, a, b, 18);
184 R1(b, c, d, e, a, 19);
185 R2(a, b, c, d, e, 20);
186 R2(e, a, b, c, d, 21);
187 R2(d, e, a, b, c, 22);
188 R2(c, d, e, a, b, 23);
189 R2(b, c, d, e, a, 24);
190 R2(a, b, c, d, e, 25);
191 R2(e, a, b, c, d, 26);
192 R2(d, e, a, b, c, 27);
193 R2(c, d, e, a, b, 28);
194 R2(b, c, d, e, a, 29);
195 R2(a, b, c, d, e, 30);
196 R2(e, a, b, c, d, 31);
197 R2(d, e, a, b, c, 32);
198 R2(c, d, e, a, b, 33);
199 R2(b, c, d, e, a, 34);
200 R2(a, b, c, d, e, 35);
201 R2(e, a, b, c, d, 36);
202 R2(d, e, a, b, c, 37);
203 R2(c, d, e, a, b, 38);
204 R2(b, c, d, e, a, 39);
205 R3(a, b, c, d, e, 40);
206 R3(e, a, b, c, d, 41);
207 R3(d, e, a, b, c, 42);
208 R3(c, d, e, a, b, 43);
209 R3(b, c, d, e, a, 44);
210 R3(a, b, c, d, e, 45);
211 R3(e, a, b, c, d, 46);
212 R3(d, e, a, b, c, 47);
213 R3(c, d, e, a, b, 48);
214 R3(b, c, d, e, a, 49);
215 R3(a, b, c, d, e, 50);
216 R3(e, a, b, c, d, 51);
217 R3(d, e, a, b, c, 52);
218 R3(c, d, e, a, b, 53);
219 R3(b, c, d, e, a, 54);
220 R3(a, b, c, d, e, 55);
221 R3(e, a, b, c, d, 56);
222 R3(d, e, a, b, c, 57);
223 R3(c, d, e, a, b, 58);
224 R3(b, c, d, e, a, 59);
225 R4(a, b, c, d, e, 60);
226 R4(e, a, b, c, d, 61);
227 R4(d, e, a, b, c, 62);
228 R4(c, d, e, a, b, 63);
229 R4(b, c, d, e, a, 64);
230 R4(a, b, c, d, e, 65);
231 R4(e, a, b, c, d, 66);
232 R4(d, e, a, b, c, 67);
233 R4(c, d, e, a, b, 68);
234 R4(b, c, d, e, a, 69);
235 R4(a, b, c, d, e, 70);
236 R4(e, a, b, c, d, 71);
237 R4(d, e, a, b, c, 72);
238 R4(c, d, e, a, b, 73);
239 R4(b, c, d, e, a, 74);
240 R4(a, b, c, d, e, 75);
241 R4(e, a, b, c, d, 76);
242 R4(d, e, a, b, c, 77);
243 R4(c, d, e, a, b, 78);
244 R4(b, c, d, e, a, 79);
245
246 /* Add the working vars back into context.state[] */
247 state[0] += a;
248 state[1] += b;
249 state[2] += c;
250 state[3] += d;
251 state[4] += e;
252 }
253
254
255 /* SHA1Init - Initialize new context */
256 SHA_API void
257 SHA1_Init(SHA_CTX *context)
258 {
259 /* SHA1 initialization constants */
260 context->state[0] = 0x67452301;
261 context->state[1] = 0xEFCDAB89;
262 context->state[2] = 0x98BADCFE;
263 context->state[3] = 0x10325476;
264 context->state[4] = 0xC3D2E1F0;
265 context->count[0] = context->count[1] = 0;
266 }
267
268
269 SHA_API void
270 SHA1_Update(SHA_CTX *context, const uint8_t *data, const uint32_t len)
271 {
272 uint32_t i, j;
273
274 j = context->count[0];
275 if ((context->count[0] += (len << 3)) < j) {
276 context->count[1]++;
277 }
278 context->count[1] += (len >> 29);
279 j = (j >> 3) & 63;
280 if ((j + len) > 63) {
281 i = 64 - j;
282 memcpy(&context->buffer[j], data, i);
283 SHA1_Transform(context->state, context->buffer);
284 for (; i + 63 < len; i += 64) {
285 SHA1_Transform(context->state, &data[i]);
286 }
287 j = 0;
288 } else {
289 i = 0;
290 }
291 memcpy(&context->buffer[j], &data[i], len - i);
292 }
293
294
295 /* Add padding and return the message digest. */
296 SHA_API void
297 SHA1_Final(unsigned char *digest, SHA_CTX *context)
298 {
299 uint32_t i;
300 uint8_t finalcount[8];
301
302 for (i = 0; i < 8; i++) {
303 finalcount[i] =
304 (uint8_t)((context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8))
305 & 255); /* Endian independent */
306 }
307 SHA1_Update(context, (uint8_t *)"\x80", 1);
308 while ((context->count[0] & 504) != 448) {
309 SHA1_Update(context, (uint8_t *)"\x00", 1);
310 }
311 SHA1_Update(context, finalcount, 8); /* Should cause a SHA1_Transform() */
312 for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
313 digest[i] =
314 (uint8_t)((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
315 }
316
317 /* Wipe variables */
318 memset(context, '\0', sizeof(*context));
319 }
320
321
322 /* End of sha1.inl */