diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/README --- a/tools/vtpm_manager/README Thu Jul 01 14:17:13 2010 -0400 +++ b/tools/vtpm_manager/README Tue Jul 20 15:26:31 2010 -0400 @@ -43,9 +43,6 @@ LOGGING_MODULES -> How extensive logging happens see util/log.h for more info -VTPM_MULTI_VM -> Defined: VTPMs run in their own VMs - Not Defined (default): VTPMs are processes - # Debugging flags that may disappear without notice in the future DUMMY_BACKEND -> vtpm_manager listens on /tmp/in.fifo and @@ -59,6 +56,10 @@ lost. However this has no protection from malicious app issuing a TPM_OwnerClear to wipe the TPM +VTPM_STUBDOM -> vtpm_manager runs in vtpm_stubdom mode with + vtpm instances running in mini-os domains + (see: stubdom/vtpm/README for details) + Requirements ============ - xen-unstable diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/Rules.mk --- a/tools/vtpm_manager/Rules.mk Thu Jul 01 14:17:13 2010 -0400 +++ b/tools/vtpm_manager/Rules.mk Tue Jul 20 15:26:31 2010 -0400 @@ -40,12 +40,12 @@ #CFLAGS += -DLOGGING_MODULES=0x0 #CFLAGS += -DLOGGING_MODULES=0xff -# Use frontend/backend pairs between manager & DMs? -#CFLAGS += -DVTPM_MULTI_VM - # vtpm_manager listens on fifo's rather than backend #CFLAGS += -DDUMMY_BACKEND +# Build for use with vtpm-stubdom +#CFLAGS += -DVTPM_STUBDOM + # TCS talks to fifo's rather than /dev/tpm. TPM Emulator assumed on fifos #CFLAGS += -DDUMMY_TPM diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/crypto/crypto.h --- a/tools/vtpm_manager/crypto/crypto.h Thu Jul 01 14:17:13 2010 -0400 +++ b/tools/vtpm_manager/crypto/crypto.h Tue Jul 20 15:26:31 2010 -0400 @@ -127,6 +127,8 @@ /*[IN]*/ BYTE *modulus, CRYPTO_INFO* cryptoInfo); +void Crypto_RSACryptoInfoFree(CRYPTO_INFO* cryptoInfo); + // // symmetric pack and unpack operations // diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/crypto/rsa.c --- a/tools/vtpm_manager/crypto/rsa.c Thu Jul 01 14:17:13 2010 -0400 +++ b/tools/vtpm_manager/crypto/rsa.c Tue Jul 20 15:26:31 2010 -0400 @@ -149,6 +149,10 @@ } +void Crypto_RSACryptoInfoFree(CRYPTO_INFO* cryptoInfo) { + RSA_free(cryptoInfo->keyInfo); +} + int Crypto_RSAEnc( CRYPTO_INFO *key, UINT32 inDataSize, BYTE *inData, @@ -161,6 +165,7 @@ if (paddedData == NULL) return -1; + memset(paddedData, 0, sizeof(BYTE) * paddedDataSize); *outDataSize = 0; diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/crypto/sym_crypto.c --- a/tools/vtpm_manager/crypto/sym_crypto.c Thu Jul 01 14:17:13 2010 -0400 +++ b/tools/vtpm_manager/crypto/sym_crypto.c Tue Jul 20 15:26:31 2010 -0400 @@ -41,6 +41,7 @@ #include #include "tcg.h" +#include "log.h" #include "sym_crypto.h" typedef enum crypt_op_type_t { @@ -119,11 +120,11 @@ buffer_init_const (&iv, EVP_MAX_IV_LENGTH, ZERO_IV); - buffer_init (o_cipher, - clear->size + - EVP_CIPHER_iv_length(key->cipher) + - EVP_CIPHER_block_size (key->cipher), - 0); + TPMTRYRETURN( buffer_init (o_cipher, + clear->size + + EVP_CIPHER_iv_length(key->cipher) + + EVP_CIPHER_block_size (key->cipher), + 0) ); // copy the IV into the front buffer_copy (o_cipher, &iv); @@ -139,6 +140,7 @@ goto egress; abort_egress: + buffer_free(o_cipher); egress: @@ -170,7 +172,7 @@ // and decrypt TPMTRYRETURN ( ossl_symcrypto_op (key, &cipher_alias, &iv, o_clear, CRYPT_DECRYPT) ); - + goto egress; abort_egress: diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/manager/dmictl.c --- a/tools/vtpm_manager/manager/dmictl.c Thu Jul 01 14:17:13 2010 -0400 +++ b/tools/vtpm_manager/manager/dmictl.c Tue Jul 20 15:26:31 2010 -0400 @@ -116,6 +116,13 @@ return (VTPM_Close_DMI_Extra(dmi_res) ); } + +void free_dmi(VTPM_DMI_RESOURCE *dmi_res) { + if(dmi_res != NULL) { + free(dmi_res->NVMLocation); + } + free(dmi_res); +} TPM_RESULT VTPM_Handle_New_DMI(const buffer_t *param_buf) { @@ -254,7 +261,7 @@ // Close DMI first TPMTRYRETURN(close_dmi( dmi_res )); - free ( dmi_res ); + free_dmi(dmi_res); status=TPM_SUCCESS; goto egress; diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/manager/securestorage.c --- a/tools/vtpm_manager/manager/securestorage.c Thu Jul 01 14:17:13 2010 -0400 +++ b/tools/vtpm_manager/manager/securestorage.c Tue Jul 20 15:26:31 2010 -0400 @@ -42,7 +42,6 @@ #include #include #include - #include "tcg.h" #include "vtpm_manager.h" #include "vtpmpriv.h" @@ -86,8 +85,9 @@ data_cipher32.size = buffer_len(&data_cipher); data_cipher32.data = data_cipher.bytes; - + TPMTRYRETURN( buffer_init(sealed_data, 2 * sizeof(UINT32) + symkey_cipher32.size + data_cipher32.size, NULL)); + memset(sealed_data->bytes, 0, sealed_data->size); BSG_PackList(sealed_data->bytes, 2, BSG_TPM_SIZE32_DATA, &symkey_cipher32, @@ -114,6 +114,32 @@ return status; } +TPM_RESULT symkey_encrypt(const buffer_t *inbuf, + CRYPTO_INFO *asymkey, + buffer_t *sealed_key) { + buffer_t symkey_cipher = NULL_BUF; + struct pack_constbuf_t symkey_cipher32; + TPM_RESULT status = TPM_SUCCESS; + + // Encrypt symmetric key + TPMTRYRETURN( VTSP_Bind( asymkey, + inbuf, + &symkey_cipher)); + + symkey_cipher32.size = buffer_len(&symkey_cipher); + symkey_cipher32.data = symkey_cipher.bytes; + + TPMTRYRETURN( buffer_init(sealed_key, sizeof(UINT32) + symkey_cipher32.size, NULL)); + BSG_PackList(sealed_key->bytes, 1, + BSG_TPM_SIZE32_DATA, &symkey_cipher32); + goto egress; +abort_egress: +egress: + buffer_free( &symkey_cipher); + return status; +} + + TPM_RESULT envelope_decrypt(const buffer_t *cipher, TCS_CONTEXT_HANDLE TCSContext, TPM_HANDLE keyHandle, @@ -125,7 +151,7 @@ buffer_t data_cipher = NULL_BUF, symkey_clear = NULL_BUF, symkey_cipher = NULL_BUF; - struct pack_buf_t symkey_cipher32, data_cipher32; + struct pack_buf_t symkey_cipher32 = NULL_PACK_BUF, data_cipher32 = NULL_PACK_BUF; int i; memset(&symkey, 0, sizeof(symkey_t)); @@ -175,26 +201,68 @@ buffer_free ( &data_cipher); buffer_free ( &symkey_clear); buffer_free ( &symkey_cipher); + BSG_Destroy(BSG_TPM_SIZE32_DATA, &symkey_cipher32); + BSG_Destroy(BSG_TPM_SIZE32_DATA, &data_cipher32); Crypto_symcrypto_freekey (&symkey); + return status; } +TPM_RESULT symkey_decrypt(const buffer_t *cipher, + TCS_CONTEXT_HANDLE TCSContext, + TPM_HANDLE keyHandle, + const TPM_AUTHDATA *key_usage_auth, + buffer_t *symkey_clear) { + + TPM_RESULT status = TPM_SUCCESS; + symkey_t symkey; + buffer_t symkey_cipher = NULL_BUF; + struct pack_buf_t symkey_cipher32 = NULL_PACK_BUF; + int i; + + memset(&symkey, 0, sizeof(symkey_t)); + + BSG_UnpackList(cipher->bytes, 1, + BSG_TPM_SIZE32_DATA, &symkey_cipher32); + + TPMTRYRETURN( buffer_init_alias_convert (&symkey_cipher, + symkey_cipher32.size, + symkey_cipher32.data) ); + + // Decrypt Symmetric Key + TPMTRYRETURN( VTSP_Unbind( TCSContext, + keyHandle, + &symkey_cipher, + key_usage_auth, + symkey_clear, + &(vtpm_globals->keyAuth) ) ); + + goto egress; + abort_egress: + vtpmlogerror(VTPM_LOG_VTPM, "Failed to decrypt symmetric key status=%d\n.", status); + + egress: + BSG_Destroy(BSG_TPM_SIZE32_DATA, &symkey_cipher32); + return status; +} + TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI_RESOURCE *myDMI, const buffer_t *inbuf, buffer_t *outbuf) { TPM_RESULT status = TPM_SUCCESS; - int fh; + int fh = -1; long bytes_written; buffer_t sealed_NVM = NULL_BUF; - - vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Saving %d bytes of NVM.\n", buffer_len(inbuf)); + const buffer_t* nvmbuf = inbuf; - 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) ); - + // 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 +273,6 @@ status = TPM_IOERROR; goto abort_egress; } - close(fh); Crypto_SHA1Full (sealed_NVM.bytes, buffer_len(&sealed_NVM), (BYTE *) &myDMI->NVM_measurement); @@ -215,6 +282,7 @@ vtpmlogerror(VTPM_LOG_VTPM, "Failed to save NVM\n."); egress: + close(fh); buffer_free(&sealed_NVM); return status; } @@ -229,7 +297,8 @@ buffer_t sealed_NVM = NULL_BUF; long fh_size; - int fh, stat_ret, i; + int fh = -1; + int stat_ret, i; struct stat file_stat; TPM_DIGEST sealedNVMHash; @@ -241,6 +310,7 @@ //Read sealed blob off disk from NVMLocation fh = open(myDMI->NVMLocation, O_RDONLY); + printf("Filename: %s\n", myDMI->NVMLocation); stat_ret = fstat(fh, &file_stat); if (stat_ret == 0) fh_size = file_stat.st_size; @@ -254,7 +324,6 @@ status = TPM_IOERROR; goto abort_egress; } - close(fh); vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Load_NVMing[%d],\n", buffer_len(&sealed_NVM)); @@ -289,10 +358,173 @@ egress: buffer_free( &sealed_NVM ); + close(fh); return status; } +TPM_RESULT VTPM_Handle_Get_NVM_Size( VTPM_DMI_RESOURCE *myDMI, + const buffer_t *inbuf, + buffer_t *outbuf) { + TPM_RESULT status = TPM_SUCCESS; + long fh_size; + int fh = -1; + int stat_ret; + struct stat file_stat; + UINT32 fh_size_pack; + + buffer_t sealedNVM; + buffer_init(&sealedNVM, 0, NULL); + struct pack_buf_t symkey_cipher32 = NULL_PACK_BUF, data_cipher32 = NULL_PACK_BUF; + + fh = open(myDMI->NVMLocation, O_RDONLY); + printf("Filename: %s\n", myDMI->NVMLocation); + stat_ret = fstat(fh, &file_stat); + if (stat_ret == 0) + fh_size = file_stat.st_size; + else { + status = TPM_IOERROR; + goto abort_egress; + } + TPMTRYRETURN(buffer_init(&sealedNVM, fh_size, NULL)); + if (read(fh, sealedNVM.bytes, buffer_len(&sealedNVM)) != fh_size) { + status = TPM_IOERROR; + goto abort_egress; + } + + BSG_UnpackList(sealedNVM.bytes, 2, + BSG_TPM_SIZE32_DATA, &symkey_cipher32, + BSG_TPM_SIZE32_DATA, &data_cipher32); + + TPMTRYRETURN(buffer_init(outbuf, sizeof(UINT32), NULL)); + BSG_PackList(outbuf->bytes, 1, + BSG_TYPE_UINT32, (BYTE*)&(data_cipher32.size)); + + + abort_egress: + vtpmlogerror(VTPM_LOG_VTPM, "Failed to retreive size of NVM\n"); + + egress: + BSG_Destroy(BSG_TPM_SIZE32_DATA, &symkey_cipher32); + BSG_Destroy(BSG_TPM_SIZE32_DATA, &data_cipher32); + buffer_free(&sealedNVM); + close(fh); + return status; +} + +TPM_RESULT VTPM_Handle_Load_Key(VTPM_DMI_RESOURCE *myDMI, + const buffer_t *inbuf, + buffer_t *outbuf) { + + TPM_RESULT status = TPM_SUCCESS; + + buffer_t sealed_NVM = NULL_BUF; + long fh_size; + int fh = -1; + int stat_ret, i; + struct stat file_stat; + TPM_DIGEST sealedNVMHash; + + if (myDMI->NVMLocation == NULL) { + vtpmlogerror(VTPM_LOG_VTPM, "Unable to load NVM because the file name NULL.\n"); + status = TPM_AUTHFAIL; + goto abort_egress; + } + + //Read sealed blob off disk from NVMLocation + fh = open(myDMI->NVMLocation, O_RDONLY); + printf("Filename: %s\n", myDMI->NVMLocation); + stat_ret = fstat(fh, &file_stat); + if (stat_ret == 0) + fh_size = file_stat.st_size; + else { + status = TPM_IOERROR; + goto abort_egress; + } + + TPMTRYRETURN( buffer_init( &sealed_NVM, fh_size, NULL) ); + if (read(fh, sealed_NVM.bytes, buffer_len(&sealed_NVM)) != fh_size) { + status = TPM_IOERROR; + goto abort_egress; + } + + vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Loading %d byte encryption key,\n", buffer_len(&sealed_NVM)); + + Crypto_SHA1Full(sealed_NVM.bytes, buffer_len(&sealed_NVM), (BYTE *) &sealedNVMHash); + + // Verify measurement of sealed blob. + if (memcmp(&sealedNVMHash, &myDMI->NVM_measurement, sizeof(TPM_DIGEST)) ) { + vtpmlogerror(VTPM_LOG_VTPM, "VTPM LoadKey NVM measurement check failed.\n"); + vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Correct hash: "); + for (i=0; i< sizeof(TPM_DIGEST); i++) + vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", ((BYTE*)&myDMI->NVM_measurement)[i]); + vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); + + vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Measured hash: "); + for (i=0; i< sizeof(TPM_DIGEST); i++) + vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", ((BYTE*)&sealedNVMHash)[i]); + vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); + + status = TPM_AUTHFAIL; + goto abort_egress; + } + + //Decrypt the key into the output buffer + TPMTRYRETURN( symkey_decrypt(&sealed_NVM, + myDMI->TCSContext, + vtpm_globals->storageKeyHandle, + (const TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth, + outbuf) ); + goto egress; + + abort_egress: + vtpmlogerror(VTPM_LOG_VTPM, "Failed to load Key\n."); + + egress: + buffer_free( &sealed_NVM ); + close(fh); + + return status; +} + +TPM_RESULT VTPM_Handle_Save_Key(VTPM_DMI_RESOURCE *myDMI, + const buffer_t *inbuf, + buffer_t *outbuf) { + TPM_RESULT status = TPM_SUCCESS; + int fh = -1; + long bytes_written; + buffer_t sealed_key = NULL_BUF; + + TPMTRYRETURN( symkey_encrypt(inbuf, + &vtpm_globals->storageKey, + &sealed_key) ); + + vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Saving %d byte Encryption Key.\n", buffer_len(inbuf)); + + // Write sealed blob off disk from NVMLocation + // TODO: How to properly return from these. Do we care if we return failure + // after writing the file? We can't get the old one back. + // TODO: Backup old file and try and recover that way. + fh = open(myDMI->NVMLocation, O_WRONLY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE); + if ( (bytes_written = write(fh, sealed_key.bytes, buffer_len(&sealed_key) ) != (long) buffer_len(&sealed_key))) { + vtpmlogerror(VTPM_LOG_VTPM, "We just overwrote a DMI_NVM and failed to finish. %ld/%ld bytes.\n", bytes_written, (long)buffer_len(&sealed_key)); + status = TPM_IOERROR; + goto abort_egress; + } + + Crypto_SHA1Full (sealed_key.bytes, buffer_len(&sealed_key), (BYTE *) &myDMI->NVM_measurement); + + goto egress; + + abort_egress: + vtpmlogerror(VTPM_LOG_VTPM, "Failed to save Key\n."); + + egress: + close(fh); + buffer_free(&sealed_key); + return status; +} + TPM_RESULT VTPM_SaveManagerData(void) { TPM_RESULT status=TPM_SUCCESS; @@ -364,6 +596,7 @@ BSG_TPM_DIGEST, &dmi_res->DMI_measurement); } while (hashtable_iterator_advance(dmi_itr)); + free(dmi_itr); } fh = open(STATE_FILE, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE); @@ -389,6 +622,7 @@ free(flat_boot_key); free(flat_enc); + buffer_free(&clear_flat_global); buffer_free(&enc_flat_global); free(flat_dmis); close(fh); @@ -403,8 +637,9 @@ int fh, stat_ret, dmis=0; long fh_size = 0, step_size; BYTE *flat_table=NULL; - buffer_t unsealed_data, enc_table_abuf; - struct pack_buf_t storage_key_pack, boot_key_pack; + buffer_t unsealed_data = NULL_BUF; + buffer_t enc_table_abuf; + struct pack_buf_t storage_key_pack = NULL_PACK_BUF, boot_key_pack = NULL_PACK_BUF; UINT32 *dmi_id_key, enc_size; BYTE vtpm_manager_gen; @@ -438,9 +673,9 @@ BSG_TPM_SIZE32_DATA, &boot_key_pack, BSG_TYPE_UINT32, &enc_size); - TPMTRYRETURN(buffer_init(&vtpm_globals->bootKeyWrap, 0, 0) ); TPMTRYRETURN(buffer_init_alias_convert(&enc_table_abuf, enc_size, flat_table + step_size) ); - TPMTRYRETURN(buffer_append_raw(&vtpm_globals->bootKeyWrap, boot_key_pack.size, boot_key_pack.data) ); + TPMTRYRETURN(buffer_init(&vtpm_globals->bootKeyWrap, boot_key_pack.size, boot_key_pack.data) ); + //Load Boot Key TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle, @@ -471,8 +706,8 @@ BSG_TPM_SECRET, &vtpm_globals->storage_key_usage_auth, BSG_TPM_SIZE32_DATA, &storage_key_pack); - TPMTRYRETURN(buffer_init(&vtpm_globals->storageKeyWrap, 0, 0) ); - TPMTRYRETURN(buffer_append_raw(&vtpm_globals->storageKeyWrap, storage_key_pack.size, storage_key_pack.data) ); + TPMTRYRETURN(buffer_init(&vtpm_globals->storageKeyWrap, storage_key_pack.size, storage_key_pack.data) ); + // Per DMI values to be saved while ( step_size < fh_size ){ @@ -501,7 +736,10 @@ abort_egress: vtpmlogerror(VTPM_LOG_VTPM, "Failed to load service data with error = %s\n", tpm_get_error_name(status)); egress: + BSG_Destroy(BSG_TPM_SIZE32_DATA, &boot_key_pack); + BSG_Destroy(BSG_TPM_SIZE32_DATA, &storage_key_pack); + buffer_free(&unsealed_data); free(flat_table); close(fh); diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/manager/vtpm_ipc.c --- a/tools/vtpm_manager/manager/vtpm_ipc.c Thu Jul 01 14:17:13 2010 -0400 +++ b/tools/vtpm_manager/manager/vtpm_ipc.c Tue Jul 20 15:26:31 2010 -0400 @@ -41,15 +41,35 @@ #include "vtpmpriv.h" #include "log.h" -int vtpm_ipc_init(vtpm_ipc_handle_t *ipc_h, char* name, int flags, BOOL create) { +volatile sig_atomic_t IPC_QUIT_FLAG = 0; + +const static struct timeval TIMEOUT = { + .tv_sec = 1, + .tv_usec = 0 +}; + +int vtpm_ipc_init(vtpm_ipc_handle_t *ipc_h, char* name, int flags, BOOL create, BOOL preopen) { + int rc; + ipc_h->name = name; ipc_h->flags = flags; ipc_h->fh = VTPM_IPC_CLOSED; - if (create) - return(vtpm_ipc_create(ipc_h)); - else - return 0; + if (create) { + if((rc = vtpm_ipc_create(ipc_h) != 0)) { + return rc; + } + } + + if(preopen) { + ipc_h->fh = open(ipc_h->name, ipc_h->flags); + if ( ipc_h->fh == VTPM_IPC_CLOSED ) { + vtpmlogerror(VTPM_LOG_VTPM, "VTPM ERROR: Can't open %s\n", ipc_h->name); + return -1; + } + } + return 0; + } // Create the file that needs opening. Used only for FIFOs @@ -68,8 +88,6 @@ } } - ipc_h->fh = VTPM_IPC_CLOSED; - return 0; } @@ -78,6 +96,8 @@ int vtpm_ipc_read(vtpm_ipc_handle_t *ipc_h, vtpm_ipc_handle_t *alt_ipc_h, BYTE *bytes, UINT32 size){ vtpm_ipc_handle_t *my_ipc_h; int result; + fd_set fds; + struct timeval timeout; if (ipc_h) { my_ipc_h = ipc_h; @@ -94,9 +114,19 @@ return -1; } + FD_ZERO(&fds); + while(!FD_ISSET( my_ipc_h->fh, &fds )) { + timeout = TIMEOUT; + if (IPC_QUIT_FLAG) { + return -1; + } + FD_SET(my_ipc_h->fh, &fds); + select(my_ipc_h->fh + 1, &fds, NULL, NULL, &timeout); + } + result = read(my_ipc_h->fh, bytes, size); if (result < 0) { - my_ipc_h->fh = VTPM_IPC_CLOSED; + my_ipc_h->fh = VTPM_IPC_CLOSED; } return (result); @@ -106,6 +136,8 @@ int vtpm_ipc_write(vtpm_ipc_handle_t *ipc_h, vtpm_ipc_handle_t *alt_ipc_h, BYTE *bytes, UINT32 size) { vtpm_ipc_handle_t *my_ipc_h; int result; + fd_set fds; + struct timeval timeout; if (ipc_h) { my_ipc_h = ipc_h; @@ -122,6 +154,16 @@ return -1; } + FD_ZERO(&fds); + while(!FD_ISSET( my_ipc_h->fh, &fds )) { + timeout = TIMEOUT; + if (IPC_QUIT_FLAG) { + return -1; + } + FD_SET(my_ipc_h->fh, &fds); + select(my_ipc_h->fh + 1, NULL, &fds, NULL, &timeout); + } + result = write(my_ipc_h->fh, bytes, size); if (result < 0) { my_ipc_h->fh = VTPM_IPC_CLOSED; diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/manager/vtpm_ipc.h --- a/tools/vtpm_manager/manager/vtpm_ipc.h Thu Jul 01 14:17:13 2010 -0400 +++ b/tools/vtpm_manager/manager/vtpm_ipc.h Tue Jul 20 15:26:31 2010 -0400 @@ -39,10 +39,14 @@ #ifndef __VTPM_IO_H__ #define __VTPM_IO_H__ +#include + #include "tcg.h" #define VTPM_IPC_CLOSED -1 +extern volatile sig_atomic_t IPC_QUIT_FLAG; + // Represents an (somewhat) abstracted io handle. typedef struct vtpm_ipc_handle_t { int fh; // IO handle. @@ -53,7 +57,7 @@ } vtpm_ipc_handle_t; -int vtpm_ipc_init(vtpm_ipc_handle_t *ioh, char* name, int flags, BOOL create); +int vtpm_ipc_init(vtpm_ipc_handle_t *ioh, char* name, int flags, BOOL create, BOOL preopen); // Create the file that needs opening. Used only for FIFOs // FYI: This may cause problems in other file IO schemes. We'll see. diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/manager/vtpm_manager.c --- a/tools/vtpm_manager/manager/vtpm_manager.c Thu Jul 01 14:17:13 2010 -0400 +++ b/tools/vtpm_manager/manager/vtpm_manager.c Tue Jul 20 15:26:31 2010 -0400 @@ -44,6 +44,7 @@ #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 +55,8 @@ VTPM_GLOBALS *vtpm_globals=NULL; // --------------------------- Well Known Auths -------------------------- -const TPM_AUTHDATA SRK_AUTH = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; +const TPM_AUTHDATA SRK_AUTH = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; #ifdef WELL_KNOWN_OWNER_AUTH static BYTE FIXED_OWNER_AUTH[20] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -74,6 +75,67 @@ } // --------------------------- Functions ------------------------------ +TPM_RESULT VTPM_FlushResources() { + TPM_RESULT status = TPM_SUCCESS; + + TDDL_BYTE buf[TCPA_MAX_BUFFER_LENGTH]; + TDDL_UINT32 bufsiz; + + UINT16 packedsz; + int size; + UINT32 handle; + BYTE* ptr; + + int i, j; + +#define RLISTSZ 6 + TPM_RESOURCE_TYPE reslist[RLISTSZ] = { TPM_RT_KEY, TPM_RT_AUTH, TPM_RT_TRANS, TPM_RT_COUNTER, TPM_RT_DAA_TPM, TPM_RT_CONTEXT }; + + //Iterate through each resource type and flush all handles + for(i = 0; i < RLISTSZ; ++i) { + TPM_RESOURCE_TYPE res = reslist[i]; + // Get list of current key handles + if((status = TDDL_GetCapability( TPM_CAP_HANDLE, res, buf, &bufsiz)) != TPM_SUCCESS) { + //This can happen if the resource type is not supported + //If this happens just silently skip the resource type + if(status == TPM_BAD_MODE) { + status = TPM_SUCCESS; + continue; + //Otherwise we just fail + } else { + TPMTRYRETURN(status); + } + } + +#if 0 + //DEBUG PRINTOUTS + printf("TPM_GetCapability(TPM_CAP_HANDLE, %lu)\n", (unsigned long) res); + for(j = 0; j < bufsiz; ++j) { + printf("%02X ", buf[j]); + } + printf("\n"); +#endif + + ptr = buf; + ptr += BSG_Unpack(BSG_TYPE_UINT16, ptr, &(packedsz)); + size = packedsz; + + //Flush each handle + if(size) { + vtpmloginfo(VTPM_LOG_VTPM, "Flushing %u handle(s) of type %lu\n", size, (unsigned long) res); + for(j = 0; j < size; ++j) { + ptr += BSG_Unpack(BSG_TPM_HANDLE, ptr, &(handle)); + TPMTRYRETURN(TDDL_FlushSpecific(handle, res)); + } + } + + } + + goto egress; +abort_egress: +egress: + return status; +} TPM_RESULT VTPM_Create_Manager(){ @@ -104,6 +166,7 @@ TPMTRYRETURN(VTSP_DisablePubekRead(vtpm_globals->manager_tcs_handle, (const TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth, &vtpm_globals->keyAuth)); + Crypto_RSACryptoInfoFree(&ek_cryptoInfo); } else { vtpmloginfo(VTPM_LOG_VTPM, "Failed to readEK meaning TPM has an owner. Creating Keys off existing SRK.\n"); } @@ -203,6 +266,11 @@ vtpm_globals->manager_tcs_handle = 0; TPMTRYRETURN(TCS_create()); + + // Blow away all stale handles left in the tpm + if(VTPM_FlushResources() != TPM_SUCCESS) { + vtpmlogerror(VTPM_LOG_VTPM, "VTPM_FlushResources failed, continuing anyway..\n"); + } // Create TCS Context for service TPMTRYRETURN( TCS_OpenContext(&vtpm_globals->manager_tcs_handle ) ); @@ -228,7 +296,7 @@ TPMTRYRETURN( VTPM_Create_Manager() ); TPMTRYRETURN( VTPM_SaveManagerData() ); } else if (serviceStatus != TPM_SUCCESS) { - vtpmlogerror(VTPM_LOG_VTPM, "Failed to read existing manager file"); + vtpmlogerror(VTPM_LOG_VTPM, "Failed to read existing manager file\n"); exit(1); } @@ -267,7 +335,7 @@ close_dmi( dmi_res ); // Not really interested in return code } while (hashtable_iterator_advance(dmi_itr)); - free (dmi_itr); + free (dmi_itr); } if ( VTPM_SaveManagerData() != TPM_SUCCESS ) @@ -276,7 +344,21 @@ TCS_CloseContext(vtpm_globals->manager_tcs_handle); TCS_destroy(); - hashtable_destroy(vtpm_globals->dmi_map, 1); + if (hashtable_count(vtpm_globals->dmi_map) > 0) { + dmi_itr = hashtable_iterator(vtpm_globals->dmi_map); + do { + dmi_res = (VTPM_DMI_RESOURCE *) hashtable_iterator_value(dmi_itr); + free_dmi(dmi_res); + } while (hashtable_iterator_advance(dmi_itr)); + free (dmi_itr); + } + hashtable_destroy(vtpm_globals->dmi_map, 0); + + /* Cleanup resources */ + Crypto_RSACryptoInfoFree(&vtpm_globals->bootKey); + Crypto_RSACryptoInfoFree(&vtpm_globals->storageKey); + buffer_free(&vtpm_globals->bootKeyWrap); + buffer_free(&vtpm_globals->storageKeyWrap); free(vtpm_globals); Crypto_Exit(); diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/manager/vtpm_manager.h --- a/tools/vtpm_manager/manager/vtpm_manager.h Thu Jul 01 14:17:13 2010 -0400 +++ b/tools/vtpm_manager/manager/vtpm_manager.h Tue Jul 20 15:26:31 2010 -0400 @@ -61,6 +61,9 @@ #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_GETNVMSIZE (VTPM_ORD_BASE + 6) // DMI requests the size of nvm storage blob +#define VTPM_ORD_SAVEKEY (VTPM_ORD_BASE + 7) // DMI requests encryption key for persistent storage +#define VTPM_ORD_LOADKEY (VTPM_ORD_BASE + 8) // DMI requests symkey to be regenerated // Priviledged VTPM Commands (From management console) #define VTPM_ORD_OPEN (VTPM_PRIV_BASE + 1) // Creates/reopens DMI @@ -147,4 +150,23 @@ *********************************************************************/ +#ifndef VTPM_STUBDOM +#define TPM_EMULATOR_PATH "/usr/bin/vtpmd" +#endif + +#define VTPM_BE_FNAME "/dev/vtpm" +#define VTPM_DUMMY_TX_BE_FNAME "/var/vtpm/fifos/dummy_out.fifo" +#define VTPM_DUMMY_RX_BE_FNAME "/var/vtpm/fifos/dummy_in.fifo" +#ifndef VTPM_STUBDOM +#define VTPM_TX_TPM_FNAME "/var/vtpm/fifos/tpm_cmd_to_%d.fifo" +#define VTPM_RX_TPM_FNAME "/var/vtpm/fifos/tpm_rsp_from_all.fifo" +#define VTPM_TX_VTPM_FNAME "/var/vtpm/fifos/vtpm_rsp_to_%d.fifo" +#define VTPM_RX_VTPM_FNAME "/var/vtpm/fifos/vtpm_cmd_from_all.fifo" +#endif +#define VTPM_TX_HP_FNAME "/var/vtpm/fifos/to_console.fifo" +#define VTPM_RX_HP_FNAME "/var/vtpm/fifos/from_console.fifo" + +#define VTPM_TYPE_PVM_STRING "pvm" +#define VTPM_TYPE_HVM_STRING "hvm" + #endif //_VTPM_MANAGER_H_ diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/manager/vtpm_manager_handler.c --- a/tools/vtpm_manager/manager/vtpm_manager_handler.c Thu Jul 01 14:17:13 2010 -0400 +++ b/tools/vtpm_manager/manager/vtpm_manager_handler.c Tue Jul 20 15:26:31 2010 -0400 @@ -41,6 +41,7 @@ #include #include #include +#include #include "vtpm_manager.h" #include "vtpmpriv.h" @@ -55,6 +56,8 @@ #define vtpmhandlerloginfomore(module,fmt,args...) vtpmloginfomore (module, fmt, ##args ); #define vtpmhandlerlogerror(module,fmt,args...) vtpmlogerror (module, "[%s]: " fmt, thread_name, ##args ); +volatile sig_atomic_t HANDLER_QUIT_FLAG = 0; + // ---------------------- Prototypes ------------------- TPM_RESULT vtpm_manager_handle_vtpm_cmd(VTPM_DMI_RESOURCE *dmi_res, TPM_COMMAND_CODE ord, @@ -63,6 +66,7 @@ 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, @@ -70,6 +74,7 @@ buffer_t *param_buf, buffer_t *result_buf, char *thread_name); +#endif TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t *tx_ipc_h, vtpm_ipc_handle_t *rx_ipc_h, @@ -80,12 +85,13 @@ char *thread_name) { TPM_RESULT status = TPM_FAIL; // Should never return UINT32 dmi, in_param_size, cmd_size, out_param_size, out_message_size, reply_size; - BYTE *cmd_header=NULL, *in_param=NULL, *out_message=NULL, *reply; + BYTE *cmd_header=NULL, *in_param=NULL, *out_header=NULL, *reply; buffer_t *command_buf=NULL, *result_buf=NULL; TPM_TAG tag; TPM_COMMAND_CODE ord; VTPM_DMI_RESOURCE *dmi_res; int size_read, size_write, i; + int locked; BOOL add_header=TRUE; // This indicates to prepend a header on result_buf before sending cmd_header = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV); @@ -93,7 +99,11 @@ result_buf = (buffer_t *) malloc(sizeof(buffer_t)); // ------------------------ Main Loop -------------------------------- - while(1) { + while(!HANDLER_QUIT_FLAG) { + locked = 0; + + buffer_init(command_buf, 0, NULL); + buffer_init(result_buf, 0, NULL); vtpmhandlerloginfo(VTPM_LOG_VTPM, "%s waiting for messages.\n", thread_name); @@ -106,7 +116,9 @@ for (i=0; iis_owner = TRUE; // -------------- Dispatch Commands to Handlers ----------- if ((tag == VTPM_TAG_REQ) && (ord & VTPM_PRIV_MASK)) { @@ -162,6 +175,7 @@ } else { vtpm_lock_rdlock(); } + locked = 1; if ( !(dmi_res = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi)) || (!dmi_res->connected) ) { @@ -174,10 +188,22 @@ if (tag == VTPM_TAG_REQ) { status = vtpm_manager_handle_vtpm_cmd(dmi_res, ord, command_buf, result_buf, is_priv, thread_name); + result_buf->is_owner = TRUE; } else { // This is not a VTPM Command at all. if (fw_tpm) { +#ifdef VTPM_STUBDOM + /* In stubdom mode, we allow the vtpm domains to send raw tpm commands down the pipe + * They can also just embed their tpm commands inside VTPM commands if they wish to*/ + + /* Stick the header back onto the raw command (minus the dmiid) */ + buffer_prepend_raw(command_buf, VTPM_COMMAND_HEADER_SIZE_CLT, cmd_header + sizeof(UINT32)); + status = VTPM_Handle_TPM_Command(dmi_res, command_buf, result_buf); +#else + /* In normal mode, this is used for the guest to forward a raw command to the vtpm process */ status = vtpm_manager_handle_tpm_cmd(fw_tx_ipc_h, fw_rx_ipc_h, dmi_res, cmd_header, command_buf, result_buf, thread_name); +#endif + result_buf->is_owner = TRUE; // This means calling the DMI failed, not that the cmd failed in the DMI // Since the return will be interpretted by a TPM app, all errors are IO_ERRORs to the app @@ -207,36 +233,42 @@ // ------------------- Respond to Sender ------------------ // Errors while handling responses jump here to reply with error messages - // NOTE: Currently there are no recoverable errors in multi-VM mode. If one - // is added to the code, this ifdef should be removed. - // Also note this is NOT referring to errors in commands, but rather - // this is about I/O errors and such. -#ifndef VTPM_MULTI_VM - abort_with_error: -#endif +abort_with_error: if (add_header) { // Prepend VTPM header with destination DM stamped out_param_size = buffer_len(result_buf); out_message_size = VTPM_COMMAND_HEADER_SIZE_CLT + out_param_size; - reply_size = VTPM_COMMAND_HEADER_SIZE_SRV + out_param_size; - out_message = (BYTE *) malloc (reply_size); - reply = out_message; + out_header = (BYTE *) malloc (VTPM_COMMAND_HEADER_SIZE_SRV); - BSG_PackList(out_message, 4, + BSG_PackList(out_header, 4, BSG_TYPE_UINT32, (BYTE *) &dmi, BSG_TPM_TAG, (BYTE *) &tag, BSG_TYPE_UINT32, (BYTE *) &out_message_size, BSG_TPM_RESULT, (BYTE *) &status); - if (buffer_len(result_buf) > 0) - memcpy(out_message + VTPM_COMMAND_HEADER_SIZE_SRV, result_buf->bytes, out_param_size); - //Note: Send message + dmi_id + buffer_prepend_raw(result_buf, VTPM_COMMAND_HEADER_SIZE_SRV, out_header); + free(out_header); } else { - reply = result_buf->bytes; - reply_size = buffer_len(result_buf); +#ifdef VTPM_STUBDOM + //In stubdom mode, we need to always prepend the dmiid so the raw command can be returned to the right domain + out_header = (BYTE*) malloc(sizeof(UINT32)); + BSG_PackList(out_header, 1, + BSG_TYPE_UINT32, (BYTE*) &dmi); + buffer_prepend_raw(result_buf, sizeof(UINT32), out_header); + free(out_header); +#endif } + reply = result_buf->bytes; + reply_size = buffer_len(result_buf); +#ifndef VTPM_STUBDOM size_write = vtpm_ipc_write(tx_ipc_h, (dmi_res ? dmi_res->tx_vtpm_ipc_h : NULL), reply, reply_size ); +#else + if(reply_size >= 4096) { + vtpmhandlerlogerror(VTPM_LOG_VTPM, "MESSAGE TOO BIG!!!"); + } + size_write = vtpm_ipc_write(tx_ipc_h, NULL, reply, reply_size ); +#endif if (size_write > 0) { vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT: 0x"); for (i=0; i < reply_size; i++) @@ -247,7 +279,6 @@ vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s had error writing to ipc. Aborting... \n", thread_name); goto abort_command; } - free(out_message); out_message=NULL; if (size_write < (int)reply_size) { vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s unable to write full command to ipc (%d/%d)\n", thread_name, size_write, reply_size); @@ -264,14 +295,22 @@ buffer_free(command_buf); // If we have a write lock, save the manager table - if ((tag == VTPM_TAG_REQ) && (ord & VTPM_PRIV_MASK) && + if (locked && (tag == VTPM_TAG_REQ) && (ord & VTPM_PRIV_MASK) && (VTPM_SaveManagerData() != TPM_SUCCESS) ) { vtpmhandlerlogerror(VTPM_LOG_VTPM, "ERROR: Unable to save manager data.\n"); } - vtpm_lock_unlock(); + if(locked) { + vtpm_lock_unlock(); + } add_header = TRUE; // Reset to the default } // End while(1) + + free(cmd_header); + free(command_buf); + free(result_buf); + + vtpmhandlerloginfo(VTPM_LOG_VTPM, "exiting\n", thread_name); } @@ -313,6 +352,21 @@ status = VTPM_Handle_Load_Migration_key(command_buf, result_buf); break; + case VTPM_ORD_GETNVMSIZE: + status = VTPM_Handle_Get_NVM_Size(dmi_res, + command_buf, + result_buf); + break; + case VTPM_ORD_SAVEKEY: + status = VTPM_Handle_Save_Key(dmi_res, + command_buf, + result_buf); + break; + case VTPM_ORD_LOADKEY: + status = VTPM_Handle_Load_Key(dmi_res, + command_buf, + result_buf); + break; default: // Privileged handlers can do maintanance @@ -350,6 +404,7 @@ return(status); } +#ifndef VTPM_STUBDOM ///////////////////////////////////////////////////////////////////// TPM_RESULT vtpm_manager_handle_tpm_cmd(vtpm_ipc_handle_t *tx_ipc_h, vtpm_ipc_handle_t *rx_ipc_h, @@ -485,4 +540,5 @@ return status; } +#endif diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/manager/vtpmd.c --- a/tools/vtpm_manager/manager/vtpmd.c Thu Jul 01 14:17:13 2010 -0400 +++ b/tools/vtpm_manager/manager/vtpmd.c Tue Jul 20 15:26:31 2010 -0400 @@ -51,21 +51,6 @@ #include "log.h" #include "vtpm_ipc.h" -#define TPM_EMULATOR_PATH "/usr/bin/vtpmd" - -#define VTPM_BE_FNAME "/dev/vtpm" -#define VTPM_DUMMY_TX_BE_FNAME "/var/vtpm/fifos/dummy_out.fifo" -#define VTPM_DUMMY_RX_BE_FNAME "/var/vtpm/fifos/dummy_in.fifo" -#define VTPM_TX_TPM_FNAME "/var/vtpm/fifos/tpm_cmd_to_%d.fifo" -#define VTPM_RX_TPM_FNAME "/var/vtpm/fifos/tpm_rsp_from_all.fifo" -#define VTPM_TX_VTPM_FNAME "/var/vtpm/fifos/vtpm_rsp_to_%d.fifo" -#define VTPM_RX_VTPM_FNAME "/var/vtpm/fifos/vtpm_cmd_from_all.fifo" -#define VTPM_TX_HP_FNAME "/var/vtpm/fifos/to_console.fifo" -#define VTPM_RX_HP_FNAME "/var/vtpm/fifos/from_console.fifo" - -#define VTPM_TYPE_PVM_STRING "pvm" -#define VTPM_TYPE_HVM_STRING "hvm" - struct vtpm_thread_params_s { vtpm_ipc_handle_t *tx_ipc_h; vtpm_ipc_handle_t *rx_ipc_h; @@ -76,33 +61,27 @@ char *thread_name; }; +#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; +#endif void *vtpm_manager_thread(void *arg_void) { - TPM_RESULT *status = (TPM_RESULT *) malloc(sizeof(TPM_RESULT) ); struct vtpm_thread_params_s *arg = (struct vtpm_thread_params_s *) arg_void; - *status = VTPM_Manager_Handler(arg->tx_ipc_h, arg->rx_ipc_h, + VTPM_Manager_Handler(arg->tx_ipc_h, arg->rx_ipc_h, arg->fw_tpm, arg->fw_tx_ipc_h, arg->fw_rx_ipc_h, arg->is_priv, arg->thread_name); - return (status); + return NULL; } - -void signal_handler(int reason) { - if (pthread_equal(pthread_self(), vtpm_globals->master_pid)) { - vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager shutting down for signal %d.\n", reason); - } else { - // For old Linux Thread machines, signals are delivered to each thread. Deal with them. - vtpmloginfo(VTPM_LOG_VTPM, "Child shutting down\n"); - pthread_exit(NULL); +void signal_handler(int signal) { + if (pthread_equal(pthread_self(), vtpm_globals->master_thread)) { + vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager shutting down for signal %s(%d). Please wait..\n", strsignal(signal), signal); + HANDLER_QUIT_FLAG = IPC_QUIT_FLAG = 1; } - - VTPM_Stop_Manager(); - exit(-1); } struct sigaction ctl_c_handler; @@ -110,6 +89,7 @@ TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res, BYTE vm_type, BYTE startup_mode) { TPM_RESULT status = TPM_SUCCESS; +#ifndef VTPM_STUBDOM int fh; char dmi_id_str[11]; // UINT32s are up to 10 digits + NULL char *tx_vtpm_name, *tx_tpm_name, *vm_type_string; @@ -136,8 +116,8 @@ sprintf(tx_tpm_name, VTPM_TX_TPM_FNAME, (uint32_t) dmi_res->dmi_id); sprintf(tx_vtpm_name, VTPM_TX_VTPM_FNAME, (uint32_t) dmi_res->dmi_id); - if ( (vtpm_ipc_init(dmi_res->tx_tpm_ipc_h, tx_tpm_name, O_WRONLY | O_NONBLOCK, TRUE) != 0) || - (vtpm_ipc_init(dmi_res->tx_vtpm_ipc_h, tx_vtpm_name, O_WRONLY, TRUE) != 0) ) { //FIXME: O_NONBLOCK? + if ( (vtpm_ipc_init(dmi_res->tx_tpm_ipc_h, tx_tpm_name, O_WRONLY | O_NONBLOCK, TRUE, FALSE) != 0) || + (vtpm_ipc_init(dmi_res->tx_vtpm_ipc_h, tx_vtpm_name, O_WRONLY, TRUE, FALSE) != 0) ) { //FIXME: O_NONBLOCK? status = TPM_IOERROR; goto abort_egress; } @@ -202,14 +182,17 @@ } // If DMI = VTPM_CTL_DM status = TPM_SUCCESS; +#endif abort_egress: + //FIXME: Everything should be freed here return (status); } TPM_RESULT VTPM_Close_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res) { TPM_RESULT status = TPM_SUCCESS; +#ifndef VTPM_STUBDOM if (vtpm_globals->connected_dmis == 0) { // No more DMI's connected. Close fifo to prevent a broken pipe. // This is hackish. Need to think of another way. @@ -223,6 +206,8 @@ free(dmi_res->tx_tpm_ipc_h->name); free(dmi_res->tx_vtpm_ipc_h->name); + free(dmi_res->tx_tpm_ipc_h); + free(dmi_res->tx_vtpm_ipc_h); #ifndef MANUAL_DM_LAUNCH if (dmi_res->dmi_id != VTPM_CTL_DM) { @@ -242,14 +227,18 @@ #endif } //endif ! dom0 +#endif return status; } int main(int argc, char **argv) { - vtpm_ipc_handle_t *tx_be_ipc_h, *rx_be_ipc_h, rx_tpm_ipc_h, rx_vtpm_ipc_h, tx_hp_ipc_h, rx_hp_ipc_h; - struct vtpm_thread_params_s be_thread_params, dmi_thread_params, hp_thread_params; - pthread_t be_thread, dmi_thread, hp_thread; + vtpm_ipc_handle_t *tx_be_ipc_h, *rx_be_ipc_h, tx_hp_ipc_h, rx_hp_ipc_h; + struct vtpm_thread_params_s be_thread_params, hp_thread_params; +#ifndef VTPM_STUBDOM + vtpm_ipc_handle_t rx_tpm_ipc_h, rx_vtpm_ipc_h; + struct vtpm_thread_params_s dmi_thread_params; +#endif #ifdef DUMMY_BACKEND vtpm_ipc_handle_t tx_dummy_ipc_h, rx_dummy_ipc_h; @@ -258,7 +247,7 @@ #endif vtpmloginfo(VTPM_LOG_VTPM, "Starting VTPM.\n"); - + // -------------------- Initialize Manager ----------------- if (VTPM_Init_Manager() != TPM_SUCCESS) { vtpmlogerror(VTPM_LOG_VTPM, "Closing vtpmd due to error during startup.\n"); @@ -270,22 +259,22 @@ sigemptyset(&ctl_c_handler.sa_mask); ctl_c_handler.sa_flags = 0; - if (sigaction(SIGINT, &ctl_c_handler, NULL) == -1) + if ((sigaction(SIGINT, &ctl_c_handler, NULL) == -1) + || (sigaction(SIGQUIT, &ctl_c_handler, NULL) == -1) + || (sigaction(SIGHUP, &ctl_c_handler, NULL) == -1) ) // For easier debugging with gdb + { vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGINT handler. Ctl+break will not stop manager gently.\n"); + } - // For easier debuggin with gdb - if (sigaction(SIGHUP, &ctl_c_handler, NULL) == -1) - vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGHUP handler. Ctl+break will not stop manager gently.\n"); - + //Block all signals for child threads sigset_t sig_mask; - sigemptyset(&sig_mask); - sigaddset(&sig_mask, SIGPIPE); - sigprocmask(SIG_BLOCK, &sig_mask, NULL); + sigfillset(&sig_mask); + pthread_sigmask(SIG_SETMASK, &sig_mask, NULL); // ------------------- Set up file ipc structures ---------- #ifdef DUMMY_BACKEND - if ( (vtpm_ipc_init(&tx_dummy_ipc_h, VTPM_DUMMY_TX_BE_FNAME, O_RDWR, TRUE) != 0) || - (vtpm_ipc_init(&rx_dummy_ipc_h, VTPM_DUMMY_RX_BE_FNAME, O_RDWR, TRUE) != 0) ) { + if ( (vtpm_ipc_init(&tx_dummy_ipc_h, VTPM_DUMMY_TX_BE_FNAME, O_RDWR, TRUE, FALSE) != 0) || + (vtpm_ipc_init(&rx_dummy_ipc_h, VTPM_DUMMY_RX_BE_FNAME, O_RDWR, TRUE, FALSE) != 0) ) { vtpmlogerror(VTPM_LOG_VTPM, "Unable to create Dummy BE FIFOs.\n"); exit(-1); @@ -294,21 +283,26 @@ tx_be_ipc_h = &tx_dummy_ipc_h; rx_be_ipc_h = &rx_dummy_ipc_h; #else - vtpm_ipc_init(&real_be_ipc_h, VTPM_BE_FNAME, O_RDWR, FALSE); + vtpm_ipc_init(&real_be_ipc_h, VTPM_BE_FNAME, O_RDWR, FALSE, FALSE); tx_be_ipc_h = &real_be_ipc_h; rx_be_ipc_h = &real_be_ipc_h; #endif - if ( (vtpm_ipc_init(&rx_tpm_ipc_h, VTPM_RX_TPM_FNAME, O_RDONLY, TRUE) != 0) || - (vtpm_ipc_init(&rx_vtpm_ipc_h, VTPM_RX_VTPM_FNAME, O_RDWR, TRUE) != 0) || //FIXME: O_RDONLY? - (vtpm_ipc_init(&tx_hp_ipc_h, VTPM_TX_HP_FNAME, O_RDWR, TRUE) != 0) || - (vtpm_ipc_init(&rx_hp_ipc_h, VTPM_RX_HP_FNAME, O_RDWR, TRUE) != 0) ) { + if ( +#ifndef VTPM_STUBDOM + (vtpm_ipc_init(&rx_tpm_ipc_h, VTPM_RX_TPM_FNAME, O_RDONLY, TRUE, FALSE) != 0) || + (vtpm_ipc_init(&rx_vtpm_ipc_h, VTPM_RX_VTPM_FNAME, O_RDWR, TRUE, FALSE) != 0) || //FIXME: O_RDONLY? +#endif + (vtpm_ipc_init(&tx_hp_ipc_h, VTPM_TX_HP_FNAME, O_RDWR, TRUE, TRUE) != 0) || + (vtpm_ipc_init(&rx_hp_ipc_h, VTPM_RX_HP_FNAME, O_RDWR, TRUE, TRUE) != 0) ) { vtpmlogerror(VTPM_LOG_VTPM, "Unable to create initial FIFOs.\n"); exit(-1); } +#ifndef VTPM_STUBDOM g_rx_tpm_ipc_h = &rx_tpm_ipc_h; +#endif // -------------------- Set up thread params ------------- @@ -316,10 +310,15 @@ be_thread_params.rx_ipc_h = rx_be_ipc_h; be_thread_params.fw_tpm = TRUE; be_thread_params.fw_tx_ipc_h = NULL; +#ifndef VTPM_STUBDOM be_thread_params.fw_rx_ipc_h = &rx_tpm_ipc_h; +#else + be_thread_params.fw_rx_ipc_h = NULL; +#endif be_thread_params.is_priv = FALSE; be_thread_params.thread_name = "Backend Listener"; +#ifndef VTPM_STUBDOM dmi_thread_params.tx_ipc_h = NULL; dmi_thread_params.rx_ipc_h = &rx_vtpm_ipc_h; dmi_thread_params.fw_tpm = FALSE; @@ -327,6 +326,7 @@ dmi_thread_params.fw_rx_ipc_h = NULL; dmi_thread_params.is_priv = FALSE; dmi_thread_params.thread_name = "VTPM Listener"; +#endif hp_thread_params.tx_ipc_h = &tx_hp_ipc_h; hp_thread_params.rx_ipc_h = &rx_hp_ipc_h; @@ -340,30 +340,39 @@ vtpm_lock_init(); - vtpm_globals->master_pid = pthread_self(); + vtpm_globals->master_thread = pthread_self(); + - if (pthread_create(&be_thread, NULL, vtpm_manager_thread, &be_thread_params) != 0) { + if (pthread_create(&vtpm_globals->be_thread, NULL, vtpm_manager_thread, &be_thread_params) != 0) { vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch BE Thread.\n"); exit(-1); } - if (pthread_create(&dmi_thread, NULL, vtpm_manager_thread, &dmi_thread_params) != 0) { +#ifndef VTPM_STUBDOM + if (pthread_create(&vtpm_globals->dmi_thread, NULL, vtpm_manager_thread, &dmi_thread_params) != 0) { vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch DMI Thread.\n"); exit(-1); } - +#endif - if (pthread_create(&hp_thread, NULL, vtpm_manager_thread, &hp_thread_params) != 0) { + if (pthread_create(&vtpm_globals->hp_thread, NULL, vtpm_manager_thread, &hp_thread_params) != 0) { vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch HP Thread.\n"); exit(-1); } + //Turn signals back on for the master thread only + sigemptyset(&sig_mask); + sigaddset(&sig_mask, SIGPIPE); + pthread_sigmask(SIG_SETMASK, &sig_mask, NULL); + //Join the other threads until exit time. - pthread_join(be_thread, NULL); - pthread_join(dmi_thread, NULL); - pthread_join(hp_thread, NULL); + pthread_join(vtpm_globals->be_thread, NULL); +#ifndef VTPM_STUBDOM + pthread_join(vtpm_globals->dmi_thread, NULL); +#endif + pthread_join(vtpm_globals->hp_thread, NULL); - vtpmlogerror(VTPM_LOG_VTPM, "VTPM Manager shut down unexpectedly.\n"); + vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager shutting down...\n"); VTPM_Stop_Manager(); vtpm_lock_destroy(); diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/manager/vtpmpriv.h --- a/tools/vtpm_manager/manager/vtpmpriv.h Thu Jul 01 14:17:13 2010 -0400 +++ b/tools/vtpm_manager/manager/vtpmpriv.h Tue Jul 20 15:26:31 2010 -0400 @@ -40,6 +40,8 @@ #ifndef __VTPMPRIV_H__ #define __VTPMPRIV_H__ +#include + #include "vtpm_manager.h" #include "tcg.h" #include "tcs.h" @@ -54,16 +56,19 @@ #define DMI_NVM_FILE "/var/vtpm/vtpm_dm_%d.data" #define VTPM_CTL_DM 0 +extern volatile sig_atomic_t HANDLER_QUIT_FLAG; + // ------------------------ Private Structures ----------------------- typedef struct VTPM_DMI_RESOURCE_T { +#ifndef VTPM_STUBDOM // I/O info for Manager to talk to DMI's and controllers vtpm_ipc_handle_t *tx_vtpm_ipc_h; // TX VTPM Results to DMI vtpm_ipc_handle_t *rx_vtpm_ipc_h; // RX VTPM Commands from DMI vtpm_ipc_handle_t *tx_tpm_ipc_h; // TX TPM Commands to DMI vtpm_ipc_handle_t *rx_tpm_ipc_h; // RX TPM Results from DMI + + pid_t dmi_pid; -#ifndef VTPM_MULTI_VM - pid_t dmi_pid; #endif // Non-persistent Information @@ -77,6 +82,7 @@ BYTE dmi_type; TPM_DIGEST NVM_measurement; // Equal to the SHA1 of the blob TPM_DIGEST DMI_measurement; // Correct measurement of the owning DMI + } VTPM_DMI_RESOURCE; typedef struct tdVTPM_MIGKEY_LIST { @@ -89,8 +95,11 @@ typedef struct tdVTPM_GLOBALS { // Non-persistent data -#ifndef VTPM_MULTI_VM - pid_t master_pid; + pthread_t master_thread; + pthread_t be_thread; + pthread_t hp_thread; +#ifndef VTPM_STUBDOM + pthread_t dmi_thread; #endif int connected_dmis; // To close guest_rx when no dmis are connected @@ -143,6 +152,11 @@ const buffer_t *inbuf, buffer_t *outbuf); +TPM_RESULT VTPM_Handle_Get_NVM_Size( VTPM_DMI_RESOURCE *myDMI, + const buffer_t *inbuf, + buffer_t *outbuf); + + TPM_RESULT VTPM_Handle_TPM_Command( VTPM_DMI_RESOURCE *dmi, buffer_t *inbuf, buffer_t *outbuf); @@ -173,6 +187,9 @@ TPM_RESULT close_dmi(VTPM_DMI_RESOURCE *dmi_res); TPM_RESULT init_dmi(UINT32 dmi_id, BYTE type, VTPM_DMI_RESOURCE **dmi_res); +/* Free's dmi_res and all of it's resources */ +void free_dmi(VTPM_DMI_RESOURCE *dmi_res); + TPM_RESULT envelope_encrypt(const buffer_t *inbuf, CRYPTO_INFO *asymkey, buffer_t *sealed_data); diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/manager/vtsp.c --- a/tools/vtpm_manager/manager/vtsp.c Thu Jul 01 14:17:13 2010 -0400 +++ b/tools/vtpm_manager/manager/vtsp.c Tue Jul 20 15:26:31 2010 -0400 @@ -567,8 +567,7 @@ osapSharedSecret, auth, 0) ); // Unpack/return key structure - TPMTRYRETURN(buffer_init(pubKeyBuf, 0, 0) ); - TPMTRYRETURN(buffer_append_raw(pubKeyBuf, newKeyText.size, newKeyText.data) ); + TPMTRYRETURN(buffer_init(pubKeyBuf, newKeyText.size, newKeyText.data) ); goto egress; @@ -664,6 +663,7 @@ // Destroy rsaKeyParms BSG_Destroy(BSG_TPM_RSA_KEY_PARMS, &rsaKeyParms); + BSG_Destroy(BSG_TPM_KEY, &newKey); // Set encryption scheme cryptoinfo->encScheme = CRYPTO_ES_RSAESOAEP_SHA1_MGF1; @@ -733,8 +733,7 @@ hContext) ); // Unpack/return key structure - TPMTRYRETURN(buffer_init(clear_data, 0, 0)); - TPMTRYRETURN(buffer_append_raw (clear_data, clear_data_size, clear_data_text) ); + TPMTRYRETURN(buffer_init(clear_data, clear_data_size, clear_data_text) ); goto egress; @@ -793,8 +792,7 @@ vtpmlogerror(VTPM_LOG_VTSP, "Enc buffer just overflowed.\n"); } - buffer_init(outData, 0, NULL); - buffer_append_raw(outData, out_tmp_size, out_tmp); + buffer_init(outData, out_tmp_size, out_tmp); vtpmloginfo(VTPM_LOG_TXDATA, "Bind Generated[%d] = 0x", out_tmp_size); for(i = 0 ; i < out_tmp_size ; i++) { diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/migration/vtpm_manager_if.c --- a/tools/vtpm_manager/migration/vtpm_manager_if.c Thu Jul 01 14:17:13 2010 -0400 +++ b/tools/vtpm_manager/migration/vtpm_manager_if.c Tue Jul 20 15:26:31 2010 -0400 @@ -50,15 +50,12 @@ #include "vtpm_migrator.h" #include "vtpm_manager.h" -#define VTPM_TX_HP_FNAME "/var/vtpm/fifos/from_console.fifo" -#define VTPM_RX_HP_FNAME "/var/vtpm/fifos/to_console.fifo" - static vtpm_ipc_handle_t tx_ipc_h, rx_ipc_h; TPM_RESULT vtpm_manager_open(){ - if ( (vtpm_ipc_init(&tx_ipc_h, VTPM_TX_HP_FNAME, O_RDWR, TRUE) != 0) || //FIXME: wronly - (vtpm_ipc_init(&rx_ipc_h, VTPM_RX_HP_FNAME, O_RDWR, TRUE) != 0) ) { //FIXME: rdonly + if ( (vtpm_ipc_init(&tx_ipc_h, VTPM_TX_HP_FNAME, O_RDWR, TRUE, TRUE) != 0) || //FIXME: wronly + (vtpm_ipc_init(&rx_ipc_h, VTPM_RX_HP_FNAME, O_RDWR, TRUE, TRUE) != 0) ) { //FIXME: rdonly vtpmlogerror(VTPM_LOG_VTPM, "Unable to connect to vtpm_manager.\n"); return TPM_IOERROR; } diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/tcs/contextmgr.c --- a/tools/vtpm_manager/tcs/contextmgr.c Thu Jul 01 14:17:13 2010 -0400 +++ b/tools/vtpm_manager/tcs/contextmgr.c Tue Jul 20 15:26:31 2010 -0400 @@ -195,6 +195,7 @@ BOOL FreeHandleList( CONTEXT_HANDLE* pContextHandle) { // in HANDLE_LIST* pCurrentHandle; + HANDLE_LIST* pNext; BOOL returncode = TRUE; vtpmloginfo(VTPM_LOG_TCS_DEEP, "Freeing all handles for context\n"); @@ -205,6 +206,7 @@ pCurrentHandle = pContextHandle->pHandleList; while (pCurrentHandle != NULL) { + pNext = pCurrentHandle->pNextHandle; switch (pCurrentHandle->type) { case TPM_RT_KEY: returncode = returncode && !TCSP_EvictKey(pContextHandle->handle, pCurrentHandle->handle); @@ -216,7 +218,7 @@ returncode = FALSE; } - pCurrentHandle = pCurrentHandle->pNextHandle; + pCurrentHandle = pNext; } diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/tcs/tcs.c --- a/tools/vtpm_manager/tcs/tcs.c Thu Jul 01 14:17:13 2010 -0400 +++ b/tools/vtpm_manager/tcs/tcs.c Tue Jul 20 15:26:31 2010 -0400 @@ -113,14 +113,13 @@ TCS_CONTEXT_HANDLE *hContext; // Close all the TCS contexts. TCS should evict keys based on this - if (hashtable_count(context_ht) > 0) { + while (hashtable_count(context_ht) > 0) { context_itr = hashtable_iterator(context_ht); - do { - hContext = (TCS_CONTEXT_HANDLE *) hashtable_iterator_key(context_itr); - if (TCS_CloseContext(*hContext) != TPM_SUCCESS) - vtpmlogerror(VTPM_LOG_TCS, "Failed to close context %d properly.\n", *hContext); + + hContext = (TCS_CONTEXT_HANDLE *) hashtable_iterator_key(context_itr); + if (TCS_CloseContext(*hContext) != TPM_SUCCESS) + vtpmlogerror(VTPM_LOG_TCS, "Failed to close context %d properly.\n", *hContext); - } while (hashtable_iterator_advance(context_itr)); free(context_itr); } hashtable_destroy(context_ht, 1); @@ -534,6 +533,10 @@ BSG_TYPE_UINT32, &handle); // fill paramSize again as we now have the correct size BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2); + + if (!DeleteHandleFromList(hContext, handle)) { + vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n"); + } // call the TPM driver if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength)) @@ -545,9 +548,6 @@ BSG_TYPE_UINT32, ¶mSize, BSG_TPM_COMMAND_CODE, &returnCode); - if (!DeleteHandleFromList(hContext, handle)) - vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n"); - if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_COMMAND) { // Print debug info @@ -882,6 +882,7 @@ memcpy(*prgbKey, tempBuf, *pcKeySize); + BSG_Destroy(BSG_TPM_KEY, &wrappedKey); vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n", paramSize); } else vtpmlogerror(VTPM_LOG_TCS, "TCSP_CreateWrapKey Failed with return code %s\n", tpm_get_error_name(returnCode)); @@ -980,6 +981,10 @@ BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2); vtpmloginfo(VTPM_LOG_TCS_DEEP, "Sending paramSize = %d\n", InLength); + + if (!DeleteHandleFromList(hContext, hKey)) { + vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n"); + } // call the TPM driver if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength)) == TDDL_SUCCESS) { @@ -989,10 +994,6 @@ BSG_TYPE_UINT32, ¶mSize, BSG_TPM_COMMAND_CODE, &returnCode); - if (!DeleteHandleFromList(hContext, hKey)) { - vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n"); - } - if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_COMMAND) { vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n", paramSize); } else { @@ -1019,7 +1020,7 @@ TDDL_UINT32 OutLength = TCPA_MAX_BUFFER_LENGTH; // check input params - if (bytesRequested == NULL || *randomBytes == NULL){ + if (bytesRequested == NULL || randomBytes == NULL){ return TPM_BAD_PARAMETER; } diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/tcs/tpmddl.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/vtpm_manager/tcs/tpmddl.c Tue Jul 20 15:26:31 2010 -0400 @@ -0,0 +1,93 @@ +#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) +{ + TPM_RESULT status; + + TPM_TAG tag = TPM_TAG_RQU_COMMAND; + UINT32 paramsize = 22; + UINT32 outsize; + TPM_COMMAND_CODE ord = TPM_ORD_GetCapability; + UINT32 subcapsize = 4; + + BYTE inbuf[TCPA_MAX_BUFFER_LENGTH]; + BYTE outbuf[TCPA_MAX_BUFFER_LENGTH]; + + int offset; + + BSG_PackList(inbuf, 6, + BSG_TPM_TAG, &(tag), + BSG_TYPE_UINT32, &(paramsize), + BSG_TPM_COMMAND_CODE, &(ord), + BSG_TYPE_UINT32, &(cap), + BSG_TYPE_UINT32, &(subcapsize), + BSG_TYPE_UINT32, &(sub) + ); + + //Send the command, get the response + TPMTRYRETURN(TDDL_TransmitData( inbuf, paramsize, outbuf, &outsize)); + + offset = BSG_UnpackList(outbuf, 4, + BSG_TPM_TAG, &(tag), + BSG_TYPE_UINT32, &(paramsize), + BSG_TPM_RESULT, &(status), + BSG_TYPE_UINT32, size + ); + if (status != TPM_SUCCESS || tag != TPM_TAG_RSP_COMMAND) { + return status; + } + if(*size >= TCPA_MAX_BUFFER_LENGTH - offset) { + return TPM_FAIL; + } + memcpy(buffer, outbuf + offset, *size); + +abort_egress: + return status; +} + +TDDL_RESULT TDDL_FlushSpecific(TDDL_UINT32 handle, TDDL_UINT32 res) { + /* FIXME: Add code here to check if TPM_FlushSpecific is not supported (on 1.1 only TPMS?) + * If this is the case then we need to use TPM_EvictKey for key handles + * and TPM_Terminate_Handle/TPM_Reset for auth handles */ + TPM_RESULT status; + + TPM_TAG tag = TPM_TAG_RQU_COMMAND; + UINT32 paramsize = 18; + TPM_COMMAND_CODE ord = TPM_ORD_FlushSpecific; + + BYTE inbuf[TCPA_MAX_BUFFER_LENGTH]; + BYTE outbuf[TCPA_MAX_BUFFER_LENGTH]; + UINT32 outsize; + + int offset; + + BSG_PackList(inbuf, 5, + BSG_TPM_TAG, &(tag), + BSG_TYPE_UINT32, &(paramsize), + BSG_TPM_COMMAND_CODE, &(ord), + BSG_TPM_HANDLE, &(handle), + BSG_TPM_RESOURCE_TYPE, &(res) + ); + + //Send command + TPMTRYRETURN(TDDL_TransmitData( inbuf, paramsize, outbuf, &outsize )); + + offset = BSG_UnpackList(outbuf, 4, + BSG_TPM_TAG, &(tag), + BSG_TYPE_UINT32, &(paramsize), + BSG_TPM_RESULT, &(status) + ); + +abort_egress: + return status; + +} diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/tcs/tpmddl.h --- a/tools/vtpm_manager/tcs/tpmddl.h Thu Jul 01 14:17:13 2010 -0400 +++ b/tools/vtpm_manager/tcs/tpmddl.h Tue Jul 20 15:26:31 2010 -0400 @@ -66,4 +66,7 @@ TDDL_BYTE* buffer, TDDL_UINT32* size); +TDDL_RESULT TDDL_FlushSpecific(TDDL_UINT32 handle, + TDDL_UINT32 res); + #endif // __TPMDDL_H__ diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/tcs/transmit.c --- a/tools/vtpm_manager/tcs/transmit.c Thu Jul 01 14:17:13 2010 -0400 +++ b/tools/vtpm_manager/tcs/transmit.c Tue Jul 20 15:26:31 2010 -0400 @@ -117,7 +117,7 @@ g_tx_fd = open (TPM_TX_FNAME, O_RDWR); if (g_tx_fd < 0) { - vtpmlogerror(VTPM_LOG_TXDATA, "TPM open failed"); + vtpmlogerror(VTPM_LOG_TXDATA, "TPM open failed\n"); return TPM_IOERROR; } diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/util/buffer.c --- a/tools/vtpm_manager/util/buffer.c Thu Jul 01 14:17:13 2010 -0400 +++ b/tools/vtpm_manager/util/buffer.c Tue Jul 20 15:26:31 2010 -0400 @@ -39,6 +39,7 @@ #include #include "tcg.h" +#include "log.h" #include "bsg.h" #include "buffer.h" @@ -51,6 +52,7 @@ TPM_RESULT buffer_init (buffer_t * buf, tpm_size_t initsize, const BYTE* initval) { if (initsize == 0) { memset(buf, 0, sizeof(*buf)); + buf->bytes = NULL; return TPM_SUCCESS; } @@ -62,8 +64,11 @@ buf->size = initsize; buf->alloc_size = initsize; - if (initval) + if (initval) { memcpy (buf->bytes, initval, initsize); + } else { + memset(buf->bytes, 0, initsize); + } buf->is_owner = TRUE; @@ -190,6 +195,30 @@ return status; } +TPM_RESULT buffer_prepend_raw(buffer_t * buf, tpm_size_t len, const BYTE* bytes) { + TPM_RESULT status = TPM_SUCCESS; + long i; + + if (buf->alloc_size < buf->size + len) { + TPMTRYRETURN( buffer_priv_realloc (buf, buf->size + len) ); + } + + if(buf->size > 0) { + memmove(buf->bytes + len, buf->bytes, buf->size); + } + memcpy(buf->bytes, bytes, len); + + buf->size += len; + + goto egress; + + abort_egress: + + egress: + + return status; +} + tpm_size_t buffer_len (const buffer_t* buf) { return buf->size; } @@ -199,7 +228,6 @@ free (buf->bytes); buf->bytes = NULL; buf->size = buf->alloc_size = 0; - } return TPM_SUCCESS; diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/util/buffer.h --- a/tools/vtpm_manager/util/buffer.h Thu Jul 01 14:17:13 2010 -0400 +++ b/tools/vtpm_manager/util/buffer.h Tue Jul 20 15:26:31 2010 -0400 @@ -92,4 +92,6 @@ TPM_RESULT buffer_append_raw (buffer_t * buf, tpm_size_t len, const BYTE* bytes); +TPM_RESULT buffer_prepend_raw(buffer_t * buf, tpm_size_t len, const BYTE* bytes); + #endif // _TOOLS_H_ diff -r 7c44921abfde -r 5793f5c2d67d tools/vtpm_manager/util/tcg.h --- a/tools/vtpm_manager/util/tcg.h Thu Jul 01 14:17:13 2010 -0400 +++ b/tools/vtpm_manager/util/tcg.h Tue Jul 20 15:26:31 2010 -0400 @@ -197,6 +197,7 @@ UINT32 size; BYTE * data; } pack_buf_t; +#define NULL_PACK_BUF {0,0} typedef struct pack_constbuf_t { UINT32 size; @@ -295,6 +296,35 @@ #define TPM_ORD_LoadKeyContext (181UL + TPM_PROTECTED_ORDINAL) #define TPM_ORD_SaveAuthContext (182UL + TPM_PROTECTED_ORDINAL) #define TPM_ORD_LoadAuthContext (183UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_SaveContext (184UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_LoadContext (185UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_FlushSpecific (186UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_PCR_Reset (200UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_NV_DefineSpace (204UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_NV_WriteValue (205UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_NV_WriteValueAuth (206UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_NV_ReadValue (207UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_NV_ReadValueAuth (208UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_Delegate_UpdateVerification (209UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_Delegate_Manage (210UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_Delegate_CreateKeyDelegation (212UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_Delegate_CreateOwnerDelegation (213UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_Delegate_VerifyDelegation (214UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_Delegate_LoadOwnerDelegation (216UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_Delegate_ReadAuth (217UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_Delegate_ReadTable (219UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_CreateCounter (220UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_IncrementCounter (221UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_ReadCounter (222UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_ReleaseCounter (223UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_ReleaseCounterOwner (224UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_EstablishTransport (230UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_ExecuteTransport (231UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_ReleaseTransportSigned (232UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_GetTicks (241UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_TickStampBlob (242UL + TPM_PROTECTED_ORDINAL) +#define TPM_ORD_MAX (256UL + TPM_PROTECTED_ORDINAL) + #define TSC_ORD_PhysicalPresence (10UL + TPM_CONNECTION_ORDINAL) @@ -419,8 +449,16 @@ /// TPM_ResourceTypes #define TPM_RT_KEY 0x00000001 #define TPM_RT_AUTH 0x00000002 +#define TPM_RT_HASH 0x00000003 #define TPM_RT_TRANS 0x00000004 #define TPM_RT_CONTEXT 0x00000005 +#define TPM_RT_COUNTER 0x00000006 +#define TPM_RT_DELEGATE 0x00000007 +#define TPM_RT_DAA_TPM 0x00000008 +#define TPM_RT_DAA_V0 0x00000009 +#define TPM_RT_DAA_V1 0x0000000A + + // TPM_PROTOCOL_ID values #define TPM_PID_OIAP 0x0001 @@ -447,6 +485,64 @@ #define TPM_SS_RSASSAPKCS1v15_SHA1 0x0002 #define TPM_SS_RSASSAPKCS1v15_DER 0x0003 +/* + * TPM_CAPABILITY_AREA Values for TPM_GetCapability ([TPM_Part2], Section 21.1) + */ +#define TPM_CAP_ORD 0x00000001 +#define TPM_CAP_ALG 0x00000002 +#define TPM_CAP_PID 0x00000003 +#define TPM_CAP_FLAG 0x00000004 +#define TPM_CAP_PROPERTY 0x00000005 +#define TPM_CAP_VERSION 0x00000006 +#define TPM_CAP_KEY_HANDLE 0x00000007 +#define TPM_CAP_CHECK_LOADED 0x00000008 +#define TPM_CAP_SYM_MODE 0x00000009 +#define TPM_CAP_KEY_STATUS 0x0000000C +#define TPM_CAP_NV_LIST 0x0000000D +#define TPM_CAP_MFR 0x00000010 +#define TPM_CAP_NV_INDEX 0x00000011 +#define TPM_CAP_TRANS_ALG 0x00000012 +#define TPM_CAP_HANDLE 0x00000014 +#define TPM_CAP_TRANS_ES 0x00000015 +#define TPM_CAP_AUTH_ENCRYPT 0x00000017 +#define TPM_CAP_SELECT_SIZE 0x00000018 +#define TPM_CAP_DA_LOGIC 0x00000019 +#define TPM_CAP_VERSION_VAL 0x0000001A + +/* subCap definitions ([TPM_Part2], Section 21.2) */ +#define TPM_CAP_PROP_PCR 0x00000101 +#define TPM_CAP_PROP_DIR 0x00000102 +#define TPM_CAP_PROP_MANUFACTURER 0x00000103 +#define TPM_CAP_PROP_KEYS 0x00000104 +#define TPM_CAP_PROP_MIN_COUNTER 0x00000107 +#define TPM_CAP_FLAG_PERMANENT 0x00000108 +#define TPM_CAP_FLAG_VOLATILE 0x00000109 +#define TPM_CAP_PROP_AUTHSESS 0x0000010A +#define TPM_CAP_PROP_TRANSESS 0x0000010B +#define TPM_CAP_PROP_COUNTERS 0x0000010C +#define TPM_CAP_PROP_MAX_AUTHSESS 0x0000010D +#define TPM_CAP_PROP_MAX_TRANSESS 0x0000010E +#define TPM_CAP_PROP_MAX_COUNTERS 0x0000010F +#define TPM_CAP_PROP_MAX_KEYS 0x00000110 +#define TPM_CAP_PROP_OWNER 0x00000111 +#define TPM_CAP_PROP_CONTEXT 0x00000112 +#define TPM_CAP_PROP_MAX_CONTEXT 0x00000113 +#define TPM_CAP_PROP_FAMILYROWS 0x00000114 +#define TPM_CAP_PROP_TIS_TIMEOUT 0x00000115 +#define TPM_CAP_PROP_STARTUP_EFFECT 0x00000116 +#define TPM_CAP_PROP_DELEGATE_ROW 0x00000117 +#define TPM_CAP_PROP_MAX_DAASESS 0x00000119 +#define TPM_CAP_PROP_DAASESS 0x0000011A +#define TPM_CAP_PROP_CONTEXT_DIST 0x0000011B +#define TPM_CAP_PROP_DAA_INTERRUPT 0x0000011C +#define TPM_CAP_PROP_SESSIONS 0x0000011D +#define TPM_CAP_PROP_MAX_SESSIONS 0x0000011E +#define TPM_CAP_PROP_CMK_RESTRICTION 0x0000011F +#define TPM_CAP_PROP_DURATION 0x00000120 +#define TPM_CAP_PROP_ACTIVE_COUNTER 0x00000122 +#define TPM_CAP_PROP_MAX_NV_AVAILABLE 0x00000123 +#define TPM_CAP_PROP_INPUT_BUFFER 0x00000124 + // TPM_KEY_USAGE values #define TPM_KEY_EK 0x0000 #define TPM_KEY_SIGNING 0x0010