blob: aa5c0055a8f50dfd01484ded830f3a92c1b491b2 [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
LOGFILE=$TPMDIR/logfile
TMPFILE=$TPMDIR/tmpfile
BINFILE=$TPMDIR/binfile
SIGFILE=$TPMDIR/sigfile
SIGFILE2=$TPMDIR/sigfile2
TMP2FILE=$TPMDIR/tmpfile2
PRIVKEY=$TPMDIR/privkey.pem
PUBKEY=$TPMDIR/pubkey.pem
PUBKEYCONTEXT=$TPMDIR/pubkey.context
HKEYPRIV=${TESTDIR}/data/tpm2state3/hkey.priv
HKEYPUB=${TESTDIR}/data/tpm2state3/hkey.pub
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
}
function test_nvram_state()
{
local create="$1"
local check="$2"
local i res rc act exp ody
if [ "$create" -eq 1 ]; then
# the 1st and 2nd spaces are 'orderly' and will be cleared by reset
ody="+at ody"
for ((i=0; i < 10; i++)); do
printf "Creating NVRAM location 01%06x\n" "$i"
# the '+at wd' allows us to only write once
"${TOOLSPATH}/${PREFIX}nvdefinespace" \
-ha "$(printf "01%06x" "$i")" \
-sz $((100 + i * 10)) \
-pwdn nnn \
+at wst \
+at wd \
${ody:+${ody}} \
-hi o >/dev/null
if [ $? -ne 0 ]; then
echo "Error: nvdefinespace failed for i = $i."
exit 1
fi
if [ "$i" -eq 1 ]; then
ody=""
fi
"${TOOLSPATH}/${PREFIX}nvwrite" \
-ha "$(printf "01%06x" "$i")" \
-ic "Hello TPM2" \
-pwdn nnn
if [ $? -ne 0 ]; then
echo "Error: nwrite failed for i = $i."
exit 1
fi
"${TOOLSPATH}/${PREFIX}nvwritelock" \
-ha "$(printf "01%06x" "$i")" \
-pwdn nnn
if [ $? -ne 0 ]; then
echo "Error: nwritelock failed for i = $i."
exit 1
fi
done
# Create a counter space
echo "Creating NVRAM location 01000010 for counter"
"${TOOLSPATH}/${PREFIX}nvdefinespace" \
-hi o \
-ha 01000010 \
-pwdn nnn \
-ty c >/dev/null
if [ $? -ne 0 ]; then
echo "Error: nvdefinespace for counter failed."
exit 1
fi
echo "Incrementing the counter at location 01000010"
"${TOOLSPATH}/${PREFIX}nvincrement" \
-ha 01000010 \
-pwdn nnn >/dev/null
if [ $? -ne 0 ]; then
echo "Error: nvincrement failed."
exit 1
fi
fi
if [ "$check" -eq 1 ]; then
local last=0
if [ "$create" -eq 0 ]; then
last=2
fi
# The orderly indices must not be readable UNLESS they were just
# created. In the latter case we skip this first loop here.
for ((i=0; i < last; i++)); do
printf "Checking orderly NVRAM location 01%06x after reset\n" "$i"
"${TOOLSPATH}/${PREFIX}nvread" \
-ha "$(printf "01%06x" "$i")" \
-pwdn nnn \
-sz 10 > "$TMPFILE"
if [ $? -eq 0 ]; then
echo "Error: nvread succeeded for orderly NVRAM index; i = $i"
cat "$TMPFILE"
exit 1
fi
done
# test the non-orderly indices OR orderly we just created above
for ((i=last; i < 10; i++)); do
printf "Checking NVRAM location 01%06x\n" "$i"
"${TOOLSPATH}/${PREFIX}nvread" \
-ha "$(printf "01%06x" "$i")" \
-pwdn nnn \
-sz 10 > "$TMPFILE"
if [ $? -ne 0 ]; then
echo "Error: nvread failed for i = $i"
cat "$TMPFILE"
exit 1
fi
# we want one line with xdigits and spaces
res=$(grep -c -E "^[ [:xdigit:]]+$" < "$TMPFILE")
if [ "$res" -ne 1 ]; then
echo "Error: nvread did not show expected results"
cat "$TMPFILE"
fi
"${TOOLSPATH}/${PREFIX}nvwrite" \
-ha "$(printf "01%06x" "$i")" \
-ic "Hello TPM2" \
-pwdn nnn > "$TMPFILE"
rc=$?
if [ "$rc" -eq 0 ]; then
echo "Error: nwrite succeeded for i = $i."
exit 1
fi
done
# Read the counter
echo "Checking counter value at location 01000010"
"${TOOLSPATH}/${PREFIX}nvread" \
-ha 01000010 \
-pwdn nnn \
-sz 8 \
-of "$BINFILE" > "$TMPFILE"
if [ $? -ne 0 ]; then
echo "Error: nvread of counter failed."
cat "$TMPFILE"
exit 1
fi
exp=' 00 00 00 00 00 00 00 01'
act="$(od -t x1 -A n < "$BINFILE")"
if [ "$act" != "$exp" ]; then
echo "Error: Counter has unexpected value."
echo " expected: $exp"
echo " actual : $act"
fi
fi
}
function test_primary()
{
local create="$1"
local check="$2"
# whether we are using previous stored stated that had a different
# key and we have to use the old signature
local previousstate="$3"
local i res rc
if [ "$create" -eq 1 ]; then
# Create a permanent primary key that we expecte
# to again see after the TPM has been restarted
"${TOOLSPATH}/${PREFIX}createprimary" -hi o -si > "$TMPFILE"
if [ $? -ne 0 ]; then
echo "Error: createprimary failed."
exit 1
fi
if ! grep -q 80000000 "$TMPFILE"; then
echo "Error: createprimary did not result in expected handle 80000000"
exit 1
fi
"${TOOLSPATH}/${PREFIX}evictcontrol" -ho 80000000 -hp 81000000 -hi o
if [ $? -ne 0 ]; then
echo "Error: evictcontrol did not work"
exit 1
fi
"${TOOLSPATH}/${PREFIX}flushcontext" -ha 80000000
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
printf "Checking availability of key with perm. handle 0x81000000\n"
"${TOOLSPATH}/${PREFIX}getcapability" -cap 1 -pr 0x81000000 >"$TMPFILE"
if ! grep -q 81000000 "$TMPFILE"; then
echo "Could not find key with permanent handle 0x81000000"
exit 1
fi
printf "Verifying signature with this key\n"
echo -n "123" > "$BINFILE"
if [ "$previousstate" -eq 0 ]; then
"${TOOLSPATH}/${PREFIX}verifysignature" -hk 81000000 \
-is "${SIGFILE}" \
-if "${BINFILE}" > "$TMPFILE"
else
"${TOOLSPATH}/${PREFIX}verifysignature" -hk 81000000 \
-is "${TESTDIR}/data/tpm2state3/signature.bin" \
-if "${BINFILE}" > "$TMPFILE"
fi
if [ $? -ne 0 ]; then
echo "Verifying signature failed."
exit 1
fi
fi
}
# Allocate a SHA256 PCR bank
# This will prevent shutdown -s (with state)
function test_pcr_allocation()
{
local create="$1"
local check="$2"
local i res rc ha
if ! "$TOOLSPATH/${PREFIX}pcrallocate" | grep -q sha512; then
echo " Skipping PCR Allocate test since it does not support sha512"
return 0
fi
if [ "$create" -eq 1 ]; then
echo "Allocating SHA256 PCR bank"
"${TOOLSPATH}/${PREFIX}pcrallocate" -sha512 +sha256
for ((ha = 0; ha < 24; ha++)); do
"${TOOLSPATH}/${PREFIX}pcrread" -ha "${ha}" -halg sha512 > "$TMPFILE"
if ! grep -q "^count 1.*$" "$TMPFILE"; then
echo "Error: PCR ${ha} in SHA512 bank should be available for read before reboot"
cat "$TMPFILE"
exit 1
fi
"${TOOLSPATH}/${PREFIX}pcrread" -ha "${ha}" -halg sha256 > "$TMPFILE"
if ! grep -q "^count 1.*$" "$TMPFILE"; then
echo "Error: PCR ${ha} in SHA256 bank should be available for read before reboot"
cat "$TMPFILE"
exit 1
fi
done
fi
if [ "$check" -eq 1 ]; then
echo "Checking the PCR Allocation"
for ((ha = 0; ha < 24; ha++)); do
"${TOOLSPATH}/${PREFIX}pcrread" -ha "${ha}" -halg sha512 > "$TMPFILE"
if ! grep -q "^count 0.*$" "$TMPFILE"; then
echo "Error: PCR ${ha} in SHA512 bank should be unavailable for read after reboot"
cat "$TMPFILE"
exit 1
fi
"${TOOLSPATH}/${PREFIX}pcrread" -ha "${ha}" -halg sha256 > "$TMPFILE"
if ! grep -q "^count 1.*$" "$TMPFILE"; then
echo "Error: PCR ${ha} in SHA256 bank should be available for read after reboot"
exit 1
fi
done
fi
}
function test_hierarchy()
{
local create="$1"
local check="$2"
local hi pwdn pwda
if [ "$create" -eq 1 ]; then
echo "Setting hierarchy passwords"
# Change the hierarchy password; the 'p' hierarchy has
# no effect on permanent RAM, so we won't test that
for hi in "l" "e" "o"; do
pwdn="${hi}${hi}${hi}"
"${TOOLSPATH}/${PREFIX}hierarchychangeauth" \
-hi "${hi}" \
-pwdn "${pwdn}" > "$TMPFILE"
if [ $? -ne 0 ]; then
echo "Error: hierarchychangeauth failed to set password."
cat "$TMPFILE"
exit 1
fi
done
fi
if [ "$check" -eq 1 ]; then
echo "Checking previously set hierarchy passwords"
for hi in "l" "e" "o"; do
pwda="${hi}${hi}${hi}"
pwdn="new-${pwda}"
"${TOOLSPATH}/${PREFIX}hierarchychangeauth" \
-hi "${hi}" \
-pwda "${pwda}" \
-pwdn "${pwdn}" > "$TMPFILE"
if [ $? -ne 0 ]; then
echo "Error: hierarchychangeauth failed to change password."
cat "$TMPFILE"
exit 1
fi
# change back
"${TOOLSPATH}/${PREFIX}hierarchychangeauth" \
-hi "${hi}" \
-pwda "${pwdn}" \
-pwdn "${pwda}" > "$TMPFILE"
if [ $? -ne 0 ]; then
echo "Error: hierarchychangeauth failed to change back password."
cat "$TMPFILE"
exit 1
fi
done
fi
}
function test_hash_context()
{
local create="$1"
local check="$2"
local res
if [ "$create" -eq 1 ]; then
echo -n "123" > "${TMP2FILE}"
echo "Starting a sha1 sequence"
res="$("${TOOLSPATH}/${PREFIX}hashsequencestart" -halg sha1)"
if [ $? -ne 0 ]; then
echo "Error: Could not start hash sequence."
exit 1
fi
SHA1_SEQUENCE_HANDLE="$(echo "$res" | cut -d " " -f3)"
echo "sha1 sequence handle: $SHA1_SEQUENCE_HANDLE"
"${TOOLSPATH}/${PREFIX}sequenceupdate" \
-hs "${SHA1_SEQUENCE_HANDLE}" \
-if "${TMP2FILE}"
if [ $? -ne 0 ]; then
echo "Error: Could not updated the sha1 sequence."
exit 1
fi
echo "Updated sha1 sequence."
echo "Starting a sha256 sequence"
res="$("${TOOLSPATH}/${PREFIX}hashsequencestart" -halg sha256)"
if [ $? -ne 0 ]; then
echo "Error: Could not start sha256 sequence."
exit 1
fi
SHA256_SEQUENCE_HANDLE="$(echo "$res" | cut -d " " -f3)"
echo "sha256 sequence handle: $SHA256_SEQUENCE_HANDLE"
"${TOOLSPATH}/${PREFIX}sequenceupdate" \
-hs "${SHA256_SEQUENCE_HANDLE}" \
-if "${TMP2FILE}"
if [ $? -ne 0 ]; then
echo "Error: Could not updated the hash sequence."
exit 1
fi
echo "Updated sha256 sequence."
echo "Starting a sha384 sequence"
res="$("${TOOLSPATH}/${PREFIX}hashsequencestart" -halg sha384)"
if [ $? -ne 0 ]; then
echo "Error: Could not start sha384 sequence."
exit 1
fi
SHA384_SEQUENCE_HANDLE="$(echo "$res" | cut -d " " -f3)"
echo "sha384 sequence handle: $SHA384_SEQUENCE_HANDLE"
"${TOOLSPATH}/${PREFIX}sequenceupdate" \
-hs "${SHA384_SEQUENCE_HANDLE}" \
-if "${TMP2FILE}"
if [ $? -ne 0 ]; then
echo "Error: Could not updated the hash sequence."
exit 1
fi
echo "Updated sha384 sequence."
fi
if [ "$check" -eq 1 ]; then
echo -n "456" > "${TMP2FILE}"
echo "Completing previously started sha1 sequence"
touch "$TPMDIR/h${SHA1_SEQUENCE_HANDLE}.bin"
res=$("${TOOLSPATH}/${PREFIX}sequencecomplete" \
-hs "${SHA1_SEQUENCE_HANDLE}" \
-if "${TMP2FILE}" -v |
tail -n 4 |
grep " 7c 4a 8d ")
if [ -z "$res" ]; then
echo "Error: Did not get expected result from completing sha1 sequence."
exit 1
fi
echo "Completing previously started sha256 sequence"
touch "$TPMDIR/h${SHA256_SEQUENCE_HANDLE}.bin"
res=$("${TOOLSPATH}/${PREFIX}sequencecomplete" \
-hs "${SHA256_SEQUENCE_HANDLE}" \
-if "${TMP2FILE}" -v |
tail -n 4 |
grep " 8d 96 9e ")
if [ -z "$res" ]; then
echo "Error: Did not get expected result from completing sha256 sequence."
exit 1
fi
echo "Completing previously started sha384 sequence"
touch "$TPMDIR/h${SHA384_SEQUENCE_HANDLE}.bin"
res=$("${TOOLSPATH}/${PREFIX}sequencecomplete" \
-hs "${SHA384_SEQUENCE_HANDLE}" \
-if "${TMP2FILE}" -v |
tail -n 4 |
grep " 0a 98 9e ")
if [ -z "$res" ]; then
echo "Error: Did not get expected result from completing sha384 sequence."
exit 1
fi
fi
}
function test_session()
{
local create="$1"
local check="$2"
# whether we are using previous stored stated that had a different
# key and we have to use the old signature
local previousstate="$3"
local i res rc
if [ "$create" -eq 1 ]; then
# Create a permanent primary key that we expecte
# to again see after the TPM has been restarted
"${TOOLSPATH}/${PREFIX}createprimary" -hi o -st > "$TMPFILE"
if [ $? -ne 0 ]; then
echo "Error: createprimary for creating storage key failed."
exit 1
fi
if ! grep -q 80000000 "$TMPFILE"; then
echo "Error: createprimary did not result in expected handle 80000000"
cat "$TMPFILE"
exit 1
fi
"${TOOLSPATH}/${PREFIX}evictcontrol" -ho 80000000 -hp 81000000 -hi o
if [ $? -ne 0 ]; then
echo "Error: evictcontrol did not work"
exit 1
fi
"${TOOLSPATH}/${PREFIX}flushcontext" -ha 80000000
"${TOOLSPATH}/${PREFIX}startauthsession" -se h -bi 81000000 > "$TMPFILE"
if [ $? -ne 0 ]; then
echo "Error: Could not start an auth session."
cat "$TMPFILE"
exit 1
fi
AUTHSESSION_HANDLE=$(sed 's/Handle//' "$TMPFILE")
if [ -z "${AUTHSESSION_HANDLE}" ]; then
echo "Error: Could not get auth session handle."
exit 1
fi
fi
if [ "$check" -eq 1 ]; then
echo "Using auth session ${AUTHSESSION_HANDLE} to create a key."
"${TOOLSPATH}/${PREFIX}create" \
-hp 81000000 \
-st \
-se0 "${AUTHSESSION_HANDLE}" 1
if [ $? -ne 0 ]; then
echo "Error: Could not create key using authsession"
exit 1
fi
echo "Successfully created key"
fi
}
function test_hmac_context()
{
local create="$1"
local check="$2"
# whether we are using previous stored stated that had a different
# key and we have to use the old signature
local previousstate="$3"
local i res rc
if [ "$create" -eq 1 ]; then
"${TOOLSPATH}/${PREFIX}createprimary" -hi o -st > "$TMPFILE"
if [ $? -ne 0 ]; then
echo "Error: createprimary failed."
exit 1
fi
if ! grep -q 80000000 "$TMPFILE"; then
echo "Error: createprimary did not result in expected handle 80000000"
exit 1
fi
"${TOOLSPATH}/${PREFIX}create" -hp 80000000 -kh \
-opr "${HKEYPRIV}" -opu "${HKEYPUB}" > "$TMPFILE"
if [ $? -ne 0 ]; then
echo "Error: could not create key for HMAC"
exit 1
fi
"${TOOLSPATH}/${PREFIX}load" -hp 80000000 \
-ipr "${HKEYPRIV}" -ipu "${HKEYPUB}" -v > "$TMPFILE"
if [ $? -ne 0 ]; then
echo "Error: could not load key for HMAC"
cat "$TMPFILE"
exit 1
fi
if ! grep -q 80000001 "$TMPFILE"; then
echo "Error: load did not result in expected handle 80000001"
exit 1
fi
"${TOOLSPATH}/${PREFIX}hmacstart" -hk 80000001 > "$TMPFILE"
if [ $? -ne 0 ]; then
echo "Error: could not start HMAC sequence"
exit 1
fi
if ! grep -q 80000002 "$TMPFILE"; then
echo "Error: load did not result in expected handle 80000002"
exit 1
fi
echo -n "123" > "${TMP2FILE}"
"${TOOLSPATH}/${PREFIX}sequenceupdate" \
-hs 80000002 \
-if "${TMP2FILE}"
if [ $? -ne 0 ]; then
echo "Error: Could not updated the HMAC sequence."
exit 1
fi
echo "Updated HMAC sequence."
fi
if [ "$check" -eq 1 ]; then
echo -n "456" > "${TMP2FILE}"
echo "Completing previously started HMAC sequence"
touch "$TPMDIR/h80000002.bin"
"${TOOLSPATH}/${PREFIX}sequencecomplete" \
-hs 80000002 \
-if "${TMP2FILE}" -v |
tail -n 4 > "${TMPFILE}"
if ! grep -q " 6e 40 33 1a " "${TMPFILE}"; then
echo "Error: Did not get expected result from completing HMAC sequence."
cat "$TMPFILE"
exit 1
fi
fi
}
function test_primary_volatile_load()
{
local create="$1"
local check="$2"
# whether we are using previous stored stated that had a different
# key and we have to use the old signature
local previousstate="$3"
local i res rc
if [ "$create" -eq 1 ]; then
# Create a permanent primary key that we expecte
# to again see after the TPM has been restarted
"${TOOLSPATH}/${PREFIX}createprimary" -hi o -si > "$TMPFILE"
if [ $? -ne 0 ]; then
echo "Error: createprimary failed."
exit 1
fi
if ! grep -q 80000000 "$TMPFILE"; then
echo "Error: createprimary did not result in expected handle 80000000"
exit 1
fi
echo -n "123" > "$BINFILE"
"${TOOLSPATH}/${PREFIX}sign" -hk 80000000 -if "${BINFILE}" -os "${SIGFILE}" > "$TMPFILE"
if [ $? -ne 0 ]; then
echo "Error: Could not create signature."
cat "$TMPFILE"
exit 1
fi
printf "Verifying signature with this key (create phase)\n"
"${TOOLSPATH}/${PREFIX}verifysignature" -hk 80000000 \
-is "${SIGFILE}" \
-if "${BINFILE}" > "$TMPFILE"
if [ $? -ne 0 ]; then
echo "Verifying signature failed."
exit 1
fi
fi
if [ "$check" -eq 1 ]; then
local sigfile=${SIGFILE} hash1 hash2
if [ "$previousstate" -ne 0 ]; then
sigfile=${TESTDIR}/data/tpm2state3d/signature2.bin
fi
printf "Checking availability of key with handle 0x80000000\n"
"${TOOLSPATH}/${PREFIX}getcapability" -cap 1 -pr 0x80000000 > "$TMPFILE"
if ! grep -q 80000000 "$TMPFILE"; then
echo "Could not find key with handle 0x80000000"
exit 1
fi
printf "Verifying signature with this key (check phase)\n"
echo -n "123" > "$BINFILE"
"${TOOLSPATH}/${PREFIX}verifysignature" -hk 80000000 \
-is "${sigfile}" \
-if "${BINFILE}" > "$TMPFILE"
if [ $? -ne 0 ]; then
echo "Verifying signature failed."
exit 1
fi
if [ "$previousstate" -eq 0 ]; then
"${TOOLSPATH}/${PREFIX}sign" -hk 80000000 -if "${BINFILE}" -os "${SIGFILE2}" > "$TMPFILE"
if [ $? -ne 0 ]; then
echo "Error: Could not create signature."
cat "$TMPFILE"
exit 1
fi
hash1=$(get_sha1_file "${SIGFILE}")
hash2=$(get_sha1_file "${SIGFILE2}")
if [ "${hash1}" != "${hash2}" ]; then
echo "Error: hashes of signatures are different. Loaded key may be different."
exit 1
fi
fi
fi
}
# libtpms issue #195: Create an external key and load it into the TPM 2
# and do a context save/load cycle
function test_external_key()
{
local create="$1"
local check="$2"
if [ "$create" -eq 1 ]; then
${CERTTOOL} --generate-privkey --bits 2048 --outfile "${PRIVKEY}" &>/dev/null
${CERTTOOL} --pubkey-info --load-privkey "${PRIVKEY}" > "${PUBKEY}"
"$TOOLSPATH/${PREFIX}loadexternal" -hi o -ipem "${PUBKEY}" > "$TMPFILE"
if [ $? -ne 0 ]; then
echo "Error: loadexternal failed."
exit 1
fi
if ! grep -q 80000001 "$TMPFILE"; then
echo "Error: loadexternal did not result in expected handle 80000001"
exit 1
fi
fi
if [ "$check" -eq 1 ]; then
"$TOOLSPATH/${PREFIX}contextsave" -ha 80000001 -of "${PUBKEYCONTEXT}"
if [ $? -ne 0 ]; then
echo "Error: contextsave on loaded public key failed."
exit 1
fi
"$TOOLSPATH/${PREFIX}flushcontext" -ha 80000001
"$TOOLSPATH/${PREFIX}contextload" -if "${PUBKEYCONTEXT}" > "$TMPFILE"
if [ $? -ne 0 ]; then
echo "Error: contextload on context of public key failed."
exit 1
fi
if ! grep -q 80000001 "$TMPFILE"; then
echo "Error: contextload did not result in expected handle 80000001"
exit 1
fi
fi
}
export TPM_SERVER_TYPE=raw
export TPM_SERVER_NAME=127.0.0.1
export TPM_INTERFACE_TYPE=socsim
export TPM_COMMAND_PORT=65533
export TPM_DATA_DIR=$TPMDIR
export TPM_SESSION_ENCKEY="807e2bfe898ddaed8fa6310e716a24dc" # for sessions
$SWTPM_EXE socket \
--server port=${TPM_COMMAND_PORT} \
--tpmstate "dir=$TPMDIR" \
--pid "file=$PID_FILE" \
--ctrl "type=unixio,path=$SOCK_PATH" \
--log "file=$LOGFILE,level=20" \
--tpm2 \
${SWTPM_TEST_SECCOMP_OPT:+${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
test_nvram_state 1 1
test_primary 1 1 0
test_pcr_allocation 1 0 # can only check after reboot
test_hierarchy 1 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"
# Store this state for later usage
# cp $TPMDIR/tpm2-00.permall ${TESTDIR}/data/tpm2state3;
# cp $SIGFILE ${TESTDIR}/data/tpm2state3/signature.bin
#################################################################
# Run TPM2 with the created state and verify it's the same
$SWTPM_EXE socket \
--server port=${TPM_COMMAND_PORT} \
--tpmstate "dir=$TPMDIR" \
--pid "file=$PID_FILE" \
--ctrl "type=unixio,path=$SOCK_PATH" \
--log "file=$LOGFILE,level=20" \
--tpm2 \
${SWTPM_TEST_SECCOMP_OPT:+${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"
exit 1
fi
"${TOOLSPATH}/${PREFIX}startup" -c
if [ $? -ne 0 ]; then
echo "Error: tpm_startup clear failed."
cat "$LOGFILE"
exit 1
fi
test_nvram_state 0 1
test_primary 0 1 0
test_pcr_allocation 0 1
test_hierarchy 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
rm -f "$TPMDIR/"*
cp -f "${TESTDIR}/data/tpm2state3/tpm2-00.permall" "$TPMDIR/tpm2-00.permall"
$SWTPM_EXE socket \
--server port=${TPM_COMMAND_PORT} \
--tpmstate "dir=$TPMDIR" \
--pid "file=$PID_FILE" \
--ctrl "type=unixio,path=$SOCK_PATH" \
--log "file=$LOGFILE,level=20" \
--tpm2 \
${SWTPM_TEST_SECCOMP_OPT:+${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
test_nvram_state 0 1
test_primary 0 1 1
test_pcr_allocation 0 1
test_hierarchy 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"
#
#
# Tests with volatile state
#
#
rm -f "${TPMDIR}"/*
$SWTPM_EXE socket \
--server port=${TPM_COMMAND_PORT} \
--tpmstate "dir=$TPMDIR" \
--pid "file=$PID_FILE" \
--ctrl "type=unixio,path=$SOCK_PATH" \
--log "file=$LOGFILE,level=20" \
--tpm2 \
${SWTPM_TEST_SECCOMP_OPT:+${SWTPM_TEST_SECCOMP_OPT}} &
if wait_for_file "$PID_FILE" 3; then
echo "Error: (3) 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."
cat "$LOGFILE"
exit 1
fi
test_session 1 1
test_hash_context 1 0
act=$($SWTPM_IOCTL --unix "$SOCK_PATH" -v 2>&1)
if [ $? -ne 0 ]; then
echo "Error: $SWTPM_IOCTL CMD_STORE_VOLATILE failed: $act"
exit 1
fi
"${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
#################################################################
# Run TPM2 with the saved volatile state
# create a backup for running the next test...
# cp $TPMDIR/tpm2-00.permall ${TESTDIR}/data/tpm2state3b/tpm2-00.permall
# cp $TPMDIR/tpm2-00.volatilestate ${TESTDIR}/data/tpm2state3b/tpm2-00.volatilestate
# cp $TPMDIR/h02000000.bin ${TESTDIR}/data/tpm2state3b/h02000000.bin
# cp $TPMDIR/h81000000.bin ${TESTDIR}/data/tpm2state3b/h81000000.bin
$SWTPM_EXE socket \
--server port=${TPM_COMMAND_PORT} \
--tpmstate "dir=$TPMDIR" \
--pid "file=$PID_FILE" \
--ctrl "type=unixio,path=$SOCK_PATH" \
--log "file=$LOGFILE,level=20" \
--tpm2 \
${SWTPM_TEST_SECCOMP_OPT:+${SWTPM_TEST_SECCOMP_OPT}} &
if wait_for_file "$PID_FILE" 3; then
echo "Error: (3) 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
cat "$LOGFILE"
echo "Error: $SWTPM_IOCTL CMD_INIT failed: $act"
exit 1
fi
test_hash_context 0 1
test_session 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
#####################################################################
# Run TPM2 with previously saved (volatile) state and verify it's
# working as well
cp -f "${TESTDIR}/data/tpm2state3b/tpm2-00.permall" "$TPMDIR/tpm2-00.permall"
cp -f "${TESTDIR}/data/tpm2state3b/tpm2-00.volatilestate" "$TPMDIR/tpm2-00.volatilestate"
cp -f "${TESTDIR}/data/tpm2state3b/h02000000.bin" "$TPMDIR/h02000000.bin"
cp -f "${TESTDIR}/data/tpm2state3b/h81000000.bin" "$TPMDIR/h81000000.bin"
$SWTPM_EXE socket \
--server port=${TPM_COMMAND_PORT} \
--tpmstate "dir=$TPMDIR" \
--pid "file=$PID_FILE" \
--ctrl "type=unixio,path=$SOCK_PATH" \
--log "file=$LOGFILE,level=20" \
--tpm2 \
${SWTPM_TEST_SECCOMP_OPT:+${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"
tail -n 10 "$LOGFILE"
exit 1
fi
test_hash_context 0 1
test_session 0 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
echo "Test 2 OK"
#
#
# Tests with volatile state -- 2nd test
#
#
rm -f "${TPMDIR}"/*
$SWTPM_EXE socket \
--server port=${TPM_COMMAND_PORT} \
--tpmstate "dir=$TPMDIR" \
--pid "file=$PID_FILE" \
--ctrl "type=unixio,path=$SOCK_PATH" \
--log "file=$LOGFILE,level=20" \
--tpm2 \
${SWTPM_TEST_SECCOMP_OPT:+${SWTPM_TEST_SECCOMP_OPT}} &
if wait_for_file "$PID_FILE" 3; then
echo "Error: (3) 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."
cat "$LOGFILE"
exit 1
fi
# we only run this to generate the AES key which is different every time...
# test_hmac_context 1 0
act=$($SWTPM_IOCTL --unix "$SOCK_PATH" -v 2>&1)
if [ $? -ne 0 ]; then
echo "Error: $SWTPM_IOCTL CMD_STORE_VOLATILE failed: $act"
exit 1
fi
"${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
#################################################################
# Run TPM2 with the saved volatile state
# create a backup for running the next test...
# cp $TPMDIR/tpm2-00.permall ${TESTDIR}/data/tpm2state3c/tpm2-00.permall
# cp $TPMDIR/tpm2-00.volatilestate ${TESTDIR}/data/tpm2state3c/tpm2-00.volatilestate
#echo $TPMDIR
#ls -l $TPMDIR
$SWTPM_EXE socket \
--server port=${TPM_COMMAND_PORT} \
--tpmstate "dir=$TPMDIR" \
--pid "file=$PID_FILE" \
--ctrl "type=unixio,path=$SOCK_PATH" \
--log "file=$LOGFILE,level=20" \
--tpm2 \
${SWTPM_TEST_SECCOMP_OPT:+${SWTPM_TEST_SECCOMP_OPT}} &
if wait_for_file "$PID_FILE" 3; then
echo "Error: (3) 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
cat "$LOGFILE"
echo "Error: $SWTPM_IOCTL CMD_INIT failed: $act"
exit 1
fi
# since the AES key is different every time, we cannot run
# the HMAC function that's using it since the result would
# be different every time
# test_hmac_context 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
#####################################################################
# Run TPM2 with previously saved (volatile) state and verify it's
# working as well
cp -f "${TESTDIR}/data/tpm2state3c/tpm2-00.volatilestate" "$TPMDIR/tpm2-00.volatilestate"
cp -f "${TESTDIR}/data/tpm2state3c/tpm2-00.permall" "$TPMDIR/tpm2-00.permall"
$SWTPM_EXE socket \
--server port=${TPM_COMMAND_PORT} \
--tpmstate "dir=$TPMDIR" \
--pid "file=$PID_FILE" \
--ctrl "type=unixio,path=$SOCK_PATH" \
--log "file=$LOGFILE,level=20" \
--tpm2 \
${SWTPM_TEST_SECCOMP_OPT:+${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
test_hmac_context 0 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
echo "Test 3 OK"
#
#
# Tests with volatile state -- 3rd test
#
#
rm -f "${TPMDIR}"/*
$SWTPM_EXE socket \
--server port=${TPM_COMMAND_PORT} \
--tpmstate "dir=$TPMDIR" \
--pid "file=$PID_FILE" \
--ctrl "type=unixio,path=$SOCK_PATH" \
--log "file=$LOGFILE,level=20" \
--tpm2 \
${SWTPM_TEST_SECCOMP_OPT:+${SWTPM_TEST_SECCOMP_OPT}} &
if wait_for_file "$PID_FILE" 3; then
echo "Error: (3) 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."
cat "$LOGFILE"
exit 1
fi
test_primary_volatile_load 1 0 0
test_external_key 1 1
act=$($SWTPM_IOCTL --unix "$SOCK_PATH" -v 2>&1)
if [ $? -ne 0 ]; then
echo "Error: $SWTPM_IOCTL CMD_STORE_VOLATILE failed: $act"
exit 1
fi
"${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
#################################################################
# Run TPM2 with the saved volatile state
# create a backup for running the next test...
# cp $TPMDIR/tpm2-00.volatilestate ${TESTDIR}/data/tpm2state3d/tpm2-00.volatilestate
# cp $TPMDIR/tpm2-00.permall ${TESTDIR}/data/tpm2state3d/tpm2-00.permall
# cp $SIGFILE ${TESTDIR}/data/tpm2state3d/signature2.bin
#echo $TPMDIR
#ls -l $TPMDIR
$SWTPM_EXE socket \
--server port=${TPM_COMMAND_PORT} \
--tpmstate "dir=$TPMDIR" \
--pid "file=$PID_FILE" \
--ctrl "type=unixio,path=$SOCK_PATH" \
--log "file=$LOGFILE,level=20" \
--tpm2 \
${SWTPM_TEST_SECCOMP_OPT:+${SWTPM_TEST_SECCOMP_OPT}} &
if wait_for_file "$PID_FILE" 3; then
echo "Error: (3) 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
cat "$LOGFILE"
echo "Error: $SWTPM_IOCTL CMD_INIT failed: $act"
exit 1
fi
test_primary_volatile_load 0 1 0
test_external_key 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
#####################################################################
# Run TPM2 with previously saved (volatile) state and verify it's
# working as well
cp -f "${TESTDIR}/data/tpm2state3d/tpm2-00.permall" "$TPMDIR/tpm2-00.permall"
cp -f "${TESTDIR}/data/tpm2state3d/tpm2-00.volatilestate" "$TPMDIR/tpm2-00.volatilestate"
$SWTPM_EXE socket \
--server port=${TPM_COMMAND_PORT} \
--tpmstate "dir=$TPMDIR" \
--pid "file=$PID_FILE" \
--ctrl "type=unixio,path=$SOCK_PATH" \
--log "file=$LOGFILE,level=20" \
--tpm2 \
${SWTPM_TEST_SECCOMP_OPT:+${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
test_primary_volatile_load 0 1 1
test_external_key 0 1
# Create the orderly nv indices and have them cleared (for coverage)
test_nvram_state 1 1
"${TOOLSPATH}/${PREFIX}clear" -hi p
if [ $? -ne 0 ]; then
echo "Error: 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 4 OK"
exit 0