Skip to content
4 changes: 2 additions & 2 deletions tests/api/test_digest.h
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ do { \
ExpectIntEQ(wc_##name##_Final(&dst, hashDst, WC_##upper##_COUNT * 8), 0); \
ExpectBufEQ(hashSrc, emptyHash, WC_##upper##_COUNT * 8); \
ExpectBufEQ(hashDst, emptyHash, WC_##upper##_COUNT * 8); \
wc_##name##_Free(&src); \
wc_##name##_Free(&dst); \
\
/* Test buffered data is copied. */ \
ExpectIntEQ(wc_##name##_Update(&src, (byte*)"abc", 3), 0); \
Expand All @@ -583,7 +583,7 @@ do { \
ExpectIntEQ(wc_##name##_Final(&dst, hashDst, WC_##upper##_COUNT * 8), 0); \
ExpectBufEQ(hashSrc, abcHash, WC_##upper##_COUNT * 8); \
ExpectBufEQ(hashDst, abcHash, WC_##upper##_COUNT * 8); \
wc_##name##_Free(&src); \
wc_##name##_Free(&dst); \
\
/* Test count of length is copied. */ \
ExpectIntEQ(wc_##name##_Update(&src, data, sizeof(data)), 0); \
Expand Down
84 changes: 59 additions & 25 deletions wolfcrypt/src/aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,7 @@ static WC_INLINE void wc_Stm32_CrypAesBlock(const byte* in, byte* out)

if (AES_set_encrypt_key_AESNI(userKey,bits,temp_key)
== WC_NO_ERR_TRACE(BAD_FUNC_ARG)) {
ForceZero(temp_key, sizeof(Aes));
WC_FREE_VAR_EX(temp_key, aes->heap, DYNAMIC_TYPE_AES);
return BAD_FUNC_ARG;
}
Expand Down Expand Up @@ -1099,6 +1100,9 @@ static WC_INLINE void wc_Stm32_CrypAesBlock(const byte* in, byte* out)

Key_Schedule[0] = Temp_Key_Schedule[nr];

/* temp_key holds the expanded key schedule
* (ISO/IEC 19790:2012 7.9.7). */
ForceZero(temp_key, sizeof(Aes));
WC_FREE_VAR_EX(temp_key, aes->heap, DYNAMIC_TYPE_AES);

return 0;
Expand Down Expand Up @@ -9088,6 +9092,7 @@ void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,

/* Copy the result into s. */
XMEMCPY(s, x, sSz);
ForceZero(x, sizeof(x));
}

#ifdef WOLFSSL_AESGCM_STREAM
Expand Down Expand Up @@ -9188,6 +9193,7 @@ void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,

/* Copy the result into s. */
XMEMCPY(s, x, sSz);
ForceZero(x, sizeof(x));
}

#ifdef WOLFSSL_AESGCM_STREAM
Expand Down Expand Up @@ -9571,6 +9577,7 @@ void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,

/* Copy the result into s. */
XMEMCPY(s, x, sSz);
ForceZero(x, sizeof(x));
}

#ifdef WOLFSSL_AESGCM_STREAM
Expand Down Expand Up @@ -10073,6 +10080,7 @@ void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,

/* Copy the result into s. */
XMEMCPY(s, x, sSz);
ForceZero(x, sizeof(x));
}

#ifdef WOLFSSL_AESGCM_STREAM
Expand Down Expand Up @@ -10249,6 +10257,7 @@ void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);
#endif
XMEMCPY(s, x, sSz);
ForceZero(x, sizeof(x));
}
#endif /* !FREESCALE_LTC_AES_GCM */

Expand Down Expand Up @@ -10556,6 +10565,7 @@ void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
ByteReverseWords(x, x, WC_AES_BLOCK_SIZE);
#endif
XMEMCPY(s, x, sSz);
ForceZero(x, sizeof(x));
}

#ifdef WOLFSSL_AESGCM_STREAM
Expand Down Expand Up @@ -12713,20 +12723,23 @@ static WARN_UNUSED_RESULT int AesGcmCryptUpdate_C(
else
#endif /* HAVE_AES_ECB */
{
ALIGN32 byte scratch[WC_AES_BLOCK_SIZE];
/* Encrypt block by block. */
while (blocks--) {
ALIGN32 byte scratch[WC_AES_BLOCK_SIZE];
IncrementGcmCounter(AES_COUNTER(aes));
/* Encrypt counter into a buffer. */
ret = wc_AesEncrypt(aes, AES_COUNTER(aes), scratch);
if (ret != 0)
if (ret != 0) {
ForceZero(scratch, sizeof(scratch));
return ret;
}
/* XOR plain text into encrypted counter into cipher text buffer. */
xorbufout(out, scratch, in, WC_AES_BLOCK_SIZE);
/* Data complete. */
in += WC_AES_BLOCK_SIZE;
out += WC_AES_BLOCK_SIZE;
}
ForceZero(scratch, sizeof(scratch));
}

if (partial != 0) {
Expand Down Expand Up @@ -15453,7 +15466,7 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
wolfSSL_CryptHwMutexUnLock();

if (status != kStatus_Success) {
XMEMSET(out, 0, inSz);
ForceZero(out, inSz);
return AES_CCM_AUTH_E;
}
return 0;
Expand Down Expand Up @@ -15946,7 +15959,7 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
WOLFSSL_MSG("Preserve output for vector responses");
#else
if (inSz > 0)
XMEMSET(out, 0, inSz);
ForceZero(out, inSz);
#endif
ret = AES_CCM_AUTH_E;
}
Expand Down Expand Up @@ -16256,8 +16269,19 @@ void wc_AesFree(Aes* aes)
aes->keyInstalled = 0;
/* If callback wants standard free, it can set devId to INVALID_DEVID.
* Otherwise assume the callback handled cleanup. */
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
/* Release heap state first; the wipe drops its pointers. */
#if defined(WOLFSSL_AESGCM_STREAM) && defined(WOLFSSL_SMALL_STACK) && \
!defined(WOLFSSL_AESNI)
if (aes->streamData != NULL) {
ForceZero(aes->streamData, aes->streamData_sz);
XFREE(aes->streamData, aes->heap, DYNAMIC_TYPE_AES);
aes->streamData = NULL;
}
#endif
ForceZero(aes, sizeof(Aes));
return;
}
/* fall-through when unavailable */
}
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_FREE */
Expand Down Expand Up @@ -17598,13 +17622,14 @@ static int AesKeyWrapRaw(Aes* aes, word32 inSz, byte* out, const byte* aiv)
VECTOR_REGISTERS_POP;
#endif

if (ret != 0)
return ret;

/* C[0] = A */
XMEMCPY(out, tmp, KEYWRAP_BLOCK_SIZE);
if (ret == 0) {
/* C[0] = A */
XMEMCPY(out, tmp, KEYWRAP_BLOCK_SIZE);
}
/* tmp holds A || P[i] on an encrypt failure (ISO/IEC 19790:2012 7.9.7). */
ForceZero(tmp, sizeof(tmp));

return 0;
return ret;
}

int wc_AesKeyWrap_ex(Aes *aes, const byte* in, word32 inSz, byte* out,
Expand Down Expand Up @@ -17766,13 +17791,20 @@ static int AesKeyUnWrapRaw(Aes* aes, const byte* in, word32 inSz, byte* out,
VECTOR_REGISTERS_POP;
#endif

if (ret != 0)
return ret;

/* return recovered A */
XMEMCPY(aOut, tmp, KEYWRAP_BLOCK_SIZE);
if (ret == 0) {
/* return recovered A */
XMEMCPY(aOut, tmp, KEYWRAP_BLOCK_SIZE);
}
else {
/* Partially recovered plaintext (ISO/IEC 19790:2012 7.9.7). */
ForceZero(out, inSz - KEYWRAP_BLOCK_SIZE);
}
/* tmp ends holding the first 8 bytes of the recovered key
* (ISO/IEC 19790:2012 7.9.7). */
ForceZero(tmp, sizeof(tmp));
ForceZero(t, sizeof(t));

return 0;
return ret;
}

int wc_AesKeyUnWrap_ex(Aes *aes, const byte* in, word32 inSz, byte* out,
Expand Down Expand Up @@ -18630,10 +18662,11 @@ static int AesXtsEncrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
byte tweak_block[WC_AES_BLOCK_SIZE];

ret = wc_AesEncryptDirect(&xaes->tweak, tweak_block, i);
if (ret != 0)
return ret;

return AesXtsEncryptUpdate_sw(xaes, out, in, sz, tweak_block);
if (ret == 0) {
ret = AesXtsEncryptUpdate_sw(xaes, out, in, sz, tweak_block);
}
ForceZero(tweak_block, sizeof(tweak_block));
return ret;
}
#endif /* !WOLFSSL_RISCV_ASM */
#endif
Expand Down Expand Up @@ -19177,10 +19210,11 @@ static int AesXtsDecrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
byte tweak_block[WC_AES_BLOCK_SIZE];

ret = wc_AesEncryptDirect(&xaes->tweak, tweak_block, i);
if (ret != 0)
return ret;

return AesXtsDecryptUpdate_sw(xaes, out, in, sz, tweak_block);
if (ret == 0) {
ret = AesXtsDecryptUpdate_sw(xaes, out, in, sz, tweak_block);
}
ForceZero(tweak_block, sizeof(tweak_block));
return ret;
}
#endif /* !WOLFSSL_RISCV_ASM */
#endif
Expand Down
2 changes: 2 additions & 0 deletions wolfcrypt/src/cmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,7 @@ int wc_AesCmacGenerate(byte* out, word32* outSz,


#ifdef WOLFSSL_SMALL_STACK
ForceZero(cmac, sizeof(Cmac));
XFREE(cmac, NULL, DYNAMIC_TYPE_CMAC);
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
wc_MemZero_Check(cmac, sizeof(Cmac));
Expand Down Expand Up @@ -676,6 +677,7 @@ int wc_AesCmacVerify(const byte* check, word32 checkSz,
INVALID_DEVID);

#ifdef WOLFSSL_SMALL_STACK
ForceZero(cmac, sizeof(Cmac));
XFREE(cmac, NULL, DYNAMIC_TYPE_CMAC);
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
wc_MemZero_Check(cmac, sizeof(Cmac));
Expand Down
17 changes: 14 additions & 3 deletions wolfcrypt/src/curve25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,12 @@ static int wc_curve25519_make_key_nb(WC_RNG* rng, int keysize,
if (ret == 0) {
key->pubSet = 1;
}
else if (ret != FP_WOULDBLOCK) {
/* Public half failed: drop the scalar too
* (ISO/IEC 19790:2012 7.9.7). */
ForceZero(key->k, sizeof(key->k));
key->privSet = 0;
}
}

return ret;
Expand All @@ -717,7 +723,7 @@ int wc_curve25519_set_nonblock(curve25519_key* key, x25519_nb_ctx_t* ctx)
/* If a different context is already set, clear it before replacing.
* The caller is responsible for freeing any heap-allocated context. */
if (key->nb_ctx != NULL && key->nb_ctx != ctx) {
XMEMSET(key->nb_ctx, 0, sizeof(x25519_nb_ctx_t));
ForceZero(key->nb_ctx, sizeof(x25519_nb_ctx_t));
}
if (ctx != NULL) {
XMEMSET(ctx, 0, sizeof(x25519_nb_ctx_t));
Expand Down Expand Up @@ -792,6 +798,12 @@ int wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key)
}
#endif
key->pubSet = (ret == 0);
if (ret != 0) {
/* Public half failed: drop the scalar too
* (ISO/IEC 19790:2012 7.9.7). */
ForceZero(key->k, sizeof(key->k));
key->privSet = 0;
}
}
}
#endif /* !WOLFSSL_SE050 */
Expand Down Expand Up @@ -867,7 +879,7 @@ static int wc_curve25519_shared_secret_nb(curve25519_key* privKey,
}

