Self Signing For Secure Boot
Here's how to do your own signing for use with Secure Boot!
Stuff you need
- software that needs to be signed
- shim - https://github.com/mjg59/shim/releases/download/0.8/shim-0.8.tar.bz2
- grub2 - upstream from gnu.org or your distro, plus these patches if your distro doesn't have them:
- the linux kernel from whatever distro you're using.
- pesign - https://github.com/vathpela/pesign/releases/download/0.110/pesign-0.110.tar.bz2
Create signing keys
This is pretty easy on a modern Linux distro when you've got pesign installed, though it is recommended to use a hardware security mechanism like a smart card or USB FIPS 140 Level 2 conforming device to generate and store the cryptographic keys. There's a short tutorial on that over at User:Pjones/SecureBootSmartCardDeployment, though for these purposes you don't really need a separate CA key; a single self-signed key should do. Assuming you've got the device itself set up and its modules added to the nss db in /etc/pki/pesign, and it presents a token in your pesign nss database named "fred", you need to create the key pair and certificates:
efikeygen -t fred -S -n jrh-signer -c "CN=J.Random Hacker's Code Signing Authority and Amalgamated Distillates, Inc." -u "https://example.com/jrh-signer-info"
Build shim with your key built in to it
At the least, you need some things from shim signed, and you need to build it with your keys built in. Basically this:
jrh-machine:~/shim-0.8$ certutil -d /etc/pki/pesign -h fred -L -n jrh-signer -r > jrh-signer.cer jrh-machine:~/shim-0.8$ make 'DEFAULT_LOADER=\\\\grubx64.efi' VENDOR_CERT_FILE=jrh-signer.cer shim.efi MokManager.efi fallback.efi jrh-machine:~/shim-0.8$ pesign -t fred -c jrh-signer -s -i shim.efi -o shim-signed.efi jrh-machine:~/shim-0.8$ pesign -t fred -c jrh-signer -s -i fallback.efi -o fallback-signed.efi jrh-machine:~/shim-0.8$ pesign -t fred -c jrh-signer -s -i MokManager.efi -o MokManager-signed.efi
Here we're assuming the bootloader will be installed as "EFI/jrh/grubx64.efi" on the ESP.
Assuming the EFI system partition is mounted on /boot/efi/, you'll also need to copy the files into place. Don't just change -o above to point there; you may hit this problem and find yourself having a very confusing week.
mkdir -p /boot/efi/EFI/jrh/ /boot/efi/EFI/BOOT cp shim-signed.efi /boot/efi/EFI/jrh/shim.efi cp MokManager-signed.efi /boot/efi/EFI/jrh/MokManager.efi cp shim-signed.efi /boot/efi/EFI/BOOTX64.EFI cp fallback.efi /boot/efi/EFI/BOOT/fallback.efi
You'll also want to make a BOOT.CSV for fallback to find in EFI\jrh\ ; it's a UCS-2 LE file, so do something like:
echo -n "shim.efi,JRH-OS,,This is the boot entry for JRH-OS" | ( printf "\xff\xfe" ; sed 's/./&\x00/g') > /boot/efi/EFI/jrh/BOOT.CSV
At this point you need to build the bootloader, including using "grub-mkimage" to make a reasonable grubx64.efi image. If your distro already has that, all you really need to do is make sure it's signed with your signature:
jrh-machine:~/tmp$ pesign -i grub-2.02/grub.efi -o grub.efi -r -u 0 jrh-machine:~/tmp$ pesign -t fred -c jrh-signer -s -i -i grub.efi -o grub-signed.efi jrh-machine:~/tmp$ cp grub-signed.efi /boot/efi/EFI/jrh/grubx64.efi
And do the same with the kernel:
jrh-machine:~/tmp$ pesign -i /boot/vmlinuz-3.15.6-200.fc20.x86_64 -o vmlinuz-unsigned -r -u 0 jrh-machine:~/tmp$ pesign -t fred -c jrh-signer -s -i -i vmlinuz-unsigned.efi -o vmlinuz-signed jrh-machine:~/tmp$ cp vmlinuz-signed /boot/vmlinuz-3.15.6-200.fc20.x86_64
Again, don't sign things on /boot, it'll make you likely to hit this pit of dispair.
You'll need to re-do grub and the kernel any time you upgrade them. If you have a reasonable level of minor paranoia about protecting keys and you've used an HSM with a pin code or at the least kept the keys on e.g. a USB stick that's not normally mounted on the machine you're doing signing for, then you probably can't really automate it. Sorry.