• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2012 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 logging, os
6from autotest_lib.server import utils
7from autotest_lib.server.cros.faft.firmware_test import FirmwareTest
8from autotest_lib.client.common_lib import error
9
10
11class firmware_UpdateFirmwareDataKeyVersion(FirmwareTest):
12    """
13    This test requires a USB test image plugged in. The firmware id
14    should matches fwid of shellball chromeos-firmwareupdate, or user can
15    provide a shellball to do this test. In this way, the client will be update
16    with the given shellball first. On runtime, this test modifies shellball
17    and runs autoupdate. Check firmware datakey version after boot with
18    firmware B, and then recover firmware A and B to original shellball.
19    """
20    version = 1
21
22    def resign_datakey_version(self, host):
23        """Resigns the datakey version."""
24        host.send_file(os.path.join(self.bindir,
25                                    'files/common.sh'),
26                       os.path.join(self.faft_client.updater.get_temp_path(),
27                                     'common.sh'))
28        host.send_file(os.path.join(self.bindir,
29                                    'files/make_keys.sh'),
30                       os.path.join(self.faft_client.updater.get_temp_path(),
31                                    'make_keys.sh'))
32
33        self.faft_client.system.run_shell_command('/bin/bash %s %s' % (
34             os.path.join(self.faft_client.updater.get_temp_path(),
35                          'make_keys.sh'),
36             self._update_version))
37
38
39    def check_firmware_datakey_version(self, expected_ver):
40        """Checks the firmware datakey version."""
41        actual_ver = self.faft_client.bios.get_datakey_version(
42                'b' if self.fw_vboot2 else 'a')
43        actual_tpm_fwver = self.faft_client.tpm.get_firmware_datakey_version()
44        if actual_ver != expected_ver or actual_tpm_fwver != expected_ver:
45            raise error.TestFail(
46                'Firmware data key version should be %s,'
47                'but got (fwver, tpm_fwver) = (%s, %s).'
48                % (expected_ver, actual_ver, actual_tpm_fwver))
49        else:
50            logging.info(
51                'Update success, now datakey version is %s', actual_ver)
52
53
54    def initialize(self, host, cmdline_args):
55        """Setup the test"""
56        dict_args = utils.args_to_dict(cmdline_args)
57        shellball_path = dict_args.get('shellball', None)
58        super(firmware_UpdateFirmwareDataKeyVersion, self).initialize(
59            host, cmdline_args)
60        self.backup_firmware()
61        self.switcher.setup_mode('normal')
62        self.setup_firmwareupdate_shellball(shellball_path)
63
64        # Update firmware if needed
65        if shellball_path:
66            self.set_hardware_write_protect(enable=False)
67            self.faft_client.updater.run_factory_install()
68            self.switcher.mode_aware_reboot()
69
70        self.setup_usbkey(usbkey=True)
71        self._fwid = self.faft_client.updater.get_section_fwid()
72
73        self.fw_ver_tpm = self.faft_client.tpm.get_firmware_datakey_version()
74        actual_ver = self.faft_client.bios.get_datakey_version('a')
75        logging.info('Origin version is %s', actual_ver)
76        self._update_version = actual_ver + 1
77        logging.info('Firmware version will update to version %s',
78            self._update_version)
79
80        self.resign_datakey_version(host)
81        self.faft_client.updater.resign_firmware(1)
82        self.faft_client.updater.repack_shellball('test')
83
84
85    def cleanup(self):
86        """Cleanup after the test"""
87        try:
88            if (self.faft_client.tpm.get_firmware_datakey_version() !=
89                                                       self.fw_ver_tpm):
90                self.reboot_and_reset_tpm()
91            self.restore_firmware()
92            self.invalidate_firmware_setup()
93        except Exception as e:
94            logging.error("Caught exception: %s", str(e))
95        super(firmware_UpdateFirmwareDataKeyVersion, self).cleanup()
96
97
98    def run_once(self):
99        """Runs a single iteration of the test."""
100        logging.info("Update firmware with new datakey version.")
101        self.check_state((self.checkers.crossystem_checker, {
102                          'fwid': self._fwid
103                          }))
104        self.check_state((self.checkers.fw_tries_checker, 'A'))
105        self.faft_client.updater.run_autoupdate('test')
106        self.switcher.mode_aware_reboot()
107
108        logging.info("Check firmware data key version and Rollback.")
109        self.faft_client.updater.run_bootok('test')
110        self.check_state((self.checkers.fw_tries_checker, 'B'))
111        self.switcher.mode_aware_reboot()
112
113        logging.info("Check firmware and TPM version, then recovery.")
114        self.check_state((self.checkers.fw_tries_checker,
115                          'B' if self.fw_vboot2 else 'A'))
116        self.check_firmware_datakey_version(self._update_version)
117        self.faft_client.updater.run_recovery()
118        self.reboot_and_reset_tpm()
119
120        logging.info("Check Rollback version.")
121        self.check_state((self.checkers.crossystem_checker, {
122                          'fwid': self._fwid
123                          }))
124        self.check_state((self.checkers.fw_tries_checker,
125                          'B' if self.fw_vboot2 else 'A'))
126        self.check_firmware_datakey_version(self._update_version - 1)
127