1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
|
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
set -ex
set -o pipefail
export SYSTEMD_LOG_LEVEL=debug
# Prepare fresh disk image
img="/var/tmp/test.img"
truncate -s 20M $img
echo -n passphrase >/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
/usr/lib/systemd/systemd-cryptsetup attach test-volume $img - tpm2-device=auto,headless=1
/usr/lib/systemd/systemd-cryptsetup detach test-volume
# Check with wrong PCR
tpm2_pcrextend 7:sha256=0000000000000000000000000000000000000000000000000000000000000000
(! /usr/lib/systemd/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 /usr/lib/systemd/systemd-cryptsetup attach test-volume $img - tpm2-device=auto,headless=1
/usr/lib/systemd/systemd-cryptsetup detach test-volume
# Check failure with wrong PIN
(! PIN=123457 /usr/lib/systemd/systemd-cryptsetup attach test-volume $img - tpm2-device=auto,headless=1)
# Check LUKS2 token plugin unlock (i.e. without specifying tpm2-device=auto)
if cryptsetup --help | grep -q 'LUKS2 external token plugin support is compiled-in' && \
[ -f "$(cryptsetup --help | sed -n -r 's/.*LUKS2 external token plugin path: (.*)\./\1/p')/libcryptsetup-token-systemd-tpm2.so" ]; then
PIN=123456 /usr/lib/systemd/systemd-cryptsetup attach test-volume $img - headless=1
/usr/lib/systemd/systemd-cryptsetup detach test-volume
# Check failure with wrong PIN
(! PIN=123457 /usr/lib/systemd/systemd-cryptsetup attach test-volume $img - headless=1)
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 /usr/lib/systemd/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
/usr/lib/systemd/systemd-cryptsetup attach test-volume $img - tpm2-device=auto,headless=1
/usr/lib/systemd/systemd-cryptsetup detach test-volume
# Check with wrong PCR 0
tpm2_pcrextend 0:sha256=0000000000000000000000000000000000000000000000000000000000000000
/usr/lib/systemd/systemd-cryptsetup attach test-volume $img - tpm2-device=auto,headless=1 && exit 1
rm $img
if [[ -e /usr/lib/systemd/systemd-measure ]]; then
echo HALLO >/tmp/tpmdata1
echo foobar >/tmp/tpmdata2
cat >/tmp/result <<EOF
11:sha1=5177e4ad69db92192c10e5f80402bf81bfec8a81
11:sha256=37b48bd0b222394dbe3cceff2fca4660c4b0a90ae9369ec90b42f14489989c13
11:sha384=5573f9b2caf55b1d0a6a701f890662d682af961899f0419cf1e2d5ea4a6a68c1f25bd4f5b8a0865eeee82af90f5cb087
11:sha512=961305d7e9981d6606d1ce97b3a9a1f92610cac033e9c39064895f0e306abc1680463d55767bd98e751eae115bdef3675a9ee1d29ed37da7885b1db45bb2555b
EOF
/usr/lib/systemd/systemd-measure calculate --linux=/tmp/tpmdata1 --initrd=/tmp/tpmdata2 --bank=sha1 --bank=sha256 --bank=sha384 --bank=sha512 --phase=: | cmp - /tmp/result
cat >/tmp/result.json <<EOF
{"sha1":[{"pcr":11,"hash":"5177e4ad69db92192c10e5f80402bf81bfec8a81"}],"sha256":[{"pcr":11,"hash":"37b48bd0b222394dbe3cceff2fca4660c4b0a90ae9369ec90b42f14489989c13"}],"sha384":[{"pcr":11,"hash":"5573f9b2caf55b1d0a6a701f890662d682af961899f0419cf1e2d5ea4a6a68c1f25bd4f5b8a0865eeee82af90f5cb087"}],"sha512":[{"pcr":11,"hash":"961305d7e9981d6606d1ce97b3a9a1f92610cac033e9c39064895f0e306abc1680463d55767bd98e751eae115bdef3675a9ee1d29ed37da7885b1db45bb2555b"}]}
EOF
/usr/lib/systemd/systemd-measure calculate --linux=/tmp/tpmdata1 --initrd=/tmp/tpmdata2 --bank=sha1 --bank=sha256 --bank=sha384 --bank=sha512 --phase=: -j | diff -u - /tmp/result.json
cat >/tmp/result <<EOF
11:sha1=6765ee305db063040c454d32697d922b3d4f232b
11:sha256=21c49c1242042649e09c156546fd7d425ccc3c67359f840507b30be4e0f6f699
11:sha384=08d0b003a134878eee552070d51d58abe942f457ca85704131dd36f73728e7327ca837594bc9d5ac7de818d02a3d5dd2
11:sha512=65120f6ebc04b156421c6f3d543b2fad545363d9ca61c514205459e9c0e0b22e09c23605eae5853e38458ef3ca54e087168af8d8a882a98d220d9391e48be6d0
EOF
/usr/lib/systemd/systemd-measure calculate --linux=/tmp/tpmdata1 --initrd=/tmp/tpmdata2 --bank=sha1 --bank=sha256 --bank=sha384 --bank=sha512 --phase=foo | cmp - /tmp/result
cat >/tmp/result.json <<EOF
{"sha1":[{"phase":"foo","pcr":11,"hash":"6765ee305db063040c454d32697d922b3d4f232b"}],"sha256":[{"phase":"foo","pcr":11,"hash":"21c49c1242042649e09c156546fd7d425ccc3c67359f840507b30be4e0f6f699"}],"sha384":[{"phase":"foo","pcr":11,"hash":"08d0b003a134878eee552070d51d58abe942f457ca85704131dd36f73728e7327ca837594bc9d5ac7de818d02a3d5dd2"}],"sha512":[{"phase":"foo","pcr":11,"hash":"65120f6ebc04b156421c6f3d543b2fad545363d9ca61c514205459e9c0e0b22e09c23605eae5853e38458ef3ca54e087168af8d8a882a98d220d9391e48be6d0"}]}
EOF
/usr/lib/systemd/systemd-measure calculate --linux=/tmp/tpmdata1 --initrd=/tmp/tpmdata2 --bank=sha1 --bank=sha256 --bank=sha384 --bank=sha512 --phase=foo -j | diff -u - /tmp/result.json
rm /tmp/result /tmp/result.json
else
echo "/usr/lib/systemd/systemd-measure not found, skipping PCR policy test case"
fi
if [ -e /usr/lib/systemd/systemd-measure ] && \
[ -f /sys/class/tpm/tpm0/pcr-sha1/11 ] && \
[ -f /sys/class/tpm/tpm0/pcr-sha256/11 ]; then
# Generate key pair
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out "/tmp/pcrsign-private.pem"
openssl rsa -pubout -in "/tmp/pcrsign-private.pem" -out "/tmp/pcrsign-public.pem"
MEASURE_BANKS=("--bank=sha256")
# Check if SHA1 signatures are supported
#
# Some distros have started phasing out SHA1, so make sure the SHA1
# signatures are supported before trying to use them.
if echo hello | openssl dgst -sign /tmp/pcrsign-private.pem -sha1 >/dev/null; then
MEASURE_BANKS+=("--bank=sha1")
fi
# Sign current PCR state with it
/usr/lib/systemd/systemd-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.
/usr/lib/systemd/systemd-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 /usr/lib/systemd/systemd-cryptsetup attach test-volume2 $img - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1
SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 /usr/lib/systemd/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 /usr/lib/systemd/systemd-cryptsetup attach test-volume2 $img - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1
SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 /usr/lib/systemd/systemd-cryptsetup detach test-volume2
# After extending the PCR things should fail
tpm2_pcrextend 11:sha256=0000000000000000000000000000000000000000000000000000000000000000
(! SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 /usr/lib/systemd/systemd-cryptsetup attach test-volume2 $img - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1)
(! SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 /usr/lib/systemd/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
/usr/lib/systemd/systemd-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 /usr/lib/systemd/systemd-cryptsetup attach test-volume2 $img - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig3",headless=1
/usr/lib/systemd/systemd-cryptsetup detach test-volume2
SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 /usr/lib/systemd/systemd-cryptsetup attach test-volume2 $img - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig3",headless=1
/usr/lib/systemd/systemd-cryptsetup detach test-volume2
# Test --append mode and de-duplication. With the same parameters signing should not add a new entry
/usr/lib/systemd/systemd-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
/usr/lib/systemd/systemd-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 /usr/lib/systemd/systemd-cryptsetup attach test-volume2 $img - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig5",headless=1
/usr/lib/systemd/systemd-cryptsetup detach test-volume2
# Adding both signatures once more should not change anything, due to the deduplication
/usr/lib/systemd/systemd-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"
/usr/lib/systemd/systemd-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 $img
else
echo "/usr/lib/systemd/systemd-measure or PCR sysfs files not found, skipping signed PCR policy test case"
fi
if [ -e /usr/lib/systemd/systemd-pcrphase ] && \
[ -f /sys/class/tpm/tpm0/pcr-sha256/11 ]; 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 /usr/lib/systemd/systemd-pcrphase --machine-id
mv /etc/machine-id.save /etc/machine-id
tpm2_pcrread sha256:15 -Q -o /tmp/newpcr15
# And check it matches expectations
( cat /tmp/oldpcr15 ;
echo -n "machine-id:994013bf23864ee7992eab39a96dd3bb" | openssl dgst -binary -sha256 ) | openssl dgst -binary -sha256 | cmp - /tmp/newpcr15
rm /tmp/oldpcr15 /tmp/newpcr15
# And similar for the boot phase measurement into PCR 11
tpm2_pcrread sha256:11 -Q -o /tmp/oldpcr11
SYSTEMD_FORCE_MEASURE=1 /usr/lib/systemd/systemd-pcrphase foobar
tpm2_pcrread sha256:11 -Q -o /tmp/newpcr11
( cat /tmp/oldpcr11 ;
echo -n "foobar" | openssl dgst -binary -sha256 ) | openssl dgst -binary -sha256 | cmp - /tmp/newpcr11
rm /tmp/oldpcr11 /tmp/newpcr11
else
echo "/usr/lib/systemd/systemd-pcrphase or PCR sysfs files not found, skipping PCR extension test case"
fi
# 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 /tmp/testdata
# negative tests for cryptenroll
# Prepare a new disk image
img_2="/var/tmp/file_enroll.txt"
truncate -s 20M $img_2
echo -n password >/tmp/password
cryptsetup luksFormat -q --pbkdf pbkdf2 --pbkdf-force-iterations 1000 --use-urandom $img_2 /tmp/password
#boolean_arguments
(! systemd-cryptenroll --fido2-with-client-pin=false)
(! systemd-cryptenroll --fido2-with-user-presence=f $img_2 /tmp/foo)
(! systemd-cryptenroll --fido2-with-client-pin=1234 $img_2)
systemd-cryptenroll --fido2-with-client-pin=false $img_2
(! systemd-cryptenroll --fido2-with-user-presence=1234 $img_2)
systemd-cryptenroll --fido2-with-user-presence=false $img_2
(! systemd-cryptenroll --fido2-with-user-verification=1234 $img_2)
(! systemd-cryptenroll --tpm2-with-pin=1234 $img_2)
systemd-cryptenroll --fido2-with-user-verification=false $img_2
#arg_enroll_type
(! systemd-cryptenroll --recovery-key --password $img_2)
(! systemd-cryptenroll --password --recovery-key $img_2)
(! systemd-cryptenroll --password --fido2-device=auto $img_2)
(! systemd-cryptenroll --password --pkcs11-token-uri=auto $img_2)
(! systemd-cryptenroll --password --tpm2-device=auto $img_2)
#arg_unlock_type
(! systemd-cryptenroll --unlock-fido2-device=auto --unlock-fido2-device=auto $img_2)
(! systemd-cryptenroll --unlock-fido2-device=auto --unlock-key-file=/tmp/unlock $img_2)
#fido2_cred_algorithm
(! systemd-cryptenroll --fido2-credential-algorithm=es512 $img_2)
#tpm2_errors
(! systemd-cryptenroll --tpm2-public-key-pcrs=key $img_2)
(! systemd-cryptenroll --tpm2-pcrs=key $img_2)
(! systemd-cryptenroll --tpm2-pcrs=44+8 $img_2)
systemd-cryptenroll --tpm2-pcrs=8 $img_2
(! systemd-cryptenroll --tpm2-pcrs=hello $img_2)
systemd-cryptenroll --tpm2-pcrs=boot-loader-code+boot-loader-config $img_2
#wipe_slots
(! systemd-cryptenroll --wipe-slot $img_2)
(! systemd-cryptenroll --wipe-slot=10240000 $img_2)
#fido2_multiple_auto
(! systemd-cryptenroll --fido2-device=auto --unlock-fido2-device=auto $img_2)
echo OK >/testok
exit 0
|