Craton HSM
Deterministic Random Bit Generator
Deterministic Random Bit Generator
All randomness consumed by Craton HSM — key generation, nonce generation, IV generation, ECDSA per-signature randomness, padding in PSS and OAEP, PQC key material, and callers of C_GenerateRandom — flows through a single HMAC_DRBG instance constructed per NIST SP 800-90A Rev.1. The operating-system RNG (OsRng) is used only as the entropy source for the DRBG and for the continuous health test; it is never returned to callers directly.
Construction
| Property | Value |
|---|---|
| Algorithm | HMAC_DRBG, SP 800-90A §10.1.2 |
| Underlying function | HMAC-SHA256 |
| Security strength | 256 bits |
| Internal state | K (32 bytes), V (32 bytes), reseed counter, last-output block |
| Reseed interval | 2⁴⁸ requests (SP 800-90A Table 2) |
| Prediction resistance | Enabled — reseeds from OS entropy on every generate() call |
| State zeroization | K and V zeroed on drop via ZeroizeOnDrop |
HMAC-SHA384 and HMAC-SHA512 variants are reserved for a future configuration option but are not currently selectable.
Instantiation
At load time the DRBG is instantiated with 48 bytes of seed material (32 bytes entropy plus a 16-byte nonce) drawn from OsRng. The SP 800-90A Update(seed_material) derivation function initialises K and V from this seed.
Reseeding
Craton HSM operates in prediction-resistance mode: before each generate() call, the DRBG draws fresh entropy from OsRng and applies Update(additional_input). This guarantees forward secrecy — an attacker who recovers the internal state learns nothing about prior output or about output produced after the next generate call.
Explicit reseeding is also available through C_SeedRandom, which feeds caller-supplied entropy into Update() as additional input. Caller entropy never replaces OS entropy; it is mixed in.
Continuous health tests
Two tests run alongside the DRBG.
- Continuous RNG health test (SP 800-90B §4.9). The last 32 bytes of
OsRngoutput are stored in aMutex<[u8; 32]>; each new OS entropy draw is compared against the previous. A match failsC_GenerateRandomwithCKR_FUNCTION_FAILED. - Continuous DRBG self-test. The last output block of the DRBG is stored and compared against the next output. A repeat triggers a health-test failure and transitions the module to the error state.
Known-answer test
During Power-On Self-Test, a NIST CAVP vector is passed to a deterministically seeded DRBG instance and the output is compared byte-for-byte to the expected value. Failure prevents the module from becoming operational; see Self-tests.
All key generation routes through DRBG
A DrbgRng adapter implements the rand_core::CryptoRng and RngCore traits against the shared HmacDrbg. All key generation paths — RSA, ECDSA P-256 / P-384, Ed25519, AES, and the PQC crates — accept an RNG by reference, and the adapter is the only RNG passed into those paths. Prior to v0.9.1, RSA / EC / Ed25519 generation called OsRng directly; this has been closed as part of the security audit (see FIPS gap analysis).
The PQC crates bridge between rand_core 0.6 (used by the classical RustCrypto crates) and rand_core 0.10 (used by ml-kem 0.3.0-rc and peers). The DrbgRng adapter implements both traits so the same DRBG state backs both halves of the crypto stack.
Entropy source
Entropy is drawn from the OS CSPRNG:
| Platform | Source |
|---|---|
| Linux | getrandom(2) |
| macOS | CCRandomGenerateBytes via getentropy |
| Windows | BCryptGenRandom via windows-sys |
Craton HSM does not qualify its own entropy source; FIPS Level 2+ deployments that require SP 800-90B entropy-source qualification should consult FIPS gap analysis, item P2-13.
API exposure
| PKCS#11 function | DRBG behaviour |
|---|---|
C_GenerateRandom | Returns the requested number of DRBG output bytes |
C_SeedRandom | Mixes caller-supplied bytes into the DRBG via Update |
| (internal) key generation | Uses the shared DrbgRng adapter |
C_GenerateRandom returns CKR_FUNCTION_FAILED if either continuous health test trips, and CKR_DEVICE_ERROR if the module is in POST-failed state.