1# Copyright 2014 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import hashlib, logging, os 6 7from autotest_lib.client.common_lib import error 8from autotest_lib.server.cros.faft.firmware_test import FirmwareTest 9 10 11class firmware_TPMExtend(FirmwareTest): 12 """Test to ensure TPM PCRs are extended correctly.""" 13 version = 1 14 15 def initialize(self, host, cmdline_args): 16 super(firmware_TPMExtend, self).initialize(host, cmdline_args) 17 self.switcher.setup_mode('normal') 18 self.setup_usbkey(usbkey=True, host=False) 19 20 def _check_pcr(self, num, hash_obj): 21 """Returns true iff PCR |num| was extended with hashlib |hash_obj|.""" 22 pcrs_file='/sys/class/misc/tpm0/device/pcrs' 23 if not os.path.exists(pcrs_file): 24 pcrs_file='/sys/class/tpm/tpm0/device/pcrs' 25 pcrs = '\n'.join(self.faft_client.system.run_shell_command_get_output( 26 'cat %s' % pcrs_file)) 27 logging.debug('Dumping PCRs read from device: \n%s', pcrs) 28 extended = hashlib.sha1('\0' * 20 + hash_obj.digest()[:20]).hexdigest() 29 spaced = ' '.join(extended[i:i+2] for i in xrange(0, len(extended), 2)) 30 logging.debug('PCR %d should contain hash: %s', num, spaced) 31 return ('PCR-%.2d: %s' % (num, spaced.upper())) in pcrs 32 33 def run_once(self): 34 logging.info('Verifying HWID digest in PCR1') 35 hwid = self.faft_client.system.run_shell_command_get_output( 36 'crossystem hwid')[0] 37 logging.debug('HWID reported by device is: %s', hwid) 38 if not self._check_pcr(1, hashlib.sha256(hwid)): 39 error.TestFail('PCR1 was not extended with SHA256 digest of HWID!') 40 41 logging.info('Verifying bootmode digest in PCR0 in normal mode') 42 self.check_state((self.checkers.crossystem_checker, { 43 'devsw_boot': '0', 44 'mainfw_type': 'normal' 45 })) 46 # dev_mode: 0, rec_mode: 0, keyblock_flags: "normal" (1) 47 if not self._check_pcr(0, hashlib.sha1(chr(0) + chr(0) + chr(1))): 48 error.TestFail('PCR0 was not extended with bootmode 0|0|1!') 49 50 logging.info('Verifying bootmode digest in PCR0 in recovery mode') 51 self.switcher.reboot_to_mode(to_mode='rec') 52 self.check_state((self.checkers.crossystem_checker, { 53 'devsw_boot': '0', 54 'mainfw_type': 'recovery' 55 })) 56 # dev_mode: 0, rec_mode: 1, keyblock_flags: "unknown" (0) 57 if not self._check_pcr(0, hashlib.sha1(chr(0) + chr(1) + chr(0))): 58 error.TestFail('PCR0 was not extended with bootmode 0|1|0!') 59 60 logging.info('Transitioning to dev mode for next test') 61 self.switcher.reboot_to_mode(to_mode='dev') 62 63 logging.info('Verifying bootmode digest in PCR0 in developer mode') 64 self.check_state((self.checkers.crossystem_checker, { 65 'devsw_boot': '1', 66 'mainfw_type': 'developer' 67 })) 68 # dev_mode: 1, rec_mode: 0, keyblock_flags: "normal" (1) 69 if not self._check_pcr(0, hashlib.sha1(chr(1) + chr(0) + chr(1))): 70 error.TestFail('PCR0 was not extended with bootmode 1|0|1!') 71 72 logging.info('Verifying bootmode digest in PCR0 in dev-recovery mode') 73 self.switcher.reboot_to_mode(to_mode='rec') 74 self.check_state((self.checkers.crossystem_checker, { 75 'devsw_boot': '1', 76 'mainfw_type': 'recovery' 77 })) 78 # dev_mode: 1, rec_mode: 1, keyblock_flags: "unknown" (0) 79 if not self._check_pcr(0, hashlib.sha1(chr(1) + chr(1) + chr(0))): 80 error.TestFail('PCR0 was not extended with bootmode 1|1|0!') 81 82 logging.info('All done, returning to normal mode') 83 self.switcher.reboot_to_mode(to_mode='normal') 84