Background
Some people choose to use a security feature which verifies files on /boot
(which are typically unencrypted) before using them. One example is PureBoot, which verifies the hashes of all files on /boot
against a file signed by the user’s GPG key. The correct usage of this feature is to sign the files immediately after they are installed/updated (under the assumption that the update process is secure) so that future tampering can be detected. However, an operational mistake may leave the files unsigned and unattended for an unacceptable period of time. This guide explains how to manually verify the files.
Required Equipment
- A trusted ISO (or other media which can be booted, as this cannot be done with the untrusted files in
/boot
) - A trusted copy of the QubesOS signing key for the relevant version (or the QMSK, which can be used to establish trust in a downloaded signing key)
- An internet connection
Process
For each package, we have to:
- Download the relevant RPM and buildinfo files from the QubesOS server
- Verify both files
- Extract the binaries & compare their hashes
The process will use an example of an updated (and currently untrusted) hypervisor, consisting of the following files:
/boot/xen-4.17.2.gz
/boot/efi/EFI/qubes/xen-4.17.2.efi
/boot/efi/EFI/quebs/xen.efi
Download the relevant files
We can manually download RPM and buildinfo files from https://yum.qubes-os.org. For example, at time of writing the packages for 4.2 are found at Index of /r4.2/current/host/fc37/rpm/ (if you need to check files that were installed to dom0 or domU, replace host
with dom0
or vm
, repsectively). A single buildinfo file might contain hashes for multiple RPM packages. For example, in this case we need the buildinfo file xen-4.17.2-8.fc37.x86_64.buildinfo to verify the RPM file xen-hypervisor-4.17.2-8.fc37.x86_64.rpm.
Verify both files
The buildinfo package should be signed by the release signing key for the relevant QubesOS release. It can be checked just like any other GPG-signed file:
gpg --verify xen-4.17.2-8.fc37.x86_64.buildinfo
Then check the hash of the RPM file and check that it matches the hash listed in the buildinfo file (buildinfo is a plaintext format, so you can just grep the file for the hash):
grep $(sha256sum xen-hypervisor-4.17.2-8.fc37.x86_64.rpm | cut -f1) xen-4.17.2-8.fc37.x86_64.buildinfo
Extract the binaries
RPM files can be unpacked using the rpm2cpio
utility:
rpm2cpio xen-hypervisor-4.17.2-8.fc37.x86_64.rpm | cpio -imvd
Then, the hashes should match (replace {boot-drive}
with the drive designation for your boot partition, such as sda1
, and leave out the curly braces):
mount /dev/{boot-drive} /mnt
sha256sum boot/xen-4.17.2.gz /mnt/xen-4.17.2.gz
sha256sum boot/efi/EFI/qubes/xen-4.17.2.efi /mnt/efi/EFI/qubes/xen-4.17.2.efi /mnt/efi/EFI/qubes/xen.efi
Note that xen.efi
is a copy of xen-4.17.2.efi
, and the copy is not stored literally within the RPM, but since they hash to the same value we can be confident that they are not malicious.