[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 4/4] vtpm: add deep quote support



This allows the client of a vTPM to request a quote from the physical
TPM which includes PCRs from both the physical and virtual TPMs, signed
by an AIK from the physical TPM. This quote can be used to provide
evidence of the complete launch environment of a virtual machine.

Signed-off-by: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
---
 stubdom/Makefile             |   1 +
 stubdom/vtpm-deepquote.patch | 187 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 188 insertions(+)
 create mode 100644 stubdom/vtpm-deepquote.patch

diff --git a/stubdom/Makefile b/stubdom/Makefile
index a97ac7e..d01bce4 100644
--- a/stubdom/Makefile
+++ b/stubdom/Makefile
@@ -212,6 +212,7 @@ tpm_emulator-$(XEN_TARGET_ARCH): 
tpm_emulator-$(TPMEMU_VERSION).tar.gz
        patch -d $@ -p1 < vtpm-bufsize.patch
        patch -d $@ -p1 < vtpm-locality.patch
        patch -d $@ -p1 < vtpm-parent-sign-ek.patch
+       patch -d $@ -p1 < vtpm-deepquote.patch
        mkdir $@/build
        cd $@/build; CC=${CC} $(CMAKE) .. -DCMAKE_C_FLAGS:STRING="-std=c99 
-DTPM_NO_EXTERN $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) 
-Wno-declaration-after-statement"
        touch $@
diff --git a/stubdom/vtpm-deepquote.patch b/stubdom/vtpm-deepquote.patch
new file mode 100644
index 0000000..6344f38
--- /dev/null
+++ b/stubdom/vtpm-deepquote.patch
@@ -0,0 +1,187 @@
+diff --git a/tpm/tpm_cmd_handler.c b/tpm/tpm_cmd_handler.c
+index 0fabf98..69511d1 100644
+--- a/tpm/tpm_cmd_handler.c
++++ b/tpm/tpm_cmd_handler.c
+@@ -3343,6 +3343,39 @@ static TPM_RESULT execute_TPM_ParentSignEK(TPM_REQUEST 
*req, TPM_RESPONSE *rsp)
+       return res;
+ }
+ 
++static TPM_RESULT execute_TPM_DeepQuote(TPM_REQUEST *req, TPM_RESPONSE *rsp)
++{
++      TPM_NONCE nonce;
++      TPM_RESULT res;
++      UINT32 sigSize;
++      BYTE *sig;
++      BYTE *ptr;
++      UINT32 len;
++      TPM_PCR_SELECTION myPCR;
++      TPM_PCR_SELECTION ptPCR;
++
++      tpm_compute_in_param_digest(req);
++
++      ptr = req->param;
++      len = req->paramSize;
++      if (tpm_unmarshal_TPM_NONCE(&ptr, &len, &nonce)
++              || tpm_unmarshal_TPM_PCR_SELECTION(&ptr, &len, &myPCR)
++              || tpm_unmarshal_TPM_PCR_SELECTION(&ptr, &len, &ptPCR)
++              || len != 0) return TPM_BAD_PARAMETER;
++
++      res = TPM_DeepQuote(&nonce, &myPCR, &ptPCR, &req->auth1, &sigSize, 
&sig);
++      if (res != TPM_SUCCESS) return res;
++      rsp->paramSize = len = sigSize;
++      rsp->param = ptr = tpm_malloc(len);
++      if (ptr == NULL || tpm_marshal_BLOB(&ptr, &len, sig, sigSize)) {
++              tpm_free(rsp->param);
++              res = TPM_FAIL;
++      }
++      tpm_free(sig);
++
++      return res;
++}
++
+ static void tpm_setup_rsp_auth(TPM_COMMAND_CODE ordinal, TPM_RESPONSE *rsp) 
+ {
+   tpm_hmac_ctx_t hmac;
+@@ -4098,6 +4131,11 @@ void tpm_execute_command(TPM_REQUEST *req, TPM_RESPONSE 
*rsp)
+       res = execute_TPM_ParentSignEK(req, rsp);
+     break;
+ 
++    case TPM_ORD_DeepQuote:
++      debug("[TPM_ORD_DeepQuote]");
++      res = execute_TPM_DeepQuote(req, rsp);
++    break;
++
+     default:
+ #ifdef MTM_EMULATOR
+       res = mtm_execute_command(req, rsp);
+diff --git a/tpm/tpm_commands.h b/tpm/tpm_commands.h
+index 7fef934..328d1be 100644
+--- a/tpm/tpm_commands.h
++++ b/tpm/tpm_commands.h
+@@ -3071,6 +3071,25 @@ TPM_RESULT TPM_ParentSignEK(
+   BYTE **sig
+ );
+ 
++/**
++ * TPM_DeepQuote - gets a hardware TPM quote of a vTPM's PCRs
++ * @externalData: [in] AntiReplay nonce to prevent replay of messages
++ * @myPCR: [in] PCR selection for the virtual TPM
++ * @ptPCR: [in] PCR selection for the hardware TPM
++ * @auth1: [in, out] Authorization protocol parameters
++ * @sigSize: [out] The length of the returned digital signature
++ * @sig: [out] The resulting digital signature and PCR values
++ * Returns: TPM_SUCCESS on success, a TPM error code otherwise.
++ */
++TPM_RESULT TPM_DeepQuote(
++  TPM_NONCE *externalData,
++  TPM_PCR_SELECTION *myPCR,
++  TPM_PCR_SELECTION *ptPCR,
++  TPM_AUTH *auth1,
++  UINT32 *sigSize,
++  BYTE **sig
++);
++
+ /*
+  * Error handling
+  * [tpm_error.c]
+diff --git a/tpm/tpm_credentials.c b/tpm/tpm_credentials.c
+index 01f29e6..c0d62e7 100644
+--- a/tpm/tpm_credentials.c
++++ b/tpm/tpm_credentials.c
+@@ -211,3 +211,49 @@ TPM_RESULT TPM_ParentSignEK(TPM_NONCE *externalData, 
TPM_PCR_SELECTION *sel,
+       free_TPM_PUBKEY(pubKey);
+       return res;
+ }
++
++static const BYTE dquot_hdr[] = {
++      0, 0, 0, 0, 'D', 'Q', 'U', 'T'
++};
++
++TPM_RESULT TPM_DeepQuote(TPM_NONCE *externalData, TPM_PCR_SELECTION *myPCR,
++                         TPM_PCR_SELECTION *ptPCR, TPM_AUTH *auth1,
++                         UINT32 *sigSize, BYTE **sig)
++{
++      TPM_RESULT res;
++      TPM_DIGEST hres;
++      TPM_PCR_INFO_SHORT pcrData;
++      tpm_sha1_ctx_t ctx;
++      BYTE *buf, *ptr;
++      UINT32 size, len;
++
++      info("TPM_DeepQuote()");
++
++      res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, 
TPM_KH_OWNER);
++      if (res != TPM_SUCCESS) return res;
++
++      res = tpm_compute_pcr_digest(myPCR, &pcrData.digestAtRelease, NULL);
++      if (res != TPM_SUCCESS) return res;
++
++      pcrData.pcrSelection.sizeOfSelect = myPCR->sizeOfSelect;
++      memcpy(pcrData.pcrSelection.pcrSelect, myPCR->pcrSelect, 
myPCR->sizeOfSelect);
++      pcrData.localityAtRelease = 1 << tpmData.stany.flags.localityModifier;
++
++      size = len = sizeof_TPM_PCR_INFO_SHORT(pcrData);
++      buf = ptr = tpm_malloc(size);
++      if (buf == NULL) return TPM_NOSPACE;
++      if (tpm_marshal_TPM_PCR_INFO_SHORT(&ptr, &len, &pcrData))
++              return TPM_FAIL;
++
++      tpm_sha1_init(&ctx);
++      tpm_sha1_update(&ctx, dquot_hdr, 8);
++      tpm_sha1_update(&ctx, externalData->nonce, 20);
++      tpm_sha1_update(&ctx, buf, size);
++      tpm_sha1_final(&ctx, hres.digest);
++
++      tpm_free(buf);
++
++      res = VTPM_GetParentQuote(&hres, ptPCR, sigSize, sig);
++
++      return res;
++}
+diff --git a/tpm/tpm_structures.h b/tpm/tpm_structures.h
+index b0f4625..dfb1894 100644
+--- a/tpm/tpm_structures.h
++++ b/tpm/tpm_structures.h
+@@ -660,6 +660,42 @@ typedef struct tdTPM_CMK_MA_APPROVAL {
+ 
+ /* VTPM-only commands: */
+ /*
++ * Deep Quote - Create quote of PCRs
++ * Input:
++ *   TPM_TAG             tag           TPM_TAG_RQU_AUTH1_COMMAND
++ *   UINT32              paramSize     Total size of request
++ *   TPM_COMMAND_CODE    ordinal       TPM_ORD_DeepQuote
++ *   TPM_NONCE           externData    20 bytes of external data
++ *   TPM_PCR_SELECTION   vtSel         PCR selection for virtual TPM
++ *   TPM_PCR_SELECTION   ptSel         PCR selection for physical TPM
++ *   ---
++ *   UINT32              authHandle    Owner authorization session (OIAP)
++ *   TPM_NONCE           nonceOdd      Nonce for authHandle
++ *   BOOL                continueAuth  Continue flag for authHandle
++ *   TPM_AUTHDATA        privAuth      Authorization digest for command
++ *
++ * Output:
++ *   TPM_TAG             tag           TPM_TAG_RSP_AUTH1_COMMAND
++ *   UINT32              paramSize     Total size of response
++ *   TPM_RESULT          returnCode    Return code of the operation
++ *   BYTE[]              sig           Signature provided by physical TPM
++ *   TPM_PCRVALUE[]      pcrValue      Values of hardware PCRs used in the 
quote
++ *   ---
++ *   TPM_NONCE           nonceEven     Nonce for authHandle
++ *   BOOL                continueAuth  Continue flag for authHandle
++ *   TPM_AUTHDATA        resAuth       Authorization digest for response
++ *
++ * The values of the virutal TPM's PCRs are not included in the response.
++ * The signature is a standard TPM_Quote response from the physical TPM; its
++ * externalData is the SHA1 hash of the following structure:
++ *   TPM_STRUCT_VER      version       MUST be 0.0.0.0
++ *   BYTE[4]             fixed         MUST be the string "DQUT"
++ *   TPM_NONCE           externData    From input to the deep quote
++ *   TPM_PCR_INFO_SHORT  pcrData       Virtual TPM's PCRs
++ */
++#define TPM_ORD_DeepQuote                       (TPM_VENDOR_COMMAND | 
TPM_ORD_Quote)
++
++/*
+  * ParentSignEK - Proof of fresh provisioning and EK value
+  *
+  * Input:
-- 
1.8.5.3


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.