[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 8/9] stubdom/grub: verify vTPM label if requested
Daniel De Graaf, le Mon 21 Apr 2014 13:23:04 -0400, a écrit : > 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> > Cc: Samuel Thibault <samuel.thibault@xxxxxxxxxxxx> Acked-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxx> > --- > 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; > -- > 1.9.0 > -- Samuel There are two types of Linux developers - those who can spell, and those who can't. There is a constant pitched battle between the two. (From one of the post-1.1.54 kernel update messages posted to c.o.l.a) _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |