Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do Secure Boot signing for official builds in a separate additional job #2491

Merged
merged 5 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions build_image
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ DEFINE_string disk_layout "" \
"The disk layout type to use for this image."
DEFINE_string group "${DEFAULT_GROUP}" \
"The update group."
DEFINE_boolean generate_update "${FLAGS_FALSE}" \
"Generate update payload. (prod only)"
DEFINE_boolean extract_update "${FLAGS_TRUE}" \
"Extract the /usr partition for generating updates."
"Extract the /usr partition for generating updates. Only valid for the prod image."
DEFINE_boolean generate_update "${FLAGS_TRUE}" \
"Generate update payload for testing. The update is signed with a dev key. The kernel is signed with a dev key (unofficial builds) or not at all (official builds). Only valid for the prod image. Implies --extract_update."
DEFINE_string developer_data "" \
"Insert a custom cloudinit file into the image."
DEFINE_string devcontainer_binhost "${DEFAULT_DEVCONTAINER_BINHOST}" \
Expand Down Expand Up @@ -139,6 +139,11 @@ fi
# Create the output directory and temporary mount points.
mkdir -p "${BUILD_DIR}"

# --generate_update implies --extract_update.
if [[ ${FLAGS_generate_update} -eq ${FLAGS_TRUE} ]]; then
FLAGS_extract_update=${FLAGS_TRUE}
fi

DISK_LAYOUT="${FLAGS_disk_layout:-base}"
CONTAINER_LAYOUT="${FLAGS_disk_layout:-container}"

Expand Down Expand Up @@ -169,11 +174,12 @@ fi
if [[ "${PROD_IMAGE}" -eq 1 ]]; then
IMAGE_BUILD_TYPE="prod"
create_prod_image ${FLATCAR_PRODUCTION_IMAGE_NAME} ${DISK_LAYOUT} ${FLAGS_group} ${FLAGS_base_pkg} ${FLAGS_base_sysexts}
if [[ ${FLAGS_generate_update} -eq ${FLAGS_TRUE} ]]; then
generate_update "${FLATCAR_PRODUCTION_IMAGE_NAME}" ${DISK_LAYOUT}
elif [[ ${FLAGS_extract_update} -eq ${FLAGS_TRUE} ]]; then
if [[ ${FLAGS_extract_update} -eq ${FLAGS_TRUE} ]]; then
extract_update "${FLATCAR_PRODUCTION_IMAGE_NAME}" "${DISK_LAYOUT}"
fi
if [[ ${FLAGS_generate_update} -eq ${FLAGS_TRUE} ]]; then
generate_update "${FLATCAR_PRODUCTION_IMAGE_NAME}" "${DISK_LAYOUT}"
fi
if [[ "${PROD_TAR}" -eq 1 ]]; then
create_prod_tar ${FLATCAR_PRODUCTION_IMAGE_NAME}
fi
Expand All @@ -182,9 +188,7 @@ if [[ "${SYSEXT}" -eq 1 ]]; then
create_prod_sysexts "${FLATCAR_PRODUCTION_IMAGE_NAME}"
fi

if [[ ${FLAGS_generate_update} -eq ${FLAGS_TRUE} ]] || \
[[ ${FLAGS_extract_update} -eq ${FLAGS_TRUE} ]]
then
if [[ ${FLAGS_extract_update} -eq ${FLAGS_TRUE} ]]; then
zip_update_tools
fi

Expand Down
126 changes: 89 additions & 37 deletions build_library/build_image_util.sh
Original file line number Diff line number Diff line change
Expand Up @@ -61,57 +61,43 @@ delete_prompt() {
extract_update() {
local image_name="$1"
local disk_layout="$2"
local update_path="${BUILD_DIR}/${image_name%_image.bin}_update.bin"
local update="${BUILD_DIR}/${image_name%_image.bin}_update.bin"

"${BUILD_LIBRARY_DIR}/disk_util" --disk_layout="${disk_layout}" \
extract "${BUILD_DIR}/${image_name}" "USR-A" "${update_path}"
extract "${BUILD_DIR}/${image_name}" "USR-A" "${update}"

# Compress image
files_to_evaluate+=( "${update_path}" )
files_to_evaluate+=( "${update}" )
compress_disk_images files_to_evaluate

# For production as well as dev builds we generate a dev-key-signed update
# payload for running tests (the signature won't be accepted by production systems).
local update_test="${BUILD_DIR}/flatcar_test_update.gz"
delta_generator \
-private_key "/usr/share/update_engine/update-payload-key.key.pem" \
-new_image "${update_path}" \
-new_kernel "${BUILD_DIR}/${image_name%.bin}.vmlinuz" \
-out_file "${update_test}"
}

zip_update_tools() {
# There isn't a 'dev' variant of this zip, so always call it production.
local update_zip="flatcar_production_update.zip"

info "Generating update tools zip"
# Make sure some vars this script needs are exported
export REPO_MANIFESTS_DIR SCRIPTS_DIR
"${BUILD_LIBRARY_DIR}/generate_au_zip.py" \
--arch "$(get_sdk_arch)" --output-dir "${BUILD_DIR}" --zip-name "${update_zip}"
}

generate_update() {
local image_name="$1"
local disk_layout="$2"
local image_kernel="${BUILD_DIR}/${image_name%.bin}.vmlinuz"
local update_prefix="${image_name%_image.bin}_update"
local update="${BUILD_DIR}/${update_prefix}"
local update="${BUILD_DIR}/${image_name%_image.bin}_update.bin"
local devkey="/usr/share/update_engine/update-payload-key.key.pem"

# Extract the partition if it isn't extracted already.
[[ -s ${update} ]] || extract_update "${image_name}" "${disk_layout}"

echo "Generating update payload, signed with a dev key"
"${BUILD_LIBRARY_DIR}/disk_util" --disk_layout="${disk_layout}" \
extract "${BUILD_DIR}/${image_name}" "USR-A" "${update}.bin"
delta_generator \
-private_key "${devkey}" \
-new_image "${update}.bin" \
-new_image "${update}" \
-new_kernel "${image_kernel}" \
-out_file "${update}.gz"
-out_file "${BUILD_DIR}/flatcar_test_update.gz"
}

# Compress image
declare -a files_to_evaluate
files_to_evaluate+=( "${update}.bin" )
compress_disk_images files_to_evaluate
zip_update_tools() {
# There isn't a 'dev' variant of this zip, so always call it production.
local update_zip="flatcar_production_update.zip"

info "Generating update tools zip"
# Make sure some vars this script needs are exported
local -x REPO_MANIFESTS_DIR SCRIPTS_DIR
"${BUILD_LIBRARY_DIR}/generate_au_zip.py" \
--arch "$(get_sdk_arch)" --output-dir "${BUILD_DIR}" --zip-name "${update_zip}"
}

# ldconfig cannot generate caches for non-native arches.
Expand Down Expand Up @@ -805,10 +791,12 @@ EOF
seek=${verity_offset} count=64 bs=1 status=none
fi

# Sign the kernel after /usr is in a consistent state and verity is calculated
[[ ${COREOS_OFFICIAL:-0} -ne 1 ]] && \
do_sbsign --output "${root_fs_dir}/boot/flatcar/vmlinuz-a"{,}
cleanup_sbsign_certs
# Sign the kernel after /usr is in a consistent state and verity is
# 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
# copying kernel from vfat so ignore the permissions
Expand Down Expand Up @@ -894,3 +882,67 @@ EOF
cleanup_mounts "${root_fs_dir}"
trap - EXIT
}

sbsign_image() {
local image_name="$1"
local disk_layout="$2"
local root_fs_dir="$3"
local image_kernel="$4"
local pcr_policy="$5"
local image_grub="$6"

local disk_img="${BUILD_DIR}/${image_name}"
local EFI_ARCH

case "${BOARD}" in
amd64-usr) EFI_ARCH="x64" ;;
arm64-usr) EFI_ARCH="aa64" ;;
*) die "Unknown board ${BOARD@Q}" ;;
esac

"${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

# Sign the kernel with the shim-embedded key.
do_sbsign --output "${root_fs_dir}/boot/flatcar/vmlinuz-a"{,}

if [[ -n "${image_kernel}" ]]; then
# copying kernel from vfat so ignore the permissions
cp --no-preserve=mode \
"${root_fs_dir}/boot/flatcar/vmlinuz-a" \
"${BUILD_DIR}/${image_kernel}"
fi

# Sign GRUB and mokmanager(mm) with the shim-embedded key.
do_sbsign --output "${root_fs_dir}/boot/EFI/boot/grub${EFI_ARCH}.efi"{,}
do_sbsign --output "${root_fs_dir}/boot/EFI/boot/mm${EFI_ARCH}.efi"{,}

# copying from vfat so ignore permissions
if [[ -n "${image_grub}" ]]; then
cp --no-preserve=mode "${root_fs_dir}/boot/EFI/boot/grub${EFI_ARCH}.efi" \
"${BUILD_DIR}/${image_grub}"
fi

if [[ -n "${pcr_policy}" ]]; then
mkdir -p "${BUILD_DIR}/pcrs"
"${BUILD_LIBRARY_DIR}"/generate_kernel_hash.py \
"${root_fs_dir}/boot/flatcar/vmlinuz-a" "${FLATCAR_VERSION}" \
>"${BUILD_DIR}/pcrs/kernel.config"
fi

cleanup_mounts "${root_fs_dir}"
cleanup_sbsign_certs
trap - EXIT

if [[ -n "${pcr_policy}" ]]; then
"${BUILD_LIBRARY_DIR}"/generate_grub_hashes.py \
"${disk_img}" /usr/lib/grub/ "${BUILD_DIR}/pcrs" "${FLATCAR_VERSION}"

info "Generating $pcr_policy"
pushd "${BUILD_DIR}" >/dev/null
zip --quiet -r -9 "${BUILD_DIR}/${pcr_policy}" pcrs
popd >/dev/null
rm -rf "${BUILD_DIR}/pcrs"
fi
}
2 changes: 1 addition & 1 deletion build_library/grub_install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ case "${FLAGS_target}" in
--output "${ESP_DIR}/EFI/boot/boot${EFI_ARCH}.efi" \
"${BOARD_ROOT}/usr/lib/shim/shim${EFI_ARCH}.efi"
else
# Official build: Copy the unsigned files.
# Official build: Copy signed shim and mm for signing later.
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" \
Expand Down
100 changes: 0 additions & 100 deletions build_library/modify_image_util.sh

This file was deleted.

32 changes: 32 additions & 0 deletions build_library/prod_image_util.sh
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,15 @@ EOF
"${image_initrd_contents_wtd}" \
"${image_disk_usage}"

# Official builds will sign and upload these files later, so remove them to
# prevent them from being uploaded now.
if [[ ${COREOS_OFFICIAL:-0} -eq 1 ]]; then
rm -v \
"${BUILD_DIR}/${image_kernel}" \
"${BUILD_DIR}/${image_pcr_policy}" \
"${BUILD_DIR}/${image_grub}"
fi

local files_to_evaluate=( "${BUILD_DIR}/${image_name}" )
compress_disk_images files_to_evaluate
}
Expand Down Expand Up @@ -225,3 +234,26 @@ create_prod_sysexts() {
-out_file "${BUILD_DIR}/flatcar_test_update-${name}.gz"
done
}

sbsign_prod_image() {
local image_name="$1"
local disk_layout="$2"

info "Signing production image ${image_name} for Secure Boot"
local root_fs_dir="${BUILD_DIR}/rootfs"
local image_prefix="${image_name%.bin}"
local image_kernel="${image_prefix}.vmlinuz"
local image_pcr_policy="${image_prefix}_pcr_policy.zip"
local image_grub="${image_prefix}.grub"

sbsign_image \
"${image_name}" \
"${disk_layout}" \
"${root_fs_dir}" \
"${image_kernel}" \
"${image_pcr_policy}" \
"${image_grub}"

local files_to_evaluate=( "${BUILD_DIR}/${image_name}" )
compress_disk_images files_to_evaluate
}
Loading