xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Daniel De Graaf <dgdegra@tycho.nsa.gov>
To: Matthew Fioravante <matthew.fioravante@jhuapl.edu>
Cc: "samuel.thibault@ens-lyon.org" <samuel.thibault@ens-lyon.org>,
	"Ian.Jackson@eu.citrix.com" <Ian.Jackson@eu.citrix.com>,
	"Ian.Campbell@citrix.com" <Ian.Campbell@citrix.com>,
	"xen-devel@lists.xen.org" <xen-devel@lists.xen.org>
Subject: Re: [PATCH 9/9] stubdom/vtpm: Add PCR pass-through to hardware TPM
Date: Tue, 04 Dec 2012 13:43:14 -0500	[thread overview]
Message-ID: <50BE4442.6070902@tycho.nsa.gov> (raw)
In-Reply-To: <50BE3730.2030509@jhuapl.edu>

On 12/04/2012 12:47 PM, Matthew Fioravante wrote:
> So this maps a fixed set of PCRs always? 

Yes; and making them not the last 24 (or last N) PCRs requires a more
complex patch, since the PCR-modification code also needs to be changed.

> Is there any use case where the user might want the PCR mappings to be configurable? Might they want to disable this feature to disallow Hardware PCR access in the vm?

I think all of these configuration options will be needed for this to be 
truly useful in an upstream vTPM implementation; however, they require 
more significant changes to the TPM emulator itself, since values that
are currently #defines need to be changed to be configurable at TPM
creation. Adding more configuration will also eventually run past the
limits of what is reasonable to place on the vTPM's command line, so it
may be useful to consider how to define this type of configuration so 
that it still ends up in the vTPM's measurement when create by a 
measuring domain builder (hash of a config struct on the command line).

Things that I think could be configurable:
  * Localities and what domains can use them (I have a command-line 
    based patch for this).
  * PCRs beyond the defined minimum (currently 24): what localities have 
    extend/clear access to them, or what HW-PCR they are mapped to
  * Maximum sizes of TPM items: NV area, counters, sessions, etc
  
TPM version 2.0 may address some of these issues in the specification, 
so it may be reasonable to require compile-time configuration for a 1.2
TPM, and allow the owner to define the rest at runtime in a 2.0 TPM.

> Also can you update the docs/misc/vtpm.txt documentation with a note about this and the grub feature?

Sure.
 
> On 11/30/2012 09:49 AM, Daniel De Graaf wrote:
>> This allows the hardware TPM's PCRs to be accessed from a vTPM for
>> debugging and as a simple alternative to a deep quote in situations
>> where the integrity of the vTPM's own TCB is not in question.
>>
>> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
>> ---
>>   stubdom/Makefile                   |  1 +
>>   stubdom/vtpm-pcr-passthrough.patch | 73 ++++++++++++++++++++++++++++++++++++++
>>   stubdom/vtpm/vtpm_cmd.c            | 38 ++++++++++++++++++++
>>   3 files changed, 112 insertions(+)
>>   create mode 100644 stubdom/vtpm-pcr-passthrough.patch
>>
>> diff --git a/stubdom/Makefile b/stubdom/Makefile
>> index 790b547..03ec07e 100644
>> --- a/stubdom/Makefile
>> +++ b/stubdom/Makefile
>> @@ -210,6 +210,7 @@ tpm_emulator-$(XEN_TARGET_ARCH): tpm_emulator-$(TPMEMU_VERSION).tar.gz
>>       patch -d $@ -p1 < vtpm-locality.patch
>>       patch -d $@ -p1 < vtpm-bufsize.patch
>>       patch -d $@ -p1 < vtpm-locality5-pcrs.patch
>> +    patch -d $@ -p1 < vtpm-pcr-passthrough.patch
>>       mkdir $@/build
>>       cd $@/build; $(CMAKE) .. -DCMAKE_C_COMPILER=${CC} -DCMAKE_C_FLAGS="-std=c99 -DTPM_NO_EXTERN $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-declaration-after-statement"
>>       touch $@
>> diff --git a/stubdom/vtpm-pcr-passthrough.patch b/stubdom/vtpm-pcr-passthrough.patch
>> new file mode 100644
>> index 0000000..4e898a5
>> --- /dev/null
>> +++ b/stubdom/vtpm-pcr-passthrough.patch
>> @@ -0,0 +1,73 @@
>> +diff --git a/tpm/tpm_capability.c b/tpm/tpm_capability.c
>> +index f8f7f0f..885af52 100644
>> +--- a/tpm/tpm_capability.c
>> ++++ b/tpm/tpm_capability.c
>> +@@ -72,7 +72,7 @@ static TPM_RESULT cap_property(UINT32 subCapSize, BYTE *subCap,
>> +   switch (property) {
>> +     case TPM_CAP_PROP_PCR:
>> +       debug("[TPM_CAP_PROP_PCR]");
>> +-      return return_UINT32(respSize, resp, TPM_NUM_PCR);
>> ++      return return_UINT32(respSize, resp, TPM_NUM_PCR_V);
>> +
>> +     case TPM_CAP_PROP_DIR:
>> +       debug("[TPM_CAP_PROP_DIR]");
>> +diff --git a/tpm/tpm_emulator_extern.h b/tpm/tpm_emulator_extern.h
>> +index 36a32dd..77ed595 100644
>> +--- a/tpm/tpm_emulator_extern.h
>> ++++ b/tpm/tpm_emulator_extern.h
>> +@@ -56,6 +56,7 @@ void (*tpm_free)(/*const*/ void *ptr);
>> + /* random numbers */
>> +
>> + void (*tpm_get_extern_random_bytes)(void *buf, size_t nbytes);
>> ++void tpm_get_extern_pcr(int index, void *buf);
>> +
>> + /* usec since last call */
>> +
>> +diff --git a/tpm/tpm_integrity.c b/tpm/tpm_integrity.c
>> +index 66ece83..f3c4196 100644
>> +--- a/tpm/tpm_integrity.c
>> ++++ b/tpm/tpm_integrity.c
>> +@@ -56,8 +56,11 @@ TPM_RESULT TPM_Extend(TPM_PCRINDEX pcrNum, TPM_DIGEST *inDigest,
>> + TPM_RESULT TPM_PCRRead(TPM_PCRINDEX pcrIndex, TPM_PCRVALUE *outDigest)
>> + {
>> +   info("TPM_PCRRead()");
>> +-  if (pcrIndex >= TPM_NUM_PCR) return TPM_BADINDEX;
>> +-  memcpy(outDigest, &PCR_VALUE[pcrIndex], sizeof(TPM_PCRVALUE));
>> ++  if (pcrIndex >= TPM_NUM_PCR_V) return TPM_BADINDEX;
>> ++  if (pcrIndex >= TPM_NUM_PCR)
>> ++    tpm_get_extern_pcr(pcrIndex - TPM_NUM_PCR, outDigest);
>> ++  else
>> ++    memcpy(outDigest, &PCR_VALUE[pcrIndex], sizeof(TPM_PCRVALUE));
>> +   return TPM_SUCCESS;
>> + }
>> +
>> +@@ -138,12 +141,15 @@ TPM_RESULT tpm_compute_pcr_digest(TPM_PCR_SELECTION *pcrSelection,
>> +   BYTE *buf, *ptr;
>> +   info("tpm_compute_pcr_digest()");
>> +   /* create PCR composite */
>> +-  if ((pcrSelection->sizeOfSelect * 8) > TPM_NUM_PCR
>> ++  if ((pcrSelection->sizeOfSelect * 8) > TPM_NUM_PCR_V
>> +       || pcrSelection->sizeOfSelect == 0) return TPM_INVALID_PCR_INFO;
>> +   for (i = 0, j = 0; i < pcrSelection->sizeOfSelect * 8; i++) {
>> +     /* is PCR number i selected ? */
>> +     if (pcrSelection->pcrSelect[i >> 3] & (1 << (i & 7))) {
>> +-      memcpy(&comp.pcrValue[j++], &PCR_VALUE[i], sizeof(TPM_PCRVALUE));
>> ++      if (i >= TPM_NUM_PCR)
>> ++        tpm_get_extern_pcr(i - TPM_NUM_PCR, &comp.pcrValue[j++]);
>> ++      else
>> ++        memcpy(&comp.pcrValue[j++], &PCR_VALUE[i], sizeof(TPM_PCRVALUE));
>> +     }
>> +   }
>> +   memcpy(&comp.select, pcrSelection, sizeof(TPM_PCR_SELECTION));
>> +diff --git a/tpm/tpm_structures.h b/tpm/tpm_structures.h
>> +index 08cef1e..8c97fc5 100644
>> +--- a/tpm/tpm_structures.h
>> ++++ b/tpm/tpm_structures.h
>> +@@ -677,6 +677,7 @@ typedef struct tdTPM_CMK_MA_APPROVAL {
>> +  * Number of PCRs of the TPM (must be a multiple of eight)
>> +  */
>> + #define TPM_NUM_PCR 32
>> ++#define TPM_NUM_PCR_V (TPM_NUM_PCR + 24)
>> +
>> + /*
>> +  * TPM_PCR_SELECTION ([TPM_Part2], Section 8.1)
>> diff --git a/stubdom/vtpm/vtpm_cmd.c b/stubdom/vtpm/vtpm_cmd.c
>> index 7eae98b..ed058fb 100644
>> --- a/stubdom/vtpm/vtpm_cmd.c
>> +++ b/stubdom/vtpm/vtpm_cmd.c
>> @@ -134,6 +134,44 @@ egress:
>>     }
>>   +extern struct tpmfront_dev* tpmfront_dev;
>> +void tpm_get_extern_pcr(int index, void *buf) {
>> +   TPM_RESULT status = TPM_SUCCESS;
>> +   uint8_t* cmdbuf, *resp, *bptr;
>> +   size_t resplen = 0;
>> +   UINT32 len;
>> +
>> +   /*Ask the real tpm for the PCR value */
>> +   TPM_TAG tag = TPM_TAG_RQU_COMMAND;
>> +   UINT32 size;
>> +   TPM_COMMAND_CODE ord = TPM_ORD_PCRRead;
>> +   len = size = sizeof(TPM_TAG) + sizeof(UINT32) + sizeof(TPM_COMMAND_CODE) + sizeof(UINT32);
>> +
>> +   /*Create the raw tpm command */
>> +   bptr = cmdbuf = malloc(size);
>> +   TRYFAILGOTO(pack_header(&bptr, &len, tag, size, ord));
>> +   TRYFAILGOTO(tpm_marshal_UINT32(&bptr, &len, index));
>> +
>> +   /* Send cmd, wait for response */
>> +   TRYFAILGOTOMSG(tpmfront_cmd(tpmfront_dev, cmdbuf, size, &resp, &resplen),
>> +      ERR_TPMFRONT);
>> +
>> +   bptr = resp; len = resplen;
>> +   TRYFAILGOTOMSG(unpack_header(&bptr, &len, &tag, &size, &ord), ERR_MALFORMED);
>> +
>> +   //Check return status of command
>> +   CHECKSTATUSGOTO(ord, "TPM_PCRRead()");
>> +
>> +   //Get the PCR value out
>> +   TRYFAILGOTOMSG(tpm_unmarshal_BYTE_ARRAY(&bptr, &len, buf, 20), ERR_MALFORMED);
>> +
>> +   goto egress;
>> +abort_egress:
>> +   memset(buf, 0x20, 20);
>> +egress:
>> +   free(cmdbuf);
>> +}
>> +
>>   TPM_RESULT VTPM_LoadHashKey(struct tpmfront_dev* tpmfront_dev, uint8_t** data, size_t* data_length)
>>   {
>>      TPM_RESULT status = TPM_SUCCESS;
> 
> 


-- 
Daniel De Graaf
National Security Agency

  reply	other threads:[~2012-12-04 18:43 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-11-30 14:49 [PATCH v2 0/9] vTPM new ABI, extensions Daniel De Graaf
2012-11-30 14:49 ` [PATCH 1/9] stubdom: Change vTPM shared page ABI Daniel De Graaf
2012-11-30 14:49 ` [PATCH 2/9] stubdom/vtpm: Support locality field Daniel De Graaf
2012-12-04 17:43   ` Matthew Fioravante
2012-11-30 14:49 ` [PATCH 3/9] stubdom/vtpm: correct the buffer size returned by TPM_CAP_PROP_INPUT_BUFFER Daniel De Graaf
2012-11-30 14:49 ` [PATCH 4/9] stubdom/vtpm: Add locality-5 PCRs Daniel De Graaf
2012-11-30 14:49 ` [PATCH 5/9] stubdom/vtpm: Allow repoen of closed devices Daniel De Graaf
2012-11-30 14:49 ` [PATCH 6/9] stubdom/vtpm: make state save operation atomic Daniel De Graaf
2012-11-30 14:49 ` [PATCH 7/9] stubdom/grub: send kernel measurements to vTPM Daniel De Graaf
2012-12-04  0:17   ` Samuel Thibault
2012-12-04 17:44   ` Matthew Fioravante
2012-11-30 14:49 ` [PATCH 8/9] stubdom/vtpm: support multiple backends Daniel De Graaf
2012-11-30 14:49 ` [PATCH 9/9] stubdom/vtpm: Add PCR pass-through to hardware TPM Daniel De Graaf
2012-12-04 17:47   ` Matthew Fioravante
2012-12-04 18:43     ` Daniel De Graaf [this message]
2012-12-04 18:53       ` Matthew Fioravante
2012-12-04  0:18 ` [PATCH v2 0/9] vTPM new ABI, extensions Samuel Thibault
2012-12-04 18:55 ` Matthew Fioravante
2012-12-04 19:00   ` Daniel De Graaf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=50BE4442.6070902@tycho.nsa.gov \
    --to=dgdegra@tycho.nsa.gov \
    --cc=Ian.Campbell@citrix.com \
    --cc=Ian.Jackson@eu.citrix.com \
    --cc=matthew.fioravante@jhuapl.edu \
    --cc=samuel.thibault@ens-lyon.org \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).