{"id":131561,"date":"2023-02-01T08:00:00","date_gmt":"2023-02-01T08:00:00","guid":{"rendered":"https:\/\/fedoramagazine.org\/?p=37747"},"modified":"2023-02-01T08:00:00","modified_gmt":"2023-02-01T08:00:00","slug":"automatically-decrypt-your-disk-using-tpm2","status":"publish","type":"post","link":"https:\/\/sickgaming.net\/blog\/2023\/02\/01\/automatically-decrypt-your-disk-using-tpm2\/","title":{"rendered":"Automatically decrypt your disk using TPM2"},"content":{"rendered":"<p>This article demonstrates how to configure clevis and systemd-cryptenroll using a Trusted Platform Module 2 chip to automatically decrypt your LUKS-encrypted partitions at boot.<\/p>\n<p> <span id=\"more-37747\"><\/span> <\/p>\n<p>If you just want to get automatic decryption going you may skip directly to the Prerequisites section.<\/p>\n<h2>Motivation<\/h2>\n<p>Disk encryption protects your data (private keys and critical documents) through direct access of your hardware. Think of selling your notebook \/ smartphone or it being stolen by an opportunistic evil actor. Any data, even if &#8220;deleted&#8221;, is recoverable and hence may fall into the hands of an unknown third party.<\/p>\n<p>Disk encryption <strong>does not<\/strong> protect your data from access on the running system. For example, disk encryption does not protect your data from access by malware running as your user or in kernel space. It&#8217;s already decrypted at that point.<\/p>\n<p>Entering the passphrase to decrypt the disk at boot can become quite tedious. On modern systems a secure hardware chip called &#8220;TPM&#8221; (Trusted Platform Module) can store a secret and automatically decrypt your disk. This is an <strong>alternative<\/strong> factor, not a <strong>second<\/strong> factor. Keep that in mind. Done right, this is an alternative with a level of security similar to a passphrase.<\/p>\n<h2>Background<\/h2>\n<p>A TPM2 chip is a little hardware module inside your device which basically provides APIs for either WRITE-only or READ-only information. This way you might write a secret onto it, but you can never read it out later (but the TPM may use it later internally). Or you write info at one point that you only read out later. The TPM2 provides something called PCRs (Platform Configuration Registers). These registers take SHA1 or SHA256 hashes and contain <em>measurements<\/em> used to assert integrity of, for example, the UEFI configuration.<\/p>\n<p>Enable or disable Secure Boot in the system&#8217;s UEFI. Among other things, Secure Boot computes hashes of every component in the boot chain (UEFI and its configuration, bootloader, etc.) and chains them together such that a change in one of those components changes the computed and stored hashes in all following PCRs. This way you can build up trust about the environment you are in. Having a measure of the trustworthiness of your environment is useful, for example, when decrypting your disk. The <a href=\"https:\/\/trustedcomputinggroup.org\/resource\/tcg-efi-platform-specification\/\" target=\"_blank\" rel=\"noreferrer noopener\">UEFI Secure Boot specification<\/a> defines PCRs 0 &#8211; 7. Everything beyond that is free for the OS and applications to use.<\/p>\n<h3>A summary of what is measured into which PCRs according to the spec<\/h3>\n<ul>\n<li><strong>PCR 0<\/strong>: the EFI Firmware info like its version<\/li>\n<li><strong>PCR 1<\/strong>: additional config and info related to the EFI Firmware<\/li>\n<li><strong>PCR 2<\/strong>: EFI drives from hardware components (like RAID controller)<\/li>\n<li><strong>PCR 3<\/strong>: additional config and info to drivers stored in 2<\/li>\n<li><strong>PCR 4<\/strong>: pre-OS diagnostics and the EFI OS Loader<\/li>\n<li><strong>PCR 5<\/strong>: config of the EFI OS Loader and GPT table<\/li>\n<li><strong>PCR 6<\/strong>: is reserved for host platform manufacturer variables and is not used by EFI<\/li>\n<li><strong>PCR 7<\/strong>: stores secure boot policy configuration<\/li>\n<\/ul>\n<h3>Some examples on what is measured into which PCR<\/h3>\n<ul>\n<li>Changes to the initramfs measure into PCRs 9 and 10. So if you regenerate the initramfs using <em>dracut -f<\/em> you have to rebind. This will happen on every update to the kernel.<\/li>\n<li>Changes to the Grub configuration, like adding kernel arguments, kernels, etc. measure into PCRs 8, 9 and 10.<\/li>\n<li>Storage devices measure into PCRs 8 and 10. However, Hubs and YubiKeys do not seem to measure in any PCR.<\/li>\n<li>Additional operating systems measure into PCR 1. This occurs, for example, when attaching a USB stick before boot with a Fedora Linux live image.<\/li>\n<li>Booting into a live image changes PCRs 1, 4, 5, 8, 9 and 10.<\/li>\n<\/ul>\n<p>A tool called <em>clevis<\/em> generates a new decryption secret for the LUKS encrypted disk, stores it in the TPM2 chip and configures the TPM2 to only return the secret if the PCR state matches the one at configuration time. Clevis will attempt to retrieve the secret and automatically decrypt the disk at boot time only if the state is as expected.<\/p>\n<h2>Security implications<\/h2>\n<p>As you establish an alternative unlock method using only the on-board hardware of your platform, you have to trust your platform manufacturer to do their job right. This is a delicate topic. There is trust in a secure hardware and firmware design. Then there is trust that the UEFI, bootloader, kernel, initramfs, etc. are all unmodified. Combined you expect a trustworthy environment where it is OK to automatically decrypt the disk.<\/p>\n<p>That being said you have to trust (or better, <em>verify<\/em>) that the manufacturer did not mess anything up in the overall platform design for this to be considered a fairly safe decryption alternative. There are a range of cases where things did not work out as planned. For example, when <a href=\"https:\/\/dolosgroup.io\/blog\/2021\/7\/9\/from-stolen-laptop-to-inside-the-company-network\" target=\"_blank\" rel=\"noreferrer noopener\">security researches showed that BitLocker on a Lenovo notebook would use unencrypted SPI communication<\/a> with the TPM2 leaking the LUKS passphrase in plain text without even altering the system, or that BitLocker used the native encryption features of SSD drives that you can <a href=\"https:\/\/blog.elcomsoft.com\/2019\/01\/life-after-trim-using-factory-access-mode-for-imaging-ssd-drives\/\" target=\"_blank\" rel=\"noreferrer noopener\">by-pass through factory reset<\/a>.<\/p>\n<p>These examples are all about BitLocker but it should make it clear that if the overall design is broken, then the secret is accessible and this alternative method less secure than a passphrase only present in your head (and somewhere safe like a password manager). On the other hand, keep in mind that in most cases elaborate research and attacks to access a drive&#8217;s data are not worth the effort for an opportunistic bad actor. Additionally, not having to enter a passphrase on every boot should help adoption of this technology as it is transparent but adds additional hurdles to unwanted access.<\/p>\n<h2>Prerequisites<\/h2>\n<p>First check that:<\/p>\n<ul>\n<li>Secure Boot is enabled and working<\/li>\n<li>A TPM2 chip is available<\/li>\n<li>The <em>clevis<\/em> package is installed<\/li>\n<\/ul>\n<p>Clevis is where the magic happens. It&#8217;s a tool you use in the running OS to bind the TPM2 as an <strong>alternative<\/strong> decryption method and use it inside the <em>initramfs<\/em> to read the decryption secret from the TPM2.<\/p>\n<p>Check that secure boot is enabled. The output of <em>dmesg<\/em> should look like this:<\/p>\n<pre class=\"wp-block-preformatted\">$ dmesg | grep Secure\n[ 0.000000] secureboot: Secure boot enabled\n[ 0.000000] Kernel is locked down from EFI Secure Boot mode; see man kernel_lockdown.7\n[ 0.005537] secureboot: Secure boot enabled\n[ 1.582598] integrity: Loaded X.509 cert 'Fedora Secure Boot CA: fde32599c2d61db1bf5807335d7b20e4cd963b42'\n[ 35.382910] Bluetooth: hci0: Secure boot is enabled<\/pre>\n<p>Check <em>dmesg<\/em> for the presence of a TPM2 chip:<\/p>\n<pre class=\"wp-block-preformatted\">$ dmesg | grep TPM\n[ 0.005598] ACPI: TPM2 0x000000005D757000 00004C (v04 DELL Dell Inc 00000002 01000013)<\/pre>\n<p>Install the <em>clevis<\/em> dependencies and regenerate your initramfs using <em>dracut<\/em>.<\/p>\n<pre class=\"wp-block-preformatted\">sudo dnf install clevis clevis-luks clevis-dracut clevis-udisks2 clevis-systemd\nsudo dracut -fv --regenerate-all\nsudo systemctl reboot<\/pre>\n<p>The <strong>reboot<\/strong> is <strong>important<\/strong> to get the correct PCR<strong> <\/strong>measurements based on the new initramfs image used for the next step.<\/p>\n<h2>Configure clevis<\/h2>\n<p>To bind the LUKS-encrypted partition with the TPM2 chip. Point clevis to your (root) LUKS partition and specify the PCRs it should use.<\/p>\n<p>Enter your current LUKS passphrase when asked. The process uses this to generate a new independent secret that will tie your LUKS partition to the TPM2 for use as an <strong>alternative<\/strong> decryption method. So if it does not work you will still have the option to enter your decryption passphrase directly.<\/p>\n<pre class=\"wp-block-preformatted\">sudo clevis luks bind -d \/dev\/nvme... tpm2 '{\"pcr_ids\":\"1,4,5,7,9\"}'<\/pre>\n<p>As mentioned previously, PCRs 1, 4 and 5 change when booting into another system such as a live disk. PCR 7 tracks the current UEFI Secure Boot policy and PCR 9 changes if the initramfs loaded via EFI changes.<\/p>\n<p>Note: If you just want to protect the LUKS passphrase from live images but don&#8217;t care about more &#8220;elaborate&#8221; attacks such as altering the unsigned initramfs on the unencrypted boot partition, then you might omit PCR 9 and save yourself the trouble of rebinding on updates.<\/p>\n<h2>Automatically decrypt additional partitions<\/h2>\n<p>In case of secondary encrypted partitions use <em>\/etc\/crypttab<\/em>.<\/p>\n<p>Use <em>systemd-cryptenroll<\/em> to register the disk for <em>systemd<\/em> to unlock:<\/p>\n<pre class=\"wp-block-preformatted\">sudo systemd-cryptenroll \/dev\/nvme0n1... --tpm2-device=auto --tpm2-pcrs=1,4,5,7,9<\/pre>\n<p>Then reflect that config in your <em>\/etc\/crypttab<\/em> by appending the options <em>tpm2-device=auto,tpm2-pcrs=1,4,5,7,9<\/em>.<\/p>\n<h2>Unbind, rebind and edit<\/h2>\n<p><strong>List all current bindings of a device<\/strong>:<\/p>\n<pre class=\"wp-block-preformatted\">$ sudo clevis luks list -d \/dev\/nvme0n1... tpm2\n1: tpm2 '{\"hash\":\"sha256\",\"key\":\"ecc\",\"pcr_bank\":\"sha256\",\"pcr_ids\":\"0,1,2,3,4,5,7,9\"}'<\/pre>\n<p><strong>Unbind a device<\/strong>:<\/p>\n<pre class=\"wp-block-preformatted\">sudo clevis luks unbind -d \/dev\/nvme0n1... -s 1 tpm2<\/pre>\n<p>The <strong>-s<\/strong> parameter specifies the slot of the alternative secret for this disk stored in the TPM. It should be 1 if you always unbind before binding again.<\/p>\n<p><strong>Regenerate binding, in case the PCRs have changed<\/strong>:<\/p>\n<pre class=\"wp-block-preformatted\">sudo clevis luks regen -d \/dev\/nvme0n1... -s 1 tpm2<\/pre>\n<p><strong>Edit the configuration of a device<\/strong>:<\/p>\n<pre class=\"wp-block-preformatted\">sudo clevis luks edit -d \/dev\/nvme0n1... -s 1 -c '{\"pcr_ids\":\"0,1,2,3,4,5,7,9\"}'<\/pre>\n<h2>Troubleshooting<\/h2>\n<p><strong>Disk decryption passphrase prompt shows at boot, but goes away after a while<\/strong>:<\/p>\n<p>Add a sleep command to the <em>systemd-ask-password-playmouth.service<\/em> file using <em>systemctl edit<\/em> to avoid requests to the TPM before its kernel module is loaded:<\/p>\n<pre class=\"wp-block-preformatted\">[Service]\nExecStartPre=\/bin\/sleep 10<\/pre>\n<p>Add the following to the config file <em>\/etc\/dracut.conf.d\/systemd-ask-password-plymouth.conf<\/em>:<\/p>\n<pre class=\"wp-block-preformatted\">install_items+=\" \/etc\/systemd\/system\/systemd-ask-password-plymouth.service.d\/override.conf \"<\/pre>\n<p>Then regenerate <em>dracut<\/em> via <em>sudo dracut -fv &#8211;regenerate-all<\/em>.<\/p>\n<p>Reboot and then regenerate the binding:<\/p>\n<pre class=\"wp-block-preformatted\">sudo systemctl reboot\n...\nsudo clevis luks regen -d \/dev\/nvme0n1... -s 1<\/pre>\n<h2>Resources<\/h2>\n<ul>\n<li><a href=\"https:\/\/blog.dowhile0.org\/2017\/10\/18\/automatic-luks-volumes-unlocking-using-a-tpm2-chip\/\" target=\"_blank\" rel=\"noreferrer noopener\">Automatic LUKS volume unlocking using a TPM2 chip<\/a><\/li>\n<li><a href=\"https:\/\/discussion.fedoraproject.org\/t\/automatic-decrypt-with-tpm2-on-silverblue\/8424\/18\" target=\"_blank\" rel=\"noreferrer noopener\">Automatically decrypt with TPM2 on Silverblue (Discussion)<\/a><\/li>\n<li><a href=\"https:\/\/security.stackexchange.com\/questions\/124338\/right-way-to-use-the-tpm-for-full-disk-encryption\" target=\"_blank\" rel=\"noreferrer noopener\">Right way to use the tpm for full disk encryption (Security StackExchange)<\/a><\/li>\n<li><a href=\"https:\/\/security.stackexchange.com\/questions\/39329\/how-does-the-tpm-perform-integrity-measurements-on-a-system\/44350#44350\" target=\"_blank\" rel=\"noreferrer noopener\">How does the TPM perform integrity measurements on a system (Security StackExchange)<\/a><\/li>\n<li><a href=\"https:\/\/www.tevora.com\/threat-blog\/configuring-secure-boot-tpm-2\/\" target=\"_blank\" rel=\"noreferrer noopener\">Configuring SecureBoot + TPM2<\/a><\/li>\n<li><a href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/security\/information-protection\/tpm\/switch-pcr-banks-on-tpm-2-0-devices\" target=\"_blank\" rel=\"noreferrer noopener\">Switch PCR banks on TPM2 devices<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/vchatterji\/tpm2-luks\" target=\"_blank\" rel=\"noreferrer noopener\">tpm2-luks project on Github<\/a><\/li>\n<li><a href=\"https:\/\/security.stackexchange.com\/questions\/252391\/understanding-tpm-pcrs-pcr-banks-indexes-and-their-relations\" target=\"_blank\" rel=\"noreferrer noopener\">Understanding TPM PCRs, PCR banks and their relations<\/a><\/li>\n<li><a href=\"https:\/\/dolosgroup.io\/blog\/2021\/7\/9\/from-stolen-laptop-to-inside-the-company-network\" target=\"_blank\" rel=\"noreferrer noopener\">From a stolen laptop to inside the company network<\/a><\/li>\n<li><a href=\"https:\/\/trustedcomputinggroup.org\/resource\/tpm-library-specification\/\" target=\"_blank\" rel=\"noreferrer noopener\">TPM library specification<\/a><\/li>\n<li><a href=\"https:\/\/trustedcomputinggroup.org\/resource\/tcg-efi-platform-specification\/\" target=\"_blank\" rel=\"noreferrer noopener\">TCG EFI Platform specification<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>This article demonstrates how to configure clevis and systemd-cryptenroll using a Trusted Platform Module 2 chip to automatically decrypt your LUKS-encrypted partitions at boot. If you just want to get automatic decryption going you may skip directly to the Prerequisites section. Motivation Disk encryption protects your data (private keys and critical documents) through direct access [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[48],"tags":[1430,566,606,45,1431,46,47,1432,1433,1434],"class_list":["post-131561","post","type-post","status-publish","format-standard","hentry","category-fedora-os","tag-clevis","tag-encryption","tag-faqs-and-guides","tag-fedora","tag-luks","tag-magazine","tag-news","tag-secure-boot","tag-tpm","tag-tpm2"],"_links":{"self":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts\/131561","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/comments?post=131561"}],"version-history":[{"count":0,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts\/131561\/revisions"}],"wp:attachment":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/media?parent=131561"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/categories?post=131561"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/tags?post=131561"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}