View previous topic :: View next topic |
Author |
Message |
FlyingBullets n00b
Joined: 19 Mar 2024 Posts: 21
|
Posted: Sat Dec 14, 2024 5:11 pm Post subject: GRUB cannot boot with secure boot [SOLVED] |
|
|
#######
PROBLEM
#######
I'm trying to use secure boot with my setup, but I keep getting errors in GRUB.
#####
SETUP
#####
My setup is the following:
Drive Partition_name Mountpoint
/dev/sda
|-/dev/sda1 EFI System /efi
|-/dev/sda2 Linux extended boot /boot
`-/dev/sda3 Linx filesystem
sda1 is the ESP where the '.efi' file is /efi/EFI/BOOT/BOOTX64.EFI
sda2 is the XBOOT that contains:
|-grub/
|-amd-uc.img
|-intel-uc.img
|-System.map-x.y.z-gentoo
|-config-x.y.z-gentoo
|-initramfs-x.y.z-gentoo.img
`-vmlinuz-x.y.z-gentoo
sda3 is the encrypted root.
sys-kernel/installkernel is compiled with:
USE="dracut grub"
sys-boot/grub is compiled with:
USE="device-mapper fonts nls secureboot themes"
GRUB_PLATFORMS="efi-64"
GRUB is installed with the following command:
Code: | grub-install --removable --target=x86_64-efi --efi-directory=/efi |
I compile my own kernel from sys-kernel/gentoo-sources.
The current setup works -- I use the installkernel script to configure Dracut and GRUB when I run 'make install'.
###################################
TRYING TO USE SECURE BOOT ATTEMPT 1
###################################
I followed the instructions on the "Secure Boot" wiki page up to section "Signing Boot Files":
- set SECUREBOOT_SIGN_KEY and SECUREBOOT_SIGN_CERT in make.conf
- make my own keys
- sign my keys
- install my keys to the UEFI
The "Signing Boot Files" section does not explain well what files need to be signed, it only shows the kernel being
signed and only talks about UKI and initramfs. I signed what I could and signed:
- /efi/EFI/BOOT/BOOTX64.EFI
- /boot/vmlinuz-x.y.z-gentoo
with
Code: | sbsign --cert my_db.crt --key my_db.key <efi file> --output <efi file> |
I also checked they were signed with the right key with 'sbverify'.
When I try to boot, the GRUB menu doesn't show up and I'm given:
Code: | error: prohibited by secure boot policy.
Entering rescue mode...
grub rescue> |
###################################
TRYING TO USE SECURE BOOT ATTEMPT 2
###################################
When I install sys-boot/grub with USE="secureboot", there is a message stating that it makes the signed standalone
GRUB executables in /usr/lib/grub/grub-<target>.efi(.signed) and that these executables need the grub.cfg file
in the same directory.
So I ran the following commands:
Code: | export GRUB_CFG=/efi/EFI/BOOT/grub.cfg
cd /usr/src/linux
make install
cp /usr/lib/grub/grub-x86_64.efi.signed /efi/EFI/BOOT/BOOTX64.EFI
sbsign --cert my_db.crt --key my_db.key /boot/vmlinuz-x.y.z-gentoo --output /boot/vmlinuz-x.y.z-gentoo |
I verified the efi and kernel were both signed and rebooted. The GRUB menu showed up like normal and gave me the
usual options:
Code: | Gentoo GNU/Linux
Advanced options for Gentoo GNU/Linux
UEFI Firmware Settings |
But when I tried to boot Gentoo, I get the following error:
Code: | Loading Linux x.y.z-gentoo ...
error: shim_lock protocol not found.
Loading initial ramdisk ...
error: you need to load the kernel first.
Press any key to continue... |
I did some more research, but everyone seems to have their own solution that only applies to them:
- some say use UKI
- some say build the initramfs into the kernel
- something something GRUB modules
- grub-install options
I tried various solutions, but nothing seems to work.
Last edited by FlyingBullets on Fri Dec 20, 2024 8:16 pm; edited 1 time in total |
|
Back to top |
|
|
rab0171610 Guru
Joined: 24 Dec 2022 Posts: 444
|
Posted: Sat Dec 14, 2024 5:41 pm Post subject: |
|
|
My solution is to disable it entirely. I assume you have decided that you are at high risk of unauthorized code execution, a bootkit, or some sort of malware that specifically affects your Linux installation. My question, seeing your exhaustive efforts to enable and troubleshoot secure boot, is are you sure you really need it?
Do you have reason to believe that your system integrity is at risk and need to verify it every time you boot?
If you do not need it after all, then simply disable it. If you feel you %100 require it or benefit from it for your use case, then proceed.
Obviously, if you must dual-boot with Windows for some reason, it may be difficult to avoid. Otherwise it is optional. |
|
Back to top |
|
|
FlyingBullets n00b
Joined: 19 Mar 2024 Posts: 21
|
Posted: Sat Dec 14, 2024 6:24 pm Post subject: |
|
|
Quote: | My question, seeing your exhaustive efforts to enable and troubleshoot secure boot, is are you sure you really need it? |
Yes. |
|
Back to top |
|
|
Child_of_Sun_24 l33t
Joined: 28 Jul 2004 Posts: 605
|
Posted: Sat Dec 14, 2024 6:31 pm Post subject: |
|
|
I use secureboot with sys-boot/shim and it works with dual-boot windows.
https://wiki.gentoo.org/wiki/Shim
Here is everything discribed what you need for it. |
|
Back to top |
|
|
pietinger Moderator
Joined: 17 Oct 2006 Posts: 5254 Location: Bavaria
|
|
Back to top |
|
|
rab0171610 Guru
Joined: 24 Dec 2022 Posts: 444
|
Posted: Sat Dec 14, 2024 7:33 pm Post subject: |
|
|
FlyingBullets wrote: | Quote: | My question, seeing your exhaustive efforts to enable and troubleshoot secure boot, is are you sure you really need it? |
Yes. |
Perfectly understandable. I wanted to put it out there because it is a valid question that users should be asking themselves before spending the time and effort in setting it up and troubleshooting -- as might be the case for other users who read this post in the future. |
|
Back to top |
|
|
FlyingBullets n00b
Joined: 19 Mar 2024 Posts: 21
|
Posted: Sat Dec 14, 2024 8:01 pm Post subject: |
|
|
Quote: | I use secureboot with sys-boot/shim... |
I don't want to use shim; I want to use my own keys.
Quote: | If you need an initramfs (because your root partition is encrypted) then USE an embedded initramfs. |
I'm going to try several things:
- Dracut has some uefi parameters to embed the initramfs Update: I don't think this does what I think it does.
- Using an EFI Stub to be loaded by GRUB
- UKI
Quote: | If it is grub - and UEFI has started your grub, ANYTHING else is THEN the job of grub. |
That's how I want things to be handled; I want to keep using GRUB so that I can switch between kernels in case I mess something up; I don't want to boot directly into a kernel. I get that all executables should be signed, but that didn't work.
What I would like to know is why GRUB is giving me this "shim_lock" error.
Update:
The "EFI Stub" wiki page is not helpful in learning how to actually embed an initramfs, it only talks about the subject and something about CPIO files. It says that Dracut can make them, but I can't find anything in the Dracut man pages about ".cpio" files. Also, I'm being told to set CONFIG_INITRAMFS_SOURCE=/usr/src/initramfs ...but that doesn't exist? |
|
Back to top |
|
|
FlyingBullets n00b
Joined: 19 Mar 2024 Posts: 21
|
Posted: Sat Dec 14, 2024 9:10 pm Post subject: |
|
|
As a sanity check, I made a UKI by following the instructions on the "Unified kernel image" wiki page; I was able to boot with secure boot, but I had to boot directly into the kernel.
I'm still working on getting GRUB to work. |
|
Back to top |
|
|
zen_desu n00b
Joined: 25 Oct 2024 Posts: 71
|
Posted: Sat Dec 14, 2024 9:12 pm Post subject: |
|
|
If you want to embed a CPIO archive into the kernel, you must remove compression on that file if there is any.
If you want to embed a dracut initramfs into the kernel, I think you have to use special tools to extract it because Dracut makes a "layered" CPIO for early microcode.
Once extracted, you can point CONFIG_INITRAMFS_SOURCE to the directory containing the extracted initramfs.
You do not need to embed the initramfs for secure boot. This just ensures the initramfs is signed because the whole kernel (containing the initramfs) is signed.
A more straightforward method is to use a UKI.
FlyingBullets wrote: | As a sanity check, I made a UKI by following the instructions on the "Unified kernel image" wiki page; I was able to boot with secure boot, but I had to boot directly into the kernel.
I'm still working on getting GRUB to work. |
I would just do this tbh. Getting GRUB to work with SB is a bit of a pain. If you can directly boot into the kernel, why not do that? _________________ µgRD dev
Wiki writer |
|
Back to top |
|
|
pietinger Moderator
Joined: 17 Oct 2006 Posts: 5254 Location: Bavaria
|
Posted: Sat Dec 14, 2024 9:25 pm Post subject: |
|
|
zen_desu wrote: | If you want to embed a CPIO archive into the kernel, you must remove compression on that file if there is any. [...] |
Are you sure? I ask because /usr/src/linux/usr/Makefile says:
Code: | # If CONFIG_INITRAMFS_SOURCE specifies a single file, and it is suffixed with
# .cpio, use it directly as an initramfs.
ifneq ($(filter %.cpio,$(ramfs-input)),)
cpio-data := $(ramfs-input)
endif
# If CONFIG_INITRAMFS_SOURCE specifies a single file, and it is suffixed with
# .cpio.*, use it directly as an initramfs, and avoid double compression.
ifeq ($(words $(subst .cpio.,$(space),$(ramfs-input))),2)
cpio-data := $(ramfs-input)
compress-y := copy
endif |
... see the 2nd part -> # .cpio.*
and in my article I wrote:
Quote: | It is important to use suffix .cpio so "make" understand it is a CPIO file !
It is important to use suffix .cpio.gz so "make" understand it is an already gzipped CPIO file |
_________________ https://wiki.gentoo.org/wiki/User:Pietinger |
|
Back to top |
|
|
zen_desu n00b
Joined: 25 Oct 2024 Posts: 71
|
Posted: Sat Dec 14, 2024 9:37 pm Post subject: |
|
|
pietinger wrote: | zen_desu wrote: | If you want to embed a CPIO archive into the kernel, you must remove compression on that file if there is any. [...] |
Are you sure? I ask because /usr/src/linux/usr/Makefile says:
Code: | # If CONFIG_INITRAMFS_SOURCE specifies a single file, and it is suffixed with
# .cpio, use it directly as an initramfs.
ifneq ($(filter %.cpio,$(ramfs-input)),)
cpio-data := $(ramfs-input)
endif
# If CONFIG_INITRAMFS_SOURCE specifies a single file, and it is suffixed with
# .cpio.*, use it directly as an initramfs, and avoid double compression.
ifeq ($(words $(subst .cpio.,$(space),$(ramfs-input))),2)
cpio-data := $(ramfs-input)
compress-y := copy
endif |
... see the 2nd part -> # .cpio.*
and in my article I wrote:
Quote: | It is important to use suffix .cpio so "make" understand it is a CPIO file !
It is important to use suffix .cpio.gz so "make" understand it is an already gzipped CPIO file |
|
Ah that explains why I had issues in the past. Initramfs images are often installed with a .img suffix. I don't recall if this worked when it was a plain CPIO, but I definitely had issues when the compression extension was not included, as it often is not. _________________ µgRD dev
Wiki writer |
|
Back to top |
|
|
FlyingBullets n00b
Joined: 19 Mar 2024 Posts: 21
|
Posted: Sat Dec 14, 2024 10:01 pm Post subject: |
|
|
Quote: | If you can directly boot into the kernel, why not do that? |
I would like to have a menu of different kernels to select from when I boot the machine. If a new kernel build doesn't boot, I can easily select another one. Although, using a UKI means that only one file has to be unencrypted outside of full disk encryption, I can keep everything in /boot on the same partition as root. But that shouldn't matter as long as the GRUB efi and kernel (with embedded initramfs) are signed right? There shouldn't be any holes in the boot chain right?
Quote: | I think you have to use special tools to extract it because Dracut makes a "layered" CPIO for early microcode. |
Dracut makes files with extension ".img", is there a way to convert them to ".cpio"? I tried setting CONFIG_INITRAMFS_SOURCE=/usr/lib/dracut and it didn't error, but I was still unable to achieve my goal. |
|
Back to top |
|
|
zen_desu n00b
Joined: 25 Oct 2024 Posts: 71
|
Posted: Sat Dec 14, 2024 10:08 pm Post subject: |
|
|
If your system has a boot menu, you can use that. I do that on most of my systems, I can press f12 or whatever to see boot options and change which kernel version I'm booting into.
You can also install an EDK2 shell to your ESP if your UEFI doesn't have similar. Using that, you can boot any kernel/initramfs/cmdline you want.
Technically a UKI means you only need a single unencrypted file, but it has components equivalent to multiple files, more or less. You can almost treat it like a self extracting archive. When it runs, it extracts parts such as the kernel/initramfs from itself.
It being a single file mostly helps with signing as only a single file must be signed.
I think you can simply change the extension of the dracut ".img" to ".cpio.zstd" for example, if it uses zstd compression.
CONFIG_INITRAMFS_SOURCE should target either the initramfs file (properly suffixed) or a directory containing the initramfs tree which will be packed as part of the kernel build process. _________________ µgRD dev
Wiki writer |
|
Back to top |
|
|
sMueggli Guru
Joined: 03 Sep 2022 Posts: 514
|
Posted: Sun Dec 15, 2024 1:50 pm Post subject: |
|
|
I think you did not sign all the necessary parts of Grub. For example the "insmod" commands in grub.cfg will fail. The needed modules have to be part of the standalone Grub image.
Links:
And why are you using "--removable"? As long as you have no other systems, you will not see any difference. But the "\EFI\BOOT\BOOTx64.efi" might be overwritten with other EFI binaries. |
|
Back to top |
|
|
Nowa Developer
Joined: 25 Jun 2014 Posts: 463 Location: Nijmegen
|
Posted: Sun Dec 15, 2024 8:08 pm Post subject: Re: GRUB cannot boot with secure boot |
|
|
FlyingBullets wrote: |
GRUB is installed with the following command:
Code: | grub-install --removable --target=x86_64-efi --efi-directory=/efi |
|
This cannot work, grub-install will by default create a modular grub without an sbat section. The sbat section is required to boot with shim. And loading modules is prohibited when secure boot is enabled (hence your 'error: prohibited by secure boot policy.').
Instead, enable the "secureboot" flag on sys-boot/grub and follow the steps in the handbook: https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Bootloader#Optional:_Secure_Boot (copy the prebuilt stand-alone /usr/lib/grub/grub-x86_64.efi.signed, register with efibootmgr, generate grub.cfg and set GRUB_CFG in the environment)
UKI is separate to the issue at hand, note that grub does NOT support loading UKI's with secureboot enabled through shim (this requires patches from Ubuntu or Fedora, see https://bugs.gentoo.org/942201) _________________ OS: Gentoo 6.10.12-gentoo-dist, ~amd64, 23.0/desktop/plasma/systemd
MB: MSI Z370-A PRO
CPU: Intel Core i9-9900KS
GPU: Intel Arc A770 16GB & Intel UHD Graphics 630
SSD: Samsung 970 EVO Plus 2 TB
RAM: Crucial Ballistix 32GB DDR4-2400 |
|
Back to top |
|
|
GDH-gentoo Veteran
Joined: 20 Jul 2019 Posts: 1777 Location: South America
|
Posted: Mon Dec 16, 2024 12:13 am Post subject: Re: GRUB cannot boot with secure boot |
|
|
FlyingBullets wrote: | I did some more research, but everyone seems to have their own solution that only applies to them:
- some say use UKI
- some say build the initramfs into the kernel
- something something GRUB modules
- grub-install options |
That's because setting up secure boot is actually quite complex, and so, a) many people don't bother, which reduces the pool of experienced people, b) a lot of documentation is written in tutorial or instruction list format (and this includes the Handbook's section on it), which obviously applies to the one setup the author wished to document (in the case of the Handbook, that's the Shim), and excludes other possibilities. One of which might just be the one you would like to set up So here's one long attempt at clarification.
Disclaimer: I use (and even like) GRUB2 even with UEFI setups, I don't use secure boot, and if I did, I would go with the Shim and a MOK. That said, I spent some time reading GRUB's code to find out stuff that does not appear in documentation, which also means I could have gotten it wrong.
First:
FlyingBullets wrote: | The "Signing Boot Files" section does not explain well what files need to be signed, it only shows the kernel being
signed and only talks about UKI and initramfs. I signed what I could and signed:
- /efi/EFI/BOOT/BOOTX64.EFI
- /boot/vmlinuz-x.y.z-gentoo
with
Code: | sbsign --cert my_db.crt --key my_db.key <efi file> --output <efi file> |
|
One has to understand that there are three mechanisms for verifying files with digital signatures, that could be used in secure boot scenarios. All of them make use of asymmetric encryption, and therefore, a public and a private signing key pair, so they all generically involve "signing" of some sort, but their technical details are actually different:
- The mechanism used by UEFI firmware and the Shim. I will call it the "secure boot mechanism", because is it the one actually described in the UEFI specification, and will do that even though the Shim is a sort of add-on.
- A mechanism that can be used by GRUB for verifying files that it reads once it is running, independent of the secure boot mechanism. More on this later in the post.
- The mechanism used by the kernel for verifying the kernel modules that it loads. I won't talk about it here.
Now, sbsign is only used for signing files that will be verified with the mechanism #1. And these can only be of one type: EFI PE32+ files. So, which files are PE32+ files that could appear in a secure boot scenario? They are:
- EFI stub kernels. They resemble PE32+ files.
- The bootloader's EFI executable, if you are using one. That's grubx64.efi for GRUB.
- The Shim, shimx64.efi, if you are using it.
- Unified Kernel Images (UKI), if you are using them.
Here's the first set of alternatives that complicates any attempt at making a general secure boot article. So, which scenario is the one you want? That's the second one, i. e. the bootloader scenario.
Second: you want GRUB, so clearly, sbsign would be used at least for signing its EFI executable. But now you also have to satisfy GRUB's additional requirements. And you see, when GRUB detects that it is being run with secure boot enabled, it enters a mode of operation called "lockdown mode". Lockdown mode prevents you from doing stuff that could compromise the security. And one of its requirements is that, when GRUB is asked to read a file, if it is of certain types, then it must be verified with a digital signature. And these types of files include Linux kernels and GRUB modules.
Third: How do you make GRUB accept a kernel in lockdown mode? There's two ways, apparently:
- GPG-style detached signatures, which is mechanism #2 in the previous list, and is documented in GRUB's manual. This can be used to sign arbitrary files, not just EFI PE32+ ones, but is competely independent of the secure boot mechanism, which I'm sure has the potential to confuse people.
- The secure boot mechanism. Which would only work with PE32+ files, so kernels have to be EFI stubs that you must also sign with sbsign.
While alternative #2 is mentioned in the manual, you'll note that the corresponding section is quite slim. Also, if this alternative is used, GRUB will not allow loading of modules, so all needed ones must be embedded in GRUB's core image. The automation in Gentoo's ebuild activated by setting the secureboot USE flag does that to an extent, but I'm not sure it guarantees that there will never be a need to load a module. Or read a file other than a PE32+ one that needs verification in lockdown mode.
Therefore, as Nowa said, attempt 1 failed with:
FlyingBullets wrote: | Code: | error: prohibited by secure boot policy.
Entering rescue mode...
grub rescue> |
|
Now, what I think is the real problem in your case: I believe, from looking at the code, that alternative #2 can only be used when the Shim is installed, even if you have replaced all keys in the UEFI secure boot db. It's because the Shim installs some sort of callback mechanism that bootloaders can then use to verify signatures on PE32+ files, with keys in the UEFI secure boot db and MOKs (which are not needed in your case), and GRUB seems to rely on that. That's the "shim lock protocol" in this message:
FlyingBullets wrote: | Code: | Loading Linux x.y.z-gentoo ...
error: shim_lock protocol not found.
Loading initial ramdisk ...
error: you need to load the kernel first.
Press any key to continue... |
|
I believe that attempt 2 failed because you don't have the Shim.
Last one: GRUB will make you use the GPG-style detached signatures alternative if it is asked to read a file that requires verification in lockdown mode, but is not an EFI PE32+ file.
So what then? It looks like, if you want to use GRUB, you'd have to either use the GPG-style detached signatures alternative, which Gentoo's automation will not set up for you, or try installing the Shim, and signing it with one of your keys. Gentoo's Shim is already signed with a signature that you probably won't be able to verify with the keys in your UEFI db, if you replaced its contents. I don't know if you can just use sbsign with a signed file, or if it is more complicated than that.
There's an old thread here somewhere from someone that managed to make GRUB boot with secure boot enabled and GPG-style detached signatures.
EDIT to add Just to be clear:
FlyingBullets wrote: | I followed the instructions on the "Secure Boot" wiki page up to section "Signing Boot Files":
- ...
- make my own keys
- sign my keys
- install my keys to the UEFI |
FlyingBullets wrote: | Quote: | I use secureboot with sys-boot/shim... |
I don't want to use shim; I want to use my own keys. |
I assumed in all places where I referred to your specific setup that this means "I replaced the Platform Key, Key Exchange Keys and all keys in the secure boot db with my own".
EDIT 2: Corrected information about what happens with GRUB modules when kernel signatures are verified with the secure boot protocol. _________________
NeddySeagoon wrote: | I'm not a witch, I'm a retired electronics engineer |
Ionen wrote: | As a packager I just don't want things to get messier with weird build systems and multiple toolchains requirements though |
Last edited by GDH-gentoo on Tue Dec 17, 2024 1:27 am; edited 1 time in total |
|
Back to top |
|
|
FlyingBullets n00b
Joined: 19 Mar 2024 Posts: 21
|
Posted: Mon Dec 16, 2024 4:11 am Post subject: |
|
|
sMueggli wrote: | I think you did not sign all the necessary parts of Grub. For example the "insmod" commands in grub.cfg will fail. The needed modules have to be part of the standalone Grub image. |
You are correct, after reading the info pages of GRUB, I learned that GRUB must have the modules it uses embedded at install time (grub-install) or the modules need to be signed with a GPG key that GRUB checks; the key is given to GRUB at install time with "-k, --pubkey". When I used Gentoo's automatically generated GRUB efi file (/usr/lib/grub/grub-x86_64.efi.signed) it had a size of 14M; the original one (before I went on this secure boot journey) was 294K; this leads me to believe that Gentoo's automatically generated one embeds the modules and why I was able to boot Gentoo's, but not mine. I remember seeing a "insmod" error one time attempting to boot, but I can't remember what configuration I had because I've already gone through 30.
When I tried to do this manually:
Code: | grub-install --removable --target=x86_64-efi --efi-directory=/efi --modules="$(ls /boot/grub/x86_64-efi | grep -E '\.mod$')" |
I got an efi file of size 2.8M; it booted, but I was not met with the normal menu, I was met with the following screen:
Code: | GNU GRUB version 2.12
Minimal BASH-like line editing is supported. For the first word, TAB
lists possible command completions. Anywhere else TAB lists possible
device or file completions. To enable less(1)-like paging, "set
pager=1".
grub> |
sMueggli wrote: | And why are you using "--removable"? As long as you have no other systems, you will not see any difference. But the "\EFI\BOOT\BOOTx64.efi" might be overwritten with other EFI binaries. |
I installed Gentoo on one machine so many times that I filled up the NVRAM and kept getting errors from "grub-install". I spent a day debugging it and added a solution to GRUB/Troubleshooting (the solution was on the Arch wiki: delete "dump-*" files in NVRAM). I use "--removable" because it doesn't modify the UEFI, it uses the generic "/EFI/BOOT/BOOTX64.EFI".
GDH-gentoo wrote: | I assumed in all places where I referred to your specific setup that this means "I replaced the Platform Key, Key Exchange Keys and all keys in the secure boot db with my own". |
Correct.
GDH-gentoo wrote: | 1. The mechanism used by UEFI firmware and the Shim. I will call it the "secure boot mechanism", because is it the one actually described in the UEFI specification, and will do that even though the Shim is a sort of add-on.
2. A mechanism that can be used by GRUB for verifying files that it reads once it is running, independent of the secure boot mechanism. More on this later in the post.
3. The mechanism used by the kernel for verifying the kernel modules that it loads. I won't talk about it here. |
I think you explained it best. I thought secure boot was, "the UEFI checks all executable files when booting". But there is actually a boot chain where each step checks the next with it's own method:
1. The UEFI checks the signature of the efi file to boot (GRUB in my case) with it's own keys.
2. GRUB checks the signature of it's modules and kernel to boot with it's own keys.
3. The kernel checks the signature of it's modules to probe with it's own keys.
So really, I have 3 sets of keys: one for the UEFI and efi file, one for GRUB and it's modules and the kernel (and initramfs?), and one for the kernel and it's modules.
I guess I have steps (1) and (3) done because I already use signed kernel modules.
GDH-gentoo wrote: | So what then? It looks like, if you want to use GRUB, you'd have to either use the GPG-style detached signatures alternative, which Gentoo's automation will not set up for you, or try installing the Shim, and signing it with one of your keys. Gentoo's Shim is already signed with a signature that you probably won't be able to verify with the keys in your UEFI db, if you replaced its contents. |
I'm okay with using PGP keys -- learning something new is fun :3 I can make a script to automate the signing, I just need to know what exactly to sign >.<
There is a section in the GRUB info pages that if shim is not going to be used, then the "--disable-shim-lock" option must be added to the "grub-install" command.
EDIT: I also read in the info pages that "--efi-directory" AND "--boot-directory" must be used when using "--removable", but I never ran into problems... until now...
GDH-gentoo wrote: | I don't know if you can just use sbsign with a signed file, or if it is more complicated than that. |
I can concatenate the factory keys and my keys so that they both work, this is explained in the "Secure Boot" wiki page:
Code: | cat factory/db.esl custom/db.esl >new_db.esl |
Heh, as I'm typing this post, I'm trying to get back to my default setup and I keep discovering new errors >.<
My latest one is:
Code: | Booting `Gentoo GNU/Linux'
Loading Linux x.y.z-gentoo.efi...
Loading initial ramdisk...
systemd-boot: Assertion 'device' failed at ../systemd-stable-254.17/src/boot/efi/part-discovery.c:251@partition_open, halting. |
EDIT: Woops! GRUB was trying to load an efi file with the same name as the kernel and it showed up first in the menu without me noticing: vmlinuz-x.y.z-gentoo(.efi) |
|
Back to top |
|
|
GDH-gentoo Veteran
Joined: 20 Jul 2019 Posts: 1777 Location: South America
|
Posted: Tue Dec 17, 2024 2:09 am Post subject: |
|
|
FlyingBullets wrote: | I installed Gentoo on one machine so many times that I filled up the NVRAM and kept getting errors from "grub-install". I spent a day debugging it and added a solution to GRUB/Troubleshooting (the solution was on the Arch wiki: delete "dump-*" files in NVRAM). I use "--removable" because it doesn't modify the UEFI, it uses the generic "/EFI/BOOT/BOOTX64.EFI". |
There is no need to do that. If you don't want grub-install modifying the UEFI firmware's nonvolatile storage, there's the --no-nvram option. Modifiying it is only needed once anyway, to create a Boot#### variable for grubx64.efi and make the firmware use that when booting. It can remain unmodified until you change the bootloader or switch to booting EFI stubs or UKIs directly.
FlyingBullets wrote: | But there is actually a boot chain where each step checks the next with it's own method:
1. The UEFI checks the signature of the efi file to boot (GRUB in my case) with it's own keys.
2. GRUB checks the signature of it's modules and kernel to boot with it's own keys.
3. The kernel checks the signature of it's modules to probe with it's own keys.
So really, I have 3 sets of keys: one for the UEFI and efi file, one for GRUB and it's modules and the kernel (and initramfs?), and one for the kernel and it's modules.
I guess I have steps (1) and (3) done because I already use signed kernel modules. |
(1) for sure, when you replaced the secure boot db contents with your own keys and enabled secure boot. (3) yes if you used a distribution kernel with the modules-sign USE flag set, or a manually configured kernel with CONFIG_MODULE_SIG_ALL.
FlyingBullets wrote: | There is a section in the GRUB info pages that if shim is not going to be used, then the "--disable-shim-lock" option must be added to the "grub-install" command. |
This disables signature verification of kernels using keys in the secure boot db and MOKs (alternative #2, which I believe needs the Shim installed), but with secure boot enabled in the UEFI firmware, GRUB must still have its EFI executable signed with a key in db, and will still run in lockdown mode and require that you use OpenPGP signatures for everything else (alternative #1, with the public key embedded in its core image with --pubkey). I remember that it was said in this other thread that the pgp module also had to be embedded in the core image.
GDH-gentoo wrote: | Third: How do you make GRUB accept a kernel in lockdown mode? There's two ways, apparently:
- GPG-style detached signatures, which is mechanism #2 in the previous list, and is documented in GRUB's manual. This can be used to sign arbitrary files, not just EFI PE32+ ones, but is competely independent of the secure boot mechanism, which I'm sure has the potential to confuse people.
- The secure boot mechanism. Which would only work with PE32+ files, so kernels have to be EFI stubs that you must also sign with sbsign.
|
FlyingBullets wrote: | I'm okay with using PGP keys -- learning something new is fun :3 I can make a script to automate the signing, I just need to know what exactly to sign >.< |
Pretty much everything: kernel, separate initramfs if there is one, non-embedded GRUB modules, GRUB's configuration file and environment block, etc. The manual shows in the digital signatures section how to do it with the gpg program in a for loop.
FlyingBullets wrote: | EDIT: I also read in the info pages that "--efi-directory" AND "--boot-directory" must be used when using "--removable", but I never ran into problems... until now... |
If you mean the last sentence of this part, that applies to the case in which you want to create a bootable removable medium.
FlyingBullets wrote: | Heh, as I'm typing this post, I'm trying to get back to my default setup and I keep discovering new errors >.<
My latest one is:
Code: | Booting `Gentoo GNU/Linux'
Loading Linux x.y.z-gentoo.efi...
Loading initial ramdisk...
systemd-boot: Assertion 'device' failed at ../systemd-stable-254.17/src/boot/efi/part-discovery.c:251@partition_open, halting. |
EDIT: Woops! GRUB was trying to load an efi file with the same name as the kernel and it showed up first in the menu without me noticing: vmlinuz-x.y.z-gentoo(.efi) |
Looks like it was the UKI you made earlier. _________________
NeddySeagoon wrote: | I'm not a witch, I'm a retired electronics engineer |
Ionen wrote: | As a packager I just don't want things to get messier with weird build systems and multiple toolchains requirements though |
|
|
Back to top |
|
|
FlyingBullets n00b
Joined: 19 Mar 2024 Posts: 21
|
Posted: Thu Dec 19, 2024 5:23 pm Post subject: |
|
|
I can't seem to get GRUB to work with GPG. The GPG application is more complicated than I thought.
Code: |
# Make the GPG key.
gpg --full-gen-key
RSA and RSA
2048 bits
Key does not expire
Real name: grub_key
No passphrase
# Get the public key from GPG.
gpg --output grub_key_public --armor --export grub_key
# Make the GRUB executable and embed the public key.
grub-install --removable --target=x86_64-efi --efi-directory=/efi --boot-directory=/boot --disable-shim-lock --pubkey=/path/to/grub_key_public
# Sign the GRUB executable with the 'db' key for secure boot to verify.
sbsign --cert /path/to/db.crt --key /path/to/db.key /efi/EFI/BOOT/BOOTX64.EFI --output /efi/EFI/BOOT/BOOTX64.EFI
# Sign GRUB modules, config files, kernels, inramfs, etc. with the GPG key for GRUB to verify.
for valid_file in $(find /boot -regextype -posix-extended -regex '.*(\.cfg|\.lst|\.mod|vmlinuz.*gentoo(\.old)?|init.*\.img(\.old)?|grubenv)$'); do
# Delete old signature.
[[ -f "$valid_file".sig ]] && rm "$valid_file".sig
gpg --batch --detach-sign "$valid_file"
done |
EDIT: Forgot to post the error message; on boot, GRUB gave the following error message:
Code: | error: verification requested but nobody cares: (hd0,gpt2)/grub/x86_64-efi/normal.mod.
Entering rescue mode...
grub rescue> |
Disabling secure boot in the UEFI makes GRUB work normally. I've clearly gotten past step (1) (get secure boot to load GRUB), but I'm stuck on step (2) (get GRUB to load the modules, config, kernel, etc.).
EDIT 2: I repeated the original steps in this post with --modules="pgp.mod" for grub-install and got the following error:
Code: | error loading initial key: bad signature
Aborted. Press any key to exit. |
Last edited by FlyingBullets on Thu Dec 19, 2024 9:12 pm; edited 1 time in total |
|
Back to top |
|
|
Child_of_Sun_24 l33t
Joined: 28 Jul 2004 Posts: 605
|
Posted: Thu Dec 19, 2024 7:11 pm Post subject: |
|
|
When you embed the modules in the grubx64.efi file, you don't need the insmod commands in grub.cfg.
Since i use sys-boot/shim, my setup is not directly compareble to your setup but maybe this commands help you:
Installing grub:
Code: | grub-install --no-nvram --efi-directory=/efi --boot-directory=/boot --bootloader-id Cracked.OS --disable-shim-lock --sbat=/usr/share/grub/sbat.csv --modules "boot.mod btrfs.mod cat.mod configfile.mod echo.mod efifwsetup.mod efinet.mod font.mod gettext.mod gzio.mod halt.mod help.mod jpeg.mod keystatus.mod loadenv.mod loopback.mod ls.mod lsefi.mod lsefimmap.mod lsefisystab.mod lssal.mod memdisk.mod minicmd.mod part_gpt.mod part_msdos.mod png.mod probe.mod reboot.mod regexp.mod search.mod search_fs_uuid.mod search_fs_file.mod search_label.mod sleep.mod smbios.mod squash4.mod test.mod true.mod video.mod xfs.mod iso9660.mod fat.mod chain.mod normal.mod linux.mod linux16.mod video.mod gfxmenu.mod gfxterm_background.mod gfxterm_menu.mod gfxterm.mod video_fb.mod efi_gop.mod efi_uga.mod video_fb.mod all_video.mod ntfs.mod" |
My grub.cfg:
Code: | set timeout=30
set default=0
loadfont unicode
set menu_color_normal=white/black
set menu_color_highlight=black/light-gray
menuentry "Cracked.OS" {
set gfxpayload=keep
search --no-floppy --fs-uuid --set=root 4e13eec9-bced-4375-94ff-ad488a03f349
linux (${root})/boot/vmlinuz root=PARTUUID=197f3c03-eb46-479d-82a6-1a3a701500e7 ro init=/usr/lib/systemd/systemd rootfstype=btrfs rootflags=ssd,thread_pool=10,compress=zstd amd_pstate=guided cpufreq.scaling_governor=schedutil cpufreq.default_governor=schedutil crypt=0 passdev=none
}
#menuentry "Cracked.OS-Testing" {
# set gfxpayload=keep
# linux /vmlinuz-6.12.0-rc5-Cracked.OS root=PARTUUID=197f3c03-eb46-479d-82a6-1a3a701500e7 ro init=/usr/lib/systemd/systemd rootfstype=btrfs rootflags=ssd,thread_pool=10,compress=zstd amd_pstate=guided cpufreq.scaling_governor=schedutil cpufreq.default_governor=schedutil crypt=0 passdev=none nouveau.config=NvGspRm=1
#}
menuentry 'Windows 11 x64' {
search --no-floppy --fs-uuid --set=root 67D3-2C0E
chainloader (${root})/EFI/Microsoft/Boot/bootmgfw.efi
}
menuentry 'Rescue' {
set gfxpayload=keep
search --no-floppy --fs-uuid --set=root 67D3-2C0E
linux (${root})/sysresccd/boot/x86_64/vmlinuz archisobasedir=sysresccd archisolabel=BOOT iomem=relaxed copytoram setkmap=de
initrd (${root})/sysresccd/boot/intel_ucode.img /sysresccd/boot/amd_ucode.img /sysresccd/boot/x86_64/sysresccd.img
} |
I don't know if it helps you, but maybe it can push you in the right direction.
I have to add that when i install all modules in grubx64.efi i become the same output like you, i don't know which module is responsible for this behavior, but when i use the modules from my command it works. |
|
Back to top |
|
|
GDH-gentoo Veteran
Joined: 20 Jul 2019 Posts: 1777 Location: South America
|
Posted: Thu Dec 19, 2024 9:34 pm Post subject: |
|
|
FlyingBullets wrote: | EDIT 2: I repeated the original steps in this post with --modules="pgp.mod" for grub-install and got the following error:
Code: | error loading initial key: bad signature
Aborted. Press any key to exit. |
|
That's some kind of problem with the key in the file that you passed to grub-install with --pubkey. Try gpg --export without --armor. _________________
NeddySeagoon wrote: | I'm not a witch, I'm a retired electronics engineer |
Ionen wrote: | As a packager I just don't want things to get messier with weird build systems and multiple toolchains requirements though |
|
|
Back to top |
|
|
FlyingBullets n00b
Joined: 19 Mar 2024 Posts: 21
|
Posted: Thu Dec 19, 2024 11:01 pm Post subject: |
|
|
GDH-gentoo wrote: | That's some kind of problem with the key in the file that you passed to grub-install with --pubkey. Try gpg --export without --armor. |
That was the problem.
I then tried the grub-install command again without any embedded modules:
Code: | error: verification requested but nobody cares: (hd0,gpt2)/grub/x86_64-efi/normal.mod.
Entering rescue mode...
grub rescue> |
Okay, then I tried adding --modules="pgp.mod" to grub-install:
Code: | error: hash `sha256' not loaded.
Entering rescue mode...
grub rescue> |
Now --modules="pgp.mod gcry_sha256.mod":
Code: | error: public key 9f7aeba555c2655 not found.
Entering rescue mode...
grub rescue> |
I had the public key stored in the encrypted partition, so I moved it to /boot/grub_pub because I thought GRUB couldn't read the key. I changed the grub-install command to use --pubkey=/boot/grub_pub. But this shouldn't matter because the public key is embedded in the executable... right?
This did not work, I got the same error as before. I then tried --modules="pgp.mod gcry_sha256.mod btrfs.mod" because /boot is formatted in btrfs; this also did not work -- I'm left with the same previous error message.
Also, if you're wondering why not just use --modules="$(find /boot -name '*.mod')" to embed all the modules, it's because I'm met with the following screen:
Code: | GNU GRUB version 2.12
Minimal BASH-like line editing is supported. For the first word, TAB
lists possible command completions. Anywhere else TAB lists possible
device or file completions. To enable less(1)-like paging, "set
pager=1".
grub> |
|
|
Back to top |
|
|
GDH-gentoo Veteran
Joined: 20 Jul 2019 Posts: 1777 Location: South America
|
Posted: Fri Dec 20, 2024 1:14 am Post subject: |
|
|
FlyingBullets wrote: | Now --modules="pgp.mod gcry_sha256.mod": |
This looks like the right one. By the way, you can omit the ".mod" in this option.
FlyingBullets wrote: | Code: | error: public key 9f7aeba555c2655 not found |
|
So close... I believe this means that the fingerprint of the public key that should be used for verifying a detached signature did not match the fingerprint of the key embedded with the --pubkey option. Compare the (hexadecimal) number in the error message with the number(s) in the outputs of GRUB's list_trusted command (type it in the rescue prompt) and the gpg --fingerprint command (in the booted Gentoo). _________________
NeddySeagoon wrote: | I'm not a witch, I'm a retired electronics engineer |
Ionen wrote: | As a packager I just don't want things to get messier with weird build systems and multiple toolchains requirements though |
|
|
Back to top |
|
|
FlyingBullets n00b
Joined: 19 Mar 2024 Posts: 21
|
Posted: Fri Dec 20, 2024 4:23 pm Post subject: |
|
|
Code: | error: public key 9f7aeba555c2655 not found.
Entering rescue mode...
grub rescue> list_trusted
f289 6b1f d553 9e1e f4dd 1990 4fa1 f05c 98ea 3cb8
d11d 5954 ba3a 326b b36c d152 6167 66f3 a1cc 1df7
grub rescue> |
Code: | gpg --fingerprint
[keyboxd]
---------
pub rsa2048 2024-12-19 [SC]
26E0 257B C5D1 383D C792 D321 5526 5C55 BAAE F709
uid [ultimate] test
sub rsa2048 2024-12-19 [E]
pub rsa2048 2024-12-17 [SC]
F289 6B1F D553 9E1E F4DD 1990 4FA1 F05C 98EA 3CB8
uid [ultimate] grub_key
sub rsa2048 2024-12-17 [E] |
Strange... the F289 key is there. I think GPG might be using the wrong key when signing the stuff in /boot -- it's using the "test" key instead of the "grub_key" key.
Update: Yes, that was the issue! My script that signs everything in /boot:
Code: | for valid_file in $(find /boot -regextype -posix-extended -regex '.*(\.cfg|\.lst|\.mod|vmlinuz.*gentoo(\.old)?|init.*\.img(\.old)?|grubenv)$'); do
# Delete old signature.
[[ -f "$valid_file".sig ]] && rm "$valid_file".sig
gpg --batch --detach-sign "$valid_file"
done |
Uses gpg --batch --detach-sign "$valid_file" (does not specify what key to use).
I deleted the "test" key and re-ran my signing script: the good news is that we've moved past the error; the bad news is that we're not done yet. The GRUB error went away, but now nothing happens when the UEFI loads... I get the splash screen of the motherboard manufacturer, but it stays there as if it's frozen. I think I'm still missing one or two GRUB modules to embed.
EDIT: It was a missing module; the list of modules that work is: --modules="pgp gcry_sha256 gcry_rsa". After I made this change, GRUB complained that the microcode files were not signed (/boot/*-uc.img), so I signed those as well. FINALLY the machine booted like normal -- the GRUB menu showed up, selected the first entry, ran the kernel, and presented a login screen! The only thing left to do is actually enable secure boot in the UEFI, so I did; GRUB booted, presented the menu, selected the first entry, aaaaaaaaaaand gave me the following error:
Code: | Booting `Gentoo GNU/Linux'
Loading Linux x.y.z-gentoo ...
Loading initial ramdisk ...
error: cannot load image.
Failed to boot both default and fallback entries.
Press any key to continue... |
It kicked me back to the GRUB menu; I then manually selected the first entry several times; I got varying error messages:
Code: | Loading Linux x.y.z-gentoo ...
Loading initial ramdisk ...
error: you need to load the kernel first.
Press any key to continue... |
Code: | error: cannot load the image.
Loading Linux x.y.z-gentoo ...
Loading initial ramdisk ...
error: you need to load the kernel first.
Press any key to continue... |
|
|
Back to top |
|
|
FlyingBullets n00b
Joined: 19 Mar 2024 Posts: 21
|
Posted: Fri Dec 20, 2024 8:15 pm Post subject: |
|
|
AH I GOT IT!
Code: | dmesg | grep -i secure
[ 0.002375] [ T0] Secure boot enabled |
What you have to do is sign the kernel with the UEFI db key AND the GRUB key! More importantly, it needs to be signed with the db key first because it embeds the signature in the kernel, THEN signed with the GRUB key to make the detached signature.
So, in order to use secure boot with GRUB and custom UEFI keys:
1) Make the PK, KEK, and db private keys for the UEFI.
2) Install the 'auth' files generated from the UEFI private keys into the actual UEFI.
3) Make the GRUB key pair with GPG.
4) Extract the public key from the GRUB GPG key pair into some file "grub_public_key".
5) Make the GRUB executable with grub-install with the following options:
* --disable-shim-lock (we are not using shim)
* --pubkey=/path/to/grub_public_key (embeds the public key into the GRUB executable to check the signatures of signed files in /boot)
* --modules="XXX" (XXX is a list of the required modules needed for signature verification; in this case, it's "pgp", "gcry_sha256", and "gcry_rsa")
6) Sign all EFI files that will be used in the boot chain with the UEFI db key with sbsign; this includes the GRUB executable and any kernels.
7) Sign all
* kernels
* inramfses
* microcode
* GRUB modules, configs, environment blocks, etc
with the GRUB GPG key to create a detached signature for all of them.
I will add detailed instructions to the "Secure Boot" wiki page soon.
Thanks everyone who helped solve this issue, especially you GDH-gentoo! |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|