diff -uprN tpm_emulator/AUTHORS vtpm/AUTHORS --- tpm_emulator/AUTHORS 2006-12-08 12:51:29.000000000 -0800 +++ vtpm/AUTHORS 2006-12-13 16:38:52.000000000 -0800 @@ -1,3 +1,3 @@ Mario Strasser Heiko Stamer [DAA] -INTEL Corp <> [Dropped to Ring3] +INTEL Corp <> [VTPM Extensions] diff -uprN tpm_emulator/ChangeLog vtpm/ChangeLog --- tpm_emulator/ChangeLog 2006-12-08 12:51:29.000000000 -0800 +++ vtpm/ChangeLog 2006-12-13 16:38:52.000000000 -0800 @@ -1,5 +1,6 @@ ????-??-?? Intel Corp * Moved module out of kernel to run as a ring 3 app + * Modified save_to_file and load_from_file to call xen VTPM manager 2006-06-23 Mario Strasser * tpm_startup.c: behaviour of ST_CLEAR and storage of diff -uprN tpm_emulator/linux_module.h vtpm/linux_module.h --- tpm_emulator/linux_module.h 2006-12-08 12:51:29.000000000 -0800 +++ vtpm/linux_module.h 2007-01-09 14:49:06.000000000 -0800 @@ -44,18 +44,26 @@ #define TPM_DEVICE_NAME "tpm" #define TPM_MODULE_NAME "tpm_emulator" +/* debug and log output functions */ +extern int dmi_id; + #ifdef DEBUG -#define debug(fmt, ...) printf("TPMD: %s:%d: Debug: " fmt "\n", \ - __FILE__, __LINE__, ## __VA_ARGS__) +#define debug(fmt, ...) printf("TPMD[%d]: %s:%d: Debug: " fmt "\n", \ + dmi_id, __FILE__, __LINE__, ## __VA_ARGS__) +#define debug_nostop(fmt, ...) printf("TPMD[%d]: %s:%d: Debug: " fmt, \ + dmi_id, __FILE__, __LINE__, ## __VA_ARGS__) +#define debug_more(fmt, ...) printf( fmt, ## __VA_ARGS__ ) #else #define debug(fmt, ...) +#define debug_nostop(fmt, ...) +#define debug_more(fmt, ...) #endif -#define info(fmt, ...) printf("TPMD: %s:%d: Info: " fmt "\n", \ - __FILE__, __LINE__, ## __VA_ARGS__) -#define error(fmt, ...) printf("TPMD: %s:%d: Error: " fmt "\n", \ - __FILE__, __LINE__, ## __VA_ARGS__) -#define alert(fmt, ...) printf("TPMD: %s:%d: Alert: " fmt "\n", \ - __FILE__, __LINE__, ## __VA_ARGS__) +#define info(fmt, ...) printf("TPMD[%d]: %s:%d: Info: " fmt "\n", \ + dmi_id, __FILE__, __LINE__, ## __VA_ARGS__) +#define error(fmt, ...) printf("TPMD[%d]: %s:%d: Error: " fmt "\n", \ + dmi_id, __FILE__, __LINE__, ## __VA_ARGS__) +#define alert(fmt, ...) printf("TPMD[%d]: %s:%d: Alert: " fmt "\n", \ + dmi_id, __FILE__, __LINE__, ## __VA_ARGS__) /* memory allocation */ diff -uprN tpm_emulator/Makefile vtpm/Makefile --- tpm_emulator/Makefile 2006-12-08 12:51:29.000000000 -0800 +++ vtpm/Makefile 2006-12-13 16:38:52.000000000 -0800 @@ -7,7 +7,7 @@ COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/) # module settings -BIN := tpm_emulator +BIN := vtpmd VERSION_MAJOR := 0 VERSION_MINOR := 4 VERSION_BUILD := $(shell date +"%s") @@ -22,7 +22,7 @@ TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin CC := gcc CFLAGS += -g -Wall $(INCLUDE) -DDEBUG -CFLAGS += -I. -Itpm +CFLAGS += -I. -Itpm -I../../vtpm_manager/manager # Is the simulator running in it's own vm? #CFLAGS += -DVTPM_MULTI_VM @@ -62,7 +62,6 @@ $(BIN): $(src)/crypto/gmp.h $(src)/crypt install: $(BIN) $(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR) - @if [ ! -d "/var/tpm" ]; then mkdir /var/tpm; fi clean: rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a $(OBJS) @@ -98,3 +97,4 @@ version: @echo "#endif /* _TPM_VERSION_H_ */" >> $(src)/tpm_version.h .PHONY: all install clean dist gmp version + diff -uprN tpm_emulator/tpm/tpm_capability.c vtpm/tpm/tpm_capability.c --- tpm_emulator/tpm/tpm_capability.c 2006-06-23 03:37:07.000000000 -0700 +++ vtpm/tpm/tpm_capability.c 2007-01-10 10:00:49.000000000 -0800 @@ -136,8 +136,18 @@ static TPM_RESULT cap_property(UINT32 su case TPM_CAP_PROP_TIS_TIMEOUT: debug("[TPM_CAP_PROP_TIS_TIMEOUT]"); - /* TODO: TPM_CAP_PROP_TIS_TIMEOUT */ - return TPM_FAIL; + /* TODO: TPM_CAP_PROP_TIS_TIMEOUT: Measure these values and determine correct ones */ + UINT32 len = *respSize = 16; + BYTE *ptr = *resp = tpm_malloc(*respSize); + if (ptr == NULL || + tpm_marshal_UINT32(&ptr, &len, 200000) || + tpm_marshal_UINT32(&ptr, &len, 200000) || + tpm_marshal_UINT32(&ptr, &len, 200000) || + tpm_marshal_UINT32(&ptr, &len, 200000)) { + tpm_free(*resp); + return TPM_FAIL; + } + return TPM_SUCCESS; case TPM_CAP_PROP_STARTUP_EFFECT: debug("[TPM_CAP_PROP_STARTUP_EFFECT]"); @@ -190,7 +200,11 @@ static TPM_RESULT cap_property(UINT32 su case TPM_CAP_PROP_DURATION: debug("[TPM_CAP_PROP_DURATION]"); - /* TODO: TPM_CAP_PROP_DURATION */ + /* TODO: TPM_CAP_PROP_DURATION: Measure these values and return accurate ones */ + BYTE dur[]= {0x0,0x0,0x0,0xc,0x0,0x7,0xa1,0x20,0x0,0x1e,0x84,0x80,0x11,0xe1,0xa3,0x0}; + *respSize = 16; + *resp = tpm_malloc(*respSize); + memcpy(*resp,dur,16); return TPM_FAIL; case TPM_CAP_PROP_ACTIVE_COUNTER: diff -uprN tpm_emulator/tpm/tpm_cmd_handler.c vtpm/tpm/tpm_cmd_handler.c --- tpm_emulator/tpm/tpm_cmd_handler.c 2008-02-27 16:35:41.000000000 -0500 +++ vtpm/tpm/tpm_cmd_handler.c 2008-02-28 14:43:28.000000000 -0500 @@ -94,12 +94,18 @@ void tpm_compute_out_param_digest(TPM_CO sha1_ctx_t sha1; UINT32 res = CPU_TO_BE32(rsp->result); UINT32 ord = CPU_TO_BE32(ordinal); + UINT32 offset = 0; /* compute SHA1 hash */ sha1_init(&sha1); sha1_update(&sha1, (BYTE*)&res, 4); sha1_update(&sha1, (BYTE*)&ord, 4); - sha1_update(&sha1, rsp->param, rsp->paramSize); + if (ordinal == TPM_ORD_LoadKey2) { + offset = 4; + } + if (rsp->paramSize - offset > 0) { + sha1_update(&sha1, rsp->param + offset, rsp->paramSize - offset); + } sha1_final(&sha1, rsp->auth1->digest); if (rsp->auth2 != NULL) memcpy(rsp->auth2->digest, rsp->auth1->digest, sizeof(rsp->auth1->digest)); diff -uprN tpm_emulator/tpm/tpm_data.c vtpm/tpm/tpm_data.c --- tpm_emulator/tpm/tpm_data.c 2008-02-27 16:35:41.000000000 -0500 +++ vtpm/tpm/tpm_data.c 2008-02-27 16:35:40.000000000 -0500 @@ -1,6 +1,7 @@ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux * Copyright (C) 2004 Mario Strasser , * Swiss Federal Institute of Technology (ETH) Zurich + * Copyright (C) 2005 INTEL Corp * * This module is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published @@ -15,10 +16,15 @@ * $Id: tpm_data.c 98 2006-05-07 14:16:29Z hstamer $ */ +#include +#include +#include +#include + #include "tpm_emulator.h" #include "tpm_structures.h" #include "tpm_marshalling.h" -#include "linux_module.h" +#include "vtpm_manager.h" TPM_DATA tpmData; @@ -158,45 +164,232 @@ void tpm_release_data(void) #include #include #include -#include -#define TPM_STORAGE_FILE "/var/tpm/tpm_emulator-1.2." STR(VERSION_MAJOR) "." STR(VERSION_MINOR) + static int vtpm_tx_fh=-1, vtpm_rx_fh=-1; + +#ifdef VTPM_MUTLI_VM + #define DEV_FE "/dev/tpm" +#else + #define VTPM_RX_FIFO_D "/var/vtpm/fifos/vtpm_rsp_to_%d.fifo" + #define VTPM_TX_FIFO "/var/vtpm/fifos/vtpm_cmd_from_all.fifo" + + extern int dmi_id; + static char *vtpm_rx_name=NULL; +#endif static int write_to_file(uint8_t *data, size_t data_length) { - int res; - int fp; - fp = open(TPM_STORAGE_FILE, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR); - res = write(fp, data, data_length); - close(fp); - return (res == data_length) ? 0 : -1; + int res, out_data_size, in_header_size; + BYTE *ptr, *out_data, *in_header; + UINT32 result, len, in_rsp_size; + UINT16 tag = VTPM_TAG_REQ; + + printf("Saving NVM\n"); + if (vtpm_tx_fh < 0) { +#ifdef VTPM_MUTLI_VM + vtpm_tx_fh = open(DEV_FE, O_RDWR); +#else + vtpm_tx_fh = open(VTPM_TX_FIFO, O_WRONLY); +#endif + } + + if (vtpm_tx_fh < 0) { + return -1; + } + + // Send request to VTPM Manager to encrypt data +#ifdef VTPM_MUTLI_VM + out_data_size = len = VTPM_COMMAND_HEADER_SIZE_CLT + data_length; +#else + out_data_size = len = VTPM_COMMAND_HEADER_SIZE_SRV + data_length; +#endif + + out_data = ptr = (BYTE *) malloc(len); + + if (ptr == NULL +#ifndef VTPM_MUTLI_VM + || tpm_marshal_UINT32(&ptr, &len, dmi_id) +#endif + || tpm_marshal_UINT16(&ptr, &len, tag) +#ifdef VTPM_MUTLI_VM + || tpm_marshal_UINT32(&ptr, &len, out_data_size) +#else + || tpm_marshal_UINT32(&ptr, &len, out_data_size - sizeof(uint32_t)) +#endif + || tpm_marshal_UINT32(&ptr, &len, VTPM_ORD_SAVENVM) + || tpm_marshal_BYTE_ARRAY(&ptr, &len, data, data_length)) { + free(out_data); + return -1; + } + + printf("\tSending SaveNVM Command.\n"); + res = write(vtpm_tx_fh, out_data, out_data_size); + free(out_data); + if (res != out_data_size) return -1; + + if (vtpm_rx_fh < 0) { +#ifdef VTPM_MUTLI_VM + vtpm_rx_fh = vtpm_tx_fh +#else + if (vtpm_rx_name == NULL) { + vtpm_rx_name = malloc(10 + strlen(VTPM_RX_FIFO_D)); + sprintf(vtpm_rx_name, VTPM_RX_FIFO_D, (uint32_t) dmi_id); + } + vtpm_rx_fh = open(vtpm_rx_name, O_RDONLY); +#endif + } + + if (vtpm_rx_fh < 0) { + return -1; + } + + // Read Header of response so we can get the size & status +#ifdef VTPM_MUTLI_VM + in_header_size = len = VTPM_COMMAND_HEADER_SIZE_CLT; +#else + in_header_size = len = VTPM_COMMAND_HEADER_SIZE_SRV; +#endif + in_header = ptr = malloc(in_header_size); + + printf("\tReading SaveNVM header.\n"); + res = read(vtpm_rx_fh, in_header, in_header_size); + + if ( (res != in_header_size) +#ifndef VTPM_MUTLI_VM + || tpm_unmarshal_UINT32(&ptr, &len, (UINT32*)&dmi_id) +#endif + || tpm_unmarshal_UINT16(&ptr, &len, &tag) + || tpm_unmarshal_UINT32(&ptr, &len, &in_rsp_size) + || tpm_unmarshal_UINT32(&ptr, &len, &result) ) { + free(in_header); + return -1; + } + free(in_header); + + if (result != VTPM_SUCCESS) { + return -1; + } + +#ifdef VTPM_MUTLI_VM + close(vtpm_tx_fh); close(vtpm_rx_fh); +#endif + + printf("\tFinishing up SaveNVM\n"); + return (0); } static int read_from_file(uint8_t **data, size_t *data_length) { - int res; - int fp, file_status; - struct stat file_info; - fp = open(TPM_STORAGE_FILE, O_RDONLY, 0); - file_status = fstat(fp, &file_info); - if (file_status < 0) { - close(fp); - return -1; - } + int res, out_data_size, in_header_size; + uint8_t *ptr, *out_data, *in_header; + UINT16 tag = VTPM_TAG_REQ; + UINT32 len, in_rsp_size, result; +#ifdef VTPM_MUTLI_VM + int vtpm_rx_fh, vtpm_tx_fh; +#endif + + printf("Loading NVM.\n"); + if (vtpm_tx_fh < 0) { +#ifdef VTPM_MUTLI_VM + vtpm_tx_fh = open(DEV_FE, O_RDWR); +#else + vtpm_tx_fh = open(VTPM_TX_FIFO, O_WRONLY); +#endif + } - *data_length = file_info.st_size; - *data = tpm_malloc(*data_length); - if (*data == NULL) { - close(fp); + if (vtpm_tx_fh < 0) { + return -1; + } + + // Send request to VTPM Manager to encrypt data +#ifdef VTPM_MUTLI_VM + out_data_size = len = VTPM_COMMAND_HEADER_SIZE_CLT; +#else + out_data_size = len = VTPM_COMMAND_HEADER_SIZE_SRV; +#endif + out_data = ptr = (BYTE *) malloc(len); + + if (ptr == NULL +#ifndef VTPM_MUTLI_VM + || tpm_marshal_UINT32(&ptr, &len, dmi_id) +#endif + || tpm_marshal_UINT16(&ptr, &len, tag) +#ifdef VTPM_MUTLI_VM + || tpm_marshal_UINT32(&ptr, &len, out_data_size) +#else + || tpm_marshal_UINT32(&ptr, &len, out_data_size - sizeof(uint32_t)) +#endif + || tpm_marshal_UINT32(&ptr, &len, VTPM_ORD_LOADNVM)) { + free(out_data); return -1; } - res = read(fp, *data, *data_length); - close(fp); + + printf("\tSending LoadNVM command\n"); + res = write(vtpm_tx_fh, out_data, out_data_size); + free(out_data); + if (res != out_data_size) return -1; + + if (vtpm_rx_fh < 0) { +#ifdef VTPM_MUTLI_VM + vtpm_rx_fh = vtpm_tx_fh; +#else + if (vtpm_rx_name == NULL) { + vtpm_rx_name = malloc(10 + strlen(VTPM_RX_FIFO_D)); + sprintf(vtpm_rx_name, VTPM_RX_FIFO_D, (uint32_t) dmi_id); + } + vtpm_rx_fh = open(vtpm_rx_name, O_RDONLY); +#endif + } + + if (vtpm_rx_fh < 0) { + return -1; + } + + // Read Header of response so we can get the size & status +#ifdef VTPM_MUTLI_VM + in_header_size = len = VTPM_COMMAND_HEADER_SIZE_CLT; +#else + in_header_size = len = VTPM_COMMAND_HEADER_SIZE_SRV; +#endif + in_header = ptr = malloc(in_header_size); + + printf("\tReading LoadNVM header\n"); + res = read(vtpm_rx_fh, in_header, in_header_size); + + if ( (res != in_header_size) +#ifndef VTPM_MUTLI_VM + || tpm_unmarshal_UINT32(&ptr, &len, (UINT32*)&dmi_id) +#endif + || tpm_unmarshal_UINT16(&ptr, &len, &tag) + || tpm_unmarshal_UINT32(&ptr, &len, &in_rsp_size) + || tpm_unmarshal_UINT32(&ptr, &len, &result) ) { + free(in_header); + return -1; + } + free(in_header); + + if (result != VTPM_SUCCESS) { + return -1; + } + + // Read Encrypted data from VTPM Manager + *data_length = in_rsp_size - VTPM_COMMAND_HEADER_SIZE_CLT; + *data = (uint8_t *) malloc(*data_length); + + printf("\tReading clear data from LoadNVM.\n"); + res = read(vtpm_rx_fh, *data, *data_length); +#ifdef VTPM_MUTLI_VM + close(vtpm_rx_fh);close(vtpm_tx_fh); +#endif + + printf("\tReturing from loading NVM\n"); if (res != *data_length) { - tpm_free(*data); - return -1; + free(*data); + return -1; + } else { + return 0; } - return 0; + } #else diff -uprN tpm_emulator/tpmd.c vtpm/tpmd.c --- tpm_emulator/tpmd.c 2006-12-08 12:51:29.000000000 -0800 +++ vtpm/tpmd.c 2007-01-09 14:48:56.000000000 -0800 @@ -21,12 +21,24 @@ #include #include #include +#include +#include +#include #include "tpm_emulator.h" +#include "vtpm_manager.h" -#define TPM_RX_FNAME "/var/tpm/tpm_in.fifo" -#define TPM_TX_FNAME "/var/tpm/tpm_out.fifo" +#ifdef VTPM_MULTI_VM + #define DEV_BE "/dev/vtpm" +#else + #define PVM_RX_FIFO_D "/var/vtpm/fifos/tpm_cmd_to_%d.fifo" + #define PVM_TX_FIFO "/var/vtpm/fifos/tpm_rsp_from_all.fifo" + #define HVM_RX_FIFO_D "/var/vtpm/socks/%d.socket" +#endif + + int dmi_id; + #define BUFFER_SIZE 2048 static int devurandom=0; @@ -38,7 +50,7 @@ void get_random_bytes(void *buf, int nby } if (read(devurandom, buf, nbytes) != nbytes) { - printf("Can't get random number.\n"); + error("Can't get random number.\n"); exit(-1); } } @@ -52,105 +64,182 @@ uint64_t tpm_get_ticks(void) int main(int argc, char **argv) { - uint8_t in[BUFFER_SIZE], *out; + uint8_t type, in[BUFFER_SIZE], *out, *addressed_out; + char *vtpm_rx_file=NULL; uint32_t out_size; int in_size, written; - int i; - struct stat file_info; + int i, guest_id=-1; - int tpm_tx_fh=-1, tpm_rx_fh=-1; +#ifndef VTPM_MULTI_VM + int sockfd = -1; + struct sockaddr_un addr; + struct sockaddr_un client_addr; + unsigned int client_length; + +#endif + + int vtpm_tx_fh=-1, vtpm_rx_fh=-1; +#ifdef VTPM_MULTI_VM if (argc < 2) { - printf("Usage: tpmd clear|save|deactivated\n" ); + error("Usage: tpmd clear|save|deactivated\n" ); +#else + if (argc < 4) { + error("Usage: tpmd clear|save|deactivated pvm|hvm vtpmid\n" ); +#endif return -1; } +#ifndef VTPM_MULTI_VM + /* setup type of vm */ + if (!strcmp(argv[2], "pvm")) { + type = VTPM_TYPE_PVM; // Get commands from vTPM Manager through fifo + } else if (!strcmp(argv[2], "hvm")) { + type = VTPM_TYPE_HVM; // Get commands from qemu via socket + } else { + error("invalid vTPM type '%s'.\n", argv[2]); + } + + dmi_id = atoi(argv[3]); + + if (type == VTPM_TYPE_PVM) { + vtpm_rx_file = malloc(10 + strlen(PVM_RX_FIFO_D)); + sprintf(vtpm_rx_file, PVM_RX_FIFO_D, (uint32_t) dmi_id); + } else { + vtpm_rx_file = malloc(10 + strlen(HVM_RX_FIFO_D)); + sprintf(vtpm_rx_file, HVM_RX_FIFO_D, (uint32_t) dmi_id); + + if ( (sockfd = socket(PF_UNIX,SOCK_STREAM,0)) < 0) { + error("Unable to create socket. errno = %d\n", errno); + exit (-1); + } + + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path,vtpm_rx_file ); + unlink(addr.sun_path); + } +#endif + +#ifdef VTPM_MULTI_VM + info("Initializing tpm state: %s\n", argv[1]); +#else + info("Initializing tpm state: %s, type: %s, id: %d\n", argv[1], argv[2], dmi_id); +#endif + /* initialize TPM emulator */ if (!strcmp(argv[1], "clear")) { - printf("Initializing tpm: %s\n", argv[1]); tpm_emulator_init(1); - } else if (!strcmp(argv[1], "save")) { - printf("Initializing tpm: %s\n", argv[1]); + } else if (!strcmp(argv[1], "save")) { tpm_emulator_init(2); } else if (!strcmp(argv[1], "deactivated")) { - printf("Initializing tpm: %s\n", argv[1]); tpm_emulator_init(3); } else { - printf("invalid startup mode '%s'; must be 'clear', " + error("invalid startup mode '%s'; must be 'clear', " "'save' (default) or 'deactivated", argv[1]); return -1; } - - if ( stat(TPM_RX_FNAME, &file_info) == -1) { - if ( mkfifo(TPM_RX_FNAME, S_IWUSR | S_IRUSR ) ) { - printf("Failed to create fifo %s.\n", TPM_RX_FNAME); - return -1; - } - } - - if ( stat(TPM_TX_FNAME, &file_info) == -1) { - if ( mkfifo(TPM_TX_FNAME, S_IWUSR | S_IRUSR ) ) { - printf("Failed to create fifo %s.\n", TPM_TX_FNAME); - return -1; - } - } - + while (1) { abort_command: - if (tpm_rx_fh < 0) { - tpm_rx_fh = open(TPM_RX_FNAME, O_RDONLY); + if (vtpm_rx_fh < 0) { +#ifdef VTPM_MUTLI_VM + vtpm_rx_fh = open(DEV_BE, O_RDWR); +#else + if (type == VTPM_TYPE_PVM) { + vtpm_rx_fh = open(vtpm_rx_file, O_RDONLY); + } else { + if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + error("Unable to bind(). errno = %d\n", errno); + exit (-1); + } + + if (listen(sockfd, 10) <0) { + error("Unable to listen(). errno = %d\n", errno); + exit (-1); + } + + memset(&client_addr, 0, sizeof(client_addr)); + client_length = sizeof(client_addr); + + vtpm_rx_fh = vtpm_tx_fh = accept(sockfd, (struct sockaddr *)&client_addr, &client_length); + } +#endif } - if (tpm_rx_fh < 0) { - printf("ERROR: failed to open devices to listen to guest.\n"); + if (vtpm_rx_fh < 0) { + error("Failed to open devices to listen to guest.\n"); return -1; } - if (tpm_tx_fh < 0) { - tpm_tx_fh = open(TPM_TX_FNAME, O_WRONLY); - } - - if (tpm_tx_fh < 0) { - printf("ERROR: failed to open devices to respond to guest.\n"); - return -1; - } - - in_size = read(tpm_rx_fh, in, BUFFER_SIZE); + in_size = read(vtpm_rx_fh, in, BUFFER_SIZE); if (in_size < 6) { // Magic size of minium TPM command - printf("Recv[%d] to small: 0x", in_size); + info("Recv incomplete command of %d bytes.", in_size); if (in_size <= 0) { - close(tpm_rx_fh); - tpm_rx_fh = -1; + close(vtpm_rx_fh); + vtpm_rx_fh = -1; goto abort_command; } } else { - printf("Recv[%d]: 0x", in_size); + debug_nostop("Recv[%d]: 0x", in_size); for (i=0; i< in_size; i++) - printf("%x ", in[i]); - printf("\n"); + debug_more("%x ", in[i]); + debug_more("\n"); } - - if (tpm_handle_command(in, in_size, &out, &out_size) != 0) { - printf("ERROR: Handler Failed.\n"); + if (guest_id == -1) { + guest_id = *((uint32_t *) in); + } else { + if (guest_id != *((uint32_t *) in) ) { + error("WARNING: More than one guest attached\n"); + } + } + + if (vtpm_tx_fh < 0) { +#ifdef VTPM_MUTLI_VM + vtpm_tx_fh = open(DEV_BE, O_RDWR); + vtpm_rx_fh = vtpm_tx_fh; +#else + if (type == VTPM_TYPE_PVM) { + vtpm_tx_fh = open(PVM_TX_FIFO, O_WRONLY); + } // No need to open the other direction for HVM +#endif + } + + if (vtpm_tx_fh < 0) { + error("Failed to open devices to respond to guest.\n"); + return -1; + } + + // Handle the command, but skip the domain id header + if (tpm_handle_command(in + sizeof(uint32_t), in_size - sizeof(uint32_t), &out, &out_size) != 0) { + error("Handler Failed.\n"); } - written = write(tpm_tx_fh, out, out_size); + addressed_out = (uint8_t *) tpm_malloc(sizeof(uint32_t) + out_size); + *(uint32_t *) addressed_out = *(uint32_t *) in; + memcpy(addressed_out + sizeof(uint32_t), out, out_size); + + written = write(vtpm_tx_fh, addressed_out, out_size + sizeof(uint32_t)); - if (written != out_size ) { - printf("ERROR: Part of response not written %d/%d.\nAttempt: ", written, out_size); + if (written != out_size + sizeof(uint32_t)) { + error("Part of response not written %d/%d.\n", written, out_size); } else { - printf("Sent[%Zu]: ", out_size); + debug_nostop("Sent[%Zu]: ", out_size + sizeof(uint32_t)); + for (i=0; i< out_size+ sizeof(uint32_t); i++) + debug_more("%x ", addressed_out[i]); + debug_more("\n"); } - for (i=0; i< out_size; i++) - printf("%x ", out[i]); - printf("\n"); tpm_free(out); + tpm_free(addressed_out); } // loop tpm_emulator_shutdown(); - close(tpm_tx_fh); - close(tpm_rx_fh); + close(vtpm_tx_fh); +#ifndef VTPM_MUTLI_VM + close(vtpm_rx_fh); + free (vtpm_rx_file); +#endif }