Mercurial > hg > index.fcgi > gift-gnutella > gift-gnutella-0.0.11-1pba
comparison src/sha1.c @ 0:d39e1d0d75b6
initial add
author | paulo@hit-nxdomain.opendns.com |
---|---|
date | Sat, 20 Feb 2010 21:18:28 -0800 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4d0741aafb6a |
---|---|
1 /* | |
2 * $Id: sha1.c,v 1.18 2006/07/09 13:05:20 mkern Exp $ | |
3 * | |
4 * (PD) 2001 The Bitzi Corporation | |
5 * Please see http://bitzi.com/publicdomain for more info. | |
6 * | |
7 * NIST Secure Hash Algorithm | |
8 * heavily modified by Uwe Hollerbach <uh@alumni.caltech edu> | |
9 * from Peter C. Gutmann's implementation as found in | |
10 * Applied Cryptography by Bruce Schneier | |
11 * Further modifications to include the "UNRAVEL" stuff, below | |
12 * | |
13 * New, faster sha1 code. The original code was from Bitzi corporation, and | |
14 * was in the public domain. [The original header is included.] | |
15 * | |
16 * This code is in the public domain. | |
17 */ | |
18 | |
19 #include <string.h> | |
20 #include <stdio.h> | |
21 | |
22 #include "gt_gnutella.h" | |
23 | |
24 #include "sha1.h" | |
25 #include "encoding/base32.h" | |
26 | |
27 /*****************************************************************************/ | |
28 | |
29 typedef struct sha1_state SHA_INFO; | |
30 | |
31 /* define the functions to names private to this plugin */ | |
32 #define sha_init gt_sha1_init | |
33 #define sha_update gt_sha1_append | |
34 #define sha_final gt_sha1_finish | |
35 | |
36 /*****************************************************************************/ | |
37 | |
38 void sha_init(SHA_INFO *); | |
39 void sha_update(SHA_INFO *, const void *, size_t); | |
40 void sha_final(SHA_INFO *, unsigned char [20]); | |
41 | |
42 /*****************************************************************************/ | |
43 | |
44 /* SHA f()-functions */ | |
45 | |
46 #define f1(x,y,z) ((x & y) | (~x & z)) | |
47 #define f2(x,y,z) (x ^ y ^ z) | |
48 #define f3(x,y,z) ((x & y) | (x & z) | (y & z)) | |
49 #define f4(x,y,z) (x ^ y ^ z) | |
50 | |
51 /* SHA constants */ | |
52 | |
53 #define CONST1 0x5a827999L | |
54 #define CONST2 0x6ed9eba1L | |
55 #define CONST3 0x8f1bbcdcL | |
56 #define CONST4 0xca62c1d6L | |
57 | |
58 /* truncate to 32 bits -- should be a null op on 32-bit machines */ | |
59 | |
60 #define T32(x) ((x) & 0xffffffffL) | |
61 | |
62 /* 32-bit rotate */ | |
63 | |
64 #define R32(x,n) T32(((x << n) | (x >> (32 - n)))) | |
65 | |
66 /* the generic case, for when the overall rotation is not unraveled */ | |
67 | |
68 #define FG(n) \ | |
69 T = T32(R32(A,5) + f##n(B,C,D) + E + *WP++ + CONST##n); \ | |
70 E = D; D = C; C = R32(B,30); B = A; A = T | |
71 | |
72 /* specific cases, for when the overall rotation is unraveled */ | |
73 | |
74 #define FA(n) \ | |
75 T = T32(R32(A,5) + f##n(B,C,D) + E + *WP++ + CONST##n); B = R32(B,30) | |
76 | |
77 #define FB(n) \ | |
78 E = T32(R32(T,5) + f##n(A,B,C) + D + *WP++ + CONST##n); A = R32(A,30) | |
79 | |
80 #define FC(n) \ | |
81 D = T32(R32(E,5) + f##n(T,A,B) + C + *WP++ + CONST##n); T = R32(T,30) | |
82 | |
83 #define FD(n) \ | |
84 C = T32(R32(D,5) + f##n(E,T,A) + B + *WP++ + CONST##n); E = R32(E,30) | |
85 | |
86 #define FE(n) \ | |
87 B = T32(R32(C,5) + f##n(D,E,T) + A + *WP++ + CONST##n); D = R32(D,30) | |
88 | |
89 #define FT(n) \ | |
90 A = T32(R32(B,5) + f##n(C,D,E) + T + *WP++ + CONST##n); C = R32(C,30) | |
91 | |
92 /*****************************************************************************/ | |
93 | |
94 #ifndef WIN32 | |
95 | |
96 /* sigh */ | |
97 #ifdef WORDS_BIGENDIAN | |
98 # if SIZEOF_LONG == 4 | |
99 # define SHA_BYTE_ORDER 4321 | |
100 # elif SIZEOF_LONG == 8 | |
101 # define SHA_BYTE_ORDER 87654321 | |
102 # endif | |
103 #else | |
104 # if SIZEOF_LONG == 4 | |
105 # define SHA_BYTE_ORDER 1234 | |
106 # elif SIZEOF_LONG == 8 | |
107 # define SHA_BYTE_ORDER 12345678 | |
108 # endif | |
109 #endif | |
110 | |
111 #else /* WIN32 */ | |
112 | |
113 #define SHA_BYTE_ORDER 1234 | |
114 | |
115 #endif /* !WIN32 */ | |
116 | |
117 | |
118 /* do SHA transformation */ | |
119 static void sha_transform(SHA_INFO *sha_info) | |
120 { | |
121 int i; | |
122 uint8_t *dp; | |
123 unsigned long T, A, B, C, D, E, W[80], *WP; | |
124 | |
125 dp = sha_info->data; | |
126 | |
127 /* | |
128 the following makes sure that at least one code block below is | |
129 traversed or an error is reported, without the necessity for nested | |
130 preprocessor if/else/endif blocks, which are a great pain in the | |
131 nether regions of the anatomy... | |
132 */ | |
133 #undef SWAP_DONE | |
134 | |
135 #if (SHA_BYTE_ORDER == 1234) | |
136 #define SWAP_DONE | |
137 for (i = 0; i < 16; ++i) { | |
138 T = *((unsigned long *) dp); | |
139 dp += 4; | |
140 W[i] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) | | |
141 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff); | |
142 } | |
143 #endif /* SHA_BYTE_ORDER == 1234 */ | |
144 | |
145 #if (SHA_BYTE_ORDER == 4321) | |
146 #define SWAP_DONE | |
147 for (i = 0; i < 16; ++i) { | |
148 T = *((unsigned long *) dp); | |
149 dp += 4; | |
150 W[i] = T32(T); | |
151 } | |
152 #endif /* SHA_BYTE_ORDER == 4321 */ | |
153 | |
154 #if (SHA_BYTE_ORDER == 12345678) | |
155 #define SWAP_DONE | |
156 for (i = 0; i < 16; i += 2) { | |
157 T = *((unsigned long *) dp); | |
158 dp += 8; | |
159 W[i] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) | | |
160 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff); | |
161 T >>= 32; | |
162 W[i+1] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) | | |
163 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff); | |
164 } | |
165 #endif /* SHA_BYTE_ORDER == 12345678 */ | |
166 | |
167 #if (SHA_BYTE_ORDER == 87654321) | |
168 #define SWAP_DONE | |
169 for (i = 0; i < 16; i += 2) { | |
170 T = *((unsigned long *) dp); | |
171 dp += 8; | |
172 W[i] = T32(T >> 32); | |
173 W[i+1] = T32(T); | |
174 } | |
175 #endif /* SHA_BYTE_ORDER == 87654321 */ | |
176 | |
177 #ifndef SWAP_DONE | |
178 #error Unknown byte order -- you need to add code here | |
179 #endif /* SWAP_DONE */ | |
180 | |
181 for (i = 16; i < 80; ++i) { | |
182 W[i] = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16]; | |
183 W[i] = R32(W[i], 1); | |
184 } | |
185 | |
186 A = sha_info->digest[0]; | |
187 B = sha_info->digest[1]; | |
188 C = sha_info->digest[2]; | |
189 D = sha_info->digest[3]; | |
190 E = sha_info->digest[4]; | |
191 WP = W; | |
192 | |
193 FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1); FC(1); FD(1); | |
194 FE(1); FT(1); FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1); | |
195 FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2); FE(2); FT(2); | |
196 FA(2); FB(2); FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2); | |
197 FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3); FA(3); FB(3); | |
198 FC(3); FD(3); FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3); | |
199 FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4); FC(4); FD(4); | |
200 FE(4); FT(4); FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4); | |
201 | |
202 sha_info->digest[0] = T32(sha_info->digest[0] + E); | |
203 sha_info->digest[1] = T32(sha_info->digest[1] + T); | |
204 sha_info->digest[2] = T32(sha_info->digest[2] + A); | |
205 sha_info->digest[3] = T32(sha_info->digest[3] + B); | |
206 sha_info->digest[4] = T32(sha_info->digest[4] + C); | |
207 } | |
208 | |
209 /* initialize the SHA digest */ | |
210 void sha_init(SHA_INFO *sha_info) | |
211 { | |
212 sha_info->digest[0] = 0x67452301L; | |
213 sha_info->digest[1] = 0xefcdab89L; | |
214 sha_info->digest[2] = 0x98badcfeL; | |
215 sha_info->digest[3] = 0x10325476L; | |
216 sha_info->digest[4] = 0xc3d2e1f0L; | |
217 sha_info->count_lo = 0L; | |
218 sha_info->count_hi = 0L; | |
219 sha_info->local = 0; | |
220 } | |
221 | |
222 /* update the SHA digest */ | |
223 void sha_update(SHA_INFO *sha_info, const void *data, size_t count) | |
224 { | |
225 int i; | |
226 unsigned long clo; | |
227 const uint8_t *buffer = data; | |
228 | |
229 clo = T32(sha_info->count_lo + ((unsigned long) count << 3)); | |
230 if (clo < sha_info->count_lo) { | |
231 ++sha_info->count_hi; | |
232 } | |
233 sha_info->count_lo = clo; | |
234 sha_info->count_hi += (unsigned long) count >> 29; | |
235 if (sha_info->local) { | |
236 i = SHA_BLOCKSIZE - sha_info->local; | |
237 if (i > count) { | |
238 i = count; | |
239 } | |
240 memcpy(sha_info->data + sha_info->local, buffer, i); | |
241 count -= i; | |
242 buffer += i; | |
243 sha_info->local += i; | |
244 if (sha_info->local == SHA_BLOCKSIZE) { | |
245 sha_transform(sha_info); | |
246 } else { | |
247 return; | |
248 } | |
249 } | |
250 while (count >= SHA_BLOCKSIZE) { | |
251 memcpy(sha_info->data, buffer, SHA_BLOCKSIZE); | |
252 buffer += SHA_BLOCKSIZE; | |
253 count -= SHA_BLOCKSIZE; | |
254 sha_transform(sha_info); | |
255 } | |
256 memcpy(sha_info->data, buffer, count); | |
257 sha_info->local = count; | |
258 } | |
259 | |
260 /* finish computing the SHA digest */ | |
261 void sha_final(SHA_INFO *sha_info, unsigned char *digest) | |
262 { | |
263 int count; | |
264 unsigned long lo_bit_count, hi_bit_count; | |
265 | |
266 lo_bit_count = sha_info->count_lo; | |
267 hi_bit_count = sha_info->count_hi; | |
268 count = (int) ((lo_bit_count >> 3) & 0x3f); | |
269 sha_info->data[count++] = 0x80; | |
270 if (count > SHA_BLOCKSIZE - 8) { | |
271 memset(sha_info->data + count, 0, SHA_BLOCKSIZE - count); | |
272 sha_transform(sha_info); | |
273 memset(sha_info->data, 0, SHA_BLOCKSIZE - 8); | |
274 } else { | |
275 memset(sha_info->data + count, 0, | |
276 SHA_BLOCKSIZE - 8 - count); | |
277 } | |
278 sha_info->data[56] = (unsigned char) ((hi_bit_count >> 24) & 0xff); | |
279 sha_info->data[57] = (unsigned char) ((hi_bit_count >> 16) & 0xff); | |
280 sha_info->data[58] = (unsigned char) ((hi_bit_count >> 8) & 0xff); | |
281 sha_info->data[59] = (unsigned char) ((hi_bit_count >> 0) & 0xff); | |
282 sha_info->data[60] = (unsigned char) ((lo_bit_count >> 24) & 0xff); | |
283 sha_info->data[61] = (unsigned char) ((lo_bit_count >> 16) & 0xff); | |
284 sha_info->data[62] = (unsigned char) ((lo_bit_count >> 8) & 0xff); | |
285 sha_info->data[63] = (unsigned char) ((lo_bit_count >> 0) & 0xff); | |
286 sha_transform(sha_info); | |
287 digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff); | |
288 digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff); | |
289 digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 8) & 0xff); | |
290 digest[ 3] = (unsigned char) ((sha_info->digest[0] ) & 0xff); | |
291 digest[ 4] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff); | |
292 digest[ 5] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff); | |
293 digest[ 6] = (unsigned char) ((sha_info->digest[1] >> 8) & 0xff); | |
294 digest[ 7] = (unsigned char) ((sha_info->digest[1] ) & 0xff); | |
295 digest[ 8] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff); | |
296 digest[ 9] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff); | |
297 digest[10] = (unsigned char) ((sha_info->digest[2] >> 8) & 0xff); | |
298 digest[11] = (unsigned char) ((sha_info->digest[2] ) & 0xff); | |
299 digest[12] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff); | |
300 digest[13] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff); | |
301 digest[14] = (unsigned char) ((sha_info->digest[3] >> 8) & 0xff); | |
302 digest[15] = (unsigned char) ((sha_info->digest[3] ) & 0xff); | |
303 digest[16] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff); | |
304 digest[17] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff); | |
305 digest[18] = (unsigned char) ((sha_info->digest[4] >> 8) & 0xff); | |
306 digest[19] = (unsigned char) ((sha_info->digest[4] ) & 0xff); | |
307 } | |
308 | |
309 /*****************************************************************************/ | |
310 | |
311 #define BLOCK_SIZE 8192 | |
312 | |
313 #if 0 | |
314 /* compute the SHA digest of a FILE stream */ | |
315 static void sha_stream(unsigned char digest[20], SHA_INFO *sha_info, FILE *fin) | |
316 { | |
317 int i; | |
318 uint8_t data[BLOCK_SIZE]; | |
319 | |
320 sha_init(sha_info); | |
321 while ((i = fread(data, 1, BLOCK_SIZE, fin)) > 0) { | |
322 sha_update(sha_info, data, i); | |
323 } | |
324 sha_final(sha_info, digest); | |
325 } | |
326 | |
327 /* print a SHA digest */ | |
328 static void sha_print(unsigned char digest[20]) | |
329 { | |
330 int i, j; | |
331 | |
332 for (j = 0; j < 5; ++j) { | |
333 for (i = 0; i < 4; ++i) { | |
334 printf("%02x", *digest++); | |
335 } | |
336 printf("%c", (j < 4) ? ' ' : '\n'); | |
337 } | |
338 } | |
339 #endif | |
340 | |
341 /*****************************************************************************/ | |
342 | |
343 /* | |
344 * Hash a file with the sha1 algorithm using fread. Hash the whole file if | |
345 * size == 0. | |
346 */ | |
347 static unsigned char *sha1_hash_fread (const char *file, off_t size) | |
348 { | |
349 FILE *f; | |
350 unsigned char *hash; | |
351 sha1_state_t state; | |
352 off_t len; | |
353 ssize_t n; | |
354 struct stat st; | |
355 char buf[BLOCK_SIZE]; | |
356 | |
357 if (!(f = fopen (file, "rb"))) | |
358 return NULL; | |
359 | |
360 sha_init (&state); | |
361 | |
362 if (stat (file, &st) == -1) | |
363 { | |
364 fclose (f); | |
365 return NULL; | |
366 } | |
367 | |
368 if (size == 0) | |
369 size = st.st_size; | |
370 | |
371 while (size > 0) | |
372 { | |
373 len = MIN (sizeof (buf), size); | |
374 | |
375 n = fread (buf, 1, len, f); | |
376 | |
377 if (n == 0 || n != len) | |
378 break; | |
379 | |
380 sha_update (&state, (unsigned char *) buf, len); | |
381 size -= len; | |
382 } | |
383 | |
384 fclose (f); | |
385 | |
386 if (size != 0) | |
387 return NULL; | |
388 | |
389 if ((hash = malloc (SHA1_BINSIZE))) | |
390 sha_final (&state, hash); | |
391 | |
392 return hash; | |
393 } | |
394 | |
395 /*****************************************************************************/ | |
396 | |
397 /* return a base32 representation of a sha1 hash */ | |
398 char *sha1_string (const unsigned char *sha1) | |
399 { | |
400 char *base32; | |
401 | |
402 base32 = malloc (SHA1_STRLEN + 1); | |
403 | |
404 if (!base32) | |
405 return NULL; | |
406 | |
407 gt_base32_encode (sha1, SHA1_BINSIZE, base32, SHA1_STRLEN); | |
408 base32[32] = 0; | |
409 | |
410 return base32; | |
411 } | |
412 | |
413 /*****************************************************************************/ | |
414 | |
415 unsigned char *sha1_bin (const char *ascii) | |
416 { | |
417 unsigned char *bin; | |
418 size_t len; | |
419 | |
420 /* TODO: maybe this should copy the string and pad up to the min length if | |
421 * it's less than 32? */ | |
422 len = strlen (ascii); | |
423 assert (len >= SHA1_STRLEN); | |
424 | |
425 if (!gt_base32_valid (ascii, SHA1_STRLEN)) | |
426 return NULL; | |
427 | |
428 if (!(bin = malloc (SHA1_BINSIZE))) | |
429 return NULL; | |
430 | |
431 gt_base32_decode (ascii, SHA1_STRLEN, bin, SHA1_BINSIZE); | |
432 return bin; | |
433 } | |
434 | |
435 /*****************************************************************************/ | |
436 | |
437 unsigned char *sha1_digest (const char *file, off_t size) | |
438 { | |
439 unsigned char *hash; | |
440 | |
441 if (!file) | |
442 return NULL; | |
443 | |
444 hash = sha1_hash_fread (file, size); | |
445 | |
446 return hash; | |
447 } | |
448 | |
449 unsigned char *sha1_dup (const unsigned char *sha1) | |
450 { | |
451 unsigned char *new_sha1; | |
452 | |
453 if (!(new_sha1 = malloc (SHA1_BINSIZE))) | |
454 return NULL; | |
455 | |
456 memcpy (new_sha1, sha1, SHA1_BINSIZE); | |
457 | |
458 return new_sha1; | |
459 } | |
460 | |
461 /*****************************************************************************/ | |
462 | |
463 #if 0 | |
464 #include <libgen.h> | |
465 | |
466 int main (int argc, char **argv) | |
467 { | |
468 int i; | |
469 | |
470 for (i = 1; i < argc; i++) | |
471 { | |
472 unsigned char *bin; | |
473 char *str; | |
474 | |
475 if (!(bin = sha1_digest (argv[i], 0))) | |
476 { | |
477 perror ("sha1_digest"); | |
478 continue; | |
479 } | |
480 | |
481 if ((str = sha1_string (bin))) | |
482 printf ("%s\t%s\n", basename (argv[i]), str); | |
483 | |
484 free (str); | |
485 free (bin); | |
486 } | |
487 | |
488 return 0; | |
489 } | |
490 #endif |