Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .wolfssl_known_macro_extras
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,7 @@ WC_RSA_NONBLOCK
WC_RSA_NONBLOCK_TIME
WC_RSA_NO_FERMAT_CHECK
WC_RWLOCK_OPS_INLINE
WC_SHA3_HARDEN
WC_SHA384
WC_SHA384_DIGEST_SIZE
WC_SHA512
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2726,7 +2726,7 @@ AC_ARG_ENABLE([faultharden],

if test "$ENABLED_FAULTHARDEN" = "yes"
then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CHECK_SIG_FAULTS -DWOLFSSL_CHECK_VER_FAULTS"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CHECK_SIG_FAULTS -DWOLFSSL_CHECK_VER_FAULTS -DWC_SHA3_HARDEN"
fi

AC_ARG_ENABLE([compileharden],
Expand Down
211 changes: 142 additions & 69 deletions wolfcrypt/src/sha3.c
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ static WC_INLINE word64 Load64Unaligned(const unsigned char *a)
* a Array of bytes.
* returns a 64-bit integer.
*/
static word64 Load64BitBigEndian(const byte* a)
static word64 Load64BitLittleEndian(const byte* a)
{
word64 n = 0;
int i;
Expand All @@ -595,6 +595,31 @@ static word64 Load64BitBigEndian(const byte* a)

return n;
}
#elif defined(WC_SHA3_HARDEN)
static WC_INLINE word64 Load64Unaligned(const unsigned char *a)
{
#ifdef WC_64BIT_CPU
return *(word64*)a;
#elif defined(WC_32BIT_CPU)
return (((word64)((word32*)a)[1]) << 32) ||
((word32*)a)[0];
#else
return (((word64)((word16*)a)[3]) << 48) ||
(((word64)((word16*)a)[2]) << 32) ||
(((word64)((word16*)a)[1]) << 16) ||
((word16*)a)[0];
#endif
}

/* Convert the array of bytes, in little-endian order, to a 64-bit integer.
*
* a Array of bytes.
* returns a 64-bit integer.
*/
static word64 Load64BitLittleEndian(const byte* a)
{
return Load64Unaligned(a);
}
#endif

/* Initialize the state for a SHA3-224 hash operation.
Expand Down Expand Up @@ -687,6 +712,10 @@ static int Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p)
{
word32 i;
word32 blocks;
#ifdef WC_SHA3_HARDEN
byte check = 0;
byte total_check = 0;
#endif

#if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && defined(USE_INTEL_SPEEDUP)
if (SHA3_BLOCK == sha3_block_avx2) {
Expand All @@ -703,19 +732,37 @@ static int Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p)
t = &sha3->t[sha3->i];
for (i = 0; i < l; i++) {
t[i] = data[i];
#ifdef WC_SHA3_HARDEN
check++;
#endif
}
#ifdef WC_SHA3_HARDEN
if (check != l) {
return BAD_COND_E;
}
total_check += l;
#endif
data += i;
len -= i;
sha3->i = (byte)(sha3->i + i);

if (sha3->i == p * 8) {
#if !defined(BIG_ENDIAN_ORDER)
#if !defined(BIG_ENDIAN_ORDER) && !defined(WC_SHA3_HARDEN)
xorbuf(sha3->s, sha3->t, (word32)(p * 8));
#else
#else
for (i = 0; i < p; i++) {
sha3->s[i] ^= Load64BitBigEndian(sha3->t + 8 * i);
sha3->s[i] ^= Load64BitLittleEndian(sha3->t + 8 * i);
#ifdef WC_SHA3_HARDEN
check++;
#endif
}
#ifdef WC_SHA3_HARDEN
if (check != p + l) {
return BAD_COND_E;
}
total_check += p;
#endif
#endif
#ifdef SHA3_FUNC_PTR
(*SHA3_BLOCK)(sha3->s);
#else
Expand All @@ -733,14 +780,25 @@ static int Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p)
blocks = 0;
}
#endif
#ifdef WC_SHA3_HARDEN
total_check += blocks * p;
#endif
for (; blocks > 0; blocks--) {
#if !defined(BIG_ENDIAN_ORDER)
#if !defined(BIG_ENDIAN_ORDER) && !defined(WC_SHA3_HARDEN)
xorbuf(sha3->s, data, (word32)(p * 8));
#else
#else
for (i = 0; i < p; i++) {
sha3->s[i] ^= Load64Unaligned(data + 8 * i);
#ifdef WC_SHA3_HARDEN
check++;
#endif
}
#ifdef WC_SHA3_HARDEN
if (check != total_check - ((blocks - 1) * p)) {
return BAD_COND_E;
}
#endif
#endif
#ifdef SHA3_FUNC_PTR
(*SHA3_BLOCK)(sha3->s);
#else
Expand All @@ -749,6 +807,11 @@ static int Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p)
len -= p * 8U;
data += p * 8U;
}
#ifdef WC_SHA3_HARDEN
if (check != total_check) {
return BAD_COND_E;
}
#endif
#if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && defined(USE_INTEL_SPEEDUP)
if (SHA3_BLOCK == sha3_block_avx2) {
RESTORE_VECTOR_REGISTERS();
Expand All @@ -774,11 +837,14 @@ static int Sha3Final(wc_Sha3* sha3, byte padChar, byte* hash, byte p, word32 l)
{
word32 rate = p * 8U;
word32 j;
#if defined(BIG_ENDIAN_ORDER)
#if defined(BIG_ENDIAN_ORDER) || defined(WC_SHA3_HARDEN)
word32 i;
#endif
#ifdef WC_SHA3_HARDEN
int check = 0;
#endif

#if !defined(BIG_ENDIAN_ORDER)
#if !defined(BIG_ENDIAN_ORDER) && !defined(WC_SHA3_HARDEN)
xorbuf(sha3->s, sha3->t, sha3->i);
#ifdef WOLFSSL_HASH_FLAGS
if ((p == WC_SHA3_256_COUNT) && (sha3->flags & WC_HASH_SHA3_KECCAK256)) {
Expand All @@ -800,8 +866,16 @@ static int Sha3Final(wc_Sha3* sha3, byte padChar, byte* hash, byte p, word32 l)
XMEMSET(sha3->t + sha3->i + 1, 0, rate - 1U - (sha3->i + 1U));
}
for (i = 0; i < p; i++) {
sha3->s[i] ^= Load64BitBigEndian(sha3->t + 8 * i);
sha3->s[i] ^= Load64BitLittleEndian(sha3->t + 8 * i);
#ifdef WC_SHA3_HARDEN
check++;
#endif
}
#ifdef WC_SHA3_HARDEN
if (check != p) {
return BAD_COND_E;
}
#endif
#endif

#if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && defined(USE_INTEL_SPEEDUP)
Expand Down Expand Up @@ -843,80 +917,79 @@ static int Sha3Final(wc_Sha3* sha3, byte padChar, byte* hash, byte p, word32 l)
#endif
#if defined(STM32_HASH_SHA3)

/* Supports CubeMX HAL or Standard Peripheral Library */
/* Supports CubeMX HAL or Standard Peripheral Library */

static int wc_InitSha3(wc_Sha3* sha3, void* heap, int devId)
{
if (sha3 == NULL)
return BAD_FUNC_ARG;
static int wc_InitSha3(wc_Sha3* sha3, void* heap, int devId)
{
if (sha3 == NULL)
return BAD_FUNC_ARG;

(void)devId;
(void)heap;
(void)devId;
(void)heap;

XMEMSET(sha3, 0, sizeof(wc_Sha3));
wc_Stm32_Hash_Init(&sha3->stmCtx);
return 0;
}
XMEMSET(sha3, 0, sizeof(wc_Sha3));
wc_Stm32_Hash_Init(&sha3->stmCtx);
return 0;
}

static int Stm32GetAlgo(byte p)
{
switch(p) {
case WC_SHA3_224_COUNT:
return HASH_ALGOSELECTION_SHA3_224;
case WC_SHA3_256_COUNT:
return HASH_ALGOSELECTION_SHA3_256;
case WC_SHA3_384_COUNT:
return HASH_ALGOSELECTION_SHA3_384;
case WC_SHA3_512_COUNT:
return HASH_ALGOSELECTION_SHA3_512;
}
/* Should never get here */
return WC_SHA3_224_COUNT;
static int Stm32GetAlgo(byte p)
{
switch(p) {
case WC_SHA3_224_COUNT:
return HASH_ALGOSELECTION_SHA3_224;
case WC_SHA3_256_COUNT:
return HASH_ALGOSELECTION_SHA3_256;
case WC_SHA3_384_COUNT:
return HASH_ALGOSELECTION_SHA3_384;
case WC_SHA3_512_COUNT:
return HASH_ALGOSELECTION_SHA3_512;
}
/* Should never get here */
return WC_SHA3_224_COUNT;
}

static int wc_Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p)
{
int ret = 0;
static int wc_Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p)
{
int ret = 0;

if (sha3 == NULL) {
return BAD_FUNC_ARG;
}
if (data == NULL && len == 0) {
/* valid, but do nothing */
return 0;
}
if (data == NULL) {
return BAD_FUNC_ARG;
}
if (sha3 == NULL) {
return BAD_FUNC_ARG;
}
if (data == NULL && len == 0) {
/* valid, but do nothing */
return 0;
}
if (data == NULL) {
return BAD_FUNC_ARG;
}

ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
ret = wc_Stm32_Hash_Update(&sha3->stmCtx,
Stm32GetAlgo(p), data, len, p * 8);
wolfSSL_CryptHwMutexUnLock();
}
return ret;
ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
ret = wc_Stm32_Hash_Update(&sha3->stmCtx, Stm32GetAlgo(p), data, len,
p * 8);
wolfSSL_CryptHwMutexUnLock();
}
return ret;
}

static int wc_Sha3Final(wc_Sha3* sha3, byte* hash, byte p, byte len)
{
int ret = 0;
static int wc_Sha3Final(wc_Sha3* sha3, byte* hash, byte p, byte len)
{
int ret = 0;

if (sha3 == NULL || hash == NULL) {
return BAD_FUNC_ARG;
}
if (sha3 == NULL || hash == NULL) {
return BAD_FUNC_ARG;
}

ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
ret = wc_Stm32_Hash_Final(&sha3->stmCtx,
Stm32GetAlgo(p), hash, len);
wolfSSL_CryptHwMutexUnLock();
}
ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
ret = wc_Stm32_Hash_Final(&sha3->stmCtx, Stm32GetAlgo(p), hash, len);
wolfSSL_CryptHwMutexUnLock();
}

(void)wc_InitSha3(sha3, NULL, 0); /* reset state */
(void)wc_InitSha3(sha3, NULL, 0); /* reset state */

return ret;
}
return ret;
}
#elif defined(PSOC6_HASH_SHA3)

static int wc_InitSha3(wc_Sha3* sha3, void* heap, int devId)
Expand Down