aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>2006-07-10 15:38:49 +0100
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>2006-07-10 15:38:49 +0100
commit6b900ffb504cfa4f851b6b188f0582c3c5195647 (patch)
treeaee818d678413e70eb92feb1358cf2593530c610 /tools
parentb13a112805806d2ee8ac09bd9b02b798b01276a0 (diff)
downloadxen-6b900ffb504cfa4f851b6b188f0582c3c5195647.tar.gz
xen-6b900ffb504cfa4f851b6b188f0582c3c5195647.tar.bz2
xen-6b900ffb504cfa4f851b6b188f0582c3c5195647.zip
[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@intel.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/examples/vtpm-impl56
-rw-r--r--tools/vtpm_manager/Makefile14
-rw-r--r--tools/vtpm_manager/Rules.mk1
-rw-r--r--tools/vtpm_manager/crypto/sym_crypto.c17
-rw-r--r--tools/vtpm_manager/manager/dmictl.c111
-rw-r--r--tools/vtpm_manager/manager/migration.c307
-rw-r--r--tools/vtpm_manager/manager/securestorage.c81
-rw-r--r--tools/vtpm_manager/manager/vtpm_ipc.c2
-rw-r--r--tools/vtpm_manager/manager/vtpm_manager.c4
-rw-r--r--tools/vtpm_manager/manager/vtpm_manager.h16
-rw-r--r--tools/vtpm_manager/manager/vtpm_manager_handler.c18
-rw-r--r--tools/vtpm_manager/manager/vtpmd.c1
-rw-r--r--tools/vtpm_manager/manager/vtpmpriv.h39
-rw-r--r--tools/vtpm_manager/manager/vtsp.c50
-rw-r--r--tools/vtpm_manager/manager/vtsp.h3
-rw-r--r--tools/vtpm_manager/migration/Makefile39
-rw-r--r--tools/vtpm_manager/migration/vtpm_manager_if.c186
-rw-r--r--tools/vtpm_manager/migration/vtpm_migrator.h104
-rw-r--r--tools/vtpm_manager/migration/vtpm_migrator_if.c219
-rw-r--r--tools/vtpm_manager/migration/vtpm_migratorc.c211
-rw-r--r--tools/vtpm_manager/migration/vtpm_migratord.c202
-rw-r--r--tools/vtpm_manager/migration/vtpm_migratord_handler.c171
-rw-r--r--tools/vtpm_manager/util/buffer.c23
-rw-r--r--tools/vtpm_manager/util/buffer.h4
-rw-r--r--tools/vtpm_manager/util/log.h4
-rw-r--r--tools/vtpm_manager/util/tcg.h18
26 files changed, 1750 insertions, 151 deletions
diff --git a/tools/examples/vtpm-impl b/tools/examples/vtpm-impl
index f51f3383ca..25b4e4a41b 100644
--- a/tools/examples/vtpm-impl
+++ b/tools/examples/vtpm-impl
@@ -45,6 +45,8 @@ TPM_SUCCESS=00000000
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 --git a/tools/vtpm_manager/Makefile b/tools/vtpm_manager/Makefile
index 1ae3a180ee..874e6b724e 100644
--- a/tools/vtpm_manager/Makefile
+++ b/tools/vtpm_manager/Makefile
@@ -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 --git a/tools/vtpm_manager/Rules.mk b/tools/vtpm_manager/Rules.mk
index 6f553b56fc..3435afed38 100644
--- a/tools/vtpm_manager/Rules.mk
+++ b/tools/vtpm_manager/Rules.mk
@@ -69,3 +69,4 @@ CFLAGS += -DLOGGING_MODULES="(BITMASK(VTPM_LOG_TCS)|BITMASK(VTPM_LOG_VTSP)|BITMA
CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/crypto
CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/util
CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/tcs
+CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/manager
diff --git a/tools/vtpm_manager/crypto/sym_crypto.c b/tools/vtpm_manager/crypto/sym_crypto.c
index b3bce466a5..3d86e19eb2 100644
--- a/tools/vtpm_manager/crypto/sym_crypto.c
+++ b/tools/vtpm_manager/crypto/sym_crypto.c
@@ -68,8 +68,7 @@ TPM_RESULT Crypto_symcrypto_initkey (symkey_t * key, const buffer_t* keybits) {
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 (symkey_t * key) {
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 (symkey_t* key,
// 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 (symkey_t* key,
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 --git a/tools/vtpm_manager/manager/dmictl.c b/tools/vtpm_manager/manager/dmictl.c
index 7961f98433..588dcaf560 100644
--- a/tools/vtpm_manager/manager/dmictl.c
+++ b/tools/vtpm_manager/manager/dmictl.c
@@ -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 buffer_t *param_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 buffer_t *param_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,14 +164,8 @@ TPM_RESULT VTPM_Handle_New_DMI(const buffer_t *param_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;
// Design specific new DMI code.
@@ -158,10 +173,6 @@ TPM_RESULT VTPM_Handle_New_DMI(const buffer_t *param_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 buffer_t *param_buf) {
// Close DMI first
TPMTRYRETURN(close_dmi( dmi_res ));
- free ( dmi_res );
+ free ( dmi_res );
status=TPM_SUCCESS;
goto egress;
diff --git a/tools/vtpm_manager/manager/migration.c b/tools/vtpm_manager/manager/migration.c
new file mode 100644
index 0000000000..54da708d87
--- /dev/null
+++ b/tools/vtpm_manager/manager/migration.c
@@ -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 --git a/tools/vtpm_manager/manager/securestorage.c b/tools/vtpm_manager/manager/securestorage.c
index 37c0a160c4..e4bb5dbb9b 100644
--- a/tools/vtpm_manager/manager/securestorage.c
+++ b/tools/vtpm_manager/manager/securestorage.c
@@ -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_t *inbuf,
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 cipher_size,
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_alias_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 (&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_RESOURCE *myDMI,
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_RESOURCE *myDMI,
}
-/* 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_RESOURCE *myDMI,
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);
+ vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Load_NVMing[%d],\n", buffer_len(&sealed_NVM));
- Crypto_SHA1Full(sealed_NVM, sealed_NVM_size, (BYTE *) &sealedNVMHash);
+ 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_RESOURCE *myDMI,
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_RESOURCE *myDMI,
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));
- dmis++;
+ step_size += BSG_UnpackList(flat_table + step_size, 2,
+ BSG_TYPE_UINT32, &dmi_id,
+ BSG_TYPE_BYTE, &dmi_type);
- dmi_res->connected = FALSE;
+ //TODO: Try and gracefully recover from problems.
+ TPMTRYRETURN(init_dmi(dmi_id, dmi_type, &dmi_res) );
+ dmis++;
- 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 --git a/tools/vtpm_manager/manager/vtpm_ipc.c b/tools/vtpm_manager/manager/vtpm_ipc.c
index 0b8176c00b..319dc83002 100644
--- a/tools/vtpm_manager/manager/vtpm_ipc.c
+++ b/tools/vtpm_manager/manager/vtpm_ipc.c
@@ -135,7 +135,7 @@ void vtpm_ipc_close(vtpm_ipc_handle_t *ipc_h) {
if (ipc_h) {
close(ipc_h->fh);
+ ipc_h->fh = VTPM_IPC_CLOSED;
}
- ipc_h->fh = VTPM_IPC_CLOSED;
}
diff --git a/tools/vtpm_manager/manager/vtpm_manager.c b/tools/vtpm_manager/manager/vtpm_manager.c
index e7663f4741..e089f780d6 100644
--- a/tools/vtpm_manager/manager/vtpm_manager.c
+++ b/tools/vtpm_manager/manager/vtpm_manager.c
@@ -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 --git a/tools/vtpm_manager/manager/vtpm_manager.h b/tools/vtpm_manager/manager/vtpm_manager.h
index 3df76720f8..cf9f09e636 100644
--- a/tools/vtpm_manager/manager/vtpm_manager.h
+++ b/tools/vtpm_manager/manager/vtpm_manager.h
@@ -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 --git a/tools/vtpm_manager/manager/vtpm_manager_handler.c b/tools/vtpm_manager/manager/vtpm_manager_handler.c
index c3c54362bb..3ac0928749 100644
--- a/tools/vtpm_manager/manager/vtpm_manager_handler.c
+++ b/tools/vtpm_manager/manager/vtpm_manager_handler.c
@@ -301,6 +301,16 @@ TPM_RESULT vtpm_manager_handle_vtpm_cmd(VTPM_DMI_RESOURCE *dmi_res,
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
@@ -318,6 +328,14 @@ TPM_RESULT vtpm_manager_handle_vtpm_cmd(VTPM_DMI_RESOURCE *dmi_res,
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:
status = TPM_BAD_ORDINAL;
} // switch
diff --git a/tools/vtpm_manager/manager/vtpmd.c b/tools/vtpm_manager/manager/vtpmd.c
index 5838fb1c09..8aec9769f8 100644
--- a/tools/vtpm_manager/manager/vtpmd.c
+++ b/tools/vtpm_manager/manager/vtpmd.c
@@ -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 --git a/tools/vtpm_manager/manager/vtpmpriv.h b/tools/vtpm_manager/manager/vtpmpriv.h
index 1296b1b8e5..4bec4f6baa 100644
--- a/tools/vtpm_manager/manager/vtpmpriv.h
+++ b/tools/vtpm_manager/manager/vtpmpriv.h
@@ -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 @@ typedef struct tdVTPM_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
@@ -122,6 +133,8 @@ TPM_RESULT VTPM_Manager_Handler(vtpm_ipc_handle_t *tx_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,
buffer_t *outbuf);
@@ -140,6 +153,15 @@ TPM_RESULT VTPM_Handle_Close_DMI(const buffer_t *param_buf);
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_RESOURCE *dmi_res, BYTE startup_mode);
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 --git a/tools/vtpm_manager/manager/vtsp.c b/tools/vtpm_manager/manager/vtsp.c
index f7408c6457..fc8a66ffc8 100644
--- a/tools/vtpm_manager/manager/vtsp.c
+++ b/tools/vtpm_manager/manager/vtsp.c
@@ -141,13 +141,18 @@ TPM_RESULT VerifyAuth( /*[IN]*/ const BYTE *outParamDigestText,
(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_HANDLE hContext,
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,7 +211,9 @@ TPM_RESULT VTSP_OSAP(const TCS_CONTEXT_HANDLE hContext,
memset(&auth->HMAC, 0, sizeof(TPM_DIGEST));
auth->fContinueAuthSession = FALSE;
-
+
+ vtpmloginfo(VTPM_LOG_VTSP_DEEP, "Auth Session: 0x%x opened by TPM_OSAP.\n", auth->AuthHandle);
+
goto egress;
abort_egress:
@@ -216,6 +224,23 @@ TPM_RESULT VTSP_OSAP(const TCS_CONTEXT_HANDLE hContext,
}
+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,
CRYPTO_INFO *crypto_info) {
@@ -728,6 +753,7 @@ TPM_RESULT VTSP_Bind( CRYPTO_INFO *cryptoInfo,
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 *cryptoInfo,
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 *cryptoInfo,
vtpmloginfomore(VTPM_LOG_TXDATA, "%2.2x ", out_tmp[i]);
}
vtpmloginfomore(VTPM_LOG_TXDATA, "\n");
-
+
+ goto egress;
+ abort_egress:
+ egress:
+
// Free flatBoundData
free(flatBoundData);
diff --git a/tools/vtpm_manager/manager/vtsp.h b/tools/vtpm_manager/manager/vtsp.h
index 90077c2ec1..2fb0440037 100644
--- a/tools/vtpm_manager/manager/vtsp.h
+++ b/tools/vtpm_manager/manager/vtsp.h
@@ -59,6 +59,9 @@ TPM_RESULT VTSP_OSAP( const TCS_CONTEXT_HANDLE hContext,
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 --git a/tools/vtpm_manager/migration/Makefile b/tools/vtpm_manager/migration/Makefile
new file mode 100644
index 0000000000..4cc8ea8cb6
--- /dev/null
+++ b/tools/vtpm_manager/migration/Makefile
@@ -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 --git a/tools/vtpm_manager/migration/vtpm_manager_if.c b/tools/vtpm_manager/migration/vtpm_manager_if.c
new file mode 100644
index 0000000000..08986f4fed
--- /dev/null
+++ b/tools/vtpm_manager/migration/vtpm_manager_if.c
@@ -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 --git a/tools/vtpm_manager/migration/vtpm_migrator.h b/tools/vtpm_manager/migration/vtpm_migrator.h
new file mode 100644
index 0000000000..8d52e668dd
--- /dev/null
+++ b/tools/vtpm_manager/migration/vtpm_migrator.h
@@ -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 --git a/tools/vtpm_manager/migration/vtpm_migrator_if.c b/tools/vtpm_manager/migration/vtpm_migrator_if.c
new file mode 100644
index 0000000000..de48b2dd63
--- /dev/null
+++ b/tools/vtpm_manager/migration/vtpm_migrator_if.c
@@ -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 --git a/tools/vtpm_manager/migration/vtpm_migratorc.c b/tools/vtpm_manager/migration/vtpm_migratorc.c
new file mode 100644
index 0000000000..18b3bdbe8c
--- /dev/null
+++ b/tools/vtpm_manager/migration/vtpm_migratorc.c
@@ -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 --git a/tools/vtpm_manager/migration/vtpm_migratord.c b/tools/vtpm_manager/migration/vtpm_migratord.c
new file mode 100644
index 0000000000..ea18c8c87c
--- /dev/null
+++ b/tools/vtpm_manager/migration/vtpm_migratord.c
@@ -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 --git a/tools/vtpm_manager/migration/vtpm_migratord_handler.c b/tools/vtpm_manager/migration/vtpm_migratord_handler.c
new file mode 100644
index 0000000000..80c46f01b9
--- /dev/null
+++ b/tools/vtpm_manager/migration/vtpm_migratord_handler.c
@@ -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;
+}
+
diff --git a/tools/vtpm_manager/util/buffer.c b/tools/vtpm_manager/util/buffer.c
index 7bb64f79b5..df48bc2c40 100644
--- a/tools/vtpm_manager/util/buffer.c
+++ b/tools/vtpm_manager/util/buffer.c
@@ -124,7 +124,20 @@ TPM_RESULT buffer_init_alias (buffer_t * buf, const buffer_t * b,
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, const buffer_t* src)
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 * buf, tpm_size_t len, const BYTE* bytes)
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 --git a/tools/vtpm_manager/util/buffer.h b/tools/vtpm_manager/util/buffer.h
index 9fdf7ea60f..d8a9abcfb3 100644
--- a/tools/vtpm_manager/util/buffer.h
+++ b/tools/vtpm_manager/util/buffer.h
@@ -69,6 +69,10 @@ TPM_RESULT buffer_init_const (buffer_t * buf, tpm_size_t size, const BYTE* val);
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 --git a/tools/vtpm_manager/util/log.h b/tools/vtpm_manager/util/log.h
index a35e7f19c3..1f15f5b876 100644
--- a/tools/vtpm_manager/util/log.h
+++ b/tools/vtpm_manager/util/log.h
@@ -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 --git a/tools/vtpm_manager/util/tcg.h b/tools/vtpm_manager/util/tcg.h
index f529e82a76..5c4291362f 100644
--- a/tools/vtpm_manager/util/tcg.h
+++ b/tools/vtpm_manager/util/tcg.h
@@ -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)