From 6e383cf6cd0d2af1371f40a3892d7c2962a3c299 Mon Sep 17 00:00:00 2001 From: Andreas Steffen Date: Fri, 19 Mar 2021 09:51:04 +0100 Subject: [PATCH] Full implementation of SHAKE256 The current SHAKE256 implementation squeezes output bytes only up to the rate limit of 136 bytes. This has been fixed to support the output of an unlimited amount of bytes complying with the NIST FIPS 202 standard. --- wolfcrypt/src/sha3.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/wolfcrypt/src/sha3.c b/wolfcrypt/src/sha3.c index 74375640f..dacbc0df6 100644 --- a/wolfcrypt/src/sha3.c +++ b/wolfcrypt/src/sha3.c @@ -636,30 +636,47 @@ static int Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p) * len Number of bytes in output. * returns 0 on success. */ -static int Sha3Final(wc_Sha3* sha3, byte padChar, byte* hash, byte p, byte l) +static int Sha3Final(wc_Sha3* sha3, byte padChar, byte* hash, byte p, word32 l) { +#if defined(BIG_ENDIAN_ORDER) + word32 q = (l + 7) / 8; +#endif + word32 k, rate = p * 8; byte i; byte *state = (byte *)sha3->s; - sha3->t[p * 8 - 1] = 0x00; + sha3->t[rate - 1] = 0x00; #ifdef WOLFSSL_HASH_FLAGS if (p == WC_SHA3_256_COUNT && sha3->flags & WC_HASH_SHA3_KECCAK256) { padChar = 0x01; } #endif sha3->t[ sha3->i] = padChar; - sha3->t[p * 8 - 1] |= 0x80; - for (i=sha3->i + 1; i < p * 8 - 1; i++) + sha3->t[rate - 1] |= 0x80; + for (i=sha3->i + 1; i < rate - 1; i++) sha3->t[i] = 0; for (i = 0; i < p; i++) sha3->s[i] ^= Load64BitBigEndian(sha3->t + 8 * i); BlockSha3(sha3->s); #if defined(BIG_ENDIAN_ORDER) - ByteReverseWords64(sha3->s, sha3->s, ((l+7)/8)*8); + ByteReverseWords64(sha3->s, sha3->s, (q > p) ? rate : q * 8); #endif - for (i = 0; i < l; i++) - hash[i] = state[i]; - + i = 0; + for (k = 0; k < l; k++) + { + if (i == rate) + { + i = 0; +#if defined(BIG_ENDIAN_ORDER) + ByteReverseWords64(sha3->s, sha3->s, rate); + BlockSha3(sha3->s); + ByteReverseWords64(sha3->s, sha3->s, rate); +#else + BlockSha3(sha3->s); +#endif + } + hash[k] = state[i++]; + } return 0; } @@ -763,7 +780,7 @@ static int wc_Sha3Final(wc_Sha3* sha3, byte* hash, byte p, byte len) } #endif /* WOLFSSL_ASYNC_CRYPT */ - ret = Sha3Final(sha3, 0x06, hash, p, len); + ret = Sha3Final(sha3, 0x06, hash, p, (word32)len); if (ret != 0) return ret; @@ -1193,7 +1210,7 @@ int wc_Shake256_Final(wc_Shake* shake, byte* hash, word32 hashLen) return BAD_FUNC_ARG; } - ret = Sha3Final(shake, 0x1f, hash, WC_SHA3_256_COUNT, (byte)hashLen); + ret = Sha3Final(shake, 0x1f, hash, WC_SHA3_256_COUNT, hashLen); if (ret != 0) return ret;