Skip to content

Extend TLS 1.3 async support to HKDF, HMAC, AES-GCM, RNG and X25519/Ed25519 - #11231

Merged
SparkiDev merged 4 commits into
wolfSSL:masterfrom
dgarske:cryptocb_async_tls13
Sep 10, 2026
Merged

Extend TLS 1.3 async support to HKDF, HMAC, AES-GCM, RNG and X25519/Ed25519#11231
SparkiDev merged 4 commits into
wolfSSL:masterfrom
dgarske:cryptocb_async_tls13

Conversation

@dgarske

@dgarske dgarske commented Aug 21, 2026

Copy link
Copy Markdown
Member

Allows a crypto callback (WOLF_CRYPTO_CB) that returns WC_PENDING_E to complete a TLS 1.3 handshake: the application drives it with the existing wolfSSL_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:

  • HKDF key schedule (extract/expand; wc_HKDF_Extract_ex()/wc_HKDF_Expand_ex() now propagate WC_PENDING_E)
  • AES-GCM record encrypt and decrypt
  • ECC and X25519 key-share generation and shared secret
  • ECDSA and Ed25519 sign and verify (certificate chain and CertificateVerify)
  • Transcript HMAC (Finished verify_data, PSK binders; the Hmac object is held across the retry)
  • RNG for the hello randoms

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, msgsReceived markers lost after pended replays (out-of-order failure at Finished), a re-derive against a freed key-share peer key, and stale resume state surviving wolfSSL_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/async client/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).
  • tests/utils.c TLS memio now serves a byte stream so pending re-read patterns cannot desync it.

ZD 22322

@dgarske dgarske self-assigned this Aug 21, 2026
Copilot AI lite review requested due to automatic review settings August 21, 2026 02:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread wolfssl/internal.h
@dgarske
dgarske marked this pull request as ready for review August 21, 2026 12:11
@github-actions

Copy link
Copy Markdown

retest this please

@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown

MemBrowse Memory Report

gcc-arm-cortex-m4-dtls13

  • FLASH: .text +384 B (+0.2%, 187,196 B / 1,048,576 B, total: 18% used)

gcc-arm-cortex-m4-openssl-compat

  • FLASH: .text +512 B (+0.1%, 783,780 B / 1,048,576 B, total: 75% used)

gcc-arm-cortex-m4-pq

  • FLASH: .text +384 B (+0.1%, 302,088 B / 1,048,576 B, total: 29% used)

gcc-arm-cortex-m4-rsa-only

  • FLASH: .text +384 B (+0.1%, 332,896 B / 1,048,576 B, total: 32% used)

gcc-arm-cortex-m4-tls13

  • FLASH: .text +448 B (+0.2%, 242,639 B / 262,144 B, total: 93% used)

gcc-arm-cortex-m7-pq

  • FLASH: .text +384 B (+0.1%, 303,048 B / 1,048,576 B, total: 29% used)

gcc-arm-cortex-m7-tls13

  • FLASH: .text +384 B (+0.2%, 242,639 B / 262,144 B, total: 93% used)

linuxkm-standard

@dgarske
dgarske force-pushed the cryptocb_async_tls13 branch from cd98f59 to 78e92ed Compare August 21, 2026 19:07
@dgarske dgarske changed the title Extend TLS 1.3 async support to HKDF, AES-GCM and X25519/Ed25519 Extend TLS 1.3 async support to HKDF, HMAC, AES-GCM, RNG and X25519/Ed25519 Aug 21, 2026
@dgarske
dgarske force-pushed the cryptocb_async_tls13 branch from 78e92ed to 847c62f Compare August 24, 2026 19:35
@dgarske

dgarske commented Aug 25, 2026

Copy link
Copy Markdown
Member Author

Jenkins retest this please

1 similar comment
@dgarske

dgarske commented Aug 28, 2026

Copy link
Copy Markdown
Member Author

Jenkins retest this please

@dgarske
dgarske force-pushed the cryptocb_async_tls13 branch from 847c62f to d1a6888 Compare September 2, 2026 20:08
@dgarske
dgarske requested review from wolfSSL-Fenrir-bot and a lite review from Copilot September 2, 2026 20:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread examples/async/async_tls.c
Comment thread examples/async/async_tls.c
Comment thread src/tls13.c
Comment thread tests/api/test_tls13.c
Comment thread tests/utils.c

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread wolfcrypt/src/hmac.c Outdated
Comment thread wolfcrypt/src/hmac.c Outdated
Comment thread src/tls13.c Outdated
@dgarske

dgarske commented Sep 4, 2026

Copy link
Copy Markdown
Member Author

Jenkins retest this please

1 similar comment
@dgarske

dgarske commented Sep 4, 2026

Copy link
Copy Markdown
Member Author

Jenkins retest this please

@SparkiDev

Copy link
Copy Markdown
Contributor

Jenkins: retest this please

@SparkiDev

Copy link
Copy Markdown
Contributor

generic had a failure around a DTLS13 API.

@dgarske
dgarske force-pushed the cryptocb_async_tls13 branch from 325d315 to 14be86c Compare September 9, 2026 01:03
@dgarske dgarske removed their assignment Sep 9, 2026
@dgarske
dgarske force-pushed the cryptocb_async_tls13 branch from 14be86c to 517c45f Compare September 9, 2026 23:07
@dgarske dgarske added the For This Release Release version 5.9.4 label Sep 9, 2026
@dgarske dgarske removed their assignment Sep 9, 2026
@SparkiDev
SparkiDev merged commit 252c3b1 into wolfSSL:master Sep 10, 2026
403 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

For This Release Release version 5.9.4

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants