xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/7] vtpm Mini-Os domain: vtpm_managerd
@ 2010-08-25 15:05 Matthew Fioravante
  0 siblings, 0 replies; only message in thread
From: Matthew Fioravante @ 2010-08-25 15:05 UTC (permalink / raw)
  To: xen-devel@lists.xensource.com


[-- Attachment #1.1.1: Type: text/plain, Size: 1651 bytes --]

  Signed-off-by: Matthew Fioravante <Matthew.Fioravante@jhuapl.edu>

The following is a major patch to the vtpm_manager. I apologize in 
advance for submitting such a large patch. Let me know if you'd like me 
to break it up.

This patch contains the following:
-A new routine to flush all handles from the tpm everytime vtpm_managerd 
is started. Previously if the manager would crash it would leave stale 
keys and auth handles in the tpm. After restarting the manager several 
times and letting it crash, the tpm would run out of memory and the 
manager would fail to start with a TPM_NO_SPACE error.
-Several memory errors fixed such as uninitialized reads and memory leaks.
-Fixed the signal handler to work with blocking IO and threads 
correctly. Previously the manager would not shutdown correctly when you 
tried to Ctrl+C close it on 64 bit.
-Removal of VTPM_MULTI_VM #defines. These were supposed to be a partial 
implementation for a way to run vtpms in multiple domains but it was 
never finished. It doesn't appear there has been any development on this 
for several years. Since vtpm-stubdom performs this functionality I 
removed these #defines and #ifdefs to make the code a little cleaner.
-New vTPM ordinals: VTPM_SAVE_KEY and VTPM_LOAD_KEY. The vtpm domains 
encrypt their persistent state themselves, they only request the manager 
to store the key.

-#define VTPM_STUBDOM will build the manager in stubdom mode. The 
manager can only work in either vtpm-stubdom or vtpmd mode. You cannot 
combine them. Clearing out the manager state will be required.
     # rm /var/vtpm/VTPM /var/vtpm/vtpm_dm*



[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.1.2: 1-manager.patch --]
[-- Type: text/x-patch; name="1-manager.patch", Size: 70834 bytes --]

diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/README
--- a/tools/vtpm_manager/README	Thu Jul 01 14:17:13 2010 -0400
+++ b/tools/vtpm_manager/README	Tue Jul 20 15:26:31 2010 -0400
@@ -43,9 +43,6 @@
 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 @@
                                 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 -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/Rules.mk
--- a/tools/vtpm_manager/Rules.mk	Thu Jul 01 14:17:13 2010 -0400
+++ b/tools/vtpm_manager/Rules.mk	Tue Jul 20 15:26:31 2010 -0400
@@ -40,12 +40,12 @@
 #CFLAGS += -DLOGGING_MODULES=0x0
 #CFLAGS += -DLOGGING_MODULES=0xff
 
-# Use frontend/backend pairs between manager & DMs?
-#CFLAGS += -DVTPM_MULTI_VM
-
 # 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
 
diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/crypto/crypto.h
--- a/tools/vtpm_manager/crypto/crypto.h	Thu Jul 01 14:17:13 2010 -0400
+++ b/tools/vtpm_manager/crypto/crypto.h	Tue Jul 20 15:26:31 2010 -0400
@@ -127,6 +127,8 @@
                                         /*[IN]*/ BYTE *modulus, 
                                         CRYPTO_INFO* cryptoInfo);
 
+void Crypto_RSACryptoInfoFree(CRYPTO_INFO* cryptoInfo);
+
 //
 // symmetric pack and unpack operations
 //
diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/crypto/rsa.c
--- a/tools/vtpm_manager/crypto/rsa.c	Thu Jul 01 14:17:13 2010 -0400
+++ b/tools/vtpm_manager/crypto/rsa.c	Tue Jul 20 15:26:31 2010 -0400
@@ -149,6 +149,10 @@
   
 }
 
