我正在 UEFI 中编写自己的操作系统加载程序(引导加载程序)。操作系统加载程序是 Microsoft 签名的,因此它可以在安全启动下运行。OS Loader 将能够根据用户的选择加载 Windows 或 Linux Kernel(类似于 GRUB) 因为我将 Linux Kernel 构建为 EFI Stub,所以我可以从我的 OS Loader 加载它。
但是,我有一个具体的要求。我将对 Linux 内核进行自签名。
如何建立信任链以确保我加载的是我自己的自签名 Linux 内核而不是其他未签名的内核?
根据电信公司的建议于 2022 年 1 月 21 日编辑
继续 telcoM 的回答,我从https://github.com/rhboot/shim下载了 SHIM 源,我还在https://www.rodsbooks.com/efi-bootloaders/secureboot.html#initial_shim
之后创建了 PKI 密钥
$ openssl req -new -x509 -newkey rsa:2048 -keyout MOK.key -out MOK.crt -nodes -days 3650 -subj "/CN=Your Name/"
$ openssl x509 -in MOK.crt -out MOK.cer -outform DER
使用构建的 SHIM 源
make VENDOR_CERT_FILE=MOK.cer
用 MOK.key 签署了我的 kernel.efi 以获得签署的 grubx64.efi(这是因为 SHIM 中的默认加载器是 grubx64.efi。我只是继续使用默认值)
sbsign --key MOK.key --cert MOK.crt --output grubx64.efi kernel.efi
最后,使用 shimx64.efi 作为 loader.efi (使用 PreLoader https://blog.hansenpartnership.com/linux-foundation-secure-boot-system-released/)因为目前我没有微软签署的 shimx64.efi . 此外,mmx64.efi 和 fbx64.efi 也通过 HashTool.efi 与 shimx64.efi (loader.efi) 一起注册
这是流程。
PreLoader.efi --> loader.efi(shimx64.efi) --> grubx64.efi(kernel.efi)
禁用 SecureBoot 后,一切正常,我可以启动 Linux 内核。
但是,启用 SecureBoot 后,我无法启动 grubx64.efi 映像。
进一步更新
我发现我应该使用 MokManager (mmx64.efi) 来注册 MOK.cer。尝试使用 mmx64.efi 并注册 MOK.cer。但是,看起来 Key 没有成功注册。
我错过了什么吗?
您的操作系统加载程序需要包含您将用于签署自己的内核的密钥的公共部分(也称为证书)的副本。每当该密钥发生更改时,您都需要让您的 OS Loader 由 Microsoft 重新签名。
您可能想研究
shimx64.efi
许多主要发行版用来处理安全启动的安全启动 shim 引导加载程序的源代码:https://github.com/rhboot/shim
或者,您必须将内核签名密钥的公共部分的副本添加到
db
UEFI NVRAM 变量中。通常这只有在您替换系统上的安全启动主键(PK
UEFI NVRAM 变量)时才有可能。这取决于您系统的固件实现如何(或实际上是否)可以做到这一点。常见的可能方式:
如果您的 UEFI 固件设置(“BIOS 设置”)包含直接编辑安全启动密钥库的方法,则可用于将内核签名密钥直接添加到
db
变量中。您可能必须先重置或更换PK
主键,见下文。如果您的 UEFI 固件设置不包括直接编辑安全启动密钥库的方法,但包括将
PK
安全启动的主密钥归零的方法,这足以让您入门。在Secure Boot Setup ModePK
中将 Secure Boot 的位置清零,在该模式下可以启动任何内核并且可以编辑所有 Secure Boot 密钥库。当新的安全启动主密钥(即类似于为安全启动签署内核所使用的数字证书)存储到密钥库变量时,设置模式结束。PK
在安全启动设置模式下,所有安全启动密钥库都应可由操作系统级程序编辑,例如
efivar
https://github.com/vathpela/efivar.git或sbsigntools
https://git.kernel.org/pub/scm/例如linux/kernel/git/jejb/sbsigntools.git。在实践中,这并不总是有效;它取决于系统特定固件中 UEFI 实现的属性。如果您的固件不允许通过操作系统级程序编辑安全启动密钥库,您可能会使用 UEFI 模式工具获得更好的运气,例如包
KeyTool.efi
中的: https ://git.kernel.org/pub/scm/linux/内核/git/jejb/efitools.gitefitools
(可以保护 UEFI NVRAM 变量,以便它们只能由启动时
.efi
程序访问,而不是由常规操作系统访问;我已经看到一些 UEFI 实现似乎以这种方式限制安全启动密钥库,尽管安全启动规范没有要求。)为了安全启动,您可以将您的密钥添加到“机器所有者密钥”密钥库中。Scientific Linux 过去使用以下命令来完成。
负责操作机器所有者密钥库的命令是
mokutil
.来源: http: //ftp.scientificlinux.org/linux/scientific/7.9/x86_64/release-notes/#_about_uefi_secure_boot