Skip to content

hsmCompatVerify Combined Examples

Christina Fu edited this page Sep 16, 2026 · 2 revisions

hsmCompatVerify: RSA/EC + PQC Examples (v11.10)

1. Overview

This document demonstrates HSM compatibility verification for both traditional (RSA/EC) and post-quantum (ML-DSA/ML-KEM) key archival and recovery using the hsmCompatVerify tools.

Important
Please read the Important Notes and Disclaimers on the main hsmCompatVerify page regarding HSM compatibility testing limitations and best practices.

Tested Workflows: The examples in this document demonstrate workflows that have been tested with the listed configurations. Results may vary with different HSM vendors and models.

What’s New in v11.10:

  • Full ML-DSA (NIST FIPS 204) CA signing support

  • ML-KEM (NIST FIPS 203) transport/storage key support

  • Enhanced multi-token support (CA and KRA on different HSMs)

  • Improved ML-DSA user certificate key usage handling

Key Points:

  • Verifies HSM compatibility with Dogtag KRA cryptographic operations

  • hsmCompatVerify is a standalone KRA simulator - no CA/KRA instances needed

  • Supports both traditional (RSA/EC) and post-quantum (ML-DSA/ML-KEM) workflows

  • Tests both client-side and server-side operations

  • Supports HSM/PKCS#11 token testing (single-token and multi-token modes)

2. Document Navigation

This document is organized to help you quickly find what you need:

For Most Users:

For Advanced Testing:

  • Part 1: Traditional Cryptography - Detailed workflows for RSA/EC

    • Multi-token configurations (CA and KRA on different tokens)

    • Separate archive and recovery phases (debugging and testing)

  • Part 2: Post-Quantum Cryptography - Detailed workflows for ML-DSA/ML-KEM

    • Multi-token configurations (working around HSM limitations)

    • Separate archive and recovery phases (debugging and testing)

Additional Resources:

3. Prerequisites

3.1. Software Requirements

Component Version

NSS

3.123+ (for ML-KEM/ML-DSA support)

JSS

5.10+ (for ML-KEM/ML-DSA support)

PKI

11.10+ (this version)

hsmCompatVerify

Included in PKI v11.10

dogtag-jss-tools

Required for PKCS#12 import (provides p12tool)

3.2. Test Environment

  • Working directory: ~/demo/hsm-compat

  • NSS database password: Secret.123

  • All commands run from ~/demo/hsm-compat

4. Quick Start Guide

This section shows the most common usage - verifying compatibility with a complete archival and recovery workflow in a single command.

Tip
First-time users: Start with the Software Token workflow to learn the tool without needing an HSM. Then proceed to test your actual HSM.

4.1. Initial Setup (Run Once)

Create directory structure and initialize NSS databases:

$ mkdir -p ~/demo/hsm-compat/serv ~/demo/hsm-compat/clnt
$ cd ~/demo/hsm-compat

# Create password files
$ echo "Secret.123" > serv/nss.pwd
$ echo "Secret.123" > clnt/nss.pwd
$ echo "Secret.123" > clnt/recover.pwd

# Initialize NSS databases
$ certutil -N -d serv/ -f serv/nss.pwd
$ certutil -N -d clnt/ -f clnt/nss.pwd
Note
All commands below assume you are in the ~/demo/hsm-compat directory.

4.2. Quick Start: Software Token (Learn the Tool First)

Purpose: Run this first to see what a successful workflow looks like - no HSM required!

This uses the NSS database’s internal token instead of an HSM, perfect for understanding the tool before testing your actual HSM.

4.2.1. Step 1: Setup Certificates (Run Once)

$ hsmCompatVerifyServ --setup-only \
  --pkiserv-db-path serv \
  --pkiserv-passwd-file serv/nss.pwd \
  --hsm-token "" \
  --hsm-token-passwd-file serv/nss.pwd \
  --verbose

Expected Output:

  • RSA-4096 CA certificate created (self-signed)

  • RSA-2048 Transport certificate created

  • RSA-2048 Storage certificate created

  • serv/kra_transport.pem and serv/kra_storage.pem exported

4.2.2. Step 2: Generate Client Keys

$ hsmCompatVerifyClnt \
  --client-db-path clnt \
  --client-passwd-file clnt/nss.pwd \
  --transport-cert serv/kra_transport.pem \
  --verbose

Expected Output Files:

clnt/kra-test-wrapped-session.bin  (256 bytes - RSA-OAEP wrapped session key)
clnt/kra-test-wrapped-private.bin  (1224 bytes - AES-KWP wrapped RSA private key)
clnt/kra-test-public.der           (294 bytes - RSA public key)

4.2.3. Step 3: Verify Compatibility (Combined Archive + Recovery)

$ hsmCompatVerifyServ \
  --pkiserv-db-path serv \
  --client-db-path clnt \
  --hsm-token "" \
  --hsm-token-passwd-file serv/nss.pwd \
  --subject-dn "CN=Test User" \
  --p12-output clnt/recovered.p12 \
  --recovery-passwd-file clnt/recover.pwd \
  --verbose

What Happened:

  1. Session key unwrapped using transport private key

  2. User private key unwrapped successfully

  3. User certificate created and signed by CA

  4. New session key generated for storage

  5. User private key re-wrapped with storage key

  6. LDIF file created: clnt/kra-archived-key.ldif

  7. Storage session key unwrapped

  8. User private key recovered

  9. PKCS#12 file created: clnt/recovered.p12

4.2.4. Step 4: Verify PKCS#12 File

# Inspect PKCS#12 contents
$ pk12util -l clnt/recovered.p12 -w clnt/recover.pwd

# Import using p12tool (recommended)
$ mkdir -p test-import
$ echo "Secret.123" > test-import/nss.pwd
$ certutil -N -d test-import -f test-import/nss.pwd
$ p12tool -i clnt/recovered.p12 -d test-import -w clnt/recover.pwd

# Verify import
$ certutil -L -d test-import
$ certutil -K -d test-import
Note
Use p12tool -i to import the PKCS#12 file (from dogtag-jss-tools package). If not installed: sudo dnf install dogtag-jss-tools. If unavailable, you can try pk12util -i, though it may not support all PKCS#12 encryption modes.

Success! You now understand the tool. Next, test your actual HSM below.

4.3. Quick Start: HSM with Traditional Crypto (Most Common)

Purpose: Verify your HSM supports RSA/EC key archival and recovery for KRA.

4.3.1. Step 1: Setup HSM Certificates (Run Once)

# Create HSM password file
$ echo "HSMPassword123" > serv/hsm.pwd

# Setup CA, transport, and storage certificates on HSM
$ hsmCompatVerifyServ --setup-only \
  --pkiserv-db-path serv \
  --pkiserv-passwd-file serv/nss.pwd \
  --hsm-token "myHSM" \
  --hsm-token-passwd-file serv/hsm.pwd \
  --verbose

Expected Output:

  • RSA-4096 CA certificate created (self-signed) on HSM

  • RSA-2048 Transport certificate created on HSM

  • RSA-2048 Storage certificate created on HSM

  • serv/kra_transport.pem and serv/kra_storage.pem exported

4.3.2. Step 2: Generate Client Keys

$ hsmCompatVerifyClnt \
  --client-db-path clnt \
  --client-passwd-file clnt/nss.pwd \
  --transport-cert serv/kra_transport.pem \
  --verbose

Expected Output Files:

clnt/kra-test-wrapped-session.bin  (256 bytes - RSA-OAEP wrapped session key)
clnt/kra-test-wrapped-private.bin  (1224 bytes - AES-KWP wrapped RSA private key)
clnt/kra-test-public.der           (294 bytes - RSA public key)

4.3.3. Step 3: Verify HSM Compatibility (Combined Archive + Recovery)

$ hsmCompatVerifyServ \
  --pkiserv-db-path serv \
  --client-db-path clnt \
  --hsm-token "myHSM" \
  --hsm-token-passwd-file serv/hsm.pwd \
  --subject-dn "CN=Test User" \
  --p12-output clnt/recovered.p12 \
  --recovery-passwd-file clnt/recover.pwd \
  --verbose

What Happened (all on HSM):

  1. Session key unwrapped using transport private key (RSA-OAEP)

  2. User private key unwrapped successfully (AES-KWP)

  3. User certificate created and signed by CA (RSA-SHA256)

  4. New session key generated for storage

  5. User private key re-wrapped with storage key

  6. LDIF file created: clnt/kra-archived-key.ldif

  7. Storage session key unwrapped

  8. User private key recovered

  9. PKCS#12 file created: clnt/recovered.p12

4.3.4. Step 4: Verify PKCS#12 File

# Inspect PKCS#12 contents
$ pk12util -l clnt/recovered.p12 -w clnt/recover.pwd

# Import using p12tool (recommended)
$ mkdir -p test-import
$ echo "Secret.123" > test-import/nss.pwd
$ certutil -N -d test-import -f test-import/nss.pwd
$ p12tool -i clnt/recovered.p12 -d test-import -w clnt/recover.pwd

# Verify import
$ certutil -L -d test-import
$ certutil -K -d test-import
Note
Use p12tool -i to import the PKCS#12 file (from dogtag-jss-tools package). If not installed: sudo dnf install dogtag-jss-tools. If unavailable, you can try pk12util -i, though it may not support all PKCS#12 encryption modes.

HSM Compatibility Verified! Your HSM supports all required KRA cryptographic operations for traditional (RSA/EC) algorithms.

4.4. Quick Start: HSM with PQC (Most Common)

Purpose: Verify your HSM supports post-quantum (ML-DSA/ML-KEM) key archival and recovery for KRA.

Requirements: NSS 3.123+, JSS 5.10+

4.4.1. Step 1: Setup PQC Certificates on HSM (Run Once)

# Create HSM password file (if not already created)
$ echo "HSMPassword123" > serv/hsm.pwd

# Setup PQC CA, transport, and storage certificates on HSM
$ hsmCompatVerifyServ --setup-only \
  --pqc \
  --pkiserv-db-path serv \
  --pkiserv-passwd-file serv/nss.pwd \
  --hsm-token "myHSM" \
  --hsm-token-passwd-file serv/hsm.pwd \
  --verbose

Expected Output:

  • ML-DSA-65 CA certificate created (self-signed) on HSM

  • ML-KEM-768 Transport certificate created on HSM

  • ML-KEM-768 Storage certificate created on HSM

  • serv/kra_transport.pem and serv/kra_storage.pem exported

4.4.2. Step 2: Generate Client PQC Keys

$ hsmCompatVerifyClnt \
  --pqc \
  --client-db-path clnt \
  --client-passwd-file clnt/nss.pwd \
  --transport-cert serv/kra_transport.pem \
  --user-key-type ML-KEM \
  --pqc-kem-algorithm ml-kem-768 \
  --verbose

Expected Output Files:

clnt/kra-test-kem-ciphertext.bin  (1088 bytes - ML-KEM-768 ciphertext)
clnt/kra-test-wrapped-private.bin (2512 bytes - AES-KWP wrapped ML-KEM private key)
clnt/kra-test-public.der          (1184 bytes - ML-KEM-768 public key)

4.4.3. Step 3: Verify HSM PQC Compatibility (Combined Archive + Recovery)

$ hsmCompatVerifyServ \
  --pqc \
  --pkiserv-db-path serv \
  --client-db-path clnt \
  --hsm-token "myHSM" \
  --hsm-token-passwd-file serv/hsm.pwd \
  --subject-dn "CN=Test PQC User" \
  --p12-output clnt/recovered.p12 \
  --recovery-passwd-file clnt/recover.pwd \
  --user-key-type ML-KEM \
  --verbose

