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

Simple HSM and OpenSC Based File Encryption Script System Using Derived Keys

This document describes a secure file encryption system that uses a Hardware Security Module (HSM) for key derivation. The system ensures that encryption keys are derived securely within the HSM and never stored permanently on disk.

Table of Contents

Overview

Why HSM-Based Encryption?

Traditional file encryption methods often expose encryption keys or passwords to the operating system in various ways:

  • Keys stored on disk (even if encrypted)
  • Keys loaded into OS memory
  • Keys accessible to system processes
  • Keys vulnerable to memory dumps
  • Keys potentially exposed through swap files
  • Keys that could be intercepted by malware

This HSM-based approach provides superior security by:

  1. Hardware Isolation: All key derivation operations happen inside the HSM's secure boundary
  2. Minimal Key Exposure: Keys are derived on-demand and stored only briefly in RAM-based temporary files
  3. PIN Protection: Physical possession of the HSM alone is insufficient; PIN authentication is required
  4. Tamper Resistance: HSM hardware is designed to resist physical attacks
  5. Secure Cleanup: Temporary key files are securely wiped using shred after use
  6. Process Isolation: Even if the host system is compromised, the HSM's internal operations remain secure

System Operation

The system consists of two main operations:

  1. File encryption with a unique key derived from a random salt
  2. File decryption using the same salt to derive the identical key

The system uses the HSM's SHA-256 mechanism to derive encryption keys, ensuring that key derivation happens within the secure hardware environment.

Components

System Requirements

This encryption system is designed and tested for Linux environments (tested on RHEL 9). While the core components (OpenSC, OpenSSL) are available on macOS, some adjustments might be needed for full compatibility:

  • Linux (primary platform)
    • Tested on RHEL 9
    • Should work on most modern Linux distributions
    • All components available through standard package managers
  • macOS (potentially compatible)
    • Requires OpenSC installation via Homebrew
    • May need path adjustments for PKCS#11 module
    • Limited testing available
  • Windows (untested)
    • OpenSC and OpenSSL are available for Windows
    • Would require significant path and script adjustments
    • Has not been tested by the author
    • Might work with Cygwin or WSL (Windows Subsystem for Linux)

Hardware Requirements

The code snippets shown below match the features of the following HSM tokens:

They can be purchased from either:

  • CardOMatic GmbH (Identiv uTrust 3xxx in various form factors):
    • USB Tokens (recommended for desktop usage):
      • SmartCard-HSM 4K USB-Token (Standard form factor)
      • SmartCard-HSM 4K Mini USB-Token (Compact form factor)
    • Card Formats:
      • SmartCard-HSM-4K-Dual-IF (Dual Interface)
      • SmartCard-HSM-4K-Mini-SIM
      • SmartCard-HSM-4K-Micro-SIM
    • Special Formats:
      • SmartCard-HSM 4K MicroSD Card (For mobile devices)
  • Nitrokey Shop (Nitrokey HSM 2)

All devices feature 4K storage and support the required cryptographic operations.

⚠️ Important Compatibility Note:

This encryption system specifically requires HSM capabilities that are NOT available in PIV-based smartcards (like YubiKey PIV devices). PIV smartcards:

  • Do not support direct hash operations within the device
  • Cannot perform arbitrary SHA-256 operations on input data
  • Lack the required key derivation mechanisms
  • Have limited storage for custom objects

Only true HSM devices (like SmartCard-HSM or Nitrokey HSM 2) provide the necessary cryptographic operations for this system to work. YubiHSM 2 may work as well, but that statement requires a proper validation.

Software Components

  1. OpenSC PKCS#11 module (/usr/lib64/pkcs11/opensc-pkcs11.so)
  2. aes_encrypt.sh - Encrypts files using HSM-derived keys (see the code snippets below)
  3. aes_decrypt.sh - Decrypts files using HSM-derived keys (see the code snippets below)

Security Features

  1. Hardware-Based Key Derivation
    • All key derivation happens inside the HSM
    • Uses HSM's SHA-256 mechanism
    • Requires HSM PIN authentication for both encryption and decryption
  2. Unique Keys Per File
    • Each encryption operation uses a new random 32-byte salt
    • Salt is used to derive a unique key through the HSM
    • Prevents key reuse across different files
  3. Secure Key Handling
    • Derived keys exist only in RAM-based temporary files during operations
    • Keys are securely wiped using shred after use
    • No keys are stored permanently on disk
  4. File Format
    • First 32 bytes: Random salt used for key derivation
    • Remaining bytes: AES-256 encrypted data (mode depends on implementation)
  5. Operational Security
    • HSM Redundancy: Maintain at least two HSM tokens with identical ECDSA key pairs
      • Critical for disaster recovery
      • Protects against HSM loss, theft, or hardware failure
      • Ensures access if one token gets locked out due to PIN attempts
      • Both tokens should be stored securely in different locations
    • Without a working HSM containing the correct key pair, decryption is impossible
    • Regular testing of backup HSM tokens is recommended
  6. HSM Cryptographic Capabilities

    You can inspect the HSM's supported mechanisms using:

    pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so --list-mechanisms

    Example output:

    Using slot 0 with a present token (0x0)
    Supported mechanisms:
      SHA-1, digest
      SHA224, digest
      SHA256, digest
      SHA384, digest
      SHA512, digest
      MD5, digest
      RIPEMD160, digest
      GOSTR3411, digest
      ECDSA, keySize={192,521}, hw, sign, verify, EC F_P, EC parameters, EC OID, EC uncompressed
      ECDSA-SHA384, keySize={192,521}, sign, verify
      ECDSA-SHA512, keySize={192,521}, sign, verify
      ECDSA-SHA1, keySize={192,521}, hw, sign, verify, EC F_P, EC parameters, EC OID, EC uncompressed
      ECDSA-SHA224, keySize={192,521}, hw, sign, verify, EC F_P, EC parameters, EC OID, EC uncompressed
      ECDSA-SHA256, keySize={192,521}, hw, sign, verify, EC F_P, EC parameters, EC OID, EC uncompressed
      ECDH1-COFACTOR-DERIVE, keySize={192,521}, hw, derive, EC F_P, EC parameters, EC OID, EC uncompressed
      ECDH1-DERIVE, keySize={192,521}, hw, derive, EC F_P, EC parameters, EC OID, EC uncompressed
      ECDSA-KEY-PAIR-GEN, keySize={192,521}, hw, generate_key_pair, EC F_P, EC parameters, EC OID, EC uncompressed
      RSA-X-509, keySize={1024,4096}, hw, decrypt, sign, verify
      RSA-PKCS, keySize={1024,4096}, hw, decrypt, sign, verify
      SHA1-RSA-PKCS, keySize={1024,4096}, sign, verify
      SHA224-RSA-PKCS, keySize={1024,4096}, sign, verify
      SHA256-RSA-PKCS, keySize={1024,4096}, sign, verify
      SHA384-RSA-PKCS, keySize={1024,4096}, sign, verify
      SHA512-RSA-PKCS, keySize={1024,4096}, sign, verify
      MD5-RSA-PKCS, keySize={1024,4096}, sign, verify
      RIPEMD160-RSA-PKCS, keySize={1024,4096}, sign, verify
      RSA-PKCS-PSS, keySize={1024,4096}, hw, sign, verify
      SHA1-RSA-PKCS-PSS, keySize={1024,4096}, sign, verify
      SHA224-RSA-PKCS-PSS, keySize={1024,4096}, sign, verify
      SHA256-RSA-PKCS-PSS, keySize={1024,4096}, sign, verify
      SHA384-RSA-PKCS-PSS, keySize={1024,4096}, sign, verify
      SHA512-RSA-PKCS-PSS, keySize={1024,4096}, sign, verify
      RSA-PKCS-OAEP, keySize={1024,4096}, hw, decrypt
      RSA-PKCS-KEY-PAIR-GEN, keySize={1024,4096}, generate_key_pair

    The HSM supports a comprehensive set of cryptographic operations:

    • Hash Functions:
      • SHA family (SHA-1, SHA224, SHA256, SHA384, SHA512)
      • MD5
      • RIPEMD160
      • GOSTR3411
    • ECDSA Operations (key sizes 192-521 bits):
      • Key pair generation
      • Signing/verification with various hash combinations
      • Hardware-accelerated operations
      • Support for standard curves (EC F_P)
    • RSA Operations (key sizes 1024-4096 bits):
      • Key pair generation
      • Encryption/decryption
      • Signing/verification with various hash combinations
      • Support for PKCS, PSS, and OAEP padding
    • Key Derivation:
      • ECDH1-DERIVE
      • ECDH1-COFACTOR-DERIVE

    This encryption system specifically uses the SHA256 mechanism for key derivation, ensuring the operation is performed securely within the HSM's hardware boundary.

HSM Object Inspection

To inspect the objects (keys, certificates, data) stored on your HSM, use the pkcs11-tool --list-objects command:

pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so --list-objects

Expected Output Format

The command will show all objects stored on your HSM. Here's an example output:

Using slot 0 with a present token (0x0)
Certificate Object; type = X.509 cert
  label:      vesso_ecdsa#ssh
  subject:    DN: CN=Test User
  serial:     65C25210C8EDD2269D3DFFB836C2485C0A17BC32
  ID:         01
  uri:        pkcs11:model=PKCS%2315%20emulated;manufacturer=www.CardContact.de;serial=DECC0900169;token=SmartCard-HSM%20%28UserPIN%29;id=%01;object=test_ecdsa%23ssh;type=cert

Public Key Object; EC  EC_POINT 384 bits
  EC_POINT:   046104644baa533af20667849c4a6f38092e663f376d167cc1f64adca5cda8b72b1998d7757ac9057695cec32d1fc6239f8a282c9a803cb603dc1dd81907e411e737ab8e69129ea97035895bce14cc079043848c890ef969b6330c8a65418904a9d414
  EC_PARAMS:  06052b81040022
  label:      test_ecdsa#ssh
  ID:         01
  Usage:      encrypt, verify
  Access:     local
  uri:        pkcs11:model=PKCS%2315%20emulated;manufacturer=www.CardContact.de;serial=DECC0900169;token=SmartCard-HSM%20%28UserPIN%29;id=%01;object=test_ecdsa%23ssh;type=public

Public Key Object; EC  EC_POINT 256 bits
  EC_POINT:   0441047bfd2ff666960d4186f1aab2370b138554fe2dc2163a7016e2967624b8ad1ee3e36d25c84cac28b9040cf80ff68fa63e06c73a44a21ef70a74701fa8ea30c3d4
  EC_PARAMS:  06082a8648ce3d030107
  label:      ECDH-KEY
  ID:         02
  Usage:      verify
  Access:     none
  uri:        pkcs11:model=PKCS%2315%20emulated;manufacturer=www.CardContact.de;serial=DECC0900169;token=SmartCard-HSM%20%28UserPIN%29;id=%02;object=ECDH-KEY;type=public

Public Key Object; EC  EC_POINT 256 bits
  EC_POINT:   044104e1dc094f873e00eb86626f7ae0a845885df08cb89a797d29271d6b7f602e685bf9681cda2ecaeaa671f39837a11ee9259142c706d988558db907ad6560879ac3
  EC_PARAMS:  06082a8648ce3d030107
  label:      ECDH-AES-Key
  ID:         03
  Usage:      verify
  Access:     none
  uri:        pkcs11:model=PKCS%2315%20emulated;manufacturer=www.CardContact.de;serial=DECC0900169;token=SmartCard-HSM%20%28UserPIN%29;id=%03;object=ECDH-AES-Key;type=public

Profile object 1385173136
  profile_id:          CKP_PUBLIC_CERTIFICATES_TOKEN (4)

Understanding the Output

  1. Object Types:
    • Certificate Object: X.509 certificates with subject and serial information
    • Public Key Object: Public keys with their parameters and points
    • Profile Object: HSM configuration profiles
  2. Object Attributes:
    • label: Name of the object (e.g., "test_ecdsa#ssh", "ECDH-KEY")
    • ID: Object identifier (01, 02, 03)
    • Usage: Object capabilities (encrypt, verify)
    • Access: Access restrictions (local, none)
    • uri: PKCS#11 URI identifying the object

Key Objects in This Setup

  • ID 01: SSH ECDSA key (384-bit) with certificate
  • ID 02: ECDH key (256-bit) for key exchange
  • ID 03: ECDH-AES key (256-bit) for encryption operations

Usage Notes

  1. If the HSM is locked, add --login and provide a PIN:
    pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so --login --list-objects
  2. Use this command to:
    • Verify key installation and parameters
    • Check certificate details
    • Audit HSM object configuration
    • Confirm key availability before operations

Implementation Details

Encryption Process

  1. Salt Generation
    openssl rand -out "$SALT_FILE" 32
  2. Key Derivation in HSM
    pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so \ --slot 0 \ --login \ --pin "$HSM_PIN" \ --hash \ --mechanism SHA256 \ --input-file "$SALT_FILE" > "$KEY_FILE"
  3. File Encryption
    • Salt is written to the start of the output file
    • Data is encrypted using AES-256-CTR with the derived key
    cat "$SALT_FILE" > "$OUTPUT_FILE" openssl enc -aes-256-ctr -pbkdf2 -iter 1 -salt -in "$INPUT_FILE" -kfile "$KEY_FILE" >> "$OUTPUT_FILE"
  4. Secure Cleanup
    shred -u "$SALT_FILE" "$KEY_FILE"

Decryption Process

  1. Salt Extraction
    dd if="$INPUT_FILE" of="$SALT_FILE" bs=32 count=1 dd if="$INPUT_FILE" of="$ENCRYPTED_DATA" bs=1 skip=32
  2. Key Derivation in HSM
    • Uses the same HSM SHA-256 mechanism with the extracted salt
    • Produces identical key as encryption
  3. File Decryption
    openssl enc -aes-256-ctr -pbkdf2 -iter 1 -d -salt -in "$ENCRYPTED_DATA" -out "$OUTPUT_FILE" -kfile "$KEY_FILE"
  4. Secure Cleanup
    shred -u "$SALT_FILE" "$ENCRYPTED_DATA" "$KEY_FILE"

Important Note: Why --hash Instead of --derive

When implementing this encryption system, you might be tempted to use the --derive option with pkcs11-tool. However, this will result in an error:

pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so --derive --mechanism SHA256 --input-file salt.bin error: Private key not found Aborting.

Why --derive Doesn't Work

The --derive option in pkcs11-tool is designed for key derivation operations that require a private key, such as:

  • ECDH (Elliptic Curve Diffie-Hellman) key exchange
  • Key derivation using existing private keys
  • Cryptographic operations that need a base key

The --derive option expects:

  1. A private key to be specified (using --id, --label, or --object-index)
  2. A mechanism that supports key derivation (like ECDH1-DERIVE)
  3. Input data that will be used with the private key for derivation

Why --hash is Correct

For our encryption system, we want to perform a simple hash operation on the salt to create a key. This is exactly what the --hash option provides:

pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so \ --slot 0 \ --login \ --pin "$HSM_PIN" \ --hash \ --mechanism SHA256 \ --input-file "$SALT_FILE" > final_key.bin

The --hash option:

  1. Takes input data (our salt)
  2. Performs the specified hash operation (SHA256) within the HSM
  3. Returns the hash result as output
  4. Doesn't require any private keys

HSM Private Keys vs Hash Operations

Your HSM contains several private keys (both RSA and EC), but these are for different purposes:

Private Keys with derive usage:

  • Used for ECDH key exchange operations
  • Require a corresponding public key for derivation
  • Used in protocols like TLS key exchange

Hash Operations:

  • Simple one-way functions
  • Don't require any keys
  • Perfect for our key derivation from salt

Verification

You can verify the available private keys and their capabilities:

# List private keys (requires PIN) pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so --login --list-objects --type privkey # Example output showing EC keys with derive capability: # Private Key Object; EC # label: test@example.com#59edd63 # ID: 02 # Usage: sign, derive # Access: sensitive, always sensitive, never extractable, local

The derive usage on EC keys is for ECDH operations, not for simple hashing. Our encryption system correctly uses --hash for the SHA-256 operation on the salt.

Hash Mechanism Flexibility

The encryption system is not limited to SHA-256. You can use any hash mechanism supported by your HSM, as long as it provides sufficient output length for your AES key. The choice of hash mechanism depends on your security requirements and HSM capabilities.

Available Hash Mechanisms

Based on the HSM mechanisms list shown earlier, your HSM supports these hash functions:

  • SHA-1 (160 bits) - Not recommended for new implementations
  • SHA224 (224 bits) - Adequate for AES-256
  • SHA256 (256 bits) - Recommended for AES-256
  • SHA384 (384 bits) - Excellent for AES-256, provides extra security margin
  • SHA512 (512 bits) - Maximum security, excellent for AES-256
  • MD5 (128 bits) - Not recommended, insufficient for AES-256
  • RIPEMD160 (160 bits) - Not recommended for new implementations

Recommended Hash Mechanisms

For AES-256 encryption, the following mechanisms are recommended in order of preference:

  1. SHA512 - Maximum security margin (512 bits → 256 bits)
  2. SHA384 - Excellent security margin (384 bits → 256 bits)
  3. SHA256 - Optimal fit (256 bits → 256 bits)
  4. SHA224 - Adequate but minimal margin (224 bits → 256 bits, will be padded)

Using Different Hash Mechanisms

To use a different hash mechanism, simply change the --mechanism parameter:

# Using SHA-512 (maximum security) pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so \ --slot 0 \ --login \ --pin "$HSM_PIN" \ --hash \ --mechanism SHA512 \ --input-file "$SALT_FILE" > final_key.bin # Using SHA-384 (excellent security margin) pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so \ --slot 0 \ --login \ --pin "$HSM_PIN" \ --hash \ --mechanism SHA384 \ --input-file "$SALT_FILE" > final_key.bin # Using SHA-224 (adequate but minimal margin) pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so \ --slot 0 \ --login \ --pin "$HSM_PIN" \ --hash \ --mechanism SHA224 \ --input-file "$SALT_FILE" > final_key.bin

Security Considerations

  • SHA-512/SHA-384: Provide security margin beyond AES-256 requirements
  • SHA-256: Optimal fit for AES-256, widely trusted
  • SHA-224: Adequate but provides minimal security margin
  • SHA-1/MD5: Not recommended due to known vulnerabilities
  • RIPEMD160: Not recommended for new implementations

Implementation Note

When changing hash mechanisms, ensure that:

  1. Both encryption and decryption scripts use the same mechanism
  2. The mechanism is supported by your HSM (verify with --list-mechanisms)
  3. The output length is sufficient for your AES key size
  4. You maintain consistency across all encrypted files

Checking HSM Support

Always verify that your HSM supports the chosen mechanism:

pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so --list-mechanisms | grep -E "(SHA|MD5|RIPEMD)"

Cipher Mode Security

⚠️ Important Security Warning:

The original implementation uses AES-256-CBC mode, which has known vulnerabilities including padding oracle attacks and the need for proper IV handling. Modern applications should use more secure cipher modes.

Available Secure Cipher Modes

OpenSSL supports these secure AES-256 modes:

  • AES-256-CTR (Counter Mode) - Recommended for OpenSSL enc
    • No padding required
    • Resistant to padding oracle attacks
    • Stream cipher mode
    • Note: Does not provide authentication (use with caution)
  • AES-256-GCM (Galois/Counter Mode) - Best Security (if available)
    • Provides both encryption and authentication
    • No padding required
    • Built-in integrity protection
    • Resistant to padding oracle attacks
    • Note: Not supported by OpenSSL enc command in all versions
  • AES-256-CCM (Counter with CBC-MAC) - Good Alternative (if available)
    • Provides both encryption and authentication
    • No padding required
    • Built-in integrity protection
    • Slightly more complex than GCM
    • Note: Not supported by OpenSSL enc command in all versions
  • AES-256-CBC (Cipher Block Chaining) - Not Recommended
    • Vulnerable to padding oracle attacks
    • Requires proper IV handling
    • No built-in integrity protection
    • Only use if compatibility is absolutely required

Why Avoid CBC Mode?

CBC mode has several security issues:

  1. Padding Oracle Attacks: Attackers can exploit padding validation to decrypt data
  2. IV Requirements: Requires cryptographically secure random IVs
  3. No Integrity: Provides no protection against tampering
  4. Predictable Patterns: Can leak information about plaintext structure

Recommended Implementation

Use AES-256-CTR for compatibility with OpenSSL enc command:

# Encryption with CTR (recommended for OpenSSL enc) openssl enc -aes-256-ctr -pbkdf2 -iter 1 -salt -in "$INPUT_FILE" -kfile "$KEY_FILE" >> "$OUTPUT_FILE" # Decryption with CTR (recommended for OpenSSL enc) openssl enc -aes-256-ctr -pbkdf2 -iter 1 -d -salt -in "$ENCRYPTED_DATA" -out "$OUTPUT_FILE" -kfile "$KEY_FILE"

Note: If your OpenSSL version supports GCM/CCM in the enc command, use those modes instead for better security.

Alternative: CCM Mode

If your OpenSSL version supports CCM in the enc command:

# Encryption with CCM openssl enc -aes-256-ccm -pbkdf2 -iter 1 -salt -in "$INPUT_FILE" -kfile "$KEY_FILE" >> "$OUTPUT_FILE" # Decryption with CCM openssl enc -aes-256-ccm -pbkdf2 -iter 1 -d -salt -in "$ENCRYPTED_DATA" -out "$OUTPUT_FILE" -kfile "$KEY_FILE"

Alternative: GCM Mode

If your OpenSSL version supports GCM in the enc command:

# Encryption with GCM openssl enc -aes-256-gcm -pbkdf2 -iter 1 -salt -in "$INPUT_FILE" -kfile "$KEY_FILE" >> "$OUTPUT_FILE" # Decryption with GCM openssl enc -aes-256-gcm -pbkdf2 -iter 1 -d -salt -in "$ENCRYPTED_DATA" -out "$OUTPUT_FILE" -kfile "$KEY_FILE"

File Format with CTR/GCM/CCM

When using CTR, GCM, or CCM modes, the file format remains the same:

  • First 32 bytes: Random salt for key derivation
  • Remaining bytes: AES-256-CTR/GCM/CCM encrypted data

Compatibility Considerations

  • CTR: Compatible with OpenSSL enc command, no padding oracle attacks
  • GCM/CCM: Modern, secure, but not supported by OpenSSL enc command in all versions
  • CBC: Legacy compatibility only, avoid for new systems due to padding oracle attacks

Verification

Check available cipher modes on your system:

# Check what ciphers are supported by the enc command openssl enc -list | grep -E "(aes256)" # Check if GCM/CCM are available (they may not be supported by enc command) openssl list -cipher-algorithms | grep -E "(aes256-gcm|aes256-ccm)"

Usage

Setting Up the Scripts

Before using the encryption system, you need to create the encryption and decryption scripts. Copy the following code blocks and save them with the appropriate names:

1. Create the Encryption Script

Save the following content as aes_encrypt.sh:

#!/bin/bash
set -e

if [ "$#" -ne 1 ]; then
    echo "Usage: $0 "
    exit 1
fi

INPUT_FILE="$1"
OUTPUT_FILE="${INPUT_FILE}.enc"
SALT_FILE=$(mktemp)
KEY_FILE=$(mktemp -p /dev/shm)

# Configuration
SLOT=0

# Get HSM PIN
read -s -p "Enter HSM PIN: " HSM_PIN
echo

# Generate a random salt (32 bytes)
openssl rand -out "$SALT_FILE" 32

# Use HSM's SHA-256 to create key from salt
echo "Creating key in HSM..."
pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so \
    --slot $SLOT \
    --login \
    --pin "$HSM_PIN" \
    --hash \
    --mechanism SHA256 \
    --input-file "$SALT_FILE" > "$KEY_FILE"

# Encrypt the file using the derived key from HSM
echo "Encrypting file..."
# Write salt at the start of the output file (we'll need it for decryption)
cat "$SALT_FILE" > "$OUTPUT_FILE"
# Encrypt the actual data using AES-256-CTR (more secure than CBC)
openssl enc -aes-256-ctr -pbkdf2 -iter 1 -salt -in "$INPUT_FILE" -kfile "$KEY_FILE" >> "$OUTPUT_FILE"

# Clean up
shred -u "$SALT_FILE" "$KEY_FILE"

echo "File encrypted successfully: $OUTPUT_FILE"

2. Create the Decryption Script

Save the following content as aes_decrypt.sh:

#!/bin/bash
set -e

if [ "$#" -ne 1 ]; then
    echo "Usage: $0 "
    exit 1
fi

INPUT_FILE="$1"
OUTPUT_FILE="${INPUT_FILE%.enc}.decrypted"
SALT_FILE=$(mktemp)
ENCRYPTED_DATA=$(mktemp)
KEY_FILE=$(mktemp -p /dev/shm)

# Configuration
SLOT=0

# Get HSM PIN
read -s -p "Enter HSM PIN: " HSM_PIN
echo

# Extract salt from encrypted file
dd if="$INPUT_FILE" of="$SALT_FILE" bs=32 count=1 2>/dev/null
dd if="$INPUT_FILE" of="$ENCRYPTED_DATA" bs=1 skip=32 2>/dev/null

# Use HSM's SHA-256 to create key from salt
echo "Creating key in HSM..."
pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so \
    --slot $SLOT \
    --login \
    --pin "$HSM_PIN" \
    --hash \
    --mechanism SHA256 \
    --input-file "$SALT_FILE" > "$KEY_FILE"

# Decrypt the file using the derived key from HSM
echo "Decrypting file..."
openssl enc -aes-256-ctr -pbkdf2 -iter 1 -d -salt -in "$ENCRYPTED_DATA" -out "$OUTPUT_FILE" -kfile "$KEY_FILE"

# Clean up
shred -u "$SALT_FILE" "$ENCRYPTED_DATA" "$KEY_FILE"

echo "File decrypted successfully: $OUTPUT_FILE"

3. Make the Scripts Executable

After creating both files, make them executable:

chmod +x aes_encrypt.sh aes_decrypt.sh

Using the Scripts

Encrypting a File

./aes_encrypt.sh
  • Prompts for HSM PIN
  • Creates encrypted file with .enc extension
  • Original file remains unchanged

Decrypting a File

./aes_decrypt.sh
  • Prompts for HSM PIN
  • Creates decrypted file with .decrypted extension
  • Encrypted file remains unchanged

Security Considerations

  1. HSM PIN Protection
    • PIN is never stored in scripts
    • PIN is required for both encryption and decryption
    • Multiple incorrect PIN attempts may lock the HSM
  2. Temporary Files
    • All temporary files are securely wiped using shred
    • Includes salt files, key files, and intermediate data
  3. Key Handling Reality
    • Important: Derived keys are temporarily stored in secure temporary files
    • Keys are stored in regular temp files (not /dev/shm) for binary data compatibility
    • Keys are securely wiped using shred immediately after use
    • No keys are stored permanently on disk
    • The HSM's internal operations remain secure even if the host system is compromised
  4. Cold Boot Attack Mitigation
    • Enhanced: Keys are stored in regular temp files (not /dev/shm)
    • Keys are securely wiped using shred immediately after use
    • Temporary files are created in standard temp directories
    • Reduced exposure compared to /dev/shm storage
  5. Salt Management
    • Each file gets a unique random salt
    • Salt is stored with the encrypted data
    • 32 bytes of random data provides sufficient uniqueness

Limitations

  1. HSM must be available for both encryption and decryption operations
  2. HSM PIN must be known and HSM must be in an unlocked state
  3. System depends on the HSM's SHA-256 implementation
  4. No key rotation mechanism (each file is encrypted with its own unique key)
  5. Cold Boot Attack Mitigation: Keys are stored in RAM-based temp files (/dev/shm), reducing exposure

Cold Boot Attack Mitigation

Understanding the Threat

Cold boot attacks exploit the fact that RAM contents can persist for minutes to hours after power loss, especially in cold environments. Attackers with physical access can:

  1. Extract RAM contents after system shutdown
  2. Analyze memory dumps to find encryption keys
  3. Recover keys that were stored in /dev/shm files
  4. Decrypt files using recovered keys

Enhanced Implementation Security

The updated scripts store derived keys in regular temporary files (not /dev/shm), which:

  • ✅ Provides compatibility with binary data
  • ✅ Reduces cold boot attack exposure compared to /dev/shm
  • ✅ Keys are securely wiped using shred immediately after use
  • ✅ Uses standard temp directories instead of RAM-based filesystems

Mitigation Strategies

1. Current Implementation (Enhanced)

The scripts now use regular temporary files for binary data compatibility:

# Keys are stored in regular temp files (not /dev/shm) pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so \ --slot $SLOT \ --login \ --pin "$HSM_PIN" \ --hash \ --mechanism SHA256 \ --input-file "$SALT_FILE" > "$KEY_FILE" # Use the key file directly openssl enc -aes-256-ctr -pbkdf2 -iter 1 -salt -in "$INPUT_FILE" -kfile "$KEY_FILE" >> "$OUTPUT_FILE"

2. Additional Security Enhancements

For even higher security, consider these additional measures:

#!/bin/bash
set -e

if [ "$#" -ne 1 ]; then
    echo "Usage: $0 "
    exit 1
fi

INPUT_FILE="$1"
OUTPUT_FILE="${INPUT_FILE}.enc"
SALT_FILE=$(mktemp)

# Configuration
SLOT=0

# Get HSM PIN
read -s -p "Enter HSM PIN: " HSM_PIN
echo

# Generate a random salt (32 bytes)
openssl rand -out "$SALT_FILE" 32

# Use HSM's SHA-256 to create key and use it directly
echo "Creating key in HSM..."
KEY_DATA=$(pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so \
    --slot $SLOT \
    --login \
    --pin "$HSM_PIN" \
    --hash \
    --mechanism SHA256 \
    --input-file "$SALT_FILE")

# Encrypt the file using the derived key directly
echo "Encrypting file..."
cat "$SALT_FILE" > "$OUTPUT_FILE"
echo "$KEY_DATA" | openssl enc -aes-256-ctr -pbkdf2 -iter 1 -salt -in "$INPUT_FILE" -kfile /dev/stdin >> "$OUTPUT_FILE"

# Clean up
shred -u "$SALT_FILE"

echo "File encrypted successfully: $OUTPUT_FILE"

3. System-Level Protections

Enable memory encryption:

# Check if memory encryption is available dmesg | grep -i "memory encryption\|mktme\|tme" # Enable secure boot and memory encryption in BIOS/UEFI # Use Intel TME (Total Memory Encryption) or AMD SME if available

Use encrypted swap:

# Ensure swap is encrypted swapon --show # If not encrypted, consider disabling swap for sensitive operations

4. Operational Security

Physical security measures:

  • Keep systems in secure locations
  • Use full-disk encryption
  • Implement proper shutdown procedures
  • Consider using secure enclaves (Intel SGX, AMD SEV)

Operational procedures:

  • Shut down systems immediately after sensitive operations
  • Use dedicated machines for encryption operations
  • Implement proper access controls
  • Regular security audits

Current Implementation

The scripts now implement enhanced security with binary data compatibility:

  1. Use regular temp files - Keys stored in standard temp directories (not /dev/shm)
  2. Binary data compatibility - Properly handles HSM binary output
  3. Secure cleanup - Keys wiped using shred immediately after use
  4. Reduced attack surface - No RAM-based filesystem storage

Security Trade-offs

Approach Cold Boot Risk Performance Complexity
Regular Temp Files (Current) Medium Fast Low
Memory Encryption Low Medium High
Dedicated Hardware Very Low Fast Very High

The current implementation provides a good balance of security and simplicity. For high-security environments, consider additional system-level protections like memory encryption.

Complete Implementation

The encryption system is implemented through two bash scripts that handle:

  1. Secure PIN input - Prompts for HSM PIN without displaying it
  2. Random salt generation - Creates unique 32-byte salts for each file
  3. HSM-based key derivation - Uses HSM's SHA-256 mechanism for key creation
  4. File encryption/decryption - Uses AES-256-CTR for secure encryption
  5. Secure cleanup - Wipes all temporary files using shred

The complete scripts are provided in the Usage section above, where you can copy them and save as aes_encrypt.sh and aes_decrypt.sh.

TODO List

Hardware Testing

  1. YubiHSM 2 FIPS Integration
    • Test compatibility with YubiHSM 2 FIPS
    • Verify SHA-256 mechanism availability and behavior
    • Test key derivation performance
    • Document any required modifications for YubiHSM 2 support
    • Test network sharing capabilities if relevant
    • Validate PKCS#11 module path and configuration
  2. Multiple Key Testing
    • Test behavior with multiple ECDSA keys
    • Verify key selection logic
    • Document needed modifications
    • Test key ID specification requirements

