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

[Xen-devel] [PATCH 9/9] vtpmmgr: use XSM label as vTPM kernel hash



Because there is not currently a method for the vTPM Manager to obtain a
build hash of a vTPM, use the hash of the vTPM's XSM label as a
substitute.  This allows the vTPM Manager to distinguish between vTPMs
intended to be paired with a hardware domain kernel (which cannot use
pv-grub) and vTPMs which are paired with a pv-grub domain and therefore
contain reliable measurements of the guest kernel in PCRs 4 and 5.

Signed-off-by: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
---
 docs/misc/vtpm-platforms.txt       | 14 ++++++++++++++
 docs/misc/vtpmmgr.txt              | 10 ++++++----
 stubdom/vtpmmgr/init.c             |  2 ++
 stubdom/vtpmmgr/vtpm_cmd_handler.c | 34 ++++++++++++++++++++++++++++++++--
 stubdom/vtpmmgr/vtpmmgr.h          |  6 +++++-
 5 files changed, 59 insertions(+), 7 deletions(-)

diff --git a/docs/misc/vtpm-platforms.txt b/docs/misc/vtpm-platforms.txt
index fe35fb6..5a5f767 100644
--- a/docs/misc/vtpm-platforms.txt
+++ b/docs/misc/vtpm-platforms.txt
@@ -125,3 +125,17 @@ which requires the presence of a vTPM.  To bind the 
configuration of the guest
 to the vTPM, the guest may use full-disk encryption which can be unlocked using
 an unseal operation; using the wrong vTPM will then yield a non-functioning
 guest.
+
+In order to use pv-grub to obtain measurements of the guest kernel in PCRs 4 
and
+5, it must not be possible to attach to a guest's vTPM without booting a fresh
+guest image.  This requires pairing every vTPM's launch with the launch of a
+guest, as described above, and using the --vtpm-label= argument to pv-grub so
+that it refuses to launch a guest if it could not write to the vTPM.  To permit
+the hardware domain, which cannot use pv-grub, to use a vTPM in this situation,
+multiple vTPM groups must be used in the TPM Manager.  Group 0 would be for the
+hardware domain only, and would only support vTPMs with label
+"system_u:system_r:vtpm_t".  Group 1 would support vTPMs with label
+"*:vm_r:vtpm_t", and would be used for all guest vTPMs.  The EK quote used in
+initial provisioning and any deep quotes produced later would include the 
label,
+which would allow a verifier to reliably determine if the value of the vTPM's
+PCR 4 contains the hash of the domain's kernel.
diff --git a/docs/misc/vtpmmgr.txt b/docs/misc/vtpmmgr.txt
index fe3d8a6..026c52b 100644
--- a/docs/misc/vtpmmgr.txt
+++ b/docs/misc/vtpmmgr.txt
@@ -123,7 +123,9 @@ strengthen this assumption if the creation of vTPM-labeled 
domains is more
 constrained (for example, only permitted to a domain builder service): the only
 grants mapped by the TPM Manager should belong to vTPM domains, so restricting
 the ability to map other domain's granted pages will prevent other domains from
-directly requesting keys from the TPM Manager.
+directly requesting keys from the TPM Manager.  The TPM Manager uses the hash 
of
+the XSM label of the attached vTPM as the kernel hash, so vTPMs with distinct
+labels may be further partitioned using vTPM groups.
 
 A domain with direct access to the hardware TPM will be able to decrypt the TPM
 Manager's disk image if the haredware TPM's PCR values are in a permitted
@@ -158,6 +160,6 @@ would look like the following:
 6. Attach the vTPM migration domain's vtpm/1 device to the new vtpmmgr
 7. Migration domain executes vtpmmgr_SaveHashKey on vtpm/1
 
-This requires the migration domain must be added to the list of valid vTPM
-kernel hashes.  Because the TPM Manager currently does not verify vTPM kernel
-hashes, the control domain can initiate this operation at any time.
+This requires the migration domain to be added to the list of valid vTPM kernel
+hashes. In the current version of the vtpmmgr domain, this is the hash of the
+XSM label, not the kernel.
diff --git a/stubdom/vtpmmgr/init.c b/stubdom/vtpmmgr/init.c
index c35ab8f..f3aa02f 100644
--- a/stubdom/vtpmmgr/init.c
+++ b/stubdom/vtpmmgr/init.c
@@ -386,6 +386,8 @@ static void set_opaque(domid_t domid, unsigned int handle)
 
        opq = calloc(1, sizeof(*opq));
        opq->uuid = (uuid_t*)tpmback_get_uuid(domid, handle);
+       opq->domid = domid;
+       opq->handle = handle;
        tpmback_set_opaque(domid, handle, opq);
 }
 
diff --git a/stubdom/vtpmmgr/vtpm_cmd_handler.c 
b/stubdom/vtpmmgr/vtpm_cmd_handler.c
index f2869b6..000cce8 100644
--- a/stubdom/vtpmmgr/vtpm_cmd_handler.c
+++ b/stubdom/vtpmmgr/vtpm_cmd_handler.c
@@ -59,10 +59,40 @@ static void gen_random_uuid(uuid_t uuid)
        uuid[8] = 0x80 | (uuid[8] & 0x3F);
 }
 
+/*
+ * Instead of using a kernel hash, which requires a trusted domain builder to
+ * report, use the XSM label as a substitute.
+ */
 static TPM_RESULT find_vtpm_khash(int domid, struct tpm_opaque *opq)
 {
-       // TODO getting the build hashes requires a domain builder to report 
them
-       memset(opq->kern_hash, 0, sizeof(opq->kern_hash));
+       char buf[128];
+       int i, rv;
+       buf[127] = 0;
+       rv = tpmback_get_peercontext(opq->domid, opq->handle, buf, sizeof(buf) 
- 1);
+       if (rv < 0)
+               return TPM_FAIL;
+
+       sha1((void*)buf, strlen(buf), opq->kern_hash);
+
+       /*
+        * As a hack to support the use of the XSM user field as an optional
+        * wildcard, check the hash against the group here. If it fails, replace
+        * the user field with a "*" and return the hash of that value.
+        */
+       for(i=0; i < be32_native(opq->group->seal_bits.nr_kerns); i++) {
+               if (!memcmp(opq->group->seal_bits.kernels[i].bits, 
opq->kern_hash, 20)) {
+                       return TPM_SUCCESS;
+               }
+       }
+
+       char* upos = strchr(buf, ':');
+       if (upos == NULL || upos == buf)
+               return TPM_SUCCESS;
+
+       upos--;
+       upos[0] = '*';
+
+       sha1((void*)upos, strlen(upos), opq->kern_hash);
        return TPM_SUCCESS;
 }
 
diff --git a/stubdom/vtpmmgr/vtpmmgr.h b/stubdom/vtpmmgr/vtpmmgr.h
index 68edd4c..2d9d153 100644
--- a/stubdom/vtpmmgr/vtpmmgr.h
+++ b/stubdom/vtpmmgr/vtpmmgr.h
@@ -65,7 +65,11 @@ struct tpm_opaque {
        uuid_t *uuid;
        struct mem_group *group;
        struct mem_vtpm *vtpm;
-       uint8_t kern_hash[32];
+
+       domid_t domid;
+       unsigned int handle;
+
+       uint8_t kern_hash[20];
 };
 
 // --------------------------- Global Values --------------------------
-- 
1.9.0


_______________________________________________
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®.