tlcl: use different NV_Read authorizations for fw and userland
authorAndrey Pronin <apronin@google.com>
Mon, 18 Jul 2016 18:24:55 +0000 (11:24 -0700)
committerVadim Bendebury <vbendeb@chromium.org>
Fri, 22 Jul 2016 14:42:54 +0000 (14:42 +0000)
Let's use an earlier version of CL 360944 that relies on the
global flag to decide if the platform authorization is to
be used.

As it turned out, we can't read NVRAM with empty
password authorization if platform hierarchy is still enabled
(as it is in firmware), so we keep platform authorization for
firmware, and use empty password only for userland utilities,
like tpmc.

BRANCH=none
BUG=chrome-os-partner:55531
TEST=Run 'initctl stop trunksd; tpmc read 0x1008 0xd" on
     kevin, verify that it returns the right output.

Change-Id: Ic878ebde9086e803d2487d90c55c0f19001cf94b
Signed-off-by: Andrey Pronin <apronin@google.com>
Reviewed-on: https://chromium-review.googlesource.com/362520
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
Tested-by: Andrey Pronin <apronin@chromium.org>
Commit-Queue: Vadim Bendebury <vbendeb@chromium.org>

firmware/include/tlcl.h
firmware/include/tpm2_marshaling.h
firmware/lib/tpm2_lite/marshaling.c
firmware/lib/tpm2_lite/tlcl.c
firmware/lib/tpm_lite/tlcl.c
utility/tpmc.c

index 5373120..31347eb 100644 (file)
@@ -28,6 +28,12 @@ uint32_t TlclLibInit(void);
  */
 uint32_t TlclLibClose(void);
 
+/**
+ * Indicate that we access tlcl with user privileges from OS userland
+ * as opposed to from firmware. May affect required NVRAM read authorization.
+ */
+void TlclLibAccessAsUser(void);
+
 /* Low-level operations */
 
 /**
index c72b076..2022986 100644 (file)
@@ -46,4 +46,15 @@ struct tpm2_response *tpm_unmarshal_response(TPM_CC command,
                                             void *response_body,
                                             int response_size);
 
+/**
+ * tpm_set_ph_disabled
+ *
+ * Sets the flag that indicates if platform hierarchy is disabled.
+ * certain commands, like NV_Read, may need to use different
+ * authorization if platform hierarchy is disabled.
+ *
+ * @flag: 1 if platform hierarchy is disabled, 0 otherwise
+ */
+void tpm_set_ph_disabled(int flag);
+
 #endif // __SRC_LIB_TPM2_MARSHALING_H
index febbc81..3a22b68 100644 (file)
@@ -8,6 +8,7 @@
 #include "utility.h"
 
 static uint16_t tpm_tag;  /* Depends on the command type. */
+static int ph_disabled;   /* Platform hierarchy disabled. */
 
 static void write_be16(void *dest, uint16_t val)
 {
@@ -263,7 +264,11 @@ static void marshal_nv_read(void **buffer,
 {
        struct tpm2_session_header session_header;
 
-       marshal_TPM_HANDLE(buffer, command_body->nvIndex, buffer_space);
+       /* Use empty password auth if platform hierarchy is disabled */
+       if (ph_disabled)
+               marshal_TPM_HANDLE(buffer, command_body->nvIndex, buffer_space);
+       else
+               marshal_TPM_HANDLE(buffer, TPM_RH_PLATFORM, buffer_space);
        marshal_TPM_HANDLE(buffer, command_body->nvIndex, buffer_space);
        Memset(&session_header, 0, sizeof(session_header));
        session_header.session_handle = TPM_RS_PW;
@@ -419,3 +424,8 @@ struct tpm2_response *tpm_unmarshal_response(TPM_CC command,
        /* The entire message have been parsed. */
        return &tpm2_resp;
 }
+
+void tpm_set_ph_disabled(int flag)
+{
+       ph_disabled = flag;
+}
index f335ffb..ae1fa5d 100644 (file)
@@ -52,6 +52,11 @@ uint32_t TlclLibClose(void)
        return VbExTpmClose();
 }
 
+void TlclLibAccessAsUser(void)
+{
+       tpm_set_ph_disabled(1);
+}
+
 uint32_t TlclSendReceive(const uint8_t *request, uint8_t *response,
                          int max_length)
 {
index bf2d27f..181b516 100644 (file)
@@ -152,6 +152,10 @@ uint32_t TlclLibClose(void) {
   return VbExTpmClose();
 }
 
+void TlclLibAccessAsUser(void) {
+  /* no-op for TPM1.2 */
+}
+
 uint32_t TlclStartup(void) {
   VBDEBUG(("TPM: Startup\n"));
   return Send(tpm_startup_cmd.buffer);
index 76a63e0..8d2ed24 100644 (file)
@@ -512,6 +512,7 @@ int main(int argc, char* argv[]) {
     }
 
     TlclLibInit();
+    TlclLibAccessAsUser();
 
     for (c = command_table; c < command_table + n_commands; c++) {
       if (strcmp(cmd, c->name) == 0 || strcmp(cmd, c->abbr) == 0) {