Craton HSM

Self-Tests

Self-Tests

Craton HSM runs a set of self-tests at module load time and further conditional self-tests at runtime. The tests follow FIPS 140-3 §9 (self-tests) and cover software integrity, cryptographic correctness, DRBG health, and per-key-pair consistency. Any failure transitions the module into an error state that cannot be cleared without a process restart.

Power-On Self-Tests

POST runs during C_Initialize, before any cryptographic service becomes available. The tests execute in a fixed order. Failure of any test sets an AtomicBool POST_FAILED flag, causes C_Initialize to return CKR_GENERAL_ERROR, and makes every subsequent PKCS#11 call return CKR_GENERAL_ERROR until the process restarts.

The full POST suite is 17 tests: one software integrity check and 16 known-answer tests.

Software Integrity Test (§9.4)

PropertyValue
AlgorithmHMAC-SHA256
Key32-byte compile-time constant embedded in the binary (per FIPS IG 9.7)
InputFull contents of the loaded module file
Expected digest64 hex characters in a .hmac sidecar alongside the library
OrderFirst test — runs before any KAT

Behaviour when the sidecar is missing depends on the build: under the default features the check logs a warning and passes (development mode); under the FIPS build feature the sidecar is mandatory and its absence fails POST. A mismatched HMAC always fails POST. The module path is discovered with dladdr(3) on Unix and GetModuleHandleExW / GetModuleFileNameW on Windows.

Known-Answer Tests

#AlgorithmVector sourceNotes
1SHA-256NIST FIPS 180-4, input "abc"
2SHA-384NIST FIPS 180-4, input "abc"Checks prefix of expected digest
3SHA-512NIST FIPS 180-4, input "abc"Checks prefix of expected digest
4SHA3-256NIST FIPS 202, input "abc"
5HMAC-SHA256RFC 4231 Test Case 2
6HMAC-SHA384RFC 4231 Test Case 2Checks prefix of expected MAC
7HMAC-SHA512RFC 4231 Test Case 2Checks prefix of expected MAC
8AES-256-GCMFixed key, known-answer decrypt
9AES-256-CBCFixed key and IV, hardcoded expected ciphertextUpgraded from round-trip to genuine KAT in v0.9.1
10AES-256-CTRFixed key and IV, hardcoded expected ciphertextUpgraded from round-trip to genuine KAT in v0.9.1
11RSA-2048 PKCS#1 v1.5Generated key pair, sign/verify round-tripAdded in v0.9.1
12ECDSA P-256Generated key pair, sign/verify round-trip
13ML-DSA-44Generated key pair, sign/verify round-tripNot approved, runs for correctness in non-FIPS mode
14ML-KEM-768Generated key pair, encap/decap round-tripNot approved, runs for correctness in non-FIPS mode
15OS RNG healthGenerate 256 bytes, check not all zero / not all identical; generate a second 256 bytes and compare against the firstPer SP 800-90B §4.3
16HMAC_DRBG healthInstantiate DRBG, generate two 32-byte outputs, compare
17HMAC_DRBG KATNIST CAVP vectorValidates DRBG correctness with a known input/output pair

Non-approved algorithm KATs (ML-DSA, ML-KEM) run in both modes so that any build-time breakage is caught early. In FIPS mode those mechanisms are still rejected at the enforcement layer; a passing KAT does not make the mechanism approved.

Conditional Self-Tests

Pairwise Consistency Tests (§9.6)

A pairwise consistency test runs immediately after every asymmetric key pair generation. A signature algorithm signs the fixed test string "FIPS 140-3 pairwise consistency test" with the generated private key and verifies with the generated public key; KEM algorithms perform an encap/decap round-trip.

Key typeTriggering mechanismTest
RSACKM_RSA_PKCS_KEY_PAIR_GENSHA-256 RSA PKCS#1 v1.5 sign/verify
ECDSA P-256CKM_EC_KEY_PAIR_GEN with P-256ECDSA sign/verify
ECDSA P-384CKM_EC_KEY_PAIR_GEN with P-384ECDSA sign/verify
Ed25519CKM_EDDSAEd25519 sign/verify
ML-DSACKM_ML_DSA_44 / CKM_ML_DSA_65 / CKM_ML_DSA_87ML-DSA sign/verify
SLH-DSACKM_SLH_DSA_SHA2_128S / CKM_SLH_DSA_SHA2_256SSLH-DSA sign/verify
ML-KEMCKM_ML_KEM_512 / CKM_ML_KEM_768 / CKM_ML_KEM_1024ML-KEM encap/decap

A failed pairwise test fails the enclosing C_GenerateKeyPair call and puts the module in error state. The generated key material is zeroized before the error is returned.

Continuous RNG Tests

Two continuous tests run on every random number generator call:

  • OS entropy sourceC_GenerateRandom stores the last 32 bytes of output in a Mutex<[u8; 32]> and compares each new block against the previous one. Identical consecutive output returns CKR_FUNCTION_FAILED and sets POST_FAILED.
  • HMAC_DRBG — the DRBG keeps a last_output field and compares consecutive generate calls. A match aborts the operation, zeroizes the DRBG state, and raises the error state.

Pairwise Imports

C_UnwrapKey and C_CreateObject do not run pairwise consistency on imported key pairs because the caller supplies key material rather than generating it. Imported public keys are validated for structural correctness (curve membership, RSA modulus parity) but do not re-run the KAT suite.

Failure Behaviour

All self-test failures converge on a single error state:

  1. POST_FAILED: AtomicBool is set to true.
  2. get_hsm() checks the flag on every PKCS#11 call and returns CKR_GENERAL_ERROR unconditionally.
  3. No cryptographic service can run until the process restarts.
  4. On the next C_Initialize, POST_FAILED is cleared and POST runs again before any service becomes available.

The module does not attempt automatic recovery. A POST failure is a signal that either the binary is corrupt, the environment is hostile (stuck RNG), or a primitive has a real defect — none of those are safe to paper over at runtime.

Operational Expectations

  • POST runs in under 100 ms on modern hardware, dominated by the RSA key generation for test 11.
  • Conditional tests add a small constant overhead per key pair generation. Applications that generate keys in tight loops should prefer a key ceremony tool and persist the result, rather than regenerate per request.
  • POST does not depend on token state or user login. It runs even for anonymous callers doing only digest or random operations.

Further Reading

  • fips-mode — operational configuration that activates strict approved-mode enforcement
  • gap-analysis — which KATs are approved vs. informational
  • ../security/model — broader security posture