3 # For the license, see the LICENSE file in the root directory.
5 if [ -e /run
/lock
/sbuild
]; then
6 echo "building in sbuild, avoid potential (unshare) problematic test"
10 ROOT
=${abs_top_builddir:-$(dirname "$0")/..}
11 TESTDIR
=${abs_top_testdir:-$(dirname "$0")}
13 TPMDIR
="$(mktemp -d)" ||
exit 1
14 SWTPM_CTRL_UNIX_PATH
=$TPMDIR/sock
15 PID_FILE
=$TPMDIR/swtpm.pid
16 LOG_FILE
=$TPMDIR/swtpm.log
18 RESP_PATH
=$TPMDIR/resp
20 source ${TESTDIR}/test_common
22 trap "cleanup" SIGTERM EXIT
27 if [ -n "$PID" ]; then
28 kill_quiet
-SIGTERM $PID 2>/dev
/null
32 SWTPM_INTERFACE
=socket
+unix
33 SWTPM_SERVER_PORT
=65430
34 SWTPM_SERVER_NAME
=localhost
35 source ${TESTDIR}/common
36 skip_test_no_tpm12
"${SWTPM_EXE}"
38 # Test 1: test the control channel on the socket tpm
40 # OS X would not allow nobody to access the $TPMDIR easily; skip it
41 if [ $
(id
-u) -eq 0 ] && [ "$(uname -s)" != "Darwin" ]; then
42 FILEOWNER
="$(id -u nobody) $(id -G nobody | cut -d" " -f1)"
43 RUNAS
="--runas nobody"
46 echo "Error: Could not change ownership of $TPMDIR"
51 if [[ "$(uname -s)" =~ CYGWIN_NT-
]]; then
63 # use a pseudo terminal
64 if [ -c /dev
/ptmx
]; then
66 elif [ -c /dev
/ptm
]; then
69 echo "Could not find chardev for opening file descriptor."
74 Linux|CYGWIN_NT-|Darwin
)
79 PIDPARAM
="file=$PID_FILE"
85 --tpmstate dir
=$TPMDIR \
87 --ctrl type=unixio
,path
=$SWTPM_CTRL_UNIX_PATH,mode
=${FILEMODE}${FOWNER} \
88 --log file=$LOG_FILE,level
=20 \
91 ${SWTPM_TEST_SECCOMP_OPT}
96 if [ ! -f $PID_FILE ]; then
97 echo "Error: Socket TPM did not write pidfile."
101 PID
=$
(cat "$PID_FILE")
103 # Get the capability bits: CMD_GET_CAPABILITY = 0x00 00 00 01
104 res
="$(swtpm_ctrl_tx ${SWTPM_INTERFACE} '\x00\x00\x00\x01')"
105 if [[ "$(uname -s)" =~
(Linux|OpenBSD|FreeBSD|NetBSD|Darwin|DragonFly
) ]]; then
106 exp
=" 00 00 00 00 00 01 7f ff"
108 exp
=" 00 00 00 00 00 01 6f ff"
110 if [ "$res" != "$exp" ]; then
111 echo "Error: Unexpected response from CMD_GET_CAPABILITY:"
112 echo " actual : $res"
113 echo " expected: $exp"
117 filemode
=$
(get_filemode
$SWTPM_CTRL_UNIX_PATH)
118 if [ "$filemode" != "$FILEMODE" ]; then
119 echo "Filemode bits are wrong"
120 echo "Expected: $FILEMODE"
121 echo "Actual : $filemode"
125 fileowner
=$
(get_fileowner
$SWTPM_CTRL_UNIX_PATH)
126 if [ -n "$FILEOWNER" ] && [ "$fileowner" != "$FILEOWNER" ]; then
127 echo "File ownership is wrong"
128 echo "Expected: $FILEOWNER"
129 echo "Actual : $fileowner"
133 # Send TPM_Init to the TPM: CMD_INIT = 0x00 00 00 02 + flags
134 res
="$(swtpm_ctrl_tx ${SWTPM_INTERFACE} '\x00\x00\x00\x02\x00\x00\x00\x00')"
136 if [ "$res" != "$exp" ]; then
137 echo "Error: Unexpected response from CMD_INIT:"
138 echo " actual : $res"
139 echo " expected: $exp"
143 # Send unknown command to the TPM
144 res
="$(swtpm_ctrl_tx ${SWTPM_INTERFACE} '\x00\x00\xff\xff')"
146 if [ "$res" != "$exp" ]; then
147 echo "Error: Unexpected response from sending unsupported command:"
148 echo " actual : $res"
149 echo " expected: $exp"
153 # Save the volatile state: CMD_STORE_VOLATILE = 0x00 00 00 0a
154 res
="$(swtpm_ctrl_tx ${SWTPM_INTERFACE} '\x00\x00\x00\x0a')"
156 if [ "$res" != "$exp" ]; then
157 echo "Error: Unexpected response from CMD_STORE_VOLATILE:"
158 echo " actual : $res"
159 echo " expected: $exp"
163 if [ ! -r $TPMDIR/tpm-00.volatilestate
]; then
164 echo "Error: Socket TPM: Did not write volatile state file"
168 # Send stop command to the TPM: CMD_STOP = 00 00 00 0e
169 res
="$(swtpm_ctrl_tx ${SWTPM_INTERFACE} '\x00\x00\x00\x0e')"
171 if [ "$res" != "$exp" ]; then
172 echo "Error: Socket TPM: Unexpected response from CMD_STOP:"
173 echo " actual : $res"
174 echo " expected: $exp"
178 # Send get config command to the TPM: CMD_GET_CONFIG = 00 00 00 0f
179 res
="$(swtpm_ctrl_tx ${SWTPM_INTERFACE} '\x00\x00\x00\x0f')"
180 exp
=" 00 00 00 00 00 00 00 00"
181 if [ "$res" != "$exp" ]; then
182 echo "Error: Socket TPM: Unexpected response from CMD_GET_CONFIG:"
183 echo " actual : $res"
184 echo " expected: $exp"
188 # To enable coverage of the above running as non-root we change the .gcda
189 # files' ownership with this small hack
190 if [ $
(id
-u) -eq 0 ] && [ "$(uname -s)" != "Darwin" ]; then
191 find $ROOT -name *.gcda
-exec chown nobody
{} \
;
194 # Send shutdown command to the TPM: CMD_SHUTDOWN = 00 00 00 03
195 res
="$(swtpm_ctrl_tx ${SWTPM_INTERFACE} '\x00\x00\x00\x03')"
197 if [ "$res" != "$exp" ]; then
198 echo "Error: Unexpected response from CMD_SHUTDOWN:"
199 echo " actual : $res"
200 echo " expected: $exp"
204 if wait_file_gone
$PID_FILE 2; then
205 echo "Error: TPM should have removed PID file by now."
209 if wait_process_gone
${PID} 4; then
210 echo "Error: TPM should not be running anymore."
214 check_logfile_patterns_level_20
$LOG_FILE
219 # Test 2: test the control channel on the socket tpm
221 # There are a few more tests here that require sending commands to the TPM
223 # use a pseudo terminal
224 run_swtpm
${SWTPM_INTERFACE} \
225 --tpmstate dir
=$TPMDIR \
226 --pid file=$PID_FILE \
227 --log file=$LOG_FILE \
228 --flags startup-clear \
232 if wait_for_file
${PID_FILE} 4; then
233 echo "Error: Socket TPM did not write pidfile."
238 validate_pidfile
$PID $PID_FILE
240 # Get the capability bits: CMD_GET_CAPABILITY = 0x00 00 00 01
241 res
="$(swtpm_ctrl_tx ${SWTPM_INTERFACE} '\x00\x00\x00\x01')"
242 if [[ "$(uname -s)" =~
(Linux|OpenBSD|FreeBSD|NetBSD|Darwin|DragonFly
) ]]; then
243 exp
=" 00 00 00 00 00 01 7f ff"
245 exp
=" 00 00 00 00 00 01 6f ff"
247 if [ "$res" != "$exp" ]; then
248 echo "Error: Socket TPM: Unexpected response from CMD_GET_CAPABILITY:"
249 echo " actual : $res"
250 echo " expected: $exp"
254 # Send unknown command to the TPM
255 res
="$(swtpm_ctrl_tx ${SWTPM_INTERFACE} '\x00\x00\xff\xff')"
257 if [ "$res" != "$exp" ]; then
258 echo "Error: Socket TPM: Unexpected response from sending unsupported command:"
259 echo " actual : $res"
260 echo " expected: $exp"
264 # Startup the TPM; we use --flags startup-clear, so expect this to fail with error 0x26 (INVALID POST INIT)
265 res
="$(swtpm_cmd_tx ${SWTPM_INTERFACE} '\x00\xC1\x00\x00\x00\x0C\x00\x00\x00\x99\x00\x01')"
266 exp
=' 00 c4 00 00 00 0a 00 00 00 26'
267 if [ "$res" != "$exp" ]; then
268 echo "Error: Did not get expected result from TPM_Startup(ST_Clear)"
269 echo "expected: $exp"
270 echo "received: $res"
274 # Save the volatile state: CMD_STORE_VOLATILE = 0x00 00 00 0a
275 res
="$(swtpm_ctrl_tx ${SWTPM_INTERFACE} '\x00\x00\x00\x0a')"
277 if [ "$res" != "$exp" ]; then
278 echo "Error: Socket TPM: Unexpected response from CMD_STORE_VOLATILE:"
279 echo " actual : $res"
280 echo " expected: $exp"
284 if [ ! -r $TPMDIR/tpm-00.volatilestate
]; then
285 echo "Error: Socket TPM: Did not write volatile state file"
289 # 1. Send command to get TPM established flag: CMD_GET_TPMESTABLISHED = 00 00 00 04
290 res
="$(swtpm_ctrl_tx ${SWTPM_INTERFACE} '\x00\x00\x00\x04')"
291 exp
=" 00 00 00 00 00 00 00 00"
292 if [ "$res" != "$exp" ]; then
293 echo "Error: Socket TPM: Unexpected response from sending CMD_GET_TPMESTABLISHED command:"
294 echo " actual : $res"
295 echo " expected: $exp"
299 # 2. Send command to start HASH : CMD_HASH_START = 00 00 00 06
300 res
="$(swtpm_ctrl_tx ${SWTPM_INTERFACE} '\x00\x00\x00\x06')"
302 if [ "$res" != "$exp" ]; then
303 echo "Error: Socket TPM: Unexpected response from sending CMD_HASH_START command:"
304 echo " actual : $res"
305 echo " expected: $exp"
309 # 2.1. Send command to hash data : CMD_HASH_DATA = 00 00 00 07 uint32(length) data
310 # We send 0x100 null bytes
311 echo -en '\x00\x00\x00\x07\x00\x00\x20\x00' > $CMD_PATH
312 dd if=/dev
/zero count
=$
((0x2000)) bs
=1 >> $CMD_PATH 2>/dev
/null
313 socat
-x -t10 FILE
:$CMD_PATH,rdonly UNIX-CONNECT
:$SWTPM_CTRL_UNIX_PATH 2>&1 | \
315 tail -n1 > $RESP_PATH
316 res
="$(cat $RESP_PATH)"
318 if [ "$res" != "$exp" ]; then
319 echo "Error: Socket TPM: Unexpected response from sending CMD_HASH_DATA command:"
320 echo " actual : $res"
321 echo " expected: $exp"
325 # 3. Send command to end HASH : CMD_HASH_END = 00 00 00 08
326 res
="$(swtpm_ctrl_tx ${SWTPM_INTERFACE} '\x00\x00\x00\x08')"
328 if [ "$res" != "$exp" ]; then
329 echo "Error: Socket TPM: Unexpected response from sending CMD_HASH_END command:"
330 echo " actual : $res"
331 echo " expected: $exp"
335 # 4. Send command to get TPM established flag: CMD_GET_TPMESTABLISHED = 00 00 00 04
336 res
="$(swtpm_ctrl_tx ${SWTPM_INTERFACE} '\x00\x00\x00\x04')"
337 exp
=" 00 00 00 00 01 00 00 00"
338 if [ "$res" != "$exp" ]; then
339 echo "Error: Socket TPM: Unexpected response from sending CMD_GET_TPMESTABLISHED command:"
340 echo " actual : $res"
341 echo " expected: $exp"
345 # 5. Send command to reset TPM established flag: CMD_RESET_TPMESTABLISHED = 00 00 00 0b 03
346 res
="$(swtpm_ctrl_tx ${SWTPM_INTERFACE} '\x00\x00\x00\x0b\x03')"
348 if [ "$res" != "$exp" ]; then
349 echo "Error: Socket TPM: Unexpected response from sending CMD_GET_TPMESTABLISHED command:"
350 echo " actual : $res"
351 echo " expected: $exp"
355 # 6. Send command to get TPM established flag: CMD_GET_TPMESTABLISHED = 00 00 00 04
356 res
="$(swtpm_ctrl_tx ${SWTPM_INTERFACE} '\x00\x00\x00\x04')"
357 exp
=" 00 00 00 00 00 00 00 00"
358 if [ "$res" != "$exp" ]; then
359 echo "Error: Socket TPM: Unexpected response from sending CMD_GET_TPMESTABLISHED command:"
360 echo " actual : $res"
361 echo " expected: $exp"
366 res
="$(swtpm_cmd_tx ${SWTPM_INTERFACE} '\x00\xC1\x00\x00\x00\x0E\x00\x00\x00\x15\x00\x00\x00\x11')"
367 exp
=' 00 c4 00 00 00 1e 00 00 00 00 c4 e1 e1 c9 81 c0 cd b1 e0 43 df 97 20 72 f9 5d a9 ff 06 ff'
368 if [ "$res" != "$exp" ]; then
369 echo "Error: (1) Did not get expected result from TPM_PCRRead(17)"
370 echo "expected: $exp"
371 echo "received: $res"
375 # Get the volatile state of the TPM: CMD_GET_STATEBLOB = 00 00 00 0c
376 # cmd | flags | type | offset |
377 res
="$(swtpm_ctrl_tx ${SWTPM_INTERFACE} '\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00')"
378 # result | flags | totlength | length |
379 exp
=" 00 00 00 00 00 00 00 00 00 00 04 e5 00 00 04 e5"
380 if [ "${res:0:48}" != "$exp" ]; then
381 echo "Error: Socket TPM: Unexpected response from CMD_GET_STATEBLOB:"
382 echo " actual : $res"
383 echo " expected: $exp"
387 # Send stop command to the TPM: CMD_STOP = 00 00 00 0e
388 res
="$(swtpm_ctrl_tx ${SWTPM_INTERFACE} '\x00\x00\x00\x0e')"
390 if [ "$res" != "$exp" ]; then
391 echo "Error: Socket TPM: Unexpected response from CMD_STOP:"
392 echo " actual : $res"
393 echo " expected: $exp"
397 # Read PCR 17 -- should fail now
398 res
="$(swtpm_cmd_tx ${SWTPM_INTERFACE} '\x00\xC1\x00\x00\x00\x0E\x00\x00\x00\x15\x00\x00\x00\x11')"
399 exp
=' 00 c4 00 00 00 0a 00 00 00 09'
400 if [ "$res" != "$exp" ]; then
401 echo "Error: (1) Did not get expected result from TPM_PCRRead(17)"
402 echo "expected: $exp"
403 echo "received: $res"
407 # Send get config command to the TPM: CMD_GET_CONFIG = 00 00 00 0f
408 res
="$(swtpm_ctrl_tx ${SWTPM_INTERFACE} '\x00\x00\x00\x0f')"
409 exp
=" 00 00 00 00 00 00 00 00"
410 if [ "$res" != "$exp" ]; then
411 echo "Error: Socket TPM: Unexpected response from CMD_GET_CONFIG:"
412 echo " actual : $res"
413 echo " expected: $exp"
417 # Send shutdown command to the TPM: CMD_SHUTDOWN = 00 00 00 03
418 res
="$(swtpm_ctrl_tx ${SWTPM_INTERFACE} '\x00\x00\x00\x03')"
420 if [ "$res" != "$exp" ]; then
421 echo "Error: Socket TPM: Unexpected response from CMD_SHUTDOWN:"
422 echo " actual : $res"
423 echo " expected: $exp"
427 if wait_file_gone
$PID_FILE 2; then
428 echo "Error: TPM should have removed PID file by now."
432 if wait_process_gone
${PID} 4; then
433 echo "Error: Socket TPM should not be running anymore."
437 # Expecting to see an error message for the unknown command
438 check_logfile_patterns_level_1
$LOG_FILE 1
443 # Test 3: test the control channel on the socket tpm: resume encrypted state
445 # copy all the state files
446 cp ${TESTDIR}/data
/tpmstate
2/* ${TPMDIR}
448 run_swtpm
${SWTPM_INTERFACE} \
449 --tpmstate dir
=$TPMDIR \
450 --pid file=$PID_FILE \
451 --key pwdfile
=${TESTDIR}/data
/tpmstate
2/pwdfile.txt
,kdf
=sha512 \
452 --log file=$LOG_FILE,level
=20 \
453 --flags not-need-init
456 if wait_for_file
$PID_FILE 3; then
457 echo "Error: Socket TPM did not write pidfile."
461 validate_pidfile
$PID $PID_FILE
464 res
="$(swtpm_cmd_tx ${SWTPM_INTERFACE} '\x00\xC1\x00\x00\x00\x0E\x00\x00\x00\x15\x00\x00\x00\x0a')"
465 exp
=' 00 c4 00 00 00 1e 00 00 00 00 c7 8a 6e 94 c7 3c 4d 7f c3 05 c8 a6 6b bf 15 45 f4 ed b7 a5'
466 if [ "$res" != "$exp" ]; then
467 echo "Error: (1) Did not get expected result from TPM_PCRRead(10)"
468 echo "expected: $exp"
469 echo "received: $res"
473 # Get the volatile state of the TPM: CMD_GET_STATEBLOB = 00 00 00 0c
474 # cmd | flags | type | offset |
475 vstate
="$(swtpm_ctrl_tx ${SWTPM_INTERFACE} '\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00')"
476 # result | flags | totlength | length |
477 exp
=" 00 00 00 00 00 00 00 02 00 00 05 22 00 00 05 22"
478 if [ "${vstate:0:48}" != "$exp" ]; then
479 echo "Error: Socket TPM: Unexpected response from CMD_GET_STATEBLOB:"
480 echo " actual : ${vstate:0:48}"
481 echo " expected: $exp"
485 # Send shutdown command to the TPM: CMD_SHUTDOWN = 00 00 00 03
486 res
="$(swtpm_ctrl_tx ${SWTPM_INTERFACE} '\x00\x00\x00\x03')"
488 if [ "$res" != "$exp" ]; then
489 echo "Error: Socket TPM: Unexpected response from CMD_SHUTDOWN:"
490 echo " actual : $res"
491 echo " expected: $exp"
495 if wait_file_gone
$PID_FILE 2; then
496 echo "Error: TPM should have removed PID file by now."
500 if wait_process_gone
${PID} 4; then
501 echo "Error: Socket TPM should not be running anymore."
505 check_logfile_patterns_level_20
$LOG_FILE
510 # remove volatile state
511 rm -f $TPMDIR/*.volatilestate
513 run_swtpm
${SWTPM_INTERFACE} \
514 --tpmstate dir
=$TPMDIR \
515 --pid file=$PID_FILE \
516 --key pwdfile
=${TESTDIR}/data
/tpmstate
2/pwdfile.txt
,kdf
=sha512 \
517 --log file=$LOG_FILE \
518 --flags not-need-init
521 if wait_for_file
$PID_FILE 3; then
522 echo "Error: Socket TPM did not write pidfile."
526 validate_pidfile
$PID $PID_FILE
528 # Read PCR 10 -- this should fail now
529 res
="$(swtpm_cmd_tx ${SWTPM_INTERFACE} '\x00\xC1\x00\x00\x00\x0E\x00\x00\x00\x15\x00\x00\x00\x0a')"
530 exp
=' 00 c4 00 00 00 0a 00 00 00 26'
531 if [ "$res" != "$exp" ]; then
532 echo "Error: (1) Did not get expected result from TPM_PCRRead(10)"
533 echo "expected: $exp"
534 echo "received: $res"
538 # Send stop command to the TPM: CMD_STOP = 00 00 00 0e
539 res
="$(swtpm_ctrl_tx ${SWTPM_INTERFACE} '\x00\x00\x00\x0e')"
541 if [ "$res" != "$exp" ]; then
542 echo "Error: Socket TPM: Unexpected response from CMD_STOP:"
543 echo " actual : $res"
544 echo " expected: $exp"
548 # Send the volatile state to the TPM (while it is stopped)
549 # | cmd | flags | type |
551 size
=$
((${#vstate} / 3))
552 size
=$
(printf "%08x" $size |
sed 's/\([0-9a-f]\{2\}\)/\\x\1/g')
553 vstate
=$
(echo "${vstate}" |
sed 's/ /\\x/g')
554 res
="$(swtpm_ctrl_tx ${SWTPM_INTERFACE} "\x00\x00\x00\x0d\x00\x00\x00\x02\x00\x00\x00\x02${size}${vstate}")"
556 if [ "$res" != "$exp" ]; then
557 echo "Error
: Socket TPM
: Unexpected response from CMD_SET_STATEBLOB
:"
558 echo " actual
: $res"
559 echo " expected
: $exp"
563 # Send init command to the TPM: CMD_INIT = 00 00 00 02
564 res="$
(swtpm_ctrl_tx
${SWTPM_INTERFACE} '\x00\x00\x00\x02\x00\x00\x00\x00')"
566 if [ "$res" != "$exp" ]; then
567 echo "Error
: Socket TPM
: Unexpected response from CMD_INIT
:"
568 echo " actual
: $res"
569 echo " expected
: $exp"
573 # Read PCR 10 -- has to return same result as before
574 res="$
(swtpm_cmd_tx
${SWTPM_INTERFACE} '\x00\xC1\x00\x00\x00\x0E\x00\x00\x00\x15\x00\x00\x00\x0a')"
575 exp=' 00 c4 00 00 00 1e 00 00 00 00 c7 8a 6e 94 c7 3c 4d 7f c3 05 c8 a6 6b bf 15 45 f4 ed b7 a5'
576 if [ "$res" != "$exp" ]; then
577 echo "Error
: (1) Did not get expected result from TPM_PCRRead
(10)"
578 echo "expected
: $exp"
579 echo "received
: $res"
583 # Reset PCR 20 while in locality 0 -- should not work
584 res="$
(swtpm_cmd_tx
${SWTPM_INTERFACE} '\x00\xC1\x00\x00\x00\x0F\x00\x00\x00\xC8\x00\x03\x00\x00\x10')"
585 exp=' 00 c4 00 00 00 0a 00 00 00 33'
586 if [ "$res" != "$exp" ]; then
587 echo "Error
: Trying to
reset PCR
20 in locality
0 returned unexpected result
"
588 echo "expected
: $exp"
589 echo "received
: $res"
593 # In locality 2 we can reset PCR 20
594 # Set the localoty on the TPM: CMD_SET_LOCALITY = 00 00 00 05 <locality>
595 res="$
(swtpm_ctrl_tx
${SWTPM_INTERFACE} '\x00\x00\x00\x05\x02')"
597 if [ "$res" != "$exp" ]; then
598 echo "Error
: Socket TPM
: Unexpected response from CMD_SET_LOCALITY
:"
599 echo " actual
: $res"
600 echo " expected
: $exp"
604 # Reset PCR 20 while in locality 2 -- has to work
605 res="$
(swtpm_cmd_tx
${SWTPM_INTERFACE} '\x00\xC1\x00\x00\x00\x0F\x00\x00\x00\xC8\x00\x03\x00\x00\x10')"
606 exp=' 00 c4 00 00 00 0a 00 00 00 00'
607 if [ "$res" != "$exp" ]; then
608 echo "Error
: Could not
reset PCR
20 in locality
2"
609 echo "expected
: $exp"
610 echo "received
: $res"
614 # Send shutdown command to the TPM: CMD_SHUTDOWN = 00 00 00 03
615 res="$
(swtpm_ctrl_tx
${SWTPM_INTERFACE} '\x00\x00\x00\x03')"
617 if [ "$res" != "$exp" ]; then
618 echo "Error
: Socket TPM
: Unexpected response from CMD_SHUTDOWN
:"
619 echo " actual
: $res"
620 echo " expected
: $exp"
624 if wait_file_gone $PID_FILE 2; then
625 echo "Error
: TPM should have removed PID
file by now.
"
629 if wait_process_gone ${PID} 4; then
630 echo "Error
: Socket TPM should not be running anymore.
"
634 # (Currently) expecting to see nothing in the log file
635 check_logfile_patterns_level_1 $LOG_FILE 0