annotate src/sha1.c @ 0:d39e1d0d75b6

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