Skip to content

Translate the key wrap metadata trailer - #472

Open
yosuke-wolfssl wants to merge 1 commit into
wolfSSL:mainfrom
yosuke-wolfssl:fix/f_5469
Open

Translate the key wrap metadata trailer#472
yosuke-wolfssl wants to merge 1 commit into
wolfSSL:mainfrom
yosuke-wolfssl:fix/f_5469

Conversation

@yosuke-wolfssl

@yosuke-wolfssl yosuke-wolfssl commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Problem

The key wrap protocol carries a whNvmMetadata as a raw struct trailer
after the fixed request/response headers, but the server translated only the
headers. whNvmMetadata is four uint16_t fields (id, access, flags,
len), so every one is byte-swapped for a cross-endian client/server pair:

Path Trailer Symptom for a swapped client
WH_KEY_KEYWRAP request whNvmMetadata + key id 0x4025 (TYPE=WRAPPED) read as 0x2540 (TYPE=SHE) → valid wrap rejected WH_ERROR_BADARGS
WH_KEY_KEYUNWRAPEXPORT response whNvmMetadata + key id, access, flags, len returned byte-swapped

Every other NVM message flattens the struct into message fields and translates
each one; key wrap is the only place the raw struct crosses the boundary.

Addressed by f_5469.

Fix (src/wh_server_keystore.c)

Server-side only: clients always send native byte order, and the server
translates both directions from the comm-header magic.

  • wh_MessageNvm_TranslateMetadata() — new helper in wh_message_nvm.[ch],
    in-place safe, label copied verbatim.
  • _HandleKeyWrapRequest translates on ingress before any field is
    inspected, establishing the invariant that blobs always store metadata in
    server-native order
    .
  • _HandleKeyUnwrapAndExportRequest translates on egress last, after every
    policy check has run on native values.

Both handlers are static with one call site each, so they gain a magic
parameter. No client, wire-format, or struct change.

Also fixed, found while auditing the failure paths: *out_resp_size for
KEYUNWRAPEXPORT unconditionally counts a whNvmMetadata trailer, so a failed
unwrap shipped up to 32 bytes of stale comm-buffer content to the client. The
handler now zeroes the trailer and any decrypted key with wh_Utils_ForceZero()
on every failure exit, and the dispatcher scrubs as a backstop. In-switch
returns became ret = X; break; so one epilogue covers them all.
_HandleKeyWrapRequest also sets resp->cipherType before its first failure
exit — the client checks cipherType ahead of rc, so an early return
previously surfaced as WH_ERROR_ABORTED instead of the real error.

Tests

Reworked on review: 1,179 test lines removed, 128 added. Both original
files were shapes a real peer cannot produce — wh_test_keywrap_endian.c (720)
drove whServerContext* internals with synthetic magics, and
wh_test_keywrap_endian_e2e.c (459) hand-built packets and pushed them at the
transport, because wh_CommClient only ever sends native magic. Their two
wh_test_list.c entries and the README.md coverage-gap bullet go with them.

Replaced by test-refactor/misc/wh_test_message_nvm.c, following #468: a
loopback pair structurally cannot observe a byte-order bug, so the test calls
wh_MessageNvm_TranslateMetadata() directly with WH_COMM_MAGIC_SWAP. No
packet crafting, no new entry point registered beyond the one parent function.
It asserts native magic is a no-op, all four scalars swap, the label byte
array does not move, translation is its own inverse, in-place (src == dest)
matches out-of-place, and NULL args give WH_ERROR_BADARGS. Expected values are
written out as literals rather than derived from wh_Translate16(), so the
oracle does not share the code under test. The helper is ungated, so the test
runs in every configuration.

The whNvmMetadata entry added to wh_test_check_struct_padding.c stays — it
is what keeps the raw wire struct padding-free.

Coverage dropped with the harness, none of it reachable from a real client:
foreign-magic acceptance at the comm layer, the req_packet/resp_packet
aliasing that makes egress translation an in-place swap, wrap/unwrap policy
negatives already covered by client-server/wh_test_keywrap.c, and the
malformed-request residue check for the scrub described above. The new
"keep in step with wh_MessageNvm_TranslateAddObjectRequest" comment likewise
has no test behind it; the twin is pre-existing code this PR does not touch.

Verification

On merge base 237bfbc, clean under -std=c90 -Werror -Wall -Wextra, zero
warnings in all four configurations:

Config Result
test-refactor default 46 passed / 26 skipped / 0 failed of 72
test-refactor DMA=1 50/22/0
test-refactor SHE=1 52/20/0
test-refactor NOCRYPTO=1 17/55/0

whTest_MessageNvmTranslate passes in all four. Two negative controls, each
rebuilt and re-run: dropping the access WH_T16 fails the test, and dropping
the label memcpy fails it; restoring both returns 46/26/0.

@yosuke-wolfssl yosuke-wolfssl self-assigned this Jul 21, 2026
Copilot AI review requested due to automatic review settings July 21, 2026 22:50

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 cross-endian interoperability for the key-wrap protocol by translating the whNvmMetadata “raw struct trailer” that follows the fixed key-wrap request/response headers. It introduces a dedicated metadata translation helper and applies it in the server handlers so policy checks and storage always operate on native-order metadata, while the wire-facing trailer is translated appropriately.

Changes:

  • Add wh_MessageNvm_TranslateMetadata() to translate whNvmMetadata trailers (including in-place translation support).
  • Update key wrap / unwrap-and-export server handlers to translate the metadata trailer on ingress/egress based on the request magic.
  • Add a dedicated endianness regression test for key-wrap metadata trailers and register it in the server test list.

Reviewed changes

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

Show a summary per file
File Description
wolfhsm/wh_message_nvm.h Declares the new wh_MessageNvm_TranslateMetadata() helper for raw-struct metadata trailers.
src/wh_message_nvm.c Implements wh_MessageNvm_TranslateMetadata() using existing translation macros and label passthrough.
src/wh_server_keystore.c Translates key-wrap metadata trailer on request ingest and on unwrap-and-export response egress using magic.
test-refactor/server/wh_test_keywrap_endian.c Adds endianness coverage: helper property checks plus wrap→unwrap/export round-trips under native/swapped magic.
test-refactor/wh_test_list.c Registers the new whTest_KeyWrapEndian server test.

💡 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 #472

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

No new issues found in the changed files. ✅

Comment thread src/wh_server_keystore.c Outdated
Comment thread src/wh_server_keystore.c Outdated
Comment thread test-refactor/server/wh_test_keywrap_endian.c Outdated

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

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

No new issues found in the changed files. ✅

@yosuke-wolfssl

Copy link
Copy Markdown
Contributor Author

Hello @AlexLanzano ,
I fixed issues you mentioned with some additional stuff I found during rework.
The PR description is also updated accordingly.
Could you review this again ?

@AlexLanzano

Copy link
Copy Markdown
Member

@yosuke-wolfssl Looks like you have some failing test cases with your new changes? Could you take a look?

@AlexLanzano

Copy link
Copy Markdown
Member

Looks good. Passing off to you @bigbrett

@AlexLanzano AlexLanzano removed their assignment Jul 30, 2026
@AlexLanzano
AlexLanzano requested a review from bigbrett July 30, 2026 15:59
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