GitHub - No-0n3/tkey-luks

7 min read Original article โ†—

TKey-LUKS: Hardware-Based LUKS Unlock with Tillitis TKey

Conventional Commits

Unlock LUKS encrypted root partitions at boot using Tillitis TKey hardware security key.

Overview

This project provides a secure mechanism to unlock LUKS encrypted root partitions during boot using a Tillitis TKey hardware security device. The TKey must be physically present in the computer during boot, and the LUKS encryption key is derived from cryptographic operations performed by the TKey.

Features

  • ๐Ÿ” Hardware-Based Security: LUKS key derived from TKey device secrets
  • ๐Ÿ”‘ Improved USS Derivation: Password-derived USS using PBKDF2 (never stored on disk!)
  • ๐Ÿš€ Boot Integration: Seamless integration with initramfs
  • ๐Ÿ”ง Static Binary: No dependencies in initramfs environment
  • ๐Ÿงช Test Environment: Hardware and image-based test scripts
  • ๐Ÿ“ฆ Easy Installation: Automated installation scripts
  • ๐Ÿ”„ Fallback Support: Optional password fallback
  • โœ… Conventional Commits: Strict commit standards enforced via CI and git hooks

Security Highlights

NEW: Improved USS Derivation - The User Supplied Secret (USS) is now derived from your password using PBKDF2 instead of being stored in a file. This means:

  • โœ… USS is never written to disk or stored in initramfs
  • โœ… Password is used in TWO cryptographic layers (USS + challenge)
  • โœ… Each system has a unique USS (via machine-id salt)
  • โœ… Strong KDF with 100k iterations makes brute-force harder
  • โœ… No extractable secrets from the boot partition

Why this matters: Previously, if USS was stored in initramfs, an attacker with physical access could extract it, reducing 3-factor auth to 1-factor. The improved approach keeps USS ephemeral and password-derived.

See docs/SECURITY.md for detailed security analysis and USS implementation.

Project Status

โœ… v1.1.1 Release - Salt availability fix for improved USS derivation!

Latest Updates (v1.1.1)

  • โœ… Critical Fix: Machine-id now copied to initramfs for consistent USS derivation
  • โœ… Verification Tool: New script to check salt availability
  • โœ… Documentation: Complete troubleshooting guide for USS derivation
  • โœ… Test Improvements: Fixed test scripts for better reliability

Upgrade from v1.1.0? You must rebuild initramfs and re-add LUKS keys. See docs/IMPROVED-USS-FIX.md for details.

Previous Release (v1.1.0)

  • โœ… Password-Based USS Derivation: PBKDF2-HMAC-SHA256 with 100k iterations
  • โœ… No USS Files: Removed need for USS file storage (ephemeral derivation)
  • โœ… System-Unique: Machine-id used as salt for system-specific keys
  • โœ… Double Protection: Password used in USS derivation + BLAKE2b challenge
  • โœ… Backward Compatible: Old --uss PATH still works (with warnings)
  • โœ… Debian Packaging: debian/ kept in-repo for reproducible builds; CI uses it to build packages
  • โœ… Comprehensive Documentation: Security analysis, migration guide, setup instructions

Why keep debian/ in-repo? It keeps packaging reproducible, reviewable, and buildable locally with standard debhelper tooling. CI consumes the same files to avoid drift between local and server builds.

Tested Systems

  • Ubuntu 24.04 Desktop - Full boot-time LUKS unlock with improved USS derivation
  • Real hardware: NVMe encrypted partitions with TKey
  • Boot timing: ~33 seconds total (including physical touch)
  • Test results: USS derivation deterministic, system-specific, secure

See docs/SETUP.md for setup instructions and docs/SECURITY.md for security details.

Quick Start

Prerequisites

  • Tillitis TKey hardware device
  • Linux system with initramfs-tools (Ubuntu 24.04 tested)
  • Go 1.20+ (for building client)
  • LLVM/Clang 15+ (for building device app)
  • cryptsetup-initramfs package
  • libusb-1.0-0-dev

Installation

# Clone repository with submodules
git clone --recursive https://github.com/No-0n3/tkey-luks.git
cd tkey-luks

# Install Node.js dependencies and git hooks (for contributors)
npm install

# Build all components
./scripts/build-all.sh

# Install to system
sudo make -C client install
sudo make -C device-app install
sudo make -C initramfs-hooks install

Adding TKey to LUKS Partition

# Add TKey-derived key to LUKS partition (requires existing password)
cd client
sudo ./tkey-luks-client --challenge "YourChallengePhrase" | \
  sudo cryptsetup luksAddKey /dev/nvme0n1p6 -

# Verify key was added
sudo cryptsetup luksDump /dev/nvme0n1p6

Configuring Boot Unlock (Ubuntu 24.04)

Critical: Ubuntu 24.04 requires the initramfs option in /etc/crypttab for custom unlock scripts.

Edit /etc/crypttab and add initramfs to the options:

# Before:
luks-<uuid> UUID=<uuid> none luks,discard

# After:
luks-<uuid> UUID=<uuid> none luks,discard,initramfs

Then update initramfs:

sudo update-initramfs -u -k all

Usage (Improved USS Derivation)

New enrollment process (v1.1.0+):

# Enroll with improved USS derivation (recommended)
echo "YourPassword" | sudo tkey-luks-client \
  --challenge-from-stdin \
  --derive-uss \
  --output - | \
sudo cryptsetup luksAddKey /dev/sdXY -

At Boot:

  1. System prompts for password
  2. USS derived from password using PBKDF2 (never stored!)
  3. Touch TKey when it blinks (physical authentication)
  4. System derives LUKS key and unlocks automatically

Double protection: Your password is used in both USS derivation AND the BLAKE2b challenge, providing two independent cryptographic layers.

Fallback: Emergency LUKS password still works if TKey is not present.

Testing

# Test USS derivation unit tests
cd test
./test-uss-derivation.sh

# Test with real TKey hardware
./test-improved-uss.sh

# Test LUKS image creation and unlock
cd test/luks-setup
./create-tkey-test-image.sh
./add-tkey-key.sh
./test-unlock.sh

Architecture

The system consists of three main components:

  1. Device Application: Runs on TKey, performs cryptographic operations
  2. Client Application: Runs in initramfs, communicates with TKey
  3. initramfs Hooks: Integration with boot process
[initramfs] โ†’ [Client Binary] โ†’ [USB] โ†’ [TKey Device App]
     โ†“              โ†“                         โ†“
[Derived Key] โ†’ [cryptsetup] โ†’ [Unlock LUKS]

Documentation

Boot Process Details

The TKey-LUKS unlock happens early in boot:

  1. 2s: Script starts, TKey detected at /dev/ttyACM0
  2. 14s: User enters challenge phrase
  3. 13s: Key derivation on TKey (Blake2b, 64 bytes)

Troubleshooting

TKey not detected at boot

  • Check USB connection and power
  • Verify cdc-acm module loaded: lsmod | grep cdc_acm
  • Check initramfs contents: lsinitramfs /boot/initrd.img-$(uname -r) | grep tkey

Script not running

  • Verify initramfs option in /etc/crypttab (required for Ubuntu 24.04)
  • Rebuild initramfs: sudo update-initramfs -u -k all
  • Check dmesg after boot: dmesg | grep tkey-luks

Wrong crypttab path

  • Initramfs uses /cryptroot/crypttab, not /etc/crypttab
  • Script automatically reads from correct location

Key derivation fails

  • Ensure TKey button pressed when device blinks
  • Verify password matches enrollment
  • Check TKey device app loaded correctly: dmesg | grep tkey
  • For improved USS: Ensure system machine-id hasn't changed

USS derivation issues

If upgrading from v1.0.x (file-based USS) to v1.1.0 (improved USS):

  • Old --uss PATH still works (with deprecation warning)
  • Enroll new keyslot with --derive-uss before removing old one
  • Test new keyslot boots successfully before removing old
  • See docs/USS-DERIVATION.md for migration guide

Password not working

  • Different from v1.0: Password affects both USS derivation and BLAKE2b
  • Same password must be used at boot and enrollment
  • System-specific: Machine-id used as salt (moving disk to new system requires re-enrollment)

License

This project is licensed under the BSD-2-Clause License - see the LICENSE file for details.

Contributing

Contributions welcome! This project strictly follows Conventional Commits to maintain clear and semantic commit history.

๐Ÿ“‹ Commit Message Format

All commits must follow this specification:

<type>(<scope>): <description>

[optional body]

[optional footer(s)]

Standard Types:

  • feat: A new feature for users
  • fix: A bug fix for users
  • docs: Documentation changes only
  • style: Code style changes (formatting, semicolons, etc.)
  • refactor: Code change that neither fixes a bug nor adds a feature
  • perf: Performance improvements
  • test: Adding or updating tests
  • build: Changes to build system or dependencies
  • ci: Changes to CI configuration
  • chore: Other changes that don't modify src or test files

Examples:

feat(client): add timeout configuration for TKey detection
fix(initramfs): resolve race condition in device detection
docs: update Ubuntu 24.04 installation guide
build: upgrade commitlint to v20.4.1
test: add integration tests for challenge validation

๐Ÿ”’ Commit Validation

Commits are validated locally with git hooks and in CI with GitHub Actions.

โœจ Automatic Local Validation (Recommended)

Run npm install to automatically set up git hooks:

# Install dependencies and git hooks
npm install

What happens: The commit-msg hook validates your message before the commit is created.

  • โœ… Valid messages: commit proceeds normally
  • โŒ Invalid messages: commit is rejected with helpful error messages

๐Ÿ”ง Manual Hook Installation

Reinstall hooks manually if needed:

๐Ÿงช Manual Validation

Check commits without hooks:

# Validate last commit
npx commitlint --last

# Validate a message
echo "feat: add new feature" | npx commitlint

# Validate last 5 commits
npx commitlint --from HEAD~5

๐Ÿš€ CI/CD Validation

GitHub Actions automatically validates:

  • Push events: Last commit message
  • Pull requests: All commits in the PR

Result: PRs with invalid commits will fail CI checks and cannot be merged.

This system provides security against:

  • Unauthorized boot of stolen devices
  • Cold boot attacks (limited)
  • Software-only attacks on LUKS keys

See docs/SECURITY.md for full threat model and considerations.

Acknowledgments

  • Tillitis for the TKey hardware and SDK
  • cryptsetup project
  • Linux kernel initramfs framework