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 NEEDS_SERVO_USB = True 22 23 def resign_datakey_version(self, host): 24 """Resigns the datakey version.""" 25 host.send_file(os.path.join(self.bindir, 26 'files/common.sh'), 27 os.path.join(self.faft_client.updater.get_temp_path(), 28 'common.sh')) 29 host.send_file(os.path.join(self.bindir, 30 'files/make_keys.sh'), 31 os.path.join(self.faft_client.updater.get_temp_path(), 32 'make_keys.sh')) 33 34 self.faft_client.system.run_shell_command('/bin/bash %s %s' % ( 35 os.path.join(self.faft_client.updater.get_temp_path(), 36 'make_keys.sh'), 37 self._update_version)) 38 39 40 def check_firmware_datakey_version(self, expected_ver): 41 """Checks the firmware datakey version.""" 42 actual_ver = self.faft_client.bios.get_datakey_version( 43 'b' if self.fw_vboot2 else 'a') 44 actual_tpm_fwver = self.faft_client.tpm.get_firmware_datakey_version() 45 if actual_ver != expected_ver or actual_tpm_fwver != expected_ver: 46 raise error.TestFail( 47 'Firmware data key version should be %s,' 48 'but got (fwver, tpm_fwver) = (%s, %s).' 49 % (expected_ver, actual_ver, actual_tpm_fwver)) 50 else: 51 logging.info( 52 'Update success, now datakey version is %s', actual_ver) 53 54 55 def initialize(self, host, cmdline_args): 56 """Setup the test""" 57 dict_args = utils.args_to_dict(cmdline_args) 58 shellball_path = dict_args.get('shellball', None) 59 super(firmware_UpdateFirmwareDataKeyVersion, self).initialize( 60 host, cmdline_args) 61 self.backup_firmware() 62 self.switcher.setup_mode('normal') 63 self.setup_firmwareupdate_shellball(shellball_path) 64 65 # Update firmware if needed 66 if shellball_path: 67 self.set_ap_write_protect_and_reboot(enable=False) 68 self.faft_client.updater.run_factory_install() 69 self.switcher.mode_aware_reboot() 70 71 self.setup_usbkey(usbkey=True) 72 self._fwid = self.faft_client.updater.get_section_fwid() 73 74 self.fw_ver_tpm = self.faft_client.tpm.get_firmware_datakey_version() 75 actual_ver = self.faft_client.bios.get_datakey_version('a') 76 logging.info('Origin version is %s', actual_ver) 77 self._update_version = actual_ver + 1 78 logging.info('Firmware version will update to version %s', 79 self._update_version) 80 81 self.resign_datakey_version(host) 82 self.faft_client.updater.resign_firmware(1) 83 self.faft_client.updater.repack_shellball('test') 84 85 86 def cleanup(self): 87 """Cleanup after the test""" 88 try: 89 if (self.faft_client.tpm.get_firmware_datakey_version() != 90 self.fw_ver_tpm): 91 self.reboot_and_reset_tpm() 92 self.restore_firmware() 93 self.invalidate_firmware_setup() 94 except Exception as e: 95 logging.error("Caught exception: %s", str(e)) 96 super(firmware_UpdateFirmwareDataKeyVersion, self).cleanup() 97 98 99 def run_once(self): 100 """Runs a single iteration of the test.""" 101 logging.info("Update firmware with new datakey version.") 102 self.check_state((self.checkers.crossystem_checker, { 103 'fwid': self._fwid 104 })) 105 self.check_state((self.checkers.fw_tries_checker, 'A')) 106 self.faft_client.updater.run_autoupdate('test') 107 self.switcher.mode_aware_reboot() 108 109 logging.info("Check firmware data key version and Rollback.") 110 self.faft_client.updater.run_bootok('test') 111 self.check_state((self.checkers.fw_tries_checker, 'B')) 112 self.switcher.mode_aware_reboot() 113 114 logging.info("Check firmware and TPM version, then recovery.") 115 self.check_state((self.checkers.fw_tries_checker, 116 'B' if self.fw_vboot2 else 'A')) 117 self.check_firmware_datakey_version(self._update_version) 118 self.faft_client.updater.run_recovery() 119 self.reboot_and_reset_tpm() 120 121 logging.info("Check Rollback version.") 122 self.check_state((self.checkers.crossystem_checker, { 123 'fwid': self._fwid 124 })) 125 self.check_state((self.checkers.fw_tries_checker, 126 'B' if self.fw_vboot2 else 'A')) 127 self.check_firmware_datakey_version(self._update_version - 1) 128