From: Frantisek Sumsal Date: Wed, 25 Oct 2023 12:48:30 +0000 (+0200) Subject: test: split TEST-70-TPM2 into subtests X-Git-Tag: v255-rc1~139^2~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=29be59555f478c9d029593ccf0a2f64b6ae5843f;p=thirdparty%2Fsystemd.git test: split TEST-70-TPM2 into subtests --- diff --git a/test/units/testsuite-70.creds.sh b/test/units/testsuite-70.creds.sh new file mode 100755 index 00000000000..e66bfd19c51 --- /dev/null +++ b/test/units/testsuite-70.creds.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -eux +set -o pipefail + +export SYSTEMD_LOG_LEVEL=debug + +# Ensure that sandboxing doesn't stop creds from being accessible +echo "test" > /tmp/testdata +systemd-creds encrypt /tmp/testdata /tmp/testdata.encrypted --with-key=tpm2 +# LoadCredentialEncrypted +systemd-run -p PrivateDevices=yes -p LoadCredentialEncrypted=testdata.encrypted:/tmp/testdata.encrypted --pipe --wait systemd-creds cat testdata.encrypted | cmp - /tmp/testdata +# SetCredentialEncrypted +systemd-run -p PrivateDevices=yes -p SetCredentialEncrypted=testdata.encrypted:"$(cat /tmp/testdata.encrypted)" --pipe --wait systemd-creds cat testdata.encrypted | cmp - /tmp/testdata + +rm -f /tmp/testdata diff --git a/test/units/testsuite-70.cryptenroll.sh b/test/units/testsuite-70.cryptenroll.sh new file mode 100755 index 00000000000..3f8c14e54e3 --- /dev/null +++ b/test/units/testsuite-70.cryptenroll.sh @@ -0,0 +1,84 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -eux +set -o pipefail + +cryptenroll_wipe_and_check() {( + set +o pipefail + + : >/tmp/cryptenroll.out + systemd-cryptenroll "$@" |& tee /tmp/cryptenroll.out + grep -qE "Wiped slot [[:digit:]]+" /tmp/cryptenroll.out +)} + +# There is an external issue with libcryptsetup on ppc64 that hits 95% of Ubuntu ppc64 test runs, so skip it +if [[ "$(uname -m)" == "ppc64le" ]]; then + echo "Skipping systemd-cryptenroll tests on ppc64le, see https://github.com/systemd/systemd/issues/27716" + exit 0 +fi + +export SYSTEMD_LOG_LEVEL=debug +IMAGE="$(mktemp /tmp/systemd-cryptenroll-XXX.image)" + +truncate -s 20M "$IMAGE" +echo -n password >/tmp/password +# Change file mode to avoid "/tmp/password has 0644 mode that is too permissive" messages +chmod 0600 /tmp/password +cryptsetup luksFormat -q --pbkdf pbkdf2 --pbkdf-force-iterations 1000 --use-urandom "$IMAGE" /tmp/password + +# Enroll additional tokens, keys, and passwords to exercise the list and wipe stuff +systemd-cryptenroll --unlock-key-file=/tmp/password --tpm2-device=auto "$IMAGE" +NEWPASSWORD="" systemd-cryptenroll --unlock-key-file=/tmp/password --password "$IMAGE" +NEWPASSWORD=foo systemd-cryptenroll --unlock-key-file=/tmp/password --password "$IMAGE" +for _ in {0..9}; do + systemd-cryptenroll --unlock-key-file=/tmp/password --recovery-key "$IMAGE" +done +PASSWORD="" NEWPIN=123456 systemd-cryptenroll --tpm2-device=auto --tpm2-with-pin=true "$IMAGE" +# Do some basic checks before we start wiping stuff +systemd-cryptenroll "$IMAGE" +systemd-cryptenroll "$IMAGE" | grep password +systemd-cryptenroll "$IMAGE" | grep recovery +# Let's start wiping +cryptenroll_wipe_and_check "$IMAGE" --wipe=empty +(! cryptenroll_wipe_and_check "$IMAGE" --wipe=empty) +cryptenroll_wipe_and_check "$IMAGE" --wipe=empty,0 +PASSWORD=foo NEWPASSWORD=foo cryptenroll_wipe_and_check "$IMAGE" --wipe=0,0,empty,0,pkcs11,fido2,000,recovery,password --password +systemd-cryptenroll "$IMAGE" | grep password +(! systemd-cryptenroll "$IMAGE" | grep recovery) +# We shouldn't be able to wipe all keyslots without enrolling a new key first +(! systemd-cryptenroll "$IMAGE" --wipe=all) +PASSWORD=foo NEWPASSWORD=foo cryptenroll_wipe_and_check "$IMAGE" --password --wipe=all +# Check if the newly (and only) enrolled password works +(! systemd-cryptenroll --unlock-key-file=/tmp/password --recovery-key "$IMAGE") +(! PASSWORD="" systemd-cryptenroll --recovery-key "$IMAGE") +PASSWORD=foo systemd-cryptenroll --recovery-key "$IMAGE" + +systemd-cryptenroll --fido2-with-client-pin=false "$IMAGE" +systemd-cryptenroll --fido2-with-user-presence=false "$IMAGE" +systemd-cryptenroll --fido2-with-user-verification=false "$IMAGE" +systemd-cryptenroll --tpm2-pcrs=8 "$IMAGE" +systemd-cryptenroll --tpm2-pcrs=boot-loader-code+boot-loader-config "$IMAGE" + +(! systemd-cryptenroll --fido2-with-client-pin=false) +(! systemd-cryptenroll --fido2-with-user-presence=f "$IMAGE" /tmp/foo) +(! systemd-cryptenroll --fido2-with-client-pin=1234 "$IMAGE") +(! systemd-cryptenroll --fido2-with-user-presence=1234 "$IMAGE") +(! systemd-cryptenroll --fido2-with-user-verification=1234 "$IMAGE") +(! systemd-cryptenroll --tpm2-with-pin=1234 "$IMAGE") +(! systemd-cryptenroll --recovery-key --password "$IMAGE") +(! systemd-cryptenroll --password --recovery-key "$IMAGE") +(! systemd-cryptenroll --password --fido2-device=auto "$IMAGE") +(! systemd-cryptenroll --password --pkcs11-token-uri=auto "$IMAGE") +(! systemd-cryptenroll --password --tpm2-device=auto "$IMAGE") +(! systemd-cryptenroll --unlock-fido2-device=auto --unlock-fido2-device=auto "$IMAGE") +(! systemd-cryptenroll --unlock-fido2-device=auto --unlock-key-file=/tmp/unlock "$IMAGE") +(! systemd-cryptenroll --fido2-credential-algorithm=es512 "$IMAGE") +(! systemd-cryptenroll --tpm2-public-key-pcrs=key "$IMAGE") +(! systemd-cryptenroll --tpm2-pcrs=key "$IMAGE") +(! systemd-cryptenroll --tpm2-pcrs=44+8 "$IMAGE") +(! systemd-cryptenroll --tpm2-pcrs=hello "$IMAGE") +(! systemd-cryptenroll --wipe-slot "$IMAGE") +(! systemd-cryptenroll --wipe-slot=10240000 "$IMAGE") +(! systemd-cryptenroll --fido2-device=auto --unlock-fido2-device=auto "$IMAGE") + +rm -f "$IMAGE" diff --git a/test/units/testsuite-70.cryptsetup.sh b/test/units/testsuite-70.cryptsetup.sh new file mode 100755 index 00000000000..98a188fd1e2 --- /dev/null +++ b/test/units/testsuite-70.cryptsetup.sh @@ -0,0 +1,184 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -ex +set -o pipefail + +# shellcheck source=test/units/util.sh +. "$(dirname "$0")"/util.sh + +export SYSTEMD_LOG_LEVEL=debug + +cryptsetup_has_token_plugin_support() { + local plugin_path + + plugin_path="$(cryptsetup --help | sed -nr 's/.*LUKS2 external token plugin path: (.*)\./\1/p')/libcryptsetup-token-systemd-tpm2.so)" + cryptsetup --help | grep -q 'LUKS2 external token plugin support is compiled-in' && [[ -f "$plugin_path" ]] +} + +tpm_check_failure_with_wrong_pin() { + local testIMAGE="${1:?}" + local badpin="${2:?}" + local goodpin="${3:?}" + + # We need to be careful not to trigger DA lockout; allow 2 failures + tpm2_dictionarylockout -s -n 2 + (! PIN=$badpin systemd-cryptsetup attach test-volume "$testIMAGE" - tpm2-device=auto,headless=1) + # Verify the correct PIN works, to be sure the failure wasn't a DA lockout + PIN=$goodpin systemd-cryptsetup attach test-volume "$testIMAGE" - tpm2-device=auto,headless=1 + systemd-cryptsetup detach test-volume + # Clear/reset the DA lockout counter + tpm2_dictionarylockout -c +} + +at_exit() { + # Evict the TPM primary key that we persisted + if [[ -n "${PERSISTENT_HANDLE:-}" ]]; then + tpm2_evictcontrol -c "$PERSISTENT_HANDLE" + fi +} + +trap at_exit EXIT + +# Prepare a fresh disk image +IMAGE="$(mktemp /tmp/systemd-cryptsetup-XXX.IMAGE)" + +truncate -s 20M "$IMAGE" +echo -n passphrase >/tmp/passphrase +# Change file mode to avoid "/tmp/passphrase has 0644 mode that is too permissive" messages +chmod 0600 /tmp/passphrase +cryptsetup luksFormat -q --pbkdf pbkdf2 --pbkdf-force-iterations 1000 --use-urandom "$IMAGE" /tmp/passphrase + +# Unlocking via keyfile +systemd-cryptenroll --unlock-key-file=/tmp/passphrase --tpm2-device=auto "$IMAGE" + +# Enroll unlock with default PCR policy +PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto "$IMAGE" +systemd-cryptsetup attach test-volume "$IMAGE" - tpm2-device=auto,headless=1 +systemd-cryptsetup detach test-volume + +# Check with wrong PCR +tpm2_pcrextend 7:sha256=0000000000000000000000000000000000000000000000000000000000000000 +(! systemd-cryptsetup attach test-volume "$IMAGE" - tpm2-device=auto,headless=1) + +# Enroll unlock with PCR+PIN policy +systemd-cryptenroll --wipe-slot=tpm2 "$IMAGE" +PASSWORD=passphrase NEWPIN=123456 systemd-cryptenroll --tpm2-device=auto --tpm2-with-pin=true "$IMAGE" +PIN=123456 systemd-cryptsetup attach test-volume "$IMAGE" - tpm2-device=auto,headless=1 +systemd-cryptsetup detach test-volume + +# Check failure with wrong PIN; try a few times to make sure we avoid DA lockout +for _ in {0..3}; do + tpm_check_failure_with_wrong_pin "$IMAGE" 123457 123456 +done + +# Check LUKS2 token plugin unlock (i.e. without specifying tpm2-device=auto) +if cryptsetup_has_token_plugin_support; then + PIN=123456 systemd-cryptsetup attach test-volume "$IMAGE" - headless=1 + systemd-cryptsetup detach test-volume + + # Check failure with wrong PIN + for _ in {0..3}; do + tpm_check_failure_with_wrong_pin "$IMAGE" 123457 123456 + done +else + echo 'cryptsetup has no LUKS2 token plugin support, skipping' +fi + +# Check failure with wrong PCR (and correct PIN) +tpm2_pcrextend 7:sha256=0000000000000000000000000000000000000000000000000000000000000000 +(! PIN=123456 systemd-cryptsetup attach test-volume "$IMAGE" - tpm2-device=auto,headless=1) + +# Enroll unlock with PCR 0+7 +systemd-cryptenroll --wipe-slot=tpm2 "$IMAGE" +PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 "$IMAGE" +systemd-cryptsetup attach test-volume "$IMAGE" - tpm2-device=auto,headless=1 +systemd-cryptsetup detach test-volume + +# Check with wrong PCR 0 +tpm2_pcrextend 0:sha256=0000000000000000000000000000000000000000000000000000000000000000 +(! systemd-cryptsetup attach test-volume "$IMAGE" - tpm2-device=auto,headless=1) + +if tpm_has_pcr sha256 12; then + # Enroll using an explicit PCR value (that does match current PCR value) + systemd-cryptenroll --wipe-slot=tpm2 "$IMAGE" + EXPECTED_PCR_VALUE=$(cat /sys/class/tpm/tpm0/pcr-sha256/12) + PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs="12:sha256=$EXPECTED_PCR_VALUE" "$IMAGE" + systemd-cryptsetup attach test-volume "$IMAGE" - tpm2-device=auto,headless=1 + systemd-cryptsetup detach test-volume + + # Same as above plus more PCRs without the value or alg specified + systemd-cryptenroll --wipe-slot=tpm2 "$IMAGE" + EXPECTED_PCR_VALUE=$(cat /sys/class/tpm/tpm0/pcr-sha256/12) + PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs="1,12:sha256=$EXPECTED_PCR_VALUE,3" "$IMAGE" + systemd-cryptsetup attach test-volume "$IMAGE" - tpm2-device=auto,headless=1 + systemd-cryptsetup detach test-volume + + # Same as above plus more PCRs with hash alg specified but hash value not specified + systemd-cryptenroll --wipe-slot=tpm2 "$IMAGE" + EXPECTED_PCR_VALUE=$(cat /sys/class/tpm/tpm0/pcr-sha256/12) + PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs="1:sha256,12:sha256=$EXPECTED_PCR_VALUE,3" "$IMAGE" + systemd-cryptsetup attach test-volume "$IMAGE" - tpm2-device=auto,headless=1 + systemd-cryptsetup detach test-volume + + # Now the interesting part, enrolling using a hash value that doesn't match the current PCR value + systemd-cryptenroll --wipe-slot=tpm2 "$IMAGE" + tpm2_pcrread -Q -o /tmp/pcr.dat sha256:12 + CURRENT_PCR_VALUE=$(cat /sys/class/tpm/tpm0/pcr-sha256/12) + EXPECTED_PCR_VALUE=$(cat /tmp/pcr.dat /tmp/pcr.dat | openssl dgst -sha256 -r | cut -d ' ' -f 1) + PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs="12:sha256=$EXPECTED_PCR_VALUE" "$IMAGE" + (! systemd-cryptsetup attach test-volume "$IMAGE" - tpm2-device=auto,headless=1) + tpm2_pcrextend "12:sha256=$CURRENT_PCR_VALUE" + systemd-cryptsetup attach test-volume "$IMAGE" - tpm2-device=auto,headless=1 + systemd-cryptsetup detach test-volume + + rm -f /tmp/pcr.dat +fi + +# Use default (0) seal key handle +systemd-cryptenroll --wipe-slot=tpm2 "$IMAGE" +PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-seal-key-handle=0 "$IMAGE" +systemd-cryptsetup attach test-volume "$IMAGE" - tpm2-device=auto,headless=1 +systemd-cryptsetup detach test-volume + +systemd-cryptenroll --wipe-slot=tpm2 "$IMAGE" +PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-seal-key-handle=0x0 "$IMAGE" +systemd-cryptsetup attach test-volume "$IMAGE" - tpm2-device=auto,headless=1 +systemd-cryptsetup detach test-volume + +# Use SRK seal key handle +systemd-cryptenroll --wipe-slot=tpm2 "$IMAGE" +PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-seal-key-handle=81000001 "$IMAGE" +systemd-cryptsetup attach test-volume "$IMAGE" - tpm2-device=auto,headless=1 +systemd-cryptsetup detach test-volume + +systemd-cryptenroll --wipe-slot=tpm2 "$IMAGE" +PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-seal-key-handle=0x81000001 "$IMAGE" +systemd-cryptsetup attach test-volume "$IMAGE" - tpm2-device=auto,headless=1 +systemd-cryptsetup detach test-volume + +# Test invalid ranges: pcr, nv, session, permanent +systemd-cryptenroll --wipe-slot=tpm2 "$IMAGE" +(! PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-seal-key-handle=7 "$IMAGE") # PCR +(! PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-seal-key-handle=0x01000001 "$IMAGE") # NV index +(! PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-seal-key-handle=0x02000001 "$IMAGE") # HMAC/loaded session +(! PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-seal-key-handle=0x03000001 "$IMAGE") # Policy/saved session +(! PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-seal-key-handle=0x40000001 "$IMAGE") # Permanent + +# Use non-SRK persistent seal key handle (by creating/persisting new key) +PRIMARY=/tmp/primary.ctx +tpm2_createprimary -c "$PRIMARY" +PERSISTENT_LINE=$(tpm2_evictcontrol -c "$PRIMARY" | grep persistent-handle) +PERSISTENT="0x${PERSISTENT_LINE##*0x}" +tpm2_flushcontext -t + +systemd-cryptenroll --wipe-slot=tpm2 "$IMAGE" +PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-seal-key-handle="${PERSISTENT#0x}" "$IMAGE" +systemd-cryptsetup attach test-volume "$IMAGE" - tpm2-device=auto,headless=1 +systemd-cryptsetup detach test-volume + +systemd-cryptenroll --wipe-slot=tpm2 "$IMAGE" +PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-seal-key-handle="$PERSISTENT" "$IMAGE" +systemd-cryptsetup attach test-volume "$IMAGE" - tpm2-device=auto,headless=1 +systemd-cryptsetup detach test-volume + +rm -f "$IMAGE" "$PRIMARY" diff --git a/test/units/testsuite-70.measure.sh b/test/units/testsuite-70.measure.sh new file mode 100755 index 00000000000..3336f383305 --- /dev/null +++ b/test/units/testsuite-70.measure.sh @@ -0,0 +1,130 @@ +#!/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_MEASURE="/usr/lib/systemd/systemd-measure" + +if [[ ! -x "${SD_MEASURE:?}" ]]; then + echo "$SD_MEASURE not found, skipping the test" + exit 0 +fi + +IMAGE="$(mktemp /tmp/systemd-measure-XXX.image)" + +echo HALLO >/tmp/tpmdata1 +echo foobar >/tmp/tpmdata2 + +cat >/tmp/result </tmp/result.json </tmp/result </tmp/result.json </dev/null; then + MEASURE_BANKS+=("--bank=sha1") +fi + +# Sign current PCR state with it +"$SD_MEASURE" sign --current "${MEASURE_BANKS[@]}" --private-key="/tmp/pcrsign-private.pem" --public-key="/tmp/pcrsign-public.pem" --phase=: | tee "/tmp/pcrsign.sig" +dd if=/dev/urandom of=/tmp/pcrtestdata bs=1024 count=64 +systemd-creds encrypt /tmp/pcrtestdata /tmp/pcrtestdata.encrypted --with-key=host+tpm2-with-public-key --tpm2-public-key="/tmp/pcrsign-public.pem" +systemd-creds decrypt /tmp/pcrtestdata.encrypted - --tpm2-signature="/tmp/pcrsign.sig" | cmp - /tmp/pcrtestdata + +# Invalidate PCR, decrypting should fail now +tpm2_pcrextend 11:sha256=0000000000000000000000000000000000000000000000000000000000000000 +(! systemd-creds decrypt /tmp/pcrtestdata.encrypted - --tpm2-signature="/tmp/pcrsign.sig" >/dev/null) + +# Sign new PCR state, decrypting should work now. +"$SD_MEASURE" sign --current "${MEASURE_BANKS[@]}" --private-key="/tmp/pcrsign-private.pem" --public-key="/tmp/pcrsign-public.pem" --phase=: >"/tmp/pcrsign.sig2" +systemd-creds decrypt /tmp/pcrtestdata.encrypted - --tpm2-signature="/tmp/pcrsign.sig2" | cmp - /tmp/pcrtestdata + +# Now, do the same, but with a cryptsetup binding +truncate -s 20M "$IMAGE" +cryptsetup luksFormat -q --pbkdf pbkdf2 --pbkdf-force-iterations 1000 --use-urandom "$IMAGE" /tmp/passphrase +# Ensure that an unrelated signature, when not requested, is not used +touch /run/systemd/tpm2-pcr-signature.json +systemd-cryptenroll --unlock-key-file=/tmp/passphrase --tpm2-device=auto --tpm2-public-key="/tmp/pcrsign-public.pem" "$IMAGE" +# Reset and use the signature now +rm -f /run/systemd/tpm2-pcr-signature.json +systemd-cryptenroll --wipe-slot=tpm2 "$IMAGE" +systemd-cryptenroll --unlock-key-file=/tmp/passphrase --tpm2-device=auto --tpm2-public-key="/tmp/pcrsign-public.pem" --tpm2-signature="/tmp/pcrsign.sig2" "$IMAGE" + +# Check if we can activate that (without the token module stuff) +SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 systemd-cryptsetup attach test-volume2 "$IMAGE" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1 +SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 systemd-cryptsetup detach test-volume2 + +# Check if we can activate that (and a second time with the token module stuff enabled) +SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 systemd-cryptsetup attach test-volume2 "$IMAGE" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1 +SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 systemd-cryptsetup detach test-volume2 + +# After extending the PCR things should fail +tpm2_pcrextend 11:sha256=0000000000000000000000000000000000000000000000000000000000000000 +(! SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 systemd-cryptsetup attach test-volume2 "$IMAGE" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1) +(! SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 systemd-cryptsetup attach test-volume2 "$IMAGE" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1) + +# But once we sign the current PCRs, we should be able to unlock again +"$SD_MEASURE" sign --current "${MEASURE_BANKS[@]}" --private-key="/tmp/pcrsign-private.pem" --public-key="/tmp/pcrsign-public.pem" --phase=: >"/tmp/pcrsign.sig3" +SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 systemd-cryptsetup attach test-volume2 "$IMAGE" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig3",headless=1 +systemd-cryptsetup detach test-volume2 +SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 systemd-cryptsetup attach test-volume2 "$IMAGE" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig3",headless=1 +systemd-cryptsetup detach test-volume2 + +# Test --append mode and de-duplication. With the same parameters signing should not add a new entry +"$SD_MEASURE" sign --current "${MEASURE_BANKS[@]}" --private-key="/tmp/pcrsign-private.pem" --public-key="/tmp/pcrsign-public.pem" --phase=: --append="/tmp/pcrsign.sig3" >"/tmp/pcrsign.sig4" +cmp "/tmp/pcrsign.sig3" "/tmp/pcrsign.sig4" + +# Sign one more phase, this should +"$SD_MEASURE" sign --current "${MEASURE_BANKS[@]}" --private-key="/tmp/pcrsign-private.pem" --public-key="/tmp/pcrsign-public.pem" --phase=quux:waldo --append="/tmp/pcrsign.sig4" >"/tmp/pcrsign.sig5" +(! cmp "/tmp/pcrsign.sig4" "/tmp/pcrsign.sig5") + +# Should still be good to unlock, given the old entry still exists +SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 systemd-cryptsetup attach test-volume2 "$IMAGE" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig5",headless=1 +systemd-cryptsetup detach test-volume2 + +# Adding both signatures once more should not change anything, due to the deduplication +"$SD_MEASURE" sign --current "${MEASURE_BANKS[@]}" --private-key="/tmp/pcrsign-private.pem" --public-key="/tmp/pcrsign-public.pem" --phase=: --append="/tmp/pcrsign.sig5" >"/tmp/pcrsign.sig6" +"$SD_MEASURE" sign --current "${MEASURE_BANKS[@]}" --private-key="/tmp/pcrsign-private.pem" --public-key="/tmp/pcrsign-public.pem" --phase=quux:waldo --append="/tmp/pcrsign.sig6" >"/tmp/pcrsign.sig7" +cmp "/tmp/pcrsign.sig5" "/tmp/pcrsign.sig7" + +rm -f "$IMAGE" diff --git a/test/units/testsuite-70.pcrextend.sh b/test/units/testsuite-70.pcrextend.sh new file mode 100755 index 00000000000..0c391626c2c --- /dev/null +++ b/test/units/testsuite-70.pcrextend.sh @@ -0,0 +1,58 @@ +#!/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" + +if [[ ! -x "${SD_PCREXTEND:?}" ]] || ! tpm_has_pcr sha256 11 || ! tpm_has_pcr sha256 15; then + echo "$SD_PCREXTEND or PCR sysfs files not found, skipping PCR extension tests" + exit 0 +fi + +# Let's measure the machine ID +tpm2_pcrread sha256:15 -Q -o /tmp/oldpcr15 +mv /etc/machine-id /etc/machine-id.save +echo 994013bf23864ee7992eab39a96dd3bb >/etc/machine-id +SYSTEMD_FORCE_MEASURE=1 "$SD_PCREXTEND" --machine-id +mv /etc/machine-id.save /etc/machine-id +tpm2_pcrread sha256:15 -Q -o /tmp/newpcr15 + +# And check it matches expectations +diff /tmp/newpcr15 \ + <(cat /tmp/oldpcr15 <(echo -n "machine-id:994013bf23864ee7992eab39a96dd3bb" | openssl dgst -binary -sha256) | openssl dgst -binary -sha256) + +rm -f /tmp/oldpcr15 /tmp/newpcr15 + +# Check that the event log record was properly written: +test "$(jq --seq --slurp '.[0].pcr' < /run/log/systemd/tpm2-measure.log)" == "$(printf '\x1e15')" +test "$(jq --seq --slurp --raw-output '.[0].digests[1].digest' < /run/log/systemd/tpm2-measure.log) *stdin" == "$(echo -n "machine-id:994013bf23864ee7992eab39a96dd3bb" | openssl dgst -hex -sha256 -r)" + +# And similar for the boot phase measurement into PCR 11 +tpm2_pcrread sha256:11 -Q -o /tmp/oldpcr11 +# Do the equivalent of 'SYSTEMD_FORCE_MEASURE=1 "$SD_PCREXTEND" foobar' via Varlink, just to test the Varlink logic (but first we need to patch out the conditionalization...) +mkdir -p /run/systemd/system/systemd-pcrextend.socket.d +cat > /run/systemd/system/systemd-pcrextend.socket.d/50-no-condition.conf </tmp/passphrase -# Change file mode to avoid "/tmp/passphrase has 0644 mode that is too permissive" messages -chmod 0600 /tmp/passphrase -cryptsetup luksFormat -q --pbkdf pbkdf2 --pbkdf-force-iterations 1000 --use-urandom "$img" /tmp/passphrase - -# Unlocking via keyfile -systemd-cryptenroll --unlock-key-file=/tmp/passphrase --tpm2-device=auto "$img" - -# Enroll unlock with default PCR policy -PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto "$img" -systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1 -systemd-cryptsetup detach test-volume - -# Check with wrong PCR -tpm2_pcrextend 7:sha256=0000000000000000000000000000000000000000000000000000000000000000 -(! systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1) - -# Enroll unlock with PCR+PIN policy -systemd-cryptenroll --wipe-slot=tpm2 "$img" -PASSWORD=passphrase NEWPIN=123456 systemd-cryptenroll --tpm2-device=auto --tpm2-with-pin=true "$img" -PIN=123456 systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1 -systemd-cryptsetup detach test-volume - -# Check failure with wrong PIN; try a few times to make sure we avoid DA lockout -for _ in {0..3}; do - tpm_check_failure_with_wrong_pin "$img" 123457 123456 -done - -# Check LUKS2 token plugin unlock (i.e. without specifying tpm2-device=auto) -if cryptsetup_has_token_plugin_support; then - PIN=123456 systemd-cryptsetup attach test-volume "$img" - headless=1 - systemd-cryptsetup detach test-volume - - # Check failure with wrong PIN - for _ in {0..3}; do - tpm_check_failure_with_wrong_pin "$img" 123457 123456 - done -else - echo 'cryptsetup has no LUKS2 token plugin support, skipping' -fi - -# Check failure with wrong PCR (and correct PIN) -tpm2_pcrextend 7:sha256=0000000000000000000000000000000000000000000000000000000000000000 -(! PIN=123456 systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1) - -# Enroll unlock with PCR 0+7 -systemd-cryptenroll --wipe-slot=tpm2 "$img" -PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 "$img" -systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1 -systemd-cryptsetup detach test-volume - -# Check with wrong PCR 0 -tpm2_pcrextend 0:sha256=0000000000000000000000000000000000000000000000000000000000000000 -(! systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1) - -if tpm_has_pcr sha256 12; then - # Enroll using an explicit PCR value (that does match current PCR value) - systemd-cryptenroll --wipe-slot=tpm2 "$img" - EXPECTED_PCR_VALUE=$(cat /sys/class/tpm/tpm0/pcr-sha256/12) - PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs="12:sha256=$EXPECTED_PCR_VALUE" "$img" - systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1 - systemd-cryptsetup detach test-volume - - # Same as above plus more PCRs without the value or alg specified - systemd-cryptenroll --wipe-slot=tpm2 "$img" - EXPECTED_PCR_VALUE=$(cat /sys/class/tpm/tpm0/pcr-sha256/12) - PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs="1,12:sha256=$EXPECTED_PCR_VALUE,3" "$img" - systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1 - systemd-cryptsetup detach test-volume - - # Same as above plus more PCRs with hash alg specified but hash value not specified - systemd-cryptenroll --wipe-slot=tpm2 "$img" - EXPECTED_PCR_VALUE=$(cat /sys/class/tpm/tpm0/pcr-sha256/12) - PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs="1:sha256,12:sha256=$EXPECTED_PCR_VALUE,3" "$img" - systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1 - systemd-cryptsetup detach test-volume - - # Now the interesting part, enrolling using a hash value that doesn't match the current PCR value - systemd-cryptenroll --wipe-slot=tpm2 "$img" - tpm2_pcrread -Q -o /tmp/pcr.dat sha256:12 - CURRENT_PCR_VALUE=$(cat /sys/class/tpm/tpm0/pcr-sha256/12) - EXPECTED_PCR_VALUE=$(cat /tmp/pcr.dat /tmp/pcr.dat | openssl dgst -sha256 -r | cut -d ' ' -f 1) - PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs="12:sha256=$EXPECTED_PCR_VALUE" "$img" - (! systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1) - tpm2_pcrextend "12:sha256=$CURRENT_PCR_VALUE" - systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1 - systemd-cryptsetup detach test-volume - - rm -f /tmp/pcr.dat -fi - -# Use default (0) seal key handle -systemd-cryptenroll --wipe-slot=tpm2 "$img" -PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-seal-key-handle=0 "$img" -systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1 -systemd-cryptsetup detach test-volume - -systemd-cryptenroll --wipe-slot=tpm2 "$img" -PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-seal-key-handle=0x0 "$img" -systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1 -systemd-cryptsetup detach test-volume - -# Use SRK seal key handle -systemd-cryptenroll --wipe-slot=tpm2 "$img" -PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-seal-key-handle=81000001 "$img" -systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1 -systemd-cryptsetup detach test-volume - -systemd-cryptenroll --wipe-slot=tpm2 "$img" -PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-seal-key-handle=0x81000001 "$img" -systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1 -systemd-cryptsetup detach test-volume - -# Test invalid ranges: pcr, nv, session, permanent -systemd-cryptenroll --wipe-slot=tpm2 "$img" -(! PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-seal-key-handle=7 "$img") # PCR -(! PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-seal-key-handle=0x01000001 "$img") # NV index -(! PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-seal-key-handle=0x02000001 "$img") # HMAC/loaded session -(! PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-seal-key-handle=0x03000001 "$img") # Policy/saved session -(! PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-seal-key-handle=0x40000001 "$img") # Permanent - -# Use non-SRK persistent seal key handle (by creating/persisting new key) -primary=/tmp/primary.ctx -tpm2_createprimary -c "$primary" -persistent_line=$(tpm2_evictcontrol -c "$primary" | grep persistent-handle) -persistent="0x${persistent_line##*0x}" -tpm2_flushcontext -t - -systemd-cryptenroll --wipe-slot=tpm2 "$img" -PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-seal-key-handle="${persistent#0x}" "$img" -systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1 -systemd-cryptsetup detach test-volume - -systemd-cryptenroll --wipe-slot=tpm2 "$img" -PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-seal-key-handle="$persistent" "$img" -systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1 -systemd-cryptsetup detach test-volume - -tpm2_evictcontrol -c "$persistent" -persistent="" -rm -f "$primary" - -rm -f "${img:?}" - -if [[ -x "$SD_MEASURE" ]]; then - echo HALLO >/tmp/tpmdata1 - echo foobar >/tmp/tpmdata2 - - cat >/tmp/result </tmp/result.json </tmp/result </tmp/result.json </dev/null; then - MEASURE_BANKS+=("--bank=sha1") - fi - - # Sign current PCR state with it - "$SD_MEASURE" sign --current "${MEASURE_BANKS[@]}" --private-key="/tmp/pcrsign-private.pem" --public-key="/tmp/pcrsign-public.pem" --phase=: | tee "/tmp/pcrsign.sig" - dd if=/dev/urandom of=/tmp/pcrtestdata bs=1024 count=64 - systemd-creds encrypt /tmp/pcrtestdata /tmp/pcrtestdata.encrypted --with-key=host+tpm2-with-public-key --tpm2-public-key="/tmp/pcrsign-public.pem" - systemd-creds decrypt /tmp/pcrtestdata.encrypted - --tpm2-signature="/tmp/pcrsign.sig" | cmp - /tmp/pcrtestdata - - # Invalidate PCR, decrypting should fail now - tpm2_pcrextend 11:sha256=0000000000000000000000000000000000000000000000000000000000000000 - (! systemd-creds decrypt /tmp/pcrtestdata.encrypted - --tpm2-signature="/tmp/pcrsign.sig" >/dev/null) - - # Sign new PCR state, decrypting should work now. - "$SD_MEASURE" sign --current "${MEASURE_BANKS[@]}" --private-key="/tmp/pcrsign-private.pem" --public-key="/tmp/pcrsign-public.pem" --phase=: >"/tmp/pcrsign.sig2" - systemd-creds decrypt /tmp/pcrtestdata.encrypted - --tpm2-signature="/tmp/pcrsign.sig2" | cmp - /tmp/pcrtestdata - - # Now, do the same, but with a cryptsetup binding - truncate -s 20M "$img" - cryptsetup luksFormat -q --pbkdf pbkdf2 --pbkdf-force-iterations 1000 --use-urandom "$img" /tmp/passphrase - # Ensure that an unrelated signature, when not requested, is not used - touch /run/systemd/tpm2-pcr-signature.json - systemd-cryptenroll --unlock-key-file=/tmp/passphrase --tpm2-device=auto --tpm2-public-key="/tmp/pcrsign-public.pem" "$img" - # Reset and use the signature now - rm -f /run/systemd/tpm2-pcr-signature.json - systemd-cryptenroll --wipe-slot=tpm2 "$img" - systemd-cryptenroll --unlock-key-file=/tmp/passphrase --tpm2-device=auto --tpm2-public-key="/tmp/pcrsign-public.pem" --tpm2-signature="/tmp/pcrsign.sig2" "$img" - - # Check if we can activate that (without the token module stuff) - SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 systemd-cryptsetup attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1 - SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 systemd-cryptsetup detach test-volume2 - - # Check if we can activate that (and a second time with the token module stuff enabled) - SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 systemd-cryptsetup attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1 - SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 systemd-cryptsetup detach test-volume2 - - # After extending the PCR things should fail - tpm2_pcrextend 11:sha256=0000000000000000000000000000000000000000000000000000000000000000 - (! SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 systemd-cryptsetup attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1) - (! SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 systemd-cryptsetup attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1) - - # But once we sign the current PCRs, we should be able to unlock again - "$SD_MEASURE" sign --current "${MEASURE_BANKS[@]}" --private-key="/tmp/pcrsign-private.pem" --public-key="/tmp/pcrsign-public.pem" --phase=: >"/tmp/pcrsign.sig3" - SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 systemd-cryptsetup attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig3",headless=1 - systemd-cryptsetup detach test-volume2 - SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 systemd-cryptsetup attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig3",headless=1 - systemd-cryptsetup detach test-volume2 - - # Test --append mode and de-duplication. With the same parameters signing should not add a new entry - "$SD_MEASURE" sign --current "${MEASURE_BANKS[@]}" --private-key="/tmp/pcrsign-private.pem" --public-key="/tmp/pcrsign-public.pem" --phase=: --append="/tmp/pcrsign.sig3" >"/tmp/pcrsign.sig4" - cmp "/tmp/pcrsign.sig3" "/tmp/pcrsign.sig4" - - # Sign one more phase, this should - "$SD_MEASURE" sign --current "${MEASURE_BANKS[@]}" --private-key="/tmp/pcrsign-private.pem" --public-key="/tmp/pcrsign-public.pem" --phase=quux:waldo --append="/tmp/pcrsign.sig4" >"/tmp/pcrsign.sig5" - (! cmp "/tmp/pcrsign.sig4" "/tmp/pcrsign.sig5") - - # Should still be good to unlock, given the old entry still exists - SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 systemd-cryptsetup attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig5",headless=1 - systemd-cryptsetup detach test-volume2 - - # Adding both signatures once more should not change anything, due to the deduplication - "$SD_MEASURE" sign --current "${MEASURE_BANKS[@]}" --private-key="/tmp/pcrsign-private.pem" --public-key="/tmp/pcrsign-public.pem" --phase=: --append="/tmp/pcrsign.sig5" >"/tmp/pcrsign.sig6" - "$SD_MEASURE" sign --current "${MEASURE_BANKS[@]}" --private-key="/tmp/pcrsign-private.pem" --public-key="/tmp/pcrsign-public.pem" --phase=quux:waldo --append="/tmp/pcrsign.sig6" >"/tmp/pcrsign.sig7" - cmp "/tmp/pcrsign.sig5" "/tmp/pcrsign.sig7" - - rm -f "$img" -else - echo "$SD_MEASURE or PCR sysfs files not found, skipping signed PCR policy test case" -fi - -if [[ -x "$SD_PCREXTEND" ]] && tpm_has_pcr sha256 11 && tpm_has_pcr sha256 15; then - # Let's measure the machine ID - tpm2_pcrread sha256:15 -Q -o /tmp/oldpcr15 - mv /etc/machine-id /etc/machine-id.save - echo 994013bf23864ee7992eab39a96dd3bb >/etc/machine-id - SYSTEMD_FORCE_MEASURE=1 "$SD_PCREXTEND" --machine-id - mv /etc/machine-id.save /etc/machine-id - tpm2_pcrread sha256:15 -Q -o /tmp/newpcr15 - - # And check it matches expectations - diff /tmp/newpcr15 \ - <(cat /tmp/oldpcr15 <(echo -n "machine-id:994013bf23864ee7992eab39a96dd3bb" | openssl dgst -binary -sha256) | openssl dgst -binary -sha256) - - rm -f /tmp/oldpcr15 /tmp/newpcr15 - - # Check that the event log record was properly written: - test "$(jq --seq --slurp '.[0].pcr' < /run/log/systemd/tpm2-measure.log)" == "$(printf '\x1e15')" - test "$(jq --seq --slurp --raw-output '.[0].digests[1].digest' < /run/log/systemd/tpm2-measure.log) *stdin" == "$(echo -n "machine-id:994013bf23864ee7992eab39a96dd3bb" | openssl dgst -hex -sha256 -r)" - - # And similar for the boot phase measurement into PCR 11 - tpm2_pcrread sha256:11 -Q -o /tmp/oldpcr11 - # Do the equivalent of 'SYSTEMD_FORCE_MEASURE=1 "$SD_PCREXTEND" foobar' via Varlink, just to test the Varlink logic (but first we need to patch out the conditionalization...) - mkdir -p /run/systemd/system/systemd-pcrextend.socket.d - cat > /run/systemd/system/systemd-pcrextend.socket.d/50-no-condition.conf < /tmp/testdata -systemd-creds encrypt /tmp/testdata /tmp/testdata.encrypted --with-key=tpm2 -# LoadCredentialEncrypted -systemd-run -p PrivateDevices=yes -p LoadCredentialEncrypted=testdata.encrypted:/tmp/testdata.encrypted --pipe --wait systemd-creds cat testdata.encrypted | cmp - /tmp/testdata -# SetCredentialEncrypted -systemd-run -p PrivateDevices=yes -p SetCredentialEncrypted=testdata.encrypted:"$(cat /tmp/testdata.encrypted)" --pipe --wait systemd-creds cat testdata.encrypted | cmp - /tmp/testdata -rm -f /tmp/testdata - -# There is an external issue with libcryptsetup on ppc64 that hits 95% of Ubuntu ppc64 test runs, so skip it -machine="$(uname -m)" -if [ "${machine}" = "ppc64le" ]; then - touch /testok - exit 0 -fi - -cryptenroll_wipe_and_check() {( - set +o pipefail - - : >/tmp/cryptenroll.out - systemd-cryptenroll "$@" |& tee /tmp/cryptenroll.out - grep -qE "Wiped slot [[:digit:]]+" /tmp/cryptenroll.out -)} - -img="/tmp/cryptenroll.img" -truncate -s 20M "$img" -echo -n password >/tmp/password -# Change file mode to avoid "/tmp/password has 0644 mode that is too permissive" messages -chmod 0600 /tmp/password -cryptsetup luksFormat -q --pbkdf pbkdf2 --pbkdf-force-iterations 1000 --use-urandom "$img" /tmp/password - -# Enroll additional tokens, keys, and passwords to exercise the list and wipe stuff -systemd-cryptenroll --unlock-key-file=/tmp/password --tpm2-device=auto "$img" -NEWPASSWORD="" systemd-cryptenroll --unlock-key-file=/tmp/password --password "$img" -NEWPASSWORD=foo systemd-cryptenroll --unlock-key-file=/tmp/password --password "$img" -for _ in {0..9}; do - systemd-cryptenroll --unlock-key-file=/tmp/password --recovery-key "$img" -done -PASSWORD="" NEWPIN=123456 systemd-cryptenroll --tpm2-device=auto --tpm2-with-pin=true "$img" -# Do some basic checks before we start wiping stuff -systemd-cryptenroll "$img" -systemd-cryptenroll "$img" | grep password -systemd-cryptenroll "$img" | grep recovery -# Let's start wiping -cryptenroll_wipe_and_check "$img" --wipe=empty -(! cryptenroll_wipe_and_check "$img" --wipe=empty) -cryptenroll_wipe_and_check "$img" --wipe=empty,0 -PASSWORD=foo NEWPASSWORD=foo cryptenroll_wipe_and_check "$img" --wipe=0,0,empty,0,pkcs11,fido2,000,recovery,password --password -systemd-cryptenroll "$img" | grep password -(! systemd-cryptenroll "$img" | grep recovery) -# We shouldn't be able to wipe all keyslots without enrolling a new key first -(! systemd-cryptenroll "$img" --wipe=all) -PASSWORD=foo NEWPASSWORD=foo cryptenroll_wipe_and_check "$img" --password --wipe=all -# Check if the newly (and only) enrolled password works -(! systemd-cryptenroll --unlock-key-file=/tmp/password --recovery-key "$img") -(! PASSWORD="" systemd-cryptenroll --recovery-key "$img") -PASSWORD=foo systemd-cryptenroll --recovery-key "$img" - -systemd-cryptenroll --fido2-with-client-pin=false "$img" -systemd-cryptenroll --fido2-with-user-presence=false "$img" -systemd-cryptenroll --fido2-with-user-verification=false "$img" -systemd-cryptenroll --tpm2-pcrs=8 "$img" -systemd-cryptenroll --tpm2-pcrs=boot-loader-code+boot-loader-config "$img" - -(! systemd-cryptenroll --fido2-with-client-pin=false) -(! systemd-cryptenroll --fido2-with-user-presence=f "$img" /tmp/foo) -(! systemd-cryptenroll --fido2-with-client-pin=1234 "$img") -(! systemd-cryptenroll --fido2-with-user-presence=1234 "$img") -(! systemd-cryptenroll --fido2-with-user-verification=1234 "$img") -(! systemd-cryptenroll --tpm2-with-pin=1234 "$img") -(! systemd-cryptenroll --recovery-key --password "$img") -(! systemd-cryptenroll --password --recovery-key "$img") -(! systemd-cryptenroll --password --fido2-device=auto "$img") -(! systemd-cryptenroll --password --pkcs11-token-uri=auto "$img") -(! systemd-cryptenroll --password --tpm2-device=auto "$img") -(! systemd-cryptenroll --unlock-fido2-device=auto --unlock-fido2-device=auto "$img") -(! systemd-cryptenroll --unlock-fido2-device=auto --unlock-key-file=/tmp/unlock "$img") -(! systemd-cryptenroll --fido2-credential-algorithm=es512 "$img") -(! systemd-cryptenroll --tpm2-public-key-pcrs=key "$img") -(! systemd-cryptenroll --tpm2-pcrs=key "$img") -(! systemd-cryptenroll --tpm2-pcrs=44+8 "$img") -(! systemd-cryptenroll --tpm2-pcrs=hello "$img") -(! systemd-cryptenroll --wipe-slot "$img") -(! systemd-cryptenroll --wipe-slot=10240000 "$img") -(! systemd-cryptenroll --fido2-device=auto --unlock-fido2-device=auto "$img") - -# Run this, just to get sanitizer coverage. The tools should be idempotent, hence run the multiple times. -if [[ -x "$SD_TPM2SETUP" ]]; then - "$SD_TPM2SETUP" --early=yes - "$SD_TPM2SETUP" --early=yes - "$SD_TPM2SETUP" --early=no - "$SD_TPM2SETUP" --early=no -fi - -cleanup +run_subtests touch /testok diff --git a/test/units/testsuite-70.tpm2-setup.sh b/test/units/testsuite-70.tpm2-setup.sh new file mode 100755 index 00000000000..40dce3bf2d3 --- /dev/null +++ b/test/units/testsuite-70.tpm2-setup.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -eux +set -o pipefail + +export SYSTEMD_LOG_LEVEL=debug +SD_TPM2SETUP="/usr/lib/systemd/systemd-tpm2-setup" + +if [[ ! -x "${SD_TPM2SETUP:?}" ]]; then + echo "$SD_TPM2SETUP not found, skipping the test" + exit 0 +fi + +# Run this, just to get sanitizer coverage. The tools should be idempotent, hence run the multiple times. +"$SD_TPM2SETUP" --early=yes +"$SD_TPM2SETUP" --early=yes +"$SD_TPM2SETUP" --early=no +"$SD_TPM2SETUP" --early=no diff --git a/test/units/util.sh b/test/units/util.sh index fee642fa9d8..e47d32c2b3b 100755 --- a/test/units/util.sh +++ b/test/units/util.sh @@ -182,3 +182,10 @@ cgroupfs_supports_user_xattrs() { setfattr --name="$xattr" --value=254 /sys/fs/cgroup [[ "$(getfattr --name="$xattr" --absolute-names --only-values /sys/fs/cgroup)" -eq 254 ]] } + +tpm_has_pcr() { + local algorithm="${1:?}" + local pcr="${2:?}" + + [[ -f "/sys/class/tpm/tpm0/pcr-$algorithm/$pcr" ]] +}