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.
This commit is contained in:
Andreas Steffen
2021-03-19 09:51:04 +01:00
parent a688245738
commit 6e383cf6cd

View File

@@ -636,30 +636,47 @@ static int Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p)
* len Number of bytes in output. * len Number of bytes in output.
* returns 0 on success. * 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 i;
byte *state = (byte *)sha3->s; byte *state = (byte *)sha3->s;
sha3->t[p * 8 - 1] = 0x00; sha3->t[rate - 1] = 0x00;
#ifdef WOLFSSL_HASH_FLAGS #ifdef WOLFSSL_HASH_FLAGS
if (p == WC_SHA3_256_COUNT && sha3->flags & WC_HASH_SHA3_KECCAK256) { if (p == WC_SHA3_256_COUNT && sha3->flags & WC_HASH_SHA3_KECCAK256) {
padChar = 0x01; padChar = 0x01;
} }
#endif #endif
sha3->t[ sha3->i] = padChar; sha3->t[ sha3->i] = padChar;
sha3->t[p * 8 - 1] |= 0x80; sha3->t[rate - 1] |= 0x80;
for (i=sha3->i + 1; i < p * 8 - 1; i++) for (i=sha3->i + 1; i < rate - 1; i++)
sha3->t[i] = 0; sha3->t[i] = 0;
for (i = 0; i < p; i++) for (i = 0; i < p; i++)
sha3->s[i] ^= Load64BitBigEndian(sha3->t + 8 * i); sha3->s[i] ^= Load64BitBigEndian(sha3->t + 8 * i);
BlockSha3(sha3->s); BlockSha3(sha3->s);
#if defined(BIG_ENDIAN_ORDER) #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 #endif
for (i = 0; i < l; i++) i = 0;
hash[i] = state[i]; 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; return 0;
} }
@@ -763,7 +780,7 @@ static int wc_Sha3Final(wc_Sha3* sha3, byte* hash, byte p, byte len)
} }
#endif /* WOLFSSL_ASYNC_CRYPT */ #endif /* WOLFSSL_ASYNC_CRYPT */
ret = Sha3Final(sha3, 0x06, hash, p, len); ret = Sha3Final(sha3, 0x06, hash, p, (word32)len);
if (ret != 0) if (ret != 0)
return ret; return ret;
@@ -1193,7 +1210,7 @@ int wc_Shake256_Final(wc_Shake* shake, byte* hash, word32 hashLen)
return BAD_FUNC_ARG; 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) if (ret != 0)
return ret; return ret;