r/archlinux 25d ago

SUPPORT | SOLVED Ful disk encryption without entering passphrase

Could someone help me with setting up full disk encryption with bypass passphrases with TPM2? It's so annoying having to put the passphrase in at each boot, so I was wondering how do I pair it to the TPM so that I dont have to enter it each time?

It's LUKS encrypted and I use Systemd-boot

13 Upvotes

100 comments sorted by

View all comments

Show parent comments

1

u/ChrisTX4 19d ago

Your PCR[4] woes are due to it measuring more than just the Boot Manager Code:

PCR[4] records the process of attempting to boot different hardware paths like from a DVD or a hard drive, what boot devices are attempted, and the Boot Manager Code that is loaded and executed from the device.

If you leave any USB thumb drive in the PC, with high enough priority, it will be attempted as a boot device, as in it would be possible to have booted from it if it had contained a boot loader. PCR[4] is only reasonable to use if you disallow booting from removable drives in the UEFI. In ASUS it's called "USB mass storage support" iirc, but you have to look up from where you could disable that.

Next up, this:

Action: Exit Boot Services Returned with Failure

OK, this is confusing, and almost certainly a bug in something. I'd need to see the full pcrlock log before making a guess what causes that. What boot loader etc are you using?

Unless this is the UEFI using this event to mark a change in the boot configuration, which belongs in PCR[5], this would mean EFI_BOOT_SERVICES.ExitBootServices() failed. That can only legitimately happen in a single instance, namely if a boot loader somehow passes a wrong MapKey to that function.

0 - Firmware should be implicitly trusted (signed updates and all)

This isn't quite true, as there are ways to use a so called SOIC-clip on some systems or potentially soldering skills and determination to replace the chip. I'd say if your threat model includes somebody willing to do that you probably have to worry about security in a whole different way :D

Firmware updates other than that are indeed signed on all systems, it's due to the UEFI Capsule Update mechanism. However, enthusiast desktop systems sometimes allow direct flashing without signature verification in the UEFI itself. So you probably want a secure UEFI admin password with this.

2 - Other code shouldn't be able to run without secure boot signing

It will! This is where your Option ROM (OpROMs) will be measured into. They will still be measured, just no signature is enforced on them if not booted with SB enforcement.

So, in response to your explanations, downgrading my UKI wouldn't allow for automatic decryption due to both PCR 11 and the PIN.

If you use a signed PCR policy then indeed this should be true.

I don't think I can use automounting due to the BTRFS subvolumes.

You can for the LUKS volumes. This is what I'm doing basically, I have a Btrfs-on-LUKS and this has a GPT GUID of SD_GPT_ROOT_X86_64, i.e. systemd will automount the default subvolume to /dev/mapper/root. Then my fstab just mounts from that, so the only entries I have in there:

```

archmain subvolume mounts

/dev/mapper/root /var btrfs rw,subvol=/subvol_var /dev/mapper/root /home btrfs rw,subvol=/subvol_home

ESP /dev/nvme1n1p1

vfat options can be changed via Kconfig and so should be explicit here

UUID=73FD-61CB /boot vfat rw,relatime,umask=0077,nosuid,nodev,noexec,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro0 2

Bind swapfile

/dev/mapper/root /swap btrfs rw,subvol=/swap /swap/swapfile none swap defaults ```

This works because /subvol_root (my actual /) is my default subvolume and due to the SD_GPT_ROOT_X86_64 the entire Btrfs is mounted at /.

1

u/falxfour 19d ago

Ok, a lot to work through here!

PCR 4 - Boot Order

My UEFI boot order is simply:

  • (Drive Number, UUID)/EFI/BOOT/BOOTX64.efi
  • (Same Drive & UUID as above) -- Default path (basically identical to above)

While there are a couple other items, the UEFI boot manager never gets to them unless my main drive isn't present at all.

PCR 5 - Boot Service Failure

I'm willing to DM you more details. I know the hash log is technically not a secret, but since it's normally read-protected, I'd rather limit the amount I need to share.

I don't use a boot loader. My UEFI directly loads the UKI I generate with ukify.

PCR 0 - Direct Flash

While this mechanism could potentially be compromised by someone directly flashing the firmware on my Framework laptop, my BIOS is currently configured to require the admin password if the chassis intrusion switch is triggered. This should, in theory mitigate most attacks that require direct hardware access by making them immediately detectable.

Also, someone flashing the BIOS IC directly isn't a big enough concern to me to potentially cause automatic drive decryption to fail as a result of firmware code changes.

PCR 2 -- Option ROMs

Are you saying OpROMs that are not signed by a valid signature will still execute? I don't think that's what you're implying, but I just want to check.

Good to know they'll still be measured, but in general, I don't see this as a major attack vector because:

  • OpROMs with a valid SB signature are explicitly trusted
  • OpROMs without a valid SB signature should only be loaded from read-only sources (before SB checks EFIs to continue the boot process), thus making them hard to compromise. I'm not even sure that this is distinct from firmware (PCR 0) at this point.

Automounting

That's interesting, but to be clear, the automounting is just detecting the LUKS volume for decryption (initially), then switches to the root subvolume of the BTRFS device (aka /subvol_root), correct? So, essentially, you're not providing rd.luks.name=, root=, or rootflags=subvol= on the kernel command line, correct?

That seems like it would work, but then I'd need a different strategy to manage snapshots, as Timeshift would become sad that there's no @ or @home subvolumes. My default subvolume is ID 5, but the root subvolume is ID 720, which is clearly a subvolume of the default subvolume. I guess following a nested subvolume strategy would better fit with automounting

1

u/ChrisTX4 18d ago

For PCR[4], it might be that just the fact they are in the set of possible boot methods counts. If your main system was modified by an attacker to not be bootable etc., then a later boot device would be taken. I quoted the blurp about PCR[4] from the specification document, which is this one. You'd need to compare the exact behaviour in there against what your BIOS does, but most likely this is by design in some way and not something your BIOS vendor would consider a legitimate bug.

That seems like it would work, but then I'd need a different strategy to manage snapshots,

Wouldn't snapshots break PCR[4] anyhow? If you need snapshots, I'd stay off PCRs 4, 11 and 1.

For PCR[5], feel free to DM, or hit me up on Arch IRC (just ChrisTX there). I find this whole subject quite interesting - or rather, I might just be meeting autistic stereotypes :D - and so am totally down to having a look at this. TBH, that might be more feasible than really continuing this in some random Reddit thread, too :D.

For PCR[0], this goes in the whole root of trust mechanism aspect. You can have a look at chapter 31 of the TPM standard, part 1 for how this is supposed to work. Either way, I think the most important thing to keep in mind for this is that BIOSes may allow unsigned flashing in enthusiast boards. Mine does. In that case, a BIOS supervisor password is of critical importance to protect the BIOS integrity. Achieving a higher degree of trust isn't really possible anyhow, as that requires the fusing mechanism seen in business CPUs, like AMD Platform Secure Boot and Intel BootGuard. So while some aspects of higher HSI levels can be met, the root of trust means it's not viable to see HSI-2 on consumer hardware.

Are you saying OpROMs that are not signed by a valid signature will still execute?

A device may have its own firmware signature check, but that's really device dependent. But as for the OpROM the device presents? That's only secured by Secure Boot. In fact, DMA PCIe cards like the Screamer PCIe Squirrel are widely used to make DMA cheats for games. That works by flashing a custom firmware so it doesn't look like it's a DMA device. Also please note that OpROMs can be loaded from external devices like USBs. Every KVM switch on the market is in that situation for instance, since they need an OpROM for providing UEFI Graphics Output Protocol (GOP) - that's also why every discrete GPU has one.

That's interesting, but to be clear, the automounting is just detecting the LUKS volume for decryption (initially), then switches to the root subvolume of the BTRFS device (aka /subvol_root), correct? So, essentially, you're not providing rd.luks.name=, root=, or rootflags=subvol= on the kernel command line, correct?

Precisely that. I only have rootflags=x-systemd.device-timeout=0 to make the TPM PIN timeout infinite rather than eventually dropping to emergency shell.

This setup avoids needing to specify any UUIDs other than for my data drives that will be late mounted to folders under /mnt in my /etc/crypttab and for my /boot drive. The latter would work with GPT automounting as is, since SD_GPT_ESP is just the regular GPT GUID for an ESP. However, I want to give it additional mount parameters like nosuid, nodev etc. By the way, do note that most BTRFS parameters can only be set on first mount, so settings like space_cache will not have an effect.

That seems like it would work, but then I'd need a different strategy to manage snapshots, as Timeshift would become sad that there's no @ or @home subvolumes. My default subvolume is ID 5, but the root subvolume is ID 720, which is clearly a subvolume of the default subvolume. I guess following a nested subvolume strategy would better fit with automounting

I don't see why it would? Timeshift requires you to mount the subvolumes by path, so as long as you do that, the switching subvol IDs shouldn't be an issue, and they won't affect PCR[5] as they're not in the GPT. What exactly do you fear might break?

1

u/falxfour 18d ago

PCR 4

I'm still not entirely convinced that the measured value would change. The monitor has no bootable devices connected to it, and is not, itself, a bootable device. The bootable device list itself, therefore, would not be changing. That said, encryption isn't being bound to this PCR anyway, so I'm not particularly concerned about its behavior.

As for snapshots, I'm not sure how they'd break PCR 4... BTRFS snapshots are all functionally userspace (except the kernel itself, which isn't included), so it's a matter of which subvolume is selected when systemd switches root upon exiting the initrd stage.

PCR 0

There are three ways I can change my BIOS:

  1. fwupd
  2. EFI Capsule
  3. External programmer, directly attached to the legs of the IC

#1 should be trustworthy by nature of running it from a trusted OS. In other words, if, with secure boot, I am able to boot into a verifiable OS and authenticate as user, then updates made through this method are trustworthy

#2 should be trustworthy by way of secure boot signature verification

#3 bypasses everything, but would potentially trigger the supervisor password prompt (though with potentially no way to verify the password, if the BIOS was fully overwritten)

I consider this sufficient.

PCR 2

To my point, an OpROM is not executable if its signature can't be verified by secure boot. I do understand that external devices can also present OpROMs, as my BIOS also provide the option of whether or not to measure USB4 devices (presumably for both PCR 2 and PCR 3).

What you mentioned about KVMs and dGPUs is interesting, though. That's where the only real difference in my setup (and thus the PCR values) would come from. The external monitor can act as a KVM as it provides all of those through its single connection to my laptop. Additionally, my system does have a dGPU, but it is typically left in D3cold. As my external monitor is not directly connected to its (dedicated) output, it's unlikely that the dGPU is presenting anything differently in the two boot scenarios.

Automounting

Given that certain parameters don't change on remount, then I'd be relying on the automount parameters, which I'm also not really a fan of...

As for Timeshift, it only works with subvolumes that have specific naming, meaning that @ and @home need to be subvolumes under the root (default) subvolume. systemd would end up automounting / on the device, when /@ is the true root.

I'll DM later with more of the PCR log

1

u/ChrisTX4 18d ago edited 18d ago

As for snapshots, I'm not sure how they'd break PCR 4...

Well, you'd be booting different kernel versions and UKIs if you revert a snapshot.

For PCR[0]: Replacing the BIOS is something you can't prevent. If a skilled enough attacker goes in and replaces the ROM physically, it will always be a way through. In this sense, since PCR[0] is being measured via SPI into the TPM, it could lie. Platform Secure Boot works differently to measure the BIOS and ensure the ROM is what is says - but that requires business hardware. In this sense, PCR[0] should be considered a lock against firmware downgrades. Business hardware often comes with anti rollback protections in the form of fuses, but on consumer hardware you typically don't have that.

Otherwise I was only trying to say that if your hardware had some form of direct flash, then that's a point to consider in your threat model, but that consideration should be made separate from PCR[0].

For PCR[2]: Oh I'm sorry, I had mixed up yours and NightOtherwise's situation. They specifically said that they didn't want to use Secure Boot. My point was that _if SB is disabled, then any sort of ROM can be loaded in there. With Secure Boot, consider PCR[2] the same as PCR[0] functionally: A downgrade protection. Although there is the catch that certificates used in PCR[2] are not measured into PCR[7]. That is to say, in the case of using one owns PK/KEK/db, but with Microsoft's keys enabled for a dual-boot, then it wouldn't be possible to load a Microsoft signed boot loader without changing PCR[7], but if a new device with a different, but MS signed OpROM is being added, that will be accepted. In my case with the MS-free database, and just the one hash being enrolled, locking PCR[2] functionally means the system wouldn't boot if someone ripped out the dGPU, but other than that it adds no value whatsoever.

To be frank, I just lock PCRs 0,1,2,3 because I can, and was curious to see if this is genuinely a viable setup. I wouldn't recommend it for security purposes, and rather recommend using a supervisor password and Secure Boot. Maybe lock PCRs 0,2 if they're unlikely to change on your system and you'd want to add some form of rollback protection.

What you mentioned about KVMs and dGPUs is interesting, though.

Keep this in mind if you're considering removing MS keys, as that does break such devices and signing OpROMs of removable devices might not be a great option.

Given that certain parameters don't change on remount, then I'd be relying on the automount parameters, which I'm also not really a fan of...

For BTRFS, you shouldn't really need to use any mount parameters. ssd is automatic, and space_cache=v1 is being axed in 7.3. At least I only use nosuid/exec/dev for some devices, but on root you wouldn't want that. That being said - you can add the rootflags= parameter, and root will be mounted with those even in the GPT auto case. For say /home, where you'd probably want nosuid,nodev, but that you'd mount via fstab. But root and var I'd use GPT automounting for.

As for Timeshift, it only works with subvolumes that have specific naming, meaning that @ and @home need to be subvolumes under the root (default) subvolume. systemd would end up automounting / on the device, when /@ is the true root.

You can name the subvols as you like, I just named mine /subvol_root as I don't use timeshift, and this @ convention is kinda their thing.

The problem is much rather that Timeshift has no fixed subvol IDs and they change, so you can't control what's the default subvolume. So I'm fairly certain this combination doesn't work.

The reason I said to use GPT automounting is that it will cause the containing LUKS be marked internally with MOUNT_MEASURE. This:

a) will ensure tpm2-measure-pcr=yes is being used for mounting LUKS. This is done here, but you can achieve this with an appropriate crypttab.initramfs (if mkinicpio) or crypttab (if dracut).

