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
|
#!/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")}
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:+${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"
if ! kill_quiet -0 "$PID"; 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
if ! exec 100<>"$TPM_DEVICE"; 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>&-
if ! kill_quiet -0 "$PID"; 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
|