Craton HSM

FIPS 140-3 Audit Scope

Cryptographic Module Boundary

The cryptographic module boundary encompasses all code that handles key material, performs cryptographic operations, or enforces security policy.

Inside the boundary

ComponentPathRole
Core librarysrc/All cryptographic logic
Crypto enginesrc/crypto/Algorithm implementations and self-tests
Key material managementsrc/store/RawKeyMaterial, ObjectStore, EncryptedStore
Session and authenticationsrc/session/, src/token/Session state machine, PIN hashing, login
PKCS#11 C ABIsrc/pkcs11_abi/Input validation, output marshalling
Self-testssrc/crypto/self_test.rsFIPS POST known-answer tests
Audit logsrc/audit/Tamper-evident event recording

Outside the boundary (excluded)

ComponentPathReason
gRPC daemoncraton-hsm-daemon/Network transport layer; calls into module
Admin CLItools/craton-hsm-admin/Management interface; calls into module
Spy wrappertools/pkcs11-spy/Debug/logging tool; no crypto
Deployment artifactsdeploy/Infrastructure only
Benchmarksbenches/Testing only
Third-party dependenciesCargo.lockEvaluated separately (see Dependency Audit)

Algorithm Inventory

Approved Algorithms (FIPS 140-3)

AlgorithmStandardKey SizesCrateStatus
AES-GCMSP 800-38D256-bitaes-gcm 0.10Implemented
AES-CBCSP 800-38A128/192/256-bitaes 0.8 + cbc 0.1Implemented
AES-CTRSP 800-38A128/256-bitaes 0.8 + ctr 0.9Implemented
AES-KWSP 800-38F128/256-bitaes-kw 0.2Implemented
RSA PKCS#1 v1.5FIPS 186-52048, 3072, 4096rsa 0.9Implemented
RSA-PSSFIPS 186-52048, 3072, 4096rsa 0.9Implemented
RSA-OAEPPKCS#1 v2.22048, 3072, 4096rsa 0.9Implemented
ECDSA P-256FIPS 186-5256-bitp256 0.13Implemented
ECDSA P-384FIPS 186-5384-bitp384 0.13Implemented
Ed25519RFC 8032256-bited25519-dalek 2Implemented
ECDH P-256SP 800-56A256-bitp256 0.13Implemented
ECDH P-384SP 800-56A384-bitp384 0.13Implemented
SHA-256FIPS 180-4-sha2 0.10Implemented
SHA-384FIPS 180-4-sha2 0.10Implemented
SHA-512FIPS 180-4-sha2 0.10Implemented
SHA3-256FIPS 202-sha3 0.10Implemented
SHA3-384FIPS 202-sha3 0.10Implemented
SHA3-512FIPS 202-sha3 0.10Implemented
HMAC-SHA256FIPS 198-1-hmac 0.12Implemented
HMAC-SHA384FIPS 198-1-hmac 0.12Implemented
HMAC-SHA512FIPS 198-1-hmac 0.12Implemented
PBKDF2-HMAC-SHA256SP 800-132-pbkdf2 0.12Implemented (PIN hashing)
ML-DSA-44/65/87FIPS 204-ml-dsa 0.1.0-rc.7Implemented
ML-KEM-512/768/1024FIPS 203-ml-kem 0.3.0-rc.0Implemented
SLH-DSAFIPS 205Multipleslh-dsa 0.2.0-rc.4Implemented

Non-approved (restricted by configuration)

AlgorithmStatusConfig control
SHA-1Available but blocked for signingallow_sha1_signing = false
RSA < 2048Blockedallow_weak_rsa = false

Mechanism count

