WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] [VTPM_Tools] Support for (non-local) Migr

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [VTPM_Tools] Support for (non-local) Migration added. Local migration
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 12 Jul 2006 16:50:20 +0000
Delivery-date: Wed, 12 Jul 2006 09:53:08 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID 5014fd2b5c5aab37e83ceaddb1a65b8f50d1f5f7
# Parent  a4041ac6f152b2c8c9d7efde2c1d208d01f33f28
[VTPM_Tools] Support for (non-local) Migration added. Local migration
works provided that the hotplug scripts deliver the "suspend" before
the "resume," but this is not always true.
Signed-off-by: Vinnie Scarlata <vincent.r.scarlata@xxxxxxxxx>
---
 tools/examples/vtpm-impl                              |   56 +++
 tools/vtpm_manager/Makefile                           |   14 
 tools/vtpm_manager/Rules.mk                           |    1 
 tools/vtpm_manager/crypto/sym_crypto.c                |   17 
 tools/vtpm_manager/manager/dmictl.c                   |  111 +++---
 tools/vtpm_manager/manager/migration.c                |  307 ++++++++++++++++++
 tools/vtpm_manager/manager/securestorage.c            |   85 ++--
 tools/vtpm_manager/manager/vtpm_ipc.c                 |    2 
 tools/vtpm_manager/manager/vtpm_manager.c             |    4 
 tools/vtpm_manager/manager/vtpm_manager.h             |   16 
 tools/vtpm_manager/manager/vtpm_manager_handler.c     |   18 +
 tools/vtpm_manager/manager/vtpmd.c                    |    1 
 tools/vtpm_manager/manager/vtpmpriv.h                 |   39 ++
 tools/vtpm_manager/manager/vtsp.c                     |   68 ++-
 tools/vtpm_manager/manager/vtsp.h                     |    3 
 tools/vtpm_manager/migration/Makefile                 |   39 ++
 tools/vtpm_manager/migration/vtpm_manager_if.c        |  186 ++++++++++
 tools/vtpm_manager/migration/vtpm_migrator.h          |  104 ++++++
 tools/vtpm_manager/migration/vtpm_migrator_if.c       |  219 ++++++++++++
 tools/vtpm_manager/migration/vtpm_migratorc.c         |  211 ++++++++++++
 tools/vtpm_manager/migration/vtpm_migratord.c         |  202 +++++++++++
 tools/vtpm_manager/migration/vtpm_migratord_handler.c |  171 ++++++++++
 tools/vtpm_manager/util/buffer.c                      |   23 +
 tools/vtpm_manager/util/buffer.h                      |    4 
 tools/vtpm_manager/util/log.h                         |    4 
 tools/vtpm_manager/util/tcg.h                         |   18 -
 26 files changed, 1761 insertions(+), 162 deletions(-)

diff -r a4041ac6f152 -r 5014fd2b5c5a tools/examples/vtpm-impl
--- a/tools/examples/vtpm-impl  Mon Jul 10 15:36:04 2006 +0100
+++ b/tools/examples/vtpm-impl  Mon Jul 10 15:38:49 2006 +0100
@@ -45,6 +45,8 @@ TX_VTPM_MANAGER=/var/vtpm/fifos/from_con
 TX_VTPM_MANAGER=/var/vtpm/fifos/from_console.fifo
 RX_VTPM_MANAGER=/var/vtpm/fifos/to_console.fifo
 
+VTPM_MIG=/usr/bin/vtpm_migrator
+
 # -------------------- Helpers for binary streams -----------
 
 function str_to_hex32() {
@@ -67,11 +69,17 @@ function vtpm_manager_cmd() {
  local inst=$2;
  local inst_bin=$(hex32_to_bin $inst);
 
+ claim_lock vtpm_mgr
+
  #send cmd to vtpm_manager
  printf "$cmd$inst_bin" > $TX_VTPM_MANAGER
 
  #recv response
+ set +e
  local resp_hex=`dd skip=10 bs=1 count=4 if=$RX_VTPM_MANAGER 2> /dev/null | 
xxd -ps`
+ set -e
+
+ release_lock vtpm_mgr
 
  #return whether the command was successful
  if [ $resp_hex != $TPM_SUCCESS ]; then
@@ -126,11 +134,55 @@ function vtpm_delete() {
  fi
 }
 
+# Perform a migration step. This function differentiates between migration
+# to the local host or to a remote machine.
+# Parameters:
+# 1st: destination host to migrate to
+# 2nd: name of the domain to migrate
+# 3rd: the migration step to perform
 function vtpm_migrate() {
- echo "Error: vTPM migration accross machines not implemented."
+ local instance res
+
+ instance=$(vtpmdb_find_instance $2)
+ if [ "$instance" == "" ]; then
+  log err "VTPM Migratoin failed. Unable to translation of domain name"
+  echo "Error: VTPM Migration failed while looking up instance number"
+ fi
+
+ case "$3" in
+  0)
+   #Incicate migration supported
+   echo "0" 
+  ;;
+
+  1)
+   # Get Public Key from Destination
+   # Call vtpm_manager's migration part 1
+   claim_lock vtpm_mgr
+   $VTPM_MIG $1 $2 $instance $3
+   release_lock vtpm_mgr
+  ;;
+
+  2)
+   # Call manager's migration step 2 and send result to destination
+   # If successful remove from db
+   claim_lock vtpm_mgr
+   $VTPM_MIG $1 $2 $instance $3
+   release_lock vtpm_mgr
+  ;;
+
+  3)
+   if `ps x | grep "$VTPM_MIG $1"`; then
+    log err "VTPM Migration failed to complete."
+    echo "Error: VTPM Migration failed to complete."
+   fi
+  ;;
+ esac
+ 
 }
 
+
 function vtpm_migrate_recover() {
- true
+ echo "Error: Recovery not supported yet" 
 }
 
diff -r a4041ac6f152 -r 5014fd2b5c5a tools/vtpm_manager/Makefile
--- a/tools/vtpm_manager/Makefile       Mon Jul 10 15:36:04 2006 +0100
+++ b/tools/vtpm_manager/Makefile       Mon Jul 10 15:38:49 2006 +0100
@@ -3,7 +3,7 @@ XEN_ROOT = ../..
 # Base definitions and rules
 include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
 
-SUBDIRS                = crypto tcs util manager
+SUBDIRS                = crypto tcs util manager migration
 OPENSSL_HEADER = /usr/include/openssl/crypto.h
 
 .PHONY: all
@@ -11,10 +11,13 @@ all: build
 
 .PHONY: build
 build:
-       @if [ -e $(OPENSSL_HEADER) ]; then \
-               @set -e; for subdir in $(SUBDIRS); do \
-                       $(MAKE) -C $$subdir $@; \
-               done; \
+       @set -e; if [ -e $(OPENSSL_HEADER) ]; then            \
+               if [ ! -e "migration/vtpm_ipc.c" ]; then        \
+                       ln -s ../manager/vtpm_ipc.c migration;  \
+               fi;                                    \
+               for subdir in $(SUBDIRS); do          \
+                       $(MAKE) -C $$subdir $@;       \
+               done;                                 \
        else \
                echo "*** Cannot build vtpm_manager: OpenSSL developement files 
missing."; \
        fi
@@ -34,6 +37,7 @@ clean:
 
 .PHONY: mrproper
 mrproper:
+       rm -f migration/vtpm_ipc.c
        @set -e; for subdir in $(SUBDIRS); do \
                $(MAKE) -C $$subdir $@; \
        done
diff -r a4041ac6f152 -r 5014fd2b5c5a tools/vtpm_manager/Rules.mk
--- a/tools/vtpm_manager/Rules.mk       Mon Jul 10 15:36:04 2006 +0100
+++ b/tools/vtpm_manager/Rules.mk       Mon Jul 10 15:38:49 2006 +0100
@@ -69,3 +69,4 @@ CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manag
 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 -r a4041ac6f152 -r 5014fd2b5c5a tools/vtpm_manager/crypto/sym_crypto.c
--- a/tools/vtpm_manager/crypto/sym_crypto.c    Mon Jul 10 15:36:04 2006 +0100
+++ b/tools/vtpm_manager/crypto/sym_crypto.c    Mon Jul 10 15:38:49 2006 +0100
@@ -68,8 +68,7 @@ TPM_RESULT Crypto_symcrypto_initkey (sym
   
   key->cipher = SYM_CIPHER;
   
-  status = buffer_init_copy (&key->key, keybits);
-  STATUSCHECK(status);
+  TPMTRYRETURN( buffer_init_copy (&key->key, keybits));
     
   goto egress;
   
@@ -92,8 +91,7 @@ TPM_RESULT Crypto_symcrypto_genkey (symk
   
   key->cipher = SYM_CIPHER;
   
-  status = buffer_init (&key->key, EVP_CIPHER_key_length(key->cipher), NULL);
-  STATUSCHECK (status);
+  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);
@@ -133,8 +131,7 @@ TPM_RESULT Crypto_symcrypto_encrypt (sym
   // make an alias into which we'll put the ciphertext
   buffer_init_alias (&cipher_alias, o_cipher, 
EVP_CIPHER_iv_length(key->cipher), 0);
   
-  status = ossl_symcrypto_op (key, clear, &iv, &cipher_alias, CRYPT_ENCRYPT);
-  STATUSCHECK (status);
+  TPMTRYRETURN( ossl_symcrypto_op (key, clear, &iv, &cipher_alias, 
CRYPT_ENCRYPT) );
 
   // set the output size correctly
   o_cipher->size += cipher_alias.size;
@@ -165,16 +162,14 @@ TPM_RESULT Crypto_symcrypto_decrypt (sym
   buffer_init_alias (&cipher_alias, cipher, EVP_CIPHER_iv_length(key->cipher), 
0);
   
   // prepare the output buffer
-  status = buffer_init (o_clear,
+  TPMTRYRETURN( buffer_init (o_clear,
                        cipher->size
                        - EVP_CIPHER_iv_length(key->cipher)
                        + EVP_CIPHER_block_size(key->cipher), 
-                       0);
-  STATUSCHECK(status);
+                       0) );
   
   // and decrypt
-  status = ossl_symcrypto_op (key, &cipher_alias, &iv, o_clear, CRYPT_DECRYPT);
-  STATUSCHECK (status);
+  TPMTRYRETURN ( ossl_symcrypto_op (key, &cipher_alias, &iv, o_clear, 
CRYPT_DECRYPT) );
   
   goto egress;
   
diff -r a4041ac6f152 -r 5014fd2b5c5a tools/vtpm_manager/manager/dmictl.c
--- a/tools/vtpm_manager/manager/dmictl.c       Mon Jul 10 15:36:04 2006 +0100
+++ b/tools/vtpm_manager/manager/dmictl.c       Mon Jul 10 15:38:49 2006 +0100
@@ -41,14 +41,6 @@
 #include <unistd.h>
 #include <string.h>
 
-#ifndef VTPM_MUTLI_VM
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <signal.h>
- #include <wait.h>
-#endif
-
 #include "vtpmpriv.h"
 #include "bsg.h"
 #include "buffer.h"
@@ -59,12 +51,61 @@
 
 #define TPM_EMULATOR_PATH "/usr/bin/vtpmd"
 
+// 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
+TPM_RESULT init_dmi(UINT32 dmi_id, BYTE type,  VTPM_DMI_RESOURCE **dmi_res) {
+
+  TPM_RESULT status=TPM_SUCCESS;
+  VTPM_DMI_RESOURCE *new_dmi=NULL;
+  UINT32 *dmi_id_key=NULL;
+
+  if ((new_dmi = (VTPM_DMI_RESOURCE *) malloc (sizeof(VTPM_DMI_RESOURCE))) == 
NULL) {
+      status = TPM_RESOURCES;
+      goto abort_egress;
+  }
+  memset(new_dmi, 0, sizeof(VTPM_DMI_RESOURCE));
+  new_dmi->dmi_id = dmi_id;
+  new_dmi->connected = FALSE;
+  new_dmi->TCSContext = 0;
+
+  new_dmi->NVMLocation = (char *) malloc(11 + strlen(DMI_NVM_FILE));
+  sprintf(new_dmi->NVMLocation, DMI_NVM_FILE, (uint32_t) new_dmi->dmi_id);
+
+  if ((dmi_id_key = (UINT32 *) malloc (sizeof(UINT32))) == NULL) {
+    status = TPM_RESOURCES;
+    goto abort_egress;
+  }
+  *dmi_id_key = new_dmi->dmi_id;
+
+  // 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);
+    status = TPM_FAIL;
+    goto abort_egress;
+  }
+
+  if (dmi_res)
+    *dmi_res = new_dmi;
+
+  goto egress;
+
+ abort_egress:
+  if (new_dmi) {
+    free(new_dmi->NVMLocation);
+    free(new_dmi);
+  }
+  free(dmi_id_key);
+
+ egress:
+  return status;
+}
+
 TPM_RESULT close_dmi(VTPM_DMI_RESOURCE *dmi_res) {
   if (dmi_res == NULL) 
     return TPM_SUCCESS;
 
   TCS_CloseContext(dmi_res->TCSContext);
-  free ( dmi_res->NVMLocation );
   dmi_res->connected = FALSE;
 
   vtpm_globals->connected_dmis--;
@@ -77,7 +118,7 @@ TPM_RESULT VTPM_Handle_New_DMI(const buf
   VTPM_DMI_RESOURCE *new_dmi=NULL;
   TPM_RESULT status=TPM_FAIL;
   BYTE type, startup_mode;
-  UINT32 dmi_id, *dmi_id_key=NULL; 
+  UINT32 dmi_id; 
 
   if (param_buf == NULL) { // Assume creation of Dom 0 control
     type = VTPM_TYPE_NON_MIGRATABLE;
@@ -98,37 +139,17 @@ TPM_RESULT VTPM_Handle_New_DMI(const buf
   if (new_dmi == NULL) { 
     vtpmloginfo(VTPM_LOG_VTPM, "Creating new DMI instance %d attached.\n", 
dmi_id );
     // Brand New DMI. Initialize the persistent pieces
-    if ((new_dmi = (VTPM_DMI_RESOURCE *) malloc (sizeof(VTPM_DMI_RESOURCE))) 
== NULL) {
-      status = TPM_RESOURCES;
-      goto abort_egress;
-    }
-    memset(new_dmi, 0, sizeof(VTPM_DMI_RESOURCE));
-    new_dmi->dmi_id = dmi_id;
-    new_dmi->connected = FALSE;
-
-    if (type != VTPM_TYPE_MIGRATED) {
-      new_dmi->dmi_type = type;
-    } else {
-      vtpmlogerror(VTPM_LOG_VTPM, "Creation of VTPM with illegal type.\n");
-      status = TPM_BAD_PARAMETER;
-      goto free_egress;
-    }
-    
-    if ((dmi_id_key = (UINT32 *) malloc (sizeof(UINT32))) == NULL) {
-      status = TPM_RESOURCES;
-      goto free_egress;
-    }      
-    *dmi_id_key = new_dmi->dmi_id;
-    
-    // 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);
-      status = TPM_FAIL;
-      goto free_egress;
-    }
-   
+    TPMTRYRETURN(init_dmi(dmi_id, type, &new_dmi) );  
   } else 
     vtpmloginfo(VTPM_LOG_VTPM, "Re-attaching DMI instance %d.\n", dmi_id);
+
+  if (type != VTPM_TYPE_MIGRATED) {
+    new_dmi->dmi_type = type;
+  } else {
+    vtpmlogerror(VTPM_LOG_VTPM, "Creation of VTPM with illegal type.\n");
+    status = TPM_BAD_PARAMETER;
+    goto abort_egress;
+  }
   
   if (new_dmi->connected) {
     vtpmlogerror(VTPM_LOG_VTPM, "Attempt to re-attach, currently attached 
instance %d. Ignoring\n", dmi_id);
@@ -143,13 +164,7 @@ TPM_RESULT VTPM_Handle_New_DMI(const buf
   }
 
   // Initialize the Non-persistent pieces
-  new_dmi->NVMLocation = NULL;
-  
-  new_dmi->TCSContext = 0;
   TPMTRYRETURN( TCS_OpenContext(&new_dmi->TCSContext) );
-  
-  new_dmi->NVMLocation = (char *) malloc(11 + strlen(DMI_NVM_FILE));
-  sprintf(new_dmi->NVMLocation, DMI_NVM_FILE, (uint32_t) new_dmi->dmi_id);
   
   new_dmi->connected = TRUE;  
 
@@ -158,10 +173,6 @@ TPM_RESULT VTPM_Handle_New_DMI(const buf
   status = VTPM_New_DMI_Extra(new_dmi, startup_mode);
   goto egress;
   
- free_egress:   // Error that requires freeing of newly allocated dmi 
-  free(new_dmi);
-  free(dmi_id_key);
-
  abort_egress:
   vtpmlogerror(VTPM_LOG_VTPM, "Failed to create DMI id=%d due to status=%s. 
Cleaning.\n", dmi_id, tpm_get_error_name(status));
   close_dmi(new_dmi );
@@ -240,7 +251,7 @@ TPM_RESULT VTPM_Handle_Delete_DMI( const
   
   // Close DMI first
   TPMTRYRETURN(close_dmi( dmi_res ));
-       free ( dmi_res );
+  free ( dmi_res );
        
   status=TPM_SUCCESS;    
   goto egress;
diff -r a4041ac6f152 -r 5014fd2b5c5a tools/vtpm_manager/manager/securestorage.c
--- a/tools/vtpm_manager/manager/securestorage.c        Mon Jul 10 15:36:04 
2006 +0100
+++ b/tools/vtpm_manager/manager/securestorage.c        Mon Jul 10 15:38:49 
2006 +0100
@@ -55,7 +55,7 @@
 #include "log.h"
 
 TPM_RESULT envelope_encrypt(const buffer_t     *inbuf,
-                            CRYPTO_INFO  *asymkey,
+                            CRYPTO_INFO        *asymkey,
                             buffer_t           *sealed_data) {
   TPM_RESULT status = TPM_SUCCESS;
   symkey_t    symkey;
@@ -114,8 +114,7 @@ TPM_RESULT envelope_encrypt(const buffer
   return status;
 }
 
-TPM_RESULT envelope_decrypt(const long         cipher_size,
-                            const BYTE         *cipher,
+TPM_RESULT envelope_decrypt(const buffer_t     *cipher,
                             TCS_CONTEXT_HANDLE TCSContext,
                            TPM_HANDLE         keyHandle,
                            const TPM_AUTHDATA *key_usage_auth,
@@ -131,22 +130,22 @@ TPM_RESULT envelope_decrypt(const long  
 
   memset(&symkey, 0, sizeof(symkey_t));
 
-  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Envelope Decrypt Input[%ld]: 0x", 
cipher_size);
-  for (i=0; i< cipher_size; i++)
-    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cipher[i]);
+  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]);
   vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
   
-  BSG_UnpackList(cipher, 2,
+  BSG_UnpackList(cipher->bytes, 2,
                 BSG_TPM_SIZE32_DATA, &symkey_cipher32,
                 BSG_TPM_SIZE32_DATA, &data_cipher32);
   
-  TPMTRYRETURN( buffer_init_convert (&symkey_cipher, 
-                                    symkey_cipher32.size, 
-                                    symkey_cipher32.data) );
-  
-  TPMTRYRETURN( buffer_init_convert (&data_cipher, 
-                                    data_cipher32.size, 
-                                    data_cipher32.data) );
+  TPMTRYRETURN( buffer_init_alias_convert (&symkey_cipher, 
+                                          symkey_cipher32.size, 
+                                          symkey_cipher32.data) );
+  
+  TPMTRYRETURN( buffer_init_alias_convert (&data_cipher, 
+                                          data_cipher32.size, 
+                                          data_cipher32.data) );
 
   // Decrypt Symmetric Key
   TPMTRYRETURN( VTSP_Unbind(  TCSContext,
@@ -188,7 +187,7 @@ TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI
   TPM_RESULT status = TPM_SUCCESS;
   int fh;
   long bytes_written;
-  buffer_t sealed_NVM;
+  buffer_t sealed_NVM = NULL_BUF;
   
   vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Saving %d bytes of NVM.\n", 
buffer_len(inbuf));
 
@@ -221,16 +220,14 @@ TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI
 }
 
 
-/* inbuf = null outbuf = sealed blob size, sealed blob.*/
+/* Expected Params: inbuf = null, outbuf = sealed blob size, sealed blob.*/
 TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI_RESOURCE *myDMI, 
-                               const buffer_t *inbuf, 
-                               buffer_t *outbuf) {
+                               const buffer_t    *inbuf, 
+                               buffer_t          *outbuf) {
   
   TPM_RESULT status = TPM_SUCCESS;
 
-  
-  UINT32 sealed_NVM_size;
-  BYTE *sealed_NVM = NULL;
+  buffer_t sealed_NVM = NULL_BUF;
   long fh_size;
   int fh, stat_ret, i;
   struct stat file_stat;
@@ -252,17 +249,16 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI
     goto abort_egress;
   }
   
-  sealed_NVM = (BYTE *) malloc(fh_size);
-  sealed_NVM_size = (UINT32) fh_size;
-  if (read(fh, sealed_NVM, fh_size) != fh_size) {
+  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;
   }
   close(fh);
   
-  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Load_NVMing[%ld],\n", fh_size);
-  
-  Crypto_SHA1Full(sealed_NVM, sealed_NVM_size, (BYTE *) &sealedNVMHash);    
+  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Load_NVMing[%d],\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)) ) {
@@ -281,8 +277,7 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI
     goto abort_egress;
   }
   
-    TPMTRYRETURN( envelope_decrypt(fh_size,
-                                 sealed_NVM,
+  TPMTRYRETURN( envelope_decrypt(&sealed_NVM,
                                  myDMI->TCSContext,
                                 vtpm_globals->storageKeyHandle,
                                 (const 
TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
@@ -293,7 +288,7 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI
   vtpmlogerror(VTPM_LOG_VTPM, "Failed to load NVM\n.");
   
  egress:
-  free( sealed_NVM );
+  buffer_free( &sealed_NVM );
   
   return status;
 }
@@ -408,12 +403,14 @@ 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;
+  buffer_t  unsealed_data, enc_table_abuf;
   struct pack_buf_t storage_key_pack, boot_key_pack;
   UINT32 *dmi_id_key, enc_size;
   BYTE vtpm_manager_gen;
 
   VTPM_DMI_RESOURCE *dmi_res;
+  UINT32 dmi_id;
+  BYTE dmi_type;
   struct stat file_stat;
 
   TPM_HANDLE boot_key_handle;
@@ -442,6 +439,7 @@ TPM_RESULT VTPM_LoadManagerData(void) {
                               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) );
 
   //Load Boot Key
@@ -454,8 +452,7 @@ TPM_RESULT VTPM_LoadManagerData(void) {
                               &vtpm_globals->bootKey,
                               FALSE) );
 
-  TPMTRYRETURN( envelope_decrypt(enc_size,
-                                 flat_table + step_size,
+  TPMTRYRETURN( envelope_decrypt(&enc_table_abuf,
                                  vtpm_globals->manager_tcs_handle,
                                  boot_key_handle,
                                  (const TPM_AUTHDATA*) &boot_usage_auth,
@@ -483,25 +480,17 @@ TPM_RESULT VTPM_LoadManagerData(void) {
       vtpmlogerror(VTPM_LOG_VTPM, "Encountered %ld extra bytes at end of 
manager state.\n", fh_size-step_size);
       step_size = fh_size;
     } else {
-      dmi_res = (VTPM_DMI_RESOURCE *) malloc(sizeof(VTPM_DMI_RESOURCE));
+      step_size += BSG_UnpackList(flat_table + step_size, 2,
+                                 BSG_TYPE_UINT32, &dmi_id,
+                                 BSG_TYPE_BYTE, &dmi_type);
+
+      //TODO: Try and gracefully recover from problems.
+      TPMTRYRETURN(init_dmi(dmi_id, dmi_type, &dmi_res) );
       dmis++;
 
-      dmi_res->connected = FALSE;
-
-      step_size += BSG_UnpackList(flat_table + step_size, 4,
-                                 BSG_TYPE_UINT32, &dmi_res->dmi_id,
-                                 BSG_TYPE_BYTE, &dmi_res->dmi_type,
+      step_size += BSG_UnpackList(flat_table + step_size, 2,
                                  BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
                                  BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
-
-      // install into map
-      dmi_id_key = (UINT32 *) malloc (sizeof(UINT32));
-      *dmi_id_key = dmi_res->dmi_id;
-      if (!hashtable_insert(vtpm_globals->dmi_map, dmi_id_key, dmi_res)) {
-        status = TPM_FAIL;
-        goto abort_egress;
-      }
-
     }
 
   }
diff -r a4041ac6f152 -r 5014fd2b5c5a tools/vtpm_manager/manager/vtpm_ipc.c
--- a/tools/vtpm_manager/manager/vtpm_ipc.c     Mon Jul 10 15:36:04 2006 +0100
+++ b/tools/vtpm_manager/manager/vtpm_ipc.c     Mon Jul 10 15:38:49 2006 +0100
@@ -135,7 +135,7 @@ void vtpm_ipc_close(vtpm_ipc_handle_t *i
 
   if (ipc_h) {
     close(ipc_h->fh);
+    ipc_h->fh = VTPM_IPC_CLOSED;
   }
-  ipc_h->fh = VTPM_IPC_CLOSED;
 
 }
diff -r a4041ac6f152 -r 5014fd2b5c5a tools/vtpm_manager/manager/vtpm_manager.c
--- a/tools/vtpm_manager/manager/vtpm_manager.c Mon Jul 10 15:36:04 2006 +0100
+++ b/tools/vtpm_manager/manager/vtpm_manager.c Mon Jul 10 15:38:49 2006 +0100
@@ -219,7 +219,9 @@ TPM_RESULT VTPM_Init_Manager() {
                           &vtpm_globals->keyAuth) );
   vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
 
-  // If failed, create new Manager.
+  vtpm_globals->mig_keys = NULL;
+
+  // If fails, create new Manager.
   serviceStatus = VTPM_LoadManagerData();
   if (serviceStatus == TPM_IOERROR) {
     vtpmloginfo(VTPM_LOG_VTPM, "Failed to read manager file. Assuming first 
time initialization.\n");
diff -r a4041ac6f152 -r 5014fd2b5c5a tools/vtpm_manager/manager/vtpm_manager.h
--- a/tools/vtpm_manager/manager/vtpm_manager.h Mon Jul 10 15:36:04 2006 +0100
+++ b/tools/vtpm_manager/manager/vtpm_manager.h Mon Jul 10 15:38:49 2006 +0100
@@ -56,14 +56,18 @@
 #define VTPM_PRIV_BASE      (VTPM_ORD_BASE | VTPM_PRIV_MASK)
 
 // Non-priviledged VTPM Commands (From DMI's)
-#define VTPM_ORD_SAVENVM    (VTPM_ORD_BASE + 1) // DMI Saves Secrets
-#define VTPM_ORD_LOADNVM    (VTPM_ORD_BASE + 2) // DMI Loads Secrets
-#define VTPM_ORD_TPMCOMMAND (VTPM_ORD_BASE + 3) // DMI issues HW TPM Command
+#define VTPM_ORD_SAVENVM      (VTPM_ORD_BASE + 1) // DMI Saves Secrets
+#define VTPM_ORD_LOADNVM      (VTPM_ORD_BASE + 2) // DMI Loads Secrets
+#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 
 
 // Priviledged VTPM Commands (From management console)
-#define VTPM_ORD_OPEN     (VTPM_PRIV_BASE + 1) // Creates/reopens DMI
-#define VTPM_ORD_CLOSE    (VTPM_PRIV_BASE + 2) // Closes a DMI
-#define VTPM_ORD_DELETE   (VTPM_PRIV_BASE + 3) // Permemently Deletes DMI
+#define VTPM_ORD_OPEN         (VTPM_PRIV_BASE + 1) // Creates/reopens DMI
+#define VTPM_ORD_CLOSE        (VTPM_PRIV_BASE + 2) // Closes a DMI
+#define VTPM_ORD_DELETE       (VTPM_PRIV_BASE + 3) // Permemently Deletes DMI
+#define VTPM_ORD_MIGRATE_IN   (VTPM_PRIV_BASE + 4) // Load migrated VTPM
+#define VTPM_ORD_MIGRATE_OUT  (VTPM_PRIV_BASE + 5) // migrate VTPM to dest 
 
 //************************ Return Codes ****************************
 #define VTPM_SUCCESS               0
diff -r a4041ac6f152 -r 5014fd2b5c5a 
tools/vtpm_manager/manager/vtpm_manager_handler.c
--- a/tools/vtpm_manager/manager/vtpm_manager_handler.c Mon Jul 10 15:36:04 
2006 +0100
+++ b/tools/vtpm_manager/manager/vtpm_manager_handler.c Mon Jul 10 15:38:49 
2006 +0100
@@ -301,6 +301,16 @@ TPM_RESULT vtpm_manager_handle_vtpm_cmd(
                                     command_buf, 
                                     result_buf);
     break;
+
+  case VTPM_ORD_GET_MIG_KEY:
+    status = VTPM_Handle_Get_Migration_key(command_buf, 
+                                           result_buf);
+    break;
+
+  case VTPM_ORD_LOAD_MIG_KEY:
+    status = VTPM_Handle_Load_Migration_key(command_buf, 
+                                           result_buf);
+    break;
    
   default:
     // Privileged handlers can do maintanance
@@ -316,6 +326,14 @@ TPM_RESULT vtpm_manager_handle_vtpm_cmd(
 
       case VTPM_ORD_DELETE:
         status = VTPM_Handle_Delete_DMI(command_buf);
+        break;
+
+      case VTPM_ORD_MIGRATE_IN:
+        status = VTPM_Handle_Migrate_In(command_buf, result_buf);
+        break;
+
+      case VTPM_ORD_MIGRATE_OUT:
+        status = VTPM_Handle_Migrate_Out(command_buf, result_buf);
         break;
 
       default:
diff -r a4041ac6f152 -r 5014fd2b5c5a tools/vtpm_manager/manager/vtpmd.c
--- a/tools/vtpm_manager/manager/vtpmd.c        Mon Jul 10 15:36:04 2006 +0100
+++ b/tools/vtpm_manager/manager/vtpmd.c        Mon Jul 10 15:38:49 2006 +0100
@@ -51,7 +51,6 @@
 #include "log.h"
 #include "vtpm_ipc.h"
 
-
 #define TPM_EMULATOR_PATH "/usr/bin/vtpmd"
 
 #define VTPM_BE_FNAME          "/dev/vtpm"
diff -r a4041ac6f152 -r 5014fd2b5c5a tools/vtpm_manager/manager/vtpmpriv.h
--- a/tools/vtpm_manager/manager/vtpmpriv.h     Mon Jul 10 15:36:04 2006 +0100
+++ b/tools/vtpm_manager/manager/vtpmpriv.h     Mon Jul 10 15:38:49 2006 +0100
@@ -79,6 +79,14 @@ typedef struct VTPM_DMI_RESOURCE_T {
   TPM_DIGEST            DMI_measurement;  // Correct measurement of the owning 
DMI
 } VTPM_DMI_RESOURCE;
 
+typedef struct tdVTPM_MIGKEY_LIST {
+  UINT32                name_size;
+  BYTE                  *name; // Name of destination (IP addr, domain name, 
etc)
+  CRYPTO_INFO           key;
+  struct tdVTPM_MIGKEY_LIST *next;
+} VTPM_MIGKEY_LIST;
+
+
 typedef struct tdVTPM_GLOBALS {
   // Non-persistent data
 #ifndef VTPM_MULTI_VM
@@ -88,6 +96,11 @@ typedef struct tdVTPM_GLOBALS {
   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 #
+  VTPM_MIGKEY_LIST    *mig_keys;              // Table of migration keys
+                      // Currently keys are loaded at migration time,
+                      // TODO: Make VTPM man store a keys persistently
+                      //       and update script to check if key is needed
+                      //       before fetching it.
 
   TCS_CONTEXT_HANDLE  manager_tcs_handle;     // TCS Handle used by manager
   TPM_HANDLE          storageKeyHandle;       // Key used by persistent store
@@ -109,8 +122,6 @@ extern VTPM_GLOBALS *vtpm_globals;   // 
 extern VTPM_GLOBALS *vtpm_globals;   // Key info and DMI states
 extern const TPM_AUTHDATA SRK_AUTH;  // SRK Well Known Auth Value
 
-// ********************** Command Handler Prototypes ***********************
-
 // ********************** VTPM Functions *************************
 TPM_RESULT VTPM_Init_Manager(); // Start VTPM Service
 void VTPM_Stop_Manager();  // Stop VTPM Service
@@ -121,6 +132,8 @@ TPM_RESULT VTPM_Manager_Handler(vtpm_ipc
                                 vtpm_ipc_handle_t *fw_rx_ipc_h,
                                 BOOL is_priv,
                                 char *client_name);
+
+// ********************** Command Handler Prototypes ***********************
 
 TPM_RESULT VTPM_Handle_Load_NVM(       VTPM_DMI_RESOURCE *myDMI, 
                                         const buffer_t *inbuf, 
@@ -140,6 +153,15 @@ TPM_RESULT VTPM_Handle_Close_DMI(const b
                                    
 TPM_RESULT VTPM_Handle_Delete_DMI(const buffer_t *param_buf);
 
+TPM_RESULT VTPM_Handle_Migrate_In( const buffer_t *param_buf,
+                                   buffer_t *result_buf);
+
+TPM_RESULT VTPM_Handle_Migrate_Out ( const buffer_t *param_buf,
+                                     buffer_t *result_buf);
+
+TPM_RESULT VTPM_Handle_Get_Migration_key( const buffer_t *param_buf,
+                                          buffer_t *result_buf);
+
 TPM_RESULT VTPM_SaveManagerData(void);
 TPM_RESULT VTPM_LoadManagerData(void);
 
@@ -147,5 +169,18 @@ TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_R
 
 TPM_RESULT VTPM_Close_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res);
 
+// Helper functions
 TPM_RESULT close_dmi(VTPM_DMI_RESOURCE *dmi_res);
+TPM_RESULT init_dmi(UINT32 dmi_id, BYTE type,  VTPM_DMI_RESOURCE **dmi_res);
+
+TPM_RESULT envelope_encrypt(const buffer_t     *inbuf,
+                             CRYPTO_INFO        *asymkey,
+                             buffer_t           *sealed_data);
+
+TPM_RESULT envelope_decrypt(const buffer_t     *cipher,
+                            TCS_CONTEXT_HANDLE TCSContext,
+                            TPM_HANDLE         keyHandle,
+                            const TPM_AUTHDATA *key_usage_auth,
+                            buffer_t           *unsealed_data);
+
 #endif // __VTPMPRIV_H__
diff -r a4041ac6f152 -r 5014fd2b5c5a tools/vtpm_manager/manager/vtsp.c
--- a/tools/vtpm_manager/manager/vtsp.c Mon Jul 10 15:36:04 2006 +0100
+++ b/tools/vtpm_manager/manager/vtsp.c Mon Jul 10 15:38:49 2006 +0100
@@ -141,13 +141,18 @@ TPM_RESULT VerifyAuth( /*[IN]*/ const BY
              (BYTE *) HMACkey, sizeof(TPM_DIGEST), (BYTE *) &hm);
     
   // Compare correct HMAC with provided one.
-  if (memcmp (&hm, &(auth->HMAC), sizeof(TPM_DIGEST)) == 0)  // 0 indicates 
equality
+  if (memcmp (&hm, &(auth->HMAC), sizeof(TPM_DIGEST)) == 0) { // 0 indicates 
equality
+    if (!auth->fContinueAuthSession) 
+      vtpmloginfo(VTPM_LOG_VTSP_DEEP, "Auth Session: 0x%x closed by TPM by 
fContinue=0.\n", auth->AuthHandle);
+    
     return (TPM_SUCCESS);
-  else {
+  } else {
     // If specified, reconnect the OIAP session.
     // NOTE: This only works for TCS's that never have a 0 context. 
-    if (hContext) 
+    if (hContext) {
+      vtpmloginfo(VTPM_LOG_VTSP_DEEP, "Auth Session: 0x%x closed by TPM due to 
failure.\n", auth->AuthHandle);
       VTSP_OIAP( hContext, auth);
+    }
     return (TPM_AUTHFAIL);
   }
 }
@@ -164,6 +169,7 @@ TPM_RESULT VTSP_OIAP(const TCS_CONTEXT_H
   memset(&auth->HMAC, 0, sizeof(TPM_DIGEST));
   auth->fContinueAuthSession = FALSE;
 
+  vtpmloginfo(VTPM_LOG_VTSP_DEEP, "Auth Session: 0x%x opened by TPM_OIAP.\n", 
auth->AuthHandle);
   goto egress;
   
  abort_egress:
@@ -205,16 +211,35 @@ TPM_RESULT VTSP_OSAP(const TCS_CONTEXT_H
 
   memset(&auth->HMAC, 0, sizeof(TPM_DIGEST));
   auth->fContinueAuthSession = FALSE;
-    
-  goto egress;
-  
- abort_egress:
-  
- egress:
-  
-  return status;
-}
-
+   
+  vtpmloginfo(VTPM_LOG_VTSP_DEEP, "Auth Session: 0x%x opened by TPM_OSAP.\n", 
auth->AuthHandle);
+
+  goto egress;
+  
+ abort_egress:
+  
+ egress:
+  
+  return status;
+}
+
+
+TPM_RESULT VTSP_TerminateHandle(const TCS_CONTEXT_HANDLE hContext,
+                                const TCS_AUTH *auth) {
+
+  vtpmloginfo(VTPM_LOG_VTSP, "Terminate Handle.\n");
+  TPM_RESULT status = TPM_SUCCESS;
+  TPMTRYRETURN( TCSP_TerminateHandle(hContext, auth->AuthHandle) );
+
+  vtpmloginfo(VTPM_LOG_VTSP_DEEP, "Auth Session: 0x%x closed by 
TPM_TerminateHandle.\n", auth->AuthHandle);
+  goto egress;
+
+ abort_egress:
+
+ egress:
+
+  return status;
+}
 
 
 TPM_RESULT VTSP_ReadPubek(   const TCS_CONTEXT_HANDLE hContext,
@@ -728,6 +753,7 @@ TPM_RESULT VTSP_Bind(   CRYPTO_INFO *cry
                        buffer_t *outData)               
 {
   vtpmloginfo(VTPM_LOG_VTSP, "Binding %d bytes of data.\n", 
buffer_len(inData));
+  TPM_RESULT status = TPM_SUCCESS;
   TPM_BOUND_DATA boundData;
   UINT32 i;
   
@@ -756,11 +782,11 @@ TPM_RESULT VTSP_Bind(   CRYPTO_INFO *cry
   UINT32 out_tmp_size;
   
   // Encrypt flatBoundData
-  Crypto_RSAEnc( cryptoInfo, 
-                flatBoundDataSize, 
-                flatBoundData, 
-                &out_tmp_size, 
-                out_tmp);
+  TPMTRY(TPM_ENCRYPT_ERROR, Crypto_RSAEnc( cryptoInfo, 
+                                           flatBoundDataSize, 
+                                           flatBoundData, 
+                                           &out_tmp_size, 
+                                           out_tmp) );
   
   if (out_tmp_size > RSA_KEY_SIZE/8) {
     // The result of RSAEnc should be a fixed size based on key size.
@@ -775,7 +801,11 @@ TPM_RESULT VTSP_Bind(   CRYPTO_INFO *cry
     vtpmloginfomore(VTPM_LOG_TXDATA, "%2.2x ", out_tmp[i]);
   }
   vtpmloginfomore(VTPM_LOG_TXDATA, "\n");
-  
+
+  goto egress;
+  abort_egress: 
+  egress:
+ 
   // Free flatBoundData
   free(flatBoundData);
   
diff -r a4041ac6f152 -r 5014fd2b5c5a tools/vtpm_manager/manager/vtsp.h
--- a/tools/vtpm_manager/manager/vtsp.h Mon Jul 10 15:36:04 2006 +0100
+++ b/tools/vtpm_manager/manager/vtsp.h Mon Jul 10 15:38:49 2006 +0100
@@ -58,6 +58,9 @@ TPM_RESULT VTSP_OSAP(  const TCS_CONTEXT
                        const TPM_AUTHDATA *usageAuth,
                        TPM_SECRET *sharedsecret, 
                        TCS_AUTH *auth);
+
+TPM_RESULT VTSP_TerminateHandle(const TCS_CONTEXT_HANDLE hContext,
+                                const TCS_AUTH *auth);
 
 TPM_RESULT VTSP_ReadPubek(   const TCS_CONTEXT_HANDLE hContext,
                              CRYPTO_INFO *cypto_info);
diff -r a4041ac6f152 -r 5014fd2b5c5a tools/vtpm_manager/util/buffer.c
--- a/tools/vtpm_manager/util/buffer.c  Mon Jul 10 15:36:04 2006 +0100
+++ b/tools/vtpm_manager/util/buffer.c  Mon Jul 10 15:38:49 2006 +0100
@@ -124,7 +124,20 @@ TPM_RESULT buffer_init_alias (buffer_t *
   
   return TPM_SUCCESS;
 }
-    
+
+// make an alias buffer_t into bytestream, with given length
+TPM_RESULT buffer_init_alias_convert (buffer_t * buf, tpm_size_t size, BYTE* 
val) {
+
+  buf->size = size;
+  buf->alloc_size = size;
+  buf->bytes = val;
+
+  buf->is_owner = FALSE;
+
+  return TPM_SUCCESS;
+}
+
+ 
 
 // copy into the start of dest
 TPM_RESULT buffer_copy (buffer_t * dest, const buffer_t* src)
@@ -132,8 +145,7 @@ TPM_RESULT buffer_copy (buffer_t * dest,
   TPM_RESULT status = TPM_SUCCESS;
     
   if (dest->alloc_size < src->size) {  
-    status = buffer_priv_realloc (dest, src->size);
-    STATUSCHECK (status);
+    TPMTRYRETURN( buffer_priv_realloc (dest, src->size) );
   }
   
   memcpy (dest->bytes, src->bytes, src->size);
@@ -162,8 +174,7 @@ TPM_RESULT buffer_append_raw (buffer_t *
   TPM_RESULT status = TPM_SUCCESS;
   
   if (buf->alloc_size < buf->size + len) {
-    status = buffer_priv_realloc (buf, buf->size + len);
-    STATUSCHECK (status);
+    TPMTRYRETURN( buffer_priv_realloc (buf, buf->size + len) );
   }
   
   memcpy (buf->bytes + buf->size, bytes, len);
@@ -187,6 +198,8 @@ TPM_RESULT buffer_free (buffer_t * buf) 
   if (buf && buf->is_owner && buf->bytes != NULL) {
     free (buf->bytes);
     buf->bytes = NULL;
+    buf->size = buf->alloc_size = 0;
+   
   }
   
   return TPM_SUCCESS;
diff -r a4041ac6f152 -r 5014fd2b5c5a tools/vtpm_manager/util/buffer.h
--- a/tools/vtpm_manager/util/buffer.h  Mon Jul 10 15:36:04 2006 +0100
+++ b/tools/vtpm_manager/util/buffer.h  Mon Jul 10 15:38:49 2006 +0100
@@ -69,6 +69,10 @@ TPM_RESULT buffer_init_alias (buffer_t *
 TPM_RESULT buffer_init_alias (buffer_t * buf, const buffer_t * b,
                               tpm_size_t offset, tpm_size_t);
 
+// make an alias buffer into a bytestream
+TPM_RESULT buffer_init_alias_convert (buffer_t * buf, 
+                                      tpm_size_t size, BYTE* val);
+
 // "copy constructor"
 TPM_RESULT buffer_init_copy (buffer_t * buf, const buffer_t * src);
 
diff -r a4041ac6f152 -r 5014fd2b5c5a tools/vtpm_manager/util/log.h
--- a/tools/vtpm_manager/util/log.h     Mon Jul 10 15:36:04 2006 +0100
+++ b/tools/vtpm_manager/util/log.h     Mon Jul 10 15:38:49 2006 +0100
@@ -48,6 +48,7 @@
 #define VTPM_LOG_VTSP        6
 #define VTPM_LOG_VTPM        7
 #define VTPM_LOG_VTPM_DEEP   8
+#define VTPM_LOG_VTSP_DEEP   9
 
 static char *module_names[] = { "",
                                 "CRYPTO",
@@ -57,7 +58,8 @@ static char *module_names[] = { "",
                                 "TCS",
                                 "VTSP",
                                 "VTPM",
-                                "VTPM"
+                                "VTPM",
+                                "VTSP"
                               };
 
 // Default to standard logging
diff -r a4041ac6f152 -r 5014fd2b5c5a tools/vtpm_manager/util/tcg.h
--- a/tools/vtpm_manager/util/tcg.h     Mon Jul 10 15:36:04 2006 +0100
+++ b/tools/vtpm_manager/util/tcg.h     Mon Jul 10 15:38:49 2006 +0100
@@ -466,6 +466,8 @@ typedef struct pack_constbuf_t {
 
 // ---------------------- Functions for checking TPM_RESULTs -----------------
 
+#include <stdio.h>
+
 // FIXME: Review use of these and delete unneeded ones.
 
 // these are really badly dependent on local structure:
@@ -476,25 +478,21 @@ typedef struct pack_constbuf_t {
                          goto abort_egress; } \
                     while (0)
 
-// ASSUME: the return value used after the abort_egress label has been set
-// already (eg. the 'status' local var)
-#define STATUSCHECK(s) if (s != TPM_SUCCESS) { \
-                            fprintf (stderr, "*** ERR in %s at %s:%i\n", 
__func__, __FILE__, __LINE__); \
-                            goto abort_egress; \
-                        }
-
 // DEPENDS: local var 'status' of type TPM_RESULT
 // DEPENDS: label 'abort_egress' which cleans up and returns the status
-// Try command c. If it fails, set status to s and goto shame.
+// Try command c. If it fails, set status to s and goto abort.
 #define TPMTRY(s,c) if (c != TPM_SUCCESS) { \
                        status = s; \
+                       printf("ERROR in %s at %s:%i code: %s.\n", __func__, 
__FILE__, __LINE__, tpm_get_error_name(status)); \
                        goto abort_egress; \
+                    } else {\
+                       status = c; \
                     }
 
-// Try command c. If it fails, print error message, set status to actual 
return code. Goto shame
+// Try command c. If it fails, print error message, set status to actual 
return code. Goto abort
 #define TPMTRYRETURN(c) do { status = c; \
                              if (status != TPM_SUCCESS) { \
-                               printf("ERROR in %s at %s:%i code: %s.\n", 
__func__, __FILE__, __LINE__, tpm_get_error_name(status)); \
+                               fprintf(stderr, "ERROR in %s at %s:%i code: 
%s.\n", __func__, __FILE__, __LINE__, tpm_get_error_name(status)); \
                                goto abort_egress; \
                              } \
                         } while(0)    
diff -r a4041ac6f152 -r 5014fd2b5c5a tools/vtpm_manager/manager/migration.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/vtpm_manager/manager/migration.c    Mon Jul 10 15:38:49 2006 +0100
@@ -0,0 +1,307 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+//   dmictl.c
+// 
+//     Functions for creating and destroying DMIs
+//
+// ==================================================================
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "vtpmpriv.h"
+#include "bsg.h"
+#include "buffer.h"
+#include "log.h"
+#include "hashtable.h"
+
+TPM_RESULT VTPM_Handle_Migrate_In( const buffer_t *param_buf,
+                                   buffer_t *result_buf) {
+
+  TPM_RESULT status=TPM_FAIL;
+  VTPM_DMI_RESOURCE *mig_dmi=NULL;
+  UINT32 dmi_id;
+  buffer_t dmi_state_abuf = NULL_BUF, enc_dmi_abuf = NULL_BUF, clear_dmi_blob 
= NULL_BUF;
+
+  if (param_buf == NULL) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Migration Out Failed due to bad 
parameter.\n");
+    status = TPM_BAD_PARAMETER;
+    goto abort_egress;
+  }
+
+  struct pack_buf_t enc_dmi_state_pack;
+
+  BSG_UnpackList(param_buf->bytes, 2, 
+                 BSG_TYPE_UINT32, &dmi_id,
+                 BSG_TPM_SIZE32_DATA, &enc_dmi_state_pack) ;
+
+  vtpmloginfo(VTPM_LOG_VTPM, "Migrating VTPM in dmi %d.\n", dmi_id);
+
+  mig_dmi = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, 
&dmi_id);
+  if (mig_dmi) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Incoming VTPM claims unavailable id: %d.\n", 
dmi_id);
+    status = TPM_BAD_PARAMETER;
+    goto abort_egress;
+  }    
+
+  /** UnBind Blob **/
+  TPMTRYRETURN( buffer_init_alias_convert( &enc_dmi_abuf, 
+                                           enc_dmi_state_pack.size, 
+                                           enc_dmi_state_pack.data) );
+
+  TPMTRYRETURN( envelope_decrypt( &enc_dmi_abuf,
+                                   vtpm_globals->manager_tcs_handle,
+                                   vtpm_globals->storageKeyHandle,
+                                   (const 
TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
+                                   &clear_dmi_blob) );
+
+  // Create new dmi
+  TPMTRYRETURN( init_dmi(dmi_id, VTPM_TYPE_MIGRATABLE, &mig_dmi ) ); 
+
+  /** Open Blob **/
+  struct pack_buf_t dmi_state_pack;
+
+  BSG_UnpackList(clear_dmi_blob.bytes, 2, 
+                 BSG_TPM_DIGEST, &mig_dmi->DMI_measurement,
+                 BSG_TPM_SIZE32_DATA, &dmi_state_pack);
+
+  TPMTRYRETURN( buffer_init_alias_convert(&dmi_state_abuf, 
+                                          dmi_state_pack.size, 
+                                          dmi_state_pack.data) ); 
+
+  TPMTRYRETURN( VTPM_Handle_Save_NVM(mig_dmi, &dmi_state_abuf, NULL ) );
+
+  status=TPM_SUCCESS;
+  goto egress;
+
+ abort_egress:
+    vtpmlogerror(VTPM_LOG_VTPM, "VTPM Migration IN of instance %d failed 
because of %s.\n", dmi_id, tpm_get_error_name(status) );
+
+ egress:
+  buffer_free(&clear_dmi_blob);
+  buffer_free(&dmi_state_abuf);
+ 
+  return status;
+}
+
+TPM_RESULT VTPM_Handle_Migrate_Out( const buffer_t *param_buf,
+                                    buffer_t *result_buf) {
+
+  TPM_RESULT status=TPM_FAIL;
+  VTPM_DMI_RESOURCE *mig_dmi;
+  UINT32 dmi_id;
+  VTPM_MIGKEY_LIST *last_mig, *mig_key;
+  buffer_t dmi_state=NULL_BUF, clear_dmi_blob=NULL_BUF;
+
+  if (param_buf == NULL) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Migration Out Failed due to bad 
parameter.\n");
+    status = TPM_BAD_PARAMETER;
+    goto abort_egress;
+  }
+
+  struct pack_buf_t name_pack;
+
+  BSG_UnpackList( param_buf->bytes, 2,
+                  BSG_TYPE_UINT32, &dmi_id,
+                  BSG_TPM_SIZE32_DATA, &name_pack);
+
+  vtpmloginfo(VTPM_LOG_VTPM, "Migrating out dmi %d.\n", dmi_id);
+
+  mig_dmi = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, 
&dmi_id);
+  if (mig_dmi == NULL) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Non-existent VTPM instance (%d) in 
migration.\n", dmi_id );
+    status = TPM_BAD_PARAMETER;
+    goto abort_egress;
+  }
+
+  if (mig_dmi->dmi_type != VTPM_TYPE_MIGRATABLE) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Bad VTPM type (%d) in migration of instance 
(%d).\n", mig_dmi->dmi_type, dmi_id );
+    status = TPM_BAD_PARAMETER;
+    goto abort_egress;
+  }
+
+  /** Find migration key for dest **/
+  last_mig = NULL;
+  mig_key = vtpm_globals->mig_keys;
+  while (mig_key != NULL) {
+    if (mig_key->name_size == name_pack.size)
+      if (memcmp(mig_key->name, name_pack.data, name_pack.size) == 0) {
+        break;
+      }
+    
+    last_mig = mig_key;
+    mig_key = mig_key->next;
+  }
+     
+  if (!mig_key) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Unknown Migration target host.\n");
+    status = TPM_BAD_PARAMETER;
+    goto abort_egress;
+  }
+
+  /** Mark vtpm as migrated **/
+  mig_dmi->dmi_type = VTPM_TYPE_MIGRATED;
+
+  /** Build Blob **/
+  TPMTRYRETURN( VTPM_Handle_Load_NVM(mig_dmi, NULL, &dmi_state) );
+
+  TPMTRYRETURN( buffer_init(&clear_dmi_blob, sizeof(TPM_DIGEST) + 
sizeof(UINT32) + buffer_len(&dmi_state), NULL ) ); 
+
+  struct pack_constbuf_t dmi_state_pack;
+
+  dmi_state_pack.size = buffer_len(&dmi_state);
+  dmi_state_pack.data = dmi_state.bytes;
+
+  BSG_PackList(clear_dmi_blob.bytes, 2, 
+               BSG_TPM_DIGEST, &mig_dmi->DMI_measurement,
+               BSG_TPM_SIZE32_DATA, &dmi_state_pack);
+
+  /** Bind Blob **/
+  TPMTRYRETURN( envelope_encrypt( &clear_dmi_blob,
+                                  &mig_key->key,
+                                  result_buf) );
+
+  if (last_mig)
+    last_mig->next = mig_key->next;
+  else 
+    vtpm_globals->mig_keys = mig_key->next;
+  
+  free(mig_key->name);
+  free(mig_key);
+
+  status=TPM_SUCCESS;
+  goto egress;
+
+ abort_egress:
+    vtpmlogerror(VTPM_LOG_VTPM, "VTPM Migration OUT of instance %d failed 
because of %s. Migratoin recovery may be needed.\n", dmi_id, 
tpm_get_error_name(status) );
+
+    //TODO: Create and implement a policy for what happens to mig_key on 
failed migrations.
+
+ egress:
+
+  buffer_free(&clear_dmi_blob);
+  buffer_free(&dmi_state);
+
+  return status;
+}
+
+
+TPM_RESULT VTPM_Handle_Get_Migration_key( const buffer_t *param_buf,
+                                          buffer_t *result_buf) {
+
+  TPM_RESULT status=TPM_FAIL;
+
+  vtpmloginfo(VTPM_LOG_VTPM, "Getting Migration Public Key.\n");
+
+  struct pack_buf_t pubkey_exp_pack, pubkey_mod_pack;
+  TPM_KEY mig_key;
+
+  // Unpack/return key structure
+  BSG_Unpack(BSG_TPM_KEY, vtpm_globals->storageKeyWrap.bytes , &mig_key);
+  TPM_RSA_KEY_PARMS rsaKeyParms;
+
+  BSG_Unpack(BSG_TPM_RSA_KEY_PARMS,
+               mig_key.algorithmParms.parms,
+               &rsaKeyParms);
+
+  pubkey_exp_pack.size = rsaKeyParms.exponentSize;
+  pubkey_exp_pack.data = rsaKeyParms.exponent;
+  pubkey_mod_pack.size = mig_key.pubKey.keyLength;
+  pubkey_mod_pack.data = mig_key.pubKey.key;
+
+  TPMTRYRETURN( buffer_init( result_buf, 2*sizeof(UINT32) + 
+                                         pubkey_exp_pack.size + 
+                                         pubkey_mod_pack.size, NULL ) );
+
+  BSG_PackList( result_buf->bytes, 2,
+                  BSG_TPM_SIZE32_DATA, &pubkey_exp_pack,
+                  BSG_TPM_SIZE32_DATA, &pubkey_mod_pack);
+
+
+  status=TPM_SUCCESS;
+  goto egress;
+
+ abort_egress:
+    vtpmlogerror(VTPM_LOG_VTPM, "VTPM Get Migration Key failed because of 
%s.\n", tpm_get_error_name(status) );
+ egress:
+
+  return status;
+}
+
+TPM_RESULT VTPM_Handle_Load_Migration_key( const buffer_t *param_buf,
+                                           buffer_t *result_buf) {
+
+  TPM_RESULT status=TPM_FAIL;
+  VTPM_MIGKEY_LIST *mig_key;
+
+  vtpmloginfo(VTPM_LOG_VTPM, "Loading Migration Public Key.\n");
+
+  //FIXME: Review all uses of unpacking pack_buf_t and ensure free.
+  //FIXME: Review all declarations/initializations of buffer_t that could have 
a goto that skips them and then tries to free them
+
+  struct pack_buf_t name_pack, pubkey_exp_pack, pubkey_mod_pack;
+
+  //FIXME: scan list and verify name is not already in the list
+
+  BSG_UnpackList( param_buf->bytes, 3,
+                  BSG_TPM_SIZE32_DATA, &name_pack,
+                  BSG_TPM_SIZE32_DATA, &pubkey_exp_pack,
+                  BSG_TPM_SIZE32_DATA, &pubkey_mod_pack);
+
+  //TODO: Maintain a persistent list for pub_keys.
+  //TODO: Verify pub_key is trusted
+
+  mig_key = (VTPM_MIGKEY_LIST *) malloc(sizeof(VTPM_MIGKEY_LIST));
+  memset(mig_key, 0, sizeof(VTPM_MIGKEY_LIST) );
+  mig_key->name_size = name_pack.size;
+  mig_key->name = name_pack.data;
+
+  mig_key->key.encScheme = CRYPTO_ES_RSAESOAEP_SHA1_MGF1;
+  Crypto_RSABuildCryptoInfoPublic( pubkey_exp_pack.size,
+                                   pubkey_exp_pack.data,
+                                   pubkey_mod_pack.size,
+                                   pubkey_mod_pack.data,
+                                   &mig_key->key);
+
+
+  mig_key->next = vtpm_globals->mig_keys;
+  vtpm_globals->mig_keys = mig_key;
+
+  // free(name_pack.data); Do not free. data is now part of mig_key.
+  free(pubkey_exp_pack.data);
+  free(pubkey_mod_pack.data);
+
+  return TPM_SUCCESS;
+}
diff -r a4041ac6f152 -r 5014fd2b5c5a tools/vtpm_manager/migration/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/vtpm_manager/migration/Makefile     Mon Jul 10 15:38:49 2006 +0100
@@ -0,0 +1,39 @@
+XEN_ROOT = ../../..
+include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
+
+BIND           = vtpm_migratord
+BINC           = vtpm_migrator
+
+SRCSD    = vtpm_manager_if.c vtpm_migratord.c vtpm_migratord_handler.c 
vtpm_ipc.c
+SRCSC    = vtpm_manager_if.c vtpm_migrator_if.c vtpm_migratorc.c vtpm_ipc.c
+
+OBJSD    = $(patsubst %.c,%.o,$(SRCSD))
+OBJSC    = $(patsubst %.c,%.o,$(SRCSC))
+
+.PHONY: all
+all: build
+
+.PHONY: build
+build: $(BIND) $(BINC)
+
+.PHONY: install
+install: build
+       $(INSTALL_PROG) $(BIND) $(TOOLS_INSTALL_DIR)
+       $(INSTALL_PROG) $(BINC) $(TOOLS_INSTALL_DIR)
+
+.PHONY: clean
+clean:
+       rm -f *.a *.so *.o *.rpm $(DEP_FILES)
+
+.PHONY: mrproper
+mrproper: clean
+       rm -f $(BINC) $(BIND) *~
+
+$(BIND): $(OBJSD)
+       $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@
+
+$(BINC): $(OBJSC)
+       $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@
+
+# libraries
+LIBS += ../util/libTCGUtils.a
diff -r a4041ac6f152 -r 5014fd2b5c5a 
tools/vtpm_manager/migration/vtpm_manager_if.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/vtpm_manager/migration/vtpm_manager_if.c    Mon Jul 10 15:38:49 
2006 +0100
@@ -0,0 +1,186 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// vtpm_manager_if.c
+// 
+//  Provides functions to call local vtpm manager interface (Hotplug)
+//
+// ==================================================================
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <malloc.h>
+#include <string.h>
+
+#include "tcg.h"
+#include "buffer.h"
+#include "log.h"
+#include "vtpm_ipc.h"
+#include "bsg.h"
+#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
+    vtpmlogerror(VTPM_LOG_VTPM, "Unable to connect to vtpm_manager.\n");
+    return TPM_IOERROR;
+  } 
+
+  return TPM_SUCCESS;
+}
+
+void vtpm_manager_close() {
+
+  vtpm_ipc_close(&tx_ipc_h);
+  vtpm_ipc_close(&rx_ipc_h);
+}
+
+
+TPM_RESULT vtpm_manager_command(TPM_COMMAND_CODE ord,
+                                buffer_t *command_param_buf,
+                                TPM_RESULT *cmd_status, /* out */
+                                buffer_t *result_param_buf) {
+
+  TPM_RESULT status = TPM_FAIL;
+  int  size_read, size_write, i;
+  BYTE *adj_command, response_header[VTPM_COMMAND_HEADER_SIZE_SRV];
+  UINT32 dmi_id=0, adj_command_size, out_param_size, adj_param_size;
+  TPM_TAG tag=VTPM_TAG_REQ;
+
+  if ( (!command_param_buf) || (!result_param_buf) || (!cmd_status) ) {
+    status = TPM_BAD_PARAMETER;
+    goto abort_egress;
+  }   
+  
+  adj_command_size = VTPM_COMMAND_HEADER_SIZE_SRV + 
buffer_len(command_param_buf);
+  adj_command = (BYTE *) malloc( adj_command_size );
+  if (!adj_command) {
+    status = TPM_RESOURCES;
+    goto abort_egress;
+  }
+
+  out_param_size = VTPM_COMMAND_HEADER_SIZE + buffer_len(command_param_buf);
+  BSG_PackList(adj_command, 4,
+                 BSG_TYPE_UINT32, &dmi_id,
+                 BSG_TPM_TAG, &tag,
+                 BSG_TYPE_UINT32, &out_param_size,
+                 BSG_TPM_COMMAND_CODE, &ord );
+
+  memcpy(adj_command + VTPM_COMMAND_HEADER_SIZE_SRV, command_param_buf->bytes, 
buffer_len(command_param_buf));
+
+  size_write = vtpm_ipc_write(&tx_ipc_h, NULL, adj_command, adj_command_size);
+
+  if (size_write > 0) {
+    vtpmloginfo(VTPM_LOG_VTPM_DEEP, "SENT (MGR): 0x");
+    for (i=0; i< adj_command_size; i++) {
+      vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", adj_command[i]);
+    }
+    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+  } else {
+    vtpmlogerror(VTPM_LOG_VTPM, "Error writing VTPM Manager console.\n");
+    status = TPM_IOERROR;
+    goto abort_egress;
+  }
+
+  if (size_write != (int) adj_command_size )
+    vtpmlogerror(VTPM_LOG_VTPM, "Could not write entire command to mgr 
(%d/%d)\n", size_write, adj_command_size);
+
+  // Read header for response to manager command
+  size_read = vtpm_ipc_read(&rx_ipc_h, NULL, response_header, 
VTPM_COMMAND_HEADER_SIZE_SRV);
+  if (size_read > 0) {
+    vtpmloginfo(VTPM_LOG_VTPM_DEEP, "RECV (MGR): 0x");
+    for (i=0; i<size_read; i++)
+      vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", response_header[i]);
+
+  } else {
+    vtpmlogerror(VTPM_LOG_VTPM, "Error reading from vtpm manager.\n");
+    status = TPM_IOERROR;
+    goto abort_egress;
+  }
+
+  if (size_read < (int) VTPM_COMMAND_HEADER_SIZE_SRV) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Command from vtpm_manager shorter than std 
header.\n");
+    status = TPM_IOERROR;
+    goto abort_egress;
+  }
+
+  // Unpack response from DMI for TPM command
+  BSG_UnpackList(response_header, 4,
+                 BSG_TYPE_UINT32, &dmi_id,
+                 BSG_TPM_TAG, &tag,
+                 BSG_TYPE_UINT32, &out_param_size,
+                 BSG_TPM_COMMAND_CODE, cmd_status );
+
+  // If response has parameters, read them.
+  // Note that out_param_size is in the client's context
+  adj_param_size = out_param_size - VTPM_COMMAND_HEADER_SIZE;
+  if (adj_param_size > 0) {
+    TPMTRYRETURN( buffer_init( result_param_buf, adj_param_size, NULL) );
+    size_read = vtpm_ipc_read(&rx_ipc_h, NULL, result_param_buf->bytes, 
adj_param_size);
+    if (size_read > 0) {
+      for (i=0; i< size_read; i++)
+        vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", result_param_buf->bytes[i]);
+
+    } else {
+      vtpmlogerror(VTPM_LOG_VTPM, "Error reading from vtpm manager.\n");
+      goto abort_egress;
+    }
+    vtpmloginfomore(VTPM_LOG_VTPM, "\n");
+
+    if (size_read < (int)adj_param_size) {
+      vtpmloginfomore(VTPM_LOG_VTPM, "\n");
+      vtpmlogerror(VTPM_LOG_VTPM, "Command read(%d) is shorter than header 
indicates(%d).\n", size_read, adj_param_size);
+      status = TPM_IOERROR;
+      goto abort_egress;
+    }
+  } else {
+    vtpmloginfomore(VTPM_LOG_VTPM, "\n");
+  }
+
+  status=TPM_SUCCESS;
+  goto egress;
+
+ abort_egress:
+ egress:
+
+  return status;
+}
+
+
diff -r a4041ac6f152 -r 5014fd2b5c5a 
tools/vtpm_manager/migration/vtpm_migrator.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/vtpm_manager/migration/vtpm_migrator.h      Mon Jul 10 15:38:49 
2006 +0100
@@ -0,0 +1,104 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// vtpm_migrator.h
+// 
+//  Public Interface header for VTPM Migrator 
+//
+// ==================================================================
+
+#ifndef __VTPM_MIGRATOR_H__
+#define __VTPM_MIGRATOR_H__
+
+#define VTPM_MTAG_REQ 0x02c1
+#define VTPM_MTAG_RSP 0x02c4
+
+// Header sizes. 
+#define VTPM_COMMAND_HEADER_SIZE ( 2 + 4 + 4)
+//               sizeof(TPM_TAG + UINT32 + TPM_COMMAND_CODE)
+
+//*********************** Connection Info **************************
+#define VTPM_MIG_PORT 48879 
+
+//************************ Command Codes ***************************
+#define VTPM_MORD_MIG_STEP1     0x00
+#define VTPM_MORD_MIG_STEP2     0x01
+#define VTPM_MORD_MIG_STEP3     0x02
+#define VTPM_MORD_MIG_STEP4     0x03
+
+//************************ Return Codes ****************************
+#define VTPM_SUCCESS               0
+#define VTPM_FAIL                  1
+
+/******************* Command Parameter API *************************
+
+VTPM Command Format
+  tpm tag: 2 bytes
+  command size: 4 bytes         // Size of command including header but not DMI
+  ord: 4 bytes                  // Command ordinal above
+  parameters: size - 10 bytes   // Command Parameter
+
+VTPM Response Format
+  tpm tag: 2 bytes
+  response_size: 4 bytes
+  status: 4 bytes         
+  parameters: size - 10 bytes
+
+
+VTPM_Mig_Phase1:
+    Unsupported: (Handled by scripts)
+    
+VTPM_Mig_Phase2
+  Input Parameters:
+    domain_name_size: 4 bytes
+    domain_name : domain_name_size bytes
+  Output Parameters:
+    pub_exp_size: 4 bytes
+    pub_exp: pub_exp_size bytes
+    pub_mod_size: 4 bytes
+    pub_mod: pub_mod_size bytes
+
+VTPM_Mig_Phase3
+  Input Parameters:
+    vtpm_state_size: 4 bytes
+    vtpm_state: vtpm_state_size bytes
+  Output Parameters:
+    none
+
+VTPM_Mig_Phase4
+    Unsupported: (Handled by scripts)
+
+
+*********************************************************************/
+
+#endif //_VTPM_MANAGER_H_
diff -r a4041ac6f152 -r 5014fd2b5c5a 
tools/vtpm_manager/migration/vtpm_migrator_if.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/vtpm_manager/migration/vtpm_migrator_if.c   Mon Jul 10 15:38:49 
2006 +0100
@@ -0,0 +1,219 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// vtpm_migrator_if.c
+// 
+//  Provides functions to call open network connection & call
+//  a function on the vtpm_migratord on the destination
+//
+// ==================================================================
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <string.h>
+#include <malloc.h>
+
+#include "tcg.h"
+#include "buffer.h"
+#include "log.h"
+#include "bsg.h"
+#include "vtpm_migrator.h"
+
+static int sock_desc;
+
+
+TPM_RESULT vtpm_migratord_open(char *server_address){
+
+  TPM_RESULT status = TPM_FAIL;
+
+  /* network variables */
+  struct in_addr ip_addr;
+  struct sockaddr_in server_addr;
+  int addr_len;
+  struct hostent *dns_info=NULL;
+
+  /* set up connection to server*/
+  dns_info = gethostbyname(server_address);
+  ip_addr.s_addr = *((unsigned long *) dns_info->h_addr_list[0]);
+
+  if(ip_addr.s_addr < 0) {
+    status = TPM_BAD_PARAMETER;
+    goto abort_egress;
+  }
+
+  /* set up server variable */
+  memset((char *)&server_addr, 0, sizeof(server_addr));
+  server_addr.sin_family = AF_INET;
+  server_addr.sin_port = htons(VTPM_MIG_PORT);
+  server_addr.sin_addr.s_addr = ip_addr.s_addr;
+
+  /* open socket, make connection */
+  sock_desc = socket(AF_INET, SOCK_STREAM, 0);
+
+  if (sock_desc < 0 ) {
+    status = TPM_IOERROR;
+    goto abort_egress;
+  }
+
+  if (connect(sock_desc,
+              (struct sockaddr *)&server_addr,
+              sizeof(server_addr)) < 0 ) {
+    status = TPM_BAD_PARAMETER;
+    goto abort_egress;
+  }
+
+  status = TPM_SUCCESS;
+  goto egress;
+
+ abort_egress:
+ egress:
+
+  return status;
+}
+
+void vtpm_migratord_close() {
+  close(sock_desc);
+}
+
+
+TPM_RESULT vtpm_migratord_command(TPM_COMMAND_CODE ord,
+                                buffer_t *command_param_buf,
+                                TPM_RESULT *cmd_status, /* out */
+                                buffer_t *result_param_buf) {
+
+  TPM_RESULT status = TPM_FAIL;
+  int  size_read, size_write, i;
+  BYTE *command, response_header[VTPM_COMMAND_HEADER_SIZE];
+  UINT32 dmi_id=0, command_size, out_param_size, adj_param_size;
+  TPM_TAG tag=VTPM_MTAG_REQ;
+
+  if ( (!command_param_buf) || (!result_param_buf) || (!cmd_status) ) {
+    status = TPM_BAD_PARAMETER;
+    goto abort_egress;
+  }   
+  
+  command_size = VTPM_COMMAND_HEADER_SIZE + buffer_len(command_param_buf);
+  command = (BYTE *) malloc( command_size );
+  if (!command) {
+    status = TPM_RESOURCES;
+    goto abort_egress;
+  }
+
+  BSG_PackList(command, 3,
+                 BSG_TPM_TAG, &tag,
+                 BSG_TYPE_UINT32, &command_size,
+                 BSG_TPM_COMMAND_CODE, &ord );
+
+  memcpy(command + VTPM_COMMAND_HEADER_SIZE, command_param_buf->bytes, 
buffer_len(command_param_buf));
+
+  size_write = write(sock_desc, command, command_size);
+
+  if (size_write > 0) {
+    vtpmloginfo(VTPM_LOG_VTPM_DEEP, "SENT (MIGd): 0x");
+    for (i=0; i< command_size; i++) {
+      vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", command[i]);
+    }
+    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+  } else {
+    vtpmlogerror(VTPM_LOG_VTPM, "Error writing to migration server via 
network.\n");
+    status = TPM_IOERROR;
+    goto abort_egress;
+  }
+
+  if (size_write != (int) command_size )
+    vtpmlogerror(VTPM_LOG_VTPM, "Could not write entire command to migration 
server (%d/%d)\n", size_write, command_size);
+
+  // Read header for response 
+  size_read = read(sock_desc, response_header, VTPM_COMMAND_HEADER_SIZE);
+  if (size_read > 0) {
+    vtpmloginfo(VTPM_LOG_VTPM_DEEP, "RECV (MIGd): 0x");
+    for (i=0; i<size_read; i++)
+      vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", response_header[i]);
+
+  } else {
+    vtpmlogerror(VTPM_LOG_VTPM, "Error reading from Migration Server.\n");
+    status = TPM_IOERROR;
+    goto abort_egress;
+  }
+
+  if (size_read < (int) VTPM_COMMAND_HEADER_SIZE) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Command from migration server shorter than 
std header.\n");
+    status = TPM_IOERROR;
+    goto abort_egress;
+  }
+
+  // Unpack response from DMI for TPM command
+  BSG_UnpackList(response_header, 3,
+                 BSG_TPM_TAG, &tag,
+                 BSG_TYPE_UINT32, &out_param_size,
+                 BSG_TPM_COMMAND_CODE, cmd_status );
+
+  // If response has parameters, read them.
+  adj_param_size = out_param_size - VTPM_COMMAND_HEADER_SIZE;
+  if (adj_param_size > 0) {
+    TPMTRYRETURN( buffer_init( result_param_buf, adj_param_size, NULL) );
+    size_read = read(sock_desc, result_param_buf->bytes, adj_param_size);
+    if (size_read > 0) {
+      for (i=0; i< size_read; i++)
+        vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", result_param_buf->bytes[i]);
+
+    } else {
+      vtpmlogerror(VTPM_LOG_VTPM, "Error reading from migration server.\n");
+      goto abort_egress;
+    }
+    vtpmloginfomore(VTPM_LOG_VTPM, "\n");
+
+    if (size_read < (int)adj_param_size) {
+      vtpmloginfomore(VTPM_LOG_VTPM, "\n");
+      vtpmlogerror(VTPM_LOG_VTPM, "Command read(%d) is shorter than header 
indicates(%d).\n", size_read, adj_param_size);
+      status = TPM_IOERROR;
+      goto abort_egress;
+    }
+  } else {
+    vtpmloginfomore(VTPM_LOG_VTPM, "\n");
+  }
+
+  status=TPM_SUCCESS;
+  goto egress;
+
+ abort_egress:
+ egress:
+
+  return status;
+}
+
+
diff -r a4041ac6f152 -r 5014fd2b5c5a 
tools/vtpm_manager/migration/vtpm_migratorc.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/vtpm_manager/migration/vtpm_migratorc.c     Mon Jul 10 15:38:49 
2006 +0100
@@ -0,0 +1,211 @@
+// ===================================================================
+//
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above
+//     copyright notice, this list of conditions and the following
+//     disclaimer in the documentation and/or other materials provided
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+
+#include <stdio.h>
+#include <string.h>
+
+#include "tcg.h"
+#include "log.h"
+#include "bsg.h"
+#include "buffer.h"
+#include "vtpm_migrator.h"
+#include "vtpm_manager.h"
+
+TPM_RESULT handle_vtpm_mig_step2(char *server_addr, 
+                                 char *name, 
+                                 UINT32 instance) {
+  TPM_RESULT status, cmd_status;
+  buffer_t out_param_buf=NULL_BUF, mig_key_buf=NULL_BUF, empty_buf=NULL_BUF;
+  UINT32 offset; 
+  struct pack_buf_t addr_data32;
+
+  //===== Get Destination's Public Migration Key ======
+  TPMTRYRETURN( vtpm_migratord_open(server_addr) );
+
+  TPMTRYRETURN( vtpm_migratord_command(VTPM_MORD_MIG_STEP2,
+                                     &out_param_buf,
+                                     &cmd_status, 
+                                     &mig_key_buf) ); 
+  vtpm_migratord_close();
+
+  TPMTRYRETURN(cmd_status);
+
+  //===== Load migration key into vtpm_manager ========
+
+  addr_data32.data = (BYTE *)server_addr;
+  addr_data32.size = strlen(server_addr) + 1; // Include the null
+
+  TPMTRYRETURN ( buffer_init ( &out_param_buf, 
+                               sizeof(UINT32) + addr_data32.size 
+buffer_len(&mig_key_buf),
+                               NULL ) ) ;
+
+  offset =  BSG_PackList(out_param_buf.bytes, 1,
+               BSG_TPM_SIZE32_DATA, &addr_data32);
+
+  memcpy(out_param_buf.bytes + offset , mig_key_buf.bytes, 
buffer_len(&mig_key_buf) );
+
+  TPMTRYRETURN ( vtpm_manager_open() );
+
+  TPMTRYRETURN ( vtpm_manager_command(VTPM_ORD_LOAD_MIG_KEY,
+                                      &out_param_buf,
+                                      &cmd_status,
+                                      &empty_buf) );
+
+  vtpm_manager_close();
+
+  TPMTRYRETURN(cmd_status);
+
+  goto egress;
+
+ abort_egress:
+ egress:
+
+  buffer_free(&mig_key_buf);
+  buffer_free(&out_param_buf);
+
+  return status;
+}
+
+
+TPM_RESULT handle_vtpm_mig_step3(char *server_addr, 
+                                 char *name, 
+                                 UINT32 instance) {
+  TPM_RESULT status, cmd_status;
+  buffer_t out_param_buf=NULL_BUF, state_buf=NULL_BUF, empty_buf=NULL_BUF;
+  struct pack_buf_t addr_data32, name_data32, state_data32;
+
+  //===== Get vtpm state from vtpm_manager ========
+  addr_data32.data = (BYTE *)server_addr;
+  addr_data32.size = strlen(server_addr) + 1; // Include the null
+
+  TPMTRYRETURN ( buffer_init ( &out_param_buf,
+                               (2 * sizeof(UINT32)) + addr_data32.size,
+                               NULL ) ) ;
+
+  BSG_PackList(out_param_buf.bytes, 2,
+                 BSG_TYPE_UINT32, &instance, 
+                 BSG_TPM_SIZE32_DATA, &addr_data32);
+
+  TPMTRYRETURN ( vtpm_manager_open() );
+
+  TPMTRYRETURN ( vtpm_manager_command(VTPM_ORD_MIGRATE_OUT,
+                                      &out_param_buf,
+                                      &cmd_status,
+                                      &state_buf) );
+
+  vtpm_manager_close();
+
+  TPMTRYRETURN(cmd_status);
+
+  TPMTRYRETURN( buffer_free( &out_param_buf ) );
+
+  //===== Send vtpm state to destination ======
+  name_data32.data = (BYTE *)name;
+  name_data32.size = strlen(name) + 1; // Include the null
+  state_data32.data = state_buf.bytes;
+  state_data32.size = buffer_len(&state_buf);
+
+  TPMTRYRETURN( buffer_init( &out_param_buf,
+                             2 * sizeof(UINT32) + name_data32.size + 
state_data32.size,
+                             NULL ) ) ;
+                             
+  BSG_PackList(out_param_buf.bytes, 2,
+                 BSG_TPM_SIZE32_DATA, &name_data32,
+                 BSG_TPM_SIZE32_DATA, &state_data32);
+
+  TPMTRYRETURN( vtpm_migratord_open(server_addr) );
+
+  TPMTRYRETURN( vtpm_migratord_command(VTPM_MORD_MIG_STEP3,
+                                     &out_param_buf,
+                                     &cmd_status, 
+                                     &empty_buf) ); 
+  vtpm_migratord_close();
+
+  TPMTRYRETURN(cmd_status);
+
+  goto egress;
+
+ abort_egress:
+ egress:
+
+  buffer_free( &out_param_buf);
+  buffer_free( &state_buf);
+  buffer_free( &empty_buf);
+
+  return status;
+}
+
+
+// Usage vtpm_migrator addr domain_name instance step
+
+int main(int argc, char **argv) {
+
+    /* variables for processing of command */
+    TPM_RESULT status = TPM_FAIL;
+    char *server_addr, *name;
+    UINT32 instance, step;
+
+    if (argc != 5) {
+      vtpmlogerror(VTPM_LOG_VTPM, "Usage: vtpm_migrator addr vm_name instance 
step\n");
+      vtpmlogerror(VTPM_LOG_VTPM, "       params given %d\n", argc);
+      status= TPM_BAD_PARAMETER;
+      goto abort_egress;
+    }
+
+    server_addr = argv[1];
+    name = argv[2];
+    instance = atoi( argv[3] );
+    step = atoi( argv[4] );    
+
+    switch (step) {
+    case VTPM_MORD_MIG_STEP2:
+      status = handle_vtpm_mig_step2(server_addr, name, instance);
+      break;
+ 
+    case VTPM_MORD_MIG_STEP3:
+      status = handle_vtpm_mig_step3(server_addr, name, instance);
+      break;
+
+    default:
+      status = TPM_BAD_PARAMETER;
+      goto abort_egress;
+      break;
+    }
+ 
+    goto egress;
+ abort_egress:
+ egress:
+
+    return status;
+}
+
diff -r a4041ac6f152 -r 5014fd2b5c5a 
tools/vtpm_manager/migration/vtpm_migratord.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/vtpm_manager/migration/vtpm_migratord.c     Mon Jul 10 15:38:49 
2006 +0100
@@ -0,0 +1,202 @@
+// ===================================================================
+//
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above
+//     copyright notice, this list of conditions and the following
+//     disclaimer in the documentation and/or other materials provided
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+
+#include "tcg.h"
+#include "log.h"
+#include "bsg.h"
+#include "buffer.h"
+#include "vtpm_migrator.h"
+
+void build_error_msg( buffer_t *buf, TPM_RESULT status) {
+  TPM_TAG tag = VTPM_MTAG_RSP;
+  UINT32 out_param_size = VTPM_COMMAND_HEADER_SIZE;
+
+  buffer_init(buf, out_param_size, NULL);
+ 
+  BSG_PackList(buf->bytes, 3,
+                 BSG_TPM_TAG, &tag,
+                 BSG_TYPE_UINT32, &out_param_size,
+                 BSG_TPM_RESULT, &status );
+}
+
+int main() {
+
+    /* network variables */
+    int sock_descr, client_sock=-1, len;
+    struct sockaddr_in addr;
+    struct sockaddr_in client_addr;
+    unsigned int client_length;
+    int bytes;
+
+    /* variables for processing of command */
+    TPM_RESULT status = TPM_FAIL;
+    BYTE cmd_header[VTPM_COMMAND_HEADER_SIZE];
+    TPM_TAG tag;
+    TPM_COMMAND_CODE ord;
+    UINT32 in_param_size, adj_param_size;
+    int i, size_read, size_write;
+    buffer_t in_param_buf=NULL_BUF, result_buf=NULL_BUF;
+
+
+    /* setup socket */
+    sock_descr = socket(AF_INET, SOCK_STREAM, 0);
+
+    memset(&addr, 0, sizeof(addr));
+    addr.sin_family = AF_INET;
+    addr.sin_addr.s_addr = htonl(INADDR_ANY);
+    addr.sin_port = htons(VTPM_MIG_PORT);
+
+    if (bind(sock_descr, (struct sockaddr *)&addr, sizeof(addr)) == -1 ) {
+        vtpmlogerror(VTPM_LOG_VTPM, "Failed to bind to port %d.\n", 
VTPM_MIG_PORT);
+        return 1;
+    }
+        
+    listen(sock_descr, 10);
+
+    for(;;) {
+        // ============ clear client info and wait for connection ==========
+        memset(&client_addr, 0, sizeof(client_addr));
+        client_length = sizeof(client_addr);
+
+        vtpmloginfo(VTPM_LOG_VTPM, "Waiting for incoming migrations...\n");
+        client_sock=accept(sock_descr, &client_addr, &client_length);
+        if (client_sock == -1) {
+            vtpmlogerror(VTPM_LOG_VTPM, "Incoming connectionn failed.\n");
+            goto abort_command;
+        } else {
+            vtpmloginfo(VTPM_LOG_VTPM, "Incoming connection accepted.\n");
+        }
+
+        // =================== Read incoming command ======================
+        size_read = read( client_sock, cmd_header, VTPM_COMMAND_HEADER_SIZE);
+        if (size_read > 0) {
+            vtpmloginfo(VTPM_LOG_VTPM_DEEP, "RECV: 0x");
+            for (i=0; i<size_read; i++)
+                vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
+
+        } else {
+            vtpmlogerror(VTPM_LOG_VTPM, "Error reading from socket.\n");
+            build_error_msg(&result_buf, TPM_IOERROR);
+            goto abort_command_with_error;
+        }
+
+        if (size_read < (int) VTPM_COMMAND_HEADER_SIZE) {
+            vtpmlogerror(VTPM_LOG_VTPM, "Command from socket shorter than std 
header.\n");
+            build_error_msg(&result_buf, TPM_BAD_PARAMETER);
+            goto abort_command_with_error;
+        }
+
+        // Unpack response from client
+        BSG_UnpackList(cmd_header, 3,
+                       BSG_TPM_TAG, &tag,
+                       BSG_TYPE_UINT32, &in_param_size,
+                       BSG_TPM_COMMAND_CODE, &ord );
+
+
+        // If response has parameters, read them.
+        // Note that out_param_size is in the client's context
+        adj_param_size = in_param_size - VTPM_COMMAND_HEADER_SIZE;
+        if (adj_param_size > 0) {
+            buffer_init( &in_param_buf, adj_param_size, NULL);
+            size_read = read(client_sock, in_param_buf.bytes, adj_param_size);
+            if (size_read > 0) {
+                for (i=0; i< size_read; i++)
+                vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", 
in_param_buf.bytes[i]);
+
+            } else {
+                vtpmlogerror(VTPM_LOG_VTPM, "Error reading from socket.\n");
+                build_error_msg(&result_buf, TPM_IOERROR);
+                goto abort_command_with_error;
+            }
+            vtpmloginfomore(VTPM_LOG_VTPM, "\n");
+
+            if (size_read < (int)adj_param_size) {
+                vtpmloginfomore(VTPM_LOG_VTPM, "\n");
+                vtpmlogerror(VTPM_LOG_VTPM, "Command read(%d) is shorter than 
header indicates(%d).\n", size_read, adj_param_size);
+                build_error_msg(&result_buf, TPM_BAD_PARAMETER);
+                goto abort_command_with_error;
+            }
+        } else {
+            vtpmloginfomore(VTPM_LOG_VTPM, "\n");
+        }
+
+        /* Handle Command */
+        switch (ord) {
+        case VTPM_MORD_MIG_STEP2:
+          handle_vtpm_mig_step2(&in_param_buf, &result_buf);
+          break;
+ 
+        case VTPM_MORD_MIG_STEP3:
+          handle_vtpm_mig_step3(&in_param_buf, &result_buf);
+          break;
+
+        default:
+            build_error_msg(&result_buf, TPM_BAD_PARAMETER);
+            goto abort_command_with_error;
+        }
+
+  abort_command_with_error:
+        /* Write Response */
+        size_write = write(client_sock, result_buf.bytes, 
buffer_len(&result_buf));
+
+        if (size_write > 0) {
+            vtpmloginfo(VTPM_LOG_VTPM_DEEP, "SENT: 0x");
+            for (i=0; i< buffer_len(&result_buf); i++) {
+                vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", 
result_buf.bytes[i]);
+            }
+            vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+        } else {
+            vtpmlogerror(VTPM_LOG_VTPM, "Error writing response to client.\n");
+            goto abort_command;
+        }
+
+        if (size_write != (int) buffer_len(&result_buf) )
+           vtpmlogerror(VTPM_LOG_VTPM, "Could not send entire response to 
client(%d/%d)\n", size_write, buffer_len(&result_buf));
+
+  abort_command:
+        close(client_sock);
+        buffer_free(&in_param_buf);
+        buffer_free(&result_buf);
+
+    } // For (;;)
+
+    return 0;
+}
+
diff -r a4041ac6f152 -r 5014fd2b5c5a 
tools/vtpm_manager/migration/vtpm_migratord_handler.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/vtpm_manager/migration/vtpm_migratord_handler.c     Mon Jul 10 
15:38:49 2006 +0100
@@ -0,0 +1,171 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "tcg.h"
+#include "bsg.h"
+#include "log.h"
+#include "vtpm_migrator.h"
+#include "vtpm_manager.h"
+
+#define VTPM_SH_CMD_HDR  "bash -c \"cd /etc/xen/scripts; source 
/etc/xen/scripts/vtpm-common.sh;"
+#define VTPM_SH_CMD_FTR  "\""
+#define VTPM_SH_GETINST  "vtpmdb_get_free_instancenum"
+#define VTPM_SH_ADD      "vtpm_add_and_activate"
+#define VTPM_SH_RESUME   "vtpm_resume"
+
+// This must be updated to the longest command name. Currently GETINST
+#define VTPM_SH_CMD_SIZE (strlen(VTPM_SH_CMD_HDR) + strlen(VTPM_SH_CMD_FTR) + 
1 + strlen(VTPM_SH_GETINST) + 2)
+
+void handle_vtpm_mig_step2(buffer_t *in_param_buf, buffer_t *result_buf){
+
+  TPM_TAG tag = VTPM_TAG_RSP;
+  buffer_t out_param_buf= NULL_BUF, mig_key_buf=NULL_BUF; 
+  TPM_RESULT status=TPM_SUCCESS, cmd_status;
+  UINT32 out_param_size;
+  
+  if ( (!in_param_buf) || (!result_buf) ) {
+    status = TPM_BAD_PARAMETER;
+    goto abort_egress;
+  }
+
+  // ================= Call manager and get mig key ===============
+  TPMTRYRETURN( vtpm_manager_open() ); 
+  TPMTRYRETURN( vtpm_manager_command(VTPM_ORD_GET_MIG_KEY,
+                                     &out_param_buf, // Empty
+                                     &cmd_status,
+                                     &mig_key_buf) );
+  
+  vtpm_manager_close();
+
+  TPMTRYRETURN(cmd_status);
+
+  // ==================== return the  mig key =====================
+  out_param_size =  VTPM_COMMAND_HEADER_SIZE + buffer_len(&mig_key_buf);
+
+  TPMTRYRETURN( buffer_init(result_buf, 
+                            out_param_size,
+                            NULL) );
+
+  BSG_PackList( result_buf->bytes, 3,
+                  BSG_TPM_TAG, &tag,
+                  BSG_TYPE_UINT32, &out_param_size,
+                  BSG_TPM_RESULT, &status);
+
+  memcpy(result_buf->bytes + VTPM_COMMAND_HEADER_SIZE, 
+         mig_key_buf.bytes, buffer_len(&mig_key_buf));
+
+  goto egress;
+
+ abort_egress:
+  buffer_free(result_buf);
+  build_error_msg(result_buf, status);
+
+ egress:
+  return;
+}
+
+void handle_vtpm_mig_step3(buffer_t *in_param_buf, buffer_t *result_buf){
+  
+  TPM_TAG tag = VTPM_TAG_RSP;
+  buffer_t out_param_buf= NULL_BUF, mig_key_buf=NULL_BUF, empty_buf=NULL_BUF;
+  TPM_RESULT status=TPM_SUCCESS, cmd_status;
+  UINT32 out_param_size, instance;
+  char *shell_cmd_str=NULL;
+  FILE *shell_f=NULL;
+
+  if ( (!in_param_buf) || (!result_buf) ) {
+    status = TPM_BAD_PARAMETER;
+    goto abort_egress;
+  }
+
+  // ================= Read Parameters ===============
+  struct pack_buf_t name_data32, state_data32;
+
+  BSG_UnpackList(in_param_buf->bytes, 2,
+                 BSG_TPM_SIZE32_DATA, &name_data32,
+                 BSG_TPM_SIZE32_DATA, &state_data32);
+
+  // Before using this string, protect us from a non-null term array.
+  if (name_data32.data[name_data32.size -1] != 0x00) {
+    name_data32.data[name_data32.size -1] = 0x00;
+  }
+
+  // ====== Call hotplug-script and get an instance ======
+  shell_cmd_str = (char *) malloc(VTPM_SH_CMD_SIZE + name_data32.size + 10); 
// 10 is just padding for the UINT32
+
+  sprintf(shell_cmd_str, VTPM_SH_CMD_HDR VTPM_SH_GETINST VTPM_SH_CMD_FTR);
+
+  shell_f = popen(shell_cmd_str, "r");
+  fscanf(shell_f, "%d", &instance);
+  pclose(shell_f);
+  
+  // ====== Call hotplug-script and add instance ======
+  sprintf(shell_cmd_str, VTPM_SH_CMD_HDR VTPM_SH_ADD " %s %d" VTPM_SH_CMD_FTR, 
name_data32.data, instance);
+  system(shell_cmd_str);
+
+  // ========= Call vtpm_manager and load VTPM =======
+  TPMTRYRETURN( buffer_init( &out_param_buf, 
+                             2*sizeof(UINT32) + state_data32.size,
+                             NULL) );
+
+  BSG_PackList(out_param_buf.bytes, 2,
+                 BSG_TYPE_UINT32, &instance,
+                 BSG_TPM_SIZE32_DATA, &state_data32);
+
+  TPMTRYRETURN( vtpm_manager_open() ); 
+  TPMTRYRETURN( vtpm_manager_command(VTPM_ORD_MIGRATE_IN,
+                                     &out_param_buf,
+                                     &cmd_status,
+                                     &empty_buf) );
+
+  vtpm_manager_close();
+
+  TPMTRYRETURN(cmd_status);
+
+  // ====== Call hotplug-script and resume instance ======
+  sprintf(shell_cmd_str, VTPM_SH_CMD_HDR VTPM_SH_RESUME " %d" VTPM_SH_CMD_FTR, 
instance);
+  system(shell_cmd_str);
+
+  goto egress;
+ abort_egress:
+ egress:
+  free(shell_cmd_str);
+
+  // In this case no params come back, so reuse build_error_msg even for 
succes.
+  build_error_msg(result_buf, status);
+  return;
+}
+

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [VTPM_Tools] Support for (non-local) Migration added. Local migration, Xen patchbot-unstable <=