Skip to content

Enforce NONMODIFIABLE and TRUSTED NVM policy on keystore key commit - #492

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

Enforce NONMODIFIABLE and TRUSTED NVM policy on keystore key commit#492
yosuke-wolfssl wants to merge 1 commit into
wolfSSL:mainfrom
yosuke-wolfssl:fix/f_4225

Conversation

@yosuke-wolfssl

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

Copy link
Copy Markdown
Contributor

Problem

WH_KEY_COMMIT persisted a cached key to NVM with no NONMODIFIABLE/TRUSTED
policy check, addressed by f_4225. A cache slot whose id names an immutable NVM
object could be committed over it. The obvious cache route is already blocked
(WH_KS_OP_CACHE checks both flags), so this is a defense-in-depth hole in the
central keystore gate, not a demonstrated bypass — see Tests.

Fix (src/wh_server_keystore.c)

Added a WH_KS_OP_COMMIT branch to _KeystoreCheckPolicy that reads the
stored object's flags (not the cache-first copy a client controls) and
returns WH_ERROR_ACCESS when the target is NONMODIFIABLE or TRUSTED.

  • Scoped to a cached key. An uncached id has nothing to commit and still
    reports WH_ERROR_NOTFOUND, so there is no client-visible protocol change.
  • First commit still allowed. Creating an immutable key (cache with the
    flag, then commit once) is unaffected; only overwriting an existing immutable
    object is refused.
  • Enforcement stays in the keystore gate. wh_Server_KeystoreCommitKey
    keeps its unchecked wh_Nvm_AddObjectWithReclaim, preserving the repo's
    X()/XChecked() layering.

Closes f_4225. wh_Server_KeystoreRevokeKey shares the same cache-to-NVM write
shape and is left as a separate item.

Tests

None, deliberately. The scenario — unwrap-and-cache fills a slot, then
KeyCommit overwrites a protected object — is not reachable from the client
API, so any test would only be driving a harness. The previous server-internal
test (test-refactor/server/wh_test_keystore_policy.c, 232 lines calling
wh_Server_Keystore* directly) is dropped rather than kept.

Two pre-existing gates leave the key-type sets disjoint:

Stage Types reachable
ids a client can name in KeyCommit (wh_KeyId_TranslateFromClient, src/wh_keyid.c:27) CRYPTO, WRAPPED, HW — no client flag maps to SHE, and reqId is masked to the ID field
ids unwrap-and-cache can create (src/wh_server_keystore.c:2274) WRAPPED, SHE
intersection WRAPPED — rejected by wh_Server_KeystoreCommitKey with WH_ERROR_ABORTED (src/wh_server_keystore.c:1227)

That WRAPPED rejection is already asserted from the client in
test-refactor/misc/wh_test_hwkeystore.c. The only client route to a CRYPTO
cache slot is WH_KS_OP_CACHE, which already refuses both flags; the remaining
unchecked cache paths are the SHE handlers, whose SHE-typed ids KeyCommit
cannot address.

Verification

  • test-refactor on 237bfbc: 45/26/0 default, 49/22/0 DMA=1, 51/20/0 SHE=1,
    16/55/0 NOCRYPTO=1 — matches the untouched baseline for this base.
  • Clean under -std=c90 -Werror -Wall -Wextra.
  • Legacy test/ has a pre-existing whTest_CertClientAcert failure on this
    base; it reproduces with the fix reverted, so it is unrelated to this PR.

@yosuke-wolfssl yosuke-wolfssl self-assigned this Jul 26, 2026
Copilot AI review requested due to automatic review settings July 26, 2026 23:30

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 pull request closes a defense-in-depth gap in the server keystore “gate” by ensuring WH_KEY_COMMIT cannot overwrite existing NVM objects that are marked NONMODIFIABLE or TRUSTED. The policy enforcement is implemented centrally in the keystore policy checker (rather than in the lower-level commit function), and is validated via a new server-side test suite.

Changes:

  • Add a WH_KS_OP_COMMIT policy branch that consults the stored NVM object’s flags and denies overwrite when NONMODIFIABLE or TRUSTED.
  • Register and add a new server test (whTest_KeystoreCommitPolicy) covering overwrite-denial, first-commit allowance, normal commit round-trip, and the “uncached commit returns NOTFOUND” guard.
  • Extend the server test registry to include the new test.

Reviewed changes

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

File Description
src/wh_server_keystore.c Enforces NONMODIFIABLE/TRUSTED overwrite denial for commit by checking stored NVM metadata when a cache slot is being committed.
test-refactor/server/wh_test_keystore_policy.c Adds targeted server-side tests validating commit policy behavior and ensuring stored bytes/flags remain unchanged on denied overwrite.
test-refactor/wh_test_list.c Registers the new keystore commit policy 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 #492

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

No new issues found in the changed files. ✅

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.

4 participants