What Happened (all on HSM):

  1. ML-KEM decapsulation with transport private key (recovers shared secret)

  2. User ML-KEM private key unwrapped successfully (AES-KWP)

  3. User certificate created and signed by ML-DSA CA

  4. ML-KEM encapsulation with storage public key (generates new shared secret)

  5. User private key re-wrapped with storage shared secret

  6. LDIF file created: clnt/kra-archived-key.ldif

  7. ML-KEM decapsulation with storage private key

  8. User ML-KEM private key recovered

  9. PKCS#12 file created: clnt/recovered.p12

4.4.4. Step 4: Verify PKCS#12 File

# Inspect PKCS#12 contents
$ pk12util -l clnt/recovered.p12 -w clnt/recover.pwd

# Import using p12tool (recommended)
$ mkdir -p test-import
$ echo "Secret.123" > test-import/nss.pwd
$ certutil -N -d test-import -f test-import/nss.pwd
$ p12tool -i clnt/recovered.p12 -d test-import -w clnt/recover.pwd

# Verify import
$ certutil -L -d test-import
$ certutil -K -d test-import
Note
Use p12tool -i to import the PKCS#12 file (from dogtag-jss-tools package). If not installed: sudo dnf install dogtag-jss-tools. If unavailable, you can try pk12util -i, though it may not support all PKCS#12 encryption modes.

HSM PQC Compatibility Verified! Your HSM supports all required KRA cryptographic operations for post-quantum (ML-DSA/ML-KEM) algorithms.

5. Part 1: Traditional Cryptography (RSA/EC) - Detailed Workflows

This section provides detailed workflows for advanced testing scenarios.

For most users: Use the Quick Start Guide above with combined archive+recovery.

5.1. Workflow A: Advanced Multi-Token Configuration

This example shows CA on HSM and KRA on internal NSS DB - an interim test deployment pattern where your HSM is incapable of doing AES-KWP.

5.1.1. Step 1: Setup with Multi-Token Mode

$ hsmCompatVerifyServ --setup-only \
  --pkiserv-db-path serv \
  --pkiserv-passwd-file serv/nss.pwd \
  --ca-token "myHSM" \
  --ca-token-passwd-file serv/hsm.pwd \
  --kra-token "" \
  --kra-token-passwd-file serv/nss.pwd \
  --verbose
Note
Use --ca-token "" for internal NSS DB, or "tokenName" for HSM. Same applies to --kra-token.

5.1.2. Steps 2-4: Same as Quick Start

Follow Steps 2-4 from the Quick Start Guide, but use the multi-token flags:

  • Replace --hsm-token "myHSM" with --ca-token "myHSM" --kra-token ""

  • Use --ca-token-passwd-file serv/hsm.pwd --kra-token-passwd-file serv/nss.pwd

5.2. Workflow B: Separate Archive and Recovery Phases

When to use this workflow:

  • Testing or debugging individual archival and recovery operations

  • Simulating KRA’s LDIF-based key archival/recovery process

  • Understanding the internals of KRA key wrapping mechanisms

  • Batch testing multiple recovery scenarios from the same archived LDIF

This workflow assumes you’ve already completed the Quick Start Guide’s Initial Setup and Step 1-2 (setup certificates and generate client keys).

If starting fresh, complete those steps first before continuing here.

5.2.1. Step 3a: Archive Only (--archive-only)

Unwrap the user’s private key from transport wrapping, re-wrap with storage key, and create LDIF entry.

$ hsmCompatVerifyServ --archive-only \
  --pkiserv-db-path serv \
  --client-db-path clnt \
  --hsm-token "myHSM" \
  --hsm-token-passwd-file serv/hsm.pwd \
  --subject-dn "CN=Test User" \
  --verbose

Expected Output:

  • Session key unwrapped using transport private key (HSM)

  • User private key unwrapped successfully

  • User certificate created and signed by CA

  • New session key generated for storage wrapping

  • User private key re-wrapped with storage session key

  • Session key wrapped with storage public key

  • LDIF file created: clnt/kra-archived-key.ldif (contains certificate + wrapped key data)

5.2.2. Step 3b: Recovery Only (--recover-only)

Read archived key from LDIF, unwrap with storage key, and export to PKCS#12 file for user.

$ hsmCompatVerifyServ --recover-only \
  --pkiserv-db-path serv \
  --client-db-path clnt \
  --hsm-token "myHSM" \
  --hsm-token-passwd-file serv/hsm.pwd \
  --p12-output clnt/recovered.p12 \
  --recovery-passwd-file clnt/recover.pwd \
  --verbose

Expected Output:

  • Loaded certificate + wrapped keys from LDIF

  • Session key unwrapped using storage private key (HSM)

  • User private key unwrapped successfully

  • PKCS#12 file created: clnt/recovered.p12

Verification: See the Quick Start Guide’s Step 4 for PKCS#12 verification steps.

6. Part 2: Post-Quantum Cryptography (ML-DSA/ML-KEM) - Detailed Workflows

This section provides detailed workflows for advanced PQC testing scenarios.

For most users: Use the Quick Start Guide’s PQC section above.

6.1. Workflow A: Advanced Multi-Token Configuration (PQC)

This example shows CA on HSM and KRA on internal NSS DB - e.g. an interim test deployment pattern where your HSM is capable of handling ml-dsa but does not handle persistant ml-kem key operations (encapsulation/decapsulation).

6.1.1. Step 1: Setup with Multi-Token Mode (PQC)

$ hsmCompatVerifyServ --setup-only \
  --pqc \
  --pkiserv-db-path serv \
  --pkiserv-passwd-file serv/nss.pwd \
  --ca-token "myHSM" \
  --ca-token-passwd-file serv/hsm.pwd \
  --kra-token "" \
  --kra-token-passwd-file serv/nss.pwd \
  --verbose

6.1.2. Steps 2-4: Same as PQC Quick Start

Follow Steps 2-4 from the PQC Quick Start Guide, but use the multi-token flags:

  • Replace --hsm-token "myHSM" with --ca-token "myHSM" --kra-token ""

  • Use --ca-token-passwd-file serv/hsm.pwd --kra-token-passwd-file serv/nss.pwd

  • Add --pqc and --user-key-type ML-KEM flags

6.2. Workflow B: Separate Archive and Recovery Phases (PQC)

When to use this workflow:

  • Testing or debugging individual PQC archival and recovery operations

  • Understanding ML-KEM encapsulation/decapsulation internals

  • Batch testing multiple PQC recovery scenarios from the same archived LDIF

This workflow assumes you’ve already completed the Quick Start Guide’s PQC Initial Setup and Steps 1-2 (setup PQC certificates and generate client ML-KEM keys).

If starting fresh, complete those steps first before continuing here.

6.2.1. Step 3a: Archive Only (--archive-only) for PQC

Decapsulate shared secret, unwrap user’s ML-KEM key, re-encapsulate with storage key, and create LDIF entry.

$ hsmCompatVerifyServ --archive-only \
  --pqc \
  --pkiserv-db-path serv \
  --client-db-path clnt \
  --hsm-token "myHSM" \
  --hsm-token-passwd-file serv/hsm.pwd \
  --subject-dn "CN=Test PQC User" \
  --user-key-type ML-KEM \
  --verbose

Expected Output:

  • ML-KEM decapsulation with transport private key (HSM)

  • User ML-KEM private key unwrapped successfully

  • User certificate created and signed by ML-DSA CA

  • ML-KEM encapsulation with storage public key (generates new shared secret)

  • User private key re-wrapped with storage shared secret

  • LDIF file created: clnt/kra-archived-key.ldif

6.2.2. Step 3b: Recovery Only (--recover-only) for PQC

Read archived key from LDIF, decapsulate with storage key, unwrap user key, and export to PKCS#12.

