User:Cvlc/Drafts/Dm-crypt
LUKS on a partition with TPM2, Secure Boot, and PCR policies
This example is similar to #LUKS on a partition, but integrates the use of Secure Boot and a Trusted Platform Module (TPM), enhancing the overall security of the boot process. With this setup, the root volume can only be decrypted when booting a known Unified kernel image for which a signature can be provided. See systemd-cryptenroll(1) § TPM2_PCRs_and_policies, [1] and [2].
In this configuration, the EFI system partition remains unencrypted, housing a unified kernel image and systemd-boot—both signed for use with Secure Boot. The /home
partition itself is unencrypted to avoid double encryption, since individual home directories are individually encrypted with systemd-homed. The TPM plays a crucial role by monitoring the boot phases. This approach is akin to BitLocker on Windows or FileVault on macOS. A recovery-key will also be created to make sure the data remains accessible in case of a problem with the TPM unlocking mechanism. In summary, the following tools will be needed:
- mkinitcpio to create the initramfs
- systemd-ukify(1) to package the UKI and sign it
- kernel-install to deploy it
- systemd-cryptenroll to enroll the PCR policy to the Luks volume
- systemd-homed to encrypt individual user home directories
- The setup is susceptible to cold boot attacks, where an attacker, even after a prolonged power-off period, could exploit the automatic loading of the TPM key upon turning on the computer. This is particularly relevant for high-value targets.
In this example, partitions are created respecting systemd#GPT partition automounting, there is no need for an fstab or crypttab file.
+----------------+------------------+-------------------------+-------------------- | ESP | Swap | Root partition | Home | | unencrypted | encrypted | encrypted | unencrypted | | | | | | | /boot | /swap | / | /home | | | | | | | | /dev/mapper/swap | /dev/mapper/root | | | ---------------+------------------|-------------------------+-------------------| | /dev/sda1 | /dev/sda2 | /dev/sda3 | /dev/sda4 | +----------------+------------------+-------------------------+-------------------+
Follow the Installation guide up to step Installation guide#Partition the disks.
Preparing the disk
Prior to creating any partitions, you should inform yourself about the importance and methods to securely erase the disk, described in dm-crypt/Drive preparation.
Partition the drive with the GUID Partition Table (GPT), then create the needed partitions:
- Create an EFI system partition (
/dev/sda1
in this example). Make sure to set the proper partition type (e.g. by using the 'uefi' partition type alias in fdisk). - Create the swap partition (
/dev/sda2
in this example). Make sure to set the proper partition type (e.g. by using the 'swap' partition type alias in fdisk). - Create a root partition (
/dev/sda3
in this example). Make sure to set the proper partition type (e.g. by using the '23' partition type in fdisk). - Create a home partition (
/dev/sda4
in this example). Make sure to set the proper partition type (e.g. by using the 'home' partition type alias in fdisk).
Preparing the root partition
The following commands create and mount the encrypted root partition. If you want to use particular non-default encryption options (e.g. cipher, key length), or if you don't want to use TPM based decryption, see the encryption options before executing the first command.
Create the LUKS volume (you can simply use a blank password, as it will be wiped later) and mount it:
# cryptsetup luksFormat /dev/sda2 # cryptsetup open /dev/sda2 root # mkfs.ext4 /dev/mapper/root # mount /dev/mapper/root /mnt
Preparing the EFI system partition
Format the newly created EFI system partition as instructed in EFI system partition#Format the partition and mount it afterwards.
# mount --mkdir /dev/sda1 /mnt/boot
Continue the installation process until Installation guide#Install essential packages
Installing essential packages
Read the information in this step carefully, and append the following to your final pacstrap
command:
# pacstrap -K /mnt base ..... systemd-ukify sbsigntools
Continue the installation process until Installation guide#Initramfs, but skip Installation guide#Fstab.
Configuring the initramfs
To build a working systemd based initramfs, modify the HOOKS=
line in mkinitcpio.conf as follows:
HOOKS=(systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt filesystems fsck)
Also modify MODULES=
if required.
Installing the boot loader
Install systemd-boot with:
# bootctl install
The generated Unified kernel image will be automatically recognized and does not need an entry in /efi/loader/entries/
.
See systemd-boot#Updating the UEFI boot manager and systemd-boot#Loader configuration for further configuration.
Configuring the UKI
Next, we need three different configuration files for the UKI:
- Configure any required kernel parameters in
/etc/kernel/cmdline
, eg:
/etc/kernel/cmdline
quiet bgrt_disable
root=
parameter, nor any setting related to decryption of the Luks volume. Hovever, /etc/kernel/cmdline
must exist even if empty.- Set the kernel-install layout to "uki"
/etc/kernel/install.conf
layout=uki
- Finally, configure the UKI:
/etc/kernel/uki.conf
[UKI] SecureBootPrivateKey=/etc/kernel/secure-boot-private-key.pem SecureBootCertificate=/etc/kernel/secure-boot-certificate.pem Splash=/usr/share/systemd/bootctl/splash-arch.bmp [PCRSignature:NAME] PCRPrivateKey=/etc/systemd/tpm2-pcr-private-key.pem PCRPublicKey=/etc/systemd/tpm2-pcr-public-key.pem
Splash=
is optional. Do not modify the path to the PCRPublicKey
, or systemd-cryptenroll(1) will fail to pick it up automatically.Generate the necessary keys for Secure Boot and PCR policy signing:
# ukify genkey --config=/etc/kernel/uki.conf
Next, generate the UKI:
# kernel-install add-all
==> Starting build: '6.6.22-1-lts' -> Running build hook: [systemd] -> Running build hook: [autodetect] -> Running build hook: [microcode] -> Running build hook: [modconf] -> Running build hook: [kms] -> Running build hook: [keyboard] -> Running build hook: [block] -> Running build hook: [sd-vconsole] -> Running build hook: [sd-encrypt] ==> Generating module dependencies ==> Creating zstd-compressed initcpio image: '/tmp/kernel-install.staging.HGMao7/initrd' -> Early uncompressed CPIO image generation successful ==> Initcpio image generation successful Using config file: /etc/kernel/uki.conf + sbverify --list /lib/modules/6.6.22-1-lts/vmlinuz No signature table present + /usr/lib/systemd/systemd-measure sign --linux=/lib/modules/6.6.22-1-lts/vmlinuz --osrel=/etc/os-release --cmdline=/tmp/tmp.cmdliney7tgauck --uname=/tmp/tmp.unamewizaiscx --pcrpkey=/etc/systemd/tpm2-pcr-public-key.pem --initrd=/tmp/kernel-install.staging.HGMao7/initrd --sbat=/tmp/tmp.sbat3apz9lp1 --private-key=/etc/kernel/tpm2-pcr-key.pem --public-key=/etc/systemd/tpm2-pcr-public-key.pem + sbsign --key /etc/kernel/secure-boot.key --cert /etc/kernel/secure-boot.cert /tmp/uki9or_r7sx --output /tmp/kernel-install.staging.HGMao7/uki.efi Signing Unsigned original image Wrote signed /tmp/kernel-install.staging.HGMao7/uki.efi
If all went well, remove the leftover initramfs
and vmlinuz
files from /boot
. They were automatically generated when pacstrap was run and are not needed any more.
Enroll the TPM PCR Policy in the Luks volume
The following commands will remove the empty passphrase created during the LUKS format process, create a key bound to the TPM PCR Policy, and create a recovery key to be used in case of any problems. The TPM will automatically release the key as long as the boot chain is not tampered with. See systemd-cryptenroll#Trusted Platform Module and systemd-cryptenroll(1).
# systemd-cryptenroll /dev/sda3 --recovery-key # systemd-cryptenroll /dev/sda3 --wipe-slot=empty --tpm2-device=auto
The second command automatically picks up the previously created /etc/systemd/tp2-pcr-public-key
, in order to bind the Luks encryption to the PCR policy instead of the literal PCR values.
Make sure you did not forget to set a root password, see Installation guide#Reboot to finish the installation.
Follow the steps in Kernel-install#Pacman hook to disable the mkinitcpio hooks, and automatically run kernel-install upon subsequent updates.
Secure Boot
The UKI is already automatically signed for Secure Boot. You also need to sign systemd-boot, see Systemd-boot#Signing for Secure Boot.
For a quick and easy way to implement Secure Boot, see Unified Extensible Firmware Interface/Secure Boot#Assisted process with sbctl.