+void Crypto_RSACryptoInfoFree(CRYPTO_INFO* cryptoInfo) {
+   RSA_free(cryptoInfo->keyInfo);
+}
+
 int Crypto_RSAEnc(  CRYPTO_INFO *key,
 		    UINT32 inDataSize,
 		    BYTE *inData,
@@ -161,6 +165,7 @@
     
   if (paddedData == NULL) 
     return -1;
+  memset(paddedData, 0, sizeof(BYTE) * paddedDataSize);
 
   *outDataSize = 0;
   
diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/crypto/sym_crypto.c
--- a/tools/vtpm_manager/crypto/sym_crypto.c	Thu Jul 01 14:17:13 2010 -0400
+++ b/tools/vtpm_manager/crypto/sym_crypto.c	Tue Jul 20 15:26:31 2010 -0400
@@ -41,6 +41,7 @@
 #include <openssl/rand.h>
 
 #include "tcg.h"
+#include "log.h"
 #include "sym_crypto.h"
 
 typedef enum crypt_op_type_t {
@@ -119,11 +120,11 @@
   
   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 +140,7 @@
   goto egress;
   
  abort_egress:
+  buffer_free(o_cipher);
   
  egress:
   
@@ -170,7 +172,7 @@
   
   // and decrypt
   TPMTRYRETURN ( ossl_symcrypto_op (key, &cipher_alias, &iv, o_clear, CRYPT_DECRYPT) );
-  
+
   goto egress;
   
  abort_egress:
diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/manager/dmictl.c
--- a/tools/vtpm_manager/manager/dmictl.c	Thu Jul 01 14:17:13 2010 -0400
+++ b/tools/vtpm_manager/manager/dmictl.c	Tue Jul 20 15:26:31 2010 -0400
@@ -116,6 +116,13 @@
 
   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_Handle_New_DMI(const buffer_t *param_buf) {
   
@@ -254,7 +261,7 @@
   
   // Close DMI first
   TPMTRYRETURN(close_dmi( dmi_res ));
-  free ( dmi_res );
+  free_dmi(dmi_res);
 	
   status=TPM_SUCCESS;    
   goto egress;
diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/manager/securestorage.c
--- a/tools/vtpm_manager/manager/securestorage.c	Thu Jul 01 14:17:13 2010 -0400
+++ b/tools/vtpm_manager/manager/securestorage.c	Tue Jul 20 15:26:31 2010 -0400
@@ -42,7 +42,6 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <string.h>
-
 #include "tcg.h"
 #include "vtpm_manager.h"
 #include "vtpmpriv.h"
@@ -86,8 +85,9 @@
   
   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,
@@ -114,6 +114,32 @@
   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,
@@ -125,7 +151,7 @@
   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));
@@ -175,26 +201,68 @@
   buffer_free ( &data_cipher);
   buffer_free ( &symkey_clear);
   buffer_free ( &symkey_cipher);
+  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;
+  symkey_t    symkey;
+  buffer_t    symkey_cipher = NULL_BUF;
+  struct pack_buf_t symkey_cipher32 = NULL_PACK_BUF;
+  int i;
+
+  memset(&symkey, 0, sizeof(symkey_t));
+
+  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;
 
-  TPMTRYRETURN( envelope_encrypt(inbuf,
+  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Saving %d bytes of NVM.\n", buffer_len(nvmbuf));
+
+  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 +273,6 @@
     status = TPM_IOERROR;
     goto abort_egress;
   }
-  close(fh);
   
   Crypto_SHA1Full (sealed_NVM.bytes, buffer_len(&sealed_NVM), (BYTE *) &myDMI->NVM_measurement);   
   
@@ -215,6 +282,7 @@
   vtpmlogerror(VTPM_LOG_VTPM, "Failed to save NVM\n.");
   
  egress:
+  close(fh);
   buffer_free(&sealed_NVM);
   return status;
 }
@@ -229,7 +297,8 @@
 
   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 +310,7 @@
   
   //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 +324,6 @@
     status = TPM_IOERROR;
     goto abort_egress;
   }
-  close(fh);
   
   vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Load_NVMing[%d],\n", buffer_len(&sealed_NVM));
   
@@ -289,10 +358,173 @@
   
  egress:
   buffer_free( &sealed_NVM );
+  close(fh);
   
   return status;
 }
 
+TPM_RESULT VTPM_Handle_Get_NVM_Size(   VTPM_DMI_RESOURCE *myDMI, 
+                                        const buffer_t *inbuf, 
+                                        buffer_t *outbuf) {
+  TPM_RESULT status = TPM_SUCCESS;
+  long fh_size;
+  int fh = -1;
+  int stat_ret;
+  struct stat file_stat;
+  UINT32 fh_size_pack;
+
+  buffer_t sealedNVM;
+  buffer_init(&sealedNVM, 0, NULL);
+  struct pack_buf_t symkey_cipher32 = NULL_PACK_BUF, data_cipher32 = NULL_PACK_BUF;
+
+  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(&sealedNVM, fh_size, NULL));
+  if (read(fh, sealedNVM.bytes, buffer_len(&sealedNVM)) != fh_size) {
+    status = TPM_IOERROR;
+    goto abort_egress;
+  }
+
+  BSG_UnpackList(sealedNVM.bytes, 2,
+		 BSG_TPM_SIZE32_DATA, &symkey_cipher32,
+		 BSG_TPM_SIZE32_DATA, &data_cipher32);
+
+  TPMTRYRETURN(buffer_init(outbuf, sizeof(UINT32), NULL));
+  BSG_PackList(outbuf->bytes, 1,
+	BSG_TYPE_UINT32, (BYTE*)&(data_cipher32.size));
+
+
+ abort_egress:
+  vtpmlogerror(VTPM_LOG_VTPM, "Failed to retreive size of NVM\n");
+
+ egress:
+  BSG_Destroy(BSG_TPM_SIZE32_DATA, &symkey_cipher32);
+  BSG_Destroy(BSG_TPM_SIZE32_DATA, &data_cipher32);
+  buffer_free(&sealedNVM);
+  close(fh);
+  return status;
+}
+
+TPM_RESULT VTPM_Handle_Load_Key(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_Key(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;
@@ -364,6 +596,7 @@
                                         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 +622,7 @@
 
   free(flat_boot_key);
   free(flat_enc);
+  buffer_free(&clear_flat_global);
   buffer_free(&enc_flat_global);
   free(flat_dmis);
   close(fh);
@@ -403,8 +637,9 @@
   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;
+  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 *dmi_id_key, enc_size;
   BYTE vtpm_manager_gen;
 
@@ -438,9 +673,9 @@
                               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 +706,8 @@
                   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 +736,10 @@
  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 -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/manager/vtpm_ipc.c
--- a/tools/vtpm_manager/manager/vtpm_ipc.c	Thu Jul 01 14:17:13 2010 -0400
+++ b/tools/vtpm_manager/manager/vtpm_ipc.c	Tue Jul 20 15:26:31 2010 -0400
@@ -41,15 +41,35 @@
 #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
@@ -68,8 +88,6 @@
     }
   }
 
-  ipc_h->fh = VTPM_IPC_CLOSED;
-
   return 0;
 }
 
@@ -78,6 +96,8 @@
 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 +114,19 @@
     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 +136,8 @@
 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 +154,16 @@
     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 -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/manager/vtpm_ipc.h
--- a/tools/vtpm_manager/manager/vtpm_ipc.h	Thu Jul 01 14:17:13 2010 -0400
+++ b/tools/vtpm_manager/manager/vtpm_ipc.h	Tue Jul 20 15:26:31 2010 -0400
@@ -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 @@
 } 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 -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/manager/vtpm_manager.c
--- a/tools/vtpm_manager/manager/vtpm_manager.c	Thu Jul 01 14:17:13 2010 -0400
+++ b/tools/vtpm_manager/manager/vtpm_manager.c	Tue Jul 20 15:26:31 2010 -0400
@@ -44,6 +44,7 @@
 #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 +55,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,6 +75,67 @@
 }
 
 // --------------------------- Functions ------------------------------
+TPM_RESULT VTPM_FlushResources() {
+  TPM_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;
+}
 
 TPM_RESULT VTPM_Create_Manager(){
   
@@ -104,6 +166,7 @@
     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");
   }
@@ -203,6 +266,11 @@
   vtpm_globals->manager_tcs_handle = 0;
  
   TPMTRYRETURN(TCS_create());
+
+  // Blow away all stale handles left in the tpm
+  if(VTPM_FlushResources() != 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 +296,7 @@
     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);
   }
 
@@ -267,7 +335,7 @@
 	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 +344,21 @@
   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 -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/manager/vtpm_manager.h
--- a/tools/vtpm_manager/manager/vtpm_manager.h	Thu Jul 01 14:17:13 2010 -0400
+++ b/tools/vtpm_manager/manager/vtpm_manager.h	Tue Jul 20 15:26:31 2010 -0400
@@ -61,6 +61,9 @@
 #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_GETNVMSIZE   (VTPM_ORD_BASE + 6) // DMI requests the size of nvm storage blob
+#define VTPM_ORD_SAVEKEY      (VTPM_ORD_BASE + 7) // DMI requests encryption key for persistent storage
+#define VTPM_ORD_LOADKEY      (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 +150,23 @@
 
 *********************************************************************/
 
+#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 -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/manager/vtpm_manager_handler.c
--- a/tools/vtpm_manager/manager/vtpm_manager_handler.c	Thu Jul 01 14:17:13 2010 -0400
+++ b/tools/vtpm_manager/manager/vtpm_manager_handler.c	Tue Jul 20 15:26:31 2010 -0400
@@ -41,6 +41,7 @@
 #include <unistd.h>
 #include <string.h>
 #include <errno.h>
+#include <signal.h>
 
 #include "vtpm_manager.h"
 #include "vtpmpriv.h"
@@ -55,6 +56,8 @@
 #define vtpmhandlerloginfomore(module,fmt,args...) vtpmloginfomore (module, fmt, ##args );
 #define vtpmhandlerlogerror(module,fmt,args...) vtpmlogerror (module, "[%s]: " fmt, thread_name, ##args );
 
+volatile sig_atomic_t HANDLER_QUIT_FLAG = 0;
+
 // ---------------------- Prototypes -------------------
 TPM_RESULT vtpm_manager_handle_vtpm_cmd(VTPM_DMI_RESOURCE *dmi_res,
 					TPM_COMMAND_CODE ord,
@@ -63,6 +66,7 @@
                                         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,
@@ -70,6 +74,7 @@
                                        buffer_t *param_buf,
                                        buffer_t *result_buf,
                                        char *thread_name);
+#endif
 
 TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t *tx_ipc_h, 
                                  vtpm_ipc_handle_t *rx_ipc_h,
@@ -80,12 +85,13 @@
                                  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 +99,11 @@
   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 +116,9 @@
       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 +167,7 @@
       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 +175,7 @@
     } else {
       vtpm_lock_rdlock();
     }
+    locked = 1;
 
     if ( !(dmi_res = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi)) ||
          (!dmi_res->connected) ) {
@@ -174,10 +188,22 @@
     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 +233,42 @@
     // ------------------- 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 +279,6 @@
       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 +295,22 @@
     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 +352,21 @@
     status = VTPM_Handle_Load_Migration_key(command_buf, 
                                            result_buf);
     break;
+  case VTPM_ORD_GETNVMSIZE:
+    status = VTPM_Handle_Get_NVM_Size(dmi_res,
+	  			      command_buf,
+				      result_buf);
+    break;
+  case VTPM_ORD_SAVEKEY:
+    status = VTPM_Handle_Save_Key(dmi_res,
+	  			   command_buf,
+				   result_buf);
+    break;
+  case VTPM_ORD_LOADKEY:
+    status = VTPM_Handle_Load_Key(dmi_res,
+	  			   command_buf,
+				   result_buf);
+    break;
    
   default:
     // Privileged handlers can do maintanance
@@ -350,6 +404,7 @@
   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 +540,5 @@
 
   return status;
 }
+#endif
 
diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/manager/vtpmd.c
--- a/tools/vtpm_manager/manager/vtpmd.c	Thu Jul 01 14:17:13 2010 -0400
+++ b/tools/vtpm_manager/manager/vtpmd.c	Tue Jul 20 15:26:31 2010 -0400
@@ -51,21 +51,6 @@
 #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,33 +61,27 @@
   char *thread_name;
 };
 
+#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;
+#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(), vtpm_globals->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;
@@ -110,6 +89,7 @@
 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;
@@ -136,8 +116,8 @@
     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?
+    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;
     }
@@ -202,14 +182,17 @@
 
   } // 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.
@@ -223,6 +206,8 @@
 
     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) {
@@ -242,14 +227,18 @@
 #endif
 
   } //endif ! dom0
+#endif
   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,7 +247,7 @@
 #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");
@@ -270,22 +259,22 @@
   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 +283,26 @@
   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);
+  vtpm_ipc_init(&real_be_ipc_h, VTPM_BE_FNAME, O_RDWR, FALSE, FALSE);
 
   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 +310,15 @@
   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 +326,7 @@
   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;
@@ -340,30 +340,39 @@
 
   vtpm_lock_init();
 
-  vtpm_globals->master_pid = pthread_self();
+  vtpm_globals->master_thread = pthread_self();
+
   
-  if (pthread_create(&be_thread, NULL, vtpm_manager_thread, &be_thread_params) != 0) {
+  if (pthread_create(&vtpm_globals->be_thread, NULL, vtpm_manager_thread, &be_thread_params) != 0) {
     vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch BE Thread.\n");
     exit(-1);
   }
   
-  if (pthread_create(&dmi_thread, NULL, vtpm_manager_thread, &dmi_thread_params) != 0) {
+#ifndef VTPM_STUBDOM
+  if (pthread_create(&vtpm_globals->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) {
+  if (pthread_create(&vtpm_globals->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);
-  pthread_join(dmi_thread, NULL);
-  pthread_join(hp_thread, NULL);
+  pthread_join(vtpm_globals->be_thread, NULL);
+#ifndef VTPM_STUBDOM
+  pthread_join(vtpm_globals->dmi_thread, NULL);
+#endif
+  pthread_join(vtpm_globals->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 -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/manager/vtpmpriv.h
--- a/tools/vtpm_manager/manager/vtpmpriv.h	Thu Jul 01 14:17:13 2010 -0400
+++ b/tools/vtpm_manager/manager/vtpmpriv.h	Tue Jul 20 15:26:31 2010 -0400
@@ -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,7 @@
   BYTE                  dmi_type;
   TPM_DIGEST            NVM_measurement;  // Equal to the SHA1 of the blob
   TPM_DIGEST            DMI_measurement;  // Correct measurement of the owning DMI
+
 } VTPM_DMI_RESOURCE;
 
 typedef struct tdVTPM_MIGKEY_LIST {
@@ -89,8 +95,11 @@
 
 typedef struct tdVTPM_GLOBALS {
   // Non-persistent data
-#ifndef VTPM_MULTI_VM
-  pid_t               master_pid;
+  pthread_t           master_thread;
+  pthread_t           be_thread;
+  pthread_t           hp_thread;
+#ifndef VTPM_STUBDOM
+  pthread_t           dmi_thread;
 #endif
 
   int                 connected_dmis;     // To close guest_rx when no dmis are connected
@@ -143,6 +152,11 @@
                                         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 +187,9 @@
 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);
diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/manager/vtsp.c
--- a/tools/vtpm_manager/manager/vtsp.c	Thu Jul 01 14:17:13 2010 -0400
+++ b/tools/vtpm_manager/manager/vtsp.c	Tue Jul 20 15:26:31 2010 -0400
@@ -567,8 +567,7 @@
 			    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 +663,7 @@
     
     // 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 +733,7 @@
 			    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 +792,7 @@
     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++) {
diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/migration/vtpm_manager_if.c
--- a/tools/vtpm_manager/migration/vtpm_manager_if.c	Thu Jul 01 14:17:13 2010 -0400
+++ b/tools/vtpm_manager/migration/vtpm_manager_if.c	Tue Jul 20 15:26:31 2010 -0400
@@ -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 -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/tcs/contextmgr.c
--- a/tools/vtpm_manager/tcs/contextmgr.c	Thu Jul 01 14:17:13 2010 -0400
+++ b/tools/vtpm_manager/tcs/contextmgr.c	Tue Jul 20 15:26:31 2010 -0400
@@ -195,6 +195,7 @@
 
 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 @@
   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 @@
       returncode = FALSE;
     }
     
-    pCurrentHandle = pCurrentHandle->pNextHandle;
+    pCurrentHandle = pNext;
     
   }
   
diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/tcs/tcs.c
--- a/tools/vtpm_manager/tcs/tcs.c	Thu Jul 01 14:17:13 2010 -0400
+++ b/tools/vtpm_manager/tcs/tcs.c	Tue Jul 20 15:26:31 2010 -0400
@@ -113,14 +113,13 @@
     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 @@
 			  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 @@
 			   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 @@
       
       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 @@
   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 @@
 			   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 @@
   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 -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/tcs/tpmddl.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/vtpm_manager/tcs/tpmddl.c	Tue Jul 20 15:26:31 2010 -0400
@@ -0,0 +1,93 @@
+#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)
+{
+   TPM_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 */ 
+   TPM_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;
+   
+}
diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/tcs/tpmddl.h
--- a/tools/vtpm_manager/tcs/tpmddl.h	Thu Jul 01 14:17:13 2010 -0400
+++ b/tools/vtpm_manager/tcs/tpmddl.h	Tue Jul 20 15:26:31 2010 -0400
@@ -66,4 +66,7 @@
 				TDDL_BYTE* buffer,
 				TDDL_UINT32* size);
 
+TDDL_RESULT TDDL_FlushSpecific(TDDL_UINT32 handle, 
+				TDDL_UINT32 res);
+
 #endif // __TPMDDL_H__
diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/tcs/transmit.c
--- a/tools/vtpm_manager/tcs/transmit.c	Thu Jul 01 14:17:13 2010 -0400
+++ b/tools/vtpm_manager/tcs/transmit.c	Tue Jul 20 15:26:31 2010 -0400
@@ -117,7 +117,7 @@
 
   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;
   }
   
diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/util/buffer.c
--- a/tools/vtpm_manager/util/buffer.c	Thu Jul 01 14:17:13 2010 -0400
+++ b/tools/vtpm_manager/util/buffer.c	Tue Jul 20 15:26:31 2010 -0400
@@ -39,6 +39,7 @@
 #include <sys/param.h>
 
 #include "tcg.h"
+#include "log.h"
 #include "bsg.h"
 #include "buffer.h"
 
@@ -51,6 +52,7 @@
 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 @@
   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,30 @@
   return status;
 }
 
+TPM_RESULT buffer_prepend_raw(buffer_t * buf, tpm_size_t len, const BYTE* bytes) {
+  TPM_RESULT status = TPM_SUCCESS;
+  long i;
+
+  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 +228,6 @@
     free (buf->bytes);
     buf->bytes = NULL;
     buf->size = buf->alloc_size = 0;
-   
   }
   
   return TPM_SUCCESS;
diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/util/buffer.h
--- a/tools/vtpm_manager/util/buffer.h	Thu Jul 01 14:17:13 2010 -0400
+++ b/tools/vtpm_manager/util/buffer.h	Tue Jul 20 15:26:31 2010 -0400
@@ -92,4 +92,6 @@
 
 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);
+
 #endif // _TOOLS_H_
diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/util/tcg.h
--- a/tools/vtpm_manager/util/tcg.h	Thu Jul 01 14:17:13 2010 -0400
+++ b/tools/vtpm_manager/util/tcg.h	Tue Jul 20 15:26:31 2010 -0400
@@ -197,6 +197,7 @@
   UINT32 size;
   BYTE * data;
 } pack_buf_t;
+#define NULL_PACK_BUF {0,0}
 
 typedef struct pack_constbuf_t {
   UINT32 size;
@@ -295,6 +296,35 @@
 #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 @@
 /// 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 @@
 #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

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

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

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

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2010-08-25 15:05 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-08-25 15:05 [PATCH 1/7] vtpm Mini-Os domain: vtpm_managerd Matthew Fioravante

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).