Al's Website

Just another WordPress site

Playing with UEFI Secure Boot – Part 2: Basic Authenticode signing with MS Tools


In part one we learned how to set up an emulated UEFI system with Secure Boot capability. Next we need to know how to sign executables which will run on it.

The reference documentation only gives examples of how to sign code using Microsoft tools. What it does not mention is that only the very latest versions of these tools will work. You need the Windows 8 Preview SDK and the .NET 4.5 RC. Of course these need Windows too; you can use the Windows 8 Preview release, but the tools will run fine on 7.

You will need to add the SDK bin directory to your PATH to run these commands:

$ PATH=%PATH%;C:\Program Files (x86)\Windows Kits\8.0\bin\x64

Also, when you run makecert, a dialogue will open asking for the password. Click “None”, otherwise you will need to supply the password when running later commands.

The short version is:

$ makecert -n "CN=PkRoot" -r -sv PkRoot.pvk PkRoot.cer
$ makecert -n "CN=KekRoot" -r -sv KekRoot.pvk KekRoot.cer
$ pvk2pfx -pvk KekRoot.pvk -spc KekRoot.cer -pfx KekRoot.pfx -f
$ signtool sign /f KekRoot.pfx /fd sha256 HelloWorldKek.efi

HelloWorldKek.efi is now signed by KekRoot.pfx (it signs in place, so use a copy.)

Now you need to copy PkRoot.cer, KekRoot.cer and HelloWorldKek.efi to hda and start up QEMU.

After it boots, “exit” the EFI shell and go to the Secure Boot Configuration menu. Set the mode to “Custom”. Enter the new option that appears and select “Enroll KEK”, “From File”, select KekRoot.cer, and then “Commit changes” – (Ignore the GUID stuff for now.) Now go through these steps again but this time select “Enroll PK” and select the PkRoot.cer. Finally exit these menus and select “Continue” at the top level to get back to the EFI shell. Now enter these commands on the EFI shell and you should get the same results:

Shell> fs0:

fs0:\> HelloWorld.efi
Error reported: Access Denied

fs0:\> HelloWorldKek.efi
UEFI Hello World!

Here we see that the unsigned HelloWorld.efi will NOT run but the signed HelloWorldSigned.efi WILL run.

Let’s go over what we’ve done in detail.

We made two certificates, a Platform Key and a Key Exchange Key. In short, the Platform Key controls which Key Exchange Keys can be enrolled, and the Key Exchange Keys control which software is allowed to run. In particular, software signed with the Platform Key but not with any enrolled Key Exchange Key will NOT be allowed to run in the OVMF implementation.

$ makecert -n "CN=PkRoot" -r -sv PkRoot.pvk PkRoot.cer

This makes our Platform Key (PK) certificate. The PK does two things: firstly, enrolling it is required to enable secure boot. Secondly, it controls the enrolling of KEK keys from user mode, ie through automatic software updates. Since we will not be booting a full OS, this is irrelevant to us. When a user manually configures secure boot through the BIOS menu system there are no restrictions on which KEKs may be enrolled, so effectively we only make this certificate so that we can enable secure boot, and once it is enrolled we won’t use it again.

$ makecert -n "CN=KekRoot" -r -sv KekRoot.pvk KekRoot.cer

This makes our Key Exchange Key (KEK). In order for software to boot it must be signed by an enrolled KEK, or by a certificate which chains to an enrolled KEK (more on that in the next part.) Note that KEKs do not need to chain to the PK, even if we wanted to load it with an automated update. We would only need to sign the enrolment request with the PK. The KEK also does not need to be a root certificate, nor is it necessary for the KEK’s ultimate root certificate to be enrolled.

$ pvk2pfx -pvk KekRoot.pvk -spc KekRoot.cer -pfx KekRoot.pfx -f

This merges the KEK certificate and private key into an intermediate file which is used to sign the executable.

$ signtool sign /f KekRoot.pfx /fd sha256 HelloWorldKek.efi

This signs the executable with the pfx file we just made. Note that the argument “/ac KekRoot.cer” is unnecessary. In fact it does not even do anything the way it is used in the Intel documentation.

We enrolled PkRoot as Platform Key and KekRoot as a Key Exchange Key and so out signed executable is allowed to run. It is worth repeating that only the a KEK can authenticate a particular piece of software. We can test this by signing HelloWorld with PkRoot:

$ pvk2pfx -pvk PkRoot.pvk -spc PkRoot.cer -pfx PkRoot.pfx -f
$ signtool sign /f PkRoot.pfx /fd sha256 HelloWorldPk.efi

HelloWorldPk.efi will NOT run if PkRoot.cer is enrolled as PK and KekRoot.cer is enrolled as a KEK.

In the next part I will cover chains of trust, and including intermediate certificates in the signed binary.

Leave a Reply

Required fields are marked *.