diff --git a/stubdom/vtpmmgr/marshal.h b/stubdom/vtpmmgr/marshal.h index bcc7c46be2..d826f19d89 100644 --- a/stubdom/vtpmmgr/marshal.h +++ b/stubdom/vtpmmgr/marshal.h @@ -195,6 +195,7 @@ inline int unpack3_UINT32(BYTE* ptr, UINT32* pos, UINT32 max, UINT32 *t) #define unpack3_TPM_PHYSICAL_PRESENCE(p, l, m, t) unpack3_UINT16(p, l, m, t) #define unpack3_TPM_KEY_FLAGS(p, l, m, t) unpack3_UINT32(p, l, m, t) #define unpack3_TPM_LOCALITY_SELECTION(p, l, m, t) unpack3_BYTE(p, l, m, t) +#define unpack3_TPM_DEEP_QUOTE_INFO(p, l, m, t) unpack3_UINT32(p, l, m, t) #define sizeof_TPM_RESULT(t) sizeof_UINT32(t) #define sizeof_TPM_PCRINDEX(t) sizeof_UINT32(t) diff --git a/stubdom/vtpmmgr/mgmt_authority.c b/stubdom/vtpmmgr/mgmt_authority.c index 0526a12076..b839a20cef 100644 --- a/stubdom/vtpmmgr/mgmt_authority.c +++ b/stubdom/vtpmmgr/mgmt_authority.c @@ -128,6 +128,55 @@ static int do_load_aik(struct mem_group *group, TPM_HANDLE *handle) 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 */ @@ -273,18 +322,40 @@ int group_do_activate(struct mem_group *group, void* blob, int blobSize, 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; - int rc; + 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; - rc = do_pcr_setup(group, uuid, kern_hash); - if (rc) - return rc; + 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; + + 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) @@ -296,8 +367,7 @@ int vtpm_do_quote(struct mem_group *group, const uuid_t uuid, 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); @@ -306,16 +376,19 @@ int vtpm_do_quote(struct mem_group *group, const uuid_t uuid, 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); diff --git a/stubdom/vtpmmgr/mgmt_authority.h b/stubdom/vtpmmgr/mgmt_authority.h index 1e96c8a149..cdd06aa76d 100644 --- a/stubdom/vtpmmgr/mgmt_authority.h +++ b/stubdom/vtpmmgr/mgmt_authority.h @@ -5,7 +5,7 @@ struct mem_group *vtpm_new_group(const struct tpm_authdata *privCADigest); int group_do_activate(struct mem_group *group, void* blob, int blobSize, void* resp, unsigned int *rlen); 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, + const uint8_t* kern_hash, const struct tpm_authdata *data, TPM_PCR_SELECTION *sel, uint32_t extraInfoFlags, void* pcr_out, uint32_t *pcr_size, void* sig_out); #endif diff --git a/stubdom/vtpmmgr/vtpm_cmd_handler.c b/stubdom/vtpmmgr/vtpm_cmd_handler.c index 13ead93237..2ac14fae77 100644 --- a/stubdom/vtpmmgr/vtpm_cmd_handler.c +++ b/stubdom/vtpmmgr/vtpm_cmd_handler.c @@ -282,9 +282,11 @@ static TPM_RESULT vtpmmgr_GetQuote(struct tpm_opaque *opq, tpmcmd_t* tpmcmd) 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) { @@ -297,7 +299,7 @@ static TPM_RESULT vtpmmgr_GetQuote(struct tpm_opaque *opq, tpmcmd_t* tpmcmd) 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; @@ -529,6 +531,7 @@ static TPM_RESULT vtpmmgr_GroupRegister(tpmcmd_t* tpmcmd) 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); @@ -567,7 +570,7 @@ static TPM_RESULT vtpmmgr_GroupRegister(tpmcmd_t* tpmcmd) 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; diff --git a/stubdom/vtpmmgr/vtpm_manager.h b/stubdom/vtpmmgr/vtpm_manager.h index 156c2ce0ea..2d2109dd63 100644 --- a/stubdom/vtpmmgr/vtpm_manager.h +++ b/stubdom/vtpmmgr/vtpm_manager.h @@ -46,6 +46,12 @@ // 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. @@ -110,6 +116,23 @@ * 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 @@ -117,12 +140,14 @@ * 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)