Skip to content

Stop READTRUSTED transmitting unwritten response bytes - #459

Merged
bigbrett merged 1 commit into
wolfSSL:mainfrom
yosuke-wolfssl:fix/f_6020
Jul 27, 2026
Merged

bigbrett merged 1 commit into
wolfSSL:mainfrom
yosuke-wolfssl:fix/f_6020

Conversation

@yosuke-wolfssl

@yosuke-wolfssl yosuke-wolfssl commented Jul 17, 2026 •

Copy link
Copy Markdown
Contributor

Problem

The non-DMA READTRUSTED handler sized its response from a length the callee never
resolved. When wh_Server_CertReadTrusted() failed, no certificate data was staged, but
the handler still ran resp.cert_len = cert_len and
*out_resp_size = sizeof(resp) + resp.cert_len, so the server transmitted response-packet
bytes it had never written.

The handler's return code does not prevent this: wh_Server_HandleRequestMessage() sends
the response regardless (src/wh_server.c:720-726), and the response packet is the same
buffer that carried the request, so the untouched region holds prior comm-buffer contents.

Measured before the fix: a stored 8185-byte certificate produced resp_size = 8192 (the
whole comm buffer), of which 8184 bytes were never written. The correct response is the
8-byte header alone.

Addressed by f_6020.

Root cause

wh_Server_CertReadTrusted() returned WH_ERROR_BUFFER_SIZE before assigning
*inout_cert_len, contradicting its contract in wolfhsm/wh_server_cert.h:70-72, so the
handler had only the staging clamp to report. The handler then trusted that value
unconditionally, which also leaked on internal wh_Nvm_GetMetadata() and wh_Nvm_Read()
failures.

Fix (src/wh_server_cert.c)

  • wh_Server_CertReadTrusted() reports meta.len on both the success and
    BUFFER_SIZE paths, honouring its documented contract. The caller's buffer size is
    captured first so the size check is unaffected.
  • The handler sets resp.cert_len only for outcomes that resolve a length (OK or
    BUFFER_SIZE), and adds the payload to *out_resp_size only on success. Every other
    outcome yields a header-only response.

Other callers (CertVerifyMultiRoot, CertVerifyAcert, the DMA handler) never read the
length on a failure return, so the contract change is safe for them.

Tests

New test-refactor/server/wh_test_cert_readtrusted.c drives the handler directly against a
poisoned response packet, pinning the clamp from both sides: STAGED_LEN must read back
whole, STAGED_LEN + 1 must report the stored size with a header-only response and no byte
past the header touched. A second sub-test locks the WH_ERROR_ACCESS path to no length and
no payload. It is gated only on WOLFHSM_CFG_CERTIFICATE_MANAGER, so it runs in every
config.

The oversized case was confirmed to fail against the unfixed server, so it is a negative
control. The ACCESS case passes either way and is kept as a forward-looking guard.

Verification

  • test-refactor default: 44 passed, 26 skipped, 0 failed of 70.
  • test-refactor DMA=1 ASAN=1: 48 passed, 22 skipped, 0 failed of 70.
  • Legacy test/ DMA=1 ASAN=1: passing, unchanged by this PR.

Not in this PR

  • A client-side end-to-end test was dropped per review. Reaching the over-clamp window from
    the client requires either the inline add or the DMA add depending on COMM_DATA_LEN vs
    WOLFHSM_CFG_MAX_CERT_SIZE, and those two conditions are mutually exclusive — no single
    config can exercise both, so the test necessarily carried an arm that no build compiles.
    The server-side test covers the same contract in every config.

@yosuke-wolfssl yosuke-wolfssl self-assigned this Jul 17, 2026
Copilot AI review requested due to automatic review settings July 17, 2026 08:43

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 fixes an information-leak/response-corruption issue in the non-DMA READTRUSTED certificate handler where the server could transmit bytes from the shared comm buffer that were never written (e.g., after failures), by tightening length reporting and response sizing. It also updates wh_Server_CertReadTrusted() to honor its documented contract by reporting the stored certificate length on both success and WH_ERROR_BUFFER_SIZE.

Changes:

  • Update wh_Server_CertReadTrusted() to always report meta.len via *inout_cert_len, including on WH_ERROR_BUFFER_SIZE.
  • Fix non-DMA READTRUSTED response construction to only include payload bytes in *out_resp_size on success, and only set resp.cert_len when a length is actually resolved.
  • Add targeted regression tests (server handler-level poisoning test + client API end-to-end coverage under DMA).

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
src/wh_server_cert.c Fixes the wh_Server_CertReadTrusted() length contract and prevents unwritten comm-buffer bytes from being included in READTRUSTED responses.
test-refactor/server/wh_test_cert_readtrusted.c Adds direct handler tests that poison the response packet and assert header-only sizing/no writes past header on non-success paths.
test-refactor/client-server/wh_test_client_certs.c Adds DMA-gated end-to-end client test asserting the reported stored length is preserved on WH_ERROR_BUFFER_SIZE.
test-refactor/wh_test_list.c Registers the new whTest_CertReadTrusted test in the server test group.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@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 #459

Scan targets checked: wolfhsm-core-bugs, wolfhsm-src

No new issues found in the changed files. ✅

Frauschi
Frauschi previously approved these changes Jul 23, 2026
@bigbrett
bigbrett merged commit 00bee41 into wolfSSL:main Jul 27, 2026
108 checks passed
@yosuke-wolfssl
yosuke-wolfssl deleted the fix/f_6020 branch July 29, 2026 22:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants