diff options
author | Rob Landley <rob@landley.net> | 2021-06-02 08:23:11 -0500 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2021-06-02 08:23:11 -0500 |
commit | a0cb955df0978d3a91c560ee66d4c6109acbefed (patch) | |
tree | 58b56a999e6b9fcc69a22ab37fa02761640bc395 /toys/lsb | |
parent | de474ba0395024e4149ae8be61097dec6b91cf07 (diff) | |
download | toybox-a0cb955df0978d3a91c560ee66d4c6109acbefed.tar.gz |
Cleanup.
Diffstat (limited to 'toys/lsb')
-rw-r--r-- | toys/lsb/md5sum.c | 426 |
1 files changed, 111 insertions, 315 deletions
diff --git a/toys/lsb/md5sum.c b/toys/lsb/md5sum.c index 520c59b2..8f8f92ab 100644 --- a/toys/lsb/md5sum.c +++ b/toys/lsb/md5sum.c @@ -88,32 +88,27 @@ 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 - uint32_t *rconsttable32; - uint64_t *rconsttable64; // for sha384,sha512 // Crypto variables blanked after summing union { - uint32_t i32[8]; // for md5,sha1,sha224,sha256 - uint64_t i64[8]; // for sha384,sha512 + unsigned i32[8]; // for md5,sha1,sha224,sha256 + unsigned long long i64[8]; // for sha384,sha512 } state; - uint64_t count; // the spec for sha384 and sha512 - // uses a 128-bit number to count - // the amount of input bits. When - // using a 64-bit number, the - // maximum input data size is - // about 23 petabytes. + // sha384/512 spec has 128-bit count of input bits, but 64-bit is 23 petabytes + unsigned long long count; union { char c[128]; // bytes, 1024 bits - uint32_t i32[16]; // 512 bits for md5,sha1,sha224,sha256 - uint64_t i64[16]; // 1024 bits for sha384,sha512 + unsigned i32[16]; // 512 bits for md5,sha1,sha224,sha256 + unsigned long long i64[16]; // 1024 bits for sha384,sha512 } buffer; ) // Round constants. Static table for when we haven't got floating point support #if ! CFG_TOYBOX_FLOAT -static const uint32_t md5nofloat[64] = { +static const unsigned md5nofloat[64] = { 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, @@ -129,7 +124,7 @@ static const uint32_t md5nofloat[64] = { #else #define md5nofloat 0 #endif -static uint64_t sha512nofloat[80] = { +static unsigned long long sha512nofloat[80] = { // we cannot calculate these 64-bit values using the readily // available floating point data types and math functions, // so we always use this lookup table (80 * 8 bytes) @@ -162,7 +157,7 @@ static uint64_t sha512nofloat[80] = { 0x5fcb6fab3ad6faec, 0x6c44198c4a475817 }; // sha1 needs only 4 round constant values, so prefer precomputed -static const uint32_t sha1rconsts[] = { +static const unsigned sha1rconsts[] = { 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 }; @@ -175,13 +170,13 @@ static const uint32_t sha1rconsts[] = { static void md5_transform(void) { - uint32_t x[4], *b = (uint32_t *)TT.buffer.c; + unsigned x[4], *b = TT.buffer.i32; int i; memcpy(x, TT.state.i32, sizeof(x)); - for (i=0; i<64; i++) { - uint32_t in, a, rot, temp; + for (i = 0; i<64; i++) { + unsigned in, a, rot, temp; a = (-i)&3; if (i<16) { @@ -210,7 +205,7 @@ static void md5_transform(void) temp += x[a] + b[in] + TT.rconsttable32[i]; x[a] = x[(a+1)&3] + ((temp<<rot) | (temp>>(32-rot))); } - for (i=0; i<4; i++) TT.state.i32[i] += x[i]; + for (i = 0; i<4; i++) TT.state.i32[i] += x[i]; } // Mix next 64 bytes of data into sha1 hash. @@ -218,20 +213,16 @@ static void md5_transform(void) static void sha1_transform(void) { int i, j, k, count; - uint32_t *block = TT.buffer.i32; - uint32_t oldstate[5]; - uint32_t *rot[5], *temp; + unsigned *block = TT.buffer.i32, oldstate[5], *rot[5], *temp, work; // Copy context->state.i32[] to working vars - for (i=0; i<5; i++) { + for (i = 0; i<5; i++) { oldstate[i] = TT.state.i32[i]; rot[i] = TT.state.i32 + i; } // 4 rounds of 20 operations each. - for (i=count=0; i<4; i++) { - for (j=0; j<20; j++) { - uint32_t work; - + for (i = count = 0; i<4; i++) { + for (j = 0; j<20; j++) { work = *rot[2] ^ *rot[3]; if (!i) work = (work & *rot[1]) ^ *rot[3]; else { @@ -240,7 +231,7 @@ static void sha1_transform(void) } if (!i && j<16) - work += block[count] = (rol(block[count],24)&0xFF00FF00) + work += block[count] = (ror(block[count],8)&0xFF00FF00) | (rol(block[count],8)&0x00FF00FF); else work += block[count&15] = rol(block[(count+13)&15] @@ -250,190 +241,85 @@ static void sha1_transform(void) // Rotate by one for next time. temp = rot[4]; - for (k=4; k; k--) rot[k] = rot[k-1]; + for (k = 4; k; k--) rot[k] = rot[k-1]; *rot = temp; count++; } } // Add the previous values of state.i32[] - for (i=0; i<5; i++) TT.state.i32[i] += oldstate[i]; + for (i = 0; i<5; i++) TT.state.i32[i] += oldstate[i]; } -static void sha256_transform(void) +static void sha2_32_transform(void) { + unsigned block[64], s0, s1, S0, S1, ch, maj, temp1, temp2, rot[8]; int i; - uint32_t block[64]; - uint32_t s0, s1, S0, S1, ch, maj, temp1, temp2; - uint32_t rot[8]; // a,b,c,d,e,f,g,h - - /* - printf("buffer.c[0 - 4] = %02hhX %02hhX %02hhX %02hhX %02hhX\n", TT.buffer.c[0], TT.buffer.c[1], TT.buffer.c[2], TT.buffer.c[3], TT.buffer.c[4]); - printf("buffer.c[56 - 63] = %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX\n", \ - TT.buffer.c[56], TT.buffer.c[57], TT.buffer.c[58], TT.buffer.c[59], \ - TT.buffer.c[60], TT.buffer.c[61], TT.buffer.c[62], TT.buffer.c[63]); - */ - for (i=0; i<16; i++) { - block[i] = SWAP_BE32(TT.buffer.i32[i]); - } + + for (i = 0; i<16; i++) block[i] = SWAP_BE32(TT.buffer.i32[i]); + // Extend the message schedule array beyond first 16 words - for (i=16; i<64; i++) { + for (i = 16; i<64; i++) { s0 = ror(block[i-15], 7) ^ ror(block[i-15], 18) ^ (block[i-15] >> 3); s1 = ror(block[i-2], 17) ^ ror(block[i-2], 19) ^ (block[i-2] >> 10); block[i] = block[i-16] + s0 + block[i-7] + s1; } // Copy context->state.i32[] to working vars - for (i=0; i<8; i++) { - //TT.oldstate32[i] = TT.state.i32[i]; - rot[i] = TT.state.i32[i]; - } + for (i = 0; i<8; i++) rot[i] = TT.state.i32[i]; // 64 rounds - for (i=0; i<64; i++) { + for (i = 0; i<64; i++) { S1 = ror(rot[4],6) ^ ror(rot[4],11) ^ ror(rot[4], 25); ch = (rot[4] & rot[5]) ^ ((~ rot[4]) & rot[6]); temp1 = rot[7] + S1 + ch + TT.rconsttable32[i] + block[i]; S0 = ror(rot[0],2) ^ ror(rot[0],13) ^ ror(rot[0], 22); maj = (rot[0] & rot[1]) ^ (rot[0] & rot[2]) ^ (rot[1] & rot[2]); temp2 = S0 + maj; - /* if (i < 2) { - printf("begin round %d: rot[0] = %u rot[1] = %u rot[2] = %u\n", i, rot[0], rot[1], rot[2]); - printf(" S1=%u ch=%u temp1=%u S0=%u maj=%u temp2=%u\n", S1,ch,temp1,S0,maj,temp2); - printf(" rot[7]=%u K[i]=%u W[i]=%u TT.buffer.i[i]=%u\n", rot[7],TT.rconsttable32[i],block[i],TT.buffer.i[i]); - } */ - rot[7] = rot[6]; - rot[6] = rot[5]; - rot[5] = rot[4]; - rot[4] = rot[3] + temp1; - rot[3] = rot[2]; - rot[2] = rot[1]; - rot[1] = rot[0]; + memmove(rot+1, rot, 28); + rot[4] += temp1; rot[0] = temp1 + temp2; } - //printf("%d rounds done: rot[0] = %u rot[1] = %u rot[2] = %u\n", i, rot[0], rot[1], rot[2]); // Add the previous values of state.i32[] - for (i=0; i<8; i++) TT.state.i32[i] += rot[i]; - //printf("state.i32[0] = %u state.i32[1] = %u state.i32[2] = %u\n", TT.state.i32[0], TT.state.i32[1], TT.state.i32[2]); -} - -static void sha224_transform(void) -{ - sha256_transform(); + for (i = 0; i<8; i++) TT.state.i32[i] += rot[i]; } -static void sha512_transform(void) +static void sha2_64_transform(void) { + unsigned long long block[80], s0, s1, S0, S1, ch, maj, temp1, temp2, rot[8]; int i; - uint64_t block[80]; - uint64_t s0, s1, S0, S1, ch, maj, temp1, temp2; - uint64_t rot[8]; // a,b,c,d,e,f,g,h - - /* - printf("buffer.c[0 - 4] = %02hhX %02hhX %02hhX %02hhX %02hhX\n", TT.buffer.c[0], TT.buffer.c[1], TT.buffer.c[2], TT.buffer.c[3], TT.buffer.c[4]); - printf("buffer.c[112 - 127] = %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX\n", \ - TT.buffer.c[112], TT.buffer.c[113], TT.buffer.c[114], TT.buffer.c[115], \ - TT.buffer.c[116], TT.buffer.c[117], TT.buffer.c[118], TT.buffer.c[119], \ - TT.buffer.c[120], TT.buffer.c[121], TT.buffer.c[122], TT.buffer.c[123], \ - TT.buffer.c[124], TT.buffer.c[125], TT.buffer.c[126], TT.buffer.c[127]); - */ - for (i=0; i<16; i++) { - block[i] = SWAP_BE64(TT.buffer.i64[i]); - } + + for (i=0; i<16; i++) block[i] = SWAP_BE64(TT.buffer.i64[i]); + // Extend the message schedule array beyond first 16 words - for (i=16; i<80; i++) { + for (i = 16; i<80; i++) { s0 = ror64(block[i-15], 1) ^ ror64(block[i-15], 8) ^ (block[i-15] >> 7); s1 = ror64(block[i-2], 19) ^ ror64(block[i-2], 61) ^ (block[i-2] >> 6); block[i] = block[i-16] + s0 + block[i-7] + s1; } // Copy context->state.i64[] to working vars - for (i=0; i<8; i++) { - rot[i] = TT.state.i64[i]; - } + for (i = 0; i<8; i++) rot[i] = TT.state.i64[i]; // 80 rounds - for (i=0; i<80; i++) { + for (i = 0; i<80; i++) { S1 = ror64(rot[4],14) ^ ror64(rot[4],18) ^ ror64(rot[4], 41); ch = (rot[4] & rot[5]) ^ ((~ rot[4]) & rot[6]); temp1 = rot[7] + S1 + ch + TT.rconsttable64[i] + block[i]; S0 = ror64(rot[0],28) ^ ror64(rot[0],34) ^ ror64(rot[0], 39); maj = (rot[0] & rot[1]) ^ (rot[0] & rot[2]) ^ (rot[1] & rot[2]); temp2 = S0 + maj; - /* - if (i < 3) { - printf(" S1=%lu ch=%lu temp1=%lu S0=%lu maj=%lu temp2=%lu\n", S1,ch,temp1,S0,maj,temp2); - printf(" rot[7]=%lu K[i]=%lu W[i]=%lu TT.buffer.i64[i]=%lu\n", rot[7],TT.rconsttable64[i],block[i],TT.buffer.i64[i]); - } - */ - rot[7] = rot[6]; - rot[6] = rot[5]; - rot[5] = rot[4]; - rot[4] = rot[3] + temp1; - rot[3] = rot[2]; - rot[2] = rot[1]; - rot[1] = rot[0]; + memmove(rot+1, rot, 56); + rot[4] += temp1; rot[0] = temp1 + temp2; - /* - if ((i < 3) || (i > 77)) { - //printf("after round %d: rot[0] = %lu rot[1] = %lu rot[2] = %lu\n", i, rot[0], rot[1], rot[2]); - printf("t= %d: A=%08X%08X B=%08X%08X C= %08X%08X D=%08X%08X\n", i, \ - (uint32_t) (rot[0] >> 32), (uint32_t) rot[0], \ - (uint32_t) (rot[1] >> 32), (uint32_t) rot[1], \ - (uint32_t) (rot[2] >> 32), (uint32_t) rot[2], \ - (uint32_t) (rot[3] >> 32), (uint32_t) rot[3] \ - ); - printf("t= %d: E=%08X%08X F=%08X%08X G= %08X%08X H=%08X%08X\n", i, \ - (uint32_t) (rot[4] >> 32), (uint32_t) rot[4], \ - (uint32_t) (rot[5] >> 32), (uint32_t) rot[5], \ - (uint32_t) (rot[6] >> 32), (uint32_t) rot[6], \ - (uint32_t) (rot[7] >> 32), (uint32_t) rot[7] \ - ); - } - */ } - //printf("%d rounds done: rot[0] = %lu rot[1] = %lu rot[2] = %lu\n", i, rot[0], rot[1], rot[2]); // Add the previous values of state.i64[] - /* - printf("t= %d: 0=%08X%08X 1=%08X%08X 2= %08X%08X 3=%08X%08X\n", -1, \ - (uint32_t) (TT.state.i64[0] >> 32), (uint32_t) TT.state.i64[0], \ - (uint32_t) (TT.state.i64[1] >> 32), (uint32_t) TT.state.i64[1], \ - (uint32_t) (TT.state.i64[2] >> 32), (uint32_t) TT.state.i64[2], \ - (uint32_t) (TT.state.i64[3] >> 32), (uint32_t) TT.state.i64[3] \ - ); - printf("t= %d: 4=%08X%08X 5=%08X%08X 6= %08X%08X 7=%08X%08X\n", -1, \ - (uint32_t) (TT.state.i64[4] >> 32), (uint32_t) TT.state.i64[4], \ - (uint32_t) (TT.state.i64[5] >> 32), (uint32_t) TT.state.i64[5], \ - (uint32_t) (TT.state.i64[6] >> 32), (uint32_t) TT.state.i64[6], \ - (uint32_t) (TT.state.i64[7] >> 32), (uint32_t) TT.state.i64[7] \ - ); - */ for (i=0; i<8; i++) TT.state.i64[i] += rot[i]; - /* - printf("t= %d: 0=%08X%08X 1=%08X%08X 2= %08X%08X 3=%08X%08X\n", -2, \ - (uint32_t) (TT.state.i64[0] >> 32), (uint32_t) TT.state.i64[0], \ - (uint32_t) (TT.state.i64[1] >> 32), (uint32_t) TT.state.i64[1], \ - (uint32_t) (TT.state.i64[2] >> 32), (uint32_t) TT.state.i64[2], \ - (uint32_t) (TT.state.i64[3] >> 32), (uint32_t) TT.state.i64[3] \ - ); - printf("t= %d: 4=%08X%08X 5=%08X%08X 6= %08X%08X 7=%08X%08X\n", -2, \ - (uint32_t) (TT.state.i64[4] >> 32), (uint32_t) TT.state.i64[4], \ - (uint32_t) (TT.state.i64[5] >> 32), (uint32_t) TT.state.i64[5], \ - (uint32_t) (TT.state.i64[6] >> 32), (uint32_t) TT.state.i64[6], \ - (uint32_t) (TT.state.i64[7] >> 32), (uint32_t) TT.state.i64[7] \ - ); - */ - //printf("state.i64[0] = %lu state.i64[1] = %lu state.i64[2] = %lu\n", TT.state.i64[0], TT.state.i64[1], TT.state.i64[2]); -} - -static void sha384_transform(void) -{ - sha512_transform(); } // Fill the 64/128-byte (512/1024-bit) working buffer and call transform() when full. -static void hash_update(char *data, unsigned int len, void (*transform)(void), int chunksize) +static void hash_update(char *data, unsigned int len, void (*transform)(void), + int chunksize) { unsigned int i, j; - //printf("starting hash_update() TT.count = %llu len = %d chunksize = %d\n", TT.count,len,chunksize); j = TT.count & (chunksize - 1); TT.count += len; @@ -443,18 +329,14 @@ static void hash_update(char *data, unsigned int len, void (*transform)(void), i i = chunksize - j; if (i>len) i = len; memcpy(TT.buffer.c+j, data, i); - //printf("checking chunksize. j(%d) + i(%d) = chunksize(%d) ?\n", j,i,chunksize); if (j+i != chunksize) break; // Process a frame if (IS_BIG_ENDIAN) { // TODO: test on big endian architecture - if ((TT.hashmethod == SHA512) || (TT.hashmethod == SHA384)) { + if (TT.hashmethod>=SHA384) for (j=0; j<16; j++) TT.buffer.i64[j] = SWAP_LE64(TT.buffer.i64[j]); - } else { // MD5, SHA1, SHA224, SHA256 - for (j=0; j<16; j++) TT.buffer.i32[j] = SWAP_LE32(TT.buffer.i32[j]); - } + else for (j=0; j<16; j++) TT.buffer.i32[j] = SWAP_LE32(TT.buffer.i32[j]); } - //printf("calling transform. hashmethod = %d\n", TT.hashmethod); transform(); j=0; data += i; @@ -510,92 +392,43 @@ static void do_lib_hash(int fd, char *name) static void do_builtin_hash(int fd, char *name) { - uint64_t count; - int i, chunksize, lengthsize, digestlen; - char buf, *pp; + unsigned long long count; + int i, chunksize, digestlen; + volatile char *pp; void (*transform)(void); + char buf; + + // 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) + memcpy(TT.state.i32, (unsigned []){0x67452301, 0xEFCDAB89, 0x98BADCFE, + 0x10325476, 0xC3D2E1F0}, 20); + else if (TT.hashmethod==SHA224) + memcpy(TT.state.i32, (unsigned []){0xc1059ed8, 0x367cd507, 0x3070dd17, + 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4}, 32); + else if (TT.hashmethod==SHA256) + memcpy(TT.state.i32, (unsigned []){0x6a09e667, 0xbb67ae85, 0x3c6ef372, + 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}, 32); + else if (TT.hashmethod==SHA384) + memcpy(TT.state.i64, (unsigned long long []){0xcbbb9d5dc1059ed8, + 0x629a292a367cd507, 0x9159015a3070dd17, 0x152fecd8f70e5939, + 0x67332667ffc00b31, 0x8eb44a8768581511, 0xdb0c2e0d64f98fa7, + 0x47b5481dbefa4fa4}, 64); + else memcpy(TT.state.i64, (unsigned long long []){0x6a09e667f3bcc908, + 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, + 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, + 0x5be0cd19137e2179}, 64); TT.count = 0; - switch(TT.hashmethod) { - case MD5: - case SHA1: - transform = (TT.hashmethod == MD5) ? md5_transform : sha1_transform; - digestlen = (TT.hashmethod == MD5) ? 16 : 20; // bytes - chunksize = 64; // bytes - lengthsize = 8; // bytes - TT.state.i32[0] = 0x67452301; - TT.state.i32[1] = 0xEFCDAB89; - TT.state.i32[2] = 0x98BADCFE; - TT.state.i32[3] = 0x10325476; - TT.state.i32[4] = 0xC3D2E1F0; // not used for MD5 - break; - case SHA224: - transform = sha224_transform; - digestlen = 28; - chunksize = 64; - lengthsize = 8; - TT.state.i32[0] = 0xc1059ed8; - TT.state.i32[1] = 0x367cd507; - TT.state.i32[2] = 0x3070dd17; - TT.state.i32[3] = 0xf70e5939; - TT.state.i32[4] = 0xffc00b31; - TT.state.i32[5] = 0x68581511; - TT.state.i32[6] = 0x64f98fa7; - TT.state.i32[7] = 0xbefa4fa4; - break; - case SHA256: - transform = sha256_transform; - digestlen = 32; - chunksize = 64; - lengthsize = 8; - TT.state.i32[0] = 0x6a09e667; - TT.state.i32[1] = 0xbb67ae85; - TT.state.i32[2] = 0x3c6ef372; - TT.state.i32[3] = 0xa54ff53a; - TT.state.i32[4] = 0x510e527f; - TT.state.i32[5] = 0x9b05688c; - TT.state.i32[6] = 0x1f83d9ab; - TT.state.i32[7] = 0x5be0cd19; - break; - case SHA384: - transform = sha384_transform; - digestlen = 48; - chunksize = 128; - lengthsize = 8; // bytes. should be 16 according to spec - TT.state.i64[0] = 0xcbbb9d5dc1059ed8; - TT.state.i64[1] = 0x629a292a367cd507; - TT.state.i64[2] = 0x9159015a3070dd17; - TT.state.i64[3] = 0x152fecd8f70e5939; - TT.state.i64[4] = 0x67332667ffc00b31; - TT.state.i64[5] = 0x8eb44a8768581511; - TT.state.i64[6] = 0xdb0c2e0d64f98fa7; - TT.state.i64[7] = 0x47b5481dbefa4fa4; - break; - case SHA512: - transform = sha512_transform; - digestlen = 64; - chunksize = 128; - lengthsize = 8; // bytes. should be 16 according to spec - TT.state.i64[0] = 0x6a09e667f3bcc908; - TT.state.i64[1] = 0xbb67ae8584caa73b; - TT.state.i64[2] = 0x3c6ef372fe94f82b; - TT.state.i64[3] = 0xa54ff53a5f1d36f1; - TT.state.i64[4] = 0x510e527fade682d1; - TT.state.i64[5] = 0x9b05688c2b3e6c1f; - TT.state.i64[6] = 0x1f83d9abfb41bd6b; - TT.state.i64[7] = 0x5be0cd19137e2179; - break; - default: error_exit("unrecognized hash method name"); break; - } - for (;;) { i = read(fd, toybuf, sizeof(toybuf)); if (i<1) break; hash_update(toybuf, i, transform, chunksize); } - count = TT.count << 3; // convert to bytes - // 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. @@ -603,33 +436,25 @@ static void do_builtin_hash(int fd, char *name) // Since our input up to now has been in whole bytes, we can deal with // bytes here too. buf = 0x80; + count = TT.count << 3; // convert to bits do { hash_update(&buf, 1, transform, chunksize); buf = 0; - } while ((TT.count & (chunksize - 1)) != (chunksize - lengthsize)); + } while ((TT.count & (chunksize - 1)) != (chunksize - 8)); count = (TT.hashmethod == MD5) ? SWAP_LE64(count) : SWAP_BE64(count); - //printf("count=%ld count=%08X %08X\n", count, (uint32_t) (count >> 32), (uint32_t) count); hash_update((void *)&count, 8, transform, chunksize); // write digest to toybuf - if ((TT.hashmethod == SHA384) || (TT.hashmethod == SHA512)) { - for (i=0; i<digestlen/8; i++) { - sprintf(toybuf+16*i, "%016lx", TT.state.i64[i]); - } - } else { // MD5, SHA1, SHA224, SHA256 - 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] - ); - } - } + if (TT.hashmethod>=SHA384) 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. - // if we do this with memset(), gcc throws a broken warning, and the (uint32_t) - // typecasts stop gcc from breaking "undefined behavior" that isn't. - for (pp = (void *)TT.state.i64; (uint64_t)pp-(uint64_t)TT.state.i64<sizeof(TT)-((uint64_t)TT.state.i64-(uint64_t)&TT); pp++) - *pp = 0; - i = strlen(toybuf)+1; - memset(toybuf+i, 0, sizeof(toybuf)-i); + 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; + for (i = sizeof(toybuf)-(pp-toybuf); i; i--) *pp++ = 0; } // Callback for loopfiles() @@ -639,13 +464,12 @@ static void do_hash(int fd, char *name) if (CFG_TOYBOX_LIBCRYPTO) do_lib_hash(fd, name); else do_builtin_hash(fd, name); - if (name) - printf(FLAG(b) ? "%s\n" : "%s %s\n", toybuf, name); + if (name) printf("%s %s\n"+4*!!FLAG(b), toybuf, name); } -static int do_c_line(char *line) +static void do_c_line(char *line) { - int space = 0, fail = 0; + int space = 0, fail = 0, fd; char *name; for (name = line; *name; name++) { @@ -654,42 +478,32 @@ static int do_c_line(char *line) *name = 0; } else if (space) break; } + if (!space || !*line || !*name) return error_msg("bad line %s", line); - if (!space || !*line || !*name) error_msg("bad line %s", line); - else { - int fd = !strcmp(name, "-") ? 0 : open(name, O_RDONLY); - - TT.sawline = 1; - if (fd==-1) { - perror_msg_raw(name); - *toybuf = 0; - } else do_hash(fd, 0); - if (strcasecmp(line, toybuf)) toys.exitval = fail = 1; - if (!FLAG(s)) printf("%s: %s\n", name, fail ? "FAILED" : "OK"); - if (fd>0) close(fd); - } + fd = !strcmp(name, "-") ? 0 : open(name, O_RDONLY); - return 0; + TT.sawline = 1; + if (fd==-1) { + perror_msg_raw(name); + *toybuf = 0; + } else do_hash(fd, 0); + if (strcasecmp(line, toybuf)) toys.exitval = fail = 1; + if (!FLAG(s)) printf("%s: %s\n", name, fail ? "FAILED" : "OK"); + if (fd>0) close(fd); } // Used instead of loopfiles_line to report error on files containing no hashes. static void do_c_file(char *name) { FILE *fp = !strcmp(name, "-") ? stdin : fopen(name, "r"); + char *line; - if (!fp) { - perror_msg_raw(name); - return; - } + if (!fp) return perror_msg_raw(name); TT.sawline = 0; for (;;) { - char *line = 0; - ssize_t len; - - if ((len = getline(&line, (void *)&len, fp))<1) break; - if (line[len-1]=='\n') line[len-1] = 0; + if (!(line = xgetline(fp))) break; do_c_line(line); free(line); } @@ -700,41 +514,23 @@ static void do_c_file(char *name) void md5sum_main(void) { - char **arg; int i; - if (toys.which->name[0]=='m') { - TT.hashmethod = MD5; - } - // 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) { - switch(TT.hashmethod) { - case 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; - break; - case SHA1: // no table needed for SHA1 - break; - case SHA224: - case SHA256: + if (TT.hashmethod==MD5) { + if (CFG_TOYBOX_FLOAT) { TT.rconsttable32 = xmalloc(64*4); - for (i=0; i<64; i++) { - TT.rconsttable32[i] = (uint32_t) (sha512nofloat[i] >> 32); - } - break; - case SHA384: - case SHA512: - TT.rconsttable64 = sha512nofloat; - break; - default: error_exit("unrecognized hash method name"); break; - } + 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) { + 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; } - if (FLAG(c)) for (arg = toys.optargs; *arg; arg++) do_c_file(*arg); + if (FLAG(c)) for (i = 0; toys.optargs[i]; i++) do_c_file(toys.optargs[i]); else { if (FLAG(s)) error_exit("-s only with -c"); loopfiles(toys.optargs, do_hash); |