aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2005-12-30 11:31:12 +0100
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2005-12-30 11:31:12 +0100
commitaafd5e14e1c1f65d237574655668cefa3db32154 (patch)
treeff10da25b91ea47f59d760788aee14ba0850f29d
parentfc41b5c1fdbe11dd608c8f8cf1880e30c1233668 (diff)
downloadxen-aafd5e14e1c1f65d237574655668cefa3db32154.tar.gz
xen-aafd5e14e1c1f65d237574655668cefa3db32154.tar.bz2
xen-aafd5e14e1c1f65d237574655668cefa3db32154.zip
Virtual TPM persistent states contain VTPM secrets, which are encrypted
using symmetric keys and stored on disk along with those symmetric keys. The attached patch uses the TPM to encrypt the symmetric keys and other global secrets before saving them to disk. Signed-off-by: Vinnie Scarlata <vincent.r.scarlata@intel.com>
-rw-r--r--tools/vtpm_manager/README5
-rw-r--r--tools/vtpm_manager/Rules.mk3
-rw-r--r--tools/vtpm_manager/manager/securestorage.c233
-rw-r--r--tools/vtpm_manager/manager/vtpm_manager.c96
-rw-r--r--tools/vtpm_manager/manager/vtpmpriv.h13
-rw-r--r--tools/vtpm_manager/manager/vtsp.c84
-rw-r--r--tools/vtpm_manager/manager/vtsp.h3
7 files changed, 271 insertions, 166 deletions
diff --git a/tools/vtpm_manager/README b/tools/vtpm_manager/README
index d01abf7e4b..f0d1e98cfb 100644
--- a/tools/vtpm_manager/README
+++ b/tools/vtpm_manager/README
@@ -53,11 +53,6 @@ DUMMY_BACKEND -> vtpm_manager listens on /tmp/in.fifo and
MANUAL_DM_LAUNCH -> Must manually launch & kill VTPMs
-WELL_KNOWN_SRK_AUTH -> Rather than randomly generating the password for the SRK,
- use a well known value. This is necessary for sharing use
- of the SRK across applications. Such as VTPM and Dom0
- measurement software.
-
WELL_KNOWN_OWNER_AUTH -> Rather than randomly generating the password for the owner,
use a well known value. This is useful for debugging and for
poor bios which do not support clearing TPM if OwnerAuth is
diff --git a/tools/vtpm_manager/Rules.mk b/tools/vtpm_manager/Rules.mk
index 26b44563c1..c7395864ac 100644
--- a/tools/vtpm_manager/Rules.mk
+++ b/tools/vtpm_manager/Rules.mk
@@ -56,8 +56,7 @@ CFLAGS += -DLOGGING_MODULES="(BITMASK(VTPM_LOG_TCS)|BITMASK(VTPM_LOG_VTSP)|BITMA
# Do not have manager launch DMs.
#CFLAGS += -DMANUAL_DM_LAUNCH
-# Fixed SRK
-CFLAGS += -DWELL_KNOWN_SRK_AUTH
+# Fixed OwnerAuth
#CFLAGS += -DWELL_KNOWN_OWNER_AUTH
# TPM Hardware Device or TPM Simulator
diff --git a/tools/vtpm_manager/manager/securestorage.c b/tools/vtpm_manager/manager/securestorage.c
index 5f19aa63ef..4df8531c40 100644
--- a/tools/vtpm_manager/manager/securestorage.c
+++ b/tools/vtpm_manager/manager/securestorage.c
@@ -65,7 +65,7 @@ TPM_RESULT envelope_encrypt(const buffer_t *inbuf,
UINT32 i;
struct pack_constbuf_t symkey_cipher32, data_cipher32;
- vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping[%d]: 0x", buffer_len(inbuf));
+ vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping Input[%d]: 0x", buffer_len(inbuf));
for (i=0; i< buffer_len(inbuf); i++)
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", inbuf->bytes[i]);
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
@@ -94,6 +94,12 @@ TPM_RESULT envelope_encrypt(const buffer_t *inbuf,
BSG_TPM_SIZE32_DATA, &data_cipher32);
vtpmloginfo(VTPM_LOG_VTPM, "Saved %d bytes of E(symkey) + %d bytes of E(data)\n", buffer_len(&symkey_cipher), buffer_len(&data_cipher));
+
+ vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping Output[%d]: 0x", buffer_len(sealed_data));
+ for (i=0; i< buffer_len(sealed_data); i++)
+ vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", sealed_data->bytes[i]);
+ vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+
goto egress;
abort_egress:
@@ -125,7 +131,7 @@ TPM_RESULT envelope_decrypt(const long cipher_size,
memset(&symkey, 0, sizeof(symkey_t));
- vtpmloginfo(VTPM_LOG_VTPM_DEEP, "envelope decrypting[%ld]: 0x", cipher_size);
+ vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Envelope Decrypt Input[%ld]: 0x", cipher_size);
for (i=0; i< cipher_size; i++)
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cipher[i]);
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
@@ -155,6 +161,11 @@ TPM_RESULT envelope_decrypt(const long cipher_size,
// Decrypt State
TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (&symkey, &data_cipher, unsealed_data) );
+
+ vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Envelope Decrypte Output[%d]: 0x", buffer_len(unsealed_data));
+ for (i=0; i< buffer_len(unsealed_data); i++)
+ vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", unsealed_data->bytes[i]);
+ vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
goto egress;
@@ -291,124 +302,175 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI_RESOURCE *myDMI,
return status;
}
+
TPM_RESULT VTPM_SaveService(void) {
TPM_RESULT status=TPM_SUCCESS;
int fh, dmis=-1;
-
- BYTE *flat_global;
- int flat_global_size, bytes_written;
+
+ BYTE *flat_boot_key, *flat_dmis, *flat_enc;
+ buffer_t clear_flat_global, enc_flat_global;
UINT32 storageKeySize = buffer_len(&vtpm_globals->storageKeyWrap);
+ UINT32 bootKeySize = buffer_len(&vtpm_globals->bootKeyWrap);
struct pack_buf_t storage_key_pack = {storageKeySize, vtpm_globals->storageKeyWrap.bytes};
-
+ struct pack_buf_t boot_key_pack = {bootKeySize, vtpm_globals->bootKeyWrap.bytes};
+
struct hashtable_itr *dmi_itr;
VTPM_DMI_RESOURCE *dmi_res;
-
- UINT32 flat_global_full_size;
-
- // Global Values needing to be saved
- flat_global_full_size = 3*sizeof(TPM_DIGEST) + // Auths
- sizeof(UINT32) + // storagekeysize
- storageKeySize + // storage key
- hashtable_count(vtpm_globals->dmi_map) * // num DMIS
- (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)); // Per DMI info
-
-
- flat_global = (BYTE *) malloc( flat_global_full_size);
-
- flat_global_size = BSG_PackList(flat_global, 4,
- BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
- BSG_TPM_AUTHDATA, &vtpm_globals->srk_usage_auth,
- BSG_TPM_SECRET, &vtpm_globals->storage_key_usage_auth,
- BSG_TPM_SIZE32_DATA, &storage_key_pack);
-
+
+ UINT32 boot_key_size, flat_dmis_size;
+
+ // Initially fill these with buffer sizes for each data type. Later fill
+ // in actual size, once flattened.
+ boot_key_size = sizeof(UINT32) + // bootkeysize
+ bootKeySize; // boot key
+
+ TPMTRYRETURN(buffer_init(&clear_flat_global, 3*sizeof(TPM_DIGEST) + // Auths
+ sizeof(UINT32) +// storagekeysize
+ storageKeySize, NULL) ); // storage key
+
+ flat_dmis_size = (hashtable_count(vtpm_globals->dmi_map) - 1) * // num DMIS (-1 for Dom0)
+ (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)); // Per DMI info
+
+ flat_boot_key = (BYTE *) malloc( boot_key_size );
+ flat_enc = (BYTE *) malloc( sizeof(UINT32) );
+ flat_dmis = (BYTE *) malloc( flat_dmis_size );
+
+ boot_key_size = BSG_PackList(flat_boot_key, 1,
+ BSG_TPM_SIZE32_DATA, &boot_key_pack);
+
+ BSG_PackList(clear_flat_global.bytes, 3,
+ BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
+ BSG_TPM_SECRET, &vtpm_globals->storage_key_usage_auth,
+ BSG_TPM_SIZE32_DATA, &storage_key_pack);
+
+ TPMTRYRETURN(envelope_encrypt(&clear_flat_global,
+ &vtpm_globals->bootKey,
+ &enc_flat_global) );
+
+ BSG_PackConst(buffer_len(&enc_flat_global), 4, flat_enc);
+
// Per DMI values to be saved
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);
dmis++;
// No need to save dmi0.
- if (dmi_res->dmi_id == 0)
- continue;
-
-
- flat_global_size += BSG_PackList( flat_global + flat_global_size, 3,
- BSG_TYPE_UINT32, &dmi_res->dmi_id,
- BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
- BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
-
+ if (dmi_res->dmi_id == 0)
+ continue;
+
+
+ flat_dmis_size += BSG_PackList( flat_dmis + flat_dmis_size, 3,
+ BSG_TYPE_UINT32, &dmi_res->dmi_id,
+ BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
+ BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
+
} while (hashtable_iterator_advance(dmi_itr));
}
-
- //FIXME: Once we have a way to protect a TPM key, we should use it to
- // encrypt this blob. BUT, unless there is a way to ensure the key is
- // not used by other apps, this encryption is useless.
+
fh = open(STATE_FILE, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
if (fh == -1) {
vtpmlogerror(VTPM_LOG_VTPM, "Unable to open %s file for write.\n", STATE_FILE);
status = TPM_IOERROR;
goto abort_egress;
}
-
- if ( (bytes_written = write(fh, flat_global, flat_global_size)) != flat_global_size ) {
- vtpmlogerror(VTPM_LOG_VTPM, "Failed to save service data. %d/%d bytes written.\n", bytes_written, flat_global_size);
+
+ if ( ( write(fh, flat_boot_key, boot_key_size) != boot_key_size ) ||
+ ( write(fh, flat_enc, sizeof(UINT32)) != sizeof(UINT32) ) ||
+ ( write(fh, enc_flat_global.bytes, buffer_len(&enc_flat_global)) != buffer_len(&enc_flat_global) ) ||
+ ( write(fh, flat_dmis, flat_dmis_size) != flat_dmis_size ) ) {
+ vtpmlogerror(VTPM_LOG_VTPM, "Failed to completely write service data.\n");
status = TPM_IOERROR;
goto abort_egress;
- }
- vtpm_globals->DMI_table_dirty = FALSE;
-
+ }
+
+ vtpm_globals->DMI_table_dirty = FALSE;
+
goto egress;
-
+
abort_egress:
egress:
-
- free(flat_global);
+
+ free(flat_boot_key);
+ free(flat_enc);
+ buffer_free(&enc_flat_global);
+ free(flat_dmis);
close(fh);
-
+
vtpmloginfo(VTPM_LOG_VTPM, "Saved VTPM Service state (status = %d, dmis = %d)\n", (int) status, dmis);
return status;
}
TPM_RESULT VTPM_LoadService(void) {
-
+
TPM_RESULT status=TPM_SUCCESS;
int fh, stat_ret, dmis=0;
long fh_size = 0, step_size;
- BYTE *flat_global=NULL;
- struct pack_buf_t storage_key_pack;
- UINT32 *dmi_id_key;
-
+ BYTE *flat_table=NULL;
+ buffer_t unsealed_data;
+ struct pack_buf_t storage_key_pack, boot_key_pack;
+ UINT32 *dmi_id_key, enc_size;
+
VTPM_DMI_RESOURCE *dmi_res;
struct stat file_stat;
-
+
+ TPM_HANDLE boot_key_handle;
+ TPM_AUTHDATA boot_usage_auth;
+ memset(&boot_usage_auth, 0, sizeof(TPM_AUTHDATA));
+
fh = open(STATE_FILE, O_RDONLY );
stat_ret = fstat(fh, &file_stat);
- if (stat_ret == 0)
+ if (stat_ret == 0)
fh_size = file_stat.st_size;
else {
status = TPM_IOERROR;
goto abort_egress;
}
-
- flat_global = (BYTE *) malloc(fh_size);
-
- if ((long) read(fh, flat_global, fh_size) != fh_size ) {
+
+ flat_table = (BYTE *) malloc(fh_size);
+
+ if ((long) read(fh, flat_table, fh_size) != fh_size ) {
status = TPM_IOERROR;
goto abort_egress;
}
-
+
+ // Read Boot Key
+ step_size = BSG_UnpackList( flat_table, 2,
+ BSG_TPM_SIZE32_DATA, &boot_key_pack,
+ BSG_TYPE_UINT32, &enc_size);
+
+ TPMTRYRETURN(buffer_init(&vtpm_globals->bootKeyWrap, 0, 0) );
+ TPMTRYRETURN(buffer_append_raw(&vtpm_globals->bootKeyWrap, boot_key_pack.size, boot_key_pack.data) );
+
+ //Load Boot Key
+ TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
+ TPM_SRK_KEYHANDLE,
+ &vtpm_globals->bootKeyWrap,
+ &SRK_AUTH,
+ &boot_key_handle,
+ &vtpm_globals->keyAuth,
+ &vtpm_globals->bootKey,
+ FALSE) );
+
+ TPMTRYRETURN( envelope_decrypt(enc_size,
+ flat_table + step_size,
+ vtpm_globals->manager_tcs_handle,
+ boot_key_handle,
+ (const TPM_AUTHDATA*) &boot_usage_auth,
+ &unsealed_data) );
+ step_size += enc_size;
+
// Global Values needing to be saved
- step_size = BSG_UnpackList( flat_global, 4,
- BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
- BSG_TPM_AUTHDATA, &vtpm_globals->srk_usage_auth,
- BSG_TPM_SECRET, &vtpm_globals->storage_key_usage_auth,
- BSG_TPM_SIZE32_DATA, &storage_key_pack);
-
+ BSG_UnpackList( unsealed_data.bytes, 3,
+ BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
+ 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) );
-
+
// Per DMI values to be saved
while ( step_size < fh_size ){
if (fh_size - step_size < (long) (sizeof(UINT32) + 2*sizeof(TPM_DIGEST))) {
@@ -417,35 +479,38 @@ TPM_RESULT VTPM_LoadService(void) {
} else {
dmi_res = (VTPM_DMI_RESOURCE *) malloc(sizeof(VTPM_DMI_RESOURCE));
dmis++;
-
+
dmi_res->connected = FALSE;
-
- step_size += BSG_UnpackList(flat_global + step_size, 3,
- BSG_TYPE_UINT32, &dmi_res->dmi_id,
- BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
- BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
-
+
+ step_size += BSG_UnpackList(flat_table + step_size, 3,
+ BSG_TYPE_UINT32, &dmi_res->dmi_id,
+ BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
+ BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
+
// install into map
dmi_id_key = (UINT32 *) malloc (sizeof(UINT32));
*dmi_id_key = dmi_res->dmi_id;
if (!hashtable_insert(vtpm_globals->dmi_map, dmi_id_key, dmi_res)) {
- status = TPM_FAIL;
- goto abort_egress;
+ status = TPM_FAIL;
+ goto abort_egress;
}
-
+
}
-
+
}
-
+
vtpmloginfo(VTPM_LOG_VTPM, "Loaded saved state (dmis = %d).\n", dmis);
goto egress;
-
+
abort_egress:
vtpmlogerror(VTPM_LOG_VTPM, "Failed to load service data with error = %s\n", tpm_get_error_name(status));
egress:
-
- free(flat_global);
+
+ free(flat_table);
close(fh);
-
+
+ // TODO: Could be nice and evict BootKey. (Need to add EvictKey to VTSP.
+
return status;
}
+
diff --git a/tools/vtpm_manager/manager/vtpm_manager.c b/tools/vtpm_manager/manager/vtpm_manager.c
index 48143fbc3b..c9eda0440c 100644
--- a/tools/vtpm_manager/manager/vtpm_manager.c
+++ b/tools/vtpm_manager/manager/vtpm_manager.c
@@ -74,16 +74,15 @@ VTPM_GLOBALS *vtpm_globals=NULL;
#endif
// --------------------------- Well Known Auths --------------------------
-#ifdef WELL_KNOWN_SRK_AUTH
-static BYTE FIXED_SRK_AUTH[20] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+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};
-#endif
#ifdef WELL_KNOWN_OWNER_AUTH
static BYTE FIXED_OWNER_AUTH[20] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
#endif
-
+
+
// -------------------------- Hash table functions --------------------
static unsigned int hashfunc32(void *ky) {
@@ -100,13 +99,7 @@ TPM_RESULT VTPM_Create_Service(){
TPM_RESULT status = TPM_SUCCESS;
- // Generate Auth's for SRK & Owner
-#ifdef WELL_KNOWN_SRK_AUTH
- memcpy(vtpm_globals->srk_usage_auth, FIXED_SRK_AUTH, sizeof(TPM_AUTHDATA));
-#else
- Crypto_GetRandom(vtpm_globals->srk_usage_auth, sizeof(TPM_AUTHDATA) );
-#endif
-
+ // Generate Auth for Owner
#ifdef WELL_KNOWN_OWNER_AUTH
memcpy(vtpm_globals->owner_usage_auth, FIXED_OWNER_AUTH, sizeof(TPM_AUTHDATA));
#else
@@ -116,14 +109,14 @@ TPM_RESULT VTPM_Create_Service(){
// Take Owership of TPM
CRYPTO_INFO ek_cryptoInfo;
- vtpmloginfo(VTPM_LOG_VTPM, "Attempting Pubek Read. NOTE: Failure is ok.\n");
status = VTSP_ReadPubek(vtpm_globals->manager_tcs_handle, &ek_cryptoInfo);
// If we can read PubEK then there is no owner and we should take it.
if (status == TPM_SUCCESS) {
+ vtpmloginfo(VTPM_LOG_VTPM, "Failed to readEK meaning TPM has an owner. Creating Keys off existing SRK.\n");
TPMTRYRETURN(VTSP_TakeOwnership(vtpm_globals->manager_tcs_handle,
(const TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth,
- (const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
+ &SRK_AUTH,
&ek_cryptoInfo,
&vtpm_globals->keyAuth));
@@ -142,7 +135,7 @@ TPM_RESULT VTPM_Create_Service(){
TPMTRYRETURN( VTSP_OSAP(vtpm_globals->manager_tcs_handle,
TPM_ET_KEYHANDLE,
TPM_SRK_KEYHANDLE,
- (const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
+ &SRK_AUTH,
&sharedsecret,
&osap) );
@@ -157,8 +150,43 @@ TPM_RESULT VTPM_Create_Service(){
&vtpm_globals->storageKeyWrap,
&osap) );
- vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
+ // Generate boot key's auth
+ Crypto_GetRandom( &vtpm_globals->storage_key_usage_auth,
+ sizeof(TPM_AUTHDATA) );
+ TPM_AUTHDATA bootKeyWrapAuth;
+ memset(&bootKeyWrapAuth, 0, sizeof(bootKeyWrapAuth));
+
+ TPMTRYRETURN( VTSP_OSAP(vtpm_globals->manager_tcs_handle,
+ TPM_ET_KEYHANDLE,
+ TPM_SRK_KEYHANDLE,
+ &SRK_AUTH,
+ &sharedsecret,
+ &osap) );
+
+ osap.fContinueAuthSession = FALSE;
+
+ // FIXME: This key protects the global secrets on disk. It should use TPM
+ // PCR bindings to limit its use to legit configurations.
+ // Current binds are open, implying a Trusted VM contains this code.
+ // If this VM is not Trusted, use measurement and PCR bindings.
+ TPMTRYRETURN( VTSP_CreateWrapKey( vtpm_globals->manager_tcs_handle,
+ TPM_KEY_BIND,
+ (const TPM_AUTHDATA*)&bootKeyWrapAuth,
+ TPM_SRK_KEYHANDLE,
+ (const TPM_AUTHDATA*)&sharedsecret,
+ &vtpm_globals->bootKeyWrap,
+ &osap) );
+
+ // Populate CRYPTO_INFO vtpm_globals->bootKey. This does not load it into the TPM
+ TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
+ TPM_SRK_KEYHANDLE,
+ &vtpm_globals->bootKeyWrap,
+ NULL,
+ NULL,
+ NULL,
+ &vtpm_globals->bootKey,
+ TRUE ) );
goto egress;
abort_egress:
@@ -278,24 +306,26 @@ void *VTPM_Service_Handler(void *threadTypePtr){
#endif
// Check status of rx_fh. If necessary attempt to re-open it.
+ char* s = NULL;
if (*rx_fh < 0) {
#ifdef VTPM_MULTI_VM
- *rx_fh = open(VTPM_BE_DEV, O_RDWR);
+ s = VTPM_BE_DEV;
#else
if (threadType == BE_LISTENER_THREAD)
#ifdef DUMMY_BACKEND
- *rx_fh = open("/tmp/in.fifo", O_RDWR);
+ s = "/tmp/in.fifo";
#else
- *rx_fh = open(VTPM_BE_DEV, O_RDWR);
+ s = VTPM_BE_DEV;
#endif
else // DMI Listener
- *rx_fh = open(VTPM_RX_FIFO, O_RDWR);
+ s = VTPM_RX_FIFO;
+ *rx_fh = open(s, O_RDWR);
#endif
}
// Respond to failures to open rx_fh
if (*rx_fh < 0) {
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't open inbound fh.\n");
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't open inbound fh for %s.\n", s);
#ifdef VTPM_MULTI_VM
return TPM_IOERROR;
#else
@@ -713,7 +743,7 @@ void *VTPM_Service_Handler(void *threadTypePtr){
///////////////////////////////////////////////////////////////////////////////
TPM_RESULT VTPM_Init_Service() {
- TPM_RESULT status = TPM_FAIL;
+ TPM_RESULT status = TPM_FAIL, serviceStatus;
BYTE *randomsead;
UINT32 randomsize;
@@ -737,7 +767,7 @@ TPM_RESULT VTPM_Init_Service() {
// Create new TCS Object
vtpm_globals->manager_tcs_handle = 0;
-
+
TPMTRYRETURN(TCS_create());
// Create TCS Context for service
@@ -756,17 +786,24 @@ TPM_RESULT VTPM_Init_Service() {
vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
// If failed, create new Service.
- if (VTPM_LoadService() != TPM_SUCCESS)
+ serviceStatus = VTPM_LoadService();
+ if (serviceStatus == TPM_IOERROR) {
+ vtpmloginfo(VTPM_LOG_VTPM, "Failed to read service file. Assuming first time initialization.\n");
TPMTRYRETURN( VTPM_Create_Service() );
+ } else if (serviceStatus != TPM_SUCCESS) {
+ vtpmlogerror(VTPM_LOG_VTPM, "Failed to read existing service file");
+ exit(1);
+ }
//Load Storage Key
TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
TPM_SRK_KEYHANDLE,
&vtpm_globals->storageKeyWrap,
- (const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
+ &SRK_AUTH,
&vtpm_globals->storageKeyHandle,
&vtpm_globals->keyAuth,
- &vtpm_globals->storageKey) );
+ &vtpm_globals->storageKey,
+ FALSE ) );
// Create entry for Dom0 for control messages
TPMTRYRETURN( VTPM_Handle_New_DMI(NULL) );
@@ -797,12 +834,11 @@ void VTPM_Stop_Service() {
free (dmi_itr);
}
-
- TCS_CloseContext(vtpm_globals->manager_tcs_handle);
-
- if ( (vtpm_globals->DMI_table_dirty) &&
- (VTPM_SaveService() != TPM_SUCCESS) )
+ if ( (vtpm_globals->DMI_table_dirty) && (VTPM_SaveService() != TPM_SUCCESS) )
vtpmlogerror(VTPM_LOG_VTPM, "Unable to save manager data.\n");
+
+ TCS_CloseContext(vtpm_globals->manager_tcs_handle);
+ TCS_destroy();
hashtable_destroy(vtpm_globals->dmi_map, 1);
free(vtpm_globals);
diff --git a/tools/vtpm_manager/manager/vtpmpriv.h b/tools/vtpm_manager/manager/vtpmpriv.h
index bb613aec2c..2f8c2ebc67 100644
--- a/tools/vtpm_manager/manager/vtpmpriv.h
+++ b/tools/vtpm_manager/manager/vtpmpriv.h
@@ -108,6 +108,7 @@ typedef struct tdVTPM_GLOBALS {
TCS_CONTEXT_HANDLE manager_tcs_handle; // TCS Handle used by manager
TPM_HANDLE storageKeyHandle; // Key used by persistent store
CRYPTO_INFO storageKey; // For software encryption
+ CRYPTO_INFO bootKey; // For saving table
TCS_AUTH keyAuth; // OIAP session for storageKey
BOOL DMI_table_dirty; // Indicates that a command
// has updated the DMI table
@@ -115,15 +116,17 @@ typedef struct tdVTPM_GLOBALS {
// Persistent Data
TPM_AUTHDATA owner_usage_auth; // OwnerAuth of real TPM
- TPM_AUTHDATA srk_usage_auth; // SRK Auth of real TPM
buffer_t storageKeyWrap; // Wrapped copy of storageKey
-
+ TPM_AUTHDATA srk_usage_auth;
TPM_AUTHDATA storage_key_usage_auth;
-
+
+ buffer_t bootKeyWrap; // Wrapped copy of boot key
+
}VTPM_GLOBALS;
-//Global dmi map
-extern VTPM_GLOBALS *vtpm_globals;
+// --------------------------- Global Values --------------------------
+extern VTPM_GLOBALS *vtpm_globals; // Key info and DMI states
+extern const TPM_AUTHDATA SRK_AUTH; // SRK Well Known Auth Value
// ********************** Command Handler Prototypes ***********************
TPM_RESULT VTPM_Handle_Load_NVM( VTPM_DMI_RESOURCE *myDMI,
diff --git a/tools/vtpm_manager/manager/vtsp.c b/tools/vtpm_manager/manager/vtsp.c
index b6f82e4b3a..17c3335923 100644
--- a/tools/vtpm_manager/manager/vtsp.c
+++ b/tools/vtpm_manager/manager/vtsp.c
@@ -563,63 +563,69 @@ TPM_RESULT VTSP_LoadKey(const TCS_CONTEXT_HANDLE hContext,
const TPM_AUTHDATA *parentAuth,
TPM_HANDLE *newKeyHandle,
TCS_AUTH *auth,
- CRYPTO_INFO *cryptoinfo /*= NULL*/) {
+ CRYPTO_INFO *cryptoinfo,
+ const BOOL skipTPMLoad) {
- vtpmloginfo(VTPM_LOG_VTSP, "Loading Key.\n%s","");
+ vtpmloginfo(VTPM_LOG_VTSP, "Loading Key %s.\n", (!skipTPMLoad ? "into TPM" : "only into memory"));
TPM_RESULT status = TPM_SUCCESS;
TPM_COMMAND_CODE command = TPM_ORD_LoadKey;
-
- BYTE *paramText; // Digest to make Auth.
+
+ BYTE *paramText=NULL; // Digest to make Auth.
UINT32 paramTextSize;
+
+ // SkipTPMLoad stops key from being loaded into TPM, but still generates CRYPTO_INFO for it
+ if (! skipTPMLoad) {
- if ((rgbWrappedKeyBlob == NULL) || (parentAuth == NULL) ||
- (newKeyHandle==NULL) || (auth==NULL)) {
- status = TPM_BAD_PARAMETER;
- goto abort_egress;
- }
+ if ((rgbWrappedKeyBlob == NULL) || (parentAuth == NULL) ||
+ (newKeyHandle==NULL) || (auth==NULL)) {
+ status = TPM_BAD_PARAMETER;
+ goto abort_egress;
+ }
- // Generate Extra TCS Parameters
- TPM_HANDLE phKeyHMAC;
+ // Generate Extra TCS Parameters
+ TPM_HANDLE phKeyHMAC;
- // Generate HMAC
- Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
+ // Generate HMAC
+ Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
- paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
+ paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
- paramTextSize = BSG_PackList(paramText, 1,
- BSG_TPM_COMMAND_CODE, &command);
+ paramTextSize = BSG_PackList(paramText, 1,
+ BSG_TPM_COMMAND_CODE, &command);
- memcpy(paramText + paramTextSize, rgbWrappedKeyBlob->bytes, buffer_len(rgbWrappedKeyBlob));
- paramTextSize += buffer_len(rgbWrappedKeyBlob);
+ memcpy(paramText + paramTextSize, rgbWrappedKeyBlob->bytes, buffer_len(rgbWrappedKeyBlob));
+ paramTextSize += buffer_len(rgbWrappedKeyBlob);
- TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
+ TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
parentAuth, auth) );
- // Call TCS
- TPMTRYRETURN( TCSP_LoadKeyByBlob( hContext,
- hUnwrappingKey,
- buffer_len(rgbWrappedKeyBlob),
- rgbWrappedKeyBlob->bytes,
- auth,
- newKeyHandle,
- &phKeyHMAC) );
-
- // Verify Auth
- paramTextSize = BSG_PackList(paramText, 3,
- BSG_TPM_RESULT, &status,
- BSG_TPM_COMMAND_CODE, &command,
- BSG_TPM_HANDLE, newKeyHandle);
-
- TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
- parentAuth, auth,
- hContext) );
-
- // Unpack/return key structure
+ // Call TCS
+ TPMTRYRETURN( TCSP_LoadKeyByBlob( hContext,
+ hUnwrappingKey,
+ buffer_len(rgbWrappedKeyBlob),
+ rgbWrappedKeyBlob->bytes,
+ auth,
+ newKeyHandle,
+ &phKeyHMAC) );
+
+ // Verify Auth
+ paramTextSize = BSG_PackList(paramText, 3,
+ BSG_TPM_RESULT, &status,
+ BSG_TPM_COMMAND_CODE, &command,
+ BSG_TPM_HANDLE, newKeyHandle);
+
+ TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
+ parentAuth, auth,
+ hContext) );
+ }
+
+ // Build cryptoinfo structure for software crypto function.
if (cryptoinfo != NULL) {
TPM_KEY newKey;
+ // Unpack/return key structure
BSG_Unpack(BSG_TPM_KEY, rgbWrappedKeyBlob->bytes , &newKey);
TPM_RSA_KEY_PARMS rsaKeyParms;
diff --git a/tools/vtpm_manager/manager/vtsp.h b/tools/vtpm_manager/manager/vtsp.h
index ddae64e483..93f22d34e4 100644
--- a/tools/vtpm_manager/manager/vtsp.h
+++ b/tools/vtpm_manager/manager/vtsp.h
@@ -86,7 +86,8 @@ TPM_RESULT VTSP_LoadKey(const TCS_CONTEXT_HANDLE hContext,
const TPM_AUTHDATA *parentAuth,
TPM_HANDLE *newKeyHandle,
TCS_AUTH *pAuth,
- CRYPTO_INFO *cryptoinfo);
+ CRYPTO_INFO *cryptoinfo,
+ const BOOL skipTPMLoad);
TPM_RESULT VTSP_Unbind( const TCS_CONTEXT_HANDLE hContext,
const TPM_KEY_HANDLE key_handle,