18b77a77e785f0e25b13016ed60770e521dc60e0bLogan/* This file is derived from libdex project */
28b77a77e785f0e25b13016ed60770e521dc60e0bLogan
38b77a77e785f0e25b13016ed60770e521dc60e0bLogan/*
48b77a77e785f0e25b13016ed60770e521dc60e0bLogan * Tweaked in various ways for Google/Android:
58b77a77e785f0e25b13016ed60770e521dc60e0bLogan *  - Changed from .cpp to .c.
68b77a77e785f0e25b13016ed60770e521dc60e0bLogan *  - Made argument to SHA1Update a const pointer, and enabled
78b77a77e785f0e25b13016ed60770e521dc60e0bLogan *    SHA1HANDSOFF.  This incurs a speed penalty but prevents us from
88b77a77e785f0e25b13016ed60770e521dc60e0bLogan *    trashing the input.
98b77a77e785f0e25b13016ed60770e521dc60e0bLogan *  - Include <endian.h> to get endian info.
108b77a77e785f0e25b13016ed60770e521dc60e0bLogan *  - Split a small piece into a header file.
118b77a77e785f0e25b13016ed60770e521dc60e0bLogan */
128b77a77e785f0e25b13016ed60770e521dc60e0bLogan
138b77a77e785f0e25b13016ed60770e521dc60e0bLogan/*
148b77a77e785f0e25b13016ed60770e521dc60e0bLogansha1sum: inspired by md5sum.
158b77a77e785f0e25b13016ed60770e521dc60e0bLogan
168b77a77e785f0e25b13016ed60770e521dc60e0bLoganSHA-1 in C
178b77a77e785f0e25b13016ed60770e521dc60e0bLoganBy Steve Reid <steve@edmweb.com>
188b77a77e785f0e25b13016ed60770e521dc60e0bLogan100% Public Domain
198b77a77e785f0e25b13016ed60770e521dc60e0bLogan
208b77a77e785f0e25b13016ed60770e521dc60e0bLogan-----------------
218b77a77e785f0e25b13016ed60770e521dc60e0bLoganModified 7/98
228b77a77e785f0e25b13016ed60770e521dc60e0bLoganBy James H. Brown <jbrown@burgoyne.com>
238b77a77e785f0e25b13016ed60770e521dc60e0bLoganStill 100% Public Domain
248b77a77e785f0e25b13016ed60770e521dc60e0bLogan
258b77a77e785f0e25b13016ed60770e521dc60e0bLoganbit machines
268b77a77e785f0e25b13016ed60770e521dc60e0bLoganRoutine SHA1Update changed from
278b77a77e785f0e25b13016ed60770e521dc60e0bLogan    void SHA1Update(SHA1_CTX* context, unsigned char* data,
288b77a77e785f0e25b13016ed60770e521dc60e0bLogan      unsigned int len)
298b77a77e785f0e25b13016ed60770e521dc60e0bLoganto
308b77a77e785f0e25b13016ed60770e521dc60e0bLogan    void SHA1Update(SHA1_CTX* context, unsigned char* data,
318b77a77e785f0e25b13016ed60770e521dc60e0bLogan      unsigned long len)
328b77a77e785f0e25b13016ed60770e521dc60e0bLogan
338b77a77e785f0e25b13016ed60770e521dc60e0bLoganThe 'len' parameter was declared an int which works fine on 32
348b77a77e785f0e25b13016ed60770e521dc60e0bLoganbit machines. However, on 16 bit machines an int is too small
358b77a77e785f0e25b13016ed60770e521dc60e0bLoganfor the shifts being done against it.  This caused the hash
368b77a77e785f0e25b13016ed60770e521dc60e0bLoganfunction to generate incorrect values if len was greater than
378b77a77e785f0e25b13016ed60770e521dc60e0bLogan8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
388b77a77e785f0e25b13016ed60770e521dc60e0bLogan
398b77a77e785f0e25b13016ed60770e521dc60e0bLoganSince the file IO in main() reads 16K at a time, any file 8K or
408b77a77e785f0e25b13016ed60770e521dc60e0bLoganlarger would be guaranteed to generate the wrong hash (e.g.
418b77a77e785f0e25b13016ed60770e521dc60e0bLoganTest Vector #3, a million "a"s).
428b77a77e785f0e25b13016ed60770e521dc60e0bLogan
438b77a77e785f0e25b13016ed60770e521dc60e0bLoganI also changed the declaration of variables i & j in SHA1Update
448b77a77e785f0e25b13016ed60770e521dc60e0bLoganto unsigned long from unsigned int for the same reason.
458b77a77e785f0e25b13016ed60770e521dc60e0bLogan
468b77a77e785f0e25b13016ed60770e521dc60e0bLoganThese changes should make no difference to any 32 bit
478b77a77e785f0e25b13016ed60770e521dc60e0bLoganimplementations since an int and a long are the same size in
488b77a77e785f0e25b13016ed60770e521dc60e0bLoganthose environments.
498b77a77e785f0e25b13016ed60770e521dc60e0bLogan
508b77a77e785f0e25b13016ed60770e521dc60e0bLogan--
518b77a77e785f0e25b13016ed60770e521dc60e0bLoganI also corrected a few compiler warnings generated by Borland
528b77a77e785f0e25b13016ed60770e521dc60e0bLoganC.
538b77a77e785f0e25b13016ed60770e521dc60e0bLogan1. Added #include <process.h> for exit() prototype
548b77a77e785f0e25b13016ed60770e521dc60e0bLogan2. Removed unused variable 'j' in SHA1Final
558b77a77e785f0e25b13016ed60770e521dc60e0bLogan3. Changed exit(0) to return(0) at end of main.
568b77a77e785f0e25b13016ed60770e521dc60e0bLogan
578b77a77e785f0e25b13016ed60770e521dc60e0bLoganALL changes I made can be located by searching for comments
588b77a77e785f0e25b13016ed60770e521dc60e0bLogancontaining 'JHB'
598b77a77e785f0e25b13016ed60770e521dc60e0bLogan
608b77a77e785f0e25b13016ed60770e521dc60e0bLogan-----------------
618b77a77e785f0e25b13016ed60770e521dc60e0bLoganModified 13 August 2000
628b77a77e785f0e25b13016ed60770e521dc60e0bLoganBy Michael Paul Johnson <mpj@cryptography.org>
638b77a77e785f0e25b13016ed60770e521dc60e0bLoganStill 100% Public Domain
648b77a77e785f0e25b13016ed60770e521dc60e0bLogan
658b77a77e785f0e25b13016ed60770e521dc60e0bLoganChanged command line syntax, added feature to automatically
668b77a77e785f0e25b13016ed60770e521dc60e0bLogancheck files against their previous SHA-1 check values, kind of
678b77a77e785f0e25b13016ed60770e521dc60e0bLoganlike md5sum does. Added functions hexval, verifyfile,
688b77a77e785f0e25b13016ed60770e521dc60e0bLoganand sha1file. Rewrote main().
698b77a77e785f0e25b13016ed60770e521dc60e0bLogan-----------------
708b77a77e785f0e25b13016ed60770e521dc60e0bLogan
718b77a77e785f0e25b13016ed60770e521dc60e0bLoganTest Vectors (from FIPS PUB 180-1)
728b77a77e785f0e25b13016ed60770e521dc60e0bLogan"abc"
738b77a77e785f0e25b13016ed60770e521dc60e0bLogan  A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
748b77a77e785f0e25b13016ed60770e521dc60e0bLogan"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
758b77a77e785f0e25b13016ed60770e521dc60e0bLogan  84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
768b77a77e785f0e25b13016ed60770e521dc60e0bLoganA million repetitions of "a"
778b77a77e785f0e25b13016ed60770e521dc60e0bLogan  34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
788b77a77e785f0e25b13016ed60770e521dc60e0bLogan*/
798b77a77e785f0e25b13016ed60770e521dc60e0bLogan
808b77a77e785f0e25b13016ed60770e521dc60e0bLogan#define SHA1HANDSOFF    /*Copies data before messing with it.*/
818b77a77e785f0e25b13016ed60770e521dc60e0bLogan
828b77a77e785f0e25b13016ed60770e521dc60e0bLogan/*#define CMDLINE        * include main() and file processing */
835de1adfe315bbb088f7614936b1023c6d6d3fc35Joseph Wen//#ifdef CMDLINE
845de1adfe315bbb088f7614936b1023c6d6d3fc35Joseph Wen//# undef CMDLINE         /* Never include main() for libbcc */
855de1adfe315bbb088f7614936b1023c6d6d3fc35Joseph Wen//#endif
868b77a77e785f0e25b13016ed60770e521dc60e0bLogan
878b77a77e785f0e25b13016ed60770e521dc60e0bLogan#include "sha1.h"
888b77a77e785f0e25b13016ed60770e521dc60e0bLogan
898b77a77e785f0e25b13016ed60770e521dc60e0bLogan#include <stdio.h>
908b77a77e785f0e25b13016ed60770e521dc60e0bLogan#include <string.h>
918b77a77e785f0e25b13016ed60770e521dc60e0bLogan#ifdef __BORLANDC__
928b77a77e785f0e25b13016ed60770e521dc60e0bLogan#include <dir.h>
938b77a77e785f0e25b13016ed60770e521dc60e0bLogan#include <dos.h>
948b77a77e785f0e25b13016ed60770e521dc60e0bLogan#include <process.h>   /*  prototype for exit() - JHB
958b77a77e785f0e25b13016ed60770e521dc60e0bLogan               needed for Win32, but chokes Linux - MPJ */
968b77a77e785f0e25b13016ed60770e521dc60e0bLogan#define X_LITTLE_ENDIAN /* This should be #define'd if true.*/
978b77a77e785f0e25b13016ed60770e521dc60e0bLogan#else
988b77a77e785f0e25b13016ed60770e521dc60e0bLogan# define X_LITTLE_ENDIAN
998b77a77e785f0e25b13016ed60770e521dc60e0bLogan# include <unistd.h>
1008b77a77e785f0e25b13016ed60770e521dc60e0bLogan# include <stdlib.h>
1018b77a77e785f0e25b13016ed60770e521dc60e0bLogan#endif
1028b77a77e785f0e25b13016ed60770e521dc60e0bLogan#include <ctype.h>
1038b77a77e785f0e25b13016ed60770e521dc60e0bLogan
1048b77a77e785f0e25b13016ed60770e521dc60e0bLogan#define LINESIZE 2048
1058b77a77e785f0e25b13016ed60770e521dc60e0bLogan
10673775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouilletstatic void SHA1Transform(uint32_t state[5], const uint8_t buffer[64]);
1078b77a77e785f0e25b13016ed60770e521dc60e0bLogan
1088b77a77e785f0e25b13016ed60770e521dc60e0bLogan#define rol(value,bits) \
1098b77a77e785f0e25b13016ed60770e521dc60e0bLogan (((value)<<(bits))|((value)>>(32-(bits))))
1108b77a77e785f0e25b13016ed60770e521dc60e0bLogan
1118b77a77e785f0e25b13016ed60770e521dc60e0bLogan/* blk0() and blk() perform the initial expand. */
1128b77a77e785f0e25b13016ed60770e521dc60e0bLogan/* I got the idea of expanding during the round function from
1138b77a77e785f0e25b13016ed60770e521dc60e0bLogan   SSLeay */
1148b77a77e785f0e25b13016ed60770e521dc60e0bLogan#ifdef X_LITTLE_ENDIAN
1158b77a77e785f0e25b13016ed60770e521dc60e0bLogan#define blk0(i) (block->l[i]=(rol(block->l[i],24)&0xFF00FF00) \
1168b77a77e785f0e25b13016ed60770e521dc60e0bLogan    |(rol(block->l[i],8)&0x00FF00FF))
1178b77a77e785f0e25b13016ed60770e521dc60e0bLogan#else
1188b77a77e785f0e25b13016ed60770e521dc60e0bLogan#define blk0(i) block->l[i]
1198b77a77e785f0e25b13016ed60770e521dc60e0bLogan#endif
1208b77a77e785f0e25b13016ed60770e521dc60e0bLogan#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
1218b77a77e785f0e25b13016ed60770e521dc60e0bLogan    ^block->l[(i+2)&15]^block->l[i&15],1))
1228b77a77e785f0e25b13016ed60770e521dc60e0bLogan
1238b77a77e785f0e25b13016ed60770e521dc60e0bLogan/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
1248b77a77e785f0e25b13016ed60770e521dc60e0bLogan#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
1258b77a77e785f0e25b13016ed60770e521dc60e0bLogan#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
1268b77a77e785f0e25b13016ed60770e521dc60e0bLogan#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
1278b77a77e785f0e25b13016ed60770e521dc60e0bLogan#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
1288b77a77e785f0e25b13016ed60770e521dc60e0bLogan#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
1298b77a77e785f0e25b13016ed60770e521dc60e0bLogan
1308b77a77e785f0e25b13016ed60770e521dc60e0bLogan
1318b77a77e785f0e25b13016ed60770e521dc60e0bLogan/* Hash a single 512-bit block. This is the core of the algorithm. */
1328b77a77e785f0e25b13016ed60770e521dc60e0bLogan
13373775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouilletstatic void SHA1Transform(uint32_t state[5],
13473775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouillet    const uint8_t buffer[64])
1358b77a77e785f0e25b13016ed60770e521dc60e0bLogan{
13673775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouilletuint32_t a, b, c, d, e;
1378b77a77e785f0e25b13016ed60770e521dc60e0bLogantypedef union {
13873775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouillet    uint8_t c[64];
13973775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouillet    uint32_t l[16];
1408b77a77e785f0e25b13016ed60770e521dc60e0bLogan} CHAR64LONG16;
1418b77a77e785f0e25b13016ed60770e521dc60e0bLoganCHAR64LONG16* block;
1428b77a77e785f0e25b13016ed60770e521dc60e0bLogan#ifdef SHA1HANDSOFF
14373775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouilletstatic uint8_t workspace[64];
1448b77a77e785f0e25b13016ed60770e521dc60e0bLogan    block = (CHAR64LONG16*)workspace;
1458b77a77e785f0e25b13016ed60770e521dc60e0bLogan    memcpy(block, buffer, 64);
1468b77a77e785f0e25b13016ed60770e521dc60e0bLogan#else
1478b77a77e785f0e25b13016ed60770e521dc60e0bLogan    block = (CHAR64LONG16*)buffer;
1488b77a77e785f0e25b13016ed60770e521dc60e0bLogan#endif
1498b77a77e785f0e25b13016ed60770e521dc60e0bLogan    /* Copy context->state[] to working vars */
1508b77a77e785f0e25b13016ed60770e521dc60e0bLogan    a = state[0];
1518b77a77e785f0e25b13016ed60770e521dc60e0bLogan    b = state[1];
1528b77a77e785f0e25b13016ed60770e521dc60e0bLogan    c = state[2];
1538b77a77e785f0e25b13016ed60770e521dc60e0bLogan    d = state[3];
1548b77a77e785f0e25b13016ed60770e521dc60e0bLogan    e = state[4];
1558b77a77e785f0e25b13016ed60770e521dc60e0bLogan    /* 4 rounds of 20 operations each. Loop unrolled. */
1568b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2);
1578b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R0(c,d,e,a,b, 3); R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5);
1588b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); R0(c,d,e,a,b, 8);
1598b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
1608b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14);
1618b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R0(a,b,c,d,e,15); R1(e,a,b,c,d,16); R1(d,e,a,b,c,17);
1628b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); R2(a,b,c,d,e,20);
1638b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
1648b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26);
1658b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R2(d,e,a,b,c,27); R2(c,d,e,a,b,28); R2(b,c,d,e,a,29);
1668b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); R2(d,e,a,b,c,32);
1678b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
1688b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38);
1698b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R2(b,c,d,e,a,39); R3(a,b,c,d,e,40); R3(e,a,b,c,d,41);
1708b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); R3(b,c,d,e,a,44);
1718b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
1728b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50);
1738b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R3(e,a,b,c,d,51); R3(d,e,a,b,c,52); R3(c,d,e,a,b,53);
1748b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); R3(e,a,b,c,d,56);
1758b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
1768b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62);
1778b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R4(c,d,e,a,b,63); R4(b,c,d,e,a,64); R4(a,b,c,d,e,65);
1788b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); R4(c,d,e,a,b,68);
1798b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
1808b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74);
1818b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R4(a,b,c,d,e,75); R4(e,a,b,c,d,76); R4(d,e,a,b,c,77);
1828b77a77e785f0e25b13016ed60770e521dc60e0bLogan    R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
1838b77a77e785f0e25b13016ed60770e521dc60e0bLogan
1848b77a77e785f0e25b13016ed60770e521dc60e0bLogan    /* Add the working vars back into context.state[] */
1858b77a77e785f0e25b13016ed60770e521dc60e0bLogan    state[0] += a;
1868b77a77e785f0e25b13016ed60770e521dc60e0bLogan    state[1] += b;
1878b77a77e785f0e25b13016ed60770e521dc60e0bLogan    state[2] += c;
1888b77a77e785f0e25b13016ed60770e521dc60e0bLogan    state[3] += d;
1898b77a77e785f0e25b13016ed60770e521dc60e0bLogan    state[4] += e;
1908b77a77e785f0e25b13016ed60770e521dc60e0bLogan    /* Wipe variables */
1918b77a77e785f0e25b13016ed60770e521dc60e0bLogan/*    a = b = c = d = e = 0; Nice try, but the compiler
1928b77a77e785f0e25b13016ed60770e521dc60e0bLoganoptimizes this out, anyway, and it produces an annoying
1938b77a77e785f0e25b13016ed60770e521dc60e0bLoganwarning. */
1948b77a77e785f0e25b13016ed60770e521dc60e0bLogan}
1958b77a77e785f0e25b13016ed60770e521dc60e0bLogan
1968b77a77e785f0e25b13016ed60770e521dc60e0bLogan
1978b77a77e785f0e25b13016ed60770e521dc60e0bLogan/* SHA1Init - Initialize new context */
1988b77a77e785f0e25b13016ed60770e521dc60e0bLogan
1998b77a77e785f0e25b13016ed60770e521dc60e0bLoganvoid SHA1Init(SHA1_CTX* context)
2008b77a77e785f0e25b13016ed60770e521dc60e0bLogan{
2018b77a77e785f0e25b13016ed60770e521dc60e0bLogan    /* SHA1 initialization constants */
2028b77a77e785f0e25b13016ed60770e521dc60e0bLogan    context->state[0] = 0x67452301;
2038b77a77e785f0e25b13016ed60770e521dc60e0bLogan    context->state[1] = 0xEFCDAB89;
2048b77a77e785f0e25b13016ed60770e521dc60e0bLogan    context->state[2] = 0x98BADCFE;
2058b77a77e785f0e25b13016ed60770e521dc60e0bLogan    context->state[3] = 0x10325476;
2068b77a77e785f0e25b13016ed60770e521dc60e0bLogan    context->state[4] = 0xC3D2E1F0;
2078b77a77e785f0e25b13016ed60770e521dc60e0bLogan    context->count[0] = context->count[1] = 0;
2088b77a77e785f0e25b13016ed60770e521dc60e0bLogan}
2098b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2108b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2118b77a77e785f0e25b13016ed60770e521dc60e0bLogan/* Run your data through this. */
2128b77a77e785f0e25b13016ed60770e521dc60e0bLogan
21373775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouilletvoid SHA1Update(SHA1_CTX* context, const uint8_t* data,
21473775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouillet    uint32_t len)  /* JHB */
2158b77a77e785f0e25b13016ed60770e521dc60e0bLogan{
21673775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouillet    uint32_t i, j; /* JHB */
2178b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2188b77a77e785f0e25b13016ed60770e521dc60e0bLogan    j = (context->count[0] >> 3) & 63;
2198b77a77e785f0e25b13016ed60770e521dc60e0bLogan    if ((context->count[0] += len << 3) < (len << 3))
2208b77a77e785f0e25b13016ed60770e521dc60e0bLogan        context->count[1]++;
2218b77a77e785f0e25b13016ed60770e521dc60e0bLogan    context->count[1] += (len >> 29);
2228b77a77e785f0e25b13016ed60770e521dc60e0bLogan    if ((j + len) > 63)
2238b77a77e785f0e25b13016ed60770e521dc60e0bLogan    {
2248b77a77e785f0e25b13016ed60770e521dc60e0bLogan        memcpy(&context->buffer[j], data, (i = 64-j));
2258b77a77e785f0e25b13016ed60770e521dc60e0bLogan        SHA1Transform(context->state, context->buffer);
2268b77a77e785f0e25b13016ed60770e521dc60e0bLogan        for ( ; i + 63 < len; i += 64) {
2278b77a77e785f0e25b13016ed60770e521dc60e0bLogan            SHA1Transform(context->state, &data[i]);
2288b77a77e785f0e25b13016ed60770e521dc60e0bLogan        }
2298b77a77e785f0e25b13016ed60770e521dc60e0bLogan        j = 0;
2308b77a77e785f0e25b13016ed60770e521dc60e0bLogan    }
2318b77a77e785f0e25b13016ed60770e521dc60e0bLogan    else
2328b77a77e785f0e25b13016ed60770e521dc60e0bLogan        i = 0;
2338b77a77e785f0e25b13016ed60770e521dc60e0bLogan    memcpy(&context->buffer[j], &data[i], len - i);
2348b77a77e785f0e25b13016ed60770e521dc60e0bLogan}
2358b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2368b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2378b77a77e785f0e25b13016ed60770e521dc60e0bLogan/* Add padding and return the message digest. */
2388b77a77e785f0e25b13016ed60770e521dc60e0bLogan
23973775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouilletvoid SHA1Final(uint8_t digest[HASHSIZE], SHA1_CTX*
2408b77a77e785f0e25b13016ed60770e521dc60e0bLogancontext)
2418b77a77e785f0e25b13016ed60770e521dc60e0bLogan{
24273775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouilletuint32_t i;    /* JHB */
24373775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouilletuint8_t finalcount[8];
2448b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2458b77a77e785f0e25b13016ed60770e521dc60e0bLogan    for (i = 0; i < 8; i++)
2468b77a77e785f0e25b13016ed60770e521dc60e0bLogan    {
24773775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouillet        finalcount[i] = (uint8_t)((context->count[(i>=4?
2488b77a77e785f0e25b13016ed60770e521dc60e0bLogan            0:1)]>>((3-(i&3))*8))&255);
2498b77a77e785f0e25b13016ed60770e521dc60e0bLogan        /* Endian independent */
2508b77a77e785f0e25b13016ed60770e521dc60e0bLogan    }
25173775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouillet    SHA1Update(context, (uint8_t *)"\200", 1);
2528b77a77e785f0e25b13016ed60770e521dc60e0bLogan    while ((context->count[0] & 504) != 448) {
25373775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouillet        SHA1Update(context, (uint8_t *)"\0", 1);
2548b77a77e785f0e25b13016ed60770e521dc60e0bLogan    }
2558b77a77e785f0e25b13016ed60770e521dc60e0bLogan    SHA1Update(context, finalcount, 8);
2568b77a77e785f0e25b13016ed60770e521dc60e0bLogan    /* Should cause a SHA1Transform() */
2578b77a77e785f0e25b13016ed60770e521dc60e0bLogan    for (i = 0; i < HASHSIZE; i++) {
25873775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouillet        digest[i] = (uint8_t)
2598b77a77e785f0e25b13016ed60770e521dc60e0bLogan         ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
2608b77a77e785f0e25b13016ed60770e521dc60e0bLogan    }
2618b77a77e785f0e25b13016ed60770e521dc60e0bLogan    /* Wipe variables */
2628b77a77e785f0e25b13016ed60770e521dc60e0bLogan    memset(context->buffer, 0, 64);
2638b77a77e785f0e25b13016ed60770e521dc60e0bLogan    memset(context->state, 0, HASHSIZE);
2648b77a77e785f0e25b13016ed60770e521dc60e0bLogan    memset(context->count, 0, 8);
2658b77a77e785f0e25b13016ed60770e521dc60e0bLogan    memset(&finalcount, 0, 8);
2668b77a77e785f0e25b13016ed60770e521dc60e0bLogan#ifdef SHA1HANDSOFF
2678b77a77e785f0e25b13016ed60770e521dc60e0bLogan    /* make SHA1Transform overwrite it's own static vars */
2688b77a77e785f0e25b13016ed60770e521dc60e0bLogan    SHA1Transform(context->state, context->buffer);
2698b77a77e785f0e25b13016ed60770e521dc60e0bLogan#endif
2708b77a77e785f0e25b13016ed60770e521dc60e0bLogan}
2718b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2728b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2738b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2748b77a77e785f0e25b13016ed60770e521dc60e0bLogan#ifdef CMDLINE
2758b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2768b77a77e785f0e25b13016ed60770e521dc60e0bLogan/* sha1file computes the SHA-1 hash of the named file and puts
2778b77a77e785f0e25b13016ed60770e521dc60e0bLogan   it in the 20-byte array digest. If fname is NULL, stdin is
2788b77a77e785f0e25b13016ed60770e521dc60e0bLogan   assumed.
2798b77a77e785f0e25b13016ed60770e521dc60e0bLogan*/
28073775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouilletvoid sha1file(char *fname, uint8_t* digest)
2818b77a77e785f0e25b13016ed60770e521dc60e0bLogan{
2828b77a77e785f0e25b13016ed60770e521dc60e0bLogan    int bytesread;
2838b77a77e785f0e25b13016ed60770e521dc60e0bLogan    SHA1_CTX context;
28473775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouillet    uint8_t buffer[16384];
2858b77a77e785f0e25b13016ed60770e521dc60e0bLogan    FILE* f;
2868b77a77e785f0e25b13016ed60770e521dc60e0bLogan
2878b77a77e785f0e25b13016ed60770e521dc60e0bLogan    if (fname)
2888b77a77e785f0e25b13016ed60770e521dc60e0bLogan    {
2898b77a77e785f0e25b13016ed60770e521dc60e0bLogan        f = fopen(fname, "rb");
2908b77a77e785f0e25b13016ed60770e521dc60e0bLogan        if (!f)
2918b77a77e785f0e25b13016ed60770e521dc60e0bLogan        {
2928b77a77e785f0e25b13016ed60770e521dc60e0bLogan            fprintf(stderr, "Can't open %s\n", fname);
2938b77a77e785f0e25b13016ed60770e521dc60e0bLogan            memset(digest, 0, HASHSIZE);
2948b77a77e785f0e25b13016ed60770e521dc60e0bLogan            return;
2958b77a77e785f0e25b13016ed60770e521dc60e0bLogan        }
2968b77a77e785f0e25b13016ed60770e521dc60e0bLogan    }
2978b77a77e785f0e25b13016ed60770e521dc60e0bLogan    else
2988b77a77e785f0e25b13016ed60770e521dc60e0bLogan    {
2998b77a77e785f0e25b13016ed60770e521dc60e0bLogan        f = stdin;
3008b77a77e785f0e25b13016ed60770e521dc60e0bLogan    }
3018b77a77e785f0e25b13016ed60770e521dc60e0bLogan    SHA1Init(&context);
3028b77a77e785f0e25b13016ed60770e521dc60e0bLogan    while (!feof(f))
3038b77a77e785f0e25b13016ed60770e521dc60e0bLogan    {
3048b77a77e785f0e25b13016ed60770e521dc60e0bLogan        bytesread = fread(buffer, 1, 16384, f);
3058b77a77e785f0e25b13016ed60770e521dc60e0bLogan        SHA1Update(&context, buffer, bytesread);
3068b77a77e785f0e25b13016ed60770e521dc60e0bLogan    }
3078b77a77e785f0e25b13016ed60770e521dc60e0bLogan    SHA1Final(digest, &context);
3088b77a77e785f0e25b13016ed60770e521dc60e0bLogan    if (fname)
3098b77a77e785f0e25b13016ed60770e521dc60e0bLogan        fclose(f);
3108b77a77e785f0e25b13016ed60770e521dc60e0bLogan}
3118b77a77e785f0e25b13016ed60770e521dc60e0bLogan
3128b77a77e785f0e25b13016ed60770e521dc60e0bLogan/* Convert ASCII hexidecimal digit to 4-bit value. */
31373775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouilletuint8_t hexval(char c)
3148b77a77e785f0e25b13016ed60770e521dc60e0bLogan{
31573775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouillet    uint8_t h;
3168b77a77e785f0e25b13016ed60770e521dc60e0bLogan
3178b77a77e785f0e25b13016ed60770e521dc60e0bLogan    c = toupper(c);
3188b77a77e785f0e25b13016ed60770e521dc60e0bLogan    if (c >= 'A')
3198b77a77e785f0e25b13016ed60770e521dc60e0bLogan        h = c - 'A' + 10;
3208b77a77e785f0e25b13016ed60770e521dc60e0bLogan    else
3218b77a77e785f0e25b13016ed60770e521dc60e0bLogan        h = c - '0';
3228b77a77e785f0e25b13016ed60770e521dc60e0bLogan    return h;
3238b77a77e785f0e25b13016ed60770e521dc60e0bLogan}
3248b77a77e785f0e25b13016ed60770e521dc60e0bLogan
3258b77a77e785f0e25b13016ed60770e521dc60e0bLogan/* Verify a file created with sha1sum by redirecting output
3268b77a77e785f0e25b13016ed60770e521dc60e0bLogan   to a file. */
3278b77a77e785f0e25b13016ed60770e521dc60e0bLoganint verifyfile(char *fname)
3288b77a77e785f0e25b13016ed60770e521dc60e0bLogan{
3298b77a77e785f0e25b13016ed60770e521dc60e0bLogan    int j, k;
3308b77a77e785f0e25b13016ed60770e521dc60e0bLogan    int found = 0;
33173775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouillet    uint8_t digest[HASHSIZE];
33273775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouillet    uint8_t expected_digest[HASHSIZE];
3338b77a77e785f0e25b13016ed60770e521dc60e0bLogan    FILE *checkfile;
3348b77a77e785f0e25b13016ed60770e521dc60e0bLogan    char checkline[LINESIZE];
3358b77a77e785f0e25b13016ed60770e521dc60e0bLogan    char *s;
33673775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouillet    uint8_t err;
3378b77a77e785f0e25b13016ed60770e521dc60e0bLogan
3388b77a77e785f0e25b13016ed60770e521dc60e0bLogan    checkfile = fopen(fname, "rt");
3398b77a77e785f0e25b13016ed60770e521dc60e0bLogan    if (!checkfile)
3408b77a77e785f0e25b13016ed60770e521dc60e0bLogan    {
3418b77a77e785f0e25b13016ed60770e521dc60e0bLogan        fprintf(stderr, "Can't open %s\n", fname);
3428b77a77e785f0e25b13016ed60770e521dc60e0bLogan        return(0);
3438b77a77e785f0e25b13016ed60770e521dc60e0bLogan    }
3448b77a77e785f0e25b13016ed60770e521dc60e0bLogan    do
3458b77a77e785f0e25b13016ed60770e521dc60e0bLogan    {
3468b77a77e785f0e25b13016ed60770e521dc60e0bLogan        s = fgets(checkline, LINESIZE, checkfile);
3478b77a77e785f0e25b13016ed60770e521dc60e0bLogan        if (s)
3488b77a77e785f0e25b13016ed60770e521dc60e0bLogan        {
3498b77a77e785f0e25b13016ed60770e521dc60e0bLogan            if ((strlen(checkline)>26)&&
3508b77a77e785f0e25b13016ed60770e521dc60e0bLogan                1 /*(!strncmp(checkline,"SHA1=", 5))*/)
3518b77a77e785f0e25b13016ed60770e521dc60e0bLogan            {
3528b77a77e785f0e25b13016ed60770e521dc60e0bLogan                /* Overwrite newline. */
3538b77a77e785f0e25b13016ed60770e521dc60e0bLogan                checkline[strlen(checkline)-1]=0;
3548b77a77e785f0e25b13016ed60770e521dc60e0bLogan                found = 1;
3558b77a77e785f0e25b13016ed60770e521dc60e0bLogan
3568b77a77e785f0e25b13016ed60770e521dc60e0bLogan                /* Read expected check value. */
3578b77a77e785f0e25b13016ed60770e521dc60e0bLogan                for (k=0, j=5; k < HASHSIZE; k++)
3588b77a77e785f0e25b13016ed60770e521dc60e0bLogan                {
3598b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    expected_digest[k]=hexval(checkline[j++]);
3608b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    expected_digest[k]=(expected_digest[k]<<4)
3618b77a77e785f0e25b13016ed60770e521dc60e0bLogan                        +hexval(checkline[j++]);
3628b77a77e785f0e25b13016ed60770e521dc60e0bLogan                }
3638b77a77e785f0e25b13016ed60770e521dc60e0bLogan
3648b77a77e785f0e25b13016ed60770e521dc60e0bLogan                /* Compute fingerprints */
3658b77a77e785f0e25b13016ed60770e521dc60e0bLogan                s = checkline+46;
3668b77a77e785f0e25b13016ed60770e521dc60e0bLogan                sha1file(s, digest);
3678b77a77e785f0e25b13016ed60770e521dc60e0bLogan
3688b77a77e785f0e25b13016ed60770e521dc60e0bLogan                /* Compare fingerprints */
3698b77a77e785f0e25b13016ed60770e521dc60e0bLogan                err = 0;
3708b77a77e785f0e25b13016ed60770e521dc60e0bLogan                for (k=0; k<HASHSIZE; k++)
3718b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    err |= digest[k]-
3728b77a77e785f0e25b13016ed60770e521dc60e0bLogan                        expected_digest[k];
3738b77a77e785f0e25b13016ed60770e521dc60e0bLogan                if (err)
3748b77a77e785f0e25b13016ed60770e521dc60e0bLogan                {
3758b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    fprintf(stderr, "FAILED: %s\n"
3768b77a77e785f0e25b13016ed60770e521dc60e0bLogan                        " EXPECTED: ", s);
3778b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    for (k=0; k<HASHSIZE; k++)
3788b77a77e785f0e25b13016ed60770e521dc60e0bLogan                        fprintf(stderr, "%02X",
3798b77a77e785f0e25b13016ed60770e521dc60e0bLogan                            expected_digest[k]);
3808b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    fprintf(stderr,"\n    FOUND: ");
3818b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    for (k=0; k<HASHSIZE; k++)
3828b77a77e785f0e25b13016ed60770e521dc60e0bLogan                        fprintf(stderr, "%02X", digest[k]);
3838b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    fprintf(stderr, "\n");
3848b77a77e785f0e25b13016ed60770e521dc60e0bLogan                }
3858b77a77e785f0e25b13016ed60770e521dc60e0bLogan                else
3868b77a77e785f0e25b13016ed60770e521dc60e0bLogan                {
3878b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    printf("OK: %s\n", s);
3888b77a77e785f0e25b13016ed60770e521dc60e0bLogan                }
3898b77a77e785f0e25b13016ed60770e521dc60e0bLogan            }
3908b77a77e785f0e25b13016ed60770e521dc60e0bLogan        }
3918b77a77e785f0e25b13016ed60770e521dc60e0bLogan    } while (s);
3928b77a77e785f0e25b13016ed60770e521dc60e0bLogan    return found;
3938b77a77e785f0e25b13016ed60770e521dc60e0bLogan}
3948b77a77e785f0e25b13016ed60770e521dc60e0bLogan
3958b77a77e785f0e25b13016ed60770e521dc60e0bLogan
3968b77a77e785f0e25b13016ed60770e521dc60e0bLogan
3978b77a77e785f0e25b13016ed60770e521dc60e0bLoganvoid syntax(char *progname)
3988b77a77e785f0e25b13016ed60770e521dc60e0bLogan{
3998b77a77e785f0e25b13016ed60770e521dc60e0bLogan    printf("\nsyntax:\n"
4008b77a77e785f0e25b13016ed60770e521dc60e0bLogan     "%s [-c|-h][-q] file name[s]\n"
4018b77a77e785f0e25b13016ed60770e521dc60e0bLogan     "    -c = check files against previous check values\n"
4028b77a77e785f0e25b13016ed60770e521dc60e0bLogan     "    -g = generate SHA-1 check values (default action)\n"
4038b77a77e785f0e25b13016ed60770e521dc60e0bLogan     "    -h = display this help\n"
4048b77a77e785f0e25b13016ed60770e521dc60e0bLogan     "For example,\n"
4058b77a77e785f0e25b13016ed60770e521dc60e0bLogan     "sha1sum test.txt > check.txt\n"
4068b77a77e785f0e25b13016ed60770e521dc60e0bLogan     "generates check value for test.txt in check.txt, and\n"
4078b77a77e785f0e25b13016ed60770e521dc60e0bLogan     "sha1sum -c check.txt\n"
4088b77a77e785f0e25b13016ed60770e521dc60e0bLogan     "checks test.txt against the check value in check.txt\n",
4098b77a77e785f0e25b13016ed60770e521dc60e0bLogan     progname);
4108b77a77e785f0e25b13016ed60770e521dc60e0bLogan    exit(1);
4118b77a77e785f0e25b13016ed60770e521dc60e0bLogan}
4128b77a77e785f0e25b13016ed60770e521dc60e0bLogan
4138b77a77e785f0e25b13016ed60770e521dc60e0bLogan
4148b77a77e785f0e25b13016ed60770e521dc60e0bLogan/**********************************************************/
4158b77a77e785f0e25b13016ed60770e521dc60e0bLogan
4168b77a77e785f0e25b13016ed60770e521dc60e0bLoganint main(int argc, char** argv)
4178b77a77e785f0e25b13016ed60770e521dc60e0bLogan{
4188b77a77e785f0e25b13016ed60770e521dc60e0bLogan    int i, j, k;
4198b77a77e785f0e25b13016ed60770e521dc60e0bLogan    int check = 0;
4208b77a77e785f0e25b13016ed60770e521dc60e0bLogan    int found = 0;
42173775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouillet    uint8_t digest[HASHSIZE];
42273775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouillet    uint8_t expected_digest[HASHSIZE];
4238b77a77e785f0e25b13016ed60770e521dc60e0bLogan    FILE *checkfile;
4248b77a77e785f0e25b13016ed60770e521dc60e0bLogan    char checkline[LINESIZE];
4258b77a77e785f0e25b13016ed60770e521dc60e0bLogan    char *s;
4268b77a77e785f0e25b13016ed60770e521dc60e0bLogan#ifdef __BORLANDC__
4278b77a77e785f0e25b13016ed60770e521dc60e0bLogan    struct ffblk f;
4288b77a77e785f0e25b13016ed60770e521dc60e0bLogan    int done;
4298b77a77e785f0e25b13016ed60770e521dc60e0bLogan    char path[MAXPATH];
4308b77a77e785f0e25b13016ed60770e521dc60e0bLogan    char drive[MAXDRIVE];
4318b77a77e785f0e25b13016ed60770e521dc60e0bLogan    char dir[MAXDIR];
4328b77a77e785f0e25b13016ed60770e521dc60e0bLogan    char name[MAXFILE];
4338b77a77e785f0e25b13016ed60770e521dc60e0bLogan    char ext[MAXEXT];
4348b77a77e785f0e25b13016ed60770e521dc60e0bLogan#endif
43573775bb7859ad9a326de3508a579c553c4dec6ceJean-Luc Brouillet    uint8_t err;
43626fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang    const char *binary_output_file = 0;
4375de1adfe315bbb088f7614936b1023c6d6d3fc35Joseph Wen
4388b77a77e785f0e25b13016ed60770e521dc60e0bLogan    for (i = 1; i < argc; i++)
4398b77a77e785f0e25b13016ed60770e521dc60e0bLogan    {
4408b77a77e785f0e25b13016ed60770e521dc60e0bLogan        if (argv[i][0] == '-')
4418b77a77e785f0e25b13016ed60770e521dc60e0bLogan        {
4428b77a77e785f0e25b13016ed60770e521dc60e0bLogan            switch (argv[i][1])
4438b77a77e785f0e25b13016ed60770e521dc60e0bLogan            {
44426fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang                case 'B':
44526fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang                    ++i;
44626fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang                    binary_output_file = argv[i];
44726fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang                    break;
4488b77a77e785f0e25b13016ed60770e521dc60e0bLogan                case 'c':
4498b77a77e785f0e25b13016ed60770e521dc60e0bLogan                case 'C':
4508b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    check = 1;
4518b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    break;
4528b77a77e785f0e25b13016ed60770e521dc60e0bLogan                case 'g':
4538b77a77e785f0e25b13016ed60770e521dc60e0bLogan                case 'G':
4548b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    check = 0;
4558b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    break;
4568b77a77e785f0e25b13016ed60770e521dc60e0bLogan                default:
4578b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    syntax(argv[0]);
4588b77a77e785f0e25b13016ed60770e521dc60e0bLogan            }
4598b77a77e785f0e25b13016ed60770e521dc60e0bLogan        }
4608b77a77e785f0e25b13016ed60770e521dc60e0bLogan    }
4618b77a77e785f0e25b13016ed60770e521dc60e0bLogan
46226fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang    // Read from STDIN
46326fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang    sha1file(NULL, digest);
46426fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang    if (binary_output_file) {
46526fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang      FILE *fout = fopen(binary_output_file, "wb");
46626fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang      if (!fout) {
46726fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang        fprintf(stderr, "Error: Can not write to %s.\n", binary_output_file);
46826fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang        return 1;
46926fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang      }
47026fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang      fwrite(digest, 1, HASHSIZE, fout);
47126fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang      fclose(fout);
47226fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang      return 0;
47326fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang    }
47426fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang    for (j = 0; j < HASHSIZE; j++)
47526fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang        printf("%02x", digest[j]);
47626fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang    return 0;
47726fea10655613ad184b37dfd24dd21e92a5afa95Ying Wang
4788b77a77e785f0e25b13016ed60770e521dc60e0bLogan    for (i=1; i<argc; i++)
4798b77a77e785f0e25b13016ed60770e521dc60e0bLogan    {
4808b77a77e785f0e25b13016ed60770e521dc60e0bLogan        if (argv[i][0] != '-')
4818b77a77e785f0e25b13016ed60770e521dc60e0bLogan        {
4828b77a77e785f0e25b13016ed60770e521dc60e0bLogan#ifdef __BORLANDC__
4838b77a77e785f0e25b13016ed60770e521dc60e0bLogan            fnsplit(argv[i], drive, dir, name, ext);
4848b77a77e785f0e25b13016ed60770e521dc60e0bLogan            done = findfirst(argv[i], &f, FA_RDONLY |
4858b77a77e785f0e25b13016ed60770e521dc60e0bLogan                FA_HIDDEN|FA_SYSTEM|FA_ARCH);
4868b77a77e785f0e25b13016ed60770e521dc60e0bLogan             while (!done)
4878b77a77e785f0e25b13016ed60770e521dc60e0bLogan            {
4888b77a77e785f0e25b13016ed60770e521dc60e0bLogan                sprintf(path, "%s%s%s", drive, dir, f.ff_name);
4898b77a77e785f0e25b13016ed60770e521dc60e0bLogan                s = path;
4908b77a77e785f0e25b13016ed60770e521dc60e0bLogan#else
4918b77a77e785f0e25b13016ed60770e521dc60e0bLogan                s = argv[i];
4928b77a77e785f0e25b13016ed60770e521dc60e0bLogan#endif
4938b77a77e785f0e25b13016ed60770e521dc60e0bLogan
4948b77a77e785f0e25b13016ed60770e521dc60e0bLogan                if (check)
4958b77a77e785f0e25b13016ed60770e521dc60e0bLogan                {   /* Check fingerprint file. */
4968b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    found |= verifyfile(s);
4978b77a77e785f0e25b13016ed60770e521dc60e0bLogan                }
4988b77a77e785f0e25b13016ed60770e521dc60e0bLogan                else
4998b77a77e785f0e25b13016ed60770e521dc60e0bLogan                {   /* Generate fingerprints & write to
5008b77a77e785f0e25b13016ed60770e521dc60e0bLogan                       stdout. */
5018b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    sha1file(s, digest);
5028b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    //printf("SHA1=");
5038b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    for (j=0; j<HASHSIZE; j++)
5048b77a77e785f0e25b13016ed60770e521dc60e0bLogan                        printf("%02x", digest[j]);
5058b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    printf("  %s\n", s);
5068b77a77e785f0e25b13016ed60770e521dc60e0bLogan                    found = 1;
5078b77a77e785f0e25b13016ed60770e521dc60e0bLogan                }
5088b77a77e785f0e25b13016ed60770e521dc60e0bLogan
5098b77a77e785f0e25b13016ed60770e521dc60e0bLogan#ifdef __BORLANDC__
5108b77a77e785f0e25b13016ed60770e521dc60e0bLogan                done = findnext(&f);
5118b77a77e785f0e25b13016ed60770e521dc60e0bLogan            }
5128b77a77e785f0e25b13016ed60770e521dc60e0bLogan#endif
5138b77a77e785f0e25b13016ed60770e521dc60e0bLogan
5148b77a77e785f0e25b13016ed60770e521dc60e0bLogan        }
5158b77a77e785f0e25b13016ed60770e521dc60e0bLogan    }
5168b77a77e785f0e25b13016ed60770e521dc60e0bLogan    if (!found)
5178b77a77e785f0e25b13016ed60770e521dc60e0bLogan    {
5188b77a77e785f0e25b13016ed60770e521dc60e0bLogan        if (check)
5198b77a77e785f0e25b13016ed60770e521dc60e0bLogan        {
5208b77a77e785f0e25b13016ed60770e521dc60e0bLogan            fprintf(stderr,
5218b77a77e785f0e25b13016ed60770e521dc60e0bLogan                "No SHA1 lines found in %s\n",
5228b77a77e785f0e25b13016ed60770e521dc60e0bLogan                argv[i]);
5238b77a77e785f0e25b13016ed60770e521dc60e0bLogan        }
5248b77a77e785f0e25b13016ed60770e521dc60e0bLogan        else
5258b77a77e785f0e25b13016ed60770e521dc60e0bLogan        {
5268b77a77e785f0e25b13016ed60770e521dc60e0bLogan            fprintf(stderr, "No files checked.\n");
5278b77a77e785f0e25b13016ed60770e521dc60e0bLogan            syntax(argv[0]);
5288b77a77e785f0e25b13016ed60770e521dc60e0bLogan        }
5298b77a77e785f0e25b13016ed60770e521dc60e0bLogan    }
5308b77a77e785f0e25b13016ed60770e521dc60e0bLogan    return(0);  /* JHB */
5318b77a77e785f0e25b13016ed60770e521dc60e0bLogan}
5328b77a77e785f0e25b13016ed60770e521dc60e0bLogan
5338b77a77e785f0e25b13016ed60770e521dc60e0bLogan#endif  /*CMDLINE*/
534