swtpm/tests/_test_save_load_encrypted_state
Stefan Berger f759520c02 tests: Check expected error output against expected error message
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>
2018-10-08 06:43:30 -04:00

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