# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID c0796e18b6a45f0352770e700e3f6cae028bd2e3
# Parent 3ef86b208f9bc3eac63de8c0dfe5f16c0ec47839
Add 64 bit support to the VTPM Tools plus do some minor cleanups.
The VTPM manager and VTPMs fully support both 32 and 64 bit OSes. The
tpm_emulator (provided for debugging on TPM-less machines) does not
support 64-bit kernels by default though. See the README for details on
how to use it on 64-bit kernels.
(Vinnie Scarlata, Intel Corporation)
Signed-off-by: Joe Cihula <joe.cihula@xxxxxxxxx>
diff -r 3ef86b208f9b -r c0796e18b6a4 tools/vtpm/Makefile
--- a/tools/vtpm/Makefile Tue Sep 20 09:05:03 2005
+++ b/tools/vtpm/Makefile Tue Sep 20 09:08:26 2005
@@ -4,7 +4,7 @@
include $(XEN_ROOT)/tools/vtpm/Rules.mk
# Dir name for emulator (as dom0 tpm driver)
-TPM_EMULATOR_DIR = tpm_emulator-0.2
+TPM_EMULATOR_DIR = tpm_emulator
# Dir name for vtpm instance
VTPM_DIR = vtpm
@@ -13,7 +13,7 @@
all: build
-build: $(TPM_EMULATOR_TARFILE) extract patch build_sub
+build: $(TPM_EMULATOR_DIR) $(VTPM_DIR) build_sub
install: build
$(MAKE) -C $(TPM_EMULATOR_DIR) $@
@@ -26,36 +26,32 @@
if [ -d $(VTPM_DIR) ]; \
then $(MAKE) -C $(VTPM_DIR) clean; \
fi
+
+mrproper:
+ rm -f $(TPM_EMULATOR_TARFILE)
rm -rf $(TPM_EMULATOR_DIR)
rm -rf $(VTPM_DIR)
-
-mrproper: clean
- rm -f $(TPM_EMULATOR_TARFILE)
# Download Swiss emulator
$(TPM_EMULATOR_TARFILE):
wget http://download.berlios.de/tpm-emulator/$(TPM_EMULATOR_TARFILE)
# Create vtpm and TPM emulator dirs
-extract: $(TPM_EMULATOR_DIR)/README $(VTPM_DIR)/README
-
-$(TPM_EMULATOR_DIR)/README:
- -rm -rf $(TPM_EMULATOR_DIR)
- tar -xzf $(TPM_EMULATOR_TARFILE)
-
-$(VTPM_DIR)/README:
- -rm -rf $(VTPM_DIR)
- cp -r --preserve $(TPM_EMULATOR_DIR) $(VTPM_DIR)
-
# apply patches for 1) used as dom0 tpm driver 2) used as vtpm device instance
-patch: $(TPM_EMULATOR_DIR)/Makefile $(VTPM_DIR)/Makefile
-
-$(TPM_EMULATOR_DIR)/Makefile: tpm_emulator.patch
+$(TPM_EMULATOR_DIR): $(TPM_EMULATOR_TARFILE)
+ tar -xzf $(TPM_EMULATOR_TARFILE);
+ 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
-$(VTPM_DIR)/Makefile: vtpm.patch
+$(VTPM_DIR): $(TPM_EMULATOR_TARFILE)
+ tar -xzf $(TPM_EMULATOR_TARFILE);
+ mv tpm_emulator-0.2 $(VTPM_DIR);
+
-cd $(VTPM_DIR); \
+ patch -p1 < ../tpm_emulator-0.2b-x86_64.patch; \
patch -p1 <../vtpm.patch
build_sub:
diff -r 3ef86b208f9b -r c0796e18b6a4 tools/vtpm/README
--- a/tools/vtpm/README Tue Sep 20 09:05:03 2005
+++ b/tools/vtpm/README Tue Sep 20 09:08:26 2005
@@ -23,6 +23,7 @@
- xen-unstable
- IBM frontend/backend vtpm driver patch
- vtpm_managerd
+- GNU MP Big number library (GMP)
vtpmd Flow (for vtpm_manager. vtpmd never run by default)
============================
diff -r 3ef86b208f9b -r c0796e18b6a4 tools/vtpm/tpm_emulator.patch
--- a/tools/vtpm/tpm_emulator.patch Tue Sep 20 09:05:03 2005
+++ b/tools/vtpm/tpm_emulator.patch Tue Sep 20 09:08:26 2005
@@ -1,12 +1,12 @@
-diff -uprN orig/tpm_emulator-0.2/AUTHORS tpm_emulator-0.2/AUTHORS
---- orig/tpm_emulator-0.2/AUTHORS 2005-08-17 10:58:36.000000000 -0700
-+++ tpm_emulator-0.2/AUTHORS 2005-08-17 10:55:52.000000000 -0700
+diff -uprN orig/tpm_emulator-0.2-x86_64/AUTHORS tpm_emulator/AUTHORS
+--- orig/tpm_emulator-0.2-x86_64/AUTHORS 2005-08-15 00:58:57.000000000
-0700
++++ tpm_emulator/AUTHORS 2005-09-14 20:27:22.000000000 -0700
@@ -1 +1,2 @@
Mario Strasser <mast@xxxxxxx>
+INTEL Corp <>
-diff -uprN orig/tpm_emulator-0.2/ChangeLog tpm_emulator-0.2/ChangeLog
---- orig/tpm_emulator-0.2/ChangeLog 2005-08-17 10:58:36.000000000 -0700
-+++ tpm_emulator-0.2/ChangeLog 2005-08-17 10:55:52.000000000 -0700
+diff -uprN orig/tpm_emulator-0.2-x86_64/ChangeLog tpm_emulator/ChangeLog
+--- orig/tpm_emulator-0.2-x86_64/ChangeLog 2005-08-15 00:58:57.000000000
-0700
++++ tpm_emulator/ChangeLog 2005-09-14 20:27:22.000000000 -0700
@@ -1,3 +1,7 @@
+2005-08-16: INTEL Corp
+ * Set default permissions to PCRs
@@ -15,10 +15,29 @@
2005-08-15 Mario Strasser <mast@xxxxxxx>
* all: some typos corrected
* tpm_integrity.c: bug in TPM_Extend fixed
-diff -uprN orig/tpm_emulator-0.2/Makefile tpm_emulator-0.2/Makefile
---- orig/tpm_emulator-0.2/Makefile 2005-08-17 10:58:36.000000000 -0700
-+++ tpm_emulator-0.2/Makefile 2005-08-17 10:55:52.000000000 -0700
-@@ -1,15 +1,19 @@
+diff -uprN orig/tpm_emulator-0.2-x86_64/linux_module.h
tpm_emulator/linux_module.h
+--- orig/tpm_emulator-0.2-x86_64/linux_module.h 2005-09-15
19:21:14.844078720 -0700
++++ tpm_emulator/linux_module.h 2005-09-14 20:27:22.000000000 -0700
+@@ -1,5 +1,6 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+ * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
++ * Copyright (C) 2005 INTEL Corp.
+ *
+ * This module is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+@@ -35,7 +36,7 @@
+ #include "tpm_version.h"
+
+ #define TPM_DEVICE_MINOR 224
+-#define TPM_DEVICE_NAME "tpm"
++#define TPM_DEVICE_NAME "tpm0"
+ #define TPM_MODULE_NAME "tpm_emulator"
+
+ /* debug and log output functions */
+diff -uprN orig/tpm_emulator-0.2-x86_64/Makefile tpm_emulator/Makefile
+--- orig/tpm_emulator-0.2-x86_64/Makefile 2005-09-15 19:21:14.845078568
-0700
++++ tpm_emulator/Makefile 2005-09-14 20:27:22.000000000 -0700
+@@ -1,16 +1,20 @@
# Software-Based Trusted Platform Module (TPM) Emulator for Linux
# Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>
+# Copyright (C) 2005 INTEL Corp.
@@ -33,6 +52,7 @@
-KERNEL_BUILD := /lib/modules/$(KERNEL_RELEASE)/build
+KERNEL_BUILD := $(XEN_ROOT)/linux-2.6.12-xen0
MOD_SUBDIR := misc
+ COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/)
# module settings
-MODULE_NAME := tpm_emulator
@@ -40,7 +60,7 @@
VERSION_MAJOR := 0
VERSION_MINOR := 2
VERSION_BUILD := $(shell date +"%s")
-@@ -27,11 +30,9 @@ DIRS := . crypto tpm
+@@ -34,11 +38,9 @@ DIRS := . crypto tpm
SRCS := $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.c))
OBJS := $(patsubst %.c, %.o, $(SRCS))
SRCS += $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.h))
@@ -54,7 +74,7 @@
EXTRA_CFLAGS += -I$(src) -I$(src)/crypto -I$(src)/tpm
-@@ -42,23 +43,17 @@ all: $(src)/crypto/gmp.h $(src)/crypto/l
+@@ -49,23 +51,17 @@ all: $(src)/crypto/gmp.h $(src)/crypto/l
@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules
install:
@@ -84,9 +104,9 @@
$(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/README tpm_emulator-0.2/README
---- orig/tpm_emulator-0.2/README 2005-08-17 10:58:36.000000000 -0700
-+++ tpm_emulator-0.2/README 2005-08-17 10:55:52.000000000 -0700
+diff -uprN orig/tpm_emulator-0.2-x86_64/README tpm_emulator/README
+--- orig/tpm_emulator-0.2-x86_64/README 2005-08-15 00:58:57.000000000
-0700
++++ tpm_emulator/README 2005-09-14 20:27:22.000000000 -0700
@@ -13,7 +13,8 @@ $Id: README 8 2005-01-25 21:11:45Z jmoli
Copyright
--------------------------------------------------------------------------
@@ -97,28 +117,9 @@
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-diff -uprN orig/tpm_emulator-0.2/linux_module.h tpm_emulator-0.2/linux_module.h
---- orig/tpm_emulator-0.2/linux_module.h 2005-08-17 10:58:36.000000000
-0700
-+++ tpm_emulator-0.2/linux_module.h 2005-08-17 10:55:52.000000000 -0700
-@@ -1,5 +1,6 @@
- /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
- * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
-+ * Copyright (C) 2005 INTEL Corp.
- *
- * This module is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
-@@ -33,7 +34,7 @@
- #include "tpm_version.h"
-
- #define TPM_DEVICE_MINOR 224
--#define TPM_DEVICE_NAME "tpm"
-+#define TPM_DEVICE_NAME "tpm0"
- #define TPM_MODULE_NAME "tpm_emulator"
-
- /* debug and log output functions */
-diff -uprN orig/tpm_emulator-0.2/tpm/tpm_data.c tpm_emulator-0.2/tpm/tpm_data.c
---- orig/tpm_emulator-0.2/tpm/tpm_data.c 2005-08-17 10:58:36.000000000
-0700
-+++ tpm_emulator-0.2/tpm/tpm_data.c 2005-08-17 10:55:52.000000000 -0700
+diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c
tpm_emulator/tpm/tpm_data.c
+--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c 2005-09-15
19:21:14.847078264 -0700
++++ tpm_emulator/tpm/tpm_data.c 2005-09-14 20:27:22.000000000 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -139,13 +140,3 @@
tpmData.permanent.data.pcrAttrib[i].pcrReset = TRUE;
}
/* set tick type */
-diff -uprN orig/tpm_emulator-0.2/tpm_version.h tpm_emulator-0.2/tpm_version.h
---- orig/tpm_emulator-0.2/tpm_version.h 2005-08-17 10:58:36.000000000
-0700
-+++ tpm_emulator-0.2/tpm_version.h 2005-08-17 10:55:53.000000000 -0700
-@@ -2,5 +2,5 @@
- #define _TPM_VERSION_H_
- #define VERSION_MAJOR 0
- #define VERSION_MINOR 2
--#define VERSION_BUILD 1123950310
-+#define VERSION_BUILD 1124301353
- #endif /* _TPM_VERSION_H_ */
diff -r 3ef86b208f9b -r c0796e18b6a4 tools/vtpm/vtpm.patch
--- a/tools/vtpm/vtpm.patch Tue Sep 20 09:05:03 2005
+++ b/tools/vtpm/vtpm.patch Tue Sep 20 09:08:26 2005
@@ -1,12 +1,12 @@
-diff -uprN orig/tpm_emulator-0.2/AUTHORS vtpm/AUTHORS
---- orig/tpm_emulator-0.2/AUTHORS 2005-08-17 10:58:36.000000000 -0700
-+++ vtpm/AUTHORS 2005-08-17 10:55:52.000000000 -0700
+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
@@ -1 +1,2 @@
Mario Strasser <mast@xxxxxxx>
+INTEL Corp <>
-diff -uprN orig/tpm_emulator-0.2/ChangeLog vtpm/ChangeLog
---- orig/tpm_emulator-0.2/ChangeLog 2005-08-17 10:58:36.000000000 -0700
-+++ vtpm/ChangeLog 2005-08-17 10:55:52.000000000 -0700
+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
@@ -1,3 +1,7 @@
+2005-08-16 Intel Corp
+ Moved module out of kernel to run as a ring 3 app
@@ -15,115 +15,9 @@
2005-08-15 Mario Strasser <mast@xxxxxxx>
* all: some typos corrected
* tpm_integrity.c: bug in TPM_Extend fixed
-diff -uprN orig/tpm_emulator-0.2/Makefile vtpm/Makefile
---- orig/tpm_emulator-0.2/Makefile 2005-08-17 10:58:36.000000000 -0700
-+++ vtpm/Makefile 2005-08-17 10:55:52.000000000 -0700
-@@ -1,21 +1,29 @@
- # Software-Based Trusted Platform Module (TPM) Emulator for Linux
- # Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>
-+# Copyright (C) 2005 INTEL Corp.
- #
- # $Id: Makefile 10 2005-04-26 20:59:50Z mast $
-
--# kernel settings
--KERNEL_RELEASE := $(shell uname -r)
--KERNEL_BUILD := /lib/modules/$(KERNEL_RELEASE)/build
--MOD_SUBDIR := misc
--
- # module settings
--MODULE_NAME := tpm_emulator
-+BIN := vtpmd
- VERSION_MAJOR := 0
- VERSION_MINOR := 2
- VERSION_BUILD := $(shell date +"%s")
-
--# enable/disable DEBUG messages
--EXTRA_CFLAGS += -DDEBUG -g
-+# Installation program and options
-+INSTALL = install
-+INSTALL_PROG = $(INSTALL) -m0755
-+INSTALL_DIR = $(INSTALL) -d -m0755
-+
-+# Xen tools installation directory
-+TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin
-+
-+CC := gcc
-+CFLAGS += -g -Wall $(INCLUDE) -DDEBUG
-+CFLAGS += -I. -Itpm
-+
-+# Is the simulator running in it's own vm?
-+#CFLAGS += -DVTPM_MULTI_VM
-
- # GNU MP configuration
- GMP_LIB := /usr/lib/libgmp.a
-@@ -27,38 +35,31 @@ DIRS := . crypto tpm
- SRCS := $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.c))
- OBJS := $(patsubst %.c, %.o, $(SRCS))
- SRCS += $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.h))
--DISTSRC := ./README ./AUTHORS ./ChangeLog ./Makefile $(SRCS)
--DISTDIR := tpm_emulator-$(VERSION_MAJOR).$(VERSION_MINOR)
-
--obj-m := $(MODULE_NAME).o
--$(MODULE_NAME)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
-+obj-m := $(BIN)
-+$(BIN)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
-
- EXTRA_CFLAGS += -I$(src) -I$(src)/crypto -I$(src)/tpm
-
- # do not print "Entering directory ..."
- MAKEFLAGS += --no-print-directory
-
--all: $(src)/crypto/gmp.h $(src)/crypto/libgmp.a version
-- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules
-+all: $(BIN)
-+
-+$(BIN): $(src)/crypto/gmp.h $(src)/crypto/libgmp.a version $(SRCS)
$(OBJS)
-+ $(CC) $(CFLAGS) $(OBJS) $(src)/crypto/libgmp.a -o $(BIN)
-+
-+%.o: %.c
-+ $(CC) $(CFLAGS) -c $< -o $@
-
- install:
-- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules_install
-- test -d /var/tpm || mkdir /var/tpm
-- test -c /dev/tpm || mknod /dev/tpm c 10 224
-- chmod 666 /dev/tpm
-- depmod -a
-+ $(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR)
-
- clean:
-- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean
-- rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a
-+ rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a $(OBJS)
-
--dist: $(DISTSRC)
-- rm -rf $(DISTDIR)
-- mkdir $(DISTDIR)
-- cp --parents $(DISTSRC) $(DISTDIR)/
-- rm -f $(DISTDIR)/crypto/gmp.h
-- tar -chzf $(DISTDIR).tar.gz $(DISTDIR)
-- rm -rf $(DISTDIR)
-+mrproper: clean
-+ rm -f $(BIN)
-
- $(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/README vtpm/README
---- orig/tpm_emulator-0.2/README 2005-08-17 10:58:36.000000000 -0700
-+++ vtpm/README 2005-08-17 10:55:52.000000000 -0700
-@@ -13,7 +13,8 @@ $Id: README 8 2005-01-25 21:11:45Z jmoli
- Copyright
- --------------------------------------------------------------------------
- Copyright (C) 2004 Mario Strasser <mast@xxxxxxx> and Swiss Federal
--Institute of Technology (ETH) Zurich.
-+ Institute of Technology (ETH) Zurich.
-+Copyright (C) 2005 INTEL Corp
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
-diff -uprN orig/tpm_emulator-0.2/crypto/gmp_kernel_wrapper.c
vtpm/crypto/gmp_kernel_wrapper.c
---- orig/tpm_emulator-0.2/crypto/gmp_kernel_wrapper.c 2005-08-17
10:58:36.000000000 -0700
-+++ vtpm/crypto/gmp_kernel_wrapper.c 2005-08-17 10:55:52.000000000 -0700
+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
@@ -1,5 +1,6 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -154,9 +48,9 @@
{
- void *ret = (void*)kmalloc(size, GFP_KERNEL);
- if (!ret) panic(KERN_CRIT TPM_MODULE_NAME
-- "GMP: cannot allocate memory (size=%u)\n", size);
+- "GMP: cannot allocate memory (size=%Zu)\n", size);
+ void *ret = (void*)malloc(size);
-+ if (!ret) error("GMP: cannot allocate memory (size=%u)\n", size);
++ if (!ret) error("GMP: cannot allocate memory (size=%Zu)\n", size);
return ret;
}
@@ -165,9 +59,10 @@
{
- 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=%u new_size=%u)\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);
@@ -183,9 +78,9 @@
}
}
-diff -uprN orig/tpm_emulator-0.2/crypto/rsa.c vtpm/crypto/rsa.c
---- orig/tpm_emulator-0.2/crypto/rsa.c 2005-08-17 10:58:36.000000000 -0700
-+++ vtpm/crypto/rsa.c 2005-08-17 10:55:52.000000000 -0700
+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
@@ -1,5 +1,6 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -211,8 +106,8 @@
sha1_final(&ctx, &msg[1]);
if (memcmp(&msg[1], &msg[1 + SHA1_DIGEST_LENGTH],
SHA1_DIGEST_LENGTH) != 0) return -1;
-diff -uprN orig/tpm_emulator-0.2/linux_module.c vtpm/linux_module.c
---- orig/tpm_emulator-0.2/linux_module.c 2005-08-17 10:58:36.000000000
-0700
+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
+++ 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
@@ -283,7 +178,7 @@
-
-static ssize_t tpm_read(struct file *file, char *buf, size_t count, loff_t
*ppos)
-{
-- debug("%s(%d)", __FUNCTION__, count);
+- debug("%s(%Zu)", __FUNCTION__, count);
- down(&tpm_mutex);
- if (tpm_response.data != NULL) {
- count = min(count, (size_t)tpm_response.size - (size_t)*ppos);
@@ -298,7 +193,7 @@
-
-static ssize_t tpm_write(struct file *file, const char *buf, size_t count,
loff_t *ppos)
-{
-- debug("%s(%d)", __FUNCTION__, count);
+- debug("%s(%Zu)", __FUNCTION__, count);
- down(&tpm_mutex);
- *ppos = 0;
- if (tpm_response.data != NULL) kfree(tpm_response.data);
@@ -378,9 +273,9 @@
- return (ticks > 0) ? ticks : 1;
-}
-
-diff -uprN orig/tpm_emulator-0.2/linux_module.h vtpm/linux_module.h
---- orig/tpm_emulator-0.2/linux_module.h 2005-08-17 10:58:36.000000000
-0700
-+++ vtpm/linux_module.h 2005-08-17 10:55:52.000000000 -0700
+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
@@ -1,5 +1,6 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -416,17 +311,20 @@
+/* module settings */
+#define min(A,B) ((A)<(B)?(A):(B))
+ #ifndef STR
#define STR(s) __STR__(s)
#define __STR__(s) #s
- #include "tpm_version.h"
-@@ -39,32 +45,35 @@
+@@ -39,34 +45,38 @@
+ #define TPM_MODULE_NAME "tpm_emulator"
+
/* debug and log output functions */
++extern int dmi_id;
#ifdef DEBUG
-#define debug(fmt, ...) printk(KERN_DEBUG "%s %s:%d: Debug: " fmt "\n", \
- TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
-+#define debug(fmt, ...) printf("%s:%d: Debug: " fmt "\n", \
-+ __FILE__, __LINE__, ## __VA_ARGS__)
++#define debug(fmt, ...) printf("TPMD[%d]: %s:%d: Debug: " fmt "\n", \
++ dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
#else
#define debug(fmt, ...)
#endif
@@ -436,12 +334,12 @@
- TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
-#define alert(fmt, ...) printk(KERN_ALERT "%s %s:%d: Alert: " fmt "\n", \
- TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
-+#define info(fmt, ...) printf("%s:%d: Info: " fmt "\n", \
-+ __FILE__, __LINE__, ## __VA_ARGS__)
-+#define error(fmt, ...) printf("%s:%d: Error: " fmt "\n", \
-+ __FILE__, __LINE__, ## __VA_ARGS__)
-+#define alert(fmt, ...) printf("%s:%d: Alert: " fmt "\n", \
-+ __FILE__, __LINE__, ## __VA_ARGS__)
++#define info(fmt, ...) printf("TPMD[%d]: %s:%d: Info: " fmt "\n", \
++ dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
++#define error(fmt, ...) printf("TPMD[%d]: %s:%d: Error: " fmt "\n", \
++ dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
++#define alert(fmt, ...) printf("TPMD[%d]: %s:%d: Alert: " fmt "\n", \
++ dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
/* memory allocation */
@@ -465,7 +363,7 @@
static inline void tpm_get_random_bytes(void *buf, int nbytes)
{
get_random_bytes(buf, nbytes);
-@@ -84,9 +93,9 @@ uint64_t tpm_get_ticks(void);
+@@ -86,9 +96,9 @@ uint64_t tpm_get_ticks(void);
#define CPU_TO_LE16(x) __cpu_to_le16(x)
#define BE64_TO_CPU(x) __be64_to_cpu(x)
@@ -477,9 +375,116 @@
#define BE16_TO_CPU(x) __be16_to_cpu(x)
#define LE16_TO_CPU(x) __le16_to_cpu(x)
-diff -uprN orig/tpm_emulator-0.2/tpm/tpm_audit.c vtpm/tpm/tpm_audit.c
---- orig/tpm_emulator-0.2/tpm/tpm_audit.c 2005-08-17 10:58:36.000000000
-0700
-+++ vtpm/tpm/tpm_audit.c 2005-08-17 10:55:52.000000000 -0700
+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
+@@ -1,22 +1,31 @@
+ # Software-Based Trusted Platform Module (TPM) Emulator for Linux
+ # Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>
++# Copyright (C) 2005 INTEL Corp.
+ #
+ # $Id: Makefile 10 2005-04-26 20:59:50Z mast $
+
+-# kernel settings
+-KERNEL_RELEASE := $(shell uname -r)
+-KERNEL_BUILD := /lib/modules/$(KERNEL_RELEASE)/build
+-MOD_SUBDIR := misc
+ COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/)
+
+ # module settings
+-MODULE_NAME := tpm_emulator
++BIN := vtpmd
+ VERSION_MAJOR := 0
+ VERSION_MINOR := 2
+ VERSION_BUILD := $(shell date +"%s")
+
+-# enable/disable DEBUG messages
+-EXTRA_CFLAGS += -DDEBUG -g
++# Installation program and options
++INSTALL = install
++INSTALL_PROG = $(INSTALL) -m0755
++INSTALL_DIR = $(INSTALL) -d -m0755
++
++# Xen tools installation directory
++TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin
++
++CC := gcc
++CFLAGS += -g -Wall $(INCLUDE) -DDEBUG
++CFLAGS += -I. -Itpm
++
++# Is the simulator running in it's own vm?
++#CFLAGS += -DVTPM_MULTI_VM
+
+ ifeq ($(COMPILE_ARCH),x86_64)
+ LIBDIR = lib64
+@@ -34,38 +43,31 @@ DIRS := . crypto tpm
+ SRCS := $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.c))
+ OBJS := $(patsubst %.c, %.o, $(SRCS))
+ SRCS += $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.h))
+-DISTSRC := ./README ./AUTHORS ./ChangeLog ./Makefile $(SRCS)
+-DISTDIR := tpm_emulator-$(VERSION_MAJOR).$(VERSION_MINOR)
+
+-obj-m := $(MODULE_NAME).o
+-$(MODULE_NAME)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
++obj-m := $(BIN)
++$(BIN)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
+
+ EXTRA_CFLAGS += -I$(src) -I$(src)/crypto -I$(src)/tpm
+
+ # do not print "Entering directory ..."
+ MAKEFLAGS += --no-print-directory
+
+-all: $(src)/crypto/gmp.h $(src)/crypto/libgmp.a version
+- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules
++all: $(BIN)
++
++$(BIN): $(src)/crypto/gmp.h $(src)/crypto/libgmp.a version $(SRCS)
$(OBJS)
++ $(CC) $(CFLAGS) $(OBJS) $(src)/crypto/libgmp.a -o $(BIN)
++
++%.o: %.c
++ $(CC) $(CFLAGS) -c $< -o $@
+
+ install:
+- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules_install
+- test -d /var/tpm || mkdir /var/tpm
+- test -c /dev/tpm || mknod /dev/tpm c 10 224
+- chmod 666 /dev/tpm
+- depmod -a
++ $(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR)
+
+ clean:
+- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean
+- rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a
++ rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a $(OBJS)
+
+-dist: $(DISTSRC)
+- rm -rf $(DISTDIR)
+- mkdir $(DISTDIR)
+- cp --parents $(DISTSRC) $(DISTDIR)/
+- rm -f $(DISTDIR)/crypto/gmp.h
+- tar -chzf $(DISTDIR).tar.gz $(DISTDIR)
+- rm -rf $(DISTDIR)
++mrproper: clean
++ rm -f $(BIN) tpm_version.h
+
+ $(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
+@@ -13,7 +13,8 @@ $Id: README 8 2005-01-25 21:11:45Z jmoli
+ Copyright
+ --------------------------------------------------------------------------
+ Copyright (C) 2004 Mario Strasser <mast@xxxxxxx> and Swiss Federal
+-Institute of Technology (ETH) Zurich.
++ Institute of Technology (ETH) Zurich.
++Copyright (C) 2005 INTEL Corp
+
+ This program is free software; you can redistribute it and/or modify
+ 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
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -542,9 +547,9 @@
return TPM_SUCCESS;
}
-
-diff -uprN orig/tpm_emulator-0.2/tpm/tpm_authorization.c
vtpm/tpm/tpm_authorization.c
---- orig/tpm_emulator-0.2/tpm/tpm_authorization.c 2005-08-17
10:58:36.000000000 -0700
-+++ vtpm/tpm/tpm_authorization.c 2005-08-17 10:55:52.000000000 -0700
+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
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -568,9 +573,9 @@
}
-
-
-diff -uprN orig/tpm_emulator-0.2/tpm/tpm_capability.c vtpm/tpm/tpm_capability.c
---- orig/tpm_emulator-0.2/tpm/tpm_capability.c 2005-08-17 10:58:36.000000000
-0700
-+++ vtpm/tpm/tpm_capability.c 2005-08-17 10:55:52.000000000 -0700
+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
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -593,9 +598,9 @@
}
}
-
-diff -uprN orig/tpm_emulator-0.2/tpm/tpm_cmd_handler.c
vtpm/tpm/tpm_cmd_handler.c
---- orig/tpm_emulator-0.2/tpm/tpm_cmd_handler.c 2005-08-17
10:58:36.000000000 -0700
-+++ vtpm/tpm/tpm_cmd_handler.c 2005-08-17 10:55:52.000000000 -0700
+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
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -658,9 +663,9 @@
return 0;
}
-
-diff -uprN orig/tpm_emulator-0.2/tpm/tpm_crypto.c vtpm/tpm/tpm_crypto.c
---- orig/tpm_emulator-0.2/tpm/tpm_crypto.c 2005-08-17 10:58:36.000000000
-0700
-+++ vtpm/tpm/tpm_crypto.c 2005-08-17 10:55:52.000000000 -0700
+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
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -678,14 +683,14 @@
memcpy(&buf[30], areaToSign, areaToSignSize);
if (rsa_sign(&key->key, RSA_SSA_PKCS1_SHA1,
buf, areaToSignSize + 30, *sig)) {
-@@ -379,4 +380,3 @@ TPM_RESULT TPM_CertifyKey2(TPM_KEY_HANDL
+@@ -383,4 +384,3 @@ TPM_RESULT TPM_CertifyKey2(TPM_KEY_HANDL
}
return TPM_SUCCESS;
}
-
-diff -uprN orig/tpm_emulator-0.2/tpm/tpm_data.c vtpm/tpm/tpm_data.c
---- orig/tpm_emulator-0.2/tpm/tpm_data.c 2005-08-17 10:58:36.000000000
-0700
-+++ vtpm/tpm/tpm_data.c 2005-08-17 10:55:52.000000000 -0700
+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
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1005,7 +1010,7 @@
}
#else
-@@ -231,7 +431,6 @@ int tpm_restore_permanent_data(void)
+@@ -232,7 +432,6 @@ int tpm_restore_permanent_data(void)
int tpm_erase_permanent_data(void)
{
@@ -1014,9 +1019,9 @@
return res;
}
-
-diff -uprN orig/tpm_emulator-0.2/tpm/tpm_deprecated.c vtpm/tpm/tpm_deprecated.c
---- orig/tpm_emulator-0.2/tpm/tpm_deprecated.c 2005-08-17 10:58:36.000000000
-0700
-+++ vtpm/tpm/tpm_deprecated.c 2005-08-17 10:55:52.000000000 -0700
+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
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1043,9 +1048,9 @@
authContextSize, &contextBlob);
if (res != TPM_SUCCESS) return res;
len = *authContextSize;
-diff -uprN orig/tpm_emulator-0.2/tpm/tpm_emulator.h vtpm/tpm/tpm_emulator.h
---- orig/tpm_emulator-0.2/tpm/tpm_emulator.h 2005-08-17 10:58:36.000000000
-0700
-+++ vtpm/tpm/tpm_emulator.h 2005-08-17 10:55:52.000000000 -0700
+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
@@ -1,5 +1,6 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1063,9 +1068,9 @@
/**
* tpm_emulator_init - initialises and starts the TPM emulator
-diff -uprN orig/tpm_emulator-0.2/tpm/tpm_integrity.c vtpm/tpm/tpm_integrity.c
---- orig/tpm_emulator-0.2/tpm/tpm_integrity.c 2005-08-17 10:58:36.000000000
-0700
-+++ vtpm/tpm/tpm_integrity.c 2005-08-17 10:55:52.000000000 -0700
+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
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1079,9 +1084,9 @@
return TPM_SUCCESS;
}
-
-diff -uprN orig/tpm_emulator-0.2/tpm/tpm_structures.h vtpm/tpm/tpm_structures.h
---- orig/tpm_emulator-0.2/tpm/tpm_structures.h 2005-08-17 10:58:36.000000000
-0700
-+++ vtpm/tpm/tpm_structures.h 2005-08-17 10:55:52.000000000 -0700
+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
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1099,9 +1104,9 @@
#include "crypto/rsa.h"
/*
-diff -uprN orig/tpm_emulator-0.2/tpm/tpm_testing.c vtpm/tpm/tpm_testing.c
---- orig/tpm_emulator-0.2/tpm/tpm_testing.c 2005-08-17 10:58:36.000000000
-0700
-+++ vtpm/tpm/tpm_testing.c 2005-08-17 10:55:52.000000000 -0700
+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
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1217,9 +1222,9 @@
rsa_private_key_t priv_key;
rsa_public_key_t pub_key;
-diff -uprN orig/tpm_emulator-0.2/tpm/tpm_ticks.c vtpm/tpm/tpm_ticks.c
---- orig/tpm_emulator-0.2/tpm/tpm_ticks.c 2005-08-17 10:58:36.000000000
-0700
-+++ vtpm/tpm/tpm_ticks.c 2005-08-17 10:55:52.000000000 -0700
+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
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1302,9 +1307,9 @@
}
-diff -uprN orig/tpm_emulator-0.2/tpm/vtpm_manager.h vtpm/tpm/vtpm_manager.h
---- orig/tpm_emulator-0.2/tpm/vtpm_manager.h 1969-12-31 16:00:00.000000000
-0800
-+++ vtpm/tpm/vtpm_manager.h 2005-08-17 10:55:52.000000000 -0700
+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 @@
+// ===================================================================
+//
@@ -1432,9 +1437,9 @@
+*********************************************************************/
+
+#endif //_VTPM_MANAGER_H_
-diff -uprN orig/tpm_emulator-0.2/tpmd.c vtpm/tpmd.c
---- orig/tpm_emulator-0.2/tpmd.c 1969-12-31 16:00:00.000000000 -0800
-+++ vtpm/tpmd.c 2005-08-17 10:55:52.000000000 -0700
+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
@@ -0,0 +1,207 @@
+/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+ * Copyright (C) 2005 INTEL Corp
@@ -1468,9 +1473,9 @@
+#else
+ #define GUEST_RX_FIFO_D "/var/vtpm/fifos/guest-to-%d.fifo"
+ #define GUEST_TX_FIFO "/var/vtpm/fifos/guest-from-all.fifo"
++#endif
+
+ int dmi_id;
-+#endif
+
+#define BUFFER_SIZE 2048
+
@@ -1506,7 +1511,7 @@
+{
+ uint8_t in[BUFFER_SIZE], *out, *addressed_out;
+ uint32_t out_size;
-+ int in_size, written ;
++ int in_size, written;
+ int i, guest_id=-1;
+
+ int vtpm_tx_fh=-1, vtpm_rx_fh=-1;
@@ -1602,7 +1607,7 @@
+ written = write(vtpm_tx_fh, ctrl_msg, sizeof(ctrl_msg));
+
+ if (written != sizeof(ctrl_msg)) {
-+ printf("ERROR: Part of response not written %d/%d.\n", written,
sizeof(ctrl_msg));
++ printf("ERROR: Part of response not written %d/%Zu.\n", written,
sizeof(ctrl_msg));
+ } else {
+ printf("Send Ctrl Message confermation\n");
+ }
@@ -1623,7 +1628,7 @@
+ printf("%x ", addressed_out[i]);
+ printf("\n");
+ } else {
-+ printf("Sent[%d]: ", out_size + sizeof(uint32_t));
++ printf("Sent[%Zu]: ", out_size + sizeof(uint32_t));
+ for (i=0; i< out_size+ sizeof(uint32_t); i++)
+ printf("%x ", addressed_out[i]);
+ printf("\n");
diff -r 3ef86b208f9b -r c0796e18b6a4 tools/vtpm_manager/README
--- a/tools/vtpm_manager/README Tue Sep 20 09:05:03 2005
+++ b/tools/vtpm_manager/README Tue Sep 20 09:08:26 2005
@@ -51,14 +51,24 @@
DUMMY_BACKEND -> vtpm_manager listens on /tmp/in.fifo and
/tmp/out.fifo rather than backend
-MANUAL_DM_LAUNCH -> User must manually launch & kill VTPMs
+MANUAL_DM_LAUNCH -> Must manually launch & kill VTPMs
-USE_FIXED_SRK_AUTH -> Do not randomly generate a random SRK & Owner
auth
+WELL_KNOWN_SRK_AUTH -> Rather than randomly generating the password
for the SRK,
+ use a well known value. This is necessary for
sharing use
+ of the SRK across applications. Such as VTPM
and Dom0
+ measurement software.
+
+WELL_KNOWN_OWNER_AUTH -> Rather than randomly generating the password
for the owner,
+ use a well known value. This is useful for
debugging and for
+ poor bios which do not support clearing TPM if
OwnerAuth is
+ lost. However this has no protection from
malicious app
+ issuing a TPM_OwnerClear to wipe the TPM
Requirements
============
- xen-unstable
-- IBM frontend/backend vtpm driver patch
+- vtpm frontend/backend driver patch
+- OpenSSL Library
Single-VM Flow
============================
diff -r 3ef86b208f9b -r c0796e18b6a4 tools/vtpm_manager/Rules.mk
--- a/tools/vtpm_manager/Rules.mk Tue Sep 20 09:05:03 2005
+++ b/tools/vtpm_manager/Rules.mk Tue Sep 20 09:08:26 2005
@@ -57,7 +57,8 @@
#CFLAGS += -DMANUAL_DM_LAUNCH
# Fixed SRK
-CFLAGS += -DUSE_FIXED_SRK_AUTH
+CFLAGS += -DWELL_KNOWN_SRK_AUTH
+#CFLAGS += -DWELL_KNOWN_OWNER_AUTH
# TPM Hardware Device or TPM Simulator
#CFLAGS += -DTPM_HWDEV
diff -r 3ef86b208f9b -r c0796e18b6a4 tools/vtpm_manager/crypto/Makefile
--- a/tools/vtpm_manager/crypto/Makefile Tue Sep 20 09:05:03 2005
+++ b/tools/vtpm_manager/crypto/Makefile Tue Sep 20 09:08:26 2005
@@ -13,6 +13,7 @@
rm -f *.a *.so *.o *.rpm $(DEP_FILES)
mrproper: clean
+ rm -f *~
$(BIN): $(OBJS)
$(AR) rcs $(BIN) $(OBJS)
diff -r 3ef86b208f9b -r c0796e18b6a4 tools/vtpm_manager/manager/Makefile
--- a/tools/vtpm_manager/manager/Makefile Tue Sep 20 09:05:03 2005
+++ b/tools/vtpm_manager/manager/Makefile Tue Sep 20 09:08:26 2005
@@ -17,7 +17,7 @@
rm -f *.a *.so *.o *.rpm $(DEP_FILES)
mrproper: clean
- rm -f $(BIN)
+ rm -f $(BIN) *~
$(BIN): $(OBJS)
$(CC) $(LDFLAGS) $^ $(LIBS) -o $@
diff -r 3ef86b208f9b -r c0796e18b6a4 tools/vtpm_manager/manager/dmictl.c
--- a/tools/vtpm_manager/manager/dmictl.c Tue Sep 20 09:05:03 2005
+++ b/tools/vtpm_manager/manager/dmictl.c Tue Sep 20 09:08:26 2005
@@ -1,339 +1,344 @@
-// ===================================================================
-//
-// 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.
-// ===================================================================
-//
-// dmictl.c
-//
-// Functions for creating and destroying DMIs
-//
-// ==================================================================
-
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-
-#ifndef VTPM_MUTLI_VM
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <signal.h>
- #include <wait.h>
-#endif
-
-#include "vtpmpriv.h"
-#include "bsg.h"
-#include "buffer.h"
-#include "log.h"
-#include "hashtable.h"
-#include "hashtable_itr.h"
-
-#define TPM_EMULATOR_PATH "/usr/bin/vtpmd"
-
-TPM_RESULT close_dmi( VTPM_DMI_RESOURCE *dmi_res) {
- TPM_RESULT status = TPM_FAIL;
-
- if (dmi_res == NULL)
- return TPM_SUCCESS;
-
- status = 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;
-
-
- #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) ||
- (waitpid(dmi_res->dmi_pid, NULL, 0) != dmi_res->dmi_pid)){
- vtpmlogerror(VTPM_LOG_VTPM, "Could not kill dmi on pid %d.\n",
dmi_res->dmi_pid);
- status = TPM_FAIL;
- }
- } else
- vtpmlogerror(VTPM_LOG_VTPM, "Could not kill dmi because it's pid was
0.\n");
- }
- #endif
-#endif
-
- return status;
-}
-
-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;
- int fh;
-
-#ifndef VTPM_MUTLI_VM
- 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;
- dmi_id = VTPM_CTL_DM;
- } else if (buffer_len(param_buf) != sizeof(BYTE) + sizeof(UINT32) *2) {
- vtpmloginfo(VTPM_LOG_VTPM, "New DMI command wrong length: %d.\n",
buffer_len(param_buf));
- status = TPM_BAD_PARAMETER;
- goto abort_egress;
- } else {
- BSG_UnpackList( param_buf->bytes, 3,
- BSG_TYPE_BYTE, &type,
- BSG_TYPE_UINT32, &domain_id,
- BSG_TYPE_UINT32, &dmi_id);
- }
-
- new_dmi = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map,
&dmi_id);
- if (new_dmi == NULL) {
- vtpmloginfo(VTPM_LOG_VTPM, "Creating new DMI instance %d attached on
domain %d.\n", dmi_id, domain_id);
- // Brand New DMI. Initialize the persistent pieces
- if ((new_dmi = (VTPM_DMI_RESOURCE *) malloc (sizeof(VTPM_DMI_RESOURCE)))
== NULL) {
- status = TPM_RESOURCES;
- goto abort_egress;
- }
- memset(new_dmi, 0, sizeof(VTPM_DMI_RESOURCE));
- new_dmi->dmi_id = dmi_id;
- new_dmi->connected = FALSE;
-
- if ((dmi_id_key = (UINT32 *) malloc (sizeof(UINT32))) == NULL) {
- status = TPM_RESOURCES;
- goto abort_egress;
- }
- *dmi_id_key = new_dmi->dmi_id;
-
- // install into map
- if (!hashtable_insert(vtpm_globals->dmi_map, dmi_id_key, new_dmi)){
- free(new_dmi);
- free(dmi_id_key);
- status = TPM_FAIL;
- goto egress;
- }
-
- } else
- vtpmloginfo(VTPM_LOG_VTPM, "Re-attaching DMI instance %d on domain %d
.\n", dmi_id, domain_id);
-
- if (new_dmi->connected) {
- vtpmlogerror(VTPM_LOG_VTPM, "Attempt to re-attach, currently attached
instance %d. Ignoring\n", dmi_id);
- status = TPM_BAD_PARAMETER;
- goto egress;
- }
-
- // Initialize the Non-persistent pieces
- new_dmi->dmi_domain_id = domain_id;
- new_dmi->NVMLocation = NULL;
-
- new_dmi->TCSContext = 0;
- TPMTRYRETURN( TCS_OpenContext(&new_dmi->TCSContext) );
-
- 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 ) ){
- status = TPM_FAIL;
- 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 ) ) {
- status = TPM_FAIL;
- 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;
- goto egress;
-
- abort_egress:
- close_dmi( new_dmi );
-
- egress:
- return status;
-}
-
-TPM_RESULT VTPM_Handle_Close_DMI( const buffer_t *param_buf) {
-
- TPM_RESULT status=TPM_FAIL;
- VTPM_DMI_RESOURCE *dmi_res=NULL;
- UINT32 dmi_id;
-
- if ((param_buf == NULL) || (buffer_len(param_buf) != sizeof(UINT32)) ) {
- vtpmlogerror(VTPM_LOG_VTPM, "Closing DMI has bad size.");
- status = TPM_BAD_PARAMETER;
- goto abort_egress;
- }
-
- BSG_UnpackList( param_buf->bytes, 1,
- BSG_TYPE_UINT32, &dmi_id);
-
- vtpmloginfo(VTPM_LOG_VTPM, "Closing DMI %d.\n", dmi_id);
-
- dmi_res = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map,
&dmi_id);
- if (dmi_res == NULL ) {
- vtpmlogerror(VTPM_LOG_VTPM, "Trying to close nonexistent DMI.\n");
- status = TPM_BAD_PARAMETER;
- goto abort_egress;
- }
-
- if (!dmi_res->connected) {
- vtpmlogerror(VTPM_LOG_VTPM, "Closing non-connected DMI.\n");
- status = TPM_BAD_PARAMETER;
- goto abort_egress;
- }
-
- // Close Dmi
- TPMTRYRETURN(close_dmi( dmi_res ));
-
- status=TPM_SUCCESS;
- goto egress;
-
- abort_egress:
- egress:
-
- return status;
-}
-
-TPM_RESULT VTPM_Handle_Delete_DMI( const buffer_t *param_buf) {
-
- TPM_RESULT status=TPM_FAIL;
- VTPM_DMI_RESOURCE *dmi_res=NULL;
- UINT32 dmi_id;
-
- if ((param_buf == NULL) || (buffer_len(param_buf) != sizeof(UINT32)) ) {
- vtpmlogerror(VTPM_LOG_VTPM, "Closing DMI has bad size.\n");
- status = TPM_BAD_PARAMETER;
- goto abort_egress;
- }
-
- BSG_UnpackList( param_buf->bytes, 1,
- BSG_TYPE_UINT32, &dmi_id);
-
- vtpmloginfo(VTPM_LOG_VTPM, "Deleting DMI %d.\n", dmi_id);
-
- dmi_res = (VTPM_DMI_RESOURCE *) hashtable_remove(vtpm_globals->dmi_map,
&dmi_id);
- if (dmi_res == NULL) {
- vtpmlogerror(VTPM_LOG_VTPM, "Closing non-existent DMI.\n");
- status = TPM_BAD_PARAMETER;
- goto abort_egress;
- }
-
- //TODO: Automatically delete file dmi_res->NVMLocation
-
- // Close DMI first
- TPMTRYRETURN(close_dmi( dmi_res ));
- free ( dmi_res );
-
- status=TPM_SUCCESS;
- goto egress;
-
- abort_egress:
- egress:
-
- return status;
-}
+// ===================================================================
+//
+// 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.
+// ===================================================================
+//
+// dmictl.c
+//
+// Functions for creating and destroying DMIs
+//
+// ==================================================================
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+#ifndef VTPM_MUTLI_VM
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <signal.h>
+ #include <wait.h>
+#endif
+
+#include "vtpmpriv.h"
+#include "bsg.h"
+#include "buffer.h"
+#include "log.h"
+#include "hashtable.h"
+#include "hashtable_itr.h"
+
+#define TPM_EMULATOR_PATH "/usr/bin/vtpmd"
+
+TPM_RESULT close_dmi( VTPM_DMI_RESOURCE *dmi_res) {
+ TPM_RESULT status = TPM_FAIL;
+
+ if (dmi_res == NULL)
+ return TPM_SUCCESS;
+
+ status = 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;
+
+ #ifndef MANUAL_DM_LAUNCH
+ if (dmi_res->dmi_id != VTPM_CTL_DM) {
+ if (dmi_res->dmi_pid != 0) {
+ vtpmloginfo(VTPM_LOG_VTPM, "Killing dmi on pid %d.\n", dmi_res->dmi_pid);
+ if (kill(dmi_res->dmi_pid, SIGKILL) !=0) {
+ vtpmloginfo(VTPM_LOG_VTPM, "DMI on pid %d is already dead.\n",
dmi_res->dmi_pid);
+ } else if (waitpid(dmi_res->dmi_pid, NULL, 0) != dmi_res->dmi_pid) {
+ vtpmlogerror(VTPM_LOG_VTPM, "DMI on pid %d failed to stop.\n",
dmi_res->dmi_pid);
+ status = TPM_FAIL;
+ }
+ } else {
+ vtpmlogerror(VTPM_LOG_VTPM, "Could not kill dmi because it's pid was
0.\n");
+ status = TPM_FAIL;
+ }
+ }
+ #endif
+#endif
+
+ return status;
+}
+
+TPM_RESULT VTPM_Handle_New_DMI( const buffer_t *param_buf) {
+
+ 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;
+ dmi_id = VTPM_CTL_DM;
+ } else if (buffer_len(param_buf) != sizeof(BYTE) + sizeof(UINT32) *2) {
+ vtpmloginfo(VTPM_LOG_VTPM, "New DMI command wrong length: %d.\n",
buffer_len(param_buf));
+ status = TPM_BAD_PARAMETER;
+ goto abort_egress;
+ } else {
+ BSG_UnpackList( param_buf->bytes, 3,
+ BSG_TYPE_BYTE, &type,
+ BSG_TYPE_UINT32, &domain_id,
+ BSG_TYPE_UINT32, &dmi_id);
+ }
+
+ new_dmi = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map,
&dmi_id);
+ if (new_dmi == NULL) {
+ vtpmloginfo(VTPM_LOG_VTPM, "Creating new DMI instance %d attached on
domain %d.\n", dmi_id, domain_id);
+ // Brand New DMI. Initialize the persistent pieces
+ if ((new_dmi = (VTPM_DMI_RESOURCE *) malloc (sizeof(VTPM_DMI_RESOURCE)))
== NULL) {
+ status = TPM_RESOURCES;
+ goto abort_egress;
+ }
+ memset(new_dmi, 0, sizeof(VTPM_DMI_RESOURCE));
+ new_dmi->dmi_id = dmi_id;
+ new_dmi->connected = FALSE;
+
+ if ((dmi_id_key = (UINT32 *) malloc (sizeof(UINT32))) == NULL) {
+ status = TPM_RESOURCES;
+ goto abort_egress;
+ }
+ *dmi_id_key = new_dmi->dmi_id;
+
+ // install into map
+ if (!hashtable_insert(vtpm_globals->dmi_map, dmi_id_key, new_dmi)){
+ free(new_dmi);
+ free(dmi_id_key);
+ status = TPM_FAIL;
+ goto egress;
+ }
+
+ } else
+ vtpmloginfo(VTPM_LOG_VTPM, "Re-attaching DMI instance %d on domain %d
.\n", dmi_id, domain_id);
+
+ if (new_dmi->connected) {
+ vtpmlogerror(VTPM_LOG_VTPM, "Attempt to re-attach, currently attached
instance %d. Ignoring\n", dmi_id);
+ status = TPM_BAD_PARAMETER;
+ goto egress;
+ }
+
+ // Initialize the Non-persistent pieces
+ new_dmi->dmi_domain_id = domain_id;
+ new_dmi->NVMLocation = NULL;
+
+ new_dmi->TCSContext = 0;
+ TPMTRYRETURN( TCS_OpenContext(&new_dmi->TCSContext) );
+
+ 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;
+ 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 );
+
+ egress:
+ return status;
+}
+
+TPM_RESULT VTPM_Handle_Close_DMI( const buffer_t *param_buf) {
+
+ TPM_RESULT status=TPM_FAIL;
+ VTPM_DMI_RESOURCE *dmi_res=NULL;
+ UINT32 dmi_id;
+
+ if ((param_buf == NULL) || (buffer_len(param_buf) != sizeof(UINT32)) ) {
+ vtpmlogerror(VTPM_LOG_VTPM, "Closing DMI has bad size.");
+ status = TPM_BAD_PARAMETER;
+ goto abort_egress;
+ }
+
+ BSG_UnpackList( param_buf->bytes, 1,
+ BSG_TYPE_UINT32, &dmi_id);
+
+ vtpmloginfo(VTPM_LOG_VTPM, "Closing DMI %d.\n", dmi_id);
+
+ dmi_res = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map,
&dmi_id);
+ if (dmi_res == NULL ) {
+ vtpmlogerror(VTPM_LOG_VTPM, "Trying to close nonexistent DMI.\n");
+ status = TPM_BAD_PARAMETER;
+ goto abort_egress;
+ }
+
+ if (!dmi_res->connected) {
+ vtpmlogerror(VTPM_LOG_VTPM, "Closing non-connected DMI.\n");
+ status = TPM_BAD_PARAMETER;
+ goto abort_egress;
+ }
+
+ // Close Dmi
+ TPMTRYRETURN(close_dmi( dmi_res ));
+
+ status=TPM_SUCCESS;
+ goto egress;
+
+ abort_egress:
+ egress:
+
+ return status;
+}
+
+TPM_RESULT VTPM_Handle_Delete_DMI( const buffer_t *param_buf) {
+
+ TPM_RESULT status=TPM_FAIL;
+ VTPM_DMI_RESOURCE *dmi_res=NULL;
+ UINT32 dmi_id;
+
+ if ((param_buf == NULL) || (buffer_len(param_buf) != sizeof(UINT32)) ) {
+ vtpmlogerror(VTPM_LOG_VTPM, "Closing DMI has bad size.\n");
+ status = TPM_BAD_PARAMETER;
+ goto abort_egress;
+ }
+
+ BSG_UnpackList( param_buf->bytes, 1,
+ BSG_TYPE_UINT32, &dmi_id);
+
+ vtpmloginfo(VTPM_LOG_VTPM, "Deleting DMI %d.\n", dmi_id);
+
+ dmi_res = (VTPM_DMI_RESOURCE *) hashtable_remove(vtpm_globals->dmi_map,
&dmi_id);
+ if (dmi_res == NULL) {
+ vtpmlogerror(VTPM_LOG_VTPM, "Closing non-existent DMI.\n");
+ status = TPM_BAD_PARAMETER;
+ goto abort_egress;
+ }
+
+ //TODO: Automatically delete file dmi_res->NVMLocation
+
+ // Close DMI first
+ TPMTRYRETURN(close_dmi( dmi_res ));
+ free ( dmi_res );
+
+ status=TPM_SUCCESS;
+ goto egress;
+
+ abort_egress:
+ egress:
+
+ return status;
+}
diff -r 3ef86b208f9b -r c0796e18b6a4 tools/vtpm_manager/manager/securestorage.c
--- a/tools/vtpm_manager/manager/securestorage.c Tue Sep 20 09:05:03 2005
+++ b/tools/vtpm_manager/manager/securestorage.c Tue Sep 20 09:08:26 2005
@@ -1,401 +1,401 @@
-// ===================================================================
-//
-// 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.
-// ===================================================================
-//
-// securestorage.c
-//
-// Functions regarding securely storing DMI secrets.
-//
-// ==================================================================
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "tcg.h"
-#include "vtpm_manager.h"
-#include "vtpmpriv.h"
-#include "vtsp.h"
-#include "bsg.h"
-#include "crypto.h"
-#include "hashtable.h"
-#include "hashtable_itr.h"
-#include "buffer.h"
-#include "log.h"
-
-TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI_RESOURCE *myDMI,
- const buffer_t *inbuf,
- buffer_t *outbuf) {
-
- TPM_RESULT status = TPM_SUCCESS;
- symkey_t symkey;
- buffer_t state_cipher = NULL_BUF,
- symkey_cipher = NULL_BUF;
- int fh;
- long bytes_written;
- BYTE *sealed_NVM=NULL;
- UINT32 sealed_NVM_size, i;
- struct pack_constbuf_t symkey_cipher32, state_cipher32;
-
- vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Save_NVMing[%d]: 0x", buffer_len(inbuf));
- for (i=0; i< buffer_len(inbuf); i++)
- vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", inbuf->bytes[i]);
- vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
-
- // Generate a sym key and encrypt state with it
- TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_genkey (&symkey) );
- TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_encrypt (&symkey, inbuf,
&state_cipher) );
-
- // Encrypt symmetric key
- TPMTRYRETURN( VTSP_Bind( &vtpm_globals->storageKey,
- &symkey.key,
- &symkey_cipher) );
-
- // Create output blob: symkey_size + symkey_cipher + state_cipher_size +
state_cipher
-
- symkey_cipher32.size = buffer_len(&symkey_cipher);
- symkey_cipher32.data = symkey_cipher.bytes;
-
- state_cipher32.size = buffer_len(&state_cipher);
- state_cipher32.data = state_cipher.bytes;
-
- sealed_NVM = (BYTE *) malloc( 2 * sizeof(UINT32) + symkey_cipher32.size +
state_cipher32.size);
-
- sealed_NVM_size = BSG_PackList(sealed_NVM, 2,
- BSG_TPM_SIZE32_DATA, &symkey_cipher32,
- BSG_TPM_SIZE32_DATA, &state_cipher32);
-
- // 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.
- // TODO: Backup old file and try and recover that way.
- fh = open(myDMI->NVMLocation, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
- if ( (bytes_written = write(fh, sealed_NVM, sealed_NVM_size) ) != (long)
sealed_NVM_size) {
- vtpmlogerror(VTPM_LOG_VTPM, "We just overwrote a DMI_NVM and failed to
finish. %ld/%ld bytes.\n", bytes_written, (long)sealed_NVM_size);
- status = TPM_IOERROR;
- goto abort_egress;
- }
- close(fh);
-
- Crypto_SHA1Full (sealed_NVM, sealed_NVM_size, (BYTE *)
&myDMI->NVM_measurement);
-
- vtpmloginfo(VTPM_LOG_VTPM, "Saved %d bytes of E(symkey) + %d bytes of
E(NVM)\n", buffer_len(&symkey_cipher), buffer_len(&state_cipher));
- goto egress;
-
- abort_egress:
- vtpmlogerror(VTPM_LOG_VTPM, "Failed to load NVM\n.");
-
- egress:
-
- buffer_free ( &state_cipher);
- buffer_free ( &symkey_cipher);
- free(sealed_NVM);
- Crypto_symcrypto_freekey (&symkey);
-
- return status;
-}
-
-
-/* inbuf = null outbuf = sealed blob size, sealed blob.*/
-TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI_RESOURCE *myDMI,
- const buffer_t *inbuf,
- buffer_t *outbuf) {
-
- TPM_RESULT status = TPM_SUCCESS;
- symkey_t symkey;
- buffer_t state_cipher = NULL_BUF,
- symkey_clear = NULL_BUF,
- symkey_cipher = NULL_BUF;
- struct pack_buf_t symkey_cipher32, state_cipher32;
-
- UINT32 sealed_NVM_size;
- BYTE *sealed_NVM = NULL;
- long fh_size;
- int fh, stat_ret, i;
- struct stat file_stat;
- TPM_DIGEST sealedNVMHash;
-
- memset(&symkey, 0, sizeof(symkey_t));
-
- if (myDMI->NVMLocation == NULL) {
- vtpmlogerror(VTPM_LOG_VTPM, "Unable to load NVM because the file name
NULL.\n");
- status = TPM_AUTHFAIL;
- goto abort_egress;
- }
-
- //Read sealed blob off disk from NVMLocation
- fh = open(myDMI->NVMLocation, O_RDONLY);
- stat_ret = fstat(fh, &file_stat);
- if (stat_ret == 0)
- fh_size = file_stat.st_size;
- else {
- status = TPM_IOERROR;
- goto abort_egress;
- }
-
- sealed_NVM = (BYTE *) malloc(fh_size);
- if (read(fh, sealed_NVM, fh_size) != fh_size) {
- status = TPM_IOERROR;
- goto abort_egress;
- }
- close(fh);
-
- vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Load_NVMing[%ld]: 0x", fh_size);
- for (i=0; i< fh_size; i++)
- vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", sealed_NVM[i]);
- vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
-
- sealed_NVM_size = BSG_UnpackList(sealed_NVM, 2,
- BSG_TPM_SIZE32_DATA, &symkey_cipher32,
- BSG_TPM_SIZE32_DATA, &state_cipher32);
-
- TPMTRYRETURN( buffer_init_convert (&symkey_cipher,
- symkey_cipher32.size,
- symkey_cipher32.data) );
-
- TPMTRYRETURN( buffer_init_convert (&state_cipher,
- state_cipher32.size,
- state_cipher32.data) );
-
- Crypto_SHA1Full(sealed_NVM, sealed_NVM_size, (BYTE *) &sealedNVMHash);
-
- // Verify measurement of sealed blob.
- if (memcmp(&sealedNVMHash, &myDMI->NVM_measurement, sizeof(TPM_DIGEST)) ) {
- vtpmlogerror(VTPM_LOG_VTPM, "VTPM LoadNVM NVM measurement check
failed.\n");
- vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Correct hash: ");
- for (i=0; i< sizeof(TPM_DIGEST); i++)
- vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ",
((BYTE*)&myDMI->NVM_measurement)[i]);
- vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
-
- vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Measured hash: ");
- for (i=0; i< sizeof(TPM_DIGEST); i++)
- vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", ((BYTE*)&sealedNVMHash)[i]);
- vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
-
- status = TPM_AUTHFAIL;
- goto abort_egress;
- }
-
- // Decrypt Symmetric Key
- TPMTRYRETURN( VTSP_Unbind( myDMI->TCSContext,
- vtpm_globals->storageKeyHandle,
- &symkey_cipher,
- (const
TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
- &symkey_clear,
- &(vtpm_globals->keyAuth) ) );
-
- // create symmetric key using saved bits
- Crypto_symcrypto_initkey (&symkey, &symkey_clear);
-
- // Decrypt State
- TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (&symkey, &state_cipher,
outbuf) );
-
- goto egress;
-
- abort_egress:
- vtpmlogerror(VTPM_LOG_VTPM, "Failed to load NVM\n.");
-
- egress:
-
- buffer_free ( &state_cipher);
- buffer_free ( &symkey_clear);
- buffer_free ( &symkey_cipher);
- free( sealed_NVM );
- Crypto_symcrypto_freekey (&symkey);
-
- return status;
-}
-
-TPM_RESULT VTPM_SaveService(void) {
- TPM_RESULT status=TPM_SUCCESS;
- int fh, dmis=-1;
-
- BYTE *flat_global;
- int flat_global_size, bytes_written;
- UINT32 storageKeySize = buffer_len(&vtpm_globals->storageKeyWrap);
- struct pack_buf_t storage_key_pack = {storageKeySize,
vtpm_globals->storageKeyWrap.bytes};
-
- struct hashtable_itr *dmi_itr;
- VTPM_DMI_RESOURCE *dmi_res;
-
- UINT32 flat_global_full_size;
-
- // Global Values needing to be saved
- flat_global_full_size = 3*sizeof(TPM_DIGEST) + // Auths
- sizeof(UINT32) + // storagekeysize
- storageKeySize + // storage key
- hashtable_count(vtpm_globals->dmi_map) * // num DMIS
- (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)); // Per DMI info
-
-
- flat_global = (BYTE *) malloc( flat_global_full_size);
-
- flat_global_size = BSG_PackList(flat_global, 4,
- BSG_TPM_AUTHDATA,
&vtpm_globals->owner_usage_auth,
- BSG_TPM_AUTHDATA,
&vtpm_globals->srk_usage_auth,
- BSG_TPM_SECRET,
&vtpm_globals->storage_key_usage_auth,
- BSG_TPM_SIZE32_DATA, &storage_key_pack);
-
- // Per DMI values to be saved
- if (hashtable_count(vtpm_globals->dmi_map) > 0) {
-
- dmi_itr = hashtable_iterator(vtpm_globals->dmi_map);
- do {
- dmi_res = (VTPM_DMI_RESOURCE *) hashtable_iterator_value(dmi_itr);
- dmis++;
-
- // No need to save dmi0.
- if (dmi_res->dmi_id == 0)
- continue;
-
-
- flat_global_size += BSG_PackList( flat_global + flat_global_size, 3,
- BSG_TYPE_UINT32, &dmi_res->dmi_id,
- BSG_TPM_DIGEST,
&dmi_res->NVM_measurement,
- BSG_TPM_DIGEST,
&dmi_res->DMI_measurement);
-
- } while (hashtable_iterator_advance(dmi_itr));
- }
-
- //FIXME: Once we have a way to protect a TPM key, we should use it to
- // encrypt this blob. BUT, unless there is a way to ensure the key is
- // not used by other apps, this encryption is useless.
- fh = open(STATE_FILE, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
- if (fh == -1) {
- vtpmlogerror(VTPM_LOG_VTPM, "Unable to open %s file for write.\n",
STATE_FILE);
- status = TPM_IOERROR;
- goto abort_egress;
- }
-
- if ( (bytes_written = write(fh, flat_global, flat_global_size)) !=
flat_global_size ) {
- vtpmlogerror(VTPM_LOG_VTPM, "Failed to save service data. %d/%d bytes
written.\n", bytes_written, flat_global_size);
- status = TPM_IOERROR;
- goto abort_egress;
- }
- vtpm_globals->DMI_table_dirty = FALSE;
-
- goto egress;
-
- abort_egress:
- egress:
-
- free(flat_global);
- close(fh);
-
- vtpmloginfo(VTPM_LOG_VTPM, "Saved VTPM Service state (status = %d, dmis =
%d)\n", (int) status, dmis);
- return status;
-}
-
-TPM_RESULT VTPM_LoadService(void) {
-
- TPM_RESULT status=TPM_SUCCESS;
- int fh, stat_ret, dmis=0;
- long fh_size = 0, step_size;
- BYTE *flat_global=NULL;
- struct pack_buf_t storage_key_pack;
- UINT32 *dmi_id_key;
-
- VTPM_DMI_RESOURCE *dmi_res;
- struct stat file_stat;
-
- fh = open(STATE_FILE, O_RDONLY );
- stat_ret = fstat(fh, &file_stat);
- if (stat_ret == 0)
- fh_size = file_stat.st_size;
- else {
- status = TPM_IOERROR;
- goto abort_egress;
- }
-
- flat_global = (BYTE *) malloc(fh_size);
-
- if ((long) read(fh, flat_global, fh_size) != fh_size ) {
- status = TPM_IOERROR;
- goto abort_egress;
- }
-
- // Global Values needing to be saved
- step_size = BSG_UnpackList( flat_global, 4,
- BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
- BSG_TPM_AUTHDATA, &vtpm_globals->srk_usage_auth,
- BSG_TPM_SECRET,
&vtpm_globals->storage_key_usage_auth,
- BSG_TPM_SIZE32_DATA, &storage_key_pack);
-
- TPMTRYRETURN(buffer_init(&vtpm_globals->storageKeyWrap, 0, 0) );
- TPMTRYRETURN(buffer_append_raw(&vtpm_globals->storageKeyWrap,
storage_key_pack.size, storage_key_pack.data) );
-
- // Per DMI values to be saved
- while ( step_size < fh_size ){
- if (fh_size - step_size < (long) (sizeof(UINT32) + 2*sizeof(TPM_DIGEST))) {
- vtpmlogerror(VTPM_LOG_VTPM, "Encountered %ld extra bytes at end of
manager state.\n", fh_size-step_size);
- step_size = fh_size;
- } else {
- dmi_res = (VTPM_DMI_RESOURCE *) malloc(sizeof(VTPM_DMI_RESOURCE));
- dmis++;
-
- dmi_res->connected = FALSE;
-
- step_size += BSG_UnpackList(flat_global + step_size, 3,
- BSG_TYPE_UINT32, &dmi_res->dmi_id,
- BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
- BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
-
- // install into map
- dmi_id_key = (UINT32 *) malloc (sizeof(UINT32));
- *dmi_id_key = dmi_res->dmi_id;
- if (!hashtable_insert(vtpm_globals->dmi_map, dmi_id_key, dmi_res)) {
- status = TPM_FAIL;
- goto abort_egress;
- }
-
- }
-
- }
-
- goto egress;
-
- abort_egress:
- vtpmlogerror(VTPM_LOG_VTPM, "Failed to save service data\n");
- egress:
-
- if (flat_global)
- free(flat_global);
- close(fh);
-
- vtpmloginfo(VTPM_LOG_VTPM, "Previously saved state reloaded (status = %d,
dmis = %d).\n", (int) status, dmis);
- return status;
-}
+// ===================================================================
+//
+// 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.
+// ===================================================================
+//
+// securestorage.c
+//
+// Functions regarding securely storing DMI secrets.
+//
+// ==================================================================
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "tcg.h"
+#include "vtpm_manager.h"
+#include "vtpmpriv.h"
+#include "vtsp.h"
+#include "bsg.h"
+#include "crypto.h"
+#include "hashtable.h"
+#include "hashtable_itr.h"
+#include "buffer.h"
+#include "log.h"
+
+TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI_RESOURCE *myDMI,
+ const buffer_t *inbuf,
+ buffer_t *outbuf) {
+
+ TPM_RESULT status = TPM_SUCCESS;
+ symkey_t symkey;
+ buffer_t state_cipher = NULL_BUF,
+ symkey_cipher = NULL_BUF;
+ int fh;
+ long bytes_written;
+ BYTE *sealed_NVM=NULL;
+ UINT32 sealed_NVM_size, i;
+ struct pack_constbuf_t symkey_cipher32, state_cipher32;
+
+ vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Save_NVMing[%d]: 0x", buffer_len(inbuf));
+ for (i=0; i< buffer_len(inbuf); i++)
+ vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", inbuf->bytes[i]);
+ vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+
+ // Generate a sym key and encrypt state with it
+ TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_genkey (&symkey) );
+ TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_encrypt (&symkey, inbuf,
&state_cipher) );
+
+ // Encrypt symmetric key
+ TPMTRYRETURN( VTSP_Bind( &vtpm_globals->storageKey,
+ &symkey.key,
+ &symkey_cipher) );
+
+ // Create output blob: symkey_size + symkey_cipher + state_cipher_size +
state_cipher
+
+ symkey_cipher32.size = buffer_len(&symkey_cipher);
+ symkey_cipher32.data = symkey_cipher.bytes;
+
+ state_cipher32.size = buffer_len(&state_cipher);
+ state_cipher32.data = state_cipher.bytes;
+
+ sealed_NVM = (BYTE *) malloc( 2 * sizeof(UINT32) + symkey_cipher32.size +
state_cipher32.size);
+
+ sealed_NVM_size = BSG_PackList(sealed_NVM, 2,
+ BSG_TPM_SIZE32_DATA, &symkey_cipher32,
+ BSG_TPM_SIZE32_DATA, &state_cipher32);
+
+ // 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.
+ // TODO: Backup old file and try and recover that way.
+ fh = open(myDMI->NVMLocation, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
+ if ( (bytes_written = write(fh, sealed_NVM, sealed_NVM_size) ) != (long)
sealed_NVM_size) {
+ vtpmlogerror(VTPM_LOG_VTPM, "We just overwrote a DMI_NVM and failed to
finish. %ld/%ld bytes.\n", bytes_written, (long)sealed_NVM_size);
+ status = TPM_IOERROR;
+ goto abort_egress;
+ }
+ close(fh);
+
+ Crypto_SHA1Full (sealed_NVM, sealed_NVM_size, (BYTE *)
&myDMI->NVM_measurement);
+
+ vtpmloginfo(VTPM_LOG_VTPM, "Saved %d bytes of E(symkey) + %d bytes of
E(NVM)\n", buffer_len(&symkey_cipher), buffer_len(&state_cipher));
+ goto egress;
+
+ abort_egress:
+ vtpmlogerror(VTPM_LOG_VTPM, "Failed to load NVM\n.");
+
+ egress:
+
+ buffer_free ( &state_cipher);
+ buffer_free ( &symkey_cipher);
+ free(sealed_NVM);
+ Crypto_symcrypto_freekey (&symkey);
+
+ return status;
+}
+
+
+/* inbuf = null outbuf = sealed blob size, sealed blob.*/
+TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI_RESOURCE *myDMI,
+ const buffer_t *inbuf,
+ buffer_t *outbuf) {
+
+ TPM_RESULT status = TPM_SUCCESS;
+ symkey_t symkey;
+ buffer_t state_cipher = NULL_BUF,
+ symkey_clear = NULL_BUF,
+ symkey_cipher = NULL_BUF;
+ struct pack_buf_t symkey_cipher32, state_cipher32;
+
+ UINT32 sealed_NVM_size;
+ BYTE *sealed_NVM = NULL;
+ long fh_size;
+ int fh, stat_ret, i;
+ struct stat file_stat;
+ TPM_DIGEST sealedNVMHash;
+
+ memset(&symkey, 0, sizeof(symkey_t));
+
+ if (myDMI->NVMLocation == NULL) {
+ vtpmlogerror(VTPM_LOG_VTPM, "Unable to load NVM because the file name
NULL.\n");
+ status = TPM_AUTHFAIL;
+ goto abort_egress;
+ }
+
+ //Read sealed blob off disk from NVMLocation
+ fh = open(myDMI->NVMLocation, O_RDONLY);
+ stat_ret = fstat(fh, &file_stat);
+ if (stat_ret == 0)
+ fh_size = file_stat.st_size;
+ else {
+ status = TPM_IOERROR;
+ goto abort_egress;
+ }
+
+ sealed_NVM = (BYTE *) malloc(fh_size);
+ if (read(fh, sealed_NVM, fh_size) != fh_size) {
+ status = TPM_IOERROR;
+ goto abort_egress;
+ }
+ close(fh);
+
+ vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Load_NVMing[%ld]: 0x", fh_size);
+ for (i=0; i< fh_size; i++)
+ vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", sealed_NVM[i]);
+ vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+
+ sealed_NVM_size = BSG_UnpackList(sealed_NVM, 2,
+ BSG_TPM_SIZE32_DATA, &symkey_cipher32,
+ BSG_TPM_SIZE32_DATA, &state_cipher32);
+
+ TPMTRYRETURN( buffer_init_convert (&symkey_cipher,
+ symkey_cipher32.size,
+ symkey_cipher32.data) );
+
+ TPMTRYRETURN( buffer_init_convert (&state_cipher,
+ state_cipher32.size,
+ state_cipher32.data) );
+
+ Crypto_SHA1Full(sealed_NVM, sealed_NVM_size, (BYTE *) &sealedNVMHash);
+
+ // Verify measurement of sealed blob.
+ if (memcmp(&sealedNVMHash, &myDMI->NVM_measurement, sizeof(TPM_DIGEST)) ) {
+ vtpmlogerror(VTPM_LOG_VTPM, "VTPM LoadNVM NVM measurement check
failed.\n");
+ vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Correct hash: ");
+ for (i=0; i< sizeof(TPM_DIGEST); i++)
+ vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ",
((BYTE*)&myDMI->NVM_measurement)[i]);
+ vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+
+ vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Measured hash: ");
+ for (i=0; i< sizeof(TPM_DIGEST); i++)
+ vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", ((BYTE*)&sealedNVMHash)[i]);
+ vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+
+ status = TPM_AUTHFAIL;
+ goto abort_egress;
+ }
+
+ // Decrypt Symmetric Key
+ TPMTRYRETURN( VTSP_Unbind( myDMI->TCSContext,
+ vtpm_globals->storageKeyHandle,
+ &symkey_cipher,
+ (const
TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
+ &symkey_clear,
+ &(vtpm_globals->keyAuth) ) );
+
+ // create symmetric key using saved bits
+ Crypto_symcrypto_initkey (&symkey, &symkey_clear);
+
+ // Decrypt State
+ TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (&symkey, &state_cipher,
outbuf) );
+
+ goto egress;
+
+ abort_egress:
+ vtpmlogerror(VTPM_LOG_VTPM, "Failed to load NVM\n.");
+
+ egress:
+
+ buffer_free ( &state_cipher);
+ buffer_free ( &symkey_clear);
+ buffer_free ( &symkey_cipher);
+ free( sealed_NVM );
+ Crypto_symcrypto_freekey (&symkey);
+
+ return status;
+}
+
+TPM_RESULT VTPM_SaveService(void) {
+ TPM_RESULT status=TPM_SUCCESS;
+ int fh, dmis=-1;
+
+ BYTE *flat_global;
+ int flat_global_size, bytes_written;
+ UINT32 storageKeySize = buffer_len(&vtpm_globals->storageKeyWrap);
+ struct pack_buf_t storage_key_pack = {storageKeySize,
vtpm_globals->storageKeyWrap.bytes};
+
+ struct hashtable_itr *dmi_itr;
+ VTPM_DMI_RESOURCE *dmi_res;
+
+ UINT32 flat_global_full_size;
+
+ // Global Values needing to be saved
+ flat_global_full_size = 3*sizeof(TPM_DIGEST) + // Auths
+ sizeof(UINT32) + // storagekeysize
+ storageKeySize + // storage key
+ hashtable_count(vtpm_globals->dmi_map) * // num DMIS
+ (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)); // Per DMI info
+
+
+ flat_global = (BYTE *) malloc( flat_global_full_size);
+
+ flat_global_size = BSG_PackList(flat_global, 4,
+ BSG_TPM_AUTHDATA,
&vtpm_globals->owner_usage_auth,
+ BSG_TPM_AUTHDATA,
&vtpm_globals->srk_usage_auth,
+ BSG_TPM_SECRET,
&vtpm_globals->storage_key_usage_auth,
+ BSG_TPM_SIZE32_DATA, &storage_key_pack);
+
+ // Per DMI values to be saved
+ if (hashtable_count(vtpm_globals->dmi_map) > 0) {
+
+ dmi_itr = hashtable_iterator(vtpm_globals->dmi_map);
+ do {
+ dmi_res = (VTPM_DMI_RESOURCE *) hashtable_iterator_value(dmi_itr);
+ dmis++;
+
+ // No need to save dmi0.
+ if (dmi_res->dmi_id == 0)
+ continue;
+
+
+ flat_global_size += BSG_PackList( flat_global + flat_global_size, 3,
+ BSG_TYPE_UINT32, &dmi_res->dmi_id,
+ BSG_TPM_DIGEST,
&dmi_res->NVM_measurement,
+ BSG_TPM_DIGEST,
&dmi_res->DMI_measurement);
+
+ } while (hashtable_iterator_advance(dmi_itr));
+ }
+
+ //FIXME: Once we have a way to protect a TPM key, we should use it to
+ // encrypt this blob. BUT, unless there is a way to ensure the key is
+ // not used by other apps, this encryption is useless.
+ fh = open(STATE_FILE, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
+ if (fh == -1) {
+ vtpmlogerror(VTPM_LOG_VTPM, "Unable to open %s file for write.\n",
STATE_FILE);
+ status = TPM_IOERROR;
+ goto abort_egress;
+ }
+
+ if ( (bytes_written = write(fh, flat_global, flat_global_size)) !=
flat_global_size ) {
+ vtpmlogerror(VTPM_LOG_VTPM, "Failed to save service data. %d/%d bytes
written.\n", bytes_written, flat_global_size);
+ status = TPM_IOERROR;
+ goto abort_egress;
+ }
+ vtpm_globals->DMI_table_dirty = FALSE;
+
+ goto egress;
+
+ abort_egress:
+ egress:
+
+ free(flat_global);
+ close(fh);
+
+ vtpmloginfo(VTPM_LOG_VTPM, "Saved VTPM Service state (status = %d, dmis =
%d)\n", (int) status, dmis);
+ return status;
+}
+
+TPM_RESULT VTPM_LoadService(void) {
+
+ TPM_RESULT status=TPM_SUCCESS;
+ int fh, stat_ret, dmis=0;
+ long fh_size = 0, step_size;
+ BYTE *flat_global=NULL;
+ struct pack_buf_t storage_key_pack;
+ UINT32 *dmi_id_key;
+
+ VTPM_DMI_RESOURCE *dmi_res;
+ struct stat file_stat;
+
+ fh = open(STATE_FILE, O_RDONLY );
+ stat_ret = fstat(fh, &file_stat);
+ if (stat_ret == 0)
+ fh_size = file_stat.st_size;
+ else {
+ status = TPM_IOERROR;
+ goto abort_egress;
+ }
+
+ flat_global = (BYTE *) malloc(fh_size);
+
+ if ((long) read(fh, flat_global, fh_size) != fh_size ) {
+ status = TPM_IOERROR;
+ goto abort_egress;
+ }
+
+ // Global Values needing to be saved
+ step_size = BSG_UnpackList( flat_global, 4,
+ BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
+ BSG_TPM_AUTHDATA, &vtpm_globals->srk_usage_auth,
+ BSG_TPM_SECRET,
&vtpm_globals->storage_key_usage_auth,
+ BSG_TPM_SIZE32_DATA, &storage_key_pack);
+
+ TPMTRYRETURN(buffer_init(&vtpm_globals->storageKeyWrap, 0, 0) );
+ TPMTRYRETURN(buffer_append_raw(&vtpm_globals->storageKeyWrap,
storage_key_pack.size, storage_key_pack.data) );
+
+ // Per DMI values to be saved
+ while ( step_size < fh_size ){
+ if (fh_size - step_size < (long) (sizeof(UINT32) + 2*sizeof(TPM_DIGEST))) {
+ vtpmlogerror(VTPM_LOG_VTPM, "Encountered %ld extra bytes at end of
manager state.\n", fh_size-step_size);
+ step_size = fh_size;
+ } else {
+ dmi_res = (VTPM_DMI_RESOURCE *) malloc(sizeof(VTPM_DMI_RESOURCE));
+ dmis++;
+
+ dmi_res->connected = FALSE;
+
+ step_size += BSG_UnpackList(flat_global + step_size, 3,
+ BSG_TYPE_UINT32, &dmi_res->dmi_id,
+ BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
+ BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
+
+ // install into map
+ dmi_id_key = (UINT32 *) malloc (sizeof(UINT32));
+ *dmi_id_key = dmi_res->dmi_id;
+ if (!hashtable_insert(vtpm_globals->dmi_map, dmi_id_key, dmi_res)) {
+ status = TPM_FAIL;
+ goto abort_egress;
+ }
+
+ }
+
+ }
+
+ vtpmloginfo(VTPM_LOG_VTPM, "Loaded saved state (dmis = %d).\n", dmis);
+ goto egress;
+
+ abort_egress:
+ vtpmlogerror(VTPM_LOG_VTPM, "Failed to load service data with error = %s\n",
tpm_get_error_name(status));
+ egress:
+
+ if (flat_global)
+ free(flat_global);
+ close(fh);
+
+ return status;
+}
diff -r 3ef86b208f9b -r c0796e18b6a4 tools/vtpm_manager/manager/vtpm_manager.c
--- a/tools/vtpm_manager/manager/vtpm_manager.c Tue Sep 20 09:05:03 2005
+++ b/tools/vtpm_manager/manager/vtpm_manager.c Tue Sep 20 09:08:26 2005
@@ -1,735 +1,811 @@
-// ===================================================================
-//
-// 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.c
-//
-// This file will house the main logic of the VTPM Manager
-//
-// ==================================================================
-
-#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"
-#include "bsg.h"
-#include "hashtable.h"
-#include "hashtable_itr.h"
-
-#include "log.h"
-#include "buffer.h"
-
-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
-
-// --------------------------- Static Auths --------------------------
-#ifdef USE_FIXED_SRK_AUTH
-
-static BYTE FIXED_SRK_AUTH[20] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff};
-
-static BYTE FIXED_EK_AUTH[20] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff};
-
-#endif
-
-// -------------------------- Hash table functions --------------------
-
-static unsigned int hashfunc32(void *ky) {
- return (* (UINT32 *) ky);
-}
-
-static int equals32(void *k1, void *k2) {
- return (*(UINT32 *) k1 == *(UINT32 *) k2);
-}
-
-// --------------------------- Functions ------------------------------
-
-TPM_RESULT VTPM_Create_Service(){
-
- TPM_RESULT status = TPM_SUCCESS;
-
- // Generate Auth's for SRK & Owner
-#ifdef USE_FIXED_SRK_AUTH
- memcpy(vtpm_globals->owner_usage_auth, FIXED_SRK_AUTH, sizeof(TPM_AUTHDATA));
- memcpy(vtpm_globals->srk_usage_auth, FIXED_EK_AUTH, sizeof(TPM_AUTHDATA));
-#else
- Crypto_GetRandom(vtpm_globals->owner_usage_auth, sizeof(TPM_AUTHDATA) );
- Crypto_GetRandom(vtpm_globals->srk_usage_auth, sizeof(TPM_AUTHDATA) );
-#endif
-
- // Take Owership of TPM
- CRYPTO_INFO ek_cryptoInfo;
-
- vtpmloginfo(VTPM_LOG_VTPM, "Attempting Pubek Read. NOTE: Failure is ok.\n");
- status = VTSP_ReadPubek(vtpm_globals->manager_tcs_handle, &ek_cryptoInfo);
-
- // If we can read PubEK then there is no owner and we should take it.
- if (status == TPM_SUCCESS) {
- TPMTRYRETURN(VTSP_TakeOwnership(vtpm_globals->manager_tcs_handle,
- (const
TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth,
- (const
TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
- &ek_cryptoInfo,
- &vtpm_globals->keyAuth));
-
- TPMTRYRETURN(VTSP_DisablePubekRead(vtpm_globals->manager_tcs_handle,
- (const
TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth,
- &vtpm_globals->keyAuth));
- }
-
- // Generate storage key's auth
- Crypto_GetRandom( &vtpm_globals->storage_key_usage_auth,
- sizeof(TPM_AUTHDATA) );
-
- TCS_AUTH osap;
- TPM_AUTHDATA sharedsecret;
-
- TPMTRYRETURN( VTSP_OSAP(vtpm_globals->manager_tcs_handle,
- TPM_ET_SRK,
- 0,
- (const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
- &sharedsecret,
- &osap) );
-
- TPMTRYRETURN( VTSP_CreateWrapKey( vtpm_globals->manager_tcs_handle,
- TPM_KEY_BIND,
- (const
TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
- TPM_SRK_KEYHANDLE,
- (const TPM_AUTHDATA*)&sharedsecret,
- &vtpm_globals->storageKeyWrap,
- &osap) );
-
- vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
-
- goto egress;
-
- abort_egress:
- exit(1);
-
- egress:
- vtpmloginfo(VTPM_LOG_VTPM, "New VTPM Service initialized (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, dmi_cmd_size;
- BYTE *cmd_header, *in_param, *out_message, *dmi_cmd;
- 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
- 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
-
- // TODO: Reinsert ifdefs to enable support for MULTI-VM
-
- 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, *rx_fh;
-
-#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
-
-#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 ) ){
- *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 ) ){
- *ret_value = TPM_FAIL;
- pthread_exit(ret_value);
- }
- } else
- close(fh);
-
- }
-#endif
-
- while(1) {
-
- 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");
-
-
- if (*rx_fh < 0) {
- if (threadType == BE_LISTENER_THREAD)
-#ifdef DUMMY_BACKEND
- *rx_fh = open("/tmp/in.fifo", O_RDWR);
-#else
- *rx_fh = open(VTPM_BE_DEV, O_RDWR);
-#endif
- else // DMI Listener
- *rx_fh = open(VTPM_RX_FIFO, O_RDWR);
-
- }
-
- if (*rx_fh < 0) {
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't open inbound fh.\n");
-#ifdef VTPM_MULTI_VM
- return TPM_IOERROR;
-#else
- *ret_value = TPM_IOERROR;
- pthread_exit(ret_value);
-#endif
- }
-
- 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;
- }
-
- BSG_UnpackList(cmd_header, 4,
- BSG_TYPE_UINT32, &dmi,
- BSG_TPM_TAG, &tag,
- BSG_TYPE_UINT32, &in_param_size,
- BSG_TPM_COMMAND_CODE, &ord );
-
- // 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 BE. 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");
- }
-
- if ((threadType != BE_LISTENER_THREAD) && (dmi == 0)) {
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempt to access dom0 commands from
DMI interface. Aborting...\n");
- goto abort_command;
- }
-
- 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;
- }
-
- 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.
-
- 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
-
- if (threadType == BE_LISTENER_THREAD) {
- if (dmi == 0) {
- // This usually indicates a FE/BE driver.
- 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");
-
- if (dmi_res->guest_tx_fh < 0)
- dmi_res->guest_tx_fh = open(dmi_res->guest_tx_fname, O_WRONLY |
O_NONBLOCK);
-
- 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;
- }
-
- //Note: Send message + dmi_id
- 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);
-
- if (vtpm_globals->guest_rx_fh < 0)
- vtpm_globals->guest_rx_fh = open(GUEST_RX_FIFO, O_RDONLY);
-
- 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;
- }
-
- 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;
- }
-
- BSG_UnpackList(cmd_header, 4,
- BSG_TYPE_UINT32, &dmi,
- BSG_TPM_TAG, &tag,
- BSG_TYPE_UINT32, &in_param_size,
- BSG_TPM_COMMAND_CODE, &status );
-
- // 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
-#ifdef VTPM_MULTI_VM
- 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 (UINT32 q=0; q<cmd_size; q++)
- vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[q]);
-
- vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
-
- status = TPM_FAIL;
-#else
-
-#endif
- } // end else for if BE Listener
- } // end else for is VTPM Command
-
- // Send response to Backend
- if (*tx_fh < 0) {
- 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);
- }
-
- 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
- }
-
- abort_with_error:
- // 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;
- }
-
- 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 status = TPM_FAIL;
- BYTE *randomsead;
- UINT32 randomsize;
-
- if ((vtpm_globals = (VTPM_GLOBALS *) malloc(sizeof(VTPM_GLOBALS))) == NULL){
- status = TPM_FAIL;
- 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;
-#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;
-
- TPMTRYRETURN(TCS_create());
-
- // Create TCS Context for service
- TPMTRYRETURN( TCS_OpenContext(&vtpm_globals->manager_tcs_handle ) );
-
- TPMTRYRETURN( TCSP_GetRandom(vtpm_globals->manager_tcs_handle,
-
&randomsize,
-
&randomsead));
-
- Crypto_Init(randomsead, randomsize);
- TPMTRYRETURN( TCS_FreeMemory (vtpm_globals->manager_tcs_handle,
randomsead));
-
- // Create OIAP session for service's authorized commands
- TPMTRYRETURN( VTSP_OIAP( vtpm_globals->manager_tcs_handle,
- &vtpm_globals->keyAuth) );
- vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
-
- // If failed, create new Service.
- if (VTPM_LoadService() != TPM_SUCCESS)
- TPMTRYRETURN( VTPM_Create_Service() );
-
-
- //Load Storage Key
- TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
- TPM_SRK_KEYHANDLE,
- &vtpm_globals->storageKeyWrap,
- (const
TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
- &vtpm_globals->storageKeyHandle,
- &vtpm_globals->keyAuth,
- &vtpm_globals->storageKey) );
-
- // Create entry for Dom0 for control messages
- TPMTRYRETURN( VTPM_Handle_New_DMI(NULL) );
-
- // --------------------- Command handlers ---------------------------
-
- goto egress;
-
- abort_egress:
- egress:
-
- return(status);
-}
-
-void VTPM_Stop_Service() {
- VTPM_DMI_RESOURCE *dmi_res;
- struct hashtable_itr *dmi_itr;
-
- // Close all the TCS contexts. TCS should evict keys based on this
- if (hashtable_count(vtpm_globals->dmi_map) > 0) {
- dmi_itr = hashtable_iterator(vtpm_globals->dmi_map);
- do {
- dmi_res = (VTPM_DMI_RESOURCE *) hashtable_iterator_value(dmi_itr);
- if (dmi_res->connected)
- if (close_dmi( dmi_res ) != TPM_SUCCESS)
- vtpmlogerror(VTPM_LOG_VTPM, "Failed to
close dmi %d properly.\n", dmi_res->dmi_id);
-
- } while (hashtable_iterator_advance(dmi_itr));
- free (dmi_itr);
- }
-
-
- TCS_CloseContext(vtpm_globals->manager_tcs_handle);
-
- if ( (vtpm_globals->DMI_table_dirty) &&
- (VTPM_SaveService() != TPM_SUCCESS) )
- vtpmlogerror(VTPM_LOG_VTPM, "Unable to save manager data.\n");
-
- 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");
-}
+// ===================================================================
+//
+// 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.c
+//
+// This file will house the main logic of the VTPM Manager
+//
+// ==================================================================
+
+#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"
+#include "bsg.h"
+#include "hashtable.h"
+#include "hashtable_itr.h"
+
+#include "log.h"
+#include "buffer.h"
+
+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 --------------------------
+#ifdef WELL_KNOWN_SRK_AUTH
+static BYTE FIXED_SRK_AUTH[20] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff};
+#endif
+
+#ifdef WELL_KNOWN_OWNER_AUTH
+static BYTE FIXED_OWNER_AUTH[20] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff};
+#endif
+
+// -------------------------- Hash table functions --------------------
+
+static unsigned int hashfunc32(void *ky) {
+ return (* (UINT32 *) ky);
+}
+
+static int equals32(void *k1, void *k2) {
+ return (*(UINT32 *) k1 == *(UINT32 *) k2);
+}
+
+// --------------------------- Functions ------------------------------
+
+TPM_RESULT VTPM_Create_Service(){
+
+ TPM_RESULT status = TPM_SUCCESS;
+
+ // Generate Auth's for SRK & Owner
+#ifdef WELL_KNOWN_SRK_AUTH
+ memcpy(vtpm_globals->srk_usage_auth, FIXED_SRK_AUTH, sizeof(TPM_AUTHDATA));
+#else
+ Crypto_GetRandom(vtpm_globals->srk_usage_auth, sizeof(TPM_AUTHDATA) );
+#endif
+
+#ifdef WELL_KNOWN_OWNER_AUTH
+ memcpy(vtpm_globals->owner_usage_auth, FIXED_OWNER_AUTH,
sizeof(TPM_AUTHDATA));
+#else
+ Crypto_GetRandom(vtpm_globals->owner_usage_auth, sizeof(TPM_AUTHDATA) );
+#endif
+
+ // Take Owership of TPM
+ CRYPTO_INFO ek_cryptoInfo;
+
+ vtpmloginfo(VTPM_LOG_VTPM, "Attempting Pubek Read. NOTE: Failure is ok.\n");
+ status = VTSP_ReadPubek(vtpm_globals->manager_tcs_handle, &ek_cryptoInfo);
+
+ // If we can read PubEK then there is no owner and we should take it.
+ if (status == TPM_SUCCESS) {
+ TPMTRYRETURN(VTSP_TakeOwnership(vtpm_globals->manager_tcs_handle,
+ (const
TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth,
+ (const
TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
+ &ek_cryptoInfo,
+ &vtpm_globals->keyAuth));
+
+ TPMTRYRETURN(VTSP_DisablePubekRead(vtpm_globals->manager_tcs_handle,
+ (const
TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth,
+ &vtpm_globals->keyAuth));
+ }
+
+ // Generate storage key's auth
+ Crypto_GetRandom( &vtpm_globals->storage_key_usage_auth,
+ sizeof(TPM_AUTHDATA) );
+
+ TCS_AUTH osap;
+ TPM_AUTHDATA sharedsecret;
+
+ TPMTRYRETURN( VTSP_OSAP(vtpm_globals->manager_tcs_handle,
+ TPM_ET_SRK,
+ 0,
+ (const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
+ &sharedsecret,
+ &osap) );
+
+ TPMTRYRETURN( VTSP_CreateWrapKey( vtpm_globals->manager_tcs_handle,
+ TPM_KEY_BIND,
+ (const
TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
+ TPM_SRK_KEYHANDLE,
+ (const TPM_AUTHDATA*)&sharedsecret,
+ &vtpm_globals->storageKeyWrap,
+ &osap) );
+
+ vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
+
+ goto egress;
+
+ abort_egress:
+ exit(1);
+
+ egress:
+ vtpmloginfo(VTPM_LOG_VTPM, "Finished initialized new VTPM service (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.
+ if (*rx_fh < 0) {
+#ifdef VTPM_MULTI_VM
+ *rx_fh = open(VTPM_BE_DEV, O_RDWR);
+#else
+ if (threadType == BE_LISTENER_THREAD)
+ #ifdef DUMMY_BACKEND
+ *rx_fh = open("/tmp/in.fifo", O_RDWR);
+ #else
+ *rx_fh = open(VTPM_BE_DEV, O_RDWR);
+ #endif
+ else // DMI Listener
+ *rx_fh = open(VTPM_RX_FIFO, O_RDWR);
+#endif
+ }
+
+ // Respond to failures to open rx_fh
+ if (*rx_fh < 0) {
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't open inbound fh.\n");
+#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 status = TPM_FAIL;
+ BYTE *randomsead;
+ UINT32 randomsize;
+
+ if ((vtpm_globals = (VTPM_GLOBALS *) malloc(sizeof(VTPM_GLOBALS))) == NULL){
+ status = TPM_FAIL;
+ 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;
+#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;
+
+ TPMTRYRETURN(TCS_create());
+
+ // Create TCS Context for service
+ TPMTRYRETURN( TCS_OpenContext(&vtpm_globals->manager_tcs_handle ) );
+
+ TPMTRYRETURN( TCSP_GetRandom(vtpm_globals->manager_tcs_handle,
+ &randomsize,
+ &randomsead));
+
+ Crypto_Init(randomsead, randomsize);
+ TPMTRYRETURN( TCS_FreeMemory (vtpm_globals->manager_tcs_handle,
randomsead));
+
+ // Create OIAP session for service's authorized commands
+ TPMTRYRETURN( VTSP_OIAP( vtpm_globals->manager_tcs_handle,
+ &vtpm_globals->keyAuth) );
+ vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
+
+ // If failed, create new Service.
+ if (VTPM_LoadService() != TPM_SUCCESS)
+ TPMTRYRETURN( VTPM_Create_Service() );
+
+ //Load Storage Key
+ TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
+ TPM_SRK_KEYHANDLE,
+ &vtpm_globals->storageKeyWrap,
+ (const
TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
+ &vtpm_globals->storageKeyHandle,
+ &vtpm_globals->keyAuth,
+ &vtpm_globals->storageKey) );
+
+ // Create entry for Dom0 for control messages
+ TPMTRYRETURN( VTPM_Handle_New_DMI(NULL) );
+
+ // --------------------- Command handlers ---------------------------
+
+ goto egress;
+
+ abort_egress:
+ egress:
+
+ return(status);
+}
+
+void VTPM_Stop_Service() {
+ VTPM_DMI_RESOURCE *dmi_res;
+ struct hashtable_itr *dmi_itr;
+
+ // Close all the TCS contexts. TCS should evict keys based on this
+ if (hashtable_count(vtpm_globals->dmi_map) > 0) {
+ dmi_itr = hashtable_iterator(vtpm_globals->dmi_map);
+ do {
+ dmi_res = (VTPM_DMI_RESOURCE *) hashtable_iterator_value(dmi_itr);
+ if (dmi_res->connected)
+ close_dmi( dmi_res ); // Not really interested in return code
+
+ } while (hashtable_iterator_advance(dmi_itr));
+ free (dmi_itr);
+ }
+
+
+ TCS_CloseContext(vtpm_globals->manager_tcs_handle);
+
+ if ( (vtpm_globals->DMI_table_dirty) &&
+ (VTPM_SaveService() != TPM_SUCCESS) )
+ vtpmlogerror(VTPM_LOG_VTPM, "Unable to save manager data.\n");
+
+ hashtable_destroy(vtpm_globals->dmi_map, 1);
+ free(vtpm_globals);
+
+ close(vtpm_globals->be_fh);
+ Crypto_Exit();
+
+ vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager stopped.\n");
+}
diff -r 3ef86b208f9b -r c0796e18b6a4 tools/vtpm_manager/manager/vtpmpriv.h
--- a/tools/vtpm_manager/manager/vtpmpriv.h Tue Sep 20 09:05:03 2005
+++ b/tools/vtpm_manager/manager/vtpmpriv.h Tue Sep 20 09:08:26 2005
@@ -47,8 +47,8 @@
#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
+#define VTPM_BE_DEV "/dev/vtpm0"
+#define VTPM_CTL_DM 0
#ifndef VTPM_MUTLI_VM
#include <sys/types.h>
diff -r 3ef86b208f9b -r c0796e18b6a4 tools/vtpm_manager/tcs/Makefile
--- a/tools/vtpm_manager/tcs/Makefile Tue Sep 20 09:05:03 2005
+++ b/tools/vtpm_manager/tcs/Makefile Tue Sep 20 09:08:26 2005
@@ -13,6 +13,7 @@
rm -f *.a *.so *.o *.rpm $(DEP_FILES)
mrproper: clean
+ rm -f *~
$(BIN): $(OBJS)
$(AR) rcs $(BIN) $(OBJS)
diff -r 3ef86b208f9b -r c0796e18b6a4 tools/vtpm_manager/tcs/contextmgr.c
--- a/tools/vtpm_manager/tcs/contextmgr.c Tue Sep 20 09:05:03 2005
+++ b/tools/vtpm_manager/tcs/contextmgr.c Tue Sep 20 09:08:26 2005
@@ -43,6 +43,7 @@
#include "tcs.h"
#include "contextmgr.h"
#include "log.h"
+#include "hashtable.h"
BYTE* AddMemBlock(CONTEXT_HANDLE* pContextHandle, // in
int BlockSize) { // in
@@ -131,12 +132,14 @@
return bFound;
}
-BOOL AddHandleToList(CONTEXT_HANDLE* pContextHandle, // in
+BOOL AddHandleToList(TCS_CONTEXT_HANDLE hContext, // in
TPM_RESOURCE_TYPE type, // in
TPM_HANDLE handle) { // in
HANDLE_LIST* pNewHandle = NULL;
-
+
vtpmloginfo(VTPM_LOG_TCS_DEEP, "Adding Handle to list\n");
+ CONTEXT_HANDLE* pContextHandle = LookupContext(hContext);
+
if (pContextHandle == NULL)
return 0;
@@ -154,11 +157,13 @@
return 1;
}
-BOOL DeleteHandleFromList( CONTEXT_HANDLE* pContextHandle, // in
+BOOL DeleteHandleFromList( TCS_CONTEXT_HANDLE hContext, // in
TPM_HANDLE handle) { // in
+ CONTEXT_HANDLE* pContextHandle = LookupContext(hContext);
+
HANDLE_LIST *pCurrentHandle = pContextHandle->pHandleList,
- *pLastHandle = pCurrentHandle;
+ *pLastHandle = pCurrentHandle;
vtpmloginfo(VTPM_LOG_TCS_DEEP, "Deleting Handle from list\n");
@@ -202,10 +207,10 @@
switch (pCurrentHandle->type) {
case TPM_RT_KEY:
- returncode = returncode && !TCSP_EvictKey((TCS_CONTEXT_HANDLE)
pContextHandle, pCurrentHandle->handle);
+ returncode = returncode && !TCSP_EvictKey(pContextHandle->handle,
pCurrentHandle->handle);
break;
case TPM_RT_AUTH:
- returncode = returncode && !TCSP_TerminateHandle((TCS_CONTEXT_HANDLE)
pContextHandle, pCurrentHandle->handle);
+ returncode = returncode && !TCSP_TerminateHandle(pContextHandle->handle,
pCurrentHandle->handle);
break;
default:
returncode = FALSE;
diff -r 3ef86b208f9b -r c0796e18b6a4 tools/vtpm_manager/tcs/contextmgr.h
--- a/tools/vtpm_manager/tcs/contextmgr.h Tue Sep 20 09:05:03 2005
+++ b/tools/vtpm_manager/tcs/contextmgr.h Tue Sep 20 09:08:26 2005
@@ -57,6 +57,7 @@
} HANDLE_LIST;
typedef struct context_handle {
+ TCS_CONTEXT_HANDLE handle;
int nBlockCount;
BLOCK* pTopBlock;
HANDLE_LIST* pHandleList;
@@ -69,11 +70,11 @@
BYTE* pTCPA_BYTEs); // in
-BOOL AddHandleToList( CONTEXT_HANDLE* pContextHandle, // in
+BOOL AddHandleToList( TCS_CONTEXT_HANDLE hContext, // in
TPM_RESOURCE_TYPE type, // in
TPM_HANDLE handle); // in
-BOOL DeleteHandleFromList( CONTEXT_HANDLE* pContextHandle, // in
+BOOL DeleteHandleFromList( TCS_CONTEXT_HANDLE hContext, // in
TPM_HANDLE handle); // in
BOOL FreeHandleList( CONTEXT_HANDLE* pContextHandle); // in
diff -r 3ef86b208f9b -r c0796e18b6a4 tools/vtpm_manager/tcs/tcs.c
--- a/tools/vtpm_manager/tcs/tcs.c Tue Sep 20 09:05:03 2005
+++ b/tools/vtpm_manager/tcs/tcs.c Tue Sep 20 09:08:26 2005
@@ -47,9 +47,10 @@
#include "contextmgr.h"
#include "tpmddl.h"
#include "log.h"
+#include "hashtable.h"
+#include "hashtable_itr.h"
// Static Global Vars for the TCS
-static BOOL TCS_m_bConnected;
static int TCS_m_nCount = 0;
#define TCPA_MAX_BUFFER_LENGTH 0x2000
@@ -57,6 +58,21 @@
static BYTE InBuf [TCPA_MAX_BUFFER_LENGTH];
static BYTE OutBuf[TCPA_MAX_BUFFER_LENGTH];
+struct hashtable *context_ht;
+
+// -------------------------- Hash table functions --------------------
+
+static unsigned int hashfunc32(void *ky) {
+ return (* (UINT32 *) ky);
+}
+
+static int equals32(void *k1, void *k2) {
+ return (*(UINT32 *) k1 == *(UINT32 *) k2);
+}
+
+CONTEXT_HANDLE *LookupContext( TCS_CONTEXT_HANDLE hContext) {
+ return( (CONTEXT_HANDLE *) hashtable_search(context_ht, &hContext) );
+}
//
---------------------------------------------------------------------------------
// Initialization/Uninitialization SubComponent API
@@ -64,34 +80,50 @@
TPM_RESULT TCS_create() {
TDDL_RESULT hRes = TDDL_E_FAIL;
TPM_RESULT result = TPM_FAIL;
- TCS_m_bConnected = FALSE;
if (TCS_m_nCount == 0) {
vtpmloginfo(VTPM_LOG_TCS, "Constructing new TCS:\n");
hRes = TDDL_Open();
-
- if (hRes == TDDL_SUCCESS) {
- TCS_m_bConnected = TRUE;
+
+ context_ht = create_hashtable(10, hashfunc32, equals32);
+
+ if ((hRes == TDDL_SUCCESS) && (context_ht != NULL)) {
result = TPM_SUCCESS;
+ TCS_m_nCount++;
+ } else {
+ result = TPM_IOERROR;
+ hashtable_destroy(context_ht, 1);
}
} else
- TCS_m_bConnected = TRUE;
-
- TCS_m_nCount++;
-
+ TCS_m_nCount++;
+
return(result);
}
void TCS_destroy()
{
- // FIXME: Should iterate through all open contexts and close them.
TCS_m_nCount--;
- if (TCS_m_bConnected == TRUE && TCS_m_nCount == 0) {
+ if (TCS_m_nCount == 0) {
vtpmloginfo(VTPM_LOG_TCS, "Destructing TCS:\n");
TDDL_Close();
- TCS_m_bConnected = FALSE;
+
+ struct hashtable_itr *context_itr;
+ TCS_CONTEXT_HANDLE *hContext;
+
+ // Close all the TCS contexts. TCS should evict keys based on this
+ if (hashtable_count(context_ht) > 0) {
+ context_itr = hashtable_iterator(context_ht);
+ do {
+ hContext = (TCS_CONTEXT_HANDLE *) hashtable_iterator_key(context_itr);
+ if (TCS_CloseContext(*hContext) != TPM_SUCCESS)
+ vtpmlogerror(VTPM_LOG_TCS, "Failed to close context %d
properly.\n", *hContext);
+
+ } while (hashtable_iterator_advance(context_itr));
+ free(context_itr);
+ }
+ hashtable_destroy(context_ht, 1);
}
}
@@ -101,7 +133,7 @@
BYTE** ppMemPtr) {// out
TPM_RESULT returnCode = TPM_FAIL;
- CONTEXT_HANDLE* pContextHandle = (CONTEXT_HANDLE*)hContext;
+ CONTEXT_HANDLE* pContextHandle = LookupContext(hContext);
if (pContextHandle != NULL && ppMemPtr != NULL) {
*ppMemPtr = (BYTE *)AddMemBlock(pContextHandle, MemSize);
@@ -114,7 +146,7 @@
TPM_RESULT TCS_FreeMemory( TCS_CONTEXT_HANDLE hContext, // in
BYTE* pMemory) { // in
TPM_RESULT returnCode = TPM_FAIL;
- CONTEXT_HANDLE* pContextHandle = (CONTEXT_HANDLE*)hContext;
+ CONTEXT_HANDLE* pContextHandle = LookupContext(hContext);
if ( (pContextHandle != NULL && pMemory != NULL) &&
(DeleteMemBlock(pContextHandle, pMemory) == TRUE) )
@@ -126,15 +158,15 @@
TPM_RESULT TCS_OpenContext(TCS_CONTEXT_HANDLE* hContext) { // out
TPM_RESULT returnCode = TPM_FAIL;
+ TCS_CONTEXT_HANDLE *newContext;
vtpmloginfo(VTPM_LOG_TCS, "Calling TCS_OpenContext:\n");
// hContext must point to a null memory context handle
if(*hContext == HANDLE_NULL) {
- CONTEXT_HANDLE* pContextHandle = (CONTEXT_HANDLE
*)malloc(sizeof(CONTEXT_HANDLE));
+ CONTEXT_HANDLE* pContextHandle = (CONTEXT_HANDLE *)
malloc(sizeof(CONTEXT_HANDLE));
if (pContextHandle == NULL)
return TPM_SIZE;
-
// initialize to 0
pContextHandle->nBlockCount = 0;
@@ -144,19 +176,32 @@
// Create New Block
AddMemBlock(pContextHandle, BLOCK_SIZE);
- *hContext = (TCS_CONTEXT_HANDLE)pContextHandle;
- returnCode = TPM_SUCCESS;
+ newContext = (TCS_CONTEXT_HANDLE *) malloc(sizeof(TCS_CONTEXT_HANDLE));
+ *newContext = (TCS_CONTEXT_HANDLE) (((uintptr_t) pContextHandle >> 2) &
0xffffffff);
+
+ if (hashtable_search(context_ht, &newContext) !=NULL)
+ *newContext += 1;
+
+ pContextHandle->handle = *newContext;
+ if (!hashtable_insert(context_ht, newContext, pContextHandle)) {
+ free(newContext);
+ free(pContextHandle);
+ returnCode = TPM_FAIL;
+ } else {
+ *hContext = *newContext;
+ returnCode = TPM_SUCCESS;
+ }
}
return(returnCode);
}
TPM_RESULT TCS_CloseContext(TCS_CONTEXT_HANDLE hContext) {// in
- //FIXME: TCS SHOULD Track track failed auths and make sure
+ //FIXME: TCS SHOULD Track failed auths and make sure
//we don't try and re-free them here.
TPM_RESULT returnCode = TPM_FAIL;
- CONTEXT_HANDLE* pContextHandle = (CONTEXT_HANDLE*)hContext;
+ CONTEXT_HANDLE* pContextHandle = LookupContext(hContext);
if(pContextHandle != NULL) {
// Print test info
@@ -171,6 +216,9 @@
vtpmlogerror(VTPM_LOG_TCS, "Not all handles evicted from TPM.\n");
// Release the TPM's resources
+ if (hashtable_remove(context_ht, &hContext) == NULL)
+ vtpmlogerror(VTPM_LOG_TCS, "Not all handles evicted from TPM.\n");
+
free(pContextHandle);
returnCode = TPM_SUCCESS;
}
@@ -255,7 +303,7 @@
BSG_TYPE_UINT32, authHandle,
BSG_TPM_NONCE, nonce0);
- if (!AddHandleToList((CONTEXT_HANDLE *)hContext, TPM_RT_AUTH,
*authHandle))
+ if (!AddHandleToList(hContext, TPM_RT_AUTH, *authHandle))
vtpmlogerror(VTPM_LOG_TCS, "New AuthHandle not recorded\n");
vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n", paramSize);
@@ -321,7 +369,7 @@
BSG_TPM_NONCE, nonceEven,
BSG_TPM_NONCE, nonceEvenOSAP);
- if (!AddHandleToList((CONTEXT_HANDLE *)hContext, TPM_RT_AUTH,
*authHandle)) {
+ if (!AddHandleToList(hContext, TPM_RT_AUTH, *authHandle)) {
vtpmlogerror(VTPM_LOG_TCS, "New AuthHandle not recorded\n");
}
@@ -498,7 +546,7 @@
BSG_TYPE_UINT32, ¶mSize,
BSG_TPM_COMMAND_CODE, &returnCode);
- if (!DeleteHandleFromList((CONTEXT_HANDLE *)hContext, handle))
+ if (!DeleteHandleFromList(hContext, handle))
vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n");
@@ -897,7 +945,7 @@
phKeyTCSI);
unpackAuth(pAuth, OutBuf+i);
- if (!AddHandleToList((CONTEXT_HANDLE *)hContext, TPM_RT_KEY,
*phKeyTCSI)) {
+ if (!AddHandleToList(hContext, TPM_RT_KEY, *phKeyTCSI)) {
vtpmlogerror(VTPM_LOG_TCS, "New KeyHandle not recorded\n");
}
@@ -942,7 +990,7 @@
BSG_TYPE_UINT32, ¶mSize,
BSG_TPM_COMMAND_CODE, &returnCode);
- if (!DeleteHandleFromList((CONTEXT_HANDLE *)hContext, hKey)) {
+ if (!DeleteHandleFromList(hContext, hKey)) {
vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n");
}
diff -r 3ef86b208f9b -r c0796e18b6a4 tools/vtpm_manager/tcs/tcs.h
--- a/tools/vtpm_manager/tcs/tcs.h Tue Sep 20 09:05:03 2005
+++ b/tools/vtpm_manager/tcs/tcs.h Tue Sep 20 09:08:26 2005
@@ -41,6 +41,7 @@
#define __TCS_H__
#include "tcg.h"
+#include "contextmgr.h"
#include "buffer.h"
#define HANDLE_NULL 0
@@ -235,4 +236,7 @@
UINT32 *outDataSize,// in/out
BYTE *outData); // out
+///////////// Private Functions ////////////////////
+CONTEXT_HANDLE* LookupContext( TCS_CONTEXT_HANDLE hContext);
+
#endif //TCS_H
diff -r 3ef86b208f9b -r c0796e18b6a4 tools/vtpm_manager/tcs/transmit.c
--- a/tools/vtpm_manager/tcs/transmit.c Tue Sep 20 09:05:03 2005
+++ b/tools/vtpm_manager/tcs/transmit.c Tue Sep 20 09:08:26 2005
@@ -69,7 +69,7 @@
ERRORDIE (TPM_IOERROR);
}
else if ((TDDL_UINT32) size < insize) {
- vtpmlogerror(VTPM_LOG_TXDATA, "Wrote %d instead of %d bytes!\n", size,
insize);
+ vtpmlogerror(VTPM_LOG_TXDATA, "Wrote %d instead of %d bytes!\n", (int)
size, insize);
// ... ?
}
diff -r 3ef86b208f9b -r c0796e18b6a4 tools/vtpm_manager/util/Makefile
--- a/tools/vtpm_manager/util/Makefile Tue Sep 20 09:05:03 2005
+++ b/tools/vtpm_manager/util/Makefile Tue Sep 20 09:08:26 2005
@@ -13,6 +13,7 @@
rm -f *.a *.so *.o *.rpm $(DEP_FILES)
mrproper: clean
+ rm -f *~
$(BIN): $(OBJS)
$(AR) rcs $(BIN) $(OBJS)
diff -r 3ef86b208f9b -r c0796e18b6a4 tools/vtpm_manager/util/tcg.h
--- a/tools/vtpm_manager/util/tcg.h Tue Sep 20 09:05:03 2005
+++ b/tools/vtpm_manager/util/tcg.h Tue Sep 20 09:08:26 2005
@@ -453,14 +453,14 @@
// DEPENDS: local var 'status' of type TPM_RESULT
// DEPENDS: label 'abort_egress' which cleans up and returns the status
#define ERRORDIE(s) do { status = s; \
- fprintf (stderr, "*** ERRORDIE in %s, line %i\n",
__func__, __LINE__); \
+ fprintf (stderr, "*** ERRORDIE in %s at %s: %i\n",
__func__, __FILE__, __LINE__); \
goto abort_egress; } \
while (0)
// ASSUME: the return value used after the abort_egress label has been set
// already (eg. the 'status' local var)
#define STATUSCHECK(s) if (s != TPM_SUCCESS) { \
- fprintf (stderr, "*** ERR in %s, line %i\n",
__func__, __LINE__); \
+ fprintf (stderr, "*** ERR in %s at %s:%i\n",
__func__, __FILE__, __LINE__); \
goto abort_egress; \
}
@@ -475,7 +475,7 @@
// Try command c. If it fails, print error message, set status to actual
return code. Goto shame
#define TPMTRYRETURN(c) do { status = c; \
if (status != TPM_SUCCESS) { \
- printf("ERROR in %s:%i code: %s.\n", __func__,
__LINE__, tpm_get_error_name(status)); \
+ printf("ERROR in %s at %s:%i code: %s.\n",
__func__, __FILE__, __LINE__, tpm_get_error_name(status)); \
goto abort_egress; \
} \
} while(0)
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|