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