Skip to content

This guide provides complete instructions for integrating the Thales Luna 7 HSM with Ripple Custody. It covers both form factors of the Luna 7 A-series — the Luna Network HSM 7 appliance and the Luna PCIe HSM 7 (A700) card. Both are FIPS 140-2 Level 3 certified hardware security modules that provide hardware-based key protection for your notary and vault components.

Before you begin: This guide assumes you have completed Installation environment setup and are ready to configure your HSM for use with Ripple Custody.


Overview

Supported form factors

This guide covers both form factors of the Thales Luna 7 A-series HSM. Both use an identical PKCS#11 cryptographic interface and Luna 7.x firmware — only the transport layer differs, so the Ripple Custody integration is the same for both.

AttributeLuna Network HSM 7Luna PCIe HSM 7 (A700)
ConnectionNTLS (network transport layer security), NetClient=1Local PCI bus (card installed in the host server)
Crypto interfacePKCS#11PKCS#11 (identical)
FirmwareLuna 7.xLuna 7.x (identical)
Form factorStandalone network appliancePCIe card in host server

Shared configuration: Because the cryptographic interface and firmware are identical, the HSM policies, scalable key storage (SKS) setup, key-derivation behavior, and Ripple Custody configuration described in this guide apply to both form factors. The only differences are the steps that set up the network transport — network ACLs, NTLS/mTLS certificates, and port 1792 — which do not apply to the locally-installed PCIe card (A700).

Supported hardware and minimum versions

The Ripple Custody luna KMS provider connects through the Luna client library (libCryptoki2.so) and relies on Thales BIP32/SLIP-10 vendor extensions (CKK_BIP32, CKM_BIP32_MASTER_DERIVE, CA_SIMInsert/CA_SIMExtract, and CA_Bip32ExportPublicKey), so the supported hardware is the Luna 7 generation, which exposes these extensions.

RequirementDetail
Supported modelsLuna Network HSM 7: A700, A750, A790, S700, S750, S790.
Minimum firmware and clientSLIP-10 derivation (secp256k1, ed25519, P-256) requires HSM firmware 7.8.7 or later and Luna client 10.7.1 or later.
CertificationFIPS 140-2 and 140-3 Level 3.

How Ripple Custody uses Luna HSM

Ripple Custody uses Luna HSM in two critical components:

  1. Notary: Uses the master signing key in the HSM to authenticate governance operations
  2. Vault: Uses the master encryption key in the HSM to protect account private keys

Key generation flow:

  1. During account creation, the vault requests key generation from the HSM
  2. The HSM generates the private key internally using its secure random number generator
  3. The private key is encrypted using the HSM master key via PKCS#11
  4. The encrypted key (SKS blob) is stored in the Ripple Custody database
  5. The HSM master key and plaintext private keys never leave the HSM hardware

Deployment architecture

mTLS port 1792

mTLS port 1792

Thales Luna HSM HA Group

Partition #1

Partition #2

Kubernetes Cluster

Notary + KMS Connect

Vault + KMS Connect

mTLS port 1792

mTLS port 1792

Thales Luna HSM HA Group

Partition #1

Partition #2

Kubernetes Cluster

Notary + KMS Connect

Vault + KMS Connect

The diagram above shows the Network HSM topology, where the notary and vault reach the HSM over mTLS on port 1792. For the PCIe HSM (A700), the card is installed directly in the host server and accessed over the local PCI bus, so there is no network hop between the Ripple Custody components and the HSM.


Prerequisites

Hardware and software requirements

Before starting, ensure you have:

From Thales Luna HSM:

  • One of the following Luna 7 A-series HSMs:
    • Thales Luna Network HSM 7 appliance (physical or virtual), or
    • Thales Luna PCIe HSM 7 (A700) card installed in the host server
  • Firmware version:
    • 7.7.1 or higher for BIP32 derivation
    • 7.8.7 or higher for SLIP10 derivation (recommended)
  • Application software 7.8.5-300 (for SLIP10)
  • Network HSM only: network connectivity on port 1792 (typical). The PCIe HSM (A700) is accessed locally over the PCI bus and does not use network transport.
  • Limited Crypto Officer (LCO) role configured on the assigned partition and mapped to the corresponding slot
  • Slot number and partition PIN, which Ripple Custody uses to open a session on the partition
  • Network HSM only: NTLS certificate bundle — client certificate, client private key, and HSM server certificate

