我正在 UEFI 中编写自己的操作系统加载程序(引导加载程序)。操作系统加载程序经过 Microsoft 签名,因此可以在安全启动下运行。操作系统加载器将能够根据用户的选择加载 Windows 或 Linux 内核(类似于 GRUB) 由于我已将 Linux 内核构建为 EFI 存根,因此我可以从操作系统加载器加载它。
但是,我有一个特定的要求。我将对 Linux 内核进行自签名。
如何建立信任链以确保我加载自己的自签名 Linux 内核而不是其他未签名的内核?
在处理 telcoM 的建议后于 2022 年 1 月 21 日编辑
继续 telcoM 的回答,我从下载了 SHIM 源代码https://github.com/rhboot/shim
我还创建了 PKI 密钥
https://www.rodsbooks.com/efi-bootloaders/secureboot.html#initial_shim
$ 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(使用PreLoaderhttps://blog.hansenpartnership.com/linux-foundation-secure-boot-system-released/)因为目前我没有 Microsoft 签名的 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 没有注册成功。
我错过了什么吗?
答案1
您的操作系统加载程序需要包含您将用来签署您自己的内核的密钥的公共部分(也称为证书)的副本。每当该密钥发生更改时,您都需要让 Microsoft 重新签名您的操作系统加载程序。
shimx64.efi
您可能想研究许多主要发行版用来处理安全启动的安全启动垫片引导加载程序的源代码:
https://github.com/rhboot/shim
或者,您必须将内核签名密钥的公共部分的副本添加到db
UEFI NVRAM 变量中。通常,只有当您替换PK
系统上的安全启动主密钥( UEFI NVRAM 变量)时,这才可能实现。这取决于您系统的固件实现方式(或者实际上如果)这是可以做到的。
常见的可能方式:
如果您的 UEFI 固件设置(“BIOS 设置”)包含直接编辑安全启动密钥库的方法,则可以使用该方法将内核签名密钥直接添加到变量中
db
。您可能必须PK
首先重置或替换主键,请参见下文。如果您的 UEFI 固件设置不包括直接编辑安全启动密钥库的方法,但包括将安全启动主密钥清零的方法
PK
,这足以帮助您入门。将PK
安全启动所在的位置清零安全启动设置模式,其中可以启动任何内核,并且可以编辑所有安全启动密钥库。当新的安全启动主密钥(即类似于为安全启动签名内核所使用的数字证书)存储到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
中的工具)获得更好的运气efitools
:https://git.kernel.org/pub/scm/linux/kernel/git/jejb/efitools.git
(可以保护 UEFI NVRAM 变量,以便它们只能由启动时.efi
程序访问,而不能由常规操作系统访问;我见过一些 UEFI 实现似乎以这种方式限制安全启动密钥库,尽管安全启动规范没有要求。)
答案2
为了安全启动,您可以将密钥添加到“机器所有者密钥”密钥库中。 Scientific Linux 过去使用以下命令来完成此操作。
cd /tmp
curl http://cacerts.digicert.com/DigiCertHighAssuranceEVRootCA.crt | openssl x509 -inform der > DigiCertEVCodeSign.pem
curl http://cacerts.digicert.com/DigiCertEVCodeSigningCA-SHA2.crt | openssl x509 -inform der >> DigiCertEVCodeSign.pem
curl http://ftp.scientificlinux.org/linux/scientific/7x/x86_64/os/SECURE-BOOT-KEY-fnal-sl7-exp-2023-09-27 | openssl x509 -inform der > SECURE-BOOT-KEY-fnal-sl7-exp-2023-09-27.pem
curl http://ftp.scientificlinux.org/linux/scientific/7x/x86_64/os/SECURE-BOOT-KEY-fnal-sl7-exp-2020-08-26 | openssl x509 -inform der > SECURE-BOOT-KEY-fnal-sl7-exp-2020-08-26.pem
curl http://ftp.scientificlinux.org/linux/scientific/7x/x86_64/os/SECURE-BOOT-KEY-fnal-sl7-exp-2017-07-26 | openssl x509 -inform der > SECURE-BOOT-KEY-fnal-sl7-exp-2017-07-26.pem
certtool -V --verify --load-ca-certificate=DigiCertEVCodeSign.pem --infile=SECURE-BOOT-KEY-fnal-sl7-exp-2023-09-27.pem
certtool -V --verify --load-ca-certificate=DigiCertEVCodeSign.pem --infile=SECURE-BOOT-KEY-fnal-sl7-exp-2020-08-26.pem
certtool -V --verify --load-ca-certificate=DigiCertEVCodeSign.pem --infile=SECURE-BOOT-KEY-fnal-sl7-exp-2017-07-26.pem
# use mokutil to import
mokutil --import /etc/pki/secure-boot/SECURE-BOOT-KEY-fnal-sl7-exp-2023-09-27
负责操作机器所有者密钥库的命令是mokutil
。
来源:http://ftp.scientificlinux.org/linux/scientific/7.9/x86_64/release-notes/#_about_uefi_secure_boot