Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
sha1.inl
Go to the documentation of this file.
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 <stdint.h>
90 #include <string.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] = \
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. */
149 static void
150 SHA1_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 */
257 SHA_API void
258 SHA1_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 
270 SHA_API void
271 SHA1_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. */
297 SHA_API void
298 SHA1_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 */