[coreboot-gerrit] New patch to review for coreboot: util/tss-generator: WIP - Add TSS generator

Philipp Deppenwiese (zaolin.daisuki@googlemail.com) gerrit at coreboot.org
Fri Mar 18 00:21:26 CET 2016


Philipp Deppenwiese (zaolin.daisuki at googlemail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14135

-gerrit

commit e09664eac833a5ff420af941385f9bf512cddf5b
Author: Philipp Deppenwiese <zaolin at das-labor.org>
Date:   Mon Mar 14 18:53:09 2016 +0100

    util/tss-generator: WIP - Add TSS generator
    
    Change-Id: I93ef112111b403a23c0dce4cf109b9e87424bc1a
    Signed-off-by: Philipp Deppenwiese <zaolin at das-labor.org>
---
 src/include/tpm/tss_constants.h    | 174 +++++++++---
 util/tss-generator/Makefile        |  16 ++
 util/tss-generator/Makefile.inc    |  19 ++
 util/tss-generator/tss-generator.c | 560 +++++++++++++++++++++++++++++++++++++
 util/tss-generator/tss_extras.h    |  27 ++
 util/tss-generator/tss_internal.h  |  61 ++++
 6 files changed, 824 insertions(+), 33 deletions(-)

diff --git a/src/include/tpm/tss_constants.h b/src/include/tpm/tss_constants.h
index afd2593..2417356 100644
--- a/src/include/tpm/tss_constants.h
+++ b/src/include/tpm/tss_constants.h
@@ -18,37 +18,40 @@
 
 #define TPM_E_NON_FATAL 0x800
 
-#define TPM_SUCCESS ((uint32_t)0x00000000)
-
-#define TPM_E_AREA_LOCKED           ((uint32_t)0x0000003c)
-#define TPM_E_BADINDEX              ((uint32_t)0x00000002)
-#define TPM_E_BAD_PRESENCE          ((uint32_t)0x0000002d)
-#define TPM_E_IOERROR               ((uint32_t)0x0000001f)
-#define TPM_E_INVALID_POSTINIT      ((uint32_t)0x00000026)
-#define TPM_E_MAXNVWRITES           ((uint32_t)0x00000048)
-#define TPM_E_OWNER_SET             ((uint32_t)0x00000014)
-
-#define TPM_E_NEEDS_SELFTEST ((uint32_t)(TPM_E_NON_FATAL + 1))
-#define TPM_E_DOING_SELFTEST ((uint32_t)(TPM_E_NON_FATAL + 2))
-
-#define TPM_E_ALREADY_INITIALIZED    ((uint32_t)0x00005000)  /* vboot local */
-#define TPM_E_INTERNAL_INCONSISTENCY ((uint32_t)0x00005001)  /* vboot local */
-#define TPM_E_MUST_REBOOT            ((uint32_t)0x00005002)  /* vboot local */
-#define TPM_E_CORRUPTED_STATE        ((uint32_t)0x00005003)  /* vboot local */
-#define TPM_E_COMMUNICATION_ERROR    ((uint32_t)0x00005004)  /* vboot local */
-#define TPM_E_RESPONSE_TOO_LARGE     ((uint32_t)0x00005005)  /* vboot local */
-#define TPM_E_NO_DEVICE              ((uint32_t)0x00005006)  /* vboot local */
-#define TPM_E_INPUT_TOO_SMALL        ((uint32_t)0x00005007)  /* vboot local */
-#define TPM_E_WRITE_FAILURE          ((uint32_t)0x00005008)  /* vboot local */
-#define TPM_E_READ_EMPTY             ((uint32_t)0x00005009)  /* vboot local */
-#define TPM_E_READ_FAILURE           ((uint32_t)0x0000500a)  /* vboot local */
-
-#define TPM_NV_INDEX0 ((uint32_t)0x00000000)
-#define TPM_NV_INDEX_LOCK ((uint32_t)0xffffffff)
-#define TPM_NV_PER_GLOBALLOCK (((uint32_t)1)<<15)
-#define TPM_NV_PER_PPWRITE (((uint32_t)1)<<0)
-#define TPM_NV_PER_READ_STCLEAR (((uint32_t)1)<<31)
-#define TPM_NV_PER_WRITE_STCLEAR (((uint32_t)1)<<14)
+#define TPM_SUCCESS ((uint32_t) 0x00000000)
+
+#define TPM_E_AREA_LOCKED           ((uint32_t) 0x0000003c)
+#define TPM_E_BADINDEX              ((uint32_t) 0x00000002)
+#define TPM_E_BAD_PRESENCE          ((uint32_t) 0x0000002d)
+#define TPM_E_IOERROR               ((uint32_t) 0x0000001f)
+#define TPM_E_INVALID_POSTINIT      ((uint32_t) 0x00000026)
+#define TPM_E_MAXNVWRITES           ((uint32_t) 0x00000048)
+#define TPM_E_OWNER_SET             ((uint32_t) 0x00000014)
+
+#define TPM_E_NEEDS_SELFTEST ((uint32_t) (TPM_E_NON_FATAL + 1))
+#define TPM_E_DOING_SELFTEST ((uint32_t) (TPM_E_NON_FATAL + 2))
+
+#define TPM_E_ALREADY_INITIALIZED    ((uint32_t) 0x00005000)  /* vboot local */
+#define TPM_E_INTERNAL_INCONSISTENCY ((uint32_t) 0x00005001)  /* vboot local */
+#define TPM_E_MUST_REBOOT            ((uint32_t) 0x00005002)  /* vboot local */
+#define TPM_E_CORRUPTED_STATE        ((uint32_t) 0x00005003)  /* vboot local */
+#define TPM_E_COMMUNICATION_ERROR    ((uint32_t) 0x00005004)  /* vboot local */
+#define TPM_E_RESPONSE_TOO_LARGE     ((uint32_t) 0x00005005)  /* vboot local */
+#define TPM_E_NO_DEVICE              ((uint32_t) 0x00005006)  /* vboot local */
+#define TPM_E_INPUT_TOO_SMALL        ((uint32_t) 0x00005007)  /* vboot local */
+#define TPM_E_WRITE_FAILURE          ((uint32_t) 0x00005008)  /* vboot local */
+#define TPM_E_READ_EMPTY             ((uint32_t) 0x00005009)  /* vboot local */
+#define TPM_E_READ_FAILURE           ((uint32_t) 0x0000500a)  /* vboot local */
+
+#define TPM_NV_INDEX0            ((uint32_t) 0x00000000)
+#define TPM_NV_INDEX_LOCK        ((uint32_t) 0xffffffff)
+#define TPM_NV_PER_GLOBALLOCK    (((uint32_t) 1) << 15)
+#define TPM_NV_PER_PPWRITE       (((uint32_t) 1) << 0)
+#define TPM_NV_PER_READ_STCLEAR  (((uint32_t)1) << 31)
+#define TPM_NV_PER_WRITE_STCLEAR (((uint32_t)1) << 14)
+
+#define TPM_TAG_NV_ATTRIBUTES          ((uint16_t) 0x0017)
+#define TPM_TAG_NV_DATA_PUBLIC         ((uint16_t) 0x0018)
 
 #define TPM_TAG_RQU_COMMAND       ((uint16_t) 0xc1)
 #define TPM_TAG_RQU_AUTH1_COMMAND ((uint16_t) 0xc2)
@@ -59,9 +62,75 @@
 #define TPM_TAG_RSP_AUTH2_COMMAND ((uint16_t) 0xc6)
 
 typedef uint8_t TSS_BOOL;
+typedef uint8_t TPM_BOOL;
+typedef uint16_t TPM_TAG;
 typedef uint16_t TPM_STRUCTURE_TAG;
+typedef uint32_t TPM_NV_INDEX;
+typedef uint32_t TPM_NV_PER_ATTRIBUTES;
+typedef uint8_t TPM_LOCALITY_SELECTION;
+typedef uint32_t TPM_COMMAND_CODE;
+typedef uint16_t TPM_PHYSICAL_PRESENCE;
+typedef uint16_t TPM_STARTUP_TYPE;
+typedef uint32_t TPM_CAPABILITY_AREA;
+
+#define TPM_CAP_FLAG           ((uint32_t) 0x00000004)
+#define TPM_CAP_FLAG_PERMANENT ((uint32_t) 0x00000108)
+#define TPM_CAP_FLAG_VOLATILE  ((uint32_t) 0x00000109)
+
+#define TPM_CAP_PROPERTY       ((uint32_t) 0x00000005)
+#define TPM_CAP_PROP_OWNER     ((uint32_t) 0x00000111)
+#define TPM_CAP_NV_INDEX       ((uint32_t) 0x00000011)
+
+#define TPM_ST_CLEAR       ((uint16_t) 0x0001)
+#define TPM_ST_STATE       ((uint16_t) 0x0002)
+#define TPM_ST_DEACTIVATED ((uint16_t) 0x0003)
+
+#define TPM_LOC_FOUR   (((uint32_t)1)<<4)
+#define TPM_LOC_THREE  (((uint32_t)1)<<3)
+#define TPM_LOC_TWO    (((uint32_t)1)<<2)
+#define TPM_LOC_ONE    (((uint32_t)1)<<1)
+#define TPM_LOC_ZERO   (((uint32_t)1)<<0)
+
+#define TPM_PHYSICAL_PRESENCE_LOCK          ((uint16_t) 0x0004)
+#define TPM_PHYSICAL_PRESENCE_PRESENT       ((uint16_t) 0x0008)
+#define TPM_PHYSICAL_PRESENCE_NOTPRESENT    ((uint16_t) 0x0010)
+#define TPM_PHYSICAL_PRESENCE_CMD_ENABLE    ((uint16_t) 0x0020)
+#define TPM_PHYSICAL_PRESENCE_HW_ENABLE     ((uint16_t) 0x0040)
+#define TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK ((uint16_t) 0x0080)
+#define TPM_PHYSICAL_PRESENCE_CMD_DISABLE   ((uint16_t) 0x0100)
+#define TPM_PHYSICAL_PRESENCE_HW_DISABLE    ((uint16_t) 0x0200)
+
+#define TPM_SHA1_160_HASH_LEN    0x14
+#define TPM_SHA1BASED_NONCE_LEN  TPM_SHA1_160_HASH_LEN
 
-typedef struct tdTPM_PERMANENT_FLAGS {
+typedef struct tdTPM_DIGEST
+{
+    uint8_t  digest[TPM_SHA1_160_HASH_LEN];
+} TPM_DIGEST;
+
+typedef TPM_DIGEST TPM_COMPOSITE_HASH;
+
+typedef struct tdTPM_PCR_SELECTION
+{
+    uint16_t  sizeOfSelect;
+    uint8_t   *pcrSelect;
+} TPM_PCR_SELECTION;
+
+typedef struct tdTPM_NV_ATTRIBUTES
+{
+    TPM_STRUCTURE_TAG     tag;
+    TPM_NV_PER_ATTRIBUTES attributes;
+} TPM_NV_ATTRIBUTES;
+
+typedef struct tdTPM_PCR_INFO_SHORT
+{
+    TPM_PCR_SELECTION      pcrSelection;
+    TPM_LOCALITY_SELECTION localityAtRelease;
+    TPM_COMPOSITE_HASH     digestAtRelease;
+}  TPM_PCR_INFO_SHORT;
+
+typedef struct tdTPM_PERMANENT_FLAGS
+{
 	TPM_STRUCTURE_TAG tag;
 	TSS_BOOL disable;
 	TSS_BOOL ownership;
@@ -94,4 +163,43 @@ typedef struct tdTPM_STCLEAR_FLAGS {
 	TSS_BOOL bGlobalLock;
 } TPM_STCLEAR_FLAGS;
 
-#endif /* TPM_TSS_CONSTANTS_H */
+typedef struct tdTPM_NV_DATA_PUBLIC
+{
+    TPM_STRUCTURE_TAG  tag;
+    TPM_NV_INDEX       nvIndex;
+    TPM_PCR_INFO_SHORT pcrInfoRead;
+    TPM_PCR_INFO_SHORT pcrInfoWrite;
+    TPM_NV_ATTRIBUTES  permission;
+    TPM_BOOL           bReadSTClear;
+    TPM_BOOL           bWriteSTClear;
+    TPM_BOOL           bWriteDefine;
+    uint32_t           dataSize;
+} TPM_NV_DATA_PUBLIC;
+
+typedef struct tdTPM_NONCE
+{
+    uint8_t nonce[TPM_SHA1BASED_NONCE_LEN];
+} TPM_NONCE;
+
+/* Ordinals */
+
+#define TPM_ORD_ContinueSelfTest  ((uint32_t) 0x00000053)
+#define TPM_ORD_Extend            ((uint32_t) 0x00000014)
+#define TPM_ORD_ForceClear        ((uint32_t) 0x0000005D)
+#define TPM_ORD_GetCapability     ((uint32_t) 0x00000065)
+#define TPM_ORD_GetRandom                         ((uint32_t) 0x00000046)
+#define TPM_ORD_NV_DefineSpace    ((uint32_t) 0x000000CC)
+#define TPM_ORD_NV_ReadValue      ((uint32_t) 0x000000CF)
+#define TPM_ORD_NV_WriteValue     ((uint32_t) 0x000000CD)
+#define TPM_ORD_PcrRead           ((uint32_t) 0x00000015)
+#define TPM_ORD_PhysicalEnable    ((uint32_t) 0x0000006F)
+#define TPM_ORD_PhysicalDisable   ((uint32_t) 0x00000070)
+#define TSC_ORD_PhysicalPresence  ((uint32_t) 0x4000000A)
+#define TPM_ORD_PhysicalSetDeactivated    ((uint32_t) 0x00000072)
+#define TPM_ORD_ReadPubek         ((uint32_t) 0x0000007C)
+#define TPM_ORD_SaveState         ((uint32_t) 0x00000098)
+#define TPM_ORD_SelfTestFull      ((uint32_t) 0x00000050)
+#define TPM_ORD_Startup           ((uint32_t) 0x00000099)
+
+
+#endif  /* TPM_TSS_CONSTANTS_H */
diff --git a/util/tss-generator/Makefile b/util/tss-generator/Makefile
new file mode 100644
index 0000000..63e3d69
--- /dev/null
+++ b/util/tss-generator/Makefile
@@ -0,0 +1,16 @@
+top ?= $(abspath ../..)
+objutil ?= $(top)/util
+arch ?= $(ARCH)
+
+HOSTCC ?= $(CC)
+
+.PHONY: all
+all: $(objutil)/tss-generator/tss-generator
+
+.PHONY: clean
+clean:
+	$(RM) $(objutil)/tss-generator/tss-generator $(tssobj)
+
+.SILENT:
+
+include Makefile.inc
diff --git a/util/tss-generator/Makefile.inc b/util/tss-generator/Makefile.inc
new file mode 100644
index 0000000..c3f44e5
--- /dev/null
+++ b/util/tss-generator/Makefile.inc
@@ -0,0 +1,19 @@
+tssobj :=
+tssobj += tss-generator.o
+
+TOOLCFLAGS := -Werror -Wall -Wextra
+TOOLCFLAGS += -I$(top)/src/include/tpm
+TOOLCFLAGS += -I$(top)/src/commonlib/include
+TOOLCFLAGS += -I$(objutil)/tss-generator
+
+$(objutil)/tss-generator/%.o: $(objutil)/tss-generator/%.c
+	printf "    HOSTCC     $(subst $(objutil)/,,$(@))\n"
+	$(HOSTCC) $(TOOLCFLAGS) $(HOSTCFLAGS) -c -o $@ $<
+
+$(objutil)/tss-generator/%.o: $(top)/util/tss-generator/%.c
+	printf "    HOSTCC     $(subst $(objutil)/,,$(@))\n"
+	$(HOSTCC) $(TOOLCFLAGS) $(HOSTCFLAGS) -c -o $@ $<
+
+$(objutil)/tss-generator/tss-generator: $(addprefix $(objutil)/tss-generator/,$(tssobj))
+	printf "    HOSTCC     $(subst $(objutil)/,,$(@)) (link)\n"
+	$(HOSTCC) -o $@ $(addprefix $(objutil)/tss-generator/,$(tssobj))
diff --git a/util/tss-generator/tss-generator.c b/util/tss-generator/tss-generator.c
new file mode 100644
index 0000000..44b7869
--- /dev/null
+++ b/util/tss-generator/tss-generator.c
@@ -0,0 +1,560 @@
+/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* This program generates partially filled TPM datagrams and other compile-time
+ * constants (e.g. structure sizes and offsets).  Compile this file---and ONLY
+ * this file---with -fpack-struct.  We take advantage of the fact that the
+ * (packed) TPM structures layout (mostly) match the TPM request and response
+ * datagram layout.  When they don't completely match, some fixing is necessary
+ * (see PCR_SELECTION_FIX below).
+ */
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <inttypes.h>  /* For PRIu64 */
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN)
+#include <byteswap.h>
+#include <memory.h>
+#endif
+
+#include "tss_internal.h"
+#include "tss_extras.h"
+#include <tss_constants.h>
+
+/* See struct Command below.  This structure represent a field in a TPM
+ * command.  [name] is the field name.  [visible] is 1 if the field is
+ * modified by the run-time.  Non-visible fields are initialized at build time
+ * and remain constant.  [size] is the field size in bytes.  [value] is the
+ * fixed value of non-visible fields.
+ */
+typedef struct Field {
+  const char* name;
+  int visible;
+  int offset;
+  int size;
+  uint32_t value;     /* large enough for all initializers */
+  struct Field* next;
+} Field;
+
+/* This structure is used to build (at build time) and manipulate (at firmware
+ * or emulation run time) buffers containing TPM datagrams.  [name] is the name
+ * of a TPM command.  [size] is the size of the command buffer in bytes, when
+ * known.  [max_size] is the maximum size allowed for variable-length commands
+ * (such as Read and Write).  [fields] is a link-list of command fields.
+ */
+typedef struct Command {
+  const char* name;
+  int size;
+  int max_size;
+  Field* fields;
+  struct Command* next;
+} Command;
+
+/* Adds a field to a command, and makes its offset visible.  The fields must be
+ * added at increasing offsets.
+ */
+static void AddVisibleField(Command* cmd, const char* name, int offset) {
+  Field* fld = (Field*) calloc(1, sizeof(Field));
+  if (cmd->fields != NULL) {
+    assert(offset > fld->offset);
+  }
+  fld->next = cmd->fields;
+  cmd->fields = fld;
+  fld->name = name;
+  fld->visible = 1;
+  fld->offset = offset;
+}
+
+/* Adds a constant field with its value.  The fields must be added at
+ * increasing offsets.
+ */
+static void AddInitializedField(Command* cmd, int offset,
+                                int size, uint32_t value) {
+  Field* fld = (Field*) calloc(1, sizeof(Field));
+  fld->next = cmd->fields;
+  cmd->fields = fld;
+  fld->name = NULL;
+  fld->visible = 0;
+  fld->size = size;
+  fld->offset = offset;
+  fld->value = value;
+}
+
+/* Create a structure representing a TPM command datagram.
+ */
+Command* newCommand(TPM_COMMAND_CODE code, int size) {
+  Command* cmd = (Command*) calloc(1, sizeof(Command));
+  cmd->size = size;
+  AddInitializedField(cmd, 0, sizeof(TPM_TAG), TPM_TAG_RQU_COMMAND);
+  AddInitializedField(cmd, sizeof(TPM_TAG), sizeof(uint32_t), size);
+  AddInitializedField(cmd, sizeof(TPM_TAG) + sizeof(uint32_t),
+                      sizeof(TPM_COMMAND_CODE), code);
+  return cmd;
+}
+
+/* The TPM_PCR_SELECTION structure in /usr/include/tss/tpm.h contains a pointer
+ * instead of an array[3] of bytes, so we need to adjust sizes and offsets
+ * accordingly.
+ */
+#define PCR_SELECTION_FIX (3 - sizeof(char *))
+
+/* BuildXXX builds TPM command XXX.
+ */
+Command* BuildDefineSpaceCommand(void) {
+  int nv_data_public = kTpmRequestHeaderLength;
+  int nv_index = nv_data_public + offsetof(TPM_NV_DATA_PUBLIC, nvIndex);
+  int nv_pcr_info_read = nv_data_public +
+    offsetof(TPM_NV_DATA_PUBLIC, pcrInfoRead);
+  /*
+   * Here we need to carefully add PCR_SELECTION_FIX (or twice that much) in
+   * all the places where the offset calculation would be wrong without it.
+   * The mismatch occurs in the TPM_PCR_SELECTION structure, and it must be
+   * accounted for in all the structures that include it, directly or
+   * indirectly.
+   */
+  int read_locality = nv_pcr_info_read +
+    offsetof(TPM_PCR_INFO_SHORT, localityAtRelease) + PCR_SELECTION_FIX;
+  int nv_pcr_info_write = nv_data_public +
+    offsetof(TPM_NV_DATA_PUBLIC, pcrInfoWrite) + PCR_SELECTION_FIX;
+  int write_locality = nv_pcr_info_write +
+    offsetof(TPM_PCR_INFO_SHORT, localityAtRelease) + PCR_SELECTION_FIX;
+  int nv_permission = nv_data_public +
+    offsetof(TPM_NV_DATA_PUBLIC, permission) + 2 * PCR_SELECTION_FIX;
+  int nv_permission_tag =
+    nv_permission + offsetof(TPM_NV_ATTRIBUTES, tag);
+  int nv_permission_attributes =
+    nv_permission + offsetof(TPM_NV_ATTRIBUTES, attributes);
+  int nv_datasize = nv_data_public +
+    offsetof(TPM_NV_DATA_PUBLIC, dataSize) + 2 * PCR_SELECTION_FIX;
+
+  int size = kTpmRequestHeaderLength + sizeof(TPM_NV_DATA_PUBLIC) +
+    2 * PCR_SELECTION_FIX + kEncAuthLength;
+  Command* cmd = newCommand(TPM_ORD_NV_DefineSpace, size);
+  cmd->name = "tpm_nv_definespace_cmd";
+
+  AddVisibleField(cmd, "index", nv_index);
+  AddVisibleField(cmd, "perm", nv_permission_attributes);
+  AddVisibleField(cmd, "size", nv_datasize);
+
+  AddInitializedField(cmd, nv_data_public, sizeof(uint16_t),
+                      TPM_TAG_NV_DATA_PUBLIC);
+  AddInitializedField(cmd, nv_pcr_info_read, sizeof(uint16_t), 3);
+  AddInitializedField(cmd, read_locality, sizeof(TPM_LOCALITY_SELECTION),
+                      TPM_ALL_LOCALITIES);
+  AddInitializedField(cmd, nv_pcr_info_write, sizeof(uint16_t), 3);
+  AddInitializedField(cmd, write_locality, sizeof(TPM_LOCALITY_SELECTION),
+                      TPM_ALL_LOCALITIES);
+  AddInitializedField(cmd, nv_permission_tag, sizeof(TPM_STRUCTURE_TAG),
+                      TPM_TAG_NV_ATTRIBUTES);
+  return cmd;
+}
+
+/* BuildXXX builds TPM command XXX.
+ */
+Command* BuildWriteCommand(void) {
+  Command* cmd = newCommand(TPM_ORD_NV_WriteValue, 0);
+  cmd->name = "tpm_nv_write_cmd";
+  cmd->max_size = TPM_LARGE_ENOUGH_COMMAND_SIZE;
+  AddVisibleField(cmd, "index", kTpmRequestHeaderLength);
+  AddVisibleField(cmd, "length", kTpmRequestHeaderLength + 8);
+  AddVisibleField(cmd, "data", kTpmRequestHeaderLength + 12);
+  return cmd;
+}
+
+Command* BuildReadCommand(void) {
+  int size = kTpmRequestHeaderLength + kTpmReadInfoLength;
+  Command* cmd = newCommand(TPM_ORD_NV_ReadValue, size);
+  cmd->name = "tpm_nv_read_cmd";
+  AddVisibleField(cmd, "index", kTpmRequestHeaderLength);
+  AddVisibleField(cmd, "length", kTpmRequestHeaderLength + 8);
+  return cmd;
+}
+
+Command* BuildPCRReadCommand(void) {
+  int size = kTpmRequestHeaderLength + sizeof(uint32_t);
+  Command* cmd = newCommand(TPM_ORD_PcrRead, size);
+  cmd->name = "tpm_pcr_read_cmd";
+  AddVisibleField(cmd, "pcrNum", kTpmRequestHeaderLength);
+  return cmd;
+}
+
+Command* BuildPPAssertCommand(void) {
+  int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE);
+  Command* cmd = newCommand(TSC_ORD_PhysicalPresence, size);
+  cmd->name = "tpm_ppassert_cmd";
+  AddInitializedField(cmd, kTpmRequestHeaderLength,
+                      sizeof(TPM_PHYSICAL_PRESENCE),
+                      TPM_PHYSICAL_PRESENCE_PRESENT);
+  return cmd;
+}
+
+Command* BuildPPEnableCommand(void) {
+  int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE);
+  Command* cmd = newCommand(TSC_ORD_PhysicalPresence, size);
+  cmd->name = "tpm_ppenable_cmd";
+  AddInitializedField(cmd, kTpmRequestHeaderLength,
+                      sizeof(TPM_PHYSICAL_PRESENCE),
+                      TPM_PHYSICAL_PRESENCE_CMD_ENABLE);
+  return cmd;
+}
+
+Command* BuildFinalizePPCommand(void) {
+  int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE);
+  Command* cmd = newCommand(TSC_ORD_PhysicalPresence, size);
+  cmd->name = "tpm_finalizepp_cmd";
+  AddInitializedField(cmd, kTpmRequestHeaderLength,
+                      sizeof(TPM_PHYSICAL_PRESENCE),
+                      TPM_PHYSICAL_PRESENCE_CMD_ENABLE |
+                      TPM_PHYSICAL_PRESENCE_HW_DISABLE |
+                      TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK);
+  return cmd;
+}
+
+Command* BuildPPLockCommand(void) {
+  int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE);
+  Command* cmd = newCommand(TSC_ORD_PhysicalPresence, size);
+  cmd->name = "tpm_pplock_cmd";
+  AddInitializedField(cmd, kTpmRequestHeaderLength,
+                      sizeof(TPM_PHYSICAL_PRESENCE),
+                      TPM_PHYSICAL_PRESENCE_LOCK);
+  return cmd;
+}
+
+Command* BuildStartupCommand(void) {
+  int size = kTpmRequestHeaderLength + sizeof(TPM_STARTUP_TYPE);
+  Command* cmd = newCommand(TPM_ORD_Startup, size);
+  cmd->name = "tpm_startup_cmd";
+  AddInitializedField(cmd, kTpmRequestHeaderLength,
+                      sizeof(TPM_STARTUP_TYPE),
+                      TPM_ST_CLEAR);
+  return cmd;
+}
+
+Command* BuildSaveStateCommand(void) {
+  int size = kTpmRequestHeaderLength;
+  Command* cmd = newCommand(TPM_ORD_SaveState, size);
+  cmd->name = "tpm_savestate_cmd";
+  return cmd;
+}
+
+Command* BuildResumeCommand(void) {
+  int size = kTpmRequestHeaderLength + sizeof(TPM_STARTUP_TYPE);
+  Command* cmd = newCommand(TPM_ORD_Startup, size);
+  cmd->name = "tpm_resume_cmd";
+  AddInitializedField(cmd, kTpmRequestHeaderLength,
+                      sizeof(TPM_STARTUP_TYPE),
+                      TPM_ST_STATE);
+  return cmd;
+}
+
+Command* BuildSelftestfullCommand(void) {
+  int size = kTpmRequestHeaderLength;
+  Command* cmd = newCommand(TPM_ORD_SelfTestFull, size);
+  cmd->name = "tpm_selftestfull_cmd";
+  return cmd;
+}
+
+Command* BuildContinueSelfTestCommand(void) {
+  int size = kTpmRequestHeaderLength;
+  Command* cmd = newCommand(TPM_ORD_ContinueSelfTest, size);
+  cmd->name = "tpm_continueselftest_cmd";
+  return cmd;
+}
+
+Command* BuildReadPubekCommand(void) {
+  int size = kTpmRequestHeaderLength + sizeof(TPM_NONCE);
+  Command* cmd = newCommand(TPM_ORD_ReadPubek, size);
+  cmd->name = "tpm_readpubek_cmd";
+  return cmd;
+}
+
+Command* BuildForceClearCommand(void) {
+  int size = kTpmRequestHeaderLength;
+  Command* cmd = newCommand(TPM_ORD_ForceClear, size);
+  cmd->name = "tpm_forceclear_cmd";
+  return cmd;
+}
+
+Command* BuildPhysicalEnableCommand(void) {
+  int size = kTpmRequestHeaderLength;
+  Command* cmd = newCommand(TPM_ORD_PhysicalEnable, size);
+  cmd->name = "tpm_physicalenable_cmd";
+  return cmd;
+}
+
+Command* BuildPhysicalDisableCommand(void) {
+  int size = kTpmRequestHeaderLength;
+  Command* cmd = newCommand(TPM_ORD_PhysicalDisable, size);
+  cmd->name = "tpm_physicaldisable_cmd";
+  return cmd;
+}
+
+Command* BuildPhysicalSetDeactivatedCommand(void) {
+  int size = kTpmRequestHeaderLength + sizeof(uint8_t);
+  Command* cmd = newCommand(TPM_ORD_PhysicalSetDeactivated, size);
+  cmd->name = "tpm_physicalsetdeactivated_cmd";
+  AddVisibleField(cmd, "deactivated", kTpmRequestHeaderLength);
+  return cmd;
+}
+
+Command* BuildExtendCommand(void) {
+  int size = kTpmRequestHeaderLength + sizeof(uint32_t) + kPcrDigestLength;
+  Command* cmd = newCommand(TPM_ORD_Extend, size);
+  cmd->name = "tpm_extend_cmd";
+  AddVisibleField(cmd, "pcrNum", kTpmRequestHeaderLength);
+  AddVisibleField(cmd, "inDigest", kTpmRequestHeaderLength + sizeof(uint32_t));
+  return cmd;
+}
+
+Command* BuildGetFlagsCommand(void) {
+  int size = (kTpmRequestHeaderLength +
+              sizeof(TPM_CAPABILITY_AREA) +   /* capArea */
+              sizeof(uint32_t) +              /* subCapSize */
+              sizeof(uint32_t));              /* subCap */
+
+  Command* cmd = newCommand(TPM_ORD_GetCapability, size);
+  cmd->name = "tpm_getflags_cmd";
+  AddInitializedField(cmd, kTpmRequestHeaderLength,
+                      sizeof(TPM_CAPABILITY_AREA), TPM_CAP_FLAG);
+  AddInitializedField(cmd, kTpmRequestHeaderLength +
+                      sizeof(TPM_CAPABILITY_AREA),
+                      sizeof(uint32_t), sizeof(uint32_t));
+  AddInitializedField(cmd, kTpmRequestHeaderLength +
+                      sizeof(TPM_CAPABILITY_AREA) + sizeof(uint32_t),
+                      sizeof(uint32_t), TPM_CAP_FLAG_PERMANENT);
+  return cmd;
+}
+
+Command* BuildGetSTClearFlagsCommand(void) {
+  int size = (kTpmRequestHeaderLength +
+              sizeof(TPM_CAPABILITY_AREA) +   /* capArea */
+              sizeof(uint32_t) +              /* subCapSize */
+              sizeof(uint32_t));              /* subCap */
+
+  Command* cmd = newCommand(TPM_ORD_GetCapability, size);
+  cmd->name = "tpm_getstclearflags_cmd";
+  AddInitializedField(cmd, kTpmRequestHeaderLength,
+                      sizeof(TPM_CAPABILITY_AREA), TPM_CAP_FLAG);
+  AddInitializedField(cmd, kTpmRequestHeaderLength +
+                      sizeof(TPM_CAPABILITY_AREA),
+                      sizeof(uint32_t), sizeof(uint32_t));
+  AddInitializedField(cmd, kTpmRequestHeaderLength +
+                      sizeof(TPM_CAPABILITY_AREA) + sizeof(uint32_t),
+                      sizeof(uint32_t), TPM_CAP_FLAG_VOLATILE);
+  return cmd;
+}
+
+Command* BuildGetPermissionsCommand(void) {
+  int size = (kTpmRequestHeaderLength +
+              sizeof(TPM_CAPABILITY_AREA) +   /* capArea */
+              sizeof(uint32_t) +              /* subCapSize */
+              sizeof(uint32_t));              /* subCap */
+
+  Command* cmd = newCommand(TPM_ORD_GetCapability, size);
+  cmd->name = "tpm_getpermissions_cmd";
+  AddInitializedField(cmd, kTpmRequestHeaderLength,
+                      sizeof(TPM_CAPABILITY_AREA), TPM_CAP_NV_INDEX);
+  AddInitializedField(cmd, kTpmRequestHeaderLength +
+                      sizeof(TPM_CAPABILITY_AREA),
+                      sizeof(uint32_t), sizeof(uint32_t));
+  AddVisibleField(cmd, "index", kTpmRequestHeaderLength +
+                  sizeof(TPM_CAPABILITY_AREA) + sizeof(uint32_t));
+  return cmd;
+}
+
+Command* BuildGetOwnershipCommand(void) {
+  int size = (kTpmRequestHeaderLength +
+              sizeof(TPM_CAPABILITY_AREA) +   /* capArea */
+              sizeof(uint32_t) +              /* subCapSize */
+              sizeof(uint32_t));              /* subCap */
+
+  Command* cmd = newCommand(TPM_ORD_GetCapability, size);
+  cmd->name = "tpm_getownership_cmd";
+  AddInitializedField(cmd, kTpmRequestHeaderLength,
+                      sizeof(TPM_CAPABILITY_AREA), TPM_CAP_PROPERTY);
+  AddInitializedField(cmd, kTpmRequestHeaderLength +
+                      sizeof(TPM_CAPABILITY_AREA),
+                      sizeof(uint32_t), sizeof(uint32_t));
+  AddInitializedField(cmd, kTpmRequestHeaderLength +
+                      sizeof(TPM_CAPABILITY_AREA) + sizeof(uint32_t),
+                      sizeof(uint32_t), TPM_CAP_PROP_OWNER);
+  return cmd;
+}
+
+Command* BuildGetRandomCommand(void) {
+  int size = kTpmRequestHeaderLength + sizeof(uint32_t);
+  Command* cmd = newCommand(TPM_ORD_GetRandom, size);
+  cmd->name = "tpm_get_random_cmd";
+  AddVisibleField(cmd, "bytesRequested", kTpmRequestHeaderLength);
+  return cmd;
+}
+
+/* Output the fields of a structure.
+ */
+void OutputFields(Field* fld) {
+  /*
+   * Field order is reversed.
+   */
+  if (fld != NULL) {
+    OutputFields(fld->next);
+    if (fld->visible) {
+      printf("  uint16_t %s;\n", fld->name);
+    }
+  }
+}
+
+/* Outputs a structure initializer.
+ */
+int OutputBytes_(Command* cmd, Field* fld) {
+  int cursor = 0;
+  int i;
+  /*
+   * Field order is reversed.
+   */
+  if (fld != NULL) {
+    cursor = OutputBytes_(cmd, fld->next);
+  } else {
+    return 0;
+  }
+  if (!fld->visible) {
+    /*
+     * Catch up missing fields.
+     */
+    assert(fld->offset >= cursor);
+    for (i = 0; i < fld->offset - cursor; i++) {
+      printf("0, ");
+    }
+    cursor = fld->offset;
+    switch (fld->size) {
+    case 1:
+      printf("0x%x, ", fld->value);
+      cursor += 1;
+      break;
+    case 2:
+      printf("0x%x, 0x%x, ", fld->value >> 8, fld->value & 0xff);
+      cursor += 2;
+      break;
+    case 4:
+      printf("0x%x, 0x%x, 0x%x, 0x%x, ", fld->value >> 24,
+             (fld->value >> 16) & 0xff,
+             (fld->value >> 8) & 0xff,
+             fld->value & 0xff);
+      cursor += 4;
+      break;
+    default:
+      fprintf(stderr, "invalid field size %d\n", fld->size);
+      exit(1);
+      break;
+    }
+  }
+  return cursor;
+}
+
+/* Helper to output a structure initializer.
+ */
+void OutputBytes(Command* cmd) {
+  (void) OutputBytes_(cmd, cmd->fields);
+}
+
+void OutputFieldPointers(Command* cmd, Field* fld) {
+  if (fld == NULL) {
+    return;
+  } else {
+    OutputFieldPointers(cmd, fld->next);
+    if (fld->visible) {
+      printf("%d, ", fld->offset);
+    }
+  }
+}
+
+/* Outputs the structure initializers for all commands.
+ */
+void OutputCommands(Command* cmd) {
+  if (cmd == NULL) {
+    return;
+  } else {
+    printf("const struct s_%s{\n  uint8_t buffer[%d];\n",
+           cmd->name, cmd->size == 0 ? cmd->max_size : cmd->size);
+    OutputFields(cmd->fields);
+    printf("} %s = {{", cmd->name);
+    OutputBytes(cmd);
+    printf("},\n");
+    OutputFieldPointers(cmd, cmd->fields);
+    printf("};\n\n");
+  }
+  OutputCommands(cmd->next);
+}
+
+Command* (*builders[])(void) = {
+  BuildDefineSpaceCommand,
+  BuildWriteCommand,
+  BuildReadCommand,
+  BuildPCRReadCommand,
+  BuildPPAssertCommand,
+  BuildPPEnableCommand,
+  BuildPPLockCommand,
+  BuildFinalizePPCommand,
+  BuildStartupCommand,
+  BuildSaveStateCommand,
+  BuildResumeCommand,
+  BuildSelftestfullCommand,
+  BuildContinueSelfTestCommand,
+  BuildReadPubekCommand,
+  BuildForceClearCommand,
+  BuildPhysicalDisableCommand,
+  BuildPhysicalEnableCommand,
+  BuildPhysicalSetDeactivatedCommand,
+  BuildGetFlagsCommand,
+  BuildGetSTClearFlagsCommand,
+  BuildGetPermissionsCommand,
+  BuildGetOwnershipCommand,
+  BuildGetRandomCommand,
+  BuildExtendCommand,
+};
+
+static void FreeFields(Field* fld) {
+  if (fld != NULL) {
+    Field* next_field = fld->next;
+    free(fld);
+    FreeFields(next_field);
+  }
+}
+
+static void FreeCommands(Command* cmd) {
+  if (cmd != NULL) {
+    Command* next_command = cmd->next;
+    FreeFields(cmd->fields);
+    free(cmd);
+    FreeCommands(next_command);
+  }
+}
+
+int main(void) {
+  Command* commands = NULL;
+  uint32_t i;
+  for (i = 0; i < sizeof(builders) / sizeof(builders[0]); i++) {
+    Command* cmd = builders[i]();
+    cmd->next = commands;
+    commands = cmd;
+  }
+
+  printf("/* This file is automatically generated */\n\n");
+  OutputCommands(commands);
+  printf("const int kWriteInfoLength = %d;\n", (int) sizeof(TPM_WRITE_INFO));
+  printf("const int kNvDataPublicPermissionsOffset = %d;\n",
+         (int) (offsetof(TPM_NV_DATA_PUBLIC, permission) +
+                2 * PCR_SELECTION_FIX +
+                offsetof(TPM_NV_ATTRIBUTES, attributes)));
+
+  FreeCommands(commands);
+  return 0;
+}
diff --git a/util/tss-generator/tss_extras.h b/util/tss-generator/tss_extras.h
new file mode 100644
index 0000000..0fe0982
--- /dev/null
+++ b/util/tss-generator/tss_extras.h
@@ -0,0 +1,27 @@
+/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/*
+ * TPM definitions not available in any TSS include file :-(
+ */
+
+#ifndef TPM_LITE_TPMEXTRAS_H_
+#define TPM_LITE_TPMEXTRAS_H_
+
+#define TPM_MAX_COMMAND_SIZE 4096
+#define TPM_LARGE_ENOUGH_COMMAND_SIZE 256  /* saves space in the firmware */
+#define TPM_ENCAUTH_SIZE 20
+#define TPM_PUBEK_SIZE 256
+
+#define TPM_ALL_LOCALITIES (TPM_LOC_ZERO | TPM_LOC_ONE | TPM_LOC_TWO    \
+                            | TPM_LOC_THREE | TPM_LOC_FOUR)  /* 0x1f */
+
+typedef struct tdTPM_WRITE_INFO {
+  uint32_t nvIndex;
+  uint32_t offset;
+  uint32_t dataSize;
+} TPM_WRITE_INFO;
+
+#endif
diff --git a/util/tss-generator/tss_internal.h b/util/tss-generator/tss_internal.h
new file mode 100644
index 0000000..51fe6ef
--- /dev/null
+++ b/util/tss-generator/tss_internal.h
@@ -0,0 +1,61 @@
+/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef TPM_LITE_TLCL_INTERNAL_H_
+#define TPM_LITE_TLCL_INTERNAL_H_
+
+/*
+ * These numbers derive from adding the sizes of command fields as shown in the
+ * TPM commands manual.
+ */
+#define kTpmRequestHeaderLength 10
+#define kTpmResponseHeaderLength 10
+#define kTpmReadInfoLength 12
+#define kEncAuthLength 20
+#define kPcrDigestLength 20
+
+
+/*
+ * Conversion functions.  ToTpmTYPE puts a value of type TYPE into a TPM
+ * command buffer.  FromTpmTYPE gets a value of type TYPE from a TPM command
+ * buffer into a variable.
+ */
+__attribute__((unused))
+static inline void ToTpmUint32(uint8_t *buffer, uint32_t x) {
+  buffer[0] = (uint8_t)(x >> 24);
+  buffer[1] = (uint8_t)((x >> 16) & 0xff);
+  buffer[2] = (uint8_t)((x >> 8) & 0xff);
+  buffer[3] = (uint8_t)(x & 0xff);
+}
+
+/*
+ * See comment for above function.
+ */
+__attribute__((unused))
+static inline void FromTpmUint32(const uint8_t *buffer, uint32_t *x) {
+  *x = ((buffer[0] << 24) |
+        (buffer[1] << 16) |
+        (buffer[2] << 8) |
+        buffer[3]);
+}
+
+/*
+ * See comment for above function.
+ */
+__attribute__((unused))
+static inline void ToTpmUint16(uint8_t *buffer, uint16_t x) {
+  buffer[0] = (uint8_t)(x >> 8);
+  buffer[1] = (uint8_t)(x & 0xff);
+}
+
+/*
+ * See comment for above function.
+ */
+__attribute__((unused))
+static inline void FromTpmUint16(const uint8_t *buffer, uint16_t *x) {
+  *x = (buffer[0] << 8) | buffer[1];
+}
+
+#endif  /* TPM_LITE_TLCL_INTERNAL_H_ */



More information about the coreboot-gerrit mailing list