aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/vtpm/Makefile21
-rw-r--r--tools/vtpm/tpm_emulator.patch2
-rw-r--r--tools/vtpm/vtpm.patch197
-rw-r--r--tools/vtpm_manager/Rules.mk8
-rw-r--r--tools/vtpm_manager/manager/dmictl.c138
-rw-r--r--tools/vtpm_manager/manager/securestorage.c21
-rw-r--r--tools/vtpm_manager/manager/vtpm_ipc.c141
-rw-r--r--tools/vtpm_manager/manager/vtpm_ipc.h71
-rw-r--r--tools/vtpm_manager/manager/vtpm_lock.c63
-rw-r--r--tools/vtpm_manager/manager/vtpm_lock.h48
-rw-r--r--tools/vtpm_manager/manager/vtpm_manager.c600
-rw-r--r--tools/vtpm_manager/manager/vtpm_manager.h36
-rw-r--r--tools/vtpm_manager/manager/vtpm_manager_handler.c455
-rw-r--r--tools/vtpm_manager/manager/vtpmd.c297
-rw-r--r--tools/vtpm_manager/manager/vtpmpriv.h73
15 files changed, 1178 insertions, 993 deletions
diff --git a/tools/vtpm/Makefile b/tools/vtpm/Makefile
index 377f1b0436..f7f22497ad 100644
--- a/tools/vtpm/Makefile
+++ b/tools/vtpm/Makefile
@@ -21,7 +21,9 @@ build: $(TPM_EMULATOR_DIR) $(VTPM_DIR) build_sub
.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 @@ $(TPM_EMULATOR_TARFILE):
# 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 --git a/tools/vtpm/tpm_emulator.patch b/tools/vtpm/tpm_emulator.patch
index 7be6ffdb80..a6a421a914 100644
--- a/tools/vtpm/tpm_emulator.patch
+++ b/tools/vtpm/tpm_emulator.patch
@@ -52,7 +52,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/Makefile tpm_emulator/Makefile
-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 --git a/tools/vtpm/vtpm.patch b/tools/vtpm/vtpm.patch
index 1964f3e46b..0f558b3b81 100644
--- a/tools/vtpm/vtpm.patch
+++ b/tools/vtpm/vtpm.patch
@@ -1,12 +1,12 @@
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@gmx.net>
+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/ChangeLog vtpm/ChangeLog
* 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@gmx.net>,
@@ -59,10 +59,9 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/crypto/gmp_kernel_wrapper.c vtpm/crypto/
{
- 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/crypto/gmp_kernel_wrapper.c vtpm/crypto/
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@gmx.net>,
@@ -107,7 +106,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/crypto/rsa.c vtpm/crypto/rsa.c
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/linux_module.c vtpm/linux_module.c
-}
-
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@gmx.net>,
@@ -376,8 +375,8 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/linux_module.h vtpm/linux_module.h
#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@gmx.net>
@@ -410,7 +409,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/Makefile vtpm/Makefile
+
+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/Makefile vtpm/Makefile
$(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/README vtpm/README
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@gmx.net>,
@@ -549,7 +548,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_audit.c vtpm/tpm/tpm_audit.c
-
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@gmx.net>,
@@ -575,7 +574,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_authorization.c vtpm/tpm/tpm_aut
-
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@gmx.net>,
@@ -600,7 +599,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_capability.c vtpm/tpm/tpm_capabi
-
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@gmx.net>,
@@ -664,8 +663,8 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_cmd_handler.c vtpm/tpm/tpm_cmd_h
}
-
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@gmx.net>,
@@ -689,8 +688,8 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_crypto.c vtpm/tpm/tpm_crypto.c
}
-
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@gmx.net>,
@@ -760,8 +759,8 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c vtpm/tpm/tpm_data.c
+#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/tpm/tpm_data.c vtpm/tpm/tpm_data.c
-
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@gmx.net>,
@@ -1050,7 +1049,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_deprecated.c vtpm/tpm/tpm_deprec
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@gmx.net>,
@@ -1070,7 +1069,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_emulator.h vtpm/tpm/tpm_emulator
* 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@gmx.net>,
@@ -1086,7 +1085,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_integrity.c vtpm/tpm/tpm_integri
-
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@gmx.net>,
@@ -1106,7 +1105,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_structures.h vtpm/tpm/tpm_struct
/*
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@gmx.net>,
@@ -1224,7 +1223,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_testing.c vtpm/tpm/tpm_testing.c
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@gmx.net>,
@@ -1307,139 +1306,9 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_ticks.c vtpm/tpm/tpm_ticks.c
}
-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/tpmd.c vtpm/tpmd.c
+#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 --git a/tools/vtpm_manager/Rules.mk b/tools/vtpm_manager/Rules.mk
index 9644eba6bc..0a56da49f8 100644
--- a/tools/vtpm_manager/Rules.mk
+++ b/tools/vtpm_manager/Rules.mk
@@ -40,6 +40,9 @@ $(OBJS): $(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(VTPM_LOG_TCS)|BITMASK(VTPM_LOG_VTSP)|BITMA
# 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(VTPM_LOG_TCS)|BITMASK(VTPM_LOG_VTSP)|BITMA
# 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 --git a/tools/vtpm_manager/manager/dmictl.c b/tools/vtpm_manager/manager/dmictl.c
index ffbd5cd7f2..4edd14408b 100644
--- a/tools/vtpm_manager/manager/dmictl.c
+++ b/tools/vtpm_manager/manager/dmictl.c
@@ -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;
+ return (VTPM_Close_DMI_Extra(dmi_res) );
}
-TPM_RESULT VTPM_Handle_New_DMI( const buffer_t *param_buf) {
+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 buffer_t *param_buf) {
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 buffer_t *param_buf) {
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 buffer_t *param_buf) {
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 --git a/tools/vtpm_manager/manager/securestorage.c b/tools/vtpm_manager/manager/securestorage.c
index 1c4bd4931e..b49d1298f5 100644
--- a/tools/vtpm_manager/manager/securestorage.c
+++ b/tools/vtpm_manager/manager/securestorage.c
@@ -197,9 +197,6 @@ TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI_RESOURCE *myDMI,
&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_RESOURCE *myDMI,
}
-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) {
+ if (hashtable_count(vtpm_globals->dmi_map) > 1) {
- 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 );
+ 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);
+ vtpmloginfo(VTPM_LOG_VTPM, "Saved VTPM Manager state (status = %d, dmis = %d)\n", (int) status, dmis);
return status;
}
-TPM_RESULT VTPM_LoadService(void) {
+TPM_RESULT VTPM_LoadManagerData(void) {
TPM_RESULT status=TPM_SUCCESS;
int fh, stat_ret, dmis=0;
diff --git a/tools/vtpm_manager/manager/vtpm_ipc.c b/tools/vtpm_manager/manager/vtpm_ipc.c
new file mode 100644
index 0000000000..0b8176c00b
--- /dev/null
+++ b/tools/vtpm_manager/manager/vtpm_ipc.c
@@ -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 --git a/tools/vtpm_manager/manager/vtpm_ipc.h b/tools/vtpm_manager/manager/vtpm_ipc.h
new file mode 100644
index 0000000000..529c4a29ea
--- /dev/null
+++ b/tools/vtpm_manager/manager/vtpm_ipc.h
@@ -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 --git a/tools/vtpm_manager/manager/vtpm_lock.c b/tools/vtpm_manager/manager/vtpm_lock.c
new file mode 100644
index 0000000000..e737d60d9c
--- /dev/null
+++ b/tools/vtpm_manager/manager/vtpm_lock.c
@@ -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 --git a/tools/vtpm_manager/manager/vtpm_lock.h b/tools/vtpm_manager/manager/vtpm_lock.h
new file mode 100644
index 0000000000..53a339d123
--- /dev/null
+++ b/tools/vtpm_manager/manager/vtpm_lock.h
@@ -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 --git a/tools/vtpm_manager/manager/vtpm_manager.c b/tools/vtpm_manager/manager/vtpm_manager.c
index e9061aabed..b3c98115db 100644
--- a/tools/vtpm_manager/manager/vtpm_manager.c
+++ b/tools/vtpm_manager/manager/vtpm_manager.c
@@ -39,18 +39,8 @@
#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"
#include "vtsp.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,20 +188,14 @@ 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 --git a/tools/vtpm_manager/manager/vtpm_manager.h b/tools/vtpm_manager/manager/vtpm_manager.h
index 70ceb61713..b38c1e13af 100644
--- a/tools/vtpm_manager/manager/vtpm_manager.h
+++ b/tools/vtpm_manager/manager/vtpm_manager.h
@@ -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 --git a/tools/vtpm_manager/manager/vtpm_manager_handler.c b/tools/vtpm_manager/manager/vtpm_manager_handler.c
new file mode 100644
index 0000000000..2512a859d4
--- /dev/null
+++ b/tools/vtpm_manager/manager/vtpm_manager_handler.c
@@ -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;
+}
+
diff --git a/tools/vtpm_manager/manager/vtpmd.c b/tools/vtpm_manager/manager/vtpmd.c
index a9fb9fedff..c74f17c728 100644
--- a/tools/vtpm_manager/manager/vtpmd.c
+++ b/tools/vtpm_manager/manager/vtpmd.c
@@ -38,21 +38,67 @@
// ===================================================================
#include <stdio.h>
-#include <signal.h>
-#include <sys/types.h>
#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <string.h>
+#include <pthread.h>
#include "vtpm_manager.h"
#include "vtpmpriv.h"
#include "tcg.h"
#include "log.h"
+#include "vtpm_ipc.h"
-#ifndef VTPM_MULTI_VM
- #include <pthread.h>
-#endif
-void signal_handler(int reason) {
-#ifndef VTPM_MULTI_VM
+#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) {
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);
}
-#endif
- VTPM_Stop_Service();
+
+ 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
+
+ } //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));
+ vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGHUP handler. Ctl+break will not stop manager gently.\n");
- return -1;
-#else
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 --git a/tools/vtpm_manager/manager/vtpmpriv.h b/tools/vtpm_manager/manager/vtpmpriv.h
index c579d50518..84ace076dd 100644
--- a/tools/vtpm_manager/manager/vtpmpriv.h
+++ b/tools/vtpm_manager/manager/vtpmpriv.h
@@ -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 VTPM_GLOBALS *vtpm_globals; // Key info and DMI states
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 buffer_t *param_buf);
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 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);
+TPM_RESULT close_dmi(VTPM_DMI_RESOURCE *dmi_res);
#endif // __VTPMPRIV_H__