From: Lennart Poettering Date: Tue, 16 Jul 2024 08:48:39 +0000 (+0200) Subject: ci: add testcase for multi-profile UKIs X-Git-Tag: v257-rc1~418^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a37640653cab108bb2cfdcba7e9422cced925e95;p=thirdparty%2Fsystemd.git ci: add testcase for multi-profile UKIs This tests the whole shebang: 1. That ukify can generate them properly 2. That systemd-boot can dissect them properly 3. That systemd-stub can accept profile selection propery 4. That the profile information ends up in /run/systemd/stub/ properly 5. That systemd-measure correctly calculates the expected PCR 11 values for each profile and that we can unlock a public-key bound LUKS volume with it --- diff --git a/test/TEST-86-MULTI-PROFILE-UKI/Makefile b/test/TEST-86-MULTI-PROFILE-UKI/Makefile new file mode 100644 index 00000000000..653f16163fa --- /dev/null +++ b/test/TEST-86-MULTI-PROFILE-UKI/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +all setup run clean clean-again: + true + +.PHONY: all setup run clean clean-again diff --git a/test/TEST-86-MULTI-PROFILE-UKI/meson.build b/test/TEST-86-MULTI-PROFILE-UKI/meson.build new file mode 100644 index 00000000000..53042884cc7 --- /dev/null +++ b/test/TEST-86-MULTI-PROFILE-UKI/meson.build @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +integration_tests += [ + integration_test_template + { + 'name' : fs.name(meson.current_source_dir()), + 'storage' : 'persistent', + 'vm' : true, + 'firmware' : 'auto', + }, +] diff --git a/test/TEST-86-MULTI-PROFILE-UKI/test.sh b/test/TEST-86-MULTI-PROFILE-UKI/test.sh new file mode 100755 index 00000000000..1b06a109d21 --- /dev/null +++ b/test/TEST-86-MULTI-PROFILE-UKI/test.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -e + +TEST_DESCRIPTION="Test Multi-Profile UKI Boots" + +# shellcheck source=test/test-functions +. "${TEST_BASE_DIR:?}/test-functions" + +do_test "$@" diff --git a/test/meson.build b/test/meson.build index 6acff375083..9d1a069fc92 100644 --- a/test/meson.build +++ b/test/meson.build @@ -376,6 +376,7 @@ foreach dirname : [ 'TEST-83-BTRFS', 'TEST-84-STORAGETM', 'TEST-85-NETWORK', + 'TEST-86-MULTI-PROFILE-UKI', ] subdir(dirname) endforeach diff --git a/test/units/TEST-86-MULTI-PROFILE-UKI.sh b/test/units/TEST-86-MULTI-PROFILE-UKI.sh new file mode 100755 index 00000000000..21d2349200a --- /dev/null +++ b/test/units/TEST-86-MULTI-PROFILE-UKI.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -eux +set -o pipefail + +export SYSTEMD_LOG_LEVEL=debug + +bootctl + +CURRENT_UKI=$(bootctl --print-stub-path) + +echo "CURRENT UKI ($CURRENT_UKI):" +ukify inspect "$CURRENT_UKI" +if test -f /run/systemd/stub/profile; then + echo "CURRENT PROFILE:" + cat /run/systemd/stub/profile +fi +echo "CURRENT MEASUREMENT:" +/usr/lib/systemd/systemd-measure --current +if test -f /run/systemd/tpm2-pcr-signature.json ; then + echo "CURRENT SIGNATURE:" + jq < /run/systemd/tpm2-pcr-signature.json +fi + +echo "CURRENT EVENT LOG + PCRS:" +/usr/lib/systemd/systemd-pcrlock + +if test ! -f /run/systemd/stub/profile; then + openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out /root/pcrsign.private.pem + openssl rsa -pubout -in /root/pcrsign.private.pem -out /root/pcrsign.public.pem + + ukify build --extend="$CURRENT_UKI" --output=/tmp/extended0.efi --profile='ID=profile0 +TITLE="Profile Zero"' --measure-base="$CURRENT_UKI" --pcr-private-key=/root/pcrsign.private.pem --pcr-public-key=/root/pcrsign.public.pem --pcr-banks=sha256,sha384,sha512 + + ukify build --extend=/tmp/extended0.efi --output=/tmp/extended1.efi --profile='ID=profile1 +TITLE="Profile One"' --measure-base=/tmp/extended0.efi --cmdline="testprofile1=1 $(cat /proc/cmdline)" --pcr-private-key=/root/pcrsign.private.pem --pcr-public-key=/root/pcrsign.public.pem --pcr-banks=sha256,sha384,sha512 + + ukify build --extend=/tmp/extended1.efi --output=/tmp/extended2.efi --profile='ID=profile2 +TITLE="Profile Two"' --measure-base=/tmp/extended1.efi --cmdline="testprofile2=1 $(cat /proc/cmdline)" --pcr-private-key=/root/pcrsign.private.pem --pcr-public-key=/root/pcrsign.public.pem --pcr-banks=sha256,sha384,sha512 + + echo "EXTENDED UKI:" + ukify inspect /tmp/extended2.efi + rm /tmp/extended0.efi /tmp/extended1.efi + mv /tmp/extended2.efi "$CURRENT_UKI" + + # Prepare a disk image, locked to the PCR measurements of the UKI we just generated + truncate -s 32M /root/encrypted.raw + echo -n "geheim" > /root/encrypted.secret + cryptsetup luksFormat -q --pbkdf pbkdf2 --pbkdf-force-iterations 1000 --use-urandom /root/encrypted.raw --key-file=/root/encrypted.secret + systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs= --tpm2-public-key=/root/pcrsign.public.pem --unlock-key-file=/root/encrypted.secret /root/encrypted.raw + rm -f /root/encrypted.secret + + reboot + exit 0 +else + # shellcheck source=/dev/null + . /run/systemd/stub/profile + + # Validate that with the current profile we can fulfill the PCR 11 policy + systemd-cryptsetup attach multiprof /root/encrypted.raw - tpm2-device=auto,headless=1 + systemd-cryptsetup detach multiprof + + if [ "$ID" = "profile0" ]; then + grep -v testprofile /proc/cmdline + echo "default $(basename "$CURRENT_UKI")@profile1" > "$(bootctl -p)/loader/loader.conf" + reboot + exit 0 + elif [ "$ID" = "profile1" ]; then + grep testprofile1=1 /proc/cmdline + echo "default $(basename "$CURRENT_UKI")@profile2" > "$(bootctl -p)/loader/loader.conf" + reboot + exit 0 + elif [ "$ID" = "profile2" ]; then + grep testprofile2=1 /proc/cmdline + rm /root/encrypted.raw + else + exit 1 + fi +fi + +touch /testok