diff options
-rw-r--r-- | toys/other/sha1sum.c | 102 |
1 files changed, 43 insertions, 59 deletions
diff --git a/toys/other/sha1sum.c b/toys/other/sha1sum.c index e5f336a4..3165effc 100644 --- a/toys/other/sha1sum.c +++ b/toys/other/sha1sum.c @@ -20,7 +20,7 @@ config SHA1SUM #include <toys.h> -struct sha1 { +DEFINE_GLOBALS( uint32_t state[5]; uint32_t oldstate[5]; uint64_t count; @@ -28,12 +28,9 @@ struct sha1 { unsigned char c[64]; uint32_t i[16]; } buffer; -}; +) -static void sha1_init(struct sha1 *this); -static void sha1_transform(struct sha1 *this); -static void sha1_update(struct sha1 *this, char *data, unsigned int len); -static void sha1_final(struct sha1 *this, char digest[20]); +#define TT this.sha1sum #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) @@ -52,16 +49,16 @@ static const uint32_t rconsts[]={0x5A827999,0x6ED9EBA1,0x8F1BBCDC,0xCA62C1D6}; // Hash a single 512-bit block. This is the core of the algorithm. -static void sha1_transform(struct sha1 *this) +static void sha1_transform(void) { int i, j, k, count; - uint32_t *block = this->buffer.i; + uint32_t *block = TT.buffer.i; uint32_t *rot[5], *temp; // Copy context->state[] to working vars for (i=0; i<5; i++) { - this->oldstate[i] = this->state[i]; - rot[i] = this->state + i; + TT.oldstate[i] = TT.state[i]; + rot[i] = TT.state + i; } // 4 rounds of 20 operations each. for (i=count=0; i<4; i++) { @@ -88,55 +85,57 @@ static void sha1_transform(struct sha1 *this) } } // Add the previous values of state[] - for (i=0; i<5; i++) this->state[i] += this->oldstate[i]; -} - - -// Initialize a struct sha1. - -static void sha1_init(struct sha1 *this) -{ - /* SHA1 initialization constants */ - this->state[0] = 0x67452301; - this->state[1] = 0xEFCDAB89; - this->state[2] = 0x98BADCFE; - this->state[3] = 0x10325476; - this->state[4] = 0xC3D2E1F0; - this->count = 0; + for (i=0; i<5; i++) TT.state[i] += TT.oldstate[i]; } // Fill the 64-byte working buffer and call sha1_transform() when full. -void sha1_update(struct sha1 *this, char *data, unsigned int len) +static void sha1_update(char *data, unsigned int len) { unsigned int i, j; - j = this->count & 63; - this->count += len; + j = TT.count & 63; + TT.count += len; // Enough data to process a frame? if ((j + len) > 63) { i = 64-j; - memcpy(this->buffer.c + j, data, i); - sha1_transform(this); + memcpy(TT.buffer.c + j, data, i); + sha1_transform(); for ( ; i + 63 < len; i += 64) { - memcpy(this->buffer.c, data + i, 64); - sha1_transform(this); + memcpy(TT.buffer.c, data + i, 64); + sha1_transform(); } j = 0; } else i = 0; // Grab remaining chunk - memcpy(this->buffer.c + j, data + i, len - i); + memcpy(TT.buffer.c + j, data + i, len - i); } -// Add padding and return the message digest. +// Callback for loopfiles() -void sha1_final(struct sha1 *this, char digest[20]) +static void do_sha1(int fd, char *name) { - uint64_t count = this->count << 3; - unsigned int i; + uint64_t count; + int i; char buf; + /* SHA1 initialization constants */ + TT.state[0] = 0x67452301; + TT.state[1] = 0xEFCDAB89; + TT.state[2] = 0x98BADCFE; + TT.state[3] = 0x10325476; + TT.state[4] = 0xC3D2E1F0; + TT.count = 0; + + for (;;) { + i = read(fd, toybuf, sizeof(toybuf)); + if (i<1) break; + sha1_update(toybuf, i); + } + + count = TT.count << 3; + // End the message by appending a "1" bit to the data, ending with the // message size (in bits, big endian), and adding enough zero bits in // between to pad to the end of the next 64-byte frame. @@ -146,34 +145,19 @@ void sha1_final(struct sha1 *this, char digest[20]) buf = 0x80; do { - sha1_update(this, &buf, 1); + sha1_update(&buf, 1); buf = 0; - } while ((this->count & 63) != 56); + } while ((TT.count & 63) != 56); for (i = 0; i < 8; i++) - this->buffer.c[56+i] = count >> (8*(7-i)); - sha1_transform(this); + TT.buffer.c[56+i] = count >> (8*(7-i)); + sha1_transform(); for (i = 0; i < 20; i++) - digest[i] = this->state[i>>2] >> ((3-(i & 3)) * 8); + toybuf[i] = TT.state[i>>2] >> ((3-(i & 3)) * 8); // Wipe variables. Cryptogropher paranoia. - memset(this, 0, sizeof(struct sha1)); -} - -// Callback for loopfiles() + memset(&TT, 0, sizeof(TT)); -static void do_sha1(int fd, char *name) -{ - struct sha1 this; - int len; - - sha1_init(&this); - for (;;) { - len = read(fd, toybuf, sizeof(toybuf)); - if (len<1) break; - sha1_update(&this, toybuf, len); - } - sha1_final(&this, toybuf); - for (len = 0; len < 20; len++) printf("%02x", toybuf[len]); + for (i = 0; i < 20; i++) printf("%02x", toybuf[i]); printf(" %s\n", name); } |