From mboxrd@z Thu Jan 1 00:00:00 1970 From: Matthew Fioravante Subject: PATCH [base vtpm and libxl patches 2/6] Bug fixes and breakout of vtpm_manager functionality Date: Fri, 21 Sep 2012 14:57:11 -0400 Message-ID: <505CB887.4090905@jhuapl.edu> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="===============1454697601346146772==" Return-path: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Ian Campbell , "xen-devel@lists.xensource.com" List-Id: xen-devel@lists.xenproject.org This is a cryptographically signed message in MIME format. --===============1454697601346146772== Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha1; boundary="------------ms010302090205070800070309" This is a cryptographically signed message in MIME format. --------------ms010302090205070800070309 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Fix numerous memory leaks, IO deadlocks, and other bugs that make vtpm_manager barely usable. Also breakout the vtpm_manager compilation into separate libraries to facilitate reusing parts of it in mini-os domains. Finally, add new programs for communicating with the manager correctly to avoid IO deadlock errors. Signed off by Matthew Fioravante matthew.fioravante@jhuapl.edu --- Changed since previous: * rebased off of latest xen-unstable diff --git a/tools/vtpm_manager/Makefile b/tools/vtpm_manager/Makefile --- a/tools/vtpm_manager/Makefile +++ b/tools/vtpm_manager/Makefile @@ -1,9 +1,9 @@ -XEN_ROOT =3D $(CURDIR)/../.. +XEN_ROOT =3D $(realpath ../..) =20 # Base definitions and rules -include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk +include Rules.mk =20 -SUBDIRS =3D crypto tcs util manager migration +SUBDIRS =3D crypto tcs util manager migration vtpmmgrtalk vtpmcon= nd OPENSSL_HEADER =3D /usr/include/openssl/crypto.h =20 .PHONY: all clean install diff --git a/tools/vtpm_manager/README b/tools/vtpm_manager/README --- a/tools/vtpm_manager/README +++ b/tools/vtpm_manager/README @@ -43,9 +43,6 @@ Compile Flags LOGGING_MODULES -> How extensive logging happens see util/log.h for more info =20 -VTPM_MULTI_VM -> Defined: VTPMs run in their own VMs - Not Defined (default): VTPMs are process= es - # Debugging flags that may disappear without notice in the future =20 DUMMY_BACKEND -> vtpm_manager listens on /tmp/in.fifo and= @@ -59,6 +56,10 @@ WELL_KNOWN_OWNER_AUTH -> Rather than randomly generating the password for lost. However this has no protection from malicious app issuing a TPM_OwnerClear to wipe the TPM= =20 +VTPM_STUBDOM -> vtpm_manager runs in vtpm_stubdom mode with + vtpm instances running in mini-os domains + (see: stubdom/vtpm/README for details) + Requirements =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - xen-unstable diff --git a/tools/vtpm_manager/Rules.mk b/tools/vtpm_manager/Rules.mk --- a/tools/vtpm_manager/Rules.mk +++ b/tools/vtpm_manager/Rules.mk @@ -6,7 +6,7 @@ include $(XEN_ROOT)/tools/Rules.mk # =20 # General compiler flags -CFLAGS =3D -Werror -g3 +CFLAGS =3D -Werror -g3 -I. =20 # Generic project files HDRS =3D $(wildcard *.h) @@ -31,18 +31,18 @@ $(OBJS): $(SRCS) CFLAGS +=3D -D_GNU_SOURCE =20 # Logging Level. See utils/tools.h for usage -CFLAGS +=3D -DLOGGING_MODULES=3D"(BITMASK(VTPM_LOG_TCS)|BITMASK(VTPM_LOG_VTSP)|BITMAS= K(VTPM_LOG_VTPM))" +#CFLAGS +=3D -DLOGGING_MODULES=3D"(BITMASK(VTPM_LOG_TCS)|BITMASK(VTPM_LOG_VTSP)|BITMAS= K(VTPM_LOG_VTPM))" =20 # Silent Mode #CFLAGS +=3D -DLOGGING_MODULES=3D0x0 -#CFLAGS +=3D -DLOGGING_MODULES=3D0xff - -# Use frontend/backend pairs between manager & DMs? -#CFLAGS +=3D -DVTPM_MULTI_VM +CFLAGS +=3D -DLOGGING_MODULES=3D0xff =20 # vtpm_manager listens on fifo's rather than backend #CFLAGS +=3D -DDUMMY_BACKEND =20 +# Build for use with vtpm-stubdom +#CFLAGS +=3D -DVTPM_STUBDOM + # TCS talks to fifo's rather than /dev/tpm. TPM Emulator assumed on fifo= s #CFLAGS +=3D -DDUMMY_TPM =20 @@ -52,8 +52,3 @@ CFLAGS +=3D -DLOGGING_MODULES=3D"(BITMASK(VTPM_LOG_TCS)|BITMASK(VTPM_LOG_VTSP)|BITMA # Fixed OwnerAuth #CFLAGS +=3D -DWELL_KNOWN_OWNER_AUTH =20 -# Include -CFLAGS +=3D -I$(XEN_ROOT)/tools/vtpm_manager/crypto -CFLAGS +=3D -I$(XEN_ROOT)/tools/vtpm_manager/util -CFLAGS +=3D -I$(XEN_ROOT)/tools/vtpm_manager/tcs -CFLAGS +=3D -I$(XEN_ROOT)/tools/vtpm_manager/manager diff --git a/tools/vtpm_manager/crypto/Makefile b/tools/vtpm_manager/crypto/Makefile --- a/tools/vtpm_manager/crypto/Makefile +++ b/tools/vtpm_manager/crypto/Makefile @@ -1,5 +1,9 @@ -XEN_ROOT =3D $(CURDIR)/../../.. -include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk +XEN_ROOT =3D $(realpath ../../..) +include ../Rules.mk + +CFLAGS +=3D -I../util +CFLAGS +=3D -I../tcs +CFLAGS +=3D -I../manager =20 BIN =3D libtcpaCrypto.a =20 diff --git a/tools/vtpm_manager/crypto/crypto.c b/tools/vtpm_manager/crypto/crypto.c --- a/tools/vtpm_manager/crypto/crypto.c +++ b/tools/vtpm_manager/crypto/crypto.c @@ -45,6 +45,8 @@ #include "crypto.h" #include "log.h" =20 +extern const EVP_CIPHER * SYM_CIPHER; + /** * Initialize cryptography library * @rand: random seed @@ -83,6 +85,6 @@ void Crypto_GetRandom(void* data, int size) { result =3D RAND_pseudo_bytes((BYTE*) data, size); =20 if (result <=3D 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=3D%d errstr=3D%s\n", + result, ERR_error_string (ERR_get_error(), NULL)); } diff --git a/tools/vtpm_manager/crypto/crypto.h b/tools/vtpm_manager/crypto/crypto.h --- a/tools/vtpm_manager/crypto/crypto.h +++ b/tools/vtpm_manager/crypto/crypto.h @@ -76,7 +76,7 @@ typedef struct CRYPTO_INFO { =20 void Crypto_Init(const BYTE* rand, int size); =20 -void Crypto_Exit(); +void Crypto_Exit(void); =20 void Crypto_GetRandom(void* data, int size); =20 @@ -127,6 +127,8 @@ void Crypto_RSABuildCryptoInfoPublic( /*[IN]*/ UINT32 pubExpSize, /*[IN]*/ BYTE *modulus, CRYPTO_INFO* cryptoInfo); =20 +void Crypto_RSACryptoInfoFree(CRYPTO_INFO* cryptoInfo); + // // symmetric pack and unpack operations // diff --git a/tools/vtpm_manager/crypto/rsa.c b/tools/vtpm_manager/crypto/rsa.c --- a/tools/vtpm_manager/crypto/rsa.c +++ b/tools/vtpm_manager/crypto/rsa.c @@ -149,6 +149,10 @@ void Crypto_RSABuildCryptoInfoPublic( /*[IN]*/ UINT32 pubExpSize, =20 } =20 +void Crypto_RSACryptoInfoFree(CRYPTO_INFO* cryptoInfo) { + RSA_free(cryptoInfo->keyInfo); +} + int Crypto_RSAEnc( CRYPTO_INFO *key, UINT32 inDataSize, BYTE *inData, @@ -161,6 +165,7 @@ int Crypto_RSAEnc( CRYPTO_INFO *key, =20 if (paddedData =3D=3D NULL) return -1; + memset(paddedData, 0, sizeof(BYTE) * paddedDataSize); =20 *outDataSize =3D 0; =20 diff --git a/tools/vtpm_manager/crypto/sym_crypto.c b/tools/vtpm_manager/crypto/sym_crypto.c --- a/tools/vtpm_manager/crypto/sym_crypto.c +++ b/tools/vtpm_manager/crypto/sym_crypto.c @@ -41,8 +41,16 @@ #include =20 #include "tcg.h" +#include "log.h" #include "sym_crypto.h" =20 +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 EVP_CIPHER * SYM_CIPHER =3D NULL; const BYTE ZERO_IV[EVP_MAX_IV_LENGTH] =3D {0}; =20 =20 -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 =3D TPM_SUCCESS; =20 - EVP_CIPHER_CTX_init (&key->context); + *key =3D malloc(sizeof(symkey_t)); + + EVP_CIPHER_CTX_init (&(*key)->context); =20 - key->cipher =3D SYM_CIPHER; + (*key)->cipher =3D SYM_CIPHER; =20 - TPMTRYRETURN( buffer_init_copy (&key->key, keybits)); + TPMTRYRETURN( buffer_init_copy (&(*key)->key, keybits)); =20 goto egress; =20 abort_egress: - EVP_CIPHER_CTX_cleanup (&key->context); + EVP_CIPHER_CTX_cleanup (&(*key)->context); + free(key); =20 egress: =20 @@ -82,19 +93,21 @@ TPM_RESULT Crypto_symcrypto_initkey (symkey_t * key, const buffer_t* keybits) { =20 =20 =20 -TPM_RESULT Crypto_symcrypto_genkey (symkey_t * key) { +TPM_RESULT Crypto_symcrypto_genkey (symkey_t ** key) { int res; TPM_RESULT status =3D TPM_SUCCESS; + + *key =3D malloc(sizeof(symkey_t)); =20 // hmm, EVP_CIPHER_CTX_init does not return a value - EVP_CIPHER_CTX_init (&key->context); + EVP_CIPHER_CTX_init (&(*key)->context); =20 - key->cipher =3D SYM_CIPHER; + (*key)->cipher =3D SYM_CIPHER; =20 - TPMTRYRETURN( buffer_init (&key->key, EVP_CIPHER_key_length(key->cipher), NULL)) ; + TPMTRYRETURN( buffer_init (&(*key)->key, EVP_CIPHER_key_length((*key)->cipher), NULL)) ; =20 // and generate the key material - res =3D RAND_pseudo_bytes (key->key.bytes, key->key.size); + res =3D RAND_pseudo_bytes ((*key)->key.bytes, (*key)->key.size); if (res < 0) ERRORDIE (TPM_SHORTRANDOM); =20 @@ -102,8 +115,9 @@ TPM_RESULT Crypto_symcrypto_genkey (symkey_t * key) {= goto egress; =20 abort_egress: - EVP_CIPHER_CTX_cleanup (&key->context); - buffer_free (&key->key); + EVP_CIPHER_CTX_cleanup (&(*key)->context); + buffer_free (&(*key)->key); + free(key); =20 egress: return status;=20 @@ -119,11 +133,11 @@ TPM_RESULT Crypto_symcrypto_encrypt (symkey_t* key,= =20 buffer_init_const (&iv, EVP_MAX_IV_LENGTH, ZERO_IV); =20 - 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) ); =20 // copy the IV into the front buffer_copy (o_cipher, &iv); @@ -139,6 +153,7 @@ TPM_RESULT Crypto_symcrypto_encrypt (symkey_t* key, goto egress; =20 abort_egress: + buffer_free(o_cipher); =20 egress: =20 @@ -170,7 +185,7 @@ TPM_RESULT Crypto_symcrypto_decrypt (symkey_t* key, =20 // and decrypt TPMTRYRETURN ( ossl_symcrypto_op (key, &cipher_alias, &iv, o_clear, CRYPT_DECRYPT) ); -=20 + goto egress; =20 abort_egress: @@ -188,6 +203,8 @@ TPM_RESULT Crypto_symcrypto_freekey (symkey_t * key) = { buffer_free (&key->key); =20 EVP_CIPHER_CTX_cleanup (&key->context); + + free(key); =20 return TPM_SUCCESS; } @@ -235,3 +252,8 @@ TPM_RESULT ossl_symcrypto_op (symkey_t* key, =20 return status; } + +buffer_t* Crypto_symkey_getkey(symkey_t* key) +{ + return &key->key; +} diff --git a/tools/vtpm_manager/crypto/sym_crypto.h b/tools/vtpm_manager/crypto/sym_crypto.h --- a/tools/vtpm_manager/crypto/sym_crypto.h +++ b/tools/vtpm_manager/crypto/sym_crypto.h @@ -40,21 +40,15 @@ #ifndef _SYM_CRYPTO_H #define _SYM_CRYPTO_H =20 -#include #include "buffer.h" =20 -typedef struct symkey_t { - buffer_t key; -=20 - EVP_CIPHER_CTX context; - const EVP_CIPHER * cipher; -} symkey_t; +typedef struct symkey_t symkey_t; =20 -extern const EVP_CIPHER * SYM_CIPHER; +//Allocates a symkey with random bits +TPM_RESULT Crypto_symcrypto_genkey (symkey_t ** key); =20 -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); =20 =20 // these functions will allocate their output buffers @@ -66,7 +60,10 @@ TPM_RESULT Crypto_symcrypto_decrypt (symkey_t* key, const buffer_t* cipher, buffer_t* o_clear); =20 -// only free the internal parts, not the 'key' ptr +//Frees the symkey TPM_RESULT Crypto_symcrypto_freekey (symkey_t * key); =20 +//Get the raw key byte buffer +buffer_t* Crypto_symkey_getkey(symkey_t* key); + #endif /* _SYM_CRYPTO_H */ diff --git a/tools/vtpm_manager/manager/Makefile b/tools/vtpm_manager/manager/Makefile --- a/tools/vtpm_manager/manager/Makefile +++ b/tools/vtpm_manager/manager/Makefile @@ -1,7 +1,18 @@ -XEN_ROOT =3D $(CURDIR)/../../.. -include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk +XEN_ROOT =3D $(realpath ../../..) +include ../Rules.mk + +CFLAGS +=3D -I../crypto +CFLAGS +=3D -I../util +CFLAGS +=3D -I../tcs + + +MAINS :=3D vtpmd.o +MGRLIB :=3D libvtpmmanager.a +VTSPOBJS :=3D vtsp.o +VTSPLIB :=3D libvtsp.a +BIN :=3D vtpm_managerd +OBJS :=3D $(filter-out $(MAINS) $(VTSPOBJS), $(OBJS)) =20 -BIN =3D vtpm_managerd =20 .PHONY: all all: build @@ -28,8 +39,14 @@ clean: mrproper: clean rm -f *~ =20 -$(BIN): $(OBJS) - $(CC) $(LDFLAGS) $^ $(LIBS) -o $@ +$(BIN): $(MAINS) $(MGRLIB) $(VTSPLIB) + $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@ + +$(VTSPLIB): $(VTSPOBJS) + $(AR) rcs $@ $^ + +$(MGRLIB): $(OBJS) + $(AR) rcs $@ $^ =20 # libraries LIBS +=3D ../tcs/libTCS.a ../util/libTCGUtils.a ../crypto/libtcpaCrypto.= a diff --git a/tools/vtpm_manager/manager/dmictl.c b/tools/vtpm_manager/manager/dmictl.c --- a/tools/vtpm_manager/manager/dmictl.c +++ b/tools/vtpm_manager/manager/dmictl.c @@ -40,6 +40,9 @@ #include #include #include +#include +#include +#include =20 #include "vtpmpriv.h" #include "bsg.h" @@ -51,6 +54,13 @@ =20 #define TPM_EMULATOR_PATH "/usr/bin/vtpmd" =20 +#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 b= y // design dependent code or saveNVM @@ -81,7 +91,7 @@ TPM_RESULT init_dmi(UINT32 dmi_id, BYTE dmi_type, VTPM_DMI_RESOURCE **dmi_res) { =20 // 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 =3D TPM_FAIL; goto abort_egress; } @@ -116,6 +126,161 @@ TPM_RESULT close_dmi(VTPM_DMI_RESOURCE *dmi_res) { =20 return (VTPM_Close_DMI_Extra(dmi_res) ); } + +void free_dmi(VTPM_DMI_RESOURCE *dmi_res) { + if(dmi_res !=3D 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 =3D 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 =3D=3D VTPM_CTL_DM) { + dmi_res->tx_tpm_ipc_h =3D NULL; + dmi_res->rx_tpm_ipc_h =3D NULL; + dmi_res->tx_vtpm_ipc_h =3D NULL; + dmi_res->rx_vtpm_ipc_h =3D NULL; + } else { + // Create a pair of fifo pipes + dmi_res->rx_tpm_ipc_h =3D NULL; + dmi_res->rx_vtpm_ipc_h =3D NULL; + + if ( ((dmi_res->tx_tpm_ipc_h =3D (vtpm_ipc_handle_t *) malloc (sizeof(vtpm_ipc_handle_t))) =3D=3D NULL ) || + ((dmi_res->tx_vtpm_ipc_h =3D(vtpm_ipc_handle_t *) malloc (sizeof(vtpm_ipc_handle_t))) =3D=3D NULL ) || + ((tx_tpm_name =3D (char *) malloc(11 + strlen(VTPM_TX_TPM_FNAME))) =3D=3D NULL ) || + ((tx_vtpm_name =3D(char *) malloc(11 + strlen(VTPM_TX_VTPM_FNAME))) =3D=3D NULL) ) { + status =3DTPM_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) !=3D 0) || + (vtpm_ipc_init(dmi_res->tx_vtpm_ipc_h, tx_vtpm_name, O_WRONLY, TRUE, FALSE) !=3D 0) ) { //FIXME: O_NONBLOCK? + status =3D 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 =3D open(TPM_EMULATOR_PATH, O_RDONLY); + stat_ret =3D fstat(fh, &file_stat); + if (stat_ret =3D=3D 0) + dmi_size =3D file_stat.st_size; + else { + vtpmlogerror(VTPM_LOG_VTPM, "Could not open vtpmd!!\n"); + status =3D TPM_IOERROR; + goto abort_egress; + } + dmi_buffer + */ + memset(&dmi_res->DMI_measurement, 0xcc, sizeof(TPM_DIGEST)); + + if (vm_type =3D=3D VTPM_TYPE_PVM) + vm_type_string =3D (BYTE *)&VTPM_TYPE_PVM_STRING; + else + vm_type_string =3D (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=3D%s now.\n", dmi_id_str); + dmi_res->dmi_pid =3D 0; +#else + pid_t pid =3D fork(); + + if (pid =3D=3D -1) { + vtpmlogerror(VTPM_LOG_VTPM, "Could not fork to launch vtpm\n"); + status =3D TPM_RESOURCES; + goto abort_egress; + } else if (pid =3D=3D 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 =3D 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 =3D pid; + vtpmloginfo(VTPM_LOG_VTPM, "Launching DMI on PID =3D %d\n", pid); + } +#endif // MANUAL_DM_LAUNCH + + } // If DMI =3D VTPM_CTL_DM + status =3D 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 =3D TPM_SUCCESS; + +#ifndef VTPM_STUBDOM + if (vtpm_globals->connected_dmis =3D=3D 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 !=3D 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 !=3D VTPM_CTL_DM) { + if (dmi_res->dmi_pid !=3D 0) { + vtpmloginfo(VTPM_LOG_VTPM, "Killing dmi on pid %d.\n", dmi_res->dmi_pid); + if (kill(dmi_res->dmi_pid, SIGKILL) !=3D0) { + 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) !=3D dmi_res->dmi_pid) { + vtpmlogerror(VTPM_LOG_VTPM, "DMI on pid %d failed to stop.\n", dmi_res->dmi_pid); + status =3D TPM_FAIL; + } + } else { + vtpmlogerror(VTPM_LOG_VTPM, "Could not kill dmi because it's pid was 0.\n"); + status =3D TPM_FAIL; + } + } +#endif + + } //endif ! dom0 +#endif + return status; +} + + + =20 TPM_RESULT VTPM_Handle_New_DMI(const buffer_t *param_buf) { =20 @@ -254,7 +419,7 @@ TPM_RESULT VTPM_Handle_Delete_DMI( const buffer_t *param_buf) { =20 // Close DMI first TPMTRYRETURN(close_dmi( dmi_res )); - free ( dmi_res ); + free_dmi(dmi_res); =20 status=3DTPM_SUCCESS; =20 goto egress; diff --git a/tools/vtpm_manager/manager/migration.c b/tools/vtpm_manager/manager/migration.c --- a/tools/vtpm_manager/manager/migration.c +++ b/tools/vtpm_manager/manager/migration.c @@ -40,6 +40,7 @@ #include #include #include +#include =20 #include "vtpmpriv.h" #include "bsg.h" @@ -263,7 +264,7 @@ TPM_RESULT VTPM_Handle_Get_Migration_key( const buffer_t *param_buf, TPM_RESULT VTPM_Handle_Load_Migration_key( const buffer_t *param_buf, buffer_t *result_buf) { =20 - TPM_RESULT status=3DTPM_FAIL; + TPM_RESULT status=3DTPM_SUCCESS; VTPM_MIGKEY_LIST *mig_key; =20 vtpmloginfo(VTPM_LOG_VTPM, "Loading Migration Public Key.\n"); @@ -303,5 +304,5 @@ TPM_RESULT VTPM_Handle_Load_Migration_key( const buffer_t *param_buf, free(pubkey_exp_pack.data); free(pubkey_mod_pack.data); =20 - return TPM_SUCCESS; + return status; } diff --git a/tools/vtpm_manager/manager/securestorage.c b/tools/vtpm_manager/manager/securestorage.c --- a/tools/vtpm_manager/manager/securestorage.c +++ b/tools/vtpm_manager/manager/securestorage.c @@ -42,7 +42,7 @@ #include #include #include - +#include #include "tcg.h" #include "vtpm_manager.h" #include "vtpmpriv.h" @@ -58,7 +58,7 @@ TPM_RESULT envelope_encrypt(const buffer_t *inbuf, CRYPTO_INFO *asymkey, buffer_t *sealed_data) { TPM_RESULT status =3D TPM_SUCCESS; - symkey_t symkey; + symkey_t *symkey; buffer_t data_cipher =3D NULL_BUF, symkey_cipher =3D NULL_BUF; =20 @@ -69,14 +69,14 @@ TPM_RESULT envelope_encrypt(const buffer_t *inbuf= , for (i=3D0; i< buffer_len(inbuf); i++) vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", inbuf->bytes[i]); vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); -=20 + // 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) ); =20 // Encrypt symmetric key TPMTRYRETURN( VTSP_Bind( asymkey, - &symkey.key, + Crypto_symkey_getkey(symkey), &symkey_cipher) ); =20 // Create output blob: symkey_size + symkey_cipher + state_cipher_size + state_cipher @@ -86,8 +86,9 @@ TPM_RESULT envelope_encrypt(const buffer_t *inbuf, =20 data_cipher32.size =3D buffer_len(&data_cipher); data_cipher32.data =3D data_cipher.bytes; -=20 + TPMTRYRETURN( buffer_init(sealed_data, 2 * sizeof(UINT32) + symkey_cipher32.size + data_cipher32.size, NULL)); + memset(sealed_data->bytes, 0, sealed_data->size); =20 BSG_PackList(sealed_data->bytes, 2, BSG_TPM_SIZE32_DATA, &symkey_cipher32, @@ -109,11 +110,37 @@ TPM_RESULT envelope_encrypt(const buffer_t *inb= uf, =20 buffer_free ( &data_cipher); buffer_free ( &symkey_cipher); - Crypto_symcrypto_freekey (&symkey); + Crypto_symcrypto_freekey (symkey); =20 return status; } =20 +TPM_RESULT symkey_encrypt(const buffer_t *inbuf, + CRYPTO_INFO *asymkey, + buffer_t *sealed_key) { + buffer_t symkey_cipher =3D NULL_BUF; + struct pack_constbuf_t symkey_cipher32; + TPM_RESULT status =3D TPM_SUCCESS; + + // Encrypt symmetric key + TPMTRYRETURN( VTSP_Bind( asymkey, + inbuf, + &symkey_cipher)); + + symkey_cipher32.size =3D buffer_len(&symkey_cipher); + symkey_cipher32.data =3D 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 @@ TPM_RESULT envelope_decrypt(const buffer_t =20 *cipher, buffer_t *unsealed_data) { =20 TPM_RESULT status =3D TPM_SUCCESS; - symkey_t symkey; + symkey_t *symkey; buffer_t data_cipher =3D NULL_BUF, symkey_clear =3D NULL_BUF, symkey_cipher =3D NULL_BUF; - struct pack_buf_t symkey_cipher32, data_cipher32; + struct pack_buf_t symkey_cipher32 =3D NULL_PACK_BUF, data_cipher32 =3D= NULL_PACK_BUF; int i; =20 - memset(&symkey, 0, sizeof(symkey_t)); - vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Envelope Decrypt Input[%d]: 0x", buffer_len(cipher) ); for (i=3D0; i< buffer_len(cipher); i++) vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cipher->bytes[i]); @@ -159,7 +184,7 @@ TPM_RESULT envelope_decrypt(const buffer_t *ciphe= r, Crypto_symcrypto_initkey (&symkey, &symkey_clear); =20 // 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) ); =20 vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Envelope Decrypte Output[%d]: 0x", buffer_len(unsealed_data)); for (i=3D0; i< buffer_len(unsealed_data); i++) @@ -175,26 +200,64 @@ TPM_RESULT envelope_decrypt(const buffer_t =20 *cipher, 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); + =20 return status; } =20 +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 =3D TPM_SUCCESS; + buffer_t symkey_cipher =3D NULL_BUF; + struct pack_buf_t symkey_cipher32 =3D 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=3D%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) { =20 TPM_RESULT status =3D TPM_SUCCESS; - int fh; + int fh =3D -1; long bytes_written; buffer_t sealed_NVM =3D NULL_BUF; -=20 - vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Saving %d bytes of NVM.\n", buffer_len(inbuf)); + const buffer_t* nvmbuf =3D inbuf; =20 - TPMTRYRETURN( envelope_encrypt(inbuf, + vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Saving %d bytes of NVM.\n", buffer_len(nvmbuf)); + + TPMTRYRETURN( envelope_encrypt(nvmbuf, &vtpm_globals->storageKey, &sealed_NVM) ); - =20 + // 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 @@ TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI_RESOURCE *myDMI, status =3D TPM_IOERROR; goto abort_egress; } - close(fh); =20 Crypto_SHA1Full (sealed_NVM.bytes, buffer_len(&sealed_NVM), (BYTE *) &myDMI->NVM_measurement); =20 =20 @@ -215,6 +277,7 @@ TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI_RESOURCE *myDMI, vtpmlogerror(VTPM_LOG_VTPM, "Failed to save NVM\n."); =20 egress: + close(fh); buffer_free(&sealed_NVM); return status; } @@ -229,7 +292,8 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI_RESOURCE *myDMI, =20 buffer_t sealed_NVM =3D NULL_BUF; long fh_size; - int fh, stat_ret, i; + int fh =3D -1; + int stat_ret, i; struct stat file_stat; TPM_DIGEST sealedNVMHash; =20 @@ -241,6 +305,7 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI_RESOURCE *myDMI, =20 //Read sealed blob off disk from NVMLocation fh =3D open(myDMI->NVMLocation, O_RDONLY); + printf("Filename: %s\n", myDMI->NVMLocation); stat_ret =3D fstat(fh, &file_stat); if (stat_ret =3D=3D 0) fh_size =3D file_stat.st_size; @@ -254,7 +319,6 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI_RESOURCE *myDMI, status =3D TPM_IOERROR; goto abort_egress; } - close(fh); =20 vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Load_NVMing[%d],\n", buffer_len(&sealed_NVM)); =20 @@ -289,14 +353,128 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI_RESOURCE *myDMI, =20 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 =3D TPM_SUCCESS; + + buffer_t sealed_NVM =3D NULL_BUF; + long fh_size; + int fh =3D -1; + int stat_ret, i; + struct stat file_stat; + TPM_DIGEST sealedNVMHash; + + if (myDMI->NVMLocation =3D=3D NULL) { + vtpmlogerror(VTPM_LOG_VTPM, "Unable to load NVM because the file name NULL.\n"); + status =3D TPM_AUTHFAIL; + goto abort_egress; + } + + //Read sealed blob off disk from NVMLocation + fh =3D open(myDMI->NVMLocation, O_RDONLY); + printf("Filename: %s\n", myDMI->NVMLocation); + stat_ret =3D fstat(fh, &file_stat); + if (stat_ret =3D=3D 0) + fh_size =3D file_stat.st_size; + else { + status =3D TPM_IOERROR; + goto abort_egress; + } + + TPMTRYRETURN( buffer_init( &sealed_NVM, fh_size, NULL) ); + if (read(fh, sealed_NVM.bytes, buffer_len(&sealed_NVM)) !=3D fh_size) = { + status =3D 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=3D0; 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=3D0; i< sizeof(TPM_DIGEST); i++) + vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", ((BYTE*)&sealedNVMHash)[i]); + vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); + + status =3D 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 =3D TPM_SUCCESS; + int fh =3D -1; + long bytes_written; + buffer_t sealed_key =3D 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 =3D open(myDMI->NVMLocation, O_WRONLY | O_CREAT | O_TRUNC, S_IREAD = | S_IWRITE); + if ( (bytes_written =3D write(fh, sealed_key.bytes, buffer_len(&sealed_key) ) !=3D (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 =3D TPM_IOERROR; + goto abort_egress; + } =20 + 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; } =20 =20 TPM_RESULT VTPM_SaveManagerData(void) { TPM_RESULT status=3DTPM_SUCCESS; - int fh, dmis=3D-1; + int fh =3D -1, dmis=3D-1; =20 BYTE *flat_boot_key=3DNULL, *flat_dmis=3DNULL, *flat_enc=3DNULL; buffer_t clear_flat_global=3DNULL_BUF, enc_flat_global=3DNULL_BUF; @@ -364,6 +542,7 @@ TPM_RESULT VTPM_SaveManagerData(void) { BSG_TPM_DIGEST, &dmi_res->DMI_measurement); =20 } while (hashtable_iterator_advance(dmi_itr)); + free(dmi_itr); } =20 fh =3D open(STATE_FILE, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE); @@ -389,6 +568,7 @@ TPM_RESULT VTPM_SaveManagerData(void) { =20 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 @@ TPM_RESULT VTPM_LoadManagerData(void) { int fh, stat_ret, dmis=3D0; long fh_size =3D 0, step_size; BYTE *flat_table=3DNULL; - 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 =3D NULL_BUF; + buffer_t enc_table_abuf; + struct pack_buf_t storage_key_pack =3D NULL_PACK_BUF, boot_key_pack =3D= NULL_PACK_BUF; + UINT32 enc_size; BYTE vtpm_manager_gen; =20 VTPM_DMI_RESOURCE *dmi_res; @@ -438,9 +619,9 @@ TPM_RESULT VTPM_LoadManagerData(void) { BSG_TPM_SIZE32_DATA, &boot_key_pack, BSG_TYPE_UINT32, &enc_size); =20 - 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) ); + =20 //Load Boot Key TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle, @@ -471,8 +652,8 @@ TPM_RESULT VTPM_LoadManagerData(void) { BSG_TPM_SECRET, &vtpm_globals->storage_key_usage_aut= h, BSG_TPM_SIZE32_DATA, &storage_key_pack); =20 - 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) ); + =20 // Per DMI values to be saved while ( step_size < fh_size ){ @@ -501,7 +682,10 @@ TPM_RESULT VTPM_LoadManagerData(void) { abort_egress: vtpmlogerror(VTPM_LOG_VTPM, "Failed to load service data with error =3D= %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); =20 + buffer_free(&unsealed_data); free(flat_table); close(fh); =20 diff --git a/tools/vtpm_manager/manager/vtpm_ipc.c b/tools/vtpm_manager/manager/vtpm_ipc.c --- a/tools/vtpm_manager/manager/vtpm_ipc.c +++ b/tools/vtpm_manager/manager/vtpm_ipc.c @@ -36,26 +36,49 @@ // // =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 +#include #include +#include +#include +#include #include "vtpm_ipc.h" #include "vtpmpriv.h" #include "log.h" =20 -int vtpm_ipc_init(vtpm_ipc_handle_t *ipc_h, char* name, int flags, BOOL create) { +volatile sig_atomic_t IPC_QUIT_FLAG =3D 0; + +const static struct timeval TIMEOUT =3D { + .tv_sec =3D 1, + .tv_usec =3D 0 +}; + +int vtpm_ipc_init(vtpm_ipc_handle_t *ipc_h, char* name, int flags, BOOL create, BOOL preopen) { + int rc; + ipc_h->name =3D name; ipc_h->flags =3D flags; ipc_h->fh =3D VTPM_IPC_CLOSED; =20 - if (create) - return(vtpm_ipc_create(ipc_h)); - else - return 0; + if (create) { + if((rc =3D vtpm_ipc_create(ipc_h) !=3D 0)) { + return rc; + } + } + + if(preopen) { + ipc_h->fh =3D open(ipc_h->name, ipc_h->flags); + if ( ipc_h->fh =3D=3D VTPM_IPC_CLOSED ) { + vtpmlogerror(VTPM_LOG_VTPM, "VTPM ERROR: Can't open %s\n", ipc_h->name); + return -1; + } + } + return 0; + } =20 // 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; =20 if ((!ipc_h) || (!ipc_h->name)) @@ -68,8 +91,6 @@ int vtpm_ipc_create(vtpm_ipc_handle_t *ipc_h) { } } =20 - ipc_h->fh =3D VTPM_IPC_CLOSED; - return 0; } =20 @@ -78,6 +99,8 @@ int vtpm_ipc_create(vtpm_ipc_handle_t *ipc_h) { 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; =20 if (ipc_h) { my_ipc_h =3D ipc_h; @@ -94,9 +117,19 @@ int vtpm_ipc_read(vtpm_ipc_handle_t *ipc_h, vtpm_ipc_handle_t *alt_ipc_h, BYTE * return -1; } =20 + FD_ZERO(&fds); + while(!FD_ISSET( my_ipc_h->fh, &fds )) { + timeout =3D 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 =3D read(my_ipc_h->fh, bytes, size); if (result < 0) { - my_ipc_h->fh =3D VTPM_IPC_CLOSED; + my_ipc_h->fh =3D VTPM_IPC_CLOSED; } =20 return (result); @@ -106,6 +139,8 @@ int vtpm_ipc_read(vtpm_ipc_handle_t *ipc_h, vtpm_ipc_handle_t *alt_ipc_h, BYTE * 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; =20 if (ipc_h) { my_ipc_h =3D ipc_h; @@ -122,6 +157,16 @@ int vtpm_ipc_write(vtpm_ipc_handle_t *ipc_h, vtpm_ipc_handle_t *alt_ipc_h, BYTE return -1; } =20 + FD_ZERO(&fds); + while(!FD_ISSET( my_ipc_h->fh, &fds )) { + timeout =3D 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 =3D write(my_ipc_h->fh, bytes, size); if (result < 0) { my_ipc_h->fh =3D VTPM_IPC_CLOSED; diff --git a/tools/vtpm_manager/manager/vtpm_ipc.h b/tools/vtpm_manager/manager/vtpm_ipc.h --- a/tools/vtpm_manager/manager/vtpm_ipc.h +++ b/tools/vtpm_manager/manager/vtpm_ipc.h @@ -39,10 +39,14 @@ #ifndef __VTPM_IO_H__ #define __VTPM_IO_H__ =20 +#include + #include "tcg.h" =20 #define VTPM_IPC_CLOSED -1 =20 +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 @@ typedef struct vtpm_ipc_handle_t { } vtpm_ipc_handle_t; =20 =20 -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); =20 // Create the file that needs opening. Used only for FIFOs // FYI: This may cause problems in other file IO schemes. We'll see. diff --git a/tools/vtpm_manager/manager/vtpm_lock.c b/tools/vtpm_manager/manager/vtpm_lock.c --- a/tools/vtpm_manager/manager/vtpm_lock.c +++ b/tools/vtpm_manager/manager/vtpm_lock.c @@ -40,24 +40,24 @@ =20 static pthread_rwlock_t vtpm_lock; =20 -void vtpm_lock_init() { +void vtpm_lock_init(void) { =20 pthread_rwlock_init( &vtpm_lock, NULL); } =20 -void vtpm_lock_destroy(){ +void vtpm_lock_destroy(void){ pthread_rwlock_destroy(&vtpm_lock); } =20 -void vtpm_lock_rdlock(){ +void vtpm_lock_rdlock(void){ pthread_rwlock_rdlock(&vtpm_lock); } =20 -void vtpm_lock_wrlock(){ +void vtpm_lock_wrlock(void){ pthread_rwlock_wrlock(&vtpm_lock); } =20 -void vtpm_lock_unlock(){ +void vtpm_lock_unlock(void){ pthread_rwlock_unlock(&vtpm_lock); } =20 diff --git a/tools/vtpm_manager/manager/vtpm_lock.h b/tools/vtpm_manager/manager/vtpm_lock.h --- a/tools/vtpm_manager/manager/vtpm_lock.h +++ b/tools/vtpm_manager/manager/vtpm_lock.h @@ -38,11 +38,11 @@ #ifndef __VTPM_LOCK_H__ #define __VTPM_LOCK_H__ =20 -void vtpm_lock_init(); -void vtpm_lock_destroy(); +void vtpm_lock_init(void); +void vtpm_lock_destroy(void); =20 -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); =20 #endif diff --git a/tools/vtpm_manager/manager/vtpm_manager.c b/tools/vtpm_manager/manager/vtpm_manager.c --- a/tools/vtpm_manager/manager/vtpm_manager.c +++ b/tools/vtpm_manager/manager/vtpm_manager.c @@ -40,10 +40,12 @@ #include #include #include +#include =20 #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=3DNULL; =20 // --------------------------- Well Known Auths ------------------------= -- -const TPM_AUTHDATA SRK_AUTH =3D {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 =3D {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; =20 #ifdef WELL_KNOWN_OWNER_AUTH static BYTE FIXED_OWNER_AUTH[20] =3D {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -74,7 +76,6 @@ static int equals32(void *k1, void *k2) { } =20 // --------------------------- Functions ------------------------------ - TPM_RESULT VTPM_Create_Manager(){ =20 TPM_RESULT status =3D TPM_SUCCESS; @@ -104,6 +105,7 @@ TPM_RESULT VTPM_Create_Manager(){ TPMTRYRETURN(VTSP_DisablePubekRead(vtpm_globals->manager_tcs_handle,= (const TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth,=20 &vtpm_globals->keyAuth)); =20 + 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_Create_Manager(){ } =20 ////////////////////////////////////////////////////////////////////////= /////// -TPM_RESULT VTPM_Init_Manager() { +TPM_RESULT VTPM_Init_Manager(void) { TPM_RESULT status =3D TPM_FAIL, serviceStatus; =20 BYTE *randomsead; UINT32 randomsize=3D256; @@ -203,6 +205,11 @@ TPM_RESULT VTPM_Init_Manager() { vtpm_globals->manager_tcs_handle =3D 0; =20 TPMTRYRETURN(TCS_create()); + + // Blow away all stale handles left in the tpm + if(TDDL_FlushAllResources() !=3D TPM_SUCCESS) { + vtpmlogerror(VTPM_LOG_VTPM, "VTPM_FlushResources failed, continuing anyway..\n"); + } =20 // Create TCS Context for service TPMTRYRETURN( TCS_OpenContext(&vtpm_globals->manager_tcs_handle ) ); @@ -228,7 +235,7 @@ TPM_RESULT VTPM_Init_Manager() { TPMTRYRETURN( VTPM_Create_Manager() ); =20 TPMTRYRETURN( VTPM_SaveManagerData() ); } else if (serviceStatus !=3D 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); } =20 @@ -254,7 +261,7 @@ TPM_RESULT VTPM_Init_Manager() { } =20 ////////////////////////////////////////////////////////////////////////= /////// -void VTPM_Stop_Manager() { +void VTPM_Stop_Manager(void) { VTPM_DMI_RESOURCE *dmi_res; struct hashtable_itr *dmi_itr; =20 @@ -267,7 +274,7 @@ void VTPM_Stop_Manager() { close_dmi( dmi_res ); // Not really interested in return code =20 } while (hashtable_iterator_advance(dmi_itr)); - free (dmi_itr); + free (dmi_itr); } =20 if ( VTPM_SaveManagerData() !=3D TPM_SUCCESS ) @@ -276,7 +283,21 @@ void VTPM_Stop_Manager() { TCS_CloseContext(vtpm_globals->manager_tcs_handle); TCS_destroy(); =20 - hashtable_destroy(vtpm_globals->dmi_map, 1); + if (hashtable_count(vtpm_globals->dmi_map) > 0) { + dmi_itr =3D hashtable_iterator(vtpm_globals->dmi_map); + do { + dmi_res =3D (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); =20 Crypto_Exit(); diff --git a/tools/vtpm_manager/manager/vtpm_manager.h b/tools/vtpm_manager/manager/vtpm_manager.h --- a/tools/vtpm_manager/manager/vtpm_manager.h +++ b/tools/vtpm_manager/manager/vtpm_manager.h @@ -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 =20 // Priviledged VTPM Commands (From management console) #define VTPM_ORD_OPEN (VTPM_PRIV_BASE + 1) // Creates/reopens DM= I @@ -147,4 +149,23 @@ VTPM_TPMCommand =20 *********************************************************************/ =20 +#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 --git a/tools/vtpm_manager/manager/vtpm_manager_handler.c b/tools/vtpm_manager/manager/vtpm_manager_handler.c --- a/tools/vtpm_manager/manager/vtpm_manager_handler.c +++ b/tools/vtpm_manager/manager/vtpm_manager_handler.c @@ -41,6 +41,8 @@ #include #include #include +#include +#include =20 #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" =20 #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 ); =20 -// ---------------------- 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 =3D 0; =20 TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t *tx_ipc_h, vtpm_ipc_handle_t *rx_ipc_h, @@ -80,12 +69,13 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t *tx_ipc_h, char *thread_name) { TPM_RESULT status =3D TPM_FAIL; // Should never return UINT32 dmi, in_param_size, cmd_size, out_param_size, out_message_size, reply_size; - BYTE *cmd_header=3DNULL, *in_param=3DNULL, *out_message=3DN= ULL, *reply; + BYTE *cmd_header=3DNULL, *in_param=3DNULL, *out_header=3DNU= LL, *reply; buffer_t *command_buf=3DNULL, *result_buf=3DNULL; TPM_TAG tag; TPM_COMMAND_CODE ord; VTPM_DMI_RESOURCE *dmi_res; int size_read, size_write, i; + int locked; BOOL add_header=3DTRUE; // This indicates to prepend a header on result_buf before sending =20 cmd_header =3D (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV); @@ -93,7 +83,11 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t *tx_ipc_h, result_buf =3D (buffer_t *) malloc(sizeof(buffer_t)); =20 // ------------------------ Main Loop --------------------------------= - while(1) { + while(!HANDLER_QUIT_FLAG) { + locked =3D 0; + + buffer_init(command_buf, 0, NULL); + buffer_init(result_buf, 0, NULL); =20 vtpmhandlerloginfo(VTPM_LOG_VTPM, "%s waiting for messages.\n", thread_name); =20 @@ -106,7 +100,9 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t *tx_ipc_h, for (i=3D0; iis_owner =3D TRUE; =20 // -------------- Dispatch Commands to Handlers ----------- if ((tag =3D=3D VTPM_TAG_REQ) && (ord & VTPM_PRIV_MASK)) { @@ -162,6 +159,7 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t *tx_ipc_h, } else { vtpm_lock_rdlock(); } + locked =3D 1; =20 if ( !(dmi_res =3D (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi)) || (!dmi_res->connected) ) { @@ -174,10 +172,22 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t *tx_ipc_h, if (tag =3D=3D VTPM_TAG_REQ) { =20 status =3D vtpm_manager_handle_vtpm_cmd(dmi_res, ord, command_buf,= result_buf, is_priv, thread_name); + result_buf->is_owner =3D TRUE; =20 } 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 =3D 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 =3D 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 =3D TRUE; =20 // 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 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t *tx_ipc_h, // ------------------- Respond to Sender ------------------ =20 // 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: =20 if (add_header) { // Prepend VTPM header with destination DM stamped out_param_size =3D buffer_len(result_buf); out_message_size =3D VTPM_COMMAND_HEADER_SIZE_CLT + out_param_size= ; - reply_size =3D VTPM_COMMAND_HEADER_SIZE_SRV + out_param_size; - out_message =3D (BYTE *) malloc (reply_size); - reply =3D out_message; + out_header =3D (BYTE *) malloc (VTPM_COMMAND_HEADER_SIZE_SRV); =20 - 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); =20 - 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 =3D result_buf->bytes; - reply_size =3D 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 =3D (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 }=20 + reply =3D result_buf->bytes; + reply_size =3D buffer_len(result_buf); +#ifndef VTPM_STUBDOM size_write =3D vtpm_ipc_write(tx_ipc_h, (dmi_res ? dmi_res->tx_vtpm_ipc_h : NULL), reply, reply_size ); +#else + if(reply_size >=3D 4096) { + vtpmhandlerlogerror(VTPM_LOG_VTPM, "MESSAGE TOO BIG!!!"); + } + size_write =3D vtpm_ipc_write(tx_ipc_h, NULL, reply, reply_size ); +#endif if (size_write > 0) { vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT: 0x"); for (i=3D0; i < reply_size; i++) @@ -247,7 +263,6 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t *tx_ipc_h, vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s had error writing to ipc. Aborting... \n", thread_name); goto abort_command; } - free(out_message); out_message=3DNULL; =20 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 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t *tx_ipc_h, buffer_free(command_buf); =20 // If we have a write lock, save the manager table - if ((tag =3D=3D VTPM_TAG_REQ) && (ord & VTPM_PRIV_MASK) && + if (locked && (tag =3D=3D VTPM_TAG_REQ) && (ord & VTPM_PRIV_MASK) &&= (VTPM_SaveManagerData() !=3D TPM_SUCCESS) ) { vtpmhandlerlogerror(VTPM_LOG_VTPM, "ERROR: Unable to save manager data.\n"); } =20 - vtpm_lock_unlock(); + if(locked) { + vtpm_lock_unlock(); + } add_header =3D 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); =20 } =20 @@ -313,6 +336,16 @@ TPM_RESULT vtpm_manager_handle_vtpm_cmd(VTPM_DMI_RESOURCE *dmi_res, status =3D VTPM_Handle_Load_Migration_key(command_buf, result_buf); break; + case VTPM_ORD_SAVEHASHKEY: + status =3D VTPM_Handle_Save_HashKey(dmi_res, + command_buf, + result_buf); + break; + case VTPM_ORD_LOADHASHKEY: + status =3D VTPM_Handle_Load_HashKey(dmi_res, + command_buf, + result_buf); + break; =20 default: // Privileged handlers can do maintanance @@ -350,6 +383,7 @@ TPM_RESULT vtpm_manager_handle_vtpm_cmd(VTPM_DMI_RESOURCE *dmi_res, return(status); } =20 +#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 @@ TPM_RESULT vtpm_manager_handle_tpm_cmd(vtpm_ipc_handle_t *tx_ipc_h, =20 return status; } +#endif =20 diff --git a/tools/vtpm_manager/manager/vtpm_manager_handler.h b/tools/vtpm_manager/manager/vtpm_manager_handler.h --- /dev/null +++ b/tools/vtpm_manager/manager/vtpm_manager_handler.h @@ -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 --git a/tools/vtpm_manager/manager/vtpmd.c b/tools/vtpm_manager/manager/vtpmd.c --- a/tools/vtpm_manager/manager/vtpmd.c +++ b/tools/vtpm_manager/manager/vtpmd.c @@ -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" =20 -#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 @@ struct vtpm_thread_params_s { char *thread_name; }; =20 +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 =20 void *vtpm_manager_thread(void *arg_void) { - TPM_RESULT *status =3D (TPM_RESULT *) malloc(sizeof(TPM_RESULT) ); struct vtpm_thread_params_s *arg =3D (struct vtpm_thread_params_s *) arg_void; =20 - *status =3D 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); =20 - return (status); + return NULL; } =20 - -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 =3D IPC_QUIT_FLAG =3D 1; } - - VTPM_Stop_Manager(); - exit(-1); } =20 struct sigaction ctl_c_handler; =20 -TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res, BYTE vm_type, BYTE startup_mode) { - - TPM_RESULT status =3D 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 =3D=3D VTPM_CTL_DM) { - dmi_res->tx_tpm_ipc_h =3D NULL; - dmi_res->rx_tpm_ipc_h =3D NULL; - dmi_res->tx_vtpm_ipc_h =3D NULL; - dmi_res->rx_vtpm_ipc_h =3D NULL; - } else { - // Create a pair of fifo pipes - dmi_res->rx_tpm_ipc_h =3D NULL; - dmi_res->rx_vtpm_ipc_h =3D NULL; - - if ( ((dmi_res->tx_tpm_ipc_h =3D (vtpm_ipc_handle_t *) malloc (sizeof(vtpm_ipc_handle_t))) =3D=3D NULL ) || - ((dmi_res->tx_vtpm_ipc_h =3D(vtpm_ipc_handle_t *) malloc (sizeof(vtpm_ipc_handle_t))) =3D=3D NULL ) || - ((tx_tpm_name =3D (char *) malloc(11 + strlen(VTPM_TX_TPM_FNAME))) =3D=3D NULL ) || - ((tx_vtpm_name =3D(char *) malloc(11 + strlen(VTPM_TX_VTPM_FNAME))) =3D=3D NULL) ) { - status =3DTPM_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) !=3D 0) || - (vtpm_ipc_init(dmi_res->tx_vtpm_ipc_h, tx_vtpm_name, O_WRONLY, TRUE) !=3D 0) ) { //FIXME: O_NONBLOCK? - status =3D 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 =3D open(TPM_EMULATOR_PATH, O_RDONLY); - stat_ret =3D fstat(fh, &file_stat); - if (stat_ret =3D=3D 0) - dmi_size =3D file_stat.st_size; - else { - vtpmlogerror(VTPM_LOG_VTPM, "Could not open vtpmd!!\n"); - status =3D TPM_IOERROR; - goto abort_egress; - } - dmi_buffer - */ - memset(&dmi_res->DMI_measurement, 0xcc, sizeof(TPM_DIGEST)); - - if (vm_type =3D=3D VTPM_TYPE_PVM) - vm_type_string =3D (BYTE *)&VTPM_TYPE_PVM_STRING; - else - vm_type_string =3D (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=3D%s now.\n", dmi_id_str); - dmi_res->dmi_pid =3D 0; -#else - pid_t pid =3D fork(); - - if (pid =3D=3D -1) { - vtpmlogerror(VTPM_LOG_VTPM, "Could not fork to launch vtpm\n"); - status =3D TPM_RESOURCES; - goto abort_egress; - } else if (pid =3D=3D 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 =3D 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 =3D pid; - vtpmloginfo(VTPM_LOG_VTPM, "Launching DMI on PID =3D %d\n", pid); - } -#endif // MANUAL_DM_LAUNCH - - } // If DMI =3D VTPM_CTL_DM - status =3D TPM_SUCCESS; - -abort_egress: - return (status); -} - -TPM_RESULT VTPM_Close_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res) { - TPM_RESULT status =3D TPM_SUCCESS; - - if (vtpm_globals->connected_dmis =3D=3D 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); - } - -=20 - if (dmi_res->dmi_id !=3D 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 !=3D VTPM_CTL_DM) { - if (dmi_res->dmi_pid !=3D 0) { - vtpmloginfo(VTPM_LOG_VTPM, "Killing dmi on pid %d.\n", dmi_res->dmi_pid); - if (kill(dmi_res->dmi_pid, SIGKILL) !=3D0) { - 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) !=3D dmi_res->dmi_pid) { - vtpmlogerror(VTPM_LOG_VTPM, "DMI on pid %d failed to stop.\n", dmi_res->dmi_pid); - status =3D TPM_FAIL; - } - } else { - vtpmlogerror(VTPM_LOG_VTPM, "Could not kill dmi because it's pid was 0.\n"); - status =3D 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 =20 #ifdef DUMMY_BACKEND vtpm_ipc_handle_t tx_dummy_ipc_h, rx_dummy_ipc_h; @@ -258,34 +110,28 @@ int main(int argc, char **argv) { #endif =20 vtpmloginfo(VTPM_LOG_VTPM, "Starting VTPM.\n"); - - // -------------------- Initialize Manager ----------------- - if (VTPM_Init_Manager() !=3D TPM_SUCCESS) { - vtpmlogerror(VTPM_LOG_VTPM, "Closing vtpmd due to error during startup.\n"); - return -1; - } -=20 + // -------------------- Setup Ctrl+C Handlers -------------- ctl_c_handler.sa_handler =3D signal_handler; sigemptyset(&ctl_c_handler.sa_mask); ctl_c_handler.sa_flags =3D 0; =20 =20 - if (sigaction(SIGINT, &ctl_c_handler, NULL) =3D=3D -1) + if ((sigaction(SIGINT, &ctl_c_handler, NULL) =3D=3D -1) + || (sigaction(SIGQUIT, &ctl_c_handler, NULL) =3D=3D -1) + || (sigaction(SIGHUP, &ctl_c_handler, NULL) =3D=3D -1) ) // For easi= er debugging with gdb + { vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGINT handler. Ctl+break will not stop manager gently.\n"); + } =20 - // For easier debuggin with gdb - if (sigaction(SIGHUP, &ctl_c_handler, NULL) =3D=3D -1) - vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGHUP handler. Ctl+break will not stop manager gently.\n"); =20 -=20 + //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); =20 // ------------------- Set up file ipc structures ---------- #ifdef DUMMY_BACKEND - if ( (vtpm_ipc_init(&tx_dummy_ipc_h, VTPM_DUMMY_TX_BE_FNAME, O_RDWR, TRUE) !=3D 0) || - (vtpm_ipc_init(&rx_dummy_ipc_h, VTPM_DUMMY_RX_BE_FNAME, O_RDWR, TRUE) !=3D 0) ) { + if ( (vtpm_ipc_init(&tx_dummy_ipc_h, VTPM_DUMMY_TX_BE_FNAME, O_RDWR, TRUE, FALSE) !=3D 0) || + (vtpm_ipc_init(&rx_dummy_ipc_h, VTPM_DUMMY_RX_BE_FNAME, O_RDWR, TRUE, FALSE) !=3D 0) ) { =20 vtpmlogerror(VTPM_LOG_VTPM, "Unable to create Dummy BE FIFOs.\n"); exit(-1); @@ -294,21 +140,29 @@ int main(int argc, char **argv) { tx_be_ipc_h =3D &tx_dummy_ipc_h; rx_be_ipc_h =3D &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) !=3D 0) { + vtpmlogerror(VTPM_LOG_VTPM, "Unable to open backend device " VTPM_BE_FNAME "\n"); + exit(-1); + } =20 tx_be_ipc_h =3D &real_be_ipc_h; rx_be_ipc_h =3D &real_be_ipc_h; #endif =20 - if ( (vtpm_ipc_init(&rx_tpm_ipc_h, VTPM_RX_TPM_FNAME, O_RDONLY, TRUE) !=3D 0) || - (vtpm_ipc_init(&rx_vtpm_ipc_h, VTPM_RX_VTPM_FNAME, O_RDWR, TRUE) !=3D 0) || //FIXME: O_RDONLY? - (vtpm_ipc_init(&tx_hp_ipc_h, VTPM_TX_HP_FNAME, O_RDWR, TRUE) !=3D= 0) || - (vtpm_ipc_init(&rx_hp_ipc_h, VTPM_RX_HP_FNAME, O_RDWR, TRUE) !=3D= 0) ) { + if ( +#ifndef VTPM_STUBDOM + (vtpm_ipc_init(&rx_tpm_ipc_h, VTPM_RX_TPM_FNAME, O_RDONLY, TRUE, FALSE) !=3D 0) || + (vtpm_ipc_init(&rx_vtpm_ipc_h, VTPM_RX_VTPM_FNAME, O_RDWR, TRUE, FALSE) !=3D 0) || //FIXME: O_RDONLY? +#endif + (vtpm_ipc_init(&tx_hp_ipc_h, VTPM_TX_HP_FNAME, O_RDWR, TRUE, TRUE) !=3D 0) || + (vtpm_ipc_init(&rx_hp_ipc_h, VTPM_RX_HP_FNAME, O_RDWR, TRUE, TRUE) !=3D 0) ) { vtpmlogerror(VTPM_LOG_VTPM, "Unable to create initial FIFOs.\n"); exit(-1); } =20 +#ifndef VTPM_STUBDOM g_rx_tpm_ipc_h =3D &rx_tpm_ipc_h; +#endif =20 // -------------------- Set up thread params ------------- =20 @@ -316,10 +170,15 @@ int main(int argc, char **argv) { be_thread_params.rx_ipc_h =3D rx_be_ipc_h; be_thread_params.fw_tpm =3D TRUE; be_thread_params.fw_tx_ipc_h =3D NULL; +#ifndef VTPM_STUBDOM be_thread_params.fw_rx_ipc_h =3D &rx_tpm_ipc_h; +#else + be_thread_params.fw_rx_ipc_h =3D NULL; +#endif be_thread_params.is_priv =3D FALSE; be_thread_params.thread_name =3D "Backend Listener"; =20 +#ifndef VTPM_STUBDOM dmi_thread_params.tx_ipc_h =3D NULL; dmi_thread_params.rx_ipc_h =3D &rx_vtpm_ipc_h; dmi_thread_params.fw_tpm =3D FALSE; @@ -327,6 +186,7 @@ int main(int argc, char **argv) { dmi_thread_params.fw_rx_ipc_h =3D NULL; dmi_thread_params.is_priv =3D FALSE; dmi_thread_params.thread_name =3D "VTPM Listener"; +#endif =20 hp_thread_params.tx_ipc_h =3D &tx_hp_ipc_h; hp_thread_params.rx_ipc_h =3D &rx_hp_ipc_h; @@ -336,34 +196,50 @@ int main(int argc, char **argv) { hp_thread_params.is_priv =3D TRUE; hp_thread_params.thread_name =3D "Hotplug Listener"; =20 + // -------------------- Initialize Manager ----------------- + if (VTPM_Init_Manager() !=3D TPM_SUCCESS) { + vtpmlogerror(VTPM_LOG_VTPM, "Closing vtpmd due to error during startup.\n"); + return -1; + } + + // --------------------- Launch Threads ----------------- =20 vtpm_lock_init(); =20 - vtpm_globals->master_pid =3D pthread_self(); + master_thread =3D pthread_self(); + =20 if (pthread_create(&be_thread, NULL, vtpm_manager_thread, &be_thread_params) !=3D 0) { vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch BE Thread.\n"); exit(-1); } =20 +#ifndef VTPM_STUBDOM if (pthread_create(&dmi_thread, NULL, vtpm_manager_thread, &dmi_thread_params) !=3D 0) { vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch DMI Thread.\n"); exit(-1); } - +#endif =20 if (pthread_create(&hp_thread, NULL, vtpm_manager_thread, &hp_thread_params) !=3D 0) { vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch HP Thread.\n"); exit(-1); } =20 + //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); =20 - vtpmlogerror(VTPM_LOG_VTPM, "VTPM Manager shut down unexpectedly.\n");= + vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager shutting down...\n"); =20 VTPM_Stop_Manager(); vtpm_lock_destroy(); diff --git a/tools/vtpm_manager/manager/vtpmpriv.h b/tools/vtpm_manager/manager/vtpmpriv.h --- a/tools/vtpm_manager/manager/vtpmpriv.h +++ b/tools/vtpm_manager/manager/vtpmpriv.h @@ -40,6 +40,8 @@ #ifndef __VTPMPRIV_H__ #define __VTPMPRIV_H__ =20 +#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 =20 +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; =20 -#ifndef VTPM_MULTI_VM - pid_t dmi_pid; #endif =20 // Non-persistent Information @@ -77,6 +82,9 @@ typedef struct VTPM_DMI_RESOURCE_T { BYTE dmi_type; TPM_DIGEST NVM_measurement; // Equal to the SHA1 of the bl= ob TPM_DIGEST DMI_measurement; // Correct measurement of the owning DMI + + char* uuid; + } VTPM_DMI_RESOURCE; =20 typedef struct tdVTPM_MIGKEY_LIST { @@ -89,10 +97,6 @@ typedef struct tdVTPM_MIGKEY_LIST { =20 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 =20 struct hashtable *dmi_map; // Table of all DMI's known indexed by persistent instance # @@ -123,8 +127,8 @@ extern VTPM_GLOBALS *vtpm_globals; // Key info and DMI states extern const TPM_AUTHDATA SRK_AUTH; // SRK Well Known Auth Value =20 // ********************** 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 cmd= s @@ -143,6 +147,11 @@ TPM_RESULT VTPM_Handle_Save_NVM( =20 VTPM_DMI_RESOURCE *myDMI, const buffer_t *inbuf, buffer_t *outbuf); =20 +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 VTPM_Close_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res); TPM_RESULT close_dmi(VTPM_DMI_RESOURCE *dmi_res); TPM_RESULT init_dmi(UINT32 dmi_id, BYTE type, VTPM_DMI_RESOURCE **dmi_res); =20 +/* 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 @@ TPM_RESULT envelope_decrypt(const buffer_t *ciph= er, const TPM_AUTHDATA *key_usage_auth, buffer_t *unsealed_data); =20 +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 --git a/tools/vtpm_manager/manager/vtsp.c b/tools/vtpm_manager/manager/vtsp.c --- a/tools/vtpm_manager/manager/vtsp.c +++ b/tools/vtpm_manager/manager/vtsp.c @@ -38,6 +38,7 @@ // =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 #include +#include #include "tcg.h" #include "tcs.h" #include "bsg.h" @@ -312,7 +313,7 @@ TPM_RESULT VTSP_TakeOwnership( const TCS_CONTEXT_HANDLE hContext, TPM_PROTOCOL_ID proto_id =3D TPM_PID_OWNER; BYTE *new_srk; =20 - BYTE *paramText; // Digest to make Auth. + BYTE *paramText =3D NULL; // Digest to make Auth. UINT32 paramTextSize; =20 // vars for srkpubkey parameter @@ -458,7 +459,7 @@ TPM_RESULT VTSP_CreateWrapKey( const TCS_CONTEXT_HANDLE hContext, vtpmloginfo(VTPM_LOG_VTSP, "Creating new key of type %d.\n", usage); =20 // vars for Calculate encUsageAuth - BYTE *paramText; =20 + BYTE *paramText =3D NULL; UINT32 paramTextSize; =20 // vars for Calculate encUsageAuth @@ -567,8 +568,7 @@ TPM_RESULT VTSP_CreateWrapKey( const TCS_CONTEXT_HANDLE hContext, osapSharedSecret, auth, 0) ); =20 // 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) = ); =20 goto egress; =20 @@ -664,6 +664,7 @@ TPM_RESULT VTSP_LoadKey(const TCS_CONTEXT_HANDLE =20 hContext, =20 // Destroy rsaKeyParms BSG_Destroy(BSG_TPM_RSA_KEY_PARMS, &rsaKeyParms); + BSG_Destroy(BSG_TPM_KEY, &newKey); =20 // Set encryption scheme cryptoinfo->encScheme =3D CRYPTO_ES_RSAESOAEP_SHA1_MGF1; @@ -733,8 +734,7 @@ TPM_RESULT VTSP_Unbind( const TCS_CONTEXT_HANDLE =20 hContext, hContext) ); =20 // 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)= ); =20 goto egress; =20 @@ -793,8 +793,7 @@ TPM_RESULT VTSP_Bind( CRYPTO_INFO *cryptoInfo, vtpmlogerror(VTPM_LOG_VTSP, "Enc buffer just overflowed.\n"); } =20 - buffer_init(outData, 0, NULL); - buffer_append_raw(outData, out_tmp_size, out_tmp); + buffer_init(outData, out_tmp_size, out_tmp); =20 vtpmloginfo(VTPM_LOG_TXDATA, "Bind Generated[%d] =3D 0x", out_tmp_size= ); for(i =3D 0 ; i < out_tmp_size ; i++) { @@ -1005,8 +1004,6 @@ TPM_RESULT VTSP_SaveState( const TCS_CONTEXT_HANDLE hContext) { =20 vtpmloginfo(VTPM_LOG_VTSP, "Calling TPM_SaveState.\n"); =20 - TPM_RESULT status =3D TPM_SUCCESS; - // Call TCS return ( TCSP_SaveState ( hContext ) ); =20 diff --git a/tools/vtpm_manager/manager/vtsp.h b/tools/vtpm_manager/manager/vtsp.h --- a/tools/vtpm_manager/manager/vtsp.h +++ b/tools/vtpm_manager/manager/vtsp.h @@ -42,6 +42,7 @@ =20 #include "tcg.h" #include "tcs.h" +#include "crypto.h" =20 #define KEY_BUFFER_SIZE 2048 =20 diff --git a/tools/vtpm_manager/migration/Makefile b/tools/vtpm_manager/migration/Makefile --- a/tools/vtpm_manager/migration/Makefile +++ b/tools/vtpm_manager/migration/Makefile @@ -1,5 +1,11 @@ -XEN_ROOT =3D $(CURDIR)/../../.. -include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk +XEN_ROOT =3D $(realpath ../../..) +include ../Rules.mk + +CFLAGS +=3D -I../crypto +CFLAGS +=3D -I../util +CFLAGS +=3D -I../tcs +CFLAGS +=3D -I../manager + =20 VPATH =3D ../manager =20 @@ -33,10 +39,10 @@ mrproper: clean rm -f *~ =20 $(BIND): $(OBJSD) - $(CC) $(LDFLAGS) $^ $(LIBS) -o $@ + $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@ =20 $(BINC): $(OBJSC) - $(CC) $(LDFLAGS) $^ $(LIBS) -o $@ + $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@ =20 # libraries LIBS +=3D ../util/libTCGUtils.a diff --git a/tools/vtpm_manager/migration/vtpm_manager_if.c b/tools/vtpm_manager/migration/vtpm_manager_if.c --- a/tools/vtpm_manager/migration/vtpm_manager_if.c +++ b/tools/vtpm_manager/migration/vtpm_manager_if.c @@ -50,15 +50,12 @@ #include "vtpm_migrator.h" #include "vtpm_manager.h" =20 -#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; =20 TPM_RESULT vtpm_manager_open(){ =20 - if ( (vtpm_ipc_init(&tx_ipc_h, VTPM_TX_HP_FNAME, O_RDWR, TRUE) !=3D 0= ) || //FIXME: wronly - (vtpm_ipc_init(&rx_ipc_h, VTPM_RX_HP_FNAME, O_RDWR, TRUE) !=3D 0= ) ) { //FIXME: rdonly + if ( (vtpm_ipc_init(&tx_ipc_h, VTPM_TX_HP_FNAME, O_RDWR, TRUE, TRUE) !=3D 0) || //FIXME: wronly + (vtpm_ipc_init(&rx_ipc_h, VTPM_RX_HP_FNAME, O_RDWR, TRUE, TRUE) !=3D 0) ) { //FIXME: rdonly vtpmlogerror(VTPM_LOG_VTPM, "Unable to connect to vtpm_manager.\n");= return TPM_IOERROR; } diff --git a/tools/vtpm_manager/tcs/Makefile b/tools/vtpm_manager/tcs/Makefile --- a/tools/vtpm_manager/tcs/Makefile +++ b/tools/vtpm_manager/tcs/Makefile @@ -1,5 +1,10 @@ -XEN_ROOT =3D $(CURDIR)/../../.. -include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk +XEN_ROOT =3D $(realpath ../../..) +include ../Rules.mk + +CFLAGS +=3D -I../crypto +CFLAGS +=3D -I../util +CFLAGS +=3D -I../manager + =20 BIN =3D libTCS.a =20 diff --git a/tools/vtpm_manager/tcs/contextmgr.c b/tools/vtpm_manager/tcs/contextmgr.c --- a/tools/vtpm_manager/tcs/contextmgr.c +++ b/tools/vtpm_manager/tcs/contextmgr.c @@ -195,6 +195,7 @@ BOOL DeleteHandleFromList( TCS_CONTEXT_HANDLE hContext, // in =20 BOOL FreeHandleList( CONTEXT_HANDLE* pContextHandle) { // in HANDLE_LIST* pCurrentHandle; + HANDLE_LIST* pNext; BOOL returncode =3D TRUE; =20 vtpmloginfo(VTPM_LOG_TCS_DEEP, "Freeing all handles for context\n"); @@ -205,6 +206,7 @@ BOOL FreeHandleList( CONTEXT_HANDLE* =20 pContextHandle) { // in pCurrentHandle =3D pContextHandle->pHandleList; while (pCurrentHandle !=3D NULL) { =20 + pNext =3D pCurrentHandle->pNextHandle; switch (pCurrentHandle->type) { case TPM_RT_KEY: returncode =3D returncode && !TCSP_EvictKey(pContextHandle->handle= , pCurrentHandle->handle); @@ -216,7 +218,7 @@ BOOL FreeHandleList( CONTEXT_HANDLE* =20 pContextHandle) { // in returncode =3D FALSE; } =20 - pCurrentHandle =3D pCurrentHandle->pNextHandle; + pCurrentHandle =3D pNext; =20 } =20 diff --git a/tools/vtpm_manager/tcs/tcs.c b/tools/vtpm_manager/tcs/tcs.c --- a/tools/vtpm_manager/tcs/tcs.c +++ b/tools/vtpm_manager/tcs/tcs.c @@ -77,7 +77,7 @@ CONTEXT_HANDLE *LookupContext( TCS_CONTEXT_HANDLE=20 hContext) { // -------------------------------------------------------------------------= -------- // Initialization/Uninitialization SubComponent API // -------------------------------------------------------------------------= -------- -TPM_RESULT TCS_create() { +TPM_RESULT TCS_create(void) { TDDL_RESULT hRes =3D TDDL_E_FAIL; TPM_RESULT result =3D TPM_FAIL; =20 @@ -101,7 +101,7 @@ TPM_RESULT TCS_create() { } =20 =20 -void TCS_destroy() +void TCS_destroy(void) { TCS_m_nCount--; =20 @@ -113,14 +113,13 @@ void TCS_destroy() TCS_CONTEXT_HANDLE *hContext; =20 // 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 =3D hashtable_iterator(context_ht); - do { - hContext =3D (TCS_CONTEXT_HANDLE *) hashtable_iterator_key(context_itr); - if (TCS_CloseContext(*hContext) !=3D TPM_SUCCESS) - vtpmlogerror(VTPM_LOG_TCS, "Failed to close context %d properly.\n", *hContext); + + hContext =3D (TCS_CONTEXT_HANDLE *) hashtable_iterator_key(context_itr); + if (TCS_CloseContext(*hContext) !=3D TPM_SUCCESS) + vtpmlogerror(VTPM_LOG_TCS, "Failed to close context %d properly.\n", *hContext); =20 - } while (hashtable_iterator_advance(context_itr)); free(context_itr); } hashtable_destroy(context_ht, 1); @@ -534,6 +533,10 @@ TPM_RESULT TCSP_TerminateHandle(TCS_CONTEXT_HANDLE hContext, // in 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"); + } =20 // call the TPM driver if ((hRes =3D TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength)) @@ -545,9 +548,6 @@ TPM_RESULT TCSP_TerminateHandle(TCS_CONTEXT_HANDLE hContext, // in BSG_TYPE_UINT32, ¶mSize, BSG_TPM_COMMAND_CODE, &returnCode); =20 - if (!DeleteHandleFromList(hContext, handle)) - vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n"); - =20 =20 if (returnCode =3D=3D TPM_SUCCESS && tag =3D=3D TPM_TAG_RSP_COMMAND)= { // Print debug info @@ -882,6 +882,7 @@ TPM_RESULT TCSP_CreateWrapKey(TCS_CONTEXT_HANDLE hContext, // in =20 memcpy(*prgbKey, tempBuf, *pcKeySize); =20 + 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 @@ TPM_RESULT TCSP_EvictKey(TCS_CONTEXT_HANDLE hContext, // in BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2); =20 vtpmloginfo(VTPM_LOG_TCS_DEEP, "Sending paramSize =3D %d\n", InLength)= ; + + if (!DeleteHandleFromList(hContext, hKey)) { + vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n"); + } =20 // call the TPM driver if ((hRes =3D TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength)) =3D=3D TDDL_SUCCESS) { @@ -989,10 +994,6 @@ TPM_RESULT TCSP_EvictKey(TCS_CONTEXT_HANDLE hContext, // in BSG_TYPE_UINT32, ¶mSize, BSG_TPM_COMMAND_CODE, &returnCode); =20 - if (!DeleteHandleFromList(hContext, hKey)) { - vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n"); - } =20 - =20 if (returnCode =3D=3D TPM_SUCCESS && tag =3D=3D TPM_TAG_RSP_COMMAND)= { vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n", paramSize); } else { @@ -1019,7 +1020,7 @@ TPM_RESULT TCSP_GetRandom(TCS_CONTEXT_HANDLE hContext, // in TDDL_UINT32 OutLength =3D TCPA_MAX_BUFFER_LENGTH; =20 // check input params - if (bytesRequested =3D=3D NULL || *randomBytes =3D=3D NULL){ + if (bytesRequested =3D=3D NULL || randomBytes =3D=3D NULL){ return TPM_BAD_PARAMETER; } =20 diff --git a/tools/vtpm_manager/tcs/tcs.h b/tools/vtpm_manager/tcs/tcs.h --- a/tools/vtpm_manager/tcs/tcs.h +++ b/tools/vtpm_manager/tcs/tcs.h @@ -50,8 +50,8 @@ // Exposed API // ------------------------------------------------------------------ =20 -TPM_RESULT TCS_create(); -void TCS_destroy(); +TPM_RESULT TCS_create(void); +void TCS_destroy(void); =20 TPM_RESULT TCS_OpenContext( /* OUT */ TCS_CONTEXT_HANDLE* hContext ); =20 diff --git a/tools/vtpm_manager/tcs/tpmddl.c b/tools/vtpm_manager/tcs/tpmddl.c --- /dev/null +++ b/tools/vtpm_manager/tcs/tpmddl.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2010-2012 United States Government, as represented by + * the Secretary of Defense. All rights reserved. + * + * THIS 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. + */ + +#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 =3D TPM_TAG_RQU_COMMAND; + UINT32 paramsize =3D 22; + UINT32 outsize; + TPM_COMMAND_CODE ord =3D TPM_ORD_GetCapability; + UINT32 subcapsize =3D 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 =3D BSG_UnpackList(outbuf, 4, + BSG_TPM_TAG, &(tag), + BSG_TYPE_UINT32, &(paramsize), + BSG_TPM_RESULT, &(status), + BSG_TYPE_UINT32, size + ); + if (status !=3D TPM_SUCCESS || tag !=3D TPM_TAG_RSP_COMMAND) { + return status; + } + if(*size >=3D 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 handl= es + * and TPM_Terminate_Handle/TPM_Reset for auth handles */ + TDDL_RESULT status; + + TPM_TAG tag =3D TPM_TAG_RQU_COMMAND; + UINT32 paramsize =3D 18; + TPM_COMMAND_CODE ord =3D 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 =3D 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 =3D 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] =3D { 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 =3D 0; i < RLISTSZ; ++i) { + TPM_RESOURCE_TYPE res =3D reslist[i]; + // Get list of current key handles + if((status =3D TDDL_GetCapability( TPM_CAP_HANDLE, res, buf, &bufsiz)) !=3D TPM_SUCCESS) { + //This can happen if the resource type is not supported + //If this happens just silently skip the resource type + if(status =3D=3D TPM_BAD_MODE) { + status =3D 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 =3D 0; j < bufsiz; ++j) { + printf("%02X ", buf[j]); + } + printf("\n"); +#endif + + ptr =3D buf; + ptr +=3D BSG_Unpack(BSG_TYPE_UINT16, ptr, &(packedsz)); + size =3D packedsz; + + //Flush each handle + if(size) { + vtpmloginfo(VTPM_LOG_VTPM, "Flushing %u handle(s) of type %lu\n", size, (unsigned long) res); + for(j =3D 0; j < size; ++j) { + ptr +=3D BSG_Unpack(BSG_TPM_HANDLE, ptr, &(handle)); + TPMTRYRETURN(TDDL_FlushSpecific(handle, res)); + } + } + + } + + goto egress; +abort_egress: +egress: + return status; +} diff --git a/tools/vtpm_manager/tcs/tpmddl.h b/tools/vtpm_manager/tcs/tpmddl.h --- a/tools/vtpm_manager/tcs/tpmddl.h +++ b/tools/vtpm_manager/tcs/tpmddl.h @@ -50,13 +50,14 @@ typedef unsigned int TDDL_UINT32; typedef TDDL_UINT32 TDDL_RESULT; typedef unsigned char TDDL_BYTE; =20 -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_RESULT TDDL_SetCapability( TDDL_UINT32 cap, TDDL_BYTE* buffer, TDDL_UINT32* size); =20 +TDDL_RESULT TDDL_FlushSpecific(TDDL_UINT32 handle, + TDDL_UINT32 res); + +TDDL_RESULT TDDL_FlushAllResources(void); + + #endif // __TPMDDL_H__ diff --git a/tools/vtpm_manager/tcs/transmit.c b/tools/vtpm_manager/tcs/transmit.c --- a/tools/vtpm_manager/tcs/transmit.c +++ b/tools/vtpm_manager/tcs/transmit.c @@ -104,12 +104,13 @@ TDDL_TransmitData( TDDL_BYTE* in, return status; } =20 -TPM_RESULT TDDL_Open() { +TDDL_RESULT TDDL_Open(void) { =20 TDDL_RESULT status =3D TDDL_SUCCESS; =20 + /* If tpm device is already open just silently return success */ if (g_TDDL_open) - return TPM_FAIL; + return TPM_SUCCESS; =20 #ifdef DUMMY_TPM=20 *g_rx_fdp =3D open (TPM_RX_FNAME, O_RDWR); @@ -117,7 +118,7 @@ TPM_RESULT TDDL_Open() { =20 g_tx_fd =3D 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; } =20 @@ -126,7 +127,20 @@ TPM_RESULT TDDL_Open() { return status; } =20 -void TDDL_Close() { +TDDL_RESULT TDDL_Open_use_fd(int fd) { + TDDL_RESULT status =3D TDDL_SUCCESS; + + if(g_TDDL_open) + return TPM_FAIL; + + g_tx_fd =3D fd; + + g_TDDL_open =3D 1; + + return status; +} + +void TDDL_Close(void) { if (! g_TDDL_open) return; =20 diff --git a/tools/vtpm_manager/util/Makefile b/tools/vtpm_manager/util/Makefile --- a/tools/vtpm_manager/util/Makefile +++ b/tools/vtpm_manager/util/Makefile @@ -1,5 +1,10 @@ -XEN_ROOT =3D $(CURDIR)/../../.. -include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk +XEN_ROOT =3D $(realpath ../../..) +include ../Rules.mk + +CFLAGS +=3D -I../crypto +CFLAGS +=3D -I../tcs +CFLAGS +=3D -I../manager + =20 BIN =3D libTCGUtils.a =20 diff --git a/tools/vtpm_manager/util/bsg.c b/tools/vtpm_manager/util/bsg.= c --- a/tools/vtpm_manager/util/bsg.c +++ b/tools/vtpm_manager/util/bsg.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "tcg.h" #include "crypto.h" #include "bsg.h" @@ -317,7 +318,7 @@ static const BSG_Format* find_format (BSG_Type t) { // 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; =20 diff --git a/tools/vtpm_manager/util/bsg.h b/tools/vtpm_manager/util/bsg.= h --- a/tools/vtpm_manager/util/bsg.h +++ b/tools/vtpm_manager/util/bsg.h @@ -161,6 +161,6 @@ TPM_RESULT BSG_DestroyTuple (int numParams, pack_tuple_t params[]); void BSG_PackConst(BSG_UINT32 val, int size, BSG_BYTE* dst); BSG_UINT32 BSG_UnpackConst(const BSG_BYTE* src, int size); =20 -BOOL BSG_static_selfcheck (); +BOOL BSG_static_selfcheck (void); =20 #endif diff --git a/tools/vtpm_manager/util/buffer.c b/tools/vtpm_manager/util/buffer.c --- a/tools/vtpm_manager/util/buffer.c +++ b/tools/vtpm_manager/util/buffer.c @@ -40,6 +40,7 @@ =20 #include "tcg.h" #include "bsg.h" +#include "log.h" #include "buffer.h" =20 static TPM_RESULT buffer_priv_realloc (buffer_t * buf, tpm_size_t newsiz= e); @@ -51,6 +52,7 @@ static TPM_RESULT buffer_priv_realloc (buffer_t * buf, tpm_size_t newsize); TPM_RESULT buffer_init (buffer_t * buf, tpm_size_t initsize, const BYTE* initval) { if (initsize =3D=3D 0) { memset(buf, 0, sizeof(*buf)); + buf->bytes =3D NULL; return TPM_SUCCESS; } =20 @@ -62,8 +64,11 @@ TPM_RESULT buffer_init (buffer_t * buf, tpm_size_t initsize, const BYTE* initval buf->size =3D initsize; buf->alloc_size =3D initsize; =20 - if (initval) + if (initval) { memcpy (buf->bytes, initval, initsize); + } else { + memset(buf->bytes, 0, initsize); + } =20 buf->is_owner =3D TRUE; =20 @@ -190,6 +195,29 @@ TPM_RESULT buffer_append_raw (buffer_t * buf, tpm_size_t len, const BYTE* bytes) return status; } =20 +TPM_RESULT buffer_prepend_raw(buffer_t * buf, tpm_size_t len, const BYTE* bytes) { + TPM_RESULT status =3D 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 +=3D len; + + goto egress; + + abort_egress: + + egress: + + return status; +} + tpm_size_t buffer_len (const buffer_t* buf) { return buf->size; } @@ -199,7 +227,6 @@ TPM_RESULT buffer_free (buffer_t * buf) { free (buf->bytes); buf->bytes =3D NULL; buf->size =3D buf->alloc_size =3D 0; - =20 } =20 return TPM_SUCCESS; @@ -224,3 +251,13 @@ TPM_RESULT buffer_priv_realloc (buffer_t * buf, tpm_size_t newsize) { =20 return TPM_SUCCESS; } + +TPM_RESULT buffer_truncate(buffer_t* buf, tpm_size_t len) +{ + if(len <=3D buf->size) { + buf->size =3D len; + return TPM_SUCCESS; + } + + return TPM_FAIL; +} diff --git a/tools/vtpm_manager/util/buffer.h b/tools/vtpm_manager/util/buffer.h --- a/tools/vtpm_manager/util/buffer.h +++ b/tools/vtpm_manager/util/buffer.h @@ -92,4 +92,9 @@ TPM_RESULT buffer_free (buffer_t * buf); =20 TPM_RESULT buffer_append_raw (buffer_t * buf, tpm_size_t len, const BYTE* bytes); =20 +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 --git a/tools/vtpm_manager/util/hashtable.c b/tools/vtpm_manager/util/hashtable.c --- a/tools/vtpm_manager/util/hashtable.c +++ b/tools/vtpm_manager/util/hashtable.c @@ -32,12 +32,6 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ =20 -/* - * There are duplicates of this code in: - * - tools/xenstore/hashtable.c - * - tools/blktap2/drivers/hashtable.c - */ - #include "hashtable.h" #include "hashtable_private.h" #include diff --git a/tools/vtpm_manager/util/hashtable.h b/tools/vtpm_manager/util/hashtable.h --- a/tools/vtpm_manager/util/hashtable.h +++ b/tools/vtpm_manager/util/hashtable.h @@ -32,11 +32,6 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ =20 -/* - * There are duplicates of this code in: - * - tools/xenstore/hashtable.h - * - tools/blktap2/drivers/hashtable.h - */ =20 #ifndef __HASHTABLE_CWC22_H__ #define __HASHTABLE_CWC22_H__ diff --git a/tools/vtpm_manager/util/hashtable_itr.c b/tools/vtpm_manager/util/hashtable_itr.c --- a/tools/vtpm_manager/util/hashtable_itr.c +++ b/tools/vtpm_manager/util/hashtable_itr.c @@ -32,11 +32,6 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ =20 -/* - * There are duplicates of this code in: - * - tools/blktap2/drivers/hashtable_itr.c - */ - #include "hashtable.h" #include "hashtable_private.h" #include "hashtable_itr.h" diff --git a/tools/vtpm_manager/util/hashtable_itr.h b/tools/vtpm_manager/util/hashtable_itr.h --- a/tools/vtpm_manager/util/hashtable_itr.h +++ b/tools/vtpm_manager/util/hashtable_itr.h @@ -32,11 +32,6 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ =20 -/* - * There are duplicates of this code in: - * - tools/blktap2/drivers/hashtable_itr.h - */ - =20 #ifndef __HASHTABLE_ITR_CWC22__ #define __HASHTABLE_ITR_CWC22__ diff --git a/tools/vtpm_manager/util/hashtable_private.h b/tools/vtpm_manager/util/hashtable_private.h --- a/tools/vtpm_manager/util/hashtable_private.h +++ b/tools/vtpm_manager/util/hashtable_private.h @@ -32,12 +32,6 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ =20 -/* - * There are duplicates of this code in: - * - tools/xenstore/hashtable_private.h - * - tools/blktap2/drivers/hashtable_private.h - */ - #ifndef __HASHTABLE_PRIVATE_CWC22_H__ #define __HASHTABLE_PRIVATE_CWC22_H__ =20 diff --git a/tools/vtpm_manager/util/log.c b/tools/vtpm_manager/util/log.= c --- a/tools/vtpm_manager/util/log.c +++ b/tools/vtpm_manager/util/log.c @@ -38,6 +38,17 @@ #include "buffer.h" #include "tcg.h" =20 +char *module_names[] =3D { "", + "CRYPTO", + "BSG", + "TXDATA", + "TCS", + "TCS", + "VTSP", + "VTPM", + "VTPM", + "VTSP" + }; // Helper code for the consts, eg. to produce messages for error codes. =20 typedef struct error_code_entry_t { diff --git a/tools/vtpm_manager/util/log.h b/tools/vtpm_manager/util/log.= h --- a/tools/vtpm_manager/util/log.h +++ b/tools/vtpm_manager/util/log.h @@ -36,6 +36,8 @@ =20 #include // for uint32_t #include // for pointer NULL +#include +#include =20 // =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D LOGGING =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 @@ -50,17 +52,7 @@ #define VTPM_LOG_VTPM_DEEP 8 #define VTPM_LOG_VTSP_DEEP 9 =20 -static char *module_names[] =3D { "", - "CRYPTO", - "BSG", - "TXDATA", - "TCS", - "TCS", - "VTSP", - "VTPM", - "VTPM", - "VTSP" - }; +extern char *module_names[]; =20 // Default to standard logging #ifndef LOGGING_MODULES diff --git a/tools/vtpm_manager/util/tcg.h b/tools/vtpm_manager/util/tcg.= h --- a/tools/vtpm_manager/util/tcg.h +++ b/tools/vtpm_manager/util/tcg.h @@ -197,6 +197,7 @@ typedef struct pack_buf_t { UINT32 size; BYTE * data; } pack_buf_t; +#define NULL_PACK_BUF {0,0} =20 typedef struct pack_constbuf_t { UINT32 size; @@ -295,6 +296,35 @@ typedef struct pack_constbuf_t { #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)= =20 =20 @@ -419,8 +449,16 @@ typedef struct pack_constbuf_t { /// 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 + + =20 // TPM_PROTOCOL_ID values #define TPM_PID_OIAP 0x0001 @@ -447,6 +485,64 @@ typedef struct pack_constbuf_t { #define TPM_SS_RSASSAPKCS1v15_SHA1 0x0002 #define TPM_SS_RSASSAPKCS1v15_DER 0x0003 =20 +/* + * 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 --git a/tools/vtpm_manager/vtpmconnd/Makefile b/tools/vtpm_manager/vtpmconnd/Makefile --- /dev/null +++ b/tools/vtpm_manager/vtpmconnd/Makefile @@ -0,0 +1,30 @@ +# Copyright (c) 2010-2012 United States Government, as represented by +# the Secretary of Defense. All rights reserved. +# +# THIS 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. +# + +XEN_ROOT =3D $(realpath ../../..) +include ../Rules.mk + +BIN=3Dvtpmconnd +OBJS=3Dvtpmconnd.o +CFLAGS=3D-O2 -Wall + +all: ${BIN} + +${BIN}: ${OBJS} + gcc -o $@ $< + +install: ${BIN} + install -m 0755 ${BIN} $(DESTDIR)$(BINDIR)/$(BIN) + +.PHONY: mrproper +mrproper: clean +clean: + -rm ${BIN} ${OBJS} diff --git a/tools/vtpm_manager/vtpmconnd/vtpmconnd.c b/tools/vtpm_manager/vtpmconnd/vtpmconnd.c --- /dev/null +++ b/tools/vtpm_manager/vtpmconnd/vtpmconnd.c @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2010-2012 United States Government, as represented by + * the Secretary of Defense. All rights reserved. + * + * THIS 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. + */ + +#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 =3D 0; + +struct Opts { + const char* vtpmbe; + const char* tpmdev; + int verbosity; + int daemon; +}; + +struct Opts opts =3D { + .vtpmbe =3D VTPM_BE, + .tpmdev =3D TPM_DEV, + .verbosity =3D 0, + .daemon =3D 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 =3D 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 =3D read(vbefd, buf, MAX_CMD)) < 0) { + if(errno =3D=3D 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 =3D 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 =3D write(tpmfd, buf + 4, size - 4)) !=3D 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 =3D 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 =3D 0; i < size + 4; ++i) { + printf(" %02X", buf[i]); + } + printf("\n"); + } + + if(quit) { + break; + } + + /* Send response back to vtpm_manager */ + if((wrote =3D write(vbefd, buf, size + 4)) !=3D 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 =3D -1; + struct sigaction sig; + pid_t pid; + + /* Do cmdline opts */ + opterr =3D 0; + + while ((c =3D getopt (argc, argv, "hfvb:t:")) !=3D -1) + { + switch (c) + { + case 'h': + usage(argv[0]); + return 0; + case 'f': + opts.daemon =3D 0; + break; + case 'v': + ++opts.verbosity; + break; + case 'b': + opts.vtpmbe =3D optarg; + break; + case 't': + opts.tpmdev =3D optarg; + break; + case '?': + if (optopt =3D=3D '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 =3D 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 =3D sighandler; + sigemptyset(&sig.sa_mask); + sig.sa_flags =3D 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) !=3D 0 && errno !=3D ENOENT) { + fprintf(stderr, "Unable to remove %s : %s\n", VTPM_RX_HP_FNAME, strerror(errno)); + return -1; + } + if(symlink(DEVNULL, VTPM_RX_HP_FNAME) !=3D 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) !=3D 0 && errno !=3D ENOENT) { + fprintf(stderr, "Unable to remove %s : %s\n", VTPM_TX_HP_FNAME, strerror(errno)); + return -1; + } + if((fd =3D open(VTPM_TX_HP_FNAME, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR)) < 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) !=3D 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 =3D open(opts.vtpmbe, O_RDWR)) < 0) { + fprintf(stderr, "Unable to open `%s', (%s)\n", opts.vtpmbe, strerror(errno)); + return 1; + } + if((tpmfd =3D 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 =3D main_loop(vbefd, tpmfd); + + close(vbefd); + close(tpmfd); + + remove(VTPM_RX_HP_FNAME); + remove(VTPM_TX_HP_FNAME); + + + return rc; + + +} diff --git a/tools/vtpm_manager/vtpmmgrtalk/Makefile b/tools/vtpm_manager/vtpmmgrtalk/Makefile --- /dev/null +++ b/tools/vtpm_manager/vtpmmgrtalk/Makefile @@ -0,0 +1,35 @@ +# Copyright (c) 2010-2012 United States Government, as represented by +# the Secretary of Defense. All rights reserved. +# +# THIS 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. +# + +XEN_ROOT =3D $(realpath ../../..) +include ../Rules.mk + +BIN=3Dvtpmmgrtalk +OBJS=3Dvtpmmgrtalk.o +CFLAGS=3D-Wall -O2 -g +CFLAGS +=3D -I../crypto +CFLAGS +=3D -I../util +CFLAGS +=3D -I../tcs +CFLAGS +=3D -I../manager + + +all: ${BIN} + +${BIN}: ${OBJS} + gcc -o $@ $< + +install: all + install -m 0755 ${BIN} $(DESTDIR)$(BINDIR)/$(BIN) + +.PHONY: mrproper +mrproper: clean +clean: + rm -f ${BIN} ${OBJS} diff --git a/tools/vtpm_manager/vtpmmgrtalk/vtpmmgrtalk.c b/tools/vtpm_manager/vtpmmgrtalk/vtpmmgrtalk.c --- /dev/null +++ b/tools/vtpm_manager/vtpmmgrtalk/vtpmmgrtalk.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2010-2012 United States Government, as represented by + * the Secretary of Defense. All rights reserved. + * + * THIS 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. + */ +#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 =3D 0; + + const char* wfile =3D VTPM_RX_HP_FNAME; + const char* rfile =3D 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 =3D 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 =3D 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 =3D 0; i < COMMAND_BUFFER_SIZE; ++i) { + c =3D scanf("%02hhX", buf + i); + if(c =3D=3D EOF) { + break; + } else if ( c !=3D 1) { + fprintf(stderr, "Malformed Input! Use ASCII hex!\n"); + rc =3D 1; + goto quit; + } + } + size =3D 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 =3D 1; + goto quit; + } + if(flock(rfd, LOCK_EX)) { + fprintf(stderr, "Unable to lock %s : %s\n", wfile, strerror(errno))= ; + rc =3D 1; + goto quit; + } + + /* Write the binary data to the pipe */ + if(write(wfd, buf, size) !=3D size) { + fprintf(stderr, "Error writing to %s : %s\n", wfile, strerror(errno= )); + rc =3D 1; + goto quit; + } + + /* Read the response from the manager */ + size =3D read(rfd, buf, COMMAND_BUFFER_SIZE); + if(size < 0) { + fprintf(stderr, "Error reading %s : %s\n", rfile, strerror(errno));= + rc =3D 1; + goto quit; + } + /* Output the hex */ + for(i =3D 0; i < size; ++i) { + printf("%02X", buf[i]); + } + fprintf(stderr,"\n"); + + /* Unlock the pipes */ + flock(rfd, LOCK_UN); + flock(wfd, LOCK_UN); + } + + rc =3D 0; +quit: + close(rfd); + close(wfd); + return rc; +} --------------ms010302090205070800070309 Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIDyjCC A8YwggMvoAMCAQICBD/xyf0wDQYJKoZIhvcNAQEFBQAwLzELMAkGA1UEBhMCVVMxDzANBgNV BAoTBkpIVUFQTDEPMA0GA1UECxMGQklTRENBMB4XDTEwMDYxMTE4MjIwNloXDTEzMDYxMTE4 NTIwNlowZjELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkpIVUFQTDEPMA0GA1UECxMGUGVvcGxl MTUwFgYDVQQLEw9WUE5Hcm91cC1CSVNEQ0EwGwYDVQQDExRNYXR0aGV3IEUgRmlvcmF2YW50 ZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAnpbwVSP6o1Nb5lcW7dd3yTo9iBJdi7qz 4nANOMFPK7JOy5npKN1iiousl28U/scUJES55gPwAWYJK3uVyQAsA4adgDKi5DoD1UHDQEwp bY7iHLJeq0NPr4BqYNqnCFPbE6HC8zSJrr4qKn+gVUQT39SIFqdiIPJwZL8FYTRQ/zsCAwEA AaOCAbYwggGyMAsGA1UdDwQEAwIHgDArBgNVHRAEJDAigA8yMDEwMDYxMTE4MjIwNlqBDzIw MTIwNzE3MjI1MjA2WjAbBg0rBgEEAbMlCwMBAQEBBAoWCGZpb3JhbWUxMBsGDSsGAQQBsyUL AwEBAQIEChIIMDAxMDQyNjEwWAYJYIZIAYb6ax4BBEsMSVRoZSBwcml2YXRlIGtleSBjb3Jy ZXNwb25kaW5nIHRvIHRoaXMgY2VydGlmaWNhdGUgbWF5IGhhdmUgYmVlbiBleHBvcnRlZC4w KAYDVR0RBCEwH4EdTWF0dGhldy5GaW9yYXZhbnRlQGpodWFwbC5lZHUwUgYDVR0fBEswSTBH oEWgQ6RBMD8xCzAJBgNVBAYTAlVTMQ8wDQYDVQQKEwZKSFVBUEwxDzANBgNVBAsTBkJJU0RD QTEOMAwGA1UEAxMFQ1JMNTYwHwYDVR0jBBgwFoAUCDUpmxH52EU2CyWmF2EJMB1yqeswHQYD VR0OBBYEFO6LYxg6r9wHZ+zdQtBHn1dZ/YTNMAkGA1UdEwQCMAAwGQYJKoZIhvZ9B0EABAww ChsEVjcuMQMCBLAwDQYJKoZIhvcNAQEFBQADgYEAJO9HQh4YNChVLzuZqK5ARJARD8JoujGZ fdo75quvg2jXFQe2sEjvLnxJZgm/pv8fdZakq48CWwjYHKuvIp7sDjTEsQfo+y7SpN/N2NvJ WU5SqfK1VgYtNLRRoGJUB5Q1aZ+Dg95g3kqpyfpUMISJL8IKVLtJVfN4fggFVUYZ9wwxggGr MIIBpwIBATA3MC8xCzAJBgNVBAYTAlVTMQ8wDQYDVQQKEwZKSFVBUEwxDzANBgNVBAsTBkJJ U0RDQQIEP/HJ/TAJBgUrDgMCGgUAoIHLMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJ KoZIhvcNAQkFMQ8XDTEyMDkyMTE4NTcxMVowIwYJKoZIhvcNAQkEMRYEFKPbujyMaoD5Y/bw vdjKJ+sfR8uVMGwGCSqGSIb3DQEJDzFfMF0wCwYJYIZIAWUDBAEqMAsGCWCGSAFlAwQBAjAK BggqhkiG9w0DBzAOBggqhkiG9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYI KoZIhvcNAwICASgwDQYJKoZIhvcNAQEBBQAEgYAy62HJSShxKuwnVe5wH8mywUyWOUYtBWIT JX3Gayph3FS8wW1gBX3XvFcHGxT2B+wqKKl7pKppwgXNuoHETxxnQk/GL4hHPAy40ErilrZr 9NV3V8HG43ti05+B9GhjWQTskih2BxQ4IGUOcMhBL2agyfj1ICxzDnyLtpiR3Yn21QAAAAAA AA== --------------ms010302090205070800070309-- --===============1454697601346146772== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel --===============1454697601346146772==--