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

0 comments:

Post a Comment

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