if (ret != FP_WOULDBLOCK) {
XMEMSET(privKey->nb_ctx, 0, sizeof(x25519_nb_ctx_t));
ForceZero(privKey->nb_ctx, sizeof(x25519_nb_ctx_t));
}

return ret;
Expand Down Expand Up @@ -1420,7 +1432,6 @@ void wc_curve25519_free(curve25519_key* key)
#ifdef WOLFSSL_SE050
se050_curve25519_free_key(key);
#endif

ForceZero(key, sizeof(*key));

#ifdef WOLFSSL_CHECK_MEM_ZERO
Expand Down
3 changes: 3 additions & 0 deletions wolfcrypt/src/curve448.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,9 @@ int wc_curve448_make_key(WC_RNG* rng, int keysize, curve448_key* key)
else {
ForceZero(key->k, sizeof(key->k));
XMEMSET(key->p, 0, sizeof(key->p));
/* A zeroised SSP shall not be reusable
* (ISO/IEC 19790:2012 7.9.7 [09.29]). */
key->privSet = 0;
}
}
#endif /* WOLF_CRYPTO_CB_ONLY_CURVE448 */
Expand Down
15 changes: 14 additions & 1 deletion wolfcrypt/src/dh.c
Original file line number Diff line number Diff line change
Expand Up @@ -1021,7 +1021,10 @@ int wc_DhSetNonBlock(DhKey* key, DhNb* nb)
return BAD_FUNC_ARG;

