static int handle_emuldev_command(int devfd) { ssize_t in_len; uint32_t out_len; uint8_t in[TPM_CMD_BUF_SIZE], *out; int res; debug("waiting for commands..."); in_len = read(devfd, in, sizeof(in)); debug("received %d bytes", in_len); if (in_len <= 0) return errno == -EAGAIN ? 0 : in_len; out = NULL; res = tpm_handle_command(in, in_len, &out, &out_len); if (res < 0) { error("tpm_handle_command() failed"); if (ioctl(devfd, 0, 0) < 0) return -1; } else { debug("sending %d bytes", out_len); res = write(devfd, out, out_len); if (res < 0) { error("write(%d) failed: %s", out_len, strerror(errno)); if (errno != ECANCELED) return -1; } } tpm_free(out); return 0; }
int main(void) { unsigned int in_size; unsigned char *buf; unsigned int out_size; out_size = MAX_BUF - sizeof(unsigned int); pInOutBuf = InOutBuf; originInOutBuf = InOutBuf; memcpy(&in_size, InOutBuf, sizeof(unsigned int)); if (in_size == 0xffffffff) { // use rockey for the first time; tpm_engine_first_time(); return 0; } buf = InOutBuf+ sizeof(unsigned int); if (tpm_engine_init() != 0) { return -1; } if (tpm_handle_command(buf, in_size, buf, &out_size) != 0) return -1; if (tpm_engine_final() != 0) { return -1; } memcpy(InOutBuf, &out_size, sizeof(unsigned int)); return 0; }
static void main_loop(void) { tpmcmd_t* tpmcmd = NULL; int res = -1; info("VTPM Initializing\n"); /* Set required tpm config args */ opt_args.tpmconf |= TPM_CONF_STRONG_PERSISTENCE; opt_args.tpmconf &= ~TPM_CONF_USE_INTERNAL_PRNG; opt_args.tpmconf |= TPM_CONF_GENERATE_EK; opt_args.tpmconf |= TPM_CONF_GENERATE_SEED_DAA; /* Initialize the emulator */ tpm_emulator_init(opt_args.startup, opt_args.tpmconf); /* Initialize any requested PCRs with hardware TPM values */ if(vtpm_initialize_hw_pcrs(tpmfront_dev, opt_args.hwinitpcrs) != TPM_SUCCESS) { error("Failed to initialize PCRs with hardware TPM values"); goto abort_postpcrs; } tpmcmd = tpmback_req_any(); while(tpmcmd) { /* Handle the request */ if(tpmcmd->req_len) { uint8_t* locality_mask = tpmcmd->opaque; uint8_t locality_bit = (1 << (tpmcmd->locality & 7)); int locality_byte = tpmcmd->locality >> 3; tpmcmd->resp = NULL; tpmcmd->resp_len = 0; if (nr_client_localities && !locality_mask) locality_mask = generate_locality_mask(tpmcmd->domid, tpmcmd->handle); if (nr_client_localities && !locality_mask) { error("Unknown client label in tpm_handle_command"); create_error_response(tpmcmd, TPM_FAIL); } else if (nr_client_localities && !(locality_mask[locality_byte] & locality_bit)) { error("Invalid locality (%d) for client in tpm_handle_command", tpmcmd->locality); create_error_response(tpmcmd, TPM_FAIL); } /* Check for TPM Manager passthrough command */ else if(check_passthru(tpmcmd)) { } /* Check for disabled ordinals */ else if(!check_ordinal(tpmcmd)) { create_error_response(tpmcmd, TPM_BAD_ORDINAL); } /* If not disabled, do the command */ else { if((res = tpm_handle_command(tpmcmd->req, tpmcmd->req_len, &tpmcmd->resp, &tpmcmd->resp_len, tpmcmd->locality)) != 0) { error("tpm_handle_command() failed"); create_error_response(tpmcmd, TPM_FAIL); } } } /* Send the response */ tpmback_resp(tpmcmd); /* Wait for the next request */ tpmcmd = tpmback_req_any(); }
static void main_loop(void) { int sock = -1, devfd = -1, fh, res, npoll; int32_t in_len; uint32_t out_len; uint8_t in[TPM_CMD_BUF_SIZE], *out; struct sockaddr_un addr; socklen_t addr_len; struct pollfd poll_table[2]; info("staring main loop"); /* open UNIX socket */ if (opt_socket_name) { sock = init_socket(opt_socket_name); if (sock < 0) exit(EXIT_FAILURE); } if (opt_dev_name) { devfd = init_device(opt_dev_name); if (devfd < 0) exit(EXIT_FAILURE); } /* init tpm emulator */ debug("initializing TPM emulator"); if (tpm_emulator_init(tpm_startup, tpm_config) != 0) { error("tpm_emulator_init() failed"); close(sock); unlink(opt_socket_name); exit(EXIT_FAILURE); } /* start command processing */ while (!stopflag) { /* wait for incomming connections */ debug("waiting for connections..."); npoll = 0; if (sock != -1) { poll_table[npoll].fd = sock; poll_table[npoll].events = POLLIN; poll_table[npoll++].revents = 0; } if (devfd != -1) { poll_table[npoll].fd = devfd; poll_table[npoll].events = POLLIN | POLLERR; poll_table[npoll++].revents = 0; } res = poll(poll_table, npoll, -1); if (res < 0) { error("poll(sock,dev) failed: %s", strerror(errno)); break; } if (devfd != -1 && poll_table[npoll - 1].revents) { /* if POLLERR was set, let read() handle it */ if (handle_emuldev_command(devfd) < 0) break; } if (sock == -1 || !poll_table[0].revents) continue; /* Beyond this point, npoll will always be 1 if the emulator device is * not open and 2 if it is, so we can just fill in the second slot of * the poll table unconditionally and rely on passing npoll to poll(). */ addr_len = sizeof(addr); fh = accept(sock, (struct sockaddr*)&addr, &addr_len); if (fh < 0) { error("accept() failed: %s", strerror(errno)); continue; } /* receive and handle commands */ in_len = 0; do { debug("waiting for commands..."); poll_table[0].fd = fh; poll_table[0].events = POLLIN; poll_table[0].revents = 0; poll_table[1].fd = devfd; poll_table[1].events = POLLIN | POLLERR; poll_table[1].revents = 0; res = poll(poll_table, npoll, TPM_COMMAND_TIMEOUT); if (res < 0) { error("poll(fh) failed: %s", strerror(errno)); close(fh); break; } else if (res == 0) { #ifdef TPMD_DISCONNECT_IDLE_CLIENTS info("connection closed due to inactivity"); close(fh); break; #else continue; #endif } if (poll_table[1].revents) { /* if POLLERR was set, let read() handle it */ if (handle_emuldev_command(devfd) < 0) break; } if (!poll_table[0].revents) continue; in_len = read(fh, in, sizeof(in)); if (in_len > 0) { debug("received %d bytes", in_len); out = NULL; res = tpm_handle_command(in, in_len, &out, &out_len); if (res < 0) { error("tpm_handle_command() failed"); } else { debug("sending %d bytes", out_len); uint32_t len = 0; while (len < out_len) { res = write(fh, &out[len], out_len - len); if (res < 0) { error("write(%d) failed: %s", out_len - len, strerror(errno)); break; } len += res; } tpm_free(out); } } } while (in_len > 0); close(fh); } /* shutdown tpm emulator */ tpm_emulator_shutdown(); /* close socket */ close(sock); unlink(opt_socket_name); info("main loop stopped"); }