Hello all, I'm working on a general-purpose distro modeled after the proposal made in "Fitting Everything Together". I'm planning to, by default, seal the data partition's encryption with the following PCRs: - PCR[7]: If secure boot gets turned off, or keys get replaced -> fail decryption - PCR[11]: Wrong UKI / different edition of the OS / different OS -> fail decryption - PCR[14]: MOK changed (allow given binary to bypass secure boot, or allow third-party sysext/kmods, etc) -> fail decryption Here are some of the things measured into PCR[7]: - Secure boot mode: user/audit/setup/etc - PK - KEKs - DB (twice, apparently Shim measures it a second time: https://github.com/rhboot/shim/blob/main/README.tpm#L15) - DBX (twice, ditto) - Other less common SB variables: DBT, DBR - Shim's built-in DB - Shim's built-in DBX - Shim's other built-in hashes/certs - MOK (maybe? uapi-group docs say no, Shim's docs say yes, but comments from shim devs are conflicting) - SBAT revocation data Most of the things measured into PCR[7] align with our intent of sealing it to the decryption key. If any of the mode/PK/KEKs/DB/DBT/DBR change, then it becomes possible to circumvent the OS's chain of trust. However, this does not apply to all variables: - Shim's built-in DB: This is controlled completely by the OS and verified by the firwmare's DB, so it cannot be used to bypass the chain of trust. A distro may want to swap out their signing keys for whatever reason - Shim's other build-in hashes/certs: Ditto - DBX: Revoking vulnerable boot components does not allow any bypass of the chain of trust, because it can only take away the permission to run from a binary that was previously allowed. - Shim's DBX: Ditto - SBAT Revocation data: Ditto This is a problem. Revoking vulnerable binaries should NOT cause the user to have to dig up their recovery key (IF they even have it: no matter how hard we beg there's a good chance the user will ignore our instructions to write it down). I can think of two viable solutions (and a couple non-viable ones that I listed at the end of this email for reference): 1. This is basically the approach Windows seems to take with Bitlocker. If we're about to update DBX or Shim, we temporarily enroll a new decryption method that's just using PCRs 11+14 (and NOT 7). Then, on the next boot, we re-enroll the TPM using 7+11+14 so that it's sealed to the new value of PCR[7]. This should just work, but it gives an attacker a window of opportunity to undetectably turn off secure boot and completely break the chain of trust. The window is pretty small, and Microsoft seems to be OK taking this risk, but its mere existence is unsettling to me... 2. The alternative approach involves pre-calculating PCR[7] on the client if we're updating DBX or Shim. Here's how I envision this going: - We read the TPM log (which we can trust because we're currently booted to system verified via the chain of trust) and extract everything read into PCR[7] - We clear PCR[16], then start replaying everything from the TPM log - When we reach the measurement of DBX, we pre-calculate the new value of DBX and measure that in instead. This would probably need collaboration w/ fwupd - When we reach the measurements made by Shim, we use the new values instead. See https://github.com/rhboot/shim/issues/555 - PCR[16] now contains the future value for PCR[7]. We enroll (into a new keyslot) TPM decryption. We seal against 16+11+14, but then configure it to unseal against 7+11+14 (this is the one step I'm iffy about. Is this possible??) - It is safe to perform the update now so we do so (it remains atomic: if the update fails we boot with the old PCR[7] value, and if it passes we boot with the new one) - We reboot - On next boot, the original TPM decryption fails (PCR[7] has changed!). We try the new decryption and it passes - We delete the old TPM keyslot Any thoughts and ideas about any of this? Thanks, Adrian Vovk ---- For reference, here are some of my previous possible solutions to this problem, and why I decided they won't work: 1. Is this even a problem? If secure boot is off then it's possible to spoof the TPM and make it have whatever values you want in the PCRs. However, this is a misunderstanding of how TPM works. As far as I can tell, the values of the PCRs are checked inside of the TPM itself, so to spoof one of their values the whole TPM needs to be fake. But then a fake TPM will not have the real TPM's secret keys and thus will be unable to unseal the decryption key. Thus, yes: it is a problem. 2. We can ask Shim to stop putting SBAT/their DBX and maybe even their DB into PCR[7]. However, it is highly likely that they would refuse: it's backwards-incompatible, plus they're measuring these into the PCR for a reason (not all use-cases for PCR[7] match ours). Plus, this doesn't fix the problem when (inevitably) the firmware's DBX will need to be updated 3. Perhaps sd-stub or sd-boot can do its own measurements of mode/PK/KEKs/DB/DBT/DBR into a new PCR that could be used instead of PCR[7]. Problem: When secure boot is off, nothing prevents this measurement from being replaced by something that simply measures in known-correct values instead of the real ones. Thus, this doesn't work at all