FIPS / eIDAS / KCMVP Hardware Validation Runbook · 2025-12-11
Use this runbook to validate hardware-backed crypto for the Stella Ops FIPS, eIDAS, and KCMVP compliance profiles. It is written for security engineers and validation operators running certification evidence against real HSM/QSCD/KCMVP hardware. When hardware is unavailable, keep the “non-certified” label and use the simulator (devops/services/crypto/sim-crypto-service) to exercise the registry path.
For the profile system itself and current certification baselines, see crypto-compliance.md. For configuration knobs, see crypto-profile-configuration.md.
Common prerequisites
- Hosts: Linux runners for FIPS/OpenSSL FIPS provider; EU QSCD host (HSM/smartcard) for eIDAS; KR host for KCMVP modules.
- Config: two distinct knobs control compliance behaviour and must not be confused:
- Compliance profile (the FIPS/eIDAS/KCMVP selector):
StellaOps:Crypto:Compliance:ProfileId, or envSTELLAOPS_CRYPTO_COMPLIANCE_PROFILE. Valid values:world(default),fips,gost,sm,kcmvp,eidas(seeComplianceProfilesinsrc/__Libraries/StellaOps.Cryptography/ComplianceProfiles.cs).StellaOps:Crypto:Compliance:StrictValidation(envSTELLAOPS_CRYPTO_STRICT_VALIDATION, defaulttrue) fails closed on non-compliant algorithm usage. - Registry active profile (provider-resolution ordering, not a jurisdiction):
StellaOps:Crypto:Registry:ActiveProfileselects a named provider set such asinternational,eu-prod,eu-dev,russia-prod,russia-dev,china-prod,china-dev(seesrc/Cli/StellaOps.Cli/appsettings.crypto.yaml.example). It does not acceptfips/eidas/kcmvpas values.
- Compliance profile (the FIPS/eIDAS/KCMVP selector):
- Evidence bundle: JWKS snapshot, crypto provider-resolution metrics scrape (
crypto_provider_resolutions_total/crypto_provider_resolution_failures_totalon meterstellaops.crypto; seesrc/__Libraries/StellaOps.Cryptography/CryptoProviderMetrics.cs), signing/verification logs for a fixed validation message of your choosing. - Simulator fallback (test-only, never Production/Staging): set
STELLAOPS_CRYPTO_ENABLE_SIM=1to add thesim.crypto.remoteprovider to the active profile, andSTELLAOPS_CRYPTO_SIM_URL=http://<host>:<port>to point at the simulator (devops/services/crypto/sim-crypto-service). The canonical manifest declaresrequiresExplicitUnsafeOptIn: trueonly onsim.crypto.remote; the simulator Compose overlay enforces that contract by requiringSTELLAOPS_ALLOW_UNSAFE_CRYPTO_SIM=1, and the provider is forbidden inProduction/Staging(seedevops/etc/crypto-plugins-manifest.jsonanddevops/compose/docker-compose.crypto-provider.crypto-sim.yml).
FIPS (baseline or certified)
- Select the FIPS compliance profile:
FIPS mode itself is detected from the host, not a Stella config flag:StellaOps: Crypto: Compliance: ProfileId: fips # forces SHA-256/384/512 + PBKDF2; BLAKE3 is not FIPS-approved StrictValidation: true # fail closed on non-compliant algorithm usageOperatingSystemFipsModeProbereadsHKLM\SYSTEM\CurrentControlSet\Control\Lsa\FIPSAlgorithmPolicy\Enabledon Windows and/proc/sys/crypto/fips_enabledon Linux (seesrc/Cryptography/StellaOps.Cryptography.Plugin.Fips/OperatingSystemFipsModeProbe.cs). Enable the FIPS provider at the OS/runtime layer (Windows FIPS policy, or the OpenSSL FIPS provider on Linux) rather than via an in-app toggle. There is noCrypto:Fips:UseBclFipsModeconfig key. - Keep crypto on-prem. The software-only FIPS provider
fips.ecdsa.soft(FipsSoftCryptoProvider, ES256/384/512 + SHA-256/384/512) is gated by theFIPS_SOFT_ALLOWEDenv var and is disabled unlessFIPS_SOFT_ALLOWED=1(ortrue). When a certified module is present, leaveFIPS_SOFT_ALLOWEDunset (or0) so the non-certified software provider stays off and a certified provider is resolved instead. Do not route signing through a cloud-managed KMS (no AWS/Azure/GCP KMS defaults); theAWS_USE_FIPS_ENDPOINTSflag referenced in earlier drafts is not implemented and is not part of the offline-first posture. - Run signing tests (Authority/Signer/Attestor). For CI smoke without a certified module, opt in explicitly with
FIPS_SOFT_ALLOWED=1; keep this off in any release/evidence-bearing run. - Capture evidence:
openssl fipsinstall -module <path>output (if using the OpenSSL FIPS provider).- JWKS export (P-256/384/521).
- Provider-resolution metric
crypto_provider_resolutions_total{provider="fips.ecdsa.soft"}(or the certified provider name) from meterstellaops.crypto.
- Keep the “non-certified” label until CMVP evidence is attached; the simulator may be used for CI smoke only.
eIDAS (QSCD)
The eIDAS plugin (src/__Libraries/StellaOps.Cryptography.Plugin.EIDAS/) binds StellaOps:Crypto:Profiles:eidas (EidasOptions). It does not expose a direct PKCS#11 slot/PIN configuration; qualified signing is delegated to a remote QTSP/QSCD via the Tsp adapter (see “eIDAS TSP/QSCD HTTP adapter” below), or to a local PKCS#12 keystore via Local (LocalSigningOptions) for non-qualified AdES dev signing. Earlier drafts of this runbook configured an eidas:Pkcs11 block with LibraryPath/SlotId/PinEnvVar; that block is not implemented and must not be used.
- Select the eIDAS compliance profile and point the eIDAS plugin at your QTSP:
StellaOps: Crypto: Compliance: ProfileId: eidas Profiles: eidas: SignatureLevel: QES # AdES | AES | QES SignatureFormat: CAdES # CAdES | XAdES | PAdES | JAdES DigestAlgorithm: SHA256 EvidenceProfile: BaselineB # BaselineB | BaselineT | BaselineLT | BaselineLTA Tsp: Endpoint: https://qtsp-adapter.example ApiKey: ${EIDAS_TSP_API_KEY} SignPath: /api/v1/sign VerifyPath: /api/v1/verify Keys: - KeyId: eu-qscd-signing Source: tsp # "tsp" (remote) or "local" (PKCS#12) - Import the qualified cert to the trust store; capture OCSP/CRL endpoints. EU Trusted List validation is controlled by
StellaOps:Crypto:Profiles:eidas:TrustedList(TrustedListOptions). - Export JWKS from Authority/Signer; verify
kidandcrvmatch the QSCD key. - Sign a fixed validation message; archive signature + certificate chain.
- Evidence: QTSP/QSCD response artefacts, JWKS snapshot, QSCD audit logs (if available), provider-resolution metric
crypto_provider_resolutions_total{provider="eu.eidas.soft"}(or the certified eIDAS provider name) from meterstellaops.crypto. - If QSCD hardware/QTSP is unavailable, the software-only provider
eu.eidas.soft(EidasSoftCryptoProvider, ES256/384 + SHA-256/384, non-certified, QSCD not enforced) is gated byEIDAS_SOFT_ALLOWEDand is disabled unlessEIDAS_SOFT_ALLOWED=1(ortrue). Set it for CI coverage against the simulator; keep it off in evidence-bearing runs.
eIDAS TSP/QSCD HTTP adapter
The library provider at src/__Libraries/StellaOps.Cryptography.Plugin.EIDAS/ uses the configured StellaOps:Crypto:Profiles:eidas:Tsp endpoint for remote signing and verification. It no longer fabricates signatures or accepts every verification result. Configure:
StellaOps:
Crypto:
Profiles:
eidas:
DigestAlgorithm: SHA256
SignatureLevel: QES
SignatureFormat: CAdES
Tsp:
Endpoint: https://qtsp-adapter.example
ApiKey: ${EIDAS_TSP_API_KEY}
SignPath: /api/v1/sign
VerifyPath: /api/v1/verify
Keys:
- KeyId: eu-qscd-signing
Source: tsp
The adapter receives a digest-only contract for sign/verify requests (it sends the base64 digest computed by ComputeDigest, the configured DigestAlgorithm, SignatureLevel, and SignatureFormat). Vendor QTSP/QSCD API differences should be handled behind that adapter; Stella Ops fails closed on non-success (eidas.tsp.sign_failed), empty-signature (eidas.tsp.response_empty_signature), and malformed-base64 (eidas.tsp.response_invalid_signature_base64) responses.
Note: only EvidenceProfile: BaselineB is production-ready today. Requesting BaselineT/BaselineLT/BaselineLTA causes ValidateEvidenceProfile to throw eidas.lt.evidence_embedding_not_implemented after checking the returned evidence — i.e. timestamp/revocation/archive evidence embedding for QES-LT/LTA is not yet wired (see TrustServiceProviderClient.Signing.cs). Keep the profile at BaselineB until that path lands.
KCMVP
KCMVP support in the codebase is currently limited to: (a) the kcmvp compliance profile, which selects SHA-256 for all hash purposes (ComplianceProfiles.Kcmvp), and (b) the software-only hash-only provider kr.kcmvp.hash (KcmvpHashOnlyProvider, SHA-256 content hashing only — no signing/verification). There is no KCMVP signing plugin and no config-bound KCMVP options class; an eidas-style Kcmvp: block with LibraryPath/SlotId/PinEnvVar/Algorithm: kcdsa (and ARIA/SEED/KCDSA signing) is not implemented. A certified ARIA/SEED/KCDSA module would have to be integrated as a new crypto provider plugin before signing-side KCMVP validation is meaningful.
- Select the KCMVP compliance profile:
StellaOps: Crypto: Compliance: ProfileId: kcmvp - The hash-only provider is gated by
KCMVP_HASH_ALLOWED, which — unlike the FIPS/eIDAS soft gates — is enabled by default (treated as on when the var is unset,1, ortrue). Keep it on while running hash-only baseline evidence. - Run hash tests for a fixed validation message; collect SHA-256 hashes and the provider-resolution metric
crypto_provider_resolutions_total{provider="kr.kcmvp.hash"}from meterstellaops.crypto. Signing tests are not applicable until a certified signing provider is added. - When a certified module/provider is present, set
KCMVP_HASH_ALLOWED=0to disable the hash-only provider and rerun tests to retire the hash-only label.
Evidence checklist
- Command outputs:
pkcs11-tool --list-slots,--list-objects, module self-tests (if provided). - JWKS snapshots and a crypto provider-resolution metrics scrape (
crypto_provider_resolutions_total/crypto_provider_resolution_failures_total, meterstellaops.crypto). - Signature/hash files and verification logs for the fixed validation message.
- Configuration files / env vars used during the run (record which of
FIPS_SOFT_ALLOWED,EIDAS_SOFT_ALLOWED,KCMVP_HASH_ALLOWED,STELLAOPS_CRYPTO_ENABLE_SIM,STELLAOPS_ALLOW_UNSAFE_CRYPTO_SIMwere set).
Publishing
- Attach evidence to sprint artefacts for FIPS-EIDAS-VAL-01 and KCMVP-VAL-01.
- Update RootPack manifests to remove the “non-certified” wording once certified evidence is present; otherwise keep the simulator noted as the interim path.
