[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