123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- #!/bin/sh -u
- # Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- #
- # Test the chromeos TPM recovery script by faking the entire execution
- # environment.
- rm -rf tpm-recovery-test-workdir
- mkdir tpm-recovery-test-workdir
- cd tpm-recovery-test-workdir
- test_kind=
- if [ $# -ge 1 ]; then
- test_kind="$1"
- fi
- if [ "$test_kind" != "" -a "$test_kind" != "fake" ]; then
- echo "$0: usage: $0 [fake]"
- echo "With fake as the argument, use a simulated TPM instead of the real one"
- fi
- if [ "$test_kind" = "fake" ]; then
- export USR_BIN=.
- export USR_SBIN=.
- export USR_LOCAL_BIN=.
- export USR_LOCAL_SBIN=.
- export DOT_RECOVERY=.recovery
- export ACPI_DIR=.
- ctr=../chromeos-tpm-recovery
- tpmc=./tpmc
- else
- ctr=chromeos-tpm-recovery
- tpmc=tpmc
- fi
- # For simplicity, build the permanent environment as if we prepared to run the
- # fake test, even if we're running the test on a real TPM.
- echo > .recovery
- echo 3 > BINF.0
- echo 0 > CHSW
- export NVRAM_SPACE_OVERHEAD=200
- space_overhead=$NVRAM_SPACE_OVERHEAD
- # build tpmc
- cat > tpmc <<"EOF"
- #!/bin/sh -u
- # Fake tpmc program
- definespace () {
- index=$2
- size=$3
- permissions=$4
- space_overhead=$NVRAM_SPACE_OVERHEAD
- if [ -e space.$index.data -a -e tpm-owned ]; then
- echo "cannot redefine space without auth"
- fi
- totalsize=$(( $size + $space_overhead ))
- free=$(cat nvram.freespace)
- if [ $totalsize -gt $free ]; then
- return 17 # NO_SPACE
- fi
- if [ $index != 0xf004 ]; then
- echo $size > space.$index.size
- echo $permissions > space.$index.perm
- for i in $(seq 1 $(($size))); do
- echo -n "ff " >> space.$index.data
- done
- echo $(( $free - $totalsize )) > nvram.freespace
- fi
- return 0
- }
- case $1 in
- clear)
- rm -f tpm-owned
- ;;
- enable)
- # boring
- ;;
- activate)
- # boring
- ;;
- definespace)
- definespace $*
- ;;
- getp)
- echo space blah has permissions $(cat space.$2.perm)
- ;;
- read)
- index=$2
- size=$3
- maxsize=$(cat space.$index.size)
- if [ $(($size > $maxsize)) -eq 1 ]; then
- echo "size $size too large for space (max is $maxsize)"
- exit 1
- fi
- dd if=space.$index.data bs=1 count=$(($3 * 3)) 2> /dev/null
- ;;
- write)
- args="$@"
- index=$2
- bytes="$(echo $args | sed 's/[^ ]* [^ ]* //')"
- size=$(echo $bytes | wc -w)
- maxsize=$(cat space.$index.size)
- if [ $(($size > $maxsize)) -eq 1 ]; then
- echo "size $size too large for space (max is $(($maxsize)))"
- exit 1
- fi
- re=$(echo "$bytes " | sed 's/././g')
- sed "s/$re/$bytes /" < space.$index.data > _tmp_
- mv _tmp_ space.$index.data
- ;;
- getpf)
- echo "disable 0"
- echo "deactivated 0"
- echo "nvLocked 1"
- echo "physicalPresenceLifetimeLock 1"
- echo "physicalPresenceHWEnable 0"
- echo "physicalPresenceCMDEnable 1"
- ;;
- getvf)
- echo "bGlobalLock 1"
- echo "physicalPresence 1"
- echo "physicalPresenceLock 0"
- ;;
- ppfin)
- # boring
- ;;
- ppon)
- # boring
- ;;
- *)
- echo "tpmc: invalid command $1"
- exit 1
- ;;
- esac
- EOF
- # build nvtool
- cat > tpm-nvtool <<"EOF"
- #!/bin/sh -u
- space_overhead=$NVRAM_SPACE_OVERHEAD
- print_space () {
- local index=$1
- printf "# NV Index 0x%08x" $(( $index ))
- echo " uninteresting random garbage"
- echo " further random garbage"
- echo ""
- }
- if [ "$1" = "--release" ]; then
- if [ "$2" != "--index" -o \
- "$4" != "--owner_password" ]; then
- echo "sorry, picky tpm-nvtool"
- exit 1
- fi
- index=$3
- if [ ! -f tpm-owned ]; then
- echo "tpm is unowned"
- exit 1
- fi
- size=$(cat space.$index.size)
- free=$(cat nvram.freespace)
- rm space.$index.*
- echo $(( $size + $space_overhead + $free )) > nvram.freespace
- elif [ "$1" = "--list" ]; then
- for s in space.*.data; do
- print_space $(echo $s | sed -e "s/[^.]*\.//" -e "s/\..*//")
- done
- fi
- EOF
- # build tpm_takeownership
- cat > tpm_takeownership <<"EOF"
- #!/bin/sh -u
- if [ -f tpm-owned ]; then
- echo "tpm is already owned"
- exit 1
- fi
- echo > tpm-owned
- EOF
- # build tcsd
- cat > tcsd <<"EOF"
- #!/bin/sh -u
- trap "{ rm tcsd_is_running; }" EXIT
- echo > tcsd_is_running
- sleep 365d
- EOF
- tcsd_pid=0
- start_tcsd () {
- if [ $tcsd_pid -ne 0 ]; then
- echo TCSD is already started
- exit 1
- fi
- tcsd -f &
- tcsd_pid=$!
- sleep 2
- }
- stop_tcsd () {
- if [ $tcsd_pid -eq 0 ]; then
- echo TCSD is already stopped
- exit 1
- fi
- kill $tcsd_pid
- sleep 0.5
- kill $tcsd_pid > /dev/null 2>&1
- sleep 0.5
- wait $tcsd_pid > /dev/null 2>&1 # we trust that tcsd will agree to die
- tcsd_pid=0
- }
- tpm_clear_and_reenable () {
- tpmc clear
- tpmc enable
- tpmc activate
- }
- takeownership () {
- if [ "$test_kind" = "fake" ]; then
- touch tpm_owned
- else
- tpm_clear_and_reenable
- start_tcsd
- tpm_takeownership -y -z
- stop_tcsd
- fi
- }
- remove_chromeos_spaces () {
- if [ "$test_kind" = "fake" ]; then
- rm -f space.*
- echo 1500 > nvram.freespace
- else
- takeownership
- start_tcsd
- tpm-nvtool --release --index 0x1007 --owner_password ""
- tpm-nvtool --release --index 0x1008 --owner_password ""
- stop_tcsd
- tpm_clear_and_reenable
- fi
- }
- chmod 755 tpmc tpm-nvtool tpm_takeownership tcsd
- echo "starting test, results in $(pwd)/log"
- echo "starting TPM recovery test" > log
- if ps ax | grep "tcs[d]"; then
- echo "a tcsd is process appears to be running, please kill it first"
- exit 1
- fi
- # normal run
- test_normal_run () {
- echo "TEST: normal run" >> log
- remove_chromeos_spaces
- $tpmc definespace 0x1007 0xa 0x8001
- $tpmc definespace 0x1008 0xd 0x1
- $tpmc write 0x1008 01 4c 57 52 47
- takeownership
- $ctr log
- }
- # Kernel space with wrong ID
- test_wrong_id () {
- echo "TEST: bad kernel space ID" >> log
- remove_chromeos_spaces
- $tpmc definespace 0x1007 0xa 0x8001
- $tpmc definespace 0x1008 0xd 0x1
- takeownership
- $ctr log
- }
- # Kernel space with wrong size
- test_wrong_size () {
- echo "TEST: bad kernel space size" >> log
- remove_chromeos_spaces
- $tpmc definespace 0x1007 0xa 0x8001
- $tpmc definespace 0x1008 0xc 0x1
- takeownership
- $ctr log
- }
- # Kernel space with wrong size AND bogus space to exhaust nvram
- test_wrong_size_hog () {
- echo "TEST: bad kernel space size and no room" >> log
- remove_chromeos_spaces
- $tpmc definespace 0x1007 0xa 0x8001
- $tpmc definespace 0x1008 0x1 0x1
- if [ "$test_kind" = "fake" ]; then
- space_hog_size=$(( $(cat nvram.freespace) - $space_overhead - 1 ))
- echo "remaining $(cat nvram.freespace) bytes" >> log
- else
- space_hog_size=$(( $(tpm-nvsize) - 2 ))
- fi
- echo "hogging $(( $space_hog_size )) bytes" >> log
- $tpmc definespace 0xcafe $(printf "0x%x" $space_hog_size) 0x1 \
- || echo "hogging failed!" >> log
- takeownership
- $ctr log
- }
- test_normal_run
- test_wrong_id
- test_wrong_size
- test_wrong_size_hog
- echo "test completed" >> log
- echo "test completed"
|