[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |