mirror of
https://github.com/stefanberger/swtpm.git
synced 2026-08-10 00:23:28 +00:00
Extend an existing test case with the backup option for the directory backend. Check correct behavior by trying to start swtpm with missing state decryption key and ensure that file renamings are handled as expected. Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
442 lines
12 KiB
Bash
Executable File
442 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-tpm2-encrypted-state}
|
|
SWTPM_DEV_NAME="/dev/${VTPM_NAME}"
|
|
TPM_PATH="$(mktemp -d)" || exit 1
|
|
STATE_FILE=$TPM_PATH/tpm2-00.permall
|
|
STATE_FILE_BAK=$TPM_PATH/tpm2-00.permall.bak
|
|
VOLATILE_STATE_FILE=$TPM_PATH/tpm2-00.volatilestate
|
|
KEY=1234567890abcdef1234567890abcdef
|
|
BINKEY='\x12\x34\x56\x78\x90\xab\xcd\xef\x12\x34\x56\x78\x90\xab\xcd\xef'
|
|
SWTPM_INTERFACE=${SWTPM_INTERFACE:-cuse}
|
|
SWTPM_CMD_UNIX_PATH=${TPM_PATH}/unix-cmd.sock
|
|
SWTPM_CTRL_UNIX_PATH=${TPM_PATH}/unix-ctrl.sock
|
|
|
|
keyfile=${TPM_PATH}/keyfile
|
|
logfile=${TPM_PATH}/logfile
|
|
binkeyfile=${TPM_PATH}/binkeyfile
|
|
echo "$KEY" > "${keyfile}"
|
|
echo -en "$BINKEY" > "${binkeyfile}"
|
|
|
|
function cleanup()
|
|
{
|
|
pid=${SWTPM_PID}
|
|
if [ -n "$pid" ]; then
|
|
kill_quiet -9 "$pid"
|
|
fi
|
|
rm -rf "$TPM_PATH"
|
|
}
|
|
|
|
trap "cleanup" EXIT
|
|
|
|
source "${TESTDIR}/common"
|
|
[ "${SWTPM_INTERFACE}" == "cuse" ] && source "${TESTDIR}/test_cuse"
|
|
|
|
rm -f "$STATE_FILE" "$VOLATILE_STATE_FILE" 2>/dev/null
|
|
|
|
TPM_PATH=$TPM_PATH run_swtpm "${SWTPM_INTERFACE}" \
|
|
--key "file=$keyfile,mode=aes-cbc,format=hex,remove" \
|
|
--log "file=$logfile" \
|
|
--tpm2
|
|
|
|
display_processes_by_name "swtpm"
|
|
|
|
if ! kill_quiet -0 "${SWTPM_PID}"; then
|
|
echo "Error: ${SWTPM_INTERFACE} TPM did not start."
|
|
echo "TPM Logfile:"
|
|
cat "$logfile"
|
|
exit 1
|
|
fi
|
|
|
|
if wait_file_gone "${keyfile}" 4; then
|
|
echo "Error: Keyfile $keyfile was not removed by ${SWTPM_INTERFACE} tpm."
|
|
echo "TPM Logfile:"
|
|
cat "$logfile"
|
|
exit 1
|
|
fi
|
|
|
|
# Init the TPM
|
|
if ! run_swtpm_ioctl "${SWTPM_INTERFACE}" -i; then
|
|
echo "Error: ${SWTPM_INTERFACE} TPM initialization failed."
|
|
echo "TPM Logfile:"
|
|
cat "$logfile"
|
|
exit 1
|
|
fi
|
|
|
|
if ! kill_quiet -0 "${SWTPM_PID}" 2>/dev/null; then
|
|
echo "Error: ${SWTPM_INTERFACE} TPM not running anymore after INIT."
|
|
echo "TPM Logfile:"
|
|
cat "$logfile"
|
|
exit 1
|
|
fi
|
|
|
|
# Startup the TPM
|
|
RES=$(swtpm_cmd_tx "${SWTPM_INTERFACE}" '\x80\x01\x00\x00\x00\x0c\x00\x00\x01\x44\x00\x00')
|
|
exp=' 80 01 00 00 00 0a 00 00 00 00'
|
|
if [ "$RES" != "$exp" ]; then
|
|
echo "Error: Did not get expected result from TPM2_Startup(SU_Clear)"
|
|
echo "expected: $exp"
|
|
echo "received: $RES"
|
|
exit 1
|
|
fi
|
|
|
|
if ! run_swtpm_ioctl "${SWTPM_INTERFACE}" -h 1234; then
|
|
echo "Error: Hash command did not work."
|
|
echo "TPM Logfile:"
|
|
cat "$logfile"
|
|
exit 1
|
|
fi
|
|
|
|
# Read PCR 17
|
|
RES=$(swtpm_cmd_tx "${SWTPM_INTERFACE}" '\x80\x01\x00\x00\x00\x14\x00\x00\x01\x7e\x00\x00\x00\x01\x00\x0b\x03\x00\x00\x02')
|
|
exp=' 80 01 00 00 00 3e 00 00 00 00 00 00 00 18 00 00 00 01 00 0b 03 00 00 02 00 00 00 01 00 20 fc a5 d6 49 bf b0 c9 22 fd 33 0f 79 b2 00 43 28 9d af d6 0d 01 a4 c4 37 3c f2 8a db 56 c9 b4 54'
|
|
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
|
|
|
|
# Save the volatile state
|
|
if ! run_swtpm_ioctl "${SWTPM_INTERFACE}" -v; then
|
|
echo "Error: Saving the volatile state failed."
|
|
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
|
|
|
|
if ! tmp=$(run_swtpm_ioctl "${SWTPM_INTERFACE}" -g | cut -d":" -f2); then
|
|
echo "Error: Could not get the configuration flags of the ${SWTPM_INTERFACE} TPM."
|
|
echo "TPM Logfile:"
|
|
cat "$logfile"
|
|
exit 1
|
|
fi
|
|
|
|
if [ "$tmp" != " 0x1" ]; then
|
|
echo "Error: Unexpected configuration flags: $tmp; expected 0x1."
|
|
echo "TPM Logfile:"
|
|
cat "$logfile"
|
|
exit 1
|
|
fi
|
|
|
|
# Shut the TPM down
|
|
if ! run_swtpm_ioctl "${SWTPM_INTERFACE}" -s; then
|
|
echo "Error: Could not shut down the ${SWTPM_INTERFACE} TPM."
|
|
echo "TPM Logfile:"
|
|
cat "$logfile"
|
|
exit 1
|
|
fi
|
|
|
|
# Start the TPM again; have the keyfile removed; create state backup file
|
|
run_swtpm "${SWTPM_INTERFACE}" \
|
|
--tpmstate "dir=${TPM_PATH},backup" \
|
|
--key "file=$binkeyfile,mode=aes-cbc,format=binary,remove" \
|
|
--log "file=$logfile" \
|
|
--tpm2
|
|
|
|
display_processes_by_name "swtpm"
|
|
|
|
if ! kill_quiet -0 "${SWTPM_PID}"; then
|
|
echo "Error (2): ${SWTPM_INTERFACE} TPM did not start."
|
|
echo "TPM Logfile:"
|
|
cat "$logfile"
|
|
exit 1
|
|
fi
|
|
|
|
if wait_file_gone "${binkeyfile}" 4; then
|
|
echo "Error: Keyfile $binkeyfile was not removed by ${SWTPM_INTERFACE} TPM."
|
|
echo "TPM Logfile:"
|
|
cat "$logfile"
|
|
exit 1
|
|
fi
|
|
|
|
# Init the TPM
|
|
if ! run_swtpm_ioctl "${SWTPM_INTERFACE}" -i; 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 ...
|
|
RES=$(swtpm_cmd_tx "${SWTPM_INTERFACE}" '\x80\x01\x00\x00\x00\x14\x00\x00\x01\x7e\x00\x00\x00\x01\x00\x0b\x03\x00\x00\x02')
|
|
exp=' 80 01 00 00 00 3e 00 00 00 00 00 00 00 18 00 00 00 01 00 0b 03 00 00 02 00 00 00 01 00 20 fc a5 d6 49 bf b0 c9 22 fd 33 0f 79 b2 00 43 28 9d af d6 0d 01 a4 c4 37 3c f2 8a db 56 c9 b4 54'
|
|
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
|
|
if ! run_swtpm_ioctl "${SWTPM_INTERFACE}" -v; then
|
|
echo "Error: Saving the volatile state failed."
|
|
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
|
|
if ! run_swtpm_ioctl "${SWTPM_INTERFACE}" -i; 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 ...
|
|
RES=$(swtpm_cmd_tx "${SWTPM_INTERFACE}" '\x80\x01\x00\x00\x00\x14\x00\x00\x01\x7e\x00\x00\x00\x01\x00\x0b\x03\x00\x00\x02')
|
|
exp=' 80 01 00 00 00 3e 00 00 00 00 00 00 00 18 00 00 00 01 00 0b 03 00 00 02 00 00 00 01 00 20 fc a5 d6 49 bf b0 c9 22 fd 33 0f 79 b2 00 43 28 9d af d6 0d 01 a4 c4 37 3c f2 8a db 56 c9 b4 54'
|
|
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
|
|
|
|
|
|
# Final shut down
|
|
if ! run_swtpm_ioctl "${SWTPM_INTERFACE}" -s; 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
|
|
|
|
if [ "${SWTPM_INTERFACE}" = "socket+socket" ]; then
|
|
# Record hashes of permanent state file
|
|
if ! permall_hash=$(get_sha1_file "${STATE_FILE}") || \
|
|
! permall_bak_hash=$(get_sha1_file "${STATE_FILE_BAK}"); then
|
|
echo "Error: Could not get hashes of state files"
|
|
ls -l "${TPM_PATH}"
|
|
exit 1
|
|
fi
|
|
|
|
# Start the TPM with backup option; it will not start
|
|
# and must not modify files
|
|
${SWTPM_EXE} socket \
|
|
--tpmstate "dir=${TPM_PATH},backup" \
|
|
--log "file=$logfile" \
|
|
--flags not-need-init \
|
|
--tpm2 \
|
|
${SWTPM_TEST_SECCOMP_OPT:+${SWTPM_TEST_SECCOMP_OPT}} \
|
|
--server "type=tcp,port=${SWTPM_SERVER_PORT}" \
|
|
--ctrl "type=tcp,port=${SWTPM_CTRL_PORT}" &
|
|
rc=$?
|
|
if [ "$rc" -ne 0 ]; then
|
|
echo "Error: Could not run ${SWTPM_EXE}"
|
|
exit 1
|
|
fi
|
|
SWTPM_PID=$!
|
|
if wait_process_gone "${SWTPM_PID}" 4; then
|
|
echo "Error: ${SWTPM_INTERFACE} TPM should not have started without key."
|
|
exit 1
|
|
fi
|
|
|
|
if [ "$(get_sha1_file "${STATE_FILE}")" != "${permall_hash}" ]; then
|
|
echo "Error: The ${STATE_FILE} file hash changed."
|
|
exit 1
|
|
fi
|
|
if [ "$(get_sha1_file "${STATE_FILE_BAK}")" != "${permall_bak_hash}" ]; then
|
|
echo "Error: The ${STATE_FILE_BAK} file hash changed."
|
|
exit 1
|
|
fi
|
|
|
|
rm -f "${STATE_FILE_BAK}"
|
|
|
|
# swtpm should not run; no changes to state files
|
|
${SWTPM_EXE} socket \
|
|
--tpmstate "dir=${TPM_PATH},backup" \
|
|
--log "file=$logfile" \
|
|
--flags not-need-init \
|
|
--tpm2 \
|
|
${SWTPM_TEST_SECCOMP_OPT:+${SWTPM_TEST_SECCOMP_OPT}} \
|
|
--server "type=tcp,port=${SWTPM_SERVER_PORT}" \
|
|
--ctrl "type=tcp,port=${SWTPM_CTRL_PORT}" &
|
|
rc=$?
|
|
if [ "$rc" -ne 0 ]; then
|
|
echo "Error: Could not run ${SWTPM_EXE}"
|
|
exit 1
|
|
fi
|
|
SWTPM_PID=$!
|
|
if wait_process_gone "${SWTPM_PID}" 4; then
|
|
echo "Error: ${SWTPM_INTERFACE} TPM should not have started without key and without backup file."
|
|
cat "$logfile"
|
|
exit 1
|
|
fi
|
|
if [ "$(get_sha1_file "${STATE_FILE}")" != "${permall_hash}" ]; then
|
|
echo "Error: The ${STATE_FILE} file hash changed."
|
|
exit 1
|
|
fi
|
|
if [ -f "${STATE_FILE_BAK}" ]; then
|
|
echo "Error: The state backup file ${STATE_FILE_BAK} should not exist."
|
|
ls -l "${TPM_PATH}"
|
|
exit 1
|
|
fi
|
|
|
|
mv "${STATE_FILE}" "${STATE_FILE_BAK}"
|
|
|
|
${SWTPM_EXE} socket \
|
|
--tpmstate "dir=${TPM_PATH},backup" \
|
|
--log "file=$logfile" \
|
|
--flags not-need-init \
|
|
--tpm2 \
|
|
${SWTPM_TEST_SECCOMP_OPT:+${SWTPM_TEST_SECCOMP_OPT}} \
|
|
--server "type=tcp,port=${SWTPM_SERVER_PORT}" \
|
|
--ctrl "type=tcp,port=${SWTPM_CTRL_PORT}" &
|
|
rc=$?
|
|
if [ "$rc" -ne 0 ]; then
|
|
echo "Error: Could not run ${SWTPM_EXE}"
|
|
exit 1
|
|
fi
|
|
SWTPM_PID=$!
|
|
if wait_process_gone "${SWTPM_PID}" 4; then
|
|
echo "Error: ${SWTPM_INTERFACE} TPM should not have started without key and without backup file."
|
|
cat "$logfile"
|
|
exit 1
|
|
fi
|
|
|
|
if [ "$(get_sha1_file "${STATE_FILE}")" != "${permall_hash}" ]; then
|
|
echo "Error: The ${STATE_FILE} file hash changed."
|
|
exit 1
|
|
fi
|
|
if [ -f "${STATE_FILE_BAK}" ]; then
|
|
echo "Error: The state backup file ${STATE_FILE_BAK} should not exist."
|
|
exit 1
|
|
fi
|
|
|
|
mv "${STATE_FILE}" "${STATE_FILE_BAK}"
|
|
touch "${STATE_FILE}"
|
|
if ! emptyfile_hash=$(get_sha1_file "${STATE_FILE}"); then
|
|
echo "Error: Could not get hash of empty state files"
|
|
exit 1
|
|
fi
|
|
|
|
${SWTPM_EXE} socket \
|
|
--tpmstate "dir=${TPM_PATH},backup" \
|
|
--log "file=$logfile" \
|
|
--flags not-need-init \
|
|
--tpm2 \
|
|
${SWTPM_TEST_SECCOMP_OPT:+${SWTPM_TEST_SECCOMP_OPT}} \
|
|
--server "type=tcp,port=${SWTPM_SERVER_PORT}" \
|
|
--ctrl "type=tcp,port=${SWTPM_CTRL_PORT}" &
|
|
rc=$?
|
|
if [ "$rc" -ne 0 ]; then
|
|
echo "Error: Could not run ${SWTPM_EXE}"
|
|
exit 1
|
|
fi
|
|
SWTPM_PID=$!
|
|
if wait_process_gone "${SWTPM_PID}" 4; then
|
|
echo "Error: ${SWTPM_INTERFACE} TPM should not have started without key and without backup file."
|
|
cat "$logfile"
|
|
exit 1
|
|
fi
|
|
|
|
# .bak file was previously 'normal' state file
|
|
if [ "$(get_sha1_file "${STATE_FILE_BAK}")" != "${permall_hash}" ]; then
|
|
echo "Error: The ${STATE_FILE_BAK} file hash changed."
|
|
exit 1
|
|
fi
|
|
if [ "$(get_sha1_file "${STATE_FILE}")" != "${emptyfile_hash}" ]; then
|
|
echo "Error: The (empty) ${STATE_FILE} file hash changed."
|
|
exit 1
|
|
fi
|
|
|
|
# Have it start successfully with a corrupted permanent state file and
|
|
# and available backup file
|
|
echo -en "$BINKEY" > "${binkeyfile}"
|
|
rm -f "$logfile"
|
|
|
|
run_swtpm "${SWTPM_INTERFACE}" \
|
|
--tpmstate "dir=${TPM_PATH},backup" \
|
|
--key "file=$binkeyfile,mode=aes-cbc,format=binary,remove" \
|
|
--log "file=$logfile" \
|
|
--tpm2
|
|
|
|
if wait_file_gone "${binkeyfile}" 4; then
|
|
echo "Error: Keyfile $binkeyfile was not removed by ${SWTPM_INTERFACE} TPM."
|
|
echo "TPM Logfile:"
|
|
cat "$logfile"
|
|
exit 1
|
|
fi
|
|
|
|
# Send TPM_Init
|
|
if ! run_swtpm_ioctl "${SWTPM_INTERFACE}" -i; then
|
|
echo "Error: ${SWTPM_INTERFACE} TPM initialization failed when started with backup file."
|
|
echo "TPM Logfile:"
|
|
cat "$logfile"
|
|
exit 1
|
|
fi
|
|
|
|
# Final shut down
|
|
if ! run_swtpm_ioctl "${SWTPM_INTERFACE}" -s; then
|
|
echo "Error: Could not shut down the ${SWTPM_INTERFACE} TPM when started with backup file."
|
|
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 "INFO: socket+socket interface passed backup option test"
|
|
fi
|
|
|
|
echo "OK"
|
|
|
|
exit 0
|