diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/crypto/crypto.c xen-unstable-trp-sdp/tools/vtpm_manager/crypto/crypto.c --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/crypto/crypto.c 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/crypto/crypto.c 2011-02-23 14:42:11.000000000 -0500 @@ -45,6 +45,8 @@ #include "crypto.h" #include "log.h" +extern const EVP_CIPHER * SYM_CIPHER; + /** * Initialize cryptography library * @rand: random seed @@ -83,6 +85,6 @@ result = RAND_pseudo_bytes((BYTE*) data, size); if (result <= 0) - vtpmlogerror (VTPM_LOG_CRYPTO, "RAND_pseudo_bytes failed: %s\n", - ERR_error_string (ERR_get_error(), NULL)); + vtpmlogerror (VTPM_LOG_CRYPTO, "RAND_pseudo_bytes failed: rc=%d errstr=%s\n", + result, ERR_error_string (ERR_get_error(), NULL)); } diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/crypto/crypto.h xen-unstable-trp-sdp/tools/vtpm_manager/crypto/crypto.h --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/crypto/crypto.h 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/crypto/crypto.h 2011-02-23 14:42:11.000000000 -0500 @@ -76,7 +76,7 @@ void Crypto_Init(const BYTE* rand, int size); -void Crypto_Exit(); +void Crypto_Exit(void); void Crypto_GetRandom(void* data, int size); @@ -127,6 +127,8 @@ /*[IN]*/ BYTE *modulus, CRYPTO_INFO* cryptoInfo); +void Crypto_RSACryptoInfoFree(CRYPTO_INFO* cryptoInfo); + // // symmetric pack and unpack operations // diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/crypto/Makefile xen-unstable-trp-sdp/tools/vtpm_manager/crypto/Makefile --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/crypto/Makefile 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/crypto/Makefile 2011-02-23 14:42:11.000000000 -0500 @@ -1,5 +1,11 @@ XEN_ROOT = ../../.. -include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk +include ../Rules.mk + +CFLAGS += -I../util +CFLAGS += -I../tcs +CFLAGS += -I../manager + + BIN = libtcpaCrypto.a diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/crypto/rsa.c xen-unstable-trp-sdp/tools/vtpm_manager/crypto/rsa.c --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/crypto/rsa.c 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/crypto/rsa.c 2011-02-23 14:42:11.000000000 -0500 @@ -149,6 +149,10 @@ } +void Crypto_RSACryptoInfoFree(CRYPTO_INFO* cryptoInfo) { + RSA_free(cryptoInfo->keyInfo); +} + int Crypto_RSAEnc( CRYPTO_INFO *key, UINT32 inDataSize, BYTE *inData, @@ -161,6 +165,7 @@ if (paddedData == NULL) return -1; + memset(paddedData, 0, sizeof(BYTE) * paddedDataSize); *outDataSize = 0; diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/crypto/sym_crypto.c xen-unstable-trp-sdp/tools/vtpm_manager/crypto/sym_crypto.c --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/crypto/sym_crypto.c 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/crypto/sym_crypto.c 2011-02-23 14:42:11.000000000 -0500 @@ -41,8 +41,16 @@ #include #include "tcg.h" +#include "log.h" #include "sym_crypto.h" +struct symkey_t { + buffer_t key; + + EVP_CIPHER_CTX context; + const EVP_CIPHER * cipher; +}; + typedef enum crypt_op_type_t { CRYPT_ENCRYPT, CRYPT_DECRYPT @@ -61,19 +69,22 @@ const BYTE ZERO_IV[EVP_MAX_IV_LENGTH] = {0}; -TPM_RESULT Crypto_symcrypto_initkey (symkey_t * key, const buffer_t* keybits) { +TPM_RESULT Crypto_symcrypto_initkey (symkey_t ** key, const buffer_t* keybits) { TPM_RESULT status = TPM_SUCCESS; - EVP_CIPHER_CTX_init (&key->context); + *key = malloc(sizeof(symkey_t)); + + EVP_CIPHER_CTX_init (&(*key)->context); - key->cipher = SYM_CIPHER; + (*key)->cipher = SYM_CIPHER; - TPMTRYRETURN( buffer_init_copy (&key->key, keybits)); + TPMTRYRETURN( buffer_init_copy (&(*key)->key, keybits)); goto egress; abort_egress: - EVP_CIPHER_CTX_cleanup (&key->context); + EVP_CIPHER_CTX_cleanup (&(*key)->context); + free(key); egress: @@ -82,19 +93,21 @@ -TPM_RESULT Crypto_symcrypto_genkey (symkey_t * key) { +TPM_RESULT Crypto_symcrypto_genkey (symkey_t ** key) { int res; TPM_RESULT status = TPM_SUCCESS; + + *key = malloc(sizeof(symkey_t)); // hmm, EVP_CIPHER_CTX_init does not return a value - EVP_CIPHER_CTX_init (&key->context); + EVP_CIPHER_CTX_init (&(*key)->context); - key->cipher = SYM_CIPHER; + (*key)->cipher = SYM_CIPHER; - TPMTRYRETURN( buffer_init (&key->key, EVP_CIPHER_key_length(key->cipher), NULL)) ; + 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); + res = RAND_pseudo_bytes ((*key)->key.bytes, (*key)->key.size); if (res < 0) ERRORDIE (TPM_SHORTRANDOM); @@ -102,8 +115,9 @@ goto egress; abort_egress: - EVP_CIPHER_CTX_cleanup (&key->context); - buffer_free (&key->key); + EVP_CIPHER_CTX_cleanup (&(*key)->context); + buffer_free (&(*key)->key); + free(key); egress: return status; @@ -119,11 +133,11 @@ buffer_init_const (&iv, EVP_MAX_IV_LENGTH, ZERO_IV); - buffer_init (o_cipher, - clear->size + - EVP_CIPHER_iv_length(key->cipher) + - EVP_CIPHER_block_size (key->cipher), - 0); + TPMTRYRETURN( buffer_init (o_cipher, + clear->size + + EVP_CIPHER_iv_length(key->cipher) + + EVP_CIPHER_block_size (key->cipher), + 0) ); // copy the IV into the front buffer_copy (o_cipher, &iv); @@ -139,6 +153,7 @@ goto egress; abort_egress: + buffer_free(o_cipher); egress: @@ -170,7 +185,7 @@ // and decrypt TPMTRYRETURN ( ossl_symcrypto_op (key, &cipher_alias, &iv, o_clear, CRYPT_DECRYPT) ); - + goto egress; abort_egress: @@ -188,6 +203,8 @@ buffer_free (&key->key); EVP_CIPHER_CTX_cleanup (&key->context); + + free(key); return TPM_SUCCESS; } @@ -235,3 +252,8 @@ return status; } + +buffer_t* Crypto_symkey_getkey(symkey_t* key) +{ + return &key->key; +} diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/crypto/sym_crypto.h xen-unstable-trp-sdp/tools/vtpm_manager/crypto/sym_crypto.h --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/crypto/sym_crypto.h 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/crypto/sym_crypto.h 2011-02-23 14:42:11.000000000 -0500 @@ -40,21 +40,15 @@ #ifndef _SYM_CRYPTO_H #define _SYM_CRYPTO_H -#include #include "buffer.h" -typedef struct symkey_t { - buffer_t key; - - EVP_CIPHER_CTX context; - const EVP_CIPHER * cipher; -} symkey_t; +typedef struct symkey_t symkey_t; -extern const EVP_CIPHER * SYM_CIPHER; +//Allocates a symkey with random bits +TPM_RESULT Crypto_symcrypto_genkey (symkey_t ** key); -TPM_RESULT Crypto_symcrypto_genkey (symkey_t * key); - -TPM_RESULT Crypto_symcrypto_initkey (symkey_t * key, const buffer_t* keybits); +//Allocates a symkey with given keybits +TPM_RESULT Crypto_symcrypto_initkey (symkey_t ** key, const buffer_t* keybits); // these functions will allocate their output buffers @@ -66,7 +60,10 @@ const buffer_t* cipher, buffer_t* o_clear); -// only free the internal parts, not the 'key' ptr +//Frees the symkey TPM_RESULT Crypto_symcrypto_freekey (symkey_t * key); +//Get the raw key byte buffer +buffer_t* Crypto_symkey_getkey(symkey_t* key); + #endif /* _SYM_CRYPTO_H */ diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/Makefile xen-unstable-trp-sdp/tools/vtpm_manager/Makefile --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/Makefile 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/Makefile 2011-02-23 14:42:11.000000000 -0500 @@ -1,9 +1,9 @@ XEN_ROOT = ../.. # Base definitions and rules -include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk +include Rules.mk -SUBDIRS = crypto tcs util manager migration +SUBDIRS = crypto tcs util manager migration vtpmmgrtalk vtpmconnd OPENSSL_HEADER = /usr/include/openssl/crypto.h .PHONY: all clean install diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/dmictl.c xen-unstable-trp-sdp/tools/vtpm_manager/manager/dmictl.c --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/dmictl.c 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/manager/dmictl.c 2011-02-23 14:42:11.000000000 -0500 @@ -40,6 +40,9 @@ #include #include #include +#include +#include +#include #include "vtpmpriv.h" #include "bsg.h" @@ -51,6 +54,13 @@ #define TPM_EMULATOR_PATH "/usr/bin/vtpmd" +#ifndef VTPM_STUBDOM +// This is needed to all extra_close_dmi to close this to prevent a +// broken pipe when no DMIs are left. +vtpm_ipc_handle_t *g_rx_tpm_ipc_h; +#endif + + // 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 @@ -81,7 +91,7 @@ // 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); + vtpmlogerror(VTPM_LOG_VTPM, "Failed to insert instance %" PRIu32 "into table. Aborting.\n", dmi_id); status = TPM_FAIL; goto abort_egress; } @@ -116,6 +126,161 @@ return (VTPM_Close_DMI_Extra(dmi_res) ); } + +void free_dmi(VTPM_DMI_RESOURCE *dmi_res) { + if(dmi_res != NULL) { + free(dmi_res->NVMLocation); + } + free(dmi_res); +} + +TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res, BYTE vm_type, BYTE startup_mode) { + + TPM_RESULT status = TPM_SUCCESS; +#ifndef VTPM_STUBDOM + int fh; + char dmi_id_str[11]; // UINT32s are up to 10 digits + NULL + char *tx_vtpm_name, *tx_tpm_name, *vm_type_string; + struct stat file_info; + + if (dmi_res->dmi_id == VTPM_CTL_DM) { + dmi_res->tx_tpm_ipc_h = NULL; + dmi_res->rx_tpm_ipc_h = NULL; + dmi_res->tx_vtpm_ipc_h = NULL; + dmi_res->rx_vtpm_ipc_h = NULL; + } else { + // Create a pair of fifo pipes + dmi_res->rx_tpm_ipc_h = NULL; + dmi_res->rx_vtpm_ipc_h = NULL; + + if ( ((dmi_res->tx_tpm_ipc_h = (vtpm_ipc_handle_t *) malloc (sizeof(vtpm_ipc_handle_t))) == NULL ) || + ((dmi_res->tx_vtpm_ipc_h =(vtpm_ipc_handle_t *) malloc (sizeof(vtpm_ipc_handle_t))) == NULL ) || + ((tx_tpm_name = (char *) malloc(11 + strlen(VTPM_TX_TPM_FNAME))) == NULL ) || + ((tx_vtpm_name =(char *) malloc(11 + strlen(VTPM_TX_VTPM_FNAME))) == NULL) ) { + status =TPM_RESOURCES; + goto abort_egress; + } + + sprintf(tx_tpm_name, VTPM_TX_TPM_FNAME, (uint32_t) dmi_res->dmi_id); + sprintf(tx_vtpm_name, VTPM_TX_VTPM_FNAME, (uint32_t) dmi_res->dmi_id); + + if ( (vtpm_ipc_init(dmi_res->tx_tpm_ipc_h, tx_tpm_name, O_WRONLY | O_NONBLOCK, TRUE, FALSE) != 0) || + (vtpm_ipc_init(dmi_res->tx_vtpm_ipc_h, tx_vtpm_name, O_WRONLY, TRUE, FALSE) != 0) ) { //FIXME: O_NONBLOCK? + status = TPM_IOERROR; + goto abort_egress; + } + + // Measure DMI + // FIXME: This will measure DMI. Until then use a fixed DMI_Measurement value + // Also, this mechanism is specific to 1 VM architecture. + /* + fh = open(TPM_EMULATOR_PATH, O_RDONLY); + stat_ret = fstat(fh, &file_stat); + if (stat_ret == 0) + dmi_size = file_stat.st_size; + else { + vtpmlogerror(VTPM_LOG_VTPM, "Could not open vtpmd!!\n"); + status = TPM_IOERROR; + goto abort_egress; + } + dmi_buffer + */ + memset(&dmi_res->DMI_measurement, 0xcc, sizeof(TPM_DIGEST)); + + if (vm_type == VTPM_TYPE_PVM) + vm_type_string = (BYTE *)&VTPM_TYPE_PVM_STRING; + else + vm_type_string = (BYTE *)&VTPM_TYPE_HVM_STRING; + + // Launch DMI + sprintf(dmi_id_str, "%d", (int) dmi_res->dmi_id); +#ifdef MANUAL_DM_LAUNCH + vtpmlogerror(VTPM_LOG_VTPM, "Manually start VTPM with dmi=%s now.\n", dmi_id_str); + dmi_res->dmi_pid = 0; +#else + pid_t pid = fork(); + + if (pid == -1) { + vtpmlogerror(VTPM_LOG_VTPM, "Could not fork to launch vtpm\n"); + status = TPM_RESOURCES; + goto abort_egress; + } else if (pid == 0) { + switch (startup_mode) { + case TPM_ST_CLEAR: + execl (TPM_EMULATOR_PATH, "vtpmd", "clear", vm_type_string, dmi_id_str, NULL); + break; + case TPM_ST_STATE: + execl (TPM_EMULATOR_PATH, "vtpmd", "save", vm_type_string, dmi_id_str, NULL); + break; + case TPM_ST_DEACTIVATED: + execl (TPM_EMULATOR_PATH, "vtpmd", "deactivated", vm_type_string, dmi_id_str, NULL); + break; + default: + status = TPM_BAD_PARAMETER; + goto abort_egress; + } + + // Returning from these at all is an error. + vtpmlogerror(VTPM_LOG_VTPM, "Could not exec to launch vtpm\n"); + } else { + dmi_res->dmi_pid = pid; + vtpmloginfo(VTPM_LOG_VTPM, "Launching DMI on PID = %d\n", pid); + } +#endif // MANUAL_DM_LAUNCH + + } // If DMI = VTPM_CTL_DM + status = TPM_SUCCESS; +#endif + +abort_egress: + //FIXME: Everything should be freed here + return (status); +} + +TPM_RESULT VTPM_Close_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res) { + TPM_RESULT status = TPM_SUCCESS; + +#ifndef VTPM_STUBDOM + if (vtpm_globals->connected_dmis == 0) { + // No more DMI's connected. Close fifo to prevent a broken pipe. + // This is hackish. Need to think of another way. + vtpm_ipc_close(g_rx_tpm_ipc_h); + } + + + if (dmi_res->dmi_id != VTPM_CTL_DM) { + vtpm_ipc_close(dmi_res->tx_tpm_ipc_h); + vtpm_ipc_close(dmi_res->tx_vtpm_ipc_h); + + free(dmi_res->tx_tpm_ipc_h->name); + free(dmi_res->tx_vtpm_ipc_h->name); + free(dmi_res->tx_tpm_ipc_h); + free(dmi_res->tx_vtpm_ipc_h); + +#ifndef MANUAL_DM_LAUNCH + if (dmi_res->dmi_id != VTPM_CTL_DM) { + if (dmi_res->dmi_pid != 0) { + vtpmloginfo(VTPM_LOG_VTPM, "Killing dmi on pid %d.\n", dmi_res->dmi_pid); + if (kill(dmi_res->dmi_pid, SIGKILL) !=0) { + vtpmloginfo(VTPM_LOG_VTPM, "DMI on pid %d is already dead.\n", dmi_res->dmi_pid); + } else if (waitpid(dmi_res->dmi_pid, NULL, 0) != dmi_res->dmi_pid) { + vtpmlogerror(VTPM_LOG_VTPM, "DMI on pid %d failed to stop.\n", dmi_res->dmi_pid); + status = TPM_FAIL; + } + } else { + vtpmlogerror(VTPM_LOG_VTPM, "Could not kill dmi because it's pid was 0.\n"); + status = TPM_FAIL; + } + } +#endif + + } //endif ! dom0 +#endif + return status; +} + + + TPM_RESULT VTPM_Handle_New_DMI(const buffer_t *param_buf) { @@ -254,7 +419,7 @@ // Close DMI first TPMTRYRETURN(close_dmi( dmi_res )); - free ( dmi_res ); + free_dmi(dmi_res); status=TPM_SUCCESS; goto egress; diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/Makefile xen-unstable-trp-sdp/tools/vtpm_manager/manager/Makefile --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/Makefile 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/manager/Makefile 2011-02-23 14:42:11.000000000 -0500 @@ -1,7 +1,18 @@ XEN_ROOT = ../../.. -include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk +include ../Rules.mk + +CFLAGS += -I../crypto +CFLAGS += -I../util +CFLAGS += -I../tcs + + +MAINS := vtpmd.o +MGRLIB := libvtpmmanager.a +VTSPOBJS := vtsp.o +VTSPLIB := libvtsp.a +BIN := vtpm_managerd +OBJS := $(filter-out $(MAINS) $(VTSPOBJS), $(OBJS)) -BIN = vtpm_managerd .PHONY: all all: build @@ -28,9 +39,15 @@ mrproper: clean rm -f *~ -$(BIN): $(OBJS) +$(BIN): $(MAINS) $(MGRLIB) $(VTSPLIB) $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@ +$(VTSPLIB): $(VTSPOBJS) + $(AR) rcs $@ $^ + +$(MGRLIB): $(OBJS) + $(AR) rcs $@ $^ + # libraries LIBS += ../tcs/libTCS.a ../util/libTCGUtils.a ../crypto/libtcpaCrypto.a LIBS += -lcrypto -lpthread -lm diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/migration.c xen-unstable-trp-sdp/tools/vtpm_manager/manager/migration.c --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/migration.c 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/manager/migration.c 2011-02-23 14:42:11.000000000 -0500 @@ -40,6 +40,7 @@ #include #include #include +#include #include "vtpmpriv.h" #include "bsg.h" @@ -263,7 +264,7 @@ TPM_RESULT VTPM_Handle_Load_Migration_key( const buffer_t *param_buf, buffer_t *result_buf) { - TPM_RESULT status=TPM_FAIL; + TPM_RESULT status=TPM_SUCCESS; VTPM_MIGKEY_LIST *mig_key; vtpmloginfo(VTPM_LOG_VTPM, "Loading Migration Public Key.\n"); @@ -303,5 +304,5 @@ free(pubkey_exp_pack.data); free(pubkey_mod_pack.data); - return TPM_SUCCESS; + return status; } diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/securestorage.c xen-unstable-trp-sdp/tools/vtpm_manager/manager/securestorage.c --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/securestorage.c 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/manager/securestorage.c 2011-02-23 14:42:11.000000000 -0500 @@ -42,7 +42,7 @@ #include #include #include - +#include #include "tcg.h" #include "vtpm_manager.h" #include "vtpmpriv.h" @@ -58,7 +58,7 @@ CRYPTO_INFO *asymkey, buffer_t *sealed_data) { TPM_RESULT status = TPM_SUCCESS; - symkey_t symkey; + symkey_t *symkey; buffer_t data_cipher = NULL_BUF, symkey_cipher = NULL_BUF; @@ -69,14 +69,14 @@ for (i=0; i< buffer_len(inbuf); i++) vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", inbuf->bytes[i]); vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); - + // Generate a sym key and encrypt state with it TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_genkey (&symkey) ); - TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_encrypt (&symkey, inbuf, &data_cipher) ); + TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_encrypt (symkey, inbuf, &data_cipher) ); // Encrypt symmetric key TPMTRYRETURN( VTSP_Bind( asymkey, - &symkey.key, + Crypto_symkey_getkey(symkey), &symkey_cipher) ); // Create output blob: symkey_size + symkey_cipher + state_cipher_size + state_cipher @@ -86,8 +86,9 @@ data_cipher32.size = buffer_len(&data_cipher); data_cipher32.data = data_cipher.bytes; - + TPMTRYRETURN( buffer_init(sealed_data, 2 * sizeof(UINT32) + symkey_cipher32.size + data_cipher32.size, NULL)); + memset(sealed_data->bytes, 0, sealed_data->size); BSG_PackList(sealed_data->bytes, 2, BSG_TPM_SIZE32_DATA, &symkey_cipher32, @@ -109,11 +110,37 @@ buffer_free ( &data_cipher); buffer_free ( &symkey_cipher); - Crypto_symcrypto_freekey (&symkey); + Crypto_symcrypto_freekey (symkey); return status; } +TPM_RESULT symkey_encrypt(const buffer_t *inbuf, + CRYPTO_INFO *asymkey, + buffer_t *sealed_key) { + buffer_t symkey_cipher = NULL_BUF; + struct pack_constbuf_t symkey_cipher32; + TPM_RESULT status = TPM_SUCCESS; + + // Encrypt symmetric key + TPMTRYRETURN( VTSP_Bind( asymkey, + inbuf, + &symkey_cipher)); + + symkey_cipher32.size = buffer_len(&symkey_cipher); + symkey_cipher32.data = symkey_cipher.bytes; + + TPMTRYRETURN( buffer_init(sealed_key, sizeof(UINT32) + symkey_cipher32.size, NULL)); + BSG_PackList(sealed_key->bytes, 1, + BSG_TPM_SIZE32_DATA, &symkey_cipher32); + goto egress; +abort_egress: +egress: + buffer_free( &symkey_cipher); + return status; +} + + TPM_RESULT envelope_decrypt(const buffer_t *cipher, TCS_CONTEXT_HANDLE TCSContext, TPM_HANDLE keyHandle, @@ -121,15 +148,13 @@ buffer_t *unsealed_data) { TPM_RESULT status = TPM_SUCCESS; - symkey_t symkey; + symkey_t *symkey; buffer_t data_cipher = NULL_BUF, symkey_clear = NULL_BUF, symkey_cipher = NULL_BUF; - struct pack_buf_t symkey_cipher32, data_cipher32; + struct pack_buf_t symkey_cipher32 = NULL_PACK_BUF, data_cipher32 = NULL_PACK_BUF; int i; - memset(&symkey, 0, sizeof(symkey_t)); - 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]); @@ -159,7 +184,7 @@ Crypto_symcrypto_initkey (&symkey, &symkey_clear); // Decrypt State - TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (&symkey, &data_cipher, unsealed_data) ); + TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (symkey, &data_cipher, unsealed_data) ); vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Envelope Decrypte Output[%d]: 0x", buffer_len(unsealed_data)); for (i=0; i< buffer_len(unsealed_data); i++) @@ -175,26 +200,64 @@ buffer_free ( &data_cipher); buffer_free ( &symkey_clear); buffer_free ( &symkey_cipher); - Crypto_symcrypto_freekey (&symkey); + BSG_Destroy(BSG_TPM_SIZE32_DATA, &symkey_cipher32); + BSG_Destroy(BSG_TPM_SIZE32_DATA, &data_cipher32); + Crypto_symcrypto_freekey (symkey); + return status; } +TPM_RESULT symkey_decrypt(const buffer_t *cipher, + TCS_CONTEXT_HANDLE TCSContext, + TPM_HANDLE keyHandle, + const TPM_AUTHDATA *key_usage_auth, + buffer_t *symkey_clear) { + + TPM_RESULT status = TPM_SUCCESS; + buffer_t symkey_cipher = NULL_BUF; + struct pack_buf_t symkey_cipher32 = NULL_PACK_BUF; + + BSG_UnpackList(cipher->bytes, 1, + BSG_TPM_SIZE32_DATA, &symkey_cipher32); + + TPMTRYRETURN( buffer_init_alias_convert (&symkey_cipher, + symkey_cipher32.size, + symkey_cipher32.data) ); + + // Decrypt Symmetric Key + TPMTRYRETURN( VTSP_Unbind( TCSContext, + keyHandle, + &symkey_cipher, + key_usage_auth, + symkey_clear, + &(vtpm_globals->keyAuth) ) ); + + goto egress; + abort_egress: + vtpmlogerror(VTPM_LOG_VTPM, "Failed to decrypt symmetric key status=%d\n.", status); + + egress: + BSG_Destroy(BSG_TPM_SIZE32_DATA, &symkey_cipher32); + return status; +} + TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI_RESOURCE *myDMI, const buffer_t *inbuf, buffer_t *outbuf) { TPM_RESULT status = TPM_SUCCESS; - int fh; + int fh = -1; long bytes_written; buffer_t sealed_NVM = NULL_BUF; - - vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Saving %d bytes of NVM.\n", buffer_len(inbuf)); + const buffer_t* nvmbuf = inbuf; + + vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Saving %d bytes of NVM.\n", buffer_len(nvmbuf)); - TPMTRYRETURN( envelope_encrypt(inbuf, + TPMTRYRETURN( envelope_encrypt(nvmbuf, &vtpm_globals->storageKey, &sealed_NVM) ); - + // Write sealed blob off disk from NVMLocation // TODO: How to properly return from these. Do we care if we return failure // after writing the file? We can't get the old one back. @@ -205,7 +268,6 @@ status = TPM_IOERROR; goto abort_egress; } - close(fh); Crypto_SHA1Full (sealed_NVM.bytes, buffer_len(&sealed_NVM), (BYTE *) &myDMI->NVM_measurement); @@ -215,6 +277,7 @@ vtpmlogerror(VTPM_LOG_VTPM, "Failed to save NVM\n."); egress: + close(fh); buffer_free(&sealed_NVM); return status; } @@ -229,7 +292,8 @@ buffer_t sealed_NVM = NULL_BUF; long fh_size; - int fh, stat_ret, i; + int fh = -1; + int stat_ret, i; struct stat file_stat; TPM_DIGEST sealedNVMHash; @@ -241,6 +305,7 @@ //Read sealed blob off disk from NVMLocation fh = open(myDMI->NVMLocation, O_RDONLY); + printf("Filename: %s\n", myDMI->NVMLocation); stat_ret = fstat(fh, &file_stat); if (stat_ret == 0) fh_size = file_stat.st_size; @@ -254,7 +319,6 @@ status = TPM_IOERROR; goto abort_egress; } - close(fh); vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Load_NVMing[%d],\n", buffer_len(&sealed_NVM)); @@ -289,14 +353,128 @@ egress: buffer_free( &sealed_NVM ); + close(fh); + + return status; +} + +TPM_RESULT VTPM_Handle_Load_HashKey(VTPM_DMI_RESOURCE *myDMI, + const buffer_t *inbuf, + buffer_t *outbuf) { + + TPM_RESULT status = TPM_SUCCESS; + + buffer_t sealed_NVM = NULL_BUF; + long fh_size; + int fh = -1; + int stat_ret, i; + struct stat file_stat; + TPM_DIGEST sealedNVMHash; + + if (myDMI->NVMLocation == NULL) { + vtpmlogerror(VTPM_LOG_VTPM, "Unable to load NVM because the file name NULL.\n"); + status = TPM_AUTHFAIL; + goto abort_egress; + } + + //Read sealed blob off disk from NVMLocation + fh = open(myDMI->NVMLocation, O_RDONLY); + printf("Filename: %s\n", myDMI->NVMLocation); + stat_ret = fstat(fh, &file_stat); + if (stat_ret == 0) + fh_size = file_stat.st_size; + else { + status = TPM_IOERROR; + goto abort_egress; + } + + TPMTRYRETURN( buffer_init( &sealed_NVM, fh_size, NULL) ); + if (read(fh, sealed_NVM.bytes, buffer_len(&sealed_NVM)) != fh_size) { + status = TPM_IOERROR; + goto abort_egress; + } + + vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Loading %d byte encryption key,\n", buffer_len(&sealed_NVM)); + + Crypto_SHA1Full(sealed_NVM.bytes, buffer_len(&sealed_NVM), (BYTE *) &sealedNVMHash); + + // Verify measurement of sealed blob. + if (memcmp(&sealedNVMHash, &myDMI->NVM_measurement, sizeof(TPM_DIGEST)) ) { + vtpmlogerror(VTPM_LOG_VTPM, "VTPM LoadKey NVM measurement check failed.\n"); + vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Correct hash: "); + for (i=0; i< sizeof(TPM_DIGEST); i++) + vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", ((BYTE*)&myDMI->NVM_measurement)[i]); + vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); + + vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Measured hash: "); + for (i=0; i< sizeof(TPM_DIGEST); i++) + vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", ((BYTE*)&sealedNVMHash)[i]); + vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); + + status = TPM_AUTHFAIL; + goto abort_egress; + } + + //Decrypt the key into the output buffer + TPMTRYRETURN( symkey_decrypt(&sealed_NVM, + myDMI->TCSContext, + vtpm_globals->storageKeyHandle, + (const TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth, + outbuf) ); + goto egress; + + abort_egress: + vtpmlogerror(VTPM_LOG_VTPM, "Failed to load Key\n."); + + egress: + buffer_free( &sealed_NVM ); + close(fh); + + return status; +} + +TPM_RESULT VTPM_Handle_Save_HashKey(VTPM_DMI_RESOURCE *myDMI, + const buffer_t *inbuf, + buffer_t *outbuf) { + TPM_RESULT status = TPM_SUCCESS; + int fh = -1; + long bytes_written; + buffer_t sealed_key = NULL_BUF; + + TPMTRYRETURN( symkey_encrypt(inbuf, + &vtpm_globals->storageKey, + &sealed_key) ); + + vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Saving %d byte Encryption Key.\n", buffer_len(inbuf)); + + // Write sealed blob off disk from NVMLocation + // TODO: How to properly return from these. Do we care if we return failure + // after writing the file? We can't get the old one back. + // TODO: Backup old file and try and recover that way. + fh = open(myDMI->NVMLocation, O_WRONLY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE); + if ( (bytes_written = write(fh, sealed_key.bytes, buffer_len(&sealed_key) ) != (long) buffer_len(&sealed_key))) { + vtpmlogerror(VTPM_LOG_VTPM, "We just overwrote a DMI_NVM and failed to finish. %ld/%ld bytes.\n", bytes_written, (long)buffer_len(&sealed_key)); + status = TPM_IOERROR; + goto abort_egress; + } + Crypto_SHA1Full (sealed_key.bytes, buffer_len(&sealed_key), (BYTE *) &myDMI->NVM_measurement); + + goto egress; + + abort_egress: + vtpmlogerror(VTPM_LOG_VTPM, "Failed to save Key\n."); + + egress: + close(fh); + buffer_free(&sealed_key); return status; } TPM_RESULT VTPM_SaveManagerData(void) { TPM_RESULT status=TPM_SUCCESS; - int fh, dmis=-1; + int fh = -1, dmis=-1; BYTE *flat_boot_key=NULL, *flat_dmis=NULL, *flat_enc=NULL; buffer_t clear_flat_global=NULL_BUF, enc_flat_global=NULL_BUF; @@ -364,6 +542,7 @@ BSG_TPM_DIGEST, &dmi_res->DMI_measurement); } while (hashtable_iterator_advance(dmi_itr)); + free(dmi_itr); } fh = open(STATE_FILE, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE); @@ -389,6 +568,7 @@ free(flat_boot_key); free(flat_enc); + buffer_free(&clear_flat_global); buffer_free(&enc_flat_global); free(flat_dmis); close(fh); @@ -403,9 +583,10 @@ int fh, stat_ret, dmis=0; long fh_size = 0, step_size; BYTE *flat_table=NULL; - buffer_t unsealed_data, enc_table_abuf; - struct pack_buf_t storage_key_pack, boot_key_pack; - UINT32 *dmi_id_key, enc_size; + buffer_t unsealed_data = NULL_BUF; + buffer_t enc_table_abuf; + struct pack_buf_t storage_key_pack = NULL_PACK_BUF, boot_key_pack = NULL_PACK_BUF; + UINT32 enc_size; BYTE vtpm_manager_gen; VTPM_DMI_RESOURCE *dmi_res; @@ -438,9 +619,9 @@ BSG_TPM_SIZE32_DATA, &boot_key_pack, BSG_TYPE_UINT32, &enc_size); - TPMTRYRETURN(buffer_init(&vtpm_globals->bootKeyWrap, 0, 0) ); TPMTRYRETURN(buffer_init_alias_convert(&enc_table_abuf, enc_size, flat_table + step_size) ); - TPMTRYRETURN(buffer_append_raw(&vtpm_globals->bootKeyWrap, boot_key_pack.size, boot_key_pack.data) ); + TPMTRYRETURN(buffer_init(&vtpm_globals->bootKeyWrap, boot_key_pack.size, boot_key_pack.data) ); + //Load Boot Key TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle, @@ -471,8 +652,8 @@ BSG_TPM_SECRET, &vtpm_globals->storage_key_usage_auth, BSG_TPM_SIZE32_DATA, &storage_key_pack); - TPMTRYRETURN(buffer_init(&vtpm_globals->storageKeyWrap, 0, 0) ); - TPMTRYRETURN(buffer_append_raw(&vtpm_globals->storageKeyWrap, storage_key_pack.size, storage_key_pack.data) ); + TPMTRYRETURN(buffer_init(&vtpm_globals->storageKeyWrap, storage_key_pack.size, storage_key_pack.data) ); + // Per DMI values to be saved while ( step_size < fh_size ){ @@ -501,7 +682,10 @@ abort_egress: vtpmlogerror(VTPM_LOG_VTPM, "Failed to load service data with error = %s\n", tpm_get_error_name(status)); egress: + BSG_Destroy(BSG_TPM_SIZE32_DATA, &boot_key_pack); + BSG_Destroy(BSG_TPM_SIZE32_DATA, &storage_key_pack); + buffer_free(&unsealed_data); free(flat_table); close(fh); diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/vtpmd.c xen-unstable-trp-sdp/tools/vtpm_manager/manager/vtpmd.c --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/vtpmd.c 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/manager/vtpmd.c 2011-02-23 14:42:11.000000000 -0500 @@ -45,27 +45,13 @@ #include #include #include +#include #include "vtpm_manager.h" #include "vtpmpriv.h" #include "tcg.h" #include "log.h" #include "vtpm_ipc.h" -#define TPM_EMULATOR_PATH "/usr/bin/vtpmd" - -#define VTPM_BE_FNAME "/dev/vtpm" -#define VTPM_DUMMY_TX_BE_FNAME "/var/vtpm/fifos/dummy_out.fifo" -#define VTPM_DUMMY_RX_BE_FNAME "/var/vtpm/fifos/dummy_in.fifo" -#define VTPM_TX_TPM_FNAME "/var/vtpm/fifos/tpm_cmd_to_%d.fifo" -#define VTPM_RX_TPM_FNAME "/var/vtpm/fifos/tpm_rsp_from_all.fifo" -#define VTPM_TX_VTPM_FNAME "/var/vtpm/fifos/vtpm_rsp_to_%d.fifo" -#define VTPM_RX_VTPM_FNAME "/var/vtpm/fifos/vtpm_cmd_from_all.fifo" -#define VTPM_TX_HP_FNAME "/var/vtpm/fifos/to_console.fifo" -#define VTPM_RX_HP_FNAME "/var/vtpm/fifos/from_console.fifo" - -#define VTPM_TYPE_PVM_STRING "pvm" -#define VTPM_TYPE_HVM_STRING "hvm" - struct vtpm_thread_params_s { vtpm_ipc_handle_t *tx_ipc_h; vtpm_ipc_handle_t *rx_ipc_h; @@ -76,180 +62,46 @@ char *thread_name; }; +static pthread_t master_thread; +static pthread_t be_thread; +static pthread_t hp_thread; +#ifndef VTPM_STUBDOM +static pthread_t dmi_thread; +#endif + + +#ifndef VTPM_STUBDOM // This is needed to all extra_close_dmi to close this to prevent a // broken pipe when no DMIs are left. -static vtpm_ipc_handle_t *g_rx_tpm_ipc_h; +extern vtpm_ipc_handle_t *g_rx_tpm_ipc_h; +#endif void *vtpm_manager_thread(void *arg_void) { - TPM_RESULT *status = (TPM_RESULT *) malloc(sizeof(TPM_RESULT) ); struct vtpm_thread_params_s *arg = (struct vtpm_thread_params_s *) arg_void; - *status = VTPM_Manager_Handler(arg->tx_ipc_h, arg->rx_ipc_h, + VTPM_Manager_Handler(arg->tx_ipc_h, arg->rx_ipc_h, arg->fw_tpm, arg->fw_tx_ipc_h, arg->fw_rx_ipc_h, arg->is_priv, arg->thread_name); - return (status); + return NULL; } - -void signal_handler(int reason) { - if (pthread_equal(pthread_self(), vtpm_globals->master_pid)) { - vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager shutting down for signal %d.\n", reason); - } else { - // For old Linux Thread machines, signals are delivered to each thread. Deal with them. - vtpmloginfo(VTPM_LOG_VTPM, "Child shutting down\n"); - pthread_exit(NULL); +void signal_handler(int signal) { + if (pthread_equal(pthread_self(), master_thread)) { + vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager shutting down for signal %s(%d). Please wait..\n", strsignal(signal), signal); + HANDLER_QUIT_FLAG = IPC_QUIT_FLAG = 1; } - - VTPM_Stop_Manager(); - exit(-1); } struct sigaction ctl_c_handler; -TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res, BYTE vm_type, BYTE startup_mode) { - - TPM_RESULT status = TPM_SUCCESS; - int fh; - char dmi_id_str[11]; // UINT32s are up to 10 digits + NULL - char *tx_vtpm_name, *tx_tpm_name, *vm_type_string; - struct stat file_info; - - if (dmi_res->dmi_id == VTPM_CTL_DM) { - dmi_res->tx_tpm_ipc_h = NULL; - dmi_res->rx_tpm_ipc_h = NULL; - dmi_res->tx_vtpm_ipc_h = NULL; - dmi_res->rx_vtpm_ipc_h = NULL; - } else { - // Create a pair of fifo pipes - dmi_res->rx_tpm_ipc_h = NULL; - dmi_res->rx_vtpm_ipc_h = NULL; - - if ( ((dmi_res->tx_tpm_ipc_h = (vtpm_ipc_handle_t *) malloc (sizeof(vtpm_ipc_handle_t))) == NULL ) || - ((dmi_res->tx_vtpm_ipc_h =(vtpm_ipc_handle_t *) malloc (sizeof(vtpm_ipc_handle_t))) == NULL ) || - ((tx_tpm_name = (char *) malloc(11 + strlen(VTPM_TX_TPM_FNAME))) == NULL ) || - ((tx_vtpm_name =(char *) malloc(11 + strlen(VTPM_TX_VTPM_FNAME))) == NULL) ) { - status =TPM_RESOURCES; - goto abort_egress; - } - - sprintf(tx_tpm_name, VTPM_TX_TPM_FNAME, (uint32_t) dmi_res->dmi_id); - sprintf(tx_vtpm_name, VTPM_TX_VTPM_FNAME, (uint32_t) dmi_res->dmi_id); - - if ( (vtpm_ipc_init(dmi_res->tx_tpm_ipc_h, tx_tpm_name, O_WRONLY | O_NONBLOCK, TRUE) != 0) || - (vtpm_ipc_init(dmi_res->tx_vtpm_ipc_h, tx_vtpm_name, O_WRONLY, TRUE) != 0) ) { //FIXME: O_NONBLOCK? - status = TPM_IOERROR; - goto abort_egress; - } - - // Measure DMI - // FIXME: This will measure DMI. Until then use a fixed DMI_Measurement value - // Also, this mechanism is specific to 1 VM architecture. - /* - fh = open(TPM_EMULATOR_PATH, O_RDONLY); - stat_ret = fstat(fh, &file_stat); - if (stat_ret == 0) - dmi_size = file_stat.st_size; - else { - vtpmlogerror(VTPM_LOG_VTPM, "Could not open vtpmd!!\n"); - status = TPM_IOERROR; - goto abort_egress; - } - dmi_buffer - */ - memset(&dmi_res->DMI_measurement, 0xcc, sizeof(TPM_DIGEST)); - - if (vm_type == VTPM_TYPE_PVM) - vm_type_string = (BYTE *)&VTPM_TYPE_PVM_STRING; - else - vm_type_string = (BYTE *)&VTPM_TYPE_HVM_STRING; - - // Launch DMI - sprintf(dmi_id_str, "%d", (int) dmi_res->dmi_id); -#ifdef MANUAL_DM_LAUNCH - vtpmlogerror(VTPM_LOG_VTPM, "Manually start VTPM with dmi=%s now.\n", dmi_id_str); - dmi_res->dmi_pid = 0; -#else - pid_t pid = fork(); - - if (pid == -1) { - vtpmlogerror(VTPM_LOG_VTPM, "Could not fork to launch vtpm\n"); - status = TPM_RESOURCES; - goto abort_egress; - } else if (pid == 0) { - switch (startup_mode) { - case TPM_ST_CLEAR: - execl (TPM_EMULATOR_PATH, "vtpmd", "clear", vm_type_string, dmi_id_str, NULL); - break; - case TPM_ST_STATE: - execl (TPM_EMULATOR_PATH, "vtpmd", "save", vm_type_string, dmi_id_str, NULL); - break; - case TPM_ST_DEACTIVATED: - execl (TPM_EMULATOR_PATH, "vtpmd", "deactivated", vm_type_string, dmi_id_str, NULL); - break; - default: - status = TPM_BAD_PARAMETER; - goto abort_egress; - } - - // Returning from these at all is an error. - vtpmlogerror(VTPM_LOG_VTPM, "Could not exec to launch vtpm\n"); - } else { - dmi_res->dmi_pid = pid; - vtpmloginfo(VTPM_LOG_VTPM, "Launching DMI on PID = %d\n", pid); - } -#endif // MANUAL_DM_LAUNCH - - } // If DMI = VTPM_CTL_DM - status = TPM_SUCCESS; - -abort_egress: - return (status); -} - -TPM_RESULT VTPM_Close_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res) { - TPM_RESULT status = TPM_SUCCESS; - - if (vtpm_globals->connected_dmis == 0) { - // No more DMI's connected. Close fifo to prevent a broken pipe. - // This is hackish. Need to think of another way. - vtpm_ipc_close(g_rx_tpm_ipc_h); - } - - - if (dmi_res->dmi_id != VTPM_CTL_DM) { - vtpm_ipc_close(dmi_res->tx_tpm_ipc_h); - vtpm_ipc_close(dmi_res->tx_vtpm_ipc_h); - - free(dmi_res->tx_tpm_ipc_h->name); - free(dmi_res->tx_vtpm_ipc_h->name); - -#ifndef MANUAL_DM_LAUNCH - if (dmi_res->dmi_id != VTPM_CTL_DM) { - if (dmi_res->dmi_pid != 0) { - vtpmloginfo(VTPM_LOG_VTPM, "Killing dmi on pid %d.\n", dmi_res->dmi_pid); - if (kill(dmi_res->dmi_pid, SIGKILL) !=0) { - vtpmloginfo(VTPM_LOG_VTPM, "DMI on pid %d is already dead.\n", dmi_res->dmi_pid); - } else if (waitpid(dmi_res->dmi_pid, NULL, 0) != dmi_res->dmi_pid) { - vtpmlogerror(VTPM_LOG_VTPM, "DMI on pid %d failed to stop.\n", dmi_res->dmi_pid); - status = TPM_FAIL; - } - } else { - vtpmlogerror(VTPM_LOG_VTPM, "Could not kill dmi because it's pid was 0.\n"); - status = TPM_FAIL; - } - } -#endif - - } //endif ! dom0 - return status; -} - - int main(int argc, char **argv) { - vtpm_ipc_handle_t *tx_be_ipc_h, *rx_be_ipc_h, rx_tpm_ipc_h, rx_vtpm_ipc_h, tx_hp_ipc_h, rx_hp_ipc_h; - struct vtpm_thread_params_s be_thread_params, dmi_thread_params, hp_thread_params; - pthread_t be_thread, dmi_thread, hp_thread; + vtpm_ipc_handle_t *tx_be_ipc_h, *rx_be_ipc_h, tx_hp_ipc_h, rx_hp_ipc_h; + struct vtpm_thread_params_s be_thread_params, hp_thread_params; +#ifndef VTPM_STUBDOM + vtpm_ipc_handle_t rx_tpm_ipc_h, rx_vtpm_ipc_h; + struct vtpm_thread_params_s dmi_thread_params; +#endif #ifdef DUMMY_BACKEND vtpm_ipc_handle_t tx_dummy_ipc_h, rx_dummy_ipc_h; @@ -258,34 +110,28 @@ #endif vtpmloginfo(VTPM_LOG_VTPM, "Starting VTPM.\n"); - - // -------------------- Initialize Manager ----------------- - if (VTPM_Init_Manager() != TPM_SUCCESS) { - vtpmlogerror(VTPM_LOG_VTPM, "Closing vtpmd due to error during startup.\n"); - return -1; - } - + // -------------------- Setup Ctrl+C Handlers -------------- ctl_c_handler.sa_handler = signal_handler; sigemptyset(&ctl_c_handler.sa_mask); ctl_c_handler.sa_flags = 0; - if (sigaction(SIGINT, &ctl_c_handler, NULL) == -1) + if ((sigaction(SIGINT, &ctl_c_handler, NULL) == -1) + || (sigaction(SIGQUIT, &ctl_c_handler, NULL) == -1) + || (sigaction(SIGHUP, &ctl_c_handler, NULL) == -1) ) // For easier debugging with gdb + { vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGINT handler. Ctl+break will not stop manager gently.\n"); + } - // For easier debuggin with gdb - if (sigaction(SIGHUP, &ctl_c_handler, NULL) == -1) - vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGHUP handler. Ctl+break will not stop manager gently.\n"); - + //Block all signals for child threads sigset_t sig_mask; - sigemptyset(&sig_mask); - sigaddset(&sig_mask, SIGPIPE); - sigprocmask(SIG_BLOCK, &sig_mask, NULL); + sigfillset(&sig_mask); + pthread_sigmask(SIG_SETMASK, &sig_mask, NULL); // ------------------- Set up file ipc structures ---------- #ifdef DUMMY_BACKEND - if ( (vtpm_ipc_init(&tx_dummy_ipc_h, VTPM_DUMMY_TX_BE_FNAME, O_RDWR, TRUE) != 0) || - (vtpm_ipc_init(&rx_dummy_ipc_h, VTPM_DUMMY_RX_BE_FNAME, O_RDWR, TRUE) != 0) ) { + if ( (vtpm_ipc_init(&tx_dummy_ipc_h, VTPM_DUMMY_TX_BE_FNAME, O_RDWR, TRUE, FALSE) != 0) || + (vtpm_ipc_init(&rx_dummy_ipc_h, VTPM_DUMMY_RX_BE_FNAME, O_RDWR, TRUE, FALSE) != 0) ) { vtpmlogerror(VTPM_LOG_VTPM, "Unable to create Dummy BE FIFOs.\n"); exit(-1); @@ -294,21 +140,29 @@ tx_be_ipc_h = &tx_dummy_ipc_h; rx_be_ipc_h = &rx_dummy_ipc_h; #else - vtpm_ipc_init(&real_be_ipc_h, VTPM_BE_FNAME, O_RDWR, FALSE); + if(vtpm_ipc_init(&real_be_ipc_h, VTPM_BE_FNAME, O_RDWR, FALSE, TRUE) != 0) { + vtpmlogerror(VTPM_LOG_VTPM, "Unable to open backend device " VTPM_BE_FNAME "\n"); + exit(-1); + } tx_be_ipc_h = &real_be_ipc_h; rx_be_ipc_h = &real_be_ipc_h; #endif - if ( (vtpm_ipc_init(&rx_tpm_ipc_h, VTPM_RX_TPM_FNAME, O_RDONLY, TRUE) != 0) || - (vtpm_ipc_init(&rx_vtpm_ipc_h, VTPM_RX_VTPM_FNAME, O_RDWR, TRUE) != 0) || //FIXME: O_RDONLY? - (vtpm_ipc_init(&tx_hp_ipc_h, VTPM_TX_HP_FNAME, O_RDWR, TRUE) != 0) || - (vtpm_ipc_init(&rx_hp_ipc_h, VTPM_RX_HP_FNAME, O_RDWR, TRUE) != 0) ) { + if ( +#ifndef VTPM_STUBDOM + (vtpm_ipc_init(&rx_tpm_ipc_h, VTPM_RX_TPM_FNAME, O_RDONLY, TRUE, FALSE) != 0) || + (vtpm_ipc_init(&rx_vtpm_ipc_h, VTPM_RX_VTPM_FNAME, O_RDWR, TRUE, FALSE) != 0) || //FIXME: O_RDONLY? +#endif + (vtpm_ipc_init(&tx_hp_ipc_h, VTPM_TX_HP_FNAME, O_RDWR, TRUE, TRUE) != 0) || + (vtpm_ipc_init(&rx_hp_ipc_h, VTPM_RX_HP_FNAME, O_RDWR, TRUE, TRUE) != 0) ) { vtpmlogerror(VTPM_LOG_VTPM, "Unable to create initial FIFOs.\n"); exit(-1); } +#ifndef VTPM_STUBDOM g_rx_tpm_ipc_h = &rx_tpm_ipc_h; +#endif // -------------------- Set up thread params ------------- @@ -316,10 +170,15 @@ be_thread_params.rx_ipc_h = rx_be_ipc_h; be_thread_params.fw_tpm = TRUE; be_thread_params.fw_tx_ipc_h = NULL; +#ifndef VTPM_STUBDOM be_thread_params.fw_rx_ipc_h = &rx_tpm_ipc_h; +#else + be_thread_params.fw_rx_ipc_h = NULL; +#endif be_thread_params.is_priv = FALSE; be_thread_params.thread_name = "Backend Listener"; +#ifndef VTPM_STUBDOM dmi_thread_params.tx_ipc_h = NULL; dmi_thread_params.rx_ipc_h = &rx_vtpm_ipc_h; dmi_thread_params.fw_tpm = FALSE; @@ -327,6 +186,7 @@ dmi_thread_params.fw_rx_ipc_h = NULL; dmi_thread_params.is_priv = FALSE; dmi_thread_params.thread_name = "VTPM Listener"; +#endif hp_thread_params.tx_ipc_h = &tx_hp_ipc_h; hp_thread_params.rx_ipc_h = &rx_hp_ipc_h; @@ -335,35 +195,51 @@ hp_thread_params.fw_rx_ipc_h = NULL; hp_thread_params.is_priv = TRUE; hp_thread_params.thread_name = "Hotplug Listener"; + + // -------------------- Initialize Manager ----------------- + if (VTPM_Init_Manager() != TPM_SUCCESS) { + vtpmlogerror(VTPM_LOG_VTPM, "Closing vtpmd due to error during startup.\n"); + return -1; + } + // --------------------- Launch Threads ----------------- vtpm_lock_init(); - vtpm_globals->master_pid = pthread_self(); + master_thread = pthread_self(); + if (pthread_create(&be_thread, NULL, vtpm_manager_thread, &be_thread_params) != 0) { vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch BE Thread.\n"); exit(-1); } +#ifndef VTPM_STUBDOM if (pthread_create(&dmi_thread, NULL, vtpm_manager_thread, &dmi_thread_params) != 0) { vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch DMI Thread.\n"); exit(-1); } - +#endif if (pthread_create(&hp_thread, NULL, vtpm_manager_thread, &hp_thread_params) != 0) { vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch HP Thread.\n"); exit(-1); } + //Turn signals back on for the master thread only + sigemptyset(&sig_mask); + sigaddset(&sig_mask, SIGPIPE); + pthread_sigmask(SIG_SETMASK, &sig_mask, NULL); + //Join the other threads until exit time. pthread_join(be_thread, NULL); +#ifndef VTPM_STUBDOM pthread_join(dmi_thread, NULL); +#endif pthread_join(hp_thread, NULL); - vtpmlogerror(VTPM_LOG_VTPM, "VTPM Manager shut down unexpectedly.\n"); + vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager shutting down...\n"); VTPM_Stop_Manager(); vtpm_lock_destroy(); diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/vtpm_ipc.c xen-unstable-trp-sdp/tools/vtpm_manager/manager/vtpm_ipc.c --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/vtpm_ipc.c 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/manager/vtpm_ipc.c 2011-02-23 14:42:11.000000000 -0500 @@ -36,26 +36,49 @@ // // =================================================================== +#include #include +#include +#include +#include #include "vtpm_ipc.h" #include "vtpmpriv.h" #include "log.h" -int vtpm_ipc_init(vtpm_ipc_handle_t *ipc_h, char* name, int flags, BOOL create) { +volatile sig_atomic_t IPC_QUIT_FLAG = 0; + +const static struct timeval TIMEOUT = { + .tv_sec = 1, + .tv_usec = 0 +}; + +int vtpm_ipc_init(vtpm_ipc_handle_t *ipc_h, char* name, int flags, BOOL create, BOOL preopen) { + int rc; + ipc_h->name = name; ipc_h->flags = flags; ipc_h->fh = VTPM_IPC_CLOSED; - if (create) - return(vtpm_ipc_create(ipc_h)); - else - return 0; + if (create) { + if((rc = vtpm_ipc_create(ipc_h) != 0)) { + return rc; + } + } + + if(preopen) { + ipc_h->fh = open(ipc_h->name, ipc_h->flags); + if ( ipc_h->fh == VTPM_IPC_CLOSED ) { + vtpmlogerror(VTPM_LOG_VTPM, "VTPM ERROR: Can't open %s\n", ipc_h->name); + return -1; + } + } + return 0; + } // Create the file that needs opening. Used only for FIFOs // FYI: This may cause problems in other file IO schemes. We'll see. int vtpm_ipc_create(vtpm_ipc_handle_t *ipc_h) { - int fh; struct stat file_info; if ((!ipc_h) || (!ipc_h->name)) @@ -68,8 +91,6 @@ } } - ipc_h->fh = VTPM_IPC_CLOSED; - return 0; } @@ -78,6 +99,8 @@ int vtpm_ipc_read(vtpm_ipc_handle_t *ipc_h, vtpm_ipc_handle_t *alt_ipc_h, BYTE *bytes, UINT32 size){ vtpm_ipc_handle_t *my_ipc_h; int result; + fd_set fds; + struct timeval timeout; if (ipc_h) { my_ipc_h = ipc_h; @@ -94,9 +117,19 @@ return -1; } + FD_ZERO(&fds); + while(!FD_ISSET( my_ipc_h->fh, &fds )) { + timeout = TIMEOUT; + if (IPC_QUIT_FLAG) { + return -1; + } + FD_SET(my_ipc_h->fh, &fds); + select(my_ipc_h->fh + 1, &fds, NULL, NULL, &timeout); + } + result = read(my_ipc_h->fh, bytes, size); if (result < 0) { - my_ipc_h->fh = VTPM_IPC_CLOSED; + my_ipc_h->fh = VTPM_IPC_CLOSED; } return (result); @@ -106,6 +139,8 @@ int vtpm_ipc_write(vtpm_ipc_handle_t *ipc_h, vtpm_ipc_handle_t *alt_ipc_h, BYTE *bytes, UINT32 size) { vtpm_ipc_handle_t *my_ipc_h; int result; + fd_set fds; + struct timeval timeout; if (ipc_h) { my_ipc_h = ipc_h; @@ -122,6 +157,16 @@ return -1; } + FD_ZERO(&fds); + while(!FD_ISSET( my_ipc_h->fh, &fds )) { + timeout = TIMEOUT; + if (IPC_QUIT_FLAG) { + return -1; + } + FD_SET(my_ipc_h->fh, &fds); + select(my_ipc_h->fh + 1, NULL, &fds, NULL, &timeout); + } + result = write(my_ipc_h->fh, bytes, size); if (result < 0) { my_ipc_h->fh = VTPM_IPC_CLOSED; diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/vtpm_ipc.h xen-unstable-trp-sdp/tools/vtpm_manager/manager/vtpm_ipc.h --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/vtpm_ipc.h 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/manager/vtpm_ipc.h 2011-02-23 14:42:11.000000000 -0500 @@ -39,10 +39,14 @@ #ifndef __VTPM_IO_H__ #define __VTPM_IO_H__ +#include + #include "tcg.h" #define VTPM_IPC_CLOSED -1 +extern volatile sig_atomic_t IPC_QUIT_FLAG; + // Represents an (somewhat) abstracted io handle. typedef struct vtpm_ipc_handle_t { int fh; // IO handle. @@ -53,7 +57,7 @@ } vtpm_ipc_handle_t; -int vtpm_ipc_init(vtpm_ipc_handle_t *ioh, char* name, int flags, BOOL create); +int vtpm_ipc_init(vtpm_ipc_handle_t *ioh, char* name, int flags, BOOL create, BOOL preopen); // Create the file that needs opening. Used only for FIFOs // FYI: This may cause problems in other file IO schemes. We'll see. diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/vtpm_lock.c xen-unstable-trp-sdp/tools/vtpm_manager/manager/vtpm_lock.c --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/vtpm_lock.c 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/manager/vtpm_lock.c 2011-02-23 14:42:11.000000000 -0500 @@ -40,24 +40,24 @@ static pthread_rwlock_t vtpm_lock; -void vtpm_lock_init() { +void vtpm_lock_init(void) { pthread_rwlock_init( &vtpm_lock, NULL); } -void vtpm_lock_destroy(){ +void vtpm_lock_destroy(void){ pthread_rwlock_destroy(&vtpm_lock); } -void vtpm_lock_rdlock(){ +void vtpm_lock_rdlock(void){ pthread_rwlock_rdlock(&vtpm_lock); } -void vtpm_lock_wrlock(){ +void vtpm_lock_wrlock(void){ pthread_rwlock_wrlock(&vtpm_lock); } -void vtpm_lock_unlock(){ +void vtpm_lock_unlock(void){ pthread_rwlock_unlock(&vtpm_lock); } diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/vtpm_lock.h xen-unstable-trp-sdp/tools/vtpm_manager/manager/vtpm_lock.h --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/vtpm_lock.h 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/manager/vtpm_lock.h 2011-02-23 14:42:11.000000000 -0500 @@ -38,11 +38,11 @@ #ifndef __VTPM_LOCK_H__ #define __VTPM_LOCK_H__ -void vtpm_lock_init(); -void vtpm_lock_destroy(); +void vtpm_lock_init(void); +void vtpm_lock_destroy(void); -void vtpm_lock_rdlock(); -void vtpm_lock_wrlock(); -void vtpm_lock_unlock(); +void vtpm_lock_rdlock(void); +void vtpm_lock_wrlock(void); +void vtpm_lock_unlock(void); #endif diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/vtpm_manager.c xen-unstable-trp-sdp/tools/vtpm_manager/manager/vtpm_manager.c --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/vtpm_manager.c 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/manager/vtpm_manager.c 2011-02-23 14:42:11.000000000 -0500 @@ -40,10 +40,12 @@ #include #include #include +#include #include "vtpm_manager.h" #include "vtpmpriv.h" #include "vtsp.h" +#include "tpmddl.h" #include "bsg.h" #include "hashtable.h" #include "hashtable_itr.h" @@ -54,8 +56,8 @@ VTPM_GLOBALS *vtpm_globals=NULL; // --------------------------- Well Known Auths -------------------------- -const TPM_AUTHDATA SRK_AUTH = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; +const TPM_AUTHDATA SRK_AUTH = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; #ifdef WELL_KNOWN_OWNER_AUTH static BYTE FIXED_OWNER_AUTH[20] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -74,7 +76,6 @@ } // --------------------------- Functions ------------------------------ - TPM_RESULT VTPM_Create_Manager(){ TPM_RESULT status = TPM_SUCCESS; @@ -104,6 +105,7 @@ TPMTRYRETURN(VTSP_DisablePubekRead(vtpm_globals->manager_tcs_handle, (const TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth, &vtpm_globals->keyAuth)); + Crypto_RSACryptoInfoFree(&ek_cryptoInfo); } else { vtpmloginfo(VTPM_LOG_VTPM, "Failed to readEK meaning TPM has an owner. Creating Keys off existing SRK.\n"); } @@ -181,7 +183,7 @@ } /////////////////////////////////////////////////////////////////////////////// -TPM_RESULT VTPM_Init_Manager() { +TPM_RESULT VTPM_Init_Manager(void) { TPM_RESULT status = TPM_FAIL, serviceStatus; BYTE *randomsead; UINT32 randomsize=256; @@ -203,6 +205,11 @@ vtpm_globals->manager_tcs_handle = 0; TPMTRYRETURN(TCS_create()); + + // Blow away all stale handles left in the tpm + if(TDDL_FlushAllResources() != TPM_SUCCESS) { + vtpmlogerror(VTPM_LOG_VTPM, "VTPM_FlushResources failed, continuing anyway..\n"); + } // Create TCS Context for service TPMTRYRETURN( TCS_OpenContext(&vtpm_globals->manager_tcs_handle ) ); @@ -228,7 +235,7 @@ TPMTRYRETURN( VTPM_Create_Manager() ); TPMTRYRETURN( VTPM_SaveManagerData() ); } else if (serviceStatus != TPM_SUCCESS) { - vtpmlogerror(VTPM_LOG_VTPM, "Failed to read existing manager file"); + vtpmlogerror(VTPM_LOG_VTPM, "Failed to read existing manager file\n"); exit(1); } @@ -254,7 +261,7 @@ } /////////////////////////////////////////////////////////////////////////////// -void VTPM_Stop_Manager() { +void VTPM_Stop_Manager(void) { VTPM_DMI_RESOURCE *dmi_res; struct hashtable_itr *dmi_itr; @@ -267,7 +274,7 @@ close_dmi( dmi_res ); // Not really interested in return code } while (hashtable_iterator_advance(dmi_itr)); - free (dmi_itr); + free (dmi_itr); } if ( VTPM_SaveManagerData() != TPM_SUCCESS ) @@ -276,7 +283,21 @@ TCS_CloseContext(vtpm_globals->manager_tcs_handle); TCS_destroy(); - hashtable_destroy(vtpm_globals->dmi_map, 1); + if (hashtable_count(vtpm_globals->dmi_map) > 0) { + dmi_itr = hashtable_iterator(vtpm_globals->dmi_map); + do { + dmi_res = (VTPM_DMI_RESOURCE *) hashtable_iterator_value(dmi_itr); + free_dmi(dmi_res); + } while (hashtable_iterator_advance(dmi_itr)); + free (dmi_itr); + } + hashtable_destroy(vtpm_globals->dmi_map, 0); + + /* Cleanup resources */ + Crypto_RSACryptoInfoFree(&vtpm_globals->bootKey); + Crypto_RSACryptoInfoFree(&vtpm_globals->storageKey); + buffer_free(&vtpm_globals->bootKeyWrap); + buffer_free(&vtpm_globals->storageKeyWrap); free(vtpm_globals); Crypto_Exit(); diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/vtpm_manager.h xen-unstable-trp-sdp/tools/vtpm_manager/manager/vtpm_manager.h --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/vtpm_manager.h 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/manager/vtpm_manager.h 2011-02-23 14:42:11.000000000 -0500 @@ -61,6 +61,8 @@ #define VTPM_ORD_TPMCOMMAND (VTPM_ORD_BASE + 3) // DMI issues HW TPM Command #define VTPM_ORD_GET_MIG_KEY (VTPM_ORD_BASE + 4) // Get manager's migration key #define VTPM_ORD_LOAD_MIG_KEY (VTPM_ORD_BASE + 5) // load dest migration key +#define VTPM_ORD_SAVEHASHKEY (VTPM_ORD_BASE + 7) // DMI requests encryption key for persistent storage +#define VTPM_ORD_LOADHASHKEY (VTPM_ORD_BASE + 8) // DMI requests symkey to be regenerated // Priviledged VTPM Commands (From management console) #define VTPM_ORD_OPEN (VTPM_PRIV_BASE + 1) // Creates/reopens DMI @@ -147,4 +149,23 @@ *********************************************************************/ +#ifndef VTPM_STUBDOM +#define TPM_EMULATOR_PATH "/usr/bin/vtpmd" +#endif + +#define VTPM_BE_FNAME "/dev/vtpm" +#define VTPM_DUMMY_TX_BE_FNAME "/var/vtpm/fifos/dummy_out.fifo" +#define VTPM_DUMMY_RX_BE_FNAME "/var/vtpm/fifos/dummy_in.fifo" +#ifndef VTPM_STUBDOM +#define VTPM_TX_TPM_FNAME "/var/vtpm/fifos/tpm_cmd_to_%d.fifo" +#define VTPM_RX_TPM_FNAME "/var/vtpm/fifos/tpm_rsp_from_all.fifo" +#define VTPM_TX_VTPM_FNAME "/var/vtpm/fifos/vtpm_rsp_to_%d.fifo" +#define VTPM_RX_VTPM_FNAME "/var/vtpm/fifos/vtpm_cmd_from_all.fifo" +#endif +#define VTPM_TX_HP_FNAME "/var/vtpm/fifos/to_console.fifo" +#define VTPM_RX_HP_FNAME "/var/vtpm/fifos/from_console.fifo" + +#define VTPM_TYPE_PVM_STRING "pvm" +#define VTPM_TYPE_HVM_STRING "hvm" + #endif //_VTPM_MANAGER_H_ diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/vtpm_manager_handler.c xen-unstable-trp-sdp/tools/vtpm_manager/manager/vtpm_manager_handler.c --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/vtpm_manager_handler.c 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/manager/vtpm_manager_handler.c 2011-02-23 14:42:11.000000000 -0500 @@ -41,6 +41,8 @@ #include #include #include +#include +#include #include "vtpm_manager.h" #include "vtpmpriv.h" @@ -50,26 +52,13 @@ #include "hashtable_itr.h" #include "log.h" #include "buffer.h" +#include "vtpm_manager_handler.h" #define vtpmhandlerloginfo(module,fmt,args...) vtpmloginfo (module, "[%s]: " fmt, thread_name, ##args ); #define vtpmhandlerloginfomore(module,fmt,args...) vtpmloginfomore (module, fmt, ##args ); #define vtpmhandlerlogerror(module,fmt,args...) vtpmlogerror (module, "[%s]: " fmt, thread_name, ##args ); -// ---------------------- Prototypes ------------------- -TPM_RESULT vtpm_manager_handle_vtpm_cmd(VTPM_DMI_RESOURCE *dmi_res, - TPM_COMMAND_CODE ord, - buffer_t *command_buf, - buffer_t *result_buf, - BOOL is_priv, - char *thread_name); - -TPM_RESULT vtpm_manager_handle_tpm_cmd(vtpm_ipc_handle_t *tx_ipc_h, - vtpm_ipc_handle_t *rx_ipc_h, - VTPM_DMI_RESOURCE *dmi_res, - BYTE *cmd_header, - buffer_t *param_buf, - buffer_t *result_buf, - char *thread_name); +volatile sig_atomic_t HANDLER_QUIT_FLAG = 0; TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t *tx_ipc_h, vtpm_ipc_handle_t *rx_ipc_h, @@ -80,12 +69,13 @@ char *thread_name) { TPM_RESULT status = TPM_FAIL; // Should never return UINT32 dmi, in_param_size, cmd_size, out_param_size, out_message_size, reply_size; - BYTE *cmd_header=NULL, *in_param=NULL, *out_message=NULL, *reply; + BYTE *cmd_header=NULL, *in_param=NULL, *out_header=NULL, *reply; buffer_t *command_buf=NULL, *result_buf=NULL; TPM_TAG tag; TPM_COMMAND_CODE ord; VTPM_DMI_RESOURCE *dmi_res; int size_read, size_write, i; + int locked; BOOL add_header=TRUE; // This indicates to prepend a header on result_buf before sending cmd_header = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV); @@ -93,7 +83,11 @@ result_buf = (buffer_t *) malloc(sizeof(buffer_t)); // ------------------------ Main Loop -------------------------------- - while(1) { + while(!HANDLER_QUIT_FLAG) { + locked = 0; + + buffer_init(command_buf, 0, NULL); + buffer_init(result_buf, 0, NULL); vtpmhandlerloginfo(VTPM_LOG_VTPM, "%s waiting for messages.\n", thread_name); @@ -106,7 +100,9 @@ for (i=0; iis_owner = TRUE; // -------------- Dispatch Commands to Handlers ----------- if ((tag == VTPM_TAG_REQ) && (ord & VTPM_PRIV_MASK)) { @@ -162,6 +159,7 @@ } else { vtpm_lock_rdlock(); } + locked = 1; if ( !(dmi_res = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi)) || (!dmi_res->connected) ) { @@ -174,10 +172,22 @@ if (tag == VTPM_TAG_REQ) { status = vtpm_manager_handle_vtpm_cmd(dmi_res, ord, command_buf, result_buf, is_priv, thread_name); + result_buf->is_owner = TRUE; } else { // This is not a VTPM Command at all. if (fw_tpm) { +#ifdef VTPM_STUBDOM + /* In stubdom mode, we allow the vtpm domains to send raw tpm commands down the pipe + * They can also just embed their tpm commands inside VTPM commands if they wish to*/ + + /* Stick the header back onto the raw command (minus the dmiid) */ + buffer_prepend_raw(command_buf, VTPM_COMMAND_HEADER_SIZE_CLT, cmd_header + sizeof(UINT32)); + status = VTPM_Handle_TPM_Command(dmi_res, command_buf, result_buf); +#else + /* In normal mode, this is used for the guest to forward a raw command to the vtpm process */ status = vtpm_manager_handle_tpm_cmd(fw_tx_ipc_h, fw_rx_ipc_h, dmi_res, cmd_header, command_buf, result_buf, thread_name); +#endif + result_buf->is_owner = TRUE; // This means calling the DMI failed, not that the cmd failed in the DMI // Since the return will be interpretted by a TPM app, all errors are IO_ERRORs to the app @@ -207,36 +217,42 @@ // ------------------- Respond to Sender ------------------ // Errors while handling responses jump here to reply with error messages - // NOTE: Currently there are no recoverable errors in multi-VM mode. If one - // is added to the code, this ifdef should be removed. - // Also note this is NOT referring to errors in commands, but rather - // this is about I/O errors and such. -#ifndef VTPM_MULTI_VM - abort_with_error: -#endif +abort_with_error: if (add_header) { // Prepend VTPM header with destination DM stamped out_param_size = buffer_len(result_buf); out_message_size = VTPM_COMMAND_HEADER_SIZE_CLT + out_param_size; - reply_size = VTPM_COMMAND_HEADER_SIZE_SRV + out_param_size; - out_message = (BYTE *) malloc (reply_size); - reply = out_message; + out_header = (BYTE *) malloc (VTPM_COMMAND_HEADER_SIZE_SRV); - BSG_PackList(out_message, 4, + BSG_PackList(out_header, 4, BSG_TYPE_UINT32, (BYTE *) &dmi, BSG_TPM_TAG, (BYTE *) &tag, BSG_TYPE_UINT32, (BYTE *) &out_message_size, BSG_TPM_RESULT, (BYTE *) &status); - if (buffer_len(result_buf) > 0) - memcpy(out_message + VTPM_COMMAND_HEADER_SIZE_SRV, result_buf->bytes, out_param_size); - //Note: Send message + dmi_id + buffer_prepend_raw(result_buf, VTPM_COMMAND_HEADER_SIZE_SRV, out_header); + free(out_header); } else { - reply = result_buf->bytes; - reply_size = buffer_len(result_buf); +#ifdef VTPM_STUBDOM + //In stubdom mode, we need to always prepend the dmiid so the raw command can be returned to the right domain + out_header = (BYTE*) malloc(sizeof(UINT32)); + BSG_PackList(out_header, 1, + BSG_TYPE_UINT32, (BYTE*) &dmi); + buffer_prepend_raw(result_buf, sizeof(UINT32), out_header); + free(out_header); +#endif } + reply = result_buf->bytes; + reply_size = buffer_len(result_buf); +#ifndef VTPM_STUBDOM size_write = vtpm_ipc_write(tx_ipc_h, (dmi_res ? dmi_res->tx_vtpm_ipc_h : NULL), reply, reply_size ); +#else + if(reply_size >= 4096) { + vtpmhandlerlogerror(VTPM_LOG_VTPM, "MESSAGE TOO BIG!!!"); + } + size_write = vtpm_ipc_write(tx_ipc_h, NULL, reply, reply_size ); +#endif if (size_write > 0) { vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT: 0x"); for (i=0; i < reply_size; i++) @@ -247,7 +263,6 @@ vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s had error writing to ipc. Aborting... \n", thread_name); goto abort_command; } - free(out_message); out_message=NULL; if (size_write < (int)reply_size) { vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s unable to write full command to ipc (%d/%d)\n", thread_name, size_write, reply_size); @@ -264,14 +279,22 @@ buffer_free(command_buf); // If we have a write lock, save the manager table - if ((tag == VTPM_TAG_REQ) && (ord & VTPM_PRIV_MASK) && + if (locked && (tag == VTPM_TAG_REQ) && (ord & VTPM_PRIV_MASK) && (VTPM_SaveManagerData() != TPM_SUCCESS) ) { vtpmhandlerlogerror(VTPM_LOG_VTPM, "ERROR: Unable to save manager data.\n"); } - vtpm_lock_unlock(); + if(locked) { + vtpm_lock_unlock(); + } add_header = TRUE; // Reset to the default } // End while(1) + + free(cmd_header); + free(command_buf); + free(result_buf); + + vtpmhandlerloginfo(VTPM_LOG_VTPM, "exiting\n", thread_name); } @@ -313,6 +336,16 @@ status = VTPM_Handle_Load_Migration_key(command_buf, result_buf); break; + case VTPM_ORD_SAVEHASHKEY: + status = VTPM_Handle_Save_HashKey(dmi_res, + command_buf, + result_buf); + break; + case VTPM_ORD_LOADHASHKEY: + status = VTPM_Handle_Load_HashKey(dmi_res, + command_buf, + result_buf); + break; default: // Privileged handlers can do maintanance @@ -350,6 +383,7 @@ return(status); } +#ifndef VTPM_STUBDOM ///////////////////////////////////////////////////////////////////// TPM_RESULT vtpm_manager_handle_tpm_cmd(vtpm_ipc_handle_t *tx_ipc_h, vtpm_ipc_handle_t *rx_ipc_h, @@ -485,4 +519,5 @@ return status; } +#endif diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/vtpm_manager_handler.h xen-unstable-trp-sdp/tools/vtpm_manager/manager/vtpm_manager_handler.h --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/vtpm_manager_handler.h 1969-12-31 19:00:00.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/manager/vtpm_manager_handler.h 2011-02-23 14:42:11.000000000 -0500 @@ -0,0 +1,21 @@ +#ifndef VTPM_MANAGER_HANDLER_H +#define VTPM_MANAGER_HANDLER_H +// ---------------------- Prototypes ------------------- +TPM_RESULT vtpm_manager_handle_vtpm_cmd(VTPM_DMI_RESOURCE *dmi_res, + TPM_COMMAND_CODE ord, + buffer_t *command_buf, + buffer_t *result_buf, + BOOL is_priv, + char *thread_name); + +#ifndef VTPM_STUBDOM +TPM_RESULT vtpm_manager_handle_tpm_cmd(vtpm_ipc_handle_t *tx_ipc_h, + vtpm_ipc_handle_t *rx_ipc_h, + VTPM_DMI_RESOURCE *dmi_res, + BYTE *cmd_header, + buffer_t *param_buf, + buffer_t *result_buf, + char *thread_name); +#endif + +#endif diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/vtpmpriv.h xen-unstable-trp-sdp/tools/vtpm_manager/manager/vtpmpriv.h --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/vtpmpriv.h 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/manager/vtpmpriv.h 2011-02-23 14:42:11.000000000 -0500 @@ -40,6 +40,8 @@ #ifndef __VTPMPRIV_H__ #define __VTPMPRIV_H__ +#include + #include "vtpm_manager.h" #include "tcg.h" #include "tcs.h" @@ -54,16 +56,19 @@ #define DMI_NVM_FILE "/var/vtpm/vtpm_dm_%d.data" #define VTPM_CTL_DM 0 +extern volatile sig_atomic_t HANDLER_QUIT_FLAG; + // ------------------------ Private Structures ----------------------- typedef struct VTPM_DMI_RESOURCE_T { +#ifndef VTPM_STUBDOM // I/O info for Manager to talk to DMI's and controllers vtpm_ipc_handle_t *tx_vtpm_ipc_h; // TX VTPM Results to DMI vtpm_ipc_handle_t *rx_vtpm_ipc_h; // RX VTPM Commands from DMI vtpm_ipc_handle_t *tx_tpm_ipc_h; // TX TPM Commands to DMI vtpm_ipc_handle_t *rx_tpm_ipc_h; // RX TPM Results from DMI + + pid_t dmi_pid; -#ifndef VTPM_MULTI_VM - pid_t dmi_pid; #endif // Non-persistent Information @@ -77,6 +82,9 @@ BYTE dmi_type; TPM_DIGEST NVM_measurement; // Equal to the SHA1 of the blob TPM_DIGEST DMI_measurement; // Correct measurement of the owning DMI + + char* uuid; + } VTPM_DMI_RESOURCE; typedef struct tdVTPM_MIGKEY_LIST { @@ -89,10 +97,6 @@ typedef struct tdVTPM_GLOBALS { // Non-persistent data -#ifndef VTPM_MULTI_VM - pid_t master_pid; -#endif - 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 # @@ -123,8 +127,8 @@ extern const TPM_AUTHDATA SRK_AUTH; // SRK Well Known Auth Value // ********************** VTPM Functions ************************* -TPM_RESULT VTPM_Init_Manager(); // Start VTPM Service -void VTPM_Stop_Manager(); // Stop VTPM Service +TPM_RESULT VTPM_Init_Manager(void); // Start VTPM Service +void VTPM_Stop_Manager(void); // Stop VTPM Service TPM_RESULT VTPM_Manager_Handler(vtpm_ipc_handle_t *tx_ipc_h, vtpm_ipc_handle_t *rx_ipc_h, BOOL fw_tpm, // Should forward TPM cmds @@ -143,6 +147,11 @@ const buffer_t *inbuf, buffer_t *outbuf); +TPM_RESULT VTPM_Handle_Get_NVM_Size( VTPM_DMI_RESOURCE *myDMI, + const buffer_t *inbuf, + buffer_t *outbuf); + + TPM_RESULT VTPM_Handle_TPM_Command( VTPM_DMI_RESOURCE *dmi, buffer_t *inbuf, buffer_t *outbuf); @@ -173,6 +182,9 @@ TPM_RESULT close_dmi(VTPM_DMI_RESOURCE *dmi_res); TPM_RESULT init_dmi(UINT32 dmi_id, BYTE type, VTPM_DMI_RESOURCE **dmi_res); +/* Free's dmi_res and all of it's resources */ +void free_dmi(VTPM_DMI_RESOURCE *dmi_res); + TPM_RESULT envelope_encrypt(const buffer_t *inbuf, CRYPTO_INFO *asymkey, buffer_t *sealed_data); @@ -183,4 +195,14 @@ const TPM_AUTHDATA *key_usage_auth, buffer_t *unsealed_data); +TPM_RESULT symkey_encrypt(const buffer_t *inbuf, + CRYPTO_INFO *asymkey, + buffer_t *sealed_key); + +TPM_RESULT symkey_decrypt(const buffer_t *cipher, + TCS_CONTEXT_HANDLE TCSContext, + TPM_HANDLE keyHandle, + const TPM_AUTHDATA *key_usage_auth, + buffer_t *symkey_clear); + #endif // __VTPMPRIV_H__ diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/vtsp.c xen-unstable-trp-sdp/tools/vtpm_manager/manager/vtsp.c --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/vtsp.c 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/manager/vtsp.c 2011-02-23 14:42:11.000000000 -0500 @@ -38,6 +38,7 @@ // ================================================================== #include +#include #include "tcg.h" #include "tcs.h" #include "bsg.h" @@ -312,7 +313,7 @@ TPM_PROTOCOL_ID proto_id = TPM_PID_OWNER; BYTE *new_srk; - BYTE *paramText; // Digest to make Auth. + BYTE *paramText = NULL; // Digest to make Auth. UINT32 paramTextSize; // vars for srkpubkey parameter @@ -458,7 +459,7 @@ vtpmloginfo(VTPM_LOG_VTSP, "Creating new key of type %d.\n", usage); // vars for Calculate encUsageAuth - BYTE *paramText; + BYTE *paramText = NULL; UINT32 paramTextSize; // vars for Calculate encUsageAuth @@ -567,8 +568,7 @@ osapSharedSecret, auth, 0) ); // Unpack/return key structure - TPMTRYRETURN(buffer_init(pubKeyBuf, 0, 0) ); - TPMTRYRETURN(buffer_append_raw(pubKeyBuf, newKeyText.size, newKeyText.data) ); + TPMTRYRETURN(buffer_init(pubKeyBuf, newKeyText.size, newKeyText.data) ); goto egress; @@ -664,6 +664,7 @@ // Destroy rsaKeyParms BSG_Destroy(BSG_TPM_RSA_KEY_PARMS, &rsaKeyParms); + BSG_Destroy(BSG_TPM_KEY, &newKey); // Set encryption scheme cryptoinfo->encScheme = CRYPTO_ES_RSAESOAEP_SHA1_MGF1; @@ -733,8 +734,7 @@ hContext) ); // Unpack/return key structure - TPMTRYRETURN(buffer_init(clear_data, 0, 0)); - TPMTRYRETURN(buffer_append_raw (clear_data, clear_data_size, clear_data_text) ); + TPMTRYRETURN(buffer_init(clear_data, clear_data_size, clear_data_text) ); goto egress; @@ -793,8 +793,7 @@ vtpmlogerror(VTPM_LOG_VTSP, "Enc buffer just overflowed.\n"); } - buffer_init(outData, 0, NULL); - buffer_append_raw(outData, out_tmp_size, out_tmp); + buffer_init(outData, out_tmp_size, out_tmp); vtpmloginfo(VTPM_LOG_TXDATA, "Bind Generated[%d] = 0x", out_tmp_size); for(i = 0 ; i < out_tmp_size ; i++) { @@ -1005,8 +1004,6 @@ vtpmloginfo(VTPM_LOG_VTSP, "Calling TPM_SaveState.\n"); - TPM_RESULT status = TPM_SUCCESS; - // Call TCS return ( TCSP_SaveState ( hContext ) ); @@ -1040,3 +1037,4 @@ free(resultText); return status; } + diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/vtsp.h xen-unstable-trp-sdp/tools/vtpm_manager/manager/vtsp.h --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/manager/vtsp.h 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/manager/vtsp.h 2011-02-23 14:42:11.000000000 -0500 @@ -42,6 +42,7 @@ #include "tcg.h" #include "tcs.h" +#include "crypto.h" #define KEY_BUFFER_SIZE 2048 diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/migration/Makefile xen-unstable-trp-sdp/tools/vtpm_manager/migration/Makefile --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/migration/Makefile 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/migration/Makefile 2011-02-23 14:42:11.000000000 -0500 @@ -1,5 +1,11 @@ XEN_ROOT = ../../.. -include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk +include ../Rules.mk + +CFLAGS += -I../crypto +CFLAGS += -I../util +CFLAGS += -I../tcs +CFLAGS += -I../manager + VPATH = ../manager diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/migration/vtpm_manager_if.c xen-unstable-trp-sdp/tools/vtpm_manager/migration/vtpm_manager_if.c --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/migration/vtpm_manager_if.c 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/migration/vtpm_manager_if.c 2011-02-23 14:42:11.000000000 -0500 @@ -50,15 +50,12 @@ #include "vtpm_migrator.h" #include "vtpm_manager.h" -#define VTPM_TX_HP_FNAME "/var/vtpm/fifos/from_console.fifo" -#define VTPM_RX_HP_FNAME "/var/vtpm/fifos/to_console.fifo" - static vtpm_ipc_handle_t tx_ipc_h, rx_ipc_h; TPM_RESULT vtpm_manager_open(){ - if ( (vtpm_ipc_init(&tx_ipc_h, VTPM_TX_HP_FNAME, O_RDWR, TRUE) != 0) || //FIXME: wronly - (vtpm_ipc_init(&rx_ipc_h, VTPM_RX_HP_FNAME, O_RDWR, TRUE) != 0) ) { //FIXME: rdonly + if ( (vtpm_ipc_init(&tx_ipc_h, VTPM_TX_HP_FNAME, O_RDWR, TRUE, TRUE) != 0) || //FIXME: wronly + (vtpm_ipc_init(&rx_ipc_h, VTPM_RX_HP_FNAME, O_RDWR, TRUE, TRUE) != 0) ) { //FIXME: rdonly vtpmlogerror(VTPM_LOG_VTPM, "Unable to connect to vtpm_manager.\n"); return TPM_IOERROR; } diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/README xen-unstable-trp-sdp/tools/vtpm_manager/README --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/README 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/README 2011-02-23 14:42:11.000000000 -0500 @@ -43,9 +43,6 @@ LOGGING_MODULES -> How extensive logging happens see util/log.h for more info -VTPM_MULTI_VM -> Defined: VTPMs run in their own VMs - Not Defined (default): VTPMs are processes - # Debugging flags that may disappear without notice in the future DUMMY_BACKEND -> vtpm_manager listens on /tmp/in.fifo and @@ -59,6 +56,10 @@ lost. However this has no protection from malicious app issuing a TPM_OwnerClear to wipe the TPM +VTPM_STUBDOM -> vtpm_manager runs in vtpm_stubdom mode with + vtpm instances running in mini-os domains + (see: stubdom/vtpm/README for details) + Requirements ============ - xen-unstable diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/Rules.mk xen-unstable-trp-sdp/tools/vtpm_manager/Rules.mk --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/Rules.mk 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/Rules.mk 2011-02-23 14:42:11.000000000 -0500 @@ -40,12 +40,12 @@ #CFLAGS += -DLOGGING_MODULES=0x0 #CFLAGS += -DLOGGING_MODULES=0xff -# Use frontend/backend pairs between manager & DMs? -#CFLAGS += -DVTPM_MULTI_VM - # vtpm_manager listens on fifo's rather than backend #CFLAGS += -DDUMMY_BACKEND +# Build for use with vtpm-stubdom +CFLAGS += -DVTPM_STUBDOM + # TCS talks to fifo's rather than /dev/tpm. TPM Emulator assumed on fifos #CFLAGS += -DDUMMY_TPM @@ -55,8 +55,3 @@ # Fixed OwnerAuth #CFLAGS += -DWELL_KNOWN_OWNER_AUTH -# Include -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 -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/tcs/contextmgr.c xen-unstable-trp-sdp/tools/vtpm_manager/tcs/contextmgr.c --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/tcs/contextmgr.c 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/tcs/contextmgr.c 2011-02-23 14:42:11.000000000 -0500 @@ -195,6 +195,7 @@ BOOL FreeHandleList( CONTEXT_HANDLE* pContextHandle) { // in HANDLE_LIST* pCurrentHandle; + HANDLE_LIST* pNext; BOOL returncode = TRUE; vtpmloginfo(VTPM_LOG_TCS_DEEP, "Freeing all handles for context\n"); @@ -205,6 +206,7 @@ pCurrentHandle = pContextHandle->pHandleList; while (pCurrentHandle != NULL) { + pNext = pCurrentHandle->pNextHandle; switch (pCurrentHandle->type) { case TPM_RT_KEY: returncode = returncode && !TCSP_EvictKey(pContextHandle->handle, pCurrentHandle->handle); @@ -216,7 +218,7 @@ returncode = FALSE; } - pCurrentHandle = pCurrentHandle->pNextHandle; + pCurrentHandle = pNext; } diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/tcs/Makefile xen-unstable-trp-sdp/tools/vtpm_manager/tcs/Makefile --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/tcs/Makefile 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/tcs/Makefile 2011-02-23 14:42:11.000000000 -0500 @@ -1,5 +1,10 @@ XEN_ROOT = ../../.. -include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk +include ../Rules.mk + +CFLAGS += -I../crypto +CFLAGS += -I../util +CFLAGS += -I../manager + BIN = libTCS.a diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/tcs/tcs.c xen-unstable-trp-sdp/tools/vtpm_manager/tcs/tcs.c --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/tcs/tcs.c 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/tcs/tcs.c 2011-02-23 14:42:11.000000000 -0500 @@ -77,7 +77,7 @@ // --------------------------------------------------------------------------------- // Initialization/Uninitialization SubComponent API // --------------------------------------------------------------------------------- -TPM_RESULT TCS_create() { +TPM_RESULT TCS_create(void) { TDDL_RESULT hRes = TDDL_E_FAIL; TPM_RESULT result = TPM_FAIL; @@ -101,7 +101,7 @@ } -void TCS_destroy() +void TCS_destroy(void) { TCS_m_nCount--; @@ -113,14 +113,13 @@ TCS_CONTEXT_HANDLE *hContext; // Close all the TCS contexts. TCS should evict keys based on this - if (hashtable_count(context_ht) > 0) { + while (hashtable_count(context_ht) > 0) { context_itr = hashtable_iterator(context_ht); - do { - hContext = (TCS_CONTEXT_HANDLE *) hashtable_iterator_key(context_itr); - if (TCS_CloseContext(*hContext) != TPM_SUCCESS) - vtpmlogerror(VTPM_LOG_TCS, "Failed to close context %d properly.\n", *hContext); + + hContext = (TCS_CONTEXT_HANDLE *) hashtable_iterator_key(context_itr); + if (TCS_CloseContext(*hContext) != TPM_SUCCESS) + vtpmlogerror(VTPM_LOG_TCS, "Failed to close context %d properly.\n", *hContext); - } while (hashtable_iterator_advance(context_itr)); free(context_itr); } hashtable_destroy(context_ht, 1); @@ -534,6 +533,10 @@ BSG_TYPE_UINT32, &handle); // fill paramSize again as we now have the correct size BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2); + + if (!DeleteHandleFromList(hContext, handle)) { + vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n"); + } // call the TPM driver if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength)) @@ -545,9 +548,6 @@ BSG_TYPE_UINT32, ¶mSize, BSG_TPM_COMMAND_CODE, &returnCode); - if (!DeleteHandleFromList(hContext, handle)) - vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n"); - if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_COMMAND) { // Print debug info @@ -882,6 +882,7 @@ memcpy(*prgbKey, tempBuf, *pcKeySize); + BSG_Destroy(BSG_TPM_KEY, &wrappedKey); vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n", paramSize); } else vtpmlogerror(VTPM_LOG_TCS, "TCSP_CreateWrapKey Failed with return code %s\n", tpm_get_error_name(returnCode)); @@ -980,6 +981,10 @@ BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2); vtpmloginfo(VTPM_LOG_TCS_DEEP, "Sending paramSize = %d\n", InLength); + + if (!DeleteHandleFromList(hContext, hKey)) { + vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n"); + } // call the TPM driver if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength)) == TDDL_SUCCESS) { @@ -989,10 +994,6 @@ BSG_TYPE_UINT32, ¶mSize, BSG_TPM_COMMAND_CODE, &returnCode); - if (!DeleteHandleFromList(hContext, hKey)) { - vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n"); - } - if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_COMMAND) { vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n", paramSize); } else { @@ -1019,7 +1020,7 @@ TDDL_UINT32 OutLength = TCPA_MAX_BUFFER_LENGTH; // check input params - if (bytesRequested == NULL || *randomBytes == NULL){ + if (bytesRequested == NULL || randomBytes == NULL){ return TPM_BAD_PARAMETER; } diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/tcs/tcs.h xen-unstable-trp-sdp/tools/vtpm_manager/tcs/tcs.h --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/tcs/tcs.h 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/tcs/tcs.h 2011-02-23 14:42:11.000000000 -0500 @@ -50,8 +50,8 @@ // Exposed API // ------------------------------------------------------------------ -TPM_RESULT TCS_create(); -void TCS_destroy(); +TPM_RESULT TCS_create(void); +void TCS_destroy(void); TPM_RESULT TCS_OpenContext( /* OUT */ TCS_CONTEXT_HANDLE* hContext ); diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/tcs/tpmddl.c xen-unstable-trp-sdp/tools/vtpm_manager/tcs/tpmddl.c --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/tcs/tpmddl.c 1969-12-31 19:00:00.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/tcs/tpmddl.c 2011-02-23 14:42:11.000000000 -0500 @@ -0,0 +1,191 @@ +/* LICENSE AND DISCLAIMER + * + * Copyright © 2010 The Johns Hopkins University/Applied Physics + * Laboratory + + * This software was developed at The Johns Hopkins University/Applied + * Physics Laboratory (“JHU/APL”) that is the author thereof under the + * “work made for hire” provisions of the copyright law. Permission is + * hereby granted, free of charge, to any person obtaining a copy of this + * software and associated documentation (the “Software”), to use the + * Software without restriction, including without limitation the rights to + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit others to do so, subject to the following + * conditions: + + * 1. This LICENSE AND DISCLAIMER, including the copyright notice, shall + * be included in all copies of the Software, including copies of + * substantial portions of the Software; + + * 2. JHU/APL assumes no obligation to provide support of any kind with + * regard to the Software. This includes no obligation to provide assistance + * in using the Software nor to provide updated versions of the Software; and + + * 3. THE SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT ANY + * EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES INCLUDING, BUT + * NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, AND NONINFRINGEMENT ARE HEREBY DISCLAIMED. USERS ASSUME THE + * ENTIRE RISK AND LIABILITY OF USING THE SOFTWARE. USERS ARE ADVISED TO + * TEST THE SOFTWARE THOROUGHLY BEFORE RELYING ON IT. IN NO EVENT SHALL THE + * JOHNS HOPKINS UNIVERSITY BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING, + * WITHOUT LIMITATION, ANY LOST PROFITS, LOST SAVINGS OR OTHER INCIDENTAL OR + * CONSEQUENTIAL DAMAGES, ARISING OUT OF THE USE OR INABILITY TO USE THE + * SOFTWARE. + */ + +#include +#include "tpmddl.h" +#include "tcs.h" +#include "bsg.h" +#include "log.h" + +#define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) + +TDDL_RESULT TDDL_GetCapability( TDDL_UINT32 cap, + TDDL_UINT32 sub, + TDDL_BYTE* buffer, + TDDL_UINT32* size) +{ + TDDL_RESULT status; + + TPM_TAG tag = TPM_TAG_RQU_COMMAND; + UINT32 paramsize = 22; + UINT32 outsize; + TPM_COMMAND_CODE ord = TPM_ORD_GetCapability; + UINT32 subcapsize = 4; + + BYTE inbuf[TCPA_MAX_BUFFER_LENGTH]; + BYTE outbuf[TCPA_MAX_BUFFER_LENGTH]; + + int offset; + + BSG_PackList(inbuf, 6, + BSG_TPM_TAG, &(tag), + BSG_TYPE_UINT32, &(paramsize), + BSG_TPM_COMMAND_CODE, &(ord), + BSG_TYPE_UINT32, &(cap), + BSG_TYPE_UINT32, &(subcapsize), + BSG_TYPE_UINT32, &(sub) + ); + + //Send the command, get the response + TPMTRYRETURN(TDDL_TransmitData( inbuf, paramsize, outbuf, &outsize)); + + offset = BSG_UnpackList(outbuf, 4, + BSG_TPM_TAG, &(tag), + BSG_TYPE_UINT32, &(paramsize), + BSG_TPM_RESULT, &(status), + BSG_TYPE_UINT32, size + ); + if (status != TPM_SUCCESS || tag != TPM_TAG_RSP_COMMAND) { + return status; + } + if(*size >= TCPA_MAX_BUFFER_LENGTH - offset) { + return TPM_FAIL; + } + memcpy(buffer, outbuf + offset, *size); + +abort_egress: + return status; +} + +TDDL_RESULT TDDL_FlushSpecific(TDDL_UINT32 handle, TDDL_UINT32 res) { + /* FIXME: Add code here to check if TPM_FlushSpecific is not supported (on 1.1 only TPMS?) + * If this is the case then we need to use TPM_EvictKey for key handles + * and TPM_Terminate_Handle/TPM_Reset for auth handles */ + TDDL_RESULT status; + + TPM_TAG tag = TPM_TAG_RQU_COMMAND; + UINT32 paramsize = 18; + TPM_COMMAND_CODE ord = TPM_ORD_FlushSpecific; + + BYTE inbuf[TCPA_MAX_BUFFER_LENGTH]; + BYTE outbuf[TCPA_MAX_BUFFER_LENGTH]; + UINT32 outsize; + + int offset; + + BSG_PackList(inbuf, 5, + BSG_TPM_TAG, &(tag), + BSG_TYPE_UINT32, &(paramsize), + BSG_TPM_COMMAND_CODE, &(ord), + BSG_TPM_HANDLE, &(handle), + BSG_TPM_RESOURCE_TYPE, &(res) + ); + + //Send command + TPMTRYRETURN(TDDL_TransmitData( inbuf, paramsize, outbuf, &outsize )); + + offset = BSG_UnpackList(outbuf, 4, + BSG_TPM_TAG, &(tag), + BSG_TYPE_UINT32, &(paramsize), + BSG_TPM_RESULT, &(status) + ); + +abort_egress: + return status; + +} + +TDDL_RESULT TDDL_FlushAllResources(void) { + TDDL_RESULT status = TPM_SUCCESS; + + TDDL_BYTE buf[TCPA_MAX_BUFFER_LENGTH]; + TDDL_UINT32 bufsiz; + + UINT16 packedsz; + int size; + UINT32 handle; + BYTE* ptr; + + int i, j; + +#define RLISTSZ 6 + TPM_RESOURCE_TYPE reslist[RLISTSZ] = { TPM_RT_KEY, TPM_RT_AUTH, TPM_RT_TRANS, TPM_RT_COUNTER, TPM_RT_DAA_TPM, TPM_RT_CONTEXT }; + + //Iterate through each resource type and flush all handles + for(i = 0; i < RLISTSZ; ++i) { + TPM_RESOURCE_TYPE res = reslist[i]; + // Get list of current key handles + if((status = TDDL_GetCapability( TPM_CAP_HANDLE, res, buf, &bufsiz)) != TPM_SUCCESS) { + //This can happen if the resource type is not supported + //If this happens just silently skip the resource type + if(status == TPM_BAD_MODE) { + status = TPM_SUCCESS; + continue; + //Otherwise we just fail + } else { + TPMTRYRETURN(status); + } + } + +#if 0 + //DEBUG PRINTOUTS + printf("TPM_GetCapability(TPM_CAP_HANDLE, %lu)\n", (unsigned long) res); + for(j = 0; j < bufsiz; ++j) { + printf("%02X ", buf[j]); + } + printf("\n"); +#endif + + ptr = buf; + ptr += BSG_Unpack(BSG_TYPE_UINT16, ptr, &(packedsz)); + size = packedsz; + + //Flush each handle + if(size) { + vtpmloginfo(VTPM_LOG_VTPM, "Flushing %u handle(s) of type %lu\n", size, (unsigned long) res); + for(j = 0; j < size; ++j) { + ptr += BSG_Unpack(BSG_TPM_HANDLE, ptr, &(handle)); + TPMTRYRETURN(TDDL_FlushSpecific(handle, res)); + } + } + + } + + goto egress; +abort_egress: +egress: + return status; +} + diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/tcs/tpmddl.h xen-unstable-trp-sdp/tools/vtpm_manager/tcs/tpmddl.h --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/tcs/tpmddl.h 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/tcs/tpmddl.h 2011-02-23 14:42:11.000000000 -0500 @@ -50,13 +50,14 @@ typedef TDDL_UINT32 TDDL_RESULT; typedef unsigned char TDDL_BYTE; -TDDL_RESULT TDDL_Open(); -void TDDL_Close(); +TDDL_RESULT TDDL_Open(void); +TDDL_RESULT TDDL_Open_use_fd(int fd); +void TDDL_Close(void); TDDL_RESULT TDDL_TransmitData( TDDL_BYTE* in, TDDL_UINT32 insize, TDDL_BYTE* out, TDDL_UINT32* outsize); -TDDL_RESULT TDDL_GetStatus(); +TDDL_RESULT TDDL_GetStatus(void); TDDL_RESULT TDDL_GetCapability( TDDL_UINT32 cap, TDDL_UINT32 sub, TDDL_BYTE* buffer, @@ -66,4 +67,10 @@ TDDL_BYTE* buffer, TDDL_UINT32* size); +TDDL_RESULT TDDL_FlushSpecific(TDDL_UINT32 handle, + TDDL_UINT32 res); + +TDDL_RESULT TDDL_FlushAllResources(void); + + #endif // __TPMDDL_H__ diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/tcs/transmit.c xen-unstable-trp-sdp/tools/vtpm_manager/tcs/transmit.c --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/tcs/transmit.c 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/tcs/transmit.c 2011-02-23 14:42:11.000000000 -0500 @@ -104,12 +104,13 @@ return status; } -TPM_RESULT TDDL_Open() { +TDDL_RESULT TDDL_Open(void) { TDDL_RESULT status = TDDL_SUCCESS; + /* If tpm device is already open just silently return success */ if (g_TDDL_open) - return TPM_FAIL; + return TPM_SUCCESS; #ifdef DUMMY_TPM *g_rx_fdp = open (TPM_RX_FNAME, O_RDWR); @@ -117,7 +118,7 @@ g_tx_fd = open (TPM_TX_FNAME, O_RDWR); if (g_tx_fd < 0) { - vtpmlogerror(VTPM_LOG_TXDATA, "TPM open failed"); + vtpmlogerror(VTPM_LOG_TXDATA, "TPM open failed\n"); return TPM_IOERROR; } @@ -126,7 +127,20 @@ return status; } -void TDDL_Close() { +TDDL_RESULT TDDL_Open_use_fd(int fd) { + TDDL_RESULT status = TDDL_SUCCESS; + + if(g_TDDL_open) + return TPM_FAIL; + + g_tx_fd = fd; + + g_TDDL_open = 1; + + return status; +} + +void TDDL_Close(void) { if (! g_TDDL_open) return; diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/util/bsg.c xen-unstable-trp-sdp/tools/vtpm_manager/util/bsg.c --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/util/bsg.c 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/util/bsg.c 2011-02-23 14:42:11.000000000 -0500 @@ -41,6 +41,7 @@ #include #include #include +#include #include "tcg.h" #include "crypto.h" #include "bsg.h" @@ -317,7 +318,7 @@ // FIXME: should have a function be passed in here which is called if the test // fails. Then the caller can decide what to do: abort, notify, whatever // -BOOL BSG_static_selfcheck () +BOOL BSG_static_selfcheck (void) { int i; diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/util/bsg.h xen-unstable-trp-sdp/tools/vtpm_manager/util/bsg.h --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/util/bsg.h 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/util/bsg.h 2011-02-23 14:42:11.000000000 -0500 @@ -161,6 +161,6 @@ void BSG_PackConst(BSG_UINT32 val, int size, BSG_BYTE* dst); BSG_UINT32 BSG_UnpackConst(const BSG_BYTE* src, int size); -BOOL BSG_static_selfcheck (); +BOOL BSG_static_selfcheck (void); #endif diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/util/buffer.c xen-unstable-trp-sdp/tools/vtpm_manager/util/buffer.c --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/util/buffer.c 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/util/buffer.c 2011-02-23 14:42:11.000000000 -0500 @@ -40,6 +40,7 @@ #include "tcg.h" #include "bsg.h" +#include "log.h" #include "buffer.h" static TPM_RESULT buffer_priv_realloc (buffer_t * buf, tpm_size_t newsize); @@ -51,6 +52,7 @@ TPM_RESULT buffer_init (buffer_t * buf, tpm_size_t initsize, const BYTE* initval) { if (initsize == 0) { memset(buf, 0, sizeof(*buf)); + buf->bytes = NULL; return TPM_SUCCESS; } @@ -62,8 +64,11 @@ buf->size = initsize; buf->alloc_size = initsize; - if (initval) + if (initval) { memcpy (buf->bytes, initval, initsize); + } else { + memset(buf->bytes, 0, initsize); + } buf->is_owner = TRUE; @@ -190,6 +195,29 @@ return status; } +TPM_RESULT buffer_prepend_raw(buffer_t * buf, tpm_size_t len, const BYTE* bytes) { + TPM_RESULT status = TPM_SUCCESS; + + if (buf->alloc_size < buf->size + len) { + TPMTRYRETURN( buffer_priv_realloc (buf, buf->size + len) ); + } + + if(buf->size > 0) { + memmove(buf->bytes + len, buf->bytes, buf->size); + } + memcpy(buf->bytes, bytes, len); + + buf->size += len; + + goto egress; + + abort_egress: + + egress: + + return status; +} + tpm_size_t buffer_len (const buffer_t* buf) { return buf->size; } @@ -199,7 +227,6 @@ free (buf->bytes); buf->bytes = NULL; buf->size = buf->alloc_size = 0; - } return TPM_SUCCESS; @@ -224,3 +251,13 @@ return TPM_SUCCESS; } + +TPM_RESULT buffer_truncate(buffer_t* buf, tpm_size_t len) +{ + if(len <= buf->size) { + buf->size = len; + return TPM_SUCCESS; + } + + return TPM_FAIL; +} diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/util/buffer.h xen-unstable-trp-sdp/tools/vtpm_manager/util/buffer.h --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/util/buffer.h 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/util/buffer.h 2011-02-23 14:42:11.000000000 -0500 @@ -92,4 +92,9 @@ TPM_RESULT buffer_append_raw (buffer_t * buf, tpm_size_t len, const BYTE* bytes); +TPM_RESULT buffer_prepend_raw(buffer_t * buf, tpm_size_t len, const BYTE* bytes); + +//Reduce the size of the buffer, if len > buffer size returns an error +TPM_RESULT buffer_truncate(buffer_t* buf, tpm_size_t len); + #endif // _TOOLS_H_ diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/util/log.c xen-unstable-trp-sdp/tools/vtpm_manager/util/log.c --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/util/log.c 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/util/log.c 2011-02-23 14:42:11.000000000 -0500 @@ -38,6 +38,17 @@ #include "buffer.h" #include "tcg.h" +char *module_names[] = { "", + "CRYPTO", + "BSG", + "TXDATA", + "TCS", + "TCS", + "VTSP", + "VTPM", + "VTPM", + "VTSP" + }; // Helper code for the consts, eg. to produce messages for error codes. typedef struct error_code_entry_t { diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/util/log.h xen-unstable-trp-sdp/tools/vtpm_manager/util/log.h --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/util/log.h 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/util/log.h 2011-02-23 14:42:11.000000000 -0500 @@ -36,6 +36,8 @@ #include // for uint32_t #include // for pointer NULL +#include +#include // =========================== LOGGING ============================== @@ -50,17 +52,7 @@ #define VTPM_LOG_VTPM_DEEP 8 #define VTPM_LOG_VTSP_DEEP 9 -static char *module_names[] = { "", - "CRYPTO", - "BSG", - "TXDATA", - "TCS", - "TCS", - "VTSP", - "VTPM", - "VTPM", - "VTSP" - }; +extern char *module_names[]; // Default to standard logging #ifndef LOGGING_MODULES diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/util/Makefile xen-unstable-trp-sdp/tools/vtpm_manager/util/Makefile --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/util/Makefile 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/util/Makefile 2011-02-23 14:42:11.000000000 -0500 @@ -1,5 +1,10 @@ XEN_ROOT = ../../.. -include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk +include ../Rules.mk + +CFLAGS += -I../crypto +CFLAGS += -I../tcs +CFLAGS += -I../manager + BIN = libTCGUtils.a diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/util/tcg.h xen-unstable-trp-sdp/tools/vtpm_manager/util/tcg.h --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/util/tcg.h 2011-02-23 14:47:26.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/util/tcg.h 2011-02-23 14:42:11.000000000 -0500 @@ -197,6 +197,7 @@ UINT32 size; BYTE * data; } pack_buf_t; +#define NULL_PACK_BUF {0,0} typedef struct pack_constbuf_t { UINT32 size; @@ -295,6 +296,35 @@ #define TPM_ORD_LoadKeyContext (181UL + TPM_PROTECTED_ORDINAL) #define TPM_ORD_SaveAuthContext (182UL + TPM_PROTECTED_ORDINAL) #define TPM_ORD_LoadAuthContext (183UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_SaveContext (184UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_LoadContext (185UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_FlushSpecific (186UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_PCR_Reset (200UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_NV_DefineSpace (204UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_NV_WriteValue (205UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_NV_WriteValueAuth (206UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_NV_ReadValue (207UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_NV_ReadValueAuth (208UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_Delegate_UpdateVerification (209UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_Delegate_Manage (210UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_Delegate_CreateKeyDelegation (212UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_Delegate_CreateOwnerDelegation (213UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_Delegate_VerifyDelegation (214UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_Delegate_LoadOwnerDelegation (216UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_Delegate_ReadAuth (217UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_Delegate_ReadTable (219UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_CreateCounter (220UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_IncrementCounter (221UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_ReadCounter (222UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_ReleaseCounter (223UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_ReleaseCounterOwner (224UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_EstablishTransport (230UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_ExecuteTransport (231UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_ReleaseTransportSigned (232UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_GetTicks (241UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_TickStampBlob (242UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_MAX (256UL + TPM_PROTECTED_ORDINAL) + #define TSC_ORD_PhysicalPresence (10UL + TPM_CONNECTION_ORDINAL) @@ -419,8 +449,16 @@ /// TPM_ResourceTypes #define TPM_RT_KEY 0x00000001 #define TPM_RT_AUTH 0x00000002 +#define TPM_RT_HASH 0x00000003 #define TPM_RT_TRANS 0x00000004 #define TPM_RT_CONTEXT 0x00000005 +#define TPM_RT_COUNTER 0x00000006 +#define TPM_RT_DELEGATE 0x00000007 +#define TPM_RT_DAA_TPM 0x00000008 +#define TPM_RT_DAA_V0 0x00000009 +#define TPM_RT_DAA_V1 0x0000000A + + // TPM_PROTOCOL_ID values #define TPM_PID_OIAP 0x0001 @@ -447,6 +485,64 @@ #define TPM_SS_RSASSAPKCS1v15_SHA1 0x0002 #define TPM_SS_RSASSAPKCS1v15_DER 0x0003 +/* + * TPM_CAPABILITY_AREA Values for TPM_GetCapability ([TPM_Part2], Section 21.1) + */ +#define TPM_CAP_ORD 0x00000001 +#define TPM_CAP_ALG 0x00000002 +#define TPM_CAP_PID 0x00000003 +#define TPM_CAP_FLAG 0x00000004 +#define TPM_CAP_PROPERTY 0x00000005 +#define TPM_CAP_VERSION 0x00000006 +#define TPM_CAP_KEY_HANDLE 0x00000007 +#define TPM_CAP_CHECK_LOADED 0x00000008 +#define TPM_CAP_SYM_MODE 0x00000009 +#define TPM_CAP_KEY_STATUS 0x0000000C +#define TPM_CAP_NV_LIST 0x0000000D +#define TPM_CAP_MFR 0x00000010 +#define TPM_CAP_NV_INDEX 0x00000011 +#define TPM_CAP_TRANS_ALG 0x00000012 +#define TPM_CAP_HANDLE 0x00000014 +#define TPM_CAP_TRANS_ES 0x00000015 +#define TPM_CAP_AUTH_ENCRYPT 0x00000017 +#define TPM_CAP_SELECT_SIZE 0x00000018 +#define TPM_CAP_DA_LOGIC 0x00000019 +#define TPM_CAP_VERSION_VAL 0x0000001A + +/* subCap definitions ([TPM_Part2], Section 21.2) */ +#define TPM_CAP_PROP_PCR 0x00000101 +#define TPM_CAP_PROP_DIR 0x00000102 +#define TPM_CAP_PROP_MANUFACTURER 0x00000103 +#define TPM_CAP_PROP_KEYS 0x00000104 +#define TPM_CAP_PROP_MIN_COUNTER 0x00000107 +#define TPM_CAP_FLAG_PERMANENT 0x00000108 +#define TPM_CAP_FLAG_VOLATILE 0x00000109 +#define TPM_CAP_PROP_AUTHSESS 0x0000010A +#define TPM_CAP_PROP_TRANSESS 0x0000010B +#define TPM_CAP_PROP_COUNTERS 0x0000010C +#define TPM_CAP_PROP_MAX_AUTHSESS 0x0000010D +#define TPM_CAP_PROP_MAX_TRANSESS 0x0000010E +#define TPM_CAP_PROP_MAX_COUNTERS 0x0000010F +#define TPM_CAP_PROP_MAX_KEYS 0x00000110 +#define TPM_CAP_PROP_OWNER 0x00000111 +#define TPM_CAP_PROP_CONTEXT 0x00000112 +#define TPM_CAP_PROP_MAX_CONTEXT 0x00000113 +#define TPM_CAP_PROP_FAMILYROWS 0x00000114 +#define TPM_CAP_PROP_TIS_TIMEOUT 0x00000115 +#define TPM_CAP_PROP_STARTUP_EFFECT 0x00000116 +#define TPM_CAP_PROP_DELEGATE_ROW 0x00000117 +#define TPM_CAP_PROP_MAX_DAASESS 0x00000119 +#define TPM_CAP_PROP_DAASESS 0x0000011A +#define TPM_CAP_PROP_CONTEXT_DIST 0x0000011B +#define TPM_CAP_PROP_DAA_INTERRUPT 0x0000011C +#define TPM_CAP_PROP_SESSIONS 0x0000011D +#define TPM_CAP_PROP_MAX_SESSIONS 0x0000011E +#define TPM_CAP_PROP_CMK_RESTRICTION 0x0000011F +#define TPM_CAP_PROP_DURATION 0x00000120 +#define TPM_CAP_PROP_ACTIVE_COUNTER 0x00000122 +#define TPM_CAP_PROP_MAX_NV_AVAILABLE 0x00000123 +#define TPM_CAP_PROP_INPUT_BUFFER 0x00000124 + // TPM_KEY_USAGE values #define TPM_KEY_EK 0x0000 #define TPM_KEY_SIGNING 0x0010 diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/vtpmconnd/Makefile xen-unstable-trp-sdp/tools/vtpm_manager/vtpmconnd/Makefile --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/vtpmconnd/Makefile 1969-12-31 19:00:00.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/vtpmconnd/Makefile 2011-02-23 14:42:11.000000000 -0500 @@ -0,0 +1,19 @@ +XEN_ROOT = ../.. +TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin + +BIN=vtpmconnd +OBJS=vtpmconnd.o +CFLAGS=-O2 -Wall + +all: ${BIN} + +${BIN}: ${OBJS} + gcc -o $@ $< + +install: ${BIN} + install -m 0755 ${BIN} ${TOOLS_INSTALL_DIR} + +.PHONY: mrproper +mrproper: clean +clean: + -rm ${BIN} ${OBJS} diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/vtpmconnd/vtpmconnd.c xen-unstable-trp-sdp/tools/vtpm_manager/vtpmconnd/vtpmconnd.c --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/vtpmconnd/vtpmconnd.c 1969-12-31 19:00:00.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/vtpmconnd/vtpmconnd.c 2011-02-23 14:42:11.000000000 -0500 @@ -0,0 +1,241 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../manager/vtpm_manager.h" + +#define VTPM_BE "/dev/vtpm" +#define TPM_DEV "/dev/tpm0" +#define MAX_CMD 4096 +#define DEVNULL "/dev/null" +#define TPM_SUCCESS_RESP "\x00\x00\x00\x00" "\x01\xC1" "\x00\x00\x00\x00" "\x00\x00\x00\x00" +#define TPM_SUCCESS_RESPLEN 14 + +static int quit = 0; + +struct Opts { + const char* vtpmbe; + const char* tpmdev; + int verbosity; + int daemon; +}; + +struct Opts opts = { + .vtpmbe = VTPM_BE, + .tpmdev = TPM_DEV, + .verbosity = 0, + .daemon = 1, +}; + +void usage(char* argv0) { +fprintf(stderr, "Usage:\n \ +\t%s [options] [tpm device node]\n\ +\n\ +-h\t\tdisplay usage message\n\ +-v\t\tturn up verbosity level\n\ +-t \tuse FILE for tpm device (default " TPM_DEV ")\n\ +-b \tset vtpm backend device to FILE (default: " VTPM_BE ")\n\ +-f\t\trun in the foreground\n", +argv0 +); +} + +void sighandler(int signum) { + quit = 1; +} + +int main_loop(int vbefd, int tpmfd) { + uint8_t buf[MAX_CMD]; + ssize_t size, wrote; + int i; + + while(!quit) { + /* Wait for cmd from vtpm_manager */ + if((size = read(vbefd, buf, MAX_CMD)) < 0) { + if(errno == EFAULT) { + if(opts.verbosity > 0) { + fprintf(stderr, "read() failed with error: %s, non-fatal\n", strerror(errno)); + } + continue; + } + fprintf(stderr,"Error reading from %s, (%s)\n", opts.vtpmbe, strerror(errno)); + return 1; + } + if(opts.verbosity > 0) { + printf("\nvtpm_manager req(%ld):", (long) size); + for(i = 0; i < size; ++i) { + printf(" %02X", buf[i]); + } + printf("\n"); + } + + if(quit) { + break; + } + + /* Forward the cmd to the tpm, exclude the dmi id */ + if((wrote = write(tpmfd, buf + 4, size - 4)) != size - 4) { + fprintf(stderr,"Error writing to %s, (%s)\n", opts.tpmdev, strerror(errno)); + return 1; + } + + if(quit) { + break; + } + + /* Wait for response from tpm */ + if((size = read(tpmfd, buf + 4, MAX_CMD - 4)) < 0) { + fprintf(stderr,"Error reading from %s, (%s)\n", opts.tpmdev, strerror(errno)); + return 1; + } + if(opts.verbosity > 0) { + printf("tpm resp(%ld):", (long) size); + for(i = 0; i < size + 4; ++i) { + printf(" %02X", buf[i]); + } + printf("\n"); + } + + if(quit) { + break; + } + + /* Send response back to vtpm_manager */ + if((wrote = write(vbefd, buf, size + 4)) != size + 4) { + fprintf(stderr, "Error writing to %s, (%s)\n", opts.vtpmbe, strerror(errno)); + return 1; + } + } + + return 0; + +} + +int main(int argc, char** argv) +{ + int rc; + int vbefd, tpmfd; + int c; + int fd = -1; + struct sigaction sig; + pid_t pid; + + /* Do cmdline opts */ + opterr = 0; + + while ((c = getopt (argc, argv, "hfvb:t:")) != -1) + { + switch (c) + { + case 'h': + usage(argv[0]); + return 0; + case 'f': + opts.daemon = 0; + break; + case 'v': + ++opts.verbosity; + break; + case 'b': + opts.vtpmbe = optarg; + break; + case 't': + opts.tpmdev = optarg; + break; + case '?': + if (optopt == 'c') + fprintf (stderr, "Option -%c requires an argument.\n", optopt); + else if (isprint (optopt)) + fprintf (stderr, "Unknown option `-%c'.\n", optopt); + else + fprintf (stderr, + "Unknown option character `\\x%x'.\n", + optopt); + usage(argv[0]); + return 1; + default: + return 1; + } + } + + /* DAEMONIZE */ + if(opts.daemon) { + pid = fork(); + if(pid < 0) { + fprintf(stderr, "failed to daemonize! fork() failed : %s\n", strerror(errno)); + return 1; + } + + if (pid > 0) { + return 0; + } + } + + + /* SIGNAL HANDLING */ + sig.sa_handler = sighandler; + sigemptyset(&sig.sa_mask); + sig.sa_flags = 0; + + sigaction(SIGINT, &sig, NULL); + sigaction(SIGQUIT, &sig, NULL); + sigaction(SIGTERM, &sig, NULL); + + /* FAKE OUT THE HOTPLUG SYSTEM */ + /* Whenever hotplug writes a message let it go to dev null */ + if(remove(VTPM_RX_HP_FNAME) != 0 && errno != ENOENT) { + fprintf(stderr, "Unable to remove %s : %s\n", VTPM_RX_HP_FNAME, strerror(errno)); + return -1; + } + if(symlink(DEVNULL, VTPM_RX_HP_FNAME) != 0) { + fprintf(stderr, "Unable to create symlink %s -> %s : %s\n", VTPM_RX_HP_FNAME, DEVNULL, strerror(errno)); + } + + /* Whenever hotplug tries to read a response, always return success */ + if(remove(VTPM_TX_HP_FNAME) != 0 && errno != ENOENT) { + fprintf(stderr, "Unable to remove %s : %s\n", VTPM_TX_HP_FNAME, strerror(errno)); + return -1; + } + if((fd = open(VTPM_TX_HP_FNAME, O_CREAT | O_WRONLY)) < 0) { + fprintf(stderr, "Unable to open %s for writing : %s\n", VTPM_TX_HP_FNAME, strerror(errno)); + return -1; + } + if(write(fd, TPM_SUCCESS_RESP, TPM_SUCCESS_RESPLEN) != TPM_SUCCESS_RESPLEN) { + fprintf(stderr, "Unable to write to %s : %s\n", VTPM_TX_HP_FNAME, strerror(errno)); + return -1; + } + close(fd); + /* HOTPLUG FAKE OUT DONE */ + + /* Open the backend and tpm device */ + if((vbefd = open(opts.vtpmbe, O_RDWR)) < 0) { + fprintf(stderr, "Unable to open `%s', (%s)\n", opts.vtpmbe, strerror(errno)); + return 1; + } + if((tpmfd = open(opts.tpmdev, O_RDWR)) < 0) { + fprintf(stderr, "Unable to open `%s', (%s)\n", opts.tpmdev, strerror(errno)); + return 1; + } + if(opts.verbosity > 0) { + fprintf(stderr, "Connected to vtpm backend: %s\n", opts.vtpmbe); + fprintf(stderr, "Connected to tpm: %s\n", opts.tpmdev); + } + + rc = main_loop(vbefd, tpmfd); + + close(vbefd); + close(tpmfd); + + remove(VTPM_RX_HP_FNAME); + remove(VTPM_TX_HP_FNAME); + + + return rc; + + +} diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/vtpmmgrtalk/Makefile xen-unstable-trp-sdp/tools/vtpm_manager/vtpmmgrtalk/Makefile --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/vtpmmgrtalk/Makefile 1969-12-31 19:00:00.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/vtpmmgrtalk/Makefile 2011-02-23 14:42:11.000000000 -0500 @@ -0,0 +1,59 @@ +#LICENSE AND DISCLAIMER +# +#Copyright © 2010 The Johns Hopkins University/Applied Physics +#Laboratory +# +#This software was developed at The Johns Hopkins University/Applied +#Physics Laboratory (“JHU/APL”) that is the author thereof under the +#“work made for hire” provisions of the copyright law. Permission is +#hereby granted, free of charge, to any person obtaining a copy of this +#software and associated documentation (the “Software”), to use the +#Software without restriction, including without limitation the rights to +#copy, modify, merge, publish, distribute, sublicense, and/or sell copies +#of the Software, and to permit others to do so, subject to the following +#conditions: +# +#1. This LICENSE AND DISCLAIMER, including the copyright notice, shall +#be included in all copies of the Software, including copies of +#substantial portions of the Software; +# +#2. JHU/APL assumes no obligation to provide support of any kind with +#regard to the Software. This includes no obligation to provide assistance +#in using the Software nor to provide updated versions of the Software; and +# +#3. THE SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT ANY +#EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES INCLUDING, BUT +#NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS FOR A PARTICULAR +#PURPOSE, AND NONINFRINGEMENT ARE HEREBY DISCLAIMED. USERS ASSUME THE +#ENTIRE RISK AND LIABILITY OF USING THE SOFTWARE. USERS ARE ADVISED TO +#TEST THE SOFTWARE THOROUGHLY BEFORE RELYING ON IT. IN NO EVENT SHALL THE +#JOHNS HOPKINS UNIVERSITY BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING, +#WITHOUT LIMITATION, ANY LOST PROFITS, LOST SAVINGS OR OTHER INCIDENTAL OR +#CONSEQUENTIAL DAMAGES, ARISING OUT OF THE USE OR INABILITY TO USE THE +#SOFTWARE. + + +XEN_ROOT = ../../.. +include ../Rules.mk + +BIN=vtpmmgrtalk +OBJS=vtpmmgrtalk.o +CFLAGS=-Wall -O2 -g +CFLAGS += -I../crypto +CFLAGS += -I../util +CFLAGS += -I../tcs +CFLAGS += -I../manager + + +all: ${BIN} + +${BIN}: ${OBJS} + gcc -o $@ $< + +install: all + install -m 0755 ${BIN} ${TOOLS_INSTALL_DIR} + +.PHONY: mrproper +mrproper: clean +clean: + rm -f ${BIN} ${OBJS} diff -Naur xen-unstable-trp-sdp-pristine/tools/vtpm_manager/vtpmmgrtalk/vtpmmgrtalk.c xen-unstable-trp-sdp/tools/vtpm_manager/vtpmmgrtalk/vtpmmgrtalk.c --- xen-unstable-trp-sdp-pristine/tools/vtpm_manager/vtpmmgrtalk/vtpmmgrtalk.c 1969-12-31 19:00:00.000000000 -0500 +++ xen-unstable-trp-sdp/tools/vtpm_manager/vtpmmgrtalk/vtpmmgrtalk.c 2011-02-23 14:42:11.000000000 -0500 @@ -0,0 +1,129 @@ +/* LICENSE AND DISCLAIMER + * + * Copyright © 2010 The Johns Hopkins University/Applied Physics + * Laboratory + + * This software was developed at The Johns Hopkins University/Applied + * Physics Laboratory (“JHU/APL”) that is the author thereof under the + * “work made for hire” provisions of the copyright law. Permission is + * hereby granted, free of charge, to any person obtaining a copy of this + * software and associated documentation (the “Software”), to use the + * Software without restriction, including without limitation the rights to + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit others to do so, subject to the following + * conditions: + + * 1. This LICENSE AND DISCLAIMER, including the copyright notice, shall + * be included in all copies of the Software, including copies of + * substantial portions of the Software; + + * 2. JHU/APL assumes no obligation to provide support of any kind with + * regard to the Software. This includes no obligation to provide assistance + * in using the Software nor to provide updated versions of the Software; and + + * 3. THE SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT ANY + * EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES INCLUDING, BUT + * NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, AND NONINFRINGEMENT ARE HEREBY DISCLAIMED. USERS ASSUME THE + * ENTIRE RISK AND LIABILITY OF USING THE SOFTWARE. USERS ARE ADVISED TO + * TEST THE SOFTWARE THOROUGHLY BEFORE RELYING ON IT. IN NO EVENT SHALL THE + * JOHNS HOPKINS UNIVERSITY BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING, + * WITHOUT LIMITATION, ANY LOST PROFITS, LOST SAVINGS OR OTHER INCIDENTAL OR + * CONSEQUENTIAL DAMAGES, ARISING OUT OF THE USE OR INABILITY TO USE THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "../manager/vtpm_manager.h" + +int main(int argc, char** argv) { + int wfd, rfd; + uint8_t buf[COMMAND_BUFFER_SIZE]; + ssize_t size; + int i, c; + int rc = 0; + + const char* wfile = VTPM_RX_HP_FNAME; + const char* rfile = VTPM_TX_HP_FNAME; + + /* Open for writing in non-blocking mode and exit if + * the manager is not waiting on the other side */ + if((wfd = open(wfile, O_WRONLY | O_NONBLOCK)) < 0) { + fprintf(stderr, "Error opening %s for writing : %s\n", wfile,strerror(errno)); + return 1; + } + /* Set the pipe back to blocking mode */ + fcntl(wfd, F_SETFL, 0); + + /* Open the read pipe */ + if((rfd = open(rfile, O_RDONLY)) < 0) { + close(wfd); + fprintf(stderr, "Error opening %s for reading : %s\n", rfile,strerror(errno)); + return 1; + } + + /*Grab the ASCII hex input from stdin and convert to binary */ + for(i = 0; i < COMMAND_BUFFER_SIZE; ++i) { + c = scanf("%02hhX", buf + i); + if(c == EOF) { + break; + } else if ( c != 1) { + fprintf(stderr, "Malformed Input! Use ASCII hex!\n"); + rc = 1; + goto quit; + } + } + size = i; + + /* Send request to the manager only if a request was actually given */ + if(size > 0) { + /* Lock the pipes for reading/writing */ + if(flock(wfd, LOCK_EX)) { + fprintf(stderr, "Unable to lock %s : %s\n", wfile, strerror(errno)); + rc = 1; + goto quit; + } + if(flock(rfd, LOCK_EX)) { + fprintf(stderr, "Unable to lock %s : %s\n", wfile, strerror(errno)); + rc = 1; + goto quit; + } + + /* Write the binary data to the pipe */ + if(write(wfd, buf, size) != size) { + fprintf(stderr, "Error writing to %s : %s\n", wfile, strerror(errno)); + rc = 1; + goto quit; + } + + /* Read the response from the manager */ + size = read(rfd, buf, COMMAND_BUFFER_SIZE); + if(size < 0) { + fprintf(stderr, "Error reading %s : %s\n", rfile, strerror(errno)); + rc = 1; + goto quit; + } + /* Output the hex */ + for(i = 0; i < size; ++i) { + printf("%02X", buf[i]); + } + fprintf(stderr,"\n"); + + /* Unlock the pipes */ + flock(rfd, LOCK_UN); + flock(wfd, LOCK_UN); + } + + rc = 0; +quit: + close(rfd); + close(wfd); + return rc; +}