1 #!/bin/sh -u 2 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 3 # Use of this source code is governed by a BSD-style license that can be 4 # found in the LICENSE file. 5 # 6 # Test the chromeos TPM recovery script by faking the entire execution 7 # environment. 8 9 rm -rf tpm-recovery-test-workdir 10 mkdir tpm-recovery-test-workdir 11 cd tpm-recovery-test-workdir 12 13 test_kind= 14 if [ $# -ge 1 ]; then 15 test_kind="$1" 16 fi 17 18 if [ "$test_kind" != "" -a "$test_kind" != "fake" ]; then 19 echo "$0: usage: $0 [fake]" 20 echo "With fake as the argument, use a simulated TPM instead of the real one" 21 fi 22 23 if [ "$test_kind" = "fake" ]; then 24 export USR_BIN=. 25 export USR_SBIN=. 26 export USR_LOCAL_BIN=. 27 export USR_LOCAL_SBIN=. 28 export DOT_RECOVERY=.recovery 29 export ACPI_DIR=. 30 ctr=../chromeos-tpm-recovery 31 tpmc=./tpmc 32 else 33 ctr=chromeos-tpm-recovery 34 tpmc=tpmc 35 fi 36 37 # For simplicity, build the permanent environment as if we prepared to run the 38 # fake test, even if we're running the test on a real TPM. 39 40 echo > .recovery 41 echo 3 > BINF.0 42 echo 0 > CHSW 43 44 export NVRAM_SPACE_OVERHEAD=200 45 space_overhead=$NVRAM_SPACE_OVERHEAD 46 47 # build tpmc 48 cat > tpmc <<"EOF" 49 #!/bin/sh -u 50 # Fake tpmc program 51 52 definespace () { 53 index=$2 54 size=$3 55 permissions=$4 56 space_overhead=$NVRAM_SPACE_OVERHEAD 57 58 if [ -e space.$index.data -a -e tpm-owned ]; then 59 echo "cannot redefine space without auth" 60 fi 61 62 totalsize=$(( $size + $space_overhead )) 63 free=$(cat nvram.freespace) 64 65 if [ $totalsize -gt $free ]; then 66 return 17 # NO_SPACE 67 fi 68 69 if [ $index != 0xf004 ]; then 70 echo $size > space.$index.size 71 echo $permissions > space.$index.perm 72 for i in $(seq 1 $(($size))); do 73 echo -n "ff " >> space.$index.data 74 done 75 echo $(( $free - $totalsize )) > nvram.freespace 76 fi 77 return 0 78 } 79 80 case $1 in 81 82 clear) 83 rm -f tpm-owned 84 ;; 85 86 enable) 87 # boring 88 ;; 89 90 activate) 91 # boring 92 ;; 93 94 definespace) 95 definespace $* 96 ;; 97 98 getp) 99 echo space blah has permissions $(cat space.$2.perm) 100 ;; 101 102 read) 103 index=$2 104 size=$3 105 maxsize=$(cat space.$index.size) 106 if [ $(($size > $maxsize)) -eq 1 ]; then 107 echo "size $size too large for space (max is $maxsize)" 108 exit 1 109 fi 110 dd if=space.$index.data bs=1 count=$(($3 * 3)) 2> /dev/null 111 ;; 112 113 write) 114 args="$@" 115 index=$2 116 bytes="$(echo $args | sed 's/[^ ]* [^ ]* //')" 117 size=$(echo $bytes | wc -w) 118 maxsize=$(cat space.$index.size) 119 if [ $(($size > $maxsize)) -eq 1 ]; then 120 echo "size $size too large for space (max is $(($maxsize)))" 121 exit 1 122 fi 123 re=$(echo "$bytes " | sed 's/././g') 124 sed "s/$re/$bytes /" < space.$index.data > _tmp_ 125 mv _tmp_ space.$index.data 126 ;; 127 128 getpf) 129 echo "disable 0" 130 echo "deactivated 0" 131 echo "nvLocked 1" 132 echo "physicalPresenceLifetimeLock 1" 133 echo "physicalPresenceHWEnable 0" 134 echo "physicalPresenceCMDEnable 1" 135 ;; 136 137 getvf) 138 echo "bGlobalLock 1" 139 echo "physicalPresence 1" 140 echo "physicalPresenceLock 0" 141 ;; 142 143 ppfin) 144 # boring 145 ;; 146 147 ppon) 148 # boring 149 ;; 150 151 *) 152 echo "tpmc: invalid command $1" 153 exit 1 154 ;; 155 esac 156 157 EOF 158 159 # build nvtool 160 cat > tpm-nvtool <<"EOF" 161 #!/bin/sh -u 162 163 space_overhead=$NVRAM_SPACE_OVERHEAD 164 165 print_space () { 166 local index=$1 167 printf "# NV Index 0x%08x" $(( $index )) 168 echo " uninteresting random garbage" 169 echo " further random garbage" 170 echo "" 171 } 172 173 if [ "$1" = "--release" ]; then 174 if [ "$2" != "--index" -o \ 175 "$4" != "--owner_password" ]; then 176 echo "sorry, picky tpm-nvtool" 177 exit 1 178 fi 179 index=$3 180 if [ ! -f tpm-owned ]; then 181 echo "tpm is unowned" 182 exit 1 183 fi 184 size=$(cat space.$index.size) 185 free=$(cat nvram.freespace) 186 rm space.$index.* 187 echo $(( $size + $space_overhead + $free )) > nvram.freespace 188 elif [ "$1" = "--list" ]; then 189 for s in space.*.data; do 190 print_space $(echo $s | sed -e "s/[^.]*\.//" -e "s/\..*//") 191 done 192 fi 193 EOF 194 195 # build tpm_takeownership 196 cat > tpm_takeownership <<"EOF" 197 #!/bin/sh -u 198 if [ -f tpm-owned ]; then 199 echo "tpm is already owned" 200 exit 1 201 fi 202 echo > tpm-owned 203 EOF 204 205 # build tcsd 206 cat > tcsd <<"EOF" 207 #!/bin/sh -u 208 trap "{ rm tcsd_is_running; }" EXIT 209 echo > tcsd_is_running 210 sleep 365d 211 EOF 212 213 tcsd_pid=0 214 215 start_tcsd () { 216 if [ $tcsd_pid -ne 0 ]; then 217 echo TCSD is already started 218 exit 1 219 fi 220 tcsd -f & 221 tcsd_pid=$! 222 sleep 2 223 } 224 225 stop_tcsd () { 226 if [ $tcsd_pid -eq 0 ]; then 227 echo TCSD is already stopped 228 exit 1 229 fi 230 kill $tcsd_pid 231 sleep 0.5 232 kill $tcsd_pid > /dev/null 2>&1 233 sleep 0.5 234 wait $tcsd_pid > /dev/null 2>&1 # we trust that tcsd will agree to die 235 tcsd_pid=0 236 } 237 238 tpm_clear_and_reenable () { 239 tpmc clear 240 tpmc enable 241 tpmc activate 242 } 243 244 takeownership () { 245 if [ "$test_kind" = "fake" ]; then 246 touch tpm_owned 247 else 248 tpm_clear_and_reenable 249 start_tcsd 250 tpm_takeownership -y -z 251 stop_tcsd 252 fi 253 } 254 255 remove_chromeos_spaces () { 256 if [ "$test_kind" = "fake" ]; then 257 rm -f space.* 258 echo 1500 > nvram.freespace 259 else 260 takeownership 261 start_tcsd 262 tpm-nvtool --release --index 0x1007 --owner_password "" 263 tpm-nvtool --release --index 0x1008 --owner_password "" 264 stop_tcsd 265 tpm_clear_and_reenable 266 fi 267 } 268 269 chmod 755 tpmc tpm-nvtool tpm_takeownership tcsd 270 271 echo "starting test, results in $(pwd)/log" 272 echo "starting TPM recovery test" > log 273 274 if ps ax | grep "tcs[d]"; then 275 echo "a tcsd is process appears to be running, please kill it first" 276 exit 1 277 fi 278 279 # normal run 280 test_normal_run () { 281 echo "TEST: normal run" >> log 282 283 remove_chromeos_spaces 284 $tpmc definespace 0x1007 0xa 0x8001 285 $tpmc definespace 0x1008 0xd 0x1 286 $tpmc write 0x1008 01 4c 57 52 47 287 takeownership 288 289 $ctr log 290 } 291 292 # Kernel space with wrong ID 293 test_wrong_id () { 294 echo "TEST: bad kernel space ID" >> log 295 296 remove_chromeos_spaces 297 $tpmc definespace 0x1007 0xa 0x8001 298 $tpmc definespace 0x1008 0xd 0x1 299 takeownership 300 301 $ctr log 302 } 303 304 # Kernel space with wrong size 305 test_wrong_size () { 306 echo "TEST: bad kernel space size" >> log 307 308 remove_chromeos_spaces 309 $tpmc definespace 0x1007 0xa 0x8001 310 $tpmc definespace 0x1008 0xc 0x1 311 takeownership 312 313 $ctr log 314 } 315 316 # Kernel space with wrong size AND bogus space to exhaust nvram 317 test_wrong_size_hog () { 318 echo "TEST: bad kernel space size and no room" >> log 319 320 remove_chromeos_spaces 321 $tpmc definespace 0x1007 0xa 0x8001 322 $tpmc definespace 0x1008 0x1 0x1 323 if [ "$test_kind" = "fake" ]; then 324 space_hog_size=$(( $(cat nvram.freespace) - $space_overhead - 1 )) 325 echo "remaining $(cat nvram.freespace) bytes" >> log 326 else 327 space_hog_size=$(( $(tpm-nvsize) - 2 )) 328 fi 329 echo "hogging $(( $space_hog_size )) bytes" >> log 330 $tpmc definespace 0xcafe $(printf "0x%x" $space_hog_size) 0x1 \ 331 || echo "hogging failed!" >> log 332 takeownership 333 334 $ctr log 335 } 336 337 test_normal_run 338 test_wrong_id 339 test_wrong_size 340 test_wrong_size_hog 341 342 echo "test completed" >> log 343 echo "test completed" 344