Skip to content

feat(hsm): HSM-delegated EC/ECDSA/RSA-PSS/EdDSA key generation and signing - #1169

Open
Manuthor wants to merge 6 commits into
pkcs11_v3_rolloutfrom
hsm_delegation
Open

Manuthor wants to merge 6 commits into
pkcs11_v3_rolloutfrom
hsm_delegation

Conversation

@Manuthor

@Manuthor Manuthor commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Extends HSM delegation beyond the existing RSA path: KMIP key generation and signing operations can now be delegated end-to-end to a PKCS#11 HSM for EC (NIST curves, Ed25519/Ed448, X25519), ECDSA, RSA-PSS, and EdDSA, closing #1154 and most of #1157.

Features

  • HSM-delegated RSA-PSS signingSigningAlgorithm/HsmSigningAlgorithm gain RsaPssSha256/384/512 { salt_length }, resolved from KMIP CryptographicParameters; deterministic (salt_length: 0) and default (digest-length) salt both supported.
  • HSM-delegated EC key generation — new HsmKeypairAlgorithm::EC, EcCurve enum (P-224/256/384/521, Ed25519/Ed448, X25519), new KeyMaterial::EcPrivateKey/EcPublicKey; existing ckms ec keys create and server create_key_pair.rs needed no changes (already algorithm-generic).
  • HSM-delegated ECDSA signingSigningAlgorithm::EcdsaSha256/384/512, dispatched to CKM_ECDSA_SHA*; raw PKCS#11 r‖s signatures re-encoded to DER.
  • HSM-delegated EdDSA signingEcCurve::Ed25519/Ed448 (CKM_EC_EDWARDS_KEY_PAIR_GEN), SigningAlgorithm::Ed25519/Ed448 (CKM_EDDSA), gated behind a new non-fips feature on cosmian_kms_interfaces/cosmian_kms_base_hsm/every vendor PKCS#11 loader, mirroring existing software EdDSA gating.
  • HSM-delegated X25519 key generationEcCurve::X25519 (CKM_EC_MONTGOMERY_KEY_PAIR_GEN), requested via CryptographicAlgorithm::ECDH + CURVE25519 RecommendedCurve; generated keys carry CKA_DERIVE only (derive-only). Rejected from the public HSM trait until a matching DeriveKey path exists.
  • HsmStore generalized from RSA-only to algorithm-generic (RSA or EC) keypair-creation detection, signing, and attribute reconstruction; get_key_type() validates CKA_EC_PARAMS against the FIPS-approved curve allow-list for any CKK_EC object.

Fixes

  • Preserve EC-family HSM metadata when reconstructing KMIP objects (signing algorithm, ECDH/DeriveKey typing for X25519, curve domain parameters in GetAttributes).
  • Fixed delegated-signing mechanism selection: pre-digested ECDSA/RSA-PSS now use raw CKM_ECDSA/CKM_RSA_PKCS_PSS, explicit MGF1 hash choices are preserved, and missing parameters fall back to key-aware defaults instead of assuming RSA/SHA-256.
  • Hardened edge cases: pre-digested RSA PKCS#1 v1.5 now wraps the digest as DigestInfo (raw CKM_RSA_PKCS) instead of re-hashing; KMIP Sign rejects requests setting both data and digested_data; Ed25519/Ed448 reject unsupported pre-hashed requests.
  • ckms ec sign now sends curve-appropriate CryptographicParameters automatically for HSM-delegated ECDSA/EdDSA and rejects --digested for Ed25519/Ed448 and non-signing curves (X25519/X448).

Deferred (tracked as remaining #1157 scope)

  • X25519 ECDH key agreement (DeriveKey), HKDF/SP 800-108 KDF, and message-based AEAD delegation — no available PKCS#11 simulator (SoftHSM2, Utimaco CryptoServer simulator) implements the required mechanisms in this environment.

Testing

  • Unit tests for the new SigningAlgorithm/HsmSigningAlgorithm PSS/ECDSA/EdDSA variants and mechanism dispatch, curve OID round-trips, and Edwards/Montgomery parameter encoding.
  • #[ignore]d SoftHSM2 integration tests, manually validated against live SoftHSM2 tokens: RSA-PSS (all digests/salt modes), EC keypair generation (all 4 curves), ECDSA signing (4 curves × 3 hashes, DER + OpenSSL cross-check), EdDSA sign/verify (Ed25519/Ed448).
  • Two ADRs documenting the Track A (RSA-PSS/EC/ECDSA) scope decision and its completion, including the PBKDF2/X25519-derive deferral rationale.

Closes #1154, partially addresses #1157
Closes #1182
Closes #1158

Comment thread crate/interfaces/src/hsm/hsm_store.rs Outdated
Comment thread crate/hsm/base_hsm/src/kms_hsm.rs
Comment thread crate/interfaces/src/crypto_oracle.rs Outdated
Comment thread crate/interfaces/src/hsm/hsm_store.rs
Comment thread crate/hsm/base_hsm/src/session/session_impl.rs Outdated
Comment thread crate/interfaces/src/crypto_oracle.rs Outdated
Comment thread crate/hsm/base_hsm/src/session/ec.rs
Comment thread crate/interfaces/src/hsm/hsm_store.rs Outdated
Comment thread crate/interfaces/src/crypto_oracle.rs Outdated
Comment thread crate/interfaces/src/crypto_oracle.rs

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.

🟡 Changes recommended

There are correctness gaps between the new EC/Ed signing support and actual request/filter behavior (notably default signing parameters and EC object discovery), plus documentation/ADR inconsistencies that would mislead users.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR expands KMS HSM delegation beyond RSA by adding EC keypair creation and additional signing mechanisms (RSA-PSS, ECDSA, and non-FIPS EdDSA), plus related HSM object export/metadata handling and documentation/ADRs.

Changes:

  • Add EC keypair generation and EC key export/metadata plumbing in the HSM base layer.
  • Extend signing algorithm resolution and PKCS#11 dispatch for RSA-PSS, ECDSA, and (non-FIPS) EdDSA.
  • Document the new HSM-delegated capabilities and add Track A ADRs; propagate a new non-fips feature through HSM crates.
File summaries
File Description
documentation/docs/hsm_support/hsm_operations.md Documents HSM-delegated EC keygen and signing behavior, plus PKCS#11 v3 capability notes
documentation/docs/adr/2026-09-06-hsm-track-a-ec-ecdsa-completion-pbkdf2-deferral.md Adds ADR claiming Track A EC/ECDSA completion and PBKDF2 deferral
documentation/docs/adr/2026-09-05-hsm-track-a-rsa-pss-scope-decision.md Adds initial scope decision ADR for Track A (RSA-PSS first)
crate/server/src/core/operations/destroy.rs Allows HSM guard to accept EC key types in destroy flow
crate/interfaces/src/lib.rs Exposes new EC key types/materials in interfaces crate exports
crate/interfaces/src/hsm/mod.rs Re-exports new EC HSM interface types
crate/interfaces/src/hsm/interface.rs Adds EC keypair algorithm + filters + EC key material types
crate/interfaces/src/hsm/hsm_store.rs Extends HsmStore to create/sign/export EC keys and map curves to KMIP
crate/interfaces/src/crypto_oracle.rs Adds RSA-PSS/ECDSA/EdDSA signing variants and KMIP parameter resolution tests
crate/interfaces/Cargo.toml Adds non-fips feature flag for HSM-related non-FIPS algorithms
crate/hsm/utimaco/Cargo.toml Propagates non-fips feature to vendor loader crate
crate/hsm/softhsm2/src/tests.rs Extends SoftHSM2 test suite to cover EC keygen, RSA-PSS, ECDSA, and EdDSA (non-fips)
crate/hsm/softhsm2/Cargo.toml Propagates non-fips feature to vendor loader crate
crate/hsm/smartcardhsm/Cargo.toml Propagates non-fips feature to vendor loader crate
crate/hsm/proteccio/Cargo.toml Propagates non-fips feature to vendor loader crate
crate/hsm/crypt2pay/Cargo.toml Propagates non-fips feature to vendor loader crate
crate/hsm/base_hsm/src/tests_shared.rs Adds shared EC/RSA-PSS/ECDSA/(EdDSA) test helpers and OpenSSL verification helpers
crate/hsm/base_hsm/src/session/session_impl.rs Adds signing dispatch (RSA-PSS/ECDSA/EdDSA), EC key export/metadata handling, and EC filters
crate/hsm/base_hsm/src/session/mod.rs Registers new EC session module and exposes curve helpers internally
crate/hsm/base_hsm/src/session/ec.rs Implements EC keypair generation, curve OID/name encoding, and curve helpers
crate/hsm/base_hsm/src/kms_hsm.rs Extends BaseHsm create_keypair to support EC and non-fips curves
crate/hsm/base_hsm/Cargo.toml Adds OpenSSL dependency (used by shared HSM test helpers) and non-fips feature
CHANGELOG/hsm_delegation.md Adds branch changelog entry for Track A/Track B delegation work
Cargo.lock Records added dependency (OpenSSL) in lockfile
Review details

Suppressed comments (1)

crate/interfaces/src/hsm/hsm_store.rs:1506

  • The EC Attributes created here omit key_format_type. Setting it to TransparentECPublicKey helps ensure GetAttributes and attribute-based queries report the correct key format for EC public keys.
            let mut attributes = Attributes {
                cryptographic_algorithm: Some(CryptographicAlgorithm::EC),
                cryptographic_length: Some(i32::try_from(km.curve.key_length_in_bits()).map_err(
                    |e| InterfaceError::InvalidRequest(format!("Invalid key length: {e}")),
                )?),
  • Files reviewed: 23/24 changed files
  • Comments generated: 8
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread crate/hsm/base_hsm/src/session/ec.rs
Comment thread crate/interfaces/src/hsm/hsm_store.rs
Comment thread crate/hsm/base_hsm/src/session/session_impl.rs Outdated
Comment thread crate/interfaces/src/hsm/hsm_store.rs
Comment thread crate/interfaces/src/hsm/interface.rs
Comment thread documentation/docs/hsm_support/hsm_operations.md
Comment thread documentation/docs/hsm_support/hsm_operations.md
Comment thread documentation/docs/adr/2026-09-05-hsm-track-a-rsa-pss-scope-decision.md Outdated
Comment thread crate/hsm/base_hsm/src/session/session_impl.rs
Comment thread crate/hsm/base_hsm/src/session/ec.rs
Comment thread crate/hsm/base_hsm/src/session/session_impl.rs Outdated
Comment thread crate/interfaces/src/hsm/hsm_store.rs
Comment thread crate/interfaces/src/hsm/hsm_store.rs
Comment thread crate/hsm/base_hsm/src/session/session_impl.rs
Comment thread crate/interfaces/src/crypto_oracle.rs
Comment thread crate/interfaces/src/crypto_oracle.rs
@Manuthor
Manuthor force-pushed the hsm_delegation branch 2 times, most recently from a77cefc to 57fcef2 Compare September 8, 2026 13:22
@Manuthor
Manuthor deployed to xks-remote-approval September 10, 2026 09:19 — with GitHub Actions Active
@Manuthor
Manuthor removed this pull request from stack #1181 September 10, 2026 09:19
@Manuthor
Manuthor changed the base branch from pkcs11_v3 to pkcs11_v3_rollout September 10, 2026 09:19
@Manuthor
Manuthor added this pull request to stack #1168 September 10, 2026 09:19
@Manuthor Manuthor changed the title feat: complete HSM delegation feat(hsm): HSM-delegated EC keygen, ECDSA, RSA-PSS, and EdDSA signing Sep 10, 2026
@Manuthor
Manuthor deployed to xks-remote-approval September 11, 2026 16:15 — with GitHub Actions Active
@Manuthor Manuthor changed the title feat(hsm): HSM-delegated EC keygen, ECDSA, RSA-PSS, and EdDSA signing feat(hsm): HSM-delegated EC/ECDSA/RSA-PSS/EdDSA key generation and signing Sep 17, 2026
@Manuthor
Manuthor deployed to xks-remote-approval September 17, 2026 13:05 — with GitHub Actions Active
@Manuthor
Manuthor deployed to xks-remote-approval September 18, 2026 11:15 — with GitHub Actions Active
@Manuthor
Manuthor deployed to xks-remote-approval September 18, 2026 12:31 — with GitHub Actions Active
Adds a minimal, hand-written, additive FFI surface (CK_INTERFACE,
C_GetInterfaceList) to HsmLib so the KMS can detect PKCS#11 v3.0
interface support without changing any existing v2.40 function
resolution. Fully backward-compatible: symbol resolution is
best-effort and never fails HsmLib::instantiate.

- New crate/hsm/base_hsm/src/pkcs11_v3.rs: CkInterface, CkCGetInterfaceList,
  InterfaceDescriptor, and a pure parse_interfaces() with unit tests.
- HsmLib gains supports_pkcs11_v3_interfaces() and
  list_pkcs11_v3_interfaces(), following the existing two-call PKCS#11
  convention (count then fill), with a defense-in-depth plausibility
  cap (MAX_PLAUSIBLE_PKCS11_V3_INTERFACES) on the allocation.
- Ignored SoftHSM2 integration test asserting the probe is additive
  (v2.40 library reports no v3.0 support, existing behavior unaffected).
- ADR documenting the hand-write-vs-fork-pkcs11-sys scope decision.
- mdBook doc section on PKCS#11 protocol version compatibility.
- Branch changelog entry.

Note: crate/crypto/src/openssl/ocsp.rs import-order is a pre-existing
nightly/stable rustfmt drift from a prior merge, auto-fixed here only
because the pre-commit nightly-cargo-format hook enforces it workspace-wide.

Closes #1153
Adds a minimal, hand-written, additive FFI surface (CK_INTERFACE,
C_GetInterfaceList) to HsmLib so the KMS can detect PKCS#11 v3.0
interface support without changing any existing v2.40 function
resolution. Fully backward-compatible: symbol resolution is
best-effort and never fails HsmLib::instantiate.

- New crate/hsm/base_hsm/src/pkcs11_v3.rs: CkInterface, CkCGetInterfaceList,
  InterfaceDescriptor, and a pure parse_interfaces() with unit tests.
- HsmLib gains supports_pkcs11_v3_interfaces() and
  list_pkcs11_v3_interfaces(), following the existing two-call PKCS#11
  convention (count then fill), with a defense-in-depth plausibility
  cap (MAX_PLAUSIBLE_PKCS11_V3_INTERFACES) on the allocation.
- Ignored SoftHSM2 integration test asserting the probe is additive
  (v2.40 library reports no v3.0 support, existing behavior unaffected).
- ADR documenting the hand-write-vs-fork-pkcs11-sys scope decision.
- mdBook doc section on PKCS#11 protocol version compatibility.
- Branch changelog entry.

Note: crate/crypto/src/openssl/ocsp.rs import-order is a pre-existing
nightly/stable rustfmt drift from a prior merge, auto-fixed here only
because the pre-commit nightly-cargo-format hook enforces it workspace-wide.

Closes #1153
…ces, CKM_AES_GCM, C_Verify, Ed25519 fixes)

Rolls out PKCS#11 v3.0/v3.1 conformance in `cosmian_pkcs11` (`libcosmian_pkcs11`), the KMS's own PKCS#11 provider library, while keeping the existing v2.40 `C_GetFunctionList` entry point untouched — every existing consumer (Veracrypt, LUKS, Cryhod, Oracle TDE, OpenSSH) keeps working with no configuration or code change.

- Implement v3.0 interface discovery (`C_GetInterfaceList`/`C_GetInterface`); `CK_INFO.cryptokiVersion` bumped 2.40 → 3.1.
- Add native `CKM_AES_GCM` support (AAD, `ciphertext||16-byte-tag` framing, 128-bit tag, IV 1–128 B, AAD ≤1 MiB).
- Implement real `C_VerifyInit`/`C_Verify`/`C_VerifyUpdate`/`C_VerifyFinal` (previously `CKR_FUNCTION_NOT_SUPPORTED` stubs) via a new `VerifyContext`/`Backend::remote_verify`, mirroring the existing sign path; failed verification maps to `CKR_SIGNATURE_INVALID`.
- Enrich `ckms pkcs11 verify` with full v3.0/v3.1 coverage: interface discovery, `C_GetInfo`, mechanism list/flags, and `CKO_PROFILE` self-declaration, run against the real provider `.so`/`.dylib`/`.dll`.

- Ed25519/Ed448 keys were unusable through any `CKA_KEY_TYPE`-aware client: `to_ck_key_type()` now reports `CKK_EC_EDWARDS`/`CKK_EC_MONTGOMERY`, and `key_algorithm_from_attributes()` now recognizes KMIP's dedicated `Ed25519`/`Ed448` algorithm values (closes #1183). NIST/SECG curves are unaffected.
- `CKM_RSA_PKCS_PSS` was double-hashing input instead of treating it as a pre-computed digest, per PKCS#11 v3.1 §6.4.7 — broke real `pkcs11-tool --sign --mechanism RSA-PKCS-PSS` calls.
- Added missing mandatory `CKA_MODULUS_BITS` attribute on RSA key objects.
- `C_GetMechanismInfo` was reporting `CKF_SIGN` without `CKF_VERIFY` for all signature mechanisms.
- Fixed a KMIP `SignatureVerify`-wide bug in `crate/crypto` (`ecdsa_verify`/`ed_verify`): malformed/invalid signatures raised a hard error instead of mapping to `ValidityIndicator::Invalid`, which broke `CKR_SIGNATURE_INVALID` for every PKCS#11 caller.
- Windows: avoid unaligned reads/writes into packed `CK_MECHANISM_INFO`/`CK_GCM_PARAMS`/`CK_RSA_PKCS_PSS_PARAMS` structs; keep `CK_FUNCTION_LIST.version` at 2.40 for legacy compatibility.
- `shell.nix` `WITH_HSM=1` `LD_LIBRARY_PATH` fix so HSM PKCS#11 modules (SoftHSM2) can dlopen `libstdc++.so.6` in the Nix dev shell.

- New `tests_v3.rs` modules in both `cosmian_pkcs11_module` and `cosmian_pkcs11`, splitting v2.40 baseline tests from v3.0/v3.1-specific conformance tests.
- HSM-KEK multi-curve signing tests (ECDSA P-256, secp256k1, EdDSA Ed25519, RSA-PSS) against a SoftHSM2-backed KMS.
- New external-client conformance tier (`mise run test:hsm-pkcs11-tool`): drives the same sign/verify operations through OpenSC's `pkcs11-tool` against the real, dynamically-loaded provider library — this tier is what surfaced the Ed25519/RSA-PSS/`CKA_MODULUS_BITS`/`CKF_VERIFY` bugs above.
- Table-driven test asserting all ~40 unimplemented v3.0 functions return `CKR_FUNCTION_NOT_SUPPORTED`.
- New ADR (`documentation/docs/adr/2026-09-04-pkcs11-v3-provider-rollout.md`) and reference doc (`documentation/docs/integrations/pkcs11_provider.md`).

Closes #1156, #1183
…gning

Extends HSM delegation beyond the existing RSA path: KMIP key generation and signing operations can now be delegated end-to-end to a PKCS#11 HSM for EC (NIST curves, Ed25519/Ed448, X25519), ECDSA, RSA-PSS, and EdDSA, closing #1154 and most of #1157.

## Features
- **HSM-delegated RSA-PSS signing** — `SigningAlgorithm`/`HsmSigningAlgorithm` gain `RsaPssSha256/384/512 { salt_length }`, resolved from KMIP `CryptographicParameters`; deterministic (`salt_length: 0`) and default (digest-length) salt both supported.
- **HSM-delegated EC key generation** — new `HsmKeypairAlgorithm::EC`, `EcCurve` enum (P-224/256/384/521, Ed25519/Ed448, X25519), new `KeyMaterial::EcPrivateKey`/`EcPublicKey`; existing `ckms ec keys create` and server `create_key_pair.rs` needed no changes (already algorithm-generic).
- **HSM-delegated ECDSA signing** — `SigningAlgorithm::EcdsaSha256/384/512`, dispatched to `CKM_ECDSA_SHA*`; raw PKCS#11 `r‖s` signatures re-encoded to DER.
- **HSM-delegated EdDSA signing** — `EcCurve::Ed25519`/`Ed448` (`CKM_EC_EDWARDS_KEY_PAIR_GEN`), `SigningAlgorithm::Ed25519`/`Ed448` (`CKM_EDDSA`), gated behind a new `non-fips` feature on `cosmian_kms_interfaces`/`cosmian_kms_base_hsm`/every vendor PKCS#11 loader, mirroring existing software EdDSA gating.
- **HSM-delegated X25519 key generation** — `EcCurve::X25519` (`CKM_EC_MONTGOMERY_KEY_PAIR_GEN`), requested via `CryptographicAlgorithm::ECDH` + `CURVE25519` `RecommendedCurve`; generated keys carry `CKA_DERIVE` only (derive-only). Rejected from the public `HSM` trait until a matching `DeriveKey` path exists.
- `HsmStore` generalized from RSA-only to algorithm-generic (RSA or EC) keypair-creation detection, signing, and attribute reconstruction; `get_key_type()` validates `CKA_EC_PARAMS` against the FIPS-approved curve allow-list for any `CKK_EC` object.

## Fixes
- Preserve EC-family HSM metadata when reconstructing KMIP objects (signing algorithm, `ECDH`/`DeriveKey` typing for X25519, curve domain parameters in `GetAttributes`).
- Fixed delegated-signing mechanism selection: pre-digested ECDSA/RSA-PSS now use raw `CKM_ECDSA`/`CKM_RSA_PKCS_PSS`, explicit MGF1 hash choices are preserved, and missing parameters fall back to key-aware defaults instead of assuming RSA/SHA-256.
- Hardened edge cases: pre-digested RSA PKCS#1 v1.5 now wraps the digest as `DigestInfo` (raw `CKM_RSA_PKCS`) instead of re-hashing; KMIP `Sign` rejects requests setting both `data` and `digested_data`; Ed25519/Ed448 reject unsupported pre-hashed requests.
- `ckms ec sign` now sends curve-appropriate `CryptographicParameters` automatically for HSM-delegated ECDSA/EdDSA and rejects `--digested` for Ed25519/Ed448 and non-signing curves (X25519/X448).

## Deferred (tracked as remaining #1157 scope)
- X25519 ECDH key agreement (`DeriveKey`), HKDF/SP 800-108 KDF, and message-based AEAD delegation — no available PKCS#11 simulator (SoftHSM2, Utimaco CryptoServer simulator) implements the required mechanisms in this environment.

## Testing
- Unit tests for the new `SigningAlgorithm`/`HsmSigningAlgorithm` PSS/ECDSA/EdDSA variants and mechanism dispatch, curve OID round-trips, and Edwards/Montgomery parameter encoding.
- `#[ignore]`d SoftHSM2 integration tests, manually validated against live SoftHSM2 tokens: RSA-PSS (all digests/salt modes), EC keypair generation (all 4 curves), ECDSA signing (4 curves × 3 hashes, DER + OpenSSL cross-check), EdDSA sign/verify (Ed25519/Ed448).
- Two ADRs documenting the Track A (RSA-PSS/EC/ECDSA) scope decision and its completion, including the PBKDF2/X25519-derive deferral rationale.

Closes #1154, partially addresses #1157

This branch was successfully deployed

No deployments
xks-remote-approval eff91e74 Deployed Sep 20, 2026 by Manuthor via main / test / AWS XKS — remote server #8701
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants