Documentation · Getting Started

Getting Started with TPM HSM

Set up the open-source hardware security module powered by TPM 2.0. This guide covers server installation, the desktop client, attestation, key import, and configuration.

On This Page

  1. Prerequisites
  2. Server Installation & Setup
  3. Desktop Client Installation
  4. First Steps
  5. Configuration
  6. YubiKey Setup
  7. Troubleshooting
  8. Further Resources

1. Prerequisites

Before installing TPM HSM, make sure your environment meets the following requirements.

Server requirements (Linux)

Desktop client requirements

Verify your TPM

On Linux, confirm the TPM resource manager device exists:

ls -l /dev/tpmrm0

If the device is present, your TPM 2.0 is accessible. You can also check with:

tpm2_getcap properties-fixed 2>/dev/null | head -5

Note: TPM HSM uses the TPM resource manager (/dev/tpmrm0) by default. This is the recommended TCTI for multi-process access. If your system uses a different path, you can configure it in config.yaml.

2. Server Installation & Setup

The TPM HSM server is a gRPC service that manages all TPM 2.0 operations — key import, signing, attestation, and the key registry. It runs on the machine with the physical TPM chip.

Clone the repository

git clone https://github.com/szsz/tpm-hsm.git
cd tpm-hsm

Install dependencies

The server requires the following Python packages (defined in requirements.txt):

pip install -r requirements.txt

This installs:

Start the server

python -m hsm.main

By default the server listens on 0.0.0.0:50051 using the configuration in config.yaml. You can specify a custom config path:

python -m hsm.main -c /path/to/config.yaml

On success you will see:

TPM-HSM listening on 0.0.0.0:50051

Warning: The server starts without TLS by default — this is for development only. For production, configure TLS certificates in config.yaml. See the Configuration section below.

3. Desktop Client Installation

The desktop client is a cross-platform GUI built with pywebview. It communicates with the server over gRPC and provides views for connecting, attesting, importing keys, signing, and managing the key registry.

Using the launch script (recommended)

From the repository root, run:

bash run_desktop.sh

This script automatically:

  1. Finds a suitable Python interpreter (prefers Python 3.12)
  2. Creates a virtual environment in .venv/ if one does not exist
  3. Installs desktop dependencies from desktop/requirements.txt
  4. Launches the desktop application via python -m desktop.main

Manual installation

If you prefer manual setup:

cd tpm-hsm
python3.12 -m venv .venv
source .venv/bin/activate
pip install -r desktop/requirements.txt
python -m desktop.main

The desktop client depends on:

4. First Steps

Connecting to the server

When you launch the desktop client, the first view prompts you to enter the server address. Enter the host and port where the TPM HSM server is running (e.g., 192.168.1.100:50051 or localhost:50051 for local development).

Connection settings are saved to ~/.tpm-hsm/desktop.yaml so you don't need to re-enter them each time.

Running attestation

Remote attestation proves the server has a genuine TPM 2.0 chip. This is a critical first step before trusting any keys stored on the server.

The attestation flow:

  1. The client retrieves the TPM's Endorsement Key (EK) public key and certificate
  2. The EK certificate chain is verified against known TPM manufacturer root CAs (Intel, Infineon, STMicro, Nuvoton, AMD)
  3. A MakeCredential/ActivateCredential challenge proves the Attestation Key (AK) is co-resident with the verified EK
  4. A PCR quote signed by the AK is verified for nonce freshness

In the desktop client, navigate to the Attest view and click Run Attestation. A green result means the TPM is genuine and the keys are hardware-protected.

Importing a key

TPM HSM uses a secure client-side key wrapping protocol. Private keys are never sent to the server in plaintext — they are encrypted so that only the target TPM can decrypt them.

The import process:

  1. The client fetches the TPM's Storage Root Key (SRK) public key and auth policy
  2. A random seed is RSA-OAEP encrypted to the SRK — only this specific TPM can decrypt it
  3. AES-128-CFB and HMAC keys are derived from the seed
  4. The private key is encrypted and integrity-protected client-side
  5. Three blobs (object_public, duplicate, encrypted_seed) are sent to the server
  6. The server calls TPM2_Import — the TPM decrypts the key inside silicon

In the desktop client, navigate to the Import view to import a key from your local vault or generate a new one.

Note: You can also generate keys in the Local Vault (~/.tpm-hsm/keys/), which stores password-encrypted PEM files as backup. This supports air-gapped workflows via pre-wrapping — encrypting a key for a specific TPM without a network connection.

5. Configuration

The server is configured via config.yaml in the project root. Here are all available options:

TPM settings

Key Default Description
tpm.tcti device:/dev/tpmrm0 TPM Command Transmission Interface. Use device:/dev/tpmrm0 for the resource manager (recommended) or device:/dev/tpm0 for direct access.
tpm.srk_persistent_handle null Hex handle for a persistent SRK (e.g., 0x81000001). Set to null to create a transient SRK each time the server starts.

Server settings

Key Default Description
server.listen 0.0.0.0:50051 Address and port the gRPC server binds to.
server.tls.cert Path to server TLS certificate (PEM).
server.tls.key Path to server TLS private key (PEM).
server.tls.ca_cert Path to CA certificate for client verification.
server.tls.require_client_cert false Enable mutual TLS (mTLS) — require clients to present a certificate.

Storage settings

Key Default Description
storage.database db/hsm.db Path to the SQLite database for key metadata, trusted keys, registry, and verification certificates.
storage.key_blobs_dir keys/ Directory for storing TPM key blobs on disk.

All paths are resolved relative to the config file directory.

Example: enabling TLS

tpm:
  tcti: "device:/dev/tpmrm0"
  srk_persistent_handle: null

server:
  listen: "0.0.0.0:50051"
  tls:
    cert: "tls/server.crt"
    key: "tls/server.key"
    ca_cert: "tls/ca.crt"
    require_client_cert: false

storage:
  database: "db/hsm.db"
  key_blobs_dir: "keys/"

6. YubiKey Setup

TPM HSM integrates with YubiKey PIV for hardware-backed signing authorization. A YubiKey can serve as the "trusted key" that authorizes TPM signing operations — even if the server is compromised, the TPM refuses to sign without a valid YubiKey signature.

Requirements

Generating a key on the YubiKey

TPM HSM uses the PIV Signature slot (9c) for signing authorization. From the desktop client:

  1. Navigate to the YubiKey view
  2. The client detects your YubiKey automatically
  3. Generate a new ECC P-256 key in the signature slot, or use an existing one

YubiKey attestation

YubiKey attestation proves a key was generated on the physical device (not imported). The verification chain:

  1. The YubiKey produces an attestation certificate for the key in slot 9c
  2. The intermediate CA from slot f9 (factory-provisioned by Yubico) signs this certificate
  3. The chain is verified up to the Yubico PIV Root CA
  4. Attestation OIDs reveal the YubiKey serial number, firmware version, PIN policy, and touch policy

Adding a YubiKey as a trusted key

Once your YubiKey key is attested, register it as a trusted key on the server. This allows it to authorize TPM signing operations via the PolicyAuthorize or PolicySigned mechanism. The key registry view shows trust relationships in a web of trust model.

7. Troubleshooting

Permission denied on /dev/tpmrm0

The TPM device requires appropriate permissions. Add your user to the tss group:

sudo usermod -aG tss $USER

Then log out and back in. Verify with:

ls -la /dev/tpmrm0

tpm2-pytss fails to install

The tpm2-pytss package requires the TPM2 Software Stack C libraries. On Debian/Ubuntu:

sudo apt install libtss2-dev

On Fedora:

sudo dnf install tpm2-tss-devel

Server shows "Running WITHOUT TLS"

This warning means no TLS certificate is configured. For production deployments, generate TLS certificates and configure them in config.yaml under server.tls. See the Configuration section.

Desktop client fails to start (pywebview error)

pywebview requires a GUI toolkit backend. On Linux, install one of:

# GTK backend (recommended on Linux)
sudo apt install python3-gi python3-gi-cairo gir1.2-gtk-3.0 gir1.2-webkit2-4.1

# Or Qt backend
pip install PyQt5

On Windows and macOS, pywebview uses native WebView controls and should work out of the box.

Python 3.14 compatibility

pywebview and some dependencies do not yet support Python 3.14. Use Python 3.12 for the desktop client. The run_desktop.sh script automatically prefers Python 3.12 if available.

YubiKey not detected

Ensure the PC/SC daemon is running:

sudo systemctl status pcscd

If it is not running, start and enable it:

sudo systemctl enable --now pcscd

Connection refused when connecting to server

8. Further Resources

Need help? Open an issue on GitHub Issues with details about your environment and the error you are seeing.