Status: ✅ Implemented
Version: 1.8.0-rc1
Date: January 16, 2026
This guide covers the integration of Hardware Security Modules (HSM) with ThemisDB's LoRA adapter storage to provide hardware-backed encryption. The integration uses PKCS#11 standard to support various HSM devices.
- Architecture
- Supported HSM Devices
- Installation
- Configuration
- Testing with SoftHSM2
- Production Deployment
- Security Best Practices
- Troubleshooting
ThemisDB uses envelope encryption to combine the security of HSM with the performance of software encryption:
┌─────────────────────────────────────────────────────────────┐
│ LoRA Adapter Storage │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. Generate random DEK (Data Encryption Key) │
│ ├─> 32-byte AES-256 key │
│ └─> Used for actual data encryption (fast) │
│ │
│ 2. Wrap DEK with HSM KEK (Key Encryption Key) │
│ ├─> KEK stored in HSM hardware │
│ ├─> DEK encrypted by HSM (secure) │
│ └─> Encrypted DEK stored with adapter metadata │
│ │
│ 3. Encrypt adapter data with DEK │
│ ├─> AES-256-GCM encryption │
│ ├─> Fast performance (~0.5ms per KB) │
│ └─> Authenticated encryption │
│ │
│ 4. Cache decrypted DEK │
│ ├─> TTL: 5 minutes (configurable) │
│ ├─> Reduces HSM operations │
│ └─> Thread-safe cache │
│ │
└─────────────────────────────────────────────────────────────┘
-
HSMProvider (
include/security/hsm_provider.h)- Low-level PKCS#11 interface
- Session management and pooling
- Sign/verify operations
-
HSMKeyProviderAdapter (
include/security/hsm_key_provider_adapter.h)- Bridges HSMProvider with KeyProvider interface
- Implements envelope encryption
- DEK caching and lifecycle management
-
LoRAStorageService (
include/llm/lora_framework/lora_storage_service.h)- High-level LoRA adapter storage
- Integrates with HSMKeyProviderAdapter
- Transparent encryption/decryption
| Vendor | Model | PKCS#11 Library | Tested |
|---|---|---|---|
| Thales/SafeNet | Luna Network HSM | /usr/safenet/lunaclient/lib/libCryptoki2_64.so |
✓ |
| Utimaco | CryptoServer | /opt/utimaco/lib/libcs_pkcs11_R2.so |
✓ |
| AWS | CloudHSM | /opt/cloudhsm/lib/libcloudhsm_pkcs11.so |
✓ |
| Gemalto | ProtectServer | /usr/lib/libprotect.so |
○ |
| Name | PKCS#11 Library | Use Case |
|---|---|---|
| SoftHSM2 | /usr/lib/softhsm/libsofthsm2.so |
Development & Testing |
| OpenSC | /usr/lib/opensc-pkcs11.so |
Smart card testing |
Legend: ✓ = Fully tested | ○ = Compatibility verified | ✗ = Not tested
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y \
build-essential \
cmake \
libssl-dev \
softhsm2 \
opensc-pkcs11
# RHEL/CentOS
sudo yum install -y \
gcc-c++ \
cmake \
openssl-devel \
softhsm \
openscThemisDB is built with HSM support by default. No additional compilation flags needed.
git clone https://github.com/makr-code/ThemisDB.git
cd ThemisDB
./scripts/build.shAdd HSM configuration to your LoRA storage service:
#include "llm/lora_framework/lora_storage_service.h"
themis::llm::lora::LoRAStorageService::Config config;
// Enable encryption
config.enable_encryption = true;
// Enable HSM-backed encryption
config.use_hsm_for_encryption = true;
// HSM Configuration
config.hsm_library_path = "/usr/lib/softhsm/libsofthsm2.so"; // PKCS#11 library
config.hsm_slot_id = 0; // HSM slot
config.hsm_pin = "1234"; // User PIN
config.hsm_key_label = "lora-adapter-kek"; // KEK label
config.hsm_session_pool_size = 4; // Parallel sessions
// Create storage service
auto storage = std::make_unique<themis::llm::lora::LoRAStorageService>(config);For production, avoid hardcoding PINs. Use environment variables:
export THEMIS_HSM_LIBRARY="/usr/lib/softhsm/libsofthsm2.so"
export THEMIS_HSM_SLOT="0"
export THEMIS_HSM_PIN="1234" # Use secure secret management!
export THEMIS_HSM_KEY_LABEL="lora-adapter-kek"config.hsm_library_path = std::getenv("THEMIS_HSM_LIBRARY");
config.hsm_slot_id = std::stoul(std::getenv("THEMIS_HSM_SLOT") ?: "0");
config.hsm_pin = std::getenv("THEMIS_HSM_PIN");
config.hsm_key_label = std::getenv("THEMIS_HSM_KEY_LABEL") ?: "lora-adapter-kek";# config/themisdb.yaml
lora_storage:
backend: themisdb
encryption:
enabled: true
use_hsm: true
hsm:
library_path: /usr/lib/softhsm/libsofthsm2.so
slot_id: 0
pin: ${THEMIS_HSM_PIN} # Read from environment
key_label: lora-adapter-kek
session_pool_size: 4SoftHSM2 is a software implementation of PKCS#11 for testing and development.
# Ubuntu/Debian
sudo apt-get install softhsm2
# macOS
brew install softhsm
# Verify installation
softhsm2-util --version# Create token storage directory
sudo mkdir -p /var/lib/softhsm/tokens
sudo chown -R $(whoami) /var/lib/softhsm
# Initialize token
softhsm2-util --init-token \
--slot 0 \
--label "ThemisDB-Test" \
--pin 1234 \
--so-pin 5678
# Verify token
softhsm2-util --show-slotsExpected output:
Slot 0
Slot info:
Description: SoftHSM slot ID 0x0
Manufacturer ID: SoftHSM project
Hardware version: 2.6
Firmware version: 2.6
Token present: yes
Token info:
Manufacturer ID: SoftHSM project
Model: SoftHSM v2
Hardware version: 2.6
Firmware version: 2.6
Serial number: 1234567890abcdef
Initialized: yes
User PIN init.: yes
Label: ThemisDB-Test
# Generate RSA-2048 key pair
pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so \
--login --pin 1234 \
--keypairgen \
--key-type RSA:2048 \
--label "lora-adapter-kek" \
--id 01
# Verify key
pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so \
--login --pin 1234 \
--list-objectsExpected output:
Private Key Object; RSA
label: lora-adapter-kek
ID: 01
Usage: decrypt, sign, unwrap
Public Key Object; RSA 2048 bits
label: lora-adapter-kek
ID: 01
Usage: encrypt, verify, wrap
# Set environment variables
export THEMIS_TEST_HSM_LIBRARY=/usr/lib/softhsm/libsofthsm2.so
export THEMIS_TEST_HSM_PIN=1234
# Run HSM tests
cd ThemisDB/build
ctest -R hsm -V1/3 Test #1: test_hsm_provider ...................... Passed 0.52 sec
2/3 Test #2: test_hsm_key_provider_adapter .......... Passed 1.23 sec
3/3 Test #3: test_lora_hsm_integration .............. Passed 2.15 sec
100% tests passed, 0 tests failed out of 3
- Install HSM hardware according to vendor documentation
- Connect to network (for network HSMs) or PCIe slot
- Verify hardware status LEDs
# Example for Thales Luna HSM
lunacm
> hsm init -label ThemisDB-Production
> partition create -partition themisdb -password <secure-password>
> exit
# Create KEK
cmu generatekeypair -modulusBits=2048 -label=lora-adapter-kek -sign=1 -encrypt=1Update production configuration:
# config/production/themisdb.yaml
lora_storage:
encryption:
enabled: true
use_hsm: true
hsm:
library_path: /usr/safenet/lunaclient/lib/libCryptoki2_64.so
slot_id: 0
pin: ${THEMIS_HSM_PIN} # From Vault/Secrets Manager
key_label: lora-adapter-kek
session_pool_size: 8 # Tune based on loadNever hardcode PINs! Use a secrets management system:
HashiCorp Vault:
# Store PIN in Vault
vault kv put secret/themisdb/hsm pin=<secure-pin>
# Retrieve at runtime
export THEMIS_HSM_PIN=$(vault kv get -field=pin secret/themisdb/hsm)AWS Secrets Manager:
# Store PIN
aws secretsmanager create-secret \
--name themisdb/hsm/pin \
--secret-string <secure-pin>
# Retrieve at runtime (in application startup)
aws secretsmanager get-secret-value \
--secret-id themisdb/hsm/pin \
--query SecretString \
--output textMonitor HSM health and performance:
// Get HSM statistics
auto stats = adapter->getStats();
spdlog::info("HSM Stats:");
spdlog::info(" Cache Hit Rate: {:.2f}%", stats["cache_hit_rate"].get<double>() * 100);
spdlog::info(" HSM Encrypt Ops: {}", stats["hsm_encrypt_operations"]);
spdlog::info(" HSM Decrypt Ops: {}", stats["hsm_decrypt_operations"]);
spdlog::info(" HSM Errors: {}", stats["hsm_errors"]);Integrate with Prometheus:
# prometheus.yml
- job_name: 'themisdb'
static_configs:
- targets: ['localhost:4318']
metrics_path: /metrics- ✅ DO: Store PINs in secrets manager (Vault, AWS Secrets Manager)
- ✅ DO: Rotate PINs regularly (every 90 days)
- ✅ DO: Use different PINs for dev/staging/production
- ❌ DON'T: Hardcode PINs in source code
- ❌ DON'T: Log PINs or include in error messages
- ❌ DON'T: Store PINs in plain text configuration files
- ✅ Generate KEK in HSM (never import)
- ✅ Mark KEK as non-exportable
- ✅ Implement key rotation schedule (annually)
- ✅ Backup HSM configuration (but not keys!)
- ✅ Test key recovery procedures
- ✅ Restrict HSM access to ThemisDB service account only
- ✅ Enable HSM audit logging
- ✅ Monitor failed authentication attempts
- ✅ Implement IP allowlisting for network HSMs
- ✅ Use mTLS for network HSM connections
// Optimize session pool based on load
config.hsm_session_pool_size = 8; // 8 parallel sessions
// Tune DEK cache
adapter_config.cache_ttl_ms = 300000; // 5 minutes
adapter_config.max_cache_size = 1000; // 1000 DEKs
adapter_config.enable_caching = true; // Enable cachingFor production:
- Use HSM clustering/replication
- Configure automatic failover
- Test disaster recovery procedures
- Monitor HSM health continuously
Error:
HSM initialization failed: Failed to load PKCS#11 library
Solution:
- Verify library path:
ls -la /usr/lib/softhsm/libsofthsm2.so
- Check library dependencies:
ldd /usr/lib/softhsm/libsofthsm2.so
- Set LD_LIBRARY_PATH if needed:
export LD_LIBRARY_PATH=/usr/lib/softhsm:$LD_LIBRARY_PATH
Error:
HSM initialization failed: CKR_PIN_INCORRECT
Solution:
- Verify PIN is correct
- Check token status:
pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so --show-slots
- Reset PIN if locked:
softhsm2-util --init-pin --slot 0 --pin 1234 --so-pin 5678
Error:
HSM operation failed: Key label 'lora-adapter-kek' not found
Solution:
- List available keys:
pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so \ --login --pin 1234 \ --list-objects
- Generate key if missing (see Generate KEK)
Symptom: Slow encryption/decryption
Solution:
- Check cache hit rate:
auto stats = adapter->getStats(); double hit_rate = stats["cache_hit_rate"].get<double>(); if (hit_rate < 0.80) { // Increase cache size or TTL adapter_config.cache_ttl_ms = 600000; // 10 minutes adapter_config.max_cache_size = 2000; }
- Increase session pool:
config.hsm_session_pool_size = 16; // More parallel sessions
- Monitor HSM utilization:
# For Luna HSM lunacm > partition showinfo -partition themisdb
Error:
HSM operation failed: CKR_SESSION_COUNT
Solution:
- Increase session pool size:
config.hsm_session_pool_size = 32; // Increase limit
- Close unused sessions in application code
- Check HSM session limits (vendor-specific)
- PKCS#11 Specification v2.40
- SoftHSM2 Documentation
- ThemisDB Security Documentation
- LoRA Storage Backend Documentation
For issues or questions:
- GitHub Issues: https://github.com/makr-code/ThemisDB/issues
- Security Issues: security@themisdb.io
- Documentation: https://makr-code.github.io/ThemisDB/
Last Updated: April 2026
Maintained by: ThemisDB Security Team