|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] stubdom/grub: verify vTPM label if requested
commit 331d4b0eb8beb0af9c022de50cbf341e70c7ac80
Author: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
AuthorDate: Mon Apr 21 13:23:04 2014 -0400
Commit: Ian Campbell <ian.campbell@xxxxxxxxxx>
CommitDate: Wed Apr 23 11:58:15 2014 +0100
stubdom/grub: verify vTPM label if requested
This adds an optional argument --vtpm-label=<label> to the pv-grub
command line. If specified, a vtpm device must be connected to the
pv-grub domain and the backend of this device must have the given XSM
label (which may start with a * to indicate a wildcard). Verifying the
label of the vTPM before sending measurements prevents a disaggregated
control domain that has access to xenstore but not to the guest domains
from causing the measurements performed by pv-grub to be discarded,
allowing the forgery of arbitrary kernel measurements in the TPM.
Signed-off-by: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
Cc: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
Acked-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxx>
Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---
stubdom/grub/kexec.c | 58 ++++++++++++++++++++++++++++++++++++++++-------
stubdom/grub/mini-os.c | 8 +++++-
stubdom/grub/mini-os.h | 2 +
3 files changed, 58 insertions(+), 10 deletions(-)
diff --git a/stubdom/grub/kexec.c b/stubdom/grub/kexec.c
index cef357e..dc8db81 100644
--- a/stubdom/grub/kexec.c
+++ b/stubdom/grub/kexec.c
@@ -68,6 +68,14 @@ struct pcr_extend_cmd {
unsigned char hash[20];
} __attribute__((packed));
+struct pcr_extend_rsp {
+ uint16_t tag;
+ uint32_t size;
+ uint32_t status;
+
+ unsigned char hash[20];
+} __attribute__((packed));
+
/* Not imported from polarssl's header since the prototype unhelpfully defines
* the input as unsigned char, which causes pointer type mismatches */
void sha1(const void *input, size_t ilen, unsigned char output[20]);
@@ -135,20 +143,49 @@ int kexec_allocate(struct xc_dom_image *dom, xen_vaddr_t
up_to)
return 0;
}
+/* Filled from mini-os command line or left as NULL */
+char *vtpm_label;
+
static void tpm_hash2pcr(struct xc_dom_image *dom, char *cmdline)
{
struct tpmfront_dev* tpm = init_tpmfront(NULL);
- uint8_t *resp;
+ struct pcr_extend_rsp *resp;
size_t resplen = 0;
struct pcr_extend_cmd cmd;
+ int rv;
- /* If all guests have access to a vTPM, it may be useful to replace this
- * with ASSERT(tpm) to prevent configuration errors from allowing a
guest
- * to boot without a TPM (or with a TPM that has not been sent any
- * measurements, which could allow forging the measurements).
+ /*
+ * If vtpm_label was specified on the command line, require a vTPM to be
+ * attached and for the domain providing the vTPM to have the given
+ * label.
*/
- if (!tpm)
+ if (vtpm_label) {
+ char ctx[128];
+ if (!tpm) {
+ printf("No TPM found and vtpm_label specified,
aborting!\n");
+ do_exit();
+ }
+ rv = evtchn_get_peercontext(tpm->evtchn, ctx, sizeof(ctx) - 1);
+ if (rv < 0) {
+ printf("Could not verify vtpm_label: %d\n", rv);
+ do_exit();
+ }
+ ctx[127] = 0;
+ rv = strcmp(ctx, vtpm_label);
+ if (rv && vtpm_label[0] == '*') {
+ int match_len = strlen(vtpm_label) - 1;
+ int offset = strlen(ctx) - match_len;
+ if (offset > 0)
+ rv = strcmp(ctx + offset, vtpm_label + 1);
+ }
+
+ if (rv) {
+ printf("Mismatched vtpm_label: '%s' != '%s'\n", ctx,
vtpm_label);
+ do_exit();
+ }
+ } else if (!tpm) {
return;
+ }
cmd.tag = bswap_16(TPM_TAG_RQU_COMMAND);
cmd.size = bswap_32(sizeof(cmd));
@@ -156,15 +193,18 @@ static void tpm_hash2pcr(struct xc_dom_image *dom, char
*cmdline)
cmd.pcr = bswap_32(4); // PCR #4 for kernel
sha1(dom->kernel_blob, dom->kernel_size, cmd.hash);
- tpmfront_cmd(tpm, (void*)&cmd, sizeof(cmd), &resp, &resplen);
+ rv = tpmfront_cmd(tpm, (void*)&cmd, sizeof(cmd), (void*)&resp,
&resplen);
+ ASSERT(rv == 0 && resp->status == 0);
cmd.pcr = bswap_32(5); // PCR #5 for cmdline
sha1(cmdline, strlen(cmdline), cmd.hash);
- tpmfront_cmd(tpm, (void*)&cmd, sizeof(cmd), &resp, &resplen);
+ rv = tpmfront_cmd(tpm, (void*)&cmd, sizeof(cmd), (void*)&resp,
&resplen);
+ ASSERT(rv == 0 && resp->status == 0);
cmd.pcr = bswap_32(5); // PCR #5 for initrd
sha1(dom->ramdisk_blob, dom->ramdisk_size, cmd.hash);
- tpmfront_cmd(tpm, (void*)&cmd, sizeof(cmd), &resp, &resplen);
+ rv = tpmfront_cmd(tpm, (void*)&cmd, sizeof(cmd), (void*)&resp,
&resplen);
+ ASSERT(rv == 0 && resp->status == 0);
shutdown_tpmfront(tpm);
}
diff --git a/stubdom/grub/mini-os.c b/stubdom/grub/mini-os.c
index 9d4bcc7..4fc052a 100644
--- a/stubdom/grub/mini-os.c
+++ b/stubdom/grub/mini-os.c
@@ -735,8 +735,14 @@ void __attribute__ ((noreturn)) grub_reboot (void)
* for grub's 32bit pointers to work */
char grub_scratch_mem[SCRATCH_MEMSIZE] __attribute__((aligned(PAGE_SIZE)));
-int main(int argc, char *argv[])
+int main(int argc, char **argv)
{
+ if (argc > 1 && memcmp(argv[1], "--vtpm-label=", 13) == 0) {
+ vtpm_label = argv[1] + 13;
+ argc--;
+ argv++;
+ }
+
if (argc > 1) {
strncpy(config_file, argv[1], sizeof(config_file) - 1);
config_file[sizeof(config_file) - 1] = 0;
diff --git a/stubdom/grub/mini-os.h b/stubdom/grub/mini-os.h
index 6c68441..9ec2bda 100644
--- a/stubdom/grub/mini-os.h
+++ b/stubdom/grub/mini-os.h
@@ -3,3 +3,5 @@ extern struct blkfront_dev **blk_dev;
extern struct netfront_dev *net_dev;
extern struct kbdfront_dev *kbd_dev;
extern struct fbfront_dev *fb_dev;
+
+extern char* vtpm_label;
--
generated by git-patchbot for /home/xen/git/xen.git#master
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |