]> git.proxmox.com Git - swtpm.git/blob - tests/test_tpm2_ctrlchannel2
tests: Apply patches to IBM TSS2 test suite
[swtpm.git] / tests / test_tpm2_ctrlchannel2
1 #!/usr/bin/env bash
2
3 # For the license, see the LICENSE file in the root directory.
4
5 ROOT=${abs_top_builddir:-$(dirname "$0")/..}
6 TESTDIR=${abs_top_testdir:-$(dirname "$0")}
7
8 SWTPM=swtpm
9 SWTPM_EXE=${SWTPM_EXE:-$ROOT/src/swtpm/$SWTPM}
10 SWTPM_IOCTL=${SWTPM_IOCTL:-$ROOT/src/swtpm_ioctl/swtpm_ioctl}
11 TPMDIR=`mktemp -d`
12 PID_FILE=$TPMDIR/${SWTPM}.pid
13 SOCK_PATH=$TPMDIR/sock
14 CMD_PATH=$TPMDIR/cmd
15 RESP_PATH=$TPMDIR/resp
16 LOGFILE=$TPMDIR/logfile
17 VOLATILESTATE=$TPMDIR/volatile
18
19 source ${TESTDIR}/common
20 source ${TESTDIR}/test_common
21
22 trap "cleanup" SIGTERM EXIT
23
24 function cleanup()
25 {
26 rm -rf $TPMDIR
27 if [ -n "$PID" ]; then
28 kill_quiet -SIGTERM $PID 2>/dev/null
29 fi
30 }
31
32 # Test 1: test the control channel on the chardev tpm
33 if [ $(id -u) -eq 0 ]; then
34 FOWNER=",uid=$(id -u nobody),gid=$(id -G nobody | cut -d" " -f1)"
35 FILEOWNER="$(id -u nobody) $(id -G nobody | cut -d" " -f1)"
36 fi
37
38 # make sure --print-capabiities exits with '0'
39 msg=$($SWTPM_EXE chardev --print-capabilities 2>&1)
40 if [ $? -ne 0 ]; then
41 echo "Error: swtpm chardev --print-capabilities failed"
42 echo "$msg"
43 exit 1
44 fi
45
46 FILEMODE=621
47 # use a pseudo terminal
48 exec 100<>/dev/ptmx
49 $SWTPM_EXE chardev \
50 --fd 100 \
51 --tpmstate dir=$TPMDIR \
52 --pid file=$PID_FILE \
53 --ctrl type=unixio,path=$SOCK_PATH,mode=${FILEMODE}${FOWNER} \
54 --tpm2 \
55 ${SWTPM_TEST_SECCOMP_OPT} &
56 PID=$!
57
58 if wait_for_file $PID_FILE 3; then
59 echo "Error: Chardev TPM did not write pidfile."
60 exit 1
61 fi
62
63 validate_pidfile $PID $PID_FILE
64
65 # Get the capability bits: CMD_GET_CAPABILITY = 0x00 00 00 01
66 act=$($SWTPM_IOCTL --unix $SOCK_PATH -c 2>&1)
67 if [ $? -ne 0 ]; then
68 echo "Error: $SWTPM_IOCTL CMD_GET_CAPABILITY failed: $act"
69 exit 1
70 fi
71
72 filemode=$(get_filemode $SOCK_PATH)
73 if [ "$filemode" != "$FILEMODE" ]; then
74 echo "Filemode bits are wrong"
75 echo "Expected: $FILEMODE"
76 echo "Actual : $filemode"
77 exit 1
78 fi
79
80 fileowner=$(get_fileowner $SOCK_PATH)
81 if [ -n "$FILEOWNER" ] && [ "$fileowner" != "$FILEOWNER" ]; then
82 echo "File ownership is wrong"
83 echo "Expected: $FILEOWNER"
84 echo "Actual : $fileowner"
85 exit 1
86 fi
87
88 exp="ptm capability is 0x([[:xdigit:]]+)"
89 if ! [[ "$act" =~ ^${exp}$ ]]; then
90 echo "Error: Expected string following regular expression '$exp' from ioctl tool but got '$act'."
91 exit 1
92 fi
93
94 # Send TPM_Init to the TPM: CMD_INIT = 0x00 00 00 02 + flags
95 act=$($SWTPM_IOCTL --unix $SOCK_PATH -i 2>&1)
96 if [ $? -ne 0 ]; then
97 echo "Error: $SWTPM_IOCTL CMD_INIT failed: $act"
98 exit 1
99 fi
100
101 # Save the volatile state: CMD_STORE_VOLATILE = 0x00 00 00 0a
102 act=$($SWTPM_IOCTL --unix $SOCK_PATH -v 2>&1)
103 if [ $? -ne 0 ]; then
104 echo "Error: $SWTPM_IOCTL CMD_STORE_VOLATILE failed: $act"
105 exit 1
106 fi
107
108 if [ ! -r $TPMDIR/tpm2-00.volatilestate ]; then
109 echo "Error: Socket TPM: Did not write volatile state file"
110 exit 1
111 fi
112
113 # Send stop command to the TPM: CMD_STOP = 00 00 00 0e
114 act=$($SWTPM_IOCTL --unix $SOCK_PATH --stop 2>&1)
115 if [ $? -ne 0 ]; then
116 echo "Error: $SWTPM_IOCTL CMD_STOP failed: $act"
117 exit 1
118 fi
119
120 # Send get config command to the TPM: CMD_GET_CONFIG = 00 00 00 0f
121 act=$($SWTPM_IOCTL --unix $SOCK_PATH -g 2>&1)
122 if [ $? -ne 0 ]; then
123 echo "Error: $SWTPM_IOCTL CMD_GET_CONFIG failed: $act"
124 exit 1
125 fi
126
127 exp="ptm configuration flags: 0x([[:xdigit:]]+)"
128 if ! [[ "$act" =~ ^${exp}$ ]]; then
129 echo "Error: Expected string following regular expression '$exp' from ioctl tool but got '$act'."
130 exit 1
131 fi
132
133 # Send shutdown command to the TPM: CMD_SHUTDOWN = 00 00 00 03
134 act=$($SWTPM_IOCTL --unix $SOCK_PATH -s 2>&1)
135 if [ $? -ne 0 ]; then
136 echo "Error: $SWTPM_IOCTL CMD_SHUTDOWN failed: $act"
137 exit 1
138 fi
139
140 if wait_file_gone $PID_FILE 2; then
141 echo "Error: TPM should have removed PID file by now."
142 exit 1
143 fi
144
145 if wait_process_gone ${PID} 4; then
146 echo "Error: TPM should not be running anymore."
147 exit 1
148 fi
149
150 echo "OK"
151
152 # Test 2: test the control channel on the socket tpm
153
154 # There are a few more tests here that require sending commands to the TPM
155
156 # use a pseudo terminal
157 $SWTPM_EXE socket \
158 --server port=65532,disconnect=true \
159 --tpmstate dir=$TPMDIR \
160 --pid file=$PID_FILE \
161 --ctrl type=unixio,path=$SOCK_PATH \
162 --log file=$LOGFILE,level=20 \
163 --tpm2 \
164 --flags startup-clear \
165 ${SWTPM_TEST_SECCOMP_OPT} &
166 PID=$!
167
168 if wait_for_file $PID_FILE 3; then
169 echo "Error: Socket TPM did not write pidfile."
170 exit 1
171 fi
172
173 validate_pidfile $PID $PID_FILE
174
175 exec 100<>/dev/tcp/localhost/65532
176
177 # Get the capability bits: CMD_GET_CAPABILITY = 0x00 00 00 01
178 act=$($SWTPM_IOCTL --unix $SOCK_PATH -c 2>&1)
179 if [ $? -ne 0 ]; then
180 echo "Error: $SWTPM_IOCTL CMD_GET_CAPABILITY failed: $act"
181 exit 1
182 fi
183
184 exp="ptm capability is 0x([[:xdigit:]]+)"
185 if ! [[ "$act" =~ ^${exp}$ ]]; then
186 echo "Error: Expected string following regular expression '$exp' from ioctl tool but got '$act'."
187 exit 1
188 fi
189
190 # Startup the TPM; we used --flags startup-clear so expect this to fail now with 0x100
191 echo -en '\x80\x01\x00\x00\x00\x0c\x00\x00\x01\x44\x00\x00' >&100
192 RES=$(cat <&100 | od -t x1 -A n)
193 exp=' 80 01 00 00 00 0a 00 00 01 00'
194 if [ "$RES" != "$exp" ]; then
195 echo "Error: Did not get expected result from TPM_Startup(SU_Clear)"
196 echo "expected: $exp"
197 echo "received: $RES"
198 exit 1
199 fi
200
201 # Save the volatile state: CMD_STORE_VOLATILE = 0x00 00 00 0a
202 act=$($SWTPM_IOCTL --unix $SOCK_PATH -v 2>&1)
203 if [ $? -ne 0 ]; then
204 echo "Error: $SWTPM_IOCTL CMD_STORE_VOLATILE failed: $act"
205 exit 1
206 fi
207
208 if [ ! -r $TPMDIR/tpm2-00.volatilestate ]; then
209 echo "Error: Socket TPM: Did not write volatile state file"
210 exit 1
211 fi
212
213 # 1. Send command to get TPM established flag: CMD_GET_TPMESTABLISHED = 00 00 00 04
214 act=$($SWTPM_IOCTL --unix $SOCK_PATH -e 2>&1)
215 if [ $? -ne 0 ]; then
216 echo "Error: $SWTPM_IOCTL CMD_GET_TPMESTABLISHED failed: $act"
217 exit 1
218 fi
219
220 exp="tpmEstablished is 0"
221 if [ "$act" != "$exp" ]; then
222 echo "Error: Expected '$exp' but got '$act'."
223 exit 1
224 fi
225
226 # 2. Hash the given data
227 data="a"
228 while [ ${#data} -lt $((0x2000)) ]; do
229 data="${data}${data}"
230 done
231 act=$($SWTPM_IOCTL --unix $SOCK_PATH -h $data 2>&1)
232 if [ $? -ne 0 ]; then
233 echo "Error: $SWTPM_IOCTL data hashing failed: $act"
234 exit 1
235 fi
236
237 # 3. Send command to get TPM established flag: CMD_GET_TPMESTABLISHED = 00 00 00 04
238 act=$($SWTPM_IOCTL --unix $SOCK_PATH -e 2>&1)
239 if [ $? -ne 0 ]; then
240 echo "Error: $SWTPM_IOCTL CMD_GET_TPMESTABLISHED failed: $act"
241 exit 1
242 fi
243
244 exp="tpmEstablished is 1"
245 if [ "$act" != "$exp" ]; then
246 echo "Error: Expected '$exp' but got '$act'."
247 exit 1
248 fi
249
250 # 4. Send command to reset TPM established flag: CMD_RESET_TPMESTABLISHED = 00 00 00 0b 03
251 act=$($SWTPM_IOCTL --unix $SOCK_PATH -r 3 2>&1)
252 if [ $? -ne 0 ]; then
253 echo "Error: $SWTPM_IOCTL CMD_RESET_TPMESTABLISHED failed: $act"
254 exit 1
255 fi
256
257 # 5. Send command to get TPM established flag: CMD_GET_TPMESTABLISHED = 00 00 00 04
258 act=$($SWTPM_IOCTL --unix $SOCK_PATH -e 2>&1)
259 if [ $? -ne 0 ]; then
260 echo "Error: $SWTPM_IOCTL CMD_GET_TPMESTABLISHED failed: $act"
261 exit 1
262 fi
263
264 exp="tpmEstablished is 0"
265 if [ "$act" != "$exp" ]; then
266 echo "Error: Expected '$exp' but got '$act'."
267 exit 1
268 fi
269
270 # Read PCR 17
271 exec 100<>/dev/tcp/localhost/65532
272 # length CC count hashalg sz
273 echo -en '\x80\x01\x00\x00\x00\x14\x00\x00\x01\x7e\x00\x00\x00\x01\x00\x0b\x03\x00\x00\x02' >&100
274 RES=$(cat <&100 | od -t x1 -A n | tr -d "\n")
275 exp=' 80 01 00 00 00 3e 00 00 00 00 00 00 00 18 00 00 00 01 00 0b 03 00 00 02 00 00 00 01 00 20 e5 17 e3 9b 10 a3 5b 3b b7 29 95 79 4b c6 4a 07 f8 bc b0 bd e6 bb 31 ad 35 27 fb 6f 64 f8 4c b9'
276 if [ "$RES" != "$exp" ]; then
277 echo "Error: (1) Did not get expected result from TPM_PCRRead(17)"
278 echo "expected: $exp"
279 echo "received: $RES"
280 exit 1
281 fi
282
283 # Get the volatile state of the TPM: CMD_GET_STATEBLOB = 00 00 00 0c
284 act=$($SWTPM_IOCTL --unix $SOCK_PATH --save volatile $VOLATILESTATE 2>&1)
285 if [ $? -ne 0 ]; then
286 echo "Error: $SWTPM_IOCTL CMD_GET_STATEBLOB failed: $act"
287 exit 1
288 fi
289
290 # Send stop command to the TPM: CMD_STOP = 00 00 00 0e
291 act=$($SWTPM_IOCTL --unix $SOCK_PATH --stop 2>&1)
292 if [ $? -ne 0 ]; then
293 echo "Error: $SWTPM_IOCTL CMD_STOP failed: $act"
294 exit 1
295 fi
296
297 # Read PCR 17 -- should fail now
298 exec 100<>/dev/tcp/localhost/65532
299 # length CC count hashalg sz
300 echo -en '\x80\x01\x00\x00\x00\x14\x00\x00\x01\x7e\x00\x00\x00\x01\x00\x0b\x03\x00\x00\x02' >&100
301 RES=$(cat <&100 | od -t x1 -A n | tr -d "\n")
302 exp=' 80 01 00 00 00 0a 00 00 01 01'
303 if [ "$RES" != "$exp" ]; then
304 echo "Error: (1) Did not get expected result from TPM_PCRRead(17)"
305 echo "expected: $exp"
306 echo "received: $RES"
307 exit 1
308 fi
309
310 # Send get config command to the TPM: CMD_GET_CONFIG = 00 00 00 0f
311 act=$($SWTPM_IOCTL --unix $SOCK_PATH -g 2>&1)
312 if [ $? -ne 0 ]; then
313 echo "Error: $SWTPM_IOCTL CMD_GET_CONFIG failed: $act"
314 exit 1
315 fi
316
317 exp="ptm configuration flags: 0x([[:xdigit:]]+)"
318 if ! [[ "$act" =~ ^${exp}$ ]]; then
319 echo "Error: Expected string following regular expression '$exp' from ioctl tool but got '$act'."
320 exit 1
321 fi
322
323 # Send shutdown command to the TPM: CMD_SHUTDOWN = 00 00 00 03
324 act=$($SWTPM_IOCTL --unix $SOCK_PATH -s 2>&1)
325 if [ $? -ne 0 ]; then
326 echo "Error: $SWTPM_IOCTL CMD_SHUTDOWN failed: $act"
327 exit 1
328 fi
329
330 if wait_file_gone $PID_FILE 2; then
331 echo "Error: TPM should have removed PID file by now."
332 exit 1
333 fi
334
335 if wait_process_gone ${PID} 4; then
336 echo "Error: TPM should not be running anymore."
337 exit 1
338 fi
339
340 echo "OK"
341
342 # Test 3: test the control channel on the socket tpm: resume encrypted state
343
344 # copy all the state files
345 cp ${TESTDIR}/data/tpm2state2/* ${TPMDIR}
346
347 $SWTPM_EXE socket \
348 --server port=65532,disconnect=true \
349 --tpmstate dir=$TPMDIR \
350 --pid file=$PID_FILE \
351 --ctrl type=unixio,path=$SOCK_PATH \
352 --key pwdfile=${TESTDIR}/data/tpm2state2/pwdfile.txt,kdf=sha512 \
353 --tpm2 \
354 --flags not-need-init \
355 ${SWTPM_TEST_SECCOMP_OPT} &
356 PID=$!
357
358 if wait_for_file $PID_FILE 3; then
359 echo "Error: Socket TPM did not write pidfile."
360 exit 1
361 fi
362
363 validate_pidfile $PID $PID_FILE
364
365 # Read PCR 10
366 exec 100<>/dev/tcp/localhost/65532
367 # length CC count hashalg sz
368 echo -en '\x80\x01\x00\x00\x00\x14\x00\x00\x01\x7e\x00\x00\x00\x01\x00\x0b\x03\x00\x04\x00' >&100
369 RES=$(cat <&100 | od -t x1 -A n -w128)
370 exp=' 80 01 00 00 00 3e 00 00 00 00 00 00 00 16 00 00 00 01 00 0b 03 00 04 00 00 00 00 01 00 20 f6 85 98 e5 86 8d e6 8b 97 29 99 60 f2 71 7d 17 67 89 a4 2f 9a ae a8 c7 b7 aa 79 a8 62 56 c1 de'
371 if [ "$RES" != "$exp" ]; then
372 echo "Error: (1) Did not get expected result from TPM2_PCRRead(10)"
373 echo "expected: $exp"
374 echo "received: $RES"
375 exit 1
376 fi
377
378 # Get the volatile state of the TPM: CMD_GET_STATEBLOB = 00 00 00 0c
379 rm -f $VOLATILESTATE
380 act=$($SWTPM_IOCTL --unix $SOCK_PATH --save volatile $VOLATILESTATE 2>&1)
381 if [ $? -ne 0 ]; then
382 echo "Error: $SWTPM_IOCTL CMD_GET_STATEBLOB failed: $act"
383 exit 1
384 fi
385
386 # Send shutdown command to the TPM: CMD_SHUTDOWN = 00 00 00 03
387 act=$($SWTPM_IOCTL --unix $SOCK_PATH -s 2>&1)
388 if [ $? -ne 0 ]; then
389 echo "Error: $SWTPM_IOCTL CMD_SHUTDOWN failed: $act"
390 exit 1
391 fi
392
393 if wait_process_gone ${PID} 4; then
394 echo "Error: TPM should not be running anymore."
395 exit 1
396 fi
397
398 if [ -f $PID_FILE ]; then
399 echo "Error: Socket TPM should have removed the PID file."
400 exit 1
401 fi
402
403 # remove volatile state
404 rm -f $TPMDIR/*.volatilestate
405
406 $SWTPM_EXE socket \
407 --server port=65532,disconnect=true \
408 --tpmstate dir=$TPMDIR \
409 --pid file=$PID_FILE \
410 --ctrl type=unixio,path=$SOCK_PATH \
411 --key pwdfile=${TESTDIR}/data/tpm2state2/pwdfile.txt,kdf=sha512 \
412 --tpm2 \
413 --flags not-need-init \
414 ${SWTPM_TEST_SECCOMP_OPT} &
415 PID=$!
416
417 if wait_for_file $PID_FILE 3; then
418 echo "Error: Socket TPM did not write pidfile."
419 exit 1
420 fi
421
422 validate_pidfile $PID $PID_FILE
423
424 # Read PCR 10 -- this should fail now
425 exec 100<>/dev/tcp/localhost/65532
426 # length CC count hashalg sz
427 echo -en '\x80\x01\x00\x00\x00\x14\x00\x00\x01\x7e\x00\x00\x00\x01\x00\x0b\x03\x00\x04\x00' >&100
428 RES=$(cat <&100 | od -t x1 -A n -w128)
429 exp=' 80 01 00 00 00 0a 00 00 01 00'
430 if [ "$RES" != "$exp" ]; then
431 echo "Error: (1) Did not get expected result from TPM2_PCRRead(10)"
432 echo "expected: $exp"
433 echo "received: $RES"
434 exit 1
435 fi
436
437 # Send stop command to the TPM: CMD_STOP = 00 00 00 0e
438 act=$($SWTPM_IOCTL --unix $SOCK_PATH --stop 2>&1)
439 if [ $? -ne 0 ]; then
440 echo "Error: $SWTPM_IOCTL CMD_STOP failed: $act"
441 exit 1
442 fi
443
444 # Send the volatile state to the TPM (while it is stopped)
445 act=$($SWTPM_IOCTL --unix $SOCK_PATH --load volatile $VOLATILESTATE 2>&1)
446 if [ $? -ne 0 ]; then
447 echo "Error: $SWTPM_IOCTL CMD_SET_STATEBLOB failed: $act"
448 exit 1
449 fi
450
451 # Send init command to the TPM: CMD_INIT = 00 00 00 02
452 act=$($SWTPM_IOCTL --unix $SOCK_PATH -i 2>&1)
453 if [ $? -ne 0 ]; then
454 echo "Error: $SWTPM_IOCTL CMD_INIT failed: $act"
455 exit 1
456 fi
457
458 # Read PCR 10 -- has to return same result as before
459 exec 100<>/dev/tcp/localhost/65532
460 # length CC count hashalg sz
461 echo -en '\x80\x01\x00\x00\x00\x14\x00\x00\x01\x7e\x00\x00\x00\x01\x00\x0b\x03\x00\x04\x00' >&100
462 RES=$(cat <&100 | od -t x1 -A n -w128)
463 exp=' 80 01 00 00 00 3e 00 00 00 00 00 00 00 16 00 00 00 01 00 0b 03 00 04 00 00 00 00 01 00 20 f6 85 98 e5 86 8d e6 8b 97 29 99 60 f2 71 7d 17 67 89 a4 2f 9a ae a8 c7 b7 aa 79 a8 62 56 c1 de'
464 if [ "$RES" != "$exp" ]; then
465 echo "Error: (1) Did not get expected result from TPM2_PCRRead(10)"
466 echo "expected: $exp"
467 echo "received: $RES"
468 exit 1
469 fi
470
471 # Reset PCR 20 while in locality 0 -- should not work
472 exec 100<>/dev/tcp/localhost/65532
473 echo -en '\x80\x02\x00\x00\x00\x1b\x00\x00\x01\x3d\x00\x00\x00\x14\x00\x00\x00\x09\x40\x00\x00\x09\x00\x00\x00\x00\x00' >&100
474 RES=$(cat <&100 | od -t x1 -A n)
475 exp=' 80 01 00 00 00 0a 00 00 09 07'
476 if [ "$RES" != "$exp" ]; then
477 echo "Error: Trying to reset PCR 20 in locality 0 returned unexpected result"
478 echo "expected: $exp"
479 echo "received: $RES"
480 exit 1
481 fi
482
483 # In locality 2 we can reset PCR 20
484 # Set the locality on the TPM: CMD_SET_LOCALITY = 00 00 00 05 <locality>
485 act=$($SWTPM_IOCTL --unix $SOCK_PATH -l 2 2>&1)
486 if [ $? -ne 0 ]; then
487 echo "Error: $SWTPM_IOCTL CMD_SET_LOCALITY failed: $act"
488 exit 1
489 fi
490
491 # Reset PCR 20 while in locality 2 -- has to work
492 exec 100<>/dev/tcp/localhost/65532
493 echo -en '\x80\x02\x00\x00\x00\x1b\x00\x00\x01\x3d\x00\x00\x00\x14\x00\x00\x00\x09\x40\x00\x00\x09\x00\x00\x00\x00\x00' >&100
494 RES=$(cat <&100 | od -t x1 -A n -w512)
495 exp=' 80 02 00 00 00 13 00 00 00 00 00 00 00 00 00 00 01 00 00'
496 if [ "$RES" != "$exp" ]; then
497 echo "Error: Could not reset PCR 20 in locality 2"
498 echo "expected: $exp"
499 echo "received: $RES"
500 exit 1
501 fi
502
503 # Send shutdown command to the TPM: CMD_SHUTDOWN = 00 00 00 03
504 act=$($SWTPM_IOCTL --unix $SOCK_PATH -s 2>&1)
505 if [ $? -ne 0 ]; then
506 echo "Error: $SWTPM_IOCTL CMD_SHUTDOWN failed: $act"
507 exit 1
508 fi
509
510 if wait_file_gone $PID_FILE 2; then
511 echo "Error: TPM should have removed PID file by now."
512 exit 1
513 fi
514
515 if wait_process_gone ${PID} 4; then
516 echo "Error: TPM should not be running anymore."
517 exit 1
518 fi
519
520 echo "OK"
521
522 exit 0