Showing posts with label Smart Card Shell 3. Show all posts
Showing posts with label Smart Card Shell 3. Show all posts

Encrypting files using AES keys on SmartCard HSM or Nitrokey HSM2 without key derivation

Table of Contents

  1. Overview
  2. Prerequisites
  3. Installation
  4. Configuration
  5. AES Key Generation
  6. Testing AES Keys
  7. Encryption/Decryption Scripts
  8. Usage Examples
  9. Important Notes
  10. Troubleshooting
  11. Security Considerations
  12. Conclusion

Overview

This guide explains how to use AES keys with your SmartCard HSM (Identiv uTrust 3512) for encryption and decryption operations.

What This Guide Covers

Primary Use Cases:

  • File Encryption/Decryption: Encrypt and decrypt files using AES keys stored on the SmartCard HSM. Files are transferred to the HSM token where encryption/decryption operations are performed, ensuring no sensitive data remains on the host system.
  • Data Protection: Secure sensitive data with hardware-backed AES encryption
  • Key Management: Generate, store, and manage AES keys on the HSM token
  • Multi-Token Deployment: Export and import AES keys across multiple SmartCard HSM tokens

Supported Operations:

  • AES-CBC encryption and decryption
  • AES-CMAC message authentication
  • Key wrapping and unwrapping
  • Key derivation (SP800-56C)

What This Guide Does NOT Cover:

  • RSA or ECC key operations (different guide)
  • Key derivation for file encryption
  • SSH key management (different use case)
  • Certificate operations (separate topic)

Target Applications:

  • Data at Rest Protection: Secure storage of sensitive files and databases with hardware-backed encryption
  • Secure file storage and transmission
  • Database encryption
  • Application-level data protection
  • Compliance requirements (FIPS, Common Criteria)

[WARNING] CRITICAL SECURITY WARNING: Before using AES keys on your SmartCard HSM, you must verify your firmware version. SmartCard HSM devices with firmware versions 3.1 and 3.2 have a critical bug that generates weak AES keys with little to no entropy. These keys must be considered broken and should not be used for any security operations. Read the advisory.

Required Action: SmartCard HSM and Nitrokey HSM2 - Update to firmware version 3.3 or later via the PKI-as-a-Service Portal before generating or using AES keys.

Note: RSA and ECC keys are not affected by this bug. Only AES key generation is impacted.

Prerequisites

Hardware Requirements

  • SmartCard HSM (Identiv uTrust 3512) with firmware version 3.3 or later
  • CCID-compatible card reader
  • USB connection

Software Requirements

  • Linux with PC/SC support
  • SmartCard HSM PKCS#11 library (MANDATORY) - OpenSC PKCS#11 library cannot detect or use AES keys on the token
  • OpenSC tools (pkcs11-tool)
  • SmartCard Shell3 (for AES key generation)

Firmware Verification

Before proceeding, verify your SmartCard HSM firmware version:

pkcs11-tool --module "/home/user/bin/sc-hsm-embedded-2.12/lib/libsc-hsm-pkcs11.so" \
    --show-info

Look for the firmware version in the output. If it shows version 3.1 or 3.2, you must update before using AES keys.

Installation

1. Install Development Tools

# Install development tools
sudo dnf groupinstall "Development Tools"
sudo dnf install autoconf automake libtool
sudo dnf install pcsc-lite-devel

2. Download and Compile SmartCard HSM PKCS#11 Library

[WARNING] CRITICAL: The SmartCard HSM PKCS#11 library is MANDATORY for AES key operations. The standard OpenSC PKCS#11 library cannot detect or use AES keys stored on the SmartCard HSM token.

# Download from GitHub releases
cd /tmp
wget https://github.com/CardContact/sc-hsm-embedded/releases/download/v2.12/\
    sc-hsm-embedded-2.12.tar.gz
tar -xzf sc-hsm-embedded-2.12.tar.gz
cd sc-hsm-embedded-2.12

# Configure and compile
autoreconf -fi
./configure --prefix=/home/user/bin/sc-hsm-embedded-2.12
make
make check
make install

Configuration

Environment Variables

# Set the module path
export SC_HSM_MODULE="/home/user/bin/sc-hsm-embedded-2.12/lib/libsc-hsm-pkcs11.so"
export HSM_SLOT=1

Token Detection

Verify your SmartCard HSM is detected using the SmartCard HSM PKCS#11 library (not OpenSC):

pkcs11-tool --module "/home/user/bin/sc-hsm-embedded-2.12/lib/libsc-hsm-pkcs11.so" \
    --list-token-slots

Expected output:

Available slots:
Slot 0 (0x1): Identiv uTrust 3512 SAM slot Token [CCID Interface] (55512030605)
  token label        : [REDACTED]-HISEC-1
  token manufacturer : CardContact (www.cardcontact.de)
  token model        : SmartCard-HSM
  token flags        : login required, rng, token initialized, PIN initialized

AES Key Generation

Important Note: AES Key Generation Method

AES keys on SmartCard HSM are generated and stored using SmartCard Shell3 software, not through direct PKCS#11 operations. The SmartCard Shell3 provides the interface for creating AES keys on the HSM token.

SmartCard Shell3 Requirements

  • GUI Version: SmartCard Shell3 GUI (scsh3gui) is the primary method for AES key generation
  • CLI Version: SmartCard Shell3 CLI (scsh3) has known card detection issues (see separate documentation)
  • Key Management: Keys are created through the SmartCard Shell3 Key Manager interface

Key Generation Process

  1. Launch SmartCard Shell3 GUI:
    cd /home/user/CardContact/scsh/scsh-3.18.55/
    ./scsh3gui
    
  2. Authenticate to the HSM:
    • Select your SmartCard HSM token
    • Enter your User PIN when prompted
  3. Access Key Manager:
    • Navigate to the Key Manager in the SmartCard Shell3 interface
    • Right-click on the appropriate key domain (e.g., DKEK share)
  4. Generate AES Key (presumably on the DKEK share):
    • Select "Generate Key" → "AES"
    • Choose key size (128, 192, or 256 bits)
    • Provide a label for the key
    • Select algorithms (AES-CBC, AES-CMAC, etc.)

Exporting AES Keys for Multiple Tokens

If you need to use the same AES key across multiple SmartCard HSM tokens that share the same DKEK, you can export the key:

  1. In the SmartCard Shell3 GUI, click on the AES key object in the list (PIN required)
  2. Right-click on the key and select "Wrap Key (and Certificate)"
  3. Save the key as a *.wky file
  4. Import the *.wky file on other tokens with the same DKEK share

Verifying Generated Keys

After generating AES keys via SmartCard Shell3, you can verify them using PKCS#11 tools, as shown below.

Testing AES Keys

List All AES Keys

Use the following script to list all AES keys on your token:

[WARNING] IMPORTANT: You may need to modify the following variables in the script to match your setup:

  • HSM_SLOT: The slot number where your SmartCard HSM is detected
  • SC_HSM_MODULE: Path to your SmartCard HSM PKCS#11 library

Save this script as list_aes_keys.sh:

#!/bin/bash
# list_aes_keys.sh

set -e

# Configuration
SC_HSM_MODULE="/home/user/bin/sc-hsm-embedded-2.12/lib/libsc-hsm-pkcs11.so"
HSM_SLOT=1

echo "=== AES Keys on SmartCard HSM ==="
echo "Library: $SC_HSM_MODULE"
echo "Slot: $HSM_SLOT"
echo

echo "Please enter your SmartCard HSM PIN when prompted:"

# List all secret key objects
echo "=== All Secret Key Objects ==="
pkcs11-tool --module "$SC_HSM_MODULE" \
    --slot $HSM_SLOT \
    --login \
    --list-objects \
    --type secrkey

echo
echo "=== Summary ==="
echo "The above shows all secret key objects on your SmartCard HSM token."
echo "Look for entries starting with 'Secret Key Object; AES' to find AES keys."
echo "Each AES key will show:"
echo "- Label (name)"
echo "- ID (unique identifier)"
echo "- Usage (encrypt, decrypt)"
echo "- Access (security attributes)"
echo

Usage:

chmod +x list_aes_keys.sh
./list_aes_keys.sh

Expected Output:

Secret Key Object; AES length 32
  label:      AES-1
  ID:         b20ba7e28e29c90f
  Usage:      encrypt, decrypt
  Access:     sensitive, always sensitive, never extractable, local
Secret Key Object; AES length 32
  label:      AES-2
  ID:         4eaa8024a063e8b6
  Usage:      encrypt, decrypt
  Access:     sensitive, always sensitive, never extractable, local

Encryption/Decryption Scripts

Simple AES Encryption Test

Save this script as aes_encrypt_simple.sh:

#!/bin/bash
# aes_encrypt_simple.sh

set -e

# Configuration
# [WARNING] IMPORTANT: Modify these variables to match your setup
SC_HSM_MODULE="/home/user/bin/sc-hsm-embedded-2.12/lib/libsc-hsm-pkcs11.so"
HSM_SLOT=1
AES_KEY_ID="b20ba7e28e29c90f"  # Use the ID from your AES key

echo "=== Simple AES-1 Encryption Test ==="
echo "Library: $SC_HSM_MODULE"
echo "Slot: $HSM_SLOT"
echo "Key ID: $AES_KEY_ID"
echo

# Create a test file with exactly 16 bytes (AES block size)
echo "Creating test data..."
echo -n "1234567890123456" > test_block.txt
echo "[INFO] Created test file with 16 bytes (AES block size)"

# Generate IV
echo "Generating IV..."
openssl rand -hex 16 > iv.txt
IV=$(cat iv.txt)
echo "[INFO] IV: $IV"

echo
echo "=== Attempting AES-CBC Encryption ==="
echo "Please enter your SmartCard HSM PIN when prompted:"

# Try encryption with the exact block size
pkcs11-tool --module "$SC_HSM_MODULE" \
    --slot $HSM_SLOT \
    --login \
    --encrypt \
    --mechanism AES-CBC \
    --iv "$IV" \
    --input-file test_block.txt \
    --output-file test_block.enc \
    --id "$AES_KEY_ID"

if [ $? -eq 0 ]; then
    echo "[SUCCESS] Encryption completed!"
    echo "[INFO] Encrypted file: test_block.enc"
    echo "[INFO] IV saved to: iv.txt"
else
    echo "[ERROR] Encryption failed"
fi

echo
echo "=== Test Complete ==="

Simple AES Decryption Test

Save this script as aes_decrypt_simple.sh:

#!/bin/bash
# aes_decrypt_simple.sh

set -e

# Configuration
# [WARNING] IMPORTANT: Modify these variables to match your setup
SC_HSM_MODULE="/home/user/bin/sc-hsm-embedded-2.12/lib/libsc-hsm-pkcs11.so"
HSM_SLOT=1
AES_KEY_ID="b20ba7e28e29c90f"  # Use the ID from your AES key

echo "=== Simple AES-1 Decryption Test ==="
echo "Library: $SC_HSM_MODULE"
echo "Slot: $HSM_SLOT"
echo "Key ID: $AES_KEY_ID"
echo

# Check if encrypted file exists
if [ ! -f test_block.enc ]; then
    echo "[ERROR] Encrypted file not found: test_block.enc"
    echo "Please run aes_encrypt_simple.sh first"
    exit 1
fi

# Check if IV file exists
if [ ! -f iv.txt ]; then
    echo "[ERROR] IV file not found: iv.txt"
    echo "Please run aes_encrypt_simple.sh first"
    exit 1
fi

IV=$(cat iv.txt)
echo "[INFO] Using IV: $IV"

echo
echo "=== Attempting AES-CBC Decryption ==="
echo "Please enter your SmartCard HSM PIN when prompted:"

# Try decryption
pkcs11-tool --module "$SC_HSM_MODULE" \
    --slot $HSM_SLOT \
    --login \
    --decrypt \
    --mechanism AES-CBC \
    --iv "$IV" \
    --input-file test_block.enc \
    --output-file test_block.dec \
    --id "$AES_KEY_ID"

if [ $? -eq 0 ]; then
    echo "[SUCCESS] Decryption completed!"
    echo "[INFO] Decrypted file: test_block.dec"
    
    # Verify decryption
    if diff test_block.txt test_block.dec > /dev/null; then
        echo "[SUCCESS] Decryption verified - files match!"
    else
        echo "[ERROR] Decryption failed - files don't match"
    fi
else
    echo "[ERROR] Decryption failed"
fi

echo
echo "=== Test Complete ==="

Complete AES Key Usage Script

Save this script as aes_encrypt_decrypt.sh:

#!/bin/bash

# Use the AES-1 key on SmartCard HSM for encryption/decryption
# The key was found with the new SmartCard HSM PKCS#11 library

set -e

# Configuration
# [WARNING] IMPORTANT: Modify these variables to match your setup
SC_HSM_MODULE="/home/user/bin/sc-hsm-embedded-2.12/lib/libsc-hsm-pkcs11.so"
HSM_SLOT=1
AES_KEY_LABEL="AES-1"  # Use the label from your AES key
AES_KEY_ID="b20ba7e28e29c90f"  # Use the ID from your AES key

echo "=== Using AES-1 Key on SmartCard HSM ==="
echo "Library: $SC_HSM_MODULE"
echo "Slot: $HSM_SLOT"
echo "Key Label: $AES_KEY_LABEL"
echo "Key ID: $AES_KEY_ID"
echo

# Function to encrypt a file using AES-1 key
encrypt_file() {
    local input_file="$1"
    local output_file="$2"
    
    echo "=== Encrypting with AES-1 Key ==="
    echo "Input: $input_file"
    echo "Output: $output_file"
    echo "Please enter your SmartCard HSM PIN when prompted:"
    
    # Generate a random IV (16 bytes for AES)
    echo "[INFO] Generating random IV..."
    openssl rand -hex 16 > iv.txt
    IV=$(cat iv.txt)
    echo "[INFO] IV: $IV"
    
    # Use AES-CBC encryption with the AES-1 key and IV
    pkcs11-tool --module "$SC_HSM_MODULE" \
        --slot $HSM_SLOT \
        --login \
        --encrypt \
        --mechanism AES-CBC \
        --iv "$IV" \
        --input-file "$input_file" \
        --output-file "$output_file" \
        --id "$AES_KEY_ID"
    
    if [ $? -eq 0 ]; then
        echo "[SUCCESS] File encrypted successfully"
        echo "[INFO] IV saved to iv.txt for decryption"
    else
        echo "[ERROR] Encryption failed"
        rm -f iv.txt
        return 1
    fi
}

# Function to decrypt a file using AES-1 key
decrypt_file() {
    local input_file="$1"
    local output_file="$2"
    local iv_file="${3:-iv.txt}"
    
    echo "=== Decrypting with AES-1 Key ==="
    echo "Input: $input_file"
    echo "Output: $output_file"
    echo "IV file: $iv_file"
    echo "Please enter your SmartCard HSM PIN when prompted:"
    
    if [ ! -f "$iv_file" ]; then
        echo "[ERROR] IV file not found: $iv_file"
        echo "Please provide the IV used for encryption"
        return 1
    fi
    
    IV=$(cat "$iv_file")
    echo "[INFO] Using IV: $IV"
    
    # Use AES-CBC decryption with the AES-1 key and IV
    pkcs11-tool --module "$SC_HSM_MODULE" \
        --slot $HSM_SLOT \
        --login \
        --decrypt \
        --mechanism AES-CBC \
        --iv "$IV" \
        --input-file "$input_file" \
        --output-file "$output_file" \
        --id "$AES_KEY_ID"
    
    if [ $? -eq 0 ]; then
        echo "[SUCCESS] File decrypted successfully"
    else
        echo "[ERROR] Decryption failed"
        return 1
    fi
}

# Function to test the AES-1 key with a simple operation
test_aes1_key() {
    echo "=== Testing AES-1 Key ==="
    echo "Please enter your SmartCard HSM PIN when prompted:"
    
    # Try to get key info
    pkcs11-tool --module "$SC_HSM_MODULE" \
        --slot $HSM_SLOT \
        --login \
        --list-objects \
        --type secrkey \
        --id "$AES_KEY_ID"
}

# Function to show usage
show_usage() {
    echo "Usage: $0 {encrypt|decrypt|test} [ ]"
    echo
    echo "Examples:"
    echo "  $0 test                           # Test AES-1 key"
    echo "  $0 encrypt test.txt test.txt.enc  # Encrypt file"
    echo "  $0 decrypt test.txt.enc test.txt.dec [iv.txt]  # Decrypt file"
    echo
    echo "The script uses the AES-1 key stored on your SmartCard HSM"
    echo "for AES-CBC encryption/decryption operations."
}

# Main script logic
case "${1:-}" in
    encrypt)
        if [ $# -ne 3 ]; then
            echo "[ERROR] Usage: $0 encrypt  "
            exit 1
        fi
        encrypt_file "$2" "$3"
        ;;
    decrypt)
        if [ $# -lt 3 ] || [ $# -gt 4 ]; then
            echo "[ERROR] Usage: $0 decrypt   [iv_file]"
            exit 1
        fi
        decrypt_file "$2" "$3" "${4:-}"
        ;;
    test)
        test_aes1_key
        ;;
    *)
        show_usage
        exit 1
        ;;
esac

echo
echo "=== Operation Complete ==="

Usage Examples

1. List AES Keys

./list_aes_keys.sh

2. Test Simple Encryption/Decryption

# Encrypt
./aes_encrypt_simple.sh

# Decrypt
./aes_decrypt_simple.sh

3. Use Complete Script

# Test key
./aes_encrypt_decrypt.sh test

# Encrypt file
./aes_encrypt_decrypt.sh encrypt myfile.txt myfile.txt.enc

# Decrypt file
./aes_encrypt_decrypt.sh decrypt myfile.txt.enc myfile.txt.dec

Important Notes

Data Requirements

  • Block Size: Data must be padded to AES block size (16 bytes)
  • IV Required: CBC mode requires an Initialization Vector
  • PIN Authentication: All operations require SmartCard HSM PIN

Security Features

  • Hardware Protection: Keys never leave the HSM in plaintext
  • PIN Protection: All operations require authentication
  • Key Export: Keys can be exported only between tokens sharing the same DKEK share

Supported Operations

  • AES-CBC Encryption/Decryption
  • AES-CMAC Signing
  • AES Key Generation (via SmartCard Shell3 GUI only)

Firmware Security Considerations

[WARNING] Critical HSM Firmware Bug (Versions 3.1-3.2):

  • SmartCard HSM and Nitrokey HSM2 devices with firmware versions 3.1 and 3.2 generate weak AES keys. Read the advisory.
  • These keys have little to no entropy and must be considered broken
  • Impact: Only affects AES key generation, not RSA or ECC keys
  • Solution: Be sure the tokens are running the latest firmware version. Check if newer version is available at PKI-as-a-Service-Portal, and install it before generating or using AES keys.

Update Process:

  1. Register an account at CardContact Developer Network (CDN)
  2. Create a firmware update request
  3. Select "Current token in reader" and submit
  4. Follow the portal instructions for the update process
  5. Important: All keys must be removed before firmware update
  6. After update, reinitialize the device and restore keys

Troubleshooting

Common Issues

  1. "CKR_FUNCTION_NOT_SUPPORTED"
    • Ensure data is padded to 16-byte blocks
    • Use exact block size for testing
  2. "CKR_USER_NOT_LOGGED_IN"
    • Enter PIN when prompted
    • Don't redirect output during PIN prompts
  3. "CKR_SLOT_ID_INVALID"
    • Use slot 1 instead of slot 0
    • Verify token is present

Security Considerations

Direct AES Storage vs Key Derivation

Aspect Direct AES Storage HSM Key Derivation
Key Storage AES key stored on HSM Salt stored on disk, key derived on-demand
Intermediate Data None Salt file, derived key file
Cold Boot Vulnerability Low (no temp files) Medium (temp files on disk)
Performance Fast (direct operations) Slower (derivation + operation)
Flexibility Fixed key Variable key from passphrase

Best Practices

  1. Authentication: Always authenticate before operations
  2. Data Padding: Ensure data fits AES block requirements
  3. IV Management: Use random IVs and store them securely
  4. Error Handling: Check return codes and handle failures
  5. Cleanup: Remove temporary files securely

Conclusion

This guide provides a complete workflow for using AES keys with your SmartCard HSM. The approach offers hardware-level security with direct AES operations, making it suitable for high-security applications where key protection is critical.

Technical Summary

  1. AES Key Generation: SmartCard Shell3 GUI required for key generation; PKCS#11 direct operations not supported
  2. Firmware Security: Version 3.3+ mandatory due to weak key generation vulnerability in versions 3.1-3.2
  3. Security Architecture: Hardware-protected AES keys with mandatory PIN authentication for all operations
  4. CLI Implementation: SmartCard Shell3 CLI exhibits card detection failures due to initialization sequence differences
  5. Firmware Update Protocol: Requires complete key removal and device reinitialization post-update

SmartCard Shell3 3.18.72 CLI - HSM Card Detection Issue

This document provides a comprehensive technical analysis of the SmartCard Shell3 3.18.72 CLI card detection issue, where the CLI cannot detect the SmartCard HSM card despite the card being present and accessible via PC/SC and GUI interfaces.

Table of Contents

Problem Statement

The SmartCard Shell3 3.18.72 CLI cannot detect the SmartCard HSM card, even though the card is present and accessible via PC/SC and GUI.

This issue prevents the CLI from performing any card operations, including authentication, object inspection, and key management, while the GUI works perfectly with the same card and scripts.

System Environment

Hardware Configuration

  • SmartCard HSM: Identiv uTrust 3512 SAM slot Token
  • Interface: CCID Interface (55512033274236)
  • Status: Card inserted, Shared Mode
  • Manufacturer: CardContact (www.cardcontact.de)
  • Token Label: LABEL-1

Operating System

  • OS: Linux 5.14.0-570.26.1.el9_6.x86_64
  • Distribution: Red Hat Enterprise Linux 9 (RHEL 9)
  • User: [REDACTED]
  • Working Directory: /home/user/tmp/test-05

Key Components

  • PC/SC Daemon: pcscd V 1.6.2 (Running)
  • PC/SC Library: /usr/lib64/libpcsclite.so
  • SmartCard Shell3: Version 3.18.72 at /home/user/CardContact/scsh/scsh-3.18.72/
  • SmartCard HSM PKCS#11 Library: Version 2.12 at /home/user/bin/sc-hsm-embedded-2.12/
  • Java: OpenJDK with SmartCard support

Evidence

1. Card is Present and Accessible

PC/SC can detect the card:

$ pcsc_scan Reader 0: Identiv uTrust 3512 SAM slot Token [CCID Interface] (55512033274236) 00 00 Card state: Card inserted, Shared Mode ATR: 3B DE 96 FF 81 91 FE 1F C3 80 31 81 54 48 53 4D 31 73 80 21 40 81 07 92

PKCS#11 library can access the card:

$ pkcs11-tool --module /home/user/bin/sc-hsm-embedded-2.12/lib/libsc-hsm-pkcs11.so --list-token-slots Available slots: Slot 0 (0x1): Identiv uTrust 3512 SAM slot Token [CCID Interface] (55512033274) token label : LABEL-1 token manufacturer : CardContact (www.cardcontact.de) token model : SmartCard-HSM

2. GUI Can Access and Edit Card Objects

GUI successfully connects and performs all operations:

$ ./scsh3gui # GUI successfully connects to card, authenticates, and can: # - View all stored objects (keys, certificates, data) # - Generate new keys # - Import/export certificates # - Modify card contents # - Perform all card operations normally

3. CLI Cannot Detect the Card

Error when trying to access card via CLI:

$ echo 'var card = new Card(); print(card.isCardPresent());' | java -Dsun.security.smartcardio.t1GetResponse=false -Dorg.bouncycastle.asn1.allow_unsafe_integer=true -Djava.library.path=./lib -classpath 'lib/*' de.cardcontact.scdp.engine.CommandProcessor

GPError: Card (CARD_CONNECT_FAILED/0) - "No card in reader or mute card."

Root Cause Analysis

1. Different Main Classes

CLI Startup:

java -Dsun.security.smartcardio.t1GetResponse=false -Dorg.bouncycastle.asn1.allow_unsafe_integer=true -Djava.library.path=./lib -classpath 'lib/*' de.cardcontact.scdp.engine.CommandProcessor

GUI Startup:

java -Dsun.security.smartcardio.t1GetResponse=false -Dorg.bouncycastle.asn1.allow_unsafe_integer=true -Djava.library.path=./lib -classpath 'lib/*' de.cardcontact.scdp.scsh3.GUIShell

Key Difference: CommandProcessor vs GUIShell

2. Different Initialization Sequences

GUI Initialization:

  1. Changes working directory: cd $(dirname $0)
  2. Loads opencard.properties configuration
  3. Initializes SmartCardIO factory: de.cardcontact.opencard.terminal.smartcardio.SmartCardIOFactory
  4. Sets up card service factories

CLI Initialization:

  1. No working directory change
  2. May not load opencard.properties
  3. May not initialize card services properly
  4. Different card access method

3. OpenCard Framework Configuration

GUI uses opencard.properties:

OpenCard.terminals = de.cardcontact.opencard.terminal.smartcardio.SmartCardIOFactory OpenCard.services = de.cardcontact.opencard.factory.SmartCardHSMCardServiceFactory

CLI may not load this configuration properly.

Technical Details

Card Access Methods

  1. PC/SC (Working): Direct PC/SC library access
  2. PKCS#11 (Working): SmartCard HSM PKCS#11 library
  3. SmartCard Shell3 GUI (Working): OpenCard Framework with SmartCardIO
  4. SmartCard Shell3 CLI (Broken): OpenCard Framework with different initialization

Error Analysis

Error: "No card in reader or mute card"

Possible Causes:

  1. Card Service Not Initialized: CLI doesn't load the proper card service factory
  2. Terminal Factory Not Configured: CLI doesn't use SmartCardIO factory
  3. Working Directory Issue: CLI doesn't change to proper directory
  4. Class Loading Issue: CLI can't load required card access classes

Attempted Solutions

1. Set PCSC Library Path

java -Dsun.security.smartcardio.library=/usr/lib64/libpcsclite.so ...

Result: ❌ Still fails

2. Set OpenCard Properties

java -DOpenCard.terminals="de.cardcontact.opencard.terminal.smartcardio.SmartCardIOFactory" ...

Result: ❌ Still fails

3. Kill Competing Processes

pkill -f "ssh-pkcs11-help"

Result: ❌ Still fails

4. Use GUI Working Directory

cd $(dirname $0) && java ...

Result: ❌ Class loading fails

Working Solutions

1. Hybrid Approach (Recommended)

Use GUI for card access, CLI for scripting:

# Terminal 1: Start GUI and authenticate ./scsh3gui # Select token, load keymanager, enter PIN # Keep GUI running # Terminal 2: Run CLI script echo 'load("test_card_script.js")' | java -Dsun.security.smartcardio.t1GetResponse=false -Dorg.bouncycastle.asn1.allow_unsafe_integer=true -Djava.library.path=./lib -classpath 'lib/*' de.cardcontact.scdp.engine.CommandProcessor

2. Pure GUI Approach

Use GUI directly for all operations:

./scsh3gui # Select token, load keymanager, enter PIN # Navigate to card objects # Right-click → Perform card operations

Impact on Card Operations

Since CLI cannot detect the card, it cannot:

  • Create card connections
  • Authenticate to the HSM
  • Perform any card operations
  • Access existing objects on the card

Any card operations via CLI are impossible until the card detection issue is resolved.

Conclusion

The CLI cannot detect the card because:

  1. Different Main Class: CommandProcessor vs GUIShell
  2. Different Initialization: CLI doesn't load proper card services
  3. Different Configuration: CLI may not use opencard.properties
  4. Different Working Directory: CLI doesn't change directory like GUI

The fundamental issue is that the CLI's card access initialization is broken or incomplete compared to the GUI.

Solution: Use the hybrid approach where GUI provides card access context for CLI scripting, or use GUI directly for all operations.

Summary

  • Hardware: Identiv uTrust 3512 SmartCard HSM with CCID interface
  • OS: RHEL 9 with PC/SC infrastructure
  • Tools: SmartCard Shell3 3.18.72 + PKCS#11 library 2.12
  • Status: GUI working, CLI broken for card detection
  • Issue: CLI cannot detect card due to different initialization
  • Solution: Use hybrid approach (GUI + CLI) or GUI only

What to do when an HSM token with a large number of stored certificates (or more than one HSM tokens are connected) prevents the SSH agent from using the correct key for SSH authentication on Linux

Many advanced Linux users have been struggling to get rid of one quite annoying situation - the interference between multiple HSM tokens connected to one system. Think about the situation when one token is only needed for SSH authentication and the other token is only needed for S/MIME and web authentication. If each of the tokens contains only one X.509v3 certificate and its private key, things should be fine and in that particular case the command line:

ssh-add -s /usr/lib64/opensc-pkcs11.so

will connect only two of the keys to the SSH agent.

But what if the HSM token hosts four certificates or more than one HSM token is services by the same PKCS#11 library? In that case, during the SSH authentication process, the SSH agent will try the available private keys one after another until the server accepts any of the keys as the proper authentication token. If you have too many keys in the HSM token, the ssh client will be involved in too many authentication attempts, and as a result, the SSH server will terminate the user's authentication. Of course, the latter also depends on the SSH server-side configuration, but the defaults are not in favour of executing multiple key tests.

How to solve this issue?

First, let's start with brining forward the bad news - there exists no definitive resolution in all instances. A workaround is only available. The workaround is not something compex - simply attach the HSM token that contains the key used for SSH authentication before the other HSM tokens, and execute:

ssh-add -s /usr/lib64/opensc-pkcs11.so

Afterwards, you may add as many HSM tokens as you wish to the Linux system. But only the first hinted HSM token will be used to operate with the SSH agent.

Now some details and more information about the process of using HSM tokens for authentication/signing. Read the information below if you are interested in those details.

The X.509v3 certificates get installed inside the HSM protected memory slots along with their private keys. To help the application with the access to that slots, a dedicated PKCS#11 module (library) is needed. In most cases, we employ the PKCS#11 module as a low-level backend in both direction. First, we transfer each X.509v3 certificate along with its private key to the protected memory inside the HMS token, reading that information from PKCS#12 files. Once the keys are stored inside the protected memory of the HSM token, we employ the PKCS#11 module to point the applications to the location of the installed private keys. Note that the applications never obtain direct access to the private keys. Instead, they send some computed hash to the crypto processor inside the HSM token, asking it to sign (encrypt) that hash with a private key with a certain ID (PKCS#12 module communicates those IDs to the application in advance).

Storing multiple keys inside HSM tokens always depends on the token model itself. Some tokens allow the use of multiple slots for signing and authentication, while some do not. The link below shows a good example of tokens that can store multiple X.509v3 certificates in their protected memory:

https://www.cardomatic.de/c/smartcard-hsm

Those brand of tokens can be programmed by using Smart Card Shell 3.

