#!/usr/bin/env bash # SPDX-License-Identifier: LGPL-2.1-or-later set -eux set -o pipefail # shellcheck source=test/units/util.sh . "$(dirname "$0")"/util.sh export SYSTEMD_LOG_LEVEL=debug SD_PCREXTEND="/usr/lib/systemd/systemd-pcrextend" SD_TPM2SETUP="/usr/lib/systemd/systemd-tpm2-setup" if [[ ! -x "${SD_PCREXTEND:?}" ]] || ! tpm_has_pcr sha256 11; then echo "$SD_PCREXTEND or PCR sysfs files not found, skipping PCR extension tests" exit 0 fi at_exit() { if [[ $? -ne 0 ]]; then # Dump the event log on fail, to make debugging a bit easier jq --seq --slurp /run/nvpcr/test.nvpcr </run/nvpcr/test2.nvpcr </run/nvpcr/aaa.nvpcr </run/nvpcr/zzz.nvpcr <:"). grep -F '"nvIndexName":"login","string":"login:root:' /run/log/systemd/tpm2-measure.log >/dev/null LOGIN_WORD_BY_NAME="$(login_last_word)" # Looking the same user up by numeric UID must yield the identical measured word # (systemd-pcrextend uses USERDB_PARSE_NUMERIC, and systemd-pcrlogin@.service is instanced by UID). "$SD_PCREXTEND" --login=0 LOGIN_WORD_BY_UID="$(login_last_word)" test "$LOGIN_WORD_BY_NAME" = "$LOGIN_WORD_BY_UID" # Direct tool invocations always re-extend (the once-per-boot guarantee lives in the unit's # RemainAfterExit=yes, not in the tool), so the NvPCR value must have advanced. LOGIN_DIGEST2="$(login_nvpcr_value)" test "$LOGIN_DIGEST2" != "$LOGIN_DIGEST1" fi systemd-analyze identify-tpm2 udevadm test-builtin 'tpm2_id identify' /dev/tpmrm0 # systemd-dissect calls io.systemd.PCRExtend over Varlink to extend the verity NvPCR after activation, # but systemd-pcrextend.socket has ConditionSecurity=measured-os which fails when the firmware did not # initialize PCRs (e.g. when not booting via a signed UKI). Skip the rest in that case, otherwise the # 'diff | grep' below would find no new measurement and fail. if ! systemctl is-active --quiet systemd-pcrextend.socket; then echo "systemd-pcrextend.socket not active, skipping verity NvPCR measurement check" exit 0 fi mkdir -p /tmp/nvpcr/tree touch /tmp/nvpcr/tree/file if machine_supports_verity_keyring; then SYSTEMD_REPART_OVERRIDE_FSTYPE=squashfs \ systemd-repart -P \ -s /tmp/nvpcr/tree \ --certificate=/usr/share/mkosi.crt \ --private-key=/usr/share/mkosi.key \ /var/tmp/nvpcr.raw else OPENSSL_CONFIG="/tmp/nvpcr/opensslconfig" # Unfortunately OpenSSL insists on reading some config file, hence provide one with mostly placeholder contents cat >"${OPENSSL_CONFIG:?}" <