Mailing List Archive

Virtual TPM persistent states contain VTPM secrets, which are encrypted
# HG changeset patch
# User kaf24@firebug.cl.cam.ac.uk
# Node ID 19f1f4fa7745509aa22763224657f4c294355d77
# Parent 65430a8f80d74823be5b96e1383a4eb5e33c137b
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>

diff -r 65430a8f80d7 -r 19f1f4fa7745 tools/vtpm_manager/README
--- a/tools/vtpm_manager/README Thu Dec 29 17:39:50 2005
+++ b/tools/vtpm_manager/README Fri Dec 30 10:31:12 2005
@@ -53,11 +53,6 @@

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 -r 65430a8f80d7 -r 19f1f4fa7745 tools/vtpm_manager/Rules.mk
--- a/tools/vtpm_manager/Rules.mk Thu Dec 29 17:39:50 2005
+++ b/tools/vtpm_manager/Rules.mk Fri Dec 30 10:31:12 2005
@@ -56,8 +56,7 @@
# 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 -r 65430a8f80d7 -r 19f1f4fa7745 tools/vtpm_manager/manager/securestorage.c
--- a/tools/vtpm_manager/manager/securestorage.c Thu Dec 29 17:39:50 2005
+++ b/tools/vtpm_manager/manager/securestorage.c Fri Dec 30 10:31:12 2005
@@ -65,7 +65,7 @@
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 @@
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 @@

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 @@

// 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 @@
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);
- status = TPM_IOERROR;
- goto abort_egress;
- }
- vtpm_globals->DMI_table_dirty = FALSE;
-
+
+ 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;
+
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 ) {
- status = TPM_IOERROR;
- goto abort_egress;
- }
-
+
+ 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 @@
} 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 -r 65430a8f80d7 -r 19f1f4fa7745 tools/vtpm_manager/manager/vtpm_manager.c
--- a/tools/vtpm_manager/manager/vtpm_manager.c Thu Dec 29 17:39:50 2005
+++ b/tools/vtpm_manager/manager/vtpm_manager.c Fri Dec 30 10:31:12 2005
@@ -74,16 +74,15 @@
#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 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 @@
// 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 @@
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 @@
&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 @@
#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 @@

///////////////////////////////////////////////////////////////////////////////
TPM_RESULT VTPM_Init_Service() {
- TPM_RESULT status = TPM_FAIL;
+ TPM_RESULT status = TPM_FAIL, serviceStatus;
BYTE *randomsead;
UINT32 randomsize;

@@ -737,7 +767,7 @@

// Create new TCS Object
vtpm_globals->manager_tcs_handle = 0;
-
+
TPMTRYRETURN(TCS_create());

// Create TCS Context for service
@@ -756,17 +786,24 @@
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 @@
free (dmi_itr);
}

-
+ 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);
-
- if ( (vtpm_globals->DMI_table_dirty) &&
- (VTPM_SaveService() != TPM_SUCCESS) )
- vtpmlogerror(VTPM_LOG_VTPM, "Unable to save manager data.\n");
+ TCS_destroy();

hashtable_destroy(vtpm_globals->dmi_map, 1);
free(vtpm_globals);
diff -r 65430a8f80d7 -r 19f1f4fa7745 tools/vtpm_manager/manager/vtpmpriv.h
--- a/tools/vtpm_manager/manager/vtpmpriv.h Thu Dec 29 17:39:50 2005
+++ b/tools/vtpm_manager/manager/vtpmpriv.h Fri Dec 30 10:31:12 2005
@@ -108,6 +108,7 @@
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 @@

// 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;

- 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 -r 65430a8f80d7 -r 19f1f4fa7745 tools/vtpm_manager/manager/vtsp.c
--- a/tools/vtpm_manager/manager/vtsp.c Thu Dec 29 17:39:50 2005
+++ b/tools/vtpm_manager/manager/vtsp.c Fri Dec 30 10:31:12 2005
@@ -563,63 +563,69 @@
const TPM_AUTHDATA *parentAuth,
TPM_HANDLE *newKeyHandle,
TCS_AUTH *auth,
- CRYPTO_INFO *cryptoinfo /*= NULL*/) {
-
-
- vtpmloginfo(VTPM_LOG_VTSP, "Loading Key.\n%s","");
+ CRYPTO_INFO *cryptoinfo,
+ const BOOL skipTPMLoad) {
+
+
+ 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;
-
- if ((rgbWrappedKeyBlob == NULL) || (parentAuth == NULL) ||
- (newKeyHandle==NULL) || (auth==NULL)) {
- status = TPM_BAD_PARAMETER;
- goto abort_egress;
- }
-
- // Generate Extra TCS Parameters
- TPM_HANDLE phKeyHMAC;
-
- // Generate HMAC
- Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
-
- paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
-
- paramTextSize = BSG_PackList(paramText, 1,
- BSG_TPM_COMMAND_CODE, &command);
-
- memcpy(paramText + paramTextSize, rgbWrappedKeyBlob->bytes, buffer_len(rgbWrappedKeyBlob));
- paramTextSize += buffer_len(rgbWrappedKeyBlob);
-
- TPMTRYRETURN( GenerateAuth( paramText, 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;
+ }
+
+ // Generate Extra TCS Parameters
+ TPM_HANDLE phKeyHMAC;
+
+ // Generate HMAC
+ Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
+
+ paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
+
+ paramTextSize = BSG_PackList(paramText, 1,
+ BSG_TPM_COMMAND_CODE, &command);
+
+ memcpy(paramText + paramTextSize, rgbWrappedKeyBlob->bytes, buffer_len(rgbWrappedKeyBlob));
+ paramTextSize += buffer_len(rgbWrappedKeyBlob);
+
+ 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 -r 65430a8f80d7 -r 19f1f4fa7745 tools/vtpm_manager/manager/vtsp.h
--- a/tools/vtpm_manager/manager/vtsp.h Thu Dec 29 17:39:50 2005
+++ b/tools/vtpm_manager/manager/vtsp.h Fri Dec 30 10:31:12 2005
@@ -86,7 +86,8 @@
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,

_______________________________________________
Xen-changelog mailing list
Xen-changelog@lists.xensource.com
http://lists.xensource.com/xen-changelog