1# Copyright 2018 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. 4import logging 5 6from autotest_lib.client.common_lib import error 7from autotest_lib.client.common_lib.cros import cr50_utils 8from autotest_lib.server.cros.faft.cr50_test import Cr50Test 9 10 11class firmware_Cr50TpmMode(Cr50Test): 12 """Verify TPM disabling and getting back enabled after reset.""" 13 version = 1 14 15 def get_tpm_mode(self, long_opt): 16 """Query the current TPM mode. 17 18 Args: 19 long_opt: Boolean to decide whether to use long opt 20 for gsctool command. 21 """ 22 opt_text = '--tpm_mode' if long_opt else '-m' 23 return cr50_utils.GSCTool(self.host, ['-a', opt_text]).stdout.strip() 24 25 def set_tpm_mode(self, disable_tpm, long_opt): 26 """Disable or Enable TPM mode. 27 28 Args: 29 disable_tpm: Disable TPM if True. 30 Enable (or Confirm Enabling) otherwise. 31 long_opt: Boolean to decide whether to use long opt 32 for gsctool command. 33 34 """ 35 mode_param = 'disable' if disable_tpm else 'enable' 36 opt_text = '--tpm_mode' if long_opt else '-m' 37 return cr50_utils.GSCTool(self.host, 38 ['-a', opt_text, mode_param]).stdout.strip() 39 40 def run_test_tpm_mode(self, disable_tpm, long_opt): 41 """Run a test for the case of either disabling TPM or enabling. 42 43 Args: 44 disable_tpm: Disable TPM if True. Enable TPM otherwise. 45 long_opt: Boolean to decide whether to use long opt 46 for gsctool command. 47 """ 48 # Reset the device. 49 logging.info('Reset') 50 51 self.servo.get_power_state_controller().reset() 52 self.switcher.wait_for_client() 53 54 self.fast_open(True) 55 56 # Check if TPM is enabled through console command. 57 logging.info('Get TPM Mode') 58 if not self.cr50.tpm_is_enabled(): 59 raise error.TestFail('TPM is not enabled after reset,') 60 61 # Check if Key Ladder is enabled. 62 if not self.cr50.keyladder_is_enabled(): 63 raise error.TestFail('Failed to restore H1 Key Ladder') 64 65 # Check if TPM is enabled through gsctool. 66 output_log = self.get_tpm_mode(long_opt) 67 logging.info(output_log) 68 if not 'enabled (0)' in output_log.lower(): 69 raise error.TestFail('Failed to read TPM mode after reset') 70 71 # Check if CR50 responds to a TPM request. 72 if self.tpm_is_responsive(): 73 logging.info('Checked TPM response') 74 else: 75 raise error.TestFail('Failed to check TPM response') 76 77 # Change TPM Mode 78 logging.info('Set TPM Mode') 79 output_log = self.set_tpm_mode(disable_tpm, long_opt) 80 logging.info(output_log) 81 82 # Check the result of TPM Mode. 83 if disable_tpm: 84 if not 'disabled (2)' in output_log.lower(): 85 raise error.TestFail('Failed to disable TPM: %s' % output_log) 86 87 # Check if TPM is disabled. The run should fail. 88 if self.tpm_is_responsive(): 89 raise error.TestFail('TPM responded') 90 else: 91 logging.info('TPM did not respond') 92 93 if self.cr50.keyladder_is_enabled(): 94 raise error.TestFail('Failed to revoke H1 Key Ladder') 95 else: 96 if not 'enabled (1)' in output_log.lower(): 97 raise error.TestFail('Failed to enable TPM: %s' % output_log) 98 99 # Check if TPM is enabled still. 100 if self.tpm_is_responsive(): 101 logging.info('Checked TPM response') 102 else: 103 raise error.TestFail('Failed to check TPM response') 104 105 # Subsequent set-TPM-mode vendor command should fail. 106 try: 107 output_log = self.set_tpm_mode(not disable_tpm, long_opt) 108 except error.AutoservRunError: 109 logging.info('Expectedly failed to disable TPM mode'); 110 else: 111 raise error.TestFail('Unexpected result in disabling TPM mode:' 112 ' %s' % output_log) 113 114 def run_once(self): 115 """Test Disabling TPM and Enabling TPM""" 116 long_opts = [True, False] 117 118 # One iteration runs with the short opt '-m', 119 # and the other runs with the long opt '--tpm_mode' 120 for long_opt in long_opts: 121 # Test 1. Disabling TPM 122 logging.info('Disabling TPM') 123 self.run_test_tpm_mode(True, long_opt) 124 125 # Test 2. Enabling TPM 126 logging.info('Enabling TPM') 127 self.run_test_tpm_mode(False, long_opt) 128