Imported Upstream version 2.6.1
[platform/upstream/cryptsetup.git] / tests / systemd-test-plugin
1 #!/bin/bash
2
3 CC="cc"
4
5 PASSWD="tpm2_test"
6 PASSWD2="tpm2_test2"
7 FAST_PBKDF_OPT="--pbkdf pbkdf2 --pbkdf-force-iterations 1000"
8 IMG=systemd_token_test.img
9 MAP="systemd_tpm2_test"
10
11 function bin_check()
12 {
13     command -v $1 >/dev/null || skip "WARNING: test require $1 binary, test skipped."
14 }
15
16 function cleanup() {
17     [ -S $SWTPM_STATE_DIR/ctrl.sock ] && {
18         # shutdown TPM via control socket
19         swtpm_ioctl -s --unix $SWTPM_STATE_DIR/ctrl.sock
20         sleep 1
21     }
22
23     # if graceful shutdown was successful, pidfile should be deleted
24     # if it is still present, we forcefully kill the process
25     [ -f "$SWTPM_PIDFILE" ] && {
26         kill -9 $(cat $SWTPM_PIDFILE) >/dev/null 2>&1
27     }
28
29     [ -b /dev/mapper/$MAP ] && dmsetup remove --retry $MAP
30
31     rm -f $SWTPM_PIDFILE >/dev/null 2>&1
32     rm -rf $SWTPM_STATE_DIR >/dev/null 2>&1
33     rm -f $IMG >/dev/null 2>&1
34 }
35
36 function fail()
37 {
38     echo "[FAILED]"
39     [ -n "$1" ] && echo "$1"
40     echo "FAILED backtrace:"
41     while caller $frame; do ((frame++)); done
42     cleanup
43     exit 2
44 }
45
46 function skip()
47 {
48     [ -n "$1" ] && echo "$1"
49     cleanup
50     exit 77
51 }
52
53 # Prevent downloading and compiling systemd by default
54 [ -z "$RUN_SYSTEMD_PLUGIN_TEST" ] && skip "WARNING: Variable RUN_SYSTEMD_PLUGIN_TEST must be defined, test skipped."
55
56 [ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped."
57 bin_check swtpm
58 bin_check swtpm_ioctl
59
60 CRYPTENROLL_LD_PRELOAD=""
61
62 # if CRYPTSETUP_PATH is defined, we run against installed binaries,
63 # otherwise we compile systemd tokens from source
64 [ -z "$CRYPTSETUP_PATH" ] && {
65     bin_check git
66     bin_check meson
67     bin_check ninja
68     bin_check pkgconf
69
70     TOKEN_PATH=fake_token_path.so
71     [ -f $TOKEN_PATH ] || skip "Please compile $TOKEN_PATH."
72     INSTALL_PATH=$(pwd)/external-tokens/install
73     make -C .. install DESTDIR=$INSTALL_PATH
74     PC_FILE="$(find $INSTALL_PATH -name 'libcryptsetup.pc')"
75     sed -i "s/^prefix=/prefix=${INSTALL_PATH//\//\\\/}/g" "$PC_FILE"
76     export PKG_CONFIG_PATH=$(dirname $PC_FILE)
77
78     # systemd build system misses libcryptsetup.h if it is installed in non-default path
79     export CFLAGS="${CFLAGS:-} $(pkgconf --cflags libcryptsetup)"
80
81     SYSTEMD_PATH=$(pwd)/external-tokens/systemd
82     CRYPTSETUP_PATH=$(pwd)/..
83     SYSTEMD_CRYPTENROLL=$SYSTEMD_PATH/build/systemd-cryptenroll
84
85     mkdir -p $SYSTEMD_PATH
86     [ "$(ls -A $SYSTEMD_PATH)" ] || git clone --depth=1 https://github.com/systemd/systemd.git $SYSTEMD_PATH
87     cd $SYSTEMD_PATH
88     meson -D tpm2=true -D libcryptsetup=true -D libcryptsetup-plugins=true build/ || skip "Failed to configure systemd via meson, some dependencies are probably missing."
89     ninja -C build/ systemd-cryptenroll libcryptsetup-token-systemd-tpm2.so || skip "Failed to build systemd."
90
91     cd $CRYPTSETUP_PATH/tests
92     cp $SYSTEMD_PATH/build/libcryptsetup-token-*.so ../.libs/
93     cp $SYSTEMD_PATH/build/src/shared/*.so ../.libs/
94
95     export LD_PRELOAD="${LD_PRELOAD-}:$CRYPTSETUP_PATH/tests/$TOKEN_PATH"
96     CRYPTENROLL_LD_PRELOAD="$CRYPTSETUP_PATH/.libs/libcryptsetup.so"
97 }
98 CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup
99 [ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped."
100
101 [ -z "$SYSTEMD_CRYPTENROLL" ] && {
102     bin_check systemd-cryptenroll
103     SYSTEMD_CRYPTENROLL="systemd-cryptenroll"
104 }
105
106 [ -z "$TPM_PATH" ] && {
107     echo "Setting up virtual TPM using swtpm..."
108     SWTPM_PIDFILE=$(mktemp /tmp/systemd_swtpm_pid.XXXXXX)
109     SWTPM_STATE_DIR=$(mktemp -d /tmp/systemd_swtpm_state.XXXXXX)
110     modprobe tpm_vtpm_proxy || skip "Failed to load tpm_vtpm_proxy kernel module, required for emulated TPM."
111     SWTPM_LOG=$(swtpm chardev --vtpm-proxy --tpm2 --tpmstate dir=$SWTPM_STATE_DIR -d --pid file=$SWTPM_PIDFILE --ctrl type=unixio,path=$SWTPM_STATE_DIR/ctrl.sock)
112     TPM_PATH=$(echo $SWTPM_LOG | grep -Eo '/dev/tpm([0-9])+' | sed 's/tpm/tpmrm/')
113     [ -z "$TPM_PATH" ] && skip "No TPM_PATH set and swtpm failed, test skipped."
114     sleep 1
115     echo "Virtual TPM set up at $TPM_PATH"
116 }
117
118 FAKE_TPM_PATH="$(pwd)/fake_systemd_tpm_path.so"
119 [ -f $FAKE_TPM_PATH ] || skip "Please compile $FAKE_TPM_PATH."
120 export LD_PRELOAD="$LD_PRELOAD:$FAKE_TPM_PATH"
121
122 export TPM_PATH=$TPM_PATH
123 echo "TPM path is $TPM_PATH"
124
125 dd if=/dev/zero of=$IMG bs=1M count=32 >/dev/null 2>&1
126 echo $PASSWD | $CRYPTSETUP luksFormat --type luks2 $FAST_PBKDF_OPT $IMG --force-password -q
127
128 echo "Enrolling the device to TPM 2 using systemd-cryptenroll.."
129 LD_PRELOAD="$LD_PRELOAD:$CRYPTENROLL_LD_PRELOAD" PASSWORD="$PASSWD" $SYSTEMD_CRYPTENROLL $IMG --tpm2-device=$TPM_PATH >/dev/null 2>&1
130
131 $CRYPTSETUP luksDump $IMG | grep -q "tpm2-blob" || fail "Failed to dump $IMG using systemd_tpm2 token (no tpm2-blob in output)."
132 echo "Activating the device via TPM2 external token.."
133 $CRYPTSETUP open --token-only $IMG $MAP >/dev/null 2>&1 || fail "Failed to open $IMG using systemd_tpm2 token."
134 $CRYPTSETUP close $MAP >/dev/null 2>&1 || fail "Failed to close $MAP."
135
136 echo "Adding passphrase via TPM2 token.."
137 echo $PASSWD2 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $IMG --force-password -q --token-only >/dev/null 2>&1 || fail "Failed to add passphrase by tpm2 token."
138 echo $PASSWD2 | $CRYPTSETUP open $IMG --test-passphrase --disable-external-tokens >/dev/null 2>&1 || fail "Failed to test passphrase added by tpm2 token."
139
140 echo "Exporting and removing TPM2 token.."
141 EXPORTED_TOKEN=$($CRYPTSETUP token export $IMG --token-id 0)
142 $CRYPTSETUP token remove $IMG --token-id 0
143 $CRYPTSETUP open $IMG --test-passphrase --token-only >/dev/null 2>&1 && fail "Activating without passphrase should fail after TPM2 token removal."
144
145 echo "Re-importing TPM2 token.."
146 echo $EXPORTED_TOKEN | $CRYPTSETUP token import $IMG --token-id 0 || fail "Failed to re-import deleted token."
147 $CRYPTSETUP open $IMG --test-passphrase --token-only >/dev/null 2>&1 || fail "Failed to activate after re-importing deleted token."
148
149 cleanup
150 exit 0