Craton HSM

Troubleshooting

Common PKCS#11 Error Codes

When a C_* function fails, it returns a CK_RV error code. Below are the most common ones, their causes, and fixes.

Initialization Errors

CK_RVConstantCauseFix
257CKR_CRYPTOKI_NOT_INITIALIZEDCalled a function before C_InitializeCall C_Initialize(NULL) first
258CKR_CRYPTOKI_ALREADY_INITIALIZEDC_Initialize called twiceCall C_Finalize before re-initializing
5CKR_GENERAL_ERRORPower-on self-test (POST) failedCheck binary integrity; the library may be corrupted. Rebuild from source.

Session Errors

CK_RVConstantCauseFix
3CKR_SLOT_ID_INVALIDSlot ID does not existUse C_GetSlotList to enumerate valid slot IDs
11CKR_SESSION_HANDLE_INVALIDSession handle is stale or invalidRe-open the session with C_OpenSession
14CKR_SESSION_COUNTMaximum session limit reachedClose unused sessions or increase max_sessions in config
15CKR_SESSION_READ_ONLYAttempted write operation on R/O sessionOpen session with CKF_RW_SESSION flag

Authentication Errors

CK_RVConstantCauseFix
160CKR_PIN_INCORRECTWrong PIN providedVerify PIN; note exponential backoff after failed attempts
161CKR_PIN_INVALIDPIN does not meet complexity requirementsPIN must be 4-256 bytes, >=3 distinct bytes, >=2 character classes
162CKR_PIN_LEN_RANGEPIN length outside allowed boundsCheck min_pin_length / max_pin_length in security config
163CKR_PIN_LOCKEDToo many failed login attemptsRe-initialize token via C_InitToken (SO) or wait for lockout reset
256CKR_USER_NOT_LOGGED_INPrivate object access without loginCall C_Login with the User PIN first
1CKR_FUNCTION_FAILEDPIN rate-limitedWait for the backoff period to expire (100ms base, doubles per failure, max 5s)

Cryptographic Errors

CK_RVConstantCauseFix
112CKR_MECHANISM_INVALIDUnsupported or disabled mechanismCheck C_GetMechanismList; verify algorithm policy in config
113CKR_MECHANISM_PARAM_INVALIDWrong or missing mechanism parametersVerify parameter struct (e.g., CK_RSA_PKCS_PSS_PARAMS)
98CKR_KEY_HANDLE_INVALIDKey handle not foundRe-query with C_FindObjects
99CKR_KEY_TYPE_INCONSISTENTKey type doesn't match mechanismRSA key for RSA mechanisms, EC key for ECDSA, etc.
101CKR_KEY_FUNCTION_NOT_PERMITTEDKey lacks permission for this operationSet CKA_SIGN/CKA_ENCRYPT/etc. when creating the key
32CKR_DATA_LEN_RANGEInput data exceeds maximum (64 MiB)Reduce data size or use multi-part operations
64CKR_SIGNATURE_INVALIDSignature verification failedCheck key, data, and mechanism match the signing operation
304CKR_OPERATION_NOT_INITIALIZEDNo active operation for Update/FinalCall the corresponding *Init function first
288CKR_OPERATION_ACTIVECalled *Init while another operation is activeCall *Final to complete or abandon the active operation
80CKR_BUFFER_TOO_SMALLOutput buffer is too smallCall with NULL output buffer first to query required size

Key Lifecycle Errors

CK_RVConstantCauseFix
101CKR_KEY_FUNCTION_NOT_PERMITTEDKey is deactivated or compromisedCheck CKA_START_DATE / CKA_END_DATE; generate a new key if expired
82CKR_ATTRIBUTE_READ_ONLYAttempted to modify a read-only attributeOnly modifiable attributes (CKA_LABEL, CKA_ID, etc.) can be changed

Build Issues

cargo build fails with missing protoc

error: failed to run custom build command for `craton-hsm-daemon`

Fix: Install Protocol Buffers compiler:

# Ubuntu/Debian
sudo apt install protobuf-compiler

# macOS
brew install protobuf

# Windows (via chocolatey)
choco install protoc

cargo test fails with linker errors on Windows

LINK : fatal error LNK1181: cannot open input file 'craton_hsm.lib'

Fix: Ensure you're building with the MSVC toolchain:

rustup default stable-x86_64-pc-windows-msvc

cargo test fails with craton_hsm-awslc not found

error: failed to load manifest for dependency `craton_hsm-awslc`

Fix: The FIPS backend is in a separate private repository. For open-source builds, this dev-dependency is commented out by default. If you need the FIPS backend, clone craton_hsm-enterprise alongside this repo and uncomment the dependency in Cargo.toml.

Tests must run single-threaded

PKCS#11 uses global state (C_Initialize/C_Finalize affect the entire process). Tests must run with:

cargo test -- --test-threads=1

Multi-threaded test execution will cause intermittent failures due to shared global HSM state.

Runtime Issues

POST failure on startup (CKR_GENERAL_ERROR from every function)

The Power-On Self-Test (POST) runs during C_Initialize. If any self-test fails, the library enters a degraded state where all subsequent C_* calls return CKR_GENERAL_ERROR.

Common causes:

  • Binary was modified after build (integrity check failure)
  • Corrupted download or incomplete deployment

Fix: Rebuild from source or re-download the binary. Verify with SHA-256 checksum.

RSA operations return CKR_MECHANISM_INVALID

A release build of the default (RustCrypto) backend provides no RSA private-key capability. C_Sign, C_Decrypt, and C_GenerateKeyPair with CKM_RSA_PKCS_KEY_PAIR_GEN are refused with CKR_MECHANISM_INVALID, and the log records:

WARN RSA key-pair generation refused: this build provides no RSA private-key
     capability (RUSTSEC-2023-0071). Rebuild with the aws-lc-rs backend to use RSA.

This is deliberate, not a fault. The rsa crate is subject to the Marvin timing attack (RUSTSEC-2023-0071), which is exploitable exactly where an HSM lives — a service performing private-key operations on behalf of remote callers. Release builds therefore fail closed.

RSA verification and every other algorithm (EC, Ed25519, AES, SHA-2/3, PQC) are unaffected.

To use RSA private-key operations, build with the hardened backend:

cargo build --release --no-default-features --features awslc-backend

Do not enable insecure-rustcrypto-rsa-private-ops in production; it exists so development builds and interoperability tests can exercise the RustCrypto code paths, and it reinstates the vulnerable implementation.

Note that refusing the mechanism leaves the module fully operational. If an unavailable RSA mechanism ever puts the module into an error state — every subsequent call, including AES and EC, returning CKR_FUNCTION_FAILED — that is a bug; see test_unavailable_rsa_keygen_does_not_enter_error_state.

Audit log permission denied

Failed to open audit log: permission denied

Fix: The audit log file is restricted to owner-only (0o600 on Unix, owner-only ACL on Windows). Ensure the process user owns the file:

# Unix
chown $(whoami) craton_hsm_audit.jsonl
chmod 600 craton_hsm_audit.jsonl

# Or let Craton HSM create the file fresh (delete and restart)

Token persistence not working (objects lost on restart)

Check:

  1. storage_path is set in [token] config section
  2. The path is writable and not a symlink
  3. No other process holds an exclusive lock on the .redb file
[token]
storage_path = "craton_hsm_store"

Memory locking warnings

WARN: mlock failed: Operation not permitted

Cause: The process lacks permission to lock memory pages.

Fix (Linux):

# Option 1: Set capability
sudo setcap cap_ipc_lock=ep /path/to/your_binary

# Option 2: Increase limits
echo "* soft memlock unlimited" | sudo tee -a /etc/security/limits.conf

Fix (Windows): Grant the "Lock pages in memory" user right via Local Security Policy (secpol.msc > Local Policies > User Rights Assignment).

This is a non-fatal warning. The HSM continues to operate but key material may be paged to swap.

Fork detection errors (Unix)

After fork(), the child process detects a PID mismatch and returns CKR_CRYPTOKI_NOT_INITIALIZED.

Fix: Call C_Initialize in the child process after fork. See Fork Safety for details and deployment patterns.

Database lock contention

error: Failed to acquire exclusive lock on store file

Cause: Another process already has the store file open.

Fix: Only one process can access a persistent store at a time. Use the gRPC daemon (craton-hsm-daemon) for multi-process access. See Fork Safety for deployment patterns.

Configuration Issues

Config file rejected: permission too broad

Configuration error: file has group/world-writable permissions

Fix (Unix):

chmod 600 craton_hsm.toml

Fix (Windows): Remove Everyone and Users group write permissions via file properties or:

icacls craton_hsm.toml /inheritance:r /grant:r "%USERNAME%:F"

Config file rejected: path traversal

Configuration error: path contains '..' component

Fix: Use relative paths without .. traversal. Absolute paths and UNC paths (\\server\share) are also rejected. Symlinks in the path are rejected.

PBKDF2 iterations out of range

Configuration error: pbkdf2_iterations (50000) is below the minimum of 100000

Fix: Set pbkdf2_iterations to at least 100,000 (recommended: 600,000). Maximum: 10,000,000.

Getting Help