diff --git a/wolfcrypt/src/falcon.c b/wolfcrypt/src/falcon.c index 07e06f29f7..046ce52bce 100644 --- a/wolfcrypt/src/falcon.c +++ b/wolfcrypt/src/falcon.c @@ -9540,6 +9540,9 @@ int wc_Falcon_PrivateKeyDecode(const byte* input, word32* inOutIdx, } } + /* Zeroize the decoded private key before free (matches every other secret + * temporary in this file); pubKey is public and needs no scrubbing. */ + ForceZero(privKey, FALCON_MAX_PRV_KEY_SIZE); XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); return ret; diff --git a/wolfcrypt/src/wc_xmss.c b/wolfcrypt/src/wc_xmss.c index 2ec2700034..4184438e30 100644 --- a/wolfcrypt/src/wc_xmss.c +++ b/wolfcrypt/src/wc_xmss.c @@ -787,6 +787,8 @@ static WC_INLINE int wc_xmsskey_signupdate(XmssKey* key, byte* sig, /* Free state after use. */ wc_xmss_state_free(state); } + /* Zeroize working state before free. */ + ForceZero(state, sizeof(XmssState)); WC_FREE_VAR_EX(state, key->heap, DYNAMIC_TYPE_TMP_BUFFER); } } @@ -1284,6 +1286,8 @@ int wc_XmssKey_MakeKey(XmssKey* key, WC_RNG* rng) /* Free state after use. */ wc_xmss_state_free(state); } + /* Zeroize working state before free. */ + ForceZero(state, sizeof(XmssState)); WC_FREE_VAR_EX(state, key->heap, DYNAMIC_TYPE_TMP_BUFFER); } } @@ -1305,6 +1309,14 @@ int wc_XmssKey_MakeKey(XmssKey* key, WC_RNG* rng) key->state = WC_XMSS_STATE_OK; } + /* Zeroize the secret seed (SK_seed || SK_PRF) before freeing the buffer. */ +#ifdef WOLFSSL_SMALL_STACK + if (seed != NULL) { + ForceZero(seed, 3U * key->params->n); + } +#else + ForceZero(seed, sizeof(seed)); +#endif WC_FREE_VAR_EX(seed, key->heap, DYNAMIC_TYPE_TMP_BUFFER); return ret; } @@ -2015,6 +2027,8 @@ int wc_XmssKey_Verify(XmssKey* key, const byte* sig, word32 sigLen, /* Free state after use. */ wc_xmss_state_free(state); } + /* Zeroize working state before free. */ + ForceZero(state, sizeof(XmssState)); WC_FREE_VAR_EX(state, key->heap, DYNAMIC_TYPE_TMP_BUFFER); } }