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

[Xen-changelog] [xen-unstable] [VTPM_Tools] Support for (non-local) Migration added. Local migration



# 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


 


Rackspace

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