The idea behind the UEFI Secure Boot feature is to ensure that the device will only be able to run trusted code, at least until an operating system is up and running and can make that determination itself. The feature works at the firmware level and helps guard against root kits — as long as the firmware is trusted (i.e. no one installed custom firmware without your knowledge, hence it is important to restrict access to the firmware), that firmware will keep the device from running the malware.
But how does the device firmware decide what it will allow to run (assuming you don’t turn off Secure Boot, which then means “run anything you want”)? It does this based on the certificates that are preloaded on the device into the UEFI “db” configuration, which acts as an “allow” list — anything signed by one of those certificates will be allowed to run.
- Microsoft Windows Production PCA 2011. The Windows bootloader (bootmgr.efi) is signed using this, so this is what allows Windows (and Windows PE) to run.
- Microsoft Corporation UEFI CA 2011. This one is used by Microsoft to sign non-Microsoft UEFI boot loaders, such as those used to load Linux or other operating systems. Technically, it’s described as “optional” but it would be unusual to find a device that doesn’t include it. (Windows RT devices, if you remember those, did not include this cert or any others, so as a result, it only ran Windows RT. We shall see what certs are included on Windows 10x devices…)
OEMs are then free to add their own additional certificates, so that they can run their own firmware components (e.g. the menus that you get when you go into “BIOS” setup). If I look at some of my devices, I can see this variation. From my Lenovo ThinkStation P620:
On a VMware virtual machine, the list is different:
But if I look at my Hyper-V virtual machine, I only see one:
That doesn’t mean Hyper-V can’t run other OSes — obviously it can. There is a configuration option to control what certificates are available:
If I change that value from “Microsoft Windows” (the default, corresponding to the Windows Production cert) to “Microsoft UEFI Certificate Authority” then you would only see the second certificate — if you could get Windows to boot, which you can’t without the first cert. So that is a challenging configuration if you want to run different OSes in the same VM.
Interestingly, the Surface devices that I have tried, which in theory share the same firmware as Hyper-V, have different options: They let you choose “Microsoft only,” “Microsoft & 3rd party CA” and “None” in the firmware settings. That’s a more flexible setup, as it means “Windows only” or “Windows and other stuff.”
If by chance you have turned off Secure Boot, you won’t be able to see what certificates are there, because when you check the UEFI “db” variable it’s not there. So turn it on and then check (assuming you can boot).
If you are curious where that Get-UEFISecureBootCerts cmdlet comes from, it’s from the new UEFIv2 module that I posted to the PowerShell Gallery this morning. So try it out yourself. That new cmdlet follows the UEFI spec to decode the contents of the UEFI “db” variable to pull out the certificate details.
Alright, so back to the original question: Who controls what can run on the device when Secure Boot is enabled? (As long as you can turn off Secure Boot, you always have the final authority.) As you can see from the above, it’s Microsoft and the OEMs. And since you probably don’t want to have to have an OEM- or model-specific boot loader, that effectively means it’s Microsoft. Only Windows binaries get signed with the “Windows Production” certificate, but anyone can get code signed using the “UEFI” certificate — if you pass the Microsoft requirements. You can get an idea of what those requirements entail from this blog post. It’s a non-trivial process because you are effectively having your code reviewed by Microsoft.
Notice that there are two specific call-outs in that blog: One for shim loaders, which are popular with Linux distributions; and one for iPXE, which is used (primarily) for enhancing the PXE process by enabling HTTP downloads of the boot images (instead of TFTP, which is not an efficient protocol).
Categories: Windows 10