Bound LMS, XMSS and ML-KEM DMA response frames in the crypto client - #476
Bound LMS, XMSS and ML-KEM DMA response frames in the crypto client#476yosuke-wolfssl wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR hardens the crypto client’s DMA response parsing for LMS, XMSS, and ML-KEM by validating that the received response frame is large enough to safely overlay and read fixed-size response structs, preventing stale request bytes (from the reused comm buffer) from being interpreted as response fields. It also adds a malformed-response test harness that simulates truncated frames and header-only error replies.
Changes:
- Add per-handler
res_lenreceive lengths and fixed-size frame bounds before reading response struct fields insrc/wh_client_crypto.c. - Add a scripted-transport misc test (
whTest_ClientMalformedResp) that exercises exact-fit, truncation, server-error header-only replies, and caller-capacity rejection cases. - Register the new misc test in
test-refactor/wh_test_list.c.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/wh_client_crypto.c | Adds response-length bounds (via res_len) for LMS/XMSS/ML-KEM DMA response parsing to prevent stale-buffer overlay reads. |
| test-refactor/misc/wh_test_client_malformed_resp.c | Adds a scripted transport + subtests to validate client behavior on truncated/invalid response frames. |
| test-refactor/wh_test_list.c | Registers the new malformed-response misc test entry point. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
33bee76 to
a110692
Compare
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #476
Scan targets checked: wolfhsm-crypto-bugs, wolfhsm-src
No new issues found in the changed files. ✅
Frauschi
left a comment
There was a problem hiding this comment.
LGTM, but has conflicts to main that needs fixing.
a110692 to
e1472e8
Compare
|
Hi @Frauschi , |
e1472e8 to
55b56a7
Compare
Problem
wh_Client_RecvResponsereports the received payload length but nothing validates it against the message being parsed. The comm client reuses one buffer for request and response, so a reply shorter than the response struct leaves the tail holding the client's own outbound request bytes. An unchecked overlay read then returns stale data instead of failing.Nine DMA response handlers in
wh_client_crypto.coverlay their response struct with no frame bound:wh_Client_{Lms,Xmss}MakeKeyDmares->keyId, stored into the caller's out-param and the keywh_Client_{Lms,Xmss}SignDmares->sigLen, bounded against the caller's buffer but not the framewh_Client_{Lms,Xmss}VerifyDmaresp->res, the verify verdict itselfwh_Client_{Lms,Xmss}SigsLeftDmares->sigsLeft, which gates whether a one-time key is reused_MlKemMakeKeyDmares->keyId, andres->keySizebounded only by the staging bufferFollow-up to #457, same family as #474 (CMAC) and #475 (AES DMA).
_MlDsaMakeKeyDmaalready carries this bound onmain; these nine are the remaining gap.Fix (
src/wh_client_crypto.c)Every one of these responses is fixed size with no trailing payload, so a single bound covers each site:
These nine functions previously passed
req_lenas the length out-param ofwh_Client_RecvResponse. Each now receives into its ownres_len, matching every other handler in the file.WH_ERROR_ABORTEDand hide the server'src.ret, never returns early, so the DMA unmaps and_MlKemMakeKeyDma's staging-buffer zeroize still run.res->sigLen > sigCap,res->keySize > buffer_len) bound a different thing and still returnWH_ERROR_BADARGS.The
data_sizeparameter recently added towh_Client_RecvResponsebounds the response from above (WH_ERROR_BUFFER_SIZE); this bounds it from below. This PR is now source-only.Tests
The test added by the earlier revision has been removed. It was
test-refactor/misc/wh_test_client_malformed_resp.c(711 lines), built on ascripted transport that echoed the request comm header, always wrote the response
body, and reported whatever frame length the sub-test asked for. Per review, a
test reachable only through a fake transport or a hand-built packet is testing the
harness, not the fix, so it and its
wh_test_list.centry are dropped. This alsoremoves the add/add conflict with #463/#473/#474/#475, which each created the same
file.
No replacement test is added: a conforming server always sends the full fixed-size
response, so the normal
wh_Client_*API has no path to these guards.Verification
Rebased onto
2d1b25a.test-refactor: default 43 passed / 26 skipped / 0 failed of 69 ·DMA=147/22/0 ·SHE=149/20/0test/suite clean.-std=c90 -Werror -Wall -Wextra.hdr_sz / 2),all caught; three hoist controls moving a bound out of the success branch also
failed, while the test existed.