Add missing ForceZero() calls

Fixes  F-5437 and F-5438
This commit is contained in:
Tobias Frauenschläger
2026-06-08 09:20:36 +02:00
parent c01152d35a
commit e1413a177f
2 changed files with 37 additions and 25 deletions
+13 -22
View File
@@ -31973,10 +31973,7 @@ static int eccToPKCS8(ecc_key* key, byte* output, word32* outLen,
ret = wc_BuildEccKeyDer(key, tmpDer, &sz, includePublic, 0);
if (ret < 0) {
#ifndef WOLFSSL_NO_MALLOC
XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ret;
goto exit;
}
tmpDerSz = (word32)ret;
@@ -31984,42 +31981,36 @@ static int eccToPKCS8(ecc_key* key, byte* output, word32* outLen,
ret = wc_CreatePKCS8Key(NULL, &pkcs8Sz, tmpDer, tmpDerSz, algoID,
curveOID, oidSz);
if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
#ifndef WOLFSSL_NO_MALLOC
XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ret;
goto exit;
}
if (output == NULL) {
#ifndef WOLFSSL_NO_MALLOC
XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
*outLen = pkcs8Sz;
return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
ret = WC_NO_ERR_TRACE(LENGTH_ONLY_E);
goto exit;
}
else if (*outLen < pkcs8Sz) {
#ifndef WOLFSSL_NO_MALLOC
XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
WOLFSSL_MSG("Input buffer too small for ECC PKCS#8 key");
return BUFFER_E;
ret = BUFFER_E;
goto exit;
}
ret = wc_CreatePKCS8Key(output, &pkcs8Sz, tmpDer, tmpDerSz,
algoID, curveOID, oidSz);
if (ret < 0) {
#ifndef WOLFSSL_NO_MALLOC
XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ret;
goto exit;
}
*outLen = (word32)ret;
exit:
/* tmpDer holds a plaintext copy of the ECC private key - always zeroize
* it before releasing (or before the stack buffer goes out of scope). */
ForceZero(tmpDer, ECC_BUFSIZE);
#ifndef WOLFSSL_NO_MALLOC
XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
*outLen = (word32)ret;
return ret;
}
+24 -3
View File
@@ -7927,6 +7927,12 @@ static int mldsa_make_key_from_seed(wc_MlDsaKey* key, const byte* seed)
}
#ifndef WC_MLDSA_CACHE_PRIV_VECTORS
/* Zeroize the private vectors s1, s2 and t before freeing. These occupy
* the front of the buffer; any matrix A that follows is public (expanded
* from the public seed) and need not be cleared. */
if (s1 != NULL) {
ForceZero(s1, (word32)params->s1Sz + 2U * (word32)params->s2Sz);
}
XFREE(s1, key->heap, DYNAMIC_TYPE_MLDSA);
#endif
return ret;
@@ -7945,6 +7951,7 @@ static int mldsa_make_key_from_seed(wc_MlDsaKey* key, const byte* seed)
unsigned int r;
unsigned int s;
byte kl[2];
unsigned int allocSz = 0;
#ifdef WOLFSSL_MLDSA_DYNAMIC_KEYS
ret = mldsa_alloc_priv_buf(key);
@@ -7959,8 +7966,6 @@ static int mldsa_make_key_from_seed(wc_MlDsaKey* key, const byte* seed)
/* Allocate memory for large intermediates. */
if (ret == 0) {
unsigned int allocSz;
/* s1-l, s2-k, t-k, a-1 */
allocSz = (unsigned int)params->s1Sz + params->s2Sz + params->s2Sz +
(unsigned int)MLDSA_REJ_NTT_POLY_H_SIZE +
@@ -8158,6 +8163,15 @@ static int mldsa_make_key_from_seed(wc_MlDsaKey* key, const byte* seed)
key->pubKeySet = 1;
}
/* Zeroize the whole buffer before freeing. It holds the private vectors
* s1, s2 and t at the front; the rejection-sampling / matrix A region in
* the middle is public, but the trailing t64 accumulator (POLY64 builds)
* holds A o NTT(s1) - from which s1 is recoverable - so it must be
* cleared too. As the secret material is not contiguous, zeroize the
* entire allocation rather than a sub-range. */
if (s1 != NULL) {
ForceZero(s1, allocSz);
}
XFREE(s1, key->heap, DYNAMIC_TYPE_MLDSA);
return ret;
#endif
@@ -8584,7 +8598,14 @@ static int mldsa_sign_with_seed_mu(wc_MlDsaKey* key,
ForceZero(priv_rand_seed, sizeof(priv_rand_seed));
if (y != NULL) {
ForceZero(y, allocSz);
word32 zeroSz = allocSz;
#ifndef WC_MLDSA_CACHE_MATRIX_A
/* The public matrix A is appended at the end of the buffer and is
* expanded from the public seed - it need not be zeroized. The
* preceding vectors (y, w0, s1, s2, t0, ...) are secret dependent. */
zeroSz -= (word32)params->aSz;
#endif
ForceZero(y, zeroSz);
}
XFREE(y, key->heap, DYNAMIC_TYPE_MLDSA);
return ret;