diff --git a/src/dtls13.c b/src/dtls13.c index 5b1a7a16fe..257e31ec2b 100644 --- a/src/dtls13.c +++ b/src/dtls13.c @@ -2393,7 +2393,10 @@ static Dtls13Epoch* Dtls13NewEpochSlot(WOLFSSL* ssl) WOLFSSL_MSG_EX("Delete epoch: %d", e->epochNumber); #endif /* WOLFSSL_DEBUG_TLS */ - XMEMSET(e, 0, sizeof(*e)); + /* The slot we are reusing holds the previous epoch's symmetric keys, IVs, + * and sn-keys; use ForceZero so the wipe cannot be elided by the + * optimizer when the slot is later overwritten. */ + ForceZero(e, sizeof(*e)); return e; } diff --git a/src/internal.c b/src/internal.c index 457bedf341..8f0d39244b 100644 --- a/src/internal.c +++ b/src/internal.c @@ -9192,6 +9192,11 @@ void wolfSSL_ResourceFree(WOLFSSL* ssl) #ifdef WOLFSSL_DTLS13 Dtls13FreeFsmResources(ssl); + /* Zero per-epoch symmetric keys / IVs / sn-keys so they are not left + * resident in the heap after FreeSSL releases the SSL struct. Mirrors + * the existing ForceZero on ssl->keys and ssl->clientSecret/serverSecret. */ + ForceZero(ssl->dtls13Epochs, sizeof(ssl->dtls13Epochs)); + #ifdef WOLFSSL_RW_THREADED wc_FreeMutex(&ssl->dtls13Rtx.mutex); #endif diff --git a/src/keys.c b/src/keys.c index 74b094fc59..3a980b9ce3 100644 --- a/src/keys.c +++ b/src/keys.c @@ -4138,6 +4138,8 @@ static int MakeSslMasterSecret(WOLFSSL* ssl) ENCRYPT_LEN + WC_SHA_DIGEST_SIZE); wc_MemZero_Add("MakeSslMasterSecret shaInput", shaInput, PREFIX + ENCRYPT_LEN + 2 * RAN_LEN); + wc_MemZero_Add("MakeSslMasterSecret shaOutput", shaOutput, + WC_SHA_DIGEST_SIZE); #endif XMEMSET(shaOutput, 0, WC_SHA_DIGEST_SIZE); @@ -4200,9 +4202,11 @@ static int MakeSslMasterSecret(WOLFSSL* ssl) ForceZero(md5Input, ENCRYPT_LEN + WC_SHA_DIGEST_SIZE); ForceZero(shaInput, PREFIX + ENCRYPT_LEN + 2 * RAN_LEN); + ForceZero(shaOutput, WC_SHA_DIGEST_SIZE); #ifdef WOLFSSL_CHECK_MEM_ZERO wc_MemZero_Check(md5Input, ENCRYPT_LEN + WC_SHA_DIGEST_SIZE); wc_MemZero_Check(shaInput, PREFIX + ENCRYPT_LEN + 2 * RAN_LEN); + wc_MemZero_Check(shaOutput, WC_SHA_DIGEST_SIZE); #endif WC_FREE_VAR_EX(shaOutput, NULL, DYNAMIC_TYPE_TMP_BUFFER); diff --git a/src/sniffer.c b/src/sniffer.c index 8218131435..256e9b24fc 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -7591,11 +7591,15 @@ static int parseKeyLogFile(const char* fileName, char* error) if (ret != 0) { fclose(file); + ForceZero(secret, SECRET_LENGTH); + ForceZero(secretHex, sizeof(secretHex)); return ret; } } fclose(file); + ForceZero(secret, SECRET_LENGTH); + ForceZero(secretHex, sizeof(secretHex)); return 0; } @@ -7613,6 +7617,7 @@ static void freeSecretList(void) while (current != NULL) { next = current->next; + ForceZero(current, sizeof(SecretNode)); XFREE(current, NULL, DYNAMIC_TYPE_SNIFFER_KEYLOG_NODE); current = next; } diff --git a/src/tls13.c b/src/tls13.c index 679338bf86..3aaada19e4 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -1051,17 +1051,22 @@ int Tls13_Exporter(WOLFSSL* ssl, unsigned char *out, size_t outLen, protocol, protocolLen, (byte*)label, (word32)labelLen, emptyHash, hashLen, (int)hashType); if (ret != 0) - return ret; + goto cleanup; /* Hash(context_value) */ ret = wc_Hash(hashType, context, (word32)contextLen, hashOut, WC_MAX_DIGEST_SIZE); if (ret != 0) - return ret; + goto cleanup; ret = Tls13HKDFExpandLabel(ssl, out, (word32)outLen, firstExpand, hashLen, protocol, protocolLen, exporterLabel, EXPORTER_LABEL_SZ, hashOut, hashLen, (int)hashType); +cleanup: + /* firstExpand is the per-label Derive-Secret PRK and hashOut holds + * Hash(context_value); wipe both before the stack frame is reclaimed. */ + ForceZero(firstExpand, sizeof(firstExpand)); + ForceZero(hashOut, sizeof(hashOut)); return ret; } #endif