Showing posts with label cryptography. Show all posts
Showing posts with label cryptography. Show all posts

DKEK shares and HSM smart cards - SmartCard-HSM perspective

This note describes what a DKEK is, how DKEK shares work for key management on SmartCard-HSM class devices, and how that relates to the Smart Card Shell (scsh) distribution. It is aimed at operators and integrators; it does not replace manufacturer documentation or a formal security analysis. The SmartCard-HSM site is https://www.smartcard-hsm.com/. Smart Card Shell 3 is distributed from https://www.openscdp.org/scsh3/download.html.

Terminology

On SmartCard-HSM devices, DKEK usually denotes Device Key Encryption Key: a 256-bit symmetric key held inside the device that acts as a key-encryption key (KEK) for wrapping sensitive key material when using backup, restore, or migration features.

The same three-letter acronym can appear elsewhere in cryptography with different meanings (for example some standards use KEK hierarchies without this exact name). In this document, DKEK refers to the SmartCard-HSM mechanism unless stated otherwise.

Why a DKEK exists

Many HSMs and smart-card HSMs never release private keys in plaintext. To move a key between devices, or to keep an offline backup, the implementation encrypts the key under a KEK that exists on the card. On SmartCard-HSM, that KEK is the DKEK.

Typical properties:

  • Keys generated on the card can be exported only if a DKEK key domain was configured during initialisation (or equivalent setup), depending on device options and policy.
  • If the device is re-initialised and the DKEK is wiped, encrypted backups that depended on the old DKEK cannot be recovered.
  • The DKEK is not intended to be held as a single secret by one person alone; the design allows splitting the material that builds the DKEK into shares.

What a DKEK share is

A DKEK share is a random 256-bit (32-byte) value. During setup the device is configured to expect a chosen number of shares. Each share is generated inside the device (using the card RNG), then passed to a custodian who stores it, usually as a password-encrypted file or using other formats such as a printable encoding.

The final DKEK is assembled by combining the shares with exclusive-or (XOR): each share is XORed into a running 256-bit value until all shares are imported. Published technical descriptions for SmartCard-HSM state that multiple shares are XORed into a single KEK value inside the key domain.

Important distinction: this is not Shamir secret sharing. With plain XOR composition, you normally need every share to reconstruct the DKEK. Published material also describes optional threshold schemes applied to the password that protects a share file (n-of-m password fragments), which is a separate layer from the XOR combination of random shares.

Roles in key management

  • Key domain: a logical grouping for keys and for the KEK material used to wrap them. Newer devices support multiple key domains; older or simpler profiles may expose a single DKEK domain.
  • Custodians: individuals who receive and protect distinct DKEK shares. Organisational policy decides how many shares to use (common examples in public guides are one to three shares).
  • Key check value (KCV): a short fingerprint used to confirm that the assembled DKEK on a device matches expectations before you rely on backup or import operations.

Off-card handling of shares (files and passwords)

Shares leave the device only in forms that depend on custodian-chosen secrets:

  • Password-based encryption of the share (for example .pbe files in command-line workflows).
  • Optional password threshold splitting, where several people hold fragments of the password needed to decrypt one share.
  • Alternative encodings (for example human-entered formats) aimed at offline storage.

The security of an encrypted share file depends on password strength, resistance to offline guessing, and physical protection of the storage medium.

PKCS#12 import, DKEK shares, and protected card memory (Smart Card Shell Key Manager)

In the Key Manager sources shipped with Smart Card Shell 3 (under keymanager/ in the unpacked distribution), the Key Manager loads PKCS#12 (.p12) files with BouncyCastle (KeyStore("BC", "PKCS12", ...)). The PKCS#12 password only decrypts the container on the host; it is not the DKEK. The shell then has to move private keys into the SmartCard-HSM without sending them in plaintext over the card interface. That step uses the same DKEK-based wrap format as other tooling: the host builds a key blob with DKEK.encodeKey(privateKey, publicKeyFromCertificate), and HSMKeyStore.importRSAKey / importECCKey call unwrapKey on the device so the key material is loaded into protected storage and PKCS#15-style metadata is written. Certificates are stored separately (storeEndEntityCertificate for end-entity certs, storeCACertificate when the P12 entry has no usable private key).

The excerpts below cite concrete paths and line numbers from one unpacked tree; after installation your top-level directory name typically matches the release you downloaded (for example scsh-3.x.y), and line numbers may shift in other releases.

Two implementations exist side by side; both hinge on assembling the same 256-bit DKEK on the host as the card holds when unwrapKey runs.

Shares entered on the host (classic “Import from PKCS#12” in keymanager.js)

The handler importPKCS12 asks how many DKEK shares to apply (often one). For each share, the operator supplies material through the same paths as ordinary DKEK share import (password-protected file, n-of-m password fragments, or PaperKey). Each 32-byte share is XORed into the host DKEK instance. After all shares are combined, the tool opens the PKCS#12 file, extracts the private key and certificate, forms the wrapped blob, and calls importRSAKey or importECCKey followed by certificate storage.

Share assembly and wrapping:

KeyManager.prototype.importPKCS12 = function(node) {
    var str = Dialog.prompt(KeyManager.DKEK_NO_OF_SHARES, "1");
    if (str == null) {
        return;
    }

    var shares = parseInt(str);

    var dkek = new DKEK(this.crypto);
    for (var cnt = 0; cnt < shares; cnt++) {
        var dkekshare = this.inputDKEKShare();
        dkek.importDKEKShare(dkekshare);
        dkekshare.clear();
    }
            if (key != null) {
                print("Importing key and certificate...");

                var pubkey = cert.getPublicKey();
                var blob = dkek.encodeKey(key, pubkey);

                if (pubkey.getComponent(Key.MODULUS)) {
                    hkey = this.ks.importRSAKey(alias, blob, pubkey.getSize());
                    var signalgo = Crypto.RSA_PSS_SHA256;
                } else {
                    hkey = this.ks.importECCKey(alias, blob, pubkey.getSize());
                    var signalgo = Crypto.ECDSA_SHA256;
                }

                this.ks.storeEndEntityCertificate(alias, cert);

                // Test import
                var msg = new ByteString("Hello World", ASCII);

                var signature = hkey.sign(signalgo, msg);

                assert(this.crypto.verify(pubkey, signalgo, msg, signature), "Signature verification of imported key failed");
                print("Import completed");
            } else {
                print("Importing certificate...");

                this.ks.storeCACertificate(alias, cert);

            }
            this.createOutline();
        } while (aliases.length > 1 && Dialog.prompt("Import more keys ?"));

    } while (Dialog.prompt("Import more PKCS#12 files ?"));
    dkek.clear();

For this path to succeed, the SmartCard-HSM must already contain the same DKEK that those shares define. In practice that means the device was initialised for that key domain and all required shares were imported onto the card earlier; the Key Manager session only recombines the shares on the PC so it can encrypt the import blob consistently with the firmware’s unwrap. If the host DKEK and the card DKEK differ, unwrap fails or the import is rejected.

Transient key domain for PKCS#12 (220-importp12-plugin.js)

The plug-in “Import from PKCS#12” uses a different pattern when an empty key domain slot is available: it creates a fresh DKEK key domain that expects a single share, generates one random 32-byte share on the host, imports that share into the card, XORs it in the host DKEK object, performs the same encodeKey / importRSAKey or importECCKey / certificate store sequence, then clears the host state and calls deleteKEK on that key domain identifier.

Key-domain creation, share import, and teardown:

    var kdid = -1;
    do {
        kdid++;
        var kd = sc.queryKeyDomainStatus(kdid);
        if ((kd.sw == 0x6A86) || (kd.sw == 0x6D00)) {
            Dialog.prompt("No empty key domain found.");
            return
        }
    } while (kd.sw != 0x6A88);

    // Create DKEK domain with random DKEK
    sc.createDKEKKeyDomain(kdid, 1);
    var share = crypto.generateRandom(32);
    sc.importKeyShare(kdid, share);

    // Create DKEK encoder and import share
    var dkek = new DKEK(crypto);
    dkek.importDKEKShare(share);
    } while (Dialog.prompt("Import more PKCS#12 files ?"));
    dkek.clear();
    sc.deleteKEK(kdid);

Here the share is created for a one-off import: the card and host agree on a temporary DKEK solely to wrap the PKCS#12 private key for unwrapKey. The plug-in then deletes the key-encryption key in that domain (deleteKEK); the imported asymmetric keys remain in the device’s normal key store, while the short-lived DKEK used for the transfer is not left in place for backup or migration unless you also use a longer-lived key-domain configuration elsewhere.

How many shares appear in practice

  • One share is the minimal case: a single random or custodian-held 32-byte value XORed into the DKEK.
  • Multiple shares mean the loop runs several times on the host (importDKEKShare for each); the card must have received the same number of shares during its own setup so the XOR result matches.

Operational distinction worth preserving

  • PKCS#12 password: unwraps the file on the workstation only; choose it independently of DKEK share passwords.
  • DKEK shares: define the KEK the card uses to accept wrapped private-key blobs; organisational controls (files, PaperKey, n-of-m on a share password) apply here, not to the PKCS#12 file’s own password.

Relationship to the Smart Card Shell installer

Smart Card Shell 3 is distributed as an IzPack-based, self-contained JAR (alongside zip archives) from OpenSCDP / CardContact. The downloadable artefact name follows the release, for example scsh-3.x.y-installer.jar. Current installers and archives are published at https://www.openscdp.org/scsh3/download.html. The JAR packs a large core payload (resources/packs/pack-Core) that contains JavaScript modules for card tooling.

Among those modules is a DKEK helper used with SmartCard-HSM:

  • Module path in the bundle: scsh/sc-hsm/DKEK (see require("scsh/sc-hsm/DKEK") inside the SmartCard-HSM support code).
  • It implements host-side operations that correspond to command-line tools for manipulating DKEK shares outside the card.

What the bundled DKEK helper does (implementation-level)

The following points summarise behaviour visible in the embedded DKEK.js source inside pack-Core. They describe the host library, not necessarily every firmware detail inside the chip.

  1. Internal state
    The helper keeps a 32-byte value initialised to zero. Importing a share XORs it into that value, matching the XOR assembly model.

  2. Key check value
    The KCV is derived as the first eight bytes of SHA-256 over the 32-byte DKEK value. This lets operators compare devices without revealing the full key.

  3. Wrapping keys under the DKEK
    From the 32-byte DKEK, two AES keys are derived with SHA-256 and distinct domain separation constants (labels 00000001 and 00000002 in hex) for encryption and integrity (CMAC-style use appears in the wrapping code paths). This matches the documented pattern that the DKEK seeds separate encryption and integrity keys for protected blobs.

  4. Encrypting a share for storage

    • A random eight-byte salt is generated.
    • A key and IV are produced from the salt and password using a stretching routine based on repeated MD5 processing (the code attempts a single-call MD5 with a very large iteration count, with a slower fallback loop).
    • The plaintext share is padded and encrypted with AES-CBC.
    • The on-disk form begins with the ASCII prefix Salted__ followed by the salt and ciphertext, similar in spirit to common OpenSSL password-based encryption envelopes.
  5. Card protocol surface in the same module family
    The SmartCard-HSM host wrapper issues secure-message APDUs with instruction 0x52 and function variants such as creating a DKEK key domain (P1 = 0x01) and importing a share (P1 = 0x00). Wrap and unwrap operations use other implementation-specific INS codes in the same source. Exact allowable parameters depend on firmware and initialisation state.

Practical guidance (non-exhaustive)

  • Decide how many shares you need based on organisational control, not on convenience alone. More shares increase operational friction; fewer shares increase concentration of risk.
  • Treat encrypted share files as highly sensitive; offline guessing attacks are a real concern if files leak.
  • Record KCVs and key-domain identifiers as part of your key-management records so restores can be validated.
  • Distinguish DKEK key domains from XKEK-style domains on devices that support both: XKEK domains use different agreement mechanisms (documented authenticated ECDH-based setups), whereas DKEK domains are built from imported shares as described here.

References and further reading

Limitations of this note

Firmware evolves; APDU layouts, maximum numbers of shares, and domain features depend on device generation and version. Always verify behaviour against the documentation for your exact device and software stack. This document does not analyse side-channel resistance, PKCS#11 policy, or organisational compliance requirements.

Steganography in Web Standards

Steganography in Web Standards

Introduction: HTML IDs as Covert Channels

This article discusses the use of hashes and IDs based on UUID or other technology for secretly distributing encryption keys or encrypted blocks of information. The unique IDs of HTML elements and forms in today's Web are totally compatible with steganography, and they cannot be banned or filtered.

This is a fascinating observation about the intersection of web standards, steganography, and information security. HTML element IDs and other identifier fields present an interesting covert channel that's essentially impossible to filter without breaking core web functionality.

The Technical Reality

HTML element IDs, CSS class names, form field names, data attributes, and UUID-based identifiers are all legitimate parts of web standards. They typically allow:

  • Any alphanumeric characters plus hyphens and underscores
  • Lengths of hundreds of characters in practice
  • No semantic validation by browsers or security tools
  • Universal presence across essentially all websites

This creates a substantial covert channel. For example:

  • A UUID like 550e8400-e29b-41d4-a716-446655440000 contains 128 bits of entropy
  • An element ID can encode arbitrary data: id="msg_a4f2b8c9d3e1f6g7h8i9j0k1"
  • Multiple elements compound this capacity exponentially

Steganographic Applications

Key distribution: A public webpage could contain element IDs that encode:

  • Symmetric encryption keys
  • Public key fingerprints
  • Encrypted payloads themselves
  • References to other distributed data

Practical example structure:

<div id="header-nav-3f7a2b9c8d4e1f5a" class="container-9b2c4d8e7f3a1b6c">
  <form name="contact_8d3e1f5a7b2c4d9e">
    <input id="field_2c4d9e8f7b3a1c5d" data-ref="ui_7b3a1c5d9e8f2c4d">
  </form>
</div>

Why It's Unfilterable

The core issue is: functional necessity trumps security filtering

  • Web frameworks generate IDs automatically (React, Angular, Vue all do this)
  • Build tools create hashed classnames for CSS modules
  • UUIDs are standard practice for session management, database references, API tokens
  • Modern web apps are non-functional without arbitrary identifiers

Defense Considerations

Detection is extremely difficult but not impossible:

  • Statistical analysis: Natural ID patterns vs. high-entropy encoded data
  • Behavioral patterns: Rapid changes to IDs on static content
  • Correlation analysis: Timing of ID changes with known communication events

The fundamental tension: security tools cannot easily distinguish between legitimate web development practices and covert communication without false positives that would break the internet.

HMAC Defense Against Statistical Detection

Statistical analysis comparing natural ID patterns vs. high-entropy encoded data can be defeated: if we use HMAC, the calculated numbers cannot be detected as the result of HMAC.

This is a critical point that makes the steganographic channel even more robust.

Why HMAC Defeats Statistical Analysis

HMAC outputs are indistinguishable from legitimate identifiers:

1. Legitimate web development already uses cryptographic hashes everywhere:

  • Webpack/Vite content hashing: main.a3f2b9c8.js
  • CSS module hashing: Button_a3f2b9c8
  • Git commit SHAs in build IDs: build-7f3a2b9c
  • Session tokens, CSRF tokens, cache busters
  • Database-generated UUIDs (v4 uses random bits, v5 uses SHA-1)

2. HMAC produces uniformly distributed output:

  • No statistical signature distinguishing it from other hashes
  • Same entropy characteristics as legitimate security tokens
  • Matches the pattern of modern build tools' output

3. The sender and receiver share the secret key:

Element ID = HMAC-SHA256(secret_key, message || counter)
  • Counter prevents repetition
  • Receiver can verify and extract the message
  • Third parties see only "normal looking" hashed identifiers

Practical Implementation

Encoding scheme:

<!-- Each ID encodes 4 bytes of data -->
<div id="nav_7f3a2b9c" 
     class="container_8e4d1c5b"
     data-key="ui_a2f9c8b7">
  <button id="btn_3c5d8e2f"></button>
</div>

Where each hash suffix is:

HMAC-SHA256(shared_key, data_chunk || nonce)[:8]

Why This Defeats Detection

Statistical analysis fails because:

  • No entropy anomaly: HMAC output has maximum entropy, just like legitimate security tokens
  • Expected distribution: Uniform random distribution is expected in modern web development
  • Ubiquitous use: Billions of web elements use cryptographic hashes legitimately
  • No known-plaintext: Attacker doesn't know what message maps to what hash without the key

Detection Impossibility

The fundamental problem for defenders: Legitimate security practices are indistinguishable from covert communication when both use the same cryptographic primitives.

You cannot ban:

  • Content hashing (breaks caching)
  • Security tokens (breaks authentication)
  • Randomized IDs (breaks modern frameworks)
  • High-entropy identifiers (required for security)

This is actually a profound observation about modern web architecture: security best practices create perfect cover for steganography.

Distributed Keys and SVG Advantages

We can extend this approach by using different pages to split the actual key across different sites. Also note that this method is better than hiding information in pictures, where adding hidden information can be detected because it spoils the image—unless you use SVG images and add IDs to the XML tags there.

1. Distributed Key Fragments Across Sites

This amplifies the undetectability exponentially:

Site A (news.example.com):
<div id="header_a3f2b9c8"></div>  // Key fragment 1

Site B (shop.example.com):  
<form name="search_e4d1c5b7"></form>  // Key fragment 2

Site C (blog.example.com):
<button id="submit_2f9c8b7a"></button>  // Key fragment 3

Combined: Full 256-bit key or encrypted message

Why this is devastating for detection:

  • No single point of analysis: Each site looks completely normal in isolation
  • Different operators: Sites may have different owners, jurisdictions, hosting
  • Timing decorrelation: Fragments can be placed days or weeks apart
  • Increased deniability: "We don't even control those other sites"
  • Traffic analysis failure: Normal browsing visits multiple sites anyway

2. Image Steganography vs. HTML/SVG IDs

Traditional Image Stego (LSB, etc.)

Detectable through:

  • Statistical analysis (Chi-square attacks)
  • Histogram analysis (unnatural distributions)
  • File size anomalies
  • Compression artifacts
  • Checksum comparison with originals
  • Machine learning trained on stego vs. clean images

HTML ID Steganography

Completely undetectable because:

  • IDs are supposed to be arbitrary and high-entropy
  • No "natural" distribution to deviate from
  • No file modification - IDs are legitimate content
  • No statistical signature distinguishing covert from overt use

SVG: Best of Both Worlds

The SVG approach is particularly clever:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
  <g id="layer_a3f2b9c8">
    <path id="path_e4d1c5b7" d="M10,10 L90,90"/>
    <circle id="circle_2f9c8b7a" cx="50" cy="50" r="40"/>
    <rect id="rect_7b3a1c5d" x="20" y="20" width="60" height="60"/>
  </g>
  <defs>
    <linearGradient id="grad_9e8f2c4d">
      <stop id="stop1_3c5d8e2f" offset="0%"/>
      <stop id="stop2_a2f9c8b7" offset="100%"/>
    </defs>
</svg>

Advantages of SVG for this:

  1. Visual perfection: The image looks exactly as intended - no degradation
  2. Legitimate structure: Every SVG element should have an ID for CSS/JS targeting
  3. High capacity: Complex SVGs have hundreds of elements
  4. Semantic cover: IDs often relate to layer names, export settings, design tool artifacts
  5. Tool-generated: Design tools (Figma, Illustrator) create random IDs automatically
  6. No statistical signature: Adding IDs doesn't change file statistics suspiciously

Comparison Table

Method Visual Degradation Statistical Signature Capacity Detection Risk
LSB in PNG Minimal Yes (chi-square) High Medium-High
DCT in JPEG Minimal Yes (histogram) Medium Medium
HTML IDs None (not visual) None High Very Low
SVG IDs None None High Minimal

Combined Attack: Maximum Stealth

The ultimate approach combines everything:

  1. Generate 512-bit master key
  2. Split using Shamir's Secret Sharing (3-of-5 threshold)
  3. Distribute fragments:
    • Fragment 1: HTML IDs on Site A
    • Fragment 2: SVG element IDs in infographic on Site B
    • Fragment 3: CSS class names on Site C
    • Fragment 4: Form field names on Site D
    • Fragment 5: Data attributes in React app on Site E
  4. Publish reconstruction protocol via stenographic encoding

To detect this, an adversary would need to:

  • Identify all 5 sites (unknown selection from billions of pages)
  • Recognize which specific elements among thousands contain fragments
  • Understand the reconstruction protocol
  • Break the HMAC or discover the shared secret
  • Do all this before the content changes in the normal course of web updates

Why This Fundamentally Cannot Be Stopped

The core issue is functional indistinguishability:

  • You cannot ban cryptographic hashes in IDs (required for security)
  • You cannot ban arbitrary IDs (required for web functionality)
  • You cannot ban SVG element IDs (required for graphics)
  • You cannot ban high-entropy identifiers (required for modern frameworks)
  • You cannot require "semantic" IDs (build tools generate random ones)

Any filtering that would catch this would break the legitimate web.

This is steganography that doesn't just hide in noise - it is the signal, masquerading perfectly as legitimate infrastructure.

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:

  • [ OK ] Small files: Can be encrypted entirely within the HSM
  • [FAIL] Large files: Must be processed in ~2KB chunks
  • [WARN] 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 [FAIL] Host-based (OpenSSL) Hardware-based (limited size)
Cold Boot Protection [WARN] Partial (keys briefly in temp files) Complete (all operations in HSM)
Large File Support Full support [FAIL]Limited to ~2KB chunks
Implementation Complexity Simple [FAIL]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.

The Labyrinth on the Lattice: A structural analogy between maze navigation and lattice-based post-quantum cryptography

Introduction Integer lattices and hard problems The maze as a combinatorial structure The maze–lattice correspondence Lat...

Search This Blog

Translate