aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--toys/lsb/md5sum.c127
1 files changed, 46 insertions, 81 deletions
diff --git a/toys/lsb/md5sum.c b/toys/lsb/md5sum.c
index ab4957d5..4df53a5c 100644
--- a/toys/lsb/md5sum.c
+++ b/toys/lsb/md5sum.c
@@ -17,20 +17,21 @@
* coreutils supports --status but not -s, busybox supports -s but not --status
USE_MD5SUM(NEWTOY(md5sum, "bc(check)s(status)[!bc]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_SHA1SUM(NEWTOY(sha1sum, "bc(check)s(status)[!bc]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_SHA224SUM(NEWTOY(sha224sum, "bc(check)s(status)[!bc]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_SHA256SUM(NEWTOY(sha256sum, "bc(check)s(status)[!bc]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_SHA384SUM(NEWTOY(sha384sum, "bc(check)s(status)[!bc]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_SHA512SUM(NEWTOY(sha512sum, "bc(check)s(status)[!bc]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_SHA1SUM(OLDTOY(sha1sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
+USE_SHA224SUM(OLDTOY(sha224sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
+USE_SHA256SUM(OLDTOY(sha256sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
+USE_SHA384SUM(OLDTOY(sha384sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
+USE_SHA512SUM(OLDTOY(sha512sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
config MD5SUM
bool "md5sum"
default y
help
- usage: md5sum [-bcs] [FILE]...
+ usage: ???sum [-bcs] [FILE]...
- Calculate md5 hash for each input file, reading from stdin if none.
- Output one hash (32 hex digits) for each input file, followed by filename.
+ Calculate hash for each input file, reading from stdin if none, writing
+ hexadecimal digits to stdout for each input file (md5=32 hex digits,
+ sha1=40, sha224=56, sha256=64, sha384=96, sha512=128) followed by filename.
-b Brief (hash only, no filename)
-c Check each line of each FILE is the same hash+filename we'd output
@@ -40,39 +41,31 @@ config SHA1SUM
bool "sha1sum"
default y
help
- usage: sha?sum [-bcs] [FILE]...
-
- Calculate sha hash for each input file, reading from stdin if none. Output
- one hash (40 hex digits for sha1, 56 for sha224, 64 for sha256, 96 for sha384,
- and 128 for sha512) for each input file, followed by filename.
-
- -b Brief (hash only, no filename)
- -c Check each line of each FILE is the same hash+filename we'd output
- -s No output, exit status 0 if all hashes match, 1 otherwise
+ See md5sum
config SHA224SUM
bool "sha224sum"
default y
help
- See sha1sum
+ See md5sum
config SHA256SUM
bool "sha256sum"
default y
help
- See sha1sum
+ See md5sum
config SHA384SUM
bool "sha384sum"
default y
help
- See sha1sum
+ See md5sum
config SHA512SUM
bool "sha512sum"
default y
help
- See sha1sum
+ See md5sum
*/
#define FORCE_FLAGS
@@ -88,22 +81,16 @@ typedef int SHA512_CTX;
GLOBALS(
int sawline;
- enum hashmethods { MD5, SHA1, SHA224, SHA256, SHA384, SHA512 } hashmethod;
unsigned *rconsttable32;
unsigned long long *rconsttable64; // for sha384,sha512
// Crypto variables blanked after summing
- union {
- unsigned i32[8]; // for md5,sha1,sha224,sha256
- unsigned long long i64[8]; // for sha384,sha512
- } state;
- // sha384/512 spec has 128-bit count of input bits, but 64-bit is 23 petabytes
- unsigned long long count;
+ unsigned long long count, overflow;
union {
char c[128]; // bytes, 1024 bits
unsigned i32[16]; // 512 bits for md5,sha1,sha224,sha256
unsigned long long i64[16]; // 1024 bits for sha384,sha512
- } buffer;
+ } state, buffer;
)
// Round constants. Static table for when we haven't got floating point support
@@ -322,6 +309,7 @@ static void hash_update(char *data, unsigned int len, void (*transform)(void),
unsigned int i, j;
j = TT.count & (chunksize - 1);
+ if (TT.count+len<TT.count) TT.overflow++;
TT.count += len;
for (;;) {
@@ -387,27 +375,30 @@ static void do_lib_hash(int fd, char *name)
static void do_builtin_hash(int fd, char *name)
{
- unsigned long long count;
- int i, chunksize, digestlen;
+ unsigned long long count[2];
+ int i, chunksize, digestlen, method;
volatile char *pp;
void (*transform)(void);
char buf;
+ // md5sum, sha1sum, sha224sum, sha256sum, sha384sum, sha512sum
+ method = stridx("us2581", toys.which->name[4]);
+
// select hash type
transform = (void *[]){md5_transform, sha1_transform, sha2_32_transform,
- sha2_32_transform, sha2_64_transform, sha2_64_transform}[TT.hashmethod];
- digestlen = (char []){16, 20, 28, 32, 48, 64}[TT.hashmethod];
- chunksize = 64<<(TT.hashmethod>=SHA384);
- if (TT.hashmethod<=SHA1)
+ sha2_32_transform, sha2_64_transform, sha2_64_transform}[method];
+ digestlen = (char []){16, 20, 28, 32, 48, 64}[method];
+ chunksize = 64<<(method>=4);
+ if (method<=1)
memcpy(TT.state.i32, (unsigned []){0x67452301, 0xEFCDAB89, 0x98BADCFE,
0x10325476, 0xC3D2E1F0}, 20);
- else if (TT.hashmethod==SHA224)
+ else if (method==2)
memcpy(TT.state.i32, (unsigned []){0xc1059ed8, 0x367cd507, 0x3070dd17,
0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4}, 32);
- else if (TT.hashmethod==SHA256)
+ else if (method==3)
memcpy(TT.state.i32, (unsigned []){0x6a09e667, 0xbb67ae85, 0x3c6ef372,
0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}, 32);
- else if (TT.hashmethod==SHA384)
+ else if (method==4)
memcpy(TT.state.i64, (unsigned long long []){0xcbbb9d5dc1059ed8,
0x629a292a367cd507, 0x9159015a3070dd17, 0x152fecd8f70e5939,
0x67332667ffc00b31, 0x8eb44a8768581511, 0xdb0c2e0d64f98fa7,
@@ -426,26 +417,30 @@ static void do_builtin_hash(int fd, char *name)
// 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.
+ // between to pad to the end of the next frame.
//
// Since our input up to now has been in whole bytes, we can deal with
- // bytes here too.
+ // bytes here too. sha384 and 512 use 128 bit counter, so track overflow.
buf = 0x80;
- count = TT.count << 3; // convert to bits
+ count[0] = (TT.overflow<<3)+(TT.count>>61);
+ count[1] = TT.count<<3; // convert to bits
+ for (i = 0; i<2; i++)
+ count[i] = !method ? SWAP_LE64(count[i]) : SWAP_BE64(count[i]);
+ i = 8<<(method>=4);
do {
hash_update(&buf, 1, transform, chunksize);
buf = 0;
- } while ((TT.count & (chunksize - 1)) != (chunksize - 8));
- count = (TT.hashmethod == MD5) ? SWAP_LE64(count) : SWAP_BE64(count);
- hash_update((void *)&count, 8, transform, chunksize);
+ } while ((TT.count&(chunksize-1)) != chunksize-i);
+ hash_update((void *)(count+(method<4)), i, transform, chunksize);
// write digest to toybuf
- if (TT.hashmethod>=SHA384) for (i=0; i<digestlen/8; i++)
+ if (method>=4) for (i=0; i<digestlen/8; i++)
sprintf(toybuf+16*i, "%016llx", TT.state.i64[i]);
else for (i=0; i<digestlen/4; i++)
- sprintf(toybuf+8*i, "%08x", (TT.hashmethod == MD5)
- ? bswap_32(TT.state.i32[i]) : TT.state.i32[i]);
- // Wipe variables. Cryptographer paranoia.
+ sprintf(toybuf+8*i, "%08x",
+ !method ? bswap_32(TT.state.i32[i]) : TT.state.i32[i]);
+ // Wipe variables. Cryptographer paranoia. Avoid "optimizing" out memset
+ // by looping on a volatile pointer.
i = sizeof(struct md5sum_data)-offsetof(struct md5sum_data, state.i64);
for (pp = (void *)TT.state.i64; i; i--) *pp++ = 0;
pp = toybuf+strlen(toybuf)+1;
@@ -514,15 +509,15 @@ void md5sum_main(void)
// Calculate table if we have floating point. Static version should drop
// out at compile time when we don't need it.
if (!CFG_TOYBOX_LIBCRYPTO) {
- if (TT.hashmethod==MD5) {
+ if (*toys.which->name == 'm') { // MD5
if (CFG_TOYBOX_FLOAT) {
TT.rconsttable32 = xmalloc(64*4);
for (i = 0; i<64; i++) TT.rconsttable32[i] = fabs(sin(i+1))*(1LL<<32);
} else TT.rconsttable32 = md5nofloat;
- } else if (TT.hashmethod==SHA224 || TT.hashmethod==SHA256) {
+ } else if (strchr("25", toys.which->name[4])) { // 224, 256
TT.rconsttable32 = xmalloc(64*4);
for (i=0; i<64; i++) TT.rconsttable32[i] = sha512nofloat[i] >> 32;
- } else if (TT.hashmethod>=SHA384) TT.rconsttable64 = sha512nofloat;
+ } else if (toys.which->name[3] != '1') TT.rconsttable64 = sha512nofloat;
}
if (FLAG(c)) for (i = 0; toys.optargs[i]; i++) do_c_file(toys.optargs[i]);
@@ -531,33 +526,3 @@ void md5sum_main(void)
loopfiles(toys.optargs, do_hash);
}
}
-
-void sha1sum_main(void)
-{
- TT.hashmethod = SHA1;
- md5sum_main();
-}
-
-void sha224sum_main(void)
-{
- TT.hashmethod = SHA224;
- md5sum_main();
-}
-
-void sha256sum_main(void)
-{
- TT.hashmethod = SHA256;
- md5sum_main();
-}
-
-void sha384sum_main(void)
-{
- TT.hashmethod = SHA384;
- md5sum_main();
-}
-
-void sha512sum_main(void)
-{
- TT.hashmethod = SHA512;
- md5sum_main();
-}