[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.