$ hsmCompatVerifyServ --recover-only \
  --pqc \
  --pkiserv-db-path serv \
  --client-db-path clnt \
  --hsm-token "myHSM" \
  --hsm-token-passwd-file serv/hsm.pwd \
  --p12-output clnt/recovered.p12 \
  --recovery-passwd-file clnt/recover.pwd \
  --user-key-type ML-KEM \
  --verbose

Expected Output:

  • Loaded certificate + wrapped keys from LDIF

  • ML-KEM decapsulation with storage private key (HSM)

  • User ML-KEM private key unwrapped successfully

  • PKCS#12 file created: clnt/recovered.p12

Verification: See the Quick Start Guide’s Step 4 for PKCS#12 verification steps.

7. Key Highlights

7.1. What’s New in v11.10

  • ML-DSA CA Support: Full support for ML-DSA (FIPS 204) signing certificates

  • ML-KEM Transport/Storage: ML-KEM (FIPS 203) for quantum-resistant key wrapping

  • Multi-Token Support: CA and KRA keys can be on different HSM tokens

  • Improved Key Usage: Correct key usage extensions for ML-DSA (signature-only) certificates

7.2. Algorithm Support Summary

Key Type Traditional (RSA/EC) Post-Quantum (PQC)

CA Signing

RSA-4096 or EC-nistp256

ML-DSA-65

Transport

RSA-2048

ML-KEM-768

Storage

RSA-2048

ML-KEM-768

User Keys

RSA-2048/4096, EC-nistp256

ML-KEM-768, ML-DSA-65

7.3. Cryptographic Operations

Traditional (RSA/EC):

  • RSA-OAEP: Session key wrapping with transport/storage public keys

  • AES-256-KWP: Private key wrapping (RFC 5649, FIPS-compliant)

  • AES-256-KWP: PKCS#12 private key encryption (default --pkcs12-mode kwp)

Post-Quantum (ML-DSA/ML-KEM):

  • ML-KEM encapsulation/decapsulation: Post-quantum key establishment

  • AES-256-KWP: Private key wrapping

  • AES-256-KWP: PKCS#12 private key encryption (default --pkcs12-mode kwp)

Alternative PKCS#12 modes:

  • --pkcs12-mode cbc: PBKDF2 + AES-256-CBC (for compatibility)

  • --pkcs12-mode legacy: PBE_SHA1_DES3_CBC (legacy only, not recommended)

7.4. Token Configuration Modes

Single-Token Mode:

Use --hsm-token when all certificates (CA, transport, storage) are on the same HSM token.

Multi-Token Mode:

Use --ca-token and --kra-token when CA and KRA certificates are on different tokens. This is useful for:

  • Separating CA and KRA security domains

  • Using HSM for CA and software token for KRA (or vice versa)

  • Testing different HSM configurations

8. Troubleshooting

8.1. NSS/JSS Version Check

# Check NSS version (should be 3.123+)
$ rpm -q nss

# Check for ML-KEM support
$ nss-build-flags | grep -i ml-kem

# Check JSS version (should be 5.10+)
$ rpm -q jss

8.2. Common Issues

Issue: ML-KEM key generation fails

Solution: Verify NSS 3.123+ is installed and ML-KEM support is enabled


Issue: PKCS#12 export fails for ML-KEM keys with AES-KWP mode

Solution: Try --pkcs12-mode cbc instead of --pkcs12-mode kwp if the token does not support AES-KWP


Issue: p12tool command not found

Solution: Install dogtag-jss-tools package:

sudo dnf install dogtag-jss-tools

Issue: Cannot import recovered.p12 file

Solution: Use p12tool -i instead of pk12util -i. The p12tool utility supports all PKCS#12 encryption modes. If p12tool is unavailable, try pk12util -i or use --pkcs12-mode cbc or --pkcs12-mode legacy when creating the PKCS#12 file.

p12tool -i clnt/recovered.p12 -d test-import -w clnt/recover.pwd

Issue: Multi-token setup fails with "token not found"

Solution: Verify HSM tokens are properly configured in NSS:

$ modutil -list -dbdir serv

Clone this wiki locally