mirror of
https://github.com/stefanberger/swtpm.git
synced 2025-12-31 20:04:02 +00:00
Some tests are expected to fail. Capture the error output and test it against epected error output. This also makes the test output less noisy. Also remove some other output noise. Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
461 lines
12 KiB
Bash
Executable File
461 lines
12 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# For the license, see the LICENSE file in the root directory.
|
|
#set -x
|
|
|
|
ROOT=${abs_top_builddir:-$(pwd)/..}
|
|
TESTDIR=${abs_top_testdir:-$(dirname "$0")}
|
|
|
|
VTPM_NAME="${VTPM_NAME:-vtpm-test-save-load-encrypted-state}"
|
|
SWTPM_DEV_NAME="/dev/${VTPM_NAME}"
|
|
export TPM_PATH=$(mktemp -d)
|
|
STATE_FILE=$TPM_PATH/tpm-00.permall
|
|
VOLATILE_STATE_FILE=$TPM_PATH/tpm-00.volatilestate
|
|
KEY=1234567890abcdef1234567890abcdef
|
|
MY_VOLATILE_STATE_FILE=$TPM_PATH/my.volatilestate
|
|
MY_PERMANENT_STATE_FILE=$TPM_PATH/my.permanent
|
|
SWTPM_CMD_UNIX_PATH=${TPM_PATH}/unix-cmd.sock
|
|
SWTPM_CTRL_UNIX_PATH=${TPM_PATH}/unix-ctrl.sock
|
|
SWTPM_INTERFACE=${SWTPM_INTERFACE:-cuse}
|
|
|
|
keyfile=$(mktemp)
|
|
logfile=$(mktemp)
|
|
echo "$KEY" > $keyfile
|
|
|
|
function cleanup()
|
|
{
|
|
pid=${SWTPM_PID}
|
|
if [ -n "$pid" ]; then
|
|
kill_quiet -9 $pid
|
|
fi
|
|
rm -f $keyfile $logfile
|
|
rm -rf $TPM_PATH
|
|
}
|
|
|
|
trap "cleanup" EXIT
|
|
|
|
[ "${SWTPM_INTERFACE}" == cuse ] && source ${TESTDIR}/test_cuse
|
|
source ${TESTDIR}/common
|
|
|
|
rm -f $STATE_FILE $VOLATILE_STATE_FILE 2>/dev/null
|
|
|
|
run_swtpm ${SWTPM_INTERFACE} \
|
|
--key file=$keyfile,mode=aes-cbc,format=hex \
|
|
--log file=$logfile
|
|
|
|
display_processes_by_name "$SWTPM"
|
|
|
|
kill_quiet -0 ${SWTPM_PID}
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: ${SWTPM_INTERFACE} TPM did not start."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
|
|
# Init the TPM
|
|
run_swtpm_ioctl ${SWTPM_INTERFACE} -i
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: ${SWTPM_INTERFACE} TPM initialization failed."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
|
|
kill_quiet -0 ${SWTPM_PID} 2>/dev/null
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: ${SWTPM_INTERFACE} TPM not running anymore after INIT."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
|
|
# Startup the TPM
|
|
swtpm_open_cmddev ${SWTPM_INTERFACE} 100
|
|
RES=$(swtpm_cmd_tx ${SWTPM_INTERFACE} '\x00\xC1\x00\x00\x00\x0C\x00\x00\x00\x99\x00\x01')
|
|
exp=' 00 c4 00 00 00 0a 00 00 00 00'
|
|
if [ "$RES" != "$exp" ]; then
|
|
echo "Error: Did not get expected result from TPM_Startup(ST_Clear)"
|
|
echo "expected: $exp"
|
|
echo "received: $RES"
|
|
exit 1
|
|
fi
|
|
|
|
run_swtpm_ioctl ${SWTPM_INTERFACE} -h 1234
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: Could not hash the data."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
|
|
# Read PCR 17
|
|
swtpm_open_cmddev ${SWTPM_INTERFACE} 100
|
|
RES=$(swtpm_cmd_tx ${SWTPM_INTERFACE} '\x00\xC1\x00\x00\x00\x0E\x00\x00\x00\x15\x00\x00\x00\x11')
|
|
exp=' 00 c4 00 00 00 1e 00 00 00 00 97 e9 76 e4 f2 2c d6 d2 4a fd 21 20 85 ad 7a 86 64 7f 2a e5'
|
|
if [ "$RES" != "$exp" ]; then
|
|
echo "Error: (1) Did not get expected result from TPM_PCRRead(17)"
|
|
echo "expected: $exp"
|
|
echo "received: $RES"
|
|
exit 1
|
|
fi
|
|
|
|
# Assert physical presence
|
|
swtpm_open_cmddev ${SWTPM_INTERFACE} 100
|
|
RES=$(swtpm_cmd_tx ${SWTPM_INTERFACE} '\x00\xC1\x00\x00\x00\x0C\x40\x00\x00\x0A\x00\x20')
|
|
exp=' 00 c4 00 00 00 0a 00 00 00 00'
|
|
if [ "$RES" != "$exp" ]; then
|
|
echo "Error: (1) Did not get expected result from TSC_PhysicalPresence(ENABLE)"
|
|
echo "expected: $exp"
|
|
echo "received: $RES"
|
|
exit 1
|
|
fi
|
|
|
|
# Create a big NVRAM Area with 4000 bytes (0xfa0)
|
|
tmp='\x00\xC1\x00\x00\x00\x65\x00\x00\x00\xcc\x00\x18\x00\x00\x00\x01'
|
|
tmp+='\x00\x03\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
|
tmp+='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x01'
|
|
tmp+='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
|
tmp+='\x00\x00\x00\x00\x00\x17\x00\x01\x00\x01\x00\x00\x00\x00\x00\x0f'
|
|
tmp+='\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
|
tmp+='\x00\x00\x00\x00\x00'
|
|
swtpm_open_cmddev ${SWTPM_INTERFACE} 100
|
|
RES=$(swtpm_cmd_tx ${SWTPM_INTERFACE} $tmp)
|
|
exp=' 00 c4 00 00 00 0a 00 00 00 00'
|
|
if [ "$RES" != "$exp" ]; then
|
|
echo "Error: (1) Did not get expected result from TPM_NVDefineSpace()"
|
|
echo "expected: $exp"
|
|
echo "received: $RES"
|
|
exit 1
|
|
fi
|
|
|
|
run_swtpm_ioctl ${SWTPM_INTERFACE} --save permanent $MY_PERMANENT_STATE_FILE
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: Could not write permanent state file $MY_PERMANENT_STATE_FILE."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
if [ ! -r $MY_PERMANENT_STATE_FILE ]; then
|
|
echo "Error: Permanent state file $MY_PERMANENT_STATE_FILE does not exist."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
echo "Saved permanent state."
|
|
|
|
run_swtpm_ioctl ${SWTPM_INTERFACE} --save volatile $MY_VOLATILE_STATE_FILE
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: Could not write volatile state file $MY_PERMANENT_STATE_FILE."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
if [ ! -r $MY_VOLATILE_STATE_FILE ]; then
|
|
echo "Error: Volatile state file $MY_VOLATILE_STATE_FILE does not exist."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
echo "Saved volatile state."
|
|
|
|
#ls -l $(dirname $MY_VOLATILE_STATE_FILE)/*
|
|
#sha1sum $(dirname $MY_VOLATILE_STATE_FILE)/*
|
|
|
|
# we will use our own volatile state
|
|
rm -f $VOLATILE_STATE_FILE $STATE_FILE
|
|
|
|
# Stop the TPM; this will not shut it down
|
|
exec 100>&-
|
|
run_swtpm_ioctl ${SWTPM_INTERFACE} --stop
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error (2): Could not stop the ${SWTPM_INTERFACE} TPM"
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
|
|
kill_quiet -0 ${SWTPM_PID}
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error (2): ${SWTPM_INTERFACE} TPM is not running anymore."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
|
|
# load state into the TPM
|
|
run_swtpm_ioctl ${SWTPM_INTERFACE} --load permanent $MY_PERMANENT_STATE_FILE
|
|
if [ $? -ne 0 ]; then
|
|
echo "Could not load permanent state into vTPM"
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
echo "Loaded permanent state."
|
|
|
|
run_swtpm_ioctl ${SWTPM_INTERFACE} --load volatile $MY_VOLATILE_STATE_FILE
|
|
if [ $? -ne 0 ]; then
|
|
echo "Could not load volatile state into vTPM"
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
echo "Loaded volatile state."
|
|
|
|
#ls -l $(dirname $MY_VOLATILE_STATE_FILE)/*
|
|
#sha1sum $(dirname $MY_VOLATILE_STATE_FILE)/*
|
|
|
|
# Init the TPM
|
|
run_swtpm_ioctl ${SWTPM_INTERFACE} -i
|
|
if [ $? -ne 0 ]; then
|
|
echo "TPM Init failed."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
|
|
# Volatile state must have been removed by TPM now
|
|
if [ -r $VOLATILE_STATE_FILE ]; then
|
|
echo "Error: Volatile state file $VOLATILE_STATE_FILE still exists."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
|
|
# Read the PCR again ...
|
|
swtpm_open_cmddev ${SWTPM_INTERFACE} 100
|
|
RES=$(swtpm_cmd_tx ${SWTPM_INTERFACE} '\x00\xC1\x00\x00\x00\x0E\x00\x00\x00\x15\x00\x00\x00\x11')
|
|
exp=' 00 c4 00 00 00 1e 00 00 00 00 97 e9 76 e4 f2 2c d6 d2 4a fd 21 20 85 ad 7a 86 64 7f 2a e5'
|
|
if [ "$RES" != "$exp" ]; then
|
|
echo "Error: (2) Did not get expected result from TPM_PCRRead(17)"
|
|
echo "expected: $exp"
|
|
echo "received: $RES"
|
|
exit 1
|
|
fi
|
|
|
|
# Save the volatile state again
|
|
run_swtpm_ioctl ${SWTPM_INTERFACE} -v
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: Could not have the ${SWTPM_INTERFACE} TPM write the volatile state to a file."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
if [ ! -r $VOLATILE_STATE_FILE ]; then
|
|
echo "Error: Volatile state file $VOLATILE_STATE_FILE does not exist."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
|
|
# Send a new TPM_Init
|
|
run_swtpm_ioctl ${SWTPM_INTERFACE} -i
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: ${SWTPM_INTERFACE} TPM initialization failed."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
|
|
# Volatile state must have been removed by TPM now
|
|
if [ -r $VOLATILE_STATE_FILE ]; then
|
|
echo "Error: Volatile state file $VOLATILE_STATE_FILE still exists."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
|
|
# Read the PCR again ...
|
|
swtpm_open_cmddev ${SWTPM_INTERFACE} 100
|
|
RES=$(swtpm_cmd_tx ${SWTPM_INTERFACE} '\x00\xC1\x00\x00\x00\x0E\x00\x00\x00\x15\x00\x00\x00\x11')
|
|
exp=' 00 c4 00 00 00 1e 00 00 00 00 97 e9 76 e4 f2 2c d6 d2 4a fd 21 20 85 ad 7a 86 64 7f 2a e5'
|
|
if [ "$RES" != "$exp" ]; then
|
|
echo "Error: (2) Did not get expected result from TPM_PCRRead(17)"
|
|
echo "expected: $exp"
|
|
echo "received: $RES"
|
|
exit 1
|
|
fi
|
|
|
|
run_swtpm_ioctl ${SWTPM_INTERFACE} -s
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: Could not shut down the ${SWTPM_INTERFACE} TPM."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
|
|
if wait_process_gone ${SWTPM_PID} 4; then
|
|
echo "Error: ${SWTPM_INTERFACE} TPM should not be running anymore."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
|
|
echo "Test 1: Ok"
|
|
|
|
# This time start we start the TPM with a wrong state encryption key
|
|
# (key used as password) and try to start it. It has to fail and
|
|
# the state must not have been modified.
|
|
|
|
# volatile state file does not exist
|
|
sha1_volatile=$(get_sha1_file "${VOLATILE_STATE_FILE}")
|
|
sha1_permanent=$(get_sha1_file "${STATE_FILE}")
|
|
echo "sha1(volatile) : $sha1_volatile"
|
|
echo "sha1(permanent): $sha1_permanent"
|
|
|
|
run_swtpm ${SWTPM_INTERFACE} \
|
|
--key pwdfile=$keyfile \
|
|
--log file=$logfile
|
|
|
|
display_processes_by_name "$SWTPM"
|
|
|
|
kill_quiet -0 ${SWTPM_PID}
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: ${SWTPM_INTERFACE} TPM did not start."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
|
|
# Init the TPM
|
|
ERR="$(run_swtpm_ioctl ${SWTPM_INTERFACE} -i 2>&1)"
|
|
if [ $? -eq 0 ]; then
|
|
echo "Error: ${SWTPM_INTERFACE} TPM initialization should have failed."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
exp="TPM result from PTM_INIT: 0x21"
|
|
if [ "$ERR" != "$exp" ]; then
|
|
echo "Error: Unexpected error message"
|
|
echo "Received: $ERR"
|
|
echo "Expected: $exp"
|
|
exit 1
|
|
fi
|
|
|
|
kill_quiet -0 ${SWTPM_PID} 2>/dev/null
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: ${SWTPM_INTERFACE} TPM not running anymore after failed INIT."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
|
|
if [ "${sha1_volatile}" != "$(get_sha1_file "${VOLATILE_STATE_FILE}")" ]; then
|
|
echo "Error: Volatile state file was modified during failed init."
|
|
exit 1
|
|
fi
|
|
|
|
if [ "${sha1_permanent}" != "$(get_sha1_file "${STATE_FILE}")" ]; then
|
|
echo "Error: Permanent state file was modified during failed init."
|
|
exit 1
|
|
fi
|
|
|
|
# shut it down
|
|
run_swtpm_ioctl ${SWTPM_INTERFACE} -s
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: Could not shut down the ${SWTPM_INTERFACE} TPM."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
|
|
if wait_process_gone ${SWTPM_PID} 4; then
|
|
echo "Error: ${SWTPM_INTERFACE} TPM should not be running anymore."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
|
|
echo "Test 2: Ok"
|
|
|
|
# This time start we start the TPM with a different cipher and try to
|
|
# start it. It has to fail and the state must not have been modified.
|
|
|
|
# volatile state file does not exist
|
|
sha1_volatile=$(get_sha1_file "${VOLATILE_STATE_FILE}")
|
|
sha1_permanent=$(get_sha1_file "${STATE_FILE}")
|
|
echo "sha1(volatile) : $sha1_volatile"
|
|
echo "sha1(permanent): $sha1_permanent"
|
|
|
|
# we need a 256bit key
|
|
echo "${KEY}${KEY}" > $keyfile
|
|
|
|
run_swtpm ${SWTPM_INTERFACE} \
|
|
--key pwdfile=$keyfile,mode=aes-256-cbc \
|
|
--log file=$logfile
|
|
|
|
display_processes_by_name "$SWTPM"
|
|
|
|
kill_quiet -0 ${SWTPM_PID}
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: ${SWTPM_INTERFACE} TPM did not start."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
|
|
# Init the TPM
|
|
ERR="$(run_swtpm_ioctl ${SWTPM_INTERFACE} -i 2>&1)"
|
|
if [ $? -eq 0 ]; then
|
|
echo "Error: ${SWTPM_INTERFACE} TPM initialization should have failed."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
exp="TPM result from PTM_INIT: 0x28"
|
|
if [ "$ERR" != "$exp" ]; then
|
|
echo "Error: Unexpected error message"
|
|
echo "Received: $ERR"
|
|
echo "Expected: $exp"
|
|
exit 1
|
|
fi
|
|
|
|
kill_quiet -0 ${SWTPM_PID} 2>/dev/null
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: ${SWTPM_INTERFACE} TPM not running anymore after failed INIT."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
|
|
if [ "${sha1_volatile}" != "$(get_sha1_file "${VOLATILE_STATE_FILE}")" ]; then
|
|
echo "Error: Volatile state file was modified during failed init."
|
|
exit 1
|
|
fi
|
|
|
|
if [ "${sha1_permanent}" != "$(get_sha1_file "${STATE_FILE}")" ]; then
|
|
echo "Error: Permanent state file was modified during failed init."
|
|
exit 1
|
|
fi
|
|
|
|
echo "Test 3: Ok"
|
|
|
|
# Final shut down
|
|
exec 100>&-
|
|
run_swtpm_ioctl ${SWTPM_INTERFACE} -s
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: Could not shut down the ${SWTPM_INTERFACE} TPM."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
|
|
if wait_process_gone ${SWTPM_PID} 4; then
|
|
echo "Error: ${SWTPM_INTERFACE} TPM should not be running anymore."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -e $STATE_FILE ]; then
|
|
echo "Error: TPM state file $STATE_FILE does not exist."
|
|
echo "TPM Logfile:"
|
|
cat $logfile
|
|
exit 1
|
|
fi
|
|
|
|
echo "OK"
|
|
|
|
exit 0
|