41 PKCS#11 mechanisms registered via C_GetMechanismList:

  • 10 RSA (keygen, PKCS#1, PSS with SHA-256/384/512, OAEP)
  • 7 EC (keygen, ECDSA, ECDSA-SHA*, ECDH)
  • 1 EdDSA
  • 7 AES (keygen, GCM, CBC, CBC-PAD, CTR, KW, KWP)
  • 7 Digest (SHA-1, SHA-256/384/512, SHA3-256/384/512)
  • 9 PQC (ML-KEM-512/768/1024, ML-DSA-44/65/87, SLH-DSA-128s/256s, Hybrid)

Self-Test Coverage (POST) — 17 tests (integrity + 16 KATs) ✅

The KATs run against the configured backend. run_post_algorithms takes the CryptoBackend the module will serve requests with, and the AES-GCM/CBC/CTR, SHA-2, ECDSA and RSA KATs dispatch through it. This matters whenever a backend other than the built-in RustCrypto one is selected: FIPS 140-3 requires a known-answer test for each approved algorithm the module implements, and testing a different implementation than the one in service establishes nothing about it. Until this was wired through, an AWS-LC deployment self-tested RustCrypto, so a broken or miscompiled AWS-LC would have passed POST.

HMAC, SHA3, the PQC algorithms, and the RNG/DRBG health tests are not backend-swapped, so those KATs call the shared implementations directly. The AES-GCM fixed-nonce check is likewise on the shared primitive: the backend's GCM entry point generates its own nonce by design, so there is no interface through which to pass a deterministic one. The GCM roundtrip half of that KAT does go through the backend.

RSA KAT and the RUSTSEC-2023-0071 gate. Release builds of the RustCrypto backend refuse RSA private-key operations because the rsa crate is subject to the Marvin timing attack, so RSA signature generation is not a security function those builds provide. The POST's RSA KAT therefore branches on the backend's reported capability (CryptoBackend::supports_rsa_private_ops) rather than on the build-time gate, so a backend that provides RSA — AWS-LC does — gets the full sign/verify roundtrip against its own implementation. Where private-key operations are refused it runs a verify-only known-answer test against a fixed vector, including a negative case so a verifier that accepts everything cannot pass. This keeps a KAT for every approved function the module actually provides. Before this branch existed the KAT signed unconditionally, so the POST — and therefore C_Initialize — failed on every release build.

All P0 POST KATs have been implemented. Security audit (v0.9.1) upgraded AES-CBC/CTR from circular roundtrip tests to genuine known-answer tests with hardcoded expected ciphertexts, and added RSA PKCS#1 v1.5 KAT.

TestAlgorithmVector SourceTypeStatus
Software integrityHMAC-SHA256Module binaryIntegrity check (§9.4)✅ Phase 10
SHA-256 KATSHA-256NIST "abc"Known Answer✅
SHA-384 KATSHA-384NIST "abc"Known Answer✅ Phase 6
SHA-512 KATSHA-512NIST "abc"Known Answer✅
SHA3-256 KATSHA3-256NIST "abc"Known Answer✅ Phase 6
HMAC-SHA256 KATHMAC-SHA256RFC 4231 TC2Known Answer✅
HMAC-SHA384 KATHMAC-SHA384RFC 4231 TC2Known Answer✅ Phase 6
HMAC-SHA512 KATHMAC-SHA512RFC 4231 TC2Known Answer✅ Phase 6
AES-GCM KATAES-256-GCMFixed keyRoundtrip + known-answer decrypt✅
AES-CBC KATAES-256-CBCFixed key/IVKnown Answer (hardcoded ciphertext)✅ v0.9.1 upgraded
AES-CTR KATAES-256-CTRFixed key/IVKnown Answer (hardcoded ciphertext)✅ v0.9.1 upgraded
RSA 2048 KATRSA 2048 PKCS#1 v1.5Generated key, or fixed vectorSign/Verify roundtrip, or Verify-only (positive + negative)✅ v0.9.1 added; capability-aware since the RUSTSEC-2023-0071 gate
ECDSA roundtripECDSA P-256Generated keySign/Verify✅
ML-DSA roundtripML-DSA-44Generated keySign/Verify✅
ML-KEM roundtripML-KEM-768Generated keyEncap/Decap✅ Phase 6
RNG healthOS RNGEntropy + continuousHealth✅ Phase 6 enhanced
HMAC_DRBG KATHMAC_DRBGNIST CAVP vectorKnown Answer✅ Phase 7

Continuous RNG Health Test

Per SP 800-90B, a continuous RNG test runs on every C_GenerateRandom call. Previous 32-byte output is stored; identical consecutive outputs cause CKR_FUNCTION_FAILED.

DRBG Health Test ✅

The HMAC_DRBG includes a continuous health test that compares consecutive outputs (Phase 7). A NIST CAVP known-answer test validates DRBG correctness during POST.

Test Suite Summary

SuiteTestsDescription
crypto::self_test1POST verification (17 tests: integrity + 16 KATs)
crypto::drbg6HMAC_DRBG unit tests
crypto_vectors12Phase 1 KAT tests (AES, RSA, ECDSA, EdDSA)
crypto_vectors_phase256Phase 2 KATs (ECDH, AES modes, RSA-OAEP/PSS, key wrap, digests, PBKDF2)
pkcs11_compliance1Core session state machine lifecycle
pkcs11_compliance_extended1PQC ABI, PIN enforcement, FindObjects, DestroyObject
pqc_phase319ML-KEM, ML-DSA, SLH-DSA, hybrid roundtrips
concurrent_stress5Thread-safety: ML-DSA, ML-KEM, AES, ECDSA, mixed keygen
pkcs11_error_paths50Error handling coverage for all ABI functions
session_state_machine42Session lifecycle and state transition tests
attribute_validation24Template validation and attribute handling
concurrent_session_stress6Multi-threaded session stress tests
zeroization7Key material zeroization verification (ignored by default)
persistence9Persistent storage roundtrip and integrity
multipart_sign_verify12Multi-part C_SignUpdate/Final, C_VerifyUpdate/Final
multipart_encrypt_decrypt10Multi-part C_EncryptUpdate/Final, C_DecryptUpdate/Final
supplementary_functions15C_CopyObject, C_DigestKey tests
drbg5DRBG integration tests (keygen + sign + encrypt roundtrip)
multi_slot8Multi-slot support (configurable slot count)
operation_state8C_GetOperationState/C_SetOperationState save/restore
backup_restore8Encrypted HSM backup/restore roundtrip
pkcs11_conformance46PKCS#11 ABI conformance, security hardening, config validation
Total617+

Fuzzing Infrastructure

TargetCoverageRun Command
fuzz_c_abiC_CreateObject, C_FindObjects, C_GenerateRandom, sessions, digestcargo fuzz run fuzz_c_abi
fuzz_crypto_opsAES-GCM/CBC/CTR roundtrips, digest, random ciphertext/signaturecargo fuzz run fuzz_crypto_ops
fuzz_attributesObjectStore create, read_attribute, template matchingcargo fuzz run fuzz_attributes
fuzz_session_lifecycleSession open/close, login/logout, state transitionscargo fuzz run fuzz_session_lifecycle
fuzz_buffer_overflowBuffer boundary testing for C ABI output parameterscargo fuzz run fuzz_buffer_overflow

A FIPS 140-3 audit requires a CMVP-accredited laboratory. The audit covers:

  1. Security Policy document (see security-policy.md)
  2. Finite State Model of the module (documented in architecture.md)
  3. Physical Security — N/A for software module (Level 1)
  4. Operational Environment — general-purpose OS, no modification required
  5. Cryptographic Key Management — key lifecycle, zeroization
  6. Self-Tests — POST and conditional tests
  7. Design Assurance — source code review, configuration management
  8. Mitigation of Other Attacks — N/A for Level 1

Estimated Scope for Level 1 Certification

PropertyValue
Module typeSoftware
Security level1 (no physical security requirements)
Operational environmentModifiable (general-purpose OS)
Key managementPlaintext keys in process memory (zeroized on free)
Ports and interfacesPKCS#11 C API, gRPC API
Lines of Rust code~10,000 (core library, excluding tests and tools)
Third-party crypto crates15 (see Dependency Audit in fips-gap-analysis.md)