Skip to content

Add verify-only LMS/HSS and XMSS/XMSS^MT support (RFC 8554 / RFC 8391) — Step 1 - #3

Closed
Frauschi wants to merge 1 commit into
masterfrom
claude/add-hbs-verify
Closed

Frauschi wants to merge 1 commit into
masterfrom
claude/add-hbs-verify

Conversation

@Frauschi

@Frauschi Frauschi commented Jul 8, 2026

Copy link
Copy Markdown
Owner

Overview

This is Step 1 of adding stateful hash-based signature (HBS) support to wolfPKCS11, split into phases for easier review:

  • Step 1 (this PR): verify-only support for LMS/HSS (RFC 8554) and XMSS/XMSS^MT (RFC 8391) — PKCS#11 header constants, raw public-key import, signature verification, and token-object persistence of public keys. No keygen, no signing, no private-key objects, no durable state-file framework.
  • Step 2 (future): private-key support for LMS (keygen + signing), introducing the durable state-file framework.
  • Step 3 (future): private-key support for XMSS, reusing the Step 2 framework.

Keeping Step 1 to the verify path makes it small and self-contained: a token can verify RFC 8554 / RFC 8391 signatures against imported public keys, with no changes to the storage backend beyond serializing raw public keys.

What's included

PKCS#11 API (wolfpkcs11/pkcs11.h)

  • Key types CKK_HSS, CKK_XMSS, CKK_XMSSMT; mechanisms CKM_HSS, CKM_XMSS, CKM_XMSSMT (keygen mechanisms defined for header completeness but not wired until Step 2/3).
  • LMS parameter types/constants (CK_HSS_LEVELS, CK_LMS_TYPE, CK_LMOTS_TYPE, CKL_LMS_*, CKL_LMOTS_*, CK_HSS_PARAMS). Constants are always defined; the library rejects at runtime when built without support.

Build system

  • --enable-lms → -DWOLFPKCS11_LMS and --enable-xmss → -DWOLFPKCS11_XMSS (autotools + CMake), each pulling in PKCS#11 v3.2.
  • Both self-disable when SHA-256 is unavailable (both schemes require it), mirroring the ML-DSA/ML-KEM pattern.

Verify implementation (src/internal.c, src/crypto.c, src/slot.c)

  • LMS: wc_LmsKey_Init → SetParameters → ImportPubRaw → Verify. Parameters are self-derived from the raw public key's type fields (L / LMS_type / LMOTS_type); CKA_PARAMETER_SET is accepted as an optional override.
  • XMSS/XMSS^MT: wc_XmssKey_ImportPubRaw_ex auto-derives the parameter set from the embedded OID; is_xmssmt is taken from the key type (CKK_XMSS vs CKK_XMSSMT). One XmssKey type serves both.
  • Import accepts the bare wc_*_ImportPubRaw byte format (60 bytes for HSS, 68 for XMSS with SHA-256).
  • Verify maps only a genuine mismatch (SIG_VERIFY_E) to CKR_SIGNATURE_INVALID; argument/format errors surface as function failures. Wrong-length or malformed public keys on import are rejected with CKR_ATTRIBUTE_VALUE_INVALID. Private-key import and keygen are rejected.
  • Mechanisms advertised with CKF_VERIFY only.

Token-object persistence

  • HBS public keys imported as token objects (CKA_TOKEN=CK_TRUE) are serialized to and reloaded from the token store — just the raw public-key bytes, no state-file machinery.

Testing

  • KAT import + verify (good signature accepted, tampered rejected) for HSS, XMSS and XMSS^MT.
  • Attribute round-trip (CKA_VALUE, CKA_HSS_LEVELS/LMS_TYPE/LMOTS_TYPE), C_GetMechanismInfo (CKF_VERIFY set, no CKF_SIGN), mechanism/key-type mismatch, empty-template and truncated-key rejection.
  • Standalone tests/hbs_persistence_test.c performing a real disk round-trip: create token public key → C_Finalize/C_Initialize → find by CKA_ID → re-verify.
  • Private-key-import-rejected and keygen-rejected tests.

Verified across four build configurations — disabled, --enable-lms, --enable-xmss, and both — each building clean with -Werror and passing make check (48 test programs) with no regressions. Header ABI (pkcs11.h) compiles standalone without the feature macros.

🤖 Generated with Claude Code


Generated by Claude Code

@Frauschi
Frauschi force-pushed the claude/add-hbs-verify branch from 6df7544 to e8402ca Compare July 9, 2026 17:03
Comment thread src/crypto.c Resolved
Comment thread tests/hbs_persistence_test.c Resolved
Comment thread tests/hbs_persistence_test.c Resolved
Comment thread wolfpkcs11/pkcs11.h Resolved
Comment thread wolfpkcs11/pkcs11.h Resolved
Comment thread src/internal.c Resolved
Comment thread src/internal.c Resolved
Comment thread src/internal.c Resolved
Comment thread src/internal.c Resolved
Comment thread src/internal.c Resolved
Frauschi pushed a commit that referenced this pull request Jul 14, 2026
Follow-up to the PR #3 review comments:

