It’s been bugging me for a while, that I always have to choose my OS to boot via the EFI bootselector, if I could either use the Windows bootmanager or Grub2 to do this. Grub2 with the newest os-prober version does detect and create boot entries for Windows 8.1, but the Windows bootloader refuses to boot 🙁 (probably since secure boot is off). If I select the windows bootloader via EFI it works just fine.
Anyhow, I want to try to setup a secure boot system and see if chainloading the windows bootloader does work. (Spoiler: It does! :-))
Installing and backing up
First install the package app-crypt/efitools, which pulls sys-boot/gnu-efi, both being keyworded, on your system. Problem with the efitools are that they do not detect the efivarfs properly (at least in portage’s version 1.4.2-r1). So I grabbed the ebuild from https://bugs.gentoo.org/show_bug.cgi?id=533572 and added it to my local portage. I also bumped the version of the ebuild to 1.5.3 which is the latest development version.
mkdir /etc/efikeys chmod 700 /etc/efikeys efi-readvar -v PK -o /etc/efikeys/old_PK.esl efi-readvar -v KEK -o /etc/efikeys/old_KEK.esl efi-readvar -v db -o /etc/efikeys/old_db.esl efi-readvar -v dbx -o /etc/efikeys/old_dbx.esl
Next up, after installing and backing up, is the generation of keys which will be used to sign our kernel and its modules. Please change the common name (CN) to something that suits you.
openssl req -new -x509 -newkey rsa:2048 -subj "/CN=Benjamin's platform key/" -keyout /etc/efikeys/PK.key -out /etc/efikeys/PK.crt -days 3650 -nodes -sha256 openssl req -new -x509 -newkey rsa:2048 -subj "/CN=Benjamin's key-exchange-key/" -keyout /etc/efikeys/KEK.key -out /etc/efikeys/KEK.crt -days 3650 -nodes -sha256 openssl req -new -x509 -newkey rsa:2048 -subj "/CN=Benjamin's kernel-signing key/" -keyout /etc/efikeys/db.key -out /etc/efikeys/db.crt -days 3650 -nodes -sha256 chmod 400 /etc/efikeys/*.key
Now we will use the generated key to create a signed signature list for the PK.
cert-to-efi-sig-list -g "$(uuidgen)" /etc/efikeys/PK.crt /etc/efikeys/PK.esl sign-efi-sig-list -k /etc/efikeys/PK.key -c /etc/efikeys/PK.crt PK /etc/efikeys/PK.esl /etc/efikeys/PK.auth
Rebooting and clearing secure boot storage
Now we need to reboot, enter EFI, clear the secure boot storage. Please do so, see you in a minute!
After clearing the secure boot storage efi-readvar will show this:
bentoo benjamin # efi-readvar Variable PK has no entries Variable KEK has no entries Variable db has no entries Variable dbx has no entries Variable MokList has no entries
Updating secure boot storage
Now that the secure boot storage is cleared and EFI is in setup mode, let’s update the secure boot storage with our own keys. But first we’ll reload the old contents of KEK, db and dbx, which we saved off above, so that Windows will still be permitted to load under secure boot.
Restore Microsoft keys
Issue the following commands to reload the Microsoft keys
efi-updatevar -e -f /etc/efikeys/old_KEK.esl KEK efi-updatevar -e -f /etc/efikeys/old_db.esl db efi-updatevar -e -f /etc/efikeys/old_dbx.esl dbx efi-readvar
The efi-readvar command now should show the Microsoft entries for KEK, db and dbx.
Append our keys
After we restored the Microsoft keys we now can append our own keys.
efi-updatevar -a -c /etc/efikeys/KEK.crt KEK efi-updatevar -a -c /etc/efikeys/db.crt db efi-updatevar -f /etc/efikeys/PK.auth PK efi-readvars
Voila, done! Now there should be the original key set of Microsoft and our keys in the secure boot storage. All we need to do now is sign the Kernel, but before that let’s backup the work once again.
efi-readvar -v PK -o /etc/efikeys/new_PK.esl efi-readvar -v KEK -o /etc/efikeys/new_KEK.esl efi-readvar -v db -o /etc/efikeys/new_db.esl efi-readvar -v dbx -o /etc/efikeys/new_dbx.esl
Sign the bootloader
Since I use GRUB2 as my bootloader I need to sign the file grubx64.efi to be able to use secure boot.
sbsign --key /etc/efikeys/db.key --cert /etc/efikeys/db.crt \ --output /boot/efi/EFI/gentoo/grubx64.efi.signed \ /boot/efi/EFI/gentoo/grubx64.efi mv /boot/efi/EFI/gentoo/grubx64.efi /boot/efi/EFI/gentoo/grubx64.efi.unsigned cp /boot/efi/EFI/gentoo/grubx64.efi.signed /boot/efi/EFI/gentoo/grubx64.efi
No such device error, etc
After working with the system for a while, regenerating the grub.cfg etc. pp and so forth, I again ran into the Error „No such device“ or „No valid filesystem“. The Solution to those were that I had to explicitly disable CSM in my EFI. Afterwards it worked like a charm again. Sometimes disabling and enabling secure boot help too, i do not know why.
Today I was looking for a way to fix the above and found a new BIOS/EFI version for my Board. After updating I had to redo my settings 🙁 and the secure boot keys where gone. But luckily we saved them 🙂
efi-updatevar -e -f /etc/efikeys/new_KEK.esl KEK efi-updatevar -e -f /etc/efikeys/new_db.esl db efi-updatevar -e -f /etc/efikeys/new_dbx.esl dbx efi-readvar
Credits & Sources
A big credit is going to Sakaki from the Gentoo Wiki who wrote a really informative post about how to setup secure boot.
Sakaki’s EFI Install guide – Secure Boot
Gentoo Wiki Efibootmgr