#!/usr/bin/env bash # For the license, see the LICENSE file in the root directory. #set -x if [ "$(id -u)" -ne 0 ]; then echo "Need to be root to run this test." exit 77 fi ROOT=${abs_top_builddir:-$(dirname "$0")/..} TESTDIR=${abs_top_testdir:-$(dirname "$0")} SWTPM=swtpm SWTPM_EXE=${SWTPM_EXE:-$ROOT/src/swtpm/$SWTPM} TPM_PATH="$(mktemp -d)" || exit 1 STATE_FILE=$TPM_PATH/tpm-00.permall VOLATILE_STATE_FILE=$TPM_PATH/tpm-00.volatilestate PID_FILE=$TPM_PATH/${SWTPM}.pid SOCK_PATH=$TPM_PATH/sock CMD_PATH=$TPM_PATH/cmd RESP_PATH=$TPM_PATH/resp LOGFILE=$TPM_PATH/logfile function cleanup() { pid=$(ps aux | grep $SWTPM | grep -E " file=${PID_FILE}\$" | gawk '{print $2}') if [ -n "$pid" ]; then kill_quiet -9 $pid fi rm -rf $TPM_PATH } trap "cleanup" EXIT source ${TESTDIR}/common skip_test_no_tpm12 "${SWTPM_EXE}" source ${TESTDIR}/load_vtpm_proxy rm -f $STATE_FILE $VOLATILE_STATE_FILE 2>/dev/null $SWTPM_EXE chardev --vtpm-proxy \ --tpmstate dir=$TPM_PATH \ --ctrl type=unixio,path=$SOCK_PATH \ ${SWTPM_TEST_SECCOMP_OPT} \ --pid file=$PID_FILE &>$LOGFILE & sleep 0.5 PID=$(ps aux | grep $SWTPM | grep -E " file=${PID_FILE}\$" | gawk '{print $2}') display_processes_by_name "$SWTPM" kill_quiet -0 $PID if [ $? -ne 0 ]; then echo "Error: Chardev TPM did not start." exit 1 fi if wait_for_file $PID_FILE 3; then echo "Error: Chardev TPM did not write pidfile." exit 1 fi # Wait for chardev to appear; TPM 1.2 may take a long time to self-test # with valgrind for ((i = 0; i < 200; i ++)); do if [ -z "${TPM_DEVICE}" ]; then TPM_DEVICE=$(sed -n 's,.*\(/dev/tpm[0-9]\+\).*,\1,p' $LOGFILE) if [ -n "${TPM_DEVICE}" ]; then echo "Using ${TPM_DEVICE}." fi fi if [ -n "${TPM_DEVICE}" ]; then [ -c "${TPM_DEVICE}" ] && break fi sleep 0.1 done if ! [ -c "${TPM_DEVICE}" ]; then echo "Error: Chardev ${TPM_DEVICE} did not appear" exit 1 fi # Open access to the TPM exec 100<>$TPM_DEVICE if [ $? -ne 0 ]; then echo "Error: Could not open $TPM_DEVICE" exit 1 fi # Read PCR 17 -- this should give a fatal error response echo -en '\x00\xC1\x00\x00\x00\x0E\x00\x00\x00\x15\x00\x00\x00\x11' >&100 #RES=$(cat <&100 | od -t x1 -A n -w128) RES=$(od -t x1 -A n -w128 <&100) exp=' 00 c4 00 00 00 1e 00 00 00 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff' if [ "$RES" != "$exp" ]; then echo "Error: Did not get expected result from TPM_PCRRead(17)" echo "expected: $exp" echo "received: $RES" exit 1 fi exec 100>&- kill_quiet -0 $PID if [ $? -ne 0 ]; then echo "Error: Chardev TPM must have crashed." exit 1 fi if [ ! -e $STATE_FILE ]; then echo "Error: TPM state file $STATE_FILE does not exist." exit 1 fi # Send shutdown command to the TPM: CMD_SHUTDOWN = 00 00 00 03 echo -en '\x00\x00\x00\x03' > $CMD_PATH socat -x -t10 FILE:$CMD_PATH,rdonly UNIX-CONNECT:$SOCK_PATH 2>&1 | \ sed -n '/^ /p' | \ tail -n1 > $RESP_PATH res="$(cat $RESP_PATH)" exp=" 00 00 00 00" if [ "$res" != "$exp" ]; then echo "Error: Unexpected response from CMD_SHUTDOWN:" echo " actual : $res" echo " expected: $exp" exit 1 fi if wait_file_gone $PID_FILE 2; then echo "Error: TPM should have removed PID file by now." exit 1 fi if wait_process_gone ${PID} 4; then echo "Error: TPM should not be running anymore." exit 1 fi echo "OK" exit 0