Logo ROOT   6.14/05
Reference Guide
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 <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 */
#define SHA1_DIGEST_SIZE
Definition: sha1.inl:98
static void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64])
Definition: sha1.inl:149
static uint32_t blk0(CHAR64LONG16 *block, int i)
Definition: sha1.inl:113
#define R3(v, w, x, y, z, i)
Definition: sha1.inl:139
#define R2(v, w, x, y, z, i)
Definition: sha1.inl:136
#define R0(v, w, x, y, z, i)
Definition: sha1.inl:130
SHA_API void SHA1_Init(SHA_CTX *context)
Definition: sha1.inl:257
#define rol(value, bits)
Definition: sha1.inl:100
auto * a
Definition: textangle.C:12
#define d(i)
Definition: RSha256.hxx:102
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Definition: TRolke.cxx:630
#define R4(v, w, x, y, z, i)
Definition: sha1.inl:142
auto * l
Definition: textangle.C:4
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
SHA_API void SHA1_Update(SHA_CTX *context, const uint8_t *data, const uint32_t len)
Definition: sha1.inl:270
#define c(i)
Definition: RSha256.hxx:101
SHA_API void SHA1_Final(unsigned char *digest, SHA_CTX *context)
Definition: sha1.inl:297
const Int_t n
Definition: legend1.C:16
#define R1(v, w, x, y, z, i)
Definition: sha1.inl:133