faft:cr50: Cr50TpmMode test checks Key Ladder status.

It checks whether H1 key ladder gets recovered before each test,
and checks whether it was revoked after disabling TPM.

BUG=b:118504817
BRANCH=none
TEST=test_that --board=coral ${IP} firmware_Cr50TpmMode
------------------------------------------------------------------
/t.../res...firmware_Cr50TpmMode                      [  PASSED  ]
/t.../res...firmware_Cr50TpmMode/firmware_Cr50TpmMode [  PASSED  ]
-------------------------------------------------------------------

Change-Id: I0dddbadda1efd2297ec0158ffa9ad7198a64751a
Signed-off-by: Namyoon Woo <namyoon@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1316338
Reviewed-by: Mary Ruthven <mruthven@chromium.org>
diff --git a/server/cros/faft/cr50_test.py b/server/cros/faft/cr50_test.py
index 4e66b18..4bd1a83 100644
--- a/server/cros/faft/cr50_test.py
+++ b/server/cros/faft/cr50_test.py
@@ -886,3 +886,9 @@
             self.host.run('cryptohome --action=tpm_wait_ownership')
         self.host.run('cryptohome '
                       '--action=remove_firmware_management_parameters')
+
+    def tpm_is_responsive(self):
+        """Check TPM responsiveness by running tpm_version."""
+        result = self.host.run('tpm_version', ignore_status=True)
+        logging.debug(result.stdout.strip())
+        return not result.exit_status
diff --git a/server/cros/servo/chrome_cr50.py b/server/cros/servo/chrome_cr50.py
index 95bed64..b1cc405 100644
--- a/server/cros/servo/chrome_cr50.py
+++ b/server/cros/servo/chrome_cr50.py
@@ -844,3 +844,27 @@
             logging.info('Cr50 has been up for %ds waiting %ds before update',
                          cr50_time, sleep_time)
             time.sleep(sleep_time)
+
+    def tpm_is_enabled(self):
+        """Query the current TPM mode.
+
+        Returns  True if TPM is enabled,
+                 False otherwise.
+        """
+        result = self.send_command_get_output('sysinfo',
+                ['(?i)TPM\s+MODE:\s+(enabled|disabled)'])[0][1]
+        logging.debug(result)
+
+        return result.lower() == 'enabled'
+
+    def keyladder_is_enabled(self):
+        """Get the status of H1 Key Ladder.
+
+        Returns True if H1 Key Ladder is enabled.
+                False otherwise.
+        """
+        result = self.send_command_get_output('sysinfo',
+                ['(?i)Key\s+Ladder:\s+(enabled|disabled)'])[0][1]
+        logging.debug(result)
+
+        return result.lower() == 'enabled'
diff --git a/server/site_tests/firmware_Cr50TpmMode/firmware_Cr50TpmMode.py b/server/site_tests/firmware_Cr50TpmMode/firmware_Cr50TpmMode.py
index 2b8e6d7..73ce58f 100644
--- a/server/site_tests/firmware_Cr50TpmMode/firmware_Cr50TpmMode.py
+++ b/server/site_tests/firmware_Cr50TpmMode/firmware_Cr50TpmMode.py
@@ -37,10 +37,6 @@
         return cr50_utils.GSCTool(self.host,
                  ['-a', opt_text, mode_param]).stdout.strip()
 
-    def tpm_ping(self):
-        """Check TPM responsiveness by running tpm_version."""
-        return self.host.run('tpm_version').stdout.strip()
-
     def run_test_tpm_mode(self, disable_tpm, long_opt):
         """Run a test for the case of either disabling TPM or enabling.
 
@@ -51,19 +47,32 @@
         """
         # Reset the device.
         logging.info('Reset')
+
         self.servo.get_power_state_controller().reset()
         self.switcher.wait_for_client()
 
-        # Query TPM mode, which should be 'enabled (0)'.
+        self.fast_open(True)
+
+        # Check if TPM is enabled through console command.
         logging.info('Get TPM Mode')
+        if not self.cr50.tpm_is_enabled():
+            raise error.TestFail('TPM is not enabled after reset,')
+
+        # Check if Key Ladder is enabled.
+        if not self.cr50.keyladder_is_enabled():
+            raise error.TestFail('Failed to restore H1 Key Ladder')
+
+        # Check if TPM is enabled through gsctool.
         output_log = self.get_tpm_mode(long_opt)
         logging.info(output_log)
-        if output_log != 'TPM Mode: enabled (0)':
-            raise error.TestFail('Failure in reading TPM mode after reset')
+        if not 'enabled (0)' in output_log.lower():
+            raise error.TestFail('Failed to read TPM mode after reset')
 
-        # Check that TPM is enabled.
-        self.tpm_ping()
-        logging.info('Checked TPM is enabled')
+        # Check if CR50 responds to a TPM request.
+        if self.tpm_is_responsive():
+            logging.info('Checked TPM response')
+        else:
+            raise error.TestFail('Failed to check TPM response')
 
         # Change TPM Mode
         logging.info('Set TPM Mode')
@@ -72,30 +81,32 @@
 
         # Check the result of TPM Mode.
         if disable_tpm:
-            if output_log != 'TPM Mode: disabled (2)':
-                raise error.TestFail('Failure in disabling TPM: %s' %
-                        output_log)
+            if not 'disabled (2)' in output_log.lower():
+                raise error.TestFail('Failed to disable TPM: %s' % output_log)
 
-            # Check that TPM is disabled. The run should fail.
-            try:
-                result = self.tpm_ping()
-            except error.AutoservRunError:
-                logging.info('Checked TPM is disabled')
+            # Check if TPM is disabled. The run should fail.
+            if self.tpm_is_responsive():
+                raise error.TestFail('TPM responded')
             else:
-                raise error.TestFail('Unexpected TPM response: %s' % result)
-        else:
-            if output_log != 'TPM Mode: enabled (1)':
-                raise error.TestFail('Failure in enabling TPM: %s' % output_log)
+                logging.info('TPM did not respond')
 
-            # Check the TPM is enabled still.
-            self.tpm_ping()
-            logging.info('Checked TPM is enabled')
+            if self.cr50.keyladder_is_enabled():
+                raise error.TestFail('Failed to revoke H1 Key Ladder')
+        else:
+            if not 'enabled (1)' in output_log.lower():
+                raise error.TestFail('Failed to enable TPM: %s' % output_log)
+
+            # Check if TPM is enabled still.
+            if self.tpm_is_responsive():
+                logging.info('Checked TPM response')
+            else:
+                raise error.TestFail('Failed to check TPM response')
 
             # Subsequent set-TPM-mode vendor command should fail.
             try:
                 output_log = self.set_tpm_mode(not disable_tpm, long_opt)
             except error.AutoservRunError:
-                logging.info('Expected failure in disabling TPM mode');
+                logging.info('Expectedly failed to disable TPM mode');
             else:
                 raise error.TestFail('Unexpected result in disabling TPM mode:'
                         ' %s' % output_log)