blob: 26b1705b07327b56b38edd1714fedf48dae946b7 [file] [log] [blame]
#!/usr/bin/env bash
# For the license, see the LICENSE file in the root directory.
#set -x
if [ ${SWTPM_TEST_IBMTSS2:-0} -eq 0 ]; then
echo "SWTPM_TEST_IBMTSS2 must be set to run this test."
exit 77
fi
type -p nvdefinespace startup &>/dev/null
if [ $? -ne 0 ]; then
PREFIX=tss
type -p ${PREFIX}nvdefinespace ${PREFIX}startup
fi
if [ $? -ne 0 ]; then
echo "Could not find TPM2 tools (e.g., (tss)startup, (tss)nvdefinespace) in PATH."
exit 77
fi
TOOLSPATH=$(dirname $(type -P ${PREFIX}startup))
ROOT=${abs_top_builddir:-$(dirname "$0")/..}
TESTDIR=${abs_top_testdir:-$(dirname "$0")}
SWTPM=swtpm
SWTPM_EXE=${SWTPM_EXE:-$ROOT/src/swtpm/$SWTPM}
SWTPM_IOCTL=$ROOT/src/swtpm_ioctl/swtpm_ioctl
TPMDIR="$(mktemp -d)" || exit 1
PID_FILE=$TPMDIR/${SWTPM}.pid
SOCK_PATH=$TPMDIR/sock
CMD_PATH=$TPMDIR/cmd
RESP_PATH=$TPMDIR/resp
LOGFILE=$TPMDIR/logfile
TMPFILE=$TPMDIR/tmpfile
BINFILE=$TPMDIR/binfile
SIGFILE=$TPMDIR/sigfile
STATEFILE=${STATEFILE:-$TPMDIR/state}
STORE_PARAM="dir=$TPMDIR"
if [ ${SWTPM_TEST_LINEAR_FILE:-0} -ne 0 ]; then
echo "Testing with linear file backend ($STATEFILE)"
STORE_PARAM="backend-uri=file://$STATEFILE"
fi
source ${TESTDIR}/test_common
source ${TESTDIR}/common
skip_test_no_tpm20 "${SWTPM_EXE}"
trap "cleanup" SIGTERM EXIT
function cleanup()
{
rm -rf $TPMDIR
# remove files from tss tools
rm -f h01*.bin nvp*.bin
if [ -n "$PID" ]; then
kill_quiet -SIGTERM $PID 2>/dev/null
fi
}
# Fill up the NVRAM space with 2048 bit signing keys and then an NVRAM area that
# fills it up to the last byte. We want to make sure that the OBJECTs that the
# RSA keys are creating in NVRAM can be loaded into the NVRAM again when the size
# of the OBJECT increases when for example the size of the RSA keys increases.
# This may force us to increase the NVRAM memory space in libtpms then.
function fillup_nvram()
{
local create="$1"
local check="$2"
local i sz
if [ $create -eq 1 ]; then
# Fill up the NVRAM space with RSA 2048 keys;
# exactly 65 have to fit
${TOOLSPATH}/${PREFIX}createprimary -hi o -si > $TMPFILE
if [ $? -ne 0 ]; then
echo "Error: createprimary failed."
exit 1
fi
if [ -z "$(grep 80000000 $TMPFILE)" ]; then
echo "Error: createprimary did not result in expected handle 80000000"
exit 1
fi
for ((i = 0x81000000; i < 0x81000100; i++)); do
${TOOLSPATH}/${PREFIX}evictcontrol \
-hi o \
-ho 80000000 \
-hp $(printf "%x" $i) &>$TMPFILE || break
done
${TOOLSPATH}/${PREFIX}getcapability -cap 1 -pr 81000000 -pc 80 > $TMPFILE
# We need know we need to see '65 Handles' for state created with
# libtpms-0.6.0 and 128kb NVRAM size
grep -i "65 Handles" $TMPFILE
if [ $? -ne 0 ]; then
echo "Error: Did not find '65 Handles' keyword in output"
cat $TMPFILE
exit 1
fi
# Fill up the rest of the NVRAM with a single NVRAM index whose size
# we now have to find;
# for reference: libtpms v0.6.0 allowed 236 bytes
for ((sz = 0; ; sz++)); do
${TOOLSPATH}/${PREFIX}nvdefinespace \
-hi o \
-ha 01000000 \
-sz ${sz} > ${TMPFILE} || break
# this worked, so lets remove it and try the next size
#echo "NVRAM space of size $sz could be created"
${TOOLSPATH}/${PREFIX}nvundefinespace \
-hi o \
-ha 01000000 > ${TMPFILE}
done
if [ $sz -gt 0 ]; then
sz=$((sz - 1))
echo "Creating final space of size ${sz}"
${TOOLSPATH}/${PREFIX}nvdefinespace \
-hi o \
-ha 01000000 \
-sz ${sz} > ${TMPFILE}
if [ $? -ne 0 ]; then
echo "Error: Could not create final NVRAM space."
cat ${TMPFILE}
exit 1
fi
fi
if [ $sz -eq 0 ]; then
echo "Error: NVRAM space could not be created at all; not enough space!"
exit 1
elif [ $sz -lt 236 ]; then
echo "Error: Insufficient NVRAM memory. Needed to create an NVRAM index with size 236 bytes."
exit 1
elif [ $sz -gt 236 ]; then
echo "Error: The NVRAM index is too large. Only needed 236 bytes but got $sz bytes."
exit 1
else
echo "The NVRAM index is exactly of the right size (236 bytes)."
fi
echo -n "123" > $BINFILE
${TOOLSPATH}/${PREFIX}sign \
-hk 81000000 \
-if ${BINFILE} \
-os ${SIGFILE} > $TMPFILE
if [ $? -ne 0 ]; then
echo "Error: Could not create signature."
cat $TMPFILE
exit 1
fi
fi
if [ $check -eq 1 ]; then
${TOOLSPATH}/${PREFIX}getcapability -cap 1 -pr 81000000 -pc 80 > $TMPFILE
# We need know we need to see '65 Handles' for state created with
# libtpms-0.6.0 and 128kb NVRAM size
grep -i "65 Handles" $TMPFILE
if [ $? -ne 0 ]; then
echo "Error: Did not find '65 Handles' keyword in output"
cat $TMPFILE
exit 1
fi
printf "Verifying signature with all the persisted keys\n"
echo -n "123" > $BINFILE
for ((i = 0x81000000; i < 0x81000040; i++)); do
${TOOLSPATH}/${PREFIX}verifysignature \
-hk $(printf "%x" $i) \
-is ${SIGFILE} \
-if ${BINFILE} > $TMPFILE
if [ $? -ne 0 ]; then
echo "Verifying signature failed for handle $(printf "%x" $i)."
exit 1
fi
done
fi
}
export TPM_SERVER_TYPE=raw
export TPM_SERVER_NAME=127.0.0.1
export TPM_INTERFACE_TYPE=socsim
export TPM_COMMAND_PORT=${TPM_COMMAND_PORT:-65460}
export TPM_DATA_DIR=$TPMDIR
export TPM_SESSION_ENCKEY="807e2bfe898ddaed8fa6310e716a24dc" # for sessions
$SWTPM_EXE socket \
--server port=${TPM_COMMAND_PORT} \
--tpmstate $STORE_PARAM \
--pid file=$PID_FILE \
--ctrl type=unixio,path=$SOCK_PATH \
--log file=$LOGFILE,level=20 \
--tpm2 \
${SWTPM_TEST_SECCOMP_OPT} &
if wait_for_file $PID_FILE 3; then
echo "Error: (1) Socket TPM did not write pidfile."
exit 1
fi
PID="$(cat $PID_FILE)"
# Send TPM_Init
act=$($SWTPM_IOCTL --unix $SOCK_PATH -i 2>&1)
if [ $? -ne 0 ]; then
echo "Error: $SWTPM_IOCTL CMD_INIT failed: $act"
exit 1
fi
${TOOLSPATH}/${PREFIX}startup -c
if [ $? -ne 0 ]; then
echo "Error: tpm_startup clear failed."
exit 1
fi
fillup_nvram 1 1
# Send Shutdown
act=$($SWTPM_IOCTL --unix $SOCK_PATH -s 2>&1)
if [ $? -ne 0 ]; then
echo "Error: $SWTPM_IOCTL CMD_SHUTDOWN failed: $act"
exit 1
fi
if wait_process_gone ${PID} 4; then
echo "Error: swtpm did not shut down"
exit 1
fi
echo "============================" >> $LOGFILE
echo "TPM was shut down"
# Store this state for later usage; use a really old version of libtpms: 0.6.0
#cp $TPMDIR/tpm2-00.permall ${TESTDIR}/data/tpm2state5;
#cp $SIGFILE ${TESTDIR}/data/tpm2state5/signature.bin
#################################################################
# Run TPM2 with the created state and verify it's the same
$SWTPM_EXE socket \
--server port=${TPM_COMMAND_PORT} \
--tpmstate $STORE_PARAM \
--pid file=$PID_FILE \
--ctrl type=unixio,path=$SOCK_PATH \
--log file=$LOGFILE,level=20 \
--tpm2 \
${SWTPM_TEST_SECCOMP_OPT} &
if wait_for_file $PID_FILE 3; then
echo "Error: (2) Socket TPM did not write pidfile."
exit 1
fi
echo "TPM re-started"
PID="$(cat $PID_FILE)"
# Send TPM_Init
act=$($SWTPM_IOCTL --unix $SOCK_PATH -i 2>&1)
if [ $? -ne 0 ]; then
echo "Error: $SWTPM_IOCTL CMD_INIT failed: $act"
cat $LOGFILE
exit 1
fi
${TOOLSPATH}/${PREFIX}startup -c
if [ $? -ne 0 ]; then
echo "Error: tpm_startup clear failed."
cat $LOGFILE
exit 1
fi
fillup_nvram 0 1
${TOOLSPATH}/${PREFIX}shutdown -c
if [ $? -ne 0 ]; then
echo "Error: tpm_shutdown clear failed."
cat $LOGFILE
exit 1
fi
# Send Shutdown
act=$($SWTPM_IOCTL --unix $SOCK_PATH -s 2>&1)
if [ $? -ne 0 ]; then
echo "Error: $SWTPM_IOCTL CMD_SHUTDOWN failed: $act"
exit 1
fi
echo "============================" >> $LOGFILE
echo "TPM was shut down"
#################################################################
# Run TPM2 with previously saved state and verify it's the same
if [ ${SWTPM_TEST_LINEAR_FILE:-0} -ne 0 ]; then
echo "Test 1 OK (skipped last with linear file)"
exit 0
fi
rm -f $TPMDIR/*
cp -f ${TESTDIR}/data/tpm2state5/tpm2-00.permall $TPMDIR/tpm2-00.permall
cp ${TESTDIR}/data/tpm2state5/signature.bin $SIGFILE
$SWTPM_EXE socket \
--server port=${TPM_COMMAND_PORT} \
--tpmstate $STORE_PARAM \
--pid file=$PID_FILE \
--ctrl type=unixio,path=$SOCK_PATH \
--log file=$LOGFILE,level=20 \
--tpm2 \
${SWTPM_TEST_SECCOMP_OPT} &
if wait_for_file $PID_FILE 3; then
echo "Error: (3) Socket TPM did not write pidfile."
exit 1
fi
echo "TPM started with previously generated state"
PID="$(cat $PID_FILE)"
# Send TPM_Init
act=$($SWTPM_IOCTL --unix $SOCK_PATH -i 2>&1)
if [ $? -ne 0 ]; then
echo "Error: $SWTPM_IOCTL CMD_INIT failed: $act"
exit 1
fi
${TOOLSPATH}/${PREFIX}startup -c
if [ $? -ne 0 ]; then
echo "Error: tpm_startup clear failed."
cat $LOGFILE
exit 1
fi
fillup_nvram 0 1
${TOOLSPATH}/${PREFIX}shutdown -c
if [ $? -ne 0 ]; then
echo "Error: tpm_shutdown clear failed."
cat $LOGFILE
exit 1
fi
# Send Shutdown
act=$($SWTPM_IOCTL --unix $SOCK_PATH -s 2>&1)
if [ $? -ne 0 ]; then
echo "Error: $SWTPM_IOCTL CMD_SHUTDOWN failed: $act"
exit 1
fi
echo "Test 1 OK"