Skip to content

PKCS#11 Hardware Security Module (HSM)

PKCS#11 is a cryptographic token interface standard that provides a platform-independent API to cryptographic tokens such as hardware security modules (HSMs) and smart cards. It enables secure key storage and cryptographic operations in hardware, offering enhanced security for private key protection. The standard supports various cryptographic algorithms and provides fine-grained access control through PIN-based authentication. PKCS#11 tokens can generate, store, and use cryptographic keys without exposing them to the host system, making them ideal for high-security environments where private key protection is critical.

You can read more about PKCS#11 here.

Requirements

Your HSM must support:

  • PKCS#11 interface
  • secp256k1 elliptic curve (required for Ethereum)
  • ECDSA signature generation
Verified Compatible Devices:
  • AWS CloudHSM
  • Nitrokey HSM 2
Compatible with Configuration:
  • Thales/SafeNet Luna HSMs (requires custom firmware/configuration)
  • Utimaco HSMs (requires custom configuration)
  • Ledger hardware wallets (requires unofficial PKCS#11 module)

Usage

To enable PKCS#11 you need to add the library path and authentication details to the YAML under the pkcs11 key.

Fields

library_path

This is the absolute path to your PKCS#11 library (.so file on Linux/macOS, .dll on Windows).

rrelayer.yaml
name: first-rrelayer
description: "my first rrelayer"
api_config:
  port: 3000
  authentication_username: ${RRELAYER_AUTH_USERNAME}
  authentication_password: ${RRELAYER_AUTH_PASSWORD}
signing_provider: 
  pkcs11: 
    library_path: "/usr/lib/pkcs11/opensc-pkcs11.so"

Common library paths:

  • SoftHSM: /usr/lib/softhsm/libsofthsm2.so or /opt/homebrew/lib/softhsm/libsofthsm2.so
  • OpenSC: /usr/lib/pkcs11/opensc-pkcs11.so
  • Ledger: Platform-specific Ledger PKCS#11 library

pin (optional)

The PIN or password required to authenticate with your HSM slot.

rrelayer.yaml
name: first-rrelayer
description: "my first rrelayer"
api_config:
  port: 3000
  authentication_username: ${RRELAYER_AUTH_USERNAME}
  authentication_password: ${RRELAYER_AUTH_PASSWORD}
  signing_provider: 
    pkcs11:
      library_path: "/usr/lib/pkcs11/opensc-pkcs11.so"
      pin: "${HSM_PIN}"

slot_id (optional)

The specific slot ID to use if your HSM has multiple slots. If not specified, the first available slot will be used.

rrelayer.yaml
name: first-rrelayer
description: "my first rrelayer"
api_config:
  port: 3000
  authentication_username: ${RRELAYER_AUTH_USERNAME}
  authentication_password: ${RRELAYER_AUTH_PASSWORD}
signing_provider: 
  pkcs11: 
    library_path: "/usr/lib/pkcs11/opensc-pkcs11.so"
    pin: "${HSM_PIN}"
    slot_id: 82907649

identity (required)

A unique identifier for this rrelayer instance. This identity is used to namespace key labels in the HSM, allowing multiple rrelayer instances to use the same HSM device without key conflicts.

The identity is combined with chain ID and wallet index to create unique labels like rrelayer-{identity}-wallet-{chain_id}-{wallet_index}.

rrelayer.yaml
name: first-rrelayer
description: "my first rrelayer"
api_config:
  port: 3000
  authentication_username: ${RRELAYER_AUTH_USERNAME}
  authentication_password: ${RRELAYER_AUTH_PASSWORD}
signing_provider: 
  pkcs11: 
    library_path: "/usr/lib/pkcs11/opensc-pkcs11.so"
    pin: "${HSM_PIN}"
    identity: "prod-relay-01"

test_mode (optional)

Enables testing mode for development and CI environments. When enabled, returns predetermined mock signatures instead of using the HSM for signing operations.

rrelayer.yaml
name: development-rrelayer
description: "Development rrelayer with mock HSM"
api_config:
  port: 3000
  authentication_username: ${RRELAYER_AUTH_USERNAME}
  authentication_password: ${RRELAYER_AUTH_PASSWORD}
signing_provider: 
  pkcs11: 
    library_path: "/opt/homebrew/lib/softhsm/libsofthsm2.so"
    pin: "1234"
    slot_id: 82907649
    identity: "dev-test"
    test_mode: true
Use cases for test_mode:
  • Development environment testing
  • CI/CD pipeline integration tests
  • Configuration validation
  • RRelayer integration testing
What test_mode does NOT test:
  • Real HSM compatibility
  • Actual PKCS#11 library functionality
  • Hardware-specific behaviors
  • Production signature generation

Complete Configuration Example

rrelayer.yaml
name: production-rrelayer
description: 'Production rrelayer with HSM'
api_config:
  port: 3000
  authentication_username: ${RRELAYER_AUTH_USERNAME}
  authentication_password: ${RRELAYER_AUTH_PASSWORD}
signing_provider: 
  pkcs11: 
    library_path: '/usr/lib/pkcs11/cloudhsm-pkcs11.so'
    pin: '${HSM_PIN}'
    slot_id: 1
    identity: 'prod-relay-01'

Key Management

The PKCS#11 provider automatically:

  • Generates secp256k1 key pairs on the HSM for each wallet index and chain ID combination
  • Derives Ethereum addresses using Keccak256 hashing
  • Tags keys with unique labels combining identity, chain ID, and wallet index (rrelayer-{identity}-wallet-{chain_id}-{wallet_index})
  • Maintains a cache mapping between wallet indices, chain IDs, and HSM key handles
  • Ensures keys are unique per chain and wallet combination to prevent cross-chain replay attacks

Keys are generated on-demand when first accessed and remain on the HSM for subsequent use. The identity field ensures multiple rrelayer instances can safely share the same HSM device without key conflicts.

Security Considerations

  • Private keys never leave the HSM device
  • All cryptographic operations are performed within the HSM
  • Authentication is required for each session
  • Key generation uses hardware-based entropy
  • Some HSMs support additional features like key backup and recovery

Troubleshooting

Common Issues

Library not found: Ensure the PKCS#11 library path is correct and the library is installed.

Authentication failed: Verify the PIN is correct and the slot is accessible.

secp256k1 not supported: Confirm your HSM supports the secp256k1 curve required for Ethereum.

Signature recovery failures: Some HSMs generate deterministic signatures (RFC 6979) that may be incompatible with Ethereum's signature recovery mechanism. The implementation attempts multiple recovery IDs to find a compatible signature. If no compatible signature is found, an error is returned with guidance to use an HSM with random nonce generation or one specifically designed for Ethereum.

Testing

For development and testing purposes, you can use SoftHSM:

# Install SoftHSM (macOS with Homebrew)
brew install softhsm
 
# Initialize a test slot
softhsm2-util --init-token --slot 0 --label "test-token" --pin 1234 --so-pin 5678

For development and testing environments, you can use the test_mode configuration:

test-config.yaml
signing_provider:
  pkcs11:
    library_path: '/opt/homebrew/lib/softhsm/libsofthsm2.so'
    pin: '1234'
    slot_id: 82907649
    identity: 'test-relay'
    test_mode: true # Returns mock signatures for testing