From your infrastructure:

  • Linux client machine for HSM administration (LunaCM client)
  • Network access from Kubernetes cluster to HSM on port 1792
  • Firewall rules allowing bidirectional traffic

From Ripple:

  • Ripple Custody Helm charts (version 1.16+ for SLIP10)
  • Access to the Ripple container registry (metaco.azurecr.io)

Required HSM policies

CRITICAL: The following policies are destructive and will erase existing HSM data when enabled. Enable these policies BEFORE storing any production keys.

HSM-level policies (apply to entire HSM):

  • Policy 6: Allow masking (required for SKS)
  • Policy 12: Allow non-FIPS algorithms (required for vault operations)

Partition-level policies (apply to each partition):

  • Policy 22: Allow activation
  • Policy 23: Allow auto-activation
  • Policy 41: Partition version
  • Policy 43: Allow non-FIPS algorithms

Key derivation schemes

The vault automatically detects HSM capabilities at startup and selects the appropriate derivation scheme:

SchemeSupported CurvesSupported BlockchainsFirmware Required
SLIP10 (preferred)secp256k1, Ed25519All blockchains (Bitcoin, Ethereum, XRPL, Solana, Algorand, etc.)7.8.7+
BIP32 (fallback)secp256k1 onlyBitcoin, Ethereum, XRPL, Litecoin, Polygon7.7.1+

Automatic selection: The vault will automatically choose SLIP10 if the HSM firmware supports it (7.8.7+), otherwise it defaults to BIP32. No manual configuration is required.

Key storage strategy

By default, Ripple Custody vaults use hierarchical-deterministic (HD) key derivation (SLIP10). You can optionally configure a vault to use random keys instead, but this is not the recommended default.

Random key backups: The random key strategy has implications for backups. Unlike HD-derived keys, random keys cannot be regenerated from a single seed, so their backups must be managed manually and periodically reconducted. Use HD derivation (the default) unless you have a specific requirement for random keys.

Documentation references


HSM initialization

This section covers the vendor-specific setup required to prepare your Luna HSM for use with Ripple Custody. Detailed step-by-step commands are available in the Thales Luna Network HSM 7 documentation.

Customer responsibility: Your infrastructure team performs HSM initialization. Ripple Custody only requires that the HSM be configured with the settings described below before proceeding to Ripple Custody configuration.

Step 1: Deploy and initialize Luna HSM appliance

Complete the following using Thales documentation:

  1. Physical deployment: Rack, power, and network-connect the Luna HSM appliance
  2. Initial setup: Complete the setup wizard via serial console or web interface
  3. Network configuration: Assign a static IP address accessible from your Kubernetes cluster
  4. Firmware verification: Confirm firmware is 7.7.1+ (BIP32) or 7.8.7+ (SLIP10)

Step 2: Enable required HSM policies

WARNING: Enabling these policies will destroy all existing keys and data on the HSM. Perform this step on a freshly initialized HSM or after backing up all existing keys.

HSM-level policies (required for Ripple Custody):

PolicyNameRequired ValuePurpose
6Allow masking1 (enabled)Required for Scalable Key Storage (SKS)
12Allow non-FIPS algorithms1 (enabled)Required for vault operations

Use hsm changePolicy and hsm showPolicies commands to configure and verify.

Step 3: Configure scalable key storage (SKS) partition

SKS allows you to store unlimited keys while maintaining hardware-level security. The SKS master key (SMK) remains in the HSM, while encrypted key blobs are stored externally in the Ripple Custody database.

Create one partition for Ripple Custody:

  • Partitions must be type V1 for SKS support
  • Assign a strong password for the partition
  • One partition per application is the standard design (partitions are expensive)

Enable partition-level policies on the partition:

PolicyNameRequired ValuePurpose
22Allow activation1 (enabled)Required for partition access
23Allow auto-activation1 (enabled)Required for automatic login
41Partition version1 (enabled)Required for SKS
43Allow non-FIPS algorithms1 (enabled)Required for blockchain operations

Assign client access by registering the Kubernetes client with partition access using client assignPartition.

Step 4: Configure high availability (HA) groups

HA groups provide redundancy by synchronizing keys across multiple HSM partitions. If one HSM fails, the other continues to provide cryptographic services.

Production HA Cluster

Client Cert

Client Cert

Client Cert

Thales Luna HA Group

Replication

Replication

HSM 1
Partition

HSM 2
Partition

HSM 3
Partition

Client Applications

Notary

Vault Replica

Vault Replica

Production HA Cluster

Client Cert

Client Cert

Client Cert

Thales Luna HA Group

Replication

Replication

HSM 1
Partition

HSM 2
Partition

HSM 3
Partition

Client Applications

Notary

Vault Replica

Vault Replica

Requirements:

  • At least 2 Luna HSM appliances (one partition per HSM for replication)
  • Matching partition configurations on each HSM

Configuration:

  1. Use lunacm on your Linux client to create HA groups using hagroup createGroup
  2. Add additional HSM partitions as members using hagroup addMember
  3. Verify HA configuration is saved to /etc/Chrystoki.conf

Key Chrystoki.conf settings:

  • HAOnly = 1 ensures PKCS#11 operations only use HA groups
  • VirtualTokenActiveRecovery = activeEnhanced enables automatic failover

See Thales HA configuration guide for detailed instructions.

Step 5: Configure network access and mTLS

PCIe HSM (A700): Skip this step. The card communicates with its host over the local PCI bus, so there is no network ACL, NTLS/mTLS certificate exchange, or port 1792 to configure. Instead, confirm the card is visible as a local slot using slot list in lunacm.

Network ACL: Add your Kubernetes cluster node IP range to the HSM's network ACL using network add.

mTLS Certificates: Luna HSM uses mutual TLS (mTLS) for secure communication.

  1. Generate client certificate on your Linux client using vtl createCert
  2. Register client with HSM using client register and assign partition access
  3. Download HSM server certificate for client-side verification.

You will need three files for Ripple Custody configuration:

  • Client certificate (client.pem)
  • Client private key (client.key)
  • HSM server certificate (server.pem)

Step 6: Verify HSM connectivity

Before proceeding to Ripple Custody configuration, verify:

  1. Network connectivity: Port 1792 is reachable from Kubernetes nodes
  2. PKCS#11 connectivity: vtl verify shows your HA groups
  3. Authentication: Can login to partitions with configured PINs
  4. Cryptographic operations: Basic operations execute without errors

Checkpoint: If vtl verify shows your HA groups and you can successfully login to partitions, your Luna HSM is properly configured and ready for Ripple Custody integration.


Ripple Custody configuration

Now that your Luna HSM is initialized, configure Ripple Custody to use it for the notary and vault components.

PCIe HSM (A700): The network transport fields shown in the examples below — host, port, and the client/server certificate blocks — do not apply, because the card is accessed locally over the PCI bus rather than over NTLS. Configure the same kms_luna platform with your partition slot and pin. If you are unsure which fields your deployment requires for the PCIe form factor, contact Ripple.

Step 1: Prepare certificate files

You'll need to provide three certificate files in your Helm configuration:

  1. Client certificate (<client-hostname>.pem): Authenticates Ripple Custody to the HSM
  2. Client private key (<client-hostname>Key.pem): Private key for client certificate
  3. Server certificate (server.pem): HSM's server certificate for verification

Convert certificates to base64 for Helm values:

# Client certificate
$ cat /usr/safenet/lunaclient/cert/client/<client-hostname>.pem | base64 -w 0 > client-cert.b64

# Client private key
$ cat /usr/safenet/lunaclient/cert/client/<client-hostname>Key.pem | base64 -w 0 > client-key.b64

# Server certificate
$ cat /usr/safenet/lunaclient/cert/server/server.pem | base64 -w 0 > server-cert.b64

Step 2: Configure notary with Luna HSM

Edit your production.yaml Helm values file to configure the notary component:

# production.yaml

components:
  notary:
    enabled: true

    # Platform selection
    platform: kms_luna

    # Luna HSM configuration
    kms_luna:
      host: "luna-hsm.example.com"  # Luna HSM hostname or IP
      port: "1792"                   # Luna HSM port (must be string)
      slot: "0"                      # HA group slot number (0 for first HA group)
      pin: "notary-partition-password"  # Partition password

      # Client certificate (for mTLS)
      client:
        certificate: |
          -----BEGIN CERTIFICATE-----
          MIIDXTCCAkWgAwIBAgIJAKZ...
          -----END CERTIFICATE-----
        key: |
          -----BEGIN PRIVATE KEY-----
          MIIEvQIBADANBgkqhkiG9w0...
          -----END PRIVATE KEY-----

      # Server certificate (Luna HSM)
      server:
        certificate: |
          -----BEGIN CERTIFICATE-----
          MIIDXTCCAkWgAwIBAgIJAKZ...
          -----END CERTIFICATE-----

Security best practice: Do NOT store the partition PIN directly in production.yaml. Use Kubernetes Secrets or an external secrets manager (HashiCorp Vault, Conjur) to inject the PIN at runtime.

Using Kubernetes Secrets for PIN:

# Create secret for Notary PIN
kubectl create secret generic notary-luna-pin \
  --namespace custody-core \
  --from-literal=pin='notary-partition-password'

# Reference secret in production.yaml
components:
  notary:
    platform: kms_luna
    kms_luna:
      # ... other config ...
      pinSecretRef: notary-luna-pin  # Reference to Kubernetes secret

Step 3: Configure vault with Luna HSM

Configure the vault component to use Luna HSM for key encryption:

# production.yaml

harmonize:
  vaults:
    "00000000-0000-0000-0000-000000000000":  # Default vault UUID
      enabled: true

      # Platform selection
      platform: kms_luna

      # Notary public key (obtained after Notary initialization - see Step 4)
      notary_public_key: "ed25519:50692dfa472f013e2f87e5d210be40cefe178e33787be4688d5da0afe06ed149"

      # Luna HSM configuration
      kms_luna:
        host: "luna-hsm.example.com"
        port: "1792"
        slot: "0"  # Same partition as Notary (one partition per application)
        pin: "partition-password"

        client:
          certificate: |
            -----BEGIN CERTIFICATE-----
            MIIDXTCCAkWgAwIBAgIJAKZ...
            -----END CERTIFICATE-----
          key: |
            -----BEGIN PRIVATE KEY-----
            MIIEvQIBADANBgkqhkiG9w0...
            -----END PRIVATE KEY-----

        server:
          certificate: |
            -----BEGIN CERTIFICATE-----
            MIIDXTCCAkWgAwIBAgIJAKZ...
            -----END CERTIFICATE-----

Using Kubernetes Secrets for vault PIN:

# Create secret for Vault PIN (same partition as Notary)
kubectl create secret generic vault-luna-pin \
  --namespace custody-vault \
  --from-literal=pin='partition-password'

Step 4: Complete configuration example

Here's a complete example showing both notary and vault configured with Luna HSM:

# production.yaml - Complete Luna HSM Configuration

# Global settings
harmonize:
  repository:
    base: "my-registry.example.com/harmonize"

  urls:
    base: "custody.example.com"
    tls: true

# Notary configuration
components:
  notary:
    enabled: true
    platform: kms_luna
    kms_luna:
      host: "luna-hsm.example.com"
      port: "1792"
      slot: "0"
      pin: "${NOTARY_PIN}"  # Injected from secrets manager
      client:
        certificate: |
          -----BEGIN CERTIFICATE-----
          ${LUNA_CLIENT_CERT}
          -----END CERTIFICATE-----
        key: |
          -----BEGIN PRIVATE KEY-----
          ${LUNA_CLIENT_KEY}
          -----END PRIVATE KEY-----
      server:
        certificate: |
          -----BEGIN CERTIFICATE-----
          ${LUNA_SERVER_CERT}
          -----END CERTIFICATE-----

# Vault configuration (uses same partition as Notary)
harmonize:
  vaults:
    "00000000-0000-0000-0000-000000000000":
      enabled: true
      platform: kms_luna
      notary_public_key: "ed25519:${NOTARY_PUBLIC_KEY}"  # Set after Notary initialization
      kms_luna:
        host: "luna-hsm.example.com"
        port: "1792"
        slot: "0"  # Same partition as Notary
        pin: "${PARTITION_PIN}"
        client:
          certificate: |
            -----BEGIN CERTIFICATE-----
            ${LUNA_CLIENT_CERT}
            -----END CERTIFICATE-----
        key: |
          -----BEGIN PRIVATE KEY-----
          ${LUNA_CLIENT_KEY}
          -----END PRIVATE KEY-----
        server:
          certificate: |
            -----BEGIN CERTIFICATE-----
            ${LUNA_SERVER_CERT}
            -----END CERTIFICATE-----

