Craton HSM
Key Lifecycle
Key Lifecycle
Craton HSM tracks key material through the lifecycle states defined in NIST SP 800-57 Part 1 §8. Every stored object carries an explicit state, and transitions are driven by either caller action (generation, explicit destruction, compromise flagging) or by the clock reaching the dates on CKA_START_DATE and CKA_END_DATE.
States
| State | Meaning | Operations permitted |
|---|---|---|
| Pre-activation | Key exists in storage but has not yet reached CKA_START_DATE. | None — attempts return CKR_KEY_FUNCTION_NOT_PERMITTED. |
| Active | Key is in its normal usage window. | All operations permitted by the key's PKCS#11 attributes (CKA_SIGN, CKA_DECRYPT, …). |
| Deactivated | Key is past CKA_END_DATE. It may still be used to receive data (verify signatures, decrypt ciphertexts) but must not produce new data. | Verify and decrypt only. Sign, encrypt, derive, wrap are blocked. |
| Compromised | Key has been manually marked as compromised by a Security Officer. | None — the key is retained for audit and forensic purposes but cannot be used. |
| Destroyed | Key material has been zeroised. The object handle is invalid. | None — the object will not appear in C_FindObjects and is not persisted. |
The state is held on the stored object as a KeyLifecycleState enum and is consulted on every cryptographic entry point.
Automated transitions
A lifecycle scan runs on token open and on each C_Initialize that finds an existing store. For each object it computes an effective state from the stored state plus the current time against CKA_START_DATE / CKA_END_DATE:
- Stored
Active+ futureCKA_START_DATE→ effective Pre-activation. - Stored
Active+ pastCKA_END_DATE→ effective Deactivated, persisted. - Stored
Pre-activation+ now ≥CKA_START_DATE→ effective Active, persisted. CompromisedandDestroyedare terminal with respect to time — they never transition automatically.
Persisted transitions are appended to the audit log with the old and new state and the triggering date.
PKCS#11 attribute mapping
Craton HSM exposes the lifecycle through the standard PKCS#11 v3.0 attributes:
| Attribute | Type | Role |
|---|---|---|
CKA_START_DATE | CK_DATE (YYYYMMDD) | Earliest date at which the key is permitted to be used. Objects with a future CKA_START_DATE are in pre-activation. |
CKA_END_DATE | CK_DATE | Date after which the key transitions to deactivated. Optional — a missing CKA_END_DATE means the key never auto-deactivates. |
CKA_DESTROYABLE | CK_BBOOL | When CK_FALSE, C_DestroyObject returns CKR_ACTION_PROHIBITED. Defaults to CK_TRUE. |
CKA_MODIFIABLE | CK_BBOOL | When CK_FALSE, C_SetAttributeValue cannot mutate the object. Dates remain enforceable because the module evaluates them against the stored values. |
CKA_VENDOR_FIPS_APPROVED | CK_BBOOL (0x80000001) | Vendor-defined; indicates the last operation using this key was FIPS-approved. Read-only, updated by the HSM. |
Callers set CKA_START_DATE and CKA_END_DATE at generation time, at import time via C_CreateObject, or later via C_SetAttributeValue provided CKA_MODIFIABLE is CK_TRUE.
Example: scheduling a key for rotation
import PyKCS11
import datetime
lib = PyKCS11.PyKCS11Lib()
lib.load("/opt/craton_hsm/libcraton_hsm.so")
session = lib.openSession(lib.getSlotList()[0], PyKCS11.CKF_RW_SESSION | PyKCS11.CKF_SERIAL_SESSION)
session.login("87654321")
today = datetime.date.today()
expiry = today + datetime.timedelta(days=365)
template = [
(PyKCS11.CKA_CLASS, PyKCS11.CKO_PRIVATE_KEY),
(PyKCS11.CKA_KEY_TYPE, PyKCS11.CKK_RSA),
(PyKCS11.CKA_LABEL, "signing-2026"),
(PyKCS11.CKA_SIGN, True),
(PyKCS11.CKA_START_DATE, today.strftime("%Y%m%d")),
(PyKCS11.CKA_END_DATE, expiry.strftime("%Y%m%d")),
]
Compromise and destruction
- Compromise is recorded by a Security Officer session setting a vendor-defined attribute (covered in Operations: key management). Once set, the state is persisted and the key cannot return to
Active. - Destruction is triggered by
C_DestroyObject. The key material is zeroised in memory (viaZeroizeOnDrop), removed from persistent storage, and the destruction is logged. Objects withCKA_DESTROYABLE = CK_FALSEcannot be destroyed without first clearing that attribute (ifCKA_MODIFIABLE = CK_TRUE) or at all if both are false.
Enforcement at operation time
Every cryptographic entry point (C_SignInit, C_EncryptInit, C_DecryptInit, C_VerifyInit, C_DeriveKey, C_WrapKey, C_UnwrapKey) evaluates the effective lifecycle state for the referenced key before doing anything else:
- Pre-activation →
CKR_KEY_FUNCTION_NOT_PERMITTED - Deactivated, and the operation is sign / encrypt / derive / wrap →
CKR_KEY_FUNCTION_NOT_PERMITTED - Deactivated, and the operation is verify / decrypt → permitted
- Compromised →
CKR_KEY_FUNCTION_NOT_PERMITTED - Destroyed →
CKR_OBJECT_HANDLE_INVALID(the handle was freed)
Auditing
Every state transition produces an audit entry with the object handle, old state, new state, triggering cause (date, action, or compromise marking), and the wall-clock time. Entries are chained by SHA-256 so tampering with history is detectable. See Audit.