pkcs11.h
- Trim the HBS comment blocks (CKK_HSS note removed; CKA_HSS / CKM / and
  CK_HSS_PARAMS comments reduced to the essential text).

store.h
- Reserve the private-key storage type numbers (0x10 for HSS, 0x12 for XMSS)
  for the future sign-capable builds; public keys move to 0x11 / 0x13 so each
  priv/pub pair stays adjacent and ordered private-before-public.

crypto.c
- Drop the WOLFPKCS11_LMS/XMSS #ifdef gates around CKK_HSS/CKK_XMSS/CKK_XMSSMT
  in the C_CreateObject key-type allowlist, matching the (ungated) treatment of
  the other key types.

internal.c
- LMS: rely on wc_LmsKey_ImportPubRaw to auto-derive the parameter set from the
  public key instead of parsing the type fields by hand.
- HSS parameter validation aligned with the PKCS#11 v3.3 HSS profile: the
  optional CKA_HSS_LEVELS / CKA_HSS_LMS_TYPE / CKA_HSS_LMOTS_TYPE attributes, if
  supplied on import, are validated against the parameters derived from the key
  (CKA_PARAMETER_SET cannot carry a CK_HSS_PARAMS struct through the
  ATTR_TYPE_ULONG attribute framework). WP11_Object_SetAttr now accepts these
  attributes for HSS.
- XMSS: when CKA_PARAMETER_SET (the OID as a CK_ULONG) is supplied on import it
  is validated against the OID embedded in the public key, and it can now be
  read back via C_GetAttributeValue.
- Reframe the copy-prohibition comment to cover all LMS/XMSS keys (future
  private-key state must never be duplicated); drop the DH reference and the
  redundant encode comment; fix union comment indentation; remove em-dashes.

tests
- Correct the persistence-test copyright year and note it is groundwork for the
  future private-key state persistence.
- Add HSS CKA_HSS_* and XMSS CKA_PARAMETER_SET import-validation / read-back
  tests.

Verified across the disabled / lms / xmss / both configurations with -Werror;
pkcs11v3test and hbs_persistence_test pass and make check is green (48 tests).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GtRoh5TVMmmfX81LLRbroa
Comment thread src/crypto.c Resolved
Comment thread wolfpkcs11/pkcs11.h Resolved
Comment thread src/internal.c Resolved
Comment thread src/internal.c Resolved
Add PKCS#11 verify-only support for the stateful hash-based signature
schemes LMS/HSS (RFC 8554) and XMSS/XMSS^MT (RFC 8391), backed by wolfSSL
and gated behind the --enable-lms and --enable-xmss build options.

Interface:
- Key types CKK_HSS, CKK_XMSS, CKK_XMSSMT and mechanisms CKM_HSS,
  CKM_XMSS, CKM_XMSSMT, using the OASIS PKCS#11 v3.3 standard constant
  values (not vendor-defined).
- Public keys are imported as ordinary token or session objects from the
  raw RFC 8554 / RFC 8391 public key in CKA_VALUE. wolfSSL derives the
  parameter set from the key bytes; supplied CKA_HSS_* parameter
  attributes and the XMSS CKA_PARAMETER_SET OID are validated against the
  key, and a mismatch is rejected with CKR_ATTRIBUTE_VALUE_INVALID.
- HSS parameter attributes (CKA_HSS_LEVELS, CKA_HSS_LMS_TYPE(S),
  CKA_HSS_LMOTS_TYPE(S)) and the XMSS CKA_PARAMETER_SET are exposed on
  read. CKA_HSS_KEYS_REMAINING is a private-key state property and is
  reported as unavailable in a verify-only build.
- C_Verify checks the mechanism against the key type, and reports a
  wrong-length signature or an empty message (for XMSS) as an invalid
  signature rather than a function failure.

Constraints (verify-only):
- Key generation (CKM_*_KEY_PAIR_GEN) and private-key import are
  rejected. Copying any HBS key is prohibited so that future
  sign-capable builds can never duplicate one-time-signature state.

Persistence:
- Public keys are stored and reloaded from disk via the new store types
  WOLFPKCS11_STORE_HSSKEY_PUB (0x11) and WOLFPKCS11_STORE_XMSSKEY_PUB
  (0x13), with 0x10 and 0x12 reserved for future private keys.

Tests:
- Known-answer verification, parameter-set validation, token-object
  persistence across a library reload, and negative cases covering
  private-key import, wrong mechanism/key-type pairings, and malformed,
  wrong-length, and structurally invalid public keys.
@Frauschi
Frauschi force-pushed the claude/add-hbs-verify branch from cbf5c8e to c878805 Compare July 15, 2026 10:04
@Frauschi Frauschi closed this Jul 15, 2026
@Frauschi
Frauschi deleted the claude/add-hbs-verify branch July 24, 2026 09:26
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.

1 participant