if (nb != NULL) {
XMEMSET(nb, 0, sizeof(DhNb));
ForceZero(nb, sizeof(DhNb));
}
if ((key->nb != NULL) && (key->nb != nb)) {
ForceZero(key->nb, sizeof(DhNb));
}

/* Pass NULL to disable non-blocking mode. */
Expand Down Expand Up @@ -1495,13 +1498,16 @@ static int wc_DhGenerateKeyPair_Sync(DhKey* key, WC_RNG* rng,
byte* priv, word32* privSz, byte* pub, word32* pubSz)
{
int ret;
int privWritten;

if (key == NULL || rng == NULL || priv == NULL || privSz == NULL ||
pub == NULL || pubSz == NULL) {
return BAD_FUNC_ARG;
}

ret = GeneratePrivateDh(key, rng, priv, privSz);
/* From here *privSz is the length actually written. */
privWritten = (ret == 0);

if (ret == 0)
ret = GeneratePublicDh(key, priv, *privSz, pub, pubSz);
Expand All @@ -1511,6 +1517,11 @@ static int wc_DhGenerateKeyPair_Sync(DhKey* key, WC_RNG* rng,
if (ret == 0)
ret = _ffc_pairwise_consistency_test(key, pub, *pubSz, priv, *privSz);
#endif /* FIPS V5 or later || WOLFSSL_VALIDATE_DH_KEYGEN */
if (privWritten && (ret != 0)) {
/* A failed pair is not handed back (ISO/IEC 19790:2012 7.9.7). */
ForceZero(priv, *privSz);
*privSz = 0;
}

return ret;
}
Expand Down Expand Up @@ -2563,6 +2574,8 @@ int wc_DhImportKeyPair(DhKey* key, const byte* priv, word32 privSz,
if (priv[0] == 0) {
privSz--; priv++;
}
/* Never overwrite one SSP with another (ISO/IEC 19790:2012 [09.31]). */
mp_forcezero(&key->priv);
if (mp_init(&key->priv) != MP_OKAY)
havePriv = 0;
}
Expand Down
Loading
Loading