Craton HSM
AWS-LC Backend (FIPS)
AWS-LC Backend (FIPS)
The craton-hsm-awslc crate implements the CryptoBackend trait on top of
aws-lc-rs, the Rust binding to AWS-LC.
When built with the fips feature, every classical cryptographic operation
runs inside the FIPS 140-3-validated AWS-LC module. This is the intended
software FIPS boundary for Craton HSM.
- Crate:
craton-hsm-awslc - Backend type:
AwsLcBackend - License: BSL 1.1
- MSRV: Rust 1.75
- Status: production-ready
Build
FIPS-validated primitives require the fips feature, which in turn builds
the AWS-LC FIPS module from source. The AWS-LC build script shells out to
Go, so a Go 1.21+ toolchain must be on PATH at build time. Go is not a
runtime dependency.
cargo build -p craton-hsm-awslc --features fips
Non-FIPS builds omit the feature:
cargo build -p craton-hsm-awslc
The produced binary has no Go runtime dependency. aws-lc-rs is pinned at
=1.16.2 in the workspace lockfile.
Feature Flags
| Flag | Default | Effect |
|---|---|---|
fips | off | Build the FIPS-validated AWS-LC module. Requires Go 1.21+ on PATH. |
Algorithms
All of the following run inside the FIPS boundary when fips is enabled:
- AES in GCM, CBC, CTR, and key-wrap modes (128 / 192 / 256-bit keys).
- RSA PKCS#1 v1.5, RSA-PSS, and RSA-OAEP with a 2048-bit minimum modulus enforced on both sign and verify.
- ECDSA on P-256 and P-384.
- Ed25519 sign and verify.
- ECDH on P-256 and P-384.
- SHA-2 (SHA-256, SHA-384, SHA-512).
- HKDF key derivation.
- AES key wrap / unwrap (AES-KW).
FIPS Mode Interaction
Two constructors select the operating mode:
use craton_hsm_awslc::AwsLcBackend;
use craton_hsm::crypto::backend::CryptoBackend;
// FIPS mode: reject any operation outside the FIPS boundary.
let backend = AwsLcBackend::new_fips();
// Non-FIPS mode: use all primitives, including prehashed signing.
let backend = AwsLcBackend::new();
let key = backend.generate_aes_key(32, true)?;
let ct = backend.aes_256_gcm_encrypt(key.as_ref(), b"plaintext")?;
In FIPS mode, the backend is fail-closed: every operation that cannot
be served by an AWS-LC FIPS primitive returns HsmError::MechanismInvalid
rather than falling back to software.
Unsupported Mechanisms
Two classes of operation are not available when fips_mode = true:
- SHA-1. Rejected everywhere. AES-128 key generation remains permitted because AES-128 / 192 / 256 are all FIPS-approved, but AES-256 is recommended for new keys.
- Prehashed signing.
aws-lc-rsdoes not expose prehashed signature APIs, so the eight*_sign_prehashedand*_verify_prehashedmethods fall back to RustCrypto (rsa,p256,p384) for the signature math. That path is not FIPS-validated. In FIPS mode it is rejected withMechanismInvalid; in non-FIPS mode it works.
AES-GCM Nonce Budget
The backend enforces the NIST SP 800-38D per-key 2^32 encryption limit.
A per-key counter fingerprinted with SHA-256(key) tracks encryption
operations; a key that exhausts its budget is permanently poisoned for
the remainder of the process and cannot be re-armed.
The in-memory counter is sufficient for ephemeral keys. For long-lived keys that outlive the process, use the file-backed journal:
use craton_hsm_awslc::AwsLcBackend;
let backend = AwsLcBackend::new_fips_with_persistent_gcm_counter(
"/var/lib/craton-hsm/gcm-counter.journal",
)?;
# Ok::<(), craton_hsm::error::HsmError>(())
Journal behaviour:
- Loaded on startup and verified with an HMAC-SHA256 integrity footer.
- Counters are flushed to disk with
fsyncafter every 1024-count advance, on first-sight of a key, and on poison. Worst-case lost count onSIGKILLis bounded by the 1024-count batch. - An integrity-footer mismatch fails closed: every previously recorded fingerprint is treated as poisoned for this process.
- A missing footer (e.g. a crash during write) triggers a warning; recorded values are honoured and the next flush writes a fresh footer.
- The journal HMAC key is derived from the file path. This catches accidental truncation or cross-path swaps; it is not an attacker defence — an attacker with filesystem write access already has the keys.
Only the first new_*_with_persistent_gcm_counter call in a process
installs the counter. To switch paths, restart the process.
Error Reporting
Failures surface through craton_hsm::error::HsmError.
MechanismInvalid specifically indicates that the mechanism is
intentionally unavailable in the current mode (FIPS mode + prehashed
signing, FIPS mode + SHA-1, RSA under the 2048-bit minimum, etc.).
Safety
The crate contains no direct unsafe blocks. All FFI is contained in
aws-lc-rs upstream. Private-key material is wrapped in Zeroizing
buffers and wiped on drop.
Related Documents
- FIPS certification plan — CMVP boundary, validation process, and artifact packaging.
- Reproducible builds and CMVP artifacts — tooling for preparing a validation submission.
- Compatibility matrix — tested Go / Rust / OS combinations.