Home | History | Annotate | Download | only in firmware_Cr50TpmMode
      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.
      4 import logging
      5 
      6 from autotest_lib.client.common_lib import error
      7 from autotest_lib.client.common_lib.cros import cr50_utils
      8 from autotest_lib.server.cros.faft.cr50_test import Cr50Test
      9 
     10 
     11 class 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