* [PATCH 1/7] vtpm Mini-Os domain: vtpm_managerd
@ 2010-08-25 15:05 Matthew Fioravante
0 siblings, 0 replies; only message in thread
From: Matthew Fioravante @ 2010-08-25 15:05 UTC (permalink / raw)
To: xen-devel@lists.xensource.com
[-- Attachment #1.1.1: Type: text/plain, Size: 1651 bytes --]
Signed-off-by: Matthew Fioravante <Matthew.Fioravante@jhuapl.edu>
The following is a major patch to the vtpm_manager. I apologize in
advance for submitting such a large patch. Let me know if you'd like me
to break it up.
This patch contains the following:
-A new routine to flush all handles from the tpm everytime vtpm_managerd
is started. Previously if the manager would crash it would leave stale
keys and auth handles in the tpm. After restarting the manager several
times and letting it crash, the tpm would run out of memory and the
manager would fail to start with a TPM_NO_SPACE error.
-Several memory errors fixed such as uninitialized reads and memory leaks.
-Fixed the signal handler to work with blocking IO and threads
correctly. Previously the manager would not shutdown correctly when you
tried to Ctrl+C close it on 64 bit.
-Removal of VTPM_MULTI_VM #defines. These were supposed to be a partial
implementation for a way to run vtpms in multiple domains but it was
never finished. It doesn't appear there has been any development on this
for several years. Since vtpm-stubdom performs this functionality I
removed these #defines and #ifdefs to make the code a little cleaner.
-New vTPM ordinals: VTPM_SAVE_KEY and VTPM_LOAD_KEY. The vtpm domains
encrypt their persistent state themselves, they only request the manager
to store the key.
-#define VTPM_STUBDOM will build the manager in stubdom mode. The
manager can only work in either vtpm-stubdom or vtpmd mode. You cannot
combine them. Clearing out the manager state will be required.
# rm /var/vtpm/VTPM /var/vtpm/vtpm_dm*
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.1.2: 1-manager.patch --]
[-- Type: text/x-patch; name="1-manager.patch", Size: 70834 bytes --]
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 <openssl/rand.h>
#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 <fcntl.h>
#include <unistd.h>
#include <string.h>
-
#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 <signal.h>
+
#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 <unistd.h>
#include <string.h>
#include <errno.h>
+#include <signal.h>
#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; i<size_read; i++)
vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
} else {
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s can't read from ipc. Errono = %d. Aborting... \n", thread_name, errno);
+ if (!IPC_QUIT_FLAG) {
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s can't read from ipc. Errono = %d. Aborting... \n", thread_name, errno);
+ }
goto abort_command;
}
@@ -155,6 +167,7 @@
vtpmhandlerlogerror(VTPM_LOG_VTPM, "Failed to setup buffers. Aborting...\n");
goto abort_command;
}
+ result_buf->is_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 <signal.h>
+
#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 <string.h>
+#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 <sys/param.h>
#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
[-- Attachment #1.2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 2518 bytes --]
[-- Attachment #2: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2010-08-25 15:05 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-08-25 15:05 [PATCH 1/7] vtpm Mini-Os domain: vtpm_managerd Matthew Fioravante
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).