I’ve been trying to set up hibernation on my laptop while also maintaining an encrypted root partition and swap using secure boot and my laptop’s TPM. I’ve documented the steps I’ve followed below, but I still am unable to enable hibernation.
I was under the impression that the only reason you can’t normally have both an encrypted harddrive and hibernation was because swap had to be encrypted as well, but if both the root partition and the swap are encrypted, I’m using UEFI secure boot, and they are automatically decrypted at boot using the TPM, shouldn’t that relieve those security concerns?
After completing the below, entering systemctl hibernate errors saying hibernation is not set up for the system. Am I missing something or is it just not possible? I can confirm not needing to enter passwords for my swap or root FS due to the TPM unlock.
My personal documentation below:
Drop into root shell
sudo su -
Setup LUKS encryption with automatic unlock with TPM
Install necessary components, regenerate initramfs and reboot
dnf install -y clevis clevis-luks clevis-dracut clevis-udisks2 clevis-systemd
dracut -fv --regenerate-all && systemctl reboot
Identify swap and root partition devices, names, and luks UUIDs…
lsblk -f
cryptsetup luksUUID <UUID>
In my case, my home partition is on /dev/nvme0n1p4 and my swap is /dev/nvme0n1p3
# the encrypted home partition
clevis luks bind -d /dev/nvme0n1p4 tpm2 '{"pcr_ids":"1,4,5,7"}'
# the encrypted swap
clevis luks bind -d /dev/nvme0n1p3 tpm2 '{"pcr_ids":"1,4,5,7"}'
Set a timeout before the system asks for a password, to allow time for the TPM to load and enter the password for you
systemctl edit systemd-ask-password-plymouth.service
Add the below then ctrl+o ctrl+x to save and exit
[Service]
ExecStartPre=/bin/sleep 10
Create a dracut configuration file to install the systemd-ask-password-plymouth service: vi /etc/dracut.conf.d/systemd-ask-password-plymouth.conf
Add the below, ensure there are spaces inside the quotation marks on either side of the filename
install_items+=" /etc/systemd/system/systemd-ask-password-plymouth.service.d/override.conf "
Regenerate initramfs and reboot
dracut -fv ‐‐regenerate-all && systemctl reboot
Edit crypttab file (/etc/crypttab)to specify decryption of swap file at boot, duplicate the already present line for your root FS crypttab entry and change the UUIDs to reflect the swap file, use cryptsetup luksUUID /dev/nvme0n1p3 and cryptsetup luksUUID /dev/nvme0n1p4 to get the luks UUIDs for your root and swap partitions.
<swap LUKS UUID> UUID=<swap UUID> none x-initrd.attach
<root FS LUKS UUID> UUID=<root FS UUID> none x-initrd.attach
Regenerate initramfs and reboot: dracut -fv --regenerate-all && systemct reboot
Edit fstab to include swap, append the following to /etc/fstab:
UUID=<swap UUID> none swap defaults,x-systemd.device-timeout=0 1 1
Rebind your home and swap partitions. You will have to do this every time you update the kernel.
# encrypted home partition
clevis luks regen -d /dev/nvme0n1... -s 1
# encrypted swap
clevis luks regen -d /dev/nvme0n1... -s 1
Wild guess as I’m not using dracut and have only setup encrypted hibernation on an old bios laptop…
But did you edit the systemd-sleep.conf (usually
/etc/systemd/sleep.conf, although there are some other possible locations)? The other old-school and universal way of telling your system that hibernate is enabled without systemd would be aresume=kernel parameterI’ve got multiple machines that do this, but all on nixos.
After completing the below, entering systemctl hibernate errors saying hibernation is not set up for the system.
This is weird, so I’d start here. Can you get the exact error and/or whatever it logs to journald?
I’d ignore all the TPM stuff until you can hibernate it and resume with a password. Maybe the swap is just too small? Maybe something in /etc/systemd/sleep.conf?
In case it helps, my device setup looks like this:
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS nvme0n1 crypto_LUKS 2 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx └─encrypted LVM2_member LVM2 001 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ├─encrypted-swap swap 1 swap xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx [SWAP] └─encrypted-root btrfs root xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxx xxx /mnt/root /nix/store / nvme1n1 ├─nvme1n1p1 vfat FAT32 xxxxxxxxx xxxxx xxx /boot [...]so luks -> lvm -> { swap, btrfs }
Edit:
https://wiki.archlinux.org/title/Power_management/Suspend_and_hibernate#Hibernation
When the system is running on UEFI, systemd-sleep(8) will automatically pick a suitable swap space to hibernate into, and the information of the used swap space is stored in HibernateLocation EFI variable.
So far I haven’t figured out from the systemd docs what “automatically pick a suitable swap space” actually means, or if that’s actually accurate.
Why binding specifically to PCRs 1,4,5 and 7? Are they immutable even with updates that modify bd and dbx (I think I saw one recently drop on Ubuntu)?
You know I’m not 100% sure, I was following another tutorial that I can’t find anymore, but if I remember right 1 was for the UEFI state, 4 was to make sure the bootloader wasn’t changed, 5 was for secure boot, and 7 was for the OS being booted (To make sure someone isn’t booting Kali in a live disk or something), but I could be wrong.


