![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
When I wrote about TPM attestation via 2FA, I mentioned that you needed a bootloader that actually performed measurement. I've now written some patches for Shim and Grub that do so.
The Shim code does a couple of things. The obvious one is to measure the second-stage bootloader into PCR 9. The perhaps less expected one is to measure the contents of the MokList and MokSBState UEFI variables into PCR 14. This means that if you're happy simply running a system with your own set of signing keys and just want to ensure that your secure boot configuration hasn't been compromised, you can simply seal to PCR 7 (which will contain the UEFI Secure Boot state as defined by the UEFI spec) and PCR 14 (which will contain the additional state used by Shim) and ignore all the others.
The grub code is a little more complicated because there's more ways to get it to execute code. Right now I've gone for a fairly extreme implementation. On BIOS systems, the grub stage 1 and 2 will be measured into PCR 9[1]. That's the only BIOS-specific part of things. From then on, any grub modules that are loaded will also be measured into PCR 9. The full kernel image will be measured into PCR10, and the full initramfs will be measured into PCR11. The command line passed to the kernel is in PCR12. Finally, each command executed by grub (including those in the config file) is measured into PCR 13.
That's quite a lot of measurement, and there are probably fairly reasonable circumstances under which you won't want to pay attention to all of those PCRs. But you've probably also noticed that several different things may be measured into the same PCR, and that makes it more difficult to figure out what's going on. Thankfully, the spec designers have a solution to this in the form of the TPM measurement log.
Rather than merely extending a PCR with a new hash, software can extend the measurement log at the same time. This is stored outside the TPM and so isn't directly cryptographically protected. In the simplest form, it contains a hash and some form of description of the event associated with that hash. If you replay those hashes you should end up with the same value that's in the TPM, so for attestation purposes you can perform that verification and then merely check that specific log values you care about are correct. This makes it possible to have a system perform an attestation to a remote server that contains a full list of the grub commands that it ran and for that server to make its attestation decision based on a subset of those.
No promises as yet about PCR allocation being final or these patches ever going anywhere in their current form, but it seems reasonable to get them out there so people can play. Let me know if you end up using them!
[1] The code for this is derived from the old Trusted Grub patchset, by way of Sirrix AG's Trusted Grub 2 tree.
The Shim code does a couple of things. The obvious one is to measure the second-stage bootloader into PCR 9. The perhaps less expected one is to measure the contents of the MokList and MokSBState UEFI variables into PCR 14. This means that if you're happy simply running a system with your own set of signing keys and just want to ensure that your secure boot configuration hasn't been compromised, you can simply seal to PCR 7 (which will contain the UEFI Secure Boot state as defined by the UEFI spec) and PCR 14 (which will contain the additional state used by Shim) and ignore all the others.
The grub code is a little more complicated because there's more ways to get it to execute code. Right now I've gone for a fairly extreme implementation. On BIOS systems, the grub stage 1 and 2 will be measured into PCR 9[1]. That's the only BIOS-specific part of things. From then on, any grub modules that are loaded will also be measured into PCR 9. The full kernel image will be measured into PCR10, and the full initramfs will be measured into PCR11. The command line passed to the kernel is in PCR12. Finally, each command executed by grub (including those in the config file) is measured into PCR 13.
That's quite a lot of measurement, and there are probably fairly reasonable circumstances under which you won't want to pay attention to all of those PCRs. But you've probably also noticed that several different things may be measured into the same PCR, and that makes it more difficult to figure out what's going on. Thankfully, the spec designers have a solution to this in the form of the TPM measurement log.
Rather than merely extending a PCR with a new hash, software can extend the measurement log at the same time. This is stored outside the TPM and so isn't directly cryptographically protected. In the simplest form, it contains a hash and some form of description of the event associated with that hash. If you replay those hashes you should end up with the same value that's in the TPM, so for attestation purposes you can perform that verification and then merely check that specific log values you care about are correct. This makes it possible to have a system perform an attestation to a remote server that contains a full list of the grub commands that it ran and for that server to make its attestation decision based on a subset of those.
No promises as yet about PCR allocation being final or these patches ever going anywhere in their current form, but it seems reasonable to get them out there so people can play. Let me know if you end up using them!
[1] The code for this is derived from the old Trusted Grub patchset, by way of Sirrix AG's Trusted Grub 2 tree.
deb package
Date: 2015-09-24 08:02 am (UTC)also when installing a fresh debian
no subject
Date: 2015-09-24 02:42 pm (UTC)no subject
Date: 2015-09-24 04:29 pm (UTC)no subject
Date: 2015-09-28 05:29 pm (UTC)no subject
Date: 2015-09-28 06:46 pm (UTC)no subject
Date: 2015-09-28 10:39 pm (UTC)no subject
Date: 2015-09-28 11:31 pm (UTC)no subject
Date: 2015-10-09 04:46 am (UTC)no subject
Date: 2015-10-12 03:08 pm (UTC)testing
Date: 2015-10-22 02:47 am (UTC)Some interesting bits on the TPM2 systems I tested: The NUC HSW exhibits the same capability struct packing behavior you encountered. The MSFT TrEE and TCG EFI protocol seem to disagree on this bit but the both use the same GUID which is a bit ugly.
Verifying measurements on a TPM2 system are a pain since AFAIK the kernel module doesn't have a PCR sysfs node to dump the PCRs yet. For the short term I hacked up a grub command to dump the event log.
I had hoped to be able to dump the event log after boot but the TCG ACPI spec for 2.0 doesn't include the event log like it did in 1.2 so the preboot events aren't visible to the Linux. I guess this leaves the bootloader and the kernel to sort things out for themselves?
The only work around thing I've been able to come up with requires a lot of coordination between the kernel and grub: basically passing the event log through a kernel setup_data structure. I haven't looked into more complicated scenarios like multiboot though. Have you given any thought to the "right way" to do this?
@flihp
Re: testing
Date: 2015-10-22 07:10 am (UTC)I haven't looked at the event log for TPM 2.0 devices yet. setup_data isn't the worst plan, but it's annoyingly x86 specific. We could always install a UEFI table with a pointer to it…
Re: testing
Date: 2015-10-26 02:18 pm (UTC)Re: testing
Date: 2016-11-01 03:59 pm (UTC)Re: testing
Date: 2016-11-01 04:05 pm (UTC)Integration in mainline Grub2?
Date: 2016-03-17 01:22 pm (UTC)Any plan for pushing them upstream to Grub2?