• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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