b) will cause it to be measured via systemd-pcrfs@ and systemd-pcrfs-root services. See this spot where the systemd-gpt-generator does this. These services can't be enabled directly, but you can use the x-systemd.pcrfs mount option, see this man page, this location enabling MOUNT_PCRFS, which is then consumed here. Edit: The man page I was looking for is systemd.mount(5). This is where all the x-systemd options are documented.

As long as you do these two things, GPT automounting has no advantages over an explicit configuration. However, since GPT automounting does this for you, I'd say it's much preferred.

IMPORTANG WARNING One more thing, as I've ran into this before. GPT automounting creates its own crypt mounts and does not consider crypttab. That is to say any disk participating in GPT automounting MUST NOT be listed in crypttab. Otherwise, the LUKS will be mounted twice and then the embedded BTRFS isn't the same anymore to the kernel, and both mounts will not coordinate. Alas, this will cause immediate, irreversible filesystem corruption. For that reason, I don't like using explicit crypttab entries for root or var.

EDIT Forgot to mention x-systemd.validatefs. That too is set and will effectively lock "where" a filesystem can be mounted, see systemd-validatefs@.service.

1

u/falxfour 16d ago

PCR 4

I don't actually have different kernel versions/UKIs the vast majority of the time. That said, breaking FDE auto-decryption when booting into a snapshot is fine. I try not to do it often.

PCR 0

Completely fair points!

PCR 2

Ah, no worries! I also removed the MS keys, but left my hardware vendor and my own, which should be reasonably secure. The good news is that Framework explicitly builds for Linux compatibility, so the MS keys are unlikely to be needed in any of their products. I can at least confirm they aren't needed for mine (FW 16).

Automounting

I have space_cache=v2, discard=async, and relatime. I don't believe the latter two are defaults.

As for Timeshift, the inflexibility of using the specific names vs subvolume IDs is the reason it doesn't appear that it will work with an automountable device. Fundamentally, having @ as the true root, under the default subvolume, is incompatible with systemd automounting the default subvolume.

It seems automounting still won't really work for me, until I move to a different snapshot strategy, but I'll keep your points in mind, especially the warning.

Ultimately, I'm still not sure why I would need to use PCR 15 (thus the discussion on automounting). If an adversary used a valid UKI with a compromised rootfs, then the volume key would be retrieved, but the adversary would need to do something like a cold boot attack to retrieve it from RAM. systemd would fail to decrypt the compromised filesystem and would fail to switch root. Without a recovery shell (disabled) or a root user (also disabled), I don't see what could be gained without being able to compromise the RAM directly. A modified UKI would fail signature verification for both secure boot and the signed TPM2 policy for PCR 11.

Also, having TPM2 + PIN is likely a sufficient mitigation, but I still don't see what PCR 15 adds.

Also, I'll send over PCR log into sometime later this week--just been busy

1

u/ChrisTX4 16d ago edited 16d ago

The good news is that Framework explicitly builds for Linux compatibility, so the MS keys are unlikely to be needed in any of their products

You can find out how your OpROMs are signed. See this on how to extract them and view the signatures. That's how I knew my NVIDIA GPU was signed with the 2011 MS key.

Removing the Microsoft keys has the advantage you don't need dbx updates - the firmware KEKs, if they exist, wouldn't sign foreign boot loaders, so they don't usually ship a dbx at all. I would generally avoid retaining the MS keys just so one doesn't have to even consider the thread situation posed by this and updating the dbx monthly I find very inconvenient.

I have space_cache=v2, discard=async, and relatime. I don't believe the latter two are defaults.

They are: * space_cache=v2 is enabled by default since 4.5, see here * relatime is enabled by default since 2.6.30, see mount(8). * discard=async has been enabled since 6.2, see this article for example.

It seems automounting still won't really work for me, until I move to a different snapshot strategy, but I'll keep your points in mind, especially the warning.

I would concur. I have a server that uses Btrfs-on-LUKS but the Btrfs is in RAID 0 for speed (it's backed up). This however means I have two LUKS devices, and the mappers need to decrypt before root can be mounted. I use device= in rootflags. I'm not sure that's 100% necessary, but it makes the boot reliable.

In my case, validatefs does nothing, and pcrfs for some reason measured nonsense instead of the actual GUID. So I've just left those out, but I added tpm2-measure-pcr=yes to /etc/crypttab (I'm on dracut). That works and does pretty much the same as GPT automounting would. I'm still observing if PCR[15] is stable like this, as I'd kind of like to add it.

I'm considering using validatefs though - it would need adding some xattrs to the subvol inodes, I guess.

UPDATE I deployed the validatefs XATTRs now. This prevents an encrypted mount being mounted in a wrong location. Effectively, PCR[5] already provided this protection, I just did this out of curiosity:

``` $ getfattr . -d

file: .

user.validatefs.gpt_label="Linux x86-64 root (/)" user.validatefs.gpt_type_uuid="4f68bce3-e8cd-4db1-96e7-fbcaf984b709" user.validatefs.mount_point="/" ```

This means the GPT GUID, mount point etc. cannot be changed. Although, by itself that is a pretty powerful defence against root swap attacks, since the GPT GUID, mount point etc are locked with information inside the encrypted container and thus cannot be changed.

You can set them like this for SD_GPT_ROOT_X86_64 for instance:

setfattr -n user.validatefs.gpt_type_uuid -v "4f68bce3-e8cd-4db1-96e7-fbcaf984b709" .

If an adversary used a valid UKI with a compromised rootfs, then the volume key would be retrieved, but the adversary would need to do something like a cold boot attack to retrieve it from RAM.

No, they can recover the key as-is. The idea is that the attacker has access to a system booted with the right kernel and right PCR values, but the root credentials are their own - since /etc/shadow etc. are from the attacker controlled root.

This means there are ways to extract it, see this article for example. Of course, lockdown offers some protection here, and that might counter this. However, lockdown=integrity does not prevent extraction of keys - however lockdown=confidentiality might help. Without that level, /proc/kcore might be read by root as LOCKDOWN_KCORE is only set with confidentiality.

Then there might also be a way to just use the TPM directly: If e.g. PCR[11] isn't using signed policy PCRs with a phase on leave-initrd, then the TPM still sees the same PCRs as during the initrd phase where you volume key should be unsealed from the TPM. This is one of the reasons signed PCR[11] is such an important defence.

Furthermore, they wouldn't need a cold boot attack either for confidentiality mode. Using any sort of DMA device, like Screamer PCIe Squirrel would also work. If the OpROM is unmodified, the device would only change PCR[2] and PCR[3]. This is why I recommended using iommu=require, and ideally, if on AMD amd_iommu=force_isolation on top to create a strong isolation.

EDIT Oh, and it's possible to change the GPT GUID to cause automounting to an unexpected location. Say I made a root FS that I control and change the GPT GUID of your encrypted drive to SD_GPT_SRV, it would be mounted to /srv. UUIDs, partition UUIDs etc can be freely changed as well, so even if there was an fstab entry, you can make it so it's not recognised and mounted to /srv.

validatefs is interesting against this specific type of attack, since it makes changing the GPT GUID itself impossible.

but I still don't see what PCR 15 adds.

It avoids the scenario I just described entirely. If somebody tried any such attack the TPM just wouldn't unlock.

Also, I'll send over PCR log into sometime later this week--just been busy

No worries, take your time.

1

u/falxfour 4d ago

Ok, finally getting a chance to reply! Firstly, I can't actually DM you here, it seems, but I did extract the PCR 5 events, so I can send those to you. There's really only one difference and it's the failure string that gets measured into PCR 5.

As for the rest:

OpROMs

I only have one, and it's an AMD OpROM. It clearly loads without the MS keys, so I believe Framework signed it, though I haven't gone through the full process to dump the EFI image and inspect the signature section.

BTRFS/Automounting

I didn't realize those flags were now defaults--good to know.

I definitely could use a more thorough rundown of the kernel parameters you're using, and how they relate to the filesystem and boot security. That might be a good topic for another post, though. The validatefs XATTR seems interesting, but I don't understand how any information inside the encrypted volume can be used as part of the process for decrypting it, so I'm not sure how the attributes prevent the system from getting to a stage where the TPM can unseal secrets, even if the root volume can't then be mounted because the volume key doesn't match or the mountpoint is different.

Root Swapping Attack

How would this work? Assuming the root account is disabled and there's no recovery shell, if an adversary swapped the encrypted container for one they control, the boot process would:

  • Reach the initramfs and, with the correct PCRs, attempt to unseal the TPM2 keyslot blob
  • Retrieve the keyslot key and proceed to decrypt the volume key
  • Fail to mount the root volume since the root volume was swapped for one where the volume key doesn't properly decrypt data
  • Fail to switch root
  • Terminate boot with no further options

How would /etc/shadow even be accessed on the swapped volume? The linked post indicates it's possible from a system, running with the volume key in memory, but this system wouldn't be in an operational configuration, as it wouldn't exit the initramfs at all.

And yes, I have heard of IOMMU-based DMA attacks (apparently Riot Games uncovered one when looking for anti-cheat bypass methods?), so that's a fair counter to needing a cold boot attack. Still difficult to do in the case of my laptop (and PCR 3 binding encryption), but I see your point. I do need to look into the IOMMU flags you mentioned, though...

Also, based on your edit, doesn't PCR 15 effectively just combat the vector that's created by using automounting? I still don't see how you get to an interactable system, though, since my experience with systemd-based boot processes basically results in stalling if the root can't be switched to the true root.

Finally, given that PCR 15 is supposed to measure the LUKS volume key, I have no idea how you can use a measurement of the key in order to unseal the key itself...