vtpmmgr: execute deep quote in locality 0

Enables deep quote execution for vtpmmgr which can not be started
using locality 2. Flags are used to request additional data to be
present when executing quote. They are interpreted as a bitmask of:
 * VTPM_QUOTE_FLAGS_HASH_UUID
 * VTPM_QUOTE_FLAGS_VTPM_MEASUREMENTS
 * VTPM_QUOTE_FLAGS_GROUP_INFO
 * VTPM_QUOTE_FLAGS_GROUP_PUBKEY

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.

Signed-off-by: Emil Condrea <emilcondrea@gmail.com>
Acked-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
This commit is contained in:
Emil Condrea authored and Ian Campbell committed 2015-04-16 13:57:01 +01:00
1 parent 588bb8aca7
commit 83d1be544c
5 files changed
+116 -14

No files matched your search

+1
View File
@@ -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)
+83 -10
View File
@@ -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);
+1 -1
View File
@@ -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
+5 -2
View File
@@ -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;
+26 -1
View File
@@ -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)
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.