#!/bin/sh

unsupported_machine() {
    echo "$1" 1>&2
    cleanup
    exit 77
}

failing_test() {
    echo "$1" 1>&2
    cleanup
    exit 1
}

cleanup() {
    status "Cleaning up"
    if [ -n "$swtmp_pid" ]; then
	kill $swtpm_pid 2>/dev/null
    fi
    rmmod tpm_vtpm_proxy 2>/dev/null
}

status() {
    echo "$1"
}

if [ ! -e "$AUTOPKGTEST_TMP" ]; then
    unsupported_machine "AUTOPKGTEST_TMP is not set or does not point to a directory"
fi
swtpm_pid=""

cleanup

if ! modprobe tpm_vtpm_proxy; then
    unsupported_machine "cannot modprobe tpm_vtpm_proxy"
fi

if [ -e /dev/tpm0 ]; then
    unsupported_machine "/dev/tpm0 seems to already exist"
fi

systemctl stop tcsd

status "Starting swtmp TPM simulator"
mkdir $AUTOPKGTEST_TMP/tpm_state
swtpm chardev --vtpm-proxy --tpmstate dir=$AUTOPKGTEST_TMP/tpm_state &
swtpm_pid=$!

while [ ! -e /dev/tpm0 ]; do
    sleep 1
done

systemctl start tcsd
sleep 2

status "Testing tpm_version"
if ! tpm_version 2> /dev/null; then
    failing_test "tpm_version failed"
fi


status "Testing tpm_createek"
if ! tpm_createek; then
    failing_test "Creating endorsement key failed"
fi

status "Testing tpm_takeownerzip"
if ! expect -c "spawn tpm_takeownership -z; expect \"Enter owner password:\";  send \"1234\n\"; expect \"Confirm password:\"; send \"1234\n\"; expect eof"; then
    failing_test "Unable to take ownership"
fi

status "Testing tpm_nvdefine"
if ! tpm_nvdefine -i 2 -s 8 -p OWNERWRITE --pwdo=1234 -z; then
    failing_test "tpm_nvdefine failed"
fi

status "Locking TPM nvram"
if ! tpm_nvdefine -i 0xffffffff -s 0; then
    failing_test "tmp_nvdefine failed"
fi

status "Testing a more complex tpm_nvdefine case"
sys_pcrs="$(find /sys -name pcrs|head -n1)"
if [ ! -e "$sys_pcrs" ]; then
    unsupported_machine "For some reason we cannot find pcrs file"
fi
for pcr in 17 18 19; do
    value="$(grep PCR-$pcr $sys_pcrs | cut -d':' -f2- | tr -d ' ')"
    echo "r $pcr $value" >> $AUTOPKGTEST_TMP/pcr_info
done
if ! tpm_nvdefine -i 1 -s 8 -p "OWNERWRITE|READ_STCLEAR" --pwdo=1234 -z -f $AUTOPKGTEST_TMP/pcr_info; then
    failing_test "tpm_nvdefine failed"
fi

status "Testing tpm_nvwrite"
dd if=/dev/random of=$AUTOPKGTEST_TMP/data bs=8 count=1 2>/dev/null
if ! tpm_nvwrite -i 1 -f $AUTOPKGTEST_TMP/data -z --password=1234; then
    failing_test "tpm_nvwrite failed"
fi

status "Testing tpm_nvread"
if ! tpm_nvread -i 1 -f $AUTOPKGTEST_TMP/data2; then
    failing_test "tpm_nvread failed"
fi

if ! cmp -l $AUTOPKGTEST_TMP/data $AUTOPKGTEST_TMP/data2; then
    hexdump -C $AUTOPKGTEST_TMP/data
    hexdump -C $AUTOPKGTEST_TMP/data2
    failing_test "data was modified"
fi

status "Testing tpm_nvread with zero size"
if ! tpm_nvread -i 1 -s 0; then
    failing_test "tpm_nvread with zero size failed"
fi

status "Verifying that tpm_nvread can no longer access the data"
if tpm_nvread -i 1 -f $AUTOPKGTEST_TMP/data2 2>/dev/null; then
    failing_test "tmp_nvread worked even after ST_CLEAR"
fi

status "Testing tpm_nvrelease"
if ! tpm_nvrelease -i 1 --pwdo=1234; then
    failing_test "tpm_nvrelease failed"
fi

cleanup
exit 0
