Why we rewrote SoftHSM in Rust
Buffer overflows in attribute parsing, use-after-free in session lifecycle, double-free in error paths. The case for a PKCS#11 v3.0 HSM with zero unsafe in crypto paths.
por Victor Bobrovskiy
SoftHSMv2 is the de-facto open-source software HSM. It is written in C++. It has also accumulated a decade of CVEs whose root cause is the choice of language — buffer overflows in attribute parsing, use-after-free in session lifecycle, double-free in error paths, data races in concurrent access. These are not bugs that get fixed once. They are a tax you pay forever on the implementation language.
Craton HSM is our answer: a PKCS#11 v3.0-compliant software HSM written in pure Rust, drop-in compatible with SoftHSMv2 as a dynamically loadable shared library. Same 70+ C ABI exports. Same deployment story. Different guarantees.
What we keep
PKCS#11 v3.0 surface. Any application that speaks PKCS#11 — OpenSSL engines, Java providers, Firefox NSS, pkcs11-tool — works without modification.
Deployment shapes. In-process shared library (.so / .dll / .dylib), gRPC daemon with mutual TLS, or Kubernetes sidecar behind a distroless image.
Audit transparency. Tamper-evident chained SHA-256 audit log, algorithm indicator in every entry per FIPS IG 2.4.C.
What changes
Zero unsafe code in cryptographic paths. The FFI boundary is audited and minimal; everything above it is safe Rust.
ZeroizeOnDrop on every key. Key bytes never appear in logs, debug output, or error messages. Constant-time PIN and HMAC comparison.
Post-quantum by default. ML-DSA-44/65/87, ML-KEM-512/768/1024, SLH-DSA, and hybrid ML-DSA-65 + ECDSA composite signatures — 41 mechanisms including 9 PQC where SoftHSMv2 has zero.
FIPS 140-3 Level 1 readiness. 17 power-on self-tests on every C_Initialize: software integrity (HMAC-SHA256 of module binary), 16 known-answer tests covering SHA-2/3, HMAC, AES-GCM/CBC/CTR, ECDSA, RSA-2048, ML-DSA-44, ML-KEM-768, and the DRBG, plus a continuous RNG health test.
Pluggable backends. RustCrypto (pure Rust) by default. aws-lc-rs (FIPS-validated) available through craton-hsm-enterprise — same API, different hardening posture.
The numbers
On a mid-tier server (Xeon, no AES-NI disabled):
- Ed25519 sign: 43.79 μs
- AES-256-GCM 4 KB: 3.633 μs
- RSA-2048 sign: 1.927 ms
- ML-DSA-44 sign: 711.9 μs
- ML-KEM-768 encapsulate: 74.46 μs
With the aws-lc-rs backend: RSA-2048 verify runs 8.3× faster, ECDSA verify 4.5× faster. Same API, different engine, a --features aws-lc away.
Where this goes
The regulatory environment is converging: White House ONCD, CISA, the EU Cyber Resilience Act, UN R155, FIPS 140-3 itself — all pushing toward memory-safe implementations of cryptographic primitives. This is not a technology bet. It is the direction of travel.
If you are running SoftHSMv2 in production and would rather not carry the C++ CVE stream into the next decade, the migration is mechanically a library swap — and the audit conversation is much easier when you can point at a language-level guarantee instead of a patching cadence.
Read the docs: /docs/craton-hsm. Source: github.com/craton-co/craton-hsm-core.
- rust
- cryptography
- hsm
- pkcs11
- fips-140-3