Advanced secret management

For production deployments, store sensitive credentials (PKCS#11 PIN, certificates) in an external secrets manager rather than directly in Helm values or Kubernetes secrets.

Production best practice: Never store sensitive credentials in plaintext YAML files or Git repositories.

Recommended approaches for Luna HSM credentials:

ApproachDescriptionUse Case
External Secrets Operator (ESO)Sync secrets from HashiCorp Vault, AWS Secrets Manager, or Azure Key Vault to KubernetesEnterprise environments with centralized secret management
HashiCorp Vault Agent InjectorInject secrets directly into pods at runtimeOrganizations already using Vault Agent
AWS Secrets ManagerStore and rotate secrets in AWSAWS-native deployments

For complete setup instructions, see Advanced secret management.

When using external secret management, reference the secret in your Helm values:

components:
  notary:
    platform: kms_luna
    kms_luna:
      existingSecret: "notary-luna-credentials"  # ESO-managed secret

Verification and testing

After configuring your Helm values, follow these steps to deploy and verify the integration.

Step 1: Verify HSM connectivity (before deployment)

Before deploying Ripple Custody components, verify network connectivity to the Luna HSM:

# Test network connectivity from a Kubernetes node or test pod
nc -zv luna-hsm.example.com 1792

# Expected output:
# Connection to luna-hsm.example.com 1792 port [tcp/*] succeeded!

# Verify PKCS#11 connectivity using vtl (from Luna client machine)
vtl verify

# Expected output should show your HA groups

IMPORTANT: Verify HSM connectivity before deploying components. Troubleshooting connectivity issues after deployment is more difficult.

Step 2: Deploy notary component

# Deploy Notary first (Vault needs Notary's public key)
helm upgrade --install harmonize ./harmonize-custody \
  --namespace custody-core \
  --create-namespace \
  -f production.yaml \
  --set components.vault.enabled=false \
  --set components.indexers.enabled=false

# Wait for Notary to be ready
kubectl wait --for=condition=ready pod \
  -l app=notary \
  -n custody-core \
  --timeout=300s

# Check KMS Connect sidecar logs to verify HSM connection
kubectl logs -n custody-core deployment/harmonize-notary -c kms-connect --tail=100

# Expected output should show:
# - Successful PKCS#11 connection to Luna HSM
# - HA group detection
# - Partition login success

Step 3: Initialize notary and retrieve public key

After notary is deployed and connected to the HSM, initialize it and retrieve the public key. For detailed API instructions, see the Installation and initialization guide.

# Check Notary logs for successful initialization
kubectl logs -n custody-core deployment/harmonize-notary -c notary-core --tail=50

# Retrieve Notary public key via the System Properties API
# See: API Reference > System Properties > Get System Properties

Save the notary public key - you'll need it for the vault configuration.

Step 4: Deploy vault component

Update production.yaml with the notary public key and deploy vault:

# Deploy Vault
helm upgrade --install harmonize ./harmonize-custody \
  --namespace custody-core \
  -f production.yaml

# Wait for Vault to be ready
kubectl wait --for=condition=ready pod \
  -l app=vault \
  -n custody-vault \
  --timeout=300s

# Verify Vault HSM connectivity
kubectl logs -n custody-vault deployment/harmonize-vault -c kms-connect --tail=100

Step 5: Verify end-to-end functionality

Create a test blockchain account to verify the complete integration:

  1. Register the vault via the Web UI: Administration > Vaults > Create a vault
  2. Create a test account via the Web UI: Accounts > Create account
  3. Verify account creation succeeded with a valid blockchain address

This confirms:

  • vault can communicate with Luna HSM
  • Key derivation is working (BIP32/SLIP10)
  • SKS blob encryption/storage is functional

For detailed instructions on account creation, see the Create an account guide.


Troubleshooting

Error MessageCauseSolution
CKR_DEVICE_ERRORHSM not reachableCheck network connectivity and firewall rules for port 1792
CKR_PIN_INCORRECTWrong partition passwordVerify PIN in Kubernetes secret matches HSM partition password
CKR_TOKEN_NOT_PRESENTHA group not configuredConfigure HA group and verify Chrystoki.conf
CKR_SESSION_HANDLE_INVALIDSession timeoutIncrease session timeout or check HSM load
SSL handshake failedCertificate mismatchRegenerate certificates and verify mTLS configuration
BIP32_DERIVE not supportedFirmware too oldUpgrade to firmware 7.7.1+
SLIP10_DERIVE not supportedFirmware too oldUpgrade to firmware 7.8.7+

For detailed troubleshooting, see the Thales Luna Network HSM 7 documentation.


Production best practices

For production-ready Luna HSM deployments, implement the following patterns. See Production best practices for detailed instructions that apply to all KMS platforms.

Luna HSM-specific considerations

PracticeLuna HSM Implementation
High AvailabilityConfigure Luna HA groups with hagroup createGroup and add multiple HSM members
Namespace SegmentationSeparate Luna partitions per namespace/vault for isolation
MonitoringUse lunacm commands (hsm show, partition show, hagroup show) plus Prometheus metrics
Certificate RotationGenerate new certificates with vtl createCert, update Kubernetes secrets, perform rolling update
BackupUse partition backup command, store backups securely, test quarterly
HA SyncRegularly verify HA group synchronization with hagroup synchronize

Luna HSM HA group configuration:

  • Use hagroup createGroup to create HA groups for notary and vault partitions
  • Configure HAOnly = 1 in Chrystoki.conf to ensure operations only use HA groups
  • Set VirtualTokenActiveRecovery = activeEnhanced for automatic failover

Next steps

After successfully integrating Luna HSM with Ripple Custody:

  1. Backup HSM keys: Implement backup procedures for SKS master keys.

    • Back up SMK to a secondary Luna HSM
    • Store backup HSM in secure, off-site location
    • Document recovery procedures
  2. Production hardening:

    • Enable HSM audit logging
    • Configure HSM monitoring and alerting
    • Implement HSM access controls (role-based access)
    • Schedule regular HSM firmware updates
  3. Disaster recovery planning:

    • Document HSM replacement procedures
    • Test HA failover scenarios
    • Create runbooks for common HSM issues
    • Establish HSM vendor support contacts
  4. Security audit:

    • Review HSM policies and partition configurations
    • Audit certificate expiration dates
    • Verify network ACLs are restrictive
    • Test backup and recovery procedures
  5. Review Production best practices for namespace segmentation, HA patterns, and monitoring


AWS Nitro Enclave deployment

For enhanced security, you can deploy the vault in an AWS Nitro enclave to connect your Luna HSM to Ripple Custody.

These steps require support assistance from Ripple to complete. For more information, contact your Ripple liaison.

Prerequisites

To configure a Luna HSM with AWS Nitro enclave to work with Ripple Custody, you need:

  • From Ripple:

    • An AWS enclave Terraform script
    • The encrypt-cli tool
  • From your Ripple Custody environment:

Deploy the vault

  1. Create your enclave contract, in a format similar to the following Podman Play YAML file:

    # Enclave configuration (required)
    kind: Enclave
    apiVersion: v1
    #
    # specify if enclaves requires disk storage via NBD
    requireVarDisk: false
    requireDataDisk: false
    #
    # base64 encoded disk encryption keys, min=32 byte. If empty keys are auto-generated on every boot!
    # Example: dd if=/dev/random bs=1 count=32 | base64
    encryptionKeyVar: <your-encryption-key>
    encryptionKeyData: <your-encryption-key>
    #
    # auths: login credentials for private container registries (optional)
    auths:
      - registry: metaco.azurecr.io
        username: <your-username>
        password: <your-password>
    hostname: enclave-vault-1
    ---
    # POD definition (required)
    # Pod configuration map (optional)
    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: config
    data:
    
    ---
    kind: Pod
    apiVersion: v1
    metadata:
      name: vault-pod
    spec:
      volumes:
        - name: config
          configMap:
            name: config
      containers:
    

For help to define an appropriate pod structure for the current release, contact Ripple.

  1. Using encrypt-cli, generate the enclave contract token.
  2. Run the Terraform script with the contract token created in step 2 as an input parameter.

Congratulations! You have successfully integrated Thales Luna HSM with Ripple Custody. Your notary and vault components are now protected by FIPS 140-2 Level 3 certified hardware security.