Even though the Yubico PIV tokens are popular, they cannot store multiple X.509v3 certificates and their corresponding private keys. While it is true that those PIV devices come with four slots, each slot has a different purpose, and only one of them can be employed for authentication. Which does not mean Yubico PIV tokens are not as good as the others. They just cannot store more than one certificate/key per dedicated slot. You may try to examine that by running the YubiKey Manager (Ykman) - it shows the four slots and reveals their purpose.

Regardless of the HSM management application, installation of X.509v3 certificates into the HSM tokens does not bring therein the corresponding certificate chains (even if those chains are stored in the original PKCS#12 blocks). The S/MIME client or browser that uses HSM tokens for signing or authentication is responsible for bringing the missing chain certificates into the signing or authentication process. Certificates included in chains are usually installed into special local files accessible and manageable by processing software cryptographic storage. Different programs rely on different file backends for saving and accessing the certificates needed to finish the chains when asked. For instance, Firefox, regardless of the OS environment, always employs Mozilla's NSS Shared DB files for that purpose. While running on Linux, Brave and Chrome for Linux also rely on Mozilla's NSS Shared DB. However, in the event that they are running on Windows, the Windows Certificate Store is utilized as a means of searching for certificates to complete the chain.

If you possess an HSM token that contains more than three X.509v3 certificates installed and accessible through PKCS#11 library, it is not recommended to use that token for SSH authentication. That advice is based on the way the ssh client utilizes the private keys during the authentication process.

What is the good practice to follow when preparing an HSM token, which will be used for SSH authentication only? Store only one certificate, which should be self-signed one. That self-signed X.509v3 certificate must be based on the originally generated SSH key pair stored under the ~/.ssh folder, and should be created and then inserted into the HSM token based on a PKCS#12 file. To create the self-signed certificate, simply run the command line:

openssl req -sha384 -x509 -key ~/.ssh/id_ecdsa -out ~/vesso@ssh-ecdsa.crt -subj "/CN=vesso@ssh-ecdsa" -days 3650

The self-signed certificate will be stored in ~/vesso@ssh-ecdsa.crt. Then compiose the PKCS#12 file:

openssl pkcs12 -export -legacy -key ~/.ssh/id_ecdsa -in ~/vesso@ssh-ecdsa.crt -name "vesso@ssh-ecdsa" -out vesso@ssh-ecdsa.p12

If you want to store that certificate and its private key onto your HSM key, use the appropriate device manager to import the content of the PKCS#12 file into the protected memory of the HSM token. If that is one of the HSM tokens mentioned above, adopt Smart Card Shell 3 for the import. In case you would like to use Yubico PIV token, then rely on the Yukman.

What to do if Smart Card Shell (scsh) cannot detect HSM tokens connected to RHEL9 or Rocky 9 installation

The HSM management through scsh on RHEL9 (incl Rocky 9) may pose a challenge due to an issue with the manner in which that Linux distribution installs PCSC Lite components. Consequently, neither the scsh command line tool nor scsh3gui are capable of recognizing the HSM tokens that have already been connected to the system.

The problem is caused by the set of libraries that are installed by default when smart card support is enabled on the distribution through the package system. That support implies the installation of libpcsclite.so.1 instead of libpcsclite.so. To make scsh recognize the connected HSM tokens, one should find a way to bring libpcsclite.so into the system, which is required by Java OpenJDK for successful execution of scsh classes.

Now, in greater details. By enabling smart card support, the package management system installs those two packages:

pcsc-lite
pcsc-lite-libs

as well as their dependencies. Here pcsc-lite-libs only provides:

/usr/lib64/libpcsclite.so.1

None of the above provides:

/usr/lib64/libpcsclite.so

At this juncture, it is advised to refrain from creating manually libpcsclite.so as a symlink to libpcsclite.so.1, as it may result in interference with the package system. There is a much more proper way to bring libpcsclite.so to the system:

dnf install pcsc-lite-devel

Installing pcsc-lite-devel just creates the necessary symlink and registers it in the RPM database.

SmartCard-HSM USB token: Using Smart Card Shell 3 for initializing and configuring the token, generating key pairs, and importing keys and X.509 certificates from external PKCS#12 containers

Content:

  1. Introduction
  2. Prerequisites
  3. Downloading and installing Smart Card Shell 3
  4. Running Smart Card Shell 3 GUI
  5. Loading the key manager in Smart Card Shell 3 GUI
  6. Initializing the token and configuring DKEK to enable the import of keys and X.509 certificates from PKCS#12 files
  7. Generating ECC key pair (by means of DKEK shares)
  8. Importing key pair and the corresponding X.509 certificate from PKCS#12 file into the token (by means of DKEK shares)

 

1. Introduction

The SmardCard-HSM (Standard-A USB) token (you can order it online):

is a reliable, fast, secure, and OpenSC compatible HSM device, for generating, storing, and importing RSA, AES, and Elliptic Curve (EC) keys and X.509 certificates. Maybe, the best feature of the device is its enhanced support for EC (up to 521-bit keys), and the ability to import key pairs and certificates from PKCS#12 containers. Later allows to clone a key pair into several token devices, as a hardware backup scenario.

Unfortunately, the vendor does not provide (yet) a comprehensive documentation for end users, describing in details the specific process of importing key pairs and X.509 certificates from PKCS#12 containers (files) into the token (which is something very much in demand). Therefore, the goal of this document is to fix (at least partially) that gap in the documentation.

Note, that the procedures, described above, are not part of the everyday practice. They are required only for initializing the token device, generating EC keys for curves that are not currently listed as supported in the token's firmware (for instance, secp384r1 curve is supported by the token's processor, but not listed as supported in the firmware and the OpenSC based tools cannot request secp384r1 key generation), and to import key pairs and X.509 certificates from PKCS#12 files.

 

2. Prerequisites

To be able to follow the steps given below, you need to have installed and updated Linux distribution, running a Graphical Desktop environment (GNOME, KDE). Recent OpenJDK (17 is recommended if available) must be installed and kept updated. Do not install OpenJDK manually, since it is an essential software package! Always use the package manager, provided by the vendor of your Linux distribution to install or update OpenJDK:

  • RHEL7, CentOS 7, Scientific Linux 7:

    # yum install java-11-openjdk.x86_64
  • Fedora (current), RHEL8/9, CentOS 8, Scientific Linux 8, Rocky Linux 8/9, Alma Linux 9:

    # dnf install java-17-openjdk.x86_64
  • Ubuntu:

    # apt-get install openjdk-17-jdk-headless

