Skip to content

Commit

Permalink
Merge pull request #2441 from flatcar/chewi/akv-signing
Browse files Browse the repository at this point in the history
Add (temporary) signed shim and sign official builds with Azure Key Vault
  • Loading branch information
chewi authored Nov 14, 2024
2 parents 7166dbd + 58b7eac commit 8599de5
Show file tree
Hide file tree
Showing 49 changed files with 1,838 additions and 190 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/portage-stable-packages-list
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ app-crypt/libb2
app-crypt/libmd
app-crypt/mhash
app-crypt/mit-krb5
app-crypt/p11-kit
app-crypt/pinentry
app-crypt/rhash
app-crypt/shash
Expand Down Expand Up @@ -188,6 +189,10 @@ dev-build/meson-format-array
dev-build/ninja

dev-cpp/abseil-cpp
dev-cpp/azure-core
dev-cpp/azure-identity
dev-cpp/azure-security-keyvault-certificates
dev-cpp/azure-security-keyvault-keys
dev-cpp/gflags
dev-cpp/glog
dev-cpp/gtest
Expand Down
11 changes: 4 additions & 7 deletions build_library/build_image_util.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ BUILD_DIR="${FLAGS_output_root}/${BOARD}/${IMAGE_SUBDIR}"
OUTSIDE_OUTPUT_DIR="../build/images/${BOARD}/${IMAGE_SUBDIR}"

source "${BUILD_LIBRARY_DIR}/reports_util.sh" || exit 1
source "${BUILD_LIBRARY_DIR}/sbsign_util.sh" || exit 1

set_build_symlinks() {
local build=$(basename ${BUILD_DIR})
Expand Down Expand Up @@ -826,13 +827,9 @@ EOF
fi

# Sign the kernel after /usr is in a consistent state and verity is calculated
if [[ ${COREOS_OFFICIAL:-0} -ne 1 ]]; then
sudo sbsign --key /usr/share/sb_keys/shim.key \
--cert /usr/share/sb_keys/shim.pem \
"${root_fs_dir}/boot/flatcar/vmlinuz-a"
sudo mv "${root_fs_dir}/boot/flatcar/vmlinuz-a.signed" \
"${root_fs_dir}/boot/flatcar/vmlinuz-a"
fi
[[ ${COREOS_OFFICIAL:-0} -ne 1 ]] && \
do_sbsign --output "${root_fs_dir}/boot/flatcar/vmlinuz-a"{,}
cleanup_sbsign_certs

if [[ -n "${image_kernel}" ]]; then
# copying kernel from vfat so ignore the permissions
Expand Down
148 changes: 60 additions & 88 deletions build_library/grub_install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,56 +35,49 @@ switch_to_strict_mode
# must be sourced after flags are parsed.
. "${BUILD_LIBRARY_DIR}/toolchain_util.sh" || exit 1
. "${BUILD_LIBRARY_DIR}/board_options.sh" || exit 1
. "${BUILD_LIBRARY_DIR}/sbsign_util.sh" || exit 1

# Our GRUB lives under flatcar/grub so new pygrub versions cannot find grub.cfg
GRUB_DIR="flatcar/grub/${FLAGS_target}"

# GRUB install location inside the SDK
GRUB_SRC="/usr/lib/grub/${FLAGS_target}"

# Modules required to boot a standard CoreOS configuration
CORE_MODULES=( normal search test fat part_gpt search_fs_uuid gzio search_part_label terminal gptprio configfile memdisk tar echo read btrfs )

# Name of the core image, depends on target
CORE_NAME=

# Whether the SDK's grub or the board root's grub is used. Once amd64 is
# fixed up the board root's grub will always be used.
BOARD_GRUB=1

SBAT_ARG=()

case "${FLAGS_target}" in
i386-pc)
CORE_MODULES+=( biosdisk serial )
CORE_NAME="core.img"
;;
x86_64-efi)
CORE_MODULES+=( serial linux efi_gop efinet pgp http tftp tpm )
CORE_NAME="core.efi"
SBAT_ARG=( --sbat "${BOARD_ROOT}/usr/share/grub/sbat.csv" )
;;
x86_64-xen)
CORE_NAME="core.elf"
EFI_ARCH="x64"
;;
arm64-efi)
EFI_ARCH="aa64"
;;
esac

case "${FLAGS_target}" in
x86_64-efi|arm64-efi)
GRUB_IMAGE="EFI/boot/grub${EFI_ARCH}.efi"
CORE_MODULES+=( serial linux efi_gop efinet pgp http tftp tpm )
CORE_NAME="core.efi"
BOARD_GRUB=1
SBAT_ARG=( --sbat "${BOARD_ROOT}/usr/share/grub/sbat.csv" )
;;
i386-pc)
GRUB_IMAGE="${GRUB_DIR}/core.img"
CORE_MODULES+=( biosdisk serial )
;;
x86_64-xen)
GRUB_IMAGE="xen/pvboot-x86_64.elf"
;;
*)
die_notrace "Unknown GRUB target ${FLAGS_target}"
;;
esac

if [[ $BOARD_GRUB -eq 1 ]]; then
info "Updating GRUB in ${BOARD_ROOT}"
emerge-${BOARD} \
--nodeps --select --verbose --update --getbinpkg --usepkgonly --newuse \
sys-boot/grub
GRUB_SRC="${BOARD_ROOT}/usr/lib/grub/${FLAGS_target}"
fi
info "Updating GRUB in ${BOARD_ROOT}"
emerge-${BOARD} \
--nodeps --select --verbose --update --getbinpkg --usepkgonly --newuse \
sys-boot/grub

GRUB_SRC="${BOARD_ROOT}/usr/lib/grub/${FLAGS_target}"
[[ -d "${GRUB_SRC}" ]] || die "GRUB not installed at ${GRUB_SRC}"

# In order for grub-setup-bios to properly detect the layout of the disk
Expand All @@ -97,6 +90,7 @@ ESP_DIR=
LOOP_DEV=

cleanup() {
cleanup_sbsign_certs
if [[ -d "${ESP_DIR}" ]]; then
if mountpoint -q "${ESP_DIR}"; then
sudo umount "${ESP_DIR}"
Expand Down Expand Up @@ -130,7 +124,7 @@ done
if [[ -z ${MOUNTED} ]]; then
failboat "${LOOP_DEV}p1 where art thou? udev has forsaken us!"
fi
sudo mkdir -p "${ESP_DIR}/${GRUB_DIR}"
sudo mkdir -p "${ESP_DIR}/${GRUB_DIR}" "${ESP_DIR}/${GRUB_IMAGE%/*}"

info "Compressing modules in ${GRUB_DIR}"
for file in "${GRUB_SRC}"/*{.lst,.mod}; do
Expand Down Expand Up @@ -172,15 +166,15 @@ if [[ ! -f "${ESP_DIR}/flatcar/grub/grub.cfg.tar" ]]; then
-C "${GRUB_TEMP_DIR}" "grub.cfg"
fi

info "Generating ${GRUB_DIR}/${CORE_NAME}"
info "Generating ${GRUB_IMAGE}"
sudo grub-mkimage \
--compression=auto \
--format "${FLAGS_target}" \
--directory "${GRUB_SRC}" \
--config "${ESP_DIR}/${GRUB_DIR}/load.cfg" \
--memdisk "${ESP_DIR}/flatcar/grub/grub.cfg.tar" \
"${SBAT_ARG[@]}" \
--output "${ESP_DIR}/${GRUB_DIR}/${CORE_NAME}" \
--output "${ESP_DIR}/${GRUB_IMAGE}" \
"${CORE_MODULES[@]}"

for mod in "${CORE_MODULES[@]}"; do
Expand All @@ -189,77 +183,55 @@ done

# Now target specific steps to make the system bootable
case "${FLAGS_target}" in
i386-pc)
info "Installing MBR and the BIOS Boot partition."
sudo cp "${GRUB_SRC}/boot.img" "${ESP_DIR}/${GRUB_DIR}"
sudo grub-bios-setup --device-map=/dev/null \
--directory="${ESP_DIR}/${GRUB_DIR}" "${LOOP_DEV}"
# boot.img gets manipulated by grub-bios-setup so it alone isn't
# sufficient to restore the MBR boot code if it gets corrupted.
sudo dd bs=448 count=1 status=none if="${LOOP_DEV}" \
of="${ESP_DIR}/${GRUB_DIR}/mbr.bin"
;;
x86_64-efi)
info "Installing default x86_64 UEFI bootloader."
sudo mkdir -p "${ESP_DIR}/EFI/boot"
# Use the test keys for signing unofficial builds
if [[ ${COREOS_OFFICIAL:-0} -ne 1 ]]; then
# Sign the GRUB with the shim-embedded key
sudo sbsign --key /usr/share/sb_keys/shim.key \
--cert /usr/share/sb_keys/shim.pem \
"${ESP_DIR}/${GRUB_DIR}/${CORE_NAME}"
sudo mv "${ESP_DIR}/${GRUB_DIR}/${CORE_NAME}.signed" \
"${ESP_DIR}/EFI/boot/grubx64.efi"
sudo rm "${ESP_DIR}/${GRUB_DIR}/${CORE_NAME}"
# Sign the mokmanager(mm) with the shim-embedded key
sudo sbsign --key /usr/share/sb_keys/shim.key \
--cert /usr/share/sb_keys/shim.pem \
"/usr/lib/shim/mmx64.efi"
sudo cp "/usr/lib/shim/mmx64.efi.signed" \
"${ESP_DIR}/EFI/boot/mmx64.efi"
x86_64-efi|arm64-efi)
info "Installing default ${FLAGS_target} UEFI bootloader."

sudo sbsign --key /usr/share/sb_keys/DB.key \
if [[ ${COREOS_OFFICIAL:-0} -ne 1 ]]; then
# Sign GRUB and mokmanager(mm) with the shim-embedded key.
do_sbsign --output "${ESP_DIR}/${GRUB_IMAGE}"{,}
do_sbsign --output "${ESP_DIR}/EFI/boot/mm${EFI_ARCH}.efi" \
"${BOARD_ROOT}/usr/lib/shim/mm${EFI_ARCH}.efi"

# Unofficial build: Sign shim with our development key.
sudo sbsign \
--key /usr/share/sb_keys/DB.key \
--cert /usr/share/sb_keys/DB.crt \
--output "${ESP_DIR}/EFI/boot/bootx64.efi" \
"/usr/lib/shim/shim.efi"
--output "${ESP_DIR}/EFI/boot/boot${EFI_ARCH}.efi" \
"${BOARD_ROOT}/usr/lib/shim/shim${EFI_ARCH}.efi"
else
sudo mv "${ESP_DIR}/${GRUB_DIR}/${CORE_NAME}" \
"${ESP_DIR}/EFI/boot/grubx64.efi"
sudo cp "/usr/lib/shim/shim.efi" \
"${ESP_DIR}/EFI/boot/bootx64.efi"
sudo cp "/usr/lib/shim/mmx64.efi" \
"${ESP_DIR}/EFI/boot/mmx64.efi"
# Official build: Copy the unsigned files.
sudo cp "${BOARD_ROOT}/usr/lib/shim/mm${EFI_ARCH}.efi" \
"${ESP_DIR}/EFI/boot/mm${EFI_ARCH}.efi"
sudo cp "${BOARD_ROOT}/usr/lib/shim/shim${EFI_ARCH}.efi" \
"${ESP_DIR}/EFI/boot/boot${EFI_ARCH}.efi"
fi

# copying from vfat so ignore permissions
if [[ -n "${FLAGS_copy_efi_grub}" ]]; then
cp --no-preserve=mode "${ESP_DIR}/EFI/boot/grubx64.efi" \
if [[ -n ${FLAGS_copy_efi_grub} ]]; then
cp --no-preserve=mode "${ESP_DIR}/${GRUB_IMAGE}" \
"${FLAGS_copy_efi_grub}"
fi
if [[ -n "${FLAGS_copy_shim}" ]]; then
cp --no-preserve=mode "${ESP_DIR}/EFI/boot/bootx64.efi" \
if [[ -n ${FLAGS_copy_shim} ]]; then
cp --no-preserve=mode "${ESP_DIR}/EFI/boot/boot${EFI_ARCH}.efi" \
"${FLAGS_copy_shim}"
fi
;;
i386-pc)
info "Installing MBR and the BIOS Boot partition."
sudo cp "${GRUB_SRC}/boot.img" "${ESP_DIR}/${GRUB_DIR}"
sudo grub-bios-setup --device-map=/dev/null \
--directory="${ESP_DIR}/${GRUB_DIR}" "${LOOP_DEV}"
# boot.img gets manipulated by grub-bios-setup so it alone isn't
# sufficient to restore the MBR boot code if it gets corrupted.
sudo dd bs=448 count=1 status=none if="${LOOP_DEV}" \
of="${ESP_DIR}/${GRUB_DIR}/mbr.bin"
;;
x86_64-xen)
info "Installing default x86_64 Xen bootloader."
sudo mkdir -p "${ESP_DIR}/xen" "${ESP_DIR}/boot/grub"
sudo mv "${ESP_DIR}/${GRUB_DIR}/${CORE_NAME}" \
"${ESP_DIR}/xen/pvboot-x86_64.elf"
sudo mkdir -p "${ESP_DIR}/boot/grub"
sudo cp "${BUILD_LIBRARY_DIR}/menu.lst" \
"${ESP_DIR}/boot/grub/menu.lst"
;;
arm64-efi)
info "Installing default arm64 UEFI bootloader."
sudo mkdir -p "${ESP_DIR}/EFI/boot"
#FIXME(andrejro): shim not ported to aarch64
sudo mv "${ESP_DIR}/${GRUB_DIR}/${CORE_NAME}" \
"${ESP_DIR}/EFI/boot/bootaa64.efi"
if [[ -n "${FLAGS_copy_efi_grub}" ]]; then
# copying from vfat so ignore permissions
cp --no-preserve=mode "${ESP_DIR}/EFI/boot/bootaa64.efi" \
"${FLAGS_copy_efi_grub}"
fi
;;
esac

cleanup
Expand Down
55 changes: 55 additions & 0 deletions build_library/sbsign_util.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Copyright (c) 2024 The Flatcar Maintainers.
# Use of this source code is governed by a BSD-style license that can be
# 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"
else
SBSIGN_KEY="pkcs11:token=flatcar-dev-cert"
unset SBSIGN_CERT
fi

PKCS11_MODULE_PATH="/usr/$(get_sdk_libdir)/pkcs11/azure_kms_pkcs11.so"

PKCS11_ENV=(
AZURE_KEYVAULT_URL="https://chewi-test.vault.azure.net/"
PKCS11_MODULE_PATH="${PKCS11_MODULE_PATH}"
AWS_KMS_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
set -- --engine pkcs11 "${@}"
fi

# Needs Key Vault Crypto User role.
sudo env "${PKCS11_ENV[@]}" sbsign \
--key "${SBSIGN_KEY}" \
--cert "${SBSIGN_CERT}" \
"${@}"
}
2 changes: 1 addition & 1 deletion ci-automation/vendor-testing/qemu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ SECUREBOOT=""
ovmf_vars=""

# ARM64 qemu tests only supported on UEFI
if [ "${CIA_ARCH}" = "arm64" ] && [ "${CIA_TESTSCRIPT}" != "qemu_uefi.sh" ] ; then
if [[ ${CIA_ARCH} == arm64 && ${CIA_TESTSCRIPT} != qemu_uefi*.sh ]] ; then
echo "1..1" > "${CIA_TAPFILE}"
echo "not ok - all qemu tests" >> "${CIA_TAPFILE}"
echo " ---" >> "${CIA_TAPFILE}"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DIST azure-keyvault-pkcs11-0_p20240923.tar.gz 23626 BLAKE2B 54be12edd44c7bc59c58d11ad02632d2717a7d83b19ac8d5ac70cddd5e9c2db0a41b332e82cec0467494f934f75c7fc94c336f452bc5c77ad80cea591009bfe8 SHA512 470157d672c9eac35d0026b0c8413c056bd600fff300d64a3bf2d0e218bb9e09c677e649bbe221ad60b937116676218c25f764641a5f4c709c62d9f1336a3e68
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright 1999-2024 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

EAPI=8

inherit cmake

COMMIT="7b0ca93ad046adad807ac1a6e2c56ea87c7a78ec"
DESCRIPTION="PKCS#11 module for Azure Key Vault"
HOMEPAGE="https://github.com/jepio/azure_keyvault_pkcs11"
SRC_URI="https://github.com/jepio/azure_keyvault_pkcs11/archive/${COMMIT}.tar.gz -> ${P}.tar.gz"
S="${WORKDIR}/${PN}-${COMMIT}"
LICENSE="MIT"
SLOT="0"
KEYWORDS="~amd64"

# libcurl is only NEEDED because of the Azure SDK.
RDEPEND="
dev-cpp/azure-core:=
dev-cpp/azure-identity:=
dev-cpp/azure-security-keyvault-certificates:=
dev-cpp/azure-security-keyvault-keys:=
dev-libs/json-c:=
dev-libs/openssl:=
"
DEPEND="
${RDEPEND}
app-crypt/p11-kit
"
BDEPEND="
virtual/pkgconfig
"
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
<pkgmetadata>
<maintainer type="person">
<email>[email protected]</email>
<name>James Le Cuirot</name>
</maintainer>
<upstream>
<remote-id type="github">jepio/azure_keyvault_pkcs11</remote-id>
</upstream>
</pkgmetadata>

This file was deleted.

This file was deleted.

Loading

0 comments on commit 8599de5

Please sign in to comment.