Mercurial > hg > index.fcgi > gift-gnutella > gift-gnutella-0.0.11-1pba
diff src/sha1.c @ 0:d39e1d0d75b6
initial add
author | paulo@hit-nxdomain.opendns.com |
---|---|
date | Sat, 20 Feb 2010 21:18:28 -0800 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/sha1.c Sat Feb 20 21:18:28 2010 -0800 1.3 @@ -0,0 +1,490 @@ 1.4 +/* 1.5 + * $Id: sha1.c,v 1.18 2006/07/09 13:05:20 mkern Exp $ 1.6 + * 1.7 + * (PD) 2001 The Bitzi Corporation 1.8 + * Please see http://bitzi.com/publicdomain for more info. 1.9 + * 1.10 + * NIST Secure Hash Algorithm 1.11 + * heavily modified by Uwe Hollerbach <uh@alumni.caltech edu> 1.12 + * from Peter C. Gutmann's implementation as found in 1.13 + * Applied Cryptography by Bruce Schneier 1.14 + * Further modifications to include the "UNRAVEL" stuff, below 1.15 + * 1.16 + * New, faster sha1 code. The original code was from Bitzi corporation, and 1.17 + * was in the public domain. [The original header is included.] 1.18 + * 1.19 + * This code is in the public domain. 1.20 + */ 1.21 + 1.22 +#include <string.h> 1.23 +#include <stdio.h> 1.24 + 1.25 +#include "gt_gnutella.h" 1.26 + 1.27 +#include "sha1.h" 1.28 +#include "encoding/base32.h" 1.29 + 1.30 +/*****************************************************************************/ 1.31 + 1.32 +typedef struct sha1_state SHA_INFO; 1.33 + 1.34 +/* define the functions to names private to this plugin */ 1.35 +#define sha_init gt_sha1_init 1.36 +#define sha_update gt_sha1_append 1.37 +#define sha_final gt_sha1_finish 1.38 + 1.39 +/*****************************************************************************/ 1.40 + 1.41 +void sha_init(SHA_INFO *); 1.42 +void sha_update(SHA_INFO *, const void *, size_t); 1.43 +void sha_final(SHA_INFO *, unsigned char [20]); 1.44 + 1.45 +/*****************************************************************************/ 1.46 + 1.47 +/* SHA f()-functions */ 1.48 + 1.49 +#define f1(x,y,z) ((x & y) | (~x & z)) 1.50 +#define f2(x,y,z) (x ^ y ^ z) 1.51 +#define f3(x,y,z) ((x & y) | (x & z) | (y & z)) 1.52 +#define f4(x,y,z) (x ^ y ^ z) 1.53 + 1.54 +/* SHA constants */ 1.55 + 1.56 +#define CONST1 0x5a827999L 1.57 +#define CONST2 0x6ed9eba1L 1.58 +#define CONST3 0x8f1bbcdcL 1.59 +#define CONST4 0xca62c1d6L 1.60 + 1.61 +/* truncate to 32 bits -- should be a null op on 32-bit machines */ 1.62 + 1.63 +#define T32(x) ((x) & 0xffffffffL) 1.64 + 1.65 +/* 32-bit rotate */ 1.66 + 1.67 +#define R32(x,n) T32(((x << n) | (x >> (32 - n)))) 1.68 + 1.69 +/* the generic case, for when the overall rotation is not unraveled */ 1.70 + 1.71 +#define FG(n) \ 1.72 + T = T32(R32(A,5) + f##n(B,C,D) + E + *WP++ + CONST##n); \ 1.73 + E = D; D = C; C = R32(B,30); B = A; A = T 1.74 + 1.75 +/* specific cases, for when the overall rotation is unraveled */ 1.76 + 1.77 +#define FA(n) \ 1.78 + T = T32(R32(A,5) + f##n(B,C,D) + E + *WP++ + CONST##n); B = R32(B,30) 1.79 + 1.80 +#define FB(n) \ 1.81 + E = T32(R32(T,5) + f##n(A,B,C) + D + *WP++ + CONST##n); A = R32(A,30) 1.82 + 1.83 +#define FC(n) \ 1.84 + D = T32(R32(E,5) + f##n(T,A,B) + C + *WP++ + CONST##n); T = R32(T,30) 1.85 + 1.86 +#define FD(n) \ 1.87 + C = T32(R32(D,5) + f##n(E,T,A) + B + *WP++ + CONST##n); E = R32(E,30) 1.88 + 1.89 +#define FE(n) \ 1.90 + B = T32(R32(C,5) + f##n(D,E,T) + A + *WP++ + CONST##n); D = R32(D,30) 1.91 + 1.92 +#define FT(n) \ 1.93 + A = T32(R32(B,5) + f##n(C,D,E) + T + *WP++ + CONST##n); C = R32(C,30) 1.94 + 1.95 +/*****************************************************************************/ 1.96 + 1.97 +#ifndef WIN32 1.98 + 1.99 +/* sigh */ 1.100 +#ifdef WORDS_BIGENDIAN 1.101 +# if SIZEOF_LONG == 4 1.102 +# define SHA_BYTE_ORDER 4321 1.103 +# elif SIZEOF_LONG == 8 1.104 +# define SHA_BYTE_ORDER 87654321 1.105 +# endif 1.106 +#else 1.107 +# if SIZEOF_LONG == 4 1.108 +# define SHA_BYTE_ORDER 1234 1.109 +# elif SIZEOF_LONG == 8 1.110 +# define SHA_BYTE_ORDER 12345678 1.111 +# endif 1.112 +#endif 1.113 + 1.114 +#else /* WIN32 */ 1.115 + 1.116 +#define SHA_BYTE_ORDER 1234 1.117 + 1.118 +#endif /* !WIN32 */ 1.119 + 1.120 + 1.121 +/* do SHA transformation */ 1.122 +static void sha_transform(SHA_INFO *sha_info) 1.123 +{ 1.124 + int i; 1.125 + uint8_t *dp; 1.126 + unsigned long T, A, B, C, D, E, W[80], *WP; 1.127 + 1.128 + dp = sha_info->data; 1.129 + 1.130 +/* 1.131 +the following makes sure that at least one code block below is 1.132 +traversed or an error is reported, without the necessity for nested 1.133 +preprocessor if/else/endif blocks, which are a great pain in the 1.134 +nether regions of the anatomy... 1.135 +*/ 1.136 +#undef SWAP_DONE 1.137 + 1.138 +#if (SHA_BYTE_ORDER == 1234) 1.139 +#define SWAP_DONE 1.140 + for (i = 0; i < 16; ++i) { 1.141 + T = *((unsigned long *) dp); 1.142 + dp += 4; 1.143 + W[i] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) | 1.144 + ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff); 1.145 + } 1.146 +#endif /* SHA_BYTE_ORDER == 1234 */ 1.147 + 1.148 +#if (SHA_BYTE_ORDER == 4321) 1.149 +#define SWAP_DONE 1.150 + for (i = 0; i < 16; ++i) { 1.151 + T = *((unsigned long *) dp); 1.152 + dp += 4; 1.153 + W[i] = T32(T); 1.154 + } 1.155 +#endif /* SHA_BYTE_ORDER == 4321 */ 1.156 + 1.157 +#if (SHA_BYTE_ORDER == 12345678) 1.158 +#define SWAP_DONE 1.159 + for (i = 0; i < 16; i += 2) { 1.160 + T = *((unsigned long *) dp); 1.161 + dp += 8; 1.162 + W[i] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) | 1.163 + ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff); 1.164 + T >>= 32; 1.165 + W[i+1] = ((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) | 1.166 + ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff); 1.167 + } 1.168 +#endif /* SHA_BYTE_ORDER == 12345678 */ 1.169 + 1.170 +#if (SHA_BYTE_ORDER == 87654321) 1.171 +#define SWAP_DONE 1.172 + for (i = 0; i < 16; i += 2) { 1.173 + T = *((unsigned long *) dp); 1.174 + dp += 8; 1.175 + W[i] = T32(T >> 32); 1.176 + W[i+1] = T32(T); 1.177 + } 1.178 +#endif /* SHA_BYTE_ORDER == 87654321 */ 1.179 + 1.180 +#ifndef SWAP_DONE 1.181 +#error Unknown byte order -- you need to add code here 1.182 +#endif /* SWAP_DONE */ 1.183 + 1.184 + for (i = 16; i < 80; ++i) { 1.185 + W[i] = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16]; 1.186 + W[i] = R32(W[i], 1); 1.187 + } 1.188 + 1.189 + A = sha_info->digest[0]; 1.190 + B = sha_info->digest[1]; 1.191 + C = sha_info->digest[2]; 1.192 + D = sha_info->digest[3]; 1.193 + E = sha_info->digest[4]; 1.194 + WP = W; 1.195 + 1.196 + FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1); FC(1); FD(1); 1.197 + FE(1); FT(1); FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1); 1.198 + FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2); FE(2); FT(2); 1.199 + FA(2); FB(2); FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2); 1.200 + FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3); FA(3); FB(3); 1.201 + FC(3); FD(3); FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3); 1.202 + FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4); FC(4); FD(4); 1.203 + FE(4); FT(4); FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4); 1.204 + 1.205 + sha_info->digest[0] = T32(sha_info->digest[0] + E); 1.206 + sha_info->digest[1] = T32(sha_info->digest[1] + T); 1.207 + sha_info->digest[2] = T32(sha_info->digest[2] + A); 1.208 + sha_info->digest[3] = T32(sha_info->digest[3] + B); 1.209 + sha_info->digest[4] = T32(sha_info->digest[4] + C); 1.210 +} 1.211 + 1.212 +/* initialize the SHA digest */ 1.213 +void sha_init(SHA_INFO *sha_info) 1.214 +{ 1.215 + sha_info->digest[0] = 0x67452301L; 1.216 + sha_info->digest[1] = 0xefcdab89L; 1.217 + sha_info->digest[2] = 0x98badcfeL; 1.218 + sha_info->digest[3] = 0x10325476L; 1.219 + sha_info->digest[4] = 0xc3d2e1f0L; 1.220 + sha_info->count_lo = 0L; 1.221 + sha_info->count_hi = 0L; 1.222 + sha_info->local = 0; 1.223 +} 1.224 + 1.225 +/* update the SHA digest */ 1.226 +void sha_update(SHA_INFO *sha_info, const void *data, size_t count) 1.227 +{ 1.228 + int i; 1.229 + unsigned long clo; 1.230 + const uint8_t *buffer = data; 1.231 + 1.232 + clo = T32(sha_info->count_lo + ((unsigned long) count << 3)); 1.233 + if (clo < sha_info->count_lo) { 1.234 + ++sha_info->count_hi; 1.235 + } 1.236 + sha_info->count_lo = clo; 1.237 + sha_info->count_hi += (unsigned long) count >> 29; 1.238 + if (sha_info->local) { 1.239 + i = SHA_BLOCKSIZE - sha_info->local; 1.240 + if (i > count) { 1.241 + i = count; 1.242 + } 1.243 + memcpy(sha_info->data + sha_info->local, buffer, i); 1.244 + count -= i; 1.245 + buffer += i; 1.246 + sha_info->local += i; 1.247 + if (sha_info->local == SHA_BLOCKSIZE) { 1.248 + sha_transform(sha_info); 1.249 + } else { 1.250 + return; 1.251 + } 1.252 + } 1.253 + while (count >= SHA_BLOCKSIZE) { 1.254 + memcpy(sha_info->data, buffer, SHA_BLOCKSIZE); 1.255 + buffer += SHA_BLOCKSIZE; 1.256 + count -= SHA_BLOCKSIZE; 1.257 + sha_transform(sha_info); 1.258 + } 1.259 + memcpy(sha_info->data, buffer, count); 1.260 + sha_info->local = count; 1.261 +} 1.262 + 1.263 +/* finish computing the SHA digest */ 1.264 +void sha_final(SHA_INFO *sha_info, unsigned char *digest) 1.265 +{ 1.266 + int count; 1.267 + unsigned long lo_bit_count, hi_bit_count; 1.268 + 1.269 + lo_bit_count = sha_info->count_lo; 1.270 + hi_bit_count = sha_info->count_hi; 1.271 + count = (int) ((lo_bit_count >> 3) & 0x3f); 1.272 + sha_info->data[count++] = 0x80; 1.273 + if (count > SHA_BLOCKSIZE - 8) { 1.274 + memset(sha_info->data + count, 0, SHA_BLOCKSIZE - count); 1.275 + sha_transform(sha_info); 1.276 + memset(sha_info->data, 0, SHA_BLOCKSIZE - 8); 1.277 + } else { 1.278 + memset(sha_info->data + count, 0, 1.279 + SHA_BLOCKSIZE - 8 - count); 1.280 + } 1.281 + sha_info->data[56] = (unsigned char) ((hi_bit_count >> 24) & 0xff); 1.282 + sha_info->data[57] = (unsigned char) ((hi_bit_count >> 16) & 0xff); 1.283 + sha_info->data[58] = (unsigned char) ((hi_bit_count >> 8) & 0xff); 1.284 + sha_info->data[59] = (unsigned char) ((hi_bit_count >> 0) & 0xff); 1.285 + sha_info->data[60] = (unsigned char) ((lo_bit_count >> 24) & 0xff); 1.286 + sha_info->data[61] = (unsigned char) ((lo_bit_count >> 16) & 0xff); 1.287 + sha_info->data[62] = (unsigned char) ((lo_bit_count >> 8) & 0xff); 1.288 + sha_info->data[63] = (unsigned char) ((lo_bit_count >> 0) & 0xff); 1.289 + sha_transform(sha_info); 1.290 + digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff); 1.291 + digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff); 1.292 + digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 8) & 0xff); 1.293 + digest[ 3] = (unsigned char) ((sha_info->digest[0] ) & 0xff); 1.294 + digest[ 4] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff); 1.295 + digest[ 5] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff); 1.296 + digest[ 6] = (unsigned char) ((sha_info->digest[1] >> 8) & 0xff); 1.297 + digest[ 7] = (unsigned char) ((sha_info->digest[1] ) & 0xff); 1.298 + digest[ 8] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff); 1.299 + digest[ 9] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff); 1.300 + digest[10] = (unsigned char) ((sha_info->digest[2] >> 8) & 0xff); 1.301 + digest[11] = (unsigned char) ((sha_info->digest[2] ) & 0xff); 1.302 + digest[12] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff); 1.303 + digest[13] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff); 1.304 + digest[14] = (unsigned char) ((sha_info->digest[3] >> 8) & 0xff); 1.305 + digest[15] = (unsigned char) ((sha_info->digest[3] ) & 0xff); 1.306 + digest[16] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff); 1.307 + digest[17] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff); 1.308 + digest[18] = (unsigned char) ((sha_info->digest[4] >> 8) & 0xff); 1.309 + digest[19] = (unsigned char) ((sha_info->digest[4] ) & 0xff); 1.310 +} 1.311 + 1.312 +/*****************************************************************************/ 1.313 + 1.314 +#define BLOCK_SIZE 8192 1.315 + 1.316 +#if 0 1.317 +/* compute the SHA digest of a FILE stream */ 1.318 +static void sha_stream(unsigned char digest[20], SHA_INFO *sha_info, FILE *fin) 1.319 +{ 1.320 + int i; 1.321 + uint8_t data[BLOCK_SIZE]; 1.322 + 1.323 + sha_init(sha_info); 1.324 + while ((i = fread(data, 1, BLOCK_SIZE, fin)) > 0) { 1.325 + sha_update(sha_info, data, i); 1.326 + } 1.327 + sha_final(sha_info, digest); 1.328 +} 1.329 + 1.330 +/* print a SHA digest */ 1.331 +static void sha_print(unsigned char digest[20]) 1.332 +{ 1.333 + int i, j; 1.334 + 1.335 + for (j = 0; j < 5; ++j) { 1.336 + for (i = 0; i < 4; ++i) { 1.337 + printf("%02x", *digest++); 1.338 + } 1.339 + printf("%c", (j < 4) ? ' ' : '\n'); 1.340 + } 1.341 +} 1.342 +#endif 1.343 + 1.344 +/*****************************************************************************/ 1.345 + 1.346 +/* 1.347 + * Hash a file with the sha1 algorithm using fread. Hash the whole file if 1.348 + * size == 0. 1.349 + */ 1.350 +static unsigned char *sha1_hash_fread (const char *file, off_t size) 1.351 +{ 1.352 + FILE *f; 1.353 + unsigned char *hash; 1.354 + sha1_state_t state; 1.355 + off_t len; 1.356 + ssize_t n; 1.357 + struct stat st; 1.358 + char buf[BLOCK_SIZE]; 1.359 + 1.360 + if (!(f = fopen (file, "rb"))) 1.361 + return NULL; 1.362 + 1.363 + sha_init (&state); 1.364 + 1.365 + if (stat (file, &st) == -1) 1.366 + { 1.367 + fclose (f); 1.368 + return NULL; 1.369 + } 1.370 + 1.371 + if (size == 0) 1.372 + size = st.st_size; 1.373 + 1.374 + while (size > 0) 1.375 + { 1.376 + len = MIN (sizeof (buf), size); 1.377 + 1.378 + n = fread (buf, 1, len, f); 1.379 + 1.380 + if (n == 0 || n != len) 1.381 + break; 1.382 + 1.383 + sha_update (&state, (unsigned char *) buf, len); 1.384 + size -= len; 1.385 + } 1.386 + 1.387 + fclose (f); 1.388 + 1.389 + if (size != 0) 1.390 + return NULL; 1.391 + 1.392 + if ((hash = malloc (SHA1_BINSIZE))) 1.393 + sha_final (&state, hash); 1.394 + 1.395 + return hash; 1.396 +} 1.397 + 1.398 +/*****************************************************************************/ 1.399 + 1.400 +/* return a base32 representation of a sha1 hash */ 1.401 +char *sha1_string (const unsigned char *sha1) 1.402 +{ 1.403 + char *base32; 1.404 + 1.405 + base32 = malloc (SHA1_STRLEN + 1); 1.406 + 1.407 + if (!base32) 1.408 + return NULL; 1.409 + 1.410 + gt_base32_encode (sha1, SHA1_BINSIZE, base32, SHA1_STRLEN); 1.411 + base32[32] = 0; 1.412 + 1.413 + return base32; 1.414 +} 1.415 + 1.416 +/*****************************************************************************/ 1.417 + 1.418 +unsigned char *sha1_bin (const char *ascii) 1.419 +{ 1.420 + unsigned char *bin; 1.421 + size_t len; 1.422 + 1.423 + /* TODO: maybe this should copy the string and pad up to the min length if 1.424 + * it's less than 32? */ 1.425 + len = strlen (ascii); 1.426 + assert (len >= SHA1_STRLEN); 1.427 + 1.428 + if (!gt_base32_valid (ascii, SHA1_STRLEN)) 1.429 + return NULL; 1.430 + 1.431 + if (!(bin = malloc (SHA1_BINSIZE))) 1.432 + return NULL; 1.433 + 1.434 + gt_base32_decode (ascii, SHA1_STRLEN, bin, SHA1_BINSIZE); 1.435 + return bin; 1.436 +} 1.437 + 1.438 +/*****************************************************************************/ 1.439 + 1.440 +unsigned char *sha1_digest (const char *file, off_t size) 1.441 +{ 1.442 + unsigned char *hash; 1.443 + 1.444 + if (!file) 1.445 + return NULL; 1.446 + 1.447 + hash = sha1_hash_fread (file, size); 1.448 + 1.449 + return hash; 1.450 +} 1.451 + 1.452 +unsigned char *sha1_dup (const unsigned char *sha1) 1.453 +{ 1.454 + unsigned char *new_sha1; 1.455 + 1.456 + if (!(new_sha1 = malloc (SHA1_BINSIZE))) 1.457 + return NULL; 1.458 + 1.459 + memcpy (new_sha1, sha1, SHA1_BINSIZE); 1.460 + 1.461 + return new_sha1; 1.462 +} 1.463 + 1.464 +/*****************************************************************************/ 1.465 + 1.466 +#if 0 1.467 +#include <libgen.h> 1.468 + 1.469 +int main (int argc, char **argv) 1.470 +{ 1.471 + int i; 1.472 + 1.473 + for (i = 1; i < argc; i++) 1.474 + { 1.475 + unsigned char *bin; 1.476 + char *str; 1.477 + 1.478 + if (!(bin = sha1_digest (argv[i], 0))) 1.479 + { 1.480 + perror ("sha1_digest"); 1.481 + continue; 1.482 + } 1.483 + 1.484 + if ((str = sha1_string (bin))) 1.485 + printf ("%s\t%s\n", basename (argv[i]), str); 1.486 + 1.487 + free (str); 1.488 + free (bin); 1.489 + } 1.490 + 1.491 + return 0; 1.492 +} 1.493 +#endif