YubiHSM 2 and Cold Boot Attack Prevention

Overview

While the current system uses SmartCard-HSM devices for key derivation with host-based encryption, YubiHSM 2 offers a fundamentally different approach that can provide complete protection against cold boot attacks by performing all cryptographic operations within the HSM hardware itself.

YubiHSM 2 Hardware-Based Encryption

YubiHSM 2 supports direct AES encryption and decryption operations within the HSM hardware, available with firmware version 2.3.1 or later:

Supported Operations

  • AES-128/192/256 CBC Mode: encrypt-cbc and decrypt-cbc commands
  • AES-128/192/256 ECB Mode: encrypt-ecb and decrypt-ecb commands
  • Hardware-accelerated: All operations performed within the secure hardware boundary

Cold Boot Attack Prevention

This hardware-based approach provides complete protection against cold boot attacks:

  • Keys Never Leave the HSM: AES keys are stored and used entirely within the secure hardware
  • Encryption in Hardware: All cryptographic operations occur inside the HSM's secure boundary
  • No Host Memory Exposure: Plaintext and keys are never loaded into the host system's RAM
  • Hardware Isolation: Even if the host system is compromised, the HSM's internal operations remain secure
  • FIPS 140-2 Level 3: Certified tamper-resistant hardware with physical security protections

Implementation Differences

Current System (SmartCard-HSM)

# Key derivation in HSM, encryption on host pkcs11-tool --hash --mechanism SHA256 --input-file salt.bin > key.bin openssl enc -aes-256-ctr -kfile key.bin -in file.txt -out file.enc

YubiHSM 2 Approach

# Generate AES key in HSM yubihsm-shell -a generate-symmetric-key -l "file-key" -d 1 -c encrypt-cbc,decrypt-cbc -A aes256 # Encrypt data directly in HSM (chunked) yubihsm-shell -a encrypt-cbc -i -s -i data=

Data Size Limitations

Important Constraint: YubiHSM 2 has a maximum data size of approximately 2021 bytes per operation. This means:

  • Small files: Can be encrypted entirely within the HSM
  • Large files: Must be processed in ~2KB chunks
  • ⚠️ Performance impact: Chunked processing adds complexity and latency

Security Comparison

Aspect Current System (SmartCard-HSM) YubiHSM 2
Key Derivation ✅ HSM-based SHA-256 ✅ HSM-based SHA-256
Key Storage ✅ Hardware protected ✅ Hardware protected
File Encryption ❌ Host-based (OpenSSL) ✅ Hardware-based (limited size)
Cold Boot Protection ⚠️ Partial (keys briefly in temp files) ✅ Complete (all operations in HSM)
Large File Support ✅ Full support ❌ Limited to ~2KB chunks
Implementation Complexity ✅ Simple ❌ Complex (chunking required)

Practical Considerations

Advantages of YubiHSM 2

  • Complete cold boot attack prevention
  • All cryptographic operations in hardware
  • No key exposure to host memory
  • FIPS 140-2 Level 3 certification
  • Superior security model

Disadvantages of YubiHSM 2

  • Limited to ~2KB chunks per operation
  • More complex implementation for large files
  • Higher latency due to chunked processing
  • Requires custom chunking logic
  • Not suitable for streaming encryption

Recommendation

For environments where cold boot attacks are the primary security concern, YubiHSM 2 provides superior protection by keeping all cryptographic operations within the secure hardware boundary. However, the current SmartCard-HSM approach offers a better balance of security and practicality for general file encryption use cases.

Choose YubiHSM 2 if:

  • Cold boot attacks are your primary threat model
  • You can accept the complexity of chunked processing
  • You're working with smaller files or can implement chunking
  • You require FIPS 140-2 Level 3 compliance

Choose SmartCard-HSM if:

  • You need simple, practical file encryption
  • You work with large files frequently
  • You want straightforward implementation
  • You accept the minimal cold boot attack exposure of temporary key storage

Dependencies

  • OpenSC PKCS#11 module
  • OpenSSL for AES encryption and random number generation
  • Standard Unix tools (dd, cat, shred)
  • Bash shell

For more detailed instructions about SmartCard-HSM initialization and key generation, refer to SmartCard-HSM USB Token Setup Guide.

Usage Notes

  1. If the HSM is locked, add --login and provide a PIN:
    pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so --login --list-objects
  2. Use this command to:
    • Verify key installation and parameters
    • Check certificate details
    • Audit HSM object configuration
    • Confirm key availability before operations
Creative Commons - Attribution 2.5 Generic. Powered by Blogger.

Steganography in Web Standards

Steganography in Web Standards Exploring the use of HTML IDs, UUIDs, and HMAC for cove...

Search This Blog

Translate