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