All of lore.kernel.org
 help / color / mirror / Atom feed
* [VTPM v7 1/8] add vtpm-stubdom code
@ 2012-12-06 18:19 Matthew Fioravante
  2012-12-06 18:19 ` [VTPM v7 2/8] add stubdom/vtpmmgr code Matthew Fioravante
                   ` (7 more replies)
  0 siblings, 8 replies; 14+ messages in thread
From: Matthew Fioravante @ 2012-12-06 18:19 UTC (permalink / raw)
  To: xen-devel, Ian.Jackson, Ian.Campbell; +Cc: Matthew Fioravante

Add the code base for vtpm-stubdom to the stubdom
heirarchy. Makefile changes in later patch.

Signed-off-by: Matthew Fioravante <matthew.fioravante@jhuapl.edu>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 stubdom/vtpm/Makefile    |   37 +++++
 stubdom/vtpm/minios.cfg  |   14 ++
 stubdom/vtpm/vtpm.c      |  404 ++++++++++++++++++++++++++++++++++++++++++++++
 stubdom/vtpm/vtpm.h      |   36 +++++
 stubdom/vtpm/vtpm_cmd.c  |  256 +++++++++++++++++++++++++++++
 stubdom/vtpm/vtpm_cmd.h  |   31 ++++
 stubdom/vtpm/vtpm_pcrs.c |   43 +++++
 stubdom/vtpm/vtpm_pcrs.h |   53 ++++++
 stubdom/vtpm/vtpmblk.c   |  307 +++++++++++++++++++++++++++++++++++
 stubdom/vtpm/vtpmblk.h   |   31 ++++
 10 files changed, 1212 insertions(+)
 create mode 100644 stubdom/vtpm/Makefile
 create mode 100644 stubdom/vtpm/minios.cfg
 create mode 100644 stubdom/vtpm/vtpm.c
 create mode 100644 stubdom/vtpm/vtpm.h
 create mode 100644 stubdom/vtpm/vtpm_cmd.c
 create mode 100644 stubdom/vtpm/vtpm_cmd.h
 create mode 100644 stubdom/vtpm/vtpm_pcrs.c
 create mode 100644 stubdom/vtpm/vtpm_pcrs.h
 create mode 100644 stubdom/vtpm/vtpmblk.c
 create mode 100644 stubdom/vtpm/vtpmblk.h

diff --git a/stubdom/vtpm/Makefile b/stubdom/vtpm/Makefile
new file mode 100644
index 0000000..686c0ea
--- /dev/null
+++ b/stubdom/vtpm/Makefile
@@ -0,0 +1,37 @@
+# Copyright (c) 2010-2012 United States Government, as represented by
+# the Secretary of Defense.  All rights reserved.
+#
+# THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
+# ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
+# INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
+# FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
+# DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
+# SOFTWARE.
+#
+
+XEN_ROOT=../..
+
+PSSL_DIR=../polarssl-$(XEN_TARGET_ARCH)/library
+PSSL_OBJS=aes.o sha1.o entropy.o ctr_drbg.o sha4.o
+
+TARGET=vtpm.a
+OBJS=vtpm.o vtpm_cmd.o vtpmblk.o vtpm_pcrs.o
+
+
+CPPFLAGS+=-I../tpm_emulator-$(XEN_TARGET_ARCH)/build
+CPPFLAGS+=-I../tpm_emulator-$(XEN_TARGET_ARCH)/tpm
+CPPFLAGS+=-I../tpm_emulator-$(XEN_TARGET_ARCH)/crypto
+CPPFLAGS+=-I../tpm_emulator-$(XEN_TARGET_ARCH)
+
+$(TARGET): $(OBJS)
+	ar -cr $@ $(OBJS) $(TPMEMU_OBJS) $(foreach obj,$(PSSL_OBJS),$(PSSL_DIR)/$(obj))
+
+$(OBJS): vtpm_manager.h
+
+vtpm_manager.h:
+	ln -s ../vtpmmgr/vtpm_manager.h vtpm_manager.h
+
+clean:
+	-rm $(TARGET) $(OBJS) vtpm_manager.h
+
+.PHONY: clean
diff --git a/stubdom/vtpm/minios.cfg b/stubdom/vtpm/minios.cfg
new file mode 100644
index 0000000..31652ee
--- /dev/null
+++ b/stubdom/vtpm/minios.cfg
@@ -0,0 +1,14 @@
+CONFIG_TPMFRONT=y
+CONFIG_TPM_TIS=n
+CONFIG_TPMBACK=y
+CONFIG_START_NETWORK=n
+CONFIG_TEST=n
+CONFIG_PCIFRONT=n
+CONFIG_BLKFRONT=y
+CONFIG_NETFRONT=n
+CONFIG_FBFRONT=n
+CONFIG_KBDFRONT=n
+CONFIG_CONSFRONT=n
+CONFIG_XENBUS=y
+CONFIG_LWIP=n
+CONFIG_XC=n
diff --git a/stubdom/vtpm/vtpm.c b/stubdom/vtpm/vtpm.c
new file mode 100644
index 0000000..71aef78
--- /dev/null
+++ b/stubdom/vtpm/vtpm.c
@@ -0,0 +1,404 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense.  All rights reserved.
+ *
+ * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
+ * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
+ * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
+ * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
+ * SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <syslog.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <xen/xen.h>
+#include <tpmback.h>
+#include <tpmfront.h>
+
+#include <polarssl/entropy.h>
+#include <polarssl/ctr_drbg.h>
+
+#include "tpm/tpm_emulator_extern.h"
+#include "tpm/tpm_marshalling.h"
+#include "vtpm.h"
+#include "vtpm_cmd.h"
+#include "vtpm_pcrs.h"
+#include "vtpmblk.h"
+
+#define TPM_LOG_INFO LOG_INFO
+#define TPM_LOG_ERROR LOG_ERR
+#define TPM_LOG_DEBUG LOG_DEBUG
+
+/* Global commandline options - default values */
+struct Opt_args opt_args = {
+   .startup = ST_CLEAR,
+   .loglevel = TPM_LOG_INFO,
+   .hwinitpcrs = VTPM_PCRNONE,
+   .tpmconf = 0,
+   .enable_maint_cmds = false,
+};
+
+static uint32_t badords[32];
+static unsigned int n_badords = 0;
+
+entropy_context entropy;
+ctr_drbg_context ctr_drbg;
+
+struct tpmfront_dev* tpmfront_dev;
+
+void vtpm_get_extern_random_bytes(void *buf, size_t nbytes)
+{
+   ctr_drbg_random(&ctr_drbg, buf, nbytes);
+}
+
+int vtpm_read_from_file(uint8_t **data, size_t *data_length) {
+   return read_vtpmblk(tpmfront_dev, data, data_length);
+}
+
+int vtpm_write_to_file(uint8_t *data, size_t data_length) {
+   return write_vtpmblk(tpmfront_dev, data, data_length);
+}
+
+int vtpm_extern_init_fake(void) {
+   return 0;
+}
+
+void vtpm_extern_release_fake(void) {
+}
+
+
+void vtpm_log(int priority, const char *fmt, ...)
+{
+   if(opt_args.loglevel >= priority) {
+      va_list v;
+      va_start(v, fmt);
+      vprintf(fmt, v);
+      va_end(v);
+   }
+}
+
+static uint64_t vtpm_get_ticks(void)
+{
+  static uint64_t old_t = 0;
+  uint64_t new_t, res_t;
+  struct timeval tv;
+  gettimeofday(&tv, NULL);
+  new_t = (uint64_t)tv.tv_sec * 1000000 + (uint64_t)tv.tv_usec;
+  res_t = (old_t > 0) ? new_t - old_t : 0;
+  old_t = new_t;
+  return res_t;
+}
+
+
+static int tpm_entropy_source(void* dummy, unsigned char* data, size_t len, size_t* olen) {
+   UINT32 sz = len;
+   TPM_RESULT rc = VTPM_GetRandom(tpmfront_dev, data, &sz);
+   *olen = sz;
+   return rc == TPM_SUCCESS ? 0 : POLARSSL_ERR_ENTROPY_SOURCE_FAILED;
+}
+
+int init_random(void) {
+   /* Initialize the rng */
+   entropy_init(&entropy);
+   entropy_add_source(&entropy, tpm_entropy_source, NULL, 0);
+   entropy_gather(&entropy);
+   ctr_drbg_init(&ctr_drbg, entropy_func, &entropy, NULL, 0);
+   ctr_drbg_set_prediction_resistance( &ctr_drbg, CTR_DRBG_PR_OFF );
+
+   return 0;
+}
+
+int check_ordinal(tpmcmd_t* tpmcmd) {
+   TPM_COMMAND_CODE ord;
+   UINT32 len = 4;
+   BYTE* ptr;
+   unsigned int i;
+
+   if(tpmcmd->req_len < 10) {
+      return true;
+   }
+
+   ptr = tpmcmd->req + 6;
+   tpm_unmarshal_UINT32(&ptr, &len, &ord);
+
+   for(i = 0; i < n_badords; ++i) {
+      if(ord == badords[i]) {
+         error("Disabled command ordinal (%" PRIu32") requested!\n");
+         return false;
+      }
+   }
+   return true;
+}
+
+static void main_loop(void) {
+   tpmcmd_t* tpmcmd = NULL;
+   domid_t domid;		/* Domid of frontend */
+   unsigned int handle;	/* handle of frontend */
+   int res = -1;
+
+   info("VTPM Initializing\n");
+
+   /* Set required tpm config args */
+   opt_args.tpmconf |= TPM_CONF_STRONG_PERSISTENCE;
+   opt_args.tpmconf &= ~TPM_CONF_USE_INTERNAL_PRNG;
+   opt_args.tpmconf |= TPM_CONF_GENERATE_EK;
+   opt_args.tpmconf |= TPM_CONF_GENERATE_SEED_DAA;
+
+   /* Initialize the emulator */
+   tpm_emulator_init(opt_args.startup, opt_args.tpmconf);
+
+   /* Initialize any requested PCRs with hardware TPM values */
+   if(vtpm_initialize_hw_pcrs(tpmfront_dev, opt_args.hwinitpcrs) != TPM_SUCCESS) {
+      error("Failed to initialize PCRs with hardware TPM values");
+      goto abort_postpcrs;
+   }
+
+   /* Wait for the frontend domain to connect */
+   info("Waiting for frontend domain to connect..");
+   if(tpmback_wait_for_frontend_connect(&domid, &handle) == 0) {
+      info("VTPM attached to Frontend %u/%u", (unsigned int) domid, handle);
+   } else {
+      error("Unable to attach to a frontend");
+   }
+
+   tpmcmd = tpmback_req(domid, handle);
+   while(tpmcmd) {
+      /* Handle the request */
+      if(tpmcmd->req_len) {
+	 tpmcmd->resp = NULL;
+	 tpmcmd->resp_len = 0;
+
+         /* First check for disabled ordinals */
+         if(!check_ordinal(tpmcmd)) {
+            create_error_response(tpmcmd, TPM_BAD_ORDINAL);
+         }
+         /* If not disabled, do the command */
+         else {
+            if((res = tpm_handle_command(tpmcmd->req, tpmcmd->req_len, &tpmcmd->resp, &tpmcmd->resp_len)) != 0) {
+               error("tpm_handle_command() failed");
+               create_error_response(tpmcmd, TPM_FAIL);
+            }
+         }
+      }
+
+      /* Send the response */
+      tpmback_resp(tpmcmd);
+
+      /* Wait for the next request */
+      tpmcmd = tpmback_req(domid, handle);
+
+   }
+
+abort_postpcrs:
+   info("VTPM Shutting down\n");
+
+   tpm_emulator_shutdown();
+}
+
+int parse_cmd_line(int argc, char** argv)
+{
+   char sval[25];
+   char* logstr = NULL;
+   /* Parse the command strings */
+   for(unsigned int i = 1; i < argc; ++i) {
+      if (sscanf(argv[i], "loglevel=%25s", sval) == 1){
+	 if (!strcmp(sval, "debug")) {
+	    opt_args.loglevel = TPM_LOG_DEBUG;
+	    logstr = "debug";
+	 }
+	 else if (!strcmp(sval, "info")) {
+	    logstr = "info";
+	    opt_args.loglevel = TPM_LOG_INFO;
+	 }
+	 else if (!strcmp(sval, "error")) {
+	    logstr = "error";
+	    opt_args.loglevel = TPM_LOG_ERROR;
+	 }
+      }
+      else if (!strcmp(argv[i], "clear")) {
+	 opt_args.startup = ST_CLEAR;
+      }
+      else if (!strcmp(argv[i], "save")) {
+	 opt_args.startup = ST_SAVE;
+      }
+      else if (!strcmp(argv[i], "deactivated")) {
+	 opt_args.startup = ST_DEACTIVATED;
+      }
+      else if (!strncmp(argv[i], "maintcmds=", 10)) {
+         if(!strcmp(argv[i] + 10, "1")) {
+            opt_args.enable_maint_cmds = true;
+         } else if(!strcmp(argv[i] + 10, "0")) {
+            opt_args.enable_maint_cmds = false;
+         }
+      }
+      else if(!strncmp(argv[i], "hwinitpcr=", 10)) {
+         char *pch = argv[i] + 10;
+         unsigned int v1, v2;
+         pch = strtok(pch, ",");
+         while(pch != NULL) {
+            if(!strcmp(pch, "all")) {
+               //Set all
+               opt_args.hwinitpcrs = VTPM_PCRALL;
+            } else if(!strcmp(pch, "none")) {
+               //Set none
+               opt_args.hwinitpcrs = VTPM_PCRNONE;
+            } else if(sscanf(pch, "%u", &v1) == 1) {
+               //Set one
+               if(v1 >= TPM_NUM_PCR) {
+                  error("hwinitpcr error: Invalid PCR index %u", v1);
+                  return -1;
+               }
+               opt_args.hwinitpcrs |= (1 << v1);
+            } else if(sscanf(pch, "%u-%u", &v1, &v2) == 2) {
+               //Set range
+               if(v1 >= TPM_NUM_PCR) {
+                  error("hwinitpcr error: Invalid PCR index %u", v1);
+                  return -1;
+               }
+               if(v2 >= TPM_NUM_PCR) {
+                  error("hwinitpcr error: Invalid PCR index %u", v1);
+                  return -1;
+               }
+               if(v2 < v1) {
+                  unsigned tp = v1;
+                  v1 = v2;
+                  v2 = tp;
+               }
+               for(unsigned int i = v1; i <= v2; ++i) {
+                  opt_args.hwinitpcrs |= (1 << i);
+               }
+            } else {
+               error("hwintipcr error: Invalid PCR specification : %s", pch);
+               return -1;
+            }
+            pch = strtok(NULL, ",");
+         }
+      }
+      else {
+	 error("Invalid command line option `%s'", argv[i]);
+      }
+
+   }
+
+   /* Check Errors and print results */
+   switch(opt_args.startup) {
+      case ST_CLEAR:
+	 info("Startup mode is `clear'");
+	 break;
+      case ST_SAVE:
+	 info("Startup mode is `save'");
+	 break;
+      case ST_DEACTIVATED:
+	 info("Startup mode is `deactivated'");
+	 break;
+      default:
+	 error("Invalid startup mode %d", opt_args.startup);
+	 return -1;
+   }
+
+   if(opt_args.hwinitpcrs & (VTPM_PCRALL))
+   {
+      char pcrstr[1024];
+      char* ptr = pcrstr;
+
+      pcrstr[0] = '\0';
+      info("The following PCRs will be initialized with values from the hardware TPM:");
+      for(unsigned int i = 0; i < TPM_NUM_PCR; ++i) {
+         if(opt_args.hwinitpcrs & (1 << i)) {
+            ptr += sprintf(ptr, "%u, ", i);
+         }
+      }
+      /* get rid of the last comma if any numbers were printed */
+      *(ptr -2) = '\0';
+
+      info("\t%s", pcrstr);
+   } else {
+      info("All PCRs initialized to default values");
+   }
+
+   if(!opt_args.enable_maint_cmds) {
+      info("TPM Maintenance Commands disabled");
+      badords[n_badords++] = TPM_ORD_CreateMaintenanceArchive;
+      badords[n_badords++] = TPM_ORD_LoadMaintenanceArchive;
+      badords[n_badords++] = TPM_ORD_KillMaintenanceFeature;
+      badords[n_badords++] = TPM_ORD_LoadManuMaintPub;
+      badords[n_badords++] = TPM_ORD_ReadManuMaintPub;
+   } else {
+      info("TPM Maintenance Commands enabled");
+   }
+
+   info("Log level set to %s", logstr);
+
+   return 0;
+}
+
+void cleanup_opt_args(void) {
+}
+
+int main(int argc, char **argv)
+{
+   //FIXME: initializing blkfront without this sleep causes the domain to crash on boot
+   sleep(2);
+
+   /* Setup extern function pointers */
+   tpm_extern_init = vtpm_extern_init_fake;
+   tpm_extern_release = vtpm_extern_release_fake;
+   tpm_malloc = malloc;
+   tpm_free = free;
+   tpm_log = vtpm_log;
+   tpm_get_ticks = vtpm_get_ticks;
+   tpm_get_extern_random_bytes = vtpm_get_extern_random_bytes;
+   tpm_write_to_storage = vtpm_write_to_file;
+   tpm_read_from_storage = vtpm_read_from_file;
+
+   info("starting TPM Emulator (1.2.%d.%d-%d)", VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD);
+   if(parse_cmd_line(argc, argv)) {
+      error("Error parsing commandline\n");
+      return -1;
+   }
+
+   /* Initialize devices */
+   init_tpmback();
+   if((tpmfront_dev = init_tpmfront(NULL)) == NULL) {
+      error("Unable to initialize tpmfront device");
+      goto abort_posttpmfront;
+   }
+
+   /* Seed the RNG with entropy from hardware TPM */
+   if(init_random()) {
+      error("Unable to initialize RNG");
+      goto abort_postrng;
+   }
+
+   /* Initialize blkfront device */
+   if(init_vtpmblk(tpmfront_dev)) {
+      error("Unable to initialize Blkfront persistent storage");
+      goto abort_postvtpmblk;
+   }
+
+   /* Run main loop */
+   main_loop();
+
+   /* Shutdown blkfront */
+   shutdown_vtpmblk();
+abort_postvtpmblk:
+abort_postrng:
+
+   /* Close devices */
+   shutdown_tpmfront(tpmfront_dev);
+abort_posttpmfront:
+   shutdown_tpmback();
+
+   cleanup_opt_args();
+
+   return 0;
+}
diff --git a/stubdom/vtpm/vtpm.h b/stubdom/vtpm/vtpm.h
new file mode 100644
index 0000000..5919e44
--- /dev/null
+++ b/stubdom/vtpm/vtpm.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense.  All rights reserved.
+ *
+ * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
+ * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
+ * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
+ * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
+ * SOFTWARE.
+ */
+
+#ifndef VTPM_H
+#define VTPM_H
+
+#include <stdbool.h>
+
+/* For testing */
+#define VERS_CMD "\x00\xC1\x00\x00\x00\x16\x00\x00\x00\x65\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x01\x03"
+#define VERS_CMD_LEN 22
+
+/* Global commandline options */
+struct Opt_args {
+   enum StartUp {
+      ST_CLEAR = 1,
+      ST_SAVE = 2,
+      ST_DEACTIVATED = 3
+   } startup;
+   unsigned long hwinitpcrs;
+   int loglevel;
+   uint32_t tpmconf;
+   bool enable_maint_cmds;
+};
+extern struct Opt_args opt_args;
+
+#endif
diff --git a/stubdom/vtpm/vtpm_cmd.c b/stubdom/vtpm/vtpm_cmd.c
new file mode 100644
index 0000000..7eae98b
--- /dev/null
+++ b/stubdom/vtpm/vtpm_cmd.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense.  All rights reserved.
+ *
+ * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
+ * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
+ * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
+ * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
+ * SOFTWARE.
+ */
+
+#include <types.h>
+#include <xen/xen.h>
+#include <mm.h>
+#include <gnttab.h>
+#include "tpm/tpm_marshalling.h"
+#include "vtpm_manager.h"
+#include "vtpm_cmd.h"
+#include <tpmback.h>
+
+#define TRYFAILGOTO(C) \
+   if((C)) { \
+      status = TPM_FAIL; \
+      goto abort_egress; \
+   }
+#define TRYFAILGOTOMSG(C, msg) \
+   if((C)) { \
+      status = TPM_FAIL; \
+      error(msg); \
+      goto abort_egress; \
+   }
+#define CHECKSTATUSGOTO(ret, fname) \
+   if((ret) != TPM_SUCCESS) { \
+      error("%s failed with error code (%lu)", fname, (unsigned long) ret); \
+      status = ord; \
+      goto abort_egress; \
+   }
+
+#define ERR_MALFORMED "Malformed response from backend"
+#define ERR_TPMFRONT "Error sending command through frontend device"
+
+struct shpage {
+   void* page;
+   grant_ref_t grantref;
+};
+
+typedef struct shpage shpage_t;
+
+static inline int pack_header(uint8_t** bptr, UINT32* len, TPM_TAG tag, UINT32 size, TPM_COMMAND_CODE ord)
+{
+   return *bptr == NULL ||
+	 tpm_marshal_UINT16(bptr, len, tag) ||
+	 tpm_marshal_UINT32(bptr, len, size) ||
+	 tpm_marshal_UINT32(bptr, len, ord);
+}
+
+static inline int unpack_header(uint8_t** bptr, UINT32* len, TPM_TAG* tag, UINT32* size, TPM_COMMAND_CODE* ord)
+{
+   return *bptr == NULL ||
+	 tpm_unmarshal_UINT16(bptr, len, tag) ||
+	 tpm_unmarshal_UINT32(bptr, len, size) ||
+	 tpm_unmarshal_UINT32(bptr, len, ord);
+}
+
+int create_error_response(tpmcmd_t* tpmcmd, TPM_RESULT errorcode)
+{
+   TPM_TAG tag;
+   UINT32 len = tpmcmd->req_len;
+   uint8_t* respptr;
+   uint8_t* cmdptr = tpmcmd->req;
+
+   if(!tpm_unmarshal_UINT16(&cmdptr, &len, &tag)) {
+      switch (tag) {
+         case TPM_TAG_RQU_COMMAND:
+            tag = TPM_TAG_RSP_COMMAND;
+            break;
+         case TPM_TAG_RQU_AUTH1_COMMAND:
+            tag = TPM_TAG_RQU_AUTH2_COMMAND;
+            break;
+         case TPM_TAG_RQU_AUTH2_COMMAND:
+            tag = TPM_TAG_RQU_AUTH2_COMMAND;
+            break;
+      }
+   } else {
+      tag = TPM_TAG_RSP_COMMAND;
+   }
+
+   tpmcmd->resp_len = len = 10;
+   tpmcmd->resp = respptr = tpm_malloc(tpmcmd->resp_len);
+
+   return pack_header(&respptr, &len, tag, len, errorcode);
+}
+
+TPM_RESULT VTPM_GetRandom(struct tpmfront_dev* tpmfront_dev, BYTE* bytes, UINT32 *numbytes) {
+   TPM_RESULT status = TPM_SUCCESS;
+   uint8_t* cmdbuf, *resp, *bptr;
+   size_t resplen = 0;
+   UINT32 len;
+
+   /*Ask the real tpm for random bytes for the seed */
+   TPM_TAG tag = TPM_TAG_RQU_COMMAND;
+   UINT32 size;
+   TPM_COMMAND_CODE ord = TPM_ORD_GetRandom;
+   len = size = sizeof(TPM_TAG) + sizeof(UINT32) + sizeof(TPM_COMMAND_CODE) + sizeof(UINT32);
+
+   /*Create the raw tpm command */
+   bptr = cmdbuf = malloc(size);
+   TRYFAILGOTO(pack_header(&bptr, &len, tag, size, ord));
+   TRYFAILGOTO(tpm_marshal_UINT32(&bptr, &len, *numbytes));
+
+   /* Send cmd, wait for response */
+   TRYFAILGOTOMSG(tpmfront_cmd(tpmfront_dev, cmdbuf, size, &resp, &resplen),
+      ERR_TPMFRONT);
+
+   bptr = resp; len = resplen;
+   TRYFAILGOTOMSG(unpack_header(&bptr, &len, &tag, &size, &ord), ERR_MALFORMED);
+
+   //Check return status of command
+   CHECKSTATUSGOTO(ord, "TPM_GetRandom()");
+
+   // Get the number of random bytes in the response
+   TRYFAILGOTOMSG(tpm_unmarshal_UINT32(&bptr, &len, &size), ERR_MALFORMED);
+   *numbytes = size;
+
+   //Get the random bytes out, tpm may give us less bytes than what we wanrt
+   TRYFAILGOTOMSG(tpm_unmarshal_BYTE_ARRAY(&bptr, &len, bytes, *numbytes), ERR_MALFORMED);
+
+   goto egress;
+abort_egress:
+egress:
+   free(cmdbuf);
+   return status;
+
+}
+
+TPM_RESULT VTPM_LoadHashKey(struct tpmfront_dev* tpmfront_dev, uint8_t** data, size_t* data_length)
+{
+   TPM_RESULT status = TPM_SUCCESS;
+   uint8_t* bptr, *resp;
+   uint8_t* cmdbuf = NULL;
+   size_t resplen = 0;
+   UINT32 len;
+
+   TPM_TAG tag = VTPM_TAG_REQ;
+   UINT32 size;
+   TPM_COMMAND_CODE ord = VTPM_ORD_LOADHASHKEY;
+
+   /*Create the command*/
+   len = size = VTPM_COMMAND_HEADER_SIZE;
+   bptr = cmdbuf = malloc(size);
+   TRYFAILGOTO(pack_header(&bptr, &len, tag, size, ord));
+
+   /* Send the command to vtpm_manager */
+   info("Requesting Encryption key from backend");
+   TRYFAILGOTOMSG(tpmfront_cmd(tpmfront_dev, cmdbuf, size, &resp, &resplen), ERR_TPMFRONT);
+
+   /* Unpack response header */
+   bptr = resp;
+   len = resplen;
+   TRYFAILGOTOMSG(unpack_header(&bptr, &len, &tag, &size, &ord), ERR_MALFORMED);
+
+   /* Check return code */
+   CHECKSTATUSGOTO(ord, "VTPM_LoadHashKey()");
+
+   /* Get the size of the key */
+   *data_length = size - VTPM_COMMAND_HEADER_SIZE;
+
+   /* Copy the key bits */
+   *data = malloc(*data_length);
+   memcpy(*data, bptr, *data_length);
+
+   goto egress;
+abort_egress:
+   error("VTPM_LoadHashKey failed");
+egress:
+   free(cmdbuf);
+   return status;
+}
+
+TPM_RESULT VTPM_SaveHashKey(struct tpmfront_dev* tpmfront_dev, uint8_t* data, size_t data_length)
+{
+   TPM_RESULT status = TPM_SUCCESS;
+   uint8_t* bptr, *resp;
+   uint8_t* cmdbuf = NULL;
+   size_t resplen = 0;
+   UINT32 len;
+
+   TPM_TAG tag = VTPM_TAG_REQ;
+   UINT32 size;
+   TPM_COMMAND_CODE ord = VTPM_ORD_SAVEHASHKEY;
+
+   /*Create the command*/
+   len = size = VTPM_COMMAND_HEADER_SIZE + data_length;
+   bptr = cmdbuf = malloc(size);
+   TRYFAILGOTO(pack_header(&bptr, &len, tag, size, ord));
+   memcpy(bptr, data, data_length);
+   bptr += data_length;
+
+   /* Send the command to vtpm_manager */
+   info("Sending encryption key to backend");
+   TRYFAILGOTOMSG(tpmfront_cmd(tpmfront_dev, cmdbuf, size, &resp, &resplen), ERR_TPMFRONT);
+
+   /* Unpack response header */
+   bptr = resp;
+   len = resplen;
+   TRYFAILGOTOMSG(unpack_header(&bptr, &len, &tag, &size, &ord), ERR_MALFORMED);
+
+   /* Check return code */
+   CHECKSTATUSGOTO(ord, "VTPM_SaveHashKey()");
+
+   goto egress;
+abort_egress:
+   error("VTPM_SaveHashKey failed");
+egress:
+   free(cmdbuf);
+   return status;
+}
+
+TPM_RESULT VTPM_PCRRead(struct tpmfront_dev* tpmfront_dev, UINT32 pcrIndex, BYTE* outDigest)
+{
+   TPM_RESULT status = TPM_SUCCESS;
+   uint8_t *cmdbuf, *resp, *bptr;
+   size_t resplen = 0;
+   UINT32 len;
+
+   /*Just send a TPM_PCRRead Command to the HW tpm */
+   TPM_TAG tag = TPM_TAG_RQU_COMMAND;
+   UINT32 size;
+   TPM_COMMAND_CODE ord = TPM_ORD_PCRRead;
+   len = size = sizeof(TPM_TAG) + sizeof(UINT32) + sizeof(TPM_COMMAND_CODE) + sizeof(UINT32);
+
+   /*Create the raw tpm cmd */
+   bptr = cmdbuf = malloc(size);
+   TRYFAILGOTO(pack_header(&bptr, &len, tag, size, ord));
+   TRYFAILGOTO(tpm_marshal_UINT32(&bptr, &len, pcrIndex));
+
+   /*Send Cmd wait for response */
+   TRYFAILGOTOMSG(tpmfront_cmd(tpmfront_dev, cmdbuf, size, &resp, &resplen), ERR_TPMFRONT);
+
+   bptr = resp; len = resplen;
+   TRYFAILGOTOMSG(unpack_header(&bptr, &len, &tag, &size, &ord), ERR_MALFORMED);
+
+   //Check return status of command
+   CHECKSTATUSGOTO(ord, "TPM_PCRRead");
+
+   //Get the ptr value
+   memcpy(outDigest, bptr, sizeof(TPM_PCRVALUE));
+
+   goto egress;
+abort_egress:
+egress:
+   free(cmdbuf);
+   return status;
+
+}
diff --git a/stubdom/vtpm/vtpm_cmd.h b/stubdom/vtpm/vtpm_cmd.h
new file mode 100644
index 0000000..b0bfa22
--- /dev/null
+++ b/stubdom/vtpm/vtpm_cmd.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense.  All rights reserved.
+ *
+ * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
+ * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
+ * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
+ * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
+ * SOFTWARE.
+ */
+
+#ifndef MANAGER_H
+#define MANAGER_H
+
+#include <tpmfront.h>
+#include <tpmback.h>
+#include "tpm/tpm_structures.h"
+
+/* Create a command response error header */
+int create_error_response(tpmcmd_t* tpmcmd, TPM_RESULT errorcode);
+/* Request random bytes from hardware tpm, returns 0 on success */
+TPM_RESULT VTPM_GetRandom(struct tpmfront_dev* tpmfront_dev, BYTE* bytes, UINT32* numbytes);
+/* Retreive 256 bit AES encryption key from manager */
+TPM_RESULT VTPM_LoadHashKey(struct tpmfront_dev* tpmfront_dev, uint8_t** data, size_t* data_length);
+/* Manager securely saves our 256 bit AES encryption key */
+TPM_RESULT VTPM_SaveHashKey(struct tpmfront_dev* tpmfront_dev, uint8_t* data, size_t data_length);
+/* Send a TPM_PCRRead command passthrough the manager to the hw tpm */
+TPM_RESULT VTPM_PCRRead(struct tpmfront_dev* tpmfront_dev, UINT32 pcrIndex, BYTE* outDigest);
+
+#endif
diff --git a/stubdom/vtpm/vtpm_pcrs.c b/stubdom/vtpm/vtpm_pcrs.c
new file mode 100644
index 0000000..22a6cef
--- /dev/null
+++ b/stubdom/vtpm/vtpm_pcrs.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense.  All rights reserved.
+ *
+ * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
+ * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
+ * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
+ * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
+ * SOFTWARE.
+ */
+
+#include "vtpm_pcrs.h"
+#include "vtpm_cmd.h"
+#include "tpm/tpm_data.h"
+
+#define PCR_VALUE      tpmData.permanent.data.pcrValue
+
+static int write_pcr_direct(unsigned int pcrIndex, uint8_t* val) {
+   if(pcrIndex > TPM_NUM_PCR) {
+      return TPM_BADINDEX;
+   }
+   memcpy(&PCR_VALUE[pcrIndex], val, sizeof(TPM_PCRVALUE));
+   return TPM_SUCCESS;
+}
+
+TPM_RESULT vtpm_initialize_hw_pcrs(struct tpmfront_dev* tpmfront_dev, unsigned long pcrs)
+{
+   TPM_RESULT rc = TPM_SUCCESS;
+   uint8_t digest[sizeof(TPM_PCRVALUE)];
+
+   for(unsigned int i = 0; i < TPM_NUM_PCR; ++i) {
+      if(pcrs & 1 << i) {
+         if((rc = VTPM_PCRRead(tpmfront_dev, i, digest)) != TPM_SUCCESS) {
+            error("TPM_PCRRead failed with error : %d", rc);
+            return rc;
+         }
+         write_pcr_direct(i, digest);
+      }
+   }
+
+   return rc;
+}
diff --git a/stubdom/vtpm/vtpm_pcrs.h b/stubdom/vtpm/vtpm_pcrs.h
new file mode 100644
index 0000000..11835f9
--- /dev/null
+++ b/stubdom/vtpm/vtpm_pcrs.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense.  All rights reserved.
+ *
+ * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
+ * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
+ * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
+ * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
+ * SOFTWARE.
+ */
+
+#ifndef VTPM_PCRS_H
+#define VTPM_PCRS_H
+
+#include "tpm/tpm_structures.h"
+
+#define VTPM_PCR0 1
+#define VTPM_PCR1 1 << 1
+#define VTPM_PCR2 1 << 2
+#define VTPM_PCR3 1 << 3
+#define VTPM_PCR4 1 << 4
+#define VTPM_PCR5 1 << 5
+#define VTPM_PCR6 1 << 6
+#define VTPM_PCR7 1 << 7
+#define VTPM_PCR8 1 << 8
+#define VTPM_PCR9 1 << 9
+#define VTPM_PCR10 1 << 10
+#define VTPM_PCR11 1 << 11
+#define VTPM_PCR12 1 << 12
+#define VTPM_PCR13 1 << 13
+#define VTPM_PCR14 1 << 14
+#define VTPM_PCR15 1 << 15
+#define VTPM_PCR16 1 << 16
+#define VTPM_PCR17 1 << 17
+#define VTPM_PCR18 1 << 18
+#define VTPM_PCR19 1 << 19
+#define VTPM_PCR20 1 << 20
+#define VTPM_PCR21 1 << 21
+#define VTPM_PCR22 1 << 22
+#define VTPM_PCR23 1 << 23
+
+#define VTPM_PCRALL (1 << TPM_NUM_PCR) - 1
+#define VTPM_PCRNONE 0
+
+#define VTPM_NUMPCRS 24
+
+struct tpmfront_dev;
+
+TPM_RESULT vtpm_initialize_hw_pcrs(struct tpmfront_dev* tpmfront_dev, unsigned long pcrs);
+
+
+#endif
diff --git a/stubdom/vtpm/vtpmblk.c b/stubdom/vtpm/vtpmblk.c
new file mode 100644
index 0000000..b343bd8
--- /dev/null
+++ b/stubdom/vtpm/vtpmblk.c
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense.  All rights reserved.
+ *
+ * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
+ * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
+ * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
+ * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
+ * SOFTWARE.
+ */
+
+#include <mini-os/byteorder.h>
+#include "vtpmblk.h"
+#include "tpm/tpm_marshalling.h"
+#include "vtpm_cmd.h"
+#include "polarssl/aes.h"
+#include "polarssl/sha1.h"
+#include <blkfront.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+
+/*Encryption key and block sizes */
+#define BLKSZ 16
+
+static struct blkfront_dev* blkdev = NULL;
+static int blkfront_fd = -1;
+
+int init_vtpmblk(struct tpmfront_dev* tpmfront_dev)
+{
+   struct blkfront_info blkinfo;
+   info("Initializing persistent NVM storage\n");
+
+   if((blkdev = init_blkfront(NULL, &blkinfo)) == NULL) {
+      error("BLKIO: ERROR Unable to initialize blkfront");
+      return -1;
+   }
+   if (blkinfo.info & VDISK_READONLY || blkinfo.mode != O_RDWR) {
+      error("BLKIO: ERROR block device is read only!");
+      goto error;
+   }
+   if((blkfront_fd = blkfront_open(blkdev)) == -1) {
+      error("Unable to open blkfront file descriptor!");
+      goto error;
+   }
+
+   return 0;
+error:
+   shutdown_blkfront(blkdev);
+   blkdev = NULL;
+   return -1;
+}
+
+void shutdown_vtpmblk(void)
+{
+   close(blkfront_fd);
+   blkfront_fd = -1;
+   blkdev = NULL;
+}
+
+int write_vtpmblk_raw(uint8_t *data, size_t data_length)
+{
+   int rc;
+   uint32_t lenbuf;
+   debug("Begin Write data=%p len=%u", data, data_length);
+
+   lenbuf = cpu_to_be32((uint32_t)data_length);
+
+   lseek(blkfront_fd, 0, SEEK_SET);
+   if((rc = write(blkfront_fd, (uint8_t*)&lenbuf, 4)) != 4) {
+      error("write(length) failed! error was %s", strerror(errno));
+      return -1;
+   }
+   if((rc = write(blkfront_fd, data, data_length)) != data_length) {
+      error("write(data) failed! error was %s", strerror(errno));
+      return -1;
+   }
+
+   info("Wrote %u bytes to NVM persistent storage", data_length);
+
+   return 0;
+}
+
+int read_vtpmblk_raw(uint8_t **data, size_t *data_length)
+{
+   int rc;
+   uint32_t lenbuf;
+
+   lseek(blkfront_fd, 0, SEEK_SET);
+   if(( rc = read(blkfront_fd, (uint8_t*)&lenbuf, 4)) != 4) {
+      error("read(length) failed! error was %s", strerror(errno));
+      return -1;
+   }
+   *data_length = (size_t) cpu_to_be32(lenbuf);
+   if(*data_length == 0) {
+      error("read 0 data_length for NVM");
+      return -1;
+   }
+
+   *data = tpm_malloc(*data_length);
+   if((rc = read(blkfront_fd, *data, *data_length)) != *data_length) {
+      error("read(data) failed! error was %s", strerror(errno));
+      return -1;
+   }
+
+   info("Read %u bytes from NVM persistent storage", *data_length);
+   return 0;
+}
+
+int encrypt_vtpmblk(uint8_t* clear, size_t clear_len, uint8_t** cipher, size_t* cipher_len, uint8_t* symkey)
+{
+   int rc = 0;
+   uint8_t iv[BLKSZ];
+   aes_context aes_ctx;
+   UINT32 temp;
+   int mod;
+
+   uint8_t* clbuf = NULL;
+
+   uint8_t* ivptr;
+   int ivlen;
+
+   uint8_t* cptr;	//Cipher block pointer
+   int clen;	//Cipher block length
+
+   /*Create a new 256 bit encryption key */
+   if(symkey == NULL) {
+      rc = -1;
+      goto abort_egress;
+   }
+   tpm_get_extern_random_bytes(symkey, NVMKEYSZ);
+
+   /*Setup initialization vector - random bits and then 4 bytes clear text size at the end*/
+   temp = sizeof(UINT32);
+   ivlen = BLKSZ - temp;
+   tpm_get_extern_random_bytes(iv, ivlen);
+   ivptr = iv + ivlen;
+   tpm_marshal_UINT32(&ivptr, &temp, (UINT32) clear_len);
+
+   /*The clear text needs to be padded out to a multiple of BLKSZ */
+   mod = clear_len % BLKSZ;
+   clen = mod ? clear_len + BLKSZ - mod : clear_len;
+   clbuf = malloc(clen);
+   if (clbuf == NULL) {
+      rc = -1;
+      goto abort_egress;
+   }
+   memcpy(clbuf, clear, clear_len);
+   /* zero out the padding bits - FIXME: better / more secure way to handle these? */
+   if(clen - clear_len) {
+      memset(clbuf + clear_len, 0, clen - clear_len);
+   }
+
+   /* Setup the ciphertext buffer */
+   *cipher_len = BLKSZ + clen;		/*iv + ciphertext */
+   cptr = *cipher = malloc(*cipher_len);
+   if (*cipher == NULL) {
+      rc = -1;
+      goto abort_egress;
+   }
+
+   /* Copy the IV to cipher text blob*/
+   memcpy(cptr, iv, BLKSZ);
+   cptr += BLKSZ;
+
+   /* Setup encryption */
+   aes_setkey_enc(&aes_ctx, symkey, 256);
+
+   /* Do encryption now */
+   aes_crypt_cbc(&aes_ctx, AES_ENCRYPT, clen, iv, clbuf, cptr);
+
+   goto egress;
+abort_egress:
+egress:
+   free(clbuf);
+   return rc;
+}
+int decrypt_vtpmblk(uint8_t* cipher, size_t cipher_len, uint8_t** clear, size_t* clear_len, uint8_t* symkey)
+{
+   int rc = 0;
+   uint8_t iv[BLKSZ];
+   uint8_t* ivptr;
+   UINT32 u32, temp;
+   aes_context aes_ctx;
+
+   uint8_t* cptr = cipher;	//cipher block pointer
+   int clen = cipher_len;	//cipher block length
+
+   /* Pull out the initialization vector */
+   memcpy(iv, cipher, BLKSZ);
+   cptr += BLKSZ;
+   clen -= BLKSZ;
+
+   /* Setup the clear text buffer */
+   if((*clear = malloc(clen)) == NULL) {
+      rc = -1;
+      goto abort_egress;
+   }
+
+   /* Get the length of clear text from last 4 bytes of iv */
+   temp = sizeof(UINT32);
+   ivptr = iv + BLKSZ - temp;
+   tpm_unmarshal_UINT32(&ivptr, &temp, &u32);
+   *clear_len = u32;
+
+   /* Setup decryption */
+   aes_setkey_dec(&aes_ctx, symkey, 256);
+
+   /* Do decryption now */
+   if ((clen % BLKSZ) != 0) {
+      error("Decryption Error: Cipher block size was not a multiple of %u", BLKSZ);
+      rc = -1;
+      goto abort_egress;
+   }
+   aes_crypt_cbc(&aes_ctx, AES_DECRYPT, clen, iv, cptr, *clear);
+
+   goto egress;
+abort_egress:
+egress:
+   return rc;
+}
+
+int write_vtpmblk(struct tpmfront_dev* tpmfront_dev, uint8_t* data, size_t data_length) {
+   int rc;
+   uint8_t* cipher = NULL;
+   size_t cipher_len = 0;
+   uint8_t hashkey[HASHKEYSZ];
+   uint8_t* symkey = hashkey + HASHSZ;
+
+   /* Encrypt the data */
+   if((rc = encrypt_vtpmblk(data, data_length, &cipher, &cipher_len, symkey))) {
+      goto abort_egress;
+   }
+   /* Write to disk */
+   if((rc = write_vtpmblk_raw(cipher, cipher_len))) {
+      goto abort_egress;
+   }
+   /* Get sha1 hash of data */
+   sha1(cipher, cipher_len, hashkey);
+
+   /* Send hash and key to manager */
+   if((rc = VTPM_SaveHashKey(tpmfront_dev, hashkey, HASHKEYSZ)) != TPM_SUCCESS) {
+      goto abort_egress;
+   }
+   goto egress;
+abort_egress:
+egress:
+   free(cipher);
+   return rc;
+}
+
+int read_vtpmblk(struct tpmfront_dev* tpmfront_dev, uint8_t** data, size_t *data_length) {
+   int rc;
+   uint8_t* cipher = NULL;
+   size_t cipher_len = 0;
+   size_t keysize;
+   uint8_t* hashkey = NULL;
+   uint8_t hash[HASHSZ];
+   uint8_t* symkey;
+
+   /* Retreive the hash and the key from the manager */
+   if((rc = VTPM_LoadHashKey(tpmfront_dev, &hashkey, &keysize)) != TPM_SUCCESS) {
+      goto abort_egress;
+   }
+   if(keysize != HASHKEYSZ) {
+      error("Manager returned a hashkey of invalid size! expected %d, actual %d", NVMKEYSZ, keysize);
+      rc = -1;
+      goto abort_egress;
+   }
+   symkey = hashkey + HASHSZ;
+
+   /* Read from disk now */
+   if((rc = read_vtpmblk_raw(&cipher, &cipher_len))) {
+      goto abort_egress;
+   }
+
+   /* Compute the hash of the cipher text and compare */
+   sha1(cipher, cipher_len, hash);
+   if(memcmp(hash, hashkey, HASHSZ)) {
+      int i;
+      error("NVM Storage Checksum failed!");
+      printf("Expected: ");
+      for(i = 0; i < HASHSZ; ++i) {
+	 printf("%02hhX ", hashkey[i]);
+      }
+      printf("\n");
+      printf("Actual:   ");
+      for(i = 0; i < HASHSZ; ++i) {
+	 printf("%02hhX ", hash[i]);
+      }
+      printf("\n");
+      rc = -1;
+      goto abort_egress;
+   }
+
+   /* Decrypt the blob */
+   if((rc = decrypt_vtpmblk(cipher, cipher_len, data, data_length, symkey))) {
+      goto abort_egress;
+   }
+   goto egress;
+abort_egress:
+egress:
+   free(cipher);
+   free(hashkey);
+   return rc;
+}
diff --git a/stubdom/vtpm/vtpmblk.h b/stubdom/vtpm/vtpmblk.h
new file mode 100644
index 0000000..282ce6a
--- /dev/null
+++ b/stubdom/vtpm/vtpmblk.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense.  All rights reserved.
+ *
+ * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
+ * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
+ * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
+ * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
+ * SOFTWARE.
+ */
+
+#ifndef NVM_H
+#define NVM_H
+#include <mini-os/types.h>
+#include <xen/xen.h>
+#include <tpmfront.h>
+
+#define NVMKEYSZ 32
+#define HASHSZ 20
+#define HASHKEYSZ (NVMKEYSZ + HASHSZ)
+
+int init_vtpmblk(struct tpmfront_dev* tpmfront_dev);
+void shutdown_vtpmblk(void);
+
+/* Encrypts and writes data to blk device */
+int write_vtpmblk(struct tpmfront_dev* tpmfront_dev, uint8_t *data, size_t data_length);
+/* Reads, Decrypts, and returns data from blk device */
+int read_vtpmblk(struct tpmfront_dev* tpmfront_dev, uint8_t **data, size_t *data_length);
+
+#endif
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [VTPM v7 2/8] add stubdom/vtpmmgr code
  2012-12-06 18:19 [VTPM v7 1/8] add vtpm-stubdom code Matthew Fioravante
@ 2012-12-06 18:19 ` Matthew Fioravante
  2012-12-06 18:19 ` [VTPM v7 3/8] vtpm/vtpmmgr and required libs to stubdom/Makefile Matthew Fioravante
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Matthew Fioravante @ 2012-12-06 18:19 UTC (permalink / raw)
  To: xen-devel, Ian.Jackson, Ian.Campbell; +Cc: Matthew Fioravante

Add the code base for vtpmmgrdom. Makefile changes
next patch.

Signed-off-by: Matthew Fioravante <matthew.fioravante@jhuapl.edu>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 stubdom/vtpmmgr/Makefile           |   32 ++
 stubdom/vtpmmgr/init.c             |  553 +++++++++++++++++++++
 stubdom/vtpmmgr/log.c              |  151 ++++++
 stubdom/vtpmmgr/log.h              |   85 ++++
 stubdom/vtpmmgr/marshal.h          |  528 ++++++++++++++++++++
 stubdom/vtpmmgr/minios.cfg         |   14 +
 stubdom/vtpmmgr/tcg.h              |  707 +++++++++++++++++++++++++++
 stubdom/vtpmmgr/tpm.c              |  938 ++++++++++++++++++++++++++++++++++++
 stubdom/vtpmmgr/tpm.h              |  218 +++++++++
 stubdom/vtpmmgr/tpmrsa.c           |  175 +++++++
 stubdom/vtpmmgr/tpmrsa.h           |   67 +++
 stubdom/vtpmmgr/uuid.h             |   50 ++
 stubdom/vtpmmgr/vtpm_cmd_handler.c |  152 ++++++
 stubdom/vtpmmgr/vtpm_manager.h     |   64 +++
 stubdom/vtpmmgr/vtpm_storage.c     |  794 ++++++++++++++++++++++++++++++
 stubdom/vtpmmgr/vtpm_storage.h     |   68 +++
 stubdom/vtpmmgr/vtpmmgr.c          |   93 ++++
 stubdom/vtpmmgr/vtpmmgr.h          |   77 +++
 18 files changed, 4766 insertions(+)
 create mode 100644 stubdom/vtpmmgr/Makefile
 create mode 100644 stubdom/vtpmmgr/init.c
 create mode 100644 stubdom/vtpmmgr/log.c
 create mode 100644 stubdom/vtpmmgr/log.h
 create mode 100644 stubdom/vtpmmgr/marshal.h
 create mode 100644 stubdom/vtpmmgr/minios.cfg
 create mode 100644 stubdom/vtpmmgr/tcg.h
 create mode 100644 stubdom/vtpmmgr/tpm.c
 create mode 100644 stubdom/vtpmmgr/tpm.h
 create mode 100644 stubdom/vtpmmgr/tpmrsa.c
 create mode 100644 stubdom/vtpmmgr/tpmrsa.h
 create mode 100644 stubdom/vtpmmgr/uuid.h
 create mode 100644 stubdom/vtpmmgr/vtpm_cmd_handler.c
 create mode 100644 stubdom/vtpmmgr/vtpm_manager.h
 create mode 100644 stubdom/vtpmmgr/vtpm_storage.c
 create mode 100644 stubdom/vtpmmgr/vtpm_storage.h
 create mode 100644 stubdom/vtpmmgr/vtpmmgr.c
 create mode 100644 stubdom/vtpmmgr/vtpmmgr.h

diff --git a/stubdom/vtpmmgr/Makefile b/stubdom/vtpmmgr/Makefile
new file mode 100644
index 0000000..88c83c3
--- /dev/null
+++ b/stubdom/vtpmmgr/Makefile
@@ -0,0 +1,32 @@
+# Copyright (c) 2010-2012 United States Government, as represented by
+# the Secretary of Defense.  All rights reserved.
+#
+# THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
+# ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
+# INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
+# FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
+# DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
+# SOFTWARE.
+#
+
+XEN_ROOT=../..
+
+PSSL_DIR=../polarssl-$(XEN_TARGET_ARCH)/library
+PSSL_OBJS=aes.o sha1.o entropy.o ctr_drbg.o bignum.o sha4.o havege.o timing.o entropy_poll.o
+
+TARGET=vtpmmgr.a
+OBJS=vtpmmgr.o vtpm_cmd_handler.o vtpm_storage.o init.o tpmrsa.o tpm.o log.o
+
+CFLAGS+=-Werror -Iutil -Icrypto -Itcs
+CFLAGS+=-Wno-declaration-after-statement -Wno-unused-label
+
+build: $(TARGET)
+$(TARGET): $(OBJS)
+	ar -rcs $@ $^ $(foreach obj,$(PSSL_OBJS),$(PSSL_DIR)/$(obj))
+
+clean:
+	rm -f $(TARGET) $(OBJS)
+
+distclean: clean
+
+.PHONY: clean distclean
diff --git a/stubdom/vtpmmgr/init.c b/stubdom/vtpmmgr/init.c
new file mode 100644
index 0000000..a158020
--- /dev/null
+++ b/stubdom/vtpmmgr/init.c
@@ -0,0 +1,553 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense.  All rights reserved.
+ *
+ * based off of the original tools/vtpm_manager code base which is:
+ * Copyright (c) 2005, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <xen/xen.h>
+#include <mini-os/tpmback.h>
+#include <mini-os/tpmfront.h>
+#include <mini-os/tpm_tis.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <polarssl/sha1.h>
+
+#include "log.h"
+#include "vtpmmgr.h"
+#include "vtpm_storage.h"
+#include "tpm.h"
+#include "marshal.h"
+
+struct Opts {
+   enum {
+      TPMDRV_TPM_TIS,
+      TPMDRV_TPMFRONT,
+   } tpmdriver;
+   unsigned long tpmiomem;
+   unsigned int tpmirq;
+   unsigned int tpmlocality;
+   int gen_owner_auth;
+};
+
+// --------------------------- Well Known Auths --------------------------
+const TPM_AUTHDATA WELLKNOWN_SRK_AUTH = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+const TPM_AUTHDATA WELLKNOWN_OWNER_AUTH = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+struct vtpm_globals vtpm_globals = {
+   .tpm_fd = -1,
+   .storage_key = TPM_KEY_INIT,
+   .storage_key_handle = 0,
+   .oiap = { .AuthHandle = 0 }
+};
+
+static int tpm_entropy_source(void* dummy, unsigned char* data, size_t len, size_t* olen) {
+   UINT32 sz = len;
+   TPM_RESULT rc = TPM_GetRandom(&sz, data);
+   *olen = sz;
+   return rc == TPM_SUCCESS ? 0 : POLARSSL_ERR_ENTROPY_SOURCE_FAILED;
+}
+
+static TPM_RESULT check_tpm_version(void) {
+   TPM_RESULT status;
+   UINT32 rsize;
+   BYTE* res = NULL;
+   TPM_CAP_VERSION_INFO vinfo;
+
+   TPMTRYRETURN(TPM_GetCapability(
+            TPM_CAP_VERSION_VAL,
+            0,
+            NULL,
+            &rsize,
+            &res));
+   if(rsize < 4) {
+      vtpmlogerror(VTPM_LOG_VTPM, "Invalid size returned by GetCapability!\n");
+      status = TPM_BAD_PARAMETER;
+      goto abort_egress;
+   }
+
+   unpack_TPM_CAP_VERSION_INFO(res, &vinfo, UNPACK_ALIAS);
+
+   vtpmloginfo(VTPM_LOG_VTPM, "Hardware TPM:\n");
+   vtpmloginfo(VTPM_LOG_VTPM, " version: %hhd %hhd %hhd %hhd\n",
+         vinfo.version.major, vinfo.version.minor, vinfo.version.revMajor, vinfo.version.revMinor);
+   vtpmloginfo(VTPM_LOG_VTPM, " specLevel: %hd\n", vinfo.specLevel);
+   vtpmloginfo(VTPM_LOG_VTPM, " errataRev: %hhd\n", vinfo.errataRev);
+   vtpmloginfo(VTPM_LOG_VTPM, " vendorID: %c%c%c%c\n",
+         vinfo.tpmVendorID[0], vinfo.tpmVendorID[1],
+         vinfo.tpmVendorID[2], vinfo.tpmVendorID[3]);
+   vtpmloginfo(VTPM_LOG_VTPM, " vendorSpecificSize: %hd\n", vinfo.vendorSpecificSize);
+   vtpmloginfo(VTPM_LOG_VTPM, " vendorSpecific: ");
+   for(int i = 0; i < vinfo.vendorSpecificSize; ++i) {
+      vtpmloginfomore(VTPM_LOG_VTPM, "%02hhx", vinfo.vendorSpecific[i]);
+   }
+   vtpmloginfomore(VTPM_LOG_VTPM, "\n");
+
+abort_egress:
+   free(res);
+   return status;
+}
+
+static TPM_RESULT flush_tpm(void) {
+   TPM_RESULT status = TPM_SUCCESS;
+   const TPM_RESOURCE_TYPE reslist[] = { TPM_RT_KEY, TPM_RT_AUTH, TPM_RT_TRANS, TPM_RT_COUNTER, TPM_RT_DAA_TPM, TPM_RT_CONTEXT };
+   BYTE* keylist = NULL;
+   UINT32 keylistSize;
+   BYTE* ptr;
+
+   //Iterate through each resource type and flush all handles
+   for(int i = 0; i < sizeof(reslist) / sizeof(TPM_RESOURCE_TYPE); ++i) {
+      TPM_RESOURCE_TYPE beres = cpu_to_be32(reslist[i]);
+      UINT16 size;
+      TPMTRYRETURN(TPM_GetCapability(
+               TPM_CAP_HANDLE,
+               sizeof(TPM_RESOURCE_TYPE),
+               (BYTE*)(&beres),
+               &keylistSize,
+               &keylist));
+
+      ptr = keylist;
+      ptr = unpack_UINT16(ptr, &size);
+
+      //Flush each handle
+      if(size) {
+         vtpmloginfo(VTPM_LOG_VTPM, "Flushing %u handle(s) of type %lu\n", size, (unsigned long) reslist[i]);
+         for(int j = 0; j < size; ++j) {
+            TPM_HANDLE h;
+            ptr = unpack_TPM_HANDLE(ptr, &h);
+            TPMTRYRETURN(TPM_FlushSpecific(h, reslist[i]));
+         }
+      }
+
+      free(keylist);
+      keylist = NULL;
+   }
+
+   goto egress;
+abort_egress:
+   free(keylist);
+egress:
+   return status;
+}
+
+
+static TPM_RESULT try_take_ownership(void) {
+   TPM_RESULT status = TPM_SUCCESS;
+   TPM_PUBKEY pubEK = TPM_PUBKEY_INIT;
+
+   // If we can read PubEK then there is no owner and we should take it.
+   status = TPM_ReadPubek(&pubEK);
+
+   switch(status) {
+      case TPM_DISABLED_CMD:
+         //Cannot read ek? TPM has owner
+         vtpmloginfo(VTPM_LOG_VTPM, "Failed to readEK meaning TPM has an owner. Creating Keys off existing SRK.\n");
+         status = TPM_SUCCESS;
+         break;
+      case TPM_NO_ENDORSEMENT:
+         {
+            //If theres no ek, we have to create one
+            TPM_KEY_PARMS keyInfo = {
+               .algorithmID = TPM_ALG_RSA,
+               .encScheme = TPM_ES_RSAESOAEP_SHA1_MGF1,
+               .sigScheme = TPM_SS_NONE,
+               .parmSize = 12,
+               .parms.rsa = {
+                  .keyLength = RSA_KEY_SIZE,
+                  .numPrimes = 2,
+                  .exponentSize = 0,
+                  .exponent = NULL,
+               },
+            };
+            TPMTRYRETURN(TPM_CreateEndorsementKeyPair(&keyInfo, &pubEK));
+         }
+         //fall through to take ownership
+      case TPM_SUCCESS:
+         {
+            //Construct the Srk
+            TPM_KEY srk = {
+               .ver = TPM_STRUCT_VER_1_1,
+               .keyUsage = TPM_KEY_STORAGE,
+               .keyFlags = 0x00,
+               .authDataUsage = TPM_AUTH_ALWAYS,
+               .algorithmParms = {
+                  .algorithmID = TPM_ALG_RSA,
+                  .encScheme = TPM_ES_RSAESOAEP_SHA1_MGF1,
+                  .sigScheme =  TPM_SS_NONE,
+                  .parmSize = 12,
+                  .parms.rsa = {
+                     .keyLength = RSA_KEY_SIZE,
+                     .numPrimes = 2,
+                     .exponentSize = 0,
+                     .exponent = NULL,
+                  },
+               },
+               .PCRInfoSize = 0,
+               .pubKey = {
+                  .keyLength = 0,
+                  .key = NULL,
+               },
+               .encDataSize = 0,
+            };
+
+            TPMTRYRETURN(TPM_TakeOwnership(
+                     &pubEK,
+                     (const TPM_AUTHDATA*)&vtpm_globals.owner_auth,
+                     (const TPM_AUTHDATA*)&vtpm_globals.srk_auth,
+                     &srk,
+                     NULL,
+                     &vtpm_globals.oiap));
+
+            TPMTRYRETURN(TPM_DisablePubekRead(
+                     (const TPM_AUTHDATA*)&vtpm_globals.owner_auth,
+                     &vtpm_globals.oiap));
+         }
+         break;
+      default:
+         break;
+   }
+abort_egress:
+   free_TPM_PUBKEY(&pubEK);
+   return status;
+}
+
+static void init_storage_key(TPM_KEY* key) {
+   key->ver.major = 1;
+   key->ver.minor = 1;
+   key->ver.revMajor = 0;
+   key->ver.revMinor = 0;
+
+   key->keyUsage = TPM_KEY_BIND;
+   key->keyFlags = 0;
+   key->authDataUsage = TPM_AUTH_ALWAYS;
+
+   TPM_KEY_PARMS* p = &key->algorithmParms;
+   p->algorithmID = TPM_ALG_RSA;
+   p->encScheme = TPM_ES_RSAESOAEP_SHA1_MGF1;
+   p->sigScheme = TPM_SS_NONE;
+   p->parmSize = 12;
+
+   TPM_RSA_KEY_PARMS* r = &p->parms.rsa;
+   r->keyLength = RSA_KEY_SIZE;
+   r->numPrimes = 2;
+   r->exponentSize = 0;
+   r->exponent = NULL;
+
+   key->PCRInfoSize = 0;
+   key->encDataSize = 0;
+   key->encData = NULL;
+}
+
+static int parse_auth_string(char* authstr, BYTE* target, const TPM_AUTHDATA wellknown, int allowrandom) {
+   int rc;
+   /* well known owner auth */
+   if(!strcmp(authstr, "well-known")) {
+      memcpy(target, wellknown, sizeof(TPM_AUTHDATA));
+   }
+   /* Create a randomly generated owner auth */
+   else if(allowrandom && !strcmp(authstr, "random")) {
+      return 1;
+   }
+   /* owner auth is a raw hash */
+   else if(!strncmp(authstr, "hash:", 5)) {
+      authstr += 5;
+      if((rc = strlen(authstr)) != 40) {
+         vtpmlogerror(VTPM_LOG_VTPM, "Supplied owner auth hex string `%s' must be exactly 40 characters (20 bytes) long, length=%d\n", authstr, rc);
+         return -1;
+      }
+      for(int j = 0; j < 20; ++j) {
+         if(sscanf(authstr, "%hhX", target + j) != 1) {
+            vtpmlogerror(VTPM_LOG_VTPM, "Supplied owner auth string `%s' is not a valid hex string\n", authstr);
+            return -1;
+         }
+         authstr += 2;
+      }
+   }
+   /* owner auth is a string that will be hashed */
+   else if(!strncmp(authstr, "text:", 5)) {
+      authstr += 5;
+      sha1((const unsigned char*)authstr, strlen(authstr), target);
+   }
+   else {
+      vtpmlogerror(VTPM_LOG_VTPM, "Invalid auth string %s\n", authstr);
+      return -1;
+   }
+
+   return 0;
+}
+
+int parse_cmdline_opts(int argc, char** argv, struct Opts* opts)
+{
+   int rc;
+   int i;
+
+   //Set defaults
+   memcpy(vtpm_globals.owner_auth, WELLKNOWN_OWNER_AUTH, sizeof(TPM_AUTHDATA));
+   memcpy(vtpm_globals.srk_auth, WELLKNOWN_SRK_AUTH, sizeof(TPM_AUTHDATA));
+
+   for(i = 1; i < argc; ++i) {
+      if(!strncmp(argv[i], "owner_auth:", 10)) {
+         if((rc = parse_auth_string(argv[i] + 10, vtpm_globals.owner_auth, WELLKNOWN_OWNER_AUTH, 1)) < 0) {
+            goto err_invalid;
+         }
+         if(rc == 1) {
+            opts->gen_owner_auth = 1;
+         }
+      }
+      else if(!strncmp(argv[i], "srk_auth:", 8)) {
+         if((rc = parse_auth_string(argv[i] + 8, vtpm_globals.srk_auth, WELLKNOWN_SRK_AUTH, 0)) != 0) {
+            goto err_invalid;
+         }
+      }
+      else if(!strncmp(argv[i], "tpmdriver=", 10)) {
+         if(!strcmp(argv[i] + 10, "tpm_tis")) {
+            opts->tpmdriver = TPMDRV_TPM_TIS;
+         } else if(!strcmp(argv[i] + 10, "tpmfront")) {
+            opts->tpmdriver = TPMDRV_TPMFRONT;
+         } else {
+            goto err_invalid;
+         }
+      }
+      else if(!strncmp(argv[i], "tpmiomem=",9)) {
+         if(sscanf(argv[i] + 9, "0x%lX", &opts->tpmiomem) != 1) {
+            goto err_invalid;
+         }
+      }
+      else if(!strncmp(argv[i], "tpmirq=",7)) {
+         if(!strcmp(argv[i] + 7, "probe")) {
+            opts->tpmirq = TPM_PROBE_IRQ;
+         } else if( sscanf(argv[i] + 7, "%u", &opts->tpmirq) != 1) {
+            goto err_invalid;
+         }
+      }
+      else if(!strncmp(argv[i], "tpmlocality=",12)) {
+         if(sscanf(argv[i] + 12, "%u", &opts->tpmlocality) != 1 || opts->tpmlocality > 4) {
+            goto err_invalid;
+         }
+      }
+   }
+
+   switch(opts->tpmdriver) {
+      case TPMDRV_TPM_TIS:
+         vtpmloginfo(VTPM_LOG_VTPM, "Option: Using tpm_tis driver\n");
+         break;
+      case TPMDRV_TPMFRONT:
+         vtpmloginfo(VTPM_LOG_VTPM, "Option: Using tpmfront driver\n");
+         break;
+   }
+
+   return 0;
+err_invalid:
+   vtpmlogerror(VTPM_LOG_VTPM, "Invalid Option %s\n", argv[i]);
+   return -1;
+}
+
+
+
+static TPM_RESULT vtpmmgr_create(void) {
+   TPM_RESULT status = TPM_SUCCESS;
+   TPM_AUTH_SESSION osap = TPM_AUTH_SESSION_INIT;
+   TPM_AUTHDATA sharedsecret;
+
+   // Take ownership if TPM is unowned
+   TPMTRYRETURN(try_take_ownership());
+
+   // Generate storage key's auth
+   memset(&vtpm_globals.storage_key_usage_auth, 0, sizeof(TPM_AUTHDATA));
+
+   TPMTRYRETURN( TPM_OSAP(
+            TPM_ET_KEYHANDLE,
+            TPM_SRK_KEYHANDLE,
+            (const TPM_AUTHDATA*)&vtpm_globals.srk_auth,
+            &sharedsecret,
+            &osap) );
+
+   init_storage_key(&vtpm_globals.storage_key);
+
+   //initialize the storage key
+   TPMTRYRETURN( TPM_CreateWrapKey(
+            TPM_SRK_KEYHANDLE,
+            (const TPM_AUTHDATA*)&sharedsecret,
+            (const TPM_AUTHDATA*)&vtpm_globals.storage_key_usage_auth,
+            (const TPM_AUTHDATA*)&vtpm_globals.storage_key_usage_auth,
+            &vtpm_globals.storage_key,
+            &osap) );
+
+   //Load Storage Key
+   TPMTRYRETURN( TPM_LoadKey(
+            TPM_SRK_KEYHANDLE,
+            &vtpm_globals.storage_key,
+            &vtpm_globals.storage_key_handle,
+            (const TPM_AUTHDATA*) &vtpm_globals.srk_auth,
+            &vtpm_globals.oiap));
+
+   //Make sure TPM has commited changes
+   TPMTRYRETURN( TPM_SaveState() );
+
+   //Create new disk image
+   TPMTRYRETURN(vtpm_storage_new_header());
+
+   goto egress;
+abort_egress:
+egress:
+   vtpmloginfo(VTPM_LOG_VTPM, "Finished initialized new VTPM manager\n");
+
+   //End the OSAP session
+   if(osap.AuthHandle) {
+      TPM_TerminateHandle(osap.AuthHandle);
+   }
+
+   return status;
+}
+
+TPM_RESULT vtpmmgr_init(int argc, char** argv) {
+   TPM_RESULT status = TPM_SUCCESS;
+
+   /* Default commandline options */
+   struct Opts opts = {
+      .tpmdriver = TPMDRV_TPM_TIS,
+      .tpmiomem = TPM_BASEADDR,
+      .tpmirq = 0,
+      .tpmlocality = 0,
+      .gen_owner_auth = 0,
+   };
+
+   if(parse_cmdline_opts(argc, argv, &opts) != 0) {
+      vtpmlogerror(VTPM_LOG_VTPM, "Command line parsing failed! exiting..\n");
+      status = TPM_BAD_PARAMETER;
+      goto abort_egress;
+   }
+
+   //Setup storage system
+   if(vtpm_storage_init() != 0) {
+      vtpmlogerror(VTPM_LOG_VTPM, "Unable to initialize storage subsystem!\n");
+      status = TPM_IOERROR;
+      goto abort_egress;
+   }
+
+   //Setup tpmback device
+   init_tpmback();
+
+   //Setup tpm access
+   switch(opts.tpmdriver) {
+      case TPMDRV_TPM_TIS:
+         {
+            struct tpm_chip* tpm;
+            if((tpm = init_tpm_tis(opts.tpmiomem, TPM_TIS_LOCL_INT_TO_FLAG(opts.tpmlocality), opts.tpmirq)) == NULL) {
+               vtpmlogerror(VTPM_LOG_VTPM, "Unable to initialize tpmfront device\n");
+               status = TPM_IOERROR;
+               goto abort_egress;
+            }
+            vtpm_globals.tpm_fd = tpm_tis_open(tpm);
+            tpm_tis_request_locality(tpm, opts.tpmlocality);
+         }
+         break;
+      case TPMDRV_TPMFRONT:
+         {
+            struct tpmfront_dev* tpmfront_dev;
+            if((tpmfront_dev = init_tpmfront(NULL)) == NULL) {
+               vtpmlogerror(VTPM_LOG_VTPM, "Unable to initialize tpmfront device\n");
+               status = TPM_IOERROR;
+               goto abort_egress;
+            }
+            vtpm_globals.tpm_fd = tpmfront_open(tpmfront_dev);
+         }
+         break;
+   }
+
+   //Get the version of the tpm
+   TPMTRYRETURN(check_tpm_version());
+
+   // Blow away all stale handles left in the tpm
+   if(flush_tpm() != TPM_SUCCESS) {
+      vtpmlogerror(VTPM_LOG_VTPM, "VTPM_FlushResources failed, continuing anyway..\n");
+   }
+
+   /* Initialize the rng */
+   entropy_init(&vtpm_globals.entropy);
+   entropy_add_source(&vtpm_globals.entropy, tpm_entropy_source, NULL, 0);
+   entropy_gather(&vtpm_globals.entropy);
+   ctr_drbg_init(&vtpm_globals.ctr_drbg, entropy_func, &vtpm_globals.entropy, NULL, 0);
+   ctr_drbg_set_prediction_resistance( &vtpm_globals.ctr_drbg, CTR_DRBG_PR_OFF );
+
+   // Generate Auth for Owner
+   if(opts.gen_owner_auth) {
+      vtpmmgr_rand(vtpm_globals.owner_auth, sizeof(TPM_AUTHDATA));
+   }
+
+   // Create OIAP session for service's authorized commands
+   TPMTRYRETURN( TPM_OIAP(&vtpm_globals.oiap) );
+
+   /* Load the Manager data, if it fails create a new manager */
+   if (vtpm_storage_load_header() != TPM_SUCCESS) {
+      /* If the OIAP session was closed by an error, create a new one */
+      if(vtpm_globals.oiap.AuthHandle == 0) {
+         TPMTRYRETURN( TPM_OIAP(&vtpm_globals.oiap) );
+      }
+      vtpmloginfo(VTPM_LOG_VTPM, "Failed to read manager file. Assuming first time initialization.\n");
+      TPMTRYRETURN( vtpmmgr_create() );
+   }
+
+   goto egress;
+abort_egress:
+   vtpmmgr_shutdown();
+egress:
+   return status;
+}
+
+void vtpmmgr_shutdown(void)
+{
+   /* Cleanup resources */
+   free_TPM_KEY(&vtpm_globals.storage_key);
+
+   /* Cleanup TPM resources */
+   TPM_EvictKey(vtpm_globals.storage_key_handle);
+   TPM_TerminateHandle(vtpm_globals.oiap.AuthHandle);
+
+   /* Close tpmback */
+   shutdown_tpmback();
+
+   /* Close the storage system and blkfront */
+   vtpm_storage_shutdown();
+
+   /* Close tpmfront/tpm_tis */
+   close(vtpm_globals.tpm_fd);
+
+   vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager stopped.\n");
+}
diff --git a/stubdom/vtpmmgr/log.c b/stubdom/vtpmmgr/log.c
new file mode 100644
index 0000000..a82c913
--- /dev/null
+++ b/stubdom/vtpmmgr/log.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense.  All rights reserved.
+ *
+ * based off of the original tools/vtpm_manager code base which is:
+ * Copyright (c) 2005, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "tcg.h"
+
+char *module_names[] = { "",
+                                "TPM",
+                                "TPM",
+                                "VTPM",
+                                "VTPM",
+                                "TXDATA",
+                              };
+// Helper code for the consts, eg. to produce messages for error codes.
+
+typedef struct error_code_entry_t {
+  TPM_RESULT code;
+  char * code_name;
+  char * msg;
+} error_code_entry_t;
+
+static const error_code_entry_t error_msgs [] = {
+  { TPM_SUCCESS, "TPM_SUCCESS", "Successful completion of the operation" },
+  { TPM_AUTHFAIL, "TPM_AUTHFAIL", "Authentication failed" },
+  { TPM_BADINDEX, "TPM_BADINDEX", "The index to a PCR, DIR or other register is incorrect" },
+  { TPM_BAD_PARAMETER, "TPM_BAD_PARAMETER", "One or more parameter is bad" },
+  { TPM_AUDITFAILURE, "TPM_AUDITFAILURE", "An operation completed successfully but the auditing of that operation failed." },
+  { TPM_CLEAR_DISABLED, "TPM_CLEAR_DISABLED", "The clear disable flag is set and all clear operations now require physical access" },
+  { TPM_DEACTIVATED, "TPM_DEACTIVATED", "The TPM is deactivated" },
+  { TPM_DISABLED, "TPM_DISABLED", "The TPM is disabled" },
+  { TPM_DISABLED_CMD, "TPM_DISABLED_CMD", "The target command has been disabled" },
+  { TPM_FAIL, "TPM_FAIL", "The operation failed" },
+  { TPM_BAD_ORDINAL, "TPM_BAD_ORDINAL", "The ordinal was unknown or inconsistent" },
+  { TPM_INSTALL_DISABLED, "TPM_INSTALL_DISABLED", "The ability to install an owner is disabled" },
+  { TPM_INVALID_KEYHANDLE, "TPM_INVALID_KEYHANDLE", "The key handle presented was invalid" },
+  { TPM_KEYNOTFOUND, "TPM_KEYNOTFOUND", "The target key was not found" },
+  { TPM_INAPPROPRIATE_ENC, "TPM_INAPPROPRIATE_ENC", "Unacceptable encryption scheme" },
+  { TPM_MIGRATEFAIL, "TPM_MIGRATEFAIL", "Migration authorization failed" },
+  { TPM_INVALID_PCR_INFO, "TPM_INVALID_PCR_INFO", "PCR information could not be interpreted" },
+  { TPM_NOSPACE, "TPM_NOSPACE", "No room to load key." },
+  { TPM_NOSRK, "TPM_NOSRK", "There is no SRK set" },
+  { TPM_NOTSEALED_BLOB, "TPM_NOTSEALED_BLOB", "An encrypted blob is invalid or was not created by this TPM" },
+  { TPM_OWNER_SET, "TPM_OWNER_SET", "There is already an Owner" },
+  { TPM_RESOURCES, "TPM_RESOURCES", "The TPM has insufficient internal resources to perform the requested action." },
+  { TPM_SHORTRANDOM, "TPM_SHORTRANDOM", "A random string was too short" },
+  { TPM_SIZE, "TPM_SIZE", "The TPM does not have the space to perform the operation." },
+  { TPM_WRONGPCRVAL, "TPM_WRONGPCRVAL", "The named PCR value does not match the current PCR value." },
+  { TPM_BAD_PARAM_SIZE, "TPM_BAD_PARAM_SIZE", "The paramSize argument to the command has the incorrect value" },
+  { TPM_SHA_THREAD, "TPM_SHA_THREAD", "There is no existing SHA-1 thread." },
+  { TPM_SHA_ERROR, "TPM_SHA_ERROR", "The calculation is unable to proceed because the existing SHA-1 thread has already encountered an error." },
+  { TPM_FAILEDSELFTEST, "TPM_FAILEDSELFTEST", "Self-test has failed and the TPM has shutdown." },
+  { TPM_AUTH2FAIL, "TPM_AUTH2FAIL", "The authorization for the second key in a 2 key function failed authorization" },
+  { TPM_BADTAG, "TPM_BADTAG", "The tag value sent to for a command is invalid" },
+  { TPM_IOERROR, "TPM_IOERROR", "An IO error occurred transmitting information to the TPM" },
+  { TPM_ENCRYPT_ERROR, "TPM_ENCRYPT_ERROR", "The encryption process had a problem." },
+  { TPM_DECRYPT_ERROR, "TPM_DECRYPT_ERROR", "The decryption process did not complete." },
+  { TPM_INVALID_AUTHHANDLE, "TPM_INVALID_AUTHHANDLE", "An invalid handle was used." },
+  { TPM_NO_ENDORSEMENT, "TPM_NO_ENDORSEMENT", "The TPM does not a EK installed" },
+  { TPM_INVALID_KEYUSAGE, "TPM_INVALID_KEYUSAGE", "The usage of a key is not allowed" },
+  { TPM_WRONG_ENTITYTYPE, "TPM_WRONG_ENTITYTYPE", "The submitted entity type is not allowed" },
+  { TPM_INVALID_POSTINIT, "TPM_INVALID_POSTINIT", "The command was received in the wrong sequence relative to TPM_Init and a subsequent TPM_Startup" },
+  { TPM_INAPPROPRIATE_SIG, "TPM_INAPPROPRIATE_SIG", "Signed data cannot include additional DER information" },
+  { TPM_BAD_KEY_PROPERTY, "TPM_BAD_KEY_PROPERTY", "The key properties in TPM_KEY_PARMs are not supported by this TPM" },
+
+  { TPM_BAD_MIGRATION, "TPM_BAD_MIGRATION", "The migration properties of this key are incorrect." },
+  { TPM_BAD_SCHEME, "TPM_BAD_SCHEME", "The signature or encryption scheme for this key is incorrect or not permitted in this situation." },
+  { TPM_BAD_DATASIZE, "TPM_BAD_DATASIZE", "The size of the data (or blob) parameter is bad or inconsistent with the referenced key" },
+  { TPM_BAD_MODE, "TPM_BAD_MODE", "A mode parameter is bad, such as capArea or subCapArea for TPM_GetCapability, phsicalPresence parameter for TPM_PhysicalPresence, or migrationType for TPM_CreateMigrationBlob." },
+  { TPM_BAD_PRESENCE, "TPM_BAD_PRESENCE", "Either the physicalPresence or physicalPresenceLock bits have the wrong value" },
+  { TPM_BAD_VERSION, "TPM_BAD_VERSION", "The TPM cannot perform this version of the capability" },
+  { TPM_NO_WRAP_TRANSPORT, "TPM_NO_WRAP_TRANSPORT", "The TPM does not allow for wrapped transport sessions" },
+  { TPM_AUDITFAIL_UNSUCCESSFUL, "TPM_AUDITFAIL_UNSUCCESSFUL", "TPM audit construction failed and the underlying command was returning a failure code also" },
+  { TPM_AUDITFAIL_SUCCESSFUL, "TPM_AUDITFAIL_SUCCESSFUL", "TPM audit construction failed and the underlying command was returning success" },
+  { TPM_NOTRESETABLE, "TPM_NOTRESETABLE", "Attempt to reset a PCR register that does not have the resettable attribute" },
+  { TPM_NOTLOCAL, "TPM_NOTLOCAL", "Attempt to reset a PCR register that requires locality and locality modifier not part of command transport" },
+  { TPM_BAD_TYPE, "TPM_BAD_TYPE", "Make identity blob not properly typed" },
+  { TPM_INVALID_RESOURCE, "TPM_INVALID_RESOURCE", "When saving context identified resource type does not match actual resource" },
+  { TPM_NOTFIPS, "TPM_NOTFIPS", "The TPM is attempting to execute a command only available when in FIPS mode" },
+  { TPM_INVALID_FAMILY, "TPM_INVALID_FAMILY", "The command is attempting to use an invalid family ID" },
+  { TPM_NO_NV_PERMISSION, "TPM_NO_NV_PERMISSION", "The permission to manipulate the NV storage is not available" },
+  { TPM_REQUIRES_SIGN, "TPM_REQUIRES_SIGN", "The operation requires a signed command" },
+  { TPM_KEY_NOTSUPPORTED, "TPM_KEY_NOTSUPPORTED", "Wrong operation to load an NV key" },
+  { TPM_AUTH_CONFLICT, "TPM_AUTH_CONFLICT", "NV_LoadKey blob requires both owner and blob authorization" },
+  { TPM_AREA_LOCKED, "TPM_AREA_LOCKED", "The NV area is locked and not writtable" },
+  { TPM_BAD_LOCALITY, "TPM_BAD_LOCALITY", "The locality is incorrect for the attempted operation" },
+  { TPM_READ_ONLY, "TPM_READ_ONLY", "The NV area is read only and can't be written to" },
+  { TPM_PER_NOWRITE, "TPM_PER_NOWRITE", "There is no protection on the write to the NV area" },
+  { TPM_FAMILYCOUNT, "TPM_FAMILYCOUNT", "The family count value does not match" },
+  { TPM_WRITE_LOCKED, "TPM_WRITE_LOCKED", "The NV area has already been written to" },
+  { TPM_BAD_ATTRIBUTES, "TPM_BAD_ATTRIBUTES", "The NV area attributes conflict" },
+  { TPM_INVALID_STRUCTURE, "TPM_INVALID_STRUCTURE", "The structure tag and version are invalid or inconsistent" },
+  { TPM_KEY_OWNER_CONTROL, "TPM_KEY_OWNER_CONTROL", "The key is under control of the TPM Owner and can only be evicted by the TPM Owner." },
+  { TPM_BAD_COUNTER, "TPM_BAD_COUNTER", "The counter handle is incorrect" },
+  { TPM_NOT_FULLWRITE, "TPM_NOT_FULLWRITE", "The write is not a complete write of the area" },
+  { TPM_CONTEXT_GAP, "TPM_CONTEXT_GAP", "The gap between saved context counts is too large" },
+  { TPM_MAXNVWRITES, "TPM_MAXNVWRITES", "The maximum number of NV writes without an owner has been exceeded" },
+  { TPM_NOOPERATOR, "TPM_NOOPERATOR", "No operator authorization value is set" },
+  { TPM_RESOURCEMISSING, "TPM_RESOURCEMISSING", "The resource pointed to by context is not loaded" },
+  { TPM_DELEGATE_LOCK, "TPM_DELEGATE_LOCK", "The delegate administration is locked" },
+  { TPM_DELEGATE_FAMILY, "TPM_DELEGATE_FAMILY", "Attempt to manage a family other then the delegated family" },
+  { TPM_DELEGATE_ADMIN, "TPM_DELEGATE_ADMIN", "Delegation table management not enabled" },
+  { TPM_TRANSPORT_EXCLUSIVE, "TPM_TRANSPORT_EXCLUSIVE", "There was a command executed outside of an exclusive transport session" },
+};
+
+
+// helper function for the error codes:
+const char* tpm_get_error_name (TPM_RESULT code) {
+  // just do a linear scan for now
+  unsigned i;
+  for (i = 0; i < sizeof(error_msgs)/sizeof(error_msgs[0]); i++)
+    if (code == error_msgs[i].code)
+      return error_msgs[i].code_name;
+
+    return("Unknown Error Code");
+}
diff --git a/stubdom/vtpmmgr/log.h b/stubdom/vtpmmgr/log.h
new file mode 100644
index 0000000..5c7abf5
--- /dev/null
+++ b/stubdom/vtpmmgr/log.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense.  All rights reserved.
+ *
+ * based off of the original tools/vtpm_manager code base which is:
+ * Copyright (c) 2005, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __VTPM_LOG_H__
+#define __VTPM_LOG_H__
+
+#include <stdint.h>             // for uint32_t
+#include <stddef.h>             // for pointer NULL
+#include <stdio.h>
+#include "tcg.h"
+
+// =========================== LOGGING ==============================
+
+// the logging module numbers
+#define VTPM_LOG_TPM         1
+#define VTPM_LOG_TPM_DEEP    2
+#define VTPM_LOG_VTPM        3
+#define VTPM_LOG_VTPM_DEEP   4
+#define VTPM_LOG_TXDATA      5
+
+extern char *module_names[];
+
+// Default to standard logging
+#ifndef LOGGING_MODULES
+#define LOGGING_MODULES (BITMASK(VTPM_LOG_VTPM)|BITMASK(VTPM_LOG_TPM))
+#endif
+
+// bit-access macros
+#define BITMASK(idx)      ( 1U << (idx) )
+#define GETBIT(num,idx)   ( ((num) & BITMASK(idx)) >> idx )
+#define SETBIT(num,idx)   (num) |= BITMASK(idx)
+#define CLEARBIT(num,idx) (num) &= ( ~ BITMASK(idx) )
+
+#define vtpmloginfo(module, fmt, args...) \
+  if (GETBIT (LOGGING_MODULES, module) == 1) {				\
+    fprintf (stdout, "INFO[%s]: " fmt, module_names[module], ##args); \
+  }
+
+#define vtpmloginfomore(module, fmt, args...) \
+  if (GETBIT (LOGGING_MODULES, module) == 1) {			      \
+    fprintf (stdout, fmt,##args);				      \
+  }
+
+#define vtpmlogerror(module, fmt, args...) \
+  fprintf (stderr, "ERROR[%s]: " fmt, module_names[module], ##args);
+
+//typedef UINT32 tpm_size_t;
+
+// helper function for the error codes:
+const char* tpm_get_error_name (TPM_RESULT code);
+
+#endif // _VTPM_LOG_H_
diff --git a/stubdom/vtpmmgr/marshal.h b/stubdom/vtpmmgr/marshal.h
new file mode 100644
index 0000000..77d32f0
--- /dev/null
+++ b/stubdom/vtpmmgr/marshal.h
@@ -0,0 +1,528 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense.  All rights reserved.
+ *
+ * based off of the original tools/vtpm_manager code base which is:
+ * Copyright (c) 2005, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef MARSHAL_H
+#define MARSHAL_H
+
+#include <stdlib.h>
+#include <mini-os/byteorder.h>
+#include <mini-os/endian.h>
+#include "tcg.h"
+
+typedef enum UnpackPtr {
+   UNPACK_ALIAS,
+   UNPACK_ALLOC
+} UnpackPtr;
+
+inline BYTE* pack_BYTE(BYTE* ptr, BYTE t) {
+   ptr[0] = t;
+   return ++ptr;
+}
+
+inline BYTE* unpack_BYTE(BYTE* ptr, BYTE* t) {
+   t[0] = ptr[0];
+   return ++ptr;
+}
+
+#define pack_BOOL(p, t) pack_BYTE(p, t)
+#define unpack_BOOL(p, t) unpack_BYTE(p, t)
+
+inline BYTE* pack_UINT16(BYTE* ptr, UINT16 t) {
+   BYTE* b = (BYTE*)&t;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+   ptr[0] = b[1];
+   ptr[1] = b[0];
+#elif __BYTE_ORDER == __BIG_ENDIAN
+   ptr[0] = b[0];
+   ptr[1] = b[1];
+#endif
+   return ptr + sizeof(UINT16);
+}
+
+inline BYTE* unpack_UINT16(BYTE* ptr, UINT16* t) {
+   BYTE* b = (BYTE*)t;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+   b[0] = ptr[1];
+   b[1] = ptr[0];
+#elif __BYTE_ORDER == __BIG_ENDIAN
+   b[0] = ptr[0];
+   b[1] = ptr[1];
+#endif
+   return ptr + sizeof(UINT16);
+}
+
+inline BYTE* pack_UINT32(BYTE* ptr, UINT32 t) {
+   BYTE* b = (BYTE*)&t;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+   ptr[3] = b[0];
+   ptr[2] = b[1];
+   ptr[1] = b[2];
+   ptr[0] = b[3];
+#elif __BYTE_ORDER == __BIG_ENDIAN
+   ptr[0] = b[0];
+   ptr[1] = b[1];
+   ptr[2] = b[2];
+   ptr[3] = b[3];
+#endif
+   return ptr + sizeof(UINT32);
+}
+
+inline BYTE* unpack_UINT32(BYTE* ptr, UINT32* t) {
+   BYTE* b = (BYTE*)t;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+   b[0] = ptr[3];
+   b[1] = ptr[2];
+   b[2] = ptr[1];
+   b[3] = ptr[0];
+#elif __BYTE_ORDER == __BIG_ENDIAN
+   b[0] = ptr[0];
+   b[1] = ptr[1];
+   b[2] = ptr[2];
+   b[3] = ptr[3];
+#endif
+   return ptr + sizeof(UINT32);
+}
+
+#define pack_TPM_RESULT(p, t) pack_UINT32(p, t)
+#define pack_TPM_PCRINDEX(p, t) pack_UINT32(p, t)
+#define pack_TPM_DIRINDEX(p, t) pack_UINT32(p, t)
+#define pack_TPM_HANDLE(p, t) pack_UINT32(p, t)
+#define pack_TPM_AUTHHANDLE(p, t) pack_TPM_HANDLE(p, t)
+#define pack_TCPA_HASHHANDLE(p, t) pack_TPM_HANDLE(p, t)
+#define pack_TCPA_HMACHANDLE(p, t) pack_TPM_HANDLE(p, t)
+#define pack_TCPA_ENCHANDLE(p, t) pack_TPM_HANDLE(p, t)
+#define pack_TPM_KEY_HANDLE(p, t) pack_TPM_HANDLE(p, t)
+#define pack_TCPA_ENTITYHANDLE(p, t) pack_TPM_HANDLE(p, t)
+#define pack_TPM_RESOURCE_TYPE(p, t) pack_UINT32(p, t)
+#define pack_TPM_COMMAND_CODE(p, t) pack_UINT32(p, t)
+#define pack_TPM_PROTOCOL_ID(p, t) pack_UINT16(p, t)
+#define pack_TPM_AUTH_DATA_USAGE(p, t) pack_BYTE(p, t)
+#define pack_TPM_ENTITY_TYPE(p, t) pack_UINT16(p, t)
+#define pack_TPM_ALGORITHM_ID(p, t) pack_UINT32(p, t)
+#define pack_TPM_KEY_USAGE(p, t) pack_UINT16(p, t)
+#define pack_TPM_STARTUP_TYPE(p, t) pack_UINT16(p, t)
+#define pack_TPM_CAPABILITY_AREA(p, t) pack_UINT32(p, t)
+#define pack_TPM_ENC_SCHEME(p, t) pack_UINT16(p, t)
+#define pack_TPM_SIG_SCHEME(p, t) pack_UINT16(p, t)
+#define pack_TPM_MIGRATE_SCHEME(p, t) pack_UINT16(p, t)
+#define pack_TPM_PHYSICAL_PRESENCE(p, t) pack_UINT16(p, t)
+#define pack_TPM_KEY_FLAGS(p, t) pack_UINT32(p, t)
+
+#define unpack_TPM_RESULT(p, t) unpack_UINT32(p, t)
+#define unpack_TPM_PCRINDEX(p, t) unpack_UINT32(p, t)
+#define unpack_TPM_DIRINDEX(p, t) unpack_UINT32(p, t)
+#define unpack_TPM_HANDLE(p, t) unpack_UINT32(p, t)
+#define unpack_TPM_AUTHHANDLE(p, t) unpack_TPM_HANDLE(p, t)
+#define unpack_TCPA_HASHHANDLE(p, t) unpack_TPM_HANDLE(p, t)
+#define unpack_TCPA_HMACHANDLE(p, t) unpack_TPM_HANDLE(p, t)
+#define unpack_TCPA_ENCHANDLE(p, t) unpack_TPM_HANDLE(p, t)
+#define unpack_TPM_KEY_HANDLE(p, t) unpack_TPM_HANDLE(p, t)
+#define unpack_TCPA_ENTITYHANDLE(p, t) unpack_TPM_HANDLE(p, t)
+#define unpack_TPM_RESOURCE_TYPE(p, t) unpack_UINT32(p, t)
+#define unpack_TPM_COMMAND_CODE(p, t) unpack_UINT32(p, t)
+#define unpack_TPM_PROTOCOL_ID(p, t) unpack_UINT16(p, t)
+#define unpack_TPM_AUTH_DATA_USAGE(p, t) unpack_BYTE(p, t)
+#define unpack_TPM_ENTITY_TYPE(p, t) unpack_UINT16(p, t)
+#define unpack_TPM_ALGORITHM_ID(p, t) unpack_UINT32(p, t)
+#define unpack_TPM_KEY_USAGE(p, t) unpack_UINT16(p, t)
+#define unpack_TPM_STARTUP_TYPE(p, t) unpack_UINT16(p, t)
+#define unpack_TPM_CAPABILITY_AREA(p, t) unpack_UINT32(p, t)
+#define unpack_TPM_ENC_SCHEME(p, t) unpack_UINT16(p, t)
+#define unpack_TPM_SIG_SCHEME(p, t) unpack_UINT16(p, t)
+#define unpack_TPM_MIGRATE_SCHEME(p, t) unpack_UINT16(p, t)
+#define unpack_TPM_PHYSICAL_PRESENCE(p, t) unpack_UINT16(p, t)
+#define unpack_TPM_KEY_FLAGS(p, t) unpack_UINT32(p, t)
+
+#define pack_TPM_AUTH_HANDLE(p, t) pack_UINT32(p, t);
+#define pack_TCS_CONTEXT_HANDLE(p, t) pack_UINT32(p, t);
+#define pack_TCS_KEY_HANDLE(p, t) pack_UINT32(p, t);
+
+#define unpack_TPM_AUTH_HANDLE(p, t) unpack_UINT32(p, t);
+#define unpack_TCS_CONTEXT_HANDLE(p, t) unpack_UINT32(p, t);
+#define unpack_TCS_KEY_HANDLE(p, t) unpack_UINT32(p, t);
+
+inline BYTE* pack_BUFFER(BYTE* ptr, const BYTE* buf, UINT32 size) {
+   memcpy(ptr, buf, size);
+   return ptr + size;
+}
+
+inline BYTE* unpack_BUFFER(BYTE* ptr, BYTE* buf, UINT32 size) {
+   memcpy(buf, ptr, size);
+   return ptr + size;
+}
+
+inline BYTE* unpack_ALIAS(BYTE* ptr, BYTE** buf, UINT32 size) {
+   *buf = ptr;
+   return ptr + size;
+}
+
+inline BYTE* unpack_ALLOC(BYTE* ptr, BYTE** buf, UINT32 size) {
+   if(size) {
+      *buf = malloc(size);
+      memcpy(*buf, ptr, size);
+   } else {
+      *buf = NULL;
+   }
+   return ptr + size;
+}
+
+inline BYTE* unpack_PTR(BYTE* ptr, BYTE** buf, UINT32 size, UnpackPtr alloc) {
+   if(alloc == UNPACK_ALLOC) {
+      return unpack_ALLOC(ptr, buf, size);
+   } else {
+      return unpack_ALIAS(ptr, buf, size);
+   }
+}
+
+inline BYTE* pack_TPM_AUTHDATA(BYTE* ptr, const TPM_AUTHDATA* d) {
+   return pack_BUFFER(ptr, *d, TPM_DIGEST_SIZE);
+}
+
+inline BYTE* unpack_TPM_AUTHDATA(BYTE* ptr, TPM_AUTHDATA* d) {
+   return unpack_BUFFER(ptr, *d, TPM_DIGEST_SIZE);
+}
+
+#define pack_TPM_SECRET(p, t) pack_TPM_AUTHDATA(p, t)
+#define pack_TPM_ENCAUTH(p, t) pack_TPM_AUTHDATA(p, t)
+#define pack_TPM_PAYLOAD_TYPE(p, t) pack_BYTE(p, t)
+#define pack_TPM_TAG(p, t) pack_UINT16(p, t)
+#define pack_TPM_STRUCTURE_TAG(p, t) pack_UINT16(p, t)
+
+#define unpack_TPM_SECRET(p, t) unpack_TPM_AUTHDATA(p, t)
+#define unpack_TPM_ENCAUTH(p, t) unpack_TPM_AUTHDATA(p, t)
+#define unpack_TPM_PAYLOAD_TYPE(p, t) unpack_BYTE(p, t)
+#define unpack_TPM_TAG(p, t) unpack_UINT16(p, t)
+#define unpack_TPM_STRUCTURE_TAG(p, t) unpack_UINT16(p, t)
+
+inline BYTE* pack_TPM_VERSION(BYTE* ptr, const TPM_VERSION* t) {
+   ptr[0] = t->major;
+   ptr[1] = t->minor;
+   ptr[2] = t->revMajor;
+   ptr[3] = t->revMinor;
+   return ptr + 4;
+}
+
+inline BYTE* unpack_TPM_VERSION(BYTE* ptr, TPM_VERSION* t) {
+   t->major = ptr[0];
+   t->minor = ptr[1];
+   t->revMajor = ptr[2];
+   t->revMinor = ptr[3];
+   return ptr + 4;
+}
+
+inline BYTE* pack_TPM_CAP_VERSION_INFO(BYTE* ptr, const TPM_CAP_VERSION_INFO* v) {
+   ptr = pack_TPM_STRUCTURE_TAG(ptr, v->tag);
+   ptr = pack_TPM_VERSION(ptr, &v->version);
+   ptr = pack_UINT16(ptr, v->specLevel);
+   ptr = pack_BYTE(ptr, v->errataRev);
+   ptr = pack_BUFFER(ptr, v->tpmVendorID, sizeof(v->tpmVendorID));
+   ptr = pack_UINT16(ptr, v->vendorSpecificSize);
+   ptr = pack_BUFFER(ptr, v->vendorSpecific, v->vendorSpecificSize);
+   return ptr;
+}
+
+inline BYTE* unpack_TPM_CAP_VERSION_INFO(BYTE* ptr, TPM_CAP_VERSION_INFO* v, UnpackPtr alloc) {
+   ptr = unpack_TPM_STRUCTURE_TAG(ptr, &v->tag);
+   ptr = unpack_TPM_VERSION(ptr, &v->version);
+   ptr = unpack_UINT16(ptr, &v->specLevel);
+   ptr = unpack_BYTE(ptr, &v->errataRev);
+   ptr = unpack_BUFFER(ptr, v->tpmVendorID, sizeof(v->tpmVendorID));
+   ptr = unpack_UINT16(ptr, &v->vendorSpecificSize);
+   ptr = unpack_PTR(ptr, &v->vendorSpecific, v->vendorSpecificSize, alloc);
+   return ptr;
+}
+
+inline BYTE* pack_TPM_DIGEST(BYTE* ptr, const TPM_DIGEST* d) {
+   return pack_BUFFER(ptr, d->digest, TPM_DIGEST_SIZE);
+}
+
+inline BYTE* unpack_TPM_DIGEST(BYTE* ptr, TPM_DIGEST* d) {
+   return unpack_BUFFER(ptr, d->digest, TPM_DIGEST_SIZE);
+}
+
+#define pack_TPM_PCRVALUE(ptr, d) pack_TPM_DIGEST(ptr, d);
+#define unpack_TPM_PCRVALUE(ptr, d) unpack_TPM_DIGEST(ptr, d);
+
+#define pack_TPM_COMPOSITE_HASH(ptr, d) pack_TPM_DIGEST(ptr, d);
+#define unpack_TPM_COMPOSITE_HASH(ptr, d) unpack_TPM_DIGEST(ptr, d);
+
+#define pack_TPM_DIRVALUE(ptr, d) pack_TPM_DIGEST(ptr, d);
+#define unpack_TPM_DIRVALUE(ptr, d) unpack_TPM_DIGEST(ptr, d);
+
+#define pack_TPM_HMAC(ptr, d) pack_TPM_DIGEST(ptr, d);
+#define unpack_TPM_HMAC(ptr, d) unpack_TPM_DIGEST(ptr, d);
+
+#define pack_TPM_CHOSENID_HASH(ptr, d) pack_TPM_DIGEST(ptr, d);
+#define unpack_TPM_CHOSENID_HASH(ptr, d) unpack_TPM_DIGEST(ptr, d);
+
+inline BYTE* pack_TPM_NONCE(BYTE* ptr, const TPM_NONCE* n) {
+   return pack_BUFFER(ptr, n->nonce, TPM_DIGEST_SIZE);
+}
+
+inline BYTE* unpack_TPM_NONCE(BYTE* ptr, TPM_NONCE* n) {
+   return unpack_BUFFER(ptr, n->nonce, TPM_DIGEST_SIZE);
+}
+
+inline BYTE* pack_TPM_SYMMETRIC_KEY_PARMS(BYTE* ptr, const TPM_SYMMETRIC_KEY_PARMS* k) {
+   ptr = pack_UINT32(ptr, k->keyLength);
+   ptr = pack_UINT32(ptr, k->blockSize);
+   ptr = pack_UINT32(ptr, k->ivSize);
+   return pack_BUFFER(ptr, k->IV, k->ivSize);
+}
+
+inline BYTE* unpack_TPM_SYMMETRIC_KEY_PARMS(BYTE* ptr, TPM_SYMMETRIC_KEY_PARMS* k, UnpackPtr alloc) {
+   ptr = unpack_UINT32(ptr, &k->keyLength);
+   ptr = unpack_UINT32(ptr, &k->blockSize);
+   ptr = unpack_UINT32(ptr, &k->ivSize);
+   return unpack_PTR(ptr, &k->IV, k->ivSize, alloc);
+}
+
+inline BYTE* pack_TPM_RSA_KEY_PARMS(BYTE* ptr, const TPM_RSA_KEY_PARMS* k) {
+   ptr = pack_UINT32(ptr, k->keyLength);
+   ptr = pack_UINT32(ptr, k->numPrimes);
+   ptr = pack_UINT32(ptr, k->exponentSize);
+   return pack_BUFFER(ptr, k->exponent, k->exponentSize);
+}
+
+inline BYTE* unpack_TPM_RSA_KEY_PARMS(BYTE* ptr, TPM_RSA_KEY_PARMS* k, UnpackPtr alloc) {
+   ptr = unpack_UINT32(ptr, &k->keyLength);
+   ptr = unpack_UINT32(ptr, &k->numPrimes);
+   ptr = unpack_UINT32(ptr, &k->exponentSize);
+   return unpack_PTR(ptr, &k->exponent, k->exponentSize, alloc);
+}
+
+inline BYTE* pack_TPM_KEY_PARMS(BYTE* ptr, const TPM_KEY_PARMS* k) {
+   ptr = pack_TPM_ALGORITHM_ID(ptr, k->algorithmID);
+   ptr = pack_TPM_ENC_SCHEME(ptr, k->encScheme);
+   ptr = pack_TPM_SIG_SCHEME(ptr, k->sigScheme);
+   ptr = pack_UINT32(ptr, k->parmSize);
+
+   if(k->parmSize) {
+      switch(k->algorithmID) {
+         case TPM_ALG_RSA:
+            return pack_TPM_RSA_KEY_PARMS(ptr, &k->parms.rsa);
+         case TPM_ALG_AES128:
+         case TPM_ALG_AES192:
+         case TPM_ALG_AES256:
+            return pack_TPM_SYMMETRIC_KEY_PARMS(ptr, &k->parms.sym);
+      }
+   }
+   return ptr;
+}
+
+inline BYTE* unpack_TPM_KEY_PARMS(BYTE* ptr, TPM_KEY_PARMS* k, UnpackPtr alloc) {
+   ptr = unpack_TPM_ALGORITHM_ID(ptr, &k->algorithmID);
+   ptr = unpack_TPM_ENC_SCHEME(ptr, &k->encScheme);
+   ptr = unpack_TPM_SIG_SCHEME(ptr, &k->sigScheme);
+   ptr = unpack_UINT32(ptr, &k->parmSize);
+
+   if(k->parmSize) {
+      switch(k->algorithmID) {
+         case TPM_ALG_RSA:
+            return unpack_TPM_RSA_KEY_PARMS(ptr, &k->parms.rsa, alloc);
+         case TPM_ALG_AES128:
+         case TPM_ALG_AES192:
+         case TPM_ALG_AES256:
+            return unpack_TPM_SYMMETRIC_KEY_PARMS(ptr, &k->parms.sym, alloc);
+      }
+   }
+   return ptr;
+}
+
+inline BYTE* pack_TPM_STORE_PUBKEY(BYTE* ptr, const TPM_STORE_PUBKEY* k) {
+   ptr = pack_UINT32(ptr, k->keyLength);
+   ptr = pack_BUFFER(ptr, k->key, k->keyLength);
+   return ptr;
+}
+
+inline BYTE* unpack_TPM_STORE_PUBKEY(BYTE* ptr, TPM_STORE_PUBKEY* k, UnpackPtr alloc) {
+   ptr = unpack_UINT32(ptr, &k->keyLength);
+   ptr = unpack_PTR(ptr, &k->key, k->keyLength, alloc);
+   return ptr;
+}
+
+inline BYTE* pack_TPM_PUBKEY(BYTE* ptr, const TPM_PUBKEY* k) {
+   ptr = pack_TPM_KEY_PARMS(ptr, &k->algorithmParms);
+   return pack_TPM_STORE_PUBKEY(ptr, &k->pubKey);
+}
+
+inline BYTE* unpack_TPM_PUBKEY(BYTE* ptr, TPM_PUBKEY* k, UnpackPtr alloc) {
+   ptr = unpack_TPM_KEY_PARMS(ptr, &k->algorithmParms, alloc);
+   return unpack_TPM_STORE_PUBKEY(ptr, &k->pubKey, alloc);
+}
+
+inline BYTE* pack_TPM_PCR_SELECTION(BYTE* ptr, const TPM_PCR_SELECTION* p) {
+   ptr = pack_UINT16(ptr, p->sizeOfSelect);
+   ptr = pack_BUFFER(ptr, p->pcrSelect, p->sizeOfSelect);
+   return ptr;
+}
+
+inline BYTE* unpack_TPM_PCR_SELECTION(BYTE* ptr, TPM_PCR_SELECTION* p, UnpackPtr alloc) {
+   ptr = unpack_UINT16(ptr, &p->sizeOfSelect);
+   ptr = unpack_PTR(ptr, &p->pcrSelect, p->sizeOfSelect, alloc);
+   return ptr;
+}
+
+inline BYTE* pack_TPM_PCR_INFO(BYTE* ptr, const TPM_PCR_INFO* p) {
+   ptr = pack_TPM_PCR_SELECTION(ptr, &p->pcrSelection);
+   ptr = pack_TPM_COMPOSITE_HASH(ptr, &p->digestAtRelease);
+   ptr = pack_TPM_COMPOSITE_HASH(ptr, &p->digestAtCreation);
+   return ptr;
+}
+
+inline BYTE* unpack_TPM_PCR_INFO(BYTE* ptr, TPM_PCR_INFO* p, UnpackPtr alloc) {
+   ptr = unpack_TPM_PCR_SELECTION(ptr, &p->pcrSelection, alloc);
+   ptr = unpack_TPM_COMPOSITE_HASH(ptr, &p->digestAtRelease);
+   ptr = unpack_TPM_COMPOSITE_HASH(ptr, &p->digestAtCreation);
+   return ptr;
+}
+
+inline BYTE* pack_TPM_PCR_COMPOSITE(BYTE* ptr, const TPM_PCR_COMPOSITE* p) {
+   ptr = pack_TPM_PCR_SELECTION(ptr, &p->select);
+   ptr = pack_UINT32(ptr, p->valueSize);
+   ptr = pack_BUFFER(ptr, (const BYTE*)p->pcrValue, p->valueSize);
+   return ptr;
+}
+
+inline BYTE* unpack_TPM_PCR_COMPOSITE(BYTE* ptr, TPM_PCR_COMPOSITE* p, UnpackPtr alloc) {
+   ptr = unpack_TPM_PCR_SELECTION(ptr, &p->select, alloc);
+   ptr = unpack_UINT32(ptr, &p->valueSize);
+   ptr = unpack_PTR(ptr, (BYTE**)&p->pcrValue, p->valueSize, alloc);
+   return ptr;
+}
+
+inline BYTE* pack_TPM_KEY(BYTE* ptr, const TPM_KEY* k) {
+   ptr = pack_TPM_VERSION(ptr, &k->ver);
+   ptr = pack_TPM_KEY_USAGE(ptr, k->keyUsage);
+   ptr = pack_TPM_KEY_FLAGS(ptr, k->keyFlags);
+   ptr = pack_TPM_AUTH_DATA_USAGE(ptr, k->authDataUsage);
+   ptr = pack_TPM_KEY_PARMS(ptr, &k->algorithmParms);
+   ptr = pack_UINT32(ptr, k->PCRInfoSize);
+   if(k->PCRInfoSize) {
+      ptr = pack_TPM_PCR_INFO(ptr, &k->PCRInfo);
+   }
+   ptr = pack_TPM_STORE_PUBKEY(ptr, &k->pubKey);
+   ptr = pack_UINT32(ptr, k->encDataSize);
+   return pack_BUFFER(ptr, k->encData, k->encDataSize);
+}
+
+inline BYTE* unpack_TPM_KEY(BYTE* ptr, TPM_KEY* k, UnpackPtr alloc) {
+   ptr = unpack_TPM_VERSION(ptr, &k->ver);
+   ptr = unpack_TPM_KEY_USAGE(ptr, &k->keyUsage);
+   ptr = unpack_TPM_KEY_FLAGS(ptr, &k->keyFlags);
+   ptr = unpack_TPM_AUTH_DATA_USAGE(ptr, &k->authDataUsage);
+   ptr = unpack_TPM_KEY_PARMS(ptr, &k->algorithmParms, alloc);
+   ptr = unpack_UINT32(ptr, &k->PCRInfoSize);
+   if(k->PCRInfoSize) {
+      ptr = unpack_TPM_PCR_INFO(ptr, &k->PCRInfo, alloc);
+   }
+   ptr = unpack_TPM_STORE_PUBKEY(ptr, &k->pubKey, alloc);
+   ptr = unpack_UINT32(ptr, &k->encDataSize);
+   return unpack_PTR(ptr, &k->encData, k->encDataSize, alloc);
+}
+
+inline BYTE* pack_TPM_BOUND_DATA(BYTE* ptr, const TPM_BOUND_DATA* b, UINT32 payloadSize) {
+   ptr = pack_TPM_VERSION(ptr, &b->ver);
+   ptr = pack_TPM_PAYLOAD_TYPE(ptr, b->payload);
+   return pack_BUFFER(ptr, b->payloadData, payloadSize);
+}
+
+inline BYTE* unpack_TPM_BOUND_DATA(BYTE* ptr, TPM_BOUND_DATA* b, UINT32 payloadSize, UnpackPtr alloc) {
+   ptr = unpack_TPM_VERSION(ptr, &b->ver);
+   ptr = unpack_TPM_PAYLOAD_TYPE(ptr, &b->payload);
+   return unpack_PTR(ptr, &b->payloadData, payloadSize, alloc);
+}
+
+inline BYTE* pack_TPM_STORED_DATA(BYTE* ptr, const TPM_STORED_DATA* d) {
+   ptr = pack_TPM_VERSION(ptr, &d->ver);
+   ptr = pack_UINT32(ptr, d->sealInfoSize);
+   if(d->sealInfoSize) {
+      ptr = pack_TPM_PCR_INFO(ptr, &d->sealInfo);
+   }
+   ptr = pack_UINT32(ptr, d->encDataSize);
+   ptr = pack_BUFFER(ptr, d->encData, d->encDataSize);
+   return ptr;
+}
+
+inline BYTE* unpack_TPM_STORED_DATA(BYTE* ptr, TPM_STORED_DATA* d, UnpackPtr alloc) {
+   ptr = unpack_TPM_VERSION(ptr, &d->ver);
+   ptr = unpack_UINT32(ptr, &d->sealInfoSize);
+   if(d->sealInfoSize) {
+      ptr = unpack_TPM_PCR_INFO(ptr, &d->sealInfo, alloc);
+   }
+   ptr = unpack_UINT32(ptr, &d->encDataSize);
+   ptr = unpack_PTR(ptr, &d->encData, d->encDataSize, alloc);
+   return ptr;
+}
+
+inline BYTE* pack_TPM_AUTH_SESSION(BYTE* ptr, const TPM_AUTH_SESSION* auth) {
+   ptr = pack_TPM_AUTH_HANDLE(ptr, auth->AuthHandle);
+   ptr = pack_TPM_NONCE(ptr, &auth->NonceOdd);
+   ptr = pack_BOOL(ptr, auth->fContinueAuthSession);
+   ptr = pack_TPM_AUTHDATA(ptr, &auth->HMAC);
+   return ptr;
+}
+
+inline BYTE* unpack_TPM_AUTH_SESSION(BYTE* ptr, TPM_AUTH_SESSION* auth) {
+   ptr = unpack_TPM_NONCE(ptr, &auth->NonceEven);
+   ptr = unpack_BOOL(ptr, &auth->fContinueAuthSession);
+   ptr = unpack_TPM_AUTHDATA(ptr, &auth->HMAC);
+   return ptr;
+}
+
+inline BYTE* pack_TPM_RQU_HEADER(BYTE* ptr,
+      TPM_TAG tag,
+      UINT32 size,
+      TPM_COMMAND_CODE ord) {
+   ptr = pack_UINT16(ptr, tag);
+   ptr = pack_UINT32(ptr, size);
+   return pack_UINT32(ptr, ord);
+}
+
+inline BYTE* unpack_TPM_RQU_HEADER(BYTE* ptr,
+      TPM_TAG* tag,
+      UINT32* size,
+      TPM_COMMAND_CODE* ord) {
+   ptr = unpack_UINT16(ptr, tag);
+   ptr = unpack_UINT32(ptr, size);
+   ptr = unpack_UINT32(ptr, ord);
+   return ptr;
+}
+
+#define pack_TPM_RSP_HEADER(p, t, s, r) pack_TPM_RQU_HEADER(p, t, s, r);
+#define unpack_TPM_RSP_HEADER(p, t, s, r) unpack_TPM_RQU_HEADER(p, t, s, r);
+
+#endif
diff --git a/stubdom/vtpmmgr/minios.cfg b/stubdom/vtpmmgr/minios.cfg
new file mode 100644
index 0000000..3fb383d
--- /dev/null
+++ b/stubdom/vtpmmgr/minios.cfg
@@ -0,0 +1,14 @@
+CONFIG_TPMFRONT=y
+CONFIG_TPM_TIS=y
+CONFIG_TPMBACK=y
+CONFIG_START_NETWORK=n
+CONFIG_TEST=n
+CONFIG_PCIFRONT=n
+CONFIG_BLKFRONT=y
+CONFIG_NETFRONT=n
+CONFIG_FBFRONT=n
+CONFIG_KBDFRONT=n
+CONFIG_CONSFRONT=n
+CONFIG_XENBUS=y
+CONFIG_LWIP=n
+CONFIG_XC=n
diff --git a/stubdom/vtpmmgr/tcg.h b/stubdom/vtpmmgr/tcg.h
new file mode 100644
index 0000000..7687eae
--- /dev/null
+++ b/stubdom/vtpmmgr/tcg.h
@@ -0,0 +1,707 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense.  All rights reserved.
+ *
+ * based off of the original tools/vtpm_manager code base which is:
+ * Copyright (c) 2005 Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __TCG_H__
+#define __TCG_H__
+
+#include <stdlib.h>
+#include <stdint.h>
+
+// **************************** CONSTANTS *********************************
+
+// BOOL values
+#define TRUE 0x01
+#define FALSE 0x00
+
+#define TCPA_MAX_BUFFER_LENGTH 0x2000
+
+//
+// TPM_COMMAND_CODE values
+#define TPM_PROTECTED_ORDINAL 0x00000000UL
+#define TPM_UNPROTECTED_ORDINAL 0x80000000UL
+#define TPM_CONNECTION_ORDINAL 0x40000000UL
+#define TPM_VENDOR_ORDINAL 0x20000000UL
+
+#define TPM_ORD_OIAP                     (10UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_OSAP                     (11UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ChangeAuth               (12UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_TakeOwnership            (13UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ChangeAuthAsymStart      (14UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ChangeAuthAsymFinish     (15UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ChangeAuthOwner          (16UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Extend                   (20UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_PcrRead                  (21UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Quote                    (22UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Seal                     (23UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Unseal                   (24UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_DirWriteAuth             (25UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_DirRead                  (26UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_UnBind                   (30UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_CreateWrapKey            (31UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_LoadKey                  (32UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_GetPubKey                (33UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_EvictKey                 (34UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_CreateMigrationBlob      (40UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ReWrapKey                (41UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ConvertMigrationBlob     (42UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_AuthorizeMigrationKey    (43UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_CreateMaintenanceArchive (44UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_LoadMaintenanceArchive   (45UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_KillMaintenanceFeature   (46UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_LoadManuMaintPub         (47UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ReadManuMaintPub         (48UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_CertifyKey               (50UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Sign                     (60UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_GetRandom                (70UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_StirRandom               (71UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SelfTestFull             (80UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SelfTestStartup          (81UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_CertifySelfTest          (82UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ContinueSelfTest         (83UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_GetTestResult            (84UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Reset                    (90UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_OwnerClear               (91UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_DisableOwnerClear        (92UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ForceClear               (93UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_DisableForceClear        (94UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_GetCapabilitySigned      (100UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_GetCapability            (101UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_GetCapabilityOwner       (102UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_OwnerSetDisable          (110UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_PhysicalEnable           (111UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_PhysicalDisable          (112UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SetOwnerInstall          (113UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_PhysicalSetDeactivated   (114UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SetTempDeactivated       (115UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_CreateEndorsementKeyPair (120UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_MakeIdentity             (121UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ActivateIdentity         (122UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ReadPubek                (124UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_OwnerReadPubek           (125UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_DisablePubekRead         (126UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_GetAuditEvent            (130UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_GetAuditEventSigned      (131UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_GetOrdinalAuditStatus    (140UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SetOrdinalAuditStatus    (141UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Terminate_Handle         (150UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Init                     (151UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SaveState                (152UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Startup                  (153UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SetRedirection           (154UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SHA1Start                (160UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SHA1Update               (161UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SHA1Complete             (162UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SHA1CompleteExtend       (163UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_FieldUpgrade             (170UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SaveKeyContext           (180UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_LoadKeyContext           (181UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SaveAuthContext          (182UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_LoadAuthContext          (183UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SaveContext                      (184UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_LoadContext                      (185UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_FlushSpecific                    (186UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_PCR_Reset                        (200UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_NV_DefineSpace                   (204UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_NV_WriteValue                    (205UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_NV_WriteValueAuth                (206UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_NV_ReadValue                     (207UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_NV_ReadValueAuth                 (208UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Delegate_UpdateVerification      (209UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Delegate_Manage                  (210UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Delegate_CreateKeyDelegation     (212UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Delegate_CreateOwnerDelegation   (213UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Delegate_VerifyDelegation        (214UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Delegate_LoadOwnerDelegation     (216UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Delegate_ReadAuth                (217UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Delegate_ReadTable               (219UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_CreateCounter                    (220UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_IncrementCounter                 (221UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ReadCounter                      (222UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ReleaseCounter                   (223UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ReleaseCounterOwner              (224UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_EstablishTransport               (230UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ExecuteTransport                 (231UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ReleaseTransportSigned           (232UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_GetTicks                         (241UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_TickStampBlob                    (242UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_MAX                              (256UL + TPM_PROTECTED_ORDINAL)
+
+#define TSC_ORD_PhysicalPresence         (10UL + TPM_CONNECTION_ORDINAL)
+
+
+
+//
+// TPM_RESULT values
+//
+// just put in the whole table from spec 1.2
+
+#define TPM_BASE   0x0 // The start of TPM return codes
+#define TPM_VENDOR_ERROR 0x00000400 // Mask to indicate that the error code is vendor specific for vendor specific commands
+#define TPM_NON_FATAL  0x00000800 // Mask to indicate that the error code is a non-fatal failure.
+
+#define TPM_SUCCESS   TPM_BASE // Successful completion of the operation
+#define TPM_AUTHFAIL      TPM_BASE + 1 // Authentication failed
+#define TPM_BADINDEX      TPM_BASE + 2 // The index to a PCR, DIR or other register is incorrect
+#define TPM_BAD_PARAMETER     TPM_BASE + 3 // One or more parameter is bad
+#define TPM_AUDITFAILURE     TPM_BASE + 4 // An operation completed successfully but the auditing of that operation failed.
+#define TPM_CLEAR_DISABLED     TPM_BASE + 5 // The clear disable flag is set and all clear operations now require physical access
+#define TPM_DEACTIVATED     TPM_BASE + 6 // The TPM is deactivated
+#define TPM_DISABLED      TPM_BASE + 7 // The TPM is disabled
+#define TPM_DISABLED_CMD     TPM_BASE + 8 // The target command has been disabled
+#define TPM_FAIL       TPM_BASE + 9 // The operation failed
+#define TPM_BAD_ORDINAL     TPM_BASE + 10 // The ordinal was unknown or inconsistent
+#define TPM_INSTALL_DISABLED   TPM_BASE + 11 // The ability to install an owner is disabled
+#define TPM_INVALID_KEYHANDLE  TPM_BASE + 12 // The key handle presented was invalid
+#define TPM_KEYNOTFOUND     TPM_BASE + 13 // The target key was not found
+#define TPM_INAPPROPRIATE_ENC  TPM_BASE + 14 // Unacceptable encryption scheme
+#define TPM_MIGRATEFAIL     TPM_BASE + 15 // Migration authorization failed
+#define TPM_INVALID_PCR_INFO   TPM_BASE + 16 // PCR information could not be interpreted
+#define TPM_NOSPACE      TPM_BASE + 17 // No room to load key.
+#define TPM_NOSRK       TPM_BASE + 18 // There is no SRK set
+#define TPM_NOTSEALED_BLOB     TPM_BASE + 19 // An encrypted blob is invalid or was not created by this TPM
+#define TPM_OWNER_SET      TPM_BASE + 20 // There is already an Owner
+#define TPM_RESOURCES      TPM_BASE + 21 // The TPM has insufficient internal resources to perform the requested action.
+#define TPM_SHORTRANDOM     TPM_BASE + 22 // A random string was too short
+#define TPM_SIZE       TPM_BASE + 23 // The TPM does not have the space to perform the operation.
+#define TPM_WRONGPCRVAL     TPM_BASE + 24 // The named PCR value does not match the current PCR value.
+#define TPM_BAD_PARAM_SIZE     TPM_BASE + 25 // The paramSize argument to the command has the incorrect value
+#define TPM_SHA_THREAD      TPM_BASE + 26 // There is no existing SHA-1 thread.
+#define TPM_SHA_ERROR      TPM_BASE + 27 // The calculation is unable to proceed because the existing SHA-1 thread has already encountered an error.
+#define TPM_FAILEDSELFTEST     TPM_BASE + 28 // Self-test has failed and the TPM has shutdown.
+#define TPM_AUTH2FAIL      TPM_BASE + 29 // The authorization for the second key in a 2 key function failed authorization
+#define TPM_BADTAG       TPM_BASE + 30 // The tag value sent to for a command is invalid
+#define TPM_IOERROR      TPM_BASE + 31 // An IO error occurred transmitting information to the TPM
+#define TPM_ENCRYPT_ERROR     TPM_BASE + 32 // The encryption process had a problem.
+#define TPM_DECRYPT_ERROR     TPM_BASE + 33 // The decryption process did not complete.
+#define TPM_INVALID_AUTHHANDLE TPM_BASE + 34 // An invalid handle was used.
+#define TPM_NO_ENDORSEMENT     TPM_BASE + 35 // The TPM does not a EK installed
+#define TPM_INVALID_KEYUSAGE   TPM_BASE + 36 // The usage of a key is not allowed
+#define TPM_WRONG_ENTITYTYPE   TPM_BASE + 37 // The submitted entity type is not allowed
+#define TPM_INVALID_POSTINIT   TPM_BASE + 38 // The command was received in the wrong sequence relative to TPM_Init and a subsequent TPM_Startup
+#define TPM_INAPPROPRIATE_SIG  TPM_BASE + 39 // Signed data cannot include additional DER information
+#define TPM_BAD_KEY_PROPERTY   TPM_BASE + 40 // The key properties in TPM_KEY_PARMs are not supported by this TPM
+
+#define TPM_BAD_MIGRATION      TPM_BASE + 41 // The migration properties of this key are incorrect.
+#define TPM_BAD_SCHEME       TPM_BASE + 42 // The signature or encryption scheme for this key is incorrect or not permitted in this situation.
+#define TPM_BAD_DATASIZE      TPM_BASE + 43 // The size of the data (or blob) parameter is bad or inconsistent with the referenced key
+#define TPM_BAD_MODE       TPM_BASE + 44 // A mode parameter is bad, such as capArea or subCapArea for TPM_GetCapability, phsicalPresence parameter for TPM_PhysicalPresence, or migrationType for TPM_CreateMigrationBlob.
+#define TPM_BAD_PRESENCE      TPM_BASE + 45 // Either the physicalPresence or physicalPresenceLock bits have the wrong value
+#define TPM_BAD_VERSION      TPM_BASE + 46 // The TPM cannot perform this version of the capability
+#define TPM_NO_WRAP_TRANSPORT     TPM_BASE + 47 // The TPM does not allow for wrapped transport sessions
+#define TPM_AUDITFAIL_UNSUCCESSFUL TPM_BASE + 48 // TPM audit construction failed and the underlying command was returning a failure code also
+#define TPM_AUDITFAIL_SUCCESSFUL   TPM_BASE + 49 // TPM audit construction failed and the underlying command was returning success
+#define TPM_NOTRESETABLE      TPM_BASE + 50 // Attempt to reset a PCR register that does not have the resettable attribute
+#define TPM_NOTLOCAL       TPM_BASE + 51 // Attempt to reset a PCR register that requires locality and locality modifier not part of command transport
+#define TPM_BAD_TYPE       TPM_BASE + 52 // Make identity blob not properly typed
+#define TPM_INVALID_RESOURCE     TPM_BASE + 53 // When saving context identified resource type does not match actual resource
+#define TPM_NOTFIPS       TPM_BASE + 54 // The TPM is attempting to execute a command only available when in FIPS mode
+#define TPM_INVALID_FAMILY      TPM_BASE + 55 // The command is attempting to use an invalid family ID
+#define TPM_NO_NV_PERMISSION     TPM_BASE + 56 // The permission to manipulate the NV storage is not available
+#define TPM_REQUIRES_SIGN      TPM_BASE + 57 // The operation requires a signed command
+#define TPM_KEY_NOTSUPPORTED     TPM_BASE + 58 // Wrong operation to load an NV key
+#define TPM_AUTH_CONFLICT      TPM_BASE + 59 // NV_LoadKey blob requires both owner and blob authorization
+#define TPM_AREA_LOCKED      TPM_BASE + 60 // The NV area is locked and not writtable
+#define TPM_BAD_LOCALITY      TPM_BASE + 61 // The locality is incorrect for the attempted operation
+#define TPM_READ_ONLY       TPM_BASE + 62 // The NV area is read only and can't be written to
+#define TPM_PER_NOWRITE      TPM_BASE + 63 // There is no protection on the write to the NV area
+#define TPM_FAMILYCOUNT      TPM_BASE + 64 // The family count value does not match
+#define TPM_WRITE_LOCKED      TPM_BASE + 65 // The NV area has already been written to
+#define TPM_BAD_ATTRIBUTES      TPM_BASE + 66 // The NV area attributes conflict
+#define TPM_INVALID_STRUCTURE     TPM_BASE + 67 // The structure tag and version are invalid or inconsistent
+#define TPM_KEY_OWNER_CONTROL     TPM_BASE + 68 // The key is under control of the TPM Owner and can only be evicted by the TPM Owner.
+#define TPM_BAD_COUNTER      TPM_BASE + 69 // The counter handle is incorrect
+#define TPM_NOT_FULLWRITE      TPM_BASE + 70 // The write is not a complete write of the area
+#define TPM_CONTEXT_GAP      TPM_BASE + 71 // The gap between saved context counts is too large
+#define TPM_MAXNVWRITES      TPM_BASE + 72 // The maximum number of NV writes without an owner has been exceeded
+#define TPM_NOOPERATOR       TPM_BASE + 73 // No operator authorization value is set
+#define TPM_RESOURCEMISSING     TPM_BASE + 74 // The resource pointed to by context is not loaded
+#define TPM_DELEGATE_LOCK      TPM_BASE + 75 // The delegate administration is locked
+#define TPM_DELEGATE_FAMILY     TPM_BASE + 76 // Attempt to manage a family other then the delegated family
+#define TPM_DELEGATE_ADMIN      TPM_BASE + 77 // Delegation table management not enabled
+#define TPM_TRANSPORT_EXCLUSIVE    TPM_BASE + 78 // There was a command executed outside of an exclusive transport session
+
+// TPM_STARTUP_TYPE values
+#define TPM_ST_CLEAR 0x0001
+#define TPM_ST_STATE 0x0002
+#define TPM_ST_DEACTIVATED 0x003
+
+// TPM_TAG values
+#define TPM_TAG_RQU_COMMAND 0x00c1
+#define TPM_TAG_RQU_AUTH1_COMMAND 0x00c2
+#define TPM_TAG_RQU_AUTH2_COMMAND 0x00c3
+#define TPM_TAG_RSP_COMMAND 0x00c4
+#define TPM_TAG_RSP_AUTH1_COMMAND 0x00c5
+#define TPM_TAG_RSP_AUTH2_COMMAND 0x00c6
+
+// TPM_PAYLOAD_TYPE values
+#define TPM_PT_ASYM 0x01
+#define TPM_PT_BIND 0x02
+#define TPM_PT_MIGRATE 0x03
+#define TPM_PT_MAINT 0x04
+#define TPM_PT_SEAL 0x05
+
+// TPM_ENTITY_TYPE values
+#define TPM_ET_KEYHANDLE 0x0001
+#define TPM_ET_OWNER 0x0002
+#define TPM_ET_DATA 0x0003
+#define TPM_ET_SRK 0x0004
+#define TPM_ET_KEY 0x0005
+
+/// TPM_ResourceTypes
+#define TPM_RT_KEY      0x00000001
+#define TPM_RT_AUTH     0x00000002
+#define TPM_RT_HASH     0x00000003
+#define TPM_RT_TRANS    0x00000004
+#define TPM_RT_CONTEXT  0x00000005
+#define TPM_RT_COUNTER  0x00000006
+#define TPM_RT_DELEGATE 0x00000007
+#define TPM_RT_DAA_TPM  0x00000008
+#define TPM_RT_DAA_V0   0x00000009
+#define TPM_RT_DAA_V1   0x0000000A
+
+
+
+// TPM_PROTOCOL_ID values
+#define TPM_PID_OIAP 0x0001
+#define TPM_PID_OSAP 0x0002
+#define TPM_PID_ADIP 0x0003
+#define TPM_PID_ADCP 0x0004
+#define TPM_PID_OWNER 0x0005
+
+// TPM_ALGORITHM_ID values
+#define TPM_ALG_RSA 0x00000001
+#define TPM_ALG_SHA 0x00000004
+#define TPM_ALG_HMAC 0x00000005
+#define TPM_ALG_AES128 0x00000006
+#define TPM_ALG_MFG1 0x00000007
+#define TPM_ALG_AES192 0x00000008
+#define TPM_ALG_AES256 0x00000009
+#define TPM_ALG_XOR 0x0000000A
+
+// TPM_ENC_SCHEME values
+#define TPM_ES_NONE 0x0001
+#define TPM_ES_RSAESPKCSv15 0x0002
+#define TPM_ES_RSAESOAEP_SHA1_MGF1 0x0003
+
+// TPM_SIG_SCHEME values
+#define TPM_SS_NONE 0x0001
+#define TPM_SS_RSASSAPKCS1v15_SHA1 0x0002
+#define TPM_SS_RSASSAPKCS1v15_DER 0x0003
+
+/*
+ * TPM_CAPABILITY_AREA Values for TPM_GetCapability ([TPM_Part2], Section 21.1)
+ */
+#define TPM_CAP_ORD                     0x00000001
+#define TPM_CAP_ALG                     0x00000002
+#define TPM_CAP_PID                     0x00000003
+#define TPM_CAP_FLAG                    0x00000004
+#define TPM_CAP_PROPERTY                0x00000005
+#define TPM_CAP_VERSION                 0x00000006
+#define TPM_CAP_KEY_HANDLE              0x00000007
+#define TPM_CAP_CHECK_LOADED            0x00000008
+#define TPM_CAP_SYM_MODE                0x00000009
+#define TPM_CAP_KEY_STATUS              0x0000000C
+#define TPM_CAP_NV_LIST                 0x0000000D
+#define TPM_CAP_MFR                     0x00000010
+#define TPM_CAP_NV_INDEX                0x00000011
+#define TPM_CAP_TRANS_ALG               0x00000012
+#define TPM_CAP_HANDLE                  0x00000014
+#define TPM_CAP_TRANS_ES                0x00000015
+#define TPM_CAP_AUTH_ENCRYPT            0x00000017
+#define TPM_CAP_SELECT_SIZE             0x00000018
+#define TPM_CAP_DA_LOGIC                0x00000019
+#define TPM_CAP_VERSION_VAL             0x0000001A
+
+/* subCap definitions ([TPM_Part2], Section 21.2) */
+#define TPM_CAP_PROP_PCR                0x00000101
+#define TPM_CAP_PROP_DIR                0x00000102
+#define TPM_CAP_PROP_MANUFACTURER       0x00000103
+#define TPM_CAP_PROP_KEYS               0x00000104
+#define TPM_CAP_PROP_MIN_COUNTER        0x00000107
+#define TPM_CAP_FLAG_PERMANENT          0x00000108
+#define TPM_CAP_FLAG_VOLATILE           0x00000109
+#define TPM_CAP_PROP_AUTHSESS           0x0000010A
+#define TPM_CAP_PROP_TRANSESS           0x0000010B
+#define TPM_CAP_PROP_COUNTERS           0x0000010C
+#define TPM_CAP_PROP_MAX_AUTHSESS       0x0000010D
+#define TPM_CAP_PROP_MAX_TRANSESS       0x0000010E
+#define TPM_CAP_PROP_MAX_COUNTERS       0x0000010F
+#define TPM_CAP_PROP_MAX_KEYS           0x00000110
+#define TPM_CAP_PROP_OWNER              0x00000111
+#define TPM_CAP_PROP_CONTEXT            0x00000112
+#define TPM_CAP_PROP_MAX_CONTEXT        0x00000113
+#define TPM_CAP_PROP_FAMILYROWS         0x00000114
+#define TPM_CAP_PROP_TIS_TIMEOUT        0x00000115
+#define TPM_CAP_PROP_STARTUP_EFFECT     0x00000116
+#define TPM_CAP_PROP_DELEGATE_ROW       0x00000117
+#define TPM_CAP_PROP_MAX_DAASESS        0x00000119
+#define TPM_CAP_PROP_DAASESS            0x0000011A
+#define TPM_CAP_PROP_CONTEXT_DIST       0x0000011B
+#define TPM_CAP_PROP_DAA_INTERRUPT      0x0000011C
+#define TPM_CAP_PROP_SESSIONS           0x0000011D
+#define TPM_CAP_PROP_MAX_SESSIONS       0x0000011E
+#define TPM_CAP_PROP_CMK_RESTRICTION    0x0000011F
+#define TPM_CAP_PROP_DURATION           0x00000120
+#define TPM_CAP_PROP_ACTIVE_COUNTER     0x00000122
+#define TPM_CAP_PROP_MAX_NV_AVAILABLE   0x00000123
+#define TPM_CAP_PROP_INPUT_BUFFER       0x00000124
+
+// TPM_KEY_USAGE values
+#define TPM_KEY_EK 0x0000
+#define TPM_KEY_SIGNING 0x0010
+#define TPM_KEY_STORAGE 0x0011
+#define TPM_KEY_IDENTITY 0x0012
+#define TPM_KEY_AUTHCHANGE 0X0013
+#define TPM_KEY_BIND 0x0014
+#define TPM_KEY_LEGACY 0x0015
+
+// TPM_AUTH_DATA_USAGE values
+#define TPM_AUTH_NEVER 0x00
+#define TPM_AUTH_ALWAYS 0x01
+
+// Key Handle of owner and srk
+#define TPM_OWNER_KEYHANDLE 0x40000001
+#define TPM_SRK_KEYHANDLE 0x40000000
+
+
+
+// *************************** TYPEDEFS *********************************
+typedef unsigned char BYTE;
+typedef unsigned char BOOL;
+typedef uint16_t UINT16;
+typedef uint32_t UINT32;
+typedef uint64_t UINT64;
+
+typedef UINT32 TPM_RESULT;
+typedef UINT32 TPM_PCRINDEX;
+typedef UINT32 TPM_DIRINDEX;
+typedef UINT32 TPM_HANDLE;
+typedef TPM_HANDLE TPM_AUTHHANDLE;
+typedef TPM_HANDLE TCPA_HASHHANDLE;
+typedef TPM_HANDLE TCPA_HMACHANDLE;
+typedef TPM_HANDLE TCPA_ENCHANDLE;
+typedef TPM_HANDLE TPM_KEY_HANDLE;
+typedef TPM_HANDLE TCPA_ENTITYHANDLE;
+typedef UINT32 TPM_RESOURCE_TYPE;
+typedef UINT32 TPM_COMMAND_CODE;
+typedef UINT16 TPM_PROTOCOL_ID;
+typedef BYTE TPM_AUTH_DATA_USAGE;
+typedef UINT16 TPM_ENTITY_TYPE;
+typedef UINT32 TPM_ALGORITHM_ID;
+typedef UINT16 TPM_KEY_USAGE;
+typedef UINT16 TPM_STARTUP_TYPE;
+typedef UINT32 TPM_CAPABILITY_AREA;
+typedef UINT16 TPM_ENC_SCHEME;
+typedef UINT16 TPM_SIG_SCHEME;
+typedef UINT16 TPM_MIGRATE_SCHEME;
+typedef UINT16 TPM_PHYSICAL_PRESENCE;
+typedef UINT32 TPM_KEY_FLAGS;
+
+#define TPM_DIGEST_SIZE 20  // Don't change this
+typedef BYTE TPM_AUTHDATA[TPM_DIGEST_SIZE];
+typedef TPM_AUTHDATA TPM_SECRET;
+typedef TPM_AUTHDATA TPM_ENCAUTH;
+typedef BYTE TPM_PAYLOAD_TYPE;
+typedef UINT16 TPM_TAG;
+typedef UINT16 TPM_STRUCTURE_TAG;
+
+// Data Types of the TCS
+typedef UINT32 TCS_AUTHHANDLE;  // Handle addressing a authorization session
+typedef UINT32 TCS_CONTEXT_HANDLE; // Basic context handle
+typedef UINT32 TCS_KEY_HANDLE;  // Basic key handle
+
+// ************************* STRUCTURES **********************************
+
+typedef struct TPM_VERSION {
+  BYTE major;
+  BYTE minor;
+  BYTE revMajor;
+  BYTE revMinor;
+} TPM_VERSION;
+
+static const TPM_VERSION TPM_STRUCT_VER_1_1 = { 1,1,0,0 };
+
+typedef struct TPM_CAP_VERSION_INFO {
+   TPM_STRUCTURE_TAG tag;
+   TPM_VERSION version;
+   UINT16 specLevel;
+   BYTE errataRev;
+   BYTE tpmVendorID[4];
+   UINT16 vendorSpecificSize;
+   BYTE* vendorSpecific;
+} TPM_CAP_VERSION_INFO;
+
+inline void free_TPM_CAP_VERSION_INFO(TPM_CAP_VERSION_INFO* v) {
+   free(v->vendorSpecific);
+   v->vendorSpecific = NULL;
+}
+
+typedef struct TPM_DIGEST {
+  BYTE digest[TPM_DIGEST_SIZE];
+} TPM_DIGEST;
+
+typedef TPM_DIGEST TPM_PCRVALUE;
+typedef TPM_DIGEST TPM_COMPOSITE_HASH;
+typedef TPM_DIGEST TPM_DIRVALUE;
+typedef TPM_DIGEST TPM_HMAC;
+typedef TPM_DIGEST TPM_CHOSENID_HASH;
+
+typedef struct TPM_NONCE {
+  BYTE nonce[TPM_DIGEST_SIZE];
+} TPM_NONCE;
+
+typedef struct TPM_SYMMETRIC_KEY_PARMS {
+   UINT32 keyLength;
+   UINT32 blockSize;
+   UINT32 ivSize;
+   BYTE* IV;
+} TPM_SYMMETRIC_KEY_PARMS;
+
+inline void free_TPM_SYMMETRIC_KEY_PARMS(TPM_SYMMETRIC_KEY_PARMS* p) {
+   free(p->IV);
+   p->IV = NULL;
+}
+
+#define TPM_SYMMETRIC_KEY_PARMS_INIT { 0, 0, 0, NULL }
+
+typedef struct TPM_RSA_KEY_PARMS {
+  UINT32 keyLength;
+  UINT32 numPrimes;
+  UINT32 exponentSize;
+  BYTE* exponent;
+} TPM_RSA_KEY_PARMS;
+
+#define TPM_RSA_KEY_PARMS_INIT { 0, 0, 0, NULL }
+
+inline void free_TPM_RSA_KEY_PARMS(TPM_RSA_KEY_PARMS* p) {
+   free(p->exponent);
+   p->exponent = NULL;
+}
+
+typedef struct TPM_KEY_PARMS {
+  TPM_ALGORITHM_ID algorithmID;
+  TPM_ENC_SCHEME encScheme;
+  TPM_SIG_SCHEME sigScheme;
+  UINT32 parmSize;
+  union {
+     TPM_SYMMETRIC_KEY_PARMS sym;
+     TPM_RSA_KEY_PARMS rsa;
+  } parms;
+} TPM_KEY_PARMS;
+
+#define TPM_KEY_PARMS_INIT { 0, 0, 0, 0 }
+
+inline void free_TPM_KEY_PARMS(TPM_KEY_PARMS* p) {
+   if(p->parmSize) {
+      switch(p->algorithmID) {
+         case TPM_ALG_RSA:
+            free_TPM_RSA_KEY_PARMS(&p->parms.rsa);
+            break;
+         case TPM_ALG_AES128:
+         case TPM_ALG_AES192:
+         case TPM_ALG_AES256:
+            free_TPM_SYMMETRIC_KEY_PARMS(&p->parms.sym);
+            break;
+      }
+   }
+}
+
+typedef struct TPM_STORE_PUBKEY {
+  UINT32 keyLength;
+  BYTE* key;
+} TPM_STORE_PUBKEY;
+
+#define TPM_STORE_PUBKEY_INIT { 0, NULL }
+
+inline void free_TPM_STORE_PUBKEY(TPM_STORE_PUBKEY* p) {
+   free(p->key);
+   p->key = NULL;
+}
+
+typedef struct TPM_PUBKEY {
+  TPM_KEY_PARMS algorithmParms;
+  TPM_STORE_PUBKEY pubKey;
+} TPM_PUBKEY;
+
+#define TPM_PUBKEY_INIT { TPM_KEY_PARMS_INIT, TPM_STORE_PUBKEY_INIT }
+
+inline void free_TPM_PUBKEY(TPM_PUBKEY* k) {
+   free_TPM_KEY_PARMS(&k->algorithmParms);
+   free_TPM_STORE_PUBKEY(&k->pubKey);
+}
+
+typedef struct TPM_PCR_SELECTION {
+   UINT16 sizeOfSelect;
+   BYTE* pcrSelect;
+} TPM_PCR_SELECTION;
+
+#define TPM_PCR_SELECTION_INIT { 0, NULL }
+
+inline void free_TPM_PCR_SELECTION(TPM_PCR_SELECTION* p) {
+   free(p->pcrSelect);
+   p->pcrSelect = NULL;
+}
+
+typedef struct TPM_PCR_INFO {
+   TPM_PCR_SELECTION pcrSelection;
+   TPM_COMPOSITE_HASH digestAtRelease;
+   TPM_COMPOSITE_HASH digestAtCreation;
+} TPM_PCR_INFO;
+
+#define TPM_PCR_INFO_INIT { TPM_PCR_SELECTION_INIT }
+
+inline void free_TPM_PCR_INFO(TPM_PCR_INFO* p) {
+   free_TPM_PCR_SELECTION(&p->pcrSelection);
+}
+
+typedef struct TPM_PCR_COMPOSITE {
+  TPM_PCR_SELECTION select;
+  UINT32 valueSize;
+  TPM_PCRVALUE* pcrValue;
+} TPM_PCR_COMPOSITE;
+
+#define TPM_PCR_COMPOSITE_INIT { TPM_PCR_SELECTION_INIT, 0, NULL }
+
+inline void free_TPM_PCR_COMPOSITE(TPM_PCR_COMPOSITE* p) {
+   free_TPM_PCR_SELECTION(&p->select);
+   free(p->pcrValue);
+   p->pcrValue = NULL;
+}
+
+typedef struct TPM_KEY {
+  TPM_VERSION         ver;
+  TPM_KEY_USAGE       keyUsage;
+  TPM_KEY_FLAGS       keyFlags;
+  TPM_AUTH_DATA_USAGE authDataUsage;
+  TPM_KEY_PARMS       algorithmParms;
+  UINT32              PCRInfoSize;
+  TPM_PCR_INFO        PCRInfo;
+  TPM_STORE_PUBKEY    pubKey;
+  UINT32              encDataSize;
+  BYTE*               encData;
+} TPM_KEY;
+
+#define TPM_KEY_INIT { .algorithmParms = TPM_KEY_PARMS_INIT,\
+   .PCRInfoSize = 0, .PCRInfo = TPM_PCR_INFO_INIT, \
+   .pubKey = TPM_STORE_PUBKEY_INIT, \
+   .encDataSize = 0, .encData = NULL }
+
+inline void free_TPM_KEY(TPM_KEY* k) {
+   if(k->PCRInfoSize) {
+      free_TPM_PCR_INFO(&k->PCRInfo);
+   }
+   free_TPM_STORE_PUBKEY(&k->pubKey);
+   free(k->encData);
+   k->encData = NULL;
+}
+
+typedef struct TPM_BOUND_DATA {
+  TPM_VERSION ver;
+  TPM_PAYLOAD_TYPE payload;
+  BYTE* payloadData;
+} TPM_BOUND_DATA;
+
+#define TPM_BOUND_DATA_INIT { .payloadData = NULL }
+
+inline void free_TPM_BOUND_DATA(TPM_BOUND_DATA* d) {
+   free(d->payloadData);
+   d->payloadData = NULL;
+}
+
+typedef struct TPM_STORED_DATA {
+  TPM_VERSION ver;
+  UINT32 sealInfoSize;
+  TPM_PCR_INFO sealInfo;
+  UINT32 encDataSize;
+  BYTE* encData;
+} TPM_STORED_DATA;
+
+#define TPM_STORED_DATA_INIT { .sealInfoSize = 0, sealInfo = TPM_PCR_INFO_INIT,\
+   .encDataSize = 0, .encData = NULL }
+
+inline void free_TPM_STORED_DATA(TPM_STORED_DATA* d) {
+   if(d->sealInfoSize) {
+      free_TPM_PCR_INFO(&d->sealInfo);
+   }
+   free(d->encData);
+   d->encData = NULL;
+}
+
+typedef struct TPM_AUTH_SESSION {
+  TPM_AUTHHANDLE  AuthHandle;
+  TPM_NONCE   NonceOdd;   // system
+  TPM_NONCE   NonceEven;   // TPM
+  BOOL   fContinueAuthSession;
+  TPM_AUTHDATA  HMAC;
+} TPM_AUTH_SESSION;
+
+#define TPM_AUTH_SESSION_INIT { .AuthHandle = 0, .fContinueAuthSession = FALSE }
+
+// ---------------------- Functions for checking TPM_RESULTs -----------------
+
+#include <stdio.h>
+
+// FIXME: Review use of these and delete unneeded ones.
+
+// these are really badly dependent on local structure:
+// DEPENDS: local var 'status' of type TPM_RESULT
+// DEPENDS: label 'abort_egress' which cleans up and returns the status
+#define ERRORDIE(s) do { status = s; \
+                         fprintf (stderr, "*** ERRORDIE in %s at %s: %i\n", __func__, __FILE__, __LINE__); \
+                         goto abort_egress; } \
+                    while (0)
+
+// DEPENDS: local var 'status' of type TPM_RESULT
+// DEPENDS: label 'abort_egress' which cleans up and returns the status
+// Try command c. If it fails, set status to s and goto abort.
+#define TPMTRY(s,c) if (c != TPM_SUCCESS) { \
+                       status = s; \
+                       printf("ERROR in %s at %s:%i code: %s.\n", __func__, __FILE__, __LINE__, tpm_get_error_name(status)); \
+                       goto abort_egress; \
+                    } else {\
+                       status = c; \
+                    }
+
+// Try command c. If it fails, print error message, set status to actual return code. Goto abort
+#define TPMTRYRETURN(c) do { status = c; \
+                             if (status != TPM_SUCCESS) { \
+                               fprintf(stderr, "ERROR in %s at %s:%i code: %s.\n", __func__, __FILE__, __LINE__, tpm_get_error_name(status)); \
+                               goto abort_egress; \
+                             } \
+                        } while(0)
+
+
+#endif //__TCPA_H__
diff --git a/stubdom/vtpmmgr/tpm.c b/stubdom/vtpmmgr/tpm.c
new file mode 100644
index 0000000..123a27c
--- /dev/null
+++ b/stubdom/vtpmmgr/tpm.c
@@ -0,0 +1,938 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense.  All rights reserved.
+ *
+ * based off of the original tools/vtpm_manager code base which is:
+ * Copyright (c) 2005, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <polarssl/sha1.h>
+
+#include "tcg.h"
+#include "tpm.h"
+#include "log.h"
+#include "marshal.h"
+#include "tpmrsa.h"
+#include "vtpmmgr.h"
+
+#define TCPA_MAX_BUFFER_LENGTH 0x2000
+
+#define TPM_BEGIN(TAG, ORD) \
+   const TPM_TAG intag = TAG;\
+TPM_TAG tag = intag;\
+UINT32 paramSize;\
+const TPM_COMMAND_CODE ordinal = ORD;\
+TPM_RESULT status = TPM_SUCCESS;\
+BYTE in_buf[TCPA_MAX_BUFFER_LENGTH];\
+BYTE out_buf[TCPA_MAX_BUFFER_LENGTH];\
+UINT32 out_len = sizeof(out_buf);\
+BYTE* ptr = in_buf;\
+/*Print a log message */\
+vtpmloginfo(VTPM_LOG_TPM, "%s\n", __func__);\
+/* Pack the header*/\
+ptr = pack_TPM_TAG(ptr, tag);\
+ptr += sizeof(UINT32);\
+ptr = pack_TPM_COMMAND_CODE(ptr, ordinal)\
+
+#define TPM_AUTH_BEGIN() \
+   sha1_context sha1_ctx;\
+BYTE* authbase = ptr - sizeof(TPM_COMMAND_CODE);\
+TPM_DIGEST paramDigest;\
+sha1_starts(&sha1_ctx)
+
+#define TPM_AUTH1_GEN(HMACkey, auth) do {\
+   sha1_finish(&sha1_ctx, paramDigest.digest);\
+   generateAuth(&paramDigest, HMACkey, auth);\
+   ptr = pack_TPM_AUTH_SESSION(ptr, auth);\
+} while(0)
+
+#define TPM_AUTH2_GEN(HMACkey, auth) do {\
+   generateAuth(&paramDigest, HMACkey, auth);\
+   ptr = pack_TPM_AUTH_SESSION(ptr, auth);\
+} while(0)
+
+#define TPM_TRANSMIT() do {\
+   /* Pack the command size */\
+   paramSize = ptr - in_buf;\
+   pack_UINT32(in_buf + sizeof(TPM_TAG), paramSize);\
+   if((status = TPM_TransmitData(in_buf, paramSize, out_buf, &out_len)) != TPM_SUCCESS) {\
+      goto abort_egress;\
+   }\
+} while(0)
+
+#define TPM_AUTH_VERIFY_BEGIN() do {\
+   UINT32 buf[2] = { cpu_to_be32(status), cpu_to_be32(ordinal) };\
+   sha1_starts(&sha1_ctx);\
+   sha1_update(&sha1_ctx, (unsigned char*)buf, sizeof(buf));\
+   authbase = ptr;\
+} while(0)
+
+#define TPM_AUTH1_VERIFY(HMACkey, auth) do {\
+   sha1_finish(&sha1_ctx, paramDigest.digest);\
+   ptr = unpack_TPM_AUTH_SESSION(ptr, auth);\
+   if((status = verifyAuth(&paramDigest, HMACkey, auth)) != TPM_SUCCESS) {\
+      goto abort_egress;\
+   }\
+} while(0)
+
+#define TPM_AUTH2_VERIFY(HMACkey, auth) do {\
+   ptr = unpack_TPM_AUTH_SESSION(ptr, auth);\
+   if((status = verifyAuth(&paramDigest, HMACkey, auth)) != TPM_SUCCESS) {\
+      goto abort_egress;\
+   }\
+} while(0)
+
+
+
+#define TPM_UNPACK_VERIFY() do { \
+   ptr = out_buf;\
+   ptr = unpack_TPM_RSP_HEADER(ptr, \
+         &(tag), &(paramSize), &(status));\
+   if((status) != TPM_SUCCESS || (tag) != (intag +3)) { \
+      vtpmlogerror(VTPM_LOG_TPM, "Failed with return code %s\n", tpm_get_error_name(status));\
+      goto abort_egress;\
+   }\
+} while(0)
+
+#define TPM_AUTH_HASH() do {\
+   sha1_update(&sha1_ctx, authbase, ptr - authbase);\
+   authbase = ptr;\
+} while(0)
+
+#define TPM_AUTH_SKIP() do {\
+   authbase = ptr;\
+} while(0)
+
+#define TPM_AUTH_ERR_CHECK(auth) do {\
+   if(status != TPM_SUCCESS || auth->fContinueAuthSession == FALSE) {\
+      vtpmloginfo(VTPM_LOG_TPM, "Auth Session: 0x%x closed by TPM\n", auth->AuthHandle);\
+      auth->AuthHandle = 0;\
+   }\
+} while(0)
+
+static void xorEncrypt(const TPM_SECRET* sharedSecret,
+      TPM_NONCE* nonce,
+      const TPM_AUTHDATA* inAuth0,
+      TPM_ENCAUTH outAuth0,
+      const TPM_AUTHDATA* inAuth1,
+      TPM_ENCAUTH outAuth1) {
+   BYTE XORbuffer[sizeof(TPM_SECRET) + sizeof(TPM_NONCE)];
+   BYTE XORkey[TPM_DIGEST_SIZE];
+   BYTE* ptr = XORbuffer;
+   ptr = pack_TPM_SECRET(ptr, sharedSecret);
+   ptr = pack_TPM_NONCE(ptr, nonce);
+
+   sha1(XORbuffer, ptr - XORbuffer, XORkey);
+
+   if(inAuth0) {
+      for(int i = 0; i < TPM_DIGEST_SIZE; ++i) {
+         outAuth0[i] = XORkey[i] ^ (*inAuth0)[i];
+      }
+   }
+   if(inAuth1) {
+      for(int i = 0; i < TPM_DIGEST_SIZE; ++i) {
+         outAuth1[i] = XORkey[i] ^ (*inAuth1)[i];
+      }
+   }
+
+}
+
+static void generateAuth(const TPM_DIGEST* paramDigest,
+      const TPM_SECRET* HMACkey,
+      TPM_AUTH_SESSION *auth)
+{
+   //Generate new OddNonce
+   vtpmmgr_rand((BYTE*)auth->NonceOdd.nonce, sizeof(TPM_NONCE));
+
+   // Create HMAC text. (Concat inParamsDigest with inAuthSetupParams).
+   BYTE hmacText[sizeof(TPM_DIGEST) + (2 * sizeof(TPM_NONCE)) + sizeof(BOOL)];
+   BYTE* ptr = hmacText;
+
+   ptr = pack_TPM_DIGEST(ptr, paramDigest);
+   ptr = pack_TPM_NONCE(ptr, &auth->NonceEven);
+   ptr = pack_TPM_NONCE(ptr, &auth->NonceOdd);
+   ptr = pack_BOOL(ptr, auth->fContinueAuthSession);
+
+   sha1_hmac((BYTE *) HMACkey, sizeof(TPM_DIGEST),
+         (BYTE *) hmacText, sizeof(hmacText),
+         auth->HMAC);
+}
+
+static TPM_RESULT verifyAuth(const TPM_DIGEST* paramDigest,
+      /*[IN]*/ const TPM_SECRET *HMACkey,
+      /*[IN,OUT]*/ TPM_AUTH_SESSION *auth)
+{
+
+   // Create HMAC text. (Concat inParamsDigest with inAuthSetupParams).
+   TPM_AUTHDATA hm;
+   BYTE hmacText[sizeof(TPM_DIGEST) + (2 * sizeof(TPM_NONCE)) + sizeof(BOOL)];
+   BYTE* ptr = hmacText;
+
+   ptr = pack_TPM_DIGEST(ptr, paramDigest);
+   ptr = pack_TPM_NONCE(ptr, &auth->NonceEven);
+   ptr = pack_TPM_NONCE(ptr, &auth->NonceOdd);
+   ptr = pack_BOOL(ptr, auth->fContinueAuthSession);
+
+   sha1_hmac( (BYTE *) HMACkey, sizeof(TPM_DIGEST),
+         (BYTE *) hmacText, sizeof(hmacText),
+         hm);
+
+   // Compare correct HMAC with provided one.
+   if (memcmp(hm, auth->HMAC, sizeof(TPM_DIGEST)) == 0) { // 0 indicates equality
+      return TPM_SUCCESS;
+   } else {
+      vtpmlogerror(VTPM_LOG_TPM, "Auth Session verification failed!\n");
+      return TPM_AUTHFAIL;
+   }
+}
+
+
+
+// ------------------------------------------------------------------
+// Authorization Commands
+// ------------------------------------------------------------------
+
+TPM_RESULT TPM_OIAP(TPM_AUTH_SESSION*   auth)  // out
+{
+   TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_OIAP);
+
+   TPM_TRANSMIT();
+   TPM_UNPACK_VERIFY();
+
+   memset(&auth->HMAC, 0, sizeof(TPM_DIGEST));
+   auth->fContinueAuthSession = TRUE;
+
+   ptr = unpack_UINT32(ptr, &auth->AuthHandle);
+   ptr = unpack_TPM_NONCE(ptr, &auth->NonceEven);
+
+   vtpmloginfo(VTPM_LOG_TPM, "Auth Session: 0x%x opened by TPM_OIAP.\n", auth->AuthHandle);
+
+abort_egress:
+   return status;
+}
+
+TPM_RESULT TPM_OSAP(TPM_ENTITY_TYPE  entityType,  // in
+      UINT32    entityValue, // in
+      const TPM_AUTHDATA* usageAuth, //in
+      TPM_SECRET *sharedSecret, //out
+      TPM_AUTH_SESSION *auth)
+{
+   BYTE* nonceOddOSAP;
+   TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_OSAP);
+
+   ptr = pack_TPM_ENTITY_TYPE(ptr, entityType);
+   ptr = pack_UINT32(ptr, entityValue);
+
+   //nonce Odd OSAP
+   nonceOddOSAP = ptr;
+   vtpmmgr_rand(ptr, TPM_DIGEST_SIZE);
+   ptr += TPM_DIGEST_SIZE;
+
+   TPM_TRANSMIT();
+   TPM_UNPACK_VERIFY();
+
+   ptr = unpack_UINT32(ptr, &auth->AuthHandle);
+   ptr = unpack_TPM_NONCE(ptr, &auth->NonceEven);
+
+   //Calculate session secret
+   sha1_context ctx;
+   sha1_hmac_starts(&ctx, *usageAuth, TPM_DIGEST_SIZE);
+   sha1_hmac_update(&ctx, ptr, TPM_DIGEST_SIZE); //ptr = nonceEvenOSAP
+   sha1_hmac_update(&ctx, nonceOddOSAP, TPM_DIGEST_SIZE);
+   sha1_hmac_finish(&ctx, *sharedSecret);
+
+   memset(&auth->HMAC, 0, sizeof(TPM_DIGEST));
+   auth->fContinueAuthSession = FALSE;
+
+   vtpmloginfo(VTPM_LOG_TPM, "Auth Session: 0x%x opened by TPM_OSAP.\n", auth->AuthHandle);
+
+abort_egress:
+   return status;
+}
+
+TPM_RESULT TPM_TakeOwnership(
+      const TPM_PUBKEY *pubEK, //in
+      const TPM_AUTHDATA* ownerAuth, //in
+      const TPM_AUTHDATA* srkAuth, //in
+      const TPM_KEY* inSrk, //in
+      TPM_KEY* outSrk, //out, optional
+      TPM_AUTH_SESSION*   auth)   // in, out
+{
+   int keyAlloced = 0;
+   tpmrsa_context ek_rsa = TPMRSA_CTX_INIT;
+
+   TPM_BEGIN(TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_TakeOwnership);
+   TPM_AUTH_BEGIN();
+
+   tpmrsa_set_pubkey(&ek_rsa,
+         pubEK->pubKey.key, pubEK->pubKey.keyLength,
+         pubEK->algorithmParms.parms.rsa.exponent,
+         pubEK->algorithmParms.parms.rsa.exponentSize);
+
+   /* Pack the protocol ID */
+   ptr = pack_UINT16(ptr, TPM_PID_OWNER);
+
+   /* Pack the encrypted owner auth */
+   ptr = pack_UINT32(ptr, pubEK->algorithmParms.parms.rsa.keyLength / 8);
+   tpmrsa_pub_encrypt_oaep(&ek_rsa,
+         ctr_drbg_random, &vtpm_globals.ctr_drbg,
+         sizeof(TPM_SECRET),
+         (BYTE*) ownerAuth,
+         ptr);
+   ptr += pubEK->algorithmParms.parms.rsa.keyLength / 8;
+
+   /* Pack the encrypted srk auth */
+   ptr = pack_UINT32(ptr, pubEK->algorithmParms.parms.rsa.keyLength / 8);
+   tpmrsa_pub_encrypt_oaep(&ek_rsa,
+         ctr_drbg_random, &vtpm_globals.ctr_drbg,
+         sizeof(TPM_SECRET),
+         (BYTE*) srkAuth,
+         ptr);
+   ptr += pubEK->algorithmParms.parms.rsa.keyLength / 8;
+
+   /* Pack the Srk key */
+   ptr = pack_TPM_KEY(ptr, inSrk);
+
+   /* Hash everything up to here */
+   TPM_AUTH_HASH();
+
+   /* Generate the authorization */
+   TPM_AUTH1_GEN(ownerAuth, auth);
+
+   /* Send the command to the tpm*/
+   TPM_TRANSMIT();
+   /* Unpack and validate the header */
+   TPM_UNPACK_VERIFY();
+   TPM_AUTH_VERIFY_BEGIN();
+
+   if(outSrk != NULL) {
+      /* If the user wants a copy of the srk we give it to them */
+      keyAlloced = 1;
+      ptr = unpack_TPM_KEY(ptr, outSrk, UNPACK_ALLOC);
+   } else {
+      /*otherwise just parse past it */
+      TPM_KEY temp;
+      ptr = unpack_TPM_KEY(ptr, &temp, UNPACK_ALIAS);
+   }
+
+   /* Hash the output key */
+   TPM_AUTH_HASH();
+
+   /* Verify authorizaton */
+   TPM_AUTH1_VERIFY(ownerAuth, auth);
+
+   goto egress;
+abort_egress:
+   if(keyAlloced) {
+      free_TPM_KEY(outSrk);
+   }
+egress:
+   tpmrsa_free(&ek_rsa);
+   TPM_AUTH_ERR_CHECK(auth);
+   return status;
+}
+
+
+TPM_RESULT TPM_DisablePubekRead (
+      const TPM_AUTHDATA* ownerAuth,
+      TPM_AUTH_SESSION*   auth)
+{
+   TPM_BEGIN(TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_DisablePubekRead);
+   TPM_AUTH_BEGIN();
+
+   TPM_AUTH_HASH();
+
+   TPM_AUTH1_GEN(ownerAuth, auth);
+   TPM_TRANSMIT();
+   TPM_UNPACK_VERIFY();
+   TPM_AUTH_VERIFY_BEGIN();
+
+   TPM_AUTH1_VERIFY(ownerAuth, auth);
+
+abort_egress:
+   TPM_AUTH_ERR_CHECK(auth);
+   return status;
+}
+
+
+TPM_RESULT TPM_TerminateHandle(TPM_AUTHHANDLE  handle)  // in
+{
+   if(handle == 0) {
+      return TPM_SUCCESS;
+   }
+
+   TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_Terminate_Handle);
+
+   ptr = pack_TPM_AUTHHANDLE(ptr, handle);
+
+   TPM_TRANSMIT();
+   TPM_UNPACK_VERIFY();
+
+   vtpmloginfo(VTPM_LOG_TPM, "Auth Session: 0x%x closed by TPM_TerminateHandle\n", handle);
+
+abort_egress:
+   return status;
+}
+
+TPM_RESULT TPM_Extend( TPM_PCRINDEX  pcrNum,  // in
+      TPM_DIGEST  inDigest, // in
+      TPM_PCRVALUE*  outDigest) // out
+{
+   TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_Extend);
+
+   ptr = pack_TPM_PCRINDEX(ptr, pcrNum);
+   ptr = pack_TPM_DIGEST(ptr, &inDigest);
+
+   TPM_TRANSMIT();
+   TPM_UNPACK_VERIFY();
+
+   ptr = unpack_TPM_PCRVALUE(ptr, outDigest);
+
+abort_egress:
+   return status;
+}
+
+TPM_RESULT TPM_Seal(
+      TPM_KEY_HANDLE  keyHandle,  // in
+      UINT32    pcrInfoSize, // in
+      TPM_PCR_INFO*    pcrInfo,  // in
+      UINT32    inDataSize,  // in
+      const BYTE*    inData,   // in
+      TPM_STORED_DATA* sealedData, //out
+      const TPM_SECRET* osapSharedSecret, //in
+      const TPM_AUTHDATA* sealedDataAuth, //in
+      TPM_AUTH_SESSION*   pubAuth  // in, out
+      )
+{
+   int dataAlloced = 0;
+   TPM_BEGIN(TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_Seal);
+   TPM_AUTH_BEGIN();
+
+   TPM_AUTH_HASH();
+
+   ptr = pack_TPM_KEY_HANDLE(ptr, keyHandle);
+
+   TPM_AUTH_SKIP();
+
+   xorEncrypt(osapSharedSecret, &pubAuth->NonceEven,
+         sealedDataAuth, ptr,
+         NULL, NULL);
+   ptr += sizeof(TPM_ENCAUTH);
+
+   ptr = pack_UINT32(ptr, pcrInfoSize);
+   ptr = pack_TPM_PCR_INFO(ptr, pcrInfo);
+
+   ptr = pack_UINT32(ptr, inDataSize);
+   ptr = pack_BUFFER(ptr, inData, inDataSize);
+
+   TPM_AUTH_HASH();
+
+   TPM_AUTH1_GEN(osapSharedSecret, pubAuth);
+   TPM_TRANSMIT();
+   TPM_UNPACK_VERIFY();
+   TPM_AUTH_VERIFY_BEGIN();
+
+   ptr = unpack_TPM_STORED_DATA(ptr, sealedData, UNPACK_ALLOC);
+   dataAlloced = 1;
+
+   TPM_AUTH_HASH();
+
+   TPM_AUTH1_VERIFY(osapSharedSecret, pubAuth);
+
+   goto egress;
+abort_egress:
+   if(dataAlloced) {
+      free_TPM_STORED_DATA(sealedData);
+   }
+egress:
+   TPM_AUTH_ERR_CHECK(pubAuth);
+   return status;
+}
+
+TPM_RESULT TPM_Unseal(
+      TPM_KEY_HANDLE parentHandle, // in
+      const TPM_STORED_DATA* sealedData,
+      UINT32*   outSize,  // out
+      BYTE**    out, //out
+      const TPM_AUTHDATA* key_usage_auth, //in
+      const TPM_AUTHDATA* data_usage_auth, //in
+      TPM_AUTH_SESSION*   keyAuth,  // in, out
+      TPM_AUTH_SESSION*   dataAuth  // in, out
+      )
+{
+   TPM_BEGIN(TPM_TAG_RQU_AUTH2_COMMAND, TPM_ORD_Unseal);
+   TPM_AUTH_BEGIN();
+
+   TPM_AUTH_HASH();
+
+   ptr = pack_TPM_KEY_HANDLE(ptr, parentHandle);
+
+   TPM_AUTH_SKIP();
+
+   ptr = pack_TPM_STORED_DATA(ptr, sealedData);
+
+   TPM_AUTH_HASH();
+
+   TPM_AUTH1_GEN(key_usage_auth, keyAuth);
+   TPM_AUTH2_GEN(data_usage_auth, dataAuth);
+   TPM_TRANSMIT();
+   TPM_UNPACK_VERIFY();
+   TPM_AUTH_VERIFY_BEGIN();
+
+   ptr = unpack_UINT32(ptr, outSize);
+   ptr = unpack_ALLOC(ptr, out, *outSize);
+
+   TPM_AUTH_HASH();
+
+   TPM_AUTH1_VERIFY(key_usage_auth, keyAuth);
+   TPM_AUTH2_VERIFY(data_usage_auth, dataAuth);
+
+abort_egress:
+   TPM_AUTH_ERR_CHECK(keyAuth);
+   TPM_AUTH_ERR_CHECK(dataAuth);
+   return status;
+}
+
+TPM_RESULT TPM_Bind(
+      const TPM_KEY* key,
+      const BYTE* in,
+      UINT32 ilen,
+      BYTE* out)
+{
+   TPM_RESULT status;
+   tpmrsa_context rsa = TPMRSA_CTX_INIT;
+   TPM_BOUND_DATA boundData;
+   uint8_t plain[TCPA_MAX_BUFFER_LENGTH];
+   BYTE* ptr = plain;
+
+   vtpmloginfo(VTPM_LOG_TPM, "%s\n", __func__);
+
+   tpmrsa_set_pubkey(&rsa,
+         key->pubKey.key, key->pubKey.keyLength,
+         key->algorithmParms.parms.rsa.exponent,
+         key->algorithmParms.parms.rsa.exponentSize);
+
+   // Fill boundData's accessory information
+   boundData.ver = TPM_STRUCT_VER_1_1;
+   boundData.payload = TPM_PT_BIND;
+   boundData.payloadData = (BYTE*)in;
+
+   //marshall the bound data object
+   ptr = pack_TPM_BOUND_DATA(ptr, &boundData, ilen);
+
+   // Encrypt the data
+   TPMTRYRETURN(tpmrsa_pub_encrypt_oaep(&rsa,
+            ctr_drbg_random, &vtpm_globals.ctr_drbg,
+            ptr - plain,
+            plain,
+            out));
+
+abort_egress:
+   tpmrsa_free(&rsa);
+   return status;
+
+}
+
+TPM_RESULT TPM_UnBind(
+      TPM_KEY_HANDLE  keyHandle,  // in
+      UINT32 ilen, //in
+      const BYTE* in, //
+      UINT32* olen, //
+      BYTE*    out, //out
+      const TPM_AUTHDATA* usage_auth,
+      TPM_AUTH_SESSION* auth //in, out
+      )
+{
+   TPM_BEGIN(TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_UnBind);
+   TPM_AUTH_BEGIN();
+
+   TPM_AUTH_HASH();
+
+   ptr = pack_TPM_KEY_HANDLE(ptr, keyHandle);
+
+   TPM_AUTH_SKIP();
+
+   ptr = pack_UINT32(ptr, ilen);
+   ptr = pack_BUFFER(ptr, in, ilen);
+
+   TPM_AUTH_HASH();
+
+   TPM_AUTH1_GEN(usage_auth, auth);
+   TPM_TRANSMIT();
+   TPM_UNPACK_VERIFY();
+   TPM_AUTH_VERIFY_BEGIN();
+
+   ptr = unpack_UINT32(ptr, olen);
+   if(*olen > ilen) {
+      vtpmlogerror(VTPM_LOG_TPM, "Output length < input length!\n");
+      status = TPM_IOERROR;
+      goto abort_egress;
+   }
+   ptr = unpack_BUFFER(ptr, out, *olen);
+
+   TPM_AUTH_HASH();
+
+   TPM_AUTH1_VERIFY(usage_auth, auth);
+
+abort_egress:
+egress:
+   TPM_AUTH_ERR_CHECK(auth);
+   return status;
+}
+
+TPM_RESULT TPM_CreateWrapKey(
+      TPM_KEY_HANDLE  hWrappingKey,  // in
+      const TPM_AUTHDATA* osapSharedSecret,
+      const TPM_AUTHDATA* dataUsageAuth, //in
+      const TPM_AUTHDATA* dataMigrationAuth, //in
+      TPM_KEY*     key, //in, out
+      TPM_AUTH_SESSION*   pAuth)    // in, out
+{
+   int keyAlloced = 0;
+   TPM_BEGIN(TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_CreateWrapKey);
+   TPM_AUTH_BEGIN();
+
+   TPM_AUTH_HASH();
+
+   ptr = pack_TPM_KEY_HANDLE(ptr, hWrappingKey);
+
+   TPM_AUTH_SKIP();
+
+   //Encrypted auths
+   xorEncrypt(osapSharedSecret, &pAuth->NonceEven,
+         dataUsageAuth, ptr,
+         dataMigrationAuth, ptr + sizeof(TPM_ENCAUTH));
+   ptr += sizeof(TPM_ENCAUTH) * 2;
+
+   ptr = pack_TPM_KEY(ptr, key);
+
+   TPM_AUTH_HASH();
+
+   TPM_AUTH1_GEN(osapSharedSecret, pAuth);
+   TPM_TRANSMIT();
+   TPM_UNPACK_VERIFY();
+   TPM_AUTH_VERIFY_BEGIN();
+
+   keyAlloced = 1;
+   ptr = unpack_TPM_KEY(ptr, key, UNPACK_ALLOC);
+
+   TPM_AUTH_HASH();
+
+   TPM_AUTH1_VERIFY(osapSharedSecret, pAuth);
+
+   goto egress;
+abort_egress:
+   if(keyAlloced) {
+      free_TPM_KEY(key);
+   }
+egress:
+   TPM_AUTH_ERR_CHECK(pAuth);
+   return status;
+}
+
+TPM_RESULT TPM_LoadKey(
+      TPM_KEY_HANDLE  parentHandle, //
+      const TPM_KEY* key, //in
+      TPM_HANDLE*  keyHandle,    // out
+      const TPM_AUTHDATA* usage_auth,
+      TPM_AUTH_SESSION* auth)
+{
+   TPM_BEGIN(TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_LoadKey);
+   TPM_AUTH_BEGIN();
+
+   TPM_AUTH_HASH();
+
+   ptr = pack_TPM_KEY_HANDLE(ptr, parentHandle);
+
+   TPM_AUTH_SKIP();
+
+   ptr = pack_TPM_KEY(ptr, key);
+
+   TPM_AUTH_HASH();
+
+   TPM_AUTH1_GEN(usage_auth, auth);
+   TPM_TRANSMIT();
+   TPM_UNPACK_VERIFY();
+   TPM_AUTH_VERIFY_BEGIN();
+
+   ptr = unpack_UINT32(ptr, keyHandle);
+
+   TPM_AUTH_HASH();
+
+   TPM_AUTH1_VERIFY(usage_auth, auth);
+
+   vtpmloginfo(VTPM_LOG_TPM, "Key Handle: 0x%x opened by TPM_LoadKey\n", *keyHandle);
+
+abort_egress:
+   TPM_AUTH_ERR_CHECK(auth);
+   return status;
+}
+
+TPM_RESULT TPM_EvictKey( TPM_KEY_HANDLE  hKey)  // in
+{
+   if(hKey == 0) {
+      return TPM_SUCCESS;
+   }
+
+   TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_EvictKey);
+
+   ptr = pack_TPM_KEY_HANDLE(ptr, hKey);
+
+   TPM_TRANSMIT();
+   TPM_UNPACK_VERIFY();
+
+   vtpmloginfo(VTPM_LOG_TPM, "Key handle: 0x%x closed by TPM_EvictKey\n", hKey);
+
+abort_egress:
+   return status;
+}
+
+TPM_RESULT TPM_FlushSpecific(TPM_HANDLE handle,
+      TPM_RESOURCE_TYPE rt) {
+   if(handle == 0) {
+      return TPM_SUCCESS;
+   }
+
+   TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_FlushSpecific);
+
+   ptr = pack_TPM_HANDLE(ptr, handle);
+   ptr = pack_TPM_RESOURCE_TYPE(ptr, rt);
+
+   TPM_TRANSMIT();
+   TPM_UNPACK_VERIFY();
+
+abort_egress:
+   return status;
+}
+
+TPM_RESULT TPM_GetRandom( UINT32*    bytesRequested, // in, out
+      BYTE*    randomBytes) // out
+{
+   TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_GetRandom);
+
+   // check input params
+   if (bytesRequested == NULL || randomBytes == NULL){
+      return TPM_BAD_PARAMETER;
+   }
+
+   ptr = pack_UINT32(ptr, *bytesRequested);
+
+   TPM_TRANSMIT();
+   TPM_UNPACK_VERIFY();
+
+   ptr = unpack_UINT32(ptr, bytesRequested);
+   ptr = unpack_BUFFER(ptr, randomBytes, *bytesRequested);
+
+abort_egress:
+   return status;
+}
+
+
+TPM_RESULT TPM_ReadPubek(
+      TPM_PUBKEY* pubEK //out
+      )
+{
+   BYTE* antiReplay = NULL;
+   BYTE* kptr = NULL;
+   BYTE digest[TPM_DIGEST_SIZE];
+   sha1_context ctx;
+
+   TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_ReadPubek);
+
+   //antiReplay nonce
+   vtpmmgr_rand(ptr, TPM_DIGEST_SIZE);
+   antiReplay = ptr;
+   ptr += TPM_DIGEST_SIZE;
+
+   TPM_TRANSMIT();
+   TPM_UNPACK_VERIFY();
+
+   //unpack and allocate the key
+   kptr = ptr;
+   ptr = unpack_TPM_PUBKEY(ptr, pubEK, UNPACK_ALLOC);
+
+   //Verify the checksum
+   sha1_starts(&ctx);
+   sha1_update(&ctx, kptr, ptr - kptr);
+   sha1_update(&ctx, antiReplay, TPM_DIGEST_SIZE);
+   sha1_finish(&ctx, digest);
+
+   //ptr points to the checksum computed by TPM
+   if(memcmp(digest, ptr, TPM_DIGEST_SIZE)) {
+      vtpmlogerror(VTPM_LOG_TPM, "TPM_ReadPubek: Checksum returned by TPM was invalid!\n");
+      status = TPM_FAIL;
+      goto abort_egress;
+   }
+
+   goto egress;
+abort_egress:
+   if(kptr != NULL) { //If we unpacked the pubEK, we have to free it
+      free_TPM_PUBKEY(pubEK);
+   }
+egress:
+   return status;
+}
+
+
+TPM_RESULT TPM_SaveState(void)
+{
+   TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_SaveState);
+
+   TPM_TRANSMIT();
+   TPM_UNPACK_VERIFY();
+
+abort_egress:
+   return status;
+}
+
+TPM_RESULT TPM_GetCapability(
+      TPM_CAPABILITY_AREA capArea,
+      UINT32 subCapSize,
+      const BYTE* subCap,
+      UINT32* respSize,
+      BYTE** resp)
+{
+   TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_GetCapability);
+
+   ptr = pack_TPM_CAPABILITY_AREA(ptr, capArea);
+   ptr = pack_UINT32(ptr, subCapSize);
+   ptr = pack_BUFFER(ptr, subCap, subCapSize);
+
+   TPM_TRANSMIT();
+   TPM_UNPACK_VERIFY();
+
+   ptr = unpack_UINT32(ptr, respSize);
+   ptr = unpack_ALLOC(ptr, resp, *respSize);
+
+abort_egress:
+   return status;
+}
+
+TPM_RESULT TPM_CreateEndorsementKeyPair(
+      const TPM_KEY_PARMS* keyInfo,
+      TPM_PUBKEY* pubEK)
+{
+   BYTE* kptr = NULL;
+   sha1_context ctx;
+   TPM_DIGEST checksum;
+   TPM_DIGEST hash;
+   TPM_NONCE antiReplay;
+   TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_CreateEndorsementKeyPair);
+
+   //Make anti replay nonce
+   vtpmmgr_rand(antiReplay.nonce, sizeof(antiReplay.nonce));
+
+   ptr = pack_TPM_NONCE(ptr, &antiReplay);
+   ptr = pack_TPM_KEY_PARMS(ptr, keyInfo);
+
+   TPM_TRANSMIT();
+   TPM_UNPACK_VERIFY();
+
+   sha1_starts(&ctx);
+
+   kptr = ptr;
+   ptr = unpack_TPM_PUBKEY(ptr, pubEK, UNPACK_ALLOC);
+
+   /* Hash the pub key blob */
+   sha1_update(&ctx, kptr, ptr - kptr);
+   ptr = unpack_TPM_DIGEST(ptr, &checksum);
+
+   sha1_update(&ctx, antiReplay.nonce, sizeof(antiReplay.nonce));
+
+   sha1_finish(&ctx, hash.digest);
+   if(memcmp(checksum.digest, hash.digest, TPM_DIGEST_SIZE)) {
+      vtpmloginfo(VTPM_LOG_VTPM, "TPM_CreateEndorsementKey: Checkum verification failed!\n");
+      status = TPM_FAIL;
+      goto abort_egress;
+   }
+
+   goto egress;
+abort_egress:
+   if(kptr) {
+      free_TPM_PUBKEY(pubEK);
+   }
+egress:
+   return status;
+}
+
+TPM_RESULT TPM_TransmitData(
+      BYTE* in,
+      UINT32 insize,
+      BYTE* out,
+      UINT32* outsize) {
+   TPM_RESULT status = TPM_SUCCESS;
+
+   UINT32 i;
+   vtpmloginfo(VTPM_LOG_TXDATA, "Sending buffer = 0x");
+   for(i = 0 ; i < insize ; i++)
+      vtpmloginfomore(VTPM_LOG_TXDATA, "%2.2x ", in[i]);
+
+   vtpmloginfomore(VTPM_LOG_TXDATA, "\n");
+
+   ssize_t size = 0;
+
+   // send the request
+   size = write (vtpm_globals.tpm_fd, in, insize);
+   if (size < 0) {
+      vtpmlogerror(VTPM_LOG_TXDATA, "write() failed : %s\n", strerror(errno));
+      ERRORDIE (TPM_IOERROR);
+   }
+   else if ((UINT32) size < insize) {
+      vtpmlogerror(VTPM_LOG_TXDATA, "Wrote %d instead of %d bytes!\n", (int) size, insize);
+      ERRORDIE (TPM_IOERROR);
+   }
+
+   // read the response
+   size = read (vtpm_globals.tpm_fd, out, *outsize);
+   if (size < 0) {
+      vtpmlogerror(VTPM_LOG_TXDATA, "read() failed : %s\n", strerror(errno));
+      ERRORDIE (TPM_IOERROR);
+   }
+
+   vtpmloginfo(VTPM_LOG_TXDATA, "Receiving buffer = 0x");
+   for(i = 0 ; i < size ; i++)
+      vtpmloginfomore(VTPM_LOG_TXDATA, "%2.2x ", out[i]);
+
+   vtpmloginfomore(VTPM_LOG_TXDATA, "\n");
+
+   *outsize = size;
+   goto egress;
+
+abort_egress:
+egress:
+   return status;
+}
diff --git a/stubdom/vtpmmgr/tpm.h b/stubdom/vtpmmgr/tpm.h
new file mode 100644
index 0000000..304e145
--- /dev/null
+++ b/stubdom/vtpmmgr/tpm.h
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense.  All rights reserved.
+ *
+ * based off of the original tools/vtpm_manager code base which is:
+ * Copyright (c) 2005/2006, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __TPM_H__
+#define __TPM_H__
+
+#include "tcg.h"
+
+// ------------------------------------------------------------------
+// Exposed API
+// ------------------------------------------------------------------
+
+// TPM v1.1B Command Set
+
+// Authorzation
+TPM_RESULT TPM_OIAP(
+      TPM_AUTH_SESSION*   auth //out
+      );
+
+TPM_RESULT TPM_OSAP (
+      TPM_ENTITY_TYPE entityType,  // in
+      UINT32    entityValue, // in
+      const TPM_AUTHDATA* usageAuth, //in
+      TPM_SECRET *sharedSecret, //out
+      TPM_AUTH_SESSION *auth);
+
+TPM_RESULT TPM_TakeOwnership(
+      const TPM_PUBKEY *pubEK, //in
+      const TPM_AUTHDATA* ownerAuth, //in
+      const TPM_AUTHDATA* srkAuth, //in
+      const TPM_KEY* inSrk, //in
+      TPM_KEY* outSrk, //out, optional
+      TPM_AUTH_SESSION*   auth   // in, out
+      );
+
+TPM_RESULT TPM_DisablePubekRead (
+      const TPM_AUTHDATA* ownerAuth,
+      TPM_AUTH_SESSION*   auth
+      );
+
+TPM_RESULT TPM_TerminateHandle ( TPM_AUTHHANDLE  handle  // in
+      );
+
+TPM_RESULT TPM_FlushSpecific ( TPM_HANDLE  handle,  // in
+      TPM_RESOURCE_TYPE resourceType //in
+      );
+
+// TPM Mandatory
+TPM_RESULT TPM_Extend ( TPM_PCRINDEX  pcrNum,  // in
+      TPM_DIGEST   inDigest, // in
+      TPM_PCRVALUE*   outDigest // out
+      );
+
+TPM_RESULT TPM_PcrRead ( TPM_PCRINDEX  pcrNum,  // in
+      TPM_PCRVALUE*  outDigest // out
+      );
+
+TPM_RESULT TPM_Quote ( TCS_KEY_HANDLE  keyHandle,  // in
+      TPM_NONCE   antiReplay,  // in
+      UINT32*    PcrDataSize, // in, out
+      BYTE**    PcrData,  // in, out
+      TPM_AUTH_SESSION*   privAuth,  // in, out
+      UINT32*    sigSize,  // out
+      BYTE**    sig    // out
+      );
+
+TPM_RESULT TPM_Seal(
+      TCS_KEY_HANDLE  keyHandle,  // in
+      UINT32    pcrInfoSize, // in
+      TPM_PCR_INFO*    pcrInfo,  // in
+      UINT32    inDataSize,  // in
+      const BYTE*    inData,   // in
+      TPM_STORED_DATA* sealedData, //out
+      const TPM_SECRET* osapSharedSecret, //in
+      const TPM_AUTHDATA* sealDataAuth, //in
+      TPM_AUTH_SESSION*   pubAuth  // in, out
+      );
+
+TPM_RESULT TPM_Unseal (
+      TPM_KEY_HANDLE parentHandle, // in
+      const TPM_STORED_DATA* sealedData,
+      UINT32*   outSize,  // out
+      BYTE**    out, //out
+      const TPM_AUTHDATA* key_usage_auth, //in
+      const TPM_AUTHDATA* data_usage_auth, //in
+      TPM_AUTH_SESSION*   keyAuth,  // in, out
+      TPM_AUTH_SESSION*   dataAuth  // in, out
+      );
+
+TPM_RESULT TPM_DirWriteAuth ( TPM_DIRINDEX  dirIndex,  // in
+      TPM_DIRVALUE  newContents, // in
+      TPM_AUTH_SESSION*   ownerAuth  // in, out
+      );
+
+TPM_RESULT TPM_DirRead ( TPM_DIRINDEX  dirIndex, // in
+      TPM_DIRVALUE*  dirValue // out
+      );
+
+TPM_RESULT TPM_Bind(
+      const TPM_KEY* key, //in
+      const BYTE* in, //in
+      UINT32 ilen, //in
+      BYTE* out //out, must be at least cipher block size
+      );
+
+TPM_RESULT TPM_UnBind (
+      TCS_KEY_HANDLE  keyHandle,  // in
+      UINT32 ilen, //in
+      const BYTE* in, //
+      UINT32*   outDataSize, // out
+      BYTE*    outData, //out
+      const TPM_AUTHDATA* usage_auth,
+      TPM_AUTH_SESSION* auth //in, out
+      );
+
+TPM_RESULT TPM_CreateWrapKey (
+      TCS_KEY_HANDLE  hWrappingKey,  // in
+      const TPM_AUTHDATA* osapSharedSecret,
+      const TPM_AUTHDATA* dataUsageAuth, //in
+      const TPM_AUTHDATA* dataMigrationAuth, //in
+      TPM_KEY*     key, //in
+      TPM_AUTH_SESSION*   pAuth    // in, out
+      );
+
+TPM_RESULT TPM_LoadKey (
+      TPM_KEY_HANDLE  parentHandle, //
+      const TPM_KEY* key, //in
+      TPM_HANDLE*  keyHandle,    // out
+      const TPM_AUTHDATA* usage_auth,
+      TPM_AUTH_SESSION* auth
+      );
+
+TPM_RESULT TPM_GetPubKey (  TCS_KEY_HANDLE  hKey,   // in
+      TPM_AUTH_SESSION*   pAuth,   // in, out
+      UINT32*    pcPubKeySize, // out
+      BYTE**    prgbPubKey  // out
+      );
+
+TPM_RESULT TPM_EvictKey ( TCS_KEY_HANDLE  hKey  // in
+      );
+
+TPM_RESULT TPM_FlushSpecific(TPM_HANDLE handle, //in
+      TPM_RESOURCE_TYPE rt //in
+      );
+
+TPM_RESULT TPM_Sign ( TCS_KEY_HANDLE  keyHandle,  // in
+      UINT32    areaToSignSize, // in
+      BYTE*    areaToSign,  // in
+      TPM_AUTH_SESSION*   privAuth,  // in, out
+      UINT32*    sigSize,  // out
+      BYTE**    sig    // out
+      );
+
+TPM_RESULT TPM_GetRandom (  UINT32*    bytesRequested, // in, out
+      BYTE*    randomBytes  // out
+      );
+
+TPM_RESULT TPM_StirRandom (  UINT32    inDataSize, // in
+      BYTE*    inData  // in
+      );
+
+TPM_RESULT TPM_ReadPubek (
+      TPM_PUBKEY* pubEK //out
+      );
+
+TPM_RESULT TPM_GetCapability(
+      TPM_CAPABILITY_AREA capArea,
+      UINT32 subCapSize,
+      const BYTE* subCap,
+      UINT32* respSize,
+      BYTE** resp);
+
+TPM_RESULT TPM_SaveState(void);
+
+TPM_RESULT TPM_CreateEndorsementKeyPair(
+      const TPM_KEY_PARMS* keyInfo,
+      TPM_PUBKEY* pubEK);
+
+TPM_RESULT TPM_TransmitData(
+      BYTE* in,
+      UINT32 insize,
+      BYTE* out,
+      UINT32* outsize);
+
+#endif //TPM_H
diff --git a/stubdom/vtpmmgr/tpmrsa.c b/stubdom/vtpmmgr/tpmrsa.c
new file mode 100644
index 0000000..56094e7
--- /dev/null
+++ b/stubdom/vtpmmgr/tpmrsa.c
@@ -0,0 +1,175 @@
+/*
+ *  The RSA public-key cryptosystem
+ *
+ *  Copyright (C) 2006-2011, Brainspark B.V.
+ *
+ *  This file is part of PolarSSL (http://www.polarssl.org)
+ *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ *  All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+/*
+ *  RSA was designed by Ron Rivest, Adi Shamir and Len Adleman.
+ *
+ *  http://theory.lcs.mit.edu/~rivest/rsapaper.pdf
+ *  http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf
+ */
+
+#include "tcg.h"
+#include "polarssl/sha1.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "tpmrsa.h"
+
+#define HASH_LEN 20
+
+void tpmrsa_set_pubkey(tpmrsa_context* ctx,
+      const unsigned char* key,
+      int keylen,
+      const unsigned char* exponent,
+      int explen) {
+
+   tpmrsa_free(ctx);
+
+   if(explen == 0) { //Default e= 2^16+1
+      mpi_lset(&ctx->E, 65537);
+   } else {
+      mpi_read_binary(&ctx->E, exponent, explen);
+   }
+   mpi_read_binary(&ctx->N, key, keylen);
+
+   ctx->len = ( mpi_msb(&ctx->N) + 7) >> 3;
+}
+
+static TPM_RESULT tpmrsa_public( tpmrsa_context *ctx,
+      const unsigned char *input,
+      unsigned char *output )
+{
+   int ret;
+   size_t olen;
+   mpi T;
+
+   mpi_init( &T );
+
+   MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
+
+   if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
+   {
+      mpi_free( &T );
+      return TPM_ENCRYPT_ERROR;
+   }
+
+   olen = ctx->len;
+   MPI_CHK( mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
+   MPI_CHK( mpi_write_binary( &T, output, olen ) );
+
+cleanup:
+
+   mpi_free( &T );
+
+   if( ret != 0 )
+      return TPM_ENCRYPT_ERROR;
+
+   return TPM_SUCCESS;
+}
+
+static void mgf_mask( unsigned char *dst, int dlen, unsigned char *src, int slen)
+{
+   unsigned char mask[HASH_LEN];
+   unsigned char counter[4] = {0, 0, 0, 0};
+   int i;
+   sha1_context mctx;
+
+   //We always hash the src with the counter, so save the partial hash
+   sha1_starts(&mctx);
+   sha1_update(&mctx, src, slen);
+
+   // Generate and apply dbMask
+   while(dlen > 0) {
+      //Copy the sha1 context
+      sha1_context ctx = mctx;
+
+      //compute hash for input || counter
+      sha1_update(&ctx, counter, sizeof(counter));
+      sha1_finish(&ctx, mask);
+
+      //Apply the mask
+      for(i = 0; i < (dlen < HASH_LEN ? dlen : HASH_LEN); ++i) {
+         *(dst++) ^= mask[i];
+      }
+
+      //Increment counter
+      ++counter[3];
+
+      dlen -= HASH_LEN;
+   }
+}
+
+/*
+ * Add the message padding, then do an RSA operation
+ */
+TPM_RESULT tpmrsa_pub_encrypt_oaep( tpmrsa_context *ctx,
+      int (*f_rng)(void *, unsigned char *, size_t),
+      void *p_rng,
+      size_t ilen,
+      const unsigned char *input,
+      unsigned char *output )
+{
+   int ret;
+   int olen;
+   unsigned char* seed = output + 1;
+   unsigned char* db = output + HASH_LEN +1;
+
+   olen = ctx->len-1;
+
+   if( f_rng == NULL )
+      return TPM_ENCRYPT_ERROR;
+
+   if( ilen > olen - 2 * HASH_LEN - 1)
+      return TPM_ENCRYPT_ERROR;
+
+   output[0] = 0;
+
+   //Encoding parameter p
+   sha1((unsigned char*)"TCPA", 4, db);
+
+   //PS
+   memset(db + HASH_LEN, 0,
+         olen - ilen - 2 * HASH_LEN - 1);
+
+   //constant 1 byte
+   db[olen - ilen - HASH_LEN -1] = 0x01;
+
+   //input string
+   memcpy(db + olen - ilen - HASH_LEN,
+         input, ilen);
+
+   //Generate random seed
+   if( ( ret = f_rng( p_rng, seed, HASH_LEN ) ) != 0 )
+      return TPM_ENCRYPT_ERROR;
+
+   // maskedDB: Apply dbMask to DB
+   mgf_mask( db, olen - HASH_LEN, seed, HASH_LEN);
+
+   // maskedSeed: Apply seedMask to seed
+   mgf_mask( seed, HASH_LEN, db, olen - HASH_LEN);
+
+   // Do the crypto op
+   return tpmrsa_public(ctx, output, output);
+}
diff --git a/stubdom/vtpmmgr/tpmrsa.h b/stubdom/vtpmmgr/tpmrsa.h
new file mode 100644
index 0000000..59579e7
--- /dev/null
+++ b/stubdom/vtpmmgr/tpmrsa.h
@@ -0,0 +1,67 @@
+/**
+ * \file rsa.h
+ *
+ * \brief The RSA public-key cryptosystem
+ *
+ *  Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ *  This file is part of PolarSSL (http://www.polarssl.org)
+ *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ *  All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef TPMRSA_H
+#define TPMRSA_H
+
+#include "tcg.h"
+#include <polarssl/bignum.h>
+
+/* tpm software key */
+typedef struct
+{
+    size_t len;                 /*!<  size(N) in chars  */
+
+    mpi N;                      /*!<  public modulus    */
+    mpi E;                      /*!<  public exponent   */
+
+    mpi RN;                     /*!<  cached R^2 mod N  */
+}
+tpmrsa_context;
+
+#define TPMRSA_CTX_INIT { 0, {0, 0, NULL}, {0, 0, NULL}, {0, 0, NULL}}
+
+/* Setup the rsa context using tpm public key data */
+void tpmrsa_set_pubkey(tpmrsa_context* ctx,
+      const unsigned char* key,
+      int keylen,
+      const unsigned char* exponent,
+      int explen);
+
+/* Do rsa public crypto */
+TPM_RESULT tpmrsa_pub_encrypt_oaep( tpmrsa_context *ctx,
+      int (*f_rng)(void *, unsigned char *, size_t),
+      void *p_rng,
+      size_t ilen,
+      const unsigned char *input,
+      unsigned char *output );
+
+/* free tpmrsa key */
+inline void tpmrsa_free( tpmrsa_context *ctx ) {
+   mpi_free( &ctx->RN ); mpi_free( &ctx->E  ); mpi_free( &ctx->N  );
+}
+
+#endif /* tpmrsa.h */
diff --git a/stubdom/vtpmmgr/uuid.h b/stubdom/vtpmmgr/uuid.h
new file mode 100644
index 0000000..4737645
--- /dev/null
+++ b/stubdom/vtpmmgr/uuid.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense.  All rights reserved.
+ *
+ * based off of the original tools/vtpm_manager code base which is:
+ * Copyright (c) 2005, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef VTPMMGR_UUID_H
+#define VTPMMGR_UUID_H
+
+#define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
+#define UUID_FMTLEN ((2*16)+4) /* 16 hex bytes plus 4 hypens */
+#define UUID_BYTES(uuid) uuid[0], uuid[1], uuid[2], uuid[3], \
+                                uuid[4], uuid[5], uuid[6], uuid[7], \
+                                uuid[8], uuid[9], uuid[10], uuid[11], \
+                                uuid[12], uuid[13], uuid[14], uuid[15]
+
+
+typedef uint8_t uuid_t[16];
+
+#endif
diff --git a/stubdom/vtpmmgr/vtpm_cmd_handler.c b/stubdom/vtpmmgr/vtpm_cmd_handler.c
new file mode 100644
index 0000000..f82a2a9
--- /dev/null
+++ b/stubdom/vtpmmgr/vtpm_cmd_handler.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense.  All rights reserved.
+ *
+ * based off of the original tools/vtpm_manager code base which is:
+ * Copyright (c) 2005, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <inttypes.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "marshal.h"
+#include "log.h"
+#include "vtpm_storage.h"
+#include "vtpmmgr.h"
+#include "tpm.h"
+#include "tcg.h"
+
+static TPM_RESULT vtpmmgr_SaveHashKey(
+      const uuid_t uuid,
+      tpmcmd_t* tpmcmd)
+{
+   TPM_RESULT status = TPM_SUCCESS;
+
+   if(tpmcmd->req_len != VTPM_COMMAND_HEADER_SIZE + HASHKEYSZ) {
+      vtpmlogerror(VTPM_LOG_VTPM, "VTPM_ORD_SAVEHASHKEY hashkey too short!\n");
+      status = TPM_BAD_PARAMETER;
+      goto abort_egress;
+   }
+
+   /* Do the command */
+   TPMTRYRETURN(vtpm_storage_save_hashkey(uuid, tpmcmd->req + VTPM_COMMAND_HEADER_SIZE));
+
+abort_egress:
+   pack_TPM_RSP_HEADER(tpmcmd->resp,
+         VTPM_TAG_RSP, VTPM_COMMAND_HEADER_SIZE, status);
+   tpmcmd->resp_len = VTPM_COMMAND_HEADER_SIZE;
+
+   return status;
+}
+
+static TPM_RESULT vtpmmgr_LoadHashKey(
+      const uuid_t uuid,
+      tpmcmd_t* tpmcmd) {
+   TPM_RESULT status = TPM_SUCCESS;
+
+   tpmcmd->resp_len = VTPM_COMMAND_HEADER_SIZE;
+
+   TPMTRYRETURN(vtpm_storage_load_hashkey(uuid, tpmcmd->resp + VTPM_COMMAND_HEADER_SIZE));
+
+   tpmcmd->resp_len += HASHKEYSZ;
+
+abort_egress:
+   pack_TPM_RSP_HEADER(tpmcmd->resp,
+         VTPM_TAG_RSP, tpmcmd->resp_len, status);
+
+   return status;
+}
+
+
+TPM_RESULT vtpmmgr_handle_cmd(
+      const uuid_t uuid,
+      tpmcmd_t* tpmcmd)
+{
+   TPM_RESULT status = TPM_SUCCESS;
+   TPM_TAG tag;
+   UINT32 size;
+   TPM_COMMAND_CODE ord;
+
+   unpack_TPM_RQU_HEADER(tpmcmd->req,
+         &tag, &size, &ord);
+
+   /* Handle the command now */
+   switch(tag) {
+      case VTPM_TAG_REQ:
+         //This is a vTPM command
+         switch(ord) {
+            case VTPM_ORD_SAVEHASHKEY:
+               return vtpmmgr_SaveHashKey(uuid, tpmcmd);
+            case VTPM_ORD_LOADHASHKEY:
+               return vtpmmgr_LoadHashKey(uuid, tpmcmd);
+            default:
+               vtpmlogerror(VTPM_LOG_VTPM, "Invalid vTPM Ordinal %" PRIu32 "\n", ord);
+               status = TPM_BAD_ORDINAL;
+         }
+         break;
+      case TPM_TAG_RQU_COMMAND:
+      case TPM_TAG_RQU_AUTH1_COMMAND:
+      case TPM_TAG_RQU_AUTH2_COMMAND:
+         //This is a TPM passthrough command
+         switch(ord) {
+            case TPM_ORD_GetRandom:
+               vtpmloginfo(VTPM_LOG_VTPM, "Passthrough: TPM_GetRandom\n");
+               break;
+            case TPM_ORD_PcrRead:
+               vtpmloginfo(VTPM_LOG_VTPM, "Passthrough: TPM_PcrRead\n");
+               break;
+            default:
+               vtpmlogerror(VTPM_LOG_VTPM, "TPM Disallowed Passthrough ord=%" PRIu32 "\n", ord);
+               status = TPM_DISABLED_CMD;
+               goto abort_egress;
+         }
+
+         size = TCPA_MAX_BUFFER_LENGTH;
+         TPMTRYRETURN(TPM_TransmitData(tpmcmd->req, tpmcmd->req_len, tpmcmd->resp, &size));
+         tpmcmd->resp_len = size;
+
+         unpack_TPM_RESULT(tpmcmd->resp + sizeof(TPM_TAG) + sizeof(UINT32), &status);
+         return status;
+
+         break;
+      default:
+         vtpmlogerror(VTPM_LOG_VTPM, "Invalid tag=%" PRIu16 "\n", tag);
+         status = TPM_BADTAG;
+   }
+
+abort_egress:
+   tpmcmd->resp_len = VTPM_COMMAND_HEADER_SIZE;
+   pack_TPM_RSP_HEADER(tpmcmd->resp,
+         tag + 3, tpmcmd->resp_len, status);
+
+   return status;
+}
diff --git a/stubdom/vtpmmgr/vtpm_manager.h b/stubdom/vtpmmgr/vtpm_manager.h
new file mode 100644
index 0000000..a2bbcca
--- /dev/null
+++ b/stubdom/vtpmmgr/vtpm_manager.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense.  All rights reserved.
+ *
+ * based off of the original tools/vtpm_manager code base which is:
+ * Copyright (c) 2005, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef VTPM_MANAGER_H
+#define VTPM_MANAGER_H
+
+#define VTPM_TAG_REQ 0x01c1
+#define VTPM_TAG_RSP 0x01c4
+#define COMMAND_BUFFER_SIZE 4096
+
+// Header size
+#define VTPM_COMMAND_HEADER_SIZE ( 2 + 4 + 4)
+
+//************************ Command Codes ****************************
+#define VTPM_ORD_BASE       0x0000
+#define VTPM_PRIV_MASK      0x01000000 // Priviledged VTPM Command
+#define VTPM_PRIV_BASE      (VTPM_ORD_BASE | VTPM_PRIV_MASK)
+
+// Non-priviledged VTPM Commands (From DMI's)
+#define VTPM_ORD_SAVEHASHKEY      (VTPM_ORD_BASE + 1) // DMI requests encryption key for persistent storage
+#define VTPM_ORD_LOADHASHKEY      (VTPM_ORD_BASE + 2) // DMI requests symkey to be regenerated
+
+//************************ Return Codes ****************************
+#define VTPM_SUCCESS               0
+#define VTPM_FAIL                  1
+#define VTPM_UNSUPPORTED           2
+#define VTPM_FORBIDDEN             3
+#define VTPM_RESTORE_CONTEXT_FAILED    4
+#define VTPM_INVALID_REQUEST       5
+
+#endif
diff --git a/stubdom/vtpmmgr/vtpm_storage.c b/stubdom/vtpmmgr/vtpm_storage.c
new file mode 100644
index 0000000..abb0dba
--- /dev/null
+++ b/stubdom/vtpmmgr/vtpm_storage.c
@@ -0,0 +1,794 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense.  All rights reserved.
+ *
+ * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
+ * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
+ * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
+ * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
+ * SOFTWARE.
+ */
+
+/***************************************************************
+ * DISK IMAGE LAYOUT
+ * *************************************************************
+ * All data is stored in BIG ENDIAN format
+ * *************************************************************
+ * Section 1: Header
+ *
+ * 10 bytes 	 id			ID String "VTPMMGRDOM"
+ * uint32_t	 version	        Disk Image version number (current == 1)
+ * uint32_t      storage_key_len	Length of the storage Key
+ * TPM_KEY       storage_key		Marshalled TPM_KEY structure (See TPM spec v2)
+ * RSA_BLOCK     aes_crypto             Encrypted aes key data (RSA_CIPHER_SIZE bytes), bound by the storage_key
+ *  BYTE[32] aes_key                    Aes key for encrypting the uuid table
+ *  uint32_t cipher_sz                  Encrypted size of the uuid table
+ *
+ * *************************************************************
+ * Section 2: Uuid Table
+ *
+ * This table is encrypted by the aes_key in the header. The cipher text size is just
+ * large enough to hold all of the entries plus required padding.
+ *
+ * Each entry is as follows
+ * BYTE[16] uuid                       Uuid of a vtpm that is stored on this disk
+ * uint32_t offset                     Disk offset where the vtpm data is stored
+ *
+ * *************************************************************
+ * Section 3: Vtpm Table
+ *
+ * The rest of the disk stores vtpms. Each vtpm is an RSA_BLOCK encrypted
+ * by the storage key. Each vtpm must exist on an RSA_BLOCK aligned boundary,
+ * starting at the first RSA_BLOCK aligned offset after the uuid table.
+ * As the uuid table grows, vtpms may be relocated.
+ *
+ * RSA_BLOCK     vtpm_crypto          Vtpm data encrypted by storage_key
+ *   BYTE[20]    hash                 Sha1 hash of vtpm encrypted data
+ *   BYTE[16]    vtpm_aes_key         Encryption key for vtpm data
+ *
+  *************************************************************
+ */
+#define DISKVERS 1
+#define IDSTR "VTPMMGRDOM"
+#define IDSTRLEN 10
+#define AES_BLOCK_SIZE 16
+#define AES_KEY_BITS 256
+#define AES_KEY_SIZE (AES_KEY_BITS/8)
+#define BUF_SIZE 4096
+
+#define UUID_TBL_ENT_SIZE (sizeof(uuid_t) + sizeof(uint32_t))
+
+#define HEADERSZ (10 + 4 + 4)
+
+#define TRY_READ(buf, size, msg) do {\
+   int rc; \
+   if((rc = read(blkfront_fd, buf, (size))) != (size)) { \
+      vtpmlogerror(VTPM_LOG_VTPM, "read() failed! " msg " : rc=(%d/%d), error=(%s)\n", rc, (int)(size), strerror(errno)); \
+      status = TPM_IOERROR;\
+      goto abort_egress;\
+   } \
+} while(0)
+
+#define TRY_WRITE(buf, size, msg) do {\
+   int rc; \
+   if((rc = write(blkfront_fd, buf, (size))) != (size)) { \
+      vtpmlogerror(VTPM_LOG_VTPM, "write() failed! " msg " : rc=(%d/%d), error=(%s)\n", rc, (int)(size), strerror(errno)); \
+      status = TPM_IOERROR;\
+      goto abort_egress;\
+   } \
+} while(0)
+
+#include <blkfront.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <mini-os/byteorder.h>
+#include <polarssl/aes.h>
+
+#include "vtpm_manager.h"
+#include "log.h"
+#include "marshal.h"
+#include "tpm.h"
+#include "uuid.h"
+
+#include "vtpmmgr.h"
+#include "vtpm_storage.h"
+
+#define MAX(a,b) ( ((a) > (b)) ? (a) : (b) )
+#define MIN(a,b) ( ((a) < (b)) ? (a) : (b) )
+
+/* blkfront device objets */
+static struct blkfront_dev* blkdev = NULL;
+static int blkfront_fd = -1;
+
+struct Vtpm {
+   uuid_t uuid;
+   int offset;
+};
+struct Storage {
+   int aes_offset;
+   int uuid_offset;
+   int end_offset;
+
+   int num_vtpms;
+   int num_vtpms_alloced;
+   struct Vtpm* vtpms;
+};
+
+/* Global storage data */
+static struct Storage g_store = {
+   .vtpms = NULL,
+};
+
+static int get_offset(void) {
+   return lseek(blkfront_fd, 0, SEEK_CUR);
+}
+
+static void reset_store(void) {
+   g_store.aes_offset = 0;
+   g_store.uuid_offset = 0;
+   g_store.end_offset = 0;
+
+   g_store.num_vtpms = 0;
+   g_store.num_vtpms_alloced = 0;
+   free(g_store.vtpms);
+   g_store.vtpms = NULL;
+}
+
+static int vtpm_get_index(const uuid_t uuid) {
+   int st = 0;
+   int ed = g_store.num_vtpms-1;
+   while(st <= ed) {
+      int mid = ((unsigned int)st + (unsigned int)ed) >> 1; //avoid overflow
+      int c = memcmp(uuid, &g_store.vtpms[mid].uuid, sizeof(uuid_t));
+      if(c == 0) {
+         return mid;
+      } else if(c > 0) {
+         st = mid + 1;
+      } else {
+         ed = mid - 1;
+      }
+   }
+   return -(st + 1);
+}
+
+static void vtpm_add(const uuid_t uuid, int offset, int index) {
+   /* Realloc more space if needed */
+   if(g_store.num_vtpms >= g_store.num_vtpms_alloced) {
+      g_store.num_vtpms_alloced += 16;
+      g_store.vtpms = realloc(
+            g_store.vtpms,
+            sizeof(struct Vtpm) * g_store.num_vtpms_alloced);
+   }
+
+   /* Move everybody after the new guy */
+   for(int i = g_store.num_vtpms; i > index; --i) {
+      g_store.vtpms[i] = g_store.vtpms[i-1];
+   }
+
+   vtpmloginfo(VTPM_LOG_VTPM, "Registered vtpm " UUID_FMT "\n", UUID_BYTES(uuid));
+
+   /* Finally add new one */
+   memcpy(g_store.vtpms[index].uuid, uuid, sizeof(uuid_t));
+   g_store.vtpms[index].offset = offset;
+   ++g_store.num_vtpms;
+}
+
+#if 0
+static void vtpm_remove(int index) {
+   for(i = index; i < g_store.num_vtpms; ++i) {
+      g_store.vtpms[i] = g_store.vtpms[i+1];
+   }
+   --g_store.num_vtpms;
+}
+#endif
+
+static int pack_uuid_table(uint8_t* table, int size, int* nvtpms) {
+   uint8_t* ptr = table;
+   while(*nvtpms < g_store.num_vtpms && size >= 0)
+   {
+      /* Pack the uuid */
+      memcpy(ptr, (uint8_t*)g_store.vtpms[*nvtpms].uuid, sizeof(uuid_t));
+      ptr+= sizeof(uuid_t);
+
+
+      /* Pack the offset */
+      ptr = pack_UINT32(ptr, g_store.vtpms[*nvtpms].offset);
+
+      ++*nvtpms;
+      size -= UUID_TBL_ENT_SIZE;
+   }
+   return ptr - table;
+}
+
+/* Extract the uuids */
+static int extract_uuid_table(uint8_t* table, int size) {
+   uint8_t* ptr = table;
+   for(;size >= UUID_TBL_ENT_SIZE; size -= UUID_TBL_ENT_SIZE) {
+      int index;
+      uint32_t v32;
+
+      /*uuid_t is just an array of bytes, so we can do a direct cast here */
+      uint8_t* uuid = ptr;
+      ptr += sizeof(uuid_t);
+
+      /* Get the offset of the key */
+      ptr = unpack_UINT32(ptr, &v32);
+
+      /* Insert the new vtpm in sorted order */
+      if((index = vtpm_get_index(uuid)) >= 0) {
+         vtpmlogerror(VTPM_LOG_VTPM, "Vtpm (" UUID_FMT ") exists multiple times! ignoring...\n", UUID_BYTES(uuid));
+         continue;
+      }
+      index = -index -1;
+
+      vtpm_add(uuid, v32, index);
+
+   }
+   return ptr - table;
+}
+
+static void vtpm_decrypt_block(aes_context* aes,
+      uint8_t* iv,
+      uint8_t* cipher,
+      uint8_t* plain,
+      int cipher_sz,
+      int* overlap)
+{
+   int bytes_ext;
+   /* Decrypt */
+   aes_crypt_cbc(aes, AES_DECRYPT,
+         cipher_sz,
+         iv, cipher, plain + *overlap);
+
+   /* Extract */
+   bytes_ext = extract_uuid_table(plain, cipher_sz + *overlap);
+
+   /* Copy left overs to the beginning */
+   *overlap = cipher_sz + *overlap - bytes_ext;
+   memcpy(plain, plain + bytes_ext, *overlap);
+}
+
+static int vtpm_encrypt_block(aes_context* aes,
+      uint8_t* iv,
+      uint8_t* plain,
+      uint8_t* cipher,
+      int block_sz,
+      int* overlap,
+      int* num_vtpms)
+{
+   int bytes_to_crypt;
+   int bytes_packed;
+
+   /* Pack the uuid table */
+   bytes_packed = *overlap + pack_uuid_table(plain + *overlap, block_sz - *overlap, num_vtpms);
+   bytes_to_crypt = MIN(bytes_packed, block_sz);
+
+   /* Add padding if we aren't on a multiple of the block size */
+   if(bytes_to_crypt & (AES_BLOCK_SIZE-1)) {
+      int oldsz = bytes_to_crypt;
+      //add padding
+      bytes_to_crypt += AES_BLOCK_SIZE - (bytes_to_crypt & (AES_BLOCK_SIZE-1));
+      //fill padding with random bytes
+      vtpmmgr_rand(plain + oldsz, bytes_to_crypt - oldsz);
+      *overlap = 0;
+   } else {
+      *overlap = bytes_packed - bytes_to_crypt;
+   }
+
+   /* Encrypt this chunk */
+   aes_crypt_cbc(aes, AES_ENCRYPT,
+            bytes_to_crypt,
+            iv, plain, cipher);
+
+   /* Copy the left over partials to the beginning */
+   memcpy(plain, plain + bytes_to_crypt, *overlap);
+
+   return bytes_to_crypt;
+}
+
+static TPM_RESULT vtpm_storage_new_vtpm(const uuid_t uuid, int index) {
+   TPM_RESULT status = TPM_SUCCESS;
+   uint8_t plain[BUF_SIZE + AES_BLOCK_SIZE];
+   uint8_t buf[BUF_SIZE];
+   uint8_t* ptr;
+   int cipher_sz;
+   aes_context aes;
+
+   /* Add new vtpm to the table */
+   vtpm_add(uuid, g_store.end_offset, index);
+   g_store.end_offset += RSA_CIPHER_SIZE;
+
+   /* Compute the new end location of the encrypted uuid table */
+   cipher_sz = AES_BLOCK_SIZE; //IV
+   cipher_sz += g_store.num_vtpms * UUID_TBL_ENT_SIZE; //uuid table
+   cipher_sz += (AES_BLOCK_SIZE - (cipher_sz & (AES_BLOCK_SIZE -1))) & (AES_BLOCK_SIZE-1); //aes padding
+
+   /* Does this overlap any key data? If so they need to be relocated */
+   int uuid_end = (g_store.uuid_offset + cipher_sz + RSA_CIPHER_SIZE) & ~(RSA_CIPHER_SIZE -1);
+   for(int i = 0; i < g_store.num_vtpms; ++i) {
+      if(g_store.vtpms[i].offset < uuid_end) {
+
+         vtpmloginfo(VTPM_LOG_VTPM, "Relocating vtpm data\n");
+
+         //Read the hashkey cipher text
+         lseek(blkfront_fd, g_store.vtpms[i].offset, SEEK_SET);
+         TRY_READ(buf, RSA_CIPHER_SIZE, "vtpm hashkey relocate");
+
+         //Write the cipher text to new offset
+         lseek(blkfront_fd, g_store.end_offset, SEEK_SET);
+         TRY_WRITE(buf, RSA_CIPHER_SIZE, "vtpm hashkey relocate");
+
+         //Save new offset
+         g_store.vtpms[i].offset = g_store.end_offset;
+         g_store.end_offset += RSA_CIPHER_SIZE;
+      }
+   }
+
+   vtpmloginfo(VTPM_LOG_VTPM, "Generating a new symmetric key\n");
+
+   /* Generate an aes key */
+   TPMTRYRETURN(vtpmmgr_rand(plain, AES_KEY_SIZE));
+   aes_setkey_enc(&aes, plain, AES_KEY_BITS);
+   ptr = plain + AES_KEY_SIZE;
+
+   /* Pack the crypted size */
+   ptr = pack_UINT32(ptr, cipher_sz);
+
+   vtpmloginfo(VTPM_LOG_VTPM, "Binding encrypted key\n");
+
+   /* Seal the key and size */
+   TPMTRYRETURN(TPM_Bind(&vtpm_globals.storage_key,
+            plain,
+            ptr - plain,
+            buf));
+
+   /* Write the sealed key to disk */
+   lseek(blkfront_fd, g_store.aes_offset, SEEK_SET);
+   TRY_WRITE(buf, RSA_CIPHER_SIZE, "vtpm aes key");
+
+   /* ENCRYPT AND WRITE UUID TABLE */
+
+   vtpmloginfo(VTPM_LOG_VTPM, "Encrypting the uuid table\n");
+
+   int num_vtpms = 0;
+   int overlap = 0;
+   int bytes_crypted;
+   uint8_t iv[AES_BLOCK_SIZE];
+
+   /* Generate the iv for the first block */
+   TPMTRYRETURN(vtpmmgr_rand(iv, AES_BLOCK_SIZE));
+
+   /* Copy the iv to the cipher text buffer to be written to disk */
+   memcpy(buf, iv, AES_BLOCK_SIZE);
+   ptr = buf + AES_BLOCK_SIZE;
+
+   /* Encrypt the first block of the uuid table */
+   bytes_crypted = vtpm_encrypt_block(&aes,
+         iv, //iv
+         plain, //plaintext
+         ptr, //cipher text
+         BUF_SIZE - AES_BLOCK_SIZE,
+         &overlap,
+         &num_vtpms);
+
+   /* Write the iv followed by the crypted table*/
+   TRY_WRITE(buf, bytes_crypted + AES_BLOCK_SIZE, "vtpm uuid table");
+
+   /* Decrement the number of bytes encrypted */
+   cipher_sz -= bytes_crypted + AES_BLOCK_SIZE;
+
+   /* If there are more vtpms, encrypt and write them block by block */
+   while(cipher_sz > 0) {
+      /* Encrypt the next block of the uuid table */
+      bytes_crypted = vtpm_encrypt_block(&aes,
+               iv,
+               plain,
+               buf,
+               BUF_SIZE,
+               &overlap,
+               &num_vtpms);
+
+      /* Write the cipher text to disk */
+      TRY_WRITE(buf, bytes_crypted, "vtpm uuid table");
+
+      cipher_sz -= bytes_crypted;
+   }
+
+   goto egress;
+abort_egress:
+egress:
+   return status;
+}
+
+
+/**************************************
+ * PUBLIC FUNCTIONS
+ * ***********************************/
+
+int vtpm_storage_init(void) {
+   struct blkfront_info info;
+   if((blkdev = init_blkfront(NULL, &info)) == NULL) {
+      return -1;
+   }
+   if((blkfront_fd = blkfront_open(blkdev)) < 0) {
+      return -1;
+   }
+   return 0;
+}
+
+void vtpm_storage_shutdown(void) {
+   reset_store();
+   close(blkfront_fd);
+}
+
+TPM_RESULT vtpm_storage_load_hashkey(const uuid_t uuid, uint8_t hashkey[HASHKEYSZ])
+{
+   TPM_RESULT status = TPM_SUCCESS;
+   int index;
+   uint8_t cipher[RSA_CIPHER_SIZE];
+   uint8_t clear[RSA_CIPHER_SIZE];
+   UINT32 clear_size;
+
+   /* Find the index of this uuid */
+   if((index = vtpm_get_index(uuid)) < 0) {
+      index = -index-1;
+      vtpmlogerror(VTPM_LOG_VTPM, "LoadKey failure: Unrecognized uuid! " UUID_FMT "\n", UUID_BYTES(uuid));
+      status = TPM_BAD_PARAMETER;
+      goto abort_egress;
+   }
+
+   /* Read the table entry */
+   lseek(blkfront_fd, g_store.vtpms[index].offset, SEEK_SET);
+   TRY_READ(cipher, RSA_CIPHER_SIZE, "vtpm hashkey data");
+
+   /* Decrypt the table entry */
+   TPMTRYRETURN(TPM_UnBind(
+            vtpm_globals.storage_key_handle,
+            RSA_CIPHER_SIZE,
+            cipher,
+            &clear_size,
+            clear,
+            (const TPM_AUTHDATA*)&vtpm_globals.storage_key_usage_auth,
+            &vtpm_globals.oiap));
+
+   if(clear_size < HASHKEYSZ) {
+      vtpmloginfo(VTPM_LOG_VTPM, "Decrypted Hash key size (%" PRIu32 ") was too small!\n", clear_size);
+      status = TPM_RESOURCES;
+      goto abort_egress;
+   }
+
+   memcpy(hashkey, clear, HASHKEYSZ);
+
+   vtpmloginfo(VTPM_LOG_VTPM, "Loaded hash and key for vtpm " UUID_FMT "\n", UUID_BYTES(uuid));
+   goto egress;
+abort_egress:
+   vtpmlogerror(VTPM_LOG_VTPM, "Failed to load key\n");
+egress:
+   return status;
+}
+
+TPM_RESULT vtpm_storage_save_hashkey(const uuid_t uuid, uint8_t hashkey[HASHKEYSZ])
+{
+   TPM_RESULT status = TPM_SUCCESS;
+   int index;
+   uint8_t buf[RSA_CIPHER_SIZE];
+
+   /* Find the index of this uuid */
+   if((index = vtpm_get_index(uuid)) < 0) {
+      index = -index-1;
+      /* Create a new vtpm */
+      TPMTRYRETURN( vtpm_storage_new_vtpm(uuid, index) );
+   }
+
+   /* Encrypt the hash and key */
+   TPMTRYRETURN( TPM_Bind(&vtpm_globals.storage_key,
+            hashkey,
+            HASHKEYSZ,
+            buf));
+
+   /* Write to disk */
+   lseek(blkfront_fd, g_store.vtpms[index].offset, SEEK_SET);
+   TRY_WRITE(buf, RSA_CIPHER_SIZE, "vtpm hashkey data");
+
+   vtpmloginfo(VTPM_LOG_VTPM, "Saved hash and key for vtpm " UUID_FMT "\n", UUID_BYTES(uuid));
+   goto egress;
+abort_egress:
+   vtpmlogerror(VTPM_LOG_VTPM, "Failed to save key\n");
+egress:
+   return status;
+}
+
+TPM_RESULT vtpm_storage_new_header()
+{
+   TPM_RESULT status = TPM_SUCCESS;
+   uint8_t buf[BUF_SIZE];
+   uint8_t keybuf[AES_KEY_SIZE + sizeof(uint32_t)];
+   uint8_t* ptr = buf;
+   uint8_t* sptr;
+
+   /* Clear everything first */
+   reset_store();
+
+   vtpmloginfo(VTPM_LOG_VTPM, "Creating new disk image header\n");
+
+   /*Copy the ID string */
+   memcpy(ptr, IDSTR, IDSTRLEN);
+   ptr += IDSTRLEN;
+
+   /*Copy the version */
+   ptr = pack_UINT32(ptr, DISKVERS);
+
+   /*Save the location of the key size */
+   sptr = ptr;
+   ptr += sizeof(UINT32);
+
+   vtpmloginfo(VTPM_LOG_VTPM, "Saving root storage key..\n");
+
+   /* Copy the storage key */
+   ptr = pack_TPM_KEY(ptr, &vtpm_globals.storage_key);
+
+   /* Now save the size */
+   pack_UINT32(sptr, ptr - (sptr + 4));
+
+   /* Create a fake aes key and set cipher text size to 0 */
+   memset(keybuf, 0, sizeof(keybuf));
+
+   vtpmloginfo(VTPM_LOG_VTPM, "Binding uuid table symmetric key..\n");
+
+   /* Save the location of the aes key */
+   g_store.aes_offset = ptr - buf;
+
+   /* Store the fake aes key and vtpm count */
+   TPMTRYRETURN(TPM_Bind(&vtpm_globals.storage_key,
+         keybuf,
+         sizeof(keybuf),
+         ptr));
+   ptr+= RSA_CIPHER_SIZE;
+
+   /* Write the header to disk */
+   lseek(blkfront_fd, 0, SEEK_SET);
+   TRY_WRITE(buf, ptr-buf, "vtpm header");
+
+   /* Save the location of the uuid table */
+   g_store.uuid_offset = get_offset();
+
+   /* Save the end offset */
+   g_store.end_offset = (g_store.uuid_offset + RSA_CIPHER_SIZE) & ~(RSA_CIPHER_SIZE -1);
+
+   vtpmloginfo(VTPM_LOG_VTPM, "Saved new manager disk header.\n");
+
+   goto egress;
+abort_egress:
+egress:
+   return status;
+}
+
+
+TPM_RESULT vtpm_storage_load_header(void)
+{
+   TPM_RESULT status = TPM_SUCCESS;
+   uint32_t v32;
+   uint8_t buf[BUF_SIZE];
+   uint8_t* ptr = buf;
+   aes_context aes;
+
+   /* Clear everything first */
+   reset_store();
+
+   /* Read the header from disk */
+   lseek(blkfront_fd, 0, SEEK_SET);
+   TRY_READ(buf, IDSTRLEN + sizeof(UINT32) + sizeof(UINT32), "vtpm header");
+
+   vtpmloginfo(VTPM_LOG_VTPM, "Loading disk image header\n");
+
+   /* Verify the ID string */
+   if(memcmp(ptr, IDSTR, IDSTRLEN)) {
+      vtpmlogerror(VTPM_LOG_VTPM, "Invalid ID string in disk image!\n");
+      status = TPM_FAIL;
+      goto abort_egress;
+   }
+   ptr+=IDSTRLEN;
+
+   /* Unpack the version */
+   ptr = unpack_UINT32(ptr, &v32);
+
+   /* Verify the version */
+   if(v32 != DISKVERS) {
+      vtpmlogerror(VTPM_LOG_VTPM, "Unsupported disk image version number %" PRIu32 "\n", v32);
+      status = TPM_FAIL;
+      goto abort_egress;
+   }
+
+   /* Size of the storage key */
+   ptr = unpack_UINT32(ptr, &v32);
+
+   /* Sanity check */
+   if(v32 > BUF_SIZE) {
+      vtpmlogerror(VTPM_LOG_VTPM, "Size of storage key (%" PRIu32 ") is too large!\n", v32);
+      status = TPM_IOERROR;
+      goto abort_egress;
+   }
+
+   /* read the storage key */
+   TRY_READ(buf, v32, "storage pub key");
+
+   vtpmloginfo(VTPM_LOG_VTPM, "Unpacking storage key\n");
+
+   /* unpack the storage key */
+   ptr = unpack_TPM_KEY(buf, &vtpm_globals.storage_key, UNPACK_ALLOC);
+
+   /* Load Storage Key into the TPM */
+   TPMTRYRETURN( TPM_LoadKey(
+            TPM_SRK_KEYHANDLE,
+            &vtpm_globals.storage_key,
+            &vtpm_globals.storage_key_handle,
+            (const TPM_AUTHDATA*)&vtpm_globals.srk_auth,
+            &vtpm_globals.oiap));
+
+   /* Initialize the storage key auth */
+   memset(vtpm_globals.storage_key_usage_auth, 0, sizeof(TPM_AUTHDATA));
+
+   /* Store the offset of the aes key */
+   g_store.aes_offset = get_offset();
+
+   /* Read the rsa cipher text for the aes key */
+   TRY_READ(buf, RSA_CIPHER_SIZE, "aes key");
+   ptr = buf + RSA_CIPHER_SIZE;
+
+   vtpmloginfo(VTPM_LOG_VTPM, "Unbinding uuid table symmetric key\n");
+
+   /* Decrypt the aes key protecting the uuid table */
+   UINT32 datalen;
+   TPMTRYRETURN(TPM_UnBind(
+            vtpm_globals.storage_key_handle,
+            RSA_CIPHER_SIZE,
+            buf,
+            &datalen,
+            ptr,
+            (const TPM_AUTHDATA*)&vtpm_globals.storage_key_usage_auth,
+            &vtpm_globals.oiap));
+
+   /* Validate the length of the output buffer */
+   if(datalen < AES_KEY_SIZE + sizeof(UINT32)) {
+      vtpmlogerror(VTPM_LOG_VTPM, "Unbound AES key size (%d) was too small! expected (%ld)\n", datalen, AES_KEY_SIZE + sizeof(UINT32));
+      status = TPM_IOERROR;
+      goto abort_egress;
+   }
+
+   /* Extract the aes key */
+   aes_setkey_dec(&aes, ptr, AES_KEY_BITS);
+   ptr+= AES_KEY_SIZE;
+
+   /* Extract the ciphertext size */
+   ptr = unpack_UINT32(ptr, &v32);
+   int cipher_size = v32;
+
+   /* Sanity check */
+   if(cipher_size & (AES_BLOCK_SIZE-1)) {
+      vtpmlogerror(VTPM_LOG_VTPM, "Cipher text size (%" PRIu32 ") is not a multiple of the aes block size! (%d)\n", v32, AES_BLOCK_SIZE);
+      status = TPM_IOERROR;
+      goto abort_egress;
+   }
+
+   /* Save the location of the uuid table */
+   g_store.uuid_offset = get_offset();
+
+   /* Only decrypt the table if there are vtpms to decrypt */
+   if(cipher_size > 0) {
+      int rbytes;
+      int overlap = 0;
+      uint8_t plain[BUF_SIZE + AES_BLOCK_SIZE];
+      uint8_t iv[AES_BLOCK_SIZE];
+
+      vtpmloginfo(VTPM_LOG_VTPM, "Decrypting uuid table\n");
+
+      /* Pre allocate the vtpm array */
+      g_store.num_vtpms_alloced = cipher_size / UUID_TBL_ENT_SIZE;
+      g_store.vtpms = malloc(sizeof(struct Vtpm) * g_store.num_vtpms_alloced);
+
+      /* Read the iv and the first chunk of cipher text */
+      rbytes = MIN(cipher_size, BUF_SIZE);
+      TRY_READ(buf, rbytes, "vtpm uuid table\n");
+      cipher_size -= rbytes;
+
+      /* Copy the iv */
+      memcpy(iv, buf, AES_BLOCK_SIZE);
+      ptr = buf + AES_BLOCK_SIZE;
+
+      /* Remove the iv from the number of bytes to decrypt */
+      rbytes -= AES_BLOCK_SIZE;
+
+      /* Decrypt and extract vtpms */
+      vtpm_decrypt_block(&aes,
+            iv, ptr, plain,
+            rbytes, &overlap);
+
+      /* Read the rest of the table if there is more */
+      while(cipher_size > 0) {
+         /* Read next chunk of cipher text */
+         rbytes = MIN(cipher_size, BUF_SIZE);
+         TRY_READ(buf, rbytes, "vtpm uuid table");
+         cipher_size -= rbytes;
+
+         /* Decrypt a block of text */
+         vtpm_decrypt_block(&aes,
+               iv, buf, plain,
+               rbytes, &overlap);
+
+      }
+      vtpmloginfo(VTPM_LOG_VTPM, "Loaded %d vtpms!\n", g_store.num_vtpms);
+   }
+
+   /* The end of the key table, new vtpms go here */
+   int uuid_end = (get_offset() + RSA_CIPHER_SIZE) & ~(RSA_CIPHER_SIZE -1);
+   g_store.end_offset = uuid_end;
+
+   /* Compute the end offset while validating vtpms*/
+   for(int i = 0; i < g_store.num_vtpms; ++i) {
+      /* offset must not collide with previous data */
+      if(g_store.vtpms[i].offset < uuid_end) {
+         vtpmlogerror(VTPM_LOG_VTPM, "vtpm: " UUID_FMT
+               " offset (%d) is before end of uuid table (%d)!\n",
+               UUID_BYTES(g_store.vtpms[i].uuid),
+               g_store.vtpms[i].offset, uuid_end);
+         status = TPM_IOERROR;
+         goto abort_egress;
+      }
+      /* offset must be at a multiple of cipher size */
+      if(g_store.vtpms[i].offset & (RSA_CIPHER_SIZE-1)) {
+         vtpmlogerror(VTPM_LOG_VTPM, "vtpm: " UUID_FMT
+               " offset(%d) is not at a multiple of the rsa cipher text size (%d)!\n",
+               UUID_BYTES(g_store.vtpms[i].uuid),
+               g_store.vtpms[i].offset, RSA_CIPHER_SIZE);
+         status = TPM_IOERROR;
+         goto abort_egress;
+      }
+      /* Save the last offset */
+      if(g_store.vtpms[i].offset >= g_store.end_offset) {
+         g_store.end_offset = g_store.vtpms[i].offset + RSA_CIPHER_SIZE;
+      }
+   }
+
+   goto egress;
+abort_egress:
+   //An error occured somewhere
+   vtpmlogerror(VTPM_LOG_VTPM, "Failed to load manager data!\n");
+
+   //Clear the data store
+   reset_store();
+
+   //Reset the storage key structure
+   free_TPM_KEY(&vtpm_globals.storage_key);
+   {
+      TPM_KEY key = TPM_KEY_INIT;
+      vtpm_globals.storage_key = key;
+   }
+
+   //Reset the storage key handle
+   TPM_EvictKey(vtpm_globals.storage_key_handle);
+   vtpm_globals.storage_key_handle = 0;
+egress:
+   return status;
+}
+
+#if 0
+/* For testing disk IO */
+void add_fake_vtpms(int num) {
+   for(int i = 0; i < num; ++i) {
+      uint32_t ind = cpu_to_be32(i);
+
+      uuid_t uuid;
+      memset(uuid, 0, sizeof(uuid_t));
+      memcpy(uuid, &ind, sizeof(ind));
+      int index = vtpm_get_index(uuid);
+      index = -index-1;
+
+      vtpm_storage_new_vtpm(uuid, index);
+   }
+}
+#endif
diff --git a/stubdom/vtpmmgr/vtpm_storage.h b/stubdom/vtpmmgr/vtpm_storage.h
new file mode 100644
index 0000000..a5a5fd7
--- /dev/null
+++ b/stubdom/vtpmmgr/vtpm_storage.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense.  All rights reserved.
+ *
+ * based off of the original tools/vtpm_manager code base which is:
+ * Copyright (c) 2005, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef VTPM_STORAGE_H
+#define VTPM_STORAGE_h
+
+#include "uuid.h"
+
+#define VTPM_NVMKEY_SIZE 32
+#define HASHKEYSZ (sizeof(TPM_DIGEST) + VTPM_NVMKEY_SIZE)
+
+/* Initialize the storage system and its virtual disk */
+int vtpm_storage_init(void);
+
+/* Shutdown the storage system and its virtual disk */
+void vtpm_storage_shutdown(void);
+
+/* Loads Sha1 hash and 256 bit AES key from disk and stores them
+ * packed together in outbuf. outbuf must be freed
+ * by the caller using buffer_free()
+ */
+TPM_RESULT vtpm_storage_load_hashkey(const uuid_t uuid, uint8_t hashkey[HASHKEYSZ]);
+
+/* inbuf must contain a sha1 hash followed by a 256 bit AES key.
+ * Encrypts and stores the hash and key to disk */
+TPM_RESULT vtpm_storage_save_hashkey(const uuid_t uuid, uint8_t hashkey[HASHKEYSZ]);
+
+/* Load the vtpm manager data - call this on startup */
+TPM_RESULT vtpm_storage_load_header(void);
+
+/* Saves the vtpm manager data - call this on shutdown */
+TPM_RESULT vtpm_storage_new_header(void);
+
+
+#endif
diff --git a/stubdom/vtpmmgr/vtpmmgr.c b/stubdom/vtpmmgr/vtpmmgr.c
new file mode 100644
index 0000000..563f4e8
--- /dev/null
+++ b/stubdom/vtpmmgr/vtpmmgr.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense.  All rights reserved.
+ *
+ * based off of the original tools/vtpm_manager code base which is:
+ * Copyright (c) 2005, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdint.h>
+#include <mini-os/tpmback.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "log.h"
+
+#include "vtpmmgr.h"
+#include "tcg.h"
+
+
+void main_loop(void) {
+   tpmcmd_t* tpmcmd;
+   uint8_t respbuf[TCPA_MAX_BUFFER_LENGTH];
+
+   while(1) {
+      /* Wait for requests from a vtpm */
+      vtpmloginfo(VTPM_LOG_VTPM, "Waiting for commands from vTPM's:\n");
+      if((tpmcmd = tpmback_req_any()) == NULL) {
+         vtpmlogerror(VTPM_LOG_VTPM, "NULL tpmcmd\n");
+         continue;
+      }
+
+      tpmcmd->resp = respbuf;
+
+      /* Process the command */
+      vtpmmgr_handle_cmd(tpmcmd->uuid, tpmcmd);
+
+      /* Send response */
+      tpmback_resp(tpmcmd);
+   }
+}
+
+int main(int argc, char** argv)
+{
+   int rc = 0;
+   sleep(2);
+   vtpmloginfo(VTPM_LOG_VTPM, "Starting vTPM manager domain\n");
+
+   /* Initialize the vtpm manager */
+   if(vtpmmgr_init(argc, argv) != TPM_SUCCESS) {
+      vtpmlogerror(VTPM_LOG_VTPM, "Unable to initialize vtpmmgr domain!\n");
+      rc = -1;
+      goto exit;
+   }
+
+   main_loop();
+
+   vtpmloginfo(VTPM_LOG_VTPM, "vTPM Manager shutting down...\n");
+
+   vtpmmgr_shutdown();
+
+exit:
+   return rc;
+
+}
diff --git a/stubdom/vtpmmgr/vtpmmgr.h b/stubdom/vtpmmgr/vtpmmgr.h
new file mode 100644
index 0000000..50a1992
--- /dev/null
+++ b/stubdom/vtpmmgr/vtpmmgr.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense.  All rights reserved.
+ *
+ * based off of the original tools/vtpm_manager code base which is:
+ * Copyright (c) 2005, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef VTPMMGR_H
+#define VTPMMGR_H
+
+#include <mini-os/tpmback.h>
+#include <polarssl/entropy.h>
+#include <polarssl/ctr_drbg.h>
+
+#include "uuid.h"
+#include "tcg.h"
+#include "vtpm_manager.h"
+
+#define RSA_KEY_SIZE 0x0800
+#define RSA_CIPHER_SIZE (RSA_KEY_SIZE / 8)
+
+struct vtpm_globals {
+   int tpm_fd;
+   TPM_KEY             storage_key;
+   TPM_HANDLE          storage_key_handle;       // Key used by persistent store
+   TPM_AUTH_SESSION    oiap;                // OIAP session for storageKey
+   TPM_AUTHDATA        storage_key_usage_auth;
+
+   TPM_AUTHDATA        owner_auth;
+   TPM_AUTHDATA        srk_auth;
+
+   entropy_context     entropy;
+   ctr_drbg_context    ctr_drbg;
+};
+
+// --------------------------- Global Values --------------------------
+extern struct vtpm_globals vtpm_globals;   // Key info and DMI states
+
+TPM_RESULT vtpmmgr_init(int argc, char** argv);
+void vtpmmgr_shutdown(void);
+
+TPM_RESULT vtpmmgr_handle_cmd(const uuid_t uuid, tpmcmd_t* tpmcmd);
+
+inline TPM_RESULT vtpmmgr_rand(unsigned char* bytes, size_t num_bytes) {
+   return ctr_drbg_random(&vtpm_globals.ctr_drbg, bytes, num_bytes) == 0 ? 0 : TPM_FAIL;
+}
+
+#endif
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [VTPM v7 3/8] vtpm/vtpmmgr and required libs to stubdom/Makefile
  2012-12-06 18:19 [VTPM v7 1/8] add vtpm-stubdom code Matthew Fioravante
  2012-12-06 18:19 ` [VTPM v7 2/8] add stubdom/vtpmmgr code Matthew Fioravante
@ 2012-12-06 18:19 ` Matthew Fioravante
  2012-12-06 18:19 ` [VTPM v7 4/8] Add vtpm documentation Matthew Fioravante
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Matthew Fioravante @ 2012-12-06 18:19 UTC (permalink / raw)
  To: xen-devel, Ian.Jackson, Ian.Campbell; +Cc: Matthew Fioravante

Add 3 new libraries to stubdom:
libgmp
polarssl
Berlios TPM Emulator 0.7.4

Also adds makefile structure for vtpm-stubdom and vtpmmgrdom

Signed-off-by: Matthew Fioravante <matthew.fioravante@jhuapl.edu>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 stubdom/Makefile           |  138 +++++++++++++++++++++++++++++++++++++++++++-
 stubdom/polarssl.patch     |   64 ++++++++++++++++++++
 stubdom/tpmemu-0.7.4.patch |   12 ++++
 3 files changed, 211 insertions(+), 3 deletions(-)
 create mode 100644 stubdom/polarssl.patch
 create mode 100644 stubdom/tpmemu-0.7.4.patch

diff --git a/stubdom/Makefile b/stubdom/Makefile
index 50ba360..fc70d88 100644
--- a/stubdom/Makefile
+++ b/stubdom/Makefile
@@ -31,6 +31,18 @@ GRUB_VERSION=0.97
 OCAML_URL?=http://caml.inria.fr/pub/distrib/ocaml-3.11
 OCAML_VERSION=3.11.0
 
+GMP_VERSION=4.3.2
+GMP_URL?=$(XEN_EXTFILES_URL)
+#GMP_URL?=ftp://ftp.gmplib.org/pub/gmp-$(GMP_VERSION)
+
+POLARSSL_VERSION=1.1.4
+POLARSSL_URL?=$(XEN_EXTFILES_URL)
+#POLARSSL_URL?=http://polarssl.org/code/releases
+
+TPMEMU_VERSION=0.7.4
+TPMEMU_URL?=$(XEN_EXTFILES_URL)
+#TPMEMU_URL?=http://download.berlios.de/tpm-emulator
+
 WGET=wget -c
 
 GNU_TARGET_ARCH:=$(XEN_TARGET_ARCH)
@@ -74,12 +86,12 @@ TARGET_CPPFLAGS += -I$(XEN_ROOT)/xen/include
 
 TARGET_LDFLAGS += -nostdlib -L$(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/lib
 
-TARGETS=ioemu c caml grub xenstore
+TARGETS=ioemu c caml grub xenstore vtpm vtpmmgr
 
 .PHONY: all
 all: build
 ifeq ($(STUBDOM_SUPPORTED),1)
-build: genpath ioemu-stubdom c-stubdom pv-grub xenstore-stubdom
+build: genpath ioemu-stubdom c-stubdom pv-grub xenstore-stubdom vtpm-stubdom vtpmmgrdom
 else
 build: genpath
 endif
@@ -176,6 +188,76 @@ lwip-$(XEN_TARGET_ARCH): lwip-$(LWIP_VERSION).tar.gz
 	touch $@
 
 #############
+# cross-gmp
+#############
+gmp-$(GMP_VERSION).tar.bz2:
+	$(WGET) $(GMP_URL)/$@
+
+.PHONY: cross-gmp
+ifeq ($(XEN_TARGET_ARCH), x86_32)
+   GMPEXT=ABI=32
+endif
+gmp-$(XEN_TARGET_ARCH): gmp-$(GMP_VERSION).tar.bz2 $(NEWLIB_STAMPFILE)
+	tar xjf $<
+	mv gmp-$(GMP_VERSION) $@
+	#patch -d $@ -p0 < gmp.patch
+	cd $@; CPPFLAGS="-isystem $(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/include $(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" CC=$(CC) $(GMPEXT) ./configure --disable-shared --enable-static --disable-fft --without-readline --prefix=$(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf
+	sed -i 's/#define HAVE_OBSTACK_VPRINTF 1/\/\/#define HAVE_OBSTACK_VPRINTF 1/' $@/config.h
+	touch $@
+
+GMP_STAMPFILE=$(CROSS_ROOT)/$(GNU_TARGET_ARCH)-xen-elf/lib/libgmp.a
+cross-gmp: $(GMP_STAMPFILE)
+$(GMP_STAMPFILE): gmp-$(XEN_TARGET_ARCH)
+	( cd $< && \
+	  $(MAKE) && \
+	  $(MAKE) install )
+
+#############
+# cross-polarssl
+#############
+polarssl-$(POLARSSL_VERSION)-gpl.tgz:
+	$(WGET) $(POLARSSL_URL)/$@
+
+polarssl-$(XEN_TARGET_ARCH): polarssl-$(POLARSSL_VERSION)-gpl.tgz
+	tar xzf $<
+	mv polarssl-$(POLARSSL_VERSION) $@
+	patch -d $@ -p1 < polarssl.patch
+	touch $@
+
+POLARSSL_STAMPFILE=$(CROSS_ROOT)/$(GNU_TARGET_ARCH)-xen-elf/lib/libpolarssl.a
+cross-polarssl: $(POLARSSL_STAMPFILE)
+$(POLARSSL_STAMPFILE): polarssl-$(XEN_TARGET_ARCH) $(NEWLIB_STAMPFILE) lwip-$(XEN_TARGET_ARCH)
+	 ( cd $</library && \
+	   make CC="$(CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -I $(realpath $(MINI_OS)/include)" && \
+	   mkdir -p $(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/include && \
+	   cp -r ../include/* $(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/include && \
+	   mkdir -p $(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/lib && \
+	   $(INSTALL_DATA) libpolarssl.a $(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/lib/ )
+
+#############
+# cross-tpmemu
+#############
+tpm_emulator-$(TPMEMU_VERSION).tar.gz:
+	$(WGET) $(TPMEMU_URL)/$@
+
+tpm_emulator-$(XEN_TARGET_ARCH): tpm_emulator-$(TPMEMU_VERSION).tar.gz
+	tar xzf $<
+	mv tpm_emulator-$(TPMEMU_VERSION) $@
+	patch -d $@ -p1 < tpmemu-$(TPMEMU_VERSION).patch;
+	mkdir $@/build
+	cd $@/build; cmake .. -DCMAKE_C_COMPILER=${CC} -DCMAKE_C_FLAGS="-std=c99 -DTPM_NO_EXTERN $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-declaration-after-statement"
+	touch $@
+
+TPMEMU_STAMPFILE=$(CROSS_ROOT)/$(GNU_TARGET_ARCH)-xen-elf/lib/libtpm.a
+$(TPMEMU_STAMPFILE): tpm_emulator-$(XEN_TARGET_ARCH) $(GMP_STAMPFILE)
+	( cd $</build && make VERBOSE=1 tpm_crypto tpm  )
+	cp $</build/crypto/libtpm_crypto.a $(CROSS_ROOT)/$(GNU_TARGET_ARCH)-xen-elf/lib/libtpm_crypto.a
+	cp $</build/tpm/libtpm.a $(TPMEMU_STAMPFILE)
+
+.PHONY: cross-tpmemu
+cross-tpmemu: $(TPMEMU_STAMPFILE)
+
+#############
 # Cross-ocaml
 #############
 
@@ -319,6 +401,24 @@ c: $(CROSS_ROOT)
 	CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) DESTDIR= -C $@ LWIPDIR=$(CURDIR)/lwip-$(XEN_TARGET_ARCH) 
 
 ######
+# VTPM
+######
+
+.PHONY: vtpm
+vtpm: cross-polarssl cross-tpmemu
+	make -C $(MINI_OS) links
+	XEN_TARGET_ARCH="$(XEN_TARGET_ARCH)" CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) -C $@
+
+######
+# VTPMMGR
+######
+
+.PHONY: vtpmmgr
+vtpmmgr: cross-polarssl
+	make -C $(MINI_OS) links
+	XEN_TARGET_ARCH="$(XEN_TARGET_ARCH)" CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) -C $@
+
+######
 # Grub
 ######
 
@@ -362,6 +462,14 @@ caml-stubdom: mini-os-$(XEN_TARGET_ARCH)-caml lwip-$(XEN_TARGET_ARCH) libxc cros
 c-stubdom: mini-os-$(XEN_TARGET_ARCH)-c lwip-$(XEN_TARGET_ARCH) libxc c
 	DEF_CPPFLAGS="$(TARGET_CPPFLAGS)" DEF_CFLAGS="$(TARGET_CFLAGS)" DEF_LDFLAGS="$(TARGET_LDFLAGS)" MINIOS_CONFIG="$(CURDIR)/c/minios.cfg" $(MAKE) DESTDIR= -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< LWIPDIR=$(CURDIR)/lwip-$(XEN_TARGET_ARCH) APP_OBJS=$(CURDIR)/c/main.a
 
+.PHONY: vtpm-stubdom
+vtpm-stubdom: mini-os-$(XEN_TARGET_ARCH)-vtpm vtpm
+	DEF_CPPFLAGS="$(TARGET_CPPFLAGS)" DEF_CFLAGS="$(TARGET_CFLAGS)" DEF_LDFLAGS="$(TARGET_LDFLAGS)" MINIOS_CONFIG="$(CURDIR)/vtpm/minios.cfg" $(MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< APP_OBJS="$(CURDIR)/vtpm/vtpm.a" APP_LDLIBS="-ltpm -ltpm_crypto -lgmp"
+
+.PHONY: vtpmmgrdom
+vtpmmgrdom: mini-os-$(XEN_TARGET_ARCH)-vtpmmgr vtpmmgr
+	DEF_CPPFLAGS="$(TARGET_CPPFLAGS)" DEF_CFLAGS="$(TARGET_CFLAGS)" DEF_LDFLAGS="$(TARGET_LDFLAGS)" MINIOS_CONFIG="$(CURDIR)/vtpmmgr/minios.cfg" $(MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< APP_OBJS="$(CURDIR)/vtpmmgr/vtpmmgr.a" APP_LDLIBS="-lm"
+
 .PHONY: pv-grub
 pv-grub: mini-os-$(XEN_TARGET_ARCH)-grub libxc grub
 	DEF_CPPFLAGS="$(TARGET_CPPFLAGS)" DEF_CFLAGS="$(TARGET_CFLAGS)" DEF_LDFLAGS="$(TARGET_LDFLAGS)" MINIOS_CONFIG="$(CURDIR)/grub/minios.cfg" $(MAKE) DESTDIR= -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< APP_OBJS=$(CURDIR)/grub-$(XEN_TARGET_ARCH)/main.a
@@ -375,7 +483,7 @@ xenstore-stubdom: mini-os-$(XEN_TARGET_ARCH)-xenstore libxc xenstore
 #########
 
 ifeq ($(STUBDOM_SUPPORTED),1)
-install: genpath install-readme install-ioemu install-grub install-xenstore
+install: genpath install-readme install-ioemu install-grub install-xenstore install-vtpm install-vtpmmgr
 else
 install: genpath
 endif
@@ -399,6 +507,14 @@ install-xenstore: xenstore-stubdom
 	$(INSTALL_DIR) "$(DESTDIR)/usr/lib/xen/boot"
 	$(INSTALL_DATA) mini-os-$(XEN_TARGET_ARCH)-xenstore/mini-os.gz "$(DESTDIR)/usr/lib/xen/boot/xenstore-stubdom.gz"
 
+install-vtpm: vtpm-stubdom
+	$(INSTALL_DIR) "$(DESTDIR)$(XENFIRMWAREDIR)"
+	$(INSTALL_PROG) mini-os-$(XEN_TARGET_ARCH)-vtpm/mini-os.gz "$(DESTDIR)$(XENFIRMWAREDIR)/vtpm-stubdom.gz"
+
+install-vtpmmgr: vtpm-stubdom
+	$(INSTALL_DIR) "$(DESTDIR)$(XENFIRMWAREDIR)"
+	$(INSTALL_PROG) mini-os-$(XEN_TARGET_ARCH)-vtpmmgr/mini-os.gz "$(DESTDIR)$(XENFIRMWAREDIR)/vtpmmgrdom.gz"
+
 #######
 # clean
 #######
@@ -411,8 +527,12 @@ clean:
 	rm -fr mini-os-$(XEN_TARGET_ARCH)-caml
 	rm -fr mini-os-$(XEN_TARGET_ARCH)-grub
 	rm -fr mini-os-$(XEN_TARGET_ARCH)-xenstore
+	rm -fr mini-os-$(XEN_TARGET_ARCH)-vtpm
+	rm -fr mini-os-$(XEN_TARGET_ARCH)-vtpmmgr
 	$(MAKE) DESTDIR= -C caml clean
 	$(MAKE) DESTDIR= -C c clean
+	$(MAKE) -C vtpm clean
+	$(MAKE) -C vtpmmgr clean
 	rm -fr grub-$(XEN_TARGET_ARCH)
 	rm -f $(STUBDOMPATH)
 	[ ! -d libxc-$(XEN_TARGET_ARCH) ] || $(MAKE) DESTDIR= -C libxc-$(XEN_TARGET_ARCH) clean
@@ -426,6 +546,10 @@ crossclean: clean
 	rm -fr newlib-$(XEN_TARGET_ARCH)
 	rm -fr zlib-$(XEN_TARGET_ARCH) pciutils-$(XEN_TARGET_ARCH)
 	rm -fr libxc-$(XEN_TARGET_ARCH) ioemu
+	rm -fr gmp-$(XEN_TARGET_ARCH)
+	rm -fr polarssl-$(XEN_TARGET_ARCH)
+	rm -fr openssl-$(XEN_TARGET_ARCH)
+	rm -fr tpm_emulator-$(XEN_TARGET_ARCH)
 	rm -f mk-headers-$(XEN_TARGET_ARCH)
 	rm -fr ocaml-$(XEN_TARGET_ARCH)
 	rm -fr include
@@ -434,6 +558,10 @@ crossclean: clean
 .PHONY: patchclean
 patchclean: crossclean
 	rm -fr newlib-$(NEWLIB_VERSION)
+	rm -fr gmp-$(XEN_TARGET_ARCH)
+	rm -fr polarssl-$(XEN_TARGET_ARCH)
+	rm -fr openssl-$(XEN_TARGET_ARCH)
+	rm -fr tpm_emulator-$(XEN_TARGET_ARCH)
 	rm -fr lwip-$(XEN_TARGET_ARCH)
 	rm -fr grub-upstream
 
@@ -442,10 +570,14 @@ patchclean: crossclean
 downloadclean: patchclean
 	rm -f newlib-$(NEWLIB_VERSION).tar.gz
 	rm -f zlib-$(ZLIB_VERSION).tar.gz
+	rm -f gmp-$(GMP_VERSION).tar.gz
+	rm -f tpm_emulator-$(TPMEMU_VERSION).tar.gz
 	rm -f pciutils-$(LIBPCI_VERSION).tar.bz2
 	rm -f grub-$(GRUB_VERSION).tar.gz
 	rm -f lwip-$(LWIP_VERSION).tar.gz
 	rm -f ocaml-$(OCAML_VERSION).tar.gz
+	rm -f polarssl-$(POLARSSL_VERSION)-gpl.tgz
+	rm -f openssl-$(POLARSSL_VERSION)-gpl.tgz
 
 .PHONY: distclean
 distclean: downloadclean
diff --git a/stubdom/polarssl.patch b/stubdom/polarssl.patch
new file mode 100644
index 0000000..d387d4e
--- /dev/null
+++ b/stubdom/polarssl.patch
@@ -0,0 +1,64 @@
+diff -Naur polarssl-1.1.4/include/polarssl/config.h polarssl-x86_64/include/polarssl/config.h
+--- polarssl-1.1.4/include/polarssl/config.h	2011-12-22 05:06:27.000000000 -0500
++++ polarssl-x86_64/include/polarssl/config.h	2012-10-30 17:18:07.567001000 -0400
+@@ -164,8 +164,8 @@
+  * application.
+  *
+  * Uncomment this macro to prevent loading of default entropy functions.
+-#define POLARSSL_NO_DEFAULT_ENTROPY_SOURCES
+  */
++#define POLARSSL_NO_DEFAULT_ENTROPY_SOURCES
+
+ /**
+  * \def POLARSSL_NO_PLATFORM_ENTROPY
+@@ -175,8 +175,8 @@
+  * standards like the /dev/urandom or Windows CryptoAPI.
+  *
+  * Uncomment this macro to disable the built-in platform entropy functions.
+-#define POLARSSL_NO_PLATFORM_ENTROPY
+  */
++#define POLARSSL_NO_PLATFORM_ENTROPY
+
+ /**
+  * \def POLARSSL_PKCS1_V21
+@@ -426,8 +426,8 @@
+  * Requires: POLARSSL_TIMING_C
+  *
+  * This module enables the HAVEGE random number generator.
+- */
+ #define POLARSSL_HAVEGE_C
++ */
+
+ /**
+  * \def POLARSSL_MD_C
+@@ -490,7 +490,7 @@
+  *
+  * This module provides TCP/IP networking routines.
+  */
+-#define POLARSSL_NET_C
++//#define POLARSSL_NET_C
+
+ /**
+  * \def POLARSSL_PADLOCK_C
+@@ -644,8 +644,8 @@
+  * Caller:  library/havege.c
+  *
+  * This module is used by the HAVEGE random number generator.
+- */
+ #define POLARSSL_TIMING_C
++ */
+
+ /**
+  * \def POLARSSL_VERSION_C
+diff -Naur polarssl-1.1.4/library/bignum.c polarssl-x86_64/library/bignum.c
+--- polarssl-1.1.4/library/bignum.c	2012-04-29 16:15:55.000000000 -0400
++++ polarssl-x86_64/library/bignum.c	2012-10-30 17:21:52.135000999 -0400
+@@ -1101,7 +1101,7 @@
+             Z.p[i - t - 1] = ~0;
+         else
+         {
+-#if defined(POLARSSL_HAVE_LONGLONG)
++#if 0 //defined(POLARSSL_HAVE_LONGLONG)
+             t_udbl r;
+
+             r  = (t_udbl) X.p[i] << biL;
diff --git a/stubdom/tpmemu-0.7.4.patch b/stubdom/tpmemu-0.7.4.patch
new file mode 100644
index 0000000..b84eff1
--- /dev/null
+++ b/stubdom/tpmemu-0.7.4.patch
@@ -0,0 +1,12 @@
+diff -Naur tpm_emulator-x86_64-back/tpm/tpm_emulator_extern.c tpm_emulator-x86_64/tpm/tpm_emulator_extern.c
+--- tpm_emulator-x86_64-back/tpm/tpm_emulator_extern.c	2012-04-27 10:55:46.581963398 -0400
++++ tpm_emulator-x86_64/tpm/tpm_emulator_extern.c	2012-04-27 10:56:02.193034152 -0400
+@@ -249,7 +249,7 @@
+ #else /* TPM_NO_EXTERN */
+
+ int (*tpm_extern_init)(void)                                      = NULL;
+-int (*tpm_extern_release)(void)                                   = NULL;
++void (*tpm_extern_release)(void)                                   = NULL;
+ void* (*tpm_malloc)(size_t size)                                  = NULL;
+ void (*tpm_free)(/*const*/ void *ptr)                             = NULL;
+ void (*tpm_log)(int priority, const char *fmt, ...)               = NULL;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [VTPM v7 4/8] Add vtpm documentation
  2012-12-06 18:19 [VTPM v7 1/8] add vtpm-stubdom code Matthew Fioravante
  2012-12-06 18:19 ` [VTPM v7 2/8] add stubdom/vtpmmgr code Matthew Fioravante
  2012-12-06 18:19 ` [VTPM v7 3/8] vtpm/vtpmmgr and required libs to stubdom/Makefile Matthew Fioravante
@ 2012-12-06 18:19 ` Matthew Fioravante
  2012-12-06 18:19 ` [VTPM v7 5/8] Add cmake dependency to README Matthew Fioravante
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Matthew Fioravante @ 2012-12-06 18:19 UTC (permalink / raw)
  To: xen-devel, Ian.Jackson, Ian.Campbell; +Cc: Matthew Fioravante

See the files included in this patch for details

Signed-off-by: Matthew Fioravante <matthew.fioravante@jhuapl.edu>
---
 docs/misc/vtpm.txt     |  357 ++++++++++++++++++++++++++++++++++--------------
 stubdom/vtpm/README    |   75 ++++++++++
 stubdom/vtpmmgr/README |   75 ++++++++++
 3 files changed, 401 insertions(+), 106 deletions(-)
 create mode 100644 stubdom/vtpm/README
 create mode 100644 stubdom/vtpmmgr/README

diff --git a/docs/misc/vtpm.txt b/docs/misc/vtpm.txt
index ad37fe8..fc6029a 100644
--- a/docs/misc/vtpm.txt
+++ b/docs/misc/vtpm.txt
@@ -1,152 +1,297 @@
-Copyright: IBM Corporation (C), Intel Corporation
-29 June 2006
-Authors: Stefan Berger <stefanb@us.ibm.com> (IBM), 
-         Employees of Intel Corp
-
-This document gives a short introduction to the virtual TPM support
-in XEN and goes as far as connecting a user domain to a virtual TPM
-instance and doing a short test to verify success. It is assumed
-that the user is fairly familiar with compiling and installing XEN
-and Linux on a machine. 
+Copyright (c) 2010-2012 United States Government, as represented by
+the Secretary of Defense.  All rights reserved.
+November 12 2012
+Authors: Matthew Fioravante (JHUAPL),
+
+This document describes the virtual Trusted Platform Module (vTPM) subsystem
+for Xen. The reader is assumed to have familiarity with building and installing
+Xen, Linux, and a basic understanding of the TPM and vTPM concepts.
+
+------------------------------
+INTRODUCTION
+------------------------------
+The goal of this work is to provide a TPM functionality to a virtual guest
+operating system (a DomU).  This allows programs to interact with a TPM in a
+virtual system the same way they interact with a TPM on the physical system.
+Each guest gets its own unique, emulated, software TPM.  However, each of the
+vTPM's secrets (Keys, NVRAM, etc) are managed by a vTPM Manager domain, which
+seals the secrets to the Physical TPM.  Thus, the vTPM subsystem extends the
+chain of trust rooted in the hardware TPM to virtual machines in Xen. Each
+major component of vTPM is implemented as a separate domain, providing secure
+separation guaranteed by the hypervisor. The vTPM domains are implemented in
+mini-os to reduce memory and processor overhead.
+
+This mini-os vTPM subsystem was built on top of the previous vTPM
+work done by IBM and Intel corporation.
  
-Production Prerequisites: An x86-based machine machine with a
-Linux-supported TPM on the motherboard (NSC, Atmel, Infineon, TPM V1.2).
-Development Prerequisites: An emulator for TESTING ONLY is provided
-
+------------------------------
+DESIGN OVERVIEW
+------------------------------
+
+The architecture of vTPM is described below:
+
++------------------+
+|    Linux DomU    | ...
+|       |  ^       |
+|       v  |       |
+|   xen-tpmfront   |
++------------------+
+        |  ^
+        v  |
++------------------+
+| mini-os/tpmback  |
+|       |  ^       |
+|       v  |       |
+|  vtpm-stubdom    | ...
+|       |  ^       |
+|       v  |       |
+| mini-os/tpmfront |
++------------------+
+        |  ^
+        v  |
++------------------+
+| mini-os/tpmback  |
+|       |  ^       |
+|       v  |       |
+|   vtpmmgrdom     |
+|       |  ^       |
+|       v  |       |
+| mini-os/tpm_tis  |
++------------------+
+        |  ^
+        v  |
++------------------+
+|   Hardware TPM   |
++------------------+
+ * Linux DomU: The Linux based guest that wants to use a vTPM. There many be
+               more than one of these.
+
+ * xen-tpmfront.ko: Linux kernel virtual TPM frontend driver. This driver
+                    provides vTPM access to a para-virtualized Linux based DomU.
+
+ * mini-os/tpmback: Mini-os TPM backend driver. The Linux frontend driver
+                    connects to this backend driver to facilitate
+                    communications between the Linux DomU and its vTPM. This
+                    driver is also used by vtpmmgrdom to communicate with
+                    vtpm-stubdom.
+
+ * vtpm-stubdom: A mini-os stub domain that implements a vTPM. There is a
+                 one to one mapping between running vtpm-stubdom instances and
+                 logical vtpms on the system. The vTPM Platform Configuration
+                 Registers (PCRs) are all initialized to zero.
+
+ * mini-os/tpmfront: Mini-os TPM frontend driver. The vTPM mini-os domain
+                     vtpm-stubdom uses this driver to communicate with
+                     vtpmmgrdom. This driver could also be used separately to
+                     implement a mini-os domain that wishes to use a vTPM of
+                     its own.
+
+ * vtpmmgrdom: A mini-os domain that implements the vTPM manager.
+               There is only one vTPM manager and it should be running during
+               the entire lifetime of the machine.  This domain regulates
+               access to the physical TPM on the system and secures the
+               persistent state of each vTPM.
+
+ * mini-os/tpm_tis: Mini-os TPM version 1.2 TPM Interface Specification (TIS)
+                    driver. This driver used by vtpmmgrdom to talk directly to
+                    the hardware TPM. Communication is facilitated by mapping
+                    hardware memory pages into vtpmmgrdom.
+
+ * Hardware TPM: The physical TPM that is soldered onto the motherboard.
+
+------------------------------
+INSTALLATION
+------------------------------
+
+Prerequisites:
+--------------
+You must have an x86 machine with a TPM on the motherboard.
+The only software requirement to compiling vTPM is cmake.
+You must use libxl to manage domains with vTPMs. 'xm' is
+deprecated and does not support vTPM.
 
 Compiling the XEN tree:
 -----------------------
 
-Compile the XEN tree as usual after the following lines set in the
-linux-2.6.??-xen/.config file:
+Compile and install the XEN tree as usual. Be sure to build and install
+the stubdom tree.
+
+Compiling the LINUX dom0 kernel:
+--------------------------------
 
-CONFIG_XEN_TPMDEV_BACKEND=m
+The Linux dom0 kernel has no special prerequisites.
 
-CONFIG_TCG_TPM=m
-CONFIG_TCG_TIS=m      (supported after 2.6.17-rc4)
-CONFIG_TCG_NSC=m
-CONFIG_TCG_ATMEL=m
-CONFIG_TCG_INFINEON=m
-CONFIG_TCG_XEN=m
-<possible other TPM drivers supported by Linux>
+Compiling the LINUX domU kernel:
+--------------------------------
 
-If the frontend driver needs to be compiled into the user domain
-kernel, then the following two lines should be changed.
+The domU kernel used by domains with vtpms must
+include the xen-tpmfront.ko driver. It can be built
+directly into the kernel or as a module.
 
 CONFIG_TCG_TPM=y
 CONFIG_TCG_XEN=y
 
+------------------------------
+VTPM MANAGER SETUP
+------------------------------
+
+Manager disk image setup:
+-------------------------
+
+The vTPM Manager requires a disk image to store its
+encrypted data. The image does not require a filesystem
+and can live anywhere on the host disk. The image does not need
+to be large. 8 to 16 Mb should be sufficient.
+
+# dd if=/dev/zero of=/var/vtpmmgrdom.img bs=16M count=1
+
+Manager config file:
+--------------------
+
+The vTPM Manager domain (vtpmmgrdom) must be started like
+any other Xen virtual machine and requires a config file.
+The manager requires a disk image for storage and permission
+to access the hardware memory pages for the TPM. An
+example configuration looks like the following.
+
+kernel="/usr/lib/xen/boot/vtpmmgrdom.gz"
+memory=16
+disk=["file:/var/vtpmmgrdom.img,hda,w"]
+name="vtpmmgrdom"
+iomem=["fed40,5"]
+
+The iomem line tells xl to allow access to the TPM
+IO memory pages, which are 5 pages that start at
+0xfed40000.
+
+Starting and stopping the manager:
+----------------------------------
+
+The vTPM manager should be started at boot, you may wish to
+create an init script to do this.
+
+# xl create -c vtpmmgrdom.cfg
+
+Once initialization is complete you should see the following:
+INFO[VTPM]: Waiting for commands from vTPM's:
+
+To shutdown the manager you must destroy it. To avoid data corruption,
+only destroy the manager when you see the above "Waiting for commands"
+message. This ensures the disk is in a consistent state.
+
+# xl destroy vtpmmgrdom
+
+------------------------------
+VTPM AND LINUX PVM SETUP
+------------------------------
 
-You must also enable the virtual TPM to be built:
+In the following examples we will assume we have Linux
+guest named "domu" with its associated configuration
+located at /home/user/domu. It's vtpm will be named
+domu-vtpm.
 
-In Config.mk in the Xen root directory set the line
+vTPM disk image setup:
+----------------------
 
-VTPM_TOOLS ?= y
+The vTPM requires a disk image to store its persistent
+data. The image does not require a filesystem. The image
+does not need to be large. 8 Mb should be sufficient.
 
-and in
+# dd if=/dev/zero of=/home/user/domu/vtpm.img bs=8M count=1
 
-tools/vtpm/Rules.mk set the line
+vTPM config file:
+-----------------
 
-BUILD_EMULATOR = y
+The vTPM domain requires a configuration file like
+any other domain. The vTPM requires a disk image for
+storage and a TPM frontend driver to communicate
+with the manager. An example configuration is given:
 
-Now build the Xen sources from Xen's root directory:
+kernel="/usr/lib/xen/boot/vtpm-stubdom.gz"
+memory=8
+disk=["file:/home/user/domu/vtpm.img,hda,w"]
+name="domu-vtpm"
+vtpm=["backend=vtpmmgrdom,uuid=ac0a5b9e-cbe2-4c07-b43b-1d69e46fb839"]
 
-make install
+The vtpm= line sets up the tpm frontend driver. The backend must set
+to vtpmmgrdom. You are required to generate a uuid for this vtpm.
+You can use the uuidgen unix program or some other method to create a
+uuid. The uuid uniquely identifies this vtpm to manager.
 
+If you wish to clear the vTPM data you can either recreate the
+disk image or change the uuid.
 
-Also build the initial RAM disk if necessary.
+Linux Guest config file:
+------------------------
 
-Reboot the machine with the created Xen kernel.
+The Linux guest config file needs to be modified to include
+the Linux tpmfront driver. Add the following line:
 
-Note: If you do not want any TPM-related code compiled into your
-kernel or built as module then comment all the above lines like
-this example:
-# CONFIG_TCG_TPM is not set
+vtpm=["backend=domu-vtpm"]
 
+Currently only paravirtualized guests are supported.
 
-Modifying VM Configuration files:
----------------------------------
+Launching and shut down:
+------------------------
 
-VM configuration files need to be adapted to make a TPM instance
-available to a user domain. The following VM configuration file is
-an example of how a user domain can be configured to have a TPM
-available. It works similar to making a network interface
-available to a domain.
+To launch a Linux guest with a vTPM we first have to start the vTPM domain.
 
-kernel = "/boot/vmlinuz-2.6.x"
-ramdisk = "/xen/initrd_domU/U1_ramdisk.img"
-memory = 32
-name = "TPMUserDomain0"
-vtpm = ['instance=1,backend=0']
-root = "/dev/ram0 console=tty ro"
-vif = ['backend=0']
+# xl create -c /home/user/domu/vtpm.cfg
 
-In the above configuration file the line 'vtpm = ...' provides
-information about the domain where the virtual TPM is running and
-where the TPM backend has been compiled into - this has to be 
-domain 0  at the moment - and which TPM instance the user domain
-is supposed to talk to. Note that each running VM must use a 
-different instance and that using instance 0 is NOT allowed. The
-instance parameter is taken as the desired instance number, but
-the actual instance number that is assigned to the virtual machine
-can be different. This is the case if for example that particular
-instance is already used by another virtual machine. The association
-of which TPM instance number is used by which virtual machine is
-kept in the file /var/vtpm/vtpm.db. Associations are maintained by
-a xend-internal vTPM UUID and vTPM instance number.
+After initialization is complete, you should see the following:
+Info: Waiting for frontend domain to connect..
 
-Note: If you do not want TPM functionality for your user domain simply
-leave out the 'vtpm' line in the configuration file.
+Next, launch the Linux guest
 
+# xl create -c /home/user/domu/domu.cfg
 
-Running the TPM:
-----------------
+If xen-tpmfront was compiled as a module, be sure to load it
+in the guest.
 
-To run the vTPM, the device /dev/vtpm must be available.
-Verify that 'ls -l /dev/vtpm' shows the following output:
+# modprobe xen-tpmfront
 
-crw-------  1 root root 10, 225 Aug 11 06:58 /dev/vtpm
+After the Linux domain boots and the xen-tpmfront driver is loaded,
+you should see the following on the vtpm console:
 
-If it is not available, run the following command as 'root'.
-mknod /dev/vtpm c 10 225
+Info: VTPM attached to Frontend X/Y
 
-Make sure that the vTPM is running in domain 0. To do this run the
-following:
+If you have trousers and tpm_tools installed on the guest, you can test the
+vtpm.
 
-modprobe tpmbk
+On guest:
+# tcsd (if tcsd is not running already)
+# tpm_version
 
-/usr/bin/vtpm_managerd
+The version command should return the following:
+  TPM 1.2 Version Info:
+  Chip Version:        1.2.0.7
+  Spec Level:          2
+  Errata Revision:     1
+  TPM Vendor ID:       ETHZ
+  TPM Version:         01010000
+  Manufacturer Info:   4554485a
 
-Start a user domain using the 'xm create' command. Once you are in the
-shell of the user domain, you should be able to do the following as
-user 'root':
+You should also see the command being sent to the vtpm console as well
+as the vtpm saving its state. You should see the vtpm key being
+encrypted and stored on the vtpmmgrdom console.
 
-Insert the TPM frontend into the kernel if it has been compiled as a
-kernel module.
+To shutdown the guest and its vtpm, you just have to shutdown the guest
+normally. As soon as the guest vm disconnects, the vtpm will shut itself
+down automatically.
 
-> modprobe tpm_xenu
+On guest:
+# shutdown -h now
 
-Check the status of the TPM
+You may wish to write a script to start your vtpm and guest together.
 
-> cd /sys/devices/xen/vtpm-0
-> ls
-[...]  cancel  caps   pcrs    pubek   [...]
-> cat pcrs
-PCR-00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-PCR-01: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-PCR-02: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-PCR-03: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-PCR-04: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-PCR-05: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-PCR-06: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-PCR-07: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-PCR-08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-[...]
+------------------------------
+MORE INFORMATION
+------------------------------
 
-At this point the user domain has been successfully connected to its
-virtual TPM instance.
+See stubdom/vtpmmgr/README for more details about how
+the manager domain works, how to use it, and its command line
+parameters.
 
-For further information please read the documentation in 
-tools/vtpm_manager/README and tools/vtpm/README
+See stubdom/vtpm/README for more specifics about how vtpm-stubdom
+operates and the command line options it accepts.
 
-Stefan Berger and Employees of the Intel Corp
diff --git a/stubdom/vtpm/README b/stubdom/vtpm/README
new file mode 100644
index 0000000..11bdacb
--- /dev/null
+++ b/stubdom/vtpm/README
@@ -0,0 +1,75 @@
+Copyright (c) 2010-2012 United States Government, as represented by
+the Secretary of Defense.  All rights reserved.
+November 12 2012
+Authors: Matthew Fioravante (JHUAPL),
+
+This document describes the operation and command line interface
+of vtpm-stubdom. See docs/misc/vtpm.txt for details on the
+vTPM subsystem as a whole.
+
+
+------------------------------
+OPERATION
+------------------------------
+
+The vtpm-stubdom is a mini-OS domain that emulates a TPM for the guest OS to
+use. It is a small wrapper around the Berlios TPM emulator
+version 0.7.4. Commands are passed from the linux guest via the
+mini-os TPM backend driver. vTPM data is encrypted and stored via a disk image
+provided to the virtual machine. The key used to encrypt the data along
+with a hash of the vTPM's data is sent to the vTPM manager for secure storage
+and later retrieval.  The vTPM domain communicates with the manager using a
+mini-os tpm front/back device pair.
+
+------------------------------
+COMMAND LINE ARGUMENTS
+------------------------------
+
+Command line arguments are passed to the domain via the 'extra'
+parameter in the VM config file. Each parameter is separated
+by white space. For example:
+
+extra="foo=bar baz"
+
+List of Arguments:
+------------------
+
+loglevel=<LOG>: Controls the amount of logging printed to the console.
+	The possible values for <LOG> are:
+	 error
+	 info (default)
+	 debug
+
+clear: Start the Berlios emulator in "clear" mode. (default)
+
+save: Start the Berlios emulator in "save" mode.
+
+deactivated: Start the Berlios emulator in "deactivated" mode.
+	See the Berlios TPM emulator documentation for details
+	about the startup mode. For all normal use, always use clear
+	which is the default. You should not need to specify any of these.
+
+maintcmds=<1|0>: Enable to disable the TPM maintenance commands.
+	These commands are used by tpm manufacturers and thus
+	open a security hole. They are disabled by default.
+
+hwinitpcr=<PCRSPEC>: Initialize the virtual Platform Configuration Registers
+	(PCRs) with PCR values from the hardware TPM. Each pcr specified by
+	<PCRSPEC> will be initialized with the value of that same PCR in TPM
+	once at startup. By default all PCRs are zero initialized.
+	Value values of <PCRSPEC> are:
+	 all: copy all pcrs
+	 none: copy no pcrs (default)
+	 <N>: copy pcr n
+	 <X-Y>: copy pcrs x to y (inclusive)
+
+	These can also be combined by comma separation, for example:
+	 hwinitpcrs=5,12-16
+	will copy pcrs 5, 12, 13, 14, 15, and 16.
+
+------------------------------
+REFERENCES
+------------------------------
+
+Berlios TPM Emulator:
+http://tpm-emulator.berlios.de/
diff --git a/stubdom/vtpmmgr/README b/stubdom/vtpmmgr/README
new file mode 100644
index 0000000..09f3958
--- /dev/null
+++ b/stubdom/vtpmmgr/README
@@ -0,0 +1,75 @@
+Copyright (c) 2010-2012 United States Government, as represented by
+the Secretary of Defense.  All rights reserved.
+November 12 2012
+Authors: Matthew Fioravante (JHUAPL),
+
+This document describes the operation and command line interface
+of vtpmmgrdom. See docs/misc/vtpm.txt for details on the
+vTPM subsystem as a whole.
+
+
+------------------------------
+OPERATION
+------------------------------
+
+The vtpmmgrdom implements a vTPM manager who has two major functions:
+
+ - Securely store encryption keys for each of the vTPMS
+ - Regulate access to the hardware TPM for the entire system
+
+The manager accepts commands from the vtpm-stubdom domains via the mini-os
+TPM backend driver. The vTPM manager communicates directly with hardware TPM
+using the mini-os tpm_tis driver.
+
+
+When the manager starts for the first time it will check if the TPM
+has an owner. If the TPM is unowned, it will attempt to take ownership
+with the supplied owner_auth (see below) and then create a TPM
+storage key which will be used to secure vTPM key data. Currently the
+manager only binds vTPM keys to the disk. In the future support
+for sealing to PCRs should be added.
+
+------------------------------
+COMMAND LINE ARGUMENTS
+------------------------------
+
+Command line arguments are passed to the domain via the 'extra'
+parameter in the VM config file. Each parameter is separated
+by white space. For example:
+
+extra="foo=bar baz"
+
+List of Arguments:
+------------------
+
+owner_auth=<AUTHSPEC>: Set the owner auth of the TPM. The default
+	is the well known owner auth of all ones.
+
+srk_auth=<AUTHSPEC>: Set the SRK auth for the TPM. The default is
+	the well known srk auth of all zeroes.
+	The possible values of <AUTHSPEC> are:
+	 well-known: Use the well known auth (default)
+	 random: Randomly generate an auth
+	 hash: <HASH>: Use the given 40 character ASCII hex string
+	 text: <STR>: Use sha1 hash of <STR>.
+
+tpmdriver=<DRIVER>: Which driver to use to talk to the hardware TPM.
+	Don't change this unless you know what you're doing.
+	The possible values of <DRIVER> are:
+	 tpm_tis: Use the tpm_tis driver to talk directly to the TPM.
+		The domain must have access to TPM IO memory.  (default)
+	 tpmfront: Use tpmfront to talk to the TPM. The domain must have
+		a tpmfront device setup to talk to another domain
+		which provides access to the TPM.
+
+The following options only apply to the tpm_tis driver:
+
+tpmiomem=<ADDR>: The base address of the hardware memory pages of the
+	TPM (default 0xfed40000).
+
+tpmirq=<IRQ>: The irq of the hardware TPM if using interrupts. A value of
+	"probe" can be set to probe for the irq. A value of 0
+	disabled interrupts and uses polling (default 0).
+
+tpmlocality=<LOC>: Attempt to use locality <LOC> of the hardware TPM.
+	(default 0)
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [VTPM v7 5/8] Add cmake dependency to README
  2012-12-06 18:19 [VTPM v7 1/8] add vtpm-stubdom code Matthew Fioravante
                   ` (2 preceding siblings ...)
  2012-12-06 18:19 ` [VTPM v7 4/8] Add vtpm documentation Matthew Fioravante
@ 2012-12-06 18:19 ` Matthew Fioravante
  2012-12-06 18:19 ` [VTPM v7 6/8] Add autoconf to stubdom Matthew Fioravante
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Matthew Fioravante @ 2012-12-06 18:19 UTC (permalink / raw)
  To: xen-devel, Ian.Jackson, Ian.Campbell; +Cc: Matthew Fioravante

Signed-off-by: Matthew Fioravante <matthew.fioravante@jhuapl.edu>
---
 README |    1 +
 1 file changed, 1 insertion(+)

diff --git a/README b/README
index 1938f66..6b9b510 100644
--- a/README
+++ b/README
@@ -61,6 +61,7 @@ provided by your OS distributor:
     * 16-bit x86 assembler, loader and compiler (dev86 rpm or bin86 & bcc debs)
     * ACPI ASL compiler (iasl)
     * markdown
+    * cmake (if building vtpm stub domains)
 
 In addition to the above there are a number of optional build
 prerequisites. Omitting these will cause the related features to be
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [VTPM v7 6/8] Add autoconf to stubdom
  2012-12-06 18:19 [VTPM v7 1/8] add vtpm-stubdom code Matthew Fioravante
                   ` (3 preceding siblings ...)
  2012-12-06 18:19 ` [VTPM v7 5/8] Add cmake dependency to README Matthew Fioravante
@ 2012-12-06 18:19 ` Matthew Fioravante
  2012-12-13 12:02   ` Ian Campbell
  2012-12-06 18:19 ` [VTPM v7 7/8] Add a top level configure script Matthew Fioravante
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 14+ messages in thread
From: Matthew Fioravante @ 2012-12-06 18:19 UTC (permalink / raw)
  To: xen-devel, Ian.Jackson, Ian.Campbell; +Cc: Matthew Fioravante

Please rerun autoconf after commiting this patch

Signed-off-by: Matthew Fioravante <matthew.fioravante@jhuapl.edu>
---
 autogen.sh                             |    2 +
 config/Stubdom.mk.in                   |   45 ++++++++++++++++
 {tools/m4 => m4}/curses.m4             |    0
 m4/depends.m4                          |   15 ++++++
 {tools/m4 => m4}/extfs.m4              |    0
 {tools/m4 => m4}/features.m4           |    0
 {tools/m4 => m4}/fetcher.m4            |    0
 {tools/m4 => m4}/ocaml.m4              |    0
 {tools/m4 => m4}/path_or_fail.m4       |    0
 {tools/m4 => m4}/pkg.m4                |    0
 {tools/m4 => m4}/pthread.m4            |    0
 {tools/m4 => m4}/ptyfuncs.m4           |    0
 {tools/m4 => m4}/python_devel.m4       |    0
 {tools/m4 => m4}/python_version.m4     |    0
 {tools/m4 => m4}/savevar.m4            |    0
 {tools/m4 => m4}/set_cflags_ldflags.m4 |    0
 m4/stubdom.m4                          |   89 ++++++++++++++++++++++++++++++++
 {tools/m4 => m4}/uuid.m4               |    0
 stubdom/Makefile                       |   55 +++++---------------
 stubdom/configure.ac                   |   58 +++++++++++++++++++++
 tools/configure.ac                     |   28 +++++-----
 21 files changed, 236 insertions(+), 56 deletions(-)
 create mode 100644 config/Stubdom.mk.in
 rename {tools/m4 => m4}/curses.m4 (100%)
 create mode 100644 m4/depends.m4
 rename {tools/m4 => m4}/extfs.m4 (100%)
 rename {tools/m4 => m4}/features.m4 (100%)
 rename {tools/m4 => m4}/fetcher.m4 (100%)
 rename {tools/m4 => m4}/ocaml.m4 (100%)
 rename {tools/m4 => m4}/path_or_fail.m4 (100%)
 rename {tools/m4 => m4}/pkg.m4 (100%)
 rename {tools/m4 => m4}/pthread.m4 (100%)
 rename {tools/m4 => m4}/ptyfuncs.m4 (100%)
 rename {tools/m4 => m4}/python_devel.m4 (100%)
 rename {tools/m4 => m4}/python_version.m4 (100%)
 rename {tools/m4 => m4}/savevar.m4 (100%)
 rename {tools/m4 => m4}/set_cflags_ldflags.m4 (100%)
 create mode 100644 m4/stubdom.m4
 rename {tools/m4 => m4}/uuid.m4 (100%)
 create mode 100644 stubdom/configure.ac

diff --git a/autogen.sh b/autogen.sh
index 58a71ce..ada482c 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -2,3 +2,5 @@
 cd tools
 autoconf
 autoheader
+cd ../stubdom
+autoconf
diff --git a/config/Stubdom.mk.in b/config/Stubdom.mk.in
new file mode 100644
index 0000000..432efd7
--- /dev/null
+++ b/config/Stubdom.mk.in
@@ -0,0 +1,45 @@
+# Prefix and install folder
+prefix              := @prefix@
+PREFIX              := $(prefix)
+exec_prefix         := @exec_prefix@
+libdir              := @libdir@
+LIBDIR              := $(libdir)
+
+# Path Programs
+CMAKE               := @CMAKE@
+WGET                := @WGET@ -c
+
+# A debug build of stubdom? //FIXME: Someone make this do something
+debug               := @debug@
+vtpm = @vtpm@
+
+STUBDOM_TARGETS     := @STUBDOM_TARGETS@
+STUBDOM_BUILD       := @STUBDOM_BUILD@
+STUBDOM_INSTALL     := @STUBDOM_INSTALL@
+
+ZLIB_VERSION        := @ZLIB_VERSION@
+ZLIB_URL            := @ZLIB_URL@
+
+LIBPCI_VERSION      := @LIBPCI_VERSION@
+LIBPCI_URL          := @LIBPCI_URL@
+
+NEWLIB_VERSION      := @NEWLIB_VERSION@
+NEWLIB_URL          := @NEWLIB_URL@
+
+LWIP_VERSION        := @LWIP_VERSION@
+LWIP_URL            := @LWIP_URL@
+
+GRUB_VERSION        := @GRUB_VERSION@
+GRUB_URL            := @GRUB_URL@
+
+OCAML_VERSION       := @OCAML_VERSION@
+OCAML_URL           := @OCAML_URL@
+
+GMP_VERSION         := @GMP_VERSION@
+GMP_URL             := @GMP_URL@
+
+POLARSSL_VERSION    := @POLARSSL_VERSION@
+POLARSSL_URL        := @POLARSSL_URL@
+
+TPMEMU_VERSION      := @TPMEMU_VERSION@
+TPMEMU_URL          := @TPMEMU_URL@
diff --git a/tools/m4/curses.m4 b/m4/curses.m4
similarity index 100%
rename from tools/m4/curses.m4
rename to m4/curses.m4
diff --git a/m4/depends.m4 b/m4/depends.m4
new file mode 100644
index 0000000..916e665
--- /dev/null
+++ b/m4/depends.m4
@@ -0,0 +1,15 @@
+
+AC_DEFUN([AX_DEPENDS_PATH_PROG], [
+AS_IF([test "x$$1" = "xy"], [AX_PATH_PROG_OR_FAIL([$2], [$3])], [
+AS_IF([test "x$$1" = "xn"], [
+$2="/$3-disabled-in-configure-script"
+], [
+AC_PATH_PROG([$2], [$3], [no])
+AS_IF([test x"${$2}" = "xno"], [
+$1=n
+$2="/$3-disabled-in-configure-script"
+])
+])
+])
+AC_SUBST($2)
+])
diff --git a/tools/m4/extfs.m4 b/m4/extfs.m4
similarity index 100%
rename from tools/m4/extfs.m4
rename to m4/extfs.m4
diff --git a/tools/m4/features.m4 b/m4/features.m4
similarity index 100%
rename from tools/m4/features.m4
rename to m4/features.m4
diff --git a/tools/m4/fetcher.m4 b/m4/fetcher.m4
similarity index 100%
rename from tools/m4/fetcher.m4
rename to m4/fetcher.m4
diff --git a/tools/m4/ocaml.m4 b/m4/ocaml.m4
similarity index 100%
rename from tools/m4/ocaml.m4
rename to m4/ocaml.m4
diff --git a/tools/m4/path_or_fail.m4 b/m4/path_or_fail.m4
similarity index 100%
rename from tools/m4/path_or_fail.m4
rename to m4/path_or_fail.m4
diff --git a/tools/m4/pkg.m4 b/m4/pkg.m4
similarity index 100%
rename from tools/m4/pkg.m4
rename to m4/pkg.m4
diff --git a/tools/m4/pthread.m4 b/m4/pthread.m4
similarity index 100%
rename from tools/m4/pthread.m4
rename to m4/pthread.m4
diff --git a/tools/m4/ptyfuncs.m4 b/m4/ptyfuncs.m4
similarity index 100%
rename from tools/m4/ptyfuncs.m4
rename to m4/ptyfuncs.m4
diff --git a/tools/m4/python_devel.m4 b/m4/python_devel.m4
similarity index 100%
rename from tools/m4/python_devel.m4
rename to m4/python_devel.m4
diff --git a/tools/m4/python_version.m4 b/m4/python_version.m4
similarity index 100%
rename from tools/m4/python_version.m4
rename to m4/python_version.m4
diff --git a/tools/m4/savevar.m4 b/m4/savevar.m4
similarity index 100%
rename from tools/m4/savevar.m4
rename to m4/savevar.m4
diff --git a/tools/m4/set_cflags_ldflags.m4 b/m4/set_cflags_ldflags.m4
similarity index 100%
rename from tools/m4/set_cflags_ldflags.m4
rename to m4/set_cflags_ldflags.m4
diff --git a/m4/stubdom.m4 b/m4/stubdom.m4
new file mode 100644
index 0000000..0bf0d2c
--- /dev/null
+++ b/m4/stubdom.m4
@@ -0,0 +1,89 @@
+AC_DEFUN([AX_STUBDOM_DEFAULT_ENABLE], [
+AC_ARG_ENABLE([$1],
+AS_HELP_STRING([--disable-$1], [Build and install $1 (default is ENABLED)]),[
+AX_STUBDOM_INTERNAL([$1], [$2])
+],[
+AX_ENABLE_STUBDOM([$1], [$2])
+])
+AC_SUBST([$2])
+])
+
+AC_DEFUN([AX_STUBDOM_DEFAULT_DISABLE], [
+AC_ARG_ENABLE([$1],
+AS_HELP_STRING([--enable-$1], [Build and install $1 (default is DISABLED)]),[
+AX_STUBDOM_INTERNAL([$1], [$2])
+],[
+AX_DISABLE_STUBDOM([$1], [$2])
+])
+AC_SUBST([$2])
+])
+
+AC_DEFUN([AX_STUBDOM_CONDITIONAL], [
+AC_ARG_ENABLE([$1],
+AS_HELP_STRING([--enable-$1], [Build and install $1]),[
+AX_STUBDOM_INTERNAL([$1], [$2])
+])
+])
+
+AC_DEFUN([AX_STUBDOM_CONDITIONAL_FINISH], [
+AS_IF([test "x$$2" = "xy" || test "x$$2" = "x"], [
+AX_ENABLE_STUBDOM([$1],[$2])
+],[
+AX_DISABLE_STUBDOM([$1],[$2])
+])
+AC_SUBST([$2])
+])
+
+AC_DEFUN([AX_ENABLE_STUBDOM], [
+$2=y
+STUBDOM_TARGETS="$STUBDOM_TARGETS $2"
+STUBDOM_BUILD="$STUBDOM_BUILD $1"
+STUBDOM_INSTALL="$STUBDOM_INSTALL install-$2"
+])
+
+AC_DEFUN([AX_DISABLE_STUBDOM], [
+$2=n
+])
+
+dnl Don't call this outside of this file
+AC_DEFUN([AX_STUBDOM_INTERNAL], [
+AS_IF([test "x$enableval" = "xyes"], [
+AX_ENABLE_STUBDOM([$1], [$2])
+],[
+AS_IF([test "x$enableval" = "xno"],[
+AX_DISABLE_STUBDOM([$1], [$2])
+])
+])
+])
+
+AC_DEFUN([AX_STUBDOM_FINISH], [
+AC_SUBST(STUBDOM_TARGETS)
+AC_SUBST(STUBDOM_BUILD)
+AC_SUBST(STUBDOM_INSTALL)
+echo "Will build the following stub domains:"
+for x in $STUBDOM_BUILD; do
+	echo "  $x"
+done
+])
+
+AC_DEFUN([AX_STUBDOM_LIB], [
+AC_ARG_VAR([$1_URL], [Download url for $2])
+AS_IF([test "x$$1_URL" = "x"], [
+	AS_IF([test "x$extfiles" = "xy"],
+		[$1_URL=\@S|@\@{:@XEN_EXTFILES_URL\@:}@],
+		[$1_URL="$4"])
+	])
+$1_VERSION="$3"
+AC_SUBST($1_URL)
+AC_SUBST($1_VERSION)
+])
+
+AC_DEFUN([AX_STUBDOM_LIB_NOEXT], [
+AC_ARG_VAR([$1_URL], [Download url for $2])
+AS_IF([test "x$$1_URL" = "x"], [
+	$1_URL="$4"
+	])
+$1_VERSION="$3"
+AC_SUBST($1_URL)
+AC_SUBST($1_VERSION)
+])
diff --git a/tools/m4/uuid.m4 b/m4/uuid.m4
similarity index 100%
rename from tools/m4/uuid.m4
rename to m4/uuid.m4
diff --git a/stubdom/Makefile b/stubdom/Makefile
index fc70d88..709b71e 100644
--- a/stubdom/Makefile
+++ b/stubdom/Makefile
@@ -6,44 +6,7 @@ export XEN_OS=MiniOS
 export stubdom=y
 export debug=y
 include $(XEN_ROOT)/Config.mk
-
-#ZLIB_URL?=http://www.zlib.net
-ZLIB_URL=$(XEN_EXTFILES_URL)
-ZLIB_VERSION=1.2.3
-
-#LIBPCI_URL?=http://www.kernel.org/pub/software/utils/pciutils
-LIBPCI_URL?=$(XEN_EXTFILES_URL)
-LIBPCI_VERSION=2.2.9
-
-#NEWLIB_URL?=ftp://sources.redhat.com/pub/newlib
-NEWLIB_URL?=$(XEN_EXTFILES_URL)
-NEWLIB_VERSION=1.16.0
-
-#LWIP_URL?=http://download.savannah.gnu.org/releases/lwip
-LWIP_URL?=$(XEN_EXTFILES_URL)
-LWIP_VERSION=1.3.0
-
-#GRUB_URL?=http://alpha.gnu.org/gnu/grub
-GRUB_URL?=$(XEN_EXTFILES_URL)
-GRUB_VERSION=0.97
-
-#OCAML_URL?=$(XEN_EXTFILES_URL)
-OCAML_URL?=http://caml.inria.fr/pub/distrib/ocaml-3.11
-OCAML_VERSION=3.11.0
-
-GMP_VERSION=4.3.2
-GMP_URL?=$(XEN_EXTFILES_URL)
-#GMP_URL?=ftp://ftp.gmplib.org/pub/gmp-$(GMP_VERSION)
-
-POLARSSL_VERSION=1.1.4
-POLARSSL_URL?=$(XEN_EXTFILES_URL)
-#POLARSSL_URL?=http://polarssl.org/code/releases
-
-TPMEMU_VERSION=0.7.4
-TPMEMU_URL?=$(XEN_EXTFILES_URL)
-#TPMEMU_URL?=http://download.berlios.de/tpm-emulator
-
-WGET=wget -c
+-include $(XEN_ROOT)/config/Stubdom.mk
 
 GNU_TARGET_ARCH:=$(XEN_TARGET_ARCH)
 ifeq ($(XEN_TARGET_ARCH),x86_32)
@@ -86,12 +49,12 @@ TARGET_CPPFLAGS += -I$(XEN_ROOT)/xen/include
 
 TARGET_LDFLAGS += -nostdlib -L$(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/lib
 
-TARGETS=ioemu c caml grub xenstore vtpm vtpmmgr
+TARGETS=$(STUBDOM_TARGETS)
 
 .PHONY: all
 all: build
 ifeq ($(STUBDOM_SUPPORTED),1)
-build: genpath ioemu-stubdom c-stubdom pv-grub xenstore-stubdom vtpm-stubdom vtpmmgrdom
+build: genpath $(STUBDOM_BUILD)
 else
 build: genpath
 endif
@@ -245,7 +208,7 @@ tpm_emulator-$(XEN_TARGET_ARCH): tpm_emulator-$(TPMEMU_VERSION).tar.gz
 	mv tpm_emulator-$(TPMEMU_VERSION) $@
 	patch -d $@ -p1 < tpmemu-$(TPMEMU_VERSION).patch;
 	mkdir $@/build
-	cd $@/build; cmake .. -DCMAKE_C_COMPILER=${CC} -DCMAKE_C_FLAGS="-std=c99 -DTPM_NO_EXTERN $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-declaration-after-statement"
+	cd $@/build; $(CMAKE) .. -DCMAKE_C_COMPILER=${CC} -DCMAKE_C_FLAGS="-std=c99 -DTPM_NO_EXTERN $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-declaration-after-statement"
 	touch $@
 
 TPMEMU_STAMPFILE=$(CROSS_ROOT)/$(GNU_TARGET_ARCH)-xen-elf/lib/libtpm.a
@@ -483,7 +446,7 @@ xenstore-stubdom: mini-os-$(XEN_TARGET_ARCH)-xenstore libxc xenstore
 #########
 
 ifeq ($(STUBDOM_SUPPORTED),1)
-install: genpath install-readme install-ioemu install-grub install-xenstore install-vtpm install-vtpmmgr
+install: genpath install-readme $(STUBDOM_INSTALL)
 else
 install: genpath
 endif
@@ -503,6 +466,8 @@ install-grub: pv-grub
 	$(INSTALL_DIR) "$(DESTDIR)$(XENFIRMWAREDIR)"
 	$(INSTALL_DATA) mini-os-$(XEN_TARGET_ARCH)-grub/mini-os.gz "$(DESTDIR)$(XENFIRMWAREDIR)/pv-grub-$(XEN_TARGET_ARCH).gz"
 
+install-caml: caml-stubdom
+
 install-xenstore: xenstore-stubdom
 	$(INSTALL_DIR) "$(DESTDIR)/usr/lib/xen/boot"
 	$(INSTALL_DATA) mini-os-$(XEN_TARGET_ARCH)-xenstore/mini-os.gz "$(DESTDIR)/usr/lib/xen/boot/xenstore-stubdom.gz"
@@ -581,3 +546,9 @@ downloadclean: patchclean
 
 .PHONY: distclean
 distclean: downloadclean
+	-rm ../config/Stubdom.mk
+
+ifeq (,$(findstring clean,$(MAKECMDGOALS)))
+$(XEN_ROOT)/config/Stubdom.mk:
+	$(error You have to run ./configure before building or installing stubdom)
+endif
diff --git a/stubdom/configure.ac b/stubdom/configure.ac
new file mode 100644
index 0000000..db44d4a
--- /dev/null
+++ b/stubdom/configure.ac
@@ -0,0 +1,58 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.67])
+AC_INIT([Xen Hypervisor Stub Domains], m4_esyscmd([../version.sh ../xen/Makefile]),
+    [xen-devel@lists.xen.org], [xen], [http://www.xen.org/])
+AC_CONFIG_SRCDIR([../extras/mini-os/kernel.c])
+AC_CONFIG_FILES([../config/Stubdom.mk])
+AC_PREFIX_DEFAULT([/usr])
+AC_CONFIG_AUX_DIR([../])
+
+# M4 Macro includes
+m4_include([../m4/stubdom.m4])
+m4_include([../m4/features.m4])
+m4_include([../m4/path_or_fail.m4])
+m4_include([../m4/depends.m4])
+
+# Enable/disable stub domains
+AX_STUBDOM_DEFAULT_ENABLE([ioemu-stubdom], [ioemu])
+AX_STUBDOM_DEFAULT_DISABLE([c-stubdom], [c])
+AX_STUBDOM_DEFAULT_ENABLE([caml-stubdom], [caml])
+AX_STUBDOM_DEFAULT_ENABLE([pv-grub], [grub])
+AX_STUBDOM_DEFAULT_ENABLE([xenstore-stubdom], [xenstore])
+AX_STUBDOM_CONDITIONAL([vtpm-stubdom], [vtpm])
+AX_STUBDOM_CONDITIONAL([vtpmmgrdom], [vtpmmgr])
+
+AX_ARG_DEFAULT_ENABLE([debug], [Disable debug build of stubdom])
+AX_ARG_DEFAULT_ENABLE([extfiles], [Use xen extfiles repository for libraries])
+
+AC_ARG_VAR([CMAKE], [Path to the cmake program])
+AC_ARG_VAR([WGET], [Path to wget program])
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_MAKE_SET
+AC_PROG_INSTALL
+AX_PATH_PROG_OR_FAIL([WGET], [wget])
+
+# Checks for programs that depend on a feature
+AX_DEPENDS_PATH_PROG([vtpm], [CMAKE], [cmake])
+
+# Stubdom libraries version and url setup
+AX_STUBDOM_LIB([ZLIB], [zlib], [1.2.3], [http://www.zlib.net])
+AX_STUBDOM_LIB([LIBPCI], [libpci], [2.2.9], [http://www.kernel.org/pub/software/utils/pciutils])
+AX_STUBDOM_LIB([NEWLIB], [newlib], [1.16.0], [ftp://sources.redhat.com/pub/newlib])
+AX_STUBDOM_LIB([LWIP], [lwip], [1.3.0], [http://download.savannah.gnu.org/releases/lwip])
+AX_STUBDOM_LIB([GRUB], [grub], [0.97], [http://alpha.gnu.org/gnu/grub])
+AX_STUBDOM_LIB_NOEXT([OCAML], [ocaml], [3.11.0], [http://caml.inria.fr/pub/distrib/ocaml-3.11])
+AX_STUBDOM_LIB([GMP], [libgmp], [4.3.2], [ftp://ftp.gmplib.org/pub/gmp-4.3.2])
+AX_STUBDOM_LIB([POLARSSL], [polarssl], [1.1.4], [http://polarssl.org/code/releases])
+AX_STUBDOM_LIB([TPMEMU], [berlios tpm emulator], [0.7.4], [http://download.berlios.de/tpm-emulator])
+
+#Conditionally enable these stubdoms based on the presense of dependencies
+AX_STUBDOM_CONDITIONAL_FINISH([vtpm-stubdom], [vtpm])
+AX_STUBDOM_CONDITIONAL_FINISH([vtpmmgrdom], [vtpmmgr])
+
+AX_STUBDOM_FINISH
+AC_OUTPUT()
diff --git a/tools/configure.ac b/tools/configure.ac
index 586313d..971e3e9 100644
--- a/tools/configure.ac
+++ b/tools/configure.ac
@@ -22,20 +22,20 @@ APPEND_INCLUDES and APPEND_LIB instead when possible.])
 AC_CANONICAL_HOST
 
 # M4 Macro includes
-m4_include([m4/savevar.m4])
-m4_include([m4/features.m4])
-m4_include([m4/path_or_fail.m4])
-m4_include([m4/python_version.m4])
-m4_include([m4/python_devel.m4])
-m4_include([m4/ocaml.m4])
-m4_include([m4/set_cflags_ldflags.m4])
-m4_include([m4/uuid.m4])
-m4_include([m4/pkg.m4])
-m4_include([m4/curses.m4])
-m4_include([m4/pthread.m4])
-m4_include([m4/ptyfuncs.m4])
-m4_include([m4/extfs.m4])
-m4_include([m4/fetcher.m4])
+m4_include([../m4/savevar.m4])
+m4_include([../m4/features.m4])
+m4_include([../m4/path_or_fail.m4])
+m4_include([../m4/python_version.m4])
+m4_include([../m4/python_devel.m4])
+m4_include([../m4/ocaml.m4])
+m4_include([../m4/set_cflags_ldflags.m4])
+m4_include([../m4/uuid.m4])
+m4_include([../m4/pkg.m4])
+m4_include([../m4/curses.m4])
+m4_include([../m4/pthread.m4])
+m4_include([../m4/ptyfuncs.m4])
+m4_include([../m4/extfs.m4])
+m4_include([../m4/fetcher.m4])
 
 # Enable/disable options
 AX_ARG_DEFAULT_DISABLE([githttp], [Download GIT repositories via HTTP])
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [VTPM v7 7/8] Add a top level configure script
  2012-12-06 18:19 [VTPM v7 1/8] add vtpm-stubdom code Matthew Fioravante
                   ` (4 preceding siblings ...)
  2012-12-06 18:19 ` [VTPM v7 6/8] Add autoconf to stubdom Matthew Fioravante
@ 2012-12-06 18:19 ` Matthew Fioravante
  2012-12-06 18:19 ` [VTPM v7 8/8] Add conditional build of subsystems to configure.ac Matthew Fioravante
  2012-12-13 11:48 ` [VTPM v7 1/8] add vtpm-stubdom code Ian Campbell
  7 siblings, 0 replies; 14+ messages in thread
From: Matthew Fioravante @ 2012-12-06 18:19 UTC (permalink / raw)
  To: xen-devel, Ian.Jackson, Ian.Campbell; +Cc: Matthew Fioravante

Please rerun autoconf after commiting this patch

Signed-off-by: Matthew Fioravante <matthew.fioravante@jhuapl.edu>
---
 autogen.sh                         |    1 +
 tools/config.guess => config.guess |    0
 tools/config.sub => config.sub     |    0
 configure.ac                       |   12 ++++++++++++
 tools/configure.ac                 |    4 ++--
 tools/install.sh                   |    1 -
 6 files changed, 15 insertions(+), 3 deletions(-)
 rename tools/config.guess => config.guess (100%)
 rename tools/config.sub => config.sub (100%)
 create mode 100644 configure.ac
 mode change 100755 => 100644 install.sh
 delete mode 100644 tools/install.sh

diff --git a/autogen.sh b/autogen.sh
index ada482c..1456d94 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -1,4 +1,5 @@
 #!/bin/sh -e
+autoconf
 cd tools
 autoconf
 autoheader
diff --git a/tools/config.guess b/config.guess
similarity index 100%
rename from tools/config.guess
rename to config.guess
diff --git a/tools/config.sub b/config.sub
similarity index 100%
rename from tools/config.sub
rename to config.sub
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..5dacb46
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,12 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.67])
+AC_INIT([Xen Hypervisor], m4_esyscmd([./version.sh ./xen/Makefile]),
+    [xen-devel@lists.xen.org], [xen], [http://www.xen.org/])
+AC_CONFIG_SRCDIR([./xen/common/kernel.c])
+AC_PREFIX_DEFAULT([/usr])
+
+AC_CONFIG_SUBDIRS([tools stubdom])
+
+AC_OUTPUT()
diff --git a/install.sh b/install.sh
old mode 100755
new mode 100644
diff --git a/tools/configure.ac b/tools/configure.ac
index 971e3e9..2bd71b6 100644
--- a/tools/configure.ac
+++ b/tools/configure.ac
@@ -2,13 +2,13 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ([2.67])
-AC_INIT([Xen Hypervisor], m4_esyscmd([../version.sh ../xen/Makefile]),
+AC_INIT([Xen Hypervisor Tools], m4_esyscmd([../version.sh ../xen/Makefile]),
     [xen-devel@lists.xen.org], [xen], [http://www.xen.org/])
 AC_CONFIG_SRCDIR([libxl/libxl.c])
 AC_CONFIG_FILES([../config/Tools.mk])
 AC_CONFIG_HEADERS([config.h])
 AC_PREFIX_DEFAULT([/usr])
-AC_CONFIG_AUX_DIR([.])
+AC_CONFIG_AUX_DIR([../])
 
 # Check if CFLAGS, LDFLAGS, LIBS, CPPFLAGS or CPP is set and print a warning
 
diff --git a/tools/install.sh b/tools/install.sh
deleted file mode 100644
index 3f44f99..0000000
--- a/tools/install.sh
+++ /dev/null
@@ -1 +0,0 @@
-../install.sh
\ No newline at end of file
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [VTPM v7 8/8] Add conditional build of subsystems to configure.ac
  2012-12-06 18:19 [VTPM v7 1/8] add vtpm-stubdom code Matthew Fioravante
                   ` (5 preceding siblings ...)
  2012-12-06 18:19 ` [VTPM v7 7/8] Add a top level configure script Matthew Fioravante
@ 2012-12-06 18:19 ` Matthew Fioravante
  2012-12-13 11:48 ` [VTPM v7 1/8] add vtpm-stubdom code Ian Campbell
  7 siblings, 0 replies; 14+ messages in thread
From: Matthew Fioravante @ 2012-12-06 18:19 UTC (permalink / raw)
  To: xen-devel, Ian.Jackson, Ian.Campbell; +Cc: Matthew Fioravante

The toplevel Makefile still works without running configure
and will default build everything

Signed-off-by: Matthew Fioravante <matthew.fioravante@jhuapl.edu>
---
 Makefile              |   10 ++++++++--
 config/Toplevel.mk.in |    1 +
 configure.ac          |   11 ++++++++++-
 m4/subsystem.m4       |   32 ++++++++++++++++++++++++++++++++
 4 files changed, 51 insertions(+), 3 deletions(-)
 create mode 100644 config/Toplevel.mk.in
 create mode 100644 m4/subsystem.m4

diff --git a/Makefile b/Makefile
index a6ed8be..aa3c7bd 100644
--- a/Makefile
+++ b/Makefile
@@ -6,6 +6,11 @@
 .PHONY: all
 all: dist
 
+-include config/Toplevel.mk
+SUBSYSTEMS?=xen kernels tools stubdom docs
+TARGS_DIST=$(patsubst %, dist-%, $(SUBSYSTEMS))
+TARGS_INSTALL=$(patsubst %, install-%, $(SUBSYSTEMS))
+
 export XEN_ROOT=$(CURDIR)
 include Config.mk
 
@@ -15,7 +20,7 @@ include buildconfigs/Rules.mk
 
 # build and install everything into the standard system directories
 .PHONY: install
-install: install-xen install-kernels install-tools install-stubdom install-docs
+install: $(TARGS_INSTALL)
 
 .PHONY: build
 build: kernels
@@ -37,7 +42,7 @@ test:
 # build and install everything into local dist directory
 .PHONY: dist
 dist: DESTDIR=$(DISTDIR)/install
-dist: dist-xen dist-kernels dist-tools dist-stubdom dist-docs dist-misc
+dist: $(TARGS_DIST) dist-misc
 
 dist-misc:
 	$(INSTALL_DIR) $(DISTDIR)/
@@ -151,6 +156,7 @@ endif
 # clean, but blow away kernel build tree plus tarballs
 .PHONY: distclean
 distclean:
+	-rm config/Toplevel.mk
 	$(MAKE) -C xen distclean
 	$(MAKE) -C tools distclean
 	$(MAKE) -C stubdom distclean
diff --git a/config/Toplevel.mk.in b/config/Toplevel.mk.in
new file mode 100644
index 0000000..4db7eaf
--- /dev/null
+++ b/config/Toplevel.mk.in
@@ -0,0 +1 @@
+SUBSYSTEMS               := @SUBSYSTEMS@
diff --git a/configure.ac b/configure.ac
index 5dacb46..fcbc4ae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,7 +6,16 @@ AC_INIT([Xen Hypervisor], m4_esyscmd([./version.sh ./xen/Makefile]),
     [xen-devel@lists.xen.org], [xen], [http://www.xen.org/])
 AC_CONFIG_SRCDIR([./xen/common/kernel.c])
 AC_PREFIX_DEFAULT([/usr])
+AC_CONFIG_FILES([./config/Toplevel.mk])
 
-AC_CONFIG_SUBDIRS([tools stubdom])
+m4_include([m4/features.m4])
+m4_include([m4/subsystem.m4])
+
+AX_SUBSYSTEM_DEFAULT_ENABLE([xen])
+AX_SUBSYSTEM_DEFAULT_ENABLE([kernels])
+AX_SUBSYSTEM_DEFAULT_ENABLE([tools])
+AX_SUBSYSTEM_DEFAULT_ENABLE([stubdom])
+AX_SUBSYSTEM_DEFAULT_ENABLE([docs])
+AX_SUBSYSTEM_FINISH
 
 AC_OUTPUT()
diff --git a/m4/subsystem.m4 b/m4/subsystem.m4
new file mode 100644
index 0000000..d3eb8c9
--- /dev/null
+++ b/m4/subsystem.m4
@@ -0,0 +1,32 @@
+AC_DEFUN([AX_SUBSYSTEM_DEFAULT_ENABLE], [
+AC_ARG_ENABLE([$1],
+AS_HELP_STRING([--disable-$1], [Disable build and install of $1]),[
+$1=n
+],[
+$1=y
+SUBSYSTEMS="$SUBSYSTEMS $1"
+AS_IF([test -e "$1/configure"], [
+AC_CONFIG_SUBDIRS([$1])
+])
+])
+AC_SUBST($1)
+])
+
+AC_DEFUN([AX_SUBSYSTEM_DEFAULT_DISABLE], [
+AC_ARG_ENABLE([$1],
+AS_HELP_STRING([--enable-$1], [Enable build and install of $1]),[
+$1=y
+SUBSYSTEMS="$SUBSYSTEMS $1"
+AS_IF([test -e "$1/configure"], [
+AC_CONFIG_SUBDIRS([$1])
+])
+],[
+$1=n
+])
+AC_SUBST($1)
+])
+
+
+AC_DEFUN([AX_SUBSYSTEM_FINISH], [
+AC_SUBST(SUBSYSTEMS)
+])
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [VTPM v7 1/8] add vtpm-stubdom code
  2012-12-06 18:19 [VTPM v7 1/8] add vtpm-stubdom code Matthew Fioravante
                   ` (6 preceding siblings ...)
  2012-12-06 18:19 ` [VTPM v7 8/8] Add conditional build of subsystems to configure.ac Matthew Fioravante
@ 2012-12-13 11:48 ` Ian Campbell
  2012-12-13 14:55   ` Fioravante, Matthew E.
  7 siblings, 1 reply; 14+ messages in thread
From: Ian Campbell @ 2012-12-13 11:48 UTC (permalink / raw)
  To: Matthew Fioravante; +Cc: Ian Jackson, xen-devel

For future reference please could you include an indication of what
changed in a new posting of a series, either in the 0/N mail (which is
useful to include as an intro in any case) or in the individual
changelogs.

On Thu, 2012-12-06 at 18:19 +0000, Matthew Fioravante wrote:
> Add the code base for vtpm-stubdom to the stubdom
> heirarchy. Makefile changes in later patch.
> 
> Signed-off-by: Matthew Fioravante <matthew.fioravante@jhuapl.edu>
> Acked-by: Ian Campbell <ian.campbell@citrix.com>
> ---
>  stubdom/vtpm/Makefile    |   37 +++++
>  stubdom/vtpm/minios.cfg  |   14 ++
>  stubdom/vtpm/vtpm.c      |  404 ++++++++++++++++++++++++++++++++++++++++++++++
>  stubdom/vtpm/vtpm.h      |   36 +++++
>  stubdom/vtpm/vtpm_cmd.c  |  256 +++++++++++++++++++++++++++++
>  stubdom/vtpm/vtpm_cmd.h  |   31 ++++
>  stubdom/vtpm/vtpm_pcrs.c |   43 +++++
>  stubdom/vtpm/vtpm_pcrs.h |   53 ++++++
>  stubdom/vtpm/vtpmblk.c   |  307 +++++++++++++++++++++++++++++++++++
>  stubdom/vtpm/vtpmblk.h   |   31 ++++
>  10 files changed, 1212 insertions(+)
>  create mode 100644 stubdom/vtpm/Makefile
>  create mode 100644 stubdom/vtpm/minios.cfg
>  create mode 100644 stubdom/vtpm/vtpm.c
>  create mode 100644 stubdom/vtpm/vtpm.h
>  create mode 100644 stubdom/vtpm/vtpm_cmd.c
>  create mode 100644 stubdom/vtpm/vtpm_cmd.h
>  create mode 100644 stubdom/vtpm/vtpm_pcrs.c
>  create mode 100644 stubdom/vtpm/vtpm_pcrs.h
>  create mode 100644 stubdom/vtpm/vtpmblk.c
>  create mode 100644 stubdom/vtpm/vtpmblk.h
> 
> diff --git a/stubdom/vtpm/Makefile b/stubdom/vtpm/Makefile
> new file mode 100644
> index 0000000..686c0ea
> --- /dev/null
> +++ b/stubdom/vtpm/Makefile
> @@ -0,0 +1,37 @@
> +# Copyright (c) 2010-2012 United States Government, as represented by
> +# the Secretary of Defense.  All rights reserved.
> +#
> +# THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
> +# ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
> +# INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
> +# FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
> +# DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
> +# SOFTWARE.
> +#
> +
> +XEN_ROOT=../..
> +
> +PSSL_DIR=../polarssl-$(XEN_TARGET_ARCH)/library
> +PSSL_OBJS=aes.o sha1.o entropy.o ctr_drbg.o sha4.o
> +
> +TARGET=vtpm.a
> +OBJS=vtpm.o vtpm_cmd.o vtpmblk.o vtpm_pcrs.o
> +
> +
> +CPPFLAGS+=-I../tpm_emulator-$(XEN_TARGET_ARCH)/build
> +CPPFLAGS+=-I../tpm_emulator-$(XEN_TARGET_ARCH)/tpm
> +CPPFLAGS+=-I../tpm_emulator-$(XEN_TARGET_ARCH)/crypto
> +CPPFLAGS+=-I../tpm_emulator-$(XEN_TARGET_ARCH)
> +
> +$(TARGET): $(OBJS)
> +       ar -cr $@ $(OBJS) $(TPMEMU_OBJS) $(foreach obj,$(PSSL_OBJS),$(PSSL_DIR)/$(obj))
> +
> +$(OBJS): vtpm_manager.h
> +
> +vtpm_manager.h:
> +       ln -s ../vtpmmgr/vtpm_manager.h vtpm_manager.h
> +
> +clean:
> +       -rm $(TARGET) $(OBJS) vtpm_manager.h
> +
> +.PHONY: clean
> diff --git a/stubdom/vtpm/minios.cfg b/stubdom/vtpm/minios.cfg
> new file mode 100644
> index 0000000..31652ee
> --- /dev/null
> +++ b/stubdom/vtpm/minios.cfg
> @@ -0,0 +1,14 @@
> +CONFIG_TPMFRONT=y
> +CONFIG_TPM_TIS=n
> +CONFIG_TPMBACK=y
> +CONFIG_START_NETWORK=n
> +CONFIG_TEST=n
> +CONFIG_PCIFRONT=n
> +CONFIG_BLKFRONT=y
> +CONFIG_NETFRONT=n
> +CONFIG_FBFRONT=n
> +CONFIG_KBDFRONT=n
> +CONFIG_CONSFRONT=n
> +CONFIG_XENBUS=y
> +CONFIG_LWIP=n
> +CONFIG_XC=n
> diff --git a/stubdom/vtpm/vtpm.c b/stubdom/vtpm/vtpm.c
> new file mode 100644
> index 0000000..71aef78
> --- /dev/null
> +++ b/stubdom/vtpm/vtpm.c
> @@ -0,0 +1,404 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
> + * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
> + * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
> + * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
> + * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
> + * SOFTWARE.
> + */
> +
> +#include <stdio.h>
> +#include <stdint.h>
> +#include <inttypes.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <string.h>
> +#include <syslog.h>
> +#include <stdbool.h>
> +#include <errno.h>
> +#include <sys/time.h>
> +#include <xen/xen.h>
> +#include <tpmback.h>
> +#include <tpmfront.h>
> +
> +#include <polarssl/entropy.h>
> +#include <polarssl/ctr_drbg.h>
> +
> +#include "tpm/tpm_emulator_extern.h"
> +#include "tpm/tpm_marshalling.h"
> +#include "vtpm.h"
> +#include "vtpm_cmd.h"
> +#include "vtpm_pcrs.h"
> +#include "vtpmblk.h"
> +
> +#define TPM_LOG_INFO LOG_INFO
> +#define TPM_LOG_ERROR LOG_ERR
> +#define TPM_LOG_DEBUG LOG_DEBUG
> +
> +/* Global commandline options - default values */
> +struct Opt_args opt_args = {
> +   .startup = ST_CLEAR,
> +   .loglevel = TPM_LOG_INFO,
> +   .hwinitpcrs = VTPM_PCRNONE,
> +   .tpmconf = 0,
> +   .enable_maint_cmds = false,
> +};
> +
> +static uint32_t badords[32];
> +static unsigned int n_badords = 0;
> +
> +entropy_context entropy;
> +ctr_drbg_context ctr_drbg;
> +
> +struct tpmfront_dev* tpmfront_dev;
> +
> +void vtpm_get_extern_random_bytes(void *buf, size_t nbytes)
> +{
> +   ctr_drbg_random(&ctr_drbg, buf, nbytes);
> +}
> +
> +int vtpm_read_from_file(uint8_t **data, size_t *data_length) {
> +   return read_vtpmblk(tpmfront_dev, data, data_length);
> +}
> +
> +int vtpm_write_to_file(uint8_t *data, size_t data_length) {
> +   return write_vtpmblk(tpmfront_dev, data, data_length);
> +}
> +
> +int vtpm_extern_init_fake(void) {
> +   return 0;
> +}
> +
> +void vtpm_extern_release_fake(void) {
> +}
> +
> +
> +void vtpm_log(int priority, const char *fmt, ...)
> +{
> +   if(opt_args.loglevel >= priority) {
> +      va_list v;
> +      va_start(v, fmt);
> +      vprintf(fmt, v);
> +      va_end(v);
> +   }
> +}
> +
> +static uint64_t vtpm_get_ticks(void)
> +{
> +  static uint64_t old_t = 0;
> +  uint64_t new_t, res_t;
> +  struct timeval tv;
> +  gettimeofday(&tv, NULL);
> +  new_t = (uint64_t)tv.tv_sec * 1000000 + (uint64_t)tv.tv_usec;
> +  res_t = (old_t > 0) ? new_t - old_t : 0;
> +  old_t = new_t;
> +  return res_t;
> +}
> +
> +
> +static int tpm_entropy_source(void* dummy, unsigned char* data, size_t len, size_t* olen) {
> +   UINT32 sz = len;
> +   TPM_RESULT rc = VTPM_GetRandom(tpmfront_dev, data, &sz);
> +   *olen = sz;
> +   return rc == TPM_SUCCESS ? 0 : POLARSSL_ERR_ENTROPY_SOURCE_FAILED;
> +}
> +
> +int init_random(void) {
> +   /* Initialize the rng */
> +   entropy_init(&entropy);
> +   entropy_add_source(&entropy, tpm_entropy_source, NULL, 0);
> +   entropy_gather(&entropy);
> +   ctr_drbg_init(&ctr_drbg, entropy_func, &entropy, NULL, 0);
> +   ctr_drbg_set_prediction_resistance( &ctr_drbg, CTR_DRBG_PR_OFF );
> +
> +   return 0;
> +}
> +
> +int check_ordinal(tpmcmd_t* tpmcmd) {
> +   TPM_COMMAND_CODE ord;
> +   UINT32 len = 4;
> +   BYTE* ptr;
> +   unsigned int i;
> +
> +   if(tpmcmd->req_len < 10) {
> +      return true;
> +   }
> +
> +   ptr = tpmcmd->req + 6;
> +   tpm_unmarshal_UINT32(&ptr, &len, &ord);
> +
> +   for(i = 0; i < n_badords; ++i) {
> +      if(ord == badords[i]) {
> +         error("Disabled command ordinal (%" PRIu32") requested!\n");
> +         return false;
> +      }
> +   }
> +   return true;
> +}
> +
> +static void main_loop(void) {
> +   tpmcmd_t* tpmcmd = NULL;
> +   domid_t domid;              /* Domid of frontend */
> +   unsigned int handle;        /* handle of frontend */
> +   int res = -1;
> +
> +   info("VTPM Initializing\n");
> +
> +   /* Set required tpm config args */
> +   opt_args.tpmconf |= TPM_CONF_STRONG_PERSISTENCE;
> +   opt_args.tpmconf &= ~TPM_CONF_USE_INTERNAL_PRNG;
> +   opt_args.tpmconf |= TPM_CONF_GENERATE_EK;
> +   opt_args.tpmconf |= TPM_CONF_GENERATE_SEED_DAA;
> +
> +   /* Initialize the emulator */
> +   tpm_emulator_init(opt_args.startup, opt_args.tpmconf);
> +
> +   /* Initialize any requested PCRs with hardware TPM values */
> +   if(vtpm_initialize_hw_pcrs(tpmfront_dev, opt_args.hwinitpcrs) != TPM_SUCCESS) {
> +      error("Failed to initialize PCRs with hardware TPM values");
> +      goto abort_postpcrs;
> +   }
> +
> +   /* Wait for the frontend domain to connect */
> +   info("Waiting for frontend domain to connect..");
> +   if(tpmback_wait_for_frontend_connect(&domid, &handle) == 0) {
> +      info("VTPM attached to Frontend %u/%u", (unsigned int) domid, handle);
> +   } else {
> +      error("Unable to attach to a frontend");
> +   }
> +
> +   tpmcmd = tpmback_req(domid, handle);
> +   while(tpmcmd) {
> +      /* Handle the request */
> +      if(tpmcmd->req_len) {
> +        tpmcmd->resp = NULL;
> +        tpmcmd->resp_len = 0;
> +
> +         /* First check for disabled ordinals */
> +         if(!check_ordinal(tpmcmd)) {
> +            create_error_response(tpmcmd, TPM_BAD_ORDINAL);
> +         }
> +         /* If not disabled, do the command */
> +         else {
> +            if((res = tpm_handle_command(tpmcmd->req, tpmcmd->req_len, &tpmcmd->resp, &tpmcmd->resp_len)) != 0) {
> +               error("tpm_handle_command() failed");
> +               create_error_response(tpmcmd, TPM_FAIL);
> +            }
> +         }
> +      }
> +
> +      /* Send the response */
> +      tpmback_resp(tpmcmd);
> +
> +      /* Wait for the next request */
> +      tpmcmd = tpmback_req(domid, handle);
> +
> +   }
> +
> +abort_postpcrs:
> +   info("VTPM Shutting down\n");
> +
> +   tpm_emulator_shutdown();
> +}
> +
> +int parse_cmd_line(int argc, char** argv)
> +{
> +   char sval[25];
> +   char* logstr = NULL;
> +   /* Parse the command strings */
> +   for(unsigned int i = 1; i < argc; ++i) {
> +      if (sscanf(argv[i], "loglevel=%25s", sval) == 1){
> +        if (!strcmp(sval, "debug")) {
> +           opt_args.loglevel = TPM_LOG_DEBUG;
> +           logstr = "debug";
> +        }
> +        else if (!strcmp(sval, "info")) {
> +           logstr = "info";
> +           opt_args.loglevel = TPM_LOG_INFO;
> +        }
> +        else if (!strcmp(sval, "error")) {
> +           logstr = "error";
> +           opt_args.loglevel = TPM_LOG_ERROR;
> +        }
> +      }
> +      else if (!strcmp(argv[i], "clear")) {
> +        opt_args.startup = ST_CLEAR;
> +      }
> +      else if (!strcmp(argv[i], "save")) {
> +        opt_args.startup = ST_SAVE;
> +      }
> +      else if (!strcmp(argv[i], "deactivated")) {
> +        opt_args.startup = ST_DEACTIVATED;
> +      }
> +      else if (!strncmp(argv[i], "maintcmds=", 10)) {
> +         if(!strcmp(argv[i] + 10, "1")) {
> +            opt_args.enable_maint_cmds = true;
> +         } else if(!strcmp(argv[i] + 10, "0")) {
> +            opt_args.enable_maint_cmds = false;
> +         }
> +      }
> +      else if(!strncmp(argv[i], "hwinitpcr=", 10)) {
> +         char *pch = argv[i] + 10;
> +         unsigned int v1, v2;
> +         pch = strtok(pch, ",");
> +         while(pch != NULL) {
> +            if(!strcmp(pch, "all")) {
> +               //Set all
> +               opt_args.hwinitpcrs = VTPM_PCRALL;
> +            } else if(!strcmp(pch, "none")) {
> +               //Set none
> +               opt_args.hwinitpcrs = VTPM_PCRNONE;
> +            } else if(sscanf(pch, "%u", &v1) == 1) {
> +               //Set one
> +               if(v1 >= TPM_NUM_PCR) {
> +                  error("hwinitpcr error: Invalid PCR index %u", v1);
> +                  return -1;
> +               }
> +               opt_args.hwinitpcrs |= (1 << v1);
> +            } else if(sscanf(pch, "%u-%u", &v1, &v2) == 2) {
> +               //Set range
> +               if(v1 >= TPM_NUM_PCR) {
> +                  error("hwinitpcr error: Invalid PCR index %u", v1);
> +                  return -1;
> +               }
> +               if(v2 >= TPM_NUM_PCR) {
> +                  error("hwinitpcr error: Invalid PCR index %u", v1);
> +                  return -1;
> +               }
> +               if(v2 < v1) {
> +                  unsigned tp = v1;
> +                  v1 = v2;
> +                  v2 = tp;
> +               }
> +               for(unsigned int i = v1; i <= v2; ++i) {
> +                  opt_args.hwinitpcrs |= (1 << i);
> +               }
> +            } else {
> +               error("hwintipcr error: Invalid PCR specification : %s", pch);
> +               return -1;
> +            }
> +            pch = strtok(NULL, ",");
> +         }
> +      }
> +      else {
> +        error("Invalid command line option `%s'", argv[i]);
> +      }
> +
> +   }
> +
> +   /* Check Errors and print results */
> +   switch(opt_args.startup) {
> +      case ST_CLEAR:
> +        info("Startup mode is `clear'");
> +        break;
> +      case ST_SAVE:
> +        info("Startup mode is `save'");
> +        break;
> +      case ST_DEACTIVATED:
> +        info("Startup mode is `deactivated'");
> +        break;
> +      default:
> +        error("Invalid startup mode %d", opt_args.startup);
> +        return -1;
> +   }
> +
> +   if(opt_args.hwinitpcrs & (VTPM_PCRALL))
> +   {
> +      char pcrstr[1024];
> +      char* ptr = pcrstr;
> +
> +      pcrstr[0] = '\0';
> +      info("The following PCRs will be initialized with values from the hardware TPM:");
> +      for(unsigned int i = 0; i < TPM_NUM_PCR; ++i) {
> +         if(opt_args.hwinitpcrs & (1 << i)) {
> +            ptr += sprintf(ptr, "%u, ", i);
> +         }
> +      }
> +      /* get rid of the last comma if any numbers were printed */
> +      *(ptr -2) = '\0';
> +
> +      info("\t%s", pcrstr);
> +   } else {
> +      info("All PCRs initialized to default values");
> +   }
> +
> +   if(!opt_args.enable_maint_cmds) {
> +      info("TPM Maintenance Commands disabled");
> +      badords[n_badords++] = TPM_ORD_CreateMaintenanceArchive;
> +      badords[n_badords++] = TPM_ORD_LoadMaintenanceArchive;
> +      badords[n_badords++] = TPM_ORD_KillMaintenanceFeature;
> +      badords[n_badords++] = TPM_ORD_LoadManuMaintPub;
> +      badords[n_badords++] = TPM_ORD_ReadManuMaintPub;
> +   } else {
> +      info("TPM Maintenance Commands enabled");
> +   }
> +
> +   info("Log level set to %s", logstr);
> +
> +   return 0;
> +}
> +
> +void cleanup_opt_args(void) {
> +}
> +
> +int main(int argc, char **argv)
> +{
> +   //FIXME: initializing blkfront without this sleep causes the domain to crash on boot
> +   sleep(2);
> +
> +   /* Setup extern function pointers */
> +   tpm_extern_init = vtpm_extern_init_fake;
> +   tpm_extern_release = vtpm_extern_release_fake;
> +   tpm_malloc = malloc;
> +   tpm_free = free;
> +   tpm_log = vtpm_log;
> +   tpm_get_ticks = vtpm_get_ticks;
> +   tpm_get_extern_random_bytes = vtpm_get_extern_random_bytes;
> +   tpm_write_to_storage = vtpm_write_to_file;
> +   tpm_read_from_storage = vtpm_read_from_file;
> +
> +   info("starting TPM Emulator (1.2.%d.%d-%d)", VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD);
> +   if(parse_cmd_line(argc, argv)) {
> +      error("Error parsing commandline\n");
> +      return -1;
> +   }
> +
> +   /* Initialize devices */
> +   init_tpmback();
> +   if((tpmfront_dev = init_tpmfront(NULL)) == NULL) {
> +      error("Unable to initialize tpmfront device");
> +      goto abort_posttpmfront;
> +   }
> +
> +   /* Seed the RNG with entropy from hardware TPM */
> +   if(init_random()) {
> +      error("Unable to initialize RNG");
> +      goto abort_postrng;
> +   }
> +
> +   /* Initialize blkfront device */
> +   if(init_vtpmblk(tpmfront_dev)) {
> +      error("Unable to initialize Blkfront persistent storage");
> +      goto abort_postvtpmblk;
> +   }
> +
> +   /* Run main loop */
> +   main_loop();
> +
> +   /* Shutdown blkfront */
> +   shutdown_vtpmblk();
> +abort_postvtpmblk:
> +abort_postrng:
> +
> +   /* Close devices */
> +   shutdown_tpmfront(tpmfront_dev);
> +abort_posttpmfront:
> +   shutdown_tpmback();
> +
> +   cleanup_opt_args();
> +
> +   return 0;
> +}
> diff --git a/stubdom/vtpm/vtpm.h b/stubdom/vtpm/vtpm.h
> new file mode 100644
> index 0000000..5919e44
> --- /dev/null
> +++ b/stubdom/vtpm/vtpm.h
> @@ -0,0 +1,36 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
> + * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
> + * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
> + * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
> + * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
> + * SOFTWARE.
> + */
> +
> +#ifndef VTPM_H
> +#define VTPM_H
> +
> +#include <stdbool.h>
> +
> +/* For testing */
> +#define VERS_CMD "\x00\xC1\x00\x00\x00\x16\x00\x00\x00\x65\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x01\x03"
> +#define VERS_CMD_LEN 22
> +
> +/* Global commandline options */
> +struct Opt_args {
> +   enum StartUp {
> +      ST_CLEAR = 1,
> +      ST_SAVE = 2,
> +      ST_DEACTIVATED = 3
> +   } startup;
> +   unsigned long hwinitpcrs;
> +   int loglevel;
> +   uint32_t tpmconf;
> +   bool enable_maint_cmds;
> +};
> +extern struct Opt_args opt_args;
> +
> +#endif
> diff --git a/stubdom/vtpm/vtpm_cmd.c b/stubdom/vtpm/vtpm_cmd.c
> new file mode 100644
> index 0000000..7eae98b
> --- /dev/null
> +++ b/stubdom/vtpm/vtpm_cmd.c
> @@ -0,0 +1,256 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
> + * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
> + * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
> + * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
> + * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
> + * SOFTWARE.
> + */
> +
> +#include <types.h>
> +#include <xen/xen.h>
> +#include <mm.h>
> +#include <gnttab.h>
> +#include "tpm/tpm_marshalling.h"
> +#include "vtpm_manager.h"
> +#include "vtpm_cmd.h"
> +#include <tpmback.h>
> +
> +#define TRYFAILGOTO(C) \
> +   if((C)) { \
> +      status = TPM_FAIL; \
> +      goto abort_egress; \
> +   }
> +#define TRYFAILGOTOMSG(C, msg) \
> +   if((C)) { \
> +      status = TPM_FAIL; \
> +      error(msg); \
> +      goto abort_egress; \
> +   }
> +#define CHECKSTATUSGOTO(ret, fname) \
> +   if((ret) != TPM_SUCCESS) { \
> +      error("%s failed with error code (%lu)", fname, (unsigned long) ret); \
> +      status = ord; \
> +      goto abort_egress; \
> +   }
> +
> +#define ERR_MALFORMED "Malformed response from backend"
> +#define ERR_TPMFRONT "Error sending command through frontend device"
> +
> +struct shpage {
> +   void* page;
> +   grant_ref_t grantref;
> +};
> +
> +typedef struct shpage shpage_t;
> +
> +static inline int pack_header(uint8_t** bptr, UINT32* len, TPM_TAG tag, UINT32 size, TPM_COMMAND_CODE ord)
> +{
> +   return *bptr == NULL ||
> +        tpm_marshal_UINT16(bptr, len, tag) ||
> +        tpm_marshal_UINT32(bptr, len, size) ||
> +        tpm_marshal_UINT32(bptr, len, ord);
> +}
> +
> +static inline int unpack_header(uint8_t** bptr, UINT32* len, TPM_TAG* tag, UINT32* size, TPM_COMMAND_CODE* ord)
> +{
> +   return *bptr == NULL ||
> +        tpm_unmarshal_UINT16(bptr, len, tag) ||
> +        tpm_unmarshal_UINT32(bptr, len, size) ||
> +        tpm_unmarshal_UINT32(bptr, len, ord);
> +}
> +
> +int create_error_response(tpmcmd_t* tpmcmd, TPM_RESULT errorcode)
> +{
> +   TPM_TAG tag;
> +   UINT32 len = tpmcmd->req_len;
> +   uint8_t* respptr;
> +   uint8_t* cmdptr = tpmcmd->req;
> +
> +   if(!tpm_unmarshal_UINT16(&cmdptr, &len, &tag)) {
> +      switch (tag) {
> +         case TPM_TAG_RQU_COMMAND:
> +            tag = TPM_TAG_RSP_COMMAND;
> +            break;
> +         case TPM_TAG_RQU_AUTH1_COMMAND:
> +            tag = TPM_TAG_RQU_AUTH2_COMMAND;
> +            break;
> +         case TPM_TAG_RQU_AUTH2_COMMAND:
> +            tag = TPM_TAG_RQU_AUTH2_COMMAND;
> +            break;
> +      }
> +   } else {
> +      tag = TPM_TAG_RSP_COMMAND;
> +   }
> +
> +   tpmcmd->resp_len = len = 10;
> +   tpmcmd->resp = respptr = tpm_malloc(tpmcmd->resp_len);
> +
> +   return pack_header(&respptr, &len, tag, len, errorcode);
> +}
> +
> +TPM_RESULT VTPM_GetRandom(struct tpmfront_dev* tpmfront_dev, BYTE* bytes, UINT32 *numbytes) {
> +   TPM_RESULT status = TPM_SUCCESS;
> +   uint8_t* cmdbuf, *resp, *bptr;
> +   size_t resplen = 0;
> +   UINT32 len;
> +
> +   /*Ask the real tpm for random bytes for the seed */
> +   TPM_TAG tag = TPM_TAG_RQU_COMMAND;
> +   UINT32 size;
> +   TPM_COMMAND_CODE ord = TPM_ORD_GetRandom;
> +   len = size = sizeof(TPM_TAG) + sizeof(UINT32) + sizeof(TPM_COMMAND_CODE) + sizeof(UINT32);
> +
> +   /*Create the raw tpm command */
> +   bptr = cmdbuf = malloc(size);
> +   TRYFAILGOTO(pack_header(&bptr, &len, tag, size, ord));
> +   TRYFAILGOTO(tpm_marshal_UINT32(&bptr, &len, *numbytes));
> +
> +   /* Send cmd, wait for response */
> +   TRYFAILGOTOMSG(tpmfront_cmd(tpmfront_dev, cmdbuf, size, &resp, &resplen),
> +      ERR_TPMFRONT);
> +
> +   bptr = resp; len = resplen;
> +   TRYFAILGOTOMSG(unpack_header(&bptr, &len, &tag, &size, &ord), ERR_MALFORMED);
> +
> +   //Check return status of command
> +   CHECKSTATUSGOTO(ord, "TPM_GetRandom()");
> +
> +   // Get the number of random bytes in the response
> +   TRYFAILGOTOMSG(tpm_unmarshal_UINT32(&bptr, &len, &size), ERR_MALFORMED);
> +   *numbytes = size;
> +
> +   //Get the random bytes out, tpm may give us less bytes than what we wanrt
> +   TRYFAILGOTOMSG(tpm_unmarshal_BYTE_ARRAY(&bptr, &len, bytes, *numbytes), ERR_MALFORMED);
> +
> +   goto egress;
> +abort_egress:
> +egress:
> +   free(cmdbuf);
> +   return status;
> +
> +}
> +
> +TPM_RESULT VTPM_LoadHashKey(struct tpmfront_dev* tpmfront_dev, uint8_t** data, size_t* data_length)
> +{
> +   TPM_RESULT status = TPM_SUCCESS;
> +   uint8_t* bptr, *resp;
> +   uint8_t* cmdbuf = NULL;
> +   size_t resplen = 0;
> +   UINT32 len;
> +
> +   TPM_TAG tag = VTPM_TAG_REQ;
> +   UINT32 size;
> +   TPM_COMMAND_CODE ord = VTPM_ORD_LOADHASHKEY;
> +
> +   /*Create the command*/
> +   len = size = VTPM_COMMAND_HEADER_SIZE;
> +   bptr = cmdbuf = malloc(size);
> +   TRYFAILGOTO(pack_header(&bptr, &len, tag, size, ord));
> +
> +   /* Send the command to vtpm_manager */
> +   info("Requesting Encryption key from backend");
> +   TRYFAILGOTOMSG(tpmfront_cmd(tpmfront_dev, cmdbuf, size, &resp, &resplen), ERR_TPMFRONT);
> +
> +   /* Unpack response header */
> +   bptr = resp;
> +   len = resplen;
> +   TRYFAILGOTOMSG(unpack_header(&bptr, &len, &tag, &size, &ord), ERR_MALFORMED);
> +
> +   /* Check return code */
> +   CHECKSTATUSGOTO(ord, "VTPM_LoadHashKey()");
> +
> +   /* Get the size of the key */
> +   *data_length = size - VTPM_COMMAND_HEADER_SIZE;
> +
> +   /* Copy the key bits */
> +   *data = malloc(*data_length);
> +   memcpy(*data, bptr, *data_length);
> +
> +   goto egress;
> +abort_egress:
> +   error("VTPM_LoadHashKey failed");
> +egress:
> +   free(cmdbuf);
> +   return status;
> +}
> +
> +TPM_RESULT VTPM_SaveHashKey(struct tpmfront_dev* tpmfront_dev, uint8_t* data, size_t data_length)
> +{
> +   TPM_RESULT status = TPM_SUCCESS;
> +   uint8_t* bptr, *resp;
> +   uint8_t* cmdbuf = NULL;
> +   size_t resplen = 0;
> +   UINT32 len;
> +
> +   TPM_TAG tag = VTPM_TAG_REQ;
> +   UINT32 size;
> +   TPM_COMMAND_CODE ord = VTPM_ORD_SAVEHASHKEY;
> +
> +   /*Create the command*/
> +   len = size = VTPM_COMMAND_HEADER_SIZE + data_length;
> +   bptr = cmdbuf = malloc(size);
> +   TRYFAILGOTO(pack_header(&bptr, &len, tag, size, ord));
> +   memcpy(bptr, data, data_length);
> +   bptr += data_length;
> +
> +   /* Send the command to vtpm_manager */
> +   info("Sending encryption key to backend");
> +   TRYFAILGOTOMSG(tpmfront_cmd(tpmfront_dev, cmdbuf, size, &resp, &resplen), ERR_TPMFRONT);
> +
> +   /* Unpack response header */
> +   bptr = resp;
> +   len = resplen;
> +   TRYFAILGOTOMSG(unpack_header(&bptr, &len, &tag, &size, &ord), ERR_MALFORMED);
> +
> +   /* Check return code */
> +   CHECKSTATUSGOTO(ord, "VTPM_SaveHashKey()");
> +
> +   goto egress;
> +abort_egress:
> +   error("VTPM_SaveHashKey failed");
> +egress:
> +   free(cmdbuf);
> +   return status;
> +}
> +
> +TPM_RESULT VTPM_PCRRead(struct tpmfront_dev* tpmfront_dev, UINT32 pcrIndex, BYTE* outDigest)
> +{
> +   TPM_RESULT status = TPM_SUCCESS;
> +   uint8_t *cmdbuf, *resp, *bptr;
> +   size_t resplen = 0;
> +   UINT32 len;
> +
> +   /*Just send a TPM_PCRRead Command to the HW tpm */
> +   TPM_TAG tag = TPM_TAG_RQU_COMMAND;
> +   UINT32 size;
> +   TPM_COMMAND_CODE ord = TPM_ORD_PCRRead;
> +   len = size = sizeof(TPM_TAG) + sizeof(UINT32) + sizeof(TPM_COMMAND_CODE) + sizeof(UINT32);
> +
> +   /*Create the raw tpm cmd */
> +   bptr = cmdbuf = malloc(size);
> +   TRYFAILGOTO(pack_header(&bptr, &len, tag, size, ord));
> +   TRYFAILGOTO(tpm_marshal_UINT32(&bptr, &len, pcrIndex));
> +
> +   /*Send Cmd wait for response */
> +   TRYFAILGOTOMSG(tpmfront_cmd(tpmfront_dev, cmdbuf, size, &resp, &resplen), ERR_TPMFRONT);
> +
> +   bptr = resp; len = resplen;
> +   TRYFAILGOTOMSG(unpack_header(&bptr, &len, &tag, &size, &ord), ERR_MALFORMED);
> +
> +   //Check return status of command
> +   CHECKSTATUSGOTO(ord, "TPM_PCRRead");
> +
> +   //Get the ptr value
> +   memcpy(outDigest, bptr, sizeof(TPM_PCRVALUE));
> +
> +   goto egress;
> +abort_egress:
> +egress:
> +   free(cmdbuf);
> +   return status;
> +
> +}
> diff --git a/stubdom/vtpm/vtpm_cmd.h b/stubdom/vtpm/vtpm_cmd.h
> new file mode 100644
> index 0000000..b0bfa22
> --- /dev/null
> +++ b/stubdom/vtpm/vtpm_cmd.h
> @@ -0,0 +1,31 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
> + * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
> + * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
> + * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
> + * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
> + * SOFTWARE.
> + */
> +
> +#ifndef MANAGER_H
> +#define MANAGER_H
> +
> +#include <tpmfront.h>
> +#include <tpmback.h>
> +#include "tpm/tpm_structures.h"
> +
> +/* Create a command response error header */
> +int create_error_response(tpmcmd_t* tpmcmd, TPM_RESULT errorcode);
> +/* Request random bytes from hardware tpm, returns 0 on success */
> +TPM_RESULT VTPM_GetRandom(struct tpmfront_dev* tpmfront_dev, BYTE* bytes, UINT32* numbytes);
> +/* Retreive 256 bit AES encryption key from manager */
> +TPM_RESULT VTPM_LoadHashKey(struct tpmfront_dev* tpmfront_dev, uint8_t** data, size_t* data_length);
> +/* Manager securely saves our 256 bit AES encryption key */
> +TPM_RESULT VTPM_SaveHashKey(struct tpmfront_dev* tpmfront_dev, uint8_t* data, size_t data_length);
> +/* Send a TPM_PCRRead command passthrough the manager to the hw tpm */
> +TPM_RESULT VTPM_PCRRead(struct tpmfront_dev* tpmfront_dev, UINT32 pcrIndex, BYTE* outDigest);
> +
> +#endif
> diff --git a/stubdom/vtpm/vtpm_pcrs.c b/stubdom/vtpm/vtpm_pcrs.c
> new file mode 100644
> index 0000000..22a6cef
> --- /dev/null
> +++ b/stubdom/vtpm/vtpm_pcrs.c
> @@ -0,0 +1,43 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
> + * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
> + * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
> + * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
> + * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
> + * SOFTWARE.
> + */
> +
> +#include "vtpm_pcrs.h"
> +#include "vtpm_cmd.h"
> +#include "tpm/tpm_data.h"
> +
> +#define PCR_VALUE      tpmData.permanent.data.pcrValue
> +
> +static int write_pcr_direct(unsigned int pcrIndex, uint8_t* val) {
> +   if(pcrIndex > TPM_NUM_PCR) {
> +      return TPM_BADINDEX;
> +   }
> +   memcpy(&PCR_VALUE[pcrIndex], val, sizeof(TPM_PCRVALUE));
> +   return TPM_SUCCESS;
> +}
> +
> +TPM_RESULT vtpm_initialize_hw_pcrs(struct tpmfront_dev* tpmfront_dev, unsigned long pcrs)
> +{
> +   TPM_RESULT rc = TPM_SUCCESS;
> +   uint8_t digest[sizeof(TPM_PCRVALUE)];
> +
> +   for(unsigned int i = 0; i < TPM_NUM_PCR; ++i) {
> +      if(pcrs & 1 << i) {
> +         if((rc = VTPM_PCRRead(tpmfront_dev, i, digest)) != TPM_SUCCESS) {
> +            error("TPM_PCRRead failed with error : %d", rc);
> +            return rc;
> +         }
> +         write_pcr_direct(i, digest);
> +      }
> +   }
> +
> +   return rc;
> +}
> diff --git a/stubdom/vtpm/vtpm_pcrs.h b/stubdom/vtpm/vtpm_pcrs.h
> new file mode 100644
> index 0000000..11835f9
> --- /dev/null
> +++ b/stubdom/vtpm/vtpm_pcrs.h
> @@ -0,0 +1,53 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
> + * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
> + * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
> + * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
> + * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
> + * SOFTWARE.
> + */
> +
> +#ifndef VTPM_PCRS_H
> +#define VTPM_PCRS_H
> +
> +#include "tpm/tpm_structures.h"
> +
> +#define VTPM_PCR0 1
> +#define VTPM_PCR1 1 << 1
> +#define VTPM_PCR2 1 << 2
> +#define VTPM_PCR3 1 << 3
> +#define VTPM_PCR4 1 << 4
> +#define VTPM_PCR5 1 << 5
> +#define VTPM_PCR6 1 << 6
> +#define VTPM_PCR7 1 << 7
> +#define VTPM_PCR8 1 << 8
> +#define VTPM_PCR9 1 << 9
> +#define VTPM_PCR10 1 << 10
> +#define VTPM_PCR11 1 << 11
> +#define VTPM_PCR12 1 << 12
> +#define VTPM_PCR13 1 << 13
> +#define VTPM_PCR14 1 << 14
> +#define VTPM_PCR15 1 << 15
> +#define VTPM_PCR16 1 << 16
> +#define VTPM_PCR17 1 << 17
> +#define VTPM_PCR18 1 << 18
> +#define VTPM_PCR19 1 << 19
> +#define VTPM_PCR20 1 << 20
> +#define VTPM_PCR21 1 << 21
> +#define VTPM_PCR22 1 << 22
> +#define VTPM_PCR23 1 << 23
> +
> +#define VTPM_PCRALL (1 << TPM_NUM_PCR) - 1
> +#define VTPM_PCRNONE 0
> +
> +#define VTPM_NUMPCRS 24
> +
> +struct tpmfront_dev;
> +
> +TPM_RESULT vtpm_initialize_hw_pcrs(struct tpmfront_dev* tpmfront_dev, unsigned long pcrs);
> +
> +
> +#endif
> diff --git a/stubdom/vtpm/vtpmblk.c b/stubdom/vtpm/vtpmblk.c
> new file mode 100644
> index 0000000..b343bd8
> --- /dev/null
> +++ b/stubdom/vtpm/vtpmblk.c
> @@ -0,0 +1,307 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
> + * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
> + * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
> + * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
> + * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
> + * SOFTWARE.
> + */
> +
> +#include <mini-os/byteorder.h>
> +#include "vtpmblk.h"
> +#include "tpm/tpm_marshalling.h"
> +#include "vtpm_cmd.h"
> +#include "polarssl/aes.h"
> +#include "polarssl/sha1.h"
> +#include <blkfront.h>
> +#include <unistd.h>
> +#include <errno.h>
> +#include <fcntl.h>
> +
> +/*Encryption key and block sizes */
> +#define BLKSZ 16
> +
> +static struct blkfront_dev* blkdev = NULL;
> +static int blkfront_fd = -1;
> +
> +int init_vtpmblk(struct tpmfront_dev* tpmfront_dev)
> +{
> +   struct blkfront_info blkinfo;
> +   info("Initializing persistent NVM storage\n");
> +
> +   if((blkdev = init_blkfront(NULL, &blkinfo)) == NULL) {
> +      error("BLKIO: ERROR Unable to initialize blkfront");
> +      return -1;
> +   }
> +   if (blkinfo.info & VDISK_READONLY || blkinfo.mode != O_RDWR) {
> +      error("BLKIO: ERROR block device is read only!");
> +      goto error;
> +   }
> +   if((blkfront_fd = blkfront_open(blkdev)) == -1) {
> +      error("Unable to open blkfront file descriptor!");
> +      goto error;
> +   }
> +
> +   return 0;
> +error:
> +   shutdown_blkfront(blkdev);
> +   blkdev = NULL;
> +   return -1;
> +}
> +
> +void shutdown_vtpmblk(void)
> +{
> +   close(blkfront_fd);
> +   blkfront_fd = -1;
> +   blkdev = NULL;
> +}
> +
> +int write_vtpmblk_raw(uint8_t *data, size_t data_length)
> +{
> +   int rc;
> +   uint32_t lenbuf;
> +   debug("Begin Write data=%p len=%u", data, data_length);
> +
> +   lenbuf = cpu_to_be32((uint32_t)data_length);
> +
> +   lseek(blkfront_fd, 0, SEEK_SET);
> +   if((rc = write(blkfront_fd, (uint8_t*)&lenbuf, 4)) != 4) {
> +      error("write(length) failed! error was %s", strerror(errno));
> +      return -1;
> +   }
> +   if((rc = write(blkfront_fd, data, data_length)) != data_length) {
> +      error("write(data) failed! error was %s", strerror(errno));
> +      return -1;
> +   }
> +
> +   info("Wrote %u bytes to NVM persistent storage", data_length);
> +
> +   return 0;
> +}
> +
> +int read_vtpmblk_raw(uint8_t **data, size_t *data_length)
> +{
> +   int rc;
> +   uint32_t lenbuf;
> +
> +   lseek(blkfront_fd, 0, SEEK_SET);
> +   if(( rc = read(blkfront_fd, (uint8_t*)&lenbuf, 4)) != 4) {
> +      error("read(length) failed! error was %s", strerror(errno));
> +      return -1;
> +   }
> +   *data_length = (size_t) cpu_to_be32(lenbuf);
> +   if(*data_length == 0) {
> +      error("read 0 data_length for NVM");
> +      return -1;
> +   }
> +
> +   *data = tpm_malloc(*data_length);
> +   if((rc = read(blkfront_fd, *data, *data_length)) != *data_length) {
> +      error("read(data) failed! error was %s", strerror(errno));
> +      return -1;
> +   }
> +
> +   info("Read %u bytes from NVM persistent storage", *data_length);
> +   return 0;
> +}
> +
> +int encrypt_vtpmblk(uint8_t* clear, size_t clear_len, uint8_t** cipher, size_t* cipher_len, uint8_t* symkey)
> +{
> +   int rc = 0;
> +   uint8_t iv[BLKSZ];
> +   aes_context aes_ctx;
> +   UINT32 temp;
> +   int mod;
> +
> +   uint8_t* clbuf = NULL;
> +
> +   uint8_t* ivptr;
> +   int ivlen;
> +
> +   uint8_t* cptr;      //Cipher block pointer
> +   int clen;   //Cipher block length
> +
> +   /*Create a new 256 bit encryption key */
> +   if(symkey == NULL) {
> +      rc = -1;
> +      goto abort_egress;
> +   }
> +   tpm_get_extern_random_bytes(symkey, NVMKEYSZ);
> +
> +   /*Setup initialization vector - random bits and then 4 bytes clear text size at the end*/
> +   temp = sizeof(UINT32);
> +   ivlen = BLKSZ - temp;
> +   tpm_get_extern_random_bytes(iv, ivlen);
> +   ivptr = iv + ivlen;
> +   tpm_marshal_UINT32(&ivptr, &temp, (UINT32) clear_len);
> +
> +   /*The clear text needs to be padded out to a multiple of BLKSZ */
> +   mod = clear_len % BLKSZ;
> +   clen = mod ? clear_len + BLKSZ - mod : clear_len;
> +   clbuf = malloc(clen);
> +   if (clbuf == NULL) {
> +      rc = -1;
> +      goto abort_egress;
> +   }
> +   memcpy(clbuf, clear, clear_len);
> +   /* zero out the padding bits - FIXME: better / more secure way to handle these? */
> +   if(clen - clear_len) {
> +      memset(clbuf + clear_len, 0, clen - clear_len);
> +   }
> +
> +   /* Setup the ciphertext buffer */
> +   *cipher_len = BLKSZ + clen;         /*iv + ciphertext */
> +   cptr = *cipher = malloc(*cipher_len);
> +   if (*cipher == NULL) {
> +      rc = -1;
> +      goto abort_egress;
> +   }
> +
> +   /* Copy the IV to cipher text blob*/
> +   memcpy(cptr, iv, BLKSZ);
> +   cptr += BLKSZ;
> +
> +   /* Setup encryption */
> +   aes_setkey_enc(&aes_ctx, symkey, 256);
> +
> +   /* Do encryption now */
> +   aes_crypt_cbc(&aes_ctx, AES_ENCRYPT, clen, iv, clbuf, cptr);
> +
> +   goto egress;
> +abort_egress:
> +egress:
> +   free(clbuf);
> +   return rc;
> +}
> +int decrypt_vtpmblk(uint8_t* cipher, size_t cipher_len, uint8_t** clear, size_t* clear_len, uint8_t* symkey)
> +{
> +   int rc = 0;
> +   uint8_t iv[BLKSZ];
> +   uint8_t* ivptr;
> +   UINT32 u32, temp;
> +   aes_context aes_ctx;
> +
> +   uint8_t* cptr = cipher;     //cipher block pointer
> +   int clen = cipher_len;      //cipher block length
> +
> +   /* Pull out the initialization vector */
> +   memcpy(iv, cipher, BLKSZ);
> +   cptr += BLKSZ;
> +   clen -= BLKSZ;
> +
> +   /* Setup the clear text buffer */
> +   if((*clear = malloc(clen)) == NULL) {
> +      rc = -1;
> +      goto abort_egress;
> +   }
> +
> +   /* Get the length of clear text from last 4 bytes of iv */
> +   temp = sizeof(UINT32);
> +   ivptr = iv + BLKSZ - temp;
> +   tpm_unmarshal_UINT32(&ivptr, &temp, &u32);
> +   *clear_len = u32;
> +
> +   /* Setup decryption */
> +   aes_setkey_dec(&aes_ctx, symkey, 256);
> +
> +   /* Do decryption now */
> +   if ((clen % BLKSZ) != 0) {
> +      error("Decryption Error: Cipher block size was not a multiple of %u", BLKSZ);
> +      rc = -1;
> +      goto abort_egress;
> +   }
> +   aes_crypt_cbc(&aes_ctx, AES_DECRYPT, clen, iv, cptr, *clear);
> +
> +   goto egress;
> +abort_egress:
> +egress:
> +   return rc;
> +}
> +
> +int write_vtpmblk(struct tpmfront_dev* tpmfront_dev, uint8_t* data, size_t data_length) {
> +   int rc;
> +   uint8_t* cipher = NULL;
> +   size_t cipher_len = 0;
> +   uint8_t hashkey[HASHKEYSZ];
> +   uint8_t* symkey = hashkey + HASHSZ;
> +
> +   /* Encrypt the data */
> +   if((rc = encrypt_vtpmblk(data, data_length, &cipher, &cipher_len, symkey))) {
> +      goto abort_egress;
> +   }
> +   /* Write to disk */
> +   if((rc = write_vtpmblk_raw(cipher, cipher_len))) {
> +      goto abort_egress;
> +   }
> +   /* Get sha1 hash of data */
> +   sha1(cipher, cipher_len, hashkey);
> +
> +   /* Send hash and key to manager */
> +   if((rc = VTPM_SaveHashKey(tpmfront_dev, hashkey, HASHKEYSZ)) != TPM_SUCCESS) {
> +      goto abort_egress;
> +   }
> +   goto egress;
> +abort_egress:
> +egress:
> +   free(cipher);
> +   return rc;
> +}
> +
> +int read_vtpmblk(struct tpmfront_dev* tpmfront_dev, uint8_t** data, size_t *data_length) {
> +   int rc;
> +   uint8_t* cipher = NULL;
> +   size_t cipher_len = 0;
> +   size_t keysize;
> +   uint8_t* hashkey = NULL;
> +   uint8_t hash[HASHSZ];
> +   uint8_t* symkey;
> +
> +   /* Retreive the hash and the key from the manager */
> +   if((rc = VTPM_LoadHashKey(tpmfront_dev, &hashkey, &keysize)) != TPM_SUCCESS) {
> +      goto abort_egress;
> +   }
> +   if(keysize != HASHKEYSZ) {
> +      error("Manager returned a hashkey of invalid size! expected %d, actual %d", NVMKEYSZ, keysize);
> +      rc = -1;
> +      goto abort_egress;
> +   }
> +   symkey = hashkey + HASHSZ;
> +
> +   /* Read from disk now */
> +   if((rc = read_vtpmblk_raw(&cipher, &cipher_len))) {
> +      goto abort_egress;
> +   }
> +
> +   /* Compute the hash of the cipher text and compare */
> +   sha1(cipher, cipher_len, hash);
> +   if(memcmp(hash, hashkey, HASHSZ)) {
> +      int i;
> +      error("NVM Storage Checksum failed!");
> +      printf("Expected: ");
> +      for(i = 0; i < HASHSZ; ++i) {
> +        printf("%02hhX ", hashkey[i]);
> +      }
> +      printf("\n");
> +      printf("Actual:   ");
> +      for(i = 0; i < HASHSZ; ++i) {
> +        printf("%02hhX ", hash[i]);
> +      }
> +      printf("\n");
> +      rc = -1;
> +      goto abort_egress;
> +   }
> +
> +   /* Decrypt the blob */
> +   if((rc = decrypt_vtpmblk(cipher, cipher_len, data, data_length, symkey))) {
> +      goto abort_egress;
> +   }
> +   goto egress;
> +abort_egress:
> +egress:
> +   free(cipher);
> +   free(hashkey);
> +   return rc;
> +}
> diff --git a/stubdom/vtpm/vtpmblk.h b/stubdom/vtpm/vtpmblk.h
> new file mode 100644
> index 0000000..282ce6a
> --- /dev/null
> +++ b/stubdom/vtpm/vtpmblk.h
> @@ -0,0 +1,31 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
> + * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
> + * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
> + * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
> + * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
> + * SOFTWARE.
> + */
> +
> +#ifndef NVM_H
> +#define NVM_H
> +#include <mini-os/types.h>
> +#include <xen/xen.h>
> +#include <tpmfront.h>
> +
> +#define NVMKEYSZ 32
> +#define HASHSZ 20
> +#define HASHKEYSZ (NVMKEYSZ + HASHSZ)
> +
> +int init_vtpmblk(struct tpmfront_dev* tpmfront_dev);
> +void shutdown_vtpmblk(void);
> +
> +/* Encrypts and writes data to blk device */
> +int write_vtpmblk(struct tpmfront_dev* tpmfront_dev, uint8_t *data, size_t data_length);
> +/* Reads, Decrypts, and returns data from blk device */
> +int read_vtpmblk(struct tpmfront_dev* tpmfront_dev, uint8_t **data, size_t *data_length);
> +
> +#endif
> --
> 1.7.10.4
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [VTPM v7 6/8] Add autoconf to stubdom
  2012-12-06 18:19 ` [VTPM v7 6/8] Add autoconf to stubdom Matthew Fioravante
@ 2012-12-13 12:02   ` Ian Campbell
  2012-12-13 14:15     ` Ian Jackson
  2012-12-13 15:15     ` Matthew Fioravante
  0 siblings, 2 replies; 14+ messages in thread
From: Ian Campbell @ 2012-12-13 12:02 UTC (permalink / raw)
  To: Matthew Fioravante; +Cc: Ian Jackson, xen-devel

On Thu, 2012-12-06 at 18:19 +0000, Matthew Fioravante wrote:
> Please rerun autoconf after commiting this patch
> 
> Signed-off-by: Matthew Fioravante <matthew.fioravante@jhuapl.edu>

This fails for me with :
        /local/scratch/ianc/devel/committer.git/stubdom/mini-os-x86_64-caml/test.o: In function `app_main':
        /local/scratch/ianc/devel/committer.git/extras/mini-os/test.c:511: multiple definition of `app_main'
        /local/scratch/ianc/devel/committer.git/stubdom/mini-os-x86_64-caml/main.o:/local/scratch/ianc/devel/committer.git/extras/mini-os/main.c:187: first defined here
        make[2]: *** [/local/scratch/ianc/devel/committer.git/stubdom/mini-os-x86_64-caml/mini-os] Error 1
        make[2]: Leaving directory `/local/scratch/ianc/devel/committer.git/extras/mini-os'
        make[1]: *** [caml-stubdom] Error 2
        make[1]: Leaving directory `/local/scratch/ianc/devel/committer.git/stubdom'
        make: *** [install-stubdom] Error 2
        
I'm only guessing it was this patch, but it was somewhere in this
series.

I'd already done all the autoconf faff and updated .*ignore for you
(adding autom4te.cache, config.log and config.status as appropriate). So
rather than resending please could you provide an incremental fix
against:
        git://xenbits.xen.org/people/ianc/xen-unstable.git vtpm

I'll then merge that into the appropriate patch.

It also occurs to me that this series introduces a little bisection blip
where cmake will be required (i.e. from patch 3 until here). The right
way to do this would have been to put the patch introducing autoconf at
the start. I'm inclined to just gloss over that for now, but if you feel
so inclined you could reorder things.

> ---
>  autogen.sh                             |    2 +
>  config/Stubdom.mk.in                   |   45 ++++++++++++++++
>  {tools/m4 => m4}/curses.m4             |    0
>  m4/depends.m4                          |   15 ++++++
>  {tools/m4 => m4}/extfs.m4              |    0
>  {tools/m4 => m4}/features.m4           |    0
>  {tools/m4 => m4}/fetcher.m4            |    0
>  {tools/m4 => m4}/ocaml.m4              |    0
>  {tools/m4 => m4}/path_or_fail.m4       |    0
>  {tools/m4 => m4}/pkg.m4                |    0
>  {tools/m4 => m4}/pthread.m4            |    0
>  {tools/m4 => m4}/ptyfuncs.m4           |    0
>  {tools/m4 => m4}/python_devel.m4       |    0
>  {tools/m4 => m4}/python_version.m4     |    0
>  {tools/m4 => m4}/savevar.m4            |    0
>  {tools/m4 => m4}/set_cflags_ldflags.m4 |    0
>  m4/stubdom.m4                          |   89 ++++++++++++++++++++++++++++++++
>  {tools/m4 => m4}/uuid.m4               |    0
>  stubdom/Makefile                       |   55 +++++---------------
>  stubdom/configure.ac                   |   58 +++++++++++++++++++++
>  tools/configure.ac                     |   28 +++++-----
>  21 files changed, 236 insertions(+), 56 deletions(-)
>  create mode 100644 config/Stubdom.mk.in
>  rename {tools/m4 => m4}/curses.m4 (100%)
>  create mode 100644 m4/depends.m4
>  rename {tools/m4 => m4}/extfs.m4 (100%)
>  rename {tools/m4 => m4}/features.m4 (100%)
>  rename {tools/m4 => m4}/fetcher.m4 (100%)
>  rename {tools/m4 => m4}/ocaml.m4 (100%)
>  rename {tools/m4 => m4}/path_or_fail.m4 (100%)
>  rename {tools/m4 => m4}/pkg.m4 (100%)
>  rename {tools/m4 => m4}/pthread.m4 (100%)
>  rename {tools/m4 => m4}/ptyfuncs.m4 (100%)
>  rename {tools/m4 => m4}/python_devel.m4 (100%)
>  rename {tools/m4 => m4}/python_version.m4 (100%)
>  rename {tools/m4 => m4}/savevar.m4 (100%)
>  rename {tools/m4 => m4}/set_cflags_ldflags.m4 (100%)
>  create mode 100644 m4/stubdom.m4
>  rename {tools/m4 => m4}/uuid.m4 (100%)
>  create mode 100644 stubdom/configure.ac
> 
> diff --git a/autogen.sh b/autogen.sh
> index 58a71ce..ada482c 100755
> --- a/autogen.sh
> +++ b/autogen.sh
> @@ -2,3 +2,5 @@
>  cd tools
>  autoconf
>  autoheader
> +cd ../stubdom
> +autoconf
> diff --git a/config/Stubdom.mk.in b/config/Stubdom.mk.in
> new file mode 100644
> index 0000000..432efd7
> --- /dev/null
> +++ b/config/Stubdom.mk.in
> @@ -0,0 +1,45 @@
> +# Prefix and install folder
> +prefix              := @prefix@
> +PREFIX              := $(prefix)
> +exec_prefix         := @exec_prefix@
> +libdir              := @libdir@
> +LIBDIR              := $(libdir)
> +
> +# Path Programs
> +CMAKE               := @CMAKE@
> +WGET                := @WGET@ -c
> +
> +# A debug build of stubdom? //FIXME: Someone make this do something
> +debug               := @debug@
> +vtpm = @vtpm@
> +
> +STUBDOM_TARGETS     := @STUBDOM_TARGETS@
> +STUBDOM_BUILD       := @STUBDOM_BUILD@
> +STUBDOM_INSTALL     := @STUBDOM_INSTALL@
> +
> +ZLIB_VERSION        := @ZLIB_VERSION@
> +ZLIB_URL            := @ZLIB_URL@
> +
> +LIBPCI_VERSION      := @LIBPCI_VERSION@
> +LIBPCI_URL          := @LIBPCI_URL@
> +
> +NEWLIB_VERSION      := @NEWLIB_VERSION@
> +NEWLIB_URL          := @NEWLIB_URL@
> +
> +LWIP_VERSION        := @LWIP_VERSION@
> +LWIP_URL            := @LWIP_URL@
> +
> +GRUB_VERSION        := @GRUB_VERSION@
> +GRUB_URL            := @GRUB_URL@
> +
> +OCAML_VERSION       := @OCAML_VERSION@
> +OCAML_URL           := @OCAML_URL@
> +
> +GMP_VERSION         := @GMP_VERSION@
> +GMP_URL             := @GMP_URL@
> +
> +POLARSSL_VERSION    := @POLARSSL_VERSION@
> +POLARSSL_URL        := @POLARSSL_URL@
> +
> +TPMEMU_VERSION      := @TPMEMU_VERSION@
> +TPMEMU_URL          := @TPMEMU_URL@
> diff --git a/tools/m4/curses.m4 b/m4/curses.m4
> similarity index 100%
> rename from tools/m4/curses.m4
> rename to m4/curses.m4
> diff --git a/m4/depends.m4 b/m4/depends.m4
> new file mode 100644
> index 0000000..916e665
> --- /dev/null
> +++ b/m4/depends.m4
> @@ -0,0 +1,15 @@
> +
> +AC_DEFUN([AX_DEPENDS_PATH_PROG], [
> +AS_IF([test "x$$1" = "xy"], [AX_PATH_PROG_OR_FAIL([$2], [$3])], [
> +AS_IF([test "x$$1" = "xn"], [
> +$2="/$3-disabled-in-configure-script"
> +], [
> +AC_PATH_PROG([$2], [$3], [no])
> +AS_IF([test x"${$2}" = "xno"], [
> +$1=n
> +$2="/$3-disabled-in-configure-script"
> +])
> +])
> +])
> +AC_SUBST($2)
> +])
> diff --git a/tools/m4/extfs.m4 b/m4/extfs.m4
> similarity index 100%
> rename from tools/m4/extfs.m4
> rename to m4/extfs.m4
> diff --git a/tools/m4/features.m4 b/m4/features.m4
> similarity index 100%
> rename from tools/m4/features.m4
> rename to m4/features.m4
> diff --git a/tools/m4/fetcher.m4 b/m4/fetcher.m4
> similarity index 100%
> rename from tools/m4/fetcher.m4
> rename to m4/fetcher.m4
> diff --git a/tools/m4/ocaml.m4 b/m4/ocaml.m4
> similarity index 100%
> rename from tools/m4/ocaml.m4
> rename to m4/ocaml.m4
> diff --git a/tools/m4/path_or_fail.m4 b/m4/path_or_fail.m4
> similarity index 100%
> rename from tools/m4/path_or_fail.m4
> rename to m4/path_or_fail.m4
> diff --git a/tools/m4/pkg.m4 b/m4/pkg.m4
> similarity index 100%
> rename from tools/m4/pkg.m4
> rename to m4/pkg.m4
> diff --git a/tools/m4/pthread.m4 b/m4/pthread.m4
> similarity index 100%
> rename from tools/m4/pthread.m4
> rename to m4/pthread.m4
> diff --git a/tools/m4/ptyfuncs.m4 b/m4/ptyfuncs.m4
> similarity index 100%
> rename from tools/m4/ptyfuncs.m4
> rename to m4/ptyfuncs.m4
> diff --git a/tools/m4/python_devel.m4 b/m4/python_devel.m4
> similarity index 100%
> rename from tools/m4/python_devel.m4
> rename to m4/python_devel.m4
> diff --git a/tools/m4/python_version.m4 b/m4/python_version.m4
> similarity index 100%
> rename from tools/m4/python_version.m4
> rename to m4/python_version.m4
> diff --git a/tools/m4/savevar.m4 b/m4/savevar.m4
> similarity index 100%
> rename from tools/m4/savevar.m4
> rename to m4/savevar.m4
> diff --git a/tools/m4/set_cflags_ldflags.m4 b/m4/set_cflags_ldflags.m4
> similarity index 100%
> rename from tools/m4/set_cflags_ldflags.m4
> rename to m4/set_cflags_ldflags.m4
> diff --git a/m4/stubdom.m4 b/m4/stubdom.m4
> new file mode 100644
> index 0000000..0bf0d2c
> --- /dev/null
> +++ b/m4/stubdom.m4
> @@ -0,0 +1,89 @@
> +AC_DEFUN([AX_STUBDOM_DEFAULT_ENABLE], [
> +AC_ARG_ENABLE([$1],
> +AS_HELP_STRING([--disable-$1], [Build and install $1 (default is ENABLED)]),[
> +AX_STUBDOM_INTERNAL([$1], [$2])
> +],[
> +AX_ENABLE_STUBDOM([$1], [$2])
> +])
> +AC_SUBST([$2])
> +])
> +
> +AC_DEFUN([AX_STUBDOM_DEFAULT_DISABLE], [
> +AC_ARG_ENABLE([$1],
> +AS_HELP_STRING([--enable-$1], [Build and install $1 (default is DISABLED)]),[
> +AX_STUBDOM_INTERNAL([$1], [$2])
> +],[
> +AX_DISABLE_STUBDOM([$1], [$2])
> +])
> +AC_SUBST([$2])
> +])
> +
> +AC_DEFUN([AX_STUBDOM_CONDITIONAL], [
> +AC_ARG_ENABLE([$1],
> +AS_HELP_STRING([--enable-$1], [Build and install $1]),[
> +AX_STUBDOM_INTERNAL([$1], [$2])
> +])
> +])
> +
> +AC_DEFUN([AX_STUBDOM_CONDITIONAL_FINISH], [
> +AS_IF([test "x$$2" = "xy" || test "x$$2" = "x"], [
> +AX_ENABLE_STUBDOM([$1],[$2])
> +],[
> +AX_DISABLE_STUBDOM([$1],[$2])
> +])
> +AC_SUBST([$2])
> +])
> +
> +AC_DEFUN([AX_ENABLE_STUBDOM], [
> +$2=y
> +STUBDOM_TARGETS="$STUBDOM_TARGETS $2"
> +STUBDOM_BUILD="$STUBDOM_BUILD $1"
> +STUBDOM_INSTALL="$STUBDOM_INSTALL install-$2"
> +])
> +
> +AC_DEFUN([AX_DISABLE_STUBDOM], [
> +$2=n
> +])
> +
> +dnl Don't call this outside of this file
> +AC_DEFUN([AX_STUBDOM_INTERNAL], [
> +AS_IF([test "x$enableval" = "xyes"], [
> +AX_ENABLE_STUBDOM([$1], [$2])
> +],[
> +AS_IF([test "x$enableval" = "xno"],[
> +AX_DISABLE_STUBDOM([$1], [$2])
> +])
> +])
> +])
> +
> +AC_DEFUN([AX_STUBDOM_FINISH], [
> +AC_SUBST(STUBDOM_TARGETS)
> +AC_SUBST(STUBDOM_BUILD)
> +AC_SUBST(STUBDOM_INSTALL)
> +echo "Will build the following stub domains:"
> +for x in $STUBDOM_BUILD; do
> +       echo "  $x"
> +done
> +])
> +
> +AC_DEFUN([AX_STUBDOM_LIB], [
> +AC_ARG_VAR([$1_URL], [Download url for $2])
> +AS_IF([test "x$$1_URL" = "x"], [
> +       AS_IF([test "x$extfiles" = "xy"],
> +               [$1_URL=\@S|@\@{:@XEN_EXTFILES_URL\@:}@],
> +               [$1_URL="$4"])
> +       ])
> +$1_VERSION="$3"
> +AC_SUBST($1_URL)
> +AC_SUBST($1_VERSION)
> +])
> +
> +AC_DEFUN([AX_STUBDOM_LIB_NOEXT], [
> +AC_ARG_VAR([$1_URL], [Download url for $2])
> +AS_IF([test "x$$1_URL" = "x"], [
> +       $1_URL="$4"
> +       ])
> +$1_VERSION="$3"
> +AC_SUBST($1_URL)
> +AC_SUBST($1_VERSION)
> +])
> diff --git a/tools/m4/uuid.m4 b/m4/uuid.m4
> similarity index 100%
> rename from tools/m4/uuid.m4
> rename to m4/uuid.m4
> diff --git a/stubdom/Makefile b/stubdom/Makefile
> index fc70d88..709b71e 100644
> --- a/stubdom/Makefile
> +++ b/stubdom/Makefile
> @@ -6,44 +6,7 @@ export XEN_OS=MiniOS
>  export stubdom=y
>  export debug=y
>  include $(XEN_ROOT)/Config.mk
> -
> -#ZLIB_URL?=http://www.zlib.net
> -ZLIB_URL=$(XEN_EXTFILES_URL)
> -ZLIB_VERSION=1.2.3
> -
> -#LIBPCI_URL?=http://www.kernel.org/pub/software/utils/pciutils
> -LIBPCI_URL?=$(XEN_EXTFILES_URL)
> -LIBPCI_VERSION=2.2.9
> -
> -#NEWLIB_URL?=ftp://sources.redhat.com/pub/newlib
> -NEWLIB_URL?=$(XEN_EXTFILES_URL)
> -NEWLIB_VERSION=1.16.0
> -
> -#LWIP_URL?=http://download.savannah.gnu.org/releases/lwip
> -LWIP_URL?=$(XEN_EXTFILES_URL)
> -LWIP_VERSION=1.3.0
> -
> -#GRUB_URL?=http://alpha.gnu.org/gnu/grub
> -GRUB_URL?=$(XEN_EXTFILES_URL)
> -GRUB_VERSION=0.97
> -
> -#OCAML_URL?=$(XEN_EXTFILES_URL)
> -OCAML_URL?=http://caml.inria.fr/pub/distrib/ocaml-3.11
> -OCAML_VERSION=3.11.0
> -
> -GMP_VERSION=4.3.2
> -GMP_URL?=$(XEN_EXTFILES_URL)
> -#GMP_URL?=ftp://ftp.gmplib.org/pub/gmp-$(GMP_VERSION)
> -
> -POLARSSL_VERSION=1.1.4
> -POLARSSL_URL?=$(XEN_EXTFILES_URL)
> -#POLARSSL_URL?=http://polarssl.org/code/releases
> -
> -TPMEMU_VERSION=0.7.4
> -TPMEMU_URL?=$(XEN_EXTFILES_URL)
> -#TPMEMU_URL?=http://download.berlios.de/tpm-emulator
> -
> -WGET=wget -c
> +-include $(XEN_ROOT)/config/Stubdom.mk
> 
>  GNU_TARGET_ARCH:=$(XEN_TARGET_ARCH)
>  ifeq ($(XEN_TARGET_ARCH),x86_32)
> @@ -86,12 +49,12 @@ TARGET_CPPFLAGS += -I$(XEN_ROOT)/xen/include
> 
>  TARGET_LDFLAGS += -nostdlib -L$(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/lib
> 
> -TARGETS=ioemu c caml grub xenstore vtpm vtpmmgr
> +TARGETS=$(STUBDOM_TARGETS)
> 
>  .PHONY: all
>  all: build
>  ifeq ($(STUBDOM_SUPPORTED),1)
> -build: genpath ioemu-stubdom c-stubdom pv-grub xenstore-stubdom vtpm-stubdom vtpmmgrdom
> +build: genpath $(STUBDOM_BUILD)
>  else
>  build: genpath
>  endif
> @@ -245,7 +208,7 @@ tpm_emulator-$(XEN_TARGET_ARCH): tpm_emulator-$(TPMEMU_VERSION).tar.gz
>         mv tpm_emulator-$(TPMEMU_VERSION) $@
>         patch -d $@ -p1 < tpmemu-$(TPMEMU_VERSION).patch;
>         mkdir $@/build
> -       cd $@/build; cmake .. -DCMAKE_C_COMPILER=${CC} -DCMAKE_C_FLAGS="-std=c99 -DTPM_NO_EXTERN $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-declaration-after-statement"
> +       cd $@/build; $(CMAKE) .. -DCMAKE_C_COMPILER=${CC} -DCMAKE_C_FLAGS="-std=c99 -DTPM_NO_EXTERN $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-declaration-after-statement"
>         touch $@
> 
>  TPMEMU_STAMPFILE=$(CROSS_ROOT)/$(GNU_TARGET_ARCH)-xen-elf/lib/libtpm.a
> @@ -483,7 +446,7 @@ xenstore-stubdom: mini-os-$(XEN_TARGET_ARCH)-xenstore libxc xenstore
>  #########
> 
>  ifeq ($(STUBDOM_SUPPORTED),1)
> -install: genpath install-readme install-ioemu install-grub install-xenstore install-vtpm install-vtpmmgr
> +install: genpath install-readme $(STUBDOM_INSTALL)
>  else
>  install: genpath
>  endif
> @@ -503,6 +466,8 @@ install-grub: pv-grub
>         $(INSTALL_DIR) "$(DESTDIR)$(XENFIRMWAREDIR)"
>         $(INSTALL_DATA) mini-os-$(XEN_TARGET_ARCH)-grub/mini-os.gz "$(DESTDIR)$(XENFIRMWAREDIR)/pv-grub-$(XEN_TARGET_ARCH).gz"
> 
> +install-caml: caml-stubdom
> +
>  install-xenstore: xenstore-stubdom
>         $(INSTALL_DIR) "$(DESTDIR)/usr/lib/xen/boot"
>         $(INSTALL_DATA) mini-os-$(XEN_TARGET_ARCH)-xenstore/mini-os.gz "$(DESTDIR)/usr/lib/xen/boot/xenstore-stubdom.gz"
> @@ -581,3 +546,9 @@ downloadclean: patchclean
> 
>  .PHONY: distclean
>  distclean: downloadclean
> +       -rm ../config/Stubdom.mk
> +
> +ifeq (,$(findstring clean,$(MAKECMDGOALS)))
> +$(XEN_ROOT)/config/Stubdom.mk:
> +       $(error You have to run ./configure before building or installing stubdom)
> +endif
> diff --git a/stubdom/configure.ac b/stubdom/configure.ac
> new file mode 100644
> index 0000000..db44d4a
> --- /dev/null
> +++ b/stubdom/configure.ac
> @@ -0,0 +1,58 @@
> +#                                               -*- Autoconf -*-
> +# Process this file with autoconf to produce a configure script.
> +
> +AC_PREREQ([2.67])
> +AC_INIT([Xen Hypervisor Stub Domains], m4_esyscmd([../version.sh ../xen/Makefile]),
> +    [xen-devel@lists.xen.org], [xen], [http://www.xen.org/])
> +AC_CONFIG_SRCDIR([../extras/mini-os/kernel.c])
> +AC_CONFIG_FILES([../config/Stubdom.mk])
> +AC_PREFIX_DEFAULT([/usr])
> +AC_CONFIG_AUX_DIR([../])
> +
> +# M4 Macro includes
> +m4_include([../m4/stubdom.m4])
> +m4_include([../m4/features.m4])
> +m4_include([../m4/path_or_fail.m4])
> +m4_include([../m4/depends.m4])
> +
> +# Enable/disable stub domains
> +AX_STUBDOM_DEFAULT_ENABLE([ioemu-stubdom], [ioemu])
> +AX_STUBDOM_DEFAULT_DISABLE([c-stubdom], [c])
> +AX_STUBDOM_DEFAULT_ENABLE([caml-stubdom], [caml])
> +AX_STUBDOM_DEFAULT_ENABLE([pv-grub], [grub])
> +AX_STUBDOM_DEFAULT_ENABLE([xenstore-stubdom], [xenstore])
> +AX_STUBDOM_CONDITIONAL([vtpm-stubdom], [vtpm])
> +AX_STUBDOM_CONDITIONAL([vtpmmgrdom], [vtpmmgr])
> +
> +AX_ARG_DEFAULT_ENABLE([debug], [Disable debug build of stubdom])
> +AX_ARG_DEFAULT_ENABLE([extfiles], [Use xen extfiles repository for libraries])
> +
> +AC_ARG_VAR([CMAKE], [Path to the cmake program])
> +AC_ARG_VAR([WGET], [Path to wget program])
> +
> +# Checks for programs.
> +AC_PROG_CC
> +AC_PROG_MAKE_SET
> +AC_PROG_INSTALL
> +AX_PATH_PROG_OR_FAIL([WGET], [wget])
> +
> +# Checks for programs that depend on a feature
> +AX_DEPENDS_PATH_PROG([vtpm], [CMAKE], [cmake])
> +
> +# Stubdom libraries version and url setup
> +AX_STUBDOM_LIB([ZLIB], [zlib], [1.2.3], [http://www.zlib.net])
> +AX_STUBDOM_LIB([LIBPCI], [libpci], [2.2.9], [http://www.kernel.org/pub/software/utils/pciutils])
> +AX_STUBDOM_LIB([NEWLIB], [newlib], [1.16.0], [ftp://sources.redhat.com/pub/newlib])
> +AX_STUBDOM_LIB([LWIP], [lwip], [1.3.0], [http://download.savannah.gnu.org/releases/lwip])
> +AX_STUBDOM_LIB([GRUB], [grub], [0.97], [http://alpha.gnu.org/gnu/grub])
> +AX_STUBDOM_LIB_NOEXT([OCAML], [ocaml], [3.11.0], [http://caml.inria.fr/pub/distrib/ocaml-3.11])
> +AX_STUBDOM_LIB([GMP], [libgmp], [4.3.2], [ftp://ftp.gmplib.org/pub/gmp-4.3.2])
> +AX_STUBDOM_LIB([POLARSSL], [polarssl], [1.1.4], [http://polarssl.org/code/releases])
> +AX_STUBDOM_LIB([TPMEMU], [berlios tpm emulator], [0.7.4], [http://download.berlios.de/tpm-emulator])
> +
> +#Conditionally enable these stubdoms based on the presense of dependencies
> +AX_STUBDOM_CONDITIONAL_FINISH([vtpm-stubdom], [vtpm])
> +AX_STUBDOM_CONDITIONAL_FINISH([vtpmmgrdom], [vtpmmgr])
> +
> +AX_STUBDOM_FINISH
> +AC_OUTPUT()
> diff --git a/tools/configure.ac b/tools/configure.ac
> index 586313d..971e3e9 100644
> --- a/tools/configure.ac
> +++ b/tools/configure.ac
> @@ -22,20 +22,20 @@ APPEND_INCLUDES and APPEND_LIB instead when possible.])
>  AC_CANONICAL_HOST
> 
>  # M4 Macro includes
> -m4_include([m4/savevar.m4])
> -m4_include([m4/features.m4])
> -m4_include([m4/path_or_fail.m4])
> -m4_include([m4/python_version.m4])
> -m4_include([m4/python_devel.m4])
> -m4_include([m4/ocaml.m4])
> -m4_include([m4/set_cflags_ldflags.m4])
> -m4_include([m4/uuid.m4])
> -m4_include([m4/pkg.m4])
> -m4_include([m4/curses.m4])
> -m4_include([m4/pthread.m4])
> -m4_include([m4/ptyfuncs.m4])
> -m4_include([m4/extfs.m4])
> -m4_include([m4/fetcher.m4])
> +m4_include([../m4/savevar.m4])
> +m4_include([../m4/features.m4])
> +m4_include([../m4/path_or_fail.m4])
> +m4_include([../m4/python_version.m4])
> +m4_include([../m4/python_devel.m4])
> +m4_include([../m4/ocaml.m4])
> +m4_include([../m4/set_cflags_ldflags.m4])
> +m4_include([../m4/uuid.m4])
> +m4_include([../m4/pkg.m4])
> +m4_include([../m4/curses.m4])
> +m4_include([../m4/pthread.m4])
> +m4_include([../m4/ptyfuncs.m4])
> +m4_include([../m4/extfs.m4])
> +m4_include([../m4/fetcher.m4])
> 
>  # Enable/disable options
>  AX_ARG_DEFAULT_DISABLE([githttp], [Download GIT repositories via HTTP])
> --
> 1.7.10.4
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [VTPM v7 6/8] Add autoconf to stubdom
  2012-12-13 12:02   ` Ian Campbell
@ 2012-12-13 14:15     ` Ian Jackson
  2012-12-13 15:15     ` Matthew Fioravante
  1 sibling, 0 replies; 14+ messages in thread
From: Ian Jackson @ 2012-12-13 14:15 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Matthew Fioravante, xen-devel

Ian Campbell writes ("Re: [VTPM v7 6/8] Add autoconf to stubdom"):
> It also occurs to me that this series introduces a little bisection blip
> where cmake will be required (i.e. from patch 3 until here). The right
> way to do this would have been to put the patch introducing autoconf at
> the start. I'm inclined to just gloss over that for now, but if you feel
> so inclined you could reorder things.

I would recommend reordering things, yes.

If the bisection blip bites us, what will happen is that the automatic
bisector will finger the cmake-requiring changeset.  Normally if that
happens it would be fair to ask the person who introduces the
bisection breakage to debug whatever the other problem is that the
bisector is hunting for.  I wouldn't recommend knowingly putting
oneself in that position :-).

Ian.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [VTPM v7 1/8] add vtpm-stubdom code
  2012-12-13 11:48 ` [VTPM v7 1/8] add vtpm-stubdom code Ian Campbell
@ 2012-12-13 14:55   ` Fioravante, Matthew E.
  0 siblings, 0 replies; 14+ messages in thread
From: Fioravante, Matthew E. @ 2012-12-13 14:55 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Ian Jackson, xen-devel

Ok, just for reference for now, Nothing has changed with the vtpm patches, just the autoconf stuff is evolving.

-----Original Message-----
From: Ian Campbell [mailto:Ian.Campbell@citrix.com]
Sent: Thursday, December 13, 2012 6:48 AM
To: Fioravante, Matthew E.
Cc: xen-devel@lists.xen.org; Ian Jackson
Subject: Re: [VTPM v7 1/8] add vtpm-stubdom code

For future reference please could you include an indication of what changed in a new posting of a series, either in the 0/N mail (which is useful to include as an intro in any case) or in the individual changelogs.

On Thu, 2012-12-06 at 18:19 +0000, Matthew Fioravante wrote:
> Add the code base for vtpm-stubdom to the stubdom heirarchy. Makefile
> changes in later patch.
>
> Signed-off-by: Matthew Fioravante <matthew.fioravante@jhuapl.edu>
> Acked-by: Ian Campbell <ian.campbell@citrix.com>
> ---
>  stubdom/vtpm/Makefile    |   37 +++++
>  stubdom/vtpm/minios.cfg  |   14 ++
>  stubdom/vtpm/vtpm.c      |  404 ++++++++++++++++++++++++++++++++++++++++++++++
>  stubdom/vtpm/vtpm.h      |   36 +++++
>  stubdom/vtpm/vtpm_cmd.c  |  256 +++++++++++++++++++++++++++++
>  stubdom/vtpm/vtpm_cmd.h  |   31 ++++
>  stubdom/vtpm/vtpm_pcrs.c |   43 +++++
>  stubdom/vtpm/vtpm_pcrs.h |   53 ++++++
>  stubdom/vtpm/vtpmblk.c   |  307 +++++++++++++++++++++++++++++++++++
>  stubdom/vtpm/vtpmblk.h   |   31 ++++
>  10 files changed, 1212 insertions(+)
>  create mode 100644 stubdom/vtpm/Makefile  create mode 100644
> stubdom/vtpm/minios.cfg  create mode 100644 stubdom/vtpm/vtpm.c
> create mode 100644 stubdom/vtpm/vtpm.h  create mode 100644
> stubdom/vtpm/vtpm_cmd.c  create mode 100644 stubdom/vtpm/vtpm_cmd.h
> create mode 100644 stubdom/vtpm/vtpm_pcrs.c  create mode 100644
> stubdom/vtpm/vtpm_pcrs.h  create mode 100644 stubdom/vtpm/vtpmblk.c
> create mode 100644 stubdom/vtpm/vtpmblk.h
>
> diff --git a/stubdom/vtpm/Makefile b/stubdom/vtpm/Makefile new file
> mode 100644 index 0000000..686c0ea
> --- /dev/null
> +++ b/stubdom/vtpm/Makefile
> @@ -0,0 +1,37 @@
> +# Copyright (c) 2010-2012 United States Government, as represented by
> +# the Secretary of Defense.  All rights reserved.
> +#
> +# THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
> +# ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES #
> +INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
> +# FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY #
> +DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE #
> +SOFTWARE.
> +#
> +
> +XEN_ROOT=../..
> +
> +PSSL_DIR=../polarssl-$(XEN_TARGET_ARCH)/library
> +PSSL_OBJS=aes.o sha1.o entropy.o ctr_drbg.o sha4.o
> +
> +TARGET=vtpm.a
> +OBJS=vtpm.o vtpm_cmd.o vtpmblk.o vtpm_pcrs.o
> +
> +
> +CPPFLAGS+=-I../tpm_emulator-$(XEN_TARGET_ARCH)/build
> +CPPFLAGS+=-I../tpm_emulator-$(XEN_TARGET_ARCH)/tpm
> +CPPFLAGS+=-I../tpm_emulator-$(XEN_TARGET_ARCH)/crypto
> +CPPFLAGS+=-I../tpm_emulator-$(XEN_TARGET_ARCH)
> +
> +$(TARGET): $(OBJS)
> +       ar -cr $@ $(OBJS) $(TPMEMU_OBJS) $(foreach
> +obj,$(PSSL_OBJS),$(PSSL_DIR)/$(obj))
> +
> +$(OBJS): vtpm_manager.h
> +
> +vtpm_manager.h:
> +       ln -s ../vtpmmgr/vtpm_manager.h vtpm_manager.h
> +
> +clean:
> +       -rm $(TARGET) $(OBJS) vtpm_manager.h
> +
> +.PHONY: clean
> diff --git a/stubdom/vtpm/minios.cfg b/stubdom/vtpm/minios.cfg new
> file mode 100644 index 0000000..31652ee
> --- /dev/null
> +++ b/stubdom/vtpm/minios.cfg
> @@ -0,0 +1,14 @@
> +CONFIG_TPMFRONT=y
> +CONFIG_TPM_TIS=n
> +CONFIG_TPMBACK=y
> +CONFIG_START_NETWORK=n
> +CONFIG_TEST=n
> +CONFIG_PCIFRONT=n
> +CONFIG_BLKFRONT=y
> +CONFIG_NETFRONT=n
> +CONFIG_FBFRONT=n
> +CONFIG_KBDFRONT=n
> +CONFIG_CONSFRONT=n
> +CONFIG_XENBUS=y
> +CONFIG_LWIP=n
> +CONFIG_XC=n
> diff --git a/stubdom/vtpm/vtpm.c b/stubdom/vtpm/vtpm.c new file mode
> 100644 index 0000000..71aef78
> --- /dev/null
> +++ b/stubdom/vtpm/vtpm.c
> @@ -0,0 +1,404 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented
> +by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
> + * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
> + * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY,
> +FITNESS
> + * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
> + * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING
> +THE
> + * SOFTWARE.
> + */
> +
> +#include <stdio.h>
> +#include <stdint.h>
> +#include <inttypes.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <string.h>
> +#include <syslog.h>
> +#include <stdbool.h>
> +#include <errno.h>
> +#include <sys/time.h>
> +#include <xen/xen.h>
> +#include <tpmback.h>
> +#include <tpmfront.h>
> +
> +#include <polarssl/entropy.h>
> +#include <polarssl/ctr_drbg.h>
> +
> +#include "tpm/tpm_emulator_extern.h"
> +#include "tpm/tpm_marshalling.h"
> +#include "vtpm.h"
> +#include "vtpm_cmd.h"
> +#include "vtpm_pcrs.h"
> +#include "vtpmblk.h"
> +
> +#define TPM_LOG_INFO LOG_INFO
> +#define TPM_LOG_ERROR LOG_ERR
> +#define TPM_LOG_DEBUG LOG_DEBUG
> +
> +/* Global commandline options - default values */ struct Opt_args
> +opt_args = {
> +   .startup = ST_CLEAR,
> +   .loglevel = TPM_LOG_INFO,
> +   .hwinitpcrs = VTPM_PCRNONE,
> +   .tpmconf = 0,
> +   .enable_maint_cmds = false,
> +};
> +
> +static uint32_t badords[32];
> +static unsigned int n_badords = 0;
> +
> +entropy_context entropy;
> +ctr_drbg_context ctr_drbg;
> +
> +struct tpmfront_dev* tpmfront_dev;
> +
> +void vtpm_get_extern_random_bytes(void *buf, size_t nbytes) {
> +   ctr_drbg_random(&ctr_drbg, buf, nbytes); }
> +
> +int vtpm_read_from_file(uint8_t **data, size_t *data_length) {
> +   return read_vtpmblk(tpmfront_dev, data, data_length); }
> +
> +int vtpm_write_to_file(uint8_t *data, size_t data_length) {
> +   return write_vtpmblk(tpmfront_dev, data, data_length); }
> +
> +int vtpm_extern_init_fake(void) {
> +   return 0;
> +}
> +
> +void vtpm_extern_release_fake(void) { }
> +
> +
> +void vtpm_log(int priority, const char *fmt, ...) {
> +   if(opt_args.loglevel >= priority) {
> +      va_list v;
> +      va_start(v, fmt);
> +      vprintf(fmt, v);
> +      va_end(v);
> +   }
> +}
> +
> +static uint64_t vtpm_get_ticks(void)
> +{
> +  static uint64_t old_t = 0;
> +  uint64_t new_t, res_t;
> +  struct timeval tv;
> +  gettimeofday(&tv, NULL);
> +  new_t = (uint64_t)tv.tv_sec * 1000000 + (uint64_t)tv.tv_usec;
> +  res_t = (old_t > 0) ? new_t - old_t : 0;
> +  old_t = new_t;
> +  return res_t;
> +}
> +
> +
> +static int tpm_entropy_source(void* dummy, unsigned char* data, size_t len, size_t* olen) {
> +   UINT32 sz = len;
> +   TPM_RESULT rc = VTPM_GetRandom(tpmfront_dev, data, &sz);
> +   *olen = sz;
> +   return rc == TPM_SUCCESS ? 0 : POLARSSL_ERR_ENTROPY_SOURCE_FAILED;
> +}
> +
> +int init_random(void) {
> +   /* Initialize the rng */
> +   entropy_init(&entropy);
> +   entropy_add_source(&entropy, tpm_entropy_source, NULL, 0);
> +   entropy_gather(&entropy);
> +   ctr_drbg_init(&ctr_drbg, entropy_func, &entropy, NULL, 0);
> +   ctr_drbg_set_prediction_resistance( &ctr_drbg, CTR_DRBG_PR_OFF );
> +
> +   return 0;
> +}
> +
> +int check_ordinal(tpmcmd_t* tpmcmd) {
> +   TPM_COMMAND_CODE ord;
> +   UINT32 len = 4;
> +   BYTE* ptr;
> +   unsigned int i;
> +
> +   if(tpmcmd->req_len < 10) {
> +      return true;
> +   }
> +
> +   ptr = tpmcmd->req + 6;
> +   tpm_unmarshal_UINT32(&ptr, &len, &ord);
> +
> +   for(i = 0; i < n_badords; ++i) {
> +      if(ord == badords[i]) {
> +         error("Disabled command ordinal (%" PRIu32") requested!\n");
> +         return false;
> +      }
> +   }
> +   return true;
> +}
> +
> +static void main_loop(void) {
> +   tpmcmd_t* tpmcmd = NULL;
> +   domid_t domid;              /* Domid of frontend */
> +   unsigned int handle;        /* handle of frontend */
> +   int res = -1;
> +
> +   info("VTPM Initializing\n");
> +
> +   /* Set required tpm config args */
> +   opt_args.tpmconf |= TPM_CONF_STRONG_PERSISTENCE;
> +   opt_args.tpmconf &= ~TPM_CONF_USE_INTERNAL_PRNG;
> +   opt_args.tpmconf |= TPM_CONF_GENERATE_EK;
> +   opt_args.tpmconf |= TPM_CONF_GENERATE_SEED_DAA;
> +
> +   /* Initialize the emulator */
> +   tpm_emulator_init(opt_args.startup, opt_args.tpmconf);
> +
> +   /* Initialize any requested PCRs with hardware TPM values */
> +   if(vtpm_initialize_hw_pcrs(tpmfront_dev, opt_args.hwinitpcrs) != TPM_SUCCESS) {
> +      error("Failed to initialize PCRs with hardware TPM values");
> +      goto abort_postpcrs;
> +   }
> +
> +   /* Wait for the frontend domain to connect */
> +   info("Waiting for frontend domain to connect..");
> +   if(tpmback_wait_for_frontend_connect(&domid, &handle) == 0) {
> +      info("VTPM attached to Frontend %u/%u", (unsigned int) domid, handle);
> +   } else {
> +      error("Unable to attach to a frontend");
> +   }
> +
> +   tpmcmd = tpmback_req(domid, handle);
> +   while(tpmcmd) {
> +      /* Handle the request */
> +      if(tpmcmd->req_len) {
> +        tpmcmd->resp = NULL;
> +        tpmcmd->resp_len = 0;
> +
> +         /* First check for disabled ordinals */
> +         if(!check_ordinal(tpmcmd)) {
> +            create_error_response(tpmcmd, TPM_BAD_ORDINAL);
> +         }
> +         /* If not disabled, do the command */
> +         else {
> +            if((res = tpm_handle_command(tpmcmd->req, tpmcmd->req_len, &tpmcmd->resp, &tpmcmd->resp_len)) != 0) {
> +               error("tpm_handle_command() failed");
> +               create_error_response(tpmcmd, TPM_FAIL);
> +            }
> +         }
> +      }
> +
> +      /* Send the response */
> +      tpmback_resp(tpmcmd);
> +
> +      /* Wait for the next request */
> +      tpmcmd = tpmback_req(domid, handle);
> +
> +   }
> +
> +abort_postpcrs:
> +   info("VTPM Shutting down\n");
> +
> +   tpm_emulator_shutdown();
> +}
> +
> +int parse_cmd_line(int argc, char** argv) {
> +   char sval[25];
> +   char* logstr = NULL;
> +   /* Parse the command strings */
> +   for(unsigned int i = 1; i < argc; ++i) {
> +      if (sscanf(argv[i], "loglevel=%25s", sval) == 1){
> +        if (!strcmp(sval, "debug")) {
> +           opt_args.loglevel = TPM_LOG_DEBUG;
> +           logstr = "debug";
> +        }
> +        else if (!strcmp(sval, "info")) {
> +           logstr = "info";
> +           opt_args.loglevel = TPM_LOG_INFO;
> +        }
> +        else if (!strcmp(sval, "error")) {
> +           logstr = "error";
> +           opt_args.loglevel = TPM_LOG_ERROR;
> +        }
> +      }
> +      else if (!strcmp(argv[i], "clear")) {
> +        opt_args.startup = ST_CLEAR;
> +      }
> +      else if (!strcmp(argv[i], "save")) {
> +        opt_args.startup = ST_SAVE;
> +      }
> +      else if (!strcmp(argv[i], "deactivated")) {
> +        opt_args.startup = ST_DEACTIVATED;
> +      }
> +      else if (!strncmp(argv[i], "maintcmds=", 10)) {
> +         if(!strcmp(argv[i] + 10, "1")) {
> +            opt_args.enable_maint_cmds = true;
> +         } else if(!strcmp(argv[i] + 10, "0")) {
> +            opt_args.enable_maint_cmds = false;
> +         }
> +      }
> +      else if(!strncmp(argv[i], "hwinitpcr=", 10)) {
> +         char *pch = argv[i] + 10;
> +         unsigned int v1, v2;
> +         pch = strtok(pch, ",");
> +         while(pch != NULL) {
> +            if(!strcmp(pch, "all")) {
> +               //Set all
> +               opt_args.hwinitpcrs = VTPM_PCRALL;
> +            } else if(!strcmp(pch, "none")) {
> +               //Set none
> +               opt_args.hwinitpcrs = VTPM_PCRNONE;
> +            } else if(sscanf(pch, "%u", &v1) == 1) {
> +               //Set one
> +               if(v1 >= TPM_NUM_PCR) {
> +                  error("hwinitpcr error: Invalid PCR index %u", v1);
> +                  return -1;
> +               }
> +               opt_args.hwinitpcrs |= (1 << v1);
> +            } else if(sscanf(pch, "%u-%u", &v1, &v2) == 2) {
> +               //Set range
> +               if(v1 >= TPM_NUM_PCR) {
> +                  error("hwinitpcr error: Invalid PCR index %u", v1);
> +                  return -1;
> +               }
> +               if(v2 >= TPM_NUM_PCR) {
> +                  error("hwinitpcr error: Invalid PCR index %u", v1);
> +                  return -1;
> +               }
> +               if(v2 < v1) {
> +                  unsigned tp = v1;
> +                  v1 = v2;
> +                  v2 = tp;
> +               }
> +               for(unsigned int i = v1; i <= v2; ++i) {
> +                  opt_args.hwinitpcrs |= (1 << i);
> +               }
> +            } else {
> +               error("hwintipcr error: Invalid PCR specification : %s", pch);
> +               return -1;
> +            }
> +            pch = strtok(NULL, ",");
> +         }
> +      }
> +      else {
> +        error("Invalid command line option `%s'", argv[i]);
> +      }
> +
> +   }
> +
> +   /* Check Errors and print results */
> +   switch(opt_args.startup) {
> +      case ST_CLEAR:
> +        info("Startup mode is `clear'");
> +        break;
> +      case ST_SAVE:
> +        info("Startup mode is `save'");
> +        break;
> +      case ST_DEACTIVATED:
> +        info("Startup mode is `deactivated'");
> +        break;
> +      default:
> +        error("Invalid startup mode %d", opt_args.startup);
> +        return -1;
> +   }
> +
> +   if(opt_args.hwinitpcrs & (VTPM_PCRALL))
> +   {
> +      char pcrstr[1024];
> +      char* ptr = pcrstr;
> +
> +      pcrstr[0] = '\0';
> +      info("The following PCRs will be initialized with values from the hardware TPM:");
> +      for(unsigned int i = 0; i < TPM_NUM_PCR; ++i) {
> +         if(opt_args.hwinitpcrs & (1 << i)) {
> +            ptr += sprintf(ptr, "%u, ", i);
> +         }
> +      }
> +      /* get rid of the last comma if any numbers were printed */
> +      *(ptr -2) = '\0';
> +
> +      info("\t%s", pcrstr);
> +   } else {
> +      info("All PCRs initialized to default values");
> +   }
> +
> +   if(!opt_args.enable_maint_cmds) {
> +      info("TPM Maintenance Commands disabled");
> +      badords[n_badords++] = TPM_ORD_CreateMaintenanceArchive;
> +      badords[n_badords++] = TPM_ORD_LoadMaintenanceArchive;
> +      badords[n_badords++] = TPM_ORD_KillMaintenanceFeature;
> +      badords[n_badords++] = TPM_ORD_LoadManuMaintPub;
> +      badords[n_badords++] = TPM_ORD_ReadManuMaintPub;
> +   } else {
> +      info("TPM Maintenance Commands enabled");
> +   }
> +
> +   info("Log level set to %s", logstr);
> +
> +   return 0;
> +}
> +
> +void cleanup_opt_args(void) {
> +}
> +
> +int main(int argc, char **argv)
> +{
> +   //FIXME: initializing blkfront without this sleep causes the domain to crash on boot
> +   sleep(2);
> +
> +   /* Setup extern function pointers */
> +   tpm_extern_init = vtpm_extern_init_fake;
> +   tpm_extern_release = vtpm_extern_release_fake;
> +   tpm_malloc = malloc;
> +   tpm_free = free;
> +   tpm_log = vtpm_log;
> +   tpm_get_ticks = vtpm_get_ticks;
> +   tpm_get_extern_random_bytes = vtpm_get_extern_random_bytes;
> +   tpm_write_to_storage = vtpm_write_to_file;
> +   tpm_read_from_storage = vtpm_read_from_file;
> +
> +   info("starting TPM Emulator (1.2.%d.%d-%d)", VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD);
> +   if(parse_cmd_line(argc, argv)) {
> +      error("Error parsing commandline\n");
> +      return -1;
> +   }
> +
> +   /* Initialize devices */
> +   init_tpmback();
> +   if((tpmfront_dev = init_tpmfront(NULL)) == NULL) {
> +      error("Unable to initialize tpmfront device");
> +      goto abort_posttpmfront;
> +   }
> +
> +   /* Seed the RNG with entropy from hardware TPM */
> +   if(init_random()) {
> +      error("Unable to initialize RNG");
> +      goto abort_postrng;
> +   }
> +
> +   /* Initialize blkfront device */
> +   if(init_vtpmblk(tpmfront_dev)) {
> +      error("Unable to initialize Blkfront persistent storage");
> +      goto abort_postvtpmblk;
> +   }
> +
> +   /* Run main loop */
> +   main_loop();
> +
> +   /* Shutdown blkfront */
> +   shutdown_vtpmblk();
> +abort_postvtpmblk:
> +abort_postrng:
> +
> +   /* Close devices */
> +   shutdown_tpmfront(tpmfront_dev);
> +abort_posttpmfront:
> +   shutdown_tpmback();
> +
> +   cleanup_opt_args();
> +
> +   return 0;
> +}
> diff --git a/stubdom/vtpm/vtpm.h b/stubdom/vtpm/vtpm.h new file mode
> 100644 index 0000000..5919e44
> --- /dev/null
> +++ b/stubdom/vtpm/vtpm.h
> @@ -0,0 +1,36 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented
> +by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
> + * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
> + * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY,
> +FITNESS
> + * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
> + * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING
> +THE
> + * SOFTWARE.
> + */
> +
> +#ifndef VTPM_H
> +#define VTPM_H
> +
> +#include <stdbool.h>
> +
> +/* For testing */
> +#define VERS_CMD "\x00\xC1\x00\x00\x00\x16\x00\x00\x00\x65\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x01\x03"
> +#define VERS_CMD_LEN 22
> +
> +/* Global commandline options */
> +struct Opt_args {
> +   enum StartUp {
> +      ST_CLEAR = 1,
> +      ST_SAVE = 2,
> +      ST_DEACTIVATED = 3
> +   } startup;
> +   unsigned long hwinitpcrs;
> +   int loglevel;
> +   uint32_t tpmconf;
> +   bool enable_maint_cmds;
> +};
> +extern struct Opt_args opt_args;
> +
> +#endif
> diff --git a/stubdom/vtpm/vtpm_cmd.c b/stubdom/vtpm/vtpm_cmd.c new
> file mode 100644 index 0000000..7eae98b
> --- /dev/null
> +++ b/stubdom/vtpm/vtpm_cmd.c
> @@ -0,0 +1,256 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented
> +by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
> + * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
> + * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY,
> +FITNESS
> + * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
> + * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING
> +THE
> + * SOFTWARE.
> + */
> +
> +#include <types.h>
> +#include <xen/xen.h>
> +#include <mm.h>
> +#include <gnttab.h>
> +#include "tpm/tpm_marshalling.h"
> +#include "vtpm_manager.h"
> +#include "vtpm_cmd.h"
> +#include <tpmback.h>
> +
> +#define TRYFAILGOTO(C) \
> +   if((C)) { \
> +      status = TPM_FAIL; \
> +      goto abort_egress; \
> +   }
> +#define TRYFAILGOTOMSG(C, msg) \
> +   if((C)) { \
> +      status = TPM_FAIL; \
> +      error(msg); \
> +      goto abort_egress; \
> +   }
> +#define CHECKSTATUSGOTO(ret, fname) \
> +   if((ret) != TPM_SUCCESS) { \
> +      error("%s failed with error code (%lu)", fname, (unsigned long) ret); \
> +      status = ord; \
> +      goto abort_egress; \
> +   }
> +
> +#define ERR_MALFORMED "Malformed response from backend"
> +#define ERR_TPMFRONT "Error sending command through frontend device"
> +
> +struct shpage {
> +   void* page;
> +   grant_ref_t grantref;
> +};
> +
> +typedef struct shpage shpage_t;
> +
> +static inline int pack_header(uint8_t** bptr, UINT32* len, TPM_TAG
> +tag, UINT32 size, TPM_COMMAND_CODE ord) {
> +   return *bptr == NULL ||
> +        tpm_marshal_UINT16(bptr, len, tag) ||
> +        tpm_marshal_UINT32(bptr, len, size) ||
> +        tpm_marshal_UINT32(bptr, len, ord); }
> +
> +static inline int unpack_header(uint8_t** bptr, UINT32* len, TPM_TAG*
> +tag, UINT32* size, TPM_COMMAND_CODE* ord) {
> +   return *bptr == NULL ||
> +        tpm_unmarshal_UINT16(bptr, len, tag) ||
> +        tpm_unmarshal_UINT32(bptr, len, size) ||
> +        tpm_unmarshal_UINT32(bptr, len, ord); }
> +
> +int create_error_response(tpmcmd_t* tpmcmd, TPM_RESULT errorcode) {
> +   TPM_TAG tag;
> +   UINT32 len = tpmcmd->req_len;
> +   uint8_t* respptr;
> +   uint8_t* cmdptr = tpmcmd->req;
> +
> +   if(!tpm_unmarshal_UINT16(&cmdptr, &len, &tag)) {
> +      switch (tag) {
> +         case TPM_TAG_RQU_COMMAND:
> +            tag = TPM_TAG_RSP_COMMAND;
> +            break;
> +         case TPM_TAG_RQU_AUTH1_COMMAND:
> +            tag = TPM_TAG_RQU_AUTH2_COMMAND;
> +            break;
> +         case TPM_TAG_RQU_AUTH2_COMMAND:
> +            tag = TPM_TAG_RQU_AUTH2_COMMAND;
> +            break;
> +      }
> +   } else {
> +      tag = TPM_TAG_RSP_COMMAND;
> +   }
> +
> +   tpmcmd->resp_len = len = 10;
> +   tpmcmd->resp = respptr = tpm_malloc(tpmcmd->resp_len);
> +
> +   return pack_header(&respptr, &len, tag, len, errorcode); }
> +
> +TPM_RESULT VTPM_GetRandom(struct tpmfront_dev* tpmfront_dev, BYTE* bytes, UINT32 *numbytes) {
> +   TPM_RESULT status = TPM_SUCCESS;
> +   uint8_t* cmdbuf, *resp, *bptr;
> +   size_t resplen = 0;
> +   UINT32 len;
> +
> +   /*Ask the real tpm for random bytes for the seed */
> +   TPM_TAG tag = TPM_TAG_RQU_COMMAND;
> +   UINT32 size;
> +   TPM_COMMAND_CODE ord = TPM_ORD_GetRandom;
> +   len = size = sizeof(TPM_TAG) + sizeof(UINT32) +
> + sizeof(TPM_COMMAND_CODE) + sizeof(UINT32);
> +
> +   /*Create the raw tpm command */
> +   bptr = cmdbuf = malloc(size);
> +   TRYFAILGOTO(pack_header(&bptr, &len, tag, size, ord));
> +   TRYFAILGOTO(tpm_marshal_UINT32(&bptr, &len, *numbytes));
> +
> +   /* Send cmd, wait for response */
> +   TRYFAILGOTOMSG(tpmfront_cmd(tpmfront_dev, cmdbuf, size, &resp, &resplen),
> +      ERR_TPMFRONT);
> +
> +   bptr = resp; len = resplen;
> +   TRYFAILGOTOMSG(unpack_header(&bptr, &len, &tag, &size, &ord),
> + ERR_MALFORMED);
> +
> +   //Check return status of command
> +   CHECKSTATUSGOTO(ord, "TPM_GetRandom()");
> +
> +   // Get the number of random bytes in the response
> +   TRYFAILGOTOMSG(tpm_unmarshal_UINT32(&bptr, &len, &size), ERR_MALFORMED);
> +   *numbytes = size;
> +
> +   //Get the random bytes out, tpm may give us less bytes than what we wanrt
> +   TRYFAILGOTOMSG(tpm_unmarshal_BYTE_ARRAY(&bptr, &len, bytes,
> + *numbytes), ERR_MALFORMED);
> +
> +   goto egress;
> +abort_egress:
> +egress:
> +   free(cmdbuf);
> +   return status;
> +
> +}
> +
> +TPM_RESULT VTPM_LoadHashKey(struct tpmfront_dev* tpmfront_dev,
> +uint8_t** data, size_t* data_length) {
> +   TPM_RESULT status = TPM_SUCCESS;
> +   uint8_t* bptr, *resp;
> +   uint8_t* cmdbuf = NULL;
> +   size_t resplen = 0;
> +   UINT32 len;
> +
> +   TPM_TAG tag = VTPM_TAG_REQ;
> +   UINT32 size;
> +   TPM_COMMAND_CODE ord = VTPM_ORD_LOADHASHKEY;
> +
> +   /*Create the command*/
> +   len = size = VTPM_COMMAND_HEADER_SIZE;
> +   bptr = cmdbuf = malloc(size);
> +   TRYFAILGOTO(pack_header(&bptr, &len, tag, size, ord));
> +
> +   /* Send the command to vtpm_manager */
> +   info("Requesting Encryption key from backend");
> +   TRYFAILGOTOMSG(tpmfront_cmd(tpmfront_dev, cmdbuf, size, &resp,
> + &resplen), ERR_TPMFRONT);
> +
> +   /* Unpack response header */
> +   bptr = resp;
> +   len = resplen;
> +   TRYFAILGOTOMSG(unpack_header(&bptr, &len, &tag, &size, &ord),
> + ERR_MALFORMED);
> +
> +   /* Check return code */
> +   CHECKSTATUSGOTO(ord, "VTPM_LoadHashKey()");
> +
> +   /* Get the size of the key */
> +   *data_length = size - VTPM_COMMAND_HEADER_SIZE;
> +
> +   /* Copy the key bits */
> +   *data = malloc(*data_length);
> +   memcpy(*data, bptr, *data_length);
> +
> +   goto egress;
> +abort_egress:
> +   error("VTPM_LoadHashKey failed");
> +egress:
> +   free(cmdbuf);
> +   return status;
> +}
> +
> +TPM_RESULT VTPM_SaveHashKey(struct tpmfront_dev* tpmfront_dev,
> +uint8_t* data, size_t data_length) {
> +   TPM_RESULT status = TPM_SUCCESS;
> +   uint8_t* bptr, *resp;
> +   uint8_t* cmdbuf = NULL;
> +   size_t resplen = 0;
> +   UINT32 len;
> +
> +   TPM_TAG tag = VTPM_TAG_REQ;
> +   UINT32 size;
> +   TPM_COMMAND_CODE ord = VTPM_ORD_SAVEHASHKEY;
> +
> +   /*Create the command*/
> +   len = size = VTPM_COMMAND_HEADER_SIZE + data_length;
> +   bptr = cmdbuf = malloc(size);
> +   TRYFAILGOTO(pack_header(&bptr, &len, tag, size, ord));
> +   memcpy(bptr, data, data_length);
> +   bptr += data_length;
> +
> +   /* Send the command to vtpm_manager */
> +   info("Sending encryption key to backend");
> +   TRYFAILGOTOMSG(tpmfront_cmd(tpmfront_dev, cmdbuf, size, &resp,
> + &resplen), ERR_TPMFRONT);
> +
> +   /* Unpack response header */
> +   bptr = resp;
> +   len = resplen;
> +   TRYFAILGOTOMSG(unpack_header(&bptr, &len, &tag, &size, &ord),
> + ERR_MALFORMED);
> +
> +   /* Check return code */
> +   CHECKSTATUSGOTO(ord, "VTPM_SaveHashKey()");
> +
> +   goto egress;
> +abort_egress:
> +   error("VTPM_SaveHashKey failed");
> +egress:
> +   free(cmdbuf);
> +   return status;
> +}
> +
> +TPM_RESULT VTPM_PCRRead(struct tpmfront_dev* tpmfront_dev, UINT32
> +pcrIndex, BYTE* outDigest) {
> +   TPM_RESULT status = TPM_SUCCESS;
> +   uint8_t *cmdbuf, *resp, *bptr;
> +   size_t resplen = 0;
> +   UINT32 len;
> +
> +   /*Just send a TPM_PCRRead Command to the HW tpm */
> +   TPM_TAG tag = TPM_TAG_RQU_COMMAND;
> +   UINT32 size;
> +   TPM_COMMAND_CODE ord = TPM_ORD_PCRRead;
> +   len = size = sizeof(TPM_TAG) + sizeof(UINT32) +
> + sizeof(TPM_COMMAND_CODE) + sizeof(UINT32);
> +
> +   /*Create the raw tpm cmd */
> +   bptr = cmdbuf = malloc(size);
> +   TRYFAILGOTO(pack_header(&bptr, &len, tag, size, ord));
> +   TRYFAILGOTO(tpm_marshal_UINT32(&bptr, &len, pcrIndex));
> +
> +   /*Send Cmd wait for response */
> +   TRYFAILGOTOMSG(tpmfront_cmd(tpmfront_dev, cmdbuf, size, &resp,
> + &resplen), ERR_TPMFRONT);
> +
> +   bptr = resp; len = resplen;
> +   TRYFAILGOTOMSG(unpack_header(&bptr, &len, &tag, &size, &ord),
> + ERR_MALFORMED);
> +
> +   //Check return status of command
> +   CHECKSTATUSGOTO(ord, "TPM_PCRRead");
> +
> +   //Get the ptr value
> +   memcpy(outDigest, bptr, sizeof(TPM_PCRVALUE));
> +
> +   goto egress;
> +abort_egress:
> +egress:
> +   free(cmdbuf);
> +   return status;
> +
> +}
> diff --git a/stubdom/vtpm/vtpm_cmd.h b/stubdom/vtpm/vtpm_cmd.h new
> file mode 100644 index 0000000..b0bfa22
> --- /dev/null
> +++ b/stubdom/vtpm/vtpm_cmd.h
> @@ -0,0 +1,31 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented
> +by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
> + * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
> + * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY,
> +FITNESS
> + * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
> + * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING
> +THE
> + * SOFTWARE.
> + */
> +
> +#ifndef MANAGER_H
> +#define MANAGER_H
> +
> +#include <tpmfront.h>
> +#include <tpmback.h>
> +#include "tpm/tpm_structures.h"
> +
> +/* Create a command response error header */ int
> +create_error_response(tpmcmd_t* tpmcmd, TPM_RESULT errorcode);
> +/* Request random bytes from hardware tpm, returns 0 on success */
> +TPM_RESULT VTPM_GetRandom(struct tpmfront_dev* tpmfront_dev, BYTE*
> +bytes, UINT32* numbytes);
> +/* Retreive 256 bit AES encryption key from manager */ TPM_RESULT
> +VTPM_LoadHashKey(struct tpmfront_dev* tpmfront_dev, uint8_t** data,
> +size_t* data_length);
> +/* Manager securely saves our 256 bit AES encryption key */
> +TPM_RESULT VTPM_SaveHashKey(struct tpmfront_dev* tpmfront_dev,
> +uint8_t* data, size_t data_length);
> +/* Send a TPM_PCRRead command passthrough the manager to the hw tpm
> +*/ TPM_RESULT VTPM_PCRRead(struct tpmfront_dev* tpmfront_dev, UINT32
> +pcrIndex, BYTE* outDigest);
> +
> +#endif
> diff --git a/stubdom/vtpm/vtpm_pcrs.c b/stubdom/vtpm/vtpm_pcrs.c new
> file mode 100644 index 0000000..22a6cef
> --- /dev/null
> +++ b/stubdom/vtpm/vtpm_pcrs.c
> @@ -0,0 +1,43 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented
> +by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
> + * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
> + * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY,
> +FITNESS
> + * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
> + * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING
> +THE
> + * SOFTWARE.
> + */
> +
> +#include "vtpm_pcrs.h"
> +#include "vtpm_cmd.h"
> +#include "tpm/tpm_data.h"
> +
> +#define PCR_VALUE      tpmData.permanent.data.pcrValue
> +
> +static int write_pcr_direct(unsigned int pcrIndex, uint8_t* val) {
> +   if(pcrIndex > TPM_NUM_PCR) {
> +      return TPM_BADINDEX;
> +   }
> +   memcpy(&PCR_VALUE[pcrIndex], val, sizeof(TPM_PCRVALUE));
> +   return TPM_SUCCESS;
> +}
> +
> +TPM_RESULT vtpm_initialize_hw_pcrs(struct tpmfront_dev* tpmfront_dev,
> +unsigned long pcrs) {
> +   TPM_RESULT rc = TPM_SUCCESS;
> +   uint8_t digest[sizeof(TPM_PCRVALUE)];
> +
> +   for(unsigned int i = 0; i < TPM_NUM_PCR; ++i) {
> +      if(pcrs & 1 << i) {
> +         if((rc = VTPM_PCRRead(tpmfront_dev, i, digest)) != TPM_SUCCESS) {
> +            error("TPM_PCRRead failed with error : %d", rc);
> +            return rc;
> +         }
> +         write_pcr_direct(i, digest);
> +      }
> +   }
> +
> +   return rc;
> +}
> diff --git a/stubdom/vtpm/vtpm_pcrs.h b/stubdom/vtpm/vtpm_pcrs.h new
> file mode 100644 index 0000000..11835f9
> --- /dev/null
> +++ b/stubdom/vtpm/vtpm_pcrs.h
> @@ -0,0 +1,53 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented
> +by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
> + * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
> + * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY,
> +FITNESS
> + * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
> + * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING
> +THE
> + * SOFTWARE.
> + */
> +
> +#ifndef VTPM_PCRS_H
> +#define VTPM_PCRS_H
> +
> +#include "tpm/tpm_structures.h"
> +
> +#define VTPM_PCR0 1
> +#define VTPM_PCR1 1 << 1
> +#define VTPM_PCR2 1 << 2
> +#define VTPM_PCR3 1 << 3
> +#define VTPM_PCR4 1 << 4
> +#define VTPM_PCR5 1 << 5
> +#define VTPM_PCR6 1 << 6
> +#define VTPM_PCR7 1 << 7
> +#define VTPM_PCR8 1 << 8
> +#define VTPM_PCR9 1 << 9
> +#define VTPM_PCR10 1 << 10
> +#define VTPM_PCR11 1 << 11
> +#define VTPM_PCR12 1 << 12
> +#define VTPM_PCR13 1 << 13
> +#define VTPM_PCR14 1 << 14
> +#define VTPM_PCR15 1 << 15
> +#define VTPM_PCR16 1 << 16
> +#define VTPM_PCR17 1 << 17
> +#define VTPM_PCR18 1 << 18
> +#define VTPM_PCR19 1 << 19
> +#define VTPM_PCR20 1 << 20
> +#define VTPM_PCR21 1 << 21
> +#define VTPM_PCR22 1 << 22
> +#define VTPM_PCR23 1 << 23
> +
> +#define VTPM_PCRALL (1 << TPM_NUM_PCR) - 1 #define VTPM_PCRNONE 0
> +
> +#define VTPM_NUMPCRS 24
> +
> +struct tpmfront_dev;
> +
> +TPM_RESULT vtpm_initialize_hw_pcrs(struct tpmfront_dev* tpmfront_dev,
> +unsigned long pcrs);
> +
> +
> +#endif
> diff --git a/stubdom/vtpm/vtpmblk.c b/stubdom/vtpm/vtpmblk.c new file
> mode 100644 index 0000000..b343bd8
> --- /dev/null
> +++ b/stubdom/vtpm/vtpmblk.c
> @@ -0,0 +1,307 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented
> +by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
> + * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
> + * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY,
> +FITNESS
> + * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
> + * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING
> +THE
> + * SOFTWARE.
> + */
> +
> +#include <mini-os/byteorder.h>
> +#include "vtpmblk.h"
> +#include "tpm/tpm_marshalling.h"
> +#include "vtpm_cmd.h"
> +#include "polarssl/aes.h"
> +#include "polarssl/sha1.h"
> +#include <blkfront.h>
> +#include <unistd.h>
> +#include <errno.h>
> +#include <fcntl.h>
> +
> +/*Encryption key and block sizes */
> +#define BLKSZ 16
> +
> +static struct blkfront_dev* blkdev = NULL; static int blkfront_fd =
> +-1;
> +
> +int init_vtpmblk(struct tpmfront_dev* tpmfront_dev) {
> +   struct blkfront_info blkinfo;
> +   info("Initializing persistent NVM storage\n");
> +
> +   if((blkdev = init_blkfront(NULL, &blkinfo)) == NULL) {
> +      error("BLKIO: ERROR Unable to initialize blkfront");
> +      return -1;
> +   }
> +   if (blkinfo.info & VDISK_READONLY || blkinfo.mode != O_RDWR) {
> +      error("BLKIO: ERROR block device is read only!");
> +      goto error;
> +   }
> +   if((blkfront_fd = blkfront_open(blkdev)) == -1) {
> +      error("Unable to open blkfront file descriptor!");
> +      goto error;
> +   }
> +
> +   return 0;
> +error:
> +   shutdown_blkfront(blkdev);
> +   blkdev = NULL;
> +   return -1;
> +}
> +
> +void shutdown_vtpmblk(void)
> +{
> +   close(blkfront_fd);
> +   blkfront_fd = -1;
> +   blkdev = NULL;
> +}
> +
> +int write_vtpmblk_raw(uint8_t *data, size_t data_length) {
> +   int rc;
> +   uint32_t lenbuf;
> +   debug("Begin Write data=%p len=%u", data, data_length);
> +
> +   lenbuf = cpu_to_be32((uint32_t)data_length);
> +
> +   lseek(blkfront_fd, 0, SEEK_SET);
> +   if((rc = write(blkfront_fd, (uint8_t*)&lenbuf, 4)) != 4) {
> +      error("write(length) failed! error was %s", strerror(errno));
> +      return -1;
> +   }
> +   if((rc = write(blkfront_fd, data, data_length)) != data_length) {
> +      error("write(data) failed! error was %s", strerror(errno));
> +      return -1;
> +   }
> +
> +   info("Wrote %u bytes to NVM persistent storage", data_length);
> +
> +   return 0;
> +}
> +
> +int read_vtpmblk_raw(uint8_t **data, size_t *data_length) {
> +   int rc;
> +   uint32_t lenbuf;
> +
> +   lseek(blkfront_fd, 0, SEEK_SET);
> +   if(( rc = read(blkfront_fd, (uint8_t*)&lenbuf, 4)) != 4) {
> +      error("read(length) failed! error was %s", strerror(errno));
> +      return -1;
> +   }
> +   *data_length = (size_t) cpu_to_be32(lenbuf);
> +   if(*data_length == 0) {
> +      error("read 0 data_length for NVM");
> +      return -1;
> +   }
> +
> +   *data = tpm_malloc(*data_length);
> +   if((rc = read(blkfront_fd, *data, *data_length)) != *data_length) {
> +      error("read(data) failed! error was %s", strerror(errno));
> +      return -1;
> +   }
> +
> +   info("Read %u bytes from NVM persistent storage", *data_length);
> +   return 0;
> +}
> +
> +int encrypt_vtpmblk(uint8_t* clear, size_t clear_len, uint8_t**
> +cipher, size_t* cipher_len, uint8_t* symkey) {
> +   int rc = 0;
> +   uint8_t iv[BLKSZ];
> +   aes_context aes_ctx;
> +   UINT32 temp;
> +   int mod;
> +
> +   uint8_t* clbuf = NULL;
> +
> +   uint8_t* ivptr;
> +   int ivlen;
> +
> +   uint8_t* cptr;      //Cipher block pointer
> +   int clen;   //Cipher block length
> +
> +   /*Create a new 256 bit encryption key */
> +   if(symkey == NULL) {
> +      rc = -1;
> +      goto abort_egress;
> +   }
> +   tpm_get_extern_random_bytes(symkey, NVMKEYSZ);
> +
> +   /*Setup initialization vector - random bits and then 4 bytes clear text size at the end*/
> +   temp = sizeof(UINT32);
> +   ivlen = BLKSZ - temp;
> +   tpm_get_extern_random_bytes(iv, ivlen);
> +   ivptr = iv + ivlen;
> +   tpm_marshal_UINT32(&ivptr, &temp, (UINT32) clear_len);
> +
> +   /*The clear text needs to be padded out to a multiple of BLKSZ */
> +   mod = clear_len % BLKSZ;
> +   clen = mod ? clear_len + BLKSZ - mod : clear_len;
> +   clbuf = malloc(clen);
> +   if (clbuf == NULL) {
> +      rc = -1;
> +      goto abort_egress;
> +   }
> +   memcpy(clbuf, clear, clear_len);
> +   /* zero out the padding bits - FIXME: better / more secure way to handle these? */
> +   if(clen - clear_len) {
> +      memset(clbuf + clear_len, 0, clen - clear_len);
> +   }
> +
> +   /* Setup the ciphertext buffer */
> +   *cipher_len = BLKSZ + clen;         /*iv + ciphertext */
> +   cptr = *cipher = malloc(*cipher_len);
> +   if (*cipher == NULL) {
> +      rc = -1;
> +      goto abort_egress;
> +   }
> +
> +   /* Copy the IV to cipher text blob*/
> +   memcpy(cptr, iv, BLKSZ);
> +   cptr += BLKSZ;
> +
> +   /* Setup encryption */
> +   aes_setkey_enc(&aes_ctx, symkey, 256);
> +
> +   /* Do encryption now */
> +   aes_crypt_cbc(&aes_ctx, AES_ENCRYPT, clen, iv, clbuf, cptr);
> +
> +   goto egress;
> +abort_egress:
> +egress:
> +   free(clbuf);
> +   return rc;
> +}
> +int decrypt_vtpmblk(uint8_t* cipher, size_t cipher_len, uint8_t**
> +clear, size_t* clear_len, uint8_t* symkey) {
> +   int rc = 0;
> +   uint8_t iv[BLKSZ];
> +   uint8_t* ivptr;
> +   UINT32 u32, temp;
> +   aes_context aes_ctx;
> +
> +   uint8_t* cptr = cipher;     //cipher block pointer
> +   int clen = cipher_len;      //cipher block length
> +
> +   /* Pull out the initialization vector */
> +   memcpy(iv, cipher, BLKSZ);
> +   cptr += BLKSZ;
> +   clen -= BLKSZ;
> +
> +   /* Setup the clear text buffer */
> +   if((*clear = malloc(clen)) == NULL) {
> +      rc = -1;
> +      goto abort_egress;
> +   }
> +
> +   /* Get the length of clear text from last 4 bytes of iv */
> +   temp = sizeof(UINT32);
> +   ivptr = iv + BLKSZ - temp;
> +   tpm_unmarshal_UINT32(&ivptr, &temp, &u32);
> +   *clear_len = u32;
> +
> +   /* Setup decryption */
> +   aes_setkey_dec(&aes_ctx, symkey, 256);
> +
> +   /* Do decryption now */
> +   if ((clen % BLKSZ) != 0) {
> +      error("Decryption Error: Cipher block size was not a multiple of %u", BLKSZ);
> +      rc = -1;
> +      goto abort_egress;
> +   }
> +   aes_crypt_cbc(&aes_ctx, AES_DECRYPT, clen, iv, cptr, *clear);
> +
> +   goto egress;
> +abort_egress:
> +egress:
> +   return rc;
> +}
> +
> +int write_vtpmblk(struct tpmfront_dev* tpmfront_dev, uint8_t* data, size_t data_length) {
> +   int rc;
> +   uint8_t* cipher = NULL;
> +   size_t cipher_len = 0;
> +   uint8_t hashkey[HASHKEYSZ];
> +   uint8_t* symkey = hashkey + HASHSZ;
> +
> +   /* Encrypt the data */
> +   if((rc = encrypt_vtpmblk(data, data_length, &cipher, &cipher_len, symkey))) {
> +      goto abort_egress;
> +   }
> +   /* Write to disk */
> +   if((rc = write_vtpmblk_raw(cipher, cipher_len))) {
> +      goto abort_egress;
> +   }
> +   /* Get sha1 hash of data */
> +   sha1(cipher, cipher_len, hashkey);
> +
> +   /* Send hash and key to manager */
> +   if((rc = VTPM_SaveHashKey(tpmfront_dev, hashkey, HASHKEYSZ)) != TPM_SUCCESS) {
> +      goto abort_egress;
> +   }
> +   goto egress;
> +abort_egress:
> +egress:
> +   free(cipher);
> +   return rc;
> +}
> +
> +int read_vtpmblk(struct tpmfront_dev* tpmfront_dev, uint8_t** data, size_t *data_length) {
> +   int rc;
> +   uint8_t* cipher = NULL;
> +   size_t cipher_len = 0;
> +   size_t keysize;
> +   uint8_t* hashkey = NULL;
> +   uint8_t hash[HASHSZ];
> +   uint8_t* symkey;
> +
> +   /* Retreive the hash and the key from the manager */
> +   if((rc = VTPM_LoadHashKey(tpmfront_dev, &hashkey, &keysize)) != TPM_SUCCESS) {
> +      goto abort_egress;
> +   }
> +   if(keysize != HASHKEYSZ) {
> +      error("Manager returned a hashkey of invalid size! expected %d, actual %d", NVMKEYSZ, keysize);
> +      rc = -1;
> +      goto abort_egress;
> +   }
> +   symkey = hashkey + HASHSZ;
> +
> +   /* Read from disk now */
> +   if((rc = read_vtpmblk_raw(&cipher, &cipher_len))) {
> +      goto abort_egress;
> +   }
> +
> +   /* Compute the hash of the cipher text and compare */
> +   sha1(cipher, cipher_len, hash);
> +   if(memcmp(hash, hashkey, HASHSZ)) {
> +      int i;
> +      error("NVM Storage Checksum failed!");
> +      printf("Expected: ");
> +      for(i = 0; i < HASHSZ; ++i) {
> +        printf("%02hhX ", hashkey[i]);
> +      }
> +      printf("\n");
> +      printf("Actual:   ");
> +      for(i = 0; i < HASHSZ; ++i) {
> +        printf("%02hhX ", hash[i]);
> +      }
> +      printf("\n");
> +      rc = -1;
> +      goto abort_egress;
> +   }
> +
> +   /* Decrypt the blob */
> +   if((rc = decrypt_vtpmblk(cipher, cipher_len, data, data_length, symkey))) {
> +      goto abort_egress;
> +   }
> +   goto egress;
> +abort_egress:
> +egress:
> +   free(cipher);
> +   free(hashkey);
> +   return rc;
> +}
> diff --git a/stubdom/vtpm/vtpmblk.h b/stubdom/vtpm/vtpmblk.h new file
> mode 100644 index 0000000..282ce6a
> --- /dev/null
> +++ b/stubdom/vtpm/vtpmblk.h
> @@ -0,0 +1,31 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented
> +by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
> + * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
> + * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY,
> +FITNESS
> + * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
> + * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING
> +THE
> + * SOFTWARE.
> + */
> +
> +#ifndef NVM_H
> +#define NVM_H
> +#include <mini-os/types.h>
> +#include <xen/xen.h>
> +#include <tpmfront.h>
> +
> +#define NVMKEYSZ 32
> +#define HASHSZ 20
> +#define HASHKEYSZ (NVMKEYSZ + HASHSZ)
> +
> +int init_vtpmblk(struct tpmfront_dev* tpmfront_dev); void
> +shutdown_vtpmblk(void);
> +
> +/* Encrypts and writes data to blk device */ int write_vtpmblk(struct
> +tpmfront_dev* tpmfront_dev, uint8_t *data, size_t data_length);
> +/* Reads, Decrypts, and returns data from blk device */ int
> +read_vtpmblk(struct tpmfront_dev* tpmfront_dev, uint8_t **data,
> +size_t *data_length);
> +
> +#endif
> --
> 1.7.10.4
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [VTPM v7 6/8] Add autoconf to stubdom
  2012-12-13 12:02   ` Ian Campbell
  2012-12-13 14:15     ` Ian Jackson
@ 2012-12-13 15:15     ` Matthew Fioravante
  2012-12-13 15:23       ` Ian Campbell
  1 sibling, 1 reply; 14+ messages in thread
From: Matthew Fioravante @ 2012-12-13 15:15 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Ian Jackson, xen-devel


[-- Attachment #1.1: Type: text/plain, Size: 19756 bytes --]

On 12/13/2012 07:02 AM, Ian Campbell wrote:
> On Thu, 2012-12-06 at 18:19 +0000, Matthew Fioravante wrote:
>> Please rerun autoconf after commiting this patch
>>
>> Signed-off-by: Matthew Fioravante <matthew.fioravante@jhuapl.edu>
> This fails for me with :
>          /local/scratch/ianc/devel/committer.git/stubdom/mini-os-x86_64-caml/test.o: In function `app_main':
>          /local/scratch/ianc/devel/committer.git/extras/mini-os/test.c:511: multiple definition of `app_main'
>          /local/scratch/ianc/devel/committer.git/stubdom/mini-os-x86_64-caml/main.o:/local/scratch/ianc/devel/committer.git/extras/mini-os/main.c:187: first defined here
>          make[2]: *** [/local/scratch/ianc/devel/committer.git/stubdom/mini-os-x86_64-caml/mini-os] Error 1
>          make[2]: Leaving directory `/local/scratch/ianc/devel/committer.git/extras/mini-os'
>          make[1]: *** [caml-stubdom] Error 2
>          make[1]: Leaving directory `/local/scratch/ianc/devel/committer.git/stubdom'
>          make: *** [install-stubdom] Error 2
>
> I'm only guessing it was this patch, but it was somewhere in this
> series.
Actually it looks like caml itself is just broken. The original stubdom 
makefile did not include it as a build target but my configure.ac 
erroneously enables it by default. The multiple definition problem 
occurs because like c-stubdom its minios.cfg enables CONFIG_TEST which 
defines a main function. It also defines a main function for itself.

Patch incoming
>
> I'd already done all the autoconf faff and updated .*ignore for you
> (adding autom4te.cache, config.log and config.status as appropriate). So
> rather than resending please could you provide an incremental fix
> against:
>          git://xenbits.xen.org/people/ianc/xen-unstable.git vtpm
>
> I'll then merge that into the appropriate patch.
>
> It also occurs to me that this series introduces a little bisection blip
> where cmake will be required (i.e. from patch 3 until here). The right
> way to do this would have been to put the patch introducing autoconf at
> the start. I'm inclined to just gloss over that for now, but if you feel
> so inclined you could reorder things.
I think the easiest way to fix this is to remove vtpm from the default 
built targets in stubdom. That way if someone does does a make or a make 
install in stubdom before autoconf they won't hit the cmake dependency.


>
>> ---
>>   autogen.sh                             |    2 +
>>   config/Stubdom.mk.in                   |   45 ++++++++++++++++
>>   {tools/m4 => m4}/curses.m4             |    0
>>   m4/depends.m4                          |   15 ++++++
>>   {tools/m4 => m4}/extfs.m4              |    0
>>   {tools/m4 => m4}/features.m4           |    0
>>   {tools/m4 => m4}/fetcher.m4            |    0
>>   {tools/m4 => m4}/ocaml.m4              |    0
>>   {tools/m4 => m4}/path_or_fail.m4       |    0
>>   {tools/m4 => m4}/pkg.m4                |    0
>>   {tools/m4 => m4}/pthread.m4            |    0
>>   {tools/m4 => m4}/ptyfuncs.m4           |    0
>>   {tools/m4 => m4}/python_devel.m4       |    0
>>   {tools/m4 => m4}/python_version.m4     |    0
>>   {tools/m4 => m4}/savevar.m4            |    0
>>   {tools/m4 => m4}/set_cflags_ldflags.m4 |    0
>>   m4/stubdom.m4                          |   89 ++++++++++++++++++++++++++++++++
>>   {tools/m4 => m4}/uuid.m4               |    0
>>   stubdom/Makefile                       |   55 +++++---------------
>>   stubdom/configure.ac                   |   58 +++++++++++++++++++++
>>   tools/configure.ac                     |   28 +++++-----
>>   21 files changed, 236 insertions(+), 56 deletions(-)
>>   create mode 100644 config/Stubdom.mk.in
>>   rename {tools/m4 => m4}/curses.m4 (100%)
>>   create mode 100644 m4/depends.m4
>>   rename {tools/m4 => m4}/extfs.m4 (100%)
>>   rename {tools/m4 => m4}/features.m4 (100%)
>>   rename {tools/m4 => m4}/fetcher.m4 (100%)
>>   rename {tools/m4 => m4}/ocaml.m4 (100%)
>>   rename {tools/m4 => m4}/path_or_fail.m4 (100%)
>>   rename {tools/m4 => m4}/pkg.m4 (100%)
>>   rename {tools/m4 => m4}/pthread.m4 (100%)
>>   rename {tools/m4 => m4}/ptyfuncs.m4 (100%)
>>   rename {tools/m4 => m4}/python_devel.m4 (100%)
>>   rename {tools/m4 => m4}/python_version.m4 (100%)
>>   rename {tools/m4 => m4}/savevar.m4 (100%)
>>   rename {tools/m4 => m4}/set_cflags_ldflags.m4 (100%)
>>   create mode 100644 m4/stubdom.m4
>>   rename {tools/m4 => m4}/uuid.m4 (100%)
>>   create mode 100644 stubdom/configure.ac
>>
>> diff --git a/autogen.sh b/autogen.sh
>> index 58a71ce..ada482c 100755
>> --- a/autogen.sh
>> +++ b/autogen.sh
>> @@ -2,3 +2,5 @@
>>   cd tools
>>   autoconf
>>   autoheader
>> +cd ../stubdom
>> +autoconf
>> diff --git a/config/Stubdom.mk.in b/config/Stubdom.mk.in
>> new file mode 100644
>> index 0000000..432efd7
>> --- /dev/null
>> +++ b/config/Stubdom.mk.in
>> @@ -0,0 +1,45 @@
>> +# Prefix and install folder
>> +prefix              := @prefix@
>> +PREFIX              := $(prefix)
>> +exec_prefix         := @exec_prefix@
>> +libdir              := @libdir@
>> +LIBDIR              := $(libdir)
>> +
>> +# Path Programs
>> +CMAKE               := @CMAKE@
>> +WGET                := @WGET@ -c
>> +
>> +# A debug build of stubdom? //FIXME: Someone make this do something
>> +debug               := @debug@
>> +vtpm = @vtpm@
>> +
>> +STUBDOM_TARGETS     := @STUBDOM_TARGETS@
>> +STUBDOM_BUILD       := @STUBDOM_BUILD@
>> +STUBDOM_INSTALL     := @STUBDOM_INSTALL@
>> +
>> +ZLIB_VERSION        := @ZLIB_VERSION@
>> +ZLIB_URL            := @ZLIB_URL@
>> +
>> +LIBPCI_VERSION      := @LIBPCI_VERSION@
>> +LIBPCI_URL          := @LIBPCI_URL@
>> +
>> +NEWLIB_VERSION      := @NEWLIB_VERSION@
>> +NEWLIB_URL          := @NEWLIB_URL@
>> +
>> +LWIP_VERSION        := @LWIP_VERSION@
>> +LWIP_URL            := @LWIP_URL@
>> +
>> +GRUB_VERSION        := @GRUB_VERSION@
>> +GRUB_URL            := @GRUB_URL@
>> +
>> +OCAML_VERSION       := @OCAML_VERSION@
>> +OCAML_URL           := @OCAML_URL@
>> +
>> +GMP_VERSION         := @GMP_VERSION@
>> +GMP_URL             := @GMP_URL@
>> +
>> +POLARSSL_VERSION    := @POLARSSL_VERSION@
>> +POLARSSL_URL        := @POLARSSL_URL@
>> +
>> +TPMEMU_VERSION      := @TPMEMU_VERSION@
>> +TPMEMU_URL          := @TPMEMU_URL@
>> diff --git a/tools/m4/curses.m4 b/m4/curses.m4
>> similarity index 100%
>> rename from tools/m4/curses.m4
>> rename to m4/curses.m4
>> diff --git a/m4/depends.m4 b/m4/depends.m4
>> new file mode 100644
>> index 0000000..916e665
>> --- /dev/null
>> +++ b/m4/depends.m4
>> @@ -0,0 +1,15 @@
>> +
>> +AC_DEFUN([AX_DEPENDS_PATH_PROG], [
>> +AS_IF([test "x$$1" = "xy"], [AX_PATH_PROG_OR_FAIL([$2], [$3])], [
>> +AS_IF([test "x$$1" = "xn"], [
>> +$2="/$3-disabled-in-configure-script"
>> +], [
>> +AC_PATH_PROG([$2], [$3], [no])
>> +AS_IF([test x"${$2}" = "xno"], [
>> +$1=n
>> +$2="/$3-disabled-in-configure-script"
>> +])
>> +])
>> +])
>> +AC_SUBST($2)
>> +])
>> diff --git a/tools/m4/extfs.m4 b/m4/extfs.m4
>> similarity index 100%
>> rename from tools/m4/extfs.m4
>> rename to m4/extfs.m4
>> diff --git a/tools/m4/features.m4 b/m4/features.m4
>> similarity index 100%
>> rename from tools/m4/features.m4
>> rename to m4/features.m4
>> diff --git a/tools/m4/fetcher.m4 b/m4/fetcher.m4
>> similarity index 100%
>> rename from tools/m4/fetcher.m4
>> rename to m4/fetcher.m4
>> diff --git a/tools/m4/ocaml.m4 b/m4/ocaml.m4
>> similarity index 100%
>> rename from tools/m4/ocaml.m4
>> rename to m4/ocaml.m4
>> diff --git a/tools/m4/path_or_fail.m4 b/m4/path_or_fail.m4
>> similarity index 100%
>> rename from tools/m4/path_or_fail.m4
>> rename to m4/path_or_fail.m4
>> diff --git a/tools/m4/pkg.m4 b/m4/pkg.m4
>> similarity index 100%
>> rename from tools/m4/pkg.m4
>> rename to m4/pkg.m4
>> diff --git a/tools/m4/pthread.m4 b/m4/pthread.m4
>> similarity index 100%
>> rename from tools/m4/pthread.m4
>> rename to m4/pthread.m4
>> diff --git a/tools/m4/ptyfuncs.m4 b/m4/ptyfuncs.m4
>> similarity index 100%
>> rename from tools/m4/ptyfuncs.m4
>> rename to m4/ptyfuncs.m4
>> diff --git a/tools/m4/python_devel.m4 b/m4/python_devel.m4
>> similarity index 100%
>> rename from tools/m4/python_devel.m4
>> rename to m4/python_devel.m4
>> diff --git a/tools/m4/python_version.m4 b/m4/python_version.m4
>> similarity index 100%
>> rename from tools/m4/python_version.m4
>> rename to m4/python_version.m4
>> diff --git a/tools/m4/savevar.m4 b/m4/savevar.m4
>> similarity index 100%
>> rename from tools/m4/savevar.m4
>> rename to m4/savevar.m4
>> diff --git a/tools/m4/set_cflags_ldflags.m4 b/m4/set_cflags_ldflags.m4
>> similarity index 100%
>> rename from tools/m4/set_cflags_ldflags.m4
>> rename to m4/set_cflags_ldflags.m4
>> diff --git a/m4/stubdom.m4 b/m4/stubdom.m4
>> new file mode 100644
>> index 0000000..0bf0d2c
>> --- /dev/null
>> +++ b/m4/stubdom.m4
>> @@ -0,0 +1,89 @@
>> +AC_DEFUN([AX_STUBDOM_DEFAULT_ENABLE], [
>> +AC_ARG_ENABLE([$1],
>> +AS_HELP_STRING([--disable-$1], [Build and install $1 (default is ENABLED)]),[
>> +AX_STUBDOM_INTERNAL([$1], [$2])
>> +],[
>> +AX_ENABLE_STUBDOM([$1], [$2])
>> +])
>> +AC_SUBST([$2])
>> +])
>> +
>> +AC_DEFUN([AX_STUBDOM_DEFAULT_DISABLE], [
>> +AC_ARG_ENABLE([$1],
>> +AS_HELP_STRING([--enable-$1], [Build and install $1 (default is DISABLED)]),[
>> +AX_STUBDOM_INTERNAL([$1], [$2])
>> +],[
>> +AX_DISABLE_STUBDOM([$1], [$2])
>> +])
>> +AC_SUBST([$2])
>> +])
>> +
>> +AC_DEFUN([AX_STUBDOM_CONDITIONAL], [
>> +AC_ARG_ENABLE([$1],
>> +AS_HELP_STRING([--enable-$1], [Build and install $1]),[
>> +AX_STUBDOM_INTERNAL([$1], [$2])
>> +])
>> +])
>> +
>> +AC_DEFUN([AX_STUBDOM_CONDITIONAL_FINISH], [
>> +AS_IF([test "x$$2" = "xy" || test "x$$2" = "x"], [
>> +AX_ENABLE_STUBDOM([$1],[$2])
>> +],[
>> +AX_DISABLE_STUBDOM([$1],[$2])
>> +])
>> +AC_SUBST([$2])
>> +])
>> +
>> +AC_DEFUN([AX_ENABLE_STUBDOM], [
>> +$2=y
>> +STUBDOM_TARGETS="$STUBDOM_TARGETS $2"
>> +STUBDOM_BUILD="$STUBDOM_BUILD $1"
>> +STUBDOM_INSTALL="$STUBDOM_INSTALL install-$2"
>> +])
>> +
>> +AC_DEFUN([AX_DISABLE_STUBDOM], [
>> +$2=n
>> +])
>> +
>> +dnl Don't call this outside of this file
>> +AC_DEFUN([AX_STUBDOM_INTERNAL], [
>> +AS_IF([test "x$enableval" = "xyes"], [
>> +AX_ENABLE_STUBDOM([$1], [$2])
>> +],[
>> +AS_IF([test "x$enableval" = "xno"],[
>> +AX_DISABLE_STUBDOM([$1], [$2])
>> +])
>> +])
>> +])
>> +
>> +AC_DEFUN([AX_STUBDOM_FINISH], [
>> +AC_SUBST(STUBDOM_TARGETS)
>> +AC_SUBST(STUBDOM_BUILD)
>> +AC_SUBST(STUBDOM_INSTALL)
>> +echo "Will build the following stub domains:"
>> +for x in $STUBDOM_BUILD; do
>> +       echo "  $x"
>> +done
>> +])
>> +
>> +AC_DEFUN([AX_STUBDOM_LIB], [
>> +AC_ARG_VAR([$1_URL], [Download url for $2])
>> +AS_IF([test "x$$1_URL" = "x"], [
>> +       AS_IF([test "x$extfiles" = "xy"],
>> +               [$1_URL=\@S|@\@{:@XEN_EXTFILES_URL\@:}@],
>> +               [$1_URL="$4"])
>> +       ])
>> +$1_VERSION="$3"
>> +AC_SUBST($1_URL)
>> +AC_SUBST($1_VERSION)
>> +])
>> +
>> +AC_DEFUN([AX_STUBDOM_LIB_NOEXT], [
>> +AC_ARG_VAR([$1_URL], [Download url for $2])
>> +AS_IF([test "x$$1_URL" = "x"], [
>> +       $1_URL="$4"
>> +       ])
>> +$1_VERSION="$3"
>> +AC_SUBST($1_URL)
>> +AC_SUBST($1_VERSION)
>> +])
>> diff --git a/tools/m4/uuid.m4 b/m4/uuid.m4
>> similarity index 100%
>> rename from tools/m4/uuid.m4
>> rename to m4/uuid.m4
>> diff --git a/stubdom/Makefile b/stubdom/Makefile
>> index fc70d88..709b71e 100644
>> --- a/stubdom/Makefile
>> +++ b/stubdom/Makefile
>> @@ -6,44 +6,7 @@ export XEN_OS=MiniOS
>>   export stubdom=y
>>   export debug=y
>>   include $(XEN_ROOT)/Config.mk
>> -
>> -#ZLIB_URL?=http://www.zlib.net
>> -ZLIB_URL=$(XEN_EXTFILES_URL)
>> -ZLIB_VERSION=1.2.3
>> -
>> -#LIBPCI_URL?=http://www.kernel.org/pub/software/utils/pciutils
>> -LIBPCI_URL?=$(XEN_EXTFILES_URL)
>> -LIBPCI_VERSION=2.2.9
>> -
>> -#NEWLIB_URL?=ftp://sources.redhat.com/pub/newlib
>> -NEWLIB_URL?=$(XEN_EXTFILES_URL)
>> -NEWLIB_VERSION=1.16.0
>> -
>> -#LWIP_URL?=http://download.savannah.gnu.org/releases/lwip
>> -LWIP_URL?=$(XEN_EXTFILES_URL)
>> -LWIP_VERSION=1.3.0
>> -
>> -#GRUB_URL?=http://alpha.gnu.org/gnu/grub
>> -GRUB_URL?=$(XEN_EXTFILES_URL)
>> -GRUB_VERSION=0.97
>> -
>> -#OCAML_URL?=$(XEN_EXTFILES_URL)
>> -OCAML_URL?=http://caml.inria.fr/pub/distrib/ocaml-3.11
>> -OCAML_VERSION=3.11.0
>> -
>> -GMP_VERSION=4.3.2
>> -GMP_URL?=$(XEN_EXTFILES_URL)
>> -#GMP_URL?=ftp://ftp.gmplib.org/pub/gmp-$(GMP_VERSION)
>> -
>> -POLARSSL_VERSION=1.1.4
>> -POLARSSL_URL?=$(XEN_EXTFILES_URL)
>> -#POLARSSL_URL?=http://polarssl.org/code/releases
>> -
>> -TPMEMU_VERSION=0.7.4
>> -TPMEMU_URL?=$(XEN_EXTFILES_URL)
>> -#TPMEMU_URL?=http://download.berlios.de/tpm-emulator
>> -
>> -WGET=wget -c
>> +-include $(XEN_ROOT)/config/Stubdom.mk
>>
>>   GNU_TARGET_ARCH:=$(XEN_TARGET_ARCH)
>>   ifeq ($(XEN_TARGET_ARCH),x86_32)
>> @@ -86,12 +49,12 @@ TARGET_CPPFLAGS += -I$(XEN_ROOT)/xen/include
>>
>>   TARGET_LDFLAGS += -nostdlib -L$(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/lib
>>
>> -TARGETS=ioemu c caml grub xenstore vtpm vtpmmgr
>> +TARGETS=$(STUBDOM_TARGETS)
>>
>>   .PHONY: all
>>   all: build
>>   ifeq ($(STUBDOM_SUPPORTED),1)
>> -build: genpath ioemu-stubdom c-stubdom pv-grub xenstore-stubdom vtpm-stubdom vtpmmgrdom
>> +build: genpath $(STUBDOM_BUILD)
>>   else
>>   build: genpath
>>   endif
>> @@ -245,7 +208,7 @@ tpm_emulator-$(XEN_TARGET_ARCH): tpm_emulator-$(TPMEMU_VERSION).tar.gz
>>          mv tpm_emulator-$(TPMEMU_VERSION) $@
>>          patch -d $@ -p1 < tpmemu-$(TPMEMU_VERSION).patch;
>>          mkdir $@/build
>> -       cd $@/build; cmake .. -DCMAKE_C_COMPILER=${CC} -DCMAKE_C_FLAGS="-std=c99 -DTPM_NO_EXTERN $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-declaration-after-statement"
>> +       cd $@/build; $(CMAKE) .. -DCMAKE_C_COMPILER=${CC} -DCMAKE_C_FLAGS="-std=c99 -DTPM_NO_EXTERN $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-declaration-after-statement"
>>          touch $@
>>
>>   TPMEMU_STAMPFILE=$(CROSS_ROOT)/$(GNU_TARGET_ARCH)-xen-elf/lib/libtpm.a
>> @@ -483,7 +446,7 @@ xenstore-stubdom: mini-os-$(XEN_TARGET_ARCH)-xenstore libxc xenstore
>>   #########
>>
>>   ifeq ($(STUBDOM_SUPPORTED),1)
>> -install: genpath install-readme install-ioemu install-grub install-xenstore install-vtpm install-vtpmmgr
>> +install: genpath install-readme $(STUBDOM_INSTALL)
>>   else
>>   install: genpath
>>   endif
>> @@ -503,6 +466,8 @@ install-grub: pv-grub
>>          $(INSTALL_DIR) "$(DESTDIR)$(XENFIRMWAREDIR)"
>>          $(INSTALL_DATA) mini-os-$(XEN_TARGET_ARCH)-grub/mini-os.gz "$(DESTDIR)$(XENFIRMWAREDIR)/pv-grub-$(XEN_TARGET_ARCH).gz"
>>
>> +install-caml: caml-stubdom
>> +
>>   install-xenstore: xenstore-stubdom
>>          $(INSTALL_DIR) "$(DESTDIR)/usr/lib/xen/boot"
>>          $(INSTALL_DATA) mini-os-$(XEN_TARGET_ARCH)-xenstore/mini-os.gz "$(DESTDIR)/usr/lib/xen/boot/xenstore-stubdom.gz"
>> @@ -581,3 +546,9 @@ downloadclean: patchclean
>>
>>   .PHONY: distclean
>>   distclean: downloadclean
>> +       -rm ../config/Stubdom.mk
>> +
>> +ifeq (,$(findstring clean,$(MAKECMDGOALS)))
>> +$(XEN_ROOT)/config/Stubdom.mk:
>> +       $(error You have to run ./configure before building or installing stubdom)
>> +endif
>> diff --git a/stubdom/configure.ac b/stubdom/configure.ac
>> new file mode 100644
>> index 0000000..db44d4a
>> --- /dev/null
>> +++ b/stubdom/configure.ac
>> @@ -0,0 +1,58 @@
>> +#                                               -*- Autoconf -*-
>> +# Process this file with autoconf to produce a configure script.
>> +
>> +AC_PREREQ([2.67])
>> +AC_INIT([Xen Hypervisor Stub Domains], m4_esyscmd([../version.sh ../xen/Makefile]),
>> +    [xen-devel@lists.xen.org], [xen], [http://www.xen.org/])
>> +AC_CONFIG_SRCDIR([../extras/mini-os/kernel.c])
>> +AC_CONFIG_FILES([../config/Stubdom.mk])
>> +AC_PREFIX_DEFAULT([/usr])
>> +AC_CONFIG_AUX_DIR([../])
>> +
>> +# M4 Macro includes
>> +m4_include([../m4/stubdom.m4])
>> +m4_include([../m4/features.m4])
>> +m4_include([../m4/path_or_fail.m4])
>> +m4_include([../m4/depends.m4])
>> +
>> +# Enable/disable stub domains
>> +AX_STUBDOM_DEFAULT_ENABLE([ioemu-stubdom], [ioemu])
>> +AX_STUBDOM_DEFAULT_DISABLE([c-stubdom], [c])
>> +AX_STUBDOM_DEFAULT_ENABLE([caml-stubdom], [caml])
>> +AX_STUBDOM_DEFAULT_ENABLE([pv-grub], [grub])
>> +AX_STUBDOM_DEFAULT_ENABLE([xenstore-stubdom], [xenstore])
>> +AX_STUBDOM_CONDITIONAL([vtpm-stubdom], [vtpm])
>> +AX_STUBDOM_CONDITIONAL([vtpmmgrdom], [vtpmmgr])
>> +
>> +AX_ARG_DEFAULT_ENABLE([debug], [Disable debug build of stubdom])
>> +AX_ARG_DEFAULT_ENABLE([extfiles], [Use xen extfiles repository for libraries])
>> +
>> +AC_ARG_VAR([CMAKE], [Path to the cmake program])
>> +AC_ARG_VAR([WGET], [Path to wget program])
>> +
>> +# Checks for programs.
>> +AC_PROG_CC
>> +AC_PROG_MAKE_SET
>> +AC_PROG_INSTALL
>> +AX_PATH_PROG_OR_FAIL([WGET], [wget])
>> +
>> +# Checks for programs that depend on a feature
>> +AX_DEPENDS_PATH_PROG([vtpm], [CMAKE], [cmake])
>> +
>> +# Stubdom libraries version and url setup
>> +AX_STUBDOM_LIB([ZLIB], [zlib], [1.2.3], [http://www.zlib.net])
>> +AX_STUBDOM_LIB([LIBPCI], [libpci], [2.2.9], [http://www.kernel.org/pub/software/utils/pciutils])
>> +AX_STUBDOM_LIB([NEWLIB], [newlib], [1.16.0], [ftp://sources.redhat.com/pub/newlib])
>> +AX_STUBDOM_LIB([LWIP], [lwip], [1.3.0], [http://download.savannah.gnu.org/releases/lwip])
>> +AX_STUBDOM_LIB([GRUB], [grub], [0.97], [http://alpha.gnu.org/gnu/grub])
>> +AX_STUBDOM_LIB_NOEXT([OCAML], [ocaml], [3.11.0], [http://caml.inria.fr/pub/distrib/ocaml-3.11])
>> +AX_STUBDOM_LIB([GMP], [libgmp], [4.3.2], [ftp://ftp.gmplib.org/pub/gmp-4.3.2])
>> +AX_STUBDOM_LIB([POLARSSL], [polarssl], [1.1.4], [http://polarssl.org/code/releases])
>> +AX_STUBDOM_LIB([TPMEMU], [berlios tpm emulator], [0.7.4], [http://download.berlios.de/tpm-emulator])
>> +
>> +#Conditionally enable these stubdoms based on the presense of dependencies
>> +AX_STUBDOM_CONDITIONAL_FINISH([vtpm-stubdom], [vtpm])
>> +AX_STUBDOM_CONDITIONAL_FINISH([vtpmmgrdom], [vtpmmgr])
>> +
>> +AX_STUBDOM_FINISH
>> +AC_OUTPUT()
>> diff --git a/tools/configure.ac b/tools/configure.ac
>> index 586313d..971e3e9 100644
>> --- a/tools/configure.ac
>> +++ b/tools/configure.ac
>> @@ -22,20 +22,20 @@ APPEND_INCLUDES and APPEND_LIB instead when possible.])
>>   AC_CANONICAL_HOST
>>
>>   # M4 Macro includes
>> -m4_include([m4/savevar.m4])
>> -m4_include([m4/features.m4])
>> -m4_include([m4/path_or_fail.m4])
>> -m4_include([m4/python_version.m4])
>> -m4_include([m4/python_devel.m4])
>> -m4_include([m4/ocaml.m4])
>> -m4_include([m4/set_cflags_ldflags.m4])
>> -m4_include([m4/uuid.m4])
>> -m4_include([m4/pkg.m4])
>> -m4_include([m4/curses.m4])
>> -m4_include([m4/pthread.m4])
>> -m4_include([m4/ptyfuncs.m4])
>> -m4_include([m4/extfs.m4])
>> -m4_include([m4/fetcher.m4])
>> +m4_include([../m4/savevar.m4])
>> +m4_include([../m4/features.m4])
>> +m4_include([../m4/path_or_fail.m4])
>> +m4_include([../m4/python_version.m4])
>> +m4_include([../m4/python_devel.m4])
>> +m4_include([../m4/ocaml.m4])
>> +m4_include([../m4/set_cflags_ldflags.m4])
>> +m4_include([../m4/uuid.m4])
>> +m4_include([../m4/pkg.m4])
>> +m4_include([../m4/curses.m4])
>> +m4_include([../m4/pthread.m4])
>> +m4_include([../m4/ptyfuncs.m4])
>> +m4_include([../m4/extfs.m4])
>> +m4_include([../m4/fetcher.m4])
>>
>>   # Enable/disable options
>>   AX_ARG_DEFAULT_DISABLE([githttp], [Download GIT repositories via HTTP])
>> --
>> 1.7.10.4
>>
>



[-- Attachment #1.2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 1459 bytes --]

[-- Attachment #2: Type: text/plain, Size: 126 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [VTPM v7 6/8] Add autoconf to stubdom
  2012-12-13 15:15     ` Matthew Fioravante
@ 2012-12-13 15:23       ` Ian Campbell
  0 siblings, 0 replies; 14+ messages in thread
From: Ian Campbell @ 2012-12-13 15:23 UTC (permalink / raw)
  To: Matthew Fioravante; +Cc: Ian Jackson, xen-devel

On Thu, 2012-12-13 at 15:15 +0000, Matthew Fioravante wrote:
> On 12/13/2012 07:02 AM, Ian Campbell wrote:
> > On Thu, 2012-12-06 at 18:19 +0000, Matthew Fioravante wrote:
> >> Please rerun autoconf after commiting this patch
> >>
> >> Signed-off-by: Matthew Fioravante <matthew.fioravante@jhuapl.edu>
> > This fails for me with :
> >          /local/scratch/ianc/devel/committer.git/stubdom/mini-os-x86_64-caml/test.o: In function `app_main':
> >          /local/scratch/ianc/devel/committer.git/extras/mini-os/test.c:511: multiple definition of `app_main'
> >          /local/scratch/ianc/devel/committer.git/stubdom/mini-os-x86_64-caml/main.o:/local/scratch/ianc/devel/committer.git/extras/mini-os/main.c:187: first defined here
> >          make[2]: *** [/local/scratch/ianc/devel/committer.git/stubdom/mini-os-x86_64-caml/mini-os] Error 1
> >          make[2]: Leaving directory `/local/scratch/ianc/devel/committer.git/extras/mini-os'
> >          make[1]: *** [caml-stubdom] Error 2
> >          make[1]: Leaving directory `/local/scratch/ianc/devel/committer.git/stubdom'
> >          make: *** [install-stubdom] Error 2
> >
> > I'm only guessing it was this patch, but it was somewhere in this
> > series.
> Actually it looks like caml itself is just broken. The original stubdom 
> makefile did not include it as a build target but my configure.ac 
> erroneously enables it by default. The multiple definition problem 
> occurs because like c-stubdom its minios.cfg enables CONFIG_TEST which 
> defines a main function. It also defines a main function for itself.
> 
> Patch incoming

Thanks.
> > I'd already done all the autoconf faff and updated .*ignore for you
> > (adding autom4te.cache, config.log and config.status as appropriate). So
> > rather than resending please could you provide an incremental fix
> > against:
> >          git://xenbits.xen.org/people/ianc/xen-unstable.git vtpm
> >
> > I'll then merge that into the appropriate patch.
> >
> > It also occurs to me that this series introduces a little bisection blip
> > where cmake will be required (i.e. from patch 3 until here). The right
> > way to do this would have been to put the patch introducing autoconf at
> > the start. I'm inclined to just gloss over that for now, but if you feel
> > so inclined you could reorder things.
> I think the easiest way to fix this is to remove vtpm from the default 
> built targets in stubdom. That way if someone does does a make or a make 
> install in stubdom before autoconf they won't hit the cmake dependency.

You mean drop this hunk from "vtpm/vtpmmgr and required libs to
stubdom/Makefile":
@@ -74,12 +86,12 @@ TARGET_CPPFLAGS += -I$(XEN_ROOT)/xen/include

 TARGET_LDFLAGS += -nostdlib -L$(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/lib

-TARGETS=ioemu c caml grub xenstore
+TARGETS=ioemu c caml grub xenstore vtpm vtpmmgr

and re-do it later? That would work. I'd prefer to re-add it in a
completely new patch at the end rather than conflating this with the
autoconf switch.

Ian.

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2012-12-13 15:23 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-12-06 18:19 [VTPM v7 1/8] add vtpm-stubdom code Matthew Fioravante
2012-12-06 18:19 ` [VTPM v7 2/8] add stubdom/vtpmmgr code Matthew Fioravante
2012-12-06 18:19 ` [VTPM v7 3/8] vtpm/vtpmmgr and required libs to stubdom/Makefile Matthew Fioravante
2012-12-06 18:19 ` [VTPM v7 4/8] Add vtpm documentation Matthew Fioravante
2012-12-06 18:19 ` [VTPM v7 5/8] Add cmake dependency to README Matthew Fioravante
2012-12-06 18:19 ` [VTPM v7 6/8] Add autoconf to stubdom Matthew Fioravante
2012-12-13 12:02   ` Ian Campbell
2012-12-13 14:15     ` Ian Jackson
2012-12-13 15:15     ` Matthew Fioravante
2012-12-13 15:23       ` Ian Campbell
2012-12-06 18:19 ` [VTPM v7 7/8] Add a top level configure script Matthew Fioravante
2012-12-06 18:19 ` [VTPM v7 8/8] Add conditional build of subsystems to configure.ac Matthew Fioravante
2012-12-13 11:48 ` [VTPM v7 1/8] add vtpm-stubdom code Ian Campbell
2012-12-13 14:55   ` Fioravante, Matthew E.

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.