chromeos-tpm-recovery-test 6.7 KB

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