Craton HSM

Quickstart

Quickstart

A five-minute path from a built library to a working signature. The steps below assume you have libcraton_hsm.so (or the .dylib / .dll equivalent) and the craton-admin CLI on PATH. If not, follow Installation first.

The quickstart uses pkcs11-tool from OpenSC as a generic PKCS#11 client. Install it with apt install opensc, brew install opensc, or the OpenSC Windows installer.

Throughout this page, set a shell variable so commands stay readable:

export MODULE=/usr/local/lib/libcraton_hsm.so

1. Initialise the token

A freshly built module exposes one empty slot. Initialise it with a Security Officer (SO) PIN:

craton-admin token init --label "Quickstart HSM"

craton-admin prompts for the SO PIN interactively and writes the encrypted token state to the storage_path configured in craton_hsm.toml (default: ./craton_hsm_store/). The SO PIN is the only credential that can re-initialise the token or unblock the user PIN; treat it like a root password.

Equivalent low-level call via pkcs11-tool:

pkcs11-tool --module $MODULE --init-token \
    --label "Quickstart HSM" --so-pin 12345678

2. Set the user PIN

Cryptographic operations run under the user role. The SO sets the initial user PIN; the user can change it later with craton-admin pin change.

pkcs11-tool --module $MODULE --init-pin \
    --so-pin 12345678 --pin 87654321

PIN policy defaults (see the Configuration reference):

  • Minimum length: 8 bytes.
  • Maximum length: 64 bytes.
  • Lockout after 10 consecutive failures.
  • Stored as PBKDF2-HMAC-SHA256 with 600 000 iterations.

3. Load the library and list slots

Any PKCS#11 consumer can now open the module. Confirm with:

pkcs11-tool --module $MODULE --list-slots

Expected output shape:

Available slots:
Slot 0 (0x0): Craton HSM Slot 0
  token label        : Quickstart HSM
  token manufacturer : Craton Software
  token model        : craton-hsm
  token flags        : login required, rng, token initialized, PIN initialized
  hardware version   : 0.9
  firmware version   : 0.9
  serial num         : 0000000000000001
  pin min/max        : 8/64

The PIN initialized and token initialized flags must both be present before any keygen or signing call will succeed.

4. Generate an RSA key pair

pkcs11-tool --module $MODULE --login --pin 87654321 \
    --keypairgen --key-type rsa:2048 \
    --label "qs-rsa" --id 01

Expected output shape:

Key pair generated:
Private Key Object; RSA
  label:      qs-rsa
  ID:         01
  Usage:      sign, decrypt, unwrap
  Access:     sensitive, always sensitive, never extractable, local
Public Key Object; RSA 2048 bits
  label:      qs-rsa
  ID:         01
  Usage:      verify, encrypt, wrap
  Access:     local

Key generation routes through the SP 800-90A HMAC_DRBG and runs a sign/verify pairwise consistency check before the handles are returned to the caller.

5. Sign and verify

Create a fixed-size input, sign it, then verify the signature using the public key on the token:

# 32 random bytes — matches the SHA-256 digest size pkcs11-tool expects
# when using raw ECDSA / hash-wrapping mechanisms.
head -c 32 /dev/urandom > data.bin

pkcs11-tool --module $MODULE --login --pin 87654321 \
    --sign --mechanism SHA256-RSA-PKCS \
    --id 01 \
    --input-file data.bin --output-file data.sig

pkcs11-tool --module $MODULE --login --pin 87654321 \
    --verify --mechanism SHA256-RSA-PKCS \
    --id 01 \
    --input-file data.bin --signature-file data.sig

Expected output shape:

Using signature algorithm SHA256-RSA-PKCS
Signature verified

On Windows, replace the dd / /dev/urandom step with PowerShell:

$bytes = New-Object byte[] 32
[System.Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($bytes)
[IO.File]::WriteAllBytes("data.bin", $bytes)

What just happened

  • C_Initialize ran the 17 FIPS 140-3 Power-On Self-Tests.
  • C_InitToken and C_InitPIN persisted the SO and user PIN hashes.
  • C_Login(CKU_USER, ...) authenticated the session.
  • C_GenerateKeyPair produced a 2048-bit RSA key pair, passed the pairwise consistency test, and stored both halves encrypted.
  • C_SignInit / C_Sign and C_VerifyInit / C_Verify exercised the signing path.
  • Every one of those calls wrote a chained SHA-256 audit record to craton_hsm_audit.jsonl.

Next steps

  • First token — slot/token model, SO vs user PINs, re-initialising, fork safety.
  • Examples — RSA and ECDSA via OpenSSL and pkcs11-tool, AES-GCM via Java SunPKCS11, post-quantum ML-DSA-65.
  • Configuration reference — tune PIN policy, audit, storage, slot count.