Author: Daniel De Graaf ================================================================================ Overview ================================================================================ This document describes example platforms which use virtual TPMs to provide security properties for guests running on the platforms. There are several tradeoffs between flexibility and trust which must be considered when implementing a platform containing vTPMs. ================================================================================ Example 1: Trusted Domain 0 ================================================================================ This is the simplest example and provides maximal flexibility for testing the vTPM Manager and vTPMs. The vtpmmgr, vtpm, and guest domains are created using xl from the command line on domain 0. Provisioning on domain 0: # dd if=/dev/zero of=/images/vtpmmgr-stubdom.img bs=2M count=1 # dd if=/dev/zero of=/images/vtpm-guest1.img bs=2M count=1 # dd if=/dev/zero of=/images/vtpm-guest2.img bs=2M count=1 The vtpmmgr configuration file (vtpmmgr.cfg): name="vtpmmgr" kernel="/usr/lib/xen/boot/vtpmmgr-stubdom.gz" extra="tpmlocality=2" memory=8 disk=["file:/images/vtpmmgr-stubdom.img,hda,w"] iomem=["fed42,1"] The vtpm configuration files (vtpm-guest1.cfg, vtpm-guest2.cfg): name="vtpm-guest1" kernel="/usr/lib/xen/boot/vtpm-stubdom.gz" extra="loglevel=debug" memory=8 disk=["file:/images/vtpm-guest1.img,hda,w"] vtpm=["backend=vtpmmgr,uuid=ac0a5b9e-cbe2-4c07-b43b-1d69e46fb839"] name="vtpm-guest2" kernel="/usr/lib/xen/boot/vtpm-stubdom.gz" extra="loglevel=debug" memory=8 disk=["file:/images/vtpm-guest2.img,hda,w"] vtpm=["backend=vtpmmgr,uuid=6c3ff5f1-8d58-4fed-b00d-a5ea9a817f7f"] The guest configuration files (guest1.cfg, guest2.cfg): name="guest1" kernel="/usr/lib/xen/boot/pv-grub-x86_64.gz" memory=1024 disk=["file:/images/guest1.img,xvda,w"] vif=['mac=00:01:02:03:04:05,bridge=br0'] vtpm=["backend=vtpm-guest1"] name="guest2" kernel="/usr/lib/xen/boot/pv-grub-x86_64.gz" memory=1024 disk=["file:/images/guest2.img,xvda,w"] vif=['mac=00:01:02:03:04:06,bridge=br0'] vtpm=["backend=vtpm-guest2"] Starting domains: # xl create vtpmmgr.cfg # xl create vtpm-guest1.cfg # xl create guest1.cfg ================================================================================ Example 2: Domain Builder with Static vTPMs ================================================================================ This example uses the domain builder to construct a TPM Manager and vTPM which do not require trusting the hardware domain with the vTPM's secrets. However, it is not possible to construct additional vTPMs after the system is booted, and the guests with access to vTPMs may not be rebooted without rebooting the entire platform. The domain builder (dom0) constructs: dom1 - xenstore system_u:system_r:xenstore_t dom2 - hardware system_u:system_r:hwdom_t dom3 - vtpmmgr system_u:system_r:vtpmmgr_t dom4 - vtpm-hw system_u:system_r:vtpm_t dom5 - vtpm-g1 guest1_u:vm_r:vtpm_t dom6 - vtpm-g2 guest2_u:vm_r:vtpm_t dom7 - guest1 guest1_u:vm_r:guest_t dom8 - guest2 guest2_u:vm_r:guest_t It unpauses dom1 and dom2 after setting up Xenstore. The hardware domain is not permitted access to IO memory at 0xfed42; this IO memory is accessible to the vtpmmgr domain. The two guest domains may be instantiated using pv-grub or using the same kernel as the hardware domain to conserve space in the domain builder's initrd. Once the hardware domain boots, it runs: # xl block-attach vtpmmgr 'backendtype=phy,backend=hardware,vdev=hda,access=w,target=/dev/lvm/vtpmmgr' # xl block-attach vtpm-hw 'backendtype=phy,backend=hardware,vdev=hda,access=w,target=/dev/lvm/vtpm-hw' # xl block-attach vtpm-g1 'backendtype=phy,backend=hardware,vdev=hda,access=w,target=/dev/lvm/vtpm-g1' # xl block-attach vtpm-g2 'backendtype=phy,backend=hardware,vdev=hda,access=w,target=/dev/lvm/vtpm-g2' # xl block-attach guest1 'backendtype=phy,backend=hardware,vdev=xvda,access=w,target=/dev/lvm/guest1' # xl block-attach guest2 'backendtype=phy,backend=hardware,vdev=xvda,access=w,target=/dev/lvm/guest2' # xl vtpm-attach vtpm-hw uuid=062b6416-ed46-492a-9e65-a2f92dc07f7f backend=vtpmmgr # xl vtpm-attach vtpm-g1 uuid=e9aa9d0f-ece5-4b84-b129-93004ba61a5f backend=vtpmmgr # xl vtpm-attach vtpm-g2 uuid=3fb2caf0-d305-4516-96c7-420618d98efb backend=vtpmmgr # xl vtpm-attach hardware uuid=062b6416-ed46-492a-9e65-a2f92dc07f7f backend=vtpm-hw # xl vtpm-attach guest1 uuid=e9aa9d0f-ece5-4b84-b129-93004ba61a5f backend=vtpm-g1 # xl vtpm-attach guest2 uuid=3fb2caf0-d305-4516-96c7-420618d98efb backend=vtpm-g2 Once these commands are complete, the domains are unpaused and may boot. The XSM policy must be configured to not allow any of the domain types named above to be created by any domain except the domain builder; guests created by the hardware domain or one of the primary guests acting as a control domain must have a different type. The type vtpmmgr_t may only map grants from vtpm_t; vtpm_t may only map grants from a domain of type guest_t or hwdom_t with the same user field. This example may be extended to allow dynamic creation of domains by using a domain builder that accepts build requests. A single build request would create a pair of domains using an unused XSM user field: a vTPM and a pv-grub domain 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.