Craton HSM
Migration Guide
Migrating from 0.9.x to 0.10.0
Breaking Changes Summary
| Area | Change | Impact / Migration Action |
|---|---|---|
| Rust API | AuditEvent added format_version: u32 | Update struct literals to include format_version: AUDIT_LOG_FORMAT_VERSION. |
| Rust API | aes_ctr_crypt feature-gated | Gated behind legacy-insecure-ctr. Migrate to aes_ctr_encrypt/aes_ctr_decrypt. |
| Daemon | mTLS required for non-loopback binds | Provide tls_client_ca or explicitly set allow_unauthenticated_tls = true. |
| Storage | Bounded binary codec (RHSO\x01) | Secret object store moved from JSON to binary serialization. |
| Backup | Backup format upgraded to v2 | BACKUP_VERSION = 2 uses binary payloads. Create fresh backups post-upgrade. |
| Audit Log | Canonical binary chain hashing (format_version: 1) | Mixed v0/v1 logs verify on 0.10.0; downgrading to 0.9.x requires log rotation. |
| PKCS#11 | CKM_RSA_PKCS unadvertised | Use prefixed mechanisms such as CKM_SHA256_RSA_PKCS. |
| Crypto | RustCrypto RSA private operations refused in release | Build with --no-default-features --features awslc-backend for RSA private ops. |
Audit log format
New audit entries are written with format_version: 1, a compact binary payload
encoding for the hash chain. The on-disk NDJSON line format is unchanged, so SIEM
and log-shipping integrations are unaffected.
Existing logs keep verifying: the verifier dispatches on each entry's own
format_version, and a file that mixes version 0 and version 1 entries — what an
in-place upgrade produces — verifies end to end.
Downgrading does not work. Older builds verify every entry as version 0, so they will read a version 1 entry, compute the wrong hash, and report the chain as tampered. Rotate the audit log before downgrading and archive the version 1 file.
Daemon mTLS enforcement
When running craton-hsm-daemon with TLS on non-loopback TCP interfaces (e.g. 0.0.0.0:5696),
the daemon now requires tls_client_ca for mutual authentication. If client verification
is not configured, the daemon will terminate at startup.
To migrate:
- Configure
tls_client_cain the[daemon]section with your client CA certificate. - Or, if protected by an external network security layer, explicitly set
allow_unauthenticated_tls = true.
RSA availability
Release builds of the default RustCrypto backend now refuse RSA private-key
operations with CKR_MECHANISM_INVALID rather than failing them mid-operation.
Previously an RSA C_GenerateKeyPair in a release build put the module into its
error state, disabling every algorithm. If your application uses RSA signing,
decryption, or key generation, build with --no-default-features --features awslc-backend. See
troubleshooting.md.
Library API (Rust consumers only)
AuditEvent gained a public format_version: u32 field. Code that constructs an
AuditEvent with a struct literal must add it; set it to
AUDIT_LOG_FORMAT_VERSION for new events. PKCS#11 ABI consumers are unaffected.
The legacy aes_ctr_crypt function is now gated behind the legacy-insecure-ctr feature
flag. Update code to use aes_ctr_encrypt / aes_ctr_decrypt.
Migrating from 0.9.0 to 0.9.1
v0.9.1 is a security hardening release. It is fully backward-compatible with v0.9.0 at the PKCS#11 ABI level. No application code changes are required.
Breaking Changes
None. All PKCS#11 function signatures and behavior are unchanged.
Security Fixes Applied
These fixes affect internal behavior but are transparent to consumers:
| Fix | Impact | Action Required |
|---|---|---|
| DRBG bypass eliminated | All key generation now routes through HMAC_DRBG | None (automatic) |
| Per-key GCM nonce counters | Prevents nonce reuse across AES-GCM operations | None (automatic) |
| AES-CBC/CTR self-tests upgraded | POST now uses genuine KATs with hardcoded expected ciphertexts | None (automatic) |
| RSA PKCS#1 v1.5 KAT added | POST now covers RSA signing | None (automatic) |
| Config path validation hardened | Rejects .. traversal, UNC paths, symlinks, sensitive directories | Review config file paths |
| PBKDF2 iteration floor raised | Minimum now 100,000 (was unchecked) | Update config if pbkdf2_iterations < 100000 |
Configuration Changes
Potentially breaking if your config uses values now rejected:
pbkdf2_iterations: Must be >= 100,000. If your config had a lower value, increase it.storage_path: Paths containing.., symlinks, or pointing to sensitive directories (.git,.ssh,.aws,.gnupg) are now rejected. Use simple relative paths.- File permissions: Config files must be owner-readable only (0o600 on Unix; no Everyone/Users write on Windows).
Recommended Steps
- Review your
craton_hsm.tomlfor paths and iteration counts - Rebuild from source:
cargo build --release - Run the test suite:
cargo test -- --test-threads=1 - Verify POST passes on startup (check logs for self-test results)
Migrating to 1.0.0 (Future)
The following changes are planned for the 1.0 release:
Expected Breaking Changes
-
PQC crate stabilization: The
ml-kem,ml-dsa, andslh-dsadependencies will be updated from release candidates to stable versions. This may change PQC key serialization formats. Keys generated with RC versions should be re-generated. -
rand_core unification: The dual
rand_core0.6 / 0.10 dependency will be resolved. This is an internal change but may affect customCryptoBackendimplementations. -
MSRV bump: The minimum supported Rust version may increase from 1.75 to align with dependency requirements.
Migration Checklist
- Export any PQC keys via
C_WrapKeyor backup before upgrading - Re-generate PQC keys after upgrading (format may change)
- Review
CryptoBackendtrait if you have a custom implementation - Update Rust toolchain to the new MSRV
- Run full test suite after upgrade
Backup Before Upgrading
Always create an encrypted backup before any major version upgrade:
# Via craton-hsm-admin CLI
craton-hsm-admin backup --pin <SO_PIN> --output backup-pre-1.0.enc
# Restore if needed
craton-hsm-admin restore --pin <SO_PIN> --input backup-pre-1.0.enc
See Operator Runbook for detailed backup/restore procedures.