Repository navigation
TLS: free the X25519 non-blocking context of a hybrid key share - #11871
Merged
Merged
Conversation
With WC_X25519_NONBLOCK and WOLFSSL_ASYNC_CRYPT_SW, an X25519 key made for a key share with an async device gets a non-blocking context. TLSX_KeyShare_FreeAll() freed it in the X25519 branch but not for the X25519 key of a hybrid key share such as X25519MLKEM768, so it leaked when such a key share was freed with its key still set, for example on the client after a HelloRetryRequest. Free it there as in the X25519 branch.
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
The narrow fix follows the existing allocation ownership and cleanup pattern, with no blocking issues identified.
No open issues 🎉
What changed in this PR
Fixes a memory leak in TLS hybrid key-share cleanup when an X25519 key retains its non-blocking context, such as after a failed handshake or selection of another group.
Changes:
- Frees the X25519 non-blocking context before releasing the hybrid key.
- Uses the same feature guards and cleanup pattern as standalone X25519 key shares.
| File | Description |
|---|---|
| src/tls.c | Adds non-blocking X25519 context cleanup to the hybrid key-share branch. |
Review effort: Balanced
Member
|
Okay to test. Contributor agreement on file |
Arpan0995
marked this pull request as ready for review
October 26, 2026 17:03
|
retest this please |
|
philljj
approved these changes
Oct 27, 2026
philljj
left a comment
Contributor
There was a problem hiding this comment.
Leak reproduced and confirmed fixed. Thank you!
before:
total Allocs = 3180
total Deallocs = 3177
total Bytes = 3563805
peak Bytes = 77500
current Bytes = 1584
Leak: Ptr 0x2e635110, Size 528
Leak: Ptr 0x2e635350, Size 528
Leak: Ptr 0x2e636180, Size 528
End Group : tls13
End API Testsafter:
total Allocs = 3180
total Deallocs = 3180
total Bytes = 3563806
peak Bytes = 75916
current Bytes = 0
End Group : tls13
End API Tests
Failed/Skipped/Passed/All: 0/0/1/1
wolfSSL Entering wolfSSL_CleanupTests good with multi-test with gcc-c89, clang-tidy, tls13, dtls13, etc scenarios.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
With
--enable-curve25519=nonblock(WC_X25519_NONBLOCKandWOLFSSL_ASYNC_CRYPT_SW) and an async device set on theWOLFSSLobject,TLSX_KeyShare_GenX25519Key()gives the X25519 key a non-blocking context.TLSX_KeyShare_FreeAll()frees that context in the X25519 branch (since #9721), but the hybrid branch does not free it for the X25519 key of an X25519MLKEM768 (or other X25519 hybrid) key share. So the context leaks whenever such a key share is freed while it still holds its X25519 key: on the client when the server picks another group (after a HelloRetryRequest, or by choosing another key share the client sent), and in some failed handshakes on either side, such as the ones in the test below.This frees it in the hybrid branch, in the same way as in the X25519 branch.
Testing
With an async device, the X25519 low-order cases in
test_tls13_mlkem_bad_key_share(from #11764) make two X25519MLKEM768 handshakes fail on purpose, one rejected by the server and one by the client. On master they leak three of these contexts: the client's in both handshakes, and the server's in the one the server rejects.Leak: ... Size 528allocations (528 issizeof(x25519_nb_ctx_t)here), printsWOLFSSL_TRACK_MEMORY: currentBytes after cleanup is 1584and exits with status 131 (MEMORY_E). With this change it reports success.--enable-curve25519=nonblock --enable-debug --disable-shared, macOSleaks --atExiton the same test reports three leaks on master, all fromTLSX_KeyShare_GenX25519Key(), and none with this change. The same holds for the nonblock-sp-c64 configuration from os-check-linux.json, built with--disable-shared.leaksreports one leaked context on the client in both cases, and none with this change.--apiwith no sanitizer reports, and the nonblock-sp-c64 configuration passes--api.--enable-all --enable-all-quantum-cryptobuilds with no warnings and passes the tls13 group.Checklist