tpm_lite: tpmc command to check owner auth

Add a command that checks whether the well-known secret (SHA1 hash of
20 zero bytes) works for owner authentication. This is accomplished by
sending a DefineSpace command for TPM_NV_INDEX_TRIAL, which will
trigger auth checks but not actually allocate an NVRAM space.
Successful command execution thus indicates that authorization was
successful. tpmc exposes the status via its exit status. This will be
used in the tpm-firmware-updater driver script to verify that the TPM
is in upgradable state.

BRANCH=None
BUG=chromium:788719
TEST=compiles

Change-Id: I630831127e0e01186650412a92643c2153fbe2ee
Reviewed-on: https://chromium-review.googlesource.com/978171
Trybot-Ready: Mattias Nissler <mnissler@chromium.org>
Tested-by: Mattias Nissler <mnissler@chromium.org>
Reviewed-by: Andrey Pronin <apronin@chromium.org>
diff --git a/firmware/include/tpm1_tss_constants.h b/firmware/include/tpm1_tss_constants.h
index d839791..3deef34 100644
--- a/firmware/include/tpm1_tss_constants.h
+++ b/firmware/include/tpm1_tss_constants.h
@@ -18,6 +18,7 @@
 
 #define TPM_NV_INDEX0            ((uint32_t) 0x00000000)
 #define TPM_NV_INDEX_LOCK        ((uint32_t) 0xffffffff)
+#define TPM_NV_INDEX_TRIAL       ((uint32_t) 0x0000f004)
 
 #define TPM_NV_PER_READ_STCLEAR        (((uint32_t)1) << 31)
 #define TPM_NV_PER_AUTHREAD            (((uint32_t)1) << 18)
diff --git a/utility/tpmc.c b/utility/tpmc.c
index 0584e32..68e374b 100644
--- a/utility/tpmc.c
+++ b/utility/tpmc.c
@@ -499,7 +499,25 @@
   }
   return result;
 }
-#endif
+
+static uint32_t HandlerCheckOwnerAuth(void) {
+  /* Attempt to define an NVRAM space using owner auth. We're using
+   * TPM_NV_INDEX_TRIAL, which doesn't actually allocate a space but still
+   * performs the owner authorization checks. Thus the return status indicates
+   * whether owner authorization was successful or not.
+   *
+   * The owner_auth value below is the commonly used well-known secret, i.e. the
+   * SHA1 hash of 20 zero bytes. This is the owner secret that is effective
+   * immediately after taking TPM ownership when we haven't configured a random
+   * owner password yet.
+   */
+  uint8_t owner_auth[TPM_AUTH_DATA_LEN] = {
+      0x67, 0x68, 0x03, 0x3e, 0x21, 0x64, 0x68, 0x24, 0x7b, 0xd0,
+      0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f};
+  return TlclDefineSpaceEx(owner_auth, sizeof(owner_auth), TPM_NV_INDEX_TRIAL,
+                           TPM_NV_PER_OWNERWRITE, 1, NULL, 0);
+}
+#endif  /* !TPM2_MODE */
 
 #ifdef TPM2_MODE
 static uint32_t HandlerDoNothingForTPM2(void) {
@@ -584,6 +602,9 @@
   { "ifxfieldupgradeinfo", "ifxfui",
     TPM20_NOT_IMPLEMENTED("read and print IFX field upgrade info",
       HandlerIFXFieldUpgradeInfo) },
+  { "checkownerauth", "chko",
+    TPM20_NOT_IMPLEMENTED("Check owner authorization with well-known secret",
+      HandlerCheckOwnerAuth) },
 };
 
 static int n_commands = sizeof(command_table) / sizeof(command_table[0]);