Rework handling of the Secure Boot keys and certificates

We now need the official shim vendor certificate present in the SDK when
building the kernel so that it can be inserted and used to verify the
verity root hash and signed sysexts.

While we're at it, copy the official signing certificate from Azure Key
Vault so that we don't need to fetch it every time, simplifying the
signing code.

This change also partly deals with the eventual expiration of our shim
vendor certificate. We cannot simply replace the shim with one
containing just the new certificate because it needs to be able to boot
kernels from older releases. We therefore now keep all the certificates
in the coreos-sb-keys package as separate dated PEM files that then get
combined into a single DER ESL that the shim build expects. Note that
the shim does not check certificate expiry dates. It is therefore also
no longer necessary to manually convert the certificate to DER format.
The problem of actually upgrading the shim on user systems remains.

Each certificate in the DER ESL requires an owner GUID. We previous used
a zero GUID for the DB certificates, but these were only used for
testing. I have therefore now generated a static GUID for Flatcar that
we should use going forwards.

Signed-off-by: James Le Cuirot <jlecuirot@microsoft.com>
This commit is contained in:
James Le Cuirot 2025-05-30 21:02:18 +01:00
parent 382c879bb6
commit e6e2383bf7
No known key found for this signature in database
GPG Key ID: 1226415D00DD3137
16 changed files with 160 additions and 133 deletions

View File

@ -797,7 +797,6 @@ EOF
# calculated. Only for unofficial builds as official builds get signed later.
if [[ ${COREOS_OFFICIAL:-0} -ne 1 ]]; then
do_sbsign --output "${root_fs_dir}/boot/flatcar/vmlinuz-a"{,}
cleanup_sbsign_certs
fi
if [[ -n "${image_kernel}" ]]; then
@ -904,7 +903,7 @@ sbsign_image() {
"${BUILD_LIBRARY_DIR}/disk_util" --disk_layout="${disk_layout}" \
mount "${disk_img}" "${root_fs_dir}"
trap "cleanup_mounts '${root_fs_dir}'; cleanup_sbsign_certs" EXIT
trap "cleanup_mounts '${root_fs_dir}'" EXIT
# Sign the kernel with the shim-embedded key.
do_sbsign --output "${root_fs_dir}/boot/flatcar/vmlinuz-a"{,}
@ -934,7 +933,6 @@ sbsign_image() {
fi
cleanup_mounts "${root_fs_dir}"
cleanup_sbsign_certs
trap - EXIT
if [[ -n "${pcr_policy}" ]]; then

View File

@ -90,7 +90,6 @@ ESP_DIR=
LOOP_DEV=
cleanup() {
cleanup_sbsign_certs
if [[ -d "${ESP_DIR}" ]]; then
if mountpoint -q "${ESP_DIR}"; then
sudo umount "${ESP_DIR}"
@ -200,8 +199,8 @@ case "${FLAGS_target}" in
# Unofficial build: Sign shim with our development key.
sudo sbsign \
--key /usr/share/sb_keys/DB.key \
--cert /usr/share/sb_keys/DB.crt \
--key /usr/share/sb_keys/unofficial/DB.key \
--cert /usr/share/sb_keys/unofficial/DB.pem \
--output "${ESP_DIR}/EFI/boot/boot${EFI_ARCH}.efi" \
"${BOARD_ROOT}/usr/lib/shim/shim${EFI_ARCH}.efi"
else

View File

@ -3,44 +3,23 @@
# found in the LICENSE file.
if [[ ${COREOS_OFFICIAL:-0} -ne 1 ]]; then
SBSIGN_KEY="/usr/share/sb_keys/shim.key"
SBSIGN_CERT="/usr/share/sb_keys/shim.pem"
SBSIGN_KEY="/usr/share/sb_keys/unofficial/shim.key"
SBSIGN_CERT="/usr/share/sb_keys/unofficial/shim.pem"
else
SBSIGN_KEY="pkcs11:token=flatcar-sb-dev-hsm-sign-2025"
unset SBSIGN_CERT
SBSIGN_CERT="/usr/share/sb_keys/official/signing.pem"
fi
PKCS11_MODULE_PATH="/usr/$(get_sdk_libdir)/pkcs11/azure-keyvault-pkcs11.so"
PKCS11_MODULE_PATH="$(pkg-config p11-kit-1 --variable p11_module_path)/azure-keyvault-pkcs11.so"
PKCS11_ENV=(
AZURE_CORE_COLLECT_TELEMETRY=no
AZURE_KEYVAULT_URL="https://flatcar-sb-dev-kv.vault.azure.net/"
PKCS11_MODULE_PATH="${PKCS11_MODULE_PATH}"
AZURE_KEYVAULT_PKCS11_DEBUG=1
)
get_sbsign_cert() {
if [[ ${SBSIGN_KEY} != pkcs11:* || -s ${SBSIGN_CERT-} ]]; then
return
fi
SBSIGN_CERT=$(mktemp -t signing-cert.XXXXXXXXXX.pem)
info "Fetching ${SBSIGN_KEY} from Azure"
# Needs Key Vault Reader role.
env "${PKCS11_ENV[@]}" p11-kit export-object \
--provider "${PKCS11_MODULE_PATH}" \
"${SBSIGN_KEY};type=cert" \
| tee "${SBSIGN_CERT}"
}
cleanup_sbsign_certs() {
if [[ ${SBSIGN_CERT-} == "${TMPDIR-/tmp}"/* ]]; then
rm -f -- "${SBSIGN_CERT}"
fi
}
do_sbsign() {
get_sbsign_cert
info "Signing ${@:$#} with ${SBSIGN_KEY}"
if [[ ${SBSIGN_KEY} == pkcs11:* ]]; then

View File

@ -863,7 +863,7 @@ _write_qemu_uefi_secure_conf() {
local flash_rw="$(_dst_name "_efi_vars.qcow2")"
local flash_ro="$(_dst_name "_efi_code.qcow2")"
local script="$(_dst_dir)/$(_dst_name ".sh")"
local owner="00000000-0000-0000-0000-000000000000"
local owner=$(</usr/share/sb_keys/owner.txt)
local flash_in
_write_qemu_uefi_conf
@ -886,7 +886,7 @@ _write_qemu_uefi_secure_conf() {
virt-fw-vars \
--input "${flash_in}" \
--output "$(_dst_dir)/${flash_rw}" \
--add-db "${owner}" /usr/share/sb_keys/DB.crt \
--add-db "${owner}" /usr/share/sb_keys/unofficial/DB.pem \
--add-db "${owner}" "${BUILD_LIBRARY_DIR}/flatcar-sb-dev-shim-2025.cert"
sed -e "s%^SECURE_BOOT=.*%SECURE_BOOT=1%" -i "${script}"

View File

@ -12,5 +12,4 @@ Generate the our shim certificates:
```
openssl genrsa -out "shim.key" 2048
openssl req -new -x509 -sha256 -subj "/CN=shim/" -key "shim.key" -out "shim.pem" -days 7300
openssl x509 -in "shim.pem" -inform PEM -out "shim.der" -outform DER
```

View File

@ -1,26 +0,0 @@
# Copyright (c) 2015 CoreOS Inc.
# Copyright (c) 2024 The Flatcar Maintainers.
# Distributed under the terms of the GNU General Public License v2
EAPI=8
DESCRIPTION="Flatcar Secure Boot keys"
HOMEPAGE=""
SRC_URI=""
LICENSE="BSD"
SLOT="0"
KEYWORDS="amd64 arm64"
IUSE=""
S="${WORKDIR}"
src_install() {
insinto /usr/share/sb_keys
newins "${FILESDIR}/DB.key" DB.key
newins "${FILESDIR}/DB.crt" DB.crt
# shim keys
newins "${FILESDIR}/shim.key" shim.key
newins "${FILESDIR}/shim.der" shim.der
newins "${FILESDIR}/shim.pem" shim.pem
}

View File

@ -0,0 +1,60 @@
# Copyright (c) 2015 CoreOS Inc.
# Copyright (c) 2024 The Flatcar Maintainers.
# Distributed under the terms of the GNU General Public License v2
EAPI=8
DESCRIPTION="Flatcar Secure Boot keys"
HOMEPAGE="https://www.flatcar.org/"
S="${WORKDIR}"
LICENSE="BSD"
SLOT="0"
KEYWORDS="amd64 arm64"
BDEPEND="
app-emulation/virt-firmware
dev-libs/openssl
"
# Arbitrary value created for Flatcar.
OWNER_GUID="4a974879-bf65-4eb8-b404-ac3a6141121e"
src_compile() {
local TYPE
for TYPE in unofficial official; do
mkdir "${TYPE}" || die
# Gather all the shim vendor PEM certs into an array.
local FILES=( "${FILESDIR}/${TYPE}"/shim-*.pem )
# Rewrite the newest shim vendor PEM cert in a consistent PEM format,
# checking its validity. Only the newest is needed in PEM format for
# inserting into the kernel to verify the verity root hash at boot time.
openssl x509 -in "${FILES[-1]}" -inform PEM -out "${TYPE}"/shim.pem || die
local ARGS=() FILE
for FILE in "${FILES[@]}"; do
# Add each shim vendor PEM cert to the DER ESL creation below.
ARGS+=( --add-cert "${OWNER_GUID}" "${FILE}" )
done
# This ingests shim vendor PEM certs and outputs a combined DER ESL.
virt-fw-sigdb "${ARGS[@]}" --output "${TYPE}"/shim.esl || die
done
# Rewrite the official signing PEM cert in a consistent PEM format, checking
# its validity. Only the newest is needed in PEM format to sign the
# bootloader and the kernel image. Unofficial builds are already covered
# above because the shim vendor cert /is/ the signing cert, not a CA.
openssl x509 -in "${FILESDIR}"/official/signing.pem -inform PEM -out official/signing.pem || die
}
src_install() {
insinto /usr/share/sb_keys
newins - owner.txt <<< "${OWNER_GUID}"
doins -r unofficial official
insinto /usr/share/sb_keys/unofficial
doins "${FILESDIR}"/unofficial/{DB.{key,pem},shim.key}
}

View File

@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDaDCCAlCgAwIBAgIRAINN27bWbE7vq1xOCROIuyMwDQYJKoZIhvcNAQELBQAw
PTE7MDkGA1UEAxMyRmxhdGNhciBDb250YWluZXIgTGludXggU2VjdXJlIEJvb3Qg
RGV2ZWxvcG1lbnQgQ0EwHhcNMjQxMTA3MTkwMjIyWhcNMzcwMTE5MDMxNDA3WjA9
MTswOQYDVQQDEzJGbGF0Y2FyIENvbnRhaW5lciBMaW51eCBTZWN1cmUgQm9vdCBE
ZXZlbG9wbWVudCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ5q
pvNmeh7nGFp5k4WnsOnBct1DtRcgCPbKVNOs6tvmSiygkrnw4l6mR2FJr7JPl5IE
IDttPQnotGYjKJhhEkYIcLUn91w8UAuq68iKfHcr3RKfD0u3ZzxqXzGrPaIcqbGl
GQwFxtoFxwf8MOskyM3R1zIKKYKABpEZj8Nq7Y/1tYdqip63KygJ4NGs+qYkaPcX
TlCh2rSZsc39kiGdASzHn0LsSU4IFFSLUQvNOO3DXwI0RCOrvl4KoyXtPRB33dUN
H80A/bPXUe67GBhlZyzctJ+YDSXzkPZftlAgMB/+/rtxHCSJXgGFmm5smICW4yRT
byKpnlp5apcc4x2TbQUCAwEAAaNjMGEwHwYDVR0jBBgwFoAUbfTa4PZ82LTaSzln
iD0LyFf+h7AwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
BBYEFG302uD2fNi02ks5Z4g9C8hX/oewMA0GCSqGSIb3DQEBCwUAA4IBAQBPx4C1
z5/eVwMTaDT2zo1qe+pqscMjZ1+TClQ+wK33tkHrvzfHtDnjgPDEM/rpHKucSoeS
xAdFlXqnJja0MEWdCh4503/KWOxl4quQdQclVFlV6A6/f8kbCB2hzb2k5NMUPE2b
Vg+wTOd22dm7HSeCsxkvAbtAQPDXLaBJ6dxGS7KEk3akHHIYqBSBbXEuhjgIcdJ2
5mzUCAXJEpZ1J/nqQZsZD+Ugp7iMB3JV9xC01JNWMuMlGoeI1F6orssR6jU3aCjk
jZjSnyqDINcqddkevpYWg+ffvg3ewQ4lMcFPwjGDxqPOCPZmAw/l7xd6LqFTq//C
iAQ/ssvyzfqSgqWN
-----END CERTIFICATE-----

View File

@ -0,0 +1,25 @@
-----BEGIN CERTIFICATE-----
MIIELTCCAxWgAwIBAgICCSkwDQYJKoZIhvcNAQELBQAwPTE7MDkGA1UEAxMyRmxh
dGNhciBDb250YWluZXIgTGludXggU2VjdXJlIEJvb3QgRGV2ZWxvcG1lbnQgQ0Ew
HhcNMjUwMzIwMTE0ODIyWhcNMjgwMzIwMTE0ODIyWjBCMUAwPgYDVQQDEzdGbGF0
Y2FyIENvbnRhaW5lciBMaW51eCBTZWN1cmUgQm9vdCBEZXZlbG9wbWVudCBTaWdu
aW5nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAi4DQeJdbATc+6bXu
fC45iOj+fuA9p/L7WvY0FoT4ohmynoaYgBzUXMV333H7Pzy1qknZ1Kz8A8c8nlp0
BQOr0cnvoJhPt2lOP7EofCdylOBOfWPqP9l73pATp2/jJnUi+288eSTHBX6GgLqk
PYceTjIxQWP6OzjP94ZCOBQnB6Ib4TaMbuylkz7vrog1JMPoGOdrSmZvaWqHebx5
GaPwNOQzJAw6d4rFrphqso51r/Q4vxps+fMQZoJAMP4xT1SCIQO1kFt+3Q6MFi3m
ztte5Y/Q46IvKEZaWU8K5umFnBaOWCDeFelV268TsvyrBBrCBB4Q5ooo2NiZESh4
7fS1lT3Jcr8Unw3b2E91Y/hmGRDwrC+yp+7f51gRC3UIP5AsF1oX/nF+kD+mrhhg
3gPtCXdx88ttaJBdOCMfdgoONvY8Yl1WlbjbC5pCEMK3/gV5SGCbvlAaqBkh6gvY
dsFKMCbSHg/eD6PS3bgRtfcb1jCsIXGrzJRVi/Fgu0u9D9UylNkGkrvHQ0r1ffKM
O7hlgooo9SLloU+4MLMHCujOQo978XIdsYy2DCiRQdD33LXEgQMGEcZvENIXkmFU
Iujq32PMKc31P84JPGzyeUN3VkdUPww4HRwEcsfUFJ8b4xEEmAUi/+zqz5XCo3m1
nh62zX/ByIyCmY56rgWFWmSON4UCAwEAAaMyMDAwCQYDVR0TBAIwADATBgNVHSUE
DDAKBggrBgEFBQcDAzAOBgNVHQ8BAf8EBAMCBaAwDQYJKoZIhvcNAQELBQADggEB
AGKZATREaf6bdjfYmrM0cKwlPcd9Bo95gX/uucRzLmAvgo5KftgFABhqNxQeb6g2
mkz9EKCtYt8WPH7j914yXQLLes/nrqARPIV2n0IP5SxRDmDxhSl3jhStp97idGvv
zS07tM7oHqPycwitfrJl0kbrIYXr5f2PyG2kANjPgoYHcl5KLnffv95XSokNhWFK
17asGpHUrtOlOJm1mCgjpmiotYgMIGtKFMiKB8yFQRFRnyMb7uowkq/G9btDjW/7
kVJwppmwXXL5qiAAzvFQcbBbWmiIwVXjb8OLO43dsB0znt+IMDf7itUiUCLSOjqQ
z3S4t9QNWU6jp0RBwEQfI6g=
-----END CERTIFICATE-----

View File

@ -1,72 +0,0 @@
# Copyright 2015 CoreOS, Inc.
# Distributed under the terms of the GNU General Public License v2
EAPI=7
inherit multilib
DESCRIPTION="UEFI Shim loader"
HOMEPAGE="https://github.com/rhboot/shim"
SRC_URI="https://github.com/rhboot/shim/releases/download/${PV}/shim-${PV}.tar.bz2"
KEYWORDS="amd64 arm64"
LICENSE="BSD"
SLOT="0"
IUSE="official"
RDEPEND=""
# TODO: Would be ideal to depend on sys-boot/gnu-efi package, but
# currently the shim insists on using the bundled copy. This will need
# to be addressed by patching this check out after making sure that
# our copy of gnu-efi is as usable as the bundled one.
DEPEND="
dev-libs/openssl
coreos-base/coreos-sb-keys
"
PATCHES=(
"${FILESDIR}/0001-Fix-parallel-build-of-gnu-efi.patch"
)
src_compile() {
local emake_args=(
CROSS_COMPILE="${CHOST}-"
)
sed -e "s/@@VERSION@@/${PVR}/" "${FILESDIR}"/sbat.csv.in >"${WORKDIR}/sbat.csv" || die
# Apparently our environment already has the ARCH variable in
# it, and Makefile picks it up instead of figuring it out
# itself with the compiler -dumpmachine flag. But also it
# expects a different format of the values. It wants x86_64
# instead of amd64, and aarch64 instead of arm64.
if use amd64; then
emake_args+=( ARCH=x86_64 )
elif use arm64; then
emake_args+=( ARCH=aarch64 )
fi
emake_args+=( ENABLE_SBSIGN=1 )
emake_args+=( SBATPATH="${WORKDIR}/sbat.csv" )
if use official; then
if [ -z "${SHIM_SIGNING_CERTIFICATE}" ]; then
die "use production flag needs env SHIM_SIGNING_CERTIFICATE"
fi
emake_args+=( VENDOR_CERT_FILE="${SHIM_SIGNING_CERTIFICATE}" )
else
emake_args+=( VENDOR_CERT_FILE="/usr/share/sb_keys/shim.der" )
fi
emake "${emake_args[@]}" || die
}
src_install() {
local suffix
suffix=''
if use amd64; then
suffix=x64
elif use arm64; then
suffix=aa64
fi
insinto /usr/lib/shim
newins "shim${suffix}.efi" "shim${suffix}.efi"
newins "mm${suffix}.efi" "mm${suffix}.efi"
}

View File

@ -0,0 +1,44 @@
# Copyright 2015 CoreOS, Inc.
# Distributed under the terms of the GNU General Public License v2
EAPI=8
DESCRIPTION="UEFI Shim loader"
HOMEPAGE="https://github.com/rhboot/shim"
SRC_URI="https://github.com/rhboot/shim/releases/download/${PV}/shim-${PV}.tar.bz2"
KEYWORDS="amd64 arm64"
LICENSE="BSD"
SLOT="0"
IUSE="official"
# TODO: Would be ideal to depend on sys-boot/gnu-efi package, but
# currently the shim insists on using the bundled copy. This will need
# to be addressed by patching this check out after making sure that
# our copy of gnu-efi is as usable as the bundled one.
DEPEND="
dev-libs/openssl
"
BDEPEND="
coreos-base/coreos-sb-keys
"
PATCHES=(
"${FILESDIR}/0001-Fix-parallel-build-of-gnu-efi.patch"
)
src_compile() {
sed -e "s/@@VERSION@@/${PVR}/" "${FILESDIR}"/sbat.csv.in >"${WORKDIR}/sbat.csv" || die
unset ARCH
emake \
CROSS_COMPILE="${CHOST}-" \
ENABLE_SBSIGN=1 \
SBATPATH="${WORKDIR}"/sbat.csv \
VENDOR_DB_FILE="${BROOT}"/usr/share/sb_keys/$(usex official official unofficial)/shim.esl
}
src_install() {
insinto /usr/lib/shim
doins shim?*.efi mm?*.efi
}