[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] VTPM_TOOLS: Restructured handlers for better clearity and created an ipc
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 72ef14e79cc0c07947b4fd467b62b4971b86dc3c # Parent 43d141d56c78baf60794d3db9f419fffc6efdccd VTPM_TOOLS: Restructured handlers for better clearity and created an ipc abstraction needed for expansion to hot plug and migration support. Also fixed a bug in savestate. Signed-off-by: Vinnie Scarlata <Vincent.r.scarlata@xxxxxxxxx> --- tools/vtpm/Makefile | 21 tools/vtpm/tpm_emulator.patch | 1 tools/vtpm/vtpm.patch | 163 ----- tools/vtpm_manager/Rules.mk | 8 tools/vtpm_manager/manager/dmictl.c | 142 ----- tools/vtpm_manager/manager/securestorage.c | 29 - tools/vtpm_manager/manager/vtpm_ipc.c | 141 +++++ tools/vtpm_manager/manager/vtpm_ipc.h | 71 ++ tools/vtpm_manager/manager/vtpm_lock.c | 63 ++ tools/vtpm_manager/manager/vtpm_lock.h | 48 + tools/vtpm_manager/manager/vtpm_manager.c | 602 ---------------------- tools/vtpm_manager/manager/vtpm_manager.h | 36 - tools/vtpm_manager/manager/vtpm_manager_handler.c | 455 ++++++++++++++++ tools/vtpm_manager/manager/vtpmd.c | 309 +++++++++-- tools/vtpm_manager/manager/vtpmpriv.h | 73 +- 15 files changed, 1165 insertions(+), 997 deletions(-) diff -r 43d141d56c78 -r 72ef14e79cc0 tools/vtpm/Makefile --- a/tools/vtpm/Makefile Wed May 17 23:19:18 2006 +0100 +++ b/tools/vtpm/Makefile Wed May 17 23:23:26 2006 +0100 @@ -21,7 +21,9 @@ build: $(TPM_EMULATOR_DIR) $(VTPM_DIR) b .PHONY: install install: build - $(MAKE) -C $(TPM_EMULATOR_DIR) $@ + if [ "$(BUILD_EMULATOR)" = "y" ]; then \ + $(MAKE) -C $(TPM_EMULATOR_DIR) $@ ;\ + fi $(MAKE) -C $(VTPM_DIR) $@ .PHONY: clean @@ -46,20 +48,21 @@ mrproper: # Create vtpm and TPM emulator dirs # apply patches for 1) used as dom0 tpm driver 2) used as vtpm device instance $(TPM_EMULATOR_DIR): $(TPM_EMULATOR_TARFILE) tpm_emulator.patch tpm_emulator-0.2b-x86_64.patch - tar -xzf $(TPM_EMULATOR_TARFILE); - rm -rf $(TPM_EMULATOR_DIR) - mv tpm_emulator-0.2 $(TPM_EMULATOR_DIR); - - -cd $(TPM_EMULATOR_DIR); \ - patch -p1 < ../tpm_emulator-0.2b-x86_64.patch; \ - patch -p1 <../tpm_emulator.patch + if [ "$(BUILD_EMULATOR)" = "y" ]; then \ + tar -xzf $(TPM_EMULATOR_TARFILE); \ + rm -rf $(TPM_EMULATOR_DIR); \ + mv tpm_emulator-0.2 $(TPM_EMULATOR_DIR); \ + cd $(TPM_EMULATOR_DIR); \ + patch -p1 < ../tpm_emulator-0.2b-x86_64.patch; \ + patch -p1 <../tpm_emulator.patch; \ + fi $(VTPM_DIR): $(TPM_EMULATOR_TARFILE) tpm_emulator-0.2b-x86_64.patch vtpm.patch tar -xzf $(TPM_EMULATOR_TARFILE); rm -rf $(VTPM_DIR) mv tpm_emulator-0.2 $(VTPM_DIR); - -cd $(VTPM_DIR); \ + cd $(VTPM_DIR); \ patch -p1 < ../tpm_emulator-0.2b-x86_64.patch; \ patch -p1 <../vtpm.patch diff -r 43d141d56c78 -r 72ef14e79cc0 tools/vtpm/tpm_emulator.patch --- a/tools/vtpm/tpm_emulator.patch Wed May 17 23:19:18 2006 +0100 +++ b/tools/vtpm/tpm_emulator.patch Wed May 17 23:23:26 2006 +0100 @@ -52,7 +52,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ -KERNEL_BUILD := /lib/modules/$(KERNEL_RELEASE)/build +CUR_DIR := $(shell pwd) +LINUX_VERSION := $(shell cat $(CUR_DIR)/$(XEN_ROOT)/buildconfigs/mk.linux-2.6-xen | grep "LINUX_VER" | grep "2.6" | gawk '{ print $$3 }' ) -+KERNEL_BUILD := $(XEN_ROOT)/linux-$(LINUX_VERSION)-xen0 ++KERNEL_BUILD := $(XEN_ROOT)/linux-$(LINUX_VERSION)-xen MOD_SUBDIR := misc COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/) diff -r 43d141d56c78 -r 72ef14e79cc0 tools/vtpm/vtpm.patch --- a/tools/vtpm/vtpm.patch Wed May 17 23:19:18 2006 +0100 +++ b/tools/vtpm/vtpm.patch Wed May 17 23:23:26 2006 +0100 @@ -1,12 +1,12 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ diff -uprN orig/tpm_emulator-0.2-x86_64/AUTHORS vtpm/AUTHORS --- orig/tpm_emulator-0.2-x86_64/AUTHORS 2005-08-15 00:58:57.000000000 -0700 -+++ vtpm/AUTHORS 2005-09-14 20:27:22.000000000 -0700 ++++ vtpm/AUTHORS 2006-05-17 09:31:11.000000000 -0700 @@ -1 +1,2 @@ Mario Strasser <mast@xxxxxxx> +INTEL Corp <> diff -uprN orig/tpm_emulator-0.2-x86_64/ChangeLog vtpm/ChangeLog --- orig/tpm_emulator-0.2-x86_64/ChangeLog 2005-08-15 00:58:57.000000000 -0700 -+++ vtpm/ChangeLog 2005-09-14 20:27:22.000000000 -0700 ++++ vtpm/ChangeLog 2006-05-17 09:31:11.000000000 -0700 @@ -1,3 +1,7 @@ +2005-08-16 Intel Corp + Moved module out of kernel to run as a ring 3 app @@ -16,8 +16,8 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ * all: some typos corrected * tpm_integrity.c: bug in TPM_Extend fixed diff -uprN orig/tpm_emulator-0.2-x86_64/crypto/gmp_kernel_wrapper.c vtpm/crypto/gmp_kernel_wrapper.c ---- orig/tpm_emulator-0.2-x86_64/crypto/gmp_kernel_wrapper.c 2005-09-15 19:21:42.508873032 -0700 -+++ vtpm/crypto/gmp_kernel_wrapper.c 2005-09-15 19:25:37.319176440 -0700 +--- orig/tpm_emulator-0.2-x86_64/crypto/gmp_kernel_wrapper.c 2006-05-17 09:34:13.000000000 -0700 ++++ vtpm/crypto/gmp_kernel_wrapper.c 2006-05-17 09:31:11.000000000 -0700 @@ -1,5 +1,6 @@ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>, @@ -59,10 +59,9 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ { - void *ret = (void*)kmalloc(new_size, GFP_KERNEL); - if (!ret) panic(KERN_CRIT TPM_MODULE_NAME "GMP: Cannot reallocate memory " -- "(old_size=%Zu new_size=%Zu)\n", old_size, new_size); + void *ret = (void*)malloc(new_size); + if (!ret) error("GMP: Cannot reallocate memory " -+ "(old_size=%Zu new_size=%Zu)\n", old_size, new_size); + "(old_size=%Zu new_size=%Zu)\n", old_size, new_size); memcpy(ret, oldptr, old_size); - kfree(oldptr); + free(oldptr); @@ -80,7 +79,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ diff -uprN orig/tpm_emulator-0.2-x86_64/crypto/rsa.c vtpm/crypto/rsa.c --- orig/tpm_emulator-0.2-x86_64/crypto/rsa.c 2005-08-15 00:58:57.000000000 -0700 -+++ vtpm/crypto/rsa.c 2005-09-14 20:27:22.000000000 -0700 ++++ vtpm/crypto/rsa.c 2006-05-17 09:31:11.000000000 -0700 @@ -1,5 +1,6 @@ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>, @@ -107,7 +106,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ if (memcmp(&msg[1], &msg[1 + SHA1_DIGEST_LENGTH], SHA1_DIGEST_LENGTH) != 0) return -1; diff -uprN orig/tpm_emulator-0.2-x86_64/linux_module.c vtpm/linux_module.c ---- orig/tpm_emulator-0.2-x86_64/linux_module.c 2005-09-15 19:22:40.343080896 -0700 +--- orig/tpm_emulator-0.2-x86_64/linux_module.c 2006-05-17 09:34:13.000000000 -0700 +++ vtpm/linux_module.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,163 +0,0 @@ -/* Software-Based Trusted Platform Module (TPM) Emulator for Linux @@ -274,8 +273,8 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ -} - diff -uprN orig/tpm_emulator-0.2-x86_64/linux_module.h vtpm/linux_module.h ---- orig/tpm_emulator-0.2-x86_64/linux_module.h 2005-09-15 19:21:14.844078720 -0700 -+++ vtpm/linux_module.h 2005-09-14 20:27:22.000000000 -0700 +--- orig/tpm_emulator-0.2-x86_64/linux_module.h 2006-05-17 09:34:13.000000000 -0700 ++++ vtpm/linux_module.h 2006-05-17 09:31:11.000000000 -0700 @@ -1,5 +1,6 @@ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>, @@ -376,8 +375,8 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ #define LE16_TO_CPU(x) __le16_to_cpu(x) diff -uprN orig/tpm_emulator-0.2-x86_64/Makefile vtpm/Makefile ---- orig/tpm_emulator-0.2-x86_64/Makefile 2005-09-15 19:21:14.845078568 -0700 -+++ vtpm/Makefile 2005-09-14 20:27:22.000000000 -0700 +--- orig/tpm_emulator-0.2-x86_64/Makefile 2006-05-17 09:34:13.000000000 -0700 ++++ vtpm/Makefile 2006-05-17 09:31:11.000000000 -0700 @@ -1,22 +1,31 @@ # Software-Based Trusted Platform Module (TPM) Emulator for Linux # Copyright (C) 2004 Mario Strasser <mast@xxxxxxx> @@ -410,7 +409,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ + +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 @@ -470,8 +469,8 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ $(src)/crypto/libgmp.a: test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB) $(src)/crypto/libgmp.a diff -uprN orig/tpm_emulator-0.2-x86_64/README vtpm/README ---- orig/tpm_emulator-0.2-x86_64/README 2005-08-15 00:58:57.000000000 -0700 -+++ vtpm/README 2005-09-14 20:27:22.000000000 -0700 +--- orig/tpm_emulator-0.2-x86_64/README 2006-05-17 09:34:13.000000000 -0700 ++++ vtpm/README 2006-05-17 09:31:11.000000000 -0700 @@ -13,7 +13,8 @@ $Id: README 8 2005-01-25 21:11:45Z jmoli Copyright -------------------------------------------------------------------------- @@ -484,7 +483,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ it under the terms of the GNU General Public License as published by diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_audit.c vtpm/tpm/tpm_audit.c --- orig/tpm_emulator-0.2-x86_64/tpm/tpm_audit.c 2005-08-15 00:58:57.000000000 -0700 -+++ vtpm/tpm/tpm_audit.c 2005-09-14 20:27:22.000000000 -0700 ++++ vtpm/tpm/tpm_audit.c 2006-05-17 09:31:11.000000000 -0700 @@ -1,6 +1,7 @@ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>, @@ -549,7 +548,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ - diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_authorization.c vtpm/tpm/tpm_authorization.c --- orig/tpm_emulator-0.2-x86_64/tpm/tpm_authorization.c 2005-08-15 00:58:57.000000000 -0700 -+++ vtpm/tpm/tpm_authorization.c 2005-09-14 20:27:22.000000000 -0700 ++++ vtpm/tpm/tpm_authorization.c 2006-05-17 09:31:11.000000000 -0700 @@ -1,6 +1,7 @@ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>, @@ -575,7 +574,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ - diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_capability.c vtpm/tpm/tpm_capability.c --- orig/tpm_emulator-0.2-x86_64/tpm/tpm_capability.c 2005-08-15 00:58:57.000000000 -0700 -+++ vtpm/tpm/tpm_capability.c 2005-09-14 20:27:22.000000000 -0700 ++++ vtpm/tpm/tpm_capability.c 2006-05-17 09:31:11.000000000 -0700 @@ -1,6 +1,7 @@ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>, @@ -600,7 +599,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ - diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_cmd_handler.c vtpm/tpm/tpm_cmd_handler.c --- orig/tpm_emulator-0.2-x86_64/tpm/tpm_cmd_handler.c 2005-08-15 00:58:57.000000000 -0700 -+++ vtpm/tpm/tpm_cmd_handler.c 2005-09-14 20:27:22.000000000 -0700 ++++ vtpm/tpm/tpm_cmd_handler.c 2006-05-17 09:31:11.000000000 -0700 @@ -1,6 +1,7 @@ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>, @@ -664,8 +663,8 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ } - diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_crypto.c vtpm/tpm/tpm_crypto.c ---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_crypto.c 2005-09-15 19:21:14.846078416 -0700 -+++ vtpm/tpm/tpm_crypto.c 2005-09-14 20:27:22.000000000 -0700 +--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_crypto.c 2006-05-17 09:34:13.000000000 -0700 ++++ vtpm/tpm/tpm_crypto.c 2006-05-17 09:31:11.000000000 -0700 @@ -1,6 +1,7 @@ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>, @@ -689,8 +688,8 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ } - diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c vtpm/tpm/tpm_data.c ---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c 2005-09-15 19:21:14.847078264 -0700 -+++ vtpm/tpm/tpm_data.c 2005-09-14 20:27:22.000000000 -0700 +--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c 2006-05-17 09:34:13.000000000 -0700 ++++ vtpm/tpm/tpm_data.c 2006-05-17 09:31:11.000000000 -0700 @@ -1,6 +1,7 @@ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>, @@ -760,8 +759,8 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ +#ifdef VTPM_MUTLI_VM + #define DEV_FE "/dev/tpm" +#else -+ #define VTPM_RX_FIFO_D "/var/vtpm/fifos/vtpm-to-%d.fifo" -+ #define VTPM_TX_FIFO "/var/vtpm/fifos/vtpm-from-all.fifo" ++ #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; @@ -1021,7 +1020,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ - diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_deprecated.c vtpm/tpm/tpm_deprecated.c --- orig/tpm_emulator-0.2-x86_64/tpm/tpm_deprecated.c 2005-08-15 00:58:57.000000000 -0700 -+++ vtpm/tpm/tpm_deprecated.c 2005-09-14 20:27:22.000000000 -0700 ++++ vtpm/tpm/tpm_deprecated.c 2006-05-17 09:31:11.000000000 -0700 @@ -1,6 +1,7 @@ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>, @@ -1050,7 +1049,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ len = *authContextSize; diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_emulator.h vtpm/tpm/tpm_emulator.h --- orig/tpm_emulator-0.2-x86_64/tpm/tpm_emulator.h 2005-08-15 00:58:57.000000000 -0700 -+++ vtpm/tpm/tpm_emulator.h 2005-09-14 20:27:22.000000000 -0700 ++++ vtpm/tpm/tpm_emulator.h 2006-05-17 09:31:11.000000000 -0700 @@ -1,5 +1,6 @@ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>, @@ -1070,7 +1069,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ * tpm_emulator_init - initialises and starts the TPM emulator diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_integrity.c vtpm/tpm/tpm_integrity.c --- orig/tpm_emulator-0.2-x86_64/tpm/tpm_integrity.c 2005-08-15 00:58:57.000000000 -0700 -+++ vtpm/tpm/tpm_integrity.c 2005-09-14 20:27:22.000000000 -0700 ++++ vtpm/tpm/tpm_integrity.c 2006-05-17 09:31:11.000000000 -0700 @@ -1,6 +1,7 @@ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>, @@ -1086,7 +1085,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ - diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_structures.h vtpm/tpm/tpm_structures.h --- orig/tpm_emulator-0.2-x86_64/tpm/tpm_structures.h 2005-08-15 00:58:57.000000000 -0700 -+++ vtpm/tpm/tpm_structures.h 2005-09-14 20:27:22.000000000 -0700 ++++ vtpm/tpm/tpm_structures.h 2006-05-17 09:31:11.000000000 -0700 @@ -1,6 +1,7 @@ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>, @@ -1106,7 +1105,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ /* diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_testing.c vtpm/tpm/tpm_testing.c --- orig/tpm_emulator-0.2-x86_64/tpm/tpm_testing.c 2005-08-15 00:58:57.000000000 -0700 -+++ vtpm/tpm/tpm_testing.c 2005-09-14 20:27:22.000000000 -0700 ++++ vtpm/tpm/tpm_testing.c 2006-05-17 09:31:11.000000000 -0700 @@ -1,6 +1,7 @@ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>, @@ -1224,7 +1223,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_ticks.c vtpm/tpm/tpm_ticks.c --- orig/tpm_emulator-0.2-x86_64/tpm/tpm_ticks.c 2005-08-15 00:58:57.000000000 -0700 -+++ vtpm/tpm/tpm_ticks.c 2005-09-14 20:27:22.000000000 -0700 ++++ vtpm/tpm/tpm_ticks.c 2006-05-17 09:31:11.000000000 -0700 @@ -1,6 +1,7 @@ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>, @@ -1307,139 +1306,9 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ } -diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/vtpm_manager.h vtpm/tpm/vtpm_manager.h ---- orig/tpm_emulator-0.2-x86_64/tpm/vtpm_manager.h 1969-12-31 16:00:00.000000000 -0800 -+++ vtpm/tpm/vtpm_manager.h 2005-09-14 20:27:22.000000000 -0700 -@@ -0,0 +1,126 @@ -+// =================================================================== -+// -+// Copyright (c) 2005, Intel Corp. -+// All rights reserved. -+// -+// Redistribution and use in source and binary forms, with or without -+// modification, are permitted provided that the following conditions -+// are met: -+// -+// * Redistributions of source code must retain the above copyright -+// notice, this list of conditions and the following disclaimer. -+// * Redistributions in binary form must reproduce the above -+// copyright notice, this list of conditions and the following -+// disclaimer in the documentation and/or other materials provided -+// with the distribution. -+// * Neither the name of Intel Corporation nor the names of its -+// contributors may be used to endorse or promote products derived -+// from this software without specific prior written permission. -+// -+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -+// OF THE POSSIBILITY OF SUCH DAMAGE. -+// =================================================================== -+// -+// vtpm_manager.h -+// -+// Public Interface header for VTPM Manager -+// -+// ================================================================== -+ -+#ifndef __VTPM_MANAGER_H__ -+#define __VTPM_MANAGER_H__ -+ -+#define VTPM_TAG_REQ 0x01c1 -+#define VTPM_TAG_RSP 0x01c4 -+#define COMMAND_BUFFER_SIZE 4096 -+ -+// Header sizes. Note Header MAY include the DMI -+#define VTPM_COMMAND_HEADER_SIZE_SRV ( sizeof(UINT32) + sizeof(TPM_TAG) + sizeof(UINT32) + sizeof(TPM_COMMAND_CODE)) -+#define VTPM_COMMAND_HEADER_SIZE_CLT ( sizeof(TPM_TAG) + sizeof(UINT32) + sizeof(TPM_COMMAND_CODE)) -+ -+//************************ Command Codes **************************** -+#define VTPM_ORD_OPEN 1 // ULM Creates New DMI -+#define VTPM_ORD_CLOSE 2 // ULM Closes a DMI -+#define VTPM_ORD_DELETE 3 // ULM Permemently Deletes DMI -+#define VTPM_ORD_SAVENVM 4 // DMI requests Secrets Unseal -+#define VTPM_ORD_LOADNVM 5 // DMI requests Secrets Saved -+#define VTPM_ORD_TPMCOMMAND 6 // DMI issues HW TPM Command -+ -+//************************ Return Codes **************************** -+#define VTPM_SUCCESS 0 -+#define VTPM_FAIL 1 -+#define VTPM_UNSUPPORTED 2 -+#define VTPM_FORBIDDEN 3 -+#define VTPM_RESTORE_CONTEXT_FAILED 4 -+#define VTPM_INVALID_REQUEST 5 -+ -+/******************* Command Parameter API ************************* -+ -+VTPM Command Format -+ dmi: 4 bytes // Source of message. -+ // WARNING: This is prepended by the channel. -+ // Thus it is received by VTPM Manager, -+ // but not sent by DMI -+ tpm tag: 2 bytes -+ command size: 4 bytes // Size of command including header but not DMI -+ ord: 4 bytes // Command ordinal above -+ parameters: size - 10 bytes // Command Parameter -+ -+VTPM Response Format -+ tpm tag: 2 bytes -+ response_size: 4 bytes -+ status: 4 bytes -+ parameters: size - 10 bytes -+ -+ -+VTPM_Open: -+ Input Parameters: -+ Domain_type: 1 byte -+ domain_id: 4 bytes -+ instance_id: 4 bytes -+ Output Parameters: -+ None -+ -+VTPM_Close -+ Input Parameters: -+ instance_id: 4 bytes -+ Output Parameters: -+ None -+ -+VTPM_Delete -+ Input Parameters: -+ instance_id: 4 bytes -+ Output Parameters: -+ None -+ -+VTPM_SaveNVM -+ Input Parameters: -+ data: n bytes (Header indicates size of data) -+ Output Parameters: -+ None -+ -+VTPM_LoadNVM -+ Input Parameters: -+ None -+ Output Parameters: -+ data: n bytes (Header indicates size of data) -+ -+VTPM_TPMCommand -+ Input Parameters: -+ TPM Command Byte Stream: n bytes -+ Output Parameters: -+ TPM Reponse Byte Stream: n bytes -+ -+*********************************************************************/ -+ -+#endif //_VTPM_MANAGER_H_ diff -uprN orig/tpm_emulator-0.2-x86_64/tpmd.c vtpm/tpmd.c --- orig/tpm_emulator-0.2-x86_64/tpmd.c 1969-12-31 16:00:00.000000000 -0800 -+++ vtpm/tpmd.c 2005-09-15 19:28:55.783005352 -0700 ++++ vtpm/tpmd.c 2006-05-17 09:31:11.000000000 -0700 @@ -0,0 +1,207 @@ +/* Software-Based Trusted Platform Module (TPM) Emulator for Linux + * Copyright (C) 2005 INTEL Corp @@ -1471,8 +1340,8 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ +#ifdef VTPM_MULTI_VM + #define DEV_BE "/dev/vtpm" +#else -+ #define GUEST_RX_FIFO_D "/var/vtpm/fifos/guest-to-%d.fifo" -+ #define GUEST_TX_FIFO "/var/vtpm/fifos/guest-from-all.fifo" ++ #define GUEST_RX_FIFO_D "/var/vtpm/fifos/tpm_cmd_to_%d.fifo" ++ #define GUEST_TX_FIFO "/var/vtpm/fifos/tpm_rsp_from_all.fifo" +#endif + + int dmi_id; diff -r 43d141d56c78 -r 72ef14e79cc0 tools/vtpm_manager/Rules.mk --- a/tools/vtpm_manager/Rules.mk Wed May 17 23:19:18 2006 +0100 +++ b/tools/vtpm_manager/Rules.mk Wed May 17 23:23:26 2006 +0100 @@ -40,6 +40,9 @@ OBJS = $(patsubst %.c,%.o,$(SRCS)) # Project-specific definitions # +# Need UNIX98 spec for pthread rwlocks +CFLAGS += -D_GNU_SOURCE + # Logging Level. See utils/tools.h for usage CFLAGS += -DLOGGING_MODULES="(BITMASK(VTPM_LOG_TCS)|BITMASK(VTPM_LOG_VTSP)|BITMASK(VTPM_LOG_VTPM)|BITMASK(VTPM_LOG_VTPM_DEEP))" @@ -50,7 +53,7 @@ CFLAGS += -DLOGGING_MODULES="(BITMASK(VT # Use frontend/backend pairs between manager & DMs? #CFLAGS += -DVTPM_MULTI_VM -# vtpm_manager listens on /tmp/in.fifo and /tmp/out.fifo rather than backend +# vtpm_manager listens on fifo's rather than backend #CFLAGS += -DDUMMY_BACKEND # Do not have manager launch DMs. @@ -59,9 +62,6 @@ CFLAGS += -DLOGGING_MODULES="(BITMASK(VT # Fixed OwnerAuth #CFLAGS += -DWELL_KNOWN_OWNER_AUTH -# TPM Hardware Device or TPM Simulator -#CFLAGS += -DTPM_HWDEV - # Include CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/crypto CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/util diff -r 43d141d56c78 -r 72ef14e79cc0 tools/vtpm_manager/manager/dmictl.c --- a/tools/vtpm_manager/manager/dmictl.c Wed May 17 23:19:18 2006 +0100 +++ b/tools/vtpm_manager/manager/dmictl.c Wed May 17 23:23:26 2006 +0100 @@ -55,66 +55,30 @@ #include "log.h" #include "hashtable.h" #include "hashtable_itr.h" +#include "vtpm_ipc.h" #define TPM_EMULATOR_PATH "/usr/bin/vtpmd" -TPM_RESULT close_dmi( VTPM_DMI_RESOURCE *dmi_res) { - TPM_RESULT status = TPM_FAIL; - +TPM_RESULT close_dmi(VTPM_DMI_RESOURCE *dmi_res) { if (dmi_res == NULL) return TPM_SUCCESS; - status = TCS_CloseContext(dmi_res->TCSContext); + TCS_CloseContext(dmi_res->TCSContext); free ( dmi_res->NVMLocation ); dmi_res->connected = FALSE; -#ifndef VTPM_MULTI_VM - free(dmi_res->guest_tx_fname); - free(dmi_res->vtpm_tx_fname); - - close(dmi_res->guest_tx_fh); dmi_res->guest_tx_fh = -1; - close(dmi_res->vtpm_tx_fh); dmi_res->vtpm_tx_fh = -1; vtpm_globals->connected_dmis--; - if (vtpm_globals->connected_dmis == 0) { - // No more DMI's connected. Close fifo to prevent a broken pipe. - close(vtpm_globals->guest_rx_fh); - vtpm_globals->guest_rx_fh = -1; - } - #ifndef MANUAL_DM_LAUNCH - if (dmi_res->dmi_id != VTPM_CTL_DM) { - if (dmi_res->dmi_pid != 0) { - vtpmloginfo(VTPM_LOG_VTPM, "Killing dmi on pid %d.\n", dmi_res->dmi_pid); - if (kill(dmi_res->dmi_pid, SIGKILL) !=0) { - vtpmloginfo(VTPM_LOG_VTPM, "DMI on pid %d is already dead.\n", dmi_res->dmi_pid); - } else if (waitpid(dmi_res->dmi_pid, NULL, 0) != dmi_res->dmi_pid) { - vtpmlogerror(VTPM_LOG_VTPM, "DMI on pid %d failed to stop.\n", dmi_res->dmi_pid); - status = TPM_FAIL; - } - } else { - vtpmlogerror(VTPM_LOG_VTPM, "Could not kill dmi because it's pid was 0.\n"); - status = TPM_FAIL; - } - } - #endif -#endif - - return status; -} - -TPM_RESULT VTPM_Handle_New_DMI( const buffer_t *param_buf) { + return (VTPM_Close_DMI_Extra(dmi_res) ); +} + +TPM_RESULT VTPM_Handle_New_DMI(const buffer_t *param_buf) { VTPM_DMI_RESOURCE *new_dmi=NULL; TPM_RESULT status=TPM_FAIL; BYTE type; UINT32 dmi_id, domain_id, *dmi_id_key; -#ifndef VTPM_MULTI_VM - int fh; - char dmi_id_str[11]; // UINT32s are up to 10 digits + NULL - struct stat file_info; -#endif - if (param_buf == NULL) { // Assume creation of Dom 0 control type = 0; domain_id = VTPM_CTL_DM; @@ -156,7 +120,7 @@ TPM_RESULT VTPM_Handle_New_DMI( const bu status = TPM_FAIL; goto egress; } - + } else vtpmloginfo(VTPM_LOG_VTPM, "Re-attaching DMI instance %d on domain %d .\n", dmi_id, domain_id); @@ -176,94 +140,16 @@ TPM_RESULT VTPM_Handle_New_DMI( const bu new_dmi->NVMLocation = (char *) malloc(11 + strlen(DMI_NVM_FILE)); sprintf(new_dmi->NVMLocation, DMI_NVM_FILE, (uint32_t) new_dmi->dmi_id); - // Measure DMI - // FIXME: This will measure DMI. Until then use a fixed DMI_Measurement value - /* - fh = open(TPM_EMULATOR_PATH, O_RDONLY); - stat_ret = fstat(fh, &file_stat); - if (stat_ret == 0) - dmi_size = file_stat.st_size; - else { - vtpmlogerror(VTPM_LOG_VTPM, "Could not open tpm_emulator!!\n"); - status = TPM_IOERROR; - goto abort_egress; - } - dmi_buffer - */ - memset(&new_dmi->DMI_measurement, 0xcc, sizeof(TPM_DIGEST)); - -#ifndef VTPM_MULTI_VM - if (dmi_id != VTPM_CTL_DM) { - // Create a pair of fifo pipes - if( (new_dmi->guest_tx_fname = (char *) malloc(11 + strlen(GUEST_TX_FIFO))) == NULL){ - status = TPM_RESOURCES; - goto abort_egress; - } - sprintf(new_dmi->guest_tx_fname, GUEST_TX_FIFO, (uint32_t) dmi_id); - - if ((new_dmi->vtpm_tx_fname = (char *) malloc(11 + strlen(VTPM_TX_FIFO))) == NULL) { - status = TPM_RESOURCES; - goto abort_egress; - } - sprintf(new_dmi->vtpm_tx_fname, VTPM_TX_FIFO, (uint32_t) dmi_id); - - new_dmi->guest_tx_fh = -1; - new_dmi->vtpm_tx_fh= -1; - - if ( stat(new_dmi->guest_tx_fname, &file_info) == -1) { - if ( mkfifo(new_dmi->guest_tx_fname, S_IWUSR | S_IRUSR ) ){ - vtpmlogerror(VTPM_LOG_VTPM, "Failed to create dmi fifo.\n"); - status = TPM_IOERROR; - goto abort_egress; - } - } - - if ( (fh = open(new_dmi->vtpm_tx_fname, O_RDWR)) == -1) { - if ( mkfifo(new_dmi->vtpm_tx_fname, S_IWUSR | S_IRUSR ) ) { - vtpmlogerror(VTPM_LOG_VTPM, "Failed to create dmi fifo.\n"); - status = TPM_IOERROR; - goto abort_egress; - } - } - - // Launch DMI - sprintf(dmi_id_str, "%d", (int) dmi_id); -#ifdef MANUAL_DM_LAUNCH - vtpmlogerror(VTPM_LOG_VTPM, "FAKING starting vtpm with dmi=%s\n", dmi_id_str); - new_dmi->dmi_pid = 0; -#else - pid_t pid = fork(); - - if (pid == -1) { - vtpmlogerror(VTPM_LOG_VTPM, "Could not fork to launch vtpm\n"); - status = TPM_RESOURCES; - goto abort_egress; - } else if (pid == 0) { - if ( stat(new_dmi->NVMLocation, &file_info) == -1) - execl (TPM_EMULATOR_PATH, "vtmpd", "clear", dmi_id_str, NULL); - else - execl (TPM_EMULATOR_PATH, "vtpmd", "save", dmi_id_str, NULL); - - // Returning from these at all is an error. - vtpmlogerror(VTPM_LOG_VTPM, "Could not exec to launch vtpm\n"); - } else { - new_dmi->dmi_pid = pid; - vtpmloginfo(VTPM_LOG_VTPM, "Launching DMI on PID = %d\n", pid); - } -#endif // MANUAL_DM_LAUNCH - } -#else // VTPM_MUTLI_VM - // FIXME: Measure DMI through call to Measurement agent in platform. -#endif - - vtpm_globals->DMI_table_dirty = TRUE; new_dmi->connected = TRUE; - status=TPM_SUCCESS; + + // Design specific new DMI code. + // Includes: create IPCs, Measuring DMI, and maybe launching DMI + status = VTPM_New_DMI_Extra(new_dmi); goto egress; abort_egress: vtpmlogerror(VTPM_LOG_VTPM, "Failed to create DMI id=%d due to status=%s. Cleaning.\n", dmi_id, tpm_get_error_name(status)); - close_dmi( new_dmi ); + close_dmi(new_dmi ); egress: return status; @@ -293,7 +179,7 @@ TPM_RESULT VTPM_Handle_Close_DMI( const goto abort_egress; } - if (!dmi_res->connected) { + if (!dmi_res->connected) { vtpmlogerror(VTPM_LOG_VTPM, "Closing non-connected DMI.\n"); status = TPM_BAD_PARAMETER; goto abort_egress; diff -r 43d141d56c78 -r 72ef14e79cc0 tools/vtpm_manager/manager/securestorage.c --- a/tools/vtpm_manager/manager/securestorage.c Wed May 17 23:19:18 2006 +0100 +++ b/tools/vtpm_manager/manager/securestorage.c Wed May 17 23:23:26 2006 +0100 @@ -197,9 +197,6 @@ TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI &vtpm_globals->storageKey, &sealed_NVM) ); - // Mark DMI Table so new save state info will get pushed to disk on return. - vtpm_globals->DMI_table_dirty = TRUE; - // Write sealed blob off disk from NVMLocation // TODO: How to properly return from these. Do we care if we return failure // after writing the file? We can't get the old one back. @@ -303,7 +300,7 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI } -TPM_RESULT VTPM_SaveService(void) { +TPM_RESULT VTPM_SaveManagerData(void) { TPM_RESULT status=TPM_SUCCESS; int fh, dmis=-1; @@ -317,7 +314,7 @@ TPM_RESULT VTPM_SaveService(void) { struct hashtable_itr *dmi_itr; VTPM_DMI_RESOURCE *dmi_res; - UINT32 boot_key_size, flat_dmis_size; + UINT32 boot_key_size = 0, flat_dmis_size = 0; // Initially fill these with buffer sizes for each data type. Later fill // in actual size, once flattened. @@ -347,11 +344,11 @@ TPM_RESULT VTPM_SaveService(void) { BSG_PackConst(buffer_len(&enc_flat_global), 4, flat_enc); // Per DMI values to be saved (if any exit) - if (hashtable_count(vtpm_globals->dmi_map) > 0) { - - flat_dmis_size = (hashtable_count(vtpm_globals->dmi_map) - 1) * // num DMIS (-1 for Dom0) - (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)); // Per DMI info - flat_dmis = (BYTE *) malloc( flat_dmis_size ); + if (hashtable_count(vtpm_globals->dmi_map) > 1) { + + flat_dmis = (BYTE *) malloc( + (hashtable_count(vtpm_globals->dmi_map) - 1) * // num DMIS (-1 for Dom0) + (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)) ); // Per DMI info dmi_itr = hashtable_iterator(vtpm_globals->dmi_map); do { @@ -387,8 +384,6 @@ TPM_RESULT VTPM_SaveService(void) { goto abort_egress; } - vtpm_globals->DMI_table_dirty = FALSE; - goto egress; abort_egress: @@ -400,11 +395,11 @@ TPM_RESULT VTPM_SaveService(void) { free(flat_dmis); close(fh); - vtpmloginfo(VTPM_LOG_VTPM, "Saved VTPM Service state (status = %d, dmis = %d)\n", (int) status, dmis); - return status; -} - -TPM_RESULT VTPM_LoadService(void) { + vtpmloginfo(VTPM_LOG_VTPM, "Saved VTPM Manager state (status = %d, dmis = %d)\n", (int) status, dmis); + return status; +} + +TPM_RESULT VTPM_LoadManagerData(void) { TPM_RESULT status=TPM_SUCCESS; int fh, stat_ret, dmis=0; diff -r 43d141d56c78 -r 72ef14e79cc0 tools/vtpm_manager/manager/vtpm_manager.c --- a/tools/vtpm_manager/manager/vtpm_manager.c Wed May 17 23:19:18 2006 +0100 +++ b/tools/vtpm_manager/manager/vtpm_manager.c Wed May 17 23:23:26 2006 +0100 @@ -39,17 +39,7 @@ #include <stdio.h> #include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> #include <string.h> - -#ifndef VTPM_MULTI_VM -#include <pthread.h> -#include <errno.h> -#include <aio.h> -#include <time.h> -#endif #include "vtpm_manager.h" #include "vtpmpriv.h" @@ -63,16 +53,6 @@ VTPM_GLOBALS *vtpm_globals=NULL; -#ifdef VTPM_MULTI_VM - #define vtpmhandlerloginfo(module,fmt,args...) vtpmloginfo (module, fmt, ##args ); - #define vtpmhandlerloginfomore(module,fmt,args...) vtpmloginfomore (module, fmt, ##args ); - #define vtpmhandlerlogerror(module,fmt,args...) vtpmlogerror (module, fmt, ##args ); -#else - #define vtpmhandlerloginfo(module,fmt,args...) vtpmloginfo (module, "[%d]: " fmt, threadType, ##args ); - #define vtpmhandlerloginfomore(module,fmt,args...) vtpmloginfomore (module, fmt, ##args ); - #define vtpmhandlerlogerror(module,fmt,args...) vtpmlogerror (module, "[%d]: " fmt, threadType, ##args ); -#endif - // --------------------------- Well Known Auths -------------------------- const TPM_AUTHDATA SRK_AUTH = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; @@ -95,7 +75,7 @@ static int equals32(void *k1, void *k2) // --------------------------- Functions ------------------------------ -TPM_RESULT VTPM_Create_Service(){ +TPM_RESULT VTPM_Create_Manager(){ TPM_RESULT status = TPM_SUCCESS; @@ -184,562 +164,21 @@ TPM_RESULT VTPM_Create_Service(){ NULL, &vtpm_globals->bootKey, TRUE ) ); + + printf("***************************** FIXME: SAVE NEW STATE *******\n"); goto egress; abort_egress: exit(1); egress: - vtpmloginfo(VTPM_LOG_VTPM, "Finished initialized new VTPM service (Status = %d).\n", status); + vtpmloginfo(VTPM_LOG_VTPM, "Finished initialized new VTPM manager (Status = %d).\n", status); return status; } - -////////////////////////////////////////////////////////////////////////////// -#ifdef VTPM_MULTI_VM -int VTPM_Service_Handler(){ -#else -void *VTPM_Service_Handler(void *threadTypePtr){ -#endif - TPM_RESULT status = TPM_FAIL; // Should never return - UINT32 dmi, in_param_size, cmd_size, out_param_size, out_message_size, out_message_size_full; - BYTE *cmd_header, *in_param, *out_message; - buffer_t *command_buf=NULL, *result_buf=NULL; - TPM_TAG tag; - TPM_COMMAND_CODE ord; - VTPM_DMI_RESOURCE *dmi_res; - int size_read, size_write, i; - -#ifndef VTPM_MULTI_VM - UINT32 dmi_cmd_size; - BYTE *dmi_cmd; - int threadType = *(int *) threadTypePtr; - - // async io structures - struct aiocb dmi_aio; - struct aiocb *dmi_aio_a[1]; - dmi_aio_a[0] = &dmi_aio; -#endif - -#ifdef DUMMY_BACKEND - int dummy_rx; -#endif - - cmd_header = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV); - command_buf = (buffer_t *) malloc(sizeof(buffer_t)); - result_buf = (buffer_t *) malloc(sizeof(buffer_t)); - -#ifndef VTPM_MULTI_VM - TPM_RESULT *ret_value = (TPM_RESULT *) malloc(sizeof(TPM_RESULT)); -#endif - - int *tx_fh, // Pointer to the filehandle this function will write to - *rx_fh; // Pointer to the filehandle this function will read from - // For a multi VM VTPM system, this function tx/rx with the BE - // via vtpm_globals->be_fh. - // For a single VM system, the BE_LISTENER_THREAD tx/rx with theBE - // via vtpm_globals->be_fh, and the DMI_LISTENER_THREAD rx from - // vtpm_globals->vtpm_rx_fh and tx to dmi_res->vtpm_tx_fh - - // Set rx_fh to point to the correct fh based on this mode. -#ifdef VTPM_MULTI_VM - rx_fh = &vtpm_globals->be_fh; -#else - if (threadType == BE_LISTENER_THREAD) { - #ifdef DUMMY_BACKEND - dummy_rx = -1; - rx_fh = &dummy_rx; - #else - rx_fh = &vtpm_globals->be_fh; - #endif - } else { // DMI_LISTENER_THREAD - rx_fh = &vtpm_globals->vtpm_rx_fh; - } -#endif - - // Set tx_fh to point to the correct fh based on this mode (If static) - // Create any fifos that these fh will use. -#ifndef VTPM_MULTI_VM - int fh; - if (threadType == BE_LISTENER_THREAD) { - tx_fh = &vtpm_globals->be_fh; - if ( (fh = open(GUEST_RX_FIFO, O_RDWR)) == -1) { - if ( mkfifo(GUEST_RX_FIFO, S_IWUSR | S_IRUSR ) ){ - vtpmlogerror(VTPM_LOG_VTPM, "Unable to create FIFO: %s.\n", GUEST_RX_FIFO); - *ret_value = TPM_FAIL; - pthread_exit(ret_value); - } - } else - close(fh); - - } else { // else DMI_LISTENER_THREAD - // tx_fh will be set once the DMI is identified - // But we need to make sure the read pip is created. - if ( (fh = open(VTPM_RX_FIFO, O_RDWR)) == -1) { - if ( mkfifo(VTPM_RX_FIFO, S_IWUSR | S_IRUSR ) ){ - vtpmlogerror(VTPM_LOG_VTPM, "Unable to create FIFO: %s.\n", VTPM_RX_FIFO); - *ret_value = TPM_FAIL; - pthread_exit(ret_value); - } - } else - close(fh); - - } -#else - tx_fh = &vtpm_globals->be_fh; -#endif - - ////////////////////////// Main Loop ////////////////////////////////// - while(1) { - -#ifdef VTPM_MULTI_VM - vtpmhandlerloginfo(VTPM_LOG_VTPM, "Waiting for DMI messages.\n"); -#else - if (threadType == BE_LISTENER_THREAD) { - vtpmhandlerloginfo(VTPM_LOG_VTPM, "Waiting for Guest requests & ctrl messages.\n"); - } else - vtpmhandlerloginfo(VTPM_LOG_VTPM, "Waiting for DMI messages.\n"); -#endif - - // Check status of rx_fh. If necessary attempt to re-open it. - char* s = NULL; - if (*rx_fh < 0) { -#ifdef VTPM_MULTI_VM - s = VTPM_BE_DEV; -#else - if (threadType == BE_LISTENER_THREAD) - #ifdef DUMMY_BACKEND - s = "/tmp/in.fifo"; - #else - s = VTPM_BE_DEV; - #endif - else // DMI Listener - s = VTPM_RX_FIFO; - *rx_fh = open(s, O_RDWR); -#endif - } - - // Respond to failures to open rx_fh - if (*rx_fh < 0) { - vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't open inbound fh for %s.\n", s); -#ifdef VTPM_MULTI_VM - return TPM_IOERROR; -#else - *ret_value = TPM_IOERROR; - pthread_exit(ret_value); -#endif - } - - // Read command header from rx_fh - size_read = read(*rx_fh, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV); - if (size_read > 0) { - vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV[%d}: 0x", size_read); - for (i=0; i<size_read; i++) - vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]); - } else { - vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't read from BE. Aborting... \n"); - close(*rx_fh); - *rx_fh = -1; - goto abort_command; - } - - if (size_read < (int) VTPM_COMMAND_HEADER_SIZE_SRV) { - vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "\n"); - vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command shorter than normal header (%d bytes). Aborting...\n", size_read); - goto abort_command; - } - - // Unpack header - BSG_UnpackList(cmd_header, 4, - BSG_TYPE_UINT32, &dmi, - BSG_TPM_TAG, &tag, - BSG_TYPE_UINT32, &in_param_size, - BSG_TPM_COMMAND_CODE, &ord ); - - // Using the header info, read from rx_fh the parameters of the command - // Note that in_param_size is in the client's context - cmd_size = in_param_size - VTPM_COMMAND_HEADER_SIZE_CLT; - if (cmd_size > 0) { - in_param = (BYTE *) malloc(cmd_size); - size_read = read( *rx_fh, in_param, cmd_size); - if (size_read > 0) { - for (i=0; i<size_read; i++) - vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]); - - } else { - vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error reading from cmd. Aborting... \n"); - close(*rx_fh); - *rx_fh = -1; - goto abort_command; - } - vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); - - if (size_read < (int) cmd_size) { - vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); - vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command read(%d) is shorter than header indicates(%d). Aborting...\n", size_read, cmd_size); - goto abort_command; - } - } else { - in_param = NULL; - vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); - } - -#ifndef VTPM_MULTI_VM - // It's illegal to receive a Dom0 command from a DMI. - if ((threadType != BE_LISTENER_THREAD) && (dmi == 0)) { - vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempt to access dom0 commands from DMI interface. Aborting...\n"); - goto abort_command; - } -#endif - - // Fetch infomation about the DMI issuing the request. - dmi_res = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi); - if (dmi_res == NULL) { - vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempted access to non-existent DMI in domain: %d. Aborting...\n", dmi); - goto abort_command; - } - if (!dmi_res->connected) { - vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempted access to disconnected DMI in domain: %d. Aborting...\n", dmi); - goto abort_command; - } - -#ifndef VTPM_MULTI_VM - // Now that we know which DMI this is, we can set the tx_fh handle. - if (threadType != BE_LISTENER_THREAD) - tx_fh = &dmi_res->vtpm_tx_fh; - // else we set this before the while loop since it doesn't change. -#endif - - // Init the buffers used to handle the command and the response - if ( (buffer_init_convert(command_buf, cmd_size, in_param) != TPM_SUCCESS) || - (buffer_init(result_buf, 0, 0) != TPM_SUCCESS) ) { - vtpmhandlerlogerror(VTPM_LOG_VTPM, "Failed to setup buffers. Aborting...\n"); - goto abort_command; - } - - // Dispatch it as either control or user request. - if (tag == VTPM_TAG_REQ) { - if (dmi_res->dmi_id == VTPM_CTL_DM){ - switch (ord) { - case VTPM_ORD_OPEN: - status = VTPM_Handle_New_DMI(command_buf); - break; - - case VTPM_ORD_CLOSE: - status = VTPM_Handle_Close_DMI(command_buf); - break; - - case VTPM_ORD_DELETE: - status = VTPM_Handle_Delete_DMI(command_buf); - break; - default: - status = TPM_BAD_ORDINAL; - } // switch - } else { - - switch (ord) { - case VTPM_ORD_SAVENVM: - status= VTPM_Handle_Save_NVM(dmi_res, - command_buf, - result_buf); - break; - case VTPM_ORD_LOADNVM: - status= VTPM_Handle_Load_NVM(dmi_res, - command_buf, - result_buf); - break; - - case VTPM_ORD_TPMCOMMAND: - status= VTPM_Handle_TPM_Command(dmi_res, - command_buf, - result_buf); - break; - - default: - status = TPM_BAD_ORDINAL; - } // switch - } - } else { // This is not a VTPM Command at all. - // This happens in two cases. - // MULTI_VM = A DMI illegally sent a raw TPM command to the manager - // Single VM: - // BE_LISTENER_THREAD: Guest issued a TPM command. - // Send this to DMI and wait for response - // DMI_LISTENER_THREAD: A DMI illegally sent a raw TPM command. - -#ifdef VTPM_MULTI_VM - // Raw TPM commands are not supported from the DMI - vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempt to use unsupported direct access to TPM.\n"); - vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "Bad Command. dmi:%d, tag:%d, size:%d, ord:%d, Params: ", dmi, tag, in_param_size, ord); - for (i=0; i<cmd_size; i++) - vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]); - - vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); - status = TPM_FAIL; - -#else - // If BE_LISTENER_THREAD then this is a TPM command from a guest - if (threadType == BE_LISTENER_THREAD) { - // Dom0 can't talk to the BE, so this must be a broken FE/BE or badness - if (dmi == 0) { - vtpmhandlerlogerror(VTPM_LOG_VTPM, "Illegal use of TPM command from dom0\n"); - status = TPM_FAIL; - } else { - vtpmhandlerloginfo(VTPM_LOG_VTPM, "Forwarding command to DMI.\n"); - - // open the dmi_res->guest_tx_fh to send command to DMI - if (dmi_res->guest_tx_fh < 0) - dmi_res->guest_tx_fh = open(dmi_res->guest_tx_fname, O_WRONLY | O_NONBLOCK); - - // handle failed opens dmi_res->guest_tx_fh - if (dmi_res->guest_tx_fh < 0){ - vtpmhandlerlogerror(VTPM_LOG_VTPM, "VTPM ERROR: Can't open outbound fh to dmi.\n"); - status = TPM_IOERROR; - goto abort_with_error; - } - - //Forward TPM CMD stamped with dmi_id to DMI for handling - if (cmd_size) { - dmi_cmd = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV + cmd_size); - dmi_cmd_size = VTPM_COMMAND_HEADER_SIZE_SRV + cmd_size; - memcpy(dmi_cmd, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV); - memcpy(dmi_cmd + VTPM_COMMAND_HEADER_SIZE_SRV, in_param, cmd_size); - size_write = write(dmi_res->guest_tx_fh, dmi_cmd, dmi_cmd_size); - - if (size_write > 0) { - vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT (DMI): 0x"); - for (i=0; i<VTPM_COMMAND_HEADER_SIZE_SRV + cmd_size; i++) { - vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", dmi_cmd[i]); - } - vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); - } else { - vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error writing to DMI. Aborting... \n"); - close(dmi_res->guest_tx_fh); - dmi_res->guest_tx_fh = -1; - status = TPM_IOERROR; - goto abort_with_error; - } - free(dmi_cmd); - } else { - dmi_cmd_size = VTPM_COMMAND_HEADER_SIZE_SRV; - size_write = write(dmi_res->guest_tx_fh, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV ); - if (size_write > 0) { - for (i=0; i<VTPM_COMMAND_HEADER_SIZE_SRV; i++) - vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]); - - vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); - } else { - vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error writing to DMI. Aborting... \n"); - close(dmi_res->guest_tx_fh); - dmi_res->guest_tx_fh = -1; - status = TPM_IOERROR; - goto abort_with_error; - } - } - - if (size_write != (int) dmi_cmd_size) - vtpmhandlerlogerror(VTPM_LOG_VTPM, "Could not write entire command to DMI (%d/%d)\n", size_write, dmi_cmd_size); - buffer_free(command_buf); - - // Open vtpm_globals->guest_rx_fh to receive DMI response - if (vtpm_globals->guest_rx_fh < 0) - vtpm_globals->guest_rx_fh = open(GUEST_RX_FIFO, O_RDONLY); - - // Handle open failures - if (vtpm_globals->guest_rx_fh < 0){ - vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't open inbound fh to dmi.\n"); - status = TPM_IOERROR; - goto abort_with_error; - } - - // Read header for response to TPM command from DMI - size_read = read( vtpm_globals->guest_rx_fh, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV); - if (size_read > 0) { - vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV (DMI): 0x"); - for (i=0; i<size_read; i++) - vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]); - - } else { - vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error reading from DMI. Aborting... \n"); - close(vtpm_globals->guest_rx_fh); - vtpm_globals->guest_rx_fh = -1; - status = TPM_IOERROR; - goto abort_with_error; - } - - if (size_read < (int) VTPM_COMMAND_HEADER_SIZE_SRV) { - //vtpmdeepsublog("\n"); - vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command from DMI shorter than normal header. Aborting...\n"); - status = TPM_IOERROR; - goto abort_with_error; - } - - // Unpack response from DMI for TPM command - BSG_UnpackList(cmd_header, 4, - BSG_TYPE_UINT32, &dmi, - BSG_TPM_TAG, &tag, - BSG_TYPE_UINT32, &in_param_size, - BSG_TPM_COMMAND_CODE, &status ); - - // If response has parameters, read them. - // Note that in_param_size is in the client's context - cmd_size = in_param_size - VTPM_COMMAND_HEADER_SIZE_CLT; - if (cmd_size > 0) { - in_param = (BYTE *) malloc(cmd_size); - size_read = read( vtpm_globals->guest_rx_fh, in_param, cmd_size); - if (size_read > 0) { - for (i=0; i<size_read; i++) - vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]); - - } else { - vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error reading from BE. Aborting... \n"); - close(vtpm_globals->guest_rx_fh); - vtpm_globals->guest_rx_fh = -1; - status = TPM_IOERROR; - goto abort_with_error; - } - vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n"); - - if (size_read < (int)cmd_size) { - vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n"); - vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command read(%d) from DMI is shorter than header indicates(%d). Aborting...\n", size_read, cmd_size); - status = TPM_IOERROR; - goto abort_with_error; - } - } else { - in_param = NULL; - vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n"); - } - - if (buffer_init_convert(result_buf, cmd_size, in_param) != TPM_SUCCESS) { - vtpmhandlerlogerror(VTPM_LOG_VTPM, "Failed to setup buffers. Aborting...\n"); - status = TPM_FAIL; - goto abort_with_error; - } - - vtpmhandlerloginfo(VTPM_LOG_VTPM, "Sending DMI's response to guest.\n"); - } // end else for if (dmi==0) - - } else { // This is a DMI lister thread. Thus this is from a DMI - // Raw TPM commands are not supported from the DMI - vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempt to use unsupported direct access to TPM.\n"); - vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "Bad Command. dmi:%d, tag:%d, size:%d, ord:%d, Params: ", dmi, tag, in_param_size, ord); - for (i=0; i<cmd_size; i++) - vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]); - - vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); - - status = TPM_FAIL; - } // end else for if BE Listener -#endif - - } // end else for is VTPM Command - - // This marks the beginning of preparing response to be sent out. - // Errors while handling responses jump here to reply with error messages - // NOTE: Currently there are no recoverable errors in multi-VM mode. If one - // is added to the code, this ifdef should be removed. - // Also note this is NOT referring to errors in commands, but rather - // this is about I/O errors and such. -#ifndef VTPM_MULTI_VM - abort_with_error: -#endif - - // Open tx_fh in preperation to send reponse back - if (*tx_fh < 0) { -#ifdef VTPM_MULTI_VM - *tx_fh = open(VTPM_BE_DEV, O_RDWR); -#else - if (threadType == BE_LISTENER_THREAD) - #ifdef DUMMY_BACKEND - *tx_fh = open("/tmp/out.fifo", O_RDWR); - #else - *tx_fh = open(VTPM_BE_DEV, O_RDWR); - #endif - else // DMI Listener - *tx_fh = open(dmi_res->vtpm_tx_fname, O_WRONLY); -#endif - } - - - // Handle failed open - if (*tx_fh < 0) { - vtpmhandlerlogerror(VTPM_LOG_VTPM, "VTPM ERROR: Can't open outbound fh.\n"); -#ifdef VTPM_MULTI_VM - return TPM_IOERROR; -#else - *ret_value = TPM_IOERROR; - pthread_exit(ret_value); -#endif - } - - // Prepend VTPM header with destination DM stamped - out_param_size = buffer_len(result_buf); - out_message_size = VTPM_COMMAND_HEADER_SIZE_CLT + out_param_size; - out_message_size_full = VTPM_COMMAND_HEADER_SIZE_SRV + out_param_size; - out_message = (BYTE *) malloc (out_message_size_full); - - BSG_PackList(out_message, 4, - BSG_TYPE_UINT32, (BYTE *) &dmi, - BSG_TPM_TAG, (BYTE *) &tag, - BSG_TYPE_UINT32, (BYTE *) &out_message_size, - BSG_TPM_RESULT, (BYTE *) &status); - - if (buffer_len(result_buf) > 0) - memcpy(out_message + VTPM_COMMAND_HEADER_SIZE_SRV, result_buf->bytes, out_param_size); - - - //Note: Send message + dmi_id - size_write = write(*tx_fh, out_message, out_message_size_full ); - if (size_write > 0) { - vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT: 0x"); - for (i=0; i < out_message_size_full; i++) - vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", out_message[i]); - - vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); - } else { - vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error writing to BE. Aborting... \n"); - close(*tx_fh); - *tx_fh = -1; - goto abort_command; - } - free(out_message); - - if (size_write < (int)out_message_size_full) { - vtpmhandlerlogerror(VTPM_LOG_VTPM, "Unable to write full command to BE (%d/%d)\n", size_write, out_message_size_full); - goto abort_command; - } - - // On certain failures an error message cannot be sent. - // This marks the beginning of cleanup in preperation for the next command. - abort_command: - //free buffers - bzero(cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV); - //free(in_param); // This was converted to command_buf. No need to free - if (command_buf != result_buf) - buffer_free(result_buf); - - buffer_free(command_buf); - -#ifndef VTPM_MULTI_VM - if (threadType != BE_LISTENER_THREAD) { -#endif - if ( (vtpm_globals->DMI_table_dirty) && - (VTPM_SaveService() != TPM_SUCCESS) ) { - vtpmhandlerlogerror(VTPM_LOG_VTPM, "ERROR: Unable to save manager data.\n"); - } -#ifndef VTPM_MULTI_VM - } -#endif - - } // End while(1) - -} - - /////////////////////////////////////////////////////////////////////////////// -TPM_RESULT VTPM_Init_Service() { +TPM_RESULT VTPM_Init_Manager() { TPM_RESULT status = TPM_FAIL, serviceStatus; BYTE *randomsead; UINT32 randomsize; @@ -749,19 +188,13 @@ TPM_RESULT VTPM_Init_Service() { goto abort_egress; } memset(vtpm_globals, 0, sizeof(VTPM_GLOBALS)); - vtpm_globals->be_fh = -1; - -#ifndef VTPM_MULTI_VM - vtpm_globals->vtpm_rx_fh = -1; - vtpm_globals->guest_rx_fh = -1; + vtpm_globals->connected_dmis = 0; -#endif + if ((vtpm_globals->dmi_map = create_hashtable(10, hashfunc32, equals32)) == NULL){ status = TPM_FAIL; goto abort_egress; } - - vtpm_globals->DMI_table_dirty = FALSE; // Create new TCS Object vtpm_globals->manager_tcs_handle = 0; @@ -783,13 +216,14 @@ TPM_RESULT VTPM_Init_Service() { &vtpm_globals->keyAuth) ); vtpm_globals->keyAuth.fContinueAuthSession = TRUE; - // If failed, create new Service. - serviceStatus = VTPM_LoadService(); + // If failed, create new Manager. + serviceStatus = VTPM_LoadManagerData(); if (serviceStatus == TPM_IOERROR) { - vtpmloginfo(VTPM_LOG_VTPM, "Failed to read service file. Assuming first time initialization.\n"); - TPMTRYRETURN( VTPM_Create_Service() ); + vtpmloginfo(VTPM_LOG_VTPM, "Failed to read manager file. Assuming first time initialization.\n"); + TPMTRYRETURN( VTPM_Create_Manager() ); + TPMTRYRETURN( VTPM_SaveManagerData() ); } else if (serviceStatus != TPM_SUCCESS) { - vtpmlogerror(VTPM_LOG_VTPM, "Failed to read existing service file"); + vtpmlogerror(VTPM_LOG_VTPM, "Failed to read existing manager file"); exit(1); } @@ -805,8 +239,6 @@ TPM_RESULT VTPM_Init_Service() { // Create entry for Dom0 for control messages TPMTRYRETURN( VTPM_Handle_New_DMI(NULL) ); - - // --------------------- Command handlers --------------------------- goto egress; @@ -815,8 +247,9 @@ TPM_RESULT VTPM_Init_Service() { return(status); } - -void VTPM_Stop_Service() { + +/////////////////////////////////////////////////////////////////////////////// +void VTPM_Stop_Manager() { VTPM_DMI_RESOURCE *dmi_res; struct hashtable_itr *dmi_itr; @@ -832,7 +265,7 @@ void VTPM_Stop_Service() { free (dmi_itr); } - if ( (vtpm_globals->DMI_table_dirty) && (VTPM_SaveService() != TPM_SUCCESS) ) + if ( VTPM_SaveManagerData() != TPM_SUCCESS ) vtpmlogerror(VTPM_LOG_VTPM, "Unable to save manager data.\n"); TCS_CloseContext(vtpm_globals->manager_tcs_handle); @@ -841,7 +274,6 @@ void VTPM_Stop_Service() { hashtable_destroy(vtpm_globals->dmi_map, 1); free(vtpm_globals); - close(vtpm_globals->be_fh); Crypto_Exit(); vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager stopped.\n"); diff -r 43d141d56c78 -r 72ef14e79cc0 tools/vtpm_manager/manager/vtpm_manager.h --- a/tools/vtpm_manager/manager/vtpm_manager.h Wed May 17 23:19:18 2006 +0100 +++ b/tools/vtpm_manager/manager/vtpm_manager.h Wed May 17 23:23:26 2006 +0100 @@ -40,32 +40,30 @@ #ifndef __VTPM_MANAGER_H__ #define __VTPM_MANAGER_H__ -#include "tcg.h" - #define VTPM_TAG_REQ 0x01c1 #define VTPM_TAG_RSP 0x01c4 #define COMMAND_BUFFER_SIZE 4096 // Header sizes. Note Header MAY include the DMI -#define VTPM_COMMAND_HEADER_SIZE_SRV ( sizeof(UINT32) + sizeof(TPM_TAG) + sizeof(UINT32) + sizeof(TPM_COMMAND_CODE)) -#define VTPM_COMMAND_HEADER_SIZE_CLT ( sizeof(TPM_TAG) + sizeof(UINT32) + sizeof(TPM_COMMAND_CODE)) - -// ********************** Public Functions ************************* -TPM_RESULT VTPM_Init_Service(); // Start VTPM Service -void VTPM_Stop_Service(); // Stop VTPM Service -#ifdef VTPM_MULTI_VM -int VTPM_Service_Handler(); -#else -void *VTPM_Service_Handler(void *threadTypePtr); -#endif +#define VTPM_COMMAND_HEADER_SIZE_CLT ( 2 + 4 + 4) +// sizeof(TPM_TAG + UINT32 + TPM_COMMAND_CODE) +#define VTPM_COMMAND_HEADER_SIZE_SRV ( 4 + VTPM_COMMAND_HEADER_SIZE_CLT ) +// sizeof( UINT32 + VTPM_COMMAND_HEADER_SIZE_CLT) //************************ Command Codes **************************** -#define VTPM_ORD_OPEN 1 // ULM Creates New DMI -#define VTPM_ORD_CLOSE 2 // ULM Closes a DMI -#define VTPM_ORD_DELETE 3 // ULM Permemently Deletes DMI -#define VTPM_ORD_SAVENVM 4 // DMI requests Secrets Unseal -#define VTPM_ORD_LOADNVM 5 // DMI requests Secrets Saved -#define VTPM_ORD_TPMCOMMAND 6 // DMI issues HW TPM Command +#define VTPM_ORD_BASE 0x0000 +#define VTPM_PRIV_MASK 0x01000000 // Priviledged VTPM Command +#define VTPM_PRIV_BASE (VTPM_ORD_BASE | VTPM_PRIV_MASK) + +// Non-priviledged VTPM Commands (From DMI's) +#define VTPM_ORD_SAVENVM (VTPM_ORD_BASE + 1) // DMI Saves Secrets +#define VTPM_ORD_LOADNVM (VTPM_ORD_BASE + 2) // DMI Loads Secrets +#define VTPM_ORD_TPMCOMMAND (VTPM_ORD_BASE + 3) // DMI issues HW TPM Command + +// Priviledged VTPM Commands (From management console) +#define VTPM_ORD_OPEN (VTPM_PRIV_BASE + 1) // Creates/reopens DMI +#define VTPM_ORD_CLOSE (VTPM_PRIV_BASE + 2) // Closes a DMI +#define VTPM_ORD_DELETE (VTPM_PRIV_BASE + 3) // Permemently Deletes DMI //************************ Return Codes **************************** #define VTPM_SUCCESS 0 diff -r 43d141d56c78 -r 72ef14e79cc0 tools/vtpm_manager/manager/vtpmd.c --- a/tools/vtpm_manager/manager/vtpmd.c Wed May 17 23:19:18 2006 +0100 +++ b/tools/vtpm_manager/manager/vtpmd.c Wed May 17 23:23:26 2006 +0100 @@ -38,21 +38,67 @@ // =================================================================== #include <stdio.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> #include <signal.h> -#include <sys/types.h> -#include <unistd.h> +#include <string.h> +#include <pthread.h> #include "vtpm_manager.h" #include "vtpmpriv.h" #include "tcg.h" #include "log.h" - -#ifndef VTPM_MULTI_VM - #include <pthread.h> -#endif +#include "vtpm_ipc.h" + + +#define TPM_EMULATOR_PATH "/usr/bin/vtpmd" + +#define VTPM_BE_FNAME "/dev/vtpm" +#define VTPM_DUMMY_TX_BE_FNAME "/var/vtpm/fifos/dummy_out.fifo" +#define VTPM_DUMMY_RX_BE_FNAME "/var/vtpm/fifos/dummy_in.fifo" +#define VTPM_TX_TPM_FNAME "/var/vtpm/fifos/tpm_cmd_to_%d.fifo" +#define VTPM_RX_TPM_FNAME "/var/vtpm/fifos/tpm_rsp_from_all.fifo" +#define VTPM_TX_VTPM_FNAME "/var/vtpm/fifos/vtpm_rsp_to_%d.fifo" +#define VTPM_RX_VTPM_FNAME "/var/vtpm/fifos/vtpm_cmd_from_all.fifo" +#define VTPM_TX_HP_FNAME "/var/vtpm/fifos/to_console.fifo" +#define VTPM_RX_HP_FNAME "/var/vtpm/fifos/from_console.fifo" + + +#define GUEST_TX_FIFO "/var/vtpm/fifos/guest-to-%d.fifo" +#define GUEST_RX_FIFO "/var/vtpm/fifos/guest-from-all.fifo" + +#define VTPM_TX_FIFO "/var/vtpm/fifos/vtpm-to-%d.fifo" +#define VTPM_RX_FIFO "/var/vtpm/fifos/vtpm-from-all.fifo" + + +struct vtpm_thread_params_s { + vtpm_ipc_handle_t *tx_ipc_h; + vtpm_ipc_handle_t *rx_ipc_h; + BOOL fw_tpm; + vtpm_ipc_handle_t *fw_tx_ipc_h; + vtpm_ipc_handle_t *fw_rx_ipc_h; + BOOL is_priv; + char *thread_name; +}; + +// This is needed to all extra_close_dmi to close this to prevent a +// broken pipe when no DMIs are left. +static vtpm_ipc_handle_t *g_rx_tpm_ipc_h; + +void *vtpm_manager_thread(void *arg_void) { + TPM_RESULT *status = (TPM_RESULT *) malloc(sizeof(TPM_RESULT) ); + struct vtpm_thread_params_s *arg = (struct vtpm_thread_params_s *) arg_void; + + *status = VTPM_Manager_Handler(arg->tx_ipc_h, arg->rx_ipc_h, + arg->fw_tpm, arg->fw_tx_ipc_h, arg->fw_rx_ipc_h, + arg->is_priv, arg->thread_name); + + return (status); +} + void signal_handler(int reason) { -#ifndef VTPM_MULTI_VM - if (pthread_equal(pthread_self(), vtpm_globals->master_pid)) { vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager shutting down for signal %d.\n", reason); } else { @@ -60,71 +106,258 @@ void signal_handler(int reason) { vtpmloginfo(VTPM_LOG_VTPM, "Child shutting down\n"); pthread_exit(NULL); } + + VTPM_Stop_Manager(); + exit(-1); +} + +struct sigaction ctl_c_handler; + +TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res) { + + TPM_RESULT status = TPM_SUCCESS; + int fh; + char dmi_id_str[11]; // UINT32s are up to 10 digits + NULL + char *tx_vtpm_name, *tx_tpm_name; + struct stat file_info; + + if (dmi_res->dmi_id == VTPM_CTL_DM) { + dmi_res->tx_tpm_ipc_h = NULL; + dmi_res->rx_tpm_ipc_h = NULL; + dmi_res->tx_vtpm_ipc_h = NULL; + dmi_res->rx_vtpm_ipc_h = NULL; + } else { + // Create a pair of fifo pipes + dmi_res->rx_tpm_ipc_h = NULL; + dmi_res->rx_vtpm_ipc_h = NULL; + + if ( ((dmi_res->tx_tpm_ipc_h = (vtpm_ipc_handle_t *) malloc (sizeof(vtpm_ipc_handle_t))) == NULL ) || + ((dmi_res->tx_vtpm_ipc_h =(vtpm_ipc_handle_t *) malloc (sizeof(vtpm_ipc_handle_t))) == NULL ) || + ((tx_tpm_name = (char *) malloc(11 + strlen(VTPM_TX_TPM_FNAME))) == NULL ) || + ((tx_vtpm_name =(char *) malloc(11 + strlen(VTPM_TX_VTPM_FNAME))) == NULL) ) { + status =TPM_RESOURCES; + goto abort_egress; + } + + sprintf(tx_tpm_name, VTPM_TX_TPM_FNAME, (uint32_t) dmi_res->dmi_id); + sprintf(tx_vtpm_name, VTPM_TX_VTPM_FNAME, (uint32_t) dmi_res->dmi_id); + + if ( (vtpm_ipc_init(dmi_res->tx_tpm_ipc_h, tx_tpm_name, O_WRONLY | O_NONBLOCK, TRUE) != 0) || + (vtpm_ipc_init(dmi_res->tx_vtpm_ipc_h, tx_vtpm_name, O_WRONLY, TRUE) != 0) ) { //FIXME: O_NONBLOCK? + status = TPM_IOERROR; + goto abort_egress; + } + + // Measure DMI + // FIXME: This will measure DMI. Until then use a fixed DMI_Measurement value + // Also, this mechanism is specific to 1 VM. + /* + fh = open(TPM_EMULATOR_PATH, O_RDONLY); + stat_ret = fstat(fh, &file_stat); + if (stat_ret == 0) + dmi_size = file_stat.st_size; + else { + vtpmlogerror(VTPM_LOG_VTPM, "Could not open tpm_emulator!!\n"); + status = TPM_IOERROR; + goto abort_egress; + } + dmi_buffer + */ + memset(&dmi_res->DMI_measurement, 0xcc, sizeof(TPM_DIGEST)); + + + // Launch DMI + sprintf(dmi_id_str, "%d", (int) dmi_res->dmi_id); +#ifdef MANUAL_DM_LAUNCH + vtpmlogerror(VTPM_LOG_VTPM, "Manually start VTPM with dmi=%s now.\n", dmi_id_str); + dmi_res->dmi_pid = 0; +#else + pid_t pid = fork(); + + if (pid == -1) { + vtpmlogerror(VTPM_LOG_VTPM, "Could not fork to launch vtpm\n"); + status = TPM_RESOURCES; + goto abort_egress; + } else if (pid == 0) { + if ( stat(dmi_res->NVMLocation, &file_info) == -1) + execl (TPM_EMULATOR_PATH, "vtmpd", "clear", dmi_id_str, NULL); + else + execl (TPM_EMULATOR_PATH, "vtpmd", "save", dmi_id_str, NULL); + + // Returning from these at all is an error. + vtpmlogerror(VTPM_LOG_VTPM, "Could not exec to launch vtpm\n"); + } else { + dmi_res->dmi_pid = pid; + vtpmloginfo(VTPM_LOG_VTPM, "Launching DMI on PID = %d\n", pid); + } +#endif // MANUAL_DM_LAUNCH + + } // If DMI = VTPM_CTL_DM + status = TPM_SUCCESS; + +abort_egress: + return (status); +} + +TPM_RESULT VTPM_Close_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res) { + TPM_RESULT status = TPM_SUCCESS; + + if (vtpm_globals->connected_dmis == 0) { + // No more DMI's connected. Close fifo to prevent a broken pipe. + // This is hackish. Need to think of another way. + vtpm_ipc_close(g_rx_tpm_ipc_h); + } + + + if (dmi_res->dmi_id != VTPM_CTL_DM) { + vtpm_ipc_close(dmi_res->tx_tpm_ipc_h); + vtpm_ipc_close(dmi_res->tx_vtpm_ipc_h); + + free(dmi_res->tx_tpm_ipc_h->name); + free(dmi_res->tx_vtpm_ipc_h->name); + +#ifndef MANUAL_DM_LAUNCH + if (dmi_res->dmi_id != VTPM_CTL_DM) { + if (dmi_res->dmi_pid != 0) { + vtpmloginfo(VTPM_LOG_VTPM, "Killing dmi on pid %d.\n", dmi_res->dmi_pid); + if (kill(dmi_res->dmi_pid, SIGKILL) !=0) { + vtpmloginfo(VTPM_LOG_VTPM, "DMI on pid %d is already dead.\n", dmi_res->dmi_pid); + } else if (waitpid(dmi_res->dmi_pid, NULL, 0) != dmi_res->dmi_pid) { + vtpmlogerror(VTPM_LOG_VTPM, "DMI on pid %d failed to stop.\n", dmi_res->dmi_pid); + status = TPM_FAIL; + } + } else { + vtpmlogerror(VTPM_LOG_VTPM, "Could not kill dmi because it's pid was 0.\n"); + status = TPM_FAIL; + } + } #endif - VTPM_Stop_Service(); - exit(-1); -} - -struct sigaction ctl_c_handler; + + } //endif ! dom0 + return status; +} + int main(int argc, char **argv) { + vtpm_ipc_handle_t *tx_be_ipc_h, *rx_be_ipc_h, rx_tpm_ipc_h, rx_vtpm_ipc_h, tx_hp_ipc_h, rx_hp_ipc_h; + struct vtpm_thread_params_s be_thread_params, dmi_thread_params, hp_thread_params; + pthread_t be_thread, dmi_thread, hp_thread; + +#ifdef DUMMY_BACKEND + vtpm_ipc_handle_t tx_dummy_ipc_h, rx_dummy_ipc_h; +#else + vtpm_ipc_handle_t real_be_ipc_h; +#endif vtpmloginfo(VTPM_LOG_VTPM, "Starting VTPM.\n"); - - if (VTPM_Init_Service() != TPM_SUCCESS) { + + // -------------------- Initialize Manager ----------------- + if (VTPM_Init_Manager() != TPM_SUCCESS) { vtpmlogerror(VTPM_LOG_VTPM, "Closing vtpmd due to error during startup.\n"); return -1; } + // -------------------- Setup Ctrl+C Handlers -------------- ctl_c_handler.sa_handler = signal_handler; sigemptyset(&ctl_c_handler.sa_mask); ctl_c_handler.sa_flags = 0; if (sigaction(SIGINT, &ctl_c_handler, NULL) == -1) - vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGINT handler. Ctl+break will not stop service gently.\n"); + vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGINT handler. Ctl+break will not stop manager gently.\n"); // For easier debuggin with gdb if (sigaction(SIGHUP, &ctl_c_handler, NULL) == -1) - vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGHUP handler. Ctl+break will not stop service gently.\n"); - -#ifdef VTPM_MULTI_VM - TPM_RESULT status = VTPM_Service_Handler(); - - if (status != TPM_SUCCESS) - vtpmlogerror(VTPM_LOG_VTPM, "VTPM Manager exited with status %s. It never should exit.\n", tpm_get_error_name(status)); - - return -1; -#else + vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGHUP handler. Ctl+break will not stop manager gently.\n"); + sigset_t sig_mask; - sigemptyset(&sig_mask); sigaddset(&sig_mask, SIGPIPE); sigprocmask(SIG_BLOCK, &sig_mask, NULL); - //pthread_mutex_init(&vtpm_globals->dmi_mutex, NULL); - pthread_t be_thread, dmi_thread; - int betype_be, dmitype_dmi; - + + // ------------------- Set up file ipc structures ---------- +#ifdef DUMMY_BACKEND + if ( (vtpm_ipc_init(&tx_dummy_ipc_h, VTPM_DUMMY_TX_BE_FNAME, O_RDWR, TRUE) != 0) || + (vtpm_ipc_init(&rx_dummy_ipc_h, VTPM_DUMMY_RX_BE_FNAME, O_RDWR, TRUE) != 0) ) { + + vtpmlogerror(VTPM_LOG_VTPM, "Unable to create Dummy BE FIFOs.\n"); + exit(-1); + } + + tx_be_ipc_h = &tx_dummy_ipc_h; + rx_be_ipc_h = &rx_dummy_ipc_h; +#else + vtpm_ipc_init(&real_be_ipc_h, VTPM_BE_FNAME, O_RDWR, FALSE); + + tx_be_ipc_h = &real_be_ipc_h; + rx_be_ipc_h = &real_be_ipc_h; +#endif + + if ( (vtpm_ipc_init(&rx_tpm_ipc_h, VTPM_RX_TPM_FNAME, O_RDONLY, TRUE) != 0) || + (vtpm_ipc_init(&rx_vtpm_ipc_h, VTPM_RX_VTPM_FNAME, O_RDWR, TRUE) != 0) || //FIXME: O_RDONLY? + (vtpm_ipc_init(&tx_hp_ipc_h, VTPM_TX_HP_FNAME, O_RDWR, TRUE) != 0) || + (vtpm_ipc_init(&rx_hp_ipc_h, VTPM_RX_HP_FNAME, O_RDWR, TRUE) != 0) ) { + vtpmlogerror(VTPM_LOG_VTPM, "Unable to create initial FIFOs.\n"); + exit(-1); + } + + g_rx_tpm_ipc_h = &rx_tpm_ipc_h; + + // -------------------- Set up thread params ------------- + + be_thread_params.tx_ipc_h = tx_be_ipc_h; + be_thread_params.rx_ipc_h = rx_be_ipc_h; + be_thread_params.fw_tpm = TRUE; + be_thread_params.fw_tx_ipc_h = NULL; + be_thread_params.fw_rx_ipc_h = &rx_tpm_ipc_h; + be_thread_params.is_priv = TRUE; //FIXME: Change when HP is up + be_thread_params.thread_name = "Backend Listener"; + + dmi_thread_params.tx_ipc_h = NULL; + dmi_thread_params.rx_ipc_h = &rx_vtpm_ipc_h; + dmi_thread_params.fw_tpm = FALSE; + dmi_thread_params.fw_tx_ipc_h = NULL; + dmi_thread_params.fw_rx_ipc_h = NULL; + dmi_thread_params.is_priv = FALSE; + dmi_thread_params.thread_name = "VTPM Listeners"; + + hp_thread_params.tx_ipc_h = &tx_hp_ipc_h; + hp_thread_params.rx_ipc_h = &rx_hp_ipc_h; + hp_thread_params.fw_tpm = FALSE; + hp_thread_params.fw_tx_ipc_h = NULL; + hp_thread_params.fw_rx_ipc_h = NULL; + hp_thread_params.is_priv = TRUE; + hp_thread_params.thread_name = "Hotplug Listener"; + + // --------------------- Launch Threads ----------------- + + vtpm_lock_init(); + vtpm_globals->master_pid = pthread_self(); - betype_be = BE_LISTENER_THREAD; - if (pthread_create(&be_thread, NULL, VTPM_Service_Handler, &betype_be) != 0) { + if (pthread_create(&be_thread, NULL, vtpm_manager_thread, &be_thread_params) != 0) { vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch BE Thread.\n"); exit(-1); } - dmitype_dmi = DMI_LISTENER_THREAD; - if (pthread_create(&dmi_thread, NULL, VTPM_Service_Handler, &dmitype_dmi) != 0) { + if (pthread_create(&dmi_thread, NULL, vtpm_manager_thread, &dmi_thread_params) != 0) { vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch DMI Thread.\n"); exit(-1); } - + + +// if (pthread_create(&hp_thread, NULL, vtpm_manager_thread, &hp_thread_params) != 0) { +// vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch HP Thread.\n"); +// exit(-1); +// } + //Join the other threads until exit time. pthread_join(be_thread, NULL); pthread_join(dmi_thread, NULL); -#endif + pthread_join(hp_thread, NULL); vtpmlogerror(VTPM_LOG_VTPM, "VTPM Manager shut down unexpectedly.\n"); - VTPM_Stop_Service(); + VTPM_Stop_Manager(); + vtpm_lock_destroy(); return 0; } diff -r 43d141d56c78 -r 72ef14e79cc0 tools/vtpm_manager/manager/vtpmpriv.h --- a/tools/vtpm_manager/manager/vtpmpriv.h Wed May 17 23:19:18 2006 +0100 +++ b/tools/vtpm_manager/manager/vtpmpriv.h Wed May 17 23:23:26 2006 +0100 @@ -44,42 +44,24 @@ #include "tcs.h" #include "buffer.h" #include "crypto.h" +#include "vtpm_ipc.h" #define STATE_FILE "/var/vtpm/VTPM" #define DMI_NVM_FILE "/var/vtpm/vtpm_dm_%d.data" -#define VTPM_BE_DEV "/dev/vtpm" #define VTPM_CTL_DM 0 - -#ifndef VTPM_MUTLI_VM - #include <sys/types.h> - #define GUEST_TX_FIFO "/var/vtpm/fifos/guest-to-%d.fifo" - #define GUEST_RX_FIFO "/var/vtpm/fifos/guest-from-all.fifo" - - #define VTPM_TX_FIFO "/var/vtpm/fifos/vtpm-to-%d.fifo" - #define VTPM_RX_FIFO "/var/vtpm/fifos/vtpm-from-all.fifo" - - #define BE_LISTENER_THREAD 1 - #define DMI_LISTENER_THREAD 2 - - // Seconds until DMI timeout. Timeouts result in DMI being out - // of sync, which may require a reboot of DMI and guest to recover - // from. Don't set this to low. Also note that DMI may issue a TPM - // call so we should expect time to process at DMI + TPM processing. - #define DMI_TIMEOUT 90 -#endif - // ------------------------ Private Structures ----------------------- typedef struct VTPM_DMI_RESOURCE_T { - // I/O info for Manager to talk to DMI's over FIFOs -#ifndef VTPM_MUTLI_VM - int guest_tx_fh; // open GUEST_TX_FIFO - int vtpm_tx_fh; // open VTPM_TX_FIFO - char *guest_tx_fname; // open GUEST_TX_FIFO - char *vtpm_tx_fname; // open VTPM_TX_FIFO - + // I/O info for Manager to talk to DMI's and controllers + vtpm_ipc_handle_t *tx_vtpm_ipc_h; // TX VTPM Results to DMI + vtpm_ipc_handle_t *rx_vtpm_ipc_h; // RX VTPM Commands from DMI + vtpm_ipc_handle_t *tx_tpm_ipc_h; // TX TPM Commands to DMI + vtpm_ipc_handle_t *rx_tpm_ipc_h; // RX TPM Results from DMI + +#ifndef VTPM_MULTI_VM pid_t dmi_pid; #endif + // Non-persistent Information bool connected; UINT32 dmi_domain_id; @@ -94,26 +76,19 @@ typedef struct VTPM_DMI_RESOURCE_T { typedef struct tdVTPM_GLOBALS { // Non-persistent data - int be_fh; // File handle to ipc used to communicate with backend #ifndef VTPM_MULTI_VM - int vtpm_rx_fh; - int guest_rx_fh; - int connected_dmis; // Used to close guest_rx when no dmis are connected - pid_t master_pid; #endif + + int connected_dmis; // To close guest_rx when no dmis are connected + struct hashtable *dmi_map; // Table of all DMI's known indexed by persistent instance # -#ifndef VTPM_MULTI_VM - pthread_mutex_t dmi_map_mutex; // -#endif + TCS_CONTEXT_HANDLE manager_tcs_handle; // TCS Handle used by manager TPM_HANDLE storageKeyHandle; // Key used by persistent store CRYPTO_INFO storageKey; // For software encryption CRYPTO_INFO bootKey; // For saving table TCS_AUTH keyAuth; // OIAP session for storageKey - BOOL DMI_table_dirty; // Indicates that a command - // has updated the DMI table - // Persistent Data TPM_AUTHDATA owner_usage_auth; // OwnerAuth of real TPM @@ -130,6 +105,18 @@ extern const TPM_AUTHDATA SRK_AUTH; // extern const TPM_AUTHDATA SRK_AUTH; // SRK Well Known Auth Value // ********************** Command Handler Prototypes *********************** + +// ********************** VTPM Functions ************************* +TPM_RESULT VTPM_Init_Manager(); // Start VTPM Service +void VTPM_Stop_Manager(); // Stop VTPM Service +TPM_RESULT VTPM_Manager_Handler(vtpm_ipc_handle_t *tx_ipc_h, + vtpm_ipc_handle_t *rx_ipc_h, + BOOL fw_tpm, // Should forward TPM cmds + vtpm_ipc_handle_t *fw_tx_ipc_h, + vtpm_ipc_handle_t *fw_rx_ipc_h, + BOOL is_priv, + char *client_name); + TPM_RESULT VTPM_Handle_Load_NVM( VTPM_DMI_RESOURCE *myDMI, const buffer_t *inbuf, buffer_t *outbuf); @@ -148,8 +135,12 @@ TPM_RESULT VTPM_Handle_Close_DMI(const b TPM_RESULT VTPM_Handle_Delete_DMI(const buffer_t *param_buf); -TPM_RESULT VTPM_SaveService(void); -TPM_RESULT VTPM_LoadService(void); +TPM_RESULT VTPM_SaveManagerData(void); +TPM_RESULT VTPM_LoadManagerData(void); -TPM_RESULT close_dmi( VTPM_DMI_RESOURCE *dmi_res); +TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res); + +TPM_RESULT VTPM_Close_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res); + +TPM_RESULT close_dmi(VTPM_DMI_RESOURCE *dmi_res); #endif // __VTPMPRIV_H__ diff -r 43d141d56c78 -r 72ef14e79cc0 tools/vtpm_manager/manager/vtpm_ipc.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/vtpm_manager/manager/vtpm_ipc.c Wed May 17 23:23:26 2006 +0100 @@ -0,0 +1,141 @@ +// =================================================================== +// +// Copyright (c) 2005, Intel Corp. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Intel Corporation nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +// OF THE POSSIBILITY OF SUCH DAMAGE. +// =================================================================== +// +// vtpm_ipc.c Implements ipc routines using file io. This file can +// be replaced with other ipc types. +// +// =================================================================== + +#include <sys/stat.h> +#include "vtpm_ipc.h" +#include "vtpmpriv.h" +#include "log.h" + +int vtpm_ipc_init(vtpm_ipc_handle_t *ipc_h, char* name, int flags, BOOL create) { + ipc_h->name = name; + ipc_h->flags = flags; + ipc_h->fh = VTPM_IPC_CLOSED; + + if (create) + return(vtpm_ipc_create(ipc_h)); + else + return 0; +} + +// Create the file that needs opening. Used only for FIFOs +// FYI: This may cause problems in other file IO schemes. We'll see. +int vtpm_ipc_create(vtpm_ipc_handle_t *ipc_h) { + int fh; + struct stat file_info; + + if ((!ipc_h) || (!ipc_h->name)) + return -1; + + if ( stat(ipc_h->name, &file_info) == -1) { + if ( mkfifo(ipc_h->name, S_IWUSR | S_IRUSR ) ) { + vtpmlogerror(VTPM_LOG_VTPM, "Failed to create fifo %s.\n", ipc_h->name); + return -1; + } + } + + ipc_h->fh = VTPM_IPC_CLOSED; + + return 0; +} + + +// Read size bytes. If FH isn't open, open it. +int vtpm_ipc_read(vtpm_ipc_handle_t *ipc_h, vtpm_ipc_handle_t *alt_ipc_h, BYTE *bytes, UINT32 size){ + vtpm_ipc_handle_t *my_ipc_h; + int result; + + if (ipc_h) { + my_ipc_h = ipc_h; + } else { + my_ipc_h = alt_ipc_h; + } + + if (my_ipc_h->fh == VTPM_IPC_CLOSED) { + my_ipc_h->fh = open(my_ipc_h->name, my_ipc_h->flags); + } + + if ( my_ipc_h->fh == VTPM_IPC_CLOSED ) { + vtpmlogerror(VTPM_LOG_VTPM, "VTPM ERROR: Can't open %s for reading.\n", my_ipc_h->name); + return -1; + } + + result = read(my_ipc_h->fh, bytes, size); + if (result < 0) { + my_ipc_h->fh = VTPM_IPC_CLOSED; + } + + return (result); +} + +// Write size bytes. If FH isn't open, open it. +int vtpm_ipc_write(vtpm_ipc_handle_t *ipc_h, vtpm_ipc_handle_t *alt_ipc_h, BYTE *bytes, UINT32 size) { + vtpm_ipc_handle_t *my_ipc_h; + int result; + + if (ipc_h) { + my_ipc_h = ipc_h; + } else { + my_ipc_h = alt_ipc_h; + } + + if (my_ipc_h->fh == VTPM_IPC_CLOSED) { + my_ipc_h->fh = open(my_ipc_h->name, my_ipc_h->flags); + } + + if ( my_ipc_h->fh == VTPM_IPC_CLOSED ) { + vtpmlogerror(VTPM_LOG_VTPM, "VTPM ERROR: Can't open %s for writing.\n", my_ipc_h->name); + return -1; + } + + result = write(my_ipc_h->fh, bytes, size); + if (result < 0) { + my_ipc_h->fh = VTPM_IPC_CLOSED; + } + + return (result); +} + +// Mark file as closed and try and close it. Errors not reported. +void vtpm_ipc_close(vtpm_ipc_handle_t *ipc_h) { + + if (ipc_h) { + close(ipc_h->fh); + } + ipc_h->fh = VTPM_IPC_CLOSED; + +} diff -r 43d141d56c78 -r 72ef14e79cc0 tools/vtpm_manager/manager/vtpm_ipc.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/vtpm_manager/manager/vtpm_ipc.h Wed May 17 23:23:26 2006 +0100 @@ -0,0 +1,71 @@ +// =================================================================== +// +// Copyright (c) 2005, Intel Corp. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Intel Corporation nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +// OF THE POSSIBILITY OF SUCH DAMAGE. +// =================================================================== +// +// vtpm_ipc.h Header for interprocess communication between VTPM manager +// and Guests or VTPMs +// +// =================================================================== + +#ifndef __VTPM_IO_H__ +#define __VTPM_IO_H__ + +#include "tcg.h" + +#define VTPM_IPC_CLOSED -1 + +// Represents an (somewhat) abstracted io handle. +typedef struct vtpm_ipc_handle_t { + int fh; // IO handle. + int flags; // Flags for opening. This may need to become + // a void *, but for now files use an int. + char *name; // Names for debugging as well as filenames + // for file-based io. +} vtpm_ipc_handle_t; + + +int vtpm_ipc_init(vtpm_ipc_handle_t *ioh, char* name, int flags, BOOL create); + +// Create the file that needs opening. Used only for FIFOs +// FYI: This may cause problems in other file IO schemes. We'll see. +int vtpm_ipc_create(vtpm_ipc_handle_t *ioh); + +// Read size bytes. If FH isn't open, open it. +int vtpm_ipc_read(vtpm_ipc_handle_t *ioh, vtpm_ipc_handle_t *alt_ioh, BYTE *bytes, UINT32 size); + +// Write size bytes. If FH isn't open, open it. +int vtpm_ipc_write(vtpm_ipc_handle_t *ioh, vtpm_ipc_handle_t *alt_ioh, BYTE *bytes, UINT32 size); + +// Mark file as closed and try and close it. Errors not reported. +void vtpm_ipc_close(vtpm_ipc_handle_t *ioh); + +#endif diff -r 43d141d56c78 -r 72ef14e79cc0 tools/vtpm_manager/manager/vtpm_lock.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/vtpm_manager/manager/vtpm_lock.c Wed May 17 23:23:26 2006 +0100 @@ -0,0 +1,63 @@ +// =================================================================== +// +// Copyright (c) 2005, Intel Corp. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Intel Corporation nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +// OF THE POSSIBILITY OF SUCH DAMAGE. +// =================================================================== +// +// vtpm_lock.c Provided controlled sync around access to vtpm structures +// +// =================================================================== + +#include <pthread.h> +#include "vtpm_lock.h" + +static pthread_rwlock_t vtpm_lock; + +void vtpm_lock_init() { + + pthread_rwlock_init( &vtpm_lock, NULL); +} + +void vtpm_lock_destroy(){ + pthread_rwlock_destroy(&vtpm_lock); +} + +void vtpm_lock_rdlock(){ + pthread_rwlock_rdlock(&vtpm_lock); +} + +void vtpm_lock_wrlock(){ + pthread_rwlock_wrlock(&vtpm_lock); +} + +void vtpm_lock_unlock(){ + pthread_rwlock_unlock(&vtpm_lock); +} + diff -r 43d141d56c78 -r 72ef14e79cc0 tools/vtpm_manager/manager/vtpm_lock.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/vtpm_manager/manager/vtpm_lock.h Wed May 17 23:23:26 2006 +0100 @@ -0,0 +1,48 @@ +// =================================================================== +// +// Copyright (c) 2005, Intel Corp. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Intel Corporation nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +// OF THE POSSIBILITY OF SUCH DAMAGE. +// =================================================================== +// +// vtpm_lock.h Provided controlled sync around access to vtpm structures +// +// =================================================================== + +#ifndef __VTPM_LOCK_H__ +#define __VTPM_LOCK_H__ + +void vtpm_lock_init(); +void vtpm_lock_destroy(); + +void vtpm_lock_rdlock(); +void vtpm_lock_wrlock(); +void vtpm_lock_unlock(); + +#endif diff -r 43d141d56c78 -r 72ef14e79cc0 tools/vtpm_manager/manager/vtpm_manager_handler.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/vtpm_manager/manager/vtpm_manager_handler.c Wed May 17 23:23:26 2006 +0100 @@ -0,0 +1,455 @@ +// =================================================================== +// +// Copyright (c) 2005, Intel Corp. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Intel Corporation nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +// OF THE POSSIBILITY OF SUCH DAMAGE. +// =================================================================== +// +// vtpm_manager_handler.c +// +// This file will house the main logic of the VTPM Manager +// +// ================================================================== + +#include <stdio.h> +#include <unistd.h> +#include <string.h> + +#include "vtpm_manager.h" +#include "vtpmpriv.h" +#include "vtsp.h" +#include "bsg.h" +#include "hashtable.h" +#include "hashtable_itr.h" +#include "log.h" +#include "buffer.h" + +#define vtpmhandlerloginfo(module,fmt,args...) vtpmloginfo (module, "[%s]: " fmt, thread_name, ##args ); +#define vtpmhandlerloginfomore(module,fmt,args...) vtpmloginfomore (module, fmt, ##args ); +#define vtpmhandlerlogerror(module,fmt,args...) vtpmlogerror (module, "[%s]: " fmt, thread_name, ##args ); + +// ---------------------- Prototypes ------------------- +TPM_RESULT vtpm_manager_handle_vtpm_cmd(VTPM_DMI_RESOURCE *dmi_res, + TPM_COMMAND_CODE ord, + buffer_t *command_buf, + buffer_t *result_buf, + BOOL is_priv, + char *thread_name); + +TPM_RESULT vtpm_manager_handle_tpm_cmd(vtpm_ipc_handle_t *tx_ipc_h, + vtpm_ipc_handle_t *rx_ipc_h, + VTPM_DMI_RESOURCE *dmi_res, + BYTE *cmd_header, + buffer_t *param_buf, + buffer_t *result_buf, + char *thread_name); + +TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t *tx_ipc_h, + vtpm_ipc_handle_t *rx_ipc_h, + BOOL fw_tpm, // Forward TPM cmds? + vtpm_ipc_handle_t *fw_tx_ipc_h, + vtpm_ipc_handle_t *fw_rx_ipc_h, + BOOL is_priv, + char *thread_name) { + TPM_RESULT status = TPM_FAIL; // Should never return + UINT32 dmi, in_param_size, cmd_size, out_param_size, out_message_size, out_message_size_full; + BYTE *cmd_header, *in_param, *out_message; + buffer_t *command_buf=NULL, *result_buf=NULL; + TPM_TAG tag; + TPM_COMMAND_CODE ord; + VTPM_DMI_RESOURCE *dmi_res; + int size_read, size_write, i; + + cmd_header = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV); + command_buf = (buffer_t *) malloc(sizeof(buffer_t)); + result_buf = (buffer_t *) malloc(sizeof(buffer_t)); + + // ------------------------ Main Loop -------------------------------- + while(1) { + + vtpmhandlerloginfo(VTPM_LOG_VTPM, "%s waiting for messages.\n", thread_name); + + // --------------------- Read Cmd from Sender ---------------- + + // Read command header + size_read = vtpm_ipc_read(rx_ipc_h, NULL, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV); + if (size_read > 0) { + vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV[%d}: 0x", size_read); + for (i=0; i<size_read; i++) + vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]); + } else { + vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s can't read from ipc. Aborting... \n", thread_name); + goto abort_command; + } + + if (size_read < (int) VTPM_COMMAND_HEADER_SIZE_SRV) { + vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "\n"); + vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command shorter than normal header (%d bytes). Aborting...\n", size_read); + goto abort_command; + } + + // Unpack header + BSG_UnpackList(cmd_header, 4, + BSG_TYPE_UINT32, &dmi, + BSG_TPM_TAG, &tag, + BSG_TYPE_UINT32, &in_param_size, + BSG_TPM_COMMAND_CODE, &ord ); + + // Using the header info, read the parameters of the command + // Note that in_param_size is in the client's context + cmd_size = in_param_size - VTPM_COMMAND_HEADER_SIZE_CLT; + if (cmd_size > 0) { + in_param = (BYTE *) malloc(cmd_size); + size_read = vtpm_ipc_read( rx_ipc_h, NULL, in_param, cmd_size); + if (size_read > 0) { + for (i=0; i<size_read; i++) + vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]); + + } else { + vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s had error reading cmd from ipc. Aborting... \n", thread_name); + goto abort_command; + } + vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); + + if (size_read < (int) cmd_size) { + vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); + vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command read(%d) is shorter than header indicates(%d). Aborting...\n", size_read, cmd_size); + goto abort_command; + } + } else { + in_param = NULL; + vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); + } + + // Init the buffers used to handle the command and the response + if ( (buffer_init_convert(command_buf, cmd_size, in_param) != TPM_SUCCESS) || + (buffer_init(result_buf, 0, 0) != TPM_SUCCESS) ) { + vtpmhandlerlogerror(VTPM_LOG_VTPM, "Failed to setup buffers. Aborting...\n"); + goto abort_command; + } + + // -------------- Dispatch Commands to Handlers ----------- + if ((tag == VTPM_TAG_REQ) && (ord & VTPM_PRIV_MASK)) { + vtpm_lock_wrlock(); + } else { + vtpm_lock_rdlock(); + } + + if ( !(dmi_res = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi)) || + (!dmi_res->connected) ) { + vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempted access to non-existent or disconnected DMI %d. Aborting...\n", dmi); + status = TPM_BAD_PARAMETER; + } + + if (tag == VTPM_TAG_REQ) { + + status = vtpm_manager_handle_vtpm_cmd(dmi_res, ord, command_buf, result_buf, is_priv, thread_name); + + } else { // This is not a VTPM Command at all. + if (fw_tpm) { + status = vtpm_manager_handle_tpm_cmd(fw_tx_ipc_h, fw_rx_ipc_h, dmi_res, cmd_header, command_buf, result_buf, thread_name); + + // This means calling the DMI failed, not that the cmd failed in the DMI + if (status != TPM_SUCCESS) { + goto abort_with_error; + } + } else { + // We are not supposed to forward TPM commands at all. + int i; + vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempt to use unsupported direct access to TPM.\n"); + vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "Bad Command. dmi:%d, tag:%d, size:%d, ord:%d, Params: ", dmi, tag, in_param_size, ord); + for (i=0; i<cmd_size; i++) + vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]); + + vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); + + status = TPM_FAIL; + goto abort_with_error; + } + + } // end else for is VTPM Command + + // ------------------- Respond to Sender ------------------ + + // Errors while handling responses jump here to reply with error messages + // NOTE: Currently there are no recoverable errors in multi-VM mode. If one + // is added to the code, this ifdef should be removed. + // Also note this is NOT referring to errors in commands, but rather + // this is about I/O errors and such. +#ifndef VTPM_MULTI_VM + abort_with_error: +#endif + + // Prepend VTPM header with destination DM stamped + out_param_size = buffer_len(result_buf); + out_message_size = VTPM_COMMAND_HEADER_SIZE_CLT + out_param_size; + out_message_size_full = VTPM_COMMAND_HEADER_SIZE_SRV + out_param_size; + out_message = (BYTE *) malloc (out_message_size_full); + + BSG_PackList(out_message, 4, + BSG_TYPE_UINT32, (BYTE *) &dmi, + BSG_TPM_TAG, (BYTE *) &tag, + BSG_TYPE_UINT32, (BYTE *) &out_message_size, + BSG_TPM_RESULT, (BYTE *) &status); + + if (buffer_len(result_buf) > 0) + memcpy(out_message + VTPM_COMMAND_HEADER_SIZE_SRV, result_buf->bytes, out_param_size); + + //Note: Send message + dmi_id + size_write = vtpm_ipc_write(tx_ipc_h, dmi_res->tx_vtpm_ipc_h, out_message, out_message_size_full ); + if (size_write > 0) { + vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT: 0x"); + for (i=0; i < out_message_size_full; i++) + vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", out_message[i]); + + vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); + } else { + vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s had error writing to ipc. Aborting... \n", thread_name); + goto abort_command; + } + free(out_message); + + if (size_write < (int)out_message_size_full) { + vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s unable to write full command to ipc (%d/%d)\n", thread_name, size_write, out_message_size_full); + goto abort_command; + } + + // On certain failures an error message cannot be sent. + // This marks the beginning of cleanup in preperation for the next command. + abort_command: + //free buffers + bzero(cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV); + //free(in_param); // This was converted to command_buf. No need to free + if (command_buf != result_buf) + buffer_free(result_buf); + + buffer_free(command_buf); + + // If we have a write lock, save the manager table + if ((tag == VTPM_TAG_REQ) && (ord & VTPM_PRIV_MASK) && + (VTPM_SaveManagerData() != TPM_SUCCESS) ) { + vtpmhandlerlogerror(VTPM_LOG_VTPM, "ERROR: Unable to save manager data.\n"); + } + + vtpm_lock_unlock(); + } // End while(1) + +} + +///////////////////////////////////////////////////////////////////////// +TPM_RESULT vtpm_manager_handle_vtpm_cmd(VTPM_DMI_RESOURCE *dmi_res, + TPM_COMMAND_CODE ord, + buffer_t *command_buf, + buffer_t *result_buf, + BOOL is_priv, + char *thread_name) { + + TPM_RESULT status = TPM_FAIL; + + switch (ord) { + case VTPM_ORD_SAVENVM: + status= VTPM_Handle_Save_NVM(dmi_res, + command_buf, + result_buf); + break; + + case VTPM_ORD_LOADNVM: + status= VTPM_Handle_Load_NVM(dmi_res, + command_buf, + result_buf); + break; + + case VTPM_ORD_TPMCOMMAND: + status= VTPM_Handle_TPM_Command(dmi_res, + command_buf, + result_buf); + break; + + default: + // Privileged handlers can do maintanance + if (is_priv) { + switch (ord) { + case VTPM_ORD_OPEN: + status = VTPM_Handle_New_DMI(command_buf); + break; + + case VTPM_ORD_CLOSE: + status = VTPM_Handle_Close_DMI(command_buf); + break; + + case VTPM_ORD_DELETE: + status = VTPM_Handle_Delete_DMI(command_buf); + break; + + default: + status = TPM_BAD_ORDINAL; + } // switch + } else { // is priv command + + status = TPM_BAD_ORDINAL; + } // inner switch + } // outer switch + + return(status); +} + +///////////////////////////////////////////////////////////////////// +TPM_RESULT vtpm_manager_handle_tpm_cmd(vtpm_ipc_handle_t *tx_ipc_h, + vtpm_ipc_handle_t *rx_ipc_h, + VTPM_DMI_RESOURCE *dmi_res, + BYTE *cmd_header, + buffer_t *param_buf, + buffer_t *result_buf, + char *thread_name) { + + TPM_RESULT status = TPM_FAIL; + UINT32 dmi_dst; + TPM_COMMAND_CODE ord; + TPM_TAG tag_out; + UINT32 dmi_cmd_size, in_param_size, adj_param_size; + BYTE *dmi_cmd, *in_param; + int size_read, size_write, i; + + //// Dom0 can't talk to the BE, so this must be a broken FE/BE or badness + if (dmi_res->dmi_id == VTPM_CTL_DM) { + vtpmhandlerlogerror(VTPM_LOG_VTPM, "Illegal use of TPM command from dom0\n"); + status = TPM_FAIL; + goto abort_with_error; + } + + vtpmhandlerloginfo(VTPM_LOG_VTPM, "Forwarding command to DMI.\n"); + + //Forward TPM CMD stamped with dmi_id to DMI for handling + if (buffer_len(param_buf)) { + dmi_cmd = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV + buffer_len(param_buf)); + dmi_cmd_size = VTPM_COMMAND_HEADER_SIZE_SRV + buffer_len(param_buf); + memcpy(dmi_cmd, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV); + memcpy(dmi_cmd + VTPM_COMMAND_HEADER_SIZE_SRV, param_buf->bytes, buffer_len(param_buf)); + size_write = vtpm_ipc_write(tx_ipc_h, dmi_res->tx_tpm_ipc_h, dmi_cmd, dmi_cmd_size); + + if (size_write > 0) { + vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT (DMI): 0x"); + for (i=0; i<VTPM_COMMAND_HEADER_SIZE_SRV + buffer_len(param_buf); i++) { + vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", dmi_cmd[i]); + } + vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); + } else { + vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error writing to DMI. Aborting... \n"); + status = TPM_IOERROR; + goto abort_with_error; + } + free(dmi_cmd); + } else { + dmi_cmd_size = VTPM_COMMAND_HEADER_SIZE_SRV; + size_write = vtpm_ipc_write(tx_ipc_h, dmi_res->tx_tpm_ipc_h, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV ); + if (size_write > 0) { + for (i=0; i<VTPM_COMMAND_HEADER_SIZE_SRV; i++) + vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]); + + vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); + } else { + vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error writing to DMI. Aborting... \n"); + status = TPM_IOERROR; + goto abort_with_error; + } + } + + if (size_write != (int) dmi_cmd_size) + vtpmhandlerlogerror(VTPM_LOG_VTPM, "Could not write entire command to DMI (%d/%d)\n", size_write, dmi_cmd_size); + + buffer_free(param_buf); + + // Read header for response to TPM command from DMI + size_read = vtpm_ipc_read( rx_ipc_h, dmi_res->rx_tpm_ipc_h, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV); + if (size_read > 0) { + vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV (DMI): 0x"); + for (i=0; i<size_read; i++) + vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]); + + } else { + vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error reading from DMI. Aborting... \n"); + status = TPM_IOERROR; + goto abort_with_error; + } + + if (size_read < (int) VTPM_COMMAND_HEADER_SIZE_SRV) { + vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command from DMI shorter than normal header. Aborting...\n"); + status = TPM_IOERROR; + goto abort_with_error; + } + + // Unpack response from DMI for TPM command + BSG_UnpackList(cmd_header, 4, + BSG_TYPE_UINT32, &dmi_dst, + BSG_TPM_TAG, &tag_out, + BSG_TYPE_UINT32, &in_param_size, + BSG_TPM_COMMAND_CODE, &status ); + + // If response has parameters, read them. + // Note that in_param_size is in the client's context + adj_param_size = in_param_size - VTPM_COMMAND_HEADER_SIZE_CLT; + if (adj_param_size > 0) { + in_param = (BYTE *) malloc(adj_param_size); + size_read = vtpm_ipc_read(rx_ipc_h, dmi_res->rx_tpm_ipc_h, in_param, adj_param_size); + if (size_read > 0) { + for (i=0; i<size_read; i++) + vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]); + + } else { + vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error reading from BE. Aborting... \n"); + goto abort_with_error; + } + vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n"); + + if (size_read < (int)adj_param_size) { + vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n"); + vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command read(%d) from DMI is shorter than header indicates(%d). Aborting...\n", size_read, adj_param_size); + status = TPM_IOERROR; + goto abort_with_error; + } + } else { + in_param = NULL; + vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n"); + } + + if (buffer_init_convert(result_buf, adj_param_size, in_param) != TPM_SUCCESS) { + vtpmhandlerlogerror(VTPM_LOG_VTPM, "Failed to setup buffers. Aborting...\n"); + status = TPM_FAIL; + goto abort_with_error; + } + + vtpmhandlerloginfo(VTPM_LOG_VTPM, "Sending DMI's response to guest.\n"); + + status = TPM_SUCCESS; + + abort_with_error: + + return status; +} + _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |