static void tpm_hash2pcr(struct xc_dom_image *dom, char *cmdline) { struct tpmfront_dev* tpm = init_tpmfront(NULL); uint8_t *resp; size_t resplen = 0; struct pcr_extend_cmd cmd; /* 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 (!tpm) return; cmd.tag = bswap_16(TPM_TAG_RQU_COMMAND); cmd.size = bswap_32(sizeof(cmd)); cmd.ord = bswap_32(TPM_ORD_Extend); 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); cmd.pcr = bswap_32(5); // PCR #5 for cmdline sha1(cmdline, strlen(cmdline), cmd.hash); tpmfront_cmd(tpm, (void*)&cmd, sizeof(cmd), &resp, &resplen); 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); shutdown_tpmfront(tpm); }
int close(int fd) { printk("close(%d)\n", fd); switch (files[fd].type) { default: files[fd].type = FTYPE_NONE; return 0; #ifdef CONFIG_XENBUS case FTYPE_XENBUS: xs_daemon_close((void*)(intptr_t) fd); return 0; #endif #ifdef HAVE_LWIP case FTYPE_SOCKET: { int res = lwip_close(files[fd].socket.fd); files[fd].type = FTYPE_NONE; return res; } #endif #ifdef CONFIG_XC case FTYPE_XC: minios_interface_close_fd(fd); return 0; case FTYPE_EVTCHN: minios_evtchn_close_fd(fd); return 0; case FTYPE_GNTMAP: minios_gnttab_close_fd(fd); return 0; #endif #ifdef CONFIG_NETFRONT case FTYPE_TAP: shutdown_netfront(files[fd].tap.dev); files[fd].type = FTYPE_NONE; return 0; #endif #ifdef CONFIG_BLKFRONT case FTYPE_BLK: shutdown_blkfront(files[fd].blk.dev); files[fd].type = FTYPE_NONE; return 0; #endif #ifdef CONFIG_TPMFRONT case FTYPE_TPMFRONT: shutdown_tpmfront(files[fd].tpmfront.dev); files[fd].type = FTYPE_NONE; return 0; #endif #ifdef CONFIG_TPM_TIS case FTYPE_TPM_TIS: shutdown_tpm_tis(files[fd].tpm_tis.dev); files[fd].type = FTYPE_NONE; return 0; #endif #ifdef CONFIG_KBDFRONT case FTYPE_KBD: shutdown_kbdfront(files[fd].kbd.dev); files[fd].type = FTYPE_NONE; return 0; #endif #ifdef CONFIG_FBFRONT case FTYPE_FB: shutdown_fbfront(files[fd].fb.dev); files[fd].type = FTYPE_NONE; return 0; #endif #ifdef CONFIG_CONSFRONT case FTYPE_SAVEFILE: case FTYPE_CONSOLE: fini_console(files[fd].cons.dev); files[fd].type = FTYPE_NONE; return 0; #endif case FTYPE_NONE: break; } printk("close(%d): Bad descriptor\n", fd); errno = EBADF; return -1; }
static void tpm_hash2pcr(struct xc_dom_image *dom, char *cmdline) { struct tpmfront_dev* tpm = init_tpmfront(NULL); struct pcr_extend_rsp *resp; size_t resplen = 0; struct pcr_extend_cmd cmd; int rv; /* * 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 (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)); cmd.ord = bswap_32(TPM_ORD_Extend); cmd.pcr = bswap_32(4); // PCR #4 for kernel sha1(dom->kernel_blob, dom->kernel_size, cmd.hash); 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); 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->modules[0].blob, dom->modules[0].size, cmd.hash); rv = tpmfront_cmd(tpm, (void*)&cmd, sizeof(cmd), (void*)&resp, &resplen); ASSERT(rv == 0 && resp->status == 0); shutdown_tpmfront(tpm); }
struct tpmfront_dev* init_tpmfront(const char* _nodename) { struct tpmfront_dev* dev; const char* nodename; char path[512]; char* value, *err; unsigned long long ival; printk("============= Init TPM Front ================\n"); dev = malloc(sizeof(struct tpmfront_dev)); memset(dev, 0, sizeof(struct tpmfront_dev)); #ifdef HAVE_LIBC dev->fd = -1; #endif nodename = _nodename ? _nodename : "device/vtpm/0"; dev->nodename = strdup(nodename); init_waitqueue_head(&dev->waitq); /* Get backend domid */ snprintf(path, 512, "%s/backend-id", dev->nodename); if((err = xenbus_read(XBT_NIL, path, &value))) { TPMFRONT_ERR("Unable to read %s during tpmfront initialization! error = %s\n", path, err); free(err); goto error; } if(sscanf(value, "%llu", &ival) != 1) { TPMFRONT_ERR("%s has non-integer value (%s)\n", path, value); free(value); goto error; } free(value); dev->bedomid = ival; /* Get backend xenstore path */ snprintf(path, 512, "%s/backend", dev->nodename); if((err = xenbus_read(XBT_NIL, path, &dev->bepath))) { TPMFRONT_ERR("Unable to read %s during tpmfront initialization! error = %s\n", path, err); free(err); goto error; } /* Publish protocol v2 feature */ snprintf(path, 512, "%s/feature-protocol-v2", dev->nodename); if ((err = xenbus_write(XBT_NIL, path, "1"))) { TPMFRONT_ERR("Unable to write feature-protocol-v2 node: %s\n", err); free(err); goto error; } /* Create and publish grant reference and event channel */ if (tpmfront_connect(dev)) { goto error; } /* Wait for backend to connect */ if( wait_for_backend_state_changed(dev, XenbusStateConnected)) { goto error; } /* Ensure backend is also using protocol v2 */ snprintf(path, 512, "%s/feature-protocol-v2", dev->bepath); if((err = xenbus_read(XBT_NIL, path, &value))) { TPMFRONT_ERR("Unable to read %s during tpmfront initialization! error = %s\n", path, err); free(err); goto error; } if(strcmp(value, "1")) { TPMFRONT_ERR("%s has an invalid value (%s)\n", path, value); free(value); goto error; } free(value); TPMFRONT_LOG("Initialization Completed successfully\n"); return dev; error: shutdown_tpmfront(dev); return NULL; }