My assessment of secure-boot
It is now a little over two years since I first acquired a computer with UEFI support. That was a Dell Inspiron 660. It came with Windows 8 (since upgraded to Windows 8.1). I have left secure-boot enabled for most of that time, “to keep Windows happy”. In fact Windows does not complain at all if I disable secure-boot.
My second UEFI box is almost one year old. I do not have Windows installed there. It is a Lenovo ThinkServer TS140. When I first purchased it, secure-boot did not work all that well so I left it off most of the time. I did turn it on for some testing, but it required modifying the opensuse “shim” to get it to work. The problem that I had with secure-boot is described here under the heading “Booting the Machine that supports only one signature with vendor provided Keys”. After a BIOS update a few months ago, secure-boot now works quite well on the TS140, so recently I have been leaving it enabled most of the time.
With two years of experience, it is time to give my assessment.
What does secure-boot do for me?
Quick executive summary: Not much. Although opensuse handles secure-boot quite well, I’m not persuaded that it does much that enhances my security.
Secure-boot is supposed to protect the booting of the system. I’ll discuss how well it does that later in this post. But, for now, I’ll point out that most malware problems in linux or in Windows are due to some software having an exploitable bug. Typically, the attacker finds a way to use this bug to gain root or administrative access to the system. The attack is generally done while the system is up and running. So secure-boot is not involved. The booting has already completed and secure-boot firmware has finished whatever it will do.
In other words, a typical exploit occurs too late for secure-boot to help.
To illustrate the benefits of secure-boot, Microsoft literature mentions the possibility of MBR viruses. An MBR virus would be implanted in the boot code in the MBR, and take over a machine during boot. And secure-boot does protect against that. Actually, with a UEFI box, the MBR is not used that way. But an equivalent would be for a virus to implant itself in boot code in the EFI partition. And secure-boot should prevent that by checking digital signatures of the boot code components.
As far as I know, MBR viruses are not very common. So most malware writers prefer other methods of attack. And that’s why I don’t see secure-boot as particularly useful.
Secure-boot in opensuse
Let’s look at the boot path. I’ll describe if for opensuse, though it is similar for other linux distros that support secure-boot.
The firmware loads the program “shim.efi”. This is digitally signed with a key known to the firmware. In practice it is signed by both a Microsoft key and an opensuse key. The firmware verifies the signature before it allows this component to run, and secure-boot will fail if the signature does not verify.
In turn, “shim.efi” loads “grub.efi” which is digitally signed with an opensuse key. “Shim.efi” checks the signature of “grub.efi” and won’t continue booting if verification fails. Most of the “grub2-efi” boot code is in “grub.efi”.
Next, “grub.efi” loads a configuration file “grub.cfg” from the same directory in the EFI partition. The file “grub.cfg” is a small text file. But this configuration file is unsigned, so there is no signature checking for it. In turn, this loads another text file, also called “grub.cfg”, from under the “/boot” directory of the opensuse system. Again, there is no signature check for this “grub.cfg”.
In a normal opensuse boot, the kernel is next loaded. The kernel is signed, and the code in “grub.efi” does validate this signature (or refuse to boot). The grub code must also load the “initrd” file, and pass that to the kernel. The “initrd” file is not digitally signed.
If an attacker wants to break the boot, then the obvious attack points are:
- the unsigned “grub.cfg” in the EFI partition;
- the unsigned “grub.cfg” under “/boot”;
- the unsigned “initrd” file, typically also under “/boot”.
It isn’t easy to see how to avoid these attack points. These files contain local data. The signing key is not available locally. The only signed files can be files that are factory signed, such as “grub.efi” and the kernel.
Incidentally, there must be similar limitations for Windows. Booting Windows uses local data in the BCD database (Boot Configuration Data), and for similar reasons it cannot be signed.
Does disk encryption help?
What if we encrypt the disk?
I normally use an encrypted LVM. This limits an attacker’s access when the system is not running. However, when it is running normally, software sees unencrypted data. So this does not help with malware attacking when the system is up and running.
If an attacker has access when it is not running, he cannot inject code into the service manager (for example), because of that encryption. However, the standard way of setting up an encrypted LVM, is to have a separate unencrypted “/boot”. So the three attack points that I mentioned earlier are still unprotected.
Encryption without a separate “/boot”
As discussed earlier, it is possible to have an encrypted LVM without an unencrypted “/boot”. This is not yet fully in place for opensuse, though it is mostly in place with Tumbleweed. What’s still missing is a change to “shim-install”. That’s in the works, but has not been released. With manual tweaking, you could get it to work if you know what to do.
When setup this way, two of those attack points are now protected by the system encryption. That leaves only the “grub.cfg” in the EFI partition as unprotected (unsigned).
Still, that would be enough for an attacker. The attacker could install his own signed kernel (downloadable from opensuse repos) and his own “initrd” somewhere else such as in the EFI partition. And he could modify that “grub.cfg” to load the system using those. For example, a keylogger could then be started from the “initrd” and used to snag a copy of the encryption key.
Could “grub.cfg” be protected?
Actually, I think this is possible. Whether it is worth the effort, I will leave for others to decide.
When there is no separate “/boot”, the “grub.cfg” in the EFI partition will have a “cryptomount” command. That gives grub2-efi access to the encrypted LUKS partition. It prompts the user for a key, then uses that to decode the partition. In more detail, the partition is encrypted with a random key, and this random key is then encrypted with the key that the user must enter during boot (as with “cryptomount”).
At this stage, the grub code “knows” the random encryption key. This could be used as part of a signature for the “grub.cfg”. That is to say, the “grub.cfg” could be signed with a signature that depends on the random encryption key for the LUKS partition. Once grub code has handled the “cryptomount” it could verify that signature.
This would need a change to grub2-efi. The change would be that when “cryptomount” is used in a “grub.cfg”, that file must also contain a signature. If secure boot is enabled, the grub code would verify that signature after handling the cryptomount, and refuse to continue with boot if the signature does not verify.
Is this worth the effort? Perhaps. Or maybe not. There is an additional attack point available to an attacker. The attacker could modify the BIOS. It appears that this is easier to do than it should be.