zeroize DH private keys on free

This commit is contained in:
Jeremiah Mackey
2026-04-24 17:23:28 +00:00
parent 88664f7224
commit 4c76eae0aa
4 changed files with 22 additions and 5 deletions
+3
View File
@@ -8669,6 +8669,9 @@ void FreeKeyExchange(WOLFSSL* ssl)
{
/* Cleanup signature buffer */
if (ssl->buffers.sig.buffer) {
/* May transiently hold the client's DH private exponent in the
* TLS 1.2 diffie_hellman_kea / dhe_psk_kea paths. */
ForceZero(ssl->buffers.sig.buffer, ssl->buffers.sig.length);
XFREE(ssl->buffers.sig.buffer, ssl->heap, DYNAMIC_TYPE_SIGNATURE);
ssl->buffers.sig.buffer = NULL;
ssl->buffers.sig.length = 0;
+10 -3
View File
@@ -4743,6 +4743,7 @@ int wolfSSL_DH_generate_key(WOLFSSL_DH* dh)
int ret = 1;
word32 pubSz = 0;
word32 privSz = 0;
word32 privAllocSz = 0;
int localRng = 0;
WC_RNG* rng = NULL;
WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
@@ -4792,9 +4793,12 @@ int wolfSSL_DH_generate_key(WOLFSSL_DH* dh)
else {
privSz = pubSz;
}
/* Allocate public and private key arrays. */
/* Allocate public and private key arrays. Preserve the allocation
* size because wc_DhGenerateKeyPair updates privSz in-place. */
privAllocSz = privSz;
pub = (unsigned char*)XMALLOC(pubSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
priv = (unsigned char*)XMALLOC(privSz, NULL, DYNAMIC_TYPE_PRIVATE_KEY);
priv = (unsigned char*)XMALLOC(privAllocSz, NULL,
DYNAMIC_TYPE_PRIVATE_KEY);
if (pub == NULL || priv == NULL) {
WOLFSSL_ERROR_MSG("Unable to malloc memory");
ret = 0;
@@ -4846,7 +4850,10 @@ int wolfSSL_DH_generate_key(WOLFSSL_DH* dh)
}
/* Dispose of allocated data. */
XFREE(pub, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
XFREE(priv, NULL, DYNAMIC_TYPE_PRIVATE_KEY);
if (priv != NULL) {
ForceZero(priv, privAllocSz);
XFREE(priv, NULL, DYNAMIC_TYPE_PRIVATE_KEY);
}
return ret;
}
+6 -2
View File
@@ -2459,11 +2459,15 @@ static void FreeSetupKeysArgs(WOLFSSL* ssl, void* pArgs)
args->key->type = WC_PK_TYPE_NONE;
args->key->initPriv = 0; args->key->initPub = 0;
/* Scrub the raw DH private exponent (and any other key material
* embedded in the union) before release. wc_FreeDhKey above only
* clears the mp_int DhKey, not the separate privKey byte array.
* Use ForceZero (rather than XMEMSET) so the wipe cannot be
* elided by the optimizer. */
ForceZero(args->key, sizeof(*args->key));
#ifdef WOLFSSL_ASYNC_CRYPT
XFREE(args->key, NULL, DYNAMIC_TYPE_SNIFFER_KEY);
args->key = NULL;
#else
XMEMSET(args->key, 0, sizeof(args->key));
#endif
}
+3
View File
@@ -9063,6 +9063,9 @@ static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap)
if (WOLFSSL_NAMED_GROUP_IS_FFDHE(current->group)) {
#ifndef NO_DH
wc_FreeDhKey((DhKey*)current->key);
if (current->privKey != NULL && current->privKeyLen > 0) {
ForceZero(current->privKey, current->privKeyLen);
}
#endif
}
else if (current->group == WOLFSSL_ECC_X25519) {