return TPM_LoadKey(TPM_SRK_KEYHANDLE, &key, handle, (void*)&vtpm_globals.srk_auth, &vtpm_globals.oiap);
}
+static void do_vtpminfo_hash(uint32_t extra_info_flags,struct mem_group *group,
+ const void* uuid, const uint8_t* kern_hash,unsigned char** calc_hashes)
+{
+ int i;
+ sha1_context ctx;
+ if(extra_info_flags & VTPM_QUOTE_FLAGS_HASH_UUID){
+ printk("hashing for FLAGS_HASH_UUID: ");
+ sha1_starts(&ctx);
+ if(uuid){
+ printk("true");
+ sha1_update(&ctx, (void*)uuid, 16);
+ }
+ sha1_finish(&ctx, *calc_hashes);
+ *calc_hashes = *calc_hashes + 20;
+ printk("\n");
+ }
+ if(extra_info_flags & VTPM_QUOTE_FLAGS_VTPM_MEASUREMENTS){
+ printk("hashing for VTPM_QUOTE_FLAGS_VTPM_MEASUREMENTS: ");
+ sha1_starts(&ctx);
+ if(kern_hash){
+ printk("true");
+ sha1_update(&ctx, (void*)kern_hash, 20);
+ }
+ sha1_finish(&ctx, *calc_hashes);
+ *calc_hashes = *calc_hashes + 20;
+ printk("\n");
+ }
+ if(extra_info_flags & VTPM_QUOTE_FLAGS_GROUP_INFO){
+ printk("hashing for VTPM_QUOTE_FLAGS_GROUP_INFO: true\n");
+ sha1_starts(&ctx);
+ sha1_update(&ctx, (void*)&group->id_data.saa_pubkey, sizeof(group->id_data.saa_pubkey));
+ sha1_update(&ctx, (void*)&group->details.cfg_seq, 8);
+ sha1_update(&ctx, (void*)&group->seal_bits.nr_cfgs, 4);
+ for(i=0; i < group->nr_seals; i++)
+ sha1_update(&ctx, (void*)&group->seals[i].digest_release, 20);
+ sha1_update(&ctx, (void*)&group->seal_bits.nr_kerns, 4);
+ sha1_update(&ctx, (void*)&group->seal_bits.kernels, 20 * be32_native(group->seal_bits.nr_kerns));
+ sha1_finish(&ctx, *calc_hashes);
+ *calc_hashes = *calc_hashes + 20;
+ }
+ if(extra_info_flags & VTPM_QUOTE_FLAGS_GROUP_PUBKEY){
+ printk("hashing for VTPM_QUOTE_FLAGS_GROUP_PUBKEY: true\n");
+ sha1_starts(&ctx);
+ sha1_update(&ctx, (void*)&group->id_data.saa_pubkey, sizeof(group->id_data.saa_pubkey));
+ sha1_finish(&ctx, *calc_hashes);
+ *calc_hashes = *calc_hashes + 20;
+ }
+}
+
/*
* Sets up resettable PCRs for a vTPM deep quote request
*/
int vtpm_do_quote(struct mem_group *group, const uuid_t uuid,
const uint8_t* kern_hash, const struct tpm_authdata *data, TPM_PCR_SELECTION *sel,
- void* pcr_out, uint32_t *pcr_size, void* sig_out)
+ uint32_t extra_info_flags, void* pcr_out, uint32_t *pcr_size, void* sig_out)
{
TPM_HANDLE handle;
TPM_AUTH_SESSION oiap = TPM_AUTH_SESSION_INIT;
TPM_PCR_COMPOSITE pcrs;
BYTE* sig;
UINT32 size;
+ sha1_context ctx;
+ TPM_DIGEST externData;
+ const void* data_to_quote = data;
+ unsigned char* ppcr_out = (unsigned char*)pcr_out;
+ unsigned char** pcr_outv = (unsigned char**)&ppcr_out;
+
int rc;
+ printk("Extra Info Flags =0x%x\n",extra_info_flags);
+ if((extra_info_flags & ~VTPM_QUOTE_FLAGS_HASH_UUID
+ & ~VTPM_QUOTE_FLAGS_VTPM_MEASUREMENTS
+ & ~VTPM_QUOTE_FLAGS_GROUP_INFO
+ & ~VTPM_QUOTE_FLAGS_GROUP_PUBKEY) != 0)
+ return VTPM_INVALID_REQUEST;
- rc = do_pcr_setup(group, uuid, kern_hash);
- if (rc)
- return rc;
+ sha1_starts(&ctx);
+ sha1_update(&ctx, (void*)&extra_info_flags, 4);
+ sha1_update(&ctx, (void*)data, 20);
+ if(pcr_out!=NULL && extra_info_flags!=0)
+ {
+ /*creates hashes and sets them to pcr_out*/
+ do_vtpminfo_hash(extra_info_flags,group, uuid, kern_hash, pcr_outv);
+ *pcr_size = *pcr_outv - (unsigned char*)pcr_out;
+ if(*pcr_size > 0)
+ sha1_update(&ctx, pcr_out, *pcr_size);
+ }
+ sha1_finish(&ctx, externData.digest);
+ data_to_quote = (void*)externData.digest;
rc = do_load_aik(group, &handle);
if (rc)
return rc;
}
- rc = TPM_Quote(handle, (void*)data, sel, (void*)&group->aik_authdata, &oiap, &pcrs, &sig, &size);
- printk("TPM_Quote: %d\n", rc);
+ rc = TPM_Quote(handle, data_to_quote, sel, (void*)&group->aik_authdata, &oiap, &pcrs, &sig, &size);
TPM_TerminateHandle(oiap.AuthHandle);
TPM_FlushSpecific(handle, TPM_RT_KEY);
return rc;
if (size != 256) {
printk("Bad size\n");
- return TPM_FAIL;
+ rc = TPM_FAIL;
+ goto end;
}
if (pcr_out) {
- *pcr_size = pcrs.valueSize;
- memcpy(pcr_out, pcrs.pcrValue, *pcr_size);
+ /*append TPM_PCRVALUEs after externData hashes*/
+ memcpy(pcr_out+*pcr_size, pcrs.pcrValue, pcrs.valueSize);
+ *pcr_size = *pcr_size + pcrs.valueSize;
}
memcpy(sig_out, sig, size);
+end:
free_TPM_PCR_COMPOSITE(&pcrs);
free(sig);
void *ibuf;
uint32_t pcr_size;
TPM_PCR_SELECTION sel;
+ uint32_t extra_info_flags;
UNPACK_IN(VPTR, &ibuf, 20, UNPACK_ALIAS);
UNPACK_IN(TPM_PCR_SELECTION, &sel, UNPACK_ALIAS);
+ UNPACK_IN(TPM_DEEP_QUOTE_INFO, &extra_info_flags);
UNPACK_DONE();
if (!opq->vtpm) {
printk("%02x", ((uint8_t*)ibuf)[i]);
printk("\n");
- status = vtpm_do_quote(opq->group, *opq->uuid, opq->kern_hash, ibuf, &sel, PACK_BUF + 256, &pcr_size, PACK_BUF);
+ status = vtpm_do_quote(opq->group, *opq->uuid, opq->kern_hash, ibuf, &sel, extra_info_flags, PACK_BUF + 256, &pcr_size, PACK_BUF);
if (status)
goto abort_egress;
tpmcmd->resp_len += 256 + pcr_size;
sha1_context ctx;
TPM_PCR_SELECTION sel;
void *dhkx1, *dhkx2, *gk, *sig;
+ uint32_t extra_info_flags = 0;
UNPACK_GROUP(group);
UNPACK_IN(VPTR, &dhkx1, 256, UNPACK_ALIAS);
sha1_update(&ctx, dhkx2, 256 + 32);
sha1_finish(&ctx, digest.bits);
- status = vtpm_do_quote(group, NULL, NULL, &digest, &sel, NULL, NULL, PACK_BUF);
+ status = vtpm_do_quote(group, NULL, NULL, &digest, &sel, extra_info_flags,NULL, NULL, PACK_BUF);
tpmcmd->resp_len += 256;
CMD_END;
// Header size
#define VTPM_COMMAND_HEADER_SIZE ( 2 + 4 + 4)
+//************************ Command Params ***************************
+#define VTPM_QUOTE_FLAGS_HASH_UUID 0x00000001
+#define VTPM_QUOTE_FLAGS_VTPM_MEASUREMENTS 0x00000002
+#define VTPM_QUOTE_FLAGS_GROUP_INFO 0x00000004
+#define VTPM_QUOTE_FLAGS_GROUP_PUBKEY 0x00000008
+
//************************ Command Codes ****************************
#define VTPM_ORD_BASE 0x0000
#define TPM_VENDOR_COMMAND 0x02000000 // TPM Main, part 2, section 17.
* Get a hardware TPM quote for this vTPM. The quote will use the AIK
* associated with the group this vTPM was created in. Values specific to the
* vTPM will be extended to certain resettable PCRs.
+ * Additional info can be included when creating the signature by using
+ * quoteSelect as PCR selection and by setting flags param. The externData
+ * param for TPM_Quote is calculated as:
+ * externData = SHA1 (
+ * extraInfoFlags
+ * requestData
+ * [SHA1 (
+ * [SHA1 (UUIDs if requested)]
+ * [SHA1 (vTPM measurements if requested)]
+ * [SHA1 (vTPM group update policy if requested)]
+ * [SHA1 (vTPM group public key if requested)]
+ * ) if flags !=0 ]
+ * )
+ * The response param pcrValues is an array containing requested hashes used
+ * for externData calculation : UUIDs, vTPM measurements, vTPM group update
+ * policy, group public key. At the end of these hashes the PCR values are
+ * appended.
*
* Input:
* TPM_TAG tag VTPM_TAG_REQ
* UINT32 ordinal VTPM_ORD_GET_QUOTE
* TPM_NONCE externData Data to be quoted
* PCR_SELECTION quoteSelect PCR selection for quote.
+ * UINT32 flags Bit mask of VTPM_QUOTE_FLAGS_*
* Output:
* TPM_TAG tag VTPM_TAG_RSP
* UINT32 paramSize total size
* UINT32 status return code
* BYTE[] signature 256 bytes of signature data
- * TPM_PCRVALUE[] pcrValues Values of PCRs selected by the request
+ * TPM_PCRVALUE[] pcrValues Values of additional SHA1 hashes requested,
+ * concatenated with PCRs selected by the request
*/
#define VTPM_ORD_GET_QUOTE (VTPM_ORD_BASE + 4)