Closed Zepmann closed 8 years ago
First of all thanks for this detailed bug report. Thanks to this i could very quickly reproduce this bug. I'll look into it.
I found the culprit. The grub_TPM_measureFile
function in tpm_kern.c
uses GRUB's grub_file_open
function (from file.c
) , which pre-processes compressed files (such as initramfs files) by decompressing them into memory before returning them. Therefore, grub_TPM_measureFile
(used by GRUB commands measure
, initrd
, etc.) does not measure the file on the disk (as would be expected), but the decompressed data in memory. This does not affect non-compressed files, since they are not modified by GRUB when they are loaded into memory.
The attached patch has one possible solution. It adds a grub_file_open_nofilter
function to file.c
, which is called by grub_TPM_measureFile
in tpm_kern.c
(instead of grub_file_open
). grub_file_open_nofilter
is a copy of grub_file_open
with the filter code removed. Therefore, it opens a file 'raw' into the memory. The result is as expected: the correct SHA-1 hash is now calculated over compresed (and other) files.
tgrub-1.2.1-nofilefilter.patch.zip
To apply the patch (assuming that TrustedGRUB2 is already installed):
First make sure that the debug option for TPM operations is enabled in tpm.h
, so the calculated SHA-1 hashes are visible during boot. Start from the TrustedGRUB2 source code directory.
Apply and install the patch:
patch -p1 < tgrub-1.2.1-nofilefilter.patch
make clean
make
make install
Install the patched TrustedGRUB2 to the MBR. Make sure that the device (/dev/sda
in the example below) is correct.
grub-install --recheck --target=i386-pc --directory=/usr/lib/grub/i386-pc --no-rs-codes /dev/sda
Reboot, and you will see that SHA-1 checksums for initramfs and other compressed files are now correctly calculated.
Thanks a lot for reporting and fixing this!
I would like to see more such well written issue reports on GitHub :+1:
found a simpler solution to fix this
This was tested using TrustedGRUB2 1.2.1 in debug mode on Arch Linux using the standard (latest) kernel and initramfs.
There is a bug in the SHA-1 implementation of TrustedGRUB2. If a hash is calculated over an initramfs file, the resulting SHA-1 hash is incorrect. If a hash is calculated over a file with the same size as the initramfs file but filled with random data, the SHA-1 hash is calculated correctly.
Expected behavior: SHA-1 hashes calculated by TrustedGRUB2 based on any file should be equal to the output of other SHA-1 implementations.
Actual behavior: SHA-1 hashes calculated by TrustedGRUB2 can differ compared to the output of other SHA-1 implementations.
To test this: You will need to have TrustedGRUB2 installed with the debug option for TPM operations enabled.
In binaryfiles.zip are two files. ramdisk.bin is an initramfs file. random.bin is a file filled with semi-random data (source: /dev/urandom) of the same size.
Copy these two files to your /boot partition. Add the following lines at the bottom of your Linux boot entry in /boot/grub/grub.cfg:
With debug enabled, you will see the SHA-1 hashes for two minutes. Look for the hashes calculated to extend PCRs 13 and 14. The SHA-1 hashes as calculated by TrustedGRUB2:
For reference, these are the SHA-1 values as calculated by GNU Core Utilities'
sha1sum
:The same SHA-1 function used by Microsoft's implementation, indicating that
sha1sum
is correct (since if the implementation ofsha1sum
would be flawed, it would be unlikely that Microsoft's implementation would contain the same flaw):The use of the
measure
command in TrustedGRUB2 in the above example is for clarity. The same wrong hash is also calculated by theinitrd
command. Due to this, values of PCR-10 are wrong starting from the measurement of the initramfs. Note that hashes for kernel files are calculated correctly.I also tried it with a newly generated initramfs file with some changed files inside and a newly generated random file. Again, the SHA-1 hash value calculated for the new initramfs was incorrect, whereas this value for the random data file was correctly calculated.
Correct calculation of SHA-1 hash values of startup files is vital when sealing new startup files to PCRs before a reboot and unsealing the same data after a reboot. (Re)sealing relies on two SHA-1 implementations:
sha1sum
, which is correct).