|
[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 |