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