It is not a good idea to configure the HSM token and manage its content on a system, that is used for social networking, software testing, gaming, or any other activity, that might be considered risky in this case. Always use a dedicated desktop system (or dedicated Linux virtual machine) for managing your PKI infrastructure.

You might have more than one version of OpenJDK installed on your system. So the first step is to check that and set the latest OpenJDK as a default Java provider. Execute the following command line (be super user or root):

# alternatives --config java

to check how many Java packages (provides) are installed and available locally, and which one of them is set as current default. For example, the following result:

There are 2 programs which provide 'java'.

  Selection    Command
-----------------------------------------------
*+ 1           java-11-openjdk.x86_64 (/usr/lib/jvm/java-11-openjdk-11.0.19.0.7-1.el9_1.x86_64/bin/java)
   2           java-17-openjdk.x86_64 (/usr/lib/jvm/java-17-openjdk-17.0.7.0.7-1.el9_1.x86_64/bin/java)


Enter to keep the current selection[+], or type selection number:

means there are two OpenJDK packages installed, and the first one is set a default Java provider (see which is the entry marked with "+" in the first column). To set OpenJDK 17 default Java provider, type the ID number assigned to the package in the list (in the "Selection" column) and press "Enter" afterwards (in the above example, the ID used is 2):

Enter to keep the current selection[+], or type selection number: 2

It is always a good idea to check if the symlinks created by the alternatives tool points to the correct target. The simplest way to do so for OpenJDK 11 is to follow the symlink /etc/alternatives/java:

$ ls -al /etc/alternatives/java

and verify that the target is the OpenJDK 11 java executable:

lrwxrwxrwx. 1 root root 63 Apr 29 13:58 /etc/alternatives/java -> /usr/lib/jvm/java-17-openjdk-17.0.7.0.7-1.el9_1.x86_64/bin/java

Also check if the Java major version of the target:

$ java --version

is 17:

openjdk 17.0.7 2023-04-18 LTS
OpenJDK Runtime Environment (Red_Hat-17.0.7.0.7-1.el9_1) (build 17.0.7+7-LTS)
OpenJDK 64-Bit Server VM (Red_Hat-17.0.7.0.7-1.el9_1) (build 17.0.7+7-LTS, mixed mode, sharing)

Also, have pcscd running.

 

3. Downloading and installing Smart Card Shell 3

Be sure you have OpenJDK 17 installed, as specified above. Then visit the web page:

https://www.openscdp.org/scsh3/download.html

click on "IzPack Installer" link, and save locally the provided JAR archive of the installer.

Decide what kind of installation of Smart Card Shell 3 do you really need - to allow all users of the system to run the program code (run the installer as super user), or to limit that ability to a certain unprivileged user (perform the installation using that particular user ID):

  • run the installer as super user (root):

    You should install the program into a system folder, where the users can only read and execute the Java code (no write access should be given by default). That kind of restrictions will protect the executable code from deletion of modification.

  • run the installer as a non-privileged user:

    In this case, the simplest solution is to install the program into the home folder of the user. That type of installation is recommended only for a user, who really understands how to keep the executable code safe.

If followed, the steps given bellow will install the executable code of the program in the home folder of those user, who is executing the installer.

Open a terminal and type:

$ java -jar /path/to/scsh3.XX.YYY.jar

(here XX and YYY are numbers, unique for the current version). The following window will appear (press there the button "Next" to continue):

Select the installation folder (use the button "Browse" to change it, if you do not like the one suggested by the installer), and press "Next":

Now you will be able to see the progress of the installation process (press the button "Next" to continue, when it is done):

Next, you need to decide whether or not to create a shortcut to the program in the GNOME "Applications" menu (it is recommended to create such a shortcut), and who will be able to invoke the installed program (the last is useful only if you install the software as super user or root into a system folder). Press the button "Next":

and in the last window of the installer, press "Done" to exit:

Important note for those who are running Smart Card Shell 3 on RHEL9 (Rocky Linux 9, Alma Linux 9)!

Smart Card Shell 3 needs the library libpcsclite.so, but no package provides libpcsclite.so on RHEL9. To overcome that issue, install the package pcsc-lite-libs (if it is not already installed) and create the symlink /usr/lib64/libpcsclite.so that points to /usr/lib64/libpcsclite.so.1:

cd /usr/lib64
ln -s libpcsclite.so.1 libpcsclite.so

 

4. Running Smart Card Shell 3 GUI

Be sure the Smart Card Shell 3 GUI is installed. Expand the "Applications" menu (1), go to "Programming" (2), press there "Smart Card Shell 3" (3):

and wait for the appearance of the main window of the program:

During the first run, a new window might appear, asking for configuring the path to a working directory, where the output files will be stored by default. Click the "Browse" button:

select the folder (1) and press "Open" (2) to go back:

Thus path to the folder will appear in the text field (next to the "Browse" button). In addition, mark at least "Use this as the default and do not ask again", to complete the configuration and pressing "OK" to exit:

 

5. Loading the key manager in Smart Card Shell 3 GUI

Run Smart Card Shell 3 GUI. The key manager is a loadable script, dedicated to manage the objects in the token.

To load it, either expand "File" menu and select there "Key Manager":

or press "Ctrl+M". Once loaded, the key manager will check if the token is connected and will create in the main window a tree of those objects, it discovered in the token. Details about all important events will be reported in the "Shell" tab:

 

6. Initializing the token and configuring DKEK to enable the import of keys and X.509 certificates from PKCS#12 files

The goal of the initialization process, is to enable the import (export too) of keys and X.509 certificates, stored in files (most often PKCS#12 files), into the token, , based on "device-key-encryption-key" (DKEK) type of store. Note that DKEK is not enabled by default.

WARNING! DURING THE INITIALIZATION, ALL DATA, STORED IN THE TOKEN, WILL BE LOST!

To start with the initialization, run the Smart Card Shell 3, load the key manager script, click once with the right button of the mouse upon "SmartCard-HSM" (that is the root of the key manager tree), and select "Initialize Device" in the menu:

Supply the following information (or press "Cancel" to terminate the initialization):

  • The actual SO-PIN for configuring the token. The default SO-PIN code is 3537363231383830, unless it has been changed (if you forget the SO-PIN, consider the token lost). Press "OK" to continue:

  • The label of the token (that is the token's friendly name, displayed in the PKI applications). Press "OK" to continue:

  • The authentication mechanism for restricting the access to the objects and processor of the token. In most cases, you might need to select "User PIN" (you may set another authentication mechanism, but this one is the most poplar one). Press "OK" to continue:

  • The way to restore the access to the keys and X.509 certificates, if the PIN is lost, forgotten, or locked (if a wrong PIN is entered more than 3 times, consecutively). Select "Resetting PIN with SO-PIN allowed" and press "OK" (select "Resetting PIN with SO-PIN not allowed" only in specific cases, where the implementation of such policy is necessary):

  • The new PIN code (do not use the number shown in the picture bellow). Press "OK" to continue:

  • The new PIN code (again, for confirmation). Press "OK" to continue:

  • Request for using "DKEK Shares". Press "OK" to continue:

  • The number of DKEK shares (use 1, unless you are expert). Press "OK" to continue:

  • Press "Cancel" here (if you press "OK" both SO-PIN and PIN codes will be stored locally in an unencrypted file):

After the success of the initialization, you will see only three objects displayed in the key manager tree: User PIN, SO-PIN, and DKEK entry. The message "Initializing complete" (an indication that the requested initialization has been successfully completed) will be seen in the "Shell" tab:

Note, that at this point, the requested DKEK shares are not yet initialized or/and imported to the token! The appearance of "DKEK set-up in progress with 1 of 1 shares missing" in the key manager tree indicates that. You need to request manually the creation of DKEK shares file and import its content to the token, by following strictly the instructions given bellow:

  • Request the creation of DKEK share, by clicking once with the right button of the mouse on the root of the key manager tree (on "SmartCard-HSM) and picking "Create DKEK share" in the menu:

  • Enter the name of DKEK file to create, and press "OK" (store the file in the working directory of the program, configured during the first run):

  • Set the password for protecting the DKEK share file content and press "OK":

  • Confirm the password for protecting the DKEK share file content and press "OK":

  • With the left button of the mouse, click once upon the object named "DKEK set-up in progress with 1 of 1 shares missing", displayed in the key manager section of the main window of the program:

  • Use the button "Browse" to find and choose the created DKEK file (file extension is *.pbe), and press "OK":

  • Enter the password set (before) for protecting the content of the DKEK file:

It will take up to 10 seconds to derive the keys and import the DKEK into the token (watch the related messages, appearing in the "Shell" tab). At the end, you will see that the object "DKEK set-up in progress with 1 of 1 shares missing" (in the key manager tree) will be renamed (the new name will include the ID of the DKEK object):

IMPORTANT! At this point, you need to store a copy of the DKEK share file, generated during the initialization, in a safe place!

In the examples above, that file is /home/vesso/CardContact/2019_02.pdb, but in you case the file will be with different name and location.

 

7. Generating ECC key pair (by means of DKEK shares)

IMPORTANT! Be absolutely sure that no application, other than Smart Card Shell 3, is communicating with the token. Stop all running processes of PKCS#11 compatible software (like Mozilla Firefox, Mozilla Thunderbird, Google Chrome, XCA), that might take over the token.

Start the Smart Card Shell 3, plug the token into the USB port, and load the key manager script. Be sure that the token is initialized properly, to support DKEK shares.

Click once on the token name, in the key manager section, with the right button of the mouse and select "Generate ECC Key" in the menu:

Select the elliptic curve type, and press "OK":

Provide a friendly name (alias) for the key pair (it is an internal name for naming the key pair object in the token) and press "OK":

Type (separated by comma) the list of the hex codes of the signature algorithms, that will be allowed for the signing, when using the encryption key (the most commonly used ones, 73,74,75, are given in the example bellow), then press "OK":

Wait until the token is finishing with the generation of the requested key pair. Once ready, you will see the new key object under the tree of the DKEK share:

 

7. Importing key pair and the corresponding X.509 certificate from PKCS#12 file into the token (by means of DKEK shares)

IMPORTANT! Be absolutely sure that no application, other than Smart Card Shell 3, is communicating with the token. Stop all running processes of PKCS#11 compatible software (like Mozilla Firefox, Mozilla Thunderbird, Google Chrome, XCA), that might take over the token.

Otherwise the PKCS#12 import might fail, by rising (in the "Shell" tab) the following error:

GPError: Card (CARD_INVALID_SW/27010) - "Unexpected SW1/SW2=6982 (Checking error: Security condition not satisfied) received" in ...

Start the Smart Card Shell 3, plug the token into the USB port, and load the key manager script. Be sure that the token is initialized properly, to support DKEK shares. Using DKEK share in this case is mandatory for this operation.

  • Click once on the token name in the key manager section, with the right button of the mouse, and select "Import from PKCS#12" in the menu:

  • Specify the number of DKEK shares to use (use 1, if you follow the recipes provided in this document), and click "OK":

  • Select the file, containing the DKEK shares (use the file name created during the initialization), and click "OK":

  • Enter the password for decrypting the DKEK file (that password is set during the creation of the file), click "OK", and wait up to 10 seconds for generating the shared keys:

  • Select the PKCS#12 file and click "OK":

  • Provide the password, set for protecting the content of the PKCS#12 file, and click "OK":

  • Select the key pair and X.509 certificate to import from the PKCS#12 file, by choosing their internal PKCS#12 name, and click "OK":

  • Enter a name to assign to the imported key pair and X.509 certificate, and click "OK":

  • Click "OK" if you wanna import more key pairs and X.509 certificates, stored in the same PKCS#12 file, or click "Cancel" to finish:

If the import is successful, you will see the key pair imported into the DKEK share (in the key manager section), and information about the process, in the "Shell" section (as shown in the red frames bellow):

IMPORTANT! You cannot import X.509 certificate chain from a PKCS#12 container into the token, by using the procedure proposed above.

But you might do that later, by using pkcs11-tool, it that is really necessary. Notice, that the X.509 certificates in the chain are public information and they might be used in out-of-the-box manner (installed in the software certificate repository of the browser, which will be using with the token). Their presence in the token storage is not mandatory.


Creative Commons - Attribution 2.5 Generic. Powered by Blogger.

Implementing LUKS Encryption on Software RAID Arrays with LVM2 Management

A comprehensive guide to partition-level encryption for maximum security ...

Search This Blog

Translate