Skip to content

Commit b3183b4

Browse files
committed
Do SB signing for official builds in a separate additional job
We only want to do the signing in Azure, not the whole image job. This new job downloads the unsigned image, signs it, and replaces it. Signed-off-by: James Le Cuirot <[email protected]>
1 parent 260426a commit b3183b4

File tree

5 files changed

+269
-6
lines changed

5 files changed

+269
-6
lines changed

build_library/build_image_util.sh

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -791,10 +791,12 @@ EOF
791791
seek=${verity_offset} count=64 bs=1 status=none
792792
fi
793793

794-
# Sign the kernel after /usr is in a consistent state and verity is calculated
795-
[[ ${COREOS_OFFICIAL:-0} -ne 1 ]] && \
796-
do_sbsign --output "${root_fs_dir}/boot/flatcar/vmlinuz-a"{,}
797-
cleanup_sbsign_certs
794+
# Sign the kernel after /usr is in a consistent state and verity is
795+
# calculated. Only for unofficial builds as official builds get signed later.
796+
if [[ ${COREOS_OFFICIAL:-0} -ne 1 ]]; then
797+
do_sbsign --output "${root_fs_dir}/boot/flatcar/vmlinuz-a"{,}
798+
cleanup_sbsign_certs
799+
fi
798800

799801
if [[ -n "${image_kernel}" ]]; then
800802
# copying kernel from vfat so ignore the permissions
@@ -880,3 +882,67 @@ EOF
880882
cleanup_mounts "${root_fs_dir}"
881883
trap - EXIT
882884
}
885+
886+
sbsign_image() {
887+
local image_name="$1"
888+
local disk_layout="$2"
889+
local root_fs_dir="$3"
890+
local image_kernel="$4"
891+
local pcr_policy="$5"
892+
local image_grub="$6"
893+
894+
local disk_img="${BUILD_DIR}/${image_name}"
895+
local EFI_ARCH
896+
897+
case "${BOARD}" in
898+
amd64-usr) EFI_ARCH="x64" ;;
899+
arm64-usr) EFI_ARCH="aa64" ;;
900+
*) die "Unknown board ${BOARD@Q}" ;;
901+
esac
902+
903+
"${BUILD_LIBRARY_DIR}/disk_util" --disk_layout="${disk_layout}" \
904+
mount "${disk_img}" "${root_fs_dir}"
905+
trap "cleanup_mounts '${root_fs_dir}'; cleanup_sbsign_certs" EXIT
906+
907+
# Sign the kernel with the shim-embedded key.
908+
do_sbsign --output "${root_fs_dir}/boot/flatcar/vmlinuz-a"{,}
909+
910+
if [[ -n "${image_kernel}" ]]; then
911+
# copying kernel from vfat so ignore the permissions
912+
cp --no-preserve=mode \
913+
"${root_fs_dir}/boot/flatcar/vmlinuz-a" \
914+
"${BUILD_DIR}/${image_kernel}"
915+
fi
916+
917+
# Sign GRUB and mokmanager(mm) with the shim-embedded key.
918+
do_sbsign --output "${root_fs_dir}/boot/EFI/boot/grub${EFI_ARCH}.efi"{,}
919+
do_sbsign --output "${root_fs_dir}/boot/EFI/boot/mm${EFI_ARCH}.efi"{,}
920+
921+
# copying from vfat so ignore permissions
922+
if [[ -n "${image_grub}" ]]; then
923+
cp --no-preserve=mode "${root_fs_dir}/boot/EFI/boot/grub${EFI_ARCH}.efi" \
924+
"${BUILD_DIR}/${image_grub}"
925+
fi
926+
927+
if [[ -n "${pcr_policy}" ]]; then
928+
mkdir -p "${BUILD_DIR}/pcrs"
929+
"${BUILD_LIBRARY_DIR}"/generate_kernel_hash.py \
930+
"${root_fs_dir}/boot/flatcar/vmlinuz-a" "${FLATCAR_VERSION}" \
931+
>"${BUILD_DIR}/pcrs/kernel.config"
932+
fi
933+
934+
cleanup_mounts "${root_fs_dir}"
935+
cleanup_sbsign_certs
936+
trap - EXIT
937+
938+
if [[ -n "${pcr_policy}" ]]; then
939+
"${BUILD_LIBRARY_DIR}"/generate_grub_hashes.py \
940+
"${disk_img}" /usr/lib/grub/ "${BUILD_DIR}/pcrs" "${FLATCAR_VERSION}"
941+
942+
info "Generating $pcr_policy"
943+
pushd "${BUILD_DIR}" >/dev/null
944+
zip --quiet -r -9 "${BUILD_DIR}/${pcr_policy}" pcrs
945+
popd >/dev/null
946+
rm -rf "${BUILD_DIR}/pcrs"
947+
fi
948+
}

build_library/grub_install.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,10 @@ case "${FLAGS_target}" in
205205
--output "${ESP_DIR}/EFI/boot/boot${EFI_ARCH}.efi" \
206206
"${BOARD_ROOT}/usr/lib/shim/shim${EFI_ARCH}.efi"
207207
else
208-
# Official build: Copy the unsigned files.
208+
# Official build: Copy signed shim and mm for signing later.
209209
sudo cp "${BOARD_ROOT}/usr/lib/shim/mm${EFI_ARCH}.efi" \
210210
"${ESP_DIR}/EFI/boot/mm${EFI_ARCH}.efi"
211-
sudo cp "${BOARD_ROOT}/usr/lib/shim/shim${EFI_ARCH}.efi" \
211+
sudo cp "${BOARD_ROOT}/usr/lib/shim/shim${EFI_ARCH}.efi.signed" \
212212
"${ESP_DIR}/EFI/boot/boot${EFI_ARCH}.efi"
213213
fi
214214

build_library/prod_image_util.sh

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,15 @@ EOF
180180
"${image_initrd_contents_wtd}" \
181181
"${image_disk_usage}"
182182

183+
# Official builds will sign and upload these files later, so remove them to
184+
# prevent them from being uploaded now.
185+
if [[ ${COREOS_OFFICIAL:-0} -eq 1 ]]; then
186+
rm -v \
187+
"${BUILD_DIR}/${image_kernel}" \
188+
"${BUILD_DIR}/${image_pcr_policy}" \
189+
"${BUILD_DIR}/${image_grub}"
190+
fi
191+
183192
local files_to_evaluate=( "${BUILD_DIR}/${image_name}" )
184193
compress_disk_images files_to_evaluate
185194
}
@@ -225,3 +234,26 @@ create_prod_sysexts() {
225234
-out_file "${BUILD_DIR}/flatcar_test_update-${name}.gz"
226235
done
227236
}
237+
238+
sbsign_prod_image() {
239+
local image_name="$1"
240+
local disk_layout="$2"
241+
242+
info "Signing production image ${image_name} for Secure Boot"
243+
local root_fs_dir="${BUILD_DIR}/rootfs"
244+
local image_prefix="${image_name%.bin}"
245+
local image_kernel="${image_prefix}.vmlinuz"
246+
local image_pcr_policy="${image_prefix}_pcr_policy.zip"
247+
local image_grub="${image_prefix}.grub"
248+
249+
sbsign_image \
250+
"${image_name}" \
251+
"${disk_layout}" \
252+
"${root_fs_dir}" \
253+
"${image_kernel}" \
254+
"${image_pcr_policy}" \
255+
"${image_grub}"
256+
257+
local files_to_evaluate=( "${BUILD_DIR}/${image_name}" )
258+
compress_disk_images files_to_evaluate
259+
}

ci-automation/sbsign_image.sh

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#!/bin/bash
2+
#
3+
# Copyright (c) 2024 The Flatcar Maintainers.
4+
# Use of this source code is governed by the Apache 2.0 license.
5+
6+
# >>> This file is supposed to be SOURCED from the repository ROOT. <<<
7+
#
8+
# sbsign_image() should be called w/ the positional INPUT parameters below.
9+
10+
# Secure Boot image signing build automation stub.
11+
# This script will sign an existing OS image for Secure Boot.
12+
#
13+
# PREREQUISITES:
14+
#
15+
# 1. SDK version and OS image version are recorded in sdk_container/.repo/manifests/version.txt
16+
# 2. Scripts repo version tag of OS image version to be built is available and checked out.
17+
# 3. The generic Flatcar image must be present in build cache server.
18+
#
19+
# INPUT:
20+
#
21+
# 1. Architecture (ARCH) of the TARGET vm images ("arm64", "amd64").
22+
#
23+
# OPTIONAL INPUT:
24+
#
25+
# 1. SIGNER. Environment variable. Name of the owner of the artifact signing key.
26+
# Defaults to nothing if not set - in such case, artifacts will not be signed.
27+
# If provided, SIGNING_KEY environment variable should also be provided, otherwise this environment variable will be ignored.
28+
#
29+
# 2. SIGNING_KEY. Environment variable. The artifact signing key.
30+
# Defaults to nothing if not set - in such case, artifacts will not be signed.
31+
# If provided, SIGNER environment variable should also be provided, otherwise this environment variable will be ignored.
32+
#
33+
# 3. A file ../scripts.patch to apply with "git am -3" for the scripts repo.
34+
#
35+
# OUTPUT:
36+
#
37+
# 1. OS image and related artifacts signed for Secure Boot pushed to buildcache.
38+
# 2. If signer key was passed, signatures of artifacts from point 1, pushed along to buildcache.
39+
# 3. DIGESTS of the artifacts from point 1, pushed to buildcache. If signer key was passed, armored ASCII files of the generated DIGESTS files too, pushed to buildcache.
40+
41+
function sbsign_image() {
42+
# Run a subshell, so the traps, environment changes and global
43+
# variables are not spilled into the caller.
44+
(
45+
set -euo pipefail
46+
47+
_sbsign_image_impl "${@}"
48+
)
49+
}
50+
# --
51+
52+
function _sbsign_image_impl() {
53+
local arch="$1"
54+
55+
source sdk_lib/sdk_container_common.sh
56+
local channel=""
57+
channel="$(get_git_channel)"
58+
source ci-automation/ci_automation_common.sh
59+
source ci-automation/gpg_setup.sh
60+
source sdk_container/.repo/manifests/version.txt
61+
62+
if is_official "${FLATCAR_VERSION}"; then
63+
export COREOS_OFFICIAL=1
64+
else
65+
export COREOS_OFFICIAL=0
66+
fi
67+
68+
apply_local_patches
69+
70+
local images_remote="images/${arch}/${FLATCAR_VERSION}"
71+
local images_local="__build__/images/images/${arch}-usr/${channel}-${FLATCAR_VERSION}"
72+
73+
copy_from_buildcache "${images_remote}/flatcar_production_image.bin.bz2" "${images_local}"
74+
lbunzip2 --force "${images_local}/flatcar_production_image.bin.bz2"
75+
76+
# Get SDK from either the registry or import from build cache
77+
# This is a NOP if the image is present locally.
78+
local sdk_name="flatcar-sdk-${arch}"
79+
local docker_sdk_vernum="$(vernum_to_docker_image_version "${FLATCAR_SDK_VERSION}")"
80+
81+
docker_image_from_registry_or_buildcache "${sdk_name}" "${docker_sdk_vernum}"
82+
local sdk_image="$(docker_image_fullname "${sdk_name}" "${docker_sdk_vernum}")"
83+
echo "docker image rm -f '${sdk_image}'" >> ./ci-cleanup.sh
84+
85+
./run_sdk_container -x ./ci-cleanup.sh -v "${FLATCAR_VERSION}" -U -C "${sdk_image}" \
86+
./sbsign_image --board="${arch}-usr" \
87+
--group="${channel}" --version="${FLATCAR_VERSION}" \
88+
--output_root="${CONTAINER_IMAGE_ROOT}" \
89+
--only_store_compressed
90+
91+
# Delete uncompressed generic image before signing and upload
92+
rm "${images_local}/flatcar_production_image.bin"
93+
create_digests "${SIGNER}" "${images_local}"/*
94+
sign_artifacts "${SIGNER}" "${images_local}"/*
95+
copy_to_buildcache "${images_remote}"/ "${images_local}"/*
96+
}
97+
# --

sbsign_image

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!/bin/bash
2+
3+
# Copyright (c) 2024 The Flatcar Maintainers.
4+
# Use of this source code is governed by the Apache 2.0 license.
5+
6+
# Script to sign an existing raw Flatcar disk image for Secure Boot.
7+
8+
SCRIPT_ROOT=$(dirname "$(readlink -f "$0")")
9+
. "${SCRIPT_ROOT}/common.sh" || exit 1
10+
11+
# Script must run inside the chroot
12+
assert_inside_chroot
13+
14+
assert_not_root_user
15+
16+
DEFAULT_GROUP=developer
17+
18+
# Developer-visible flags.
19+
DEFINE_string board "${DEFAULT_BOARD}" \
20+
"The board to build an image for."
21+
DEFINE_string output_root "${DEFAULT_BUILD_ROOT}/images" \
22+
"Directory in which to place image result directories (named by version)"
23+
DEFINE_string disk_layout "" \
24+
"The disk layout type to use for this image."
25+
DEFINE_string group "${DEFAULT_GROUP}" \
26+
"The update group."
27+
28+
# include upload options
29+
. "${BUILD_LIBRARY_DIR}/release_util.sh" || exit 1
30+
31+
FLAGS_HELP="USAGE: sbsign_image [flags]
32+
This script is used to sign the GRUB and kernel images within an
33+
existing raw Flatcar disk image for Secure Boot. The disk image is
34+
read from the output directory and modified in-place. The signed GRUB
35+
and kernel images are also written separately to the same directory.
36+
"
37+
show_help_if_requested "$@"
38+
39+
# The following options are advanced options, only available to those willing
40+
# to read the source code. They are not shown in help output, since they are
41+
# not needed for the typical developer workflow.
42+
DEFINE_integer build_attempt 1 \
43+
"The build attempt for this image build."
44+
DEFINE_string version "" \
45+
"Overrides version number in name to this version."
46+
47+
# Parse command line.
48+
FLAGS "$@" || exit 1
49+
50+
# Only now can we die on error. shflags functions leak non-zero error codes,
51+
# so will die prematurely if 'switch_to_strict_mode' is specified before now.
52+
switch_to_strict_mode
53+
54+
# N.B. Ordering matters for some of the libraries below, because
55+
# some of the files contain initialization used by later files.
56+
. "${BUILD_LIBRARY_DIR}/toolchain_util.sh" || exit 1
57+
. "${BUILD_LIBRARY_DIR}/board_options.sh" || exit 1
58+
. "${BUILD_LIBRARY_DIR}/build_image_util.sh" || exit 1
59+
. "${BUILD_LIBRARY_DIR}/prod_image_util.sh" || exit 1
60+
61+
# Create the output directory and temporary mount points.
62+
mkdir -p "${BUILD_DIR}"
63+
64+
fix_mtab
65+
sbsign_prod_image "${FLATCAR_PRODUCTION_IMAGE_NAME}" "${FLAGS_disk_layout:-base}"
66+
67+
echo "Done. ${FLATCAR_PRODUCTION_IMAGE_NAME} and associated files are now signed for Secure Boot in ${BUILD_DIR}."
68+
command_completed

0 commit comments

Comments
 (0)