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