Raspberry Pi TPM2 LUKS2 Auto-Unlock with systemd-cryptenroll¶
systemd-cryptenroll can enroll an external TPM 2.0 device as an unlock token for a LUKS2 volume. Test this on an empty removable data partition—not the running root filesystem—and keep an independently stored passphrase or recovery key. Auto-unlock improves unattended operation but makes recovery design more important.
The formatting commands in this guide erase the selected partition
Use an empty test device with a verified backup. Replace every <test-partition> placeholder manually only after checking lsblk. Never experiment on the current root, boot, or production data partition.
What this design protects¶
| Scenario | Expected result |
|---|---|
| Encrypted storage removed without TPM | Data remains encrypted |
| Same Pi and TPM, accepted policy | Volume unlocks automatically |
| TPM removed or cleared | TPM unlock fails; recovery credential is required |
| PCR-bound boot state changes | TPM unlock may fail; recovery/update procedure is required |
| Attacker controls an already-unlocked running Pi | Data may be accessible through the running OS |
The TPM is not the bulk encryption engine. LUKS/dm-crypt encrypts data; the TPM protects release of an enrolled randomized key.
Prerequisites¶
- A TPM 2.0 module already exposed as
/dev/tpmrm0 - Raspberry Pi OS Trixie with current updates
- An empty, disposable USB/SSD partition
- Local console access
- A tested backup and a place to store recovery material offline
Complete TPM module detection before continuing:
If the last command is unavailable or lacks TPM2 support, check the installed systemd version and package documentation before changing storage.
1. Identify an empty test partition¶
List stable identifiers, filesystems, mounts, and the current root source:
Confirm all of the following:
- it is not the device containing
/ - it is not
bootfs - it contains no required data
- it is unmounted
- its size and hardware identity match the intended test device
Prefer a stable /dev/disk/by-id/...-partN path. Do not rely on /dev/sda1, which can change when devices are reconnected.
2. Install and record the tool versions¶
Save this information with the test results because token formats, options, and boot integration can change across systemd releases.
3. Create a LUKS2 test volume¶
After verifying the target again, create the LUKS2 header:
Use a strong temporary test passphrase and store it outside the Raspberry Pi. Verify the header before creating a filesystem:
Creating the filesystem below erases any previous filesystem inside the mapping:
Write a non-secret marker and confirm it survives a close/reopen cycle:
4. Add and verify a recovery credential¶
The original LUKS passphrase is already a recovery path. You can also generate a systemd recovery key in another slot:
The command prints a recovery key. Store it in an offline password manager or controlled recovery record, not in shell history, a screenshot left on the Pi, or a file on the encrypted device.
Close the mapping and test the recovery key before enrolling the TPM:
At the prompt, use the recovery key for one test. A credential that has not successfully unlocked the volume is not a recovery plan.
Back up the LUKS header to separately protected storage:
The header backup and any valid credential can be security-sensitive. Protect and inventory it like other recovery material.
5. Enroll the TPM without PCR binding first¶
For the first controlled test, bind the token to the TPM device but explicitly select no PCRs:
This proves device discovery and token handling without confusing the test with boot measurements. It does not restrict unlock to a particular boot state.
Inspect the LUKS2 token metadata and remaining key slots:
Do not remove the passphrase or recovery-key slots.
The systemd TPM2 crypttab documentation describes how a randomized key is encrypted to a TPM-derived primary key and stored in the LUKS2 JSON token metadata.
6. Test manual TPM unlock¶
Close any active mapping:
Test through the systemd cryptsetup helper installed on the system. Its path can be found with:
On many current installations, a direct test looks like:
Verify and detach:
Use the actual helper path shown by the unit on your OS. If TPM unlock fails, stop and inspect logs; do not remove recovery slots.
7. Configure a non-critical data mount¶
Get the LUKS UUID:
Add a line to /etc/crypttab, replacing <luks-uuid>:
Add the decrypted filesystem to /etc/fstab by its filesystem UUID:
Example:
Validate the filesystem table and test generated mounts before rebooting:
Keep local console access for the first reboot. nofail prevents this non-critical data volume from making an ordinary boot dependency mandatory; choose different semantics only when the application explicitly requires the volume.
8. Decide whether PCR binding is justified¶
PCR binding should be added only after identifying what measures the Raspberry Pi boot components and how legitimate updates change those measurements.
Record several normal cold boots and one software update in a test environment:
Questions to answer:
- Which component extends each candidate PCR?
- Is a matching event log available and complete?
- Does an EEPROM, kernel, initramfs, or
config.txtupdate change it? - How will the new expected state be authorized?
- Can the recovery key unlock the volume after rejection?
Do not assume PCR 7 has PC/UEFI Secure Boot meaning on a Raspberry Pi boot stack. Empty PCR binding is device-bound only; arbitrary PCR binding can create denial of service without adding the intended trust.
When a tested PCR policy is ready, enroll a new TPM token or replace the test token using the exact systemd version's manual. Keep the previous recovery credential throughout rollout.
9. Failure drills¶
Perform these on the disposable volume:
| Drill | Expected outcome |
|---|---|
| Reboot with normal TPM | Automatic data-volume unlock works |
| Disable/remove TPM connection with power off | TPM unlock fails; recovery credential works |
| Change a measured boot component in a PCR-bound test | TPM policy rejects; recovery works |
| Revert the boot change | Approved state returns or documented re-enrollment works |
| Corrupt a copy of the LUKS header | Header backup restores only the test copy |
| Replace module | Old TPM token cannot unlock; new module can be enrolled after recovery |
Never clear the only TPM protecting production data as a test. Test replacement with disposable keys or a cloned lab design.
Remove the TPM token safely¶
First confirm that a passphrase or recovery key unlocks the volume. Then list tokens and slots:
Remove TPM2 enrollment with the installed systemd tool:
Verify the TPM token is gone and the recovery credential still works. Removing a LUKS token does not clear the entire TPM.
Root encryption is a separate project¶
Encrypting the Raspberry Pi OS root filesystem requires early-boot TPM availability, an initramfs containing the correct drivers and cryptsetup integration, correct kernel command-line/root mapping, and a remote/local recovery path. Raspberry Pi boot differs from a typical PC UEFI design.
Do not extend this data-volume walkthrough to / by changing device names. Build and test a reproducible image on separate media, then perform repeated cold boots and recovery drills before deployment.
Common mistakes¶
- Formatting the wrong partition
- Testing first on the current root filesystem
- Enrolling TPM before verifying a recovery key
- Removing every passphrase slot
- Binding to PCRs copied from a PC guide
- Storing recovery key and header backup beside the Raspberry Pi
- Assuming TPM auto-unlock protects an already-running compromised OS
- Clearing the TPM during troubleshooting
- Rebooting a remote-only device without console recovery
FAQ¶
Does TPM auto-unlock weaken encryption?¶
It changes the access policy. Storage removed from the TPM remains encrypted, but the approved device can unlock unattended. Security depends on the boot policy, physical threat, and controls on the running OS.
Must I bind LUKS2 to PCRs?¶
No. Device-only enrollment is useful for integration testing and some threat models. PCR binding adds boot-state conditions only when those measurements are meaningful and maintainable.
Why keep a passphrase after TPM unlock works?¶
TPMs, wiring, policies, and boot measurements can fail or change. A separately stored recovery credential prevents an availability failure from becoming permanent data loss.
Can I use this for NVMe?¶
Yes, for a separate data partition when the NVMe device, TPM driver, and systemd integration are available. Identify it with a stable /dev/disk/by-id path and never format the boot/root partition by accident.