Hi Lauri, On Fri, Jan 04, 2013 at 01:02:53PM +0200, Lauri Kasanen wrote: > From 84768213e7a004b9e703a1d7091bd43b34822e0c Mon Sep 17 00:00:00 2001 > From: Lauri Kasanen <cur...@operamail.com> > Date: Thu, 3 Jan 2013 21:10:01 +0200 > Subject: [PATCH] sha3sum: New applet, v2 > > - Sorted the enum by alpha (was sorted by algorithm age) > - Use normal rotate here, xor not needed > - Comment cleanup > - Remove *empty* comments > - Unify one be/le path > - Remove #define round > - Move to if(BB_ENDIAN) instead of #if
Testing on a big-endian system (PowerPC) I'm getting: # echo test |./busybox sha3sum Segmentation fault (core dumped) On a PC I get: $ echo test |./busybox sha3sum a5c3e353a185244f82a8de017db6022543d776f8943b457b6368c80854ecdfda1705e5dd514d5087116daccb7dace5ad42ab172bfe79a2c00b7a1e9c76e46b55 - Any suggestion? baruch > Signed-off-by: Lauri Kasanen <cur...@operamail.com> > --- > coreutils/Config.src | 12 ++- > coreutils/Kbuild.src | 1 + > coreutils/md5_sha1_sum.c | 17 ++++ > include/applets.src.h | 1 + > include/libbb.h | 7 ++ > libbb/hash_md5_sha.c | 212 > ++++++++++++++++++++++++++++++++++++++++++++++ > testsuite/sha3sum.tests | 3 + > 7 files changed, 250 insertions(+), 3 deletions(-) > create mode 100755 testsuite/sha3sum.tests > > diff --git a/coreutils/Config.src b/coreutils/Config.src > index a28449b..0c44c4b 100644 > --- a/coreutils/Config.src > +++ b/coreutils/Config.src > @@ -514,6 +514,12 @@ config SHA512SUM > help > Compute and check SHA512 message digest > > +config SHA3SUM > + bool "sha3sum" > + default y > + help > + Compute and check SHA3 (512-bit) message digest > + > config SLEEP > bool "sleep" > default y > @@ -766,13 +772,13 @@ config FEATURE_HUMAN_READABLE > help > Allow df, du, and ls to have human readable output. > > -comment "Common options for md5sum, sha1sum, sha256sum, sha512sum" > - depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM > +comment "Common options for md5sum, sha1sum, sha256sum, sha512sum, sha3sum" > + depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM || SHA3SUM > > config FEATURE_MD5_SHA1_SUM_CHECK > bool "Enable -c, -s and -w options" > default y > - depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM > + depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM || SHA3SUM > help > Enabling the -c options allows files to be checked > against pre-calculated hash values. > diff --git a/coreutils/Kbuild.src b/coreutils/Kbuild.src > index d6453f0..b715b9c 100644 > --- a/coreutils/Kbuild.src > +++ b/coreutils/Kbuild.src > @@ -62,6 +62,7 @@ lib-$(CONFIG_SEQ) += seq.o > lib-$(CONFIG_SHA1SUM) += md5_sha1_sum.o > lib-$(CONFIG_SHA256SUM) += md5_sha1_sum.o > lib-$(CONFIG_SHA512SUM) += md5_sha1_sum.o > +lib-$(CONFIG_SHA3SUM) += md5_sha1_sum.o > lib-$(CONFIG_SLEEP) += sleep.o > lib-$(CONFIG_SPLIT) += split.o > lib-$(CONFIG_SORT) += sort.o > diff --git a/coreutils/md5_sha1_sum.c b/coreutils/md5_sha1_sum.c > index 2cb6dd4..b62e7c2 100644 > --- a/coreutils/md5_sha1_sum.c > +++ b/coreutils/md5_sha1_sum.c > @@ -55,6 +55,16 @@ > //usage: "\n -s Don't output anything, status code shows > success" > //usage: "\n -w Warn about improperly formatted checksum lines" > //usage: ) > +//usage: > +//usage:#define sha3sum_trivial_usage > +//usage: IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[FILE]..." > +//usage:#define sha3sum_full_usage "\n\n" > +//usage: "Print" IF_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " SHA3-512 > checksums" > +//usage: IF_FEATURE_MD5_SHA1_SUM_CHECK( "\n" > +//usage: "\n -c Check sums against list in FILEs" > +//usage: "\n -s Don't output anything, status code shows > success" > +//usage: "\n -w Warn about improperly formatted checksum lines" > +//usage: ) > > #include "libbb.h" > > @@ -65,6 +75,7 @@ enum { > HASH_MD5 = 's', /* "md5>s<um" */ > HASH_SHA1 = '1', > HASH_SHA256 = '2', > + HASH_SHA3 = '3', > HASH_SHA512 = '5', > }; > > @@ -86,6 +97,7 @@ static uint8_t *hash_file(const char *filename) > { > int src_fd, hash_len, count; > union _ctx_ { > + sha3_ctx_t sha3; > sha512_ctx_t sha512; > sha256_ctx_t sha256; > sha1_ctx_t sha1; > @@ -124,6 +136,11 @@ static uint8_t *hash_file(const char *filename) > update = (void*)sha512_hash; > final = (void*)sha512_end; > hash_len = 64; > + } else if (ENABLE_SHA3SUM && hash_algo == HASH_SHA3) { > + sha3_begin(&context.sha3); > + update = (void*)sha3_hash; > + final = (void*)sha3_end; > + hash_len = 64; > } else { > xfunc_die(); /* can't reach this */ > } > diff --git a/include/applets.src.h b/include/applets.src.h > index 597b1c9..29ab167 100644 > --- a/include/applets.src.h > +++ b/include/applets.src.h > @@ -328,6 +328,7 @@ IF_SETSEBOOL(APPLET(setsebool, BB_DIR_USR_SBIN, > BB_SUID_DROP)) > IF_SETSID(APPLET(setsid, BB_DIR_USR_BIN, BB_SUID_DROP)) > IF_SETUIDGID(APPLET_ODDNAME(setuidgid, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, > setuidgid)) > IF_SHA1SUM(APPLET_NOEXEC(sha1sum, md5_sha1_sum, BB_DIR_USR_BIN, > BB_SUID_DROP, sha1sum)) > +IF_SHA3SUM(APPLET_NOEXEC(sha3sum, md5_sha1_sum, BB_DIR_USR_BIN, > BB_SUID_DROP, sha3sum)) > IF_SHA256SUM(APPLET_NOEXEC(sha256sum, md5_sha1_sum, BB_DIR_USR_BIN, > BB_SUID_DROP, sha256sum)) > IF_SHA512SUM(APPLET_NOEXEC(sha512sum, md5_sha1_sum, BB_DIR_USR_BIN, > BB_SUID_DROP, sha512sum)) > IF_SHOWKEY(APPLET(showkey, BB_DIR_USR_BIN, BB_SUID_DROP)) > diff --git a/include/libbb.h b/include/libbb.h > index 2059567..4ee07cd 100644 > --- a/include/libbb.h > +++ b/include/libbb.h > @@ -1636,6 +1636,10 @@ typedef struct sha512_ctx_t { > uint64_t hash[8]; > uint8_t wbuffer[128]; /* always correctly aligned for uint64_t */ > } sha512_ctx_t; > +ALIGNED(32) typedef struct sha3_ctx_t { > + uint8_t state[200] ALIGNED(32); > + int bitsInQueue; > +} sha3_ctx_t; > void md5_begin(md5_ctx_t *ctx) FAST_FUNC; > void md5_hash(md5_ctx_t *ctx, const void *data, size_t length) FAST_FUNC; > void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC; > @@ -1648,6 +1652,9 @@ void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC; > void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; > void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) > FAST_FUNC; > void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; > +void sha3_begin(sha3_ctx_t *state) FAST_FUNC; > +void sha3_hash(sha3_ctx_t *state, const uint8_t *data, uint64_t bytes) > FAST_FUNC; > +void sha3_end(sha3_ctx_t *state, uint8_t *res) FAST_FUNC; > > extern uint32_t *global_crc32_table; > uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC; > diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c > index a313c2a..daf2ec5 100644 > --- a/libbb/hash_md5_sha.c > +++ b/libbb/hash_md5_sha.c > @@ -31,6 +31,11 @@ static ALWAYS_INLINE uint64_t rotr64(uint64_t x, unsigned > n) > return (x >> n) | (x << (64 - n)); > } > > +/* rotl64 only used for sha3 currently */ > +static ALWAYS_INLINE uint64_t rotl64(uint64_t x, unsigned n) > +{ > + return (x << n) | (x >> (64 - n)); > +} > > /* Feed data through a temporary buffer. > * The internal buffer remembers previous data until it has 64 > @@ -896,3 +901,210 @@ void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void > *resbuf) > } > memcpy(resbuf, ctx->hash, sizeof(ctx->hash)); > } > + > + > +/* > + * The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, > + * Michael Peeters and Gilles Van Assche. For more information, feedback or > + * questions, please refer to our website: http://keccak.noekeon.org/ > + * > + * Implementation by Ronny Van Keer, > + * hereby denoted as "the implementer". > + * > + * To the extent possible under law, the implementer has waived all copyright > + * and related or neighboring rights to the source code in this file. > + * http://creativecommons.org/publicdomain/zero/1.0/ > + * > + * Busybox modifications (C) Lauri Kasanen, under the GPLv2. > + */ > + > +enum { > + cKeccakR = 576, > + cKeccakR_SizeInBytes = cKeccakR / 8, > + cKeccakNumberOfRounds = 24, > + cKeccakLaneSizeInBits = sizeof(uint64_t) * 8 > +}; > + > +static const uint64_t KeccakF_RoundConstants[cKeccakNumberOfRounds] = { > + 0x0000000000000001ULL, > + 0x0000000000008082ULL, > + 0x800000000000808aULL, > + 0x8000000080008000ULL, > + 0x000000000000808bULL, > + 0x0000000080000001ULL, > + 0x8000000080008081ULL, > + 0x8000000000008009ULL, > + 0x000000000000008aULL, > + 0x0000000000000088ULL, > + 0x0000000080008009ULL, > + 0x000000008000000aULL, > + 0x000000008000808bULL, > + 0x800000000000008bULL, > + 0x8000000000008089ULL, > + 0x8000000000008003ULL, > + 0x8000000000008002ULL, > + 0x8000000000000080ULL, > + 0x000000000000800aULL, > + 0x800000008000000aULL, > + 0x8000000080008081ULL, > + 0x8000000000008080ULL, > + 0x0000000080000001ULL, > + 0x8000000080008008ULL > +}; > + > +static const uint8_t KeccakF_RotationConstants[25] = { > + 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62, > + 18, 39, 61, 20, 44 > +}; > + > +static const uint8_t KeccakF_PiLane[25] = { > + 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20, > + 14, 22, 9, 6, 1 > +}; > + > +static const uint8_t KeccakF_Mod5[10] = { > + 0, 1, 2, 3, 4, 0, 1, 2, 3, 4 > +}; > + > +static void KeccakF(uint64_t *state, const uint64_t *in, int laneCount) > +{ > + uint8_t x, y; > + uint64_t temp; > + uint64_t BC[5]; > + int round; > + > + while (--laneCount >= 0) { > + state[laneCount] ^= SWAP_LE64(in[laneCount]); > + } > + > + for (round = 0; round < cKeccakNumberOfRounds; ++round) { > + /* Theta */ > + for (x = 0; x < 5; ++x) { > + BC[x] = > + state[x] ^ state[5 + x] ^ state[10 + x] ^ state[15 + > + x] ^ > + state[20 + x]; > + } > + for (x = 0; x < 5; ++x) { > + temp = > + BC[KeccakF_Mod5[x + 4]] ^ > + rotl64(BC[KeccakF_Mod5[x + 1]], 1); > + for (y = 0; y < 25; y += 5) { > + state[y + x] ^= temp; > + } > + } > + > + /* Rho Pi */ > + temp = state[1]; > + for (x = 0; x < 24; ++x) { > + BC[0] = state[KeccakF_PiLane[x]]; > + state[KeccakF_PiLane[x]] = > + rotl64(temp, KeccakF_RotationConstants[x]); > + temp = BC[0]; > + } > + > + /* Chi */ > + for (y = 0; y < 25; y += 5) { > + BC[0] = state[y + 0]; > + BC[1] = state[y + 1]; > + BC[2] = state[y + 2]; > + BC[3] = state[y + 3]; > + BC[4] = state[y + 4]; > + for (x = 0; x < 5; ++x) { > + state[y + x] = > + BC[x] ^ ((~BC[KeccakF_Mod5[x + 1]]) & > + BC[KeccakF_Mod5[x + 2]]); > + } > + } > + > + /* Iota */ > + state[0] ^= KeccakF_RoundConstants[round]; > + } > +} > + > +void FAST_FUNC sha3_begin(sha3_ctx_t *state) > +{ > + state->bitsInQueue = 0; > + memset(state->state, 0, sizeof(state->state)); > +} > + > +void FAST_FUNC sha3_hash(sha3_ctx_t *state, const uint8_t *data, > + uint64_t bytes) > +{ > + > + uint64_t databitlen = bytes * 8; > + > + if ((state->bitsInQueue < 0) || ((state->bitsInQueue % 8) != 0)) { > + /* Final() already called or bits already in queue not modulo > 8. */ > + return; > + } > + > + /* If already data in queue, continue queuing first */ > + for (; (databitlen >= 8) && (state->bitsInQueue != 0); > + databitlen -= 8) { > + state->state[state->bitsInQueue / 8] ^= *(data++); > + if ((state->bitsInQueue += 8) == cKeccakR) { > + KeccakF((uint64_t *) state->state, 0, 0); > + state->bitsInQueue = 0; > + } > + } > + > + /* Absorb complete blocks */ > + for (; databitlen >= cKeccakR; > + databitlen -= cKeccakR, data += cKeccakR_SizeInBytes) { > + KeccakF((uint64_t *) state->state, (const uint64_t *)data, > + cKeccakR_SizeInBytes / sizeof(uint64_t)); > + } > + > + /* Queue remaining data bytes */ > + for (; databitlen >= 8; > + databitlen -= 8, state->bitsInQueue += 8) { > + state->state[state->bitsInQueue / 8] ^= *(data++); > + } > + /* Queue eventual remaining data bits plus add first padding bit */ > + if (databitlen != 0) { > + state->state[state->bitsInQueue / 8] ^= > + (*data >> (8 - databitlen)); > + state->bitsInQueue += (int)databitlen; > + } > +} > + > +void FAST_FUNC sha3_end(sha3_ctx_t *state, uint8_t *hashval) > +{ > + const unsigned hashbytelen = 64; > + > + if (state->bitsInQueue < 0) { > + /* Final() already called. */ > + return; > + } > + > + /* Padding */ > + if (state->bitsInQueue + 1 == cKeccakR_SizeInBytes * 8) { > + state->state[cKeccakR_SizeInBytes - 1] ^= 0x80; > + KeccakF((uint64_t *) state->state, 0, 0); > + } else { > + state->state[state->bitsInQueue / 8] ^= > + 1 << (state->bitsInQueue % 8); > + } > + > + state->state[cKeccakR_SizeInBytes - 1] ^= 0x80; > + KeccakF((uint64_t *) state->state, 0, 0); > + > + /* Output */ > + > + if (BB_LITTLE_ENDIAN) { > + memcpy(hashval, state->state, hashbytelen); > + } else { > + unsigned offset; > + for (offset = 0; offset < hashbytelen; offset += > sizeof(uint64_t)) { > + uint8_t j; > + > + for (j = 0; j < sizeof(uint64_t); ++j) { > + hashval[offset + j] = > + state->state[offset + (sizeof(uint64_t) - > 1) - j]; > + } > + } > + } > + > + state->bitsInQueue = -1; /* flag final state */ > +} > diff --git a/testsuite/sha3sum.tests b/testsuite/sha3sum.tests > new file mode 100755 > index 0000000..82fada6 > --- /dev/null > +++ b/testsuite/sha3sum.tests > @@ -0,0 +1,3 @@ > +#!/bin/sh > + > +. ./md5sum.tests sha3sum > c29d77bc548fa2b20a04c861400a5360879c52156e2a54a3415b99a9a3123e1d5f36714a24eca8c1f05a8e2d8ba859c930d41141f64a255c6794436fc99c486a > -- > 1.7.2.1 > > _______________________________________________ > busybox mailing list > busybox@busybox.net > http://lists.busybox.net/mailman/listinfo/busybox -- http://baruch.siach.name/blog/ ~. .~ Tk Open Systems =}------------------------------------------------ooO--U--Ooo------------{= - bar...@tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il - _______________________________________________ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox