Skip to content

Commit 7976c03

Browse files
committed
zeroize DH private keys on free
1 parent 0d4cb0f commit 7976c03

4 files changed

Lines changed: 22 additions & 5 deletions

File tree

src/internal.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8665,6 +8665,9 @@ void FreeKeyExchange(WOLFSSL* ssl)
86658665
{
86668666
/* Cleanup signature buffer */
86678667
if (ssl->buffers.sig.buffer) {
8668+
/* May transiently hold the client's DH private exponent in the
8669+
* TLS 1.2 diffie_hellman_kea / dhe_psk_kea paths. */
8670+
ForceZero(ssl->buffers.sig.buffer, ssl->buffers.sig.length);
86688671
XFREE(ssl->buffers.sig.buffer, ssl->heap, DYNAMIC_TYPE_SIGNATURE);
86698672
ssl->buffers.sig.buffer = NULL;
86708673
ssl->buffers.sig.length = 0;

src/pk.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4743,6 +4743,7 @@ int wolfSSL_DH_generate_key(WOLFSSL_DH* dh)
47434743
int ret = 1;
47444744
word32 pubSz = 0;
47454745
word32 privSz = 0;
4746+
word32 privAllocSz = 0;
47464747
int localRng = 0;
47474748
WC_RNG* rng = NULL;
47484749
WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
@@ -4792,9 +4793,12 @@ int wolfSSL_DH_generate_key(WOLFSSL_DH* dh)
47924793
else {
47934794
privSz = pubSz;
47944795
}
4795-
/* Allocate public and private key arrays. */
4796+
/* Allocate public and private key arrays. Preserve the allocation
4797+
* size because wc_DhGenerateKeyPair updates privSz in-place. */
4798+
privAllocSz = privSz;
47964799
pub = (unsigned char*)XMALLOC(pubSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
4797-
priv = (unsigned char*)XMALLOC(privSz, NULL, DYNAMIC_TYPE_PRIVATE_KEY);
4800+
priv = (unsigned char*)XMALLOC(privAllocSz, NULL,
4801+
DYNAMIC_TYPE_PRIVATE_KEY);
47984802
if (pub == NULL || priv == NULL) {
47994803
WOLFSSL_ERROR_MSG("Unable to malloc memory");
48004804
ret = 0;
@@ -4846,7 +4850,10 @@ int wolfSSL_DH_generate_key(WOLFSSL_DH* dh)
48464850
}
48474851
/* Dispose of allocated data. */
48484852
XFREE(pub, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
4849-
XFREE(priv, NULL, DYNAMIC_TYPE_PRIVATE_KEY);
4853+
if (priv != NULL) {
4854+
ForceZero(priv, privAllocSz);
4855+
XFREE(priv, NULL, DYNAMIC_TYPE_PRIVATE_KEY);
4856+
}
48504857

48514858
return ret;
48524859
}

src/sniffer.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2459,11 +2459,15 @@ static void FreeSetupKeysArgs(WOLFSSL* ssl, void* pArgs)
24592459
args->key->type = WC_PK_TYPE_NONE;
24602460
args->key->initPriv = 0; args->key->initPub = 0;
24612461

2462+
/* Scrub the raw DH private exponent (and any other key material
2463+
* embedded in the union) before release. wc_FreeDhKey above only
2464+
* clears the mp_int DhKey, not the separate privKey byte array.
2465+
* ForceZero is used for the stack path too so the compiler
2466+
* cannot elide the wipe as dead-store to an out-of-scope object. */
2467+
ForceZero(args->key, sizeof(*args->key));
24622468
#ifdef WOLFSSL_ASYNC_CRYPT
24632469
XFREE(args->key, NULL, DYNAMIC_TYPE_SNIFFER_KEY);
24642470
args->key = NULL;
2465-
#else
2466-
XMEMSET(args->key, 0, sizeof(args->key));
24672471
#endif
24682472
}
24692473

src/tls.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9161,6 +9161,9 @@ static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap)
91619161
if (WOLFSSL_NAMED_GROUP_IS_FFDHE(current->group)) {
91629162
#ifndef NO_DH
91639163
wc_FreeDhKey((DhKey*)current->key);
9164+
if (current->privKey != NULL && current->privKeyLen > 0) {
9165+
ForceZero(current->privKey, current->privKeyLen);
9166+
}
91649167
#endif
91659168
}
91669169
else if (current->group == WOLFSSL_ECC_X25519) {

0 commit comments

Comments
 (0)