Skip to content

SHE+keywrap interop#413

Draft
bigbrett wants to merge 1 commit into
wolfSSL:mainfrom
bigbrett:she-wrapped-interop
Draft

SHE+keywrap interop#413
bigbrett wants to merge 1 commit into
wolfSSL:mainfrom
bigbrett:she-wrapped-interop

Conversation

@bigbrett

@bigbrett bigbrett commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

This branch does three related things: adds a wrap-export-by-id operation that enables SHE key interop with the wrapped-key system, makes SHE work on NVM-less servers with wrapped keys, and closes a KEK confidentiality hole in the keywrap API.

1. Wrap-export by id + SHE interop

  • New client API wh_Client_KeyWrapExport (plus split Request/Response variants), message structs, and server handler: the client names an existing keystore key by id and type, and the server reads it, checks export policy, wraps it under the KEK, and returns the blob. SHE keys wrap as TYPE=SHE while others normalize to the wrapped namespace so blobs round-trip through wh_Client_KeyUnwrapAndCache.
  • New WH_KEYID_IS_UNASSIGNED macro replaces raw WH_KEYID_ISERASED checks throughout the keystore. An id-field 0 still means "assign me one" except for the new case of SHE keys, where slot 0 (SECRET_KEY) is a real fixed id. This lets SHE slot 0 be wrap-exported and primed via unwrap-and-cache. The NVM read path deliberately skips auto-caching SHE slot 0 so a later prime of that slot isn't blocked.

2. NVM-less SHE

wh_server_she.c's LOAD_KEY, InitRnd, and ExtendSeed handlers now fall back to the key cache when server->nvm == NULL, so SHE runs on NVM-less platforms with keys primed through unwrap-and-cache.

3. Trusted KEK enforcement (WH_NVM_FLAGS_KEK)

The above features introduced a few key exfiltration pathways that had to be addressed. Most notably, KeyWrapExport/KeyUnwrapAndCache accepted any cache/NVM key as the KEK, including one the client itself cached, so a client could wrap a server-held secret under a KEK it knows and recover the plaintext offline.

The fix for this path is to introduce the concept of a "trusted KEK" for wrap operations, which can either be a hardware-only key (a la #409 ) or an NVM object with a newly introduced WH_NVM_FLAGS_KEK.

This flag is a server-only NVM flag that is NOT able to be set by the client API and is only settable exclusively by server-side utilities (which includes online use of server API or offline via whnvmtool). This flag is stripped from every client-supplied NVM object field for operations like add object, and is enforced at use time on the server.

Wrap-export and unwrap-and-cache now require the KEK to be a "trusted KEK". Plain wrap/unwrap don't, since there the client already has the plaintext. The hwkeystore header now documents that backends must refuse non-KEK keyIds themselves.

Copilot AI review requested due to automatic review settings June 19, 2026 19:19

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 adds SHE ↔ keywrap interoperability by introducing a new “wrap-and-export (by id)” operation, enforcing a “trusted KEK” policy for operations that move server-held secrets across the client boundary, and adding optional hardware-only KEK support via a hardware keystore front-end.

Changes:

  • Add trusted-KEK enforcement (WH_NVM_FLAGS_KEK + server-only flag stripping) for wrap-export and unwrap-and-cache, plus associated NVM/keystore policy gates.
  • Add hardware-only key IDs (WH_KEYTYPE_HW / WH_CLIENT_KEYID_MAKE_HW) and a new wh_hwkeystore module to fetch KEKs from a hardware backend on-demand for keywrap/datawrap.
  • Add wh_Client_KeyWrapExport* API + message types, update SHE/no-NVM behavior and add extensive tests + documentation.

Reviewed changes

Copilot reviewed 33 out of 33 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
wolfhsm/wh_settings.h Adds HW keystore configuration macros and defaults.
wolfhsm/wh_server.h Plumbs optional hwKeystore into server config/context when enabled.
wolfhsm/wh_nvm.h Tightens “checked” NVM API semantics and const-correctness for metadata sanitization.
wolfhsm/wh_message.h Adds new keystore action WH_KEY_KEYWRAPEXPORT.
wolfhsm/wh_message_keystore.h Defines wrap-export request/response wire structs + translation prototypes.
wolfhsm/wh_keyid.h Adds client HW flag, WH_KEYTYPE_HW, and WH_KEYID_IS_UNASSIGNED() helper.
wolfhsm/wh_hwkeystore.h Introduces hardware keystore front-end API and backend callback contract.
wolfhsm/wh_common.h Adds server-only WH_NVM_FLAGS_KEK and WH_NVM_FLAGS_SERVER_ONLY mask.
wolfhsm/wh_client.h Adds wrap-export API and exposes split data wrap/unwrap request/response APIs; adds HW keyId macro.
tools/whnvmtool/README.md Documents how to provision a trusted software KEK into NVM images.
test/wh_test_she.c Adds SHE↔keywrap interop coverage, trusted KEK provisioning, and reboot + no-NVM flows.
test/wh_test_she_no_nvm.h Declares new no-NVM SHE test entrypoint.
test/wh_test_she_no_nvm.c Adds full end-to-end no-NVM SHE test using unwrap-and-cache provisioning.
test/wh_test_multiclient.c Updates unwrap-and-cache tests to use a provisioned trusted KEK.
test/wh_test_keywrap.h Exposes HW keystore test callback/table for in-process servers.
test/wh_test_keywrap.c Adds wrap-export tests, trusted-KEK policy tests, and HW-keystore KEK tests.
test/wh_test_crypto.c Binds hwKeystore to in-process server harness and runs HW-keystore tests when applicable.
test/config/wolfhsm_cfg.h Enables HW keystore in test configuration when crypto is enabled.
test-refactor/wh_test_list.c Registers new hwKeystore misc/server tests in refactor harness.
test-refactor/server/wh_test_hwkeystore_server.c Adds server-side hwKeystore unit coverage + keystore rejection checks.
test-refactor/misc/wh_test_hwkeystore.c Adds end-to-end client/server hw-only KEK test over mem transport.
test-refactor/config/wolfhsm_cfg.h Enables HW keystore in refactor test configuration when crypto is enabled.
src/wh_server.c Copies hwKeystore pointer from config into server context.
src/wh_server_she.c Fixes SHE persistence behavior for no-NVM servers and PRNG seed handling.
src/wh_server_keystore.c Implements trusted-KEK enforcement, HW KEK resolution, wrap-export handler, and SHE counter guard on unwrap-and-cache.
src/wh_server_crypto.c Strips server-only flags from client-driven crypto cache-import paths.
src/wh_nvm.c Enforces KEK immutability and sanitizes server-only flags in checked add path without mutating client memory.
src/wh_message_keystore.c Implements wrap-export message translation functions.
src/wh_keyid.c Implements HW flag ↔ WH_KEYTYPE_HW translation.
src/wh_hwkeystore.c Implements hwKeystore front-end init/get/cleanup with optional locking.
src/wh_client_keywrap.c Implements wh_Client_KeyWrapExport* request/response/blocking helper.
docs/src/9-Configuration.md Documents new HW keystore macros and trusted software KEK provisioning.
docs/src/5-Features.md Documents trusted KEKs, wrap-export, and hardware-only keys.

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

Comment thread src/wh_server_keystore.c

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

Copilot reviewed 27 out of 27 changed files in this pull request and generated 2 comments.

Comment thread src/wh_server_keystore.c
Comment on lines +1869 to +1872
/* reqData/reqDataSz are unused: the key to wrap already lives in the
* keystore, so there is no inline key payload in the request. */
(void)reqData;
(void)reqDataSz;
Comment thread docs/src/5-Features.md
- a **[hardware-only key](#hardware-only-keys)**: A key stored in hardware in a port-specific manner (see next section)
- a software key carrying the server-only **`WH_NVM_FLAGS_KEK`** flag.

For a software KEK, the `WH_NVM_FLAGS_KEK` flag will be stripped by the server from *every* client request that supplies key or object metadata such that a client can never cause a key or object to carry it. The strip lives in the policy-checked entry points that all client requests funnel through. It is able to be set only by by calling the unchecked keystore/NVM API directly, which is not exposed to via the client API but remains useable for server-side code or offline provisioning via `whnvmtool`. A key carrying the flag is treated as unreadable, immutable, non-evictable, and non-exportable through the client API, and is the only cache/NVM key permitted to act as a KEK for wrap-export and unwrap-and-cache.

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

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

Low (1)

WH_NVM_FLAGS_KEK not stripped on LMS/XMSS keygen, allowing an unremovable key

File: src/wh_server_crypto.c:7151
Function: _HandleLmsKeyGenDma
Category: Key storage and access control bypass

This PR strips WH_NVM_FLAGS_SERVER_ONLY in the standard cache-import functions, but _HandleLmsKeyGenDma and _HandleXmssKeyGenDma (7654) still write client req.flags unsanitized. A client can set WH_NVM_FLAGS_KEK, producing a committed key that _KeystoreCheckPolicy/wh_Nvm_CheckPolicy then freeze, so no client API can ever evict, erase, or destroy it (permanent NVM slot exhaustion).

Recommendation: Mask off WH_NVM_FLAGS_SERVER_ONLY from req.flags in the LMS/XMSS keygen and import paths (also lines 1066, 1127, 7654), matching the other cache-import functions.


This review was generated automatically by Fenrir. Findings are non-blocking.

Add support for server-trusted software KEKs, make them (or HW keys) a requirement
for all keywrap operations, and builds SHE key interoperability on top of it.
@bigbrett bigbrett force-pushed the she-wrapped-interop branch from 37a509f to eeb6889 Compare July 2, 2026 22:16
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.

3 participants