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.
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
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.
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);
}
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;
}
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 --------------------------