Extend TLS 1.3 async support to HKDF, HMAC, AES-GCM, RNG and X25519/Ed25519 - #11231
Conversation
There was a problem hiding this comment.
Pull request overview
This PR extends wolfSSL TLS 1.3 handshake support for asynchronous crypto backends where a provider (notably WOLF_CRYPTO_CB) may return WC_PENDING_E, allowing the handshake to progress by polling/re-entering and resuming operations via callback re-invocation rather than restarting.
Changes:
- Adds TLS 1.3 async “re-invoke” resume plumbing for HKDF/key schedule, AEAD (AES-GCM), key share generation/derive, and signature operations, including state markers to avoid re-deriving completed steps.
- Updates record build/resume behavior for TLS 1.3 to correctly suspend/resume across pending operations and fixes several pending/replay edge cases.
- Adds/updates tests and example async callback simulation to exercise pending behavior across client/server paths, plus memio adjustments to behave like a TLS byte stream.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| wolfssl/wolfcrypt/settings.h | Updates async backend guidance/comments for TLS 1.2 vs TLS 1.3 behavior. |
| wolfssl/internal.h | Adds TLS 1.3 async resume state, reinvoke macro, and shared record-build args support. |
| wolfcrypt/test/test.c | Adds HKDF crypto-callback pending simulation and an HKDF async crypto-callback test. |
| wolfcrypt/src/hmac.c | Propagates WC_PENDING_E for HKDF via crypto callback; adds limited wait behavior for QAT/Cavium HMAC sub-ops. |
| wolfcrypt/src/cryptocb.c | Refines warning text for async crypto callback limitations in TLS 1.2 vs TLS 1.3. |
| tests/utils.c | Adjusts TLS memio read behavior to serve a byte stream across message boundaries; preserves DTLS datagram semantics. |
| tests/api/test_tls13.h | Registers the new TLS 1.3 crypto-callback async API test. |
| tests/api/test_tls13.c | Adds test_tls13_cryptocb_async exercising TLS 1.3 handshakes + app data with per-operation pending callbacks. |
| src/tls13.c | Implements TLS 1.3 pending/resume logic across HKDF/key schedule, AEAD encrypt/decrypt, record builder resume, and replay marker restoration. |
| src/tls.c | Improves key share generation/resume behavior for X25519 and ECC; adds derived-state guard for async retries. |
| src/ssl.c | Clears TLS 1.3 async resume markers and pending KDF async event state on wolfSSL_clear() reuse. |
| src/internal.c | Adjusts async teardown to avoid incorrectly clearing TLS 1.3 record-build resume markers except during full teardown. |
| examples/async/README.md | Documents TLS 1.3 async re-invocation behavior and the updated simulated pending device model. |
| examples/async/async_tls.h | Expands async crypto-callback context to include a simulated job table and TLS 1.2 restriction flag. |
| examples/async/async_tls.c | Implements job-table-based pending simulation across TLS 1.3 operation classes and integrates it into the callback. |
| examples/async/async_server.c | Passes TLS 1.2 selection into callback context; prints pending/job-table stats. |
| examples/async/async_client.c | Passes TLS 1.2 selection into callback context; prints pending/job-table stats. |
| doc/dox_comments/header_files/hmac.h | Documents WC_PENDING_E contracts for HKDF APIs under crypto callback and TLS 1.3 async flows. |
| configure.ac | Updates configure-time notice text to reflect TLS 1.2 record cipher limitations with callback-only async. |
| .github/workflows/async.yml | Updates workflow documentation comment to reflect pending coverage via new tests. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
retest this please |
|
cd98f59 to
78e92ed
Compare
78e92ed to
847c62f
Compare
|
Jenkins retest this please |
1 similar comment
|
Jenkins retest this please |
847c62f to
d1a6888
Compare
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Pull request overview
Copilot reviewed 20 out of 20 changed files in this pull request and generated 5 comments.
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #11231
Scan targets checked: wolfcrypt-bugs, wolfcrypt-port-bugs, wolfcrypt-rs-bugs, wolfcrypt-src, wolfssl-bugs, wolfssl-src
Findings: 4
3 finding(s) posted as inline comments (see file-level comments below)
Required changes (1)
Pending HKDF/HMAC in the PSK binder path replays DoTls13ClientHello and hashes the ClientHello into the transcript twice
File: src/tls13.c:6974
Function: DoPreSharedKeys
Category: TLS protocol issues
DeriveBinderKeyResume, DeriveFinishedSecret and BuildTls13HandshakeHmac can now return WC_PENDING_E, but they run after HashInput(ssl, input, inputSz) (src/tls13.c:6933/6949). DoTls13ClientHello's TLS_ASYNC_BEGIN case never advances ssl->options.asyncState (first advance is src/tls13.c:8317), so the retry re-executes CheckPreSharedKeys and mixes the truncated ClientHello into the transcript a second time, corrupting the server's handshake hash on every PSK/session-ticket resumption where the device pends.
Related known finding #2124 (similar but distinct): Both involve CheckPreSharedKeys' PSK-binder path, but #2124 concerns the binder ConstantCompare verification test claim, while this concerns async re-entry rehashing the ClientHello transcript; the faulting operations, root causes, and patches are distinct.
Recommendation: Advance ssl->options.asyncState past the transcript-hashing point (or record a per-ClientHello "already hashed" flag) before any pendable KDF/HMAC call in CheckPreSharedKeys.
Referenced code: src/tls13.c:6974-6977 (4 lines)
This review was generated automatically by Fenrir. Reported findings require changes before merge.
d1a6888 to
325d315
Compare
|
Jenkins retest this please |
1 similar comment
|
Jenkins retest this please |
|
Jenkins: retest this please |
|
generic had a failure around a DTLS13 API. |
325d315 to
14be86c
Compare
14be86c to
517c45f
Compare
Allows a crypto callback (
WOLF_CRYPTO_CB) that returnsWC_PENDING_Eto complete a TLS 1.3 handshake: the application drives it with the existingwolfSSL_AsyncPoll()/ re-enter loop, and the TLS 1.3 layer resumes the suspended operation by re-invoking the callback with identical arguments instead of restarting it.Asynchronous support is added for every operation class a TLS 1.3 handshake offloads:
wc_HKDF_Extract_ex()/wc_HKDF_Expand_ex()now propagateWC_PENDING_E)Poll-completing backends (Intel QuickAssist, Cavium Nitrox,
WOLF_CRYPTO_CB_ASYNC_POLL) keep their existing flows. Known limitation for follow-up: RNG requests pending inside composite wolfCrypt operations (ECDSA nonce, session-ticket IV) are not resumable. Also fixes latent async bugs found along the way, notably the TLS 1.3 record layer skipping the AEAD on a pending retry,msgsReceivedmarkers lost after pended replays (out-of-order failure at Finished), a re-derive against a freed key-share peer key, and stale resume state survivingwolfSSL_clear().New tests, all exercising both the client and the server side against a per-request pending device:
test_tls13_cryptocb_async(api suite): full TLS 1.3 handshakes plus application data over shared memio, per class (AES-GCM, ECC keygen, ECDSA sign, ECDSA verify, full HKDF schedule, transcript HMAC), asserting per-side pend counts. Runs without client authentication, and with mutual authentication for the ECDSA verify, HKDF and HMAC cases.hkdf_cryptocb_async_test()(wolfCrypt test): HKDF extract/expand/one-shot RFC 5869 vectors through a callback that pends a configured number of times.examples/asyncclient/server: simulates pending for all supported classes on TLS 1.3, with and without mutual authentication (TLS 1.2 keeps the RSA/ECDSA signing set).ZD 22322