[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH vtpm_manager 1/2] Updates and bug fixes to vtpm_manager



The following patch contains a major set of bug fixes and feature
enhancements to vtpm_manager.

vtpm_manager was previously riddled with memory leaks, race conditions,
IO deadlocks, and other assorted bugs.

This patch fixes numerous bugs in vtpm manager and also adds new
functionality for supporting vtpm stub domains. 

It adds a new program (vtpmmgrtalk) that is used by the hotplug script
fixes (next patch) to avoid IO deadlocks with pipes.

Finally, it also breaks the compilation of vtpm_manager into separate
static libraries, which are then used later by the vtpmmgrdom stub domain.

Signed of by: Matthew Fioravante matthew.fioravante@xxxxxxxxxx

diff --git a/tools/vtpm_manager/Makefile b/tools/vtpm_manager/Makefile
--- a/tools/vtpm_manager/Makefile
+++ b/tools/vtpm_manager/Makefile
@@ -1,9 +1,9 @@
-XEN_ROOT = $(CURDIR)/../..
+XEN_ROOT = $(realpath ../..)
 
 # Base definitions and rules
-include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
+include Rules.mk
 
-SUBDIRS        = crypto tcs util manager migration
+SUBDIRS        = crypto tcs util manager migration vtpmmgrtalk vtpmconnd
 OPENSSL_HEADER    = /usr/include/openssl/crypto.h
 
 .PHONY: all clean install
diff --git a/tools/vtpm_manager/README b/tools/vtpm_manager/README
--- a/tools/vtpm_manager/README
+++ b/tools/vtpm_manager/README
@@ -43,9 +43,6 @@ Compile Flags
 LOGGING_MODULES              -> How extensive logging happens
                                 see util/log.h for more info
 
-VTPM_MULTI_VM                -> Defined: VTPMs run in their own VMs
-                                Not Defined (default): VTPMs are processes
-
 # Debugging flags that may disappear without notice in the future
 
 DUMMY_BACKEND                -> vtpm_manager listens on /tmp/in.fifo and
@@ -59,6 +56,10 @@ WELL_KNOWN_OWNER_AUTH        -> Rather than randomly
generating the password for
                                 lost. However this has no protection
from malicious app
                                 issuing a TPM_OwnerClear to wipe the TPM
 
+VTPM_STUBDOM             -> vtpm_manager runs in vtpm_stubdom mode with
+                vtpm instances running in mini-os domains
+                (see: stubdom/vtpm/README for details)
+
 Requirements
 ============
 - xen-unstable
diff --git a/tools/vtpm_manager/Rules.mk b/tools/vtpm_manager/Rules.mk
--- a/tools/vtpm_manager/Rules.mk
+++ b/tools/vtpm_manager/Rules.mk
@@ -6,7 +6,7 @@ include $(XEN_ROOT)/tools/Rules.mk
 #
 
 # General compiler flags
-CFLAGS    = -Werror -g3
+CFLAGS    = -Werror -g3 -I.
 
 # Generic project files
 HDRS    = $(wildcard *.h)
@@ -31,18 +31,18 @@ $(OBJS): $(SRCS)
 CFLAGS += -D_GNU_SOURCE
 
 # Logging Level. See utils/tools.h for usage
-CFLAGS +=
-DLOGGING_MODULES="(BITMASK(VTPM_LOG_TCS)|BITMASK(VTPM_LOG_VTSP)|BITMASK(VTPM_LOG_VTPM))"
+#CFLAGS +=
-DLOGGING_MODULES="(BITMASK(VTPM_LOG_TCS)|BITMASK(VTPM_LOG_VTSP)|BITMASK(VTPM_LOG_VTPM))"
 
 # Silent Mode
 #CFLAGS += -DLOGGING_MODULES=0x0
-#CFLAGS += -DLOGGING_MODULES=0xff
-
-# Use frontend/backend pairs between manager & DMs?
-#CFLAGS += -DVTPM_MULTI_VM
+CFLAGS += -DLOGGING_MODULES=0xff
 
 # vtpm_manager listens on fifo's rather than backend
 #CFLAGS += -DDUMMY_BACKEND
 
+# Build for use with vtpm-stubdom
+#CFLAGS += -DVTPM_STUBDOM
+
 # TCS talks to fifo's rather than /dev/tpm. TPM Emulator assumed on fifos
 #CFLAGS += -DDUMMY_TPM
 
@@ -52,8 +52,3 @@ CFLAGS +=
-DLOGGING_MODULES="(BITMASK(VTPM_LOG_TCS)|BITMASK(VTPM_LOG_VTSP)|BITMA
 # Fixed OwnerAuth
 #CFLAGS += -DWELL_KNOWN_OWNER_AUTH
 
-# Include
-CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/crypto
-CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/util
-CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/tcs
-CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/manager
diff --git a/tools/vtpm_manager/crypto/Makefile
b/tools/vtpm_manager/crypto/Makefile
--- a/tools/vtpm_manager/crypto/Makefile
+++ b/tools/vtpm_manager/crypto/Makefile
@@ -1,5 +1,9 @@
-XEN_ROOT = $(CURDIR)/../../..
-include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
+XEN_ROOT = $(realpath ../../..)
+include ../Rules.mk
+
+CFLAGS += -I../util
+CFLAGS += -I../tcs
+CFLAGS += -I../manager
 
 BIN        = libtcpaCrypto.a
 
diff --git a/tools/vtpm_manager/crypto/crypto.c
b/tools/vtpm_manager/crypto/crypto.c
--- a/tools/vtpm_manager/crypto/crypto.c
+++ b/tools/vtpm_manager/crypto/crypto.c
@@ -45,6 +45,8 @@
 #include "crypto.h"
 #include "log.h"
 
+extern const EVP_CIPHER * SYM_CIPHER;
+
 /**
  * Initialize cryptography library
  * @rand: random seed
@@ -83,6 +85,6 @@ void Crypto_GetRandom(void* data, int size) {
   result = RAND_pseudo_bytes((BYTE*) data, size);
  
   if (result <= 0)
-    vtpmlogerror (VTPM_LOG_CRYPTO, "RAND_pseudo_bytes failed: %s\n",
-         ERR_error_string (ERR_get_error(), NULL));
+    vtpmlogerror (VTPM_LOG_CRYPTO, "RAND_pseudo_bytes failed: rc=%d
errstr=%s\n",
+      result, ERR_error_string (ERR_get_error(), NULL));
 }
diff --git a/tools/vtpm_manager/crypto/crypto.h
b/tools/vtpm_manager/crypto/crypto.h
--- a/tools/vtpm_manager/crypto/crypto.h
+++ b/tools/vtpm_manager/crypto/crypto.h
@@ -76,7 +76,7 @@ typedef struct CRYPTO_INFO {
 
 void Crypto_Init(const BYTE* rand, int size);
 
-void Crypto_Exit();
+void Crypto_Exit(void);
 
 void Crypto_GetRandom(void* data, int size);
 
@@ -127,6 +127,8 @@ void Crypto_RSABuildCryptoInfoPublic(   /*[IN]*/
UINT32 pubExpSize,
                                         /*[IN]*/ BYTE *modulus,
                                         CRYPTO_INFO* cryptoInfo);
 
+void Crypto_RSACryptoInfoFree(CRYPTO_INFO* cryptoInfo);
+
 //
 // symmetric pack and unpack operations
 //
diff --git a/tools/vtpm_manager/crypto/rsa.c
b/tools/vtpm_manager/crypto/rsa.c
--- a/tools/vtpm_manager/crypto/rsa.c
+++ b/tools/vtpm_manager/crypto/rsa.c
@@ -149,6 +149,10 @@ void Crypto_RSABuildCryptoInfoPublic(   /*[IN]*/
UINT32 pubExpSize,
  
 }
 
+void Crypto_RSACryptoInfoFree(CRYPTO_INFO* cryptoInfo) {
+   RSA_free(cryptoInfo->keyInfo);
+}
+
 int Crypto_RSAEnc(  CRYPTO_INFO *key,
             UINT32 inDataSize,
             BYTE *inData,
@@ -161,6 +165,7 @@ int Crypto_RSAEnc(  CRYPTO_INFO *key,
    
   if (paddedData == NULL)
     return -1;
+  memset(paddedData, 0, sizeof(BYTE) * paddedDataSize);
 
   *outDataSize = 0;
  
diff --git a/tools/vtpm_manager/crypto/sym_crypto.c
b/tools/vtpm_manager/crypto/sym_crypto.c
--- a/tools/vtpm_manager/crypto/sym_crypto.c
+++ b/tools/vtpm_manager/crypto/sym_crypto.c
@@ -41,8 +41,16 @@
 #include <openssl/rand.h>
 
 #include "tcg.h"
+#include "log.h"
 #include "sym_crypto.h"
 
+struct symkey_t {
+  buffer_t key;
+
+  EVP_CIPHER_CTX context;
+  const EVP_CIPHER * cipher;
+};
+
 typedef enum crypt_op_type_t {
   CRYPT_ENCRYPT,
   CRYPT_DECRYPT
@@ -61,19 +69,22 @@ const EVP_CIPHER * SYM_CIPHER = NULL;
 const BYTE ZERO_IV[EVP_MAX_IV_LENGTH] = {0};
 
 
-TPM_RESULT Crypto_symcrypto_initkey (symkey_t * key, const buffer_t*
keybits) {
+TPM_RESULT Crypto_symcrypto_initkey (symkey_t ** key, const buffer_t*
keybits) {
   TPM_RESULT status = TPM_SUCCESS;
  
-  EVP_CIPHER_CTX_init (&key->context);
+  *key = malloc(sizeof(symkey_t));
+
+  EVP_CIPHER_CTX_init (&(*key)->context);
  
-  key->cipher = SYM_CIPHER;
+  (*key)->cipher = SYM_CIPHER;
  
-  TPMTRYRETURN( buffer_init_copy (&key->key, keybits));
+  TPMTRYRETURN( buffer_init_copy (&(*key)->key, keybits));
    
   goto egress;
  
  abort_egress:
-  EVP_CIPHER_CTX_cleanup (&key->context);
+  EVP_CIPHER_CTX_cleanup (&(*key)->context);
+  free(key);
  
  egress:
  
@@ -82,19 +93,21 @@ TPM_RESULT Crypto_symcrypto_initkey (symkey_t * key,
const buffer_t* keybits) {
 
 
 
-TPM_RESULT Crypto_symcrypto_genkey (symkey_t * key) {
+TPM_RESULT Crypto_symcrypto_genkey (symkey_t ** key) {
   int res;
   TPM_RESULT status = TPM_SUCCESS;
+
+  *key = malloc(sizeof(symkey_t));
  
   // hmm, EVP_CIPHER_CTX_init does not return a value
-  EVP_CIPHER_CTX_init (&key->context);
+  EVP_CIPHER_CTX_init (&(*key)->context);
  
-  key->cipher = SYM_CIPHER;
+  (*key)->cipher = SYM_CIPHER;
  
-  TPMTRYRETURN( buffer_init (&key->key,
EVP_CIPHER_key_length(key->cipher), NULL)) ;
+  TPMTRYRETURN( buffer_init (&(*key)->key,
EVP_CIPHER_key_length((*key)->cipher), NULL)) ;
  
   // and generate the key material
-  res = RAND_pseudo_bytes (key->key.bytes, key->key.size);
+  res = RAND_pseudo_bytes ((*key)->key.bytes, (*key)->key.size);
   if (res < 0)
     ERRORDIE (TPM_SHORTRANDOM);
  
@@ -102,8 +115,9 @@ TPM_RESULT Crypto_symcrypto_genkey (symkey_t * key) {
   goto egress;
  
  abort_egress:
-  EVP_CIPHER_CTX_cleanup (&key->context);
-  buffer_free (&key->key);
+  EVP_CIPHER_CTX_cleanup (&(*key)->context);
+  buffer_free (&(*key)->key);
+  free(key);
  
  egress:
   return status; 
@@ -119,11 +133,11 @@ TPM_RESULT Crypto_symcrypto_encrypt (symkey_t* key,
  
   buffer_init_const (&iv, EVP_MAX_IV_LENGTH, ZERO_IV);
  
-  buffer_init (o_cipher,
-           clear->size +
-           EVP_CIPHER_iv_length(key->cipher) +
-           EVP_CIPHER_block_size (key->cipher),
-                 0);
+  TPMTRYRETURN( buffer_init (o_cipher,
+                  clear->size +
+                  EVP_CIPHER_iv_length(key->cipher) +
+                  EVP_CIPHER_block_size (key->cipher),
+                 0) );
  
   // copy the IV into the front
   buffer_copy (o_cipher, &iv);
@@ -139,6 +153,7 @@ TPM_RESULT Crypto_symcrypto_encrypt (symkey_t* key,
   goto egress;
  
  abort_egress:
+  buffer_free(o_cipher);
  
  egress:
  
@@ -170,7 +185,7 @@ TPM_RESULT Crypto_symcrypto_decrypt (symkey_t* key,
  
   // and decrypt
   TPMTRYRETURN ( ossl_symcrypto_op (key, &cipher_alias, &iv, o_clear,
CRYPT_DECRYPT) );
- 
+
   goto egress;
  
  abort_egress:
@@ -188,6 +203,8 @@ TPM_RESULT Crypto_symcrypto_freekey (symkey_t * key) {
   buffer_free (&key->key);
  
   EVP_CIPHER_CTX_cleanup (&key->context);
+
+  free(key);
  
   return TPM_SUCCESS;
 }
@@ -235,3 +252,8 @@ TPM_RESULT ossl_symcrypto_op (symkey_t* key,
  
   return status;
 }
+
+buffer_t* Crypto_symkey_getkey(symkey_t* key)
+{
+   return &key->key;
+}
diff --git a/tools/vtpm_manager/crypto/sym_crypto.h
b/tools/vtpm_manager/crypto/sym_crypto.h
--- a/tools/vtpm_manager/crypto/sym_crypto.h
+++ b/tools/vtpm_manager/crypto/sym_crypto.h
@@ -40,21 +40,15 @@
 #ifndef _SYM_CRYPTO_H
 #define _SYM_CRYPTO_H
 
-#include <openssl/evp.h>
 #include "buffer.h"
 
-typedef struct symkey_t {
-  buffer_t key;
- 
-  EVP_CIPHER_CTX context;
-  const EVP_CIPHER * cipher;
-} symkey_t;
+typedef struct symkey_t symkey_t;
 
-extern const EVP_CIPHER * SYM_CIPHER;
+//Allocates a symkey with random bits
+TPM_RESULT Crypto_symcrypto_genkey (symkey_t ** key);
 
-TPM_RESULT Crypto_symcrypto_genkey (symkey_t * key);
-
-TPM_RESULT Crypto_symcrypto_initkey (symkey_t * key, const buffer_t*
keybits);
+//Allocates a symkey with given keybits
+TPM_RESULT Crypto_symcrypto_initkey (symkey_t ** key, const buffer_t*
keybits);
 
 
 // these functions will allocate their output buffers
@@ -66,7 +60,10 @@ TPM_RESULT Crypto_symcrypto_decrypt (symkey_t* key,
                               const buffer_t* cipher,
                               buffer_t* o_clear);
 
-// only free the internal parts, not the 'key' ptr
+//Frees the symkey
 TPM_RESULT Crypto_symcrypto_freekey (symkey_t * key);
 
+//Get the raw key byte buffer
+buffer_t* Crypto_symkey_getkey(symkey_t* key);
+
 #endif /* _SYM_CRYPTO_H */
diff --git a/tools/vtpm_manager/manager/Makefile
b/tools/vtpm_manager/manager/Makefile
--- a/tools/vtpm_manager/manager/Makefile
+++ b/tools/vtpm_manager/manager/Makefile
@@ -1,7 +1,18 @@
-XEN_ROOT = $(CURDIR)/../../..
-include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
+XEN_ROOT = $(realpath ../../..)
+include ../Rules.mk
+
+CFLAGS += -I../crypto
+CFLAGS += -I../util
+CFLAGS += -I../tcs
+
+
+MAINS         := vtpmd.o
+MGRLIB         := libvtpmmanager.a
+VTSPOBJS    := vtsp.o
+VTSPLIB        := libvtsp.a
+BIN        := vtpm_managerd
+OBJS         := $(filter-out $(MAINS) $(VTSPOBJS), $(OBJS))
 
-BIN        = vtpm_managerd
 
 .PHONY: all
 all: build
@@ -28,8 +39,14 @@ clean:
 mrproper: clean
     rm -f *~
 
-$(BIN): $(OBJS)
-    $(CC) $(LDFLAGS) $^ $(LIBS) -o $@
+$(BIN): $(MAINS) $(MGRLIB) $(VTSPLIB)
+    $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@
+
+$(VTSPLIB): $(VTSPOBJS)
+    $(AR) rcs $@ $^
+
+$(MGRLIB): $(OBJS)
+    $(AR) rcs $@ $^
 
 # libraries
 LIBS += ../tcs/libTCS.a ../util/libTCGUtils.a ../crypto/libtcpaCrypto.a
diff --git a/tools/vtpm_manager/manager/dmictl.c
b/tools/vtpm_manager/manager/dmictl.c
--- a/tools/vtpm_manager/manager/dmictl.c
+++ b/tools/vtpm_manager/manager/dmictl.c
@@ -40,6 +40,9 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdlib.h>
 
 #include "vtpmpriv.h"
 #include "bsg.h"
@@ -51,6 +54,13 @@
 
 #define TPM_EMULATOR_PATH "/usr/bin/vtpmd"
 
+#ifndef VTPM_STUBDOM
+// This is needed to all extra_close_dmi to close this to prevent a
+// broken pipe when no DMIs are left.
+vtpm_ipc_handle_t *g_rx_tpm_ipc_h;
+#endif
+
+
 // if dmi_res is non-null, then return a pointer to new object.
 // Also, this does not fill in the measurements. They should be filled by
 // design dependent code or saveNVM
@@ -81,7 +91,7 @@ TPM_RESULT init_dmi(UINT32 dmi_id, BYTE dmi_type,
VTPM_DMI_RESOURCE **dmi_res) {
 
   // install into map
   if (!hashtable_insert(vtpm_globals->dmi_map, dmi_id_key, new_dmi)){
-    vtpmlogerror(VTPM_LOG_VTPM, "Failed to insert instance into table.
Aborting.\n", dmi_id);
+    vtpmlogerror(VTPM_LOG_VTPM, "Failed to insert instance %" PRIu32
"into table. Aborting.\n", dmi_id);
     status = TPM_FAIL;
     goto abort_egress;
   }
@@ -116,6 +126,161 @@ TPM_RESULT close_dmi(VTPM_DMI_RESOURCE *dmi_res) {
 
   return (VTPM_Close_DMI_Extra(dmi_res) );
 }
+
+void free_dmi(VTPM_DMI_RESOURCE *dmi_res) {
+   if(dmi_res != NULL) {
+      free(dmi_res->NVMLocation);
+   }
+   free(dmi_res);
+}
+
+TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res, BYTE vm_type,
BYTE startup_mode) {
+
+  TPM_RESULT status = TPM_SUCCESS;
+#ifndef VTPM_STUBDOM
+  int fh;
+  char dmi_id_str[11]; // UINT32s are up to 10 digits + NULL
+  char *tx_vtpm_name, *tx_tpm_name, *vm_type_string;
+  struct stat file_info;
+
+  if (dmi_res->dmi_id == VTPM_CTL_DM) {
+    dmi_res->tx_tpm_ipc_h = NULL;
+    dmi_res->rx_tpm_ipc_h = NULL;
+    dmi_res->tx_vtpm_ipc_h = NULL;
+    dmi_res->rx_vtpm_ipc_h = NULL;
+  } else {
+    // Create a pair of fifo pipes
+    dmi_res->rx_tpm_ipc_h = NULL;
+    dmi_res->rx_vtpm_ipc_h = NULL;
+
+    if ( ((dmi_res->tx_tpm_ipc_h = (vtpm_ipc_handle_t *) malloc
(sizeof(vtpm_ipc_handle_t))) == NULL ) ||
+         ((dmi_res->tx_vtpm_ipc_h =(vtpm_ipc_handle_t *) malloc
(sizeof(vtpm_ipc_handle_t))) == NULL ) ||
+         ((tx_tpm_name = (char *) malloc(11 +
strlen(VTPM_TX_TPM_FNAME))) == NULL ) ||
+         ((tx_vtpm_name =(char *) malloc(11 +
strlen(VTPM_TX_VTPM_FNAME))) == NULL) ) {
+      status =TPM_RESOURCES;
+      goto abort_egress;
+    }
+
+    sprintf(tx_tpm_name, VTPM_TX_TPM_FNAME, (uint32_t) dmi_res->dmi_id);
+    sprintf(tx_vtpm_name, VTPM_TX_VTPM_FNAME, (uint32_t) dmi_res->dmi_id);
+
+    if ( (vtpm_ipc_init(dmi_res->tx_tpm_ipc_h, tx_tpm_name, O_WRONLY |
O_NONBLOCK, TRUE, FALSE) != 0) ||
+         (vtpm_ipc_init(dmi_res->tx_vtpm_ipc_h, tx_vtpm_name, O_WRONLY,
TRUE, FALSE) != 0) ) { //FIXME: O_NONBLOCK?
+      status = TPM_IOERROR;
+      goto abort_egress;
+    }
+
+    // Measure DMI
+    // FIXME: This will measure DMI. Until then use a fixed
DMI_Measurement value
+    // Also, this mechanism is specific to 1 VM architecture.
+    /*
+    fh = open(TPM_EMULATOR_PATH, O_RDONLY);
+    stat_ret = fstat(fh, &file_stat);
+    if (stat_ret == 0)
+      dmi_size = file_stat.st_size;
+    else {
+      vtpmlogerror(VTPM_LOG_VTPM, "Could not open vtpmd!!\n");
+      status = TPM_IOERROR;
+      goto abort_egress;
+    }
+    dmi_buffer
+    */
+    memset(&dmi_res->DMI_measurement, 0xcc, sizeof(TPM_DIGEST));
+
+    if (vm_type == VTPM_TYPE_PVM)
+      vm_type_string = (BYTE *)&VTPM_TYPE_PVM_STRING;
+    else
+      vm_type_string = (BYTE *)&VTPM_TYPE_HVM_STRING;
+
+    // Launch DMI
+    sprintf(dmi_id_str, "%d", (int) dmi_res->dmi_id);
+#ifdef MANUAL_DM_LAUNCH
+    vtpmlogerror(VTPM_LOG_VTPM, "Manually start VTPM with dmi=%s
now.\n", dmi_id_str);
+    dmi_res->dmi_pid = 0;
+#else
+    pid_t pid = fork();
+
+    if (pid == -1) {
+      vtpmlogerror(VTPM_LOG_VTPM, "Could not fork to launch vtpm\n");
+      status = TPM_RESOURCES;
+      goto abort_egress;
+    } else if (pid == 0) {
+      switch (startup_mode) {
+      case TPM_ST_CLEAR:
+        execl (TPM_EMULATOR_PATH, "vtpmd", "clear", vm_type_string,
dmi_id_str, NULL);
+        break;
+      case TPM_ST_STATE:
+        execl (TPM_EMULATOR_PATH, "vtpmd", "save", vm_type_string,
dmi_id_str, NULL);
+        break;
+      case TPM_ST_DEACTIVATED:
+        execl (TPM_EMULATOR_PATH, "vtpmd", "deactivated",
vm_type_string, dmi_id_str, NULL);
+        break;
+      default:
+        status = TPM_BAD_PARAMETER;
+        goto abort_egress;
+      }
+
+      // Returning from these at all is an error.
+      vtpmlogerror(VTPM_LOG_VTPM, "Could not exec to launch vtpm\n");
+    } else {
+      dmi_res->dmi_pid = pid;
+      vtpmloginfo(VTPM_LOG_VTPM, "Launching DMI on PID = %d\n", pid);
+    }
+#endif // MANUAL_DM_LAUNCH
+
+  } // If DMI = VTPM_CTL_DM
+    status = TPM_SUCCESS;
+#endif
+
+abort_egress:
+    //FIXME: Everything should be freed here
+  return (status);
+}
+
+TPM_RESULT VTPM_Close_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res) {
+  TPM_RESULT status = TPM_SUCCESS;
+
+#ifndef VTPM_STUBDOM
+  if (vtpm_globals->connected_dmis == 0) {
+    // No more DMI's connected. Close fifo to prevent a broken pipe.
+    // This is hackish. Need to think of another way.
+    vtpm_ipc_close(g_rx_tpm_ipc_h);
+  }
+
+
+  if (dmi_res->dmi_id != VTPM_CTL_DM) {
+    vtpm_ipc_close(dmi_res->tx_tpm_ipc_h);
+    vtpm_ipc_close(dmi_res->tx_vtpm_ipc_h);
+
+    free(dmi_res->tx_tpm_ipc_h->name);
+    free(dmi_res->tx_vtpm_ipc_h->name);
+    free(dmi_res->tx_tpm_ipc_h);
+    free(dmi_res->tx_vtpm_ipc_h);
+
+#ifndef MANUAL_DM_LAUNCH
+    if (dmi_res->dmi_id != VTPM_CTL_DM) {
+      if (dmi_res->dmi_pid != 0) {
+        vtpmloginfo(VTPM_LOG_VTPM, "Killing dmi on pid %d.\n",
dmi_res->dmi_pid);
+        if (kill(dmi_res->dmi_pid, SIGKILL) !=0) {
+          vtpmloginfo(VTPM_LOG_VTPM, "DMI on pid %d is already
dead.\n", dmi_res->dmi_pid);
+        } else if (waitpid(dmi_res->dmi_pid, NULL, 0) !=
dmi_res->dmi_pid) {
+          vtpmlogerror(VTPM_LOG_VTPM, "DMI on pid %d failed to
stop.\n", dmi_res->dmi_pid);
+          status = TPM_FAIL;
+        }
+      } else {
+        vtpmlogerror(VTPM_LOG_VTPM, "Could not kill dmi because it's
pid was 0.\n");
+        status = TPM_FAIL;
+      }
+    }
+#endif
+
+  } //endif ! dom0
+#endif
+  return status;
+}
+
+
+
    
 TPM_RESULT VTPM_Handle_New_DMI(const buffer_t *param_buf) {
  
@@ -254,7 +419,7 @@ TPM_RESULT VTPM_Handle_Delete_DMI( const buffer_t
*param_buf) {
  
   // Close DMI first
   TPMTRYRETURN(close_dmi( dmi_res ));
-  free ( dmi_res );
+  free_dmi(dmi_res);
    
   status=TPM_SUCCESS;   
   goto egress;
diff --git a/tools/vtpm_manager/manager/migration.c
b/tools/vtpm_manager/manager/migration.c
--- a/tools/vtpm_manager/manager/migration.c
+++ b/tools/vtpm_manager/manager/migration.c
@@ -40,6 +40,7 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
+#include <stdlib.h>
 
 #include "vtpmpriv.h"
 #include "bsg.h"
@@ -263,7 +264,7 @@ TPM_RESULT VTPM_Handle_Get_Migration_key( const
buffer_t *param_buf,
 TPM_RESULT VTPM_Handle_Load_Migration_key( const buffer_t *param_buf,
                                            buffer_t *result_buf) {
 
-  TPM_RESULT status=TPM_FAIL;
+  TPM_RESULT status=TPM_SUCCESS;
   VTPM_MIGKEY_LIST *mig_key;
 
   vtpmloginfo(VTPM_LOG_VTPM, "Loading Migration Public Key.\n");
@@ -303,5 +304,5 @@ TPM_RESULT VTPM_Handle_Load_Migration_key( const
buffer_t *param_buf,
   free(pubkey_exp_pack.data);
   free(pubkey_mod_pack.data);
 
-  return TPM_SUCCESS;
+  return status;
 }
diff --git a/tools/vtpm_manager/manager/securestorage.c
b/tools/vtpm_manager/manager/securestorage.c
--- a/tools/vtpm_manager/manager/securestorage.c
+++ b/tools/vtpm_manager/manager/securestorage.c
@@ -42,7 +42,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <string.h>
-
+#include <stdlib.h>
 #include "tcg.h"
 #include "vtpm_manager.h"
 #include "vtpmpriv.h"
@@ -58,7 +58,7 @@ TPM_RESULT envelope_encrypt(const buffer_t     *inbuf,
                             CRYPTO_INFO        *asymkey,
                             buffer_t           *sealed_data) {
   TPM_RESULT status = TPM_SUCCESS;
-  symkey_t    symkey;
+  symkey_t    *symkey;
   buffer_t    data_cipher = NULL_BUF,
               symkey_cipher = NULL_BUF;
  
@@ -69,14 +69,14 @@ TPM_RESULT envelope_encrypt(const buffer_t     *inbuf,
   for (i=0; i< buffer_len(inbuf); i++)
     vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", inbuf->bytes[i]);
   vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
- 
+
   // Generate a sym key and encrypt state with it
   TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_genkey (&symkey) );
-  TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_encrypt (&symkey, inbuf,
&data_cipher) );
+  TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_encrypt (symkey, inbuf,
&data_cipher) );
  
   // Encrypt symmetric key
   TPMTRYRETURN( VTSP_Bind(    asymkey,
-                  &symkey.key,
+                  Crypto_symkey_getkey(symkey),
                   &symkey_cipher) );
  
   // Create output blob: symkey_size + symkey_cipher +
state_cipher_size + state_cipher
@@ -86,8 +86,9 @@ TPM_RESULT envelope_encrypt(const buffer_t     *inbuf,
  
   data_cipher32.size = buffer_len(&data_cipher);
   data_cipher32.data = data_cipher.bytes;
- 
+
   TPMTRYRETURN( buffer_init(sealed_data, 2 * sizeof(UINT32) +
symkey_cipher32.size + data_cipher32.size, NULL));
+  memset(sealed_data->bytes, 0, sealed_data->size);
  
   BSG_PackList(sealed_data->bytes, 2,
            BSG_TPM_SIZE32_DATA, &symkey_cipher32,
@@ -109,11 +110,37 @@ TPM_RESULT envelope_encrypt(const buffer_t     *inbuf,
  
   buffer_free ( &data_cipher);
   buffer_free ( &symkey_cipher);
-  Crypto_symcrypto_freekey (&symkey);
+  Crypto_symcrypto_freekey (symkey);
  
   return status;
 }
 
+TPM_RESULT symkey_encrypt(const buffer_t     *inbuf,
+                            CRYPTO_INFO        *asymkey,
+                            buffer_t           *sealed_key) {
+  buffer_t symkey_cipher = NULL_BUF;
+  struct pack_constbuf_t symkey_cipher32;
+  TPM_RESULT status = TPM_SUCCESS;
+
+  // Encrypt symmetric key
+  TPMTRYRETURN( VTSP_Bind(    asymkey,
+                  inbuf,
+                  &symkey_cipher));
+
+  symkey_cipher32.size = buffer_len(&symkey_cipher);
+  symkey_cipher32.data = symkey_cipher.bytes;
+
+  TPMTRYRETURN( buffer_init(sealed_key, sizeof(UINT32) +
symkey_cipher32.size, NULL));
+  BSG_PackList(sealed_key->bytes, 1,
+           BSG_TPM_SIZE32_DATA, &symkey_cipher32);
+  goto egress;
+abort_egress:
+egress:
+  buffer_free( &symkey_cipher);
+  return status;
+}
+ 
+
 TPM_RESULT envelope_decrypt(const buffer_t     *cipher,
                             TCS_CONTEXT_HANDLE TCSContext,
                 TPM_HANDLE         keyHandle,
@@ -121,15 +148,13 @@ TPM_RESULT envelope_decrypt(const buffer_t    
*cipher,
                             buffer_t           *unsealed_data) {
 
   TPM_RESULT status = TPM_SUCCESS;
-  symkey_t    symkey;
+  symkey_t    *symkey;
   buffer_t    data_cipher = NULL_BUF,
               symkey_clear = NULL_BUF,
               symkey_cipher = NULL_BUF;
-  struct pack_buf_t symkey_cipher32, data_cipher32;
+  struct pack_buf_t symkey_cipher32 = NULL_PACK_BUF, data_cipher32 =
NULL_PACK_BUF;
   int i;
 
-  memset(&symkey, 0, sizeof(symkey_t));
-
   vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Envelope Decrypt Input[%d]: 0x",
buffer_len(cipher) );
   for (i=0; i< buffer_len(cipher); i++)
     vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cipher->bytes[i]);
@@ -159,7 +184,7 @@ TPM_RESULT envelope_decrypt(const buffer_t     *cipher,
   Crypto_symcrypto_initkey (&symkey, &symkey_clear);
  
   // Decrypt State
-  TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (&symkey,
&data_cipher, unsealed_data) );
+  TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (symkey,
&data_cipher, unsealed_data) );
 
   vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Envelope Decrypte Output[%d]: 0x",
buffer_len(unsealed_data));
   for (i=0; i< buffer_len(unsealed_data); i++)
@@ -175,26 +200,64 @@ TPM_RESULT envelope_decrypt(const buffer_t    
*cipher,
   buffer_free ( &data_cipher);
   buffer_free ( &symkey_clear);
   buffer_free ( &symkey_cipher);
-  Crypto_symcrypto_freekey (&symkey);
+  BSG_Destroy(BSG_TPM_SIZE32_DATA, &symkey_cipher32);
+  BSG_Destroy(BSG_TPM_SIZE32_DATA, &data_cipher32);
+  Crypto_symcrypto_freekey (symkey);
+
  
   return status;
 }
 
+TPM_RESULT symkey_decrypt(const buffer_t     *cipher,
+                            TCS_CONTEXT_HANDLE TCSContext,
+                TPM_HANDLE         keyHandle,
+                const TPM_AUTHDATA *key_usage_auth,
+                            buffer_t           *symkey_clear) {
+
+  TPM_RESULT status = TPM_SUCCESS;
+  buffer_t    symkey_cipher = NULL_BUF;
+  struct pack_buf_t symkey_cipher32 = NULL_PACK_BUF;
+
+  BSG_UnpackList(cipher->bytes, 1,
+         BSG_TPM_SIZE32_DATA, &symkey_cipher32);
+ 
+  TPMTRYRETURN( buffer_init_alias_convert (&symkey_cipher,
+                           symkey_cipher32.size,
+                           symkey_cipher32.data) );
+ 
+  // Decrypt Symmetric Key
+  TPMTRYRETURN( VTSP_Unbind(  TCSContext,
+                  keyHandle,
+                  &symkey_cipher,
+                  key_usage_auth,
+                  symkey_clear,
+                  &(vtpm_globals->keyAuth) ) );
+ 
+  goto egress;
+ abort_egress:
+  vtpmlogerror(VTPM_LOG_VTPM, "Failed to decrypt symmetric key
status=%d\n.", status);
+ 
+ egress:
+  BSG_Destroy(BSG_TPM_SIZE32_DATA, &symkey_cipher32);
+  return status;
+}
+
 TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI_RESOURCE *myDMI,
                 const buffer_t *inbuf,
                 buffer_t *outbuf) {
  
   TPM_RESULT status = TPM_SUCCESS;
-  int fh;
+  int fh = -1;
   long bytes_written;
   buffer_t sealed_NVM = NULL_BUF;
- 
-  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Saving %d bytes of NVM.\n",
buffer_len(inbuf));
+  const buffer_t* nvmbuf = inbuf;
+
+  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Saving %d bytes of NVM.\n",
buffer_len(nvmbuf));
 
-  TPMTRYRETURN( envelope_encrypt(inbuf,
+  TPMTRYRETURN( envelope_encrypt(nvmbuf,
                                  &vtpm_globals->storageKey,
                                  &sealed_NVM) );
-                 
+
   // Write sealed blob off disk from NVMLocation
   // TODO: How to properly return from these. Do we care if we return
failure
   //       after writing the file? We can't get the old one back.
@@ -205,7 +268,6 @@ TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI_RESOURCE
*myDMI,
     status = TPM_IOERROR;
     goto abort_egress;
   }
-  close(fh);
  
   Crypto_SHA1Full (sealed_NVM.bytes, buffer_len(&sealed_NVM), (BYTE *)
&myDMI->NVM_measurement);  
  
@@ -215,6 +277,7 @@ TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI_RESOURCE
*myDMI,
   vtpmlogerror(VTPM_LOG_VTPM, "Failed to save NVM\n.");
  
  egress:
+  close(fh);
   buffer_free(&sealed_NVM);
   return status;
 }
@@ -229,7 +292,8 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI_RESOURCE
*myDMI,
 
   buffer_t sealed_NVM = NULL_BUF;
   long fh_size;
-  int fh, stat_ret, i;
+  int fh = -1;
+  int stat_ret, i;
   struct stat file_stat;
   TPM_DIGEST sealedNVMHash;
   
@@ -241,6 +305,7 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI_RESOURCE
*myDMI,
  
   //Read sealed blob off disk from NVMLocation
   fh = open(myDMI->NVMLocation, O_RDONLY);
+  printf("Filename: %s\n", myDMI->NVMLocation);
   stat_ret = fstat(fh, &file_stat);
   if (stat_ret == 0)
     fh_size = file_stat.st_size;
@@ -254,7 +319,6 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI_RESOURCE
*myDMI,
     status = TPM_IOERROR;
     goto abort_egress;
   }
-  close(fh);
  
   vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Load_NVMing[%d],\n",
buffer_len(&sealed_NVM));
  
@@ -289,14 +353,128 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI_RESOURCE
*myDMI,
  
  egress:
   buffer_free( &sealed_NVM );
+  close(fh);
+ 
+  return status;
+}
+
+TPM_RESULT VTPM_Handle_Load_HashKey(VTPM_DMI_RESOURCE *myDMI,
+                const buffer_t    *inbuf,
+                buffer_t          *outbuf) {
+ 
+  TPM_RESULT status = TPM_SUCCESS;
+
+  buffer_t sealed_NVM = NULL_BUF;
+  long fh_size;
+  int fh = -1;
+  int stat_ret, i;
+  struct stat file_stat;
+  TPM_DIGEST sealedNVMHash;
+  
+  if (myDMI->NVMLocation == NULL) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Unable to load NVM because the file
name NULL.\n");
+    status = TPM_AUTHFAIL;
+    goto abort_egress;
+  }
+ 
+  //Read sealed blob off disk from NVMLocation
+  fh = open(myDMI->NVMLocation, O_RDONLY);
+  printf("Filename: %s\n", myDMI->NVMLocation);
+  stat_ret = fstat(fh, &file_stat);
+  if (stat_ret == 0)
+    fh_size = file_stat.st_size;
+  else {
+    status = TPM_IOERROR;
+    goto abort_egress;
+  }
+ 
+  TPMTRYRETURN( buffer_init( &sealed_NVM, fh_size, NULL) );
+  if (read(fh, sealed_NVM.bytes, buffer_len(&sealed_NVM)) != fh_size) {
+    status = TPM_IOERROR;
+    goto abort_egress;
+  }
+ 
+  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Loading %d byte encryption key,\n",
buffer_len(&sealed_NVM));
+ 
+  Crypto_SHA1Full(sealed_NVM.bytes, buffer_len(&sealed_NVM), (BYTE *)
&sealedNVMHash);   
+ 
+  // Verify measurement of sealed blob.
+  if (memcmp(&sealedNVMHash, &myDMI->NVM_measurement,
sizeof(TPM_DIGEST)) ) {
+    vtpmlogerror(VTPM_LOG_VTPM, "VTPM LoadKey NVM measurement check
failed.\n");
+    vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Correct hash: ");
+    for (i=0; i< sizeof(TPM_DIGEST); i++)
+      vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ",
((BYTE*)&myDMI->NVM_measurement)[i]);
+    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+
+    vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Measured hash: ");
+    for (i=0; i< sizeof(TPM_DIGEST); i++)
+      vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ",
((BYTE*)&sealedNVMHash)[i]);
+    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+   
+    status = TPM_AUTHFAIL;
+    goto abort_egress;
+  }
+ 
+  //Decrypt the key into the output buffer
+  TPMTRYRETURN( symkey_decrypt(&sealed_NVM,
+                                 myDMI->TCSContext,
+                     vtpm_globals->storageKeyHandle,
+                     (const
TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
+                                 outbuf) ); 
+  goto egress;
+ 
+ abort_egress:
+  vtpmlogerror(VTPM_LOG_VTPM, "Failed to load Key\n.");
+ 
+ egress:
+  buffer_free( &sealed_NVM );
+  close(fh);
+ 
+  return status;
+}
+
+TPM_RESULT VTPM_Handle_Save_HashKey(VTPM_DMI_RESOURCE *myDMI,
+                                 const buffer_t    *inbuf,
+                 buffer_t          *outbuf) {
+  TPM_RESULT status = TPM_SUCCESS;
+  int fh = -1;
+  long bytes_written;
+  buffer_t sealed_key = NULL_BUF;
+ 
+  TPMTRYRETURN( symkey_encrypt(inbuf,
+                                 &vtpm_globals->storageKey,
+                                 &sealed_key) );
+
+  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Saving %d byte Encryption Key.\n",
buffer_len(inbuf));
+
+  // Write sealed blob off disk from NVMLocation
+  // TODO: How to properly return from these. Do we care if we return
failure
+  //       after writing the file? We can't get the old one back.
+  // TODO: Backup old file and try and recover that way.
+  fh = open(myDMI->NVMLocation, O_WRONLY | O_CREAT | O_TRUNC, S_IREAD |
S_IWRITE);
+  if ( (bytes_written = write(fh, sealed_key.bytes,
buffer_len(&sealed_key) ) != (long) buffer_len(&sealed_key))) {
+    vtpmlogerror(VTPM_LOG_VTPM, "We just overwrote a DMI_NVM and failed
to finish. %ld/%ld bytes.\n", bytes_written, (long)buffer_len(&sealed_key));
+    status = TPM_IOERROR;
+    goto abort_egress;
+  }
  
+  Crypto_SHA1Full (sealed_key.bytes, buffer_len(&sealed_key), (BYTE *)
&myDMI->NVM_measurement);  
+ 
+  goto egress;
+ 
+ abort_egress:
+  vtpmlogerror(VTPM_LOG_VTPM, "Failed to save Key\n.");
+ 
+ egress:
+  close(fh);
+  buffer_free(&sealed_key);
   return status;
 }
 
 
 TPM_RESULT VTPM_SaveManagerData(void) {
   TPM_RESULT status=TPM_SUCCESS;
-  int fh, dmis=-1;
+  int fh = -1, dmis=-1;
 
   BYTE *flat_boot_key=NULL, *flat_dmis=NULL, *flat_enc=NULL;
   buffer_t clear_flat_global=NULL_BUF, enc_flat_global=NULL_BUF;
@@ -364,6 +542,7 @@ TPM_RESULT VTPM_SaveManagerData(void) {
                                         BSG_TPM_DIGEST,
&dmi_res->DMI_measurement);
 
     } while (hashtable_iterator_advance(dmi_itr));
+    free(dmi_itr);
   }
 
   fh = open(STATE_FILE, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
@@ -389,6 +568,7 @@ TPM_RESULT VTPM_SaveManagerData(void) {
 
   free(flat_boot_key);
   free(flat_enc);
+  buffer_free(&clear_flat_global);
   buffer_free(&enc_flat_global);
   free(flat_dmis);
   close(fh);
@@ -403,9 +583,10 @@ TPM_RESULT VTPM_LoadManagerData(void) {
   int fh, stat_ret, dmis=0;
   long fh_size = 0, step_size;
   BYTE *flat_table=NULL;
-  buffer_t  unsealed_data, enc_table_abuf;
-  struct pack_buf_t storage_key_pack, boot_key_pack;
-  UINT32 *dmi_id_key, enc_size;
+  buffer_t  unsealed_data = NULL_BUF;
+  buffer_t enc_table_abuf;
+  struct pack_buf_t storage_key_pack = NULL_PACK_BUF, boot_key_pack =
NULL_PACK_BUF;
+  UINT32 enc_size;
   BYTE vtpm_manager_gen;
 
   VTPM_DMI_RESOURCE *dmi_res;
@@ -438,9 +619,9 @@ TPM_RESULT VTPM_LoadManagerData(void) {
                               BSG_TPM_SIZE32_DATA, &boot_key_pack,
                               BSG_TYPE_UINT32, &enc_size);
 
-  TPMTRYRETURN(buffer_init(&vtpm_globals->bootKeyWrap, 0, 0) );
   TPMTRYRETURN(buffer_init_alias_convert(&enc_table_abuf, enc_size,
flat_table + step_size) );
-  TPMTRYRETURN(buffer_append_raw(&vtpm_globals->bootKeyWrap,
boot_key_pack.size, boot_key_pack.data) );
+  TPMTRYRETURN(buffer_init(&vtpm_globals->bootKeyWrap,
boot_key_pack.size, boot_key_pack.data) );
+
 
   //Load Boot Key
   TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
@@ -471,8 +652,8 @@ TPM_RESULT VTPM_LoadManagerData(void) {
                   BSG_TPM_SECRET,   &vtpm_globals->storage_key_usage_auth,
                   BSG_TPM_SIZE32_DATA, &storage_key_pack);
 
-  TPMTRYRETURN(buffer_init(&vtpm_globals->storageKeyWrap, 0, 0) );
-  TPMTRYRETURN(buffer_append_raw(&vtpm_globals->storageKeyWrap,
storage_key_pack.size, storage_key_pack.data) );
+  TPMTRYRETURN(buffer_init(&vtpm_globals->storageKeyWrap,
storage_key_pack.size, storage_key_pack.data) );
+
 
   // Per DMI values to be saved
   while ( step_size < fh_size ){
@@ -501,7 +682,10 @@ TPM_RESULT VTPM_LoadManagerData(void) {
  abort_egress:
   vtpmlogerror(VTPM_LOG_VTPM, "Failed to load service data with error =
%s\n", tpm_get_error_name(status));
  egress:
+  BSG_Destroy(BSG_TPM_SIZE32_DATA, &boot_key_pack);
+  BSG_Destroy(BSG_TPM_SIZE32_DATA, &storage_key_pack);
 
+  buffer_free(&unsealed_data);
   free(flat_table);
   close(fh);
 
diff --git a/tools/vtpm_manager/manager/vtpm_ipc.c
b/tools/vtpm_manager/manager/vtpm_ipc.c
--- a/tools/vtpm_manager/manager/vtpm_ipc.c
+++ b/tools/vtpm_manager/manager/vtpm_ipc.c
@@ -36,26 +36,49 @@
 //
 // ===================================================================
 
+#include <sys/types.h>
 #include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/select.h>
 #include "vtpm_ipc.h"
 #include "vtpmpriv.h"
 #include "log.h"
 
-int vtpm_ipc_init(vtpm_ipc_handle_t *ipc_h, char* name, int flags, BOOL
create) {
+volatile sig_atomic_t IPC_QUIT_FLAG = 0;
+
+const static struct timeval TIMEOUT = {
+   .tv_sec = 1,
+   .tv_usec = 0
+};
+
+int vtpm_ipc_init(vtpm_ipc_handle_t *ipc_h, char* name, int flags, BOOL
create, BOOL preopen) {
+  int rc;
+
   ipc_h->name = name;
   ipc_h->flags = flags;
   ipc_h->fh = VTPM_IPC_CLOSED;
 
-  if (create)
-    return(vtpm_ipc_create(ipc_h));
-  else
-    return 0;
+  if (create) {
+    if((rc = vtpm_ipc_create(ipc_h) != 0)) {
+       return rc;
+    }
+  }
+
+  if(preopen) {
+    ipc_h->fh = open(ipc_h->name, ipc_h->flags);
+    if ( ipc_h->fh == VTPM_IPC_CLOSED ) {
+       vtpmlogerror(VTPM_LOG_VTPM, "VTPM ERROR: Can't open %s\n",
ipc_h->name);
+       return -1;
+    }
+  }
+  return 0;
+
 }
 
 // Create the file that needs opening. Used only for FIFOs
 // FYI: This may cause problems in other file IO schemes. We'll see.
 int vtpm_ipc_create(vtpm_ipc_handle_t *ipc_h) {
-  int fh;
   struct stat file_info;
 
   if ((!ipc_h) || (!ipc_h->name))
@@ -68,8 +91,6 @@ int vtpm_ipc_create(vtpm_ipc_handle_t *ipc_h) {
     }
   }
 
-  ipc_h->fh = VTPM_IPC_CLOSED;
-
   return 0;
 }
 
@@ -78,6 +99,8 @@ int vtpm_ipc_create(vtpm_ipc_handle_t *ipc_h) {
 int vtpm_ipc_read(vtpm_ipc_handle_t *ipc_h, vtpm_ipc_handle_t
*alt_ipc_h, BYTE *bytes, UINT32 size){
   vtpm_ipc_handle_t *my_ipc_h;
   int result;
+  fd_set fds;
+  struct timeval timeout;
  
   if (ipc_h) {
     my_ipc_h = ipc_h;
@@ -94,9 +117,19 @@ int vtpm_ipc_read(vtpm_ipc_handle_t *ipc_h,
vtpm_ipc_handle_t *alt_ipc_h, BYTE *
     return -1;
   }
 
+  FD_ZERO(&fds);
+  while(!FD_ISSET( my_ipc_h->fh, &fds )) {
+     timeout = TIMEOUT;
+     if (IPC_QUIT_FLAG) {
+    return -1;
+     }
+     FD_SET(my_ipc_h->fh, &fds);
+     select(my_ipc_h->fh + 1, &fds, NULL, NULL, &timeout);
+  }
+
   result = read(my_ipc_h->fh, bytes, size);
   if (result < 0) {
-    my_ipc_h->fh = VTPM_IPC_CLOSED;
+     my_ipc_h->fh = VTPM_IPC_CLOSED;
   }
 
   return (result);
@@ -106,6 +139,8 @@ int vtpm_ipc_read(vtpm_ipc_handle_t *ipc_h,
vtpm_ipc_handle_t *alt_ipc_h, BYTE *
 int vtpm_ipc_write(vtpm_ipc_handle_t *ipc_h, vtpm_ipc_handle_t
*alt_ipc_h, BYTE *bytes, UINT32 size) {
   vtpm_ipc_handle_t *my_ipc_h;
   int result;
+  fd_set fds;
+  struct timeval timeout;
 
   if (ipc_h) {
     my_ipc_h = ipc_h;
@@ -122,6 +157,16 @@ int vtpm_ipc_write(vtpm_ipc_handle_t *ipc_h,
vtpm_ipc_handle_t *alt_ipc_h, BYTE
     return -1;
   }
 
+  FD_ZERO(&fds);
+  while(!FD_ISSET( my_ipc_h->fh, &fds )) {
+     timeout = TIMEOUT;
+     if (IPC_QUIT_FLAG) {
+    return -1;
+     }
+     FD_SET(my_ipc_h->fh, &fds);
+     select(my_ipc_h->fh + 1, NULL, &fds, NULL, &timeout);
+  }
+
   result = write(my_ipc_h->fh, bytes, size);
   if (result < 0) {
     my_ipc_h->fh = VTPM_IPC_CLOSED;
diff --git a/tools/vtpm_manager/manager/vtpm_ipc.h
b/tools/vtpm_manager/manager/vtpm_ipc.h
--- a/tools/vtpm_manager/manager/vtpm_ipc.h
+++ b/tools/vtpm_manager/manager/vtpm_ipc.h
@@ -39,10 +39,14 @@
 #ifndef __VTPM_IO_H__
 #define __VTPM_IO_H__
 
+#include <signal.h>
+
 #include "tcg.h"
 
 #define VTPM_IPC_CLOSED -1
 
+extern volatile sig_atomic_t IPC_QUIT_FLAG;
+
 // Represents an (somewhat) abstracted io handle.
 typedef struct vtpm_ipc_handle_t {
   int fh;              // IO handle.
@@ -53,7 +57,7 @@ typedef struct vtpm_ipc_handle_t {
 } vtpm_ipc_handle_t;
 
 
-int vtpm_ipc_init(vtpm_ipc_handle_t *ioh, char* name, int flags, BOOL
create);
+int vtpm_ipc_init(vtpm_ipc_handle_t *ioh, char* name, int flags, BOOL
create, BOOL preopen);
 
 // Create the file that needs opening. Used only for FIFOs
 // FYI: This may cause problems in other file IO schemes. We'll see.
diff --git a/tools/vtpm_manager/manager/vtpm_lock.c
b/tools/vtpm_manager/manager/vtpm_lock.c
--- a/tools/vtpm_manager/manager/vtpm_lock.c
+++ b/tools/vtpm_manager/manager/vtpm_lock.c
@@ -40,24 +40,24 @@
 
 static pthread_rwlock_t vtpm_lock;
 
-void vtpm_lock_init() {
+void vtpm_lock_init(void) {
 
   pthread_rwlock_init( &vtpm_lock, NULL);
 }
 
-void vtpm_lock_destroy(){
+void vtpm_lock_destroy(void){
   pthread_rwlock_destroy(&vtpm_lock);
 }
 
-void vtpm_lock_rdlock(){
+void vtpm_lock_rdlock(void){
   pthread_rwlock_rdlock(&vtpm_lock);
 }
 
-void vtpm_lock_wrlock(){
+void vtpm_lock_wrlock(void){
   pthread_rwlock_wrlock(&vtpm_lock);
 }
 
-void vtpm_lock_unlock(){
+void vtpm_lock_unlock(void){
   pthread_rwlock_unlock(&vtpm_lock);
 }
 
diff --git a/tools/vtpm_manager/manager/vtpm_lock.h
b/tools/vtpm_manager/manager/vtpm_lock.h
--- a/tools/vtpm_manager/manager/vtpm_lock.h
+++ b/tools/vtpm_manager/manager/vtpm_lock.h
@@ -38,11 +38,11 @@
 #ifndef __VTPM_LOCK_H__
 #define __VTPM_LOCK_H__
 
-void vtpm_lock_init();
-void vtpm_lock_destroy();
+void vtpm_lock_init(void);
+void vtpm_lock_destroy(void);
 
-void vtpm_lock_rdlock();
-void vtpm_lock_wrlock();
-void vtpm_lock_unlock();
+void vtpm_lock_rdlock(void);
+void vtpm_lock_wrlock(void);
+void vtpm_lock_unlock(void);
 
 #endif
diff --git a/tools/vtpm_manager/manager/vtpm_manager.c
b/tools/vtpm_manager/manager/vtpm_manager.c
--- a/tools/vtpm_manager/manager/vtpm_manager.c
+++ b/tools/vtpm_manager/manager/vtpm_manager.c
@@ -40,10 +40,12 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
+#include <stdlib.h>
 
 #include "vtpm_manager.h"
 #include "vtpmpriv.h"
 #include "vtsp.h"
+#include "tpmddl.h"
 #include "bsg.h"
 #include "hashtable.h"
 #include "hashtable_itr.h"
@@ -54,8 +56,8 @@
 VTPM_GLOBALS *vtpm_globals=NULL;
 
 // --------------------------- Well Known Auths --------------------------
-const TPM_AUTHDATA SRK_AUTH = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
-                                  0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff};
+const TPM_AUTHDATA SRK_AUTH = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
+                                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00};
 
 #ifdef WELL_KNOWN_OWNER_AUTH
 static BYTE FIXED_OWNER_AUTH[20] =  {0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff,
@@ -74,7 +76,6 @@ static int equals32(void *k1, void *k2) {
 }
 
 // --------------------------- Functions ------------------------------
-
 TPM_RESULT VTPM_Create_Manager(){
  
   TPM_RESULT status = TPM_SUCCESS;
@@ -104,6 +105,7 @@ TPM_RESULT VTPM_Create_Manager(){
     TPMTRYRETURN(VTSP_DisablePubekRead(vtpm_globals->manager_tcs_handle,
                                        (const
TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth, 
                                        &vtpm_globals->keyAuth));    
+    Crypto_RSACryptoInfoFree(&ek_cryptoInfo);
   } else {
     vtpmloginfo(VTPM_LOG_VTPM, "Failed to readEK meaning TPM has an
owner. Creating Keys off existing SRK.\n");
   }
@@ -181,7 +183,7 @@ TPM_RESULT VTPM_Create_Manager(){
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-TPM_RESULT VTPM_Init_Manager() {
+TPM_RESULT VTPM_Init_Manager(void) {
   TPM_RESULT status = TPM_FAIL, serviceStatus;  
   BYTE *randomsead;
   UINT32 randomsize=256;
@@ -203,6 +205,11 @@ TPM_RESULT VTPM_Init_Manager() {
   vtpm_globals->manager_tcs_handle = 0;
 
   TPMTRYRETURN(TCS_create());
+
+  // Blow away all stale handles left in the tpm
+  if(TDDL_FlushAllResources() != TPM_SUCCESS) {
+     vtpmlogerror(VTPM_LOG_VTPM, "VTPM_FlushResources failed,
continuing anyway..\n");
+  }
  
   // Create TCS Context for service
   TPMTRYRETURN( TCS_OpenContext(&vtpm_globals->manager_tcs_handle ) );
@@ -228,7 +235,7 @@ TPM_RESULT VTPM_Init_Manager() {
     TPMTRYRETURN( VTPM_Create_Manager() );   
     TPMTRYRETURN( VTPM_SaveManagerData() );
   } else if (serviceStatus != TPM_SUCCESS) {
-    vtpmlogerror(VTPM_LOG_VTPM, "Failed to read existing manager file");
+    vtpmlogerror(VTPM_LOG_VTPM, "Failed to read existing manager file\n");
     exit(1);
   }
 
@@ -254,7 +261,7 @@ TPM_RESULT VTPM_Init_Manager() {
 }
 
 ///////////////////////////////////////////////////////////////////////////////

-void VTPM_Stop_Manager() {
+void VTPM_Stop_Manager(void) {
   VTPM_DMI_RESOURCE *dmi_res;
   struct hashtable_itr *dmi_itr;
  
@@ -267,7 +274,7 @@ void VTPM_Stop_Manager() {
     close_dmi( dmi_res ); // Not really interested in return code
      
     } while (hashtable_iterator_advance(dmi_itr));
-        free (dmi_itr);
+    free (dmi_itr);
   }
  
   if ( VTPM_SaveManagerData() != TPM_SUCCESS )
@@ -276,7 +283,21 @@ void VTPM_Stop_Manager() {
   TCS_CloseContext(vtpm_globals->manager_tcs_handle);
   TCS_destroy();
  
-  hashtable_destroy(vtpm_globals->dmi_map, 1);
+  if (hashtable_count(vtpm_globals->dmi_map) > 0) {
+    dmi_itr = hashtable_iterator(vtpm_globals->dmi_map);
+    do {
+      dmi_res = (VTPM_DMI_RESOURCE *) hashtable_iterator_value(dmi_itr);
+      free_dmi(dmi_res);
+    } while (hashtable_iterator_advance(dmi_itr));
+    free (dmi_itr);
+  }
+  hashtable_destroy(vtpm_globals->dmi_map, 0);
+
+  /* Cleanup resources */
+  Crypto_RSACryptoInfoFree(&vtpm_globals->bootKey);
+  Crypto_RSACryptoInfoFree(&vtpm_globals->storageKey);
+  buffer_free(&vtpm_globals->bootKeyWrap);
+  buffer_free(&vtpm_globals->storageKeyWrap);
   free(vtpm_globals);
  
   Crypto_Exit();
diff --git a/tools/vtpm_manager/manager/vtpm_manager.h
b/tools/vtpm_manager/manager/vtpm_manager.h
--- a/tools/vtpm_manager/manager/vtpm_manager.h
+++ b/tools/vtpm_manager/manager/vtpm_manager.h
@@ -61,6 +61,8 @@
 #define VTPM_ORD_TPMCOMMAND   (VTPM_ORD_BASE + 3) // DMI issues HW TPM
Command
 #define VTPM_ORD_GET_MIG_KEY  (VTPM_ORD_BASE + 4) // Get manager's
migration key
 #define VTPM_ORD_LOAD_MIG_KEY (VTPM_ORD_BASE + 5) // load dest
migration key
+#define VTPM_ORD_SAVEHASHKEY      (VTPM_ORD_BASE + 7) // DMI requests
encryption key for persistent storage
+#define VTPM_ORD_LOADHASHKEY      (VTPM_ORD_BASE + 8) // DMI requests
symkey to be regenerated
 
 // Priviledged VTPM Commands (From management console)
 #define VTPM_ORD_OPEN         (VTPM_PRIV_BASE + 1) // Creates/reopens DMI
@@ -147,4 +149,23 @@ VTPM_TPMCommand
 
 *********************************************************************/
 
+#ifndef VTPM_STUBDOM
+#define TPM_EMULATOR_PATH "/usr/bin/vtpmd"
+#endif
+
+#define VTPM_BE_FNAME          "/dev/vtpm"
+#define VTPM_DUMMY_TX_BE_FNAME "/var/vtpm/fifos/dummy_out.fifo"
+#define VTPM_DUMMY_RX_BE_FNAME "/var/vtpm/fifos/dummy_in.fifo"
+#ifndef VTPM_STUBDOM
+#define VTPM_TX_TPM_FNAME      "/var/vtpm/fifos/tpm_cmd_to_%d.fifo"
+#define VTPM_RX_TPM_FNAME      "/var/vtpm/fifos/tpm_rsp_from_all.fifo"
+#define VTPM_TX_VTPM_FNAME     "/var/vtpm/fifos/vtpm_rsp_to_%d.fifo"
+#define VTPM_RX_VTPM_FNAME     "/var/vtpm/fifos/vtpm_cmd_from_all.fifo"
+#endif
+#define VTPM_TX_HP_FNAME       "/var/vtpm/fifos/to_console.fifo"
+#define VTPM_RX_HP_FNAME       "/var/vtpm/fifos/from_console.fifo"
+
+#define VTPM_TYPE_PVM_STRING "pvm"
+#define VTPM_TYPE_HVM_STRING "hvm"
+
 #endif //_VTPM_MANAGER_H_
diff --git a/tools/vtpm_manager/manager/vtpm_manager_handler.c
b/tools/vtpm_manager/manager/vtpm_manager_handler.c
--- a/tools/vtpm_manager/manager/vtpm_manager_handler.c
+++ b/tools/vtpm_manager/manager/vtpm_manager_handler.c
@@ -41,6 +41,8 @@
 #include <unistd.h>
 #include <string.h>
 #include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
 
 #include "vtpm_manager.h"
 #include "vtpmpriv.h"
@@ -50,26 +52,13 @@
 #include "hashtable_itr.h"
 #include "log.h"
 #include "buffer.h"
+#include "vtpm_manager_handler.h"
 
 #define vtpmhandlerloginfo(module,fmt,args...) vtpmloginfo (module,
"[%s]: " fmt, thread_name, ##args );
 #define vtpmhandlerloginfomore(module,fmt,args...) vtpmloginfomore
(module, fmt, ##args );
 #define vtpmhandlerlogerror(module,fmt,args...) vtpmlogerror (module,
"[%s]: " fmt, thread_name, ##args );
 
-// ---------------------- Prototypes -------------------
-TPM_RESULT vtpm_manager_handle_vtpm_cmd(VTPM_DMI_RESOURCE *dmi_res,
-                    TPM_COMMAND_CODE ord,
-                    buffer_t *command_buf,
-                    buffer_t *result_buf,
-                                        BOOL is_priv,
-                                        char *thread_name);
-
-TPM_RESULT vtpm_manager_handle_tpm_cmd(vtpm_ipc_handle_t *tx_ipc_h,
-                                       vtpm_ipc_handle_t *rx_ipc_h,
-                                       VTPM_DMI_RESOURCE *dmi_res,
-                                       BYTE *cmd_header,
-                                       buffer_t *param_buf,
-                                       buffer_t *result_buf,
-                                       char *thread_name);
+volatile sig_atomic_t HANDLER_QUIT_FLAG = 0;
 
 TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t *tx_ipc_h,
                                  vtpm_ipc_handle_t *rx_ipc_h,
@@ -80,12 +69,13 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t
*tx_ipc_h,
                                  char *thread_name) {
   TPM_RESULT      status =  TPM_FAIL; // Should never return
   UINT32          dmi, in_param_size, cmd_size, out_param_size,
out_message_size, reply_size;
-  BYTE            *cmd_header=NULL, *in_param=NULL, *out_message=NULL,
*reply;
+  BYTE            *cmd_header=NULL, *in_param=NULL, *out_header=NULL,
*reply;
   buffer_t        *command_buf=NULL, *result_buf=NULL;
   TPM_TAG         tag;
   TPM_COMMAND_CODE ord;
   VTPM_DMI_RESOURCE *dmi_res;
   int  size_read, size_write, i;
+  int locked;
   BOOL add_header=TRUE; // This indicates to prepend a header on
result_buf before sending
  
   cmd_header = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV);
@@ -93,7 +83,11 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t
*tx_ipc_h,
   result_buf = (buffer_t *) malloc(sizeof(buffer_t));
 
   // ------------------------ Main Loop --------------------------------
-  while(1) {
+  while(!HANDLER_QUIT_FLAG) {
+    locked = 0;
+
+    buffer_init(command_buf, 0, NULL);
+    buffer_init(result_buf, 0, NULL);
    
     vtpmhandlerloginfo(VTPM_LOG_VTPM, "%s waiting for messages.\n",
thread_name);
 
@@ -106,7 +100,9 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t
*tx_ipc_h,
       for (i=0; i<size_read; i++)
     vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
     } else {
-      vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s can't read from ipc.
Errono = %d. Aborting... \n", thread_name, errno);
+      if (!IPC_QUIT_FLAG) {
+    vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s can't read from ipc. Errono
= %d. Aborting... \n", thread_name, errno);
+      }
       goto abort_command;
     }
 
@@ -155,6 +151,7 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t
*tx_ipc_h,
       vtpmhandlerlogerror(VTPM_LOG_VTPM, "Failed to setup buffers.
Aborting...\n");
       goto abort_command;
     }
+    result_buf->is_owner = TRUE;
    
     // -------------- Dispatch Commands to Handlers -----------
     if ((tag == VTPM_TAG_REQ) && (ord & VTPM_PRIV_MASK)) {
@@ -162,6 +159,7 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t
*tx_ipc_h,
     } else {
       vtpm_lock_rdlock();
     }
+    locked = 1;
 
     if ( !(dmi_res = (VTPM_DMI_RESOURCE *)
hashtable_search(vtpm_globals->dmi_map, &dmi)) ||
          (!dmi_res->connected) ) {
@@ -174,10 +172,22 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t
*tx_ipc_h,
     if (tag == VTPM_TAG_REQ) {
    
       status = vtpm_manager_handle_vtpm_cmd(dmi_res, ord, command_buf,
result_buf, is_priv, thread_name);
+      result_buf->is_owner = TRUE;
 
     } else { // This is not a VTPM Command at all.
       if (fw_tpm) {
+#ifdef VTPM_STUBDOM
+    /* In stubdom mode, we allow the vtpm domains to send raw tpm
commands down the pipe
+     * They can also just embed their tpm commands inside VTPM commands
if they wish to*/
+
+    /* Stick the header back onto the raw command (minus the dmiid) */
+    buffer_prepend_raw(command_buf, VTPM_COMMAND_HEADER_SIZE_CLT,
cmd_header + sizeof(UINT32));
+    status = VTPM_Handle_TPM_Command(dmi_res, command_buf, result_buf);
+#else
+    /* In normal mode, this is used for the guest to forward a raw
command to the vtpm process */
         status = vtpm_manager_handle_tpm_cmd(fw_tx_ipc_h, fw_rx_ipc_h,
dmi_res, cmd_header, command_buf, result_buf, thread_name);
+#endif
+        result_buf->is_owner = TRUE;
 
         // This means calling the DMI failed, not that the cmd failed
in the DMI
         // Since the return will be interpretted by a TPM app, all
errors are IO_ERRORs to the app
@@ -207,36 +217,42 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t
*tx_ipc_h,
     // ------------------- Respond to Sender ------------------
 
     // Errors while handling responses jump here to reply with error
messages
-    // NOTE: Currently there are no recoverable errors in multi-VM
mode. If one
-    //       is added to the code, this ifdef should be removed.
-    //       Also note this is NOT referring to errors in commands, but
rather
-    //       this is about I/O errors and such.
-#ifndef VTPM_MULTI_VM
- abort_with_error:
-#endif
+abort_with_error:
   
     if (add_header) {
       // Prepend VTPM header with destination DM stamped
       out_param_size = buffer_len(result_buf);
       out_message_size = VTPM_COMMAND_HEADER_SIZE_CLT + out_param_size;
-      reply_size = VTPM_COMMAND_HEADER_SIZE_SRV + out_param_size;
-      out_message = (BYTE *) malloc (reply_size);
-      reply = out_message;
+      out_header = (BYTE *) malloc (VTPM_COMMAND_HEADER_SIZE_SRV);
    
-      BSG_PackList(out_message, 4,
+      BSG_PackList(out_header, 4,
            BSG_TYPE_UINT32, (BYTE *) &dmi,
            BSG_TPM_TAG, (BYTE *) &tag,
            BSG_TYPE_UINT32, (BYTE *) &out_message_size,
            BSG_TPM_RESULT, (BYTE *) &status);
    
-      if (buffer_len(result_buf) > 0)
-        memcpy(out_message + VTPM_COMMAND_HEADER_SIZE_SRV,
result_buf->bytes, out_param_size);
-      //Note: Send message + dmi_id
+      buffer_prepend_raw(result_buf, VTPM_COMMAND_HEADER_SIZE_SRV,
out_header);
+      free(out_header);
     } else {
-      reply = result_buf->bytes;
-      reply_size = buffer_len(result_buf);
+#ifdef VTPM_STUBDOM
+       //In stubdom mode, we need to always prepend the dmiid so the
raw command can be returned to the right domain
+       out_header = (BYTE*) malloc(sizeof(UINT32));
+       BSG_PackList(out_header, 1,
+         BSG_TYPE_UINT32, (BYTE*) &dmi);
+       buffer_prepend_raw(result_buf, sizeof(UINT32), out_header);
+       free(out_header);
+#endif
     } 
+    reply = result_buf->bytes;
+    reply_size = buffer_len(result_buf);
+#ifndef VTPM_STUBDOM
     size_write = vtpm_ipc_write(tx_ipc_h, (dmi_res ?
dmi_res->tx_vtpm_ipc_h : NULL), reply, reply_size );
+#else
+    if(reply_size >= 4096) {
+       vtpmhandlerlogerror(VTPM_LOG_VTPM, "MESSAGE TOO BIG!!!");
+    }
+    size_write = vtpm_ipc_write(tx_ipc_h, NULL, reply, reply_size );
+#endif
     if (size_write > 0) {
       vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT: 0x");
       for (i=0; i < reply_size; i++)
@@ -247,7 +263,6 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t
*tx_ipc_h,
       vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s had error writing to ipc.
Aborting... \n", thread_name);
       goto abort_command;
     }
-    free(out_message); out_message=NULL;
    
     if (size_write < (int)reply_size) {
       vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s unable to write full
command to ipc (%d/%d)\n", thread_name, size_write, reply_size);
@@ -264,14 +279,22 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t
*tx_ipc_h,
     buffer_free(command_buf);
 
     // If we have a write lock, save the manager table
-    if ((tag == VTPM_TAG_REQ) && (ord & VTPM_PRIV_MASK) &&
+    if (locked && (tag == VTPM_TAG_REQ) && (ord & VTPM_PRIV_MASK) &&
         (VTPM_SaveManagerData() != TPM_SUCCESS) ) {
        vtpmhandlerlogerror(VTPM_LOG_VTPM, "ERROR: Unable to save
manager data.\n");
     }
 
-    vtpm_lock_unlock();
+    if(locked) {
+       vtpm_lock_unlock();
+    }
     add_header = TRUE; // Reset to the default
   } // End while(1)
+
+  free(cmd_header);
+  free(command_buf);
+  free(result_buf);
+
+  vtpmhandlerloginfo(VTPM_LOG_VTPM, "exiting\n", thread_name);
  
 }
 
@@ -313,6 +336,16 @@ TPM_RESULT
vtpm_manager_handle_vtpm_cmd(VTPM_DMI_RESOURCE *dmi_res,
     status = VTPM_Handle_Load_Migration_key(command_buf,
                                            result_buf);
     break;
+  case VTPM_ORD_SAVEHASHKEY:
+    status = VTPM_Handle_Save_HashKey(dmi_res,
+                     command_buf,
+                   result_buf);
+    break;
+  case VTPM_ORD_LOADHASHKEY:
+    status = VTPM_Handle_Load_HashKey(dmi_res,
+                     command_buf,
+                   result_buf);
+    break;
   
   default:
     // Privileged handlers can do maintanance
@@ -350,6 +383,7 @@ TPM_RESULT
vtpm_manager_handle_vtpm_cmd(VTPM_DMI_RESOURCE *dmi_res,
   return(status);
 }
      
+#ifndef VTPM_STUBDOM
 /////////////////////////////////////////////////////////////////////
 TPM_RESULT vtpm_manager_handle_tpm_cmd(vtpm_ipc_handle_t *tx_ipc_h,
                                        vtpm_ipc_handle_t *rx_ipc_h,
@@ -485,4 +519,5 @@ TPM_RESULT
vtpm_manager_handle_tpm_cmd(vtpm_ipc_handle_t *tx_ipc_h,
 
   return status;
 }
+#endif
 
diff --git a/tools/vtpm_manager/manager/vtpm_manager_handler.h
b/tools/vtpm_manager/manager/vtpm_manager_handler.h
--- /dev/null
+++ b/tools/vtpm_manager/manager/vtpm_manager_handler.h
@@ -0,0 +1,21 @@
+#ifndef VTPM_MANAGER_HANDLER_H
+#define VTPM_MANAGER_HANDLER_H
+// ---------------------- Prototypes -------------------
+TPM_RESULT vtpm_manager_handle_vtpm_cmd(VTPM_DMI_RESOURCE *dmi_res,
+                    TPM_COMMAND_CODE ord,
+                    buffer_t *command_buf,
+                    buffer_t *result_buf,
+                                        BOOL is_priv,
+                                        char *thread_name);
+
+#ifndef VTPM_STUBDOM
+TPM_RESULT vtpm_manager_handle_tpm_cmd(vtpm_ipc_handle_t *tx_ipc_h,
+                                       vtpm_ipc_handle_t *rx_ipc_h,
+                                       VTPM_DMI_RESOURCE *dmi_res,
+                                       BYTE *cmd_header,
+                                       buffer_t *param_buf,
+                                       buffer_t *result_buf,
+                                       char *thread_name);
+#endif
+
+#endif
diff --git a/tools/vtpm_manager/manager/vtpmd.c
b/tools/vtpm_manager/manager/vtpmd.c
--- a/tools/vtpm_manager/manager/vtpmd.c
+++ b/tools/vtpm_manager/manager/vtpmd.c
@@ -45,27 +45,13 @@
 #include <signal.h>
 #include <string.h>
 #include <pthread.h>
+#include <stdlib.h>
 #include "vtpm_manager.h"
 #include "vtpmpriv.h"
 #include "tcg.h"
 #include "log.h"
 #include "vtpm_ipc.h"
 
-#define TPM_EMULATOR_PATH "/usr/bin/vtpmd"
-
-#define VTPM_BE_FNAME          "/dev/vtpm"
-#define VTPM_DUMMY_TX_BE_FNAME "/var/vtpm/fifos/dummy_out.fifo"
-#define VTPM_DUMMY_RX_BE_FNAME "/var/vtpm/fifos/dummy_in.fifo"
-#define VTPM_TX_TPM_FNAME      "/var/vtpm/fifos/tpm_cmd_to_%d.fifo"
-#define VTPM_RX_TPM_FNAME      "/var/vtpm/fifos/tpm_rsp_from_all.fifo"
-#define VTPM_TX_VTPM_FNAME     "/var/vtpm/fifos/vtpm_rsp_to_%d.fifo"
-#define VTPM_RX_VTPM_FNAME     "/var/vtpm/fifos/vtpm_cmd_from_all.fifo"
-#define VTPM_TX_HP_FNAME       "/var/vtpm/fifos/to_console.fifo"
-#define VTPM_RX_HP_FNAME       "/var/vtpm/fifos/from_console.fifo"
-
-#define VTPM_TYPE_PVM_STRING "pvm"
-#define VTPM_TYPE_HVM_STRING "hvm"
-
 struct vtpm_thread_params_s {
   vtpm_ipc_handle_t *tx_ipc_h;
   vtpm_ipc_handle_t *rx_ipc_h;
@@ -76,180 +62,46 @@ struct vtpm_thread_params_s {
   char *thread_name;
 };
 
+static pthread_t           master_thread;
+static pthread_t           be_thread;
+static pthread_t           hp_thread;
+#ifndef VTPM_STUBDOM
+static pthread_t           dmi_thread;
+#endif
+
+
+#ifndef VTPM_STUBDOM
 // This is needed to all extra_close_dmi to close this to prevent a
 // broken pipe when no DMIs are left.
-static vtpm_ipc_handle_t *g_rx_tpm_ipc_h;
+extern vtpm_ipc_handle_t *g_rx_tpm_ipc_h;
+#endif
 
 void *vtpm_manager_thread(void *arg_void) {
-  TPM_RESULT *status = (TPM_RESULT *) malloc(sizeof(TPM_RESULT) );
   struct vtpm_thread_params_s *arg = (struct vtpm_thread_params_s *)
arg_void;
 
-  *status = VTPM_Manager_Handler(arg->tx_ipc_h, arg->rx_ipc_h,
+  VTPM_Manager_Handler(arg->tx_ipc_h, arg->rx_ipc_h,
                                  arg->fw_tpm, arg->fw_tx_ipc_h,
arg->fw_rx_ipc_h,
                                  arg->is_priv, arg->thread_name);
 
-  return (status);
+  return NULL;
 }
 
-
-void signal_handler(int reason) {
-  if (pthread_equal(pthread_self(), vtpm_globals->master_pid)) {
-    vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager shutting down for signal
%d.\n", reason);
-  } else {
-    // For old Linux Thread machines, signals are delivered to each
thread. Deal with them.
-    vtpmloginfo(VTPM_LOG_VTPM, "Child shutting down\n");
-    pthread_exit(NULL);
+void signal_handler(int signal) {
+  if (pthread_equal(pthread_self(), master_thread)) {
+    vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager shutting down for signal
%s(%d). Please wait..\n", strsignal(signal), signal);
+    HANDLER_QUIT_FLAG = IPC_QUIT_FLAG = 1;
   }
-
-  VTPM_Stop_Manager();
-  exit(-1);
 }
 
 struct sigaction ctl_c_handler;
 
-TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res, BYTE vm_type,
BYTE startup_mode) {
-
-  TPM_RESULT status = TPM_SUCCESS;
-  int fh;
-  char dmi_id_str[11]; // UINT32s are up to 10 digits + NULL
-  char *tx_vtpm_name, *tx_tpm_name, *vm_type_string;
-  struct stat file_info;
-
-  if (dmi_res->dmi_id == VTPM_CTL_DM) {
-    dmi_res->tx_tpm_ipc_h = NULL;
-    dmi_res->rx_tpm_ipc_h = NULL;
-    dmi_res->tx_vtpm_ipc_h = NULL;
-    dmi_res->rx_vtpm_ipc_h = NULL;
-  } else {
-    // Create a pair of fifo pipes
-    dmi_res->rx_tpm_ipc_h = NULL;
-    dmi_res->rx_vtpm_ipc_h = NULL;
-
-    if ( ((dmi_res->tx_tpm_ipc_h = (vtpm_ipc_handle_t *) malloc
(sizeof(vtpm_ipc_handle_t))) == NULL ) ||
-         ((dmi_res->tx_vtpm_ipc_h =(vtpm_ipc_handle_t *) malloc
(sizeof(vtpm_ipc_handle_t))) == NULL ) ||
-         ((tx_tpm_name = (char *) malloc(11 +
strlen(VTPM_TX_TPM_FNAME))) == NULL ) ||
-         ((tx_vtpm_name =(char *) malloc(11 +
strlen(VTPM_TX_VTPM_FNAME))) == NULL) ) {
-      status =TPM_RESOURCES;
-      goto abort_egress;
-    }
-
-    sprintf(tx_tpm_name, VTPM_TX_TPM_FNAME, (uint32_t) dmi_res->dmi_id);
-    sprintf(tx_vtpm_name, VTPM_TX_VTPM_FNAME, (uint32_t) dmi_res->dmi_id);
-
-    if ( (vtpm_ipc_init(dmi_res->tx_tpm_ipc_h, tx_tpm_name, O_WRONLY |
O_NONBLOCK, TRUE) != 0) ||
-         (vtpm_ipc_init(dmi_res->tx_vtpm_ipc_h, tx_vtpm_name, O_WRONLY,
TRUE) != 0) ) { //FIXME: O_NONBLOCK?
-      status = TPM_IOERROR;
-      goto abort_egress;
-    }
-
-    // Measure DMI
-    // FIXME: This will measure DMI. Until then use a fixed
DMI_Measurement value
-    // Also, this mechanism is specific to 1 VM architecture.
-    /*
-    fh = open(TPM_EMULATOR_PATH, O_RDONLY);
-    stat_ret = fstat(fh, &file_stat);
-    if (stat_ret == 0)
-      dmi_size = file_stat.st_size;
-    else {
-      vtpmlogerror(VTPM_LOG_VTPM, "Could not open vtpmd!!\n");
-      status = TPM_IOERROR;
-      goto abort_egress;
-    }
-    dmi_buffer
-    */
-    memset(&dmi_res->DMI_measurement, 0xcc, sizeof(TPM_DIGEST));
-
-    if (vm_type == VTPM_TYPE_PVM)
-      vm_type_string = (BYTE *)&VTPM_TYPE_PVM_STRING;
-    else
-      vm_type_string = (BYTE *)&VTPM_TYPE_HVM_STRING;
-
-    // Launch DMI
-    sprintf(dmi_id_str, "%d", (int) dmi_res->dmi_id);
-#ifdef MANUAL_DM_LAUNCH
-    vtpmlogerror(VTPM_LOG_VTPM, "Manually start VTPM with dmi=%s
now.\n", dmi_id_str);
-    dmi_res->dmi_pid = 0;
-#else
-    pid_t pid = fork();
-
-    if (pid == -1) {
-      vtpmlogerror(VTPM_LOG_VTPM, "Could not fork to launch vtpm\n");
-      status = TPM_RESOURCES;
-      goto abort_egress;
-    } else if (pid == 0) {
-      switch (startup_mode) {
-      case TPM_ST_CLEAR:
-        execl (TPM_EMULATOR_PATH, "vtpmd", "clear", vm_type_string,
dmi_id_str, NULL);
-        break;
-      case TPM_ST_STATE:
-        execl (TPM_EMULATOR_PATH, "vtpmd", "save", vm_type_string,
dmi_id_str, NULL);
-        break;
-      case TPM_ST_DEACTIVATED:
-        execl (TPM_EMULATOR_PATH, "vtpmd", "deactivated",
vm_type_string, dmi_id_str, NULL);
-        break;
-      default:
-        status = TPM_BAD_PARAMETER;
-        goto abort_egress;
-      }
-
-      // Returning from these at all is an error.
-      vtpmlogerror(VTPM_LOG_VTPM, "Could not exec to launch vtpm\n");
-    } else {
-      dmi_res->dmi_pid = pid;
-      vtpmloginfo(VTPM_LOG_VTPM, "Launching DMI on PID = %d\n", pid);
-    }
-#endif // MANUAL_DM_LAUNCH
-
-  } // If DMI = VTPM_CTL_DM
-    status = TPM_SUCCESS;
-
-abort_egress:
-  return (status);
-}
-
-TPM_RESULT VTPM_Close_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res) {
-  TPM_RESULT status = TPM_SUCCESS;
-
-  if (vtpm_globals->connected_dmis == 0) {
-    // No more DMI's connected. Close fifo to prevent a broken pipe.
-    // This is hackish. Need to think of another way.
-    vtpm_ipc_close(g_rx_tpm_ipc_h);
-  }
-
- 
-  if (dmi_res->dmi_id != VTPM_CTL_DM) {
-    vtpm_ipc_close(dmi_res->tx_tpm_ipc_h);
-    vtpm_ipc_close(dmi_res->tx_vtpm_ipc_h);
-
-    free(dmi_res->tx_tpm_ipc_h->name);
-    free(dmi_res->tx_vtpm_ipc_h->name);
-
-#ifndef MANUAL_DM_LAUNCH
-    if (dmi_res->dmi_id != VTPM_CTL_DM) {
-      if (dmi_res->dmi_pid != 0) {
-        vtpmloginfo(VTPM_LOG_VTPM, "Killing dmi on pid %d.\n",
dmi_res->dmi_pid);
-        if (kill(dmi_res->dmi_pid, SIGKILL) !=0) {
-          vtpmloginfo(VTPM_LOG_VTPM, "DMI on pid %d is already
dead.\n", dmi_res->dmi_pid);
-        } else if (waitpid(dmi_res->dmi_pid, NULL, 0) !=
dmi_res->dmi_pid) {
-          vtpmlogerror(VTPM_LOG_VTPM, "DMI on pid %d failed to
stop.\n", dmi_res->dmi_pid);
-          status = TPM_FAIL;
-        }
-      } else {
-        vtpmlogerror(VTPM_LOG_VTPM, "Could not kill dmi because it's
pid was 0.\n");
-        status = TPM_FAIL;
-      }
-    }
-#endif
-
-  } //endif ! dom0
-  return status;
-}
-
-
 int main(int argc, char **argv) {
-  vtpm_ipc_handle_t *tx_be_ipc_h, *rx_be_ipc_h, rx_tpm_ipc_h,
rx_vtpm_ipc_h, tx_hp_ipc_h, rx_hp_ipc_h;
-  struct vtpm_thread_params_s be_thread_params, dmi_thread_params,
hp_thread_params;
-  pthread_t be_thread, dmi_thread, hp_thread;
+  vtpm_ipc_handle_t *tx_be_ipc_h, *rx_be_ipc_h, tx_hp_ipc_h, rx_hp_ipc_h;
+  struct vtpm_thread_params_s be_thread_params, hp_thread_params;
+#ifndef VTPM_STUBDOM
+  vtpm_ipc_handle_t rx_tpm_ipc_h, rx_vtpm_ipc_h;
+  struct vtpm_thread_params_s dmi_thread_params;
+#endif
 
 #ifdef DUMMY_BACKEND
   vtpm_ipc_handle_t tx_dummy_ipc_h, rx_dummy_ipc_h;
@@ -258,34 +110,28 @@ int main(int argc, char **argv) {
 #endif
 
   vtpmloginfo(VTPM_LOG_VTPM, "Starting VTPM.\n");
-
-  // -------------------- Initialize Manager -----------------
-  if (VTPM_Init_Manager() != TPM_SUCCESS) {
-    vtpmlogerror(VTPM_LOG_VTPM, "Closing vtpmd due to error during
startup.\n");
-    return -1;
-  }
- 
+
   // -------------------- Setup Ctrl+C Handlers --------------
   ctl_c_handler.sa_handler = signal_handler;
   sigemptyset(&ctl_c_handler.sa_mask);
   ctl_c_handler.sa_flags = 0;   
  
-  if (sigaction(SIGINT, &ctl_c_handler, NULL) == -1)
+  if ((sigaction(SIGINT, &ctl_c_handler, NULL) == -1)
+    || (sigaction(SIGQUIT, &ctl_c_handler, NULL) == -1)
+    || (sigaction(SIGHUP, &ctl_c_handler, NULL) == -1) ) // For easier
debugging with gdb
+  {
     vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGINT handler.
Ctl+break will not stop manager gently.\n");
+  }
  
-  // For easier debuggin with gdb
-  if (sigaction(SIGHUP, &ctl_c_handler, NULL) == -1)
-    vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGHUP handler.
Ctl+break will not stop manager gently.\n");   
- 
+  //Block all signals for child threads
   sigset_t sig_mask;
-  sigemptyset(&sig_mask);
-  sigaddset(&sig_mask, SIGPIPE);
-  sigprocmask(SIG_BLOCK, &sig_mask, NULL);
+  sigfillset(&sig_mask);
+  pthread_sigmask(SIG_SETMASK, &sig_mask, NULL);
  
   // ------------------- Set up file ipc structures ----------
 #ifdef DUMMY_BACKEND
-  if ( (vtpm_ipc_init(&tx_dummy_ipc_h, VTPM_DUMMY_TX_BE_FNAME, O_RDWR,
TRUE) != 0) ||
-       (vtpm_ipc_init(&rx_dummy_ipc_h, VTPM_DUMMY_RX_BE_FNAME, O_RDWR,
TRUE) != 0) ) {
+  if ( (vtpm_ipc_init(&tx_dummy_ipc_h, VTPM_DUMMY_TX_BE_FNAME, O_RDWR,
TRUE, FALSE) != 0) ||
+       (vtpm_ipc_init(&rx_dummy_ipc_h, VTPM_DUMMY_RX_BE_FNAME, O_RDWR,
TRUE, FALSE) != 0) ) {
 
     vtpmlogerror(VTPM_LOG_VTPM, "Unable to create Dummy BE FIFOs.\n");
     exit(-1);
@@ -294,21 +140,29 @@ int main(int argc, char **argv) {
   tx_be_ipc_h = &tx_dummy_ipc_h;
   rx_be_ipc_h = &rx_dummy_ipc_h;
 #else
-  vtpm_ipc_init(&real_be_ipc_h, VTPM_BE_FNAME, O_RDWR, FALSE);
+  if(vtpm_ipc_init(&real_be_ipc_h, VTPM_BE_FNAME, O_RDWR, FALSE, TRUE)
!= 0) {
+     vtpmlogerror(VTPM_LOG_VTPM, "Unable to open backend device "
VTPM_BE_FNAME "\n");
+     exit(-1);
+  }
 
   tx_be_ipc_h = &real_be_ipc_h;
   rx_be_ipc_h = &real_be_ipc_h;
 #endif
 
-  if ( (vtpm_ipc_init(&rx_tpm_ipc_h, VTPM_RX_TPM_FNAME, O_RDONLY, TRUE)
!= 0) ||
-       (vtpm_ipc_init(&rx_vtpm_ipc_h, VTPM_RX_VTPM_FNAME, O_RDWR, TRUE)
!= 0) || //FIXME: O_RDONLY?
-       (vtpm_ipc_init(&tx_hp_ipc_h,  VTPM_TX_HP_FNAME, O_RDWR, TRUE) !=
0)    ||
-       (vtpm_ipc_init(&rx_hp_ipc_h,  VTPM_RX_HP_FNAME, O_RDWR, TRUE) !=
0) ) {
+  if (
+#ifndef VTPM_STUBDOM
+       (vtpm_ipc_init(&rx_tpm_ipc_h, VTPM_RX_TPM_FNAME, O_RDONLY, TRUE,
FALSE) != 0) ||
+       (vtpm_ipc_init(&rx_vtpm_ipc_h, VTPM_RX_VTPM_FNAME, O_RDWR, TRUE,
FALSE) != 0) || //FIXME: O_RDONLY?
+#endif
+       (vtpm_ipc_init(&tx_hp_ipc_h,  VTPM_TX_HP_FNAME, O_RDWR, TRUE,
TRUE) != 0)    ||
+       (vtpm_ipc_init(&rx_hp_ipc_h,  VTPM_RX_HP_FNAME, O_RDWR, TRUE,
TRUE) != 0) ) {
     vtpmlogerror(VTPM_LOG_VTPM, "Unable to create initial FIFOs.\n");
     exit(-1);
   }
 
+#ifndef VTPM_STUBDOM
   g_rx_tpm_ipc_h = &rx_tpm_ipc_h;
+#endif
 
   // -------------------- Set up thread params -------------
 
@@ -316,10 +170,15 @@ int main(int argc, char **argv) {
   be_thread_params.rx_ipc_h = rx_be_ipc_h;
   be_thread_params.fw_tpm = TRUE;
   be_thread_params.fw_tx_ipc_h = NULL;
+#ifndef VTPM_STUBDOM
   be_thread_params.fw_rx_ipc_h = &rx_tpm_ipc_h;
+#else
+  be_thread_params.fw_rx_ipc_h = NULL;
+#endif
   be_thread_params.is_priv = FALSE;
   be_thread_params.thread_name = "Backend Listener";
 
+#ifndef VTPM_STUBDOM
   dmi_thread_params.tx_ipc_h = NULL;
   dmi_thread_params.rx_ipc_h = &rx_vtpm_ipc_h;
   dmi_thread_params.fw_tpm = FALSE;
@@ -327,6 +186,7 @@ int main(int argc, char **argv) {
   dmi_thread_params.fw_rx_ipc_h = NULL;
   dmi_thread_params.is_priv = FALSE;
   dmi_thread_params.thread_name = "VTPM Listener";
+#endif
 
   hp_thread_params.tx_ipc_h = &tx_hp_ipc_h;
   hp_thread_params.rx_ipc_h = &rx_hp_ipc_h;
@@ -335,35 +195,51 @@ int main(int argc, char **argv) {
   hp_thread_params.fw_rx_ipc_h = NULL;
   hp_thread_params.is_priv = TRUE;
   hp_thread_params.thread_name = "Hotplug Listener";
+ 
+  // -------------------- Initialize Manager -----------------
+  if (VTPM_Init_Manager() != TPM_SUCCESS) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Closing vtpmd due to error during
startup.\n");
+    return -1;
+  }
+ 
 
   // --------------------- Launch Threads -----------------
 
   vtpm_lock_init();
 
-  vtpm_globals->master_pid = pthread_self();
+  master_thread = pthread_self();
+
  
   if (pthread_create(&be_thread, NULL, vtpm_manager_thread,
&be_thread_params) != 0) {
     vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch BE Thread.\n");
     exit(-1);
   }
  
+#ifndef VTPM_STUBDOM
   if (pthread_create(&dmi_thread, NULL, vtpm_manager_thread,
&dmi_thread_params) != 0) {
     vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch DMI Thread.\n");
     exit(-1);
   }
-
+#endif
 
   if (pthread_create(&hp_thread, NULL, vtpm_manager_thread,
&hp_thread_params) != 0) {
     vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch HP Thread.\n");
     exit(-1);
   }
 
+  //Turn signals back on for the master thread only
+  sigemptyset(&sig_mask);
+  sigaddset(&sig_mask, SIGPIPE);
+  pthread_sigmask(SIG_SETMASK, &sig_mask, NULL);
+
   //Join the other threads until exit time.
   pthread_join(be_thread, NULL);
+#ifndef VTPM_STUBDOM
   pthread_join(dmi_thread, NULL);
+#endif
   pthread_join(hp_thread, NULL);
 
-  vtpmlogerror(VTPM_LOG_VTPM, "VTPM Manager shut down unexpectedly.\n");
+  vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager shutting down...\n");
 
   VTPM_Stop_Manager();
   vtpm_lock_destroy();
diff --git a/tools/vtpm_manager/manager/vtpmpriv.h
b/tools/vtpm_manager/manager/vtpmpriv.h
--- a/tools/vtpm_manager/manager/vtpmpriv.h
+++ b/tools/vtpm_manager/manager/vtpmpriv.h
@@ -40,6 +40,8 @@
 #ifndef __VTPMPRIV_H__
 #define __VTPMPRIV_H__
 
+#include <signal.h>
+
 #include "vtpm_manager.h"
 #include "tcg.h"
 #include "tcs.h"
@@ -54,16 +56,19 @@
 #define DMI_NVM_FILE       "/var/vtpm/vtpm_dm_%d.data"
 #define VTPM_CTL_DM        0
 
+extern volatile sig_atomic_t HANDLER_QUIT_FLAG;
+
 // ------------------------ Private Structures -----------------------
 typedef struct VTPM_DMI_RESOURCE_T {
+#ifndef VTPM_STUBDOM
   // I/O info for Manager to talk to DMI's and controllers
   vtpm_ipc_handle_t      *tx_vtpm_ipc_h;    // TX VTPM Results to DMI
   vtpm_ipc_handle_t      *rx_vtpm_ipc_h;    // RX VTPM Commands from DMI
   vtpm_ipc_handle_t      *tx_tpm_ipc_h;     // TX TPM Commands to DMI
   vtpm_ipc_handle_t      *rx_tpm_ipc_h;     // RX TPM Results from DMI
+
+  pid_t                  dmi_pid;
 
-#ifndef VTPM_MULTI_VM
-  pid_t                 dmi_pid;
 #endif
 
   // Non-persistent Information
@@ -77,6 +82,9 @@ typedef struct VTPM_DMI_RESOURCE_T {
   BYTE                  dmi_type;
   TPM_DIGEST            NVM_measurement;  // Equal to the SHA1 of the blob
   TPM_DIGEST            DMI_measurement;  // Correct measurement of the
owning DMI
+
+  char* uuid;
+
 } VTPM_DMI_RESOURCE;
 
 typedef struct tdVTPM_MIGKEY_LIST {
@@ -89,10 +97,6 @@ typedef struct tdVTPM_MIGKEY_LIST {
 
 typedef struct tdVTPM_GLOBALS {
   // Non-persistent data
-#ifndef VTPM_MULTI_VM
-  pid_t               master_pid;
-#endif
-
   int                 connected_dmis;     // To close guest_rx when no
dmis are connected
 
   struct hashtable    *dmi_map;               // Table of all DMI's
known indexed by persistent instance #
@@ -123,8 +127,8 @@ extern VTPM_GLOBALS *vtpm_globals;   // Key info and
DMI states
 extern const TPM_AUTHDATA SRK_AUTH;  // SRK Well Known Auth Value
 
 // ********************** VTPM Functions *************************
-TPM_RESULT VTPM_Init_Manager(); // Start VTPM Service
-void VTPM_Stop_Manager();  // Stop VTPM Service
+TPM_RESULT VTPM_Init_Manager(void); // Start VTPM Service
+void VTPM_Stop_Manager(void);  // Stop VTPM Service
 TPM_RESULT VTPM_Manager_Handler(vtpm_ipc_handle_t *tx_ipc_h,
                                 vtpm_ipc_handle_t *rx_ipc_h,
                                 BOOL fw_tpm,   // Should forward TPM cmds
@@ -143,6 +147,11 @@ TPM_RESULT VTPM_Handle_Save_NVM(      
VTPM_DMI_RESOURCE *myDMI,
                                         const buffer_t *inbuf,
                                         buffer_t *outbuf);
 
+TPM_RESULT VTPM_Handle_Get_NVM_Size(   VTPM_DMI_RESOURCE *myDMI,
+                                        const buffer_t *inbuf,
+                                        buffer_t *outbuf);
+
+
 TPM_RESULT VTPM_Handle_TPM_Command(    VTPM_DMI_RESOURCE *dmi,
                                         buffer_t *inbuf,
                                         buffer_t *outbuf);
@@ -173,6 +182,9 @@ TPM_RESULT VTPM_Close_DMI_Extra(VTPM_DMI_RESOURCE
*dmi_res);
 TPM_RESULT close_dmi(VTPM_DMI_RESOURCE *dmi_res);
 TPM_RESULT init_dmi(UINT32 dmi_id, BYTE type,  VTPM_DMI_RESOURCE
**dmi_res);
 
+/* Free's dmi_res and all of it's resources */
+void free_dmi(VTPM_DMI_RESOURCE *dmi_res);
+
 TPM_RESULT envelope_encrypt(const buffer_t     *inbuf,
                              CRYPTO_INFO        *asymkey,
                              buffer_t           *sealed_data);
@@ -183,4 +195,14 @@ TPM_RESULT envelope_decrypt(const buffer_t     *cipher,
                             const TPM_AUTHDATA *key_usage_auth,
                             buffer_t           *unsealed_data);
 
+TPM_RESULT symkey_encrypt(const buffer_t     *inbuf,
+                            CRYPTO_INFO        *asymkey,
+                            buffer_t           *sealed_key);
+
+TPM_RESULT symkey_decrypt(const buffer_t     *cipher,
+                            TCS_CONTEXT_HANDLE TCSContext,
+                TPM_HANDLE         keyHandle,
+                const TPM_AUTHDATA *key_usage_auth,
+                            buffer_t           *symkey_clear);
+
 #endif // __VTPMPRIV_H__
diff --git a/tools/vtpm_manager/manager/vtsp.c
b/tools/vtpm_manager/manager/vtsp.c
--- a/tools/vtpm_manager/manager/vtsp.c
+++ b/tools/vtpm_manager/manager/vtsp.c
@@ -38,6 +38,7 @@
 // ==================================================================
 
 #include <string.h>
+#include <stdlib.h>
 #include "tcg.h"
 #include "tcs.h"
 #include "bsg.h"
@@ -312,7 +313,7 @@ TPM_RESULT VTSP_TakeOwnership(   const
TCS_CONTEXT_HANDLE hContext,
   TPM_PROTOCOL_ID proto_id = TPM_PID_OWNER;
   BYTE *new_srk;
  
-  BYTE *paramText;        // Digest to make Auth.
+  BYTE *paramText = NULL;        // Digest to make Auth.
   UINT32 paramTextSize;
  
   // vars for srkpubkey parameter
@@ -458,7 +459,7 @@ TPM_RESULT VTSP_CreateWrapKey(  const
TCS_CONTEXT_HANDLE hContext,
   vtpmloginfo(VTPM_LOG_VTSP, "Creating new key of type %d.\n", usage);
  
   // vars for Calculate encUsageAuth
-  BYTE *paramText;     
+  BYTE *paramText = NULL;
   UINT32 paramTextSize;
  
   // vars for Calculate encUsageAuth
@@ -567,8 +568,7 @@ TPM_RESULT VTSP_CreateWrapKey(  const
TCS_CONTEXT_HANDLE hContext,
                 osapSharedSecret, auth, 0) );
  
   // Unpack/return key structure
-  TPMTRYRETURN(buffer_init(pubKeyBuf, 0, 0) );
-  TPMTRYRETURN(buffer_append_raw(pubKeyBuf, newKeyText.size,
newKeyText.data) );
+  TPMTRYRETURN(buffer_init(pubKeyBuf, newKeyText.size, newKeyText.data) );
  
   goto egress;
  
@@ -664,6 +664,7 @@ TPM_RESULT VTSP_LoadKey(const TCS_CONTEXT_HANDLE   
hContext,
    
     // Destroy rsaKeyParms
     BSG_Destroy(BSG_TPM_RSA_KEY_PARMS, &rsaKeyParms);
+    BSG_Destroy(BSG_TPM_KEY, &newKey);
    
     // Set encryption scheme
     cryptoinfo->encScheme = CRYPTO_ES_RSAESOAEP_SHA1_MGF1;
@@ -733,8 +734,7 @@ TPM_RESULT VTSP_Unbind( const TCS_CONTEXT_HANDLE   
hContext,
                 hContext) );
  
   // Unpack/return key structure
-  TPMTRYRETURN(buffer_init(clear_data, 0, 0));
-  TPMTRYRETURN(buffer_append_raw (clear_data, clear_data_size,
clear_data_text) );
+  TPMTRYRETURN(buffer_init(clear_data, clear_data_size, clear_data_text) );
  
   goto egress;
  
@@ -793,8 +793,7 @@ TPM_RESULT VTSP_Bind(   CRYPTO_INFO *cryptoInfo,
     vtpmlogerror(VTPM_LOG_VTSP, "Enc buffer just overflowed.\n");
   }
  
-  buffer_init(outData, 0, NULL);
-  buffer_append_raw(outData, out_tmp_size, out_tmp);
+  buffer_init(outData, out_tmp_size, out_tmp);
  
   vtpmloginfo(VTPM_LOG_TXDATA, "Bind Generated[%d] = 0x", out_tmp_size);
   for(i = 0 ; i < out_tmp_size ; i++) {
@@ -1005,8 +1004,6 @@ TPM_RESULT VTSP_SaveState( const
TCS_CONTEXT_HANDLE    hContext) {
 
   vtpmloginfo(VTPM_LOG_VTSP, "Calling TPM_SaveState.\n");
 
-  TPM_RESULT status = TPM_SUCCESS;
-
   // Call TCS
   return ( TCSP_SaveState ( hContext ) );
 
@@ -1040,3 +1037,4 @@ TPM_RESULT VTSP_RawTransmit(const
TCS_CONTEXT_HANDLE    hContext,
   free(resultText);
   return status;
 }
+
diff --git a/tools/vtpm_manager/manager/vtsp.h
b/tools/vtpm_manager/manager/vtsp.h
--- a/tools/vtpm_manager/manager/vtsp.h
+++ b/tools/vtpm_manager/manager/vtsp.h
@@ -42,6 +42,7 @@
 
 #include "tcg.h"
 #include "tcs.h"
+#include "crypto.h"
 
 #define KEY_BUFFER_SIZE 2048
 
diff --git a/tools/vtpm_manager/migration/Makefile
b/tools/vtpm_manager/migration/Makefile
--- a/tools/vtpm_manager/migration/Makefile
+++ b/tools/vtpm_manager/migration/Makefile
@@ -1,5 +1,11 @@
-XEN_ROOT = $(CURDIR)/../../..
-include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
+XEN_ROOT = $(realpath ../../..)
+include ../Rules.mk
+
+CFLAGS += -I../crypto
+CFLAGS += -I../util
+CFLAGS += -I../tcs
+CFLAGS += -I../manager
+
 
 VPATH = ../manager
 
@@ -33,10 +39,10 @@ mrproper: clean
     rm -f *~
 
 $(BIND): $(OBJSD)
-    $(CC) $(LDFLAGS) $^ $(LIBS) -o $@
+    $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@
 
 $(BINC): $(OBJSC)
-    $(CC) $(LDFLAGS) $^ $(LIBS) -o $@
+    $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@
 
 # libraries
 LIBS += ../util/libTCGUtils.a
diff --git a/tools/vtpm_manager/migration/vtpm_manager_if.c
b/tools/vtpm_manager/migration/vtpm_manager_if.c
--- a/tools/vtpm_manager/migration/vtpm_manager_if.c
+++ b/tools/vtpm_manager/migration/vtpm_manager_if.c
@@ -50,15 +50,12 @@
 #include "vtpm_migrator.h"
 #include "vtpm_manager.h"
 
-#define VTPM_TX_HP_FNAME       "/var/vtpm/fifos/from_console.fifo"
-#define VTPM_RX_HP_FNAME       "/var/vtpm/fifos/to_console.fifo"
-
 static vtpm_ipc_handle_t tx_ipc_h, rx_ipc_h;
 
 TPM_RESULT vtpm_manager_open(){
 
-  if ( (vtpm_ipc_init(&tx_ipc_h,  VTPM_TX_HP_FNAME, O_RDWR, TRUE) != 0)
||  //FIXME: wronly
-       (vtpm_ipc_init(&rx_ipc_h,  VTPM_RX_HP_FNAME, O_RDWR, TRUE) != 0)
) { //FIXME: rdonly
+  if ( (vtpm_ipc_init(&tx_ipc_h,  VTPM_TX_HP_FNAME, O_RDWR, TRUE, TRUE)
!= 0) ||  //FIXME: wronly
+       (vtpm_ipc_init(&rx_ipc_h,  VTPM_RX_HP_FNAME, O_RDWR, TRUE, TRUE)
!= 0) ) { //FIXME: rdonly
     vtpmlogerror(VTPM_LOG_VTPM, "Unable to connect to vtpm_manager.\n");
     return TPM_IOERROR;
   }
diff --git a/tools/vtpm_manager/tcs/Makefile
b/tools/vtpm_manager/tcs/Makefile
--- a/tools/vtpm_manager/tcs/Makefile
+++ b/tools/vtpm_manager/tcs/Makefile
@@ -1,5 +1,10 @@
-XEN_ROOT = $(CURDIR)/../../..
-include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
+XEN_ROOT = $(realpath ../../..)
+include ../Rules.mk
+
+CFLAGS += -I../crypto
+CFLAGS += -I../util
+CFLAGS += -I../manager
+
 
 BIN        = libTCS.a
 
diff --git a/tools/vtpm_manager/tcs/contextmgr.c
b/tools/vtpm_manager/tcs/contextmgr.c
--- a/tools/vtpm_manager/tcs/contextmgr.c
+++ b/tools/vtpm_manager/tcs/contextmgr.c
@@ -195,6 +195,7 @@ BOOL DeleteHandleFromList(   TCS_CONTEXT_HANDLE
hContext, // in
 
 BOOL FreeHandleList(    CONTEXT_HANDLE*     pContextHandle) { // in
   HANDLE_LIST* pCurrentHandle;
+  HANDLE_LIST* pNext;
   BOOL returncode = TRUE;
  
   vtpmloginfo(VTPM_LOG_TCS_DEEP, "Freeing all handles for context\n");
@@ -205,6 +206,7 @@ BOOL FreeHandleList(    CONTEXT_HANDLE*    
pContextHandle) { // in
   pCurrentHandle = pContextHandle->pHandleList;
   while (pCurrentHandle != NULL) {
    
+    pNext = pCurrentHandle->pNextHandle;
     switch (pCurrentHandle->type) {
     case TPM_RT_KEY:
       returncode = returncode && !TCSP_EvictKey(pContextHandle->handle,
pCurrentHandle->handle);
@@ -216,7 +218,7 @@ BOOL FreeHandleList(    CONTEXT_HANDLE*    
pContextHandle) { // in
       returncode = FALSE;
     }
    
-    pCurrentHandle = pCurrentHandle->pNextHandle;
+    pCurrentHandle = pNext;
    
   }
  
diff --git a/tools/vtpm_manager/tcs/tcs.c b/tools/vtpm_manager/tcs/tcs.c
--- a/tools/vtpm_manager/tcs/tcs.c
+++ b/tools/vtpm_manager/tcs/tcs.c
@@ -77,7 +77,7 @@ CONTEXT_HANDLE *LookupContext( TCS_CONTEXT_HANDLE 
hContext) {
 //
---------------------------------------------------------------------------------
 // Initialization/Uninitialization SubComponent API
 //
---------------------------------------------------------------------------------
-TPM_RESULT TCS_create() {
+TPM_RESULT TCS_create(void) {
   TDDL_RESULT hRes = TDDL_E_FAIL;
   TPM_RESULT result = TPM_FAIL;
  
@@ -101,7 +101,7 @@ TPM_RESULT TCS_create() {
 }
 
 
-void TCS_destroy()
+void TCS_destroy(void)
 {
   TCS_m_nCount--;
  
@@ -113,14 +113,13 @@ void TCS_destroy()
     TCS_CONTEXT_HANDLE  *hContext;
    
     // Close all the TCS contexts. TCS should evict keys based on this
-    if (hashtable_count(context_ht) > 0) {
+    while (hashtable_count(context_ht) > 0) {
       context_itr = hashtable_iterator(context_ht);
-      do {
-        hContext = (TCS_CONTEXT_HANDLE *)
hashtable_iterator_key(context_itr);
-    if (TCS_CloseContext(*hContext) != TPM_SUCCESS)
-        vtpmlogerror(VTPM_LOG_TCS, "Failed to close context %d
properly.\n", *hContext);
+
+      hContext = (TCS_CONTEXT_HANDLE *)
hashtable_iterator_key(context_itr);
+      if (TCS_CloseContext(*hContext) != TPM_SUCCESS)
+        vtpmlogerror(VTPM_LOG_TCS, "Failed to close context %d
properly.\n", *hContext);
      
-      } while (hashtable_iterator_advance(context_itr));
       free(context_itr);
     }
     hashtable_destroy(context_ht, 1);
@@ -534,6 +533,10 @@ TPM_RESULT TCSP_TerminateHandle(TCS_CONTEXT_HANDLE
hContext, // in
               BSG_TYPE_UINT32, &handle);
   // fill paramSize again as we now have the correct size
   BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2);
+
+  if (!DeleteHandleFromList(hContext, handle)) {
+    vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n");
+  }
  
   // call the TPM driver
   if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength))
@@ -545,9 +548,6 @@ TPM_RESULT TCSP_TerminateHandle(TCS_CONTEXT_HANDLE
hContext, // in
                BSG_TYPE_UINT32, &paramSize,
                BSG_TPM_COMMAND_CODE, &returnCode);
    
-    if (!DeleteHandleFromList(hContext, handle))
-      vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n");
-      
    
     if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_COMMAND) {
       // Print debug info
@@ -882,6 +882,7 @@ TPM_RESULT TCSP_CreateWrapKey(TCS_CONTEXT_HANDLE
hContext,   // in
      
       memcpy(*prgbKey, tempBuf, *pcKeySize);
      
+      BSG_Destroy(BSG_TPM_KEY, &wrappedKey);
       vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n",
paramSize);
     } else
       vtpmlogerror(VTPM_LOG_TCS, "TCSP_CreateWrapKey Failed with return
code %s\n", tpm_get_error_name(returnCode));
@@ -980,6 +981,10 @@ TPM_RESULT TCSP_EvictKey(TCS_CONTEXT_HANDLE
hContext, // in
   BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2);
  
   vtpmloginfo(VTPM_LOG_TCS_DEEP, "Sending paramSize = %d\n", InLength);
+
+  if (!DeleteHandleFromList(hContext, hKey)) {
+    vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n");
+  }     
  
   // call the TPM driver
   if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength))
== TDDL_SUCCESS) {
@@ -989,10 +994,6 @@ TPM_RESULT TCSP_EvictKey(TCS_CONTEXT_HANDLE
hContext, // in
                BSG_TYPE_UINT32, &paramSize,
                BSG_TPM_COMMAND_CODE, &returnCode);
    
-    if (!DeleteHandleFromList(hContext, hKey)) {
-      vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n");
-    }     
-   
     if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_COMMAND) {
       vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n",
paramSize);
     } else {
@@ -1019,7 +1020,7 @@ TPM_RESULT TCSP_GetRandom(TCS_CONTEXT_HANDLE
hContext,  // in
   TDDL_UINT32  OutLength = TCPA_MAX_BUFFER_LENGTH;
  
   // check input params
-  if (bytesRequested == NULL || *randomBytes == NULL){
+  if (bytesRequested == NULL || randomBytes == NULL){
     return TPM_BAD_PARAMETER;
   }
  
diff --git a/tools/vtpm_manager/tcs/tcs.h b/tools/vtpm_manager/tcs/tcs.h
--- a/tools/vtpm_manager/tcs/tcs.h
+++ b/tools/vtpm_manager/tcs/tcs.h
@@ -50,8 +50,8 @@
 // Exposed API
 // ------------------------------------------------------------------
 
-TPM_RESULT TCS_create();
-void TCS_destroy();
+TPM_RESULT TCS_create(void);
+void TCS_destroy(void);
 
 TPM_RESULT TCS_OpenContext( /* OUT */ TCS_CONTEXT_HANDLE* hContext );
 
diff --git a/tools/vtpm_manager/tcs/tpmddl.c
b/tools/vtpm_manager/tcs/tpmddl.c
--- /dev/null
+++ b/tools/vtpm_manager/tcs/tpmddl.c
@@ -0,0 +1,168 @@
+/*
+ * 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 <string.h>
+#include "tpmddl.h"
+#include "tcs.h"
+#include "bsg.h"
+#include "log.h"
+
+#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
+
+TDDL_RESULT TDDL_GetCapability( TDDL_UINT32 cap,
+      TDDL_UINT32 sub,
+      TDDL_BYTE* buffer,
+      TDDL_UINT32* size)
+{
+   TDDL_RESULT status;
+
+   TPM_TAG tag = TPM_TAG_RQU_COMMAND;
+   UINT32 paramsize = 22;
+   UINT32 outsize;
+   TPM_COMMAND_CODE ord = TPM_ORD_GetCapability;
+   UINT32 subcapsize = 4;
+
+   BYTE inbuf[TCPA_MAX_BUFFER_LENGTH];
+   BYTE outbuf[TCPA_MAX_BUFFER_LENGTH];
+
+   int offset;
+
+   BSG_PackList(inbuf, 6,
+     BSG_TPM_TAG, &(tag),
+     BSG_TYPE_UINT32, &(paramsize),
+     BSG_TPM_COMMAND_CODE, &(ord),
+     BSG_TYPE_UINT32, &(cap),
+     BSG_TYPE_UINT32, &(subcapsize),
+     BSG_TYPE_UINT32, &(sub)
+     );
+
+   //Send the command, get the response
+   TPMTRYRETURN(TDDL_TransmitData( inbuf, paramsize, outbuf, &outsize));
+
+   offset = BSG_UnpackList(outbuf, 4,
+     BSG_TPM_TAG, &(tag),
+     BSG_TYPE_UINT32, &(paramsize),
+     BSG_TPM_RESULT, &(status),
+     BSG_TYPE_UINT32, size
+     );
+   if (status != TPM_SUCCESS || tag != TPM_TAG_RSP_COMMAND) {
+      return status;
+   }
+   if(*size >= TCPA_MAX_BUFFER_LENGTH - offset) {
+      return TPM_FAIL;
+   }
+   memcpy(buffer, outbuf + offset, *size);
+
+abort_egress:
+   return status;
+}
+
+TDDL_RESULT TDDL_FlushSpecific(TDDL_UINT32 handle, TDDL_UINT32 res) {
+    /* FIXME: Add code here to check if TPM_FlushSpecific is not
supported (on 1.1 only TPMS?)
+    * If this is the case then we need to use TPM_EvictKey for key handles
+    * and TPM_Terminate_Handle/TPM_Reset for auth handles */
+   TDDL_RESULT status;
+
+   TPM_TAG tag = TPM_TAG_RQU_COMMAND;
+   UINT32 paramsize = 18;
+   TPM_COMMAND_CODE ord = TPM_ORD_FlushSpecific;
+
+   BYTE inbuf[TCPA_MAX_BUFFER_LENGTH];
+   BYTE outbuf[TCPA_MAX_BUFFER_LENGTH];
+   UINT32 outsize;
+
+   int offset;
+
+   BSG_PackList(inbuf, 5,
+     BSG_TPM_TAG, &(tag),
+     BSG_TYPE_UINT32, &(paramsize),
+     BSG_TPM_COMMAND_CODE, &(ord),
+     BSG_TPM_HANDLE, &(handle),
+     BSG_TPM_RESOURCE_TYPE, &(res)
+     );
+
+   //Send command
+   TPMTRYRETURN(TDDL_TransmitData( inbuf, paramsize, outbuf, &outsize ));
+
+   offset = BSG_UnpackList(outbuf, 4,
+     BSG_TPM_TAG, &(tag),
+     BSG_TYPE_UINT32, &(paramsize),
+     BSG_TPM_RESULT, &(status)
+     );
+
+abort_egress:
+   return status;
+  
+}
+
+TDDL_RESULT TDDL_FlushAllResources(void) {
+  TDDL_RESULT status = TPM_SUCCESS;
+
+  TDDL_BYTE buf[TCPA_MAX_BUFFER_LENGTH];
+  TDDL_UINT32 bufsiz;
+
+  UINT16 packedsz;
+  int size;
+  UINT32 handle;
+  BYTE* ptr;
+
+  int i, j;
+
+#define RLISTSZ 6
+  TPM_RESOURCE_TYPE reslist[RLISTSZ] = { TPM_RT_KEY, TPM_RT_AUTH,
TPM_RT_TRANS, TPM_RT_COUNTER, TPM_RT_DAA_TPM, TPM_RT_CONTEXT };
+
+  //Iterate through each resource type and flush all handles
+  for(i = 0; i < RLISTSZ; ++i) {
+     TPM_RESOURCE_TYPE res = reslist[i];
+     // Get list of current key handles
+     if((status = TDDL_GetCapability( TPM_CAP_HANDLE, res, buf,
&bufsiz)) != TPM_SUCCESS) {
+    //This can happen if the resource type is not supported
+    //If this happens just silently skip the resource type
+    if(status == TPM_BAD_MODE) {
+       status = TPM_SUCCESS;
+       continue;
+    //Otherwise we just fail
+    } else {
+       TPMTRYRETURN(status);
+    }
+     }
+
+#if 0
+     //DEBUG PRINTOUTS
+     printf("TPM_GetCapability(TPM_CAP_HANDLE, %lu)\n", (unsigned long)
res);
+     for(j = 0; j < bufsiz; ++j) {
+    printf("%02X ", buf[j]);
+     }
+     printf("\n");
+#endif
+
+     ptr = buf;
+     ptr += BSG_Unpack(BSG_TYPE_UINT16, ptr, &(packedsz));
+     size = packedsz;
+
+     //Flush each handle
+     if(size) {
+    vtpmloginfo(VTPM_LOG_VTPM, "Flushing %u handle(s) of type %lu\n",
size, (unsigned long) res);
+    for(j = 0; j < size; ++j) {
+       ptr += BSG_Unpack(BSG_TPM_HANDLE, ptr, &(handle));
+       TPMTRYRETURN(TDDL_FlushSpecific(handle, res));
+    }
+     }
+
+  }
+
+  goto egress;
+abort_egress:
+egress:
+  return status;
+}
+
diff --git a/tools/vtpm_manager/tcs/tpmddl.h
b/tools/vtpm_manager/tcs/tpmddl.h
--- a/tools/vtpm_manager/tcs/tpmddl.h
+++ b/tools/vtpm_manager/tcs/tpmddl.h
@@ -50,13 +50,14 @@ typedef unsigned int TDDL_UINT32;
 typedef TDDL_UINT32 TDDL_RESULT;
 typedef unsigned char TDDL_BYTE;
 
-TDDL_RESULT TDDL_Open();
-void TDDL_Close();
+TDDL_RESULT TDDL_Open(void);
+TDDL_RESULT TDDL_Open_use_fd(int fd);
+void TDDL_Close(void);
 TDDL_RESULT TDDL_TransmitData( TDDL_BYTE* in,
                    TDDL_UINT32 insize,
                    TDDL_BYTE* out,
                    TDDL_UINT32* outsize);
-TDDL_RESULT TDDL_GetStatus();
+TDDL_RESULT TDDL_GetStatus(void);
 TDDL_RESULT TDDL_GetCapability( TDDL_UINT32 cap,
                 TDDL_UINT32 sub,
                 TDDL_BYTE* buffer,
@@ -66,4 +67,10 @@ TDDL_RESULT TDDL_SetCapability( TDDL_UINT32 cap,
                 TDDL_BYTE* buffer,
                 TDDL_UINT32* size);
 
+TDDL_RESULT TDDL_FlushSpecific(TDDL_UINT32 handle,
+                TDDL_UINT32 res);
+
+TDDL_RESULT TDDL_FlushAllResources(void);
+
+
 #endif // __TPMDDL_H__
diff --git a/tools/vtpm_manager/tcs/transmit.c
b/tools/vtpm_manager/tcs/transmit.c
--- a/tools/vtpm_manager/tcs/transmit.c
+++ b/tools/vtpm_manager/tcs/transmit.c
@@ -104,12 +104,13 @@ TDDL_TransmitData( TDDL_BYTE* in,
   return status;
 }
 
-TPM_RESULT TDDL_Open() {
+TDDL_RESULT TDDL_Open(void) {
  
   TDDL_RESULT status = TDDL_SUCCESS;
  
+  /* If tpm device is already open just silently return success */
   if (g_TDDL_open)
-    return TPM_FAIL;
+    return TPM_SUCCESS;
 
 #ifdef DUMMY_TPM 
   *g_rx_fdp = open (TPM_RX_FNAME, O_RDWR);
@@ -117,7 +118,7 @@ TPM_RESULT TDDL_Open() {
 
   g_tx_fd = open (TPM_TX_FNAME, O_RDWR);
   if (g_tx_fd < 0) {
-    vtpmlogerror(VTPM_LOG_TXDATA, "TPM open failed");
+    vtpmlogerror(VTPM_LOG_TXDATA, "TPM open failed\n");
     return TPM_IOERROR;
   }
  
@@ -126,7 +127,20 @@ TPM_RESULT TDDL_Open() {
   return status;
 }
 
-void TDDL_Close() {
+TDDL_RESULT TDDL_Open_use_fd(int fd) {
+   TDDL_RESULT status = TDDL_SUCCESS;
+
+   if(g_TDDL_open)
+      return TPM_FAIL;
+
+   g_tx_fd = fd;
+
+   g_TDDL_open = 1;
+
+   return status;
+}
+
+void TDDL_Close(void) {
   if (! g_TDDL_open)
         return;
 
diff --git a/tools/vtpm_manager/util/Makefile
b/tools/vtpm_manager/util/Makefile
--- a/tools/vtpm_manager/util/Makefile
+++ b/tools/vtpm_manager/util/Makefile
@@ -1,5 +1,10 @@
-XEN_ROOT = $(CURDIR)/../../..
-include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
+XEN_ROOT = $(realpath ../../..)
+include ../Rules.mk
+
+CFLAGS += -I../crypto
+CFLAGS += -I../tcs
+CFLAGS += -I../manager
+
 
 BIN        = libTCGUtils.a
 
diff --git a/tools/vtpm_manager/util/bsg.c b/tools/vtpm_manager/util/bsg.c
--- a/tools/vtpm_manager/util/bsg.c
+++ b/tools/vtpm_manager/util/bsg.c
@@ -41,6 +41,7 @@
 #include <string.h>
 #include <stdarg.h>
 #include <malloc.h>
+#include <stdlib.h>
 #include "tcg.h"
 #include "crypto.h"
 #include "bsg.h"
@@ -317,7 +318,7 @@ static const BSG_Format* find_format (BSG_Type t) {
 // FIXME: should have a function be passed in here which is called if
the test
 // fails. Then the caller can decide what to do: abort, notify, whatever
 //
-BOOL BSG_static_selfcheck ()
+BOOL BSG_static_selfcheck (void)
 {
   int i;
 
diff --git a/tools/vtpm_manager/util/bsg.h b/tools/vtpm_manager/util/bsg.h
--- a/tools/vtpm_manager/util/bsg.h
+++ b/tools/vtpm_manager/util/bsg.h
@@ -161,6 +161,6 @@ TPM_RESULT BSG_DestroyTuple (int numParams,
pack_tuple_t params[]);
 void BSG_PackConst(BSG_UINT32 val, int size, BSG_BYTE* dst);
 BSG_UINT32 BSG_UnpackConst(const BSG_BYTE* src, int size);
 
-BOOL BSG_static_selfcheck ();
+BOOL BSG_static_selfcheck (void);
 
 #endif
diff --git a/tools/vtpm_manager/util/buffer.c
b/tools/vtpm_manager/util/buffer.c
--- a/tools/vtpm_manager/util/buffer.c
+++ b/tools/vtpm_manager/util/buffer.c
@@ -40,6 +40,7 @@
 
 #include "tcg.h"
 #include "bsg.h"
+#include "log.h"
 #include "buffer.h"
 
 static TPM_RESULT buffer_priv_realloc (buffer_t * buf, tpm_size_t newsize);
@@ -51,6 +52,7 @@ static TPM_RESULT buffer_priv_realloc (buffer_t * buf,
tpm_size_t newsize);
 TPM_RESULT buffer_init (buffer_t * buf, tpm_size_t initsize, const
BYTE* initval) {
   if (initsize == 0) {
     memset(buf, 0, sizeof(*buf));
+    buf->bytes = NULL;
     return TPM_SUCCESS;
   }
  
@@ -62,8 +64,11 @@ TPM_RESULT buffer_init (buffer_t * buf, tpm_size_t
initsize, const BYTE* initval
   buf->size = initsize;
   buf->alloc_size = initsize;
  
-  if (initval)
+  if (initval) {
     memcpy (buf->bytes, initval, initsize);
+  } else {
+     memset(buf->bytes, 0, initsize);
+  }
  
   buf->is_owner = TRUE;
  
@@ -190,6 +195,29 @@ TPM_RESULT buffer_append_raw (buffer_t * buf,
tpm_size_t len, const BYTE* bytes)
   return status;
 }
 
+TPM_RESULT buffer_prepend_raw(buffer_t * buf, tpm_size_t len, const
BYTE* bytes) {
+  TPM_RESULT status = TPM_SUCCESS;
+
+  if (buf->alloc_size < buf->size + len) {
+    TPMTRYRETURN( buffer_priv_realloc (buf, buf->size + len) );
+  }
+
+  if(buf->size > 0) {
+    memmove(buf->bytes + len, buf->bytes, buf->size);
+  }
+  memcpy(buf->bytes, bytes, len);
+
+  buf->size += len;
+
+  goto egress;
+
+ abort_egress:
+
+ egress:
+
+  return status;
+}
+
 tpm_size_t buffer_len (const buffer_t* buf) {
   return buf->size;
 }
@@ -199,7 +227,6 @@ TPM_RESULT buffer_free (buffer_t * buf) {
     free (buf->bytes);
     buf->bytes = NULL;
     buf->size = buf->alloc_size = 0;
-  
   }
  
   return TPM_SUCCESS;
@@ -224,3 +251,13 @@ TPM_RESULT buffer_priv_realloc (buffer_t * buf,
tpm_size_t newsize) {
  
   return TPM_SUCCESS;
 }
+
+TPM_RESULT buffer_truncate(buffer_t* buf, tpm_size_t len)
+{
+   if(len <= buf->size) {
+      buf->size = len;
+      return TPM_SUCCESS;
+   }
+
+   return TPM_FAIL;
+}
diff --git a/tools/vtpm_manager/util/buffer.h
b/tools/vtpm_manager/util/buffer.h
--- a/tools/vtpm_manager/util/buffer.h
+++ b/tools/vtpm_manager/util/buffer.h
@@ -92,4 +92,9 @@ TPM_RESULT buffer_free (buffer_t * buf);
 
 TPM_RESULT buffer_append_raw (buffer_t * buf, tpm_size_t len, const
BYTE* bytes);
 
+TPM_RESULT buffer_prepend_raw(buffer_t * buf, tpm_size_t len, const
BYTE* bytes);
+
+//Reduce the size of the buffer, if len > buffer size returns an error
+TPM_RESULT buffer_truncate(buffer_t* buf, tpm_size_t len);
+
 #endif // _TOOLS_H_
diff --git a/tools/vtpm_manager/util/hashtable.c
b/tools/vtpm_manager/util/hashtable.c
--- a/tools/vtpm_manager/util/hashtable.c
+++ b/tools/vtpm_manager/util/hashtable.c
@@ -32,12 +32,6 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-/*
- * There are duplicates of this code in:
- *  - tools/xenstore/hashtable.c
- *  - tools/blktap2/drivers/hashtable.c
- */
-
 #include "hashtable.h"
 #include "hashtable_private.h"
 #include <stdlib.h>
diff --git a/tools/vtpm_manager/util/hashtable.h
b/tools/vtpm_manager/util/hashtable.h
--- a/tools/vtpm_manager/util/hashtable.h
+++ b/tools/vtpm_manager/util/hashtable.h
@@ -32,11 +32,6 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-/*
- * There are duplicates of this code in:
- *  - tools/xenstore/hashtable.h
- *  - tools/blktap2/drivers/hashtable.h
- */
 
 #ifndef __HASHTABLE_CWC22_H__
 #define __HASHTABLE_CWC22_H__
diff --git a/tools/vtpm_manager/util/hashtable_itr.c
b/tools/vtpm_manager/util/hashtable_itr.c
--- a/tools/vtpm_manager/util/hashtable_itr.c
+++ b/tools/vtpm_manager/util/hashtable_itr.c
@@ -32,11 +32,6 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-/*
- * There are duplicates of this code in:
- *  - tools/blktap2/drivers/hashtable_itr.c
- */
-
 #include "hashtable.h"
 #include "hashtable_private.h"
 #include "hashtable_itr.h"
diff --git a/tools/vtpm_manager/util/hashtable_itr.h
b/tools/vtpm_manager/util/hashtable_itr.h
--- a/tools/vtpm_manager/util/hashtable_itr.h
+++ b/tools/vtpm_manager/util/hashtable_itr.h
@@ -32,11 +32,6 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-/*
- * There are duplicates of this code in:
- *  - tools/blktap2/drivers/hashtable_itr.h
- */
-
 
 #ifndef __HASHTABLE_ITR_CWC22__
 #define __HASHTABLE_ITR_CWC22__
diff --git a/tools/vtpm_manager/util/hashtable_private.h
b/tools/vtpm_manager/util/hashtable_private.h
--- a/tools/vtpm_manager/util/hashtable_private.h
+++ b/tools/vtpm_manager/util/hashtable_private.h
@@ -32,12 +32,6 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-/*
- * There are duplicates of this code in:
- *  - tools/xenstore/hashtable_private.h
- *  - tools/blktap2/drivers/hashtable_private.h
- */
-
 #ifndef __HASHTABLE_PRIVATE_CWC22_H__
 #define __HASHTABLE_PRIVATE_CWC22_H__
 
diff --git a/tools/vtpm_manager/util/log.c b/tools/vtpm_manager/util/log.c
--- a/tools/vtpm_manager/util/log.c
+++ b/tools/vtpm_manager/util/log.c
@@ -38,6 +38,17 @@
 #include "buffer.h"
 #include "tcg.h"
 
+char *module_names[] = { "",
+                                "CRYPTO",
+                                "BSG",
+                                "TXDATA",
+                                "TCS",
+                                "TCS",
+                                "VTSP",
+                                "VTPM",
+                                "VTPM",
+                                "VTSP"
+                              };
 // Helper code for the consts, eg. to produce messages for error codes.
 
 typedef struct error_code_entry_t {
diff --git a/tools/vtpm_manager/util/log.h b/tools/vtpm_manager/util/log.h
--- a/tools/vtpm_manager/util/log.h
+++ b/tools/vtpm_manager/util/log.h
@@ -36,6 +36,8 @@
 
 #include <stdint.h>             // for uint32_t
 #include <stddef.h>             // for pointer NULL
+#include <stdio.h>
+#include <tcg.h>
 
 // =========================== LOGGING ==============================
 
@@ -50,17 +52,7 @@
 #define VTPM_LOG_VTPM_DEEP   8
 #define VTPM_LOG_VTSP_DEEP   9
 
-static char *module_names[] = { "",
-                                "CRYPTO",
-                                "BSG",
-                                "TXDATA",
-                                "TCS",
-                                "TCS",
-                                "VTSP",
-                                "VTPM",
-                                "VTPM",
-                                "VTSP"
-                              };
+extern char *module_names[];
 
 // Default to standard logging
 #ifndef LOGGING_MODULES
diff --git a/tools/vtpm_manager/util/tcg.h b/tools/vtpm_manager/util/tcg.h
--- a/tools/vtpm_manager/util/tcg.h
+++ b/tools/vtpm_manager/util/tcg.h
@@ -197,6 +197,7 @@ typedef struct pack_buf_t {
   UINT32 size;
   BYTE * data;
 } pack_buf_t;
+#define NULL_PACK_BUF {0,0}
 
 typedef struct pack_constbuf_t {
   UINT32 size;
@@ -295,6 +296,35 @@ typedef struct pack_constbuf_t {
 #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)
 
 
@@ -419,8 +449,16 @@ typedef struct pack_constbuf_t {
 /// 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
@@ -447,6 +485,64 @@ typedef struct pack_constbuf_t {
 #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
diff --git a/tools/vtpm_manager/vtpmconnd/Makefile
b/tools/vtpm_manager/vtpmconnd/Makefile
--- /dev/null
+++ b/tools/vtpm_manager/vtpmconnd/Makefile
@@ -0,0 +1,30 @@
+# 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 = $(realpath ../../..)
+include ../Rules.mk
+
+BIN=vtpmconnd
+OBJS=vtpmconnd.o
+CFLAGS=-O2 -Wall
+
+all: ${BIN}
+
+${BIN}: ${OBJS}
+    gcc -o $@ $<
+
+install: ${BIN}
+    install -m 0755 ${BIN} $(DESTDIR)$(BINDIR)/$(BIN)
+
+.PHONY: mrproper
+mrproper: clean
+clean:
+    -rm ${BIN} ${OBJS}
diff --git a/tools/vtpm_manager/vtpmconnd/vtpmconnd.c
b/tools/vtpm_manager/vtpmconnd/vtpmconnd.c
--- /dev/null
+++ b/tools/vtpm_manager/vtpmconnd/vtpmconnd.c
@@ -0,0 +1,253 @@
+/*
+ * 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 <string.h>
+#include <errno.h>
+#include <getopt.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <ctype.h>
+#include "../manager/vtpm_manager.h"
+
+#define VTPM_BE "/dev/vtpm"
+#define TPM_DEV "/dev/tpm0"
+#define MAX_CMD 4096
+#define DEVNULL "/dev/null"
+#define TPM_SUCCESS_RESP "\x00\x00\x00\x00" "\x01\xC1"
"\x00\x00\x00\x00" "\x00\x00\x00\x00"
+#define TPM_SUCCESS_RESPLEN 14
+
+static int quit = 0;
+
+struct Opts {
+   const char* vtpmbe;
+   const char* tpmdev;
+   int verbosity;
+   int daemon;
+};
+
+struct Opts opts = {
+   .vtpmbe = VTPM_BE,
+   .tpmdev = TPM_DEV,
+   .verbosity = 0,
+   .daemon = 1,
+};
+
+void usage(char* argv0) {
+fprintf(stderr, "Usage:\n \
+\t%s [options] [tpm device node]\n\
+\n\
+-h\t\tdisplay usage message\n\
+-v\t\tturn up verbosity level\n\
+-t <FILE>\tuse FILE for tpm device (default " TPM_DEV ")\n\
+-b <FILE>\tset vtpm backend device to FILE (default: " VTPM_BE ")\n\
+-f\t\trun in the foreground\n",
+argv0
+);
+}
+
+void sighandler(int signum) {
+   quit = 1;
+}
+
+int main_loop(int vbefd, int tpmfd) {
+   uint8_t buf[MAX_CMD];
+   ssize_t size, wrote;
+   int i;
+
+   while(!quit) {
+      /* Wait for cmd from vtpm_manager */
+      if((size = read(vbefd, buf, MAX_CMD)) < 0) {
+     if(errno == EFAULT) {
+        if(opts.verbosity > 0) {
+           fprintf(stderr, "read() failed with error: %s, non-fatal\n",
strerror(errno));
+        }
+        continue;
+     }
+     fprintf(stderr,"Error reading from %s, (%s)\n", opts.vtpmbe,
strerror(errno));
+     return 1;
+      }
+      if(opts.verbosity > 0) {
+     printf("\nvtpm_manager req(%ld):", (long) size);
+     for(i = 0; i < size; ++i) {
+        printf(" %02X", buf[i]);
+     }
+     printf("\n");
+      }
+     
+      if(quit) {
+     break;
+      }
+
+      /* Forward the cmd to the tpm, exclude the dmi id */
+      if((wrote = write(tpmfd, buf + 4, size - 4)) != size - 4) {
+     fprintf(stderr,"Error writing to %s, (%s)\n", opts.tpmdev,
strerror(errno));
+     return 1;
+      }
+
+      if(quit) {
+     break;
+      }
+
+      /* Wait for response from tpm */
+      if((size = read(tpmfd, buf + 4, MAX_CMD - 4)) < 0) {
+     fprintf(stderr,"Error reading from %s, (%s)\n", opts.tpmdev,
strerror(errno));
+     return 1;
+      }
+      if(opts.verbosity > 0) {
+     printf("tpm resp(%ld):", (long) size);
+     for(i = 0; i < size + 4; ++i) {
+        printf(" %02X", buf[i]);
+     }
+     printf("\n");
+      }
+
+      if(quit) {
+     break;
+      }
+     
+      /* Send response back to vtpm_manager */
+      if((wrote = write(vbefd, buf, size + 4)) != size + 4) {
+     fprintf(stderr, "Error writing to %s, (%s)\n", opts.vtpmbe,
strerror(errno));
+     return 1;
+      }
+   }
+
+   return 0;
+
+}
+
+int main(int argc, char** argv)
+{
+   int rc;
+   int vbefd, tpmfd;
+   int c;
+   int fd = -1;
+   struct sigaction sig;
+   pid_t pid;
+
+   /* Do cmdline opts */
+   opterr = 0;
+
+   while ((c = getopt (argc, argv, "hfvb:t:")) != -1)
+   {
+      switch (c)
+      {
+     case 'h':
+        usage(argv[0]);
+        return 0;
+     case 'f':
+        opts.daemon = 0;
+        break;
+     case 'v':
+        ++opts.verbosity;
+        break;
+     case 'b':
+        opts.vtpmbe = optarg;
+        break;
+     case 't':
+        opts.tpmdev = optarg;
+        break;
+     case '?':
+        if (optopt == 'c')
+           fprintf (stderr, "Option -%c requires an argument.\n", optopt);
+        else if (isprint (optopt))
+           fprintf (stderr, "Unknown option `-%c'.\n", optopt);
+        else
+           fprintf (stderr,
+             "Unknown option character `\\x%x'.\n",
+             optopt);
+            usage(argv[0]);
+        return 1;
+     default:
+        return 1;
+      }
+   }
+
+   /* DAEMONIZE */
+   if(opts.daemon) {
+      pid = fork();
+      if(pid < 0) {
+     fprintf(stderr, "failed to daemonize! fork() failed : %s\n",
strerror(errno));
+     return 1;
+      }
+
+      if (pid > 0) {
+     return 0;
+      }
+   }
+
+
+   /* SIGNAL HANDLING */
+   sig.sa_handler = sighandler;
+   sigemptyset(&sig.sa_mask);
+   sig.sa_flags = 0;
+
+   sigaction(SIGINT, &sig, NULL);
+   sigaction(SIGQUIT, &sig, NULL);
+   sigaction(SIGTERM, &sig, NULL);
+
+   /* FAKE OUT THE HOTPLUG SYSTEM */
+   /* Whenever hotplug writes a message let it go to dev null */
+   if(remove(VTPM_RX_HP_FNAME) != 0 && errno != ENOENT) {
+      fprintf(stderr, "Unable to remove %s : %s\n", VTPM_RX_HP_FNAME,
strerror(errno));
+      return -1;
+   }
+   if(symlink(DEVNULL, VTPM_RX_HP_FNAME) != 0) {
+      fprintf(stderr, "Unable to create symlink %s -> %s : %s\n",
VTPM_RX_HP_FNAME, DEVNULL, strerror(errno));
+   }
+
+   /* Whenever hotplug tries to read a response, always return success */
+   if(remove(VTPM_TX_HP_FNAME) != 0 && errno != ENOENT) {
+      fprintf(stderr, "Unable to remove %s : %s\n", VTPM_TX_HP_FNAME,
strerror(errno));
+      return -1;
+   }
+   if((fd = open(VTPM_TX_HP_FNAME, O_CREAT | O_WRONLY, S_IRUSR |
S_IWUSR)) < 0) {
+      fprintf(stderr, "Unable to open %s for writing : %s\n",
VTPM_TX_HP_FNAME, strerror(errno));
+      return -1;
+   }
+   if(write(fd, TPM_SUCCESS_RESP, TPM_SUCCESS_RESPLEN) !=
TPM_SUCCESS_RESPLEN) {
+      fprintf(stderr, "Unable to write to %s : %s\n", VTPM_TX_HP_FNAME,
strerror(errno));
+      return -1;
+   }
+   close(fd);
+   /* HOTPLUG FAKE OUT DONE */
+
+   /* Open the backend and tpm device */
+   if((vbefd = open(opts.vtpmbe, O_RDWR)) < 0) {
+      fprintf(stderr, "Unable to open `%s', (%s)\n", opts.vtpmbe,
strerror(errno));
+      return 1;
+   }
+   if((tpmfd = open(opts.tpmdev, O_RDWR)) < 0) {
+      fprintf(stderr, "Unable to open `%s', (%s)\n", opts.tpmdev,
strerror(errno));
+      return 1;
+   }
+   if(opts.verbosity > 0) {
+      fprintf(stderr, "Connected to vtpm backend: %s\n", opts.vtpmbe);
+      fprintf(stderr, "Connected to tpm: %s\n", opts.tpmdev);
+   }
+
+   rc = main_loop(vbefd, tpmfd);
+
+   close(vbefd);
+   close(tpmfd);
+
+   remove(VTPM_RX_HP_FNAME);
+   remove(VTPM_TX_HP_FNAME);
+
+
+   return rc;
+
+
+}
diff --git a/tools/vtpm_manager/vtpmmgrtalk/Makefile
b/tools/vtpm_manager/vtpmmgrtalk/Makefile
--- /dev/null
+++ b/tools/vtpm_manager/vtpmmgrtalk/Makefile
@@ -0,0 +1,35 @@
+# 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 = $(realpath ../../..)
+include ../Rules.mk
+
+BIN=vtpmmgrtalk
+OBJS=vtpmmgrtalk.o
+CFLAGS=-Wall -O2 -g
+CFLAGS += -I../crypto
+CFLAGS += -I../util
+CFLAGS += -I../tcs
+CFLAGS += -I../manager
+
+
+all: ${BIN}
+
+${BIN}: ${OBJS}
+    gcc -o $@ $<
+
+install: all
+    install -m 0755 ${BIN} $(DESTDIR)$(BINDIR)/$(BIN)
+
+.PHONY: mrproper
+mrproper: clean
+clean:
+    rm -f ${BIN} ${OBJS}
diff --git a/tools/vtpm_manager/vtpmmgrtalk/vtpmmgrtalk.c
b/tools/vtpm_manager/vtpmmgrtalk/vtpmmgrtalk.c
--- /dev/null
+++ b/tools/vtpm_manager/vtpmmgrtalk/vtpmmgrtalk.c
@@ -0,0 +1,105 @@
+/*
+ * 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 <unistd.h>
+#include <fcntl.h>
+#include <sys/file.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../manager/vtpm_manager.h"
+
+int main(int argc, char** argv) {
+   int wfd, rfd;
+   uint8_t buf[COMMAND_BUFFER_SIZE];
+   ssize_t size;
+   int i, c;
+   int rc = 0;
+
+   const char* wfile = VTPM_RX_HP_FNAME;
+   const char* rfile = VTPM_TX_HP_FNAME;
+
+   /* Open for writing in non-blocking mode and exit if
+    * the manager is not waiting on the other side */
+   if((wfd = open(wfile, O_WRONLY | O_NONBLOCK)) < 0) {
+      fprintf(stderr, "Error opening %s for writing : %s\n",
wfile,strerror(errno));
+      return 1;
+   }
+   /* Set the pipe back to blocking mode */
+   fcntl(wfd, F_SETFL, 0);
+
+   /* Open the read pipe */
+   if((rfd = open(rfile, O_RDONLY)) < 0) {
+      close(wfd);
+      fprintf(stderr, "Error opening %s for reading : %s\n",
rfile,strerror(errno));
+      return 1;
+   }
+  
+   /*Grab the ASCII hex input from stdin and convert to binary */
+   for(i = 0; i < COMMAND_BUFFER_SIZE; ++i) {
+      c = scanf("%02hhX", buf + i);
+      if(c == EOF) {
+     break;
+      } else if ( c != 1) {
+     fprintf(stderr, "Malformed Input! Use ASCII hex!\n");
+     rc = 1;
+     goto quit;
+      }
+   }
+   size = i;
+
+   /* Send request to the manager only if a request was actually given */
+   if(size > 0) {
+      /* Lock the pipes for reading/writing */
+      if(flock(wfd, LOCK_EX)) {
+     fprintf(stderr, "Unable to lock %s : %s\n", wfile, strerror(errno));
+     rc = 1;
+     goto quit;
+      }
+      if(flock(rfd, LOCK_EX)) {
+     fprintf(stderr, "Unable to lock %s : %s\n", wfile, strerror(errno));
+     rc = 1;
+     goto quit;
+      }
+
+      /* Write the binary data to the pipe */
+      if(write(wfd, buf, size) != size) {
+     fprintf(stderr, "Error writing to %s : %s\n", wfile, strerror(errno));
+     rc = 1;
+     goto quit;
+      }
+
+      /* Read the response from the manager */
+      size = read(rfd, buf, COMMAND_BUFFER_SIZE);
+      if(size < 0) {
+     fprintf(stderr, "Error reading %s : %s\n", rfile, strerror(errno));
+     rc = 1;
+     goto quit;
+      }
+      /* Output the hex */
+      for(i = 0; i < size; ++i) {
+     printf("%02X", buf[i]);
+      }
+      fprintf(stderr,"\n");
+
+      /* Unlock the pipes */
+      flock(rfd, LOCK_UN);
+      flock(wfd, LOCK_UN);
+   }
+
+   rc = 0;
+quit:
+   close(rfd);
+   close(wfd);
+   return rc;
+}


Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.