ia64/xen-unstable

changeset 6976:c0796e18b6a4

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@intel.com>
author kaf24@firebug.cl.cam.ac.uk
date Tue Sep 20 09:08:26 2005 +0000 (2005-09-20)
parents 3ef86b208f9b
children 750ad97f37b0
files tools/vtpm/Makefile tools/vtpm/README tools/vtpm/tpm_emulator.patch tools/vtpm/vtpm.patch tools/vtpm_manager/README tools/vtpm_manager/Rules.mk tools/vtpm_manager/crypto/Makefile tools/vtpm_manager/manager/Makefile tools/vtpm_manager/manager/dmictl.c tools/vtpm_manager/manager/securestorage.c tools/vtpm_manager/manager/vtpm_manager.c tools/vtpm_manager/manager/vtpmpriv.h tools/vtpm_manager/tcs/Makefile tools/vtpm_manager/tcs/contextmgr.c tools/vtpm_manager/tcs/contextmgr.h tools/vtpm_manager/tcs/tcs.c tools/vtpm_manager/tcs/tcs.h tools/vtpm_manager/tcs/transmit.c tools/vtpm_manager/util/Makefile tools/vtpm_manager/util/tcg.h
line diff
     1.1 --- a/tools/vtpm/Makefile	Tue Sep 20 09:05:03 2005 +0000
     1.2 +++ b/tools/vtpm/Makefile	Tue Sep 20 09:08:26 2005 +0000
     1.3 @@ -4,7 +4,7 @@ XEN_ROOT = ../..
     1.4  include $(XEN_ROOT)/tools/vtpm/Rules.mk
     1.5  
     1.6  # Dir name for emulator (as dom0 tpm driver)
     1.7 -TPM_EMULATOR_DIR = tpm_emulator-0.2
     1.8 +TPM_EMULATOR_DIR = tpm_emulator
     1.9  # Dir name for vtpm instance
    1.10  VTPM_DIR = vtpm
    1.11  
    1.12 @@ -13,7 +13,7 @@ TPM_EMULATOR_TARFILE = tpm_emulator-0.2b
    1.13  
    1.14  all: build
    1.15  
    1.16 -build: $(TPM_EMULATOR_TARFILE) extract patch build_sub
    1.17 +build: $(TPM_EMULATOR_DIR) $(VTPM_DIR) build_sub
    1.18  
    1.19  install: build
    1.20  	$(MAKE) -C $(TPM_EMULATOR_DIR) $@
    1.21 @@ -26,36 +26,32 @@ clean:
    1.22  	if [ -d $(VTPM_DIR) ]; \
    1.23  		then $(MAKE) -C $(VTPM_DIR) clean; \
    1.24  	fi
    1.25 +
    1.26 +mrproper:
    1.27 +	rm -f $(TPM_EMULATOR_TARFILE)
    1.28  	rm -rf $(TPM_EMULATOR_DIR)
    1.29  	rm -rf $(VTPM_DIR)
    1.30  
    1.31 -mrproper: clean
    1.32 -	rm -f $(TPM_EMULATOR_TARFILE)
    1.33 -
    1.34  # Download Swiss emulator
    1.35  $(TPM_EMULATOR_TARFILE):
    1.36  	wget http://download.berlios.de/tpm-emulator/$(TPM_EMULATOR_TARFILE)
    1.37  
    1.38  # Create vtpm and TPM emulator dirs
    1.39 -extract: $(TPM_EMULATOR_DIR)/README $(VTPM_DIR)/README
    1.40 -
    1.41 -$(TPM_EMULATOR_DIR)/README:
    1.42 -	-rm -rf $(TPM_EMULATOR_DIR)
    1.43 -	tar -xzf $(TPM_EMULATOR_TARFILE)
    1.44 -
    1.45 -$(VTPM_DIR)/README:
    1.46 -	-rm -rf $(VTPM_DIR)
    1.47 -	cp -r --preserve $(TPM_EMULATOR_DIR) $(VTPM_DIR)
    1.48 -
    1.49  # apply patches for 1) used as dom0 tpm driver 2) used as vtpm device instance
    1.50 -patch: $(TPM_EMULATOR_DIR)/Makefile $(VTPM_DIR)/Makefile
    1.51 -
    1.52 -$(TPM_EMULATOR_DIR)/Makefile: tpm_emulator.patch
    1.53 +$(TPM_EMULATOR_DIR): $(TPM_EMULATOR_TARFILE) 
    1.54 +	tar -xzf $(TPM_EMULATOR_TARFILE);  
    1.55 +	mv tpm_emulator-0.2 $(TPM_EMULATOR_DIR); 
    1.56 +	
    1.57  	-cd $(TPM_EMULATOR_DIR); \
    1.58 +	patch -p1 < ../tpm_emulator-0.2b-x86_64.patch; \
    1.59  	patch -p1 <../tpm_emulator.patch
    1.60  
    1.61 -$(VTPM_DIR)/Makefile: vtpm.patch
    1.62 +$(VTPM_DIR): $(TPM_EMULATOR_TARFILE)
    1.63 +	tar -xzf $(TPM_EMULATOR_TARFILE);  
    1.64 +	mv tpm_emulator-0.2 $(VTPM_DIR); 
    1.65 +
    1.66  	-cd $(VTPM_DIR); \
    1.67 +	patch -p1 < ../tpm_emulator-0.2b-x86_64.patch; \
    1.68  	patch -p1 <../vtpm.patch
    1.69  
    1.70  build_sub:
     2.1 --- a/tools/vtpm/README	Tue Sep 20 09:05:03 2005 +0000
     2.2 +++ b/tools/vtpm/README	Tue Sep 20 09:08:26 2005 +0000
     2.3 @@ -23,6 +23,7 @@ Requirements
     2.4  - xen-unstable 
     2.5  - IBM frontend/backend vtpm driver patch
     2.6  - vtpm_managerd
     2.7 +- GNU MP Big number library (GMP)
     2.8  
     2.9  vtpmd Flow (for vtpm_manager. vtpmd never run by default)
    2.10  ============================
     3.1 --- a/tools/vtpm/tpm_emulator.patch	Tue Sep 20 09:05:03 2005 +0000
     3.2 +++ b/tools/vtpm/tpm_emulator.patch	Tue Sep 20 09:08:26 2005 +0000
     3.3 @@ -1,12 +1,12 @@
     3.4 -diff -uprN orig/tpm_emulator-0.2/AUTHORS tpm_emulator-0.2/AUTHORS
     3.5 ---- orig/tpm_emulator-0.2/AUTHORS	2005-08-17 10:58:36.000000000 -0700
     3.6 -+++ tpm_emulator-0.2/AUTHORS	2005-08-17 10:55:52.000000000 -0700
     3.7 +diff -uprN orig/tpm_emulator-0.2-x86_64/AUTHORS tpm_emulator/AUTHORS
     3.8 +--- orig/tpm_emulator-0.2-x86_64/AUTHORS	2005-08-15 00:58:57.000000000 -0700
     3.9 ++++ tpm_emulator/AUTHORS	2005-09-14 20:27:22.000000000 -0700
    3.10  @@ -1 +1,2 @@
    3.11   Mario Strasser <mast@gmx.net>
    3.12  +INTEL Corp <>
    3.13 -diff -uprN orig/tpm_emulator-0.2/ChangeLog tpm_emulator-0.2/ChangeLog
    3.14 ---- orig/tpm_emulator-0.2/ChangeLog	2005-08-17 10:58:36.000000000 -0700
    3.15 -+++ tpm_emulator-0.2/ChangeLog	2005-08-17 10:55:52.000000000 -0700
    3.16 +diff -uprN orig/tpm_emulator-0.2-x86_64/ChangeLog tpm_emulator/ChangeLog
    3.17 +--- orig/tpm_emulator-0.2-x86_64/ChangeLog	2005-08-15 00:58:57.000000000 -0700
    3.18 ++++ tpm_emulator/ChangeLog	2005-09-14 20:27:22.000000000 -0700
    3.19  @@ -1,3 +1,7 @@
    3.20  +2005-08-16: INTEL Corp
    3.21  +	* Set default permissions to PCRs
    3.22 @@ -15,10 +15,29 @@ diff -uprN orig/tpm_emulator-0.2/ChangeL
    3.23   2005-08-15  Mario Strasser <mast@gmx.net>
    3.24   	* all: some typos corrected
    3.25   	* tpm_integrity.c: bug in TPM_Extend fixed
    3.26 -diff -uprN orig/tpm_emulator-0.2/Makefile tpm_emulator-0.2/Makefile
    3.27 ---- orig/tpm_emulator-0.2/Makefile	2005-08-17 10:58:36.000000000 -0700
    3.28 -+++ tpm_emulator-0.2/Makefile	2005-08-17 10:55:52.000000000 -0700
    3.29 -@@ -1,15 +1,19 @@
    3.30 +diff -uprN orig/tpm_emulator-0.2-x86_64/linux_module.h tpm_emulator/linux_module.h
    3.31 +--- orig/tpm_emulator-0.2-x86_64/linux_module.h	2005-09-15 19:21:14.844078720 -0700
    3.32 ++++ tpm_emulator/linux_module.h	2005-09-14 20:27:22.000000000 -0700
    3.33 +@@ -1,5 +1,6 @@
    3.34 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
    3.35 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
    3.36 ++ * Copyright (C) 2005 INTEL Corp.
    3.37 +  *
    3.38 +  * This module is free software; you can redistribute it and/or modify
    3.39 +  * it under the terms of the GNU General Public License as published
    3.40 +@@ -35,7 +36,7 @@
    3.41 + #include "tpm_version.h"
    3.42 + 
    3.43 + #define TPM_DEVICE_MINOR	224
    3.44 +-#define TPM_DEVICE_NAME         "tpm"
    3.45 ++#define TPM_DEVICE_NAME         "tpm0"
    3.46 + #define TPM_MODULE_NAME 	"tpm_emulator"
    3.47 + 
    3.48 + /* debug and log output functions */
    3.49 +diff -uprN orig/tpm_emulator-0.2-x86_64/Makefile tpm_emulator/Makefile
    3.50 +--- orig/tpm_emulator-0.2-x86_64/Makefile	2005-09-15 19:21:14.845078568 -0700
    3.51 ++++ tpm_emulator/Makefile	2005-09-14 20:27:22.000000000 -0700
    3.52 +@@ -1,16 +1,20 @@
    3.53   # Software-Based Trusted Platform Module (TPM) Emulator for Linux
    3.54   # Copyright (C) 2004 Mario Strasser <mast@gmx.net>
    3.55  +# Copyright (C) 2005 INTEL Corp.
    3.56 @@ -33,6 +52,7 @@ diff -uprN orig/tpm_emulator-0.2/Makefil
    3.57  -KERNEL_BUILD   := /lib/modules/$(KERNEL_RELEASE)/build
    3.58  +KERNEL_BUILD   := $(XEN_ROOT)/linux-2.6.12-xen0
    3.59   MOD_SUBDIR     := misc
    3.60 + COMPILE_ARCH    ?= $(shell uname -m | sed -e s/i.86/x86_32/)
    3.61   
    3.62   # module settings
    3.63  -MODULE_NAME    := tpm_emulator
    3.64 @@ -40,7 +60,7 @@ diff -uprN orig/tpm_emulator-0.2/Makefil
    3.65   VERSION_MAJOR  := 0
    3.66   VERSION_MINOR  := 2
    3.67   VERSION_BUILD  := $(shell date +"%s")
    3.68 -@@ -27,11 +30,9 @@ DIRS           := . crypto tpm 
    3.69 +@@ -34,11 +38,9 @@ DIRS           := . crypto tpm 
    3.70   SRCS           := $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.c))
    3.71   OBJS           := $(patsubst %.c, %.o, $(SRCS))
    3.72   SRCS           += $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.h))
    3.73 @@ -54,7 +74,7 @@ diff -uprN orig/tpm_emulator-0.2/Makefil
    3.74   
    3.75   EXTRA_CFLAGS   += -I$(src) -I$(src)/crypto -I$(src)/tpm 
    3.76   
    3.77 -@@ -42,23 +43,17 @@ all:	$(src)/crypto/gmp.h $(src)/crypto/l
    3.78 +@@ -49,23 +51,17 @@ all:	$(src)/crypto/gmp.h $(src)/crypto/l
    3.79   	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules
    3.80   
    3.81   install:
    3.82 @@ -84,9 +104,9 @@ diff -uprN orig/tpm_emulator-0.2/Makefil
    3.83   
    3.84   $(src)/crypto/libgmp.a:
    3.85   	test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB) $(src)/crypto/libgmp.a
    3.86 -diff -uprN orig/tpm_emulator-0.2/README tpm_emulator-0.2/README
    3.87 ---- orig/tpm_emulator-0.2/README	2005-08-17 10:58:36.000000000 -0700
    3.88 -+++ tpm_emulator-0.2/README	2005-08-17 10:55:52.000000000 -0700
    3.89 +diff -uprN orig/tpm_emulator-0.2-x86_64/README tpm_emulator/README
    3.90 +--- orig/tpm_emulator-0.2-x86_64/README	2005-08-15 00:58:57.000000000 -0700
    3.91 ++++ tpm_emulator/README	2005-09-14 20:27:22.000000000 -0700
    3.92  @@ -13,7 +13,8 @@ $Id: README 8 2005-01-25 21:11:45Z jmoli
    3.93   Copyright
    3.94   --------------------------------------------------------------------------
    3.95 @@ -97,28 +117,9 @@ diff -uprN orig/tpm_emulator-0.2/README 
    3.96                 
    3.97   This program is free software; you can redistribute it and/or modify
    3.98   it under the terms of the GNU General Public License as published by
    3.99 -diff -uprN orig/tpm_emulator-0.2/linux_module.h tpm_emulator-0.2/linux_module.h
   3.100 ---- orig/tpm_emulator-0.2/linux_module.h	2005-08-17 10:58:36.000000000 -0700
   3.101 -+++ tpm_emulator-0.2/linux_module.h	2005-08-17 10:55:52.000000000 -0700
   3.102 -@@ -1,5 +1,6 @@
   3.103 - /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   3.104 -  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
   3.105 -+ * Copyright (C) 2005 INTEL Corp.
   3.106 -  *
   3.107 -  * This module is free software; you can redistribute it and/or modify
   3.108 -  * it under the terms of the GNU General Public License as published
   3.109 -@@ -33,7 +34,7 @@
   3.110 - #include "tpm_version.h"
   3.111 - 
   3.112 - #define TPM_DEVICE_MINOR	224
   3.113 --#define TPM_DEVICE_NAME         "tpm"
   3.114 -+#define TPM_DEVICE_NAME         "tpm0"
   3.115 - #define TPM_MODULE_NAME 	"tpm_emulator"
   3.116 - 
   3.117 - /* debug and log output functions */
   3.118 -diff -uprN orig/tpm_emulator-0.2/tpm/tpm_data.c tpm_emulator-0.2/tpm/tpm_data.c
   3.119 ---- orig/tpm_emulator-0.2/tpm/tpm_data.c	2005-08-17 10:58:36.000000000 -0700
   3.120 -+++ tpm_emulator-0.2/tpm/tpm_data.c	2005-08-17 10:55:52.000000000 -0700
   3.121 +diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c tpm_emulator/tpm/tpm_data.c
   3.122 +--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c	2005-09-15 19:21:14.847078264 -0700
   3.123 ++++ tpm_emulator/tpm/tpm_data.c	2005-09-14 20:27:22.000000000 -0700
   3.124  @@ -1,6 +1,7 @@
   3.125   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   3.126    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
   3.127 @@ -139,13 +140,3 @@ diff -uprN orig/tpm_emulator-0.2/tpm/tpm
   3.128       tpmData.permanent.data.pcrAttrib[i].pcrReset = TRUE;
   3.129     }
   3.130     /* set tick type */
   3.131 -diff -uprN orig/tpm_emulator-0.2/tpm_version.h tpm_emulator-0.2/tpm_version.h
   3.132 ---- orig/tpm_emulator-0.2/tpm_version.h	2005-08-17 10:58:36.000000000 -0700
   3.133 -+++ tpm_emulator-0.2/tpm_version.h	2005-08-17 10:55:53.000000000 -0700
   3.134 -@@ -2,5 +2,5 @@
   3.135 - #define _TPM_VERSION_H_
   3.136 - #define VERSION_MAJOR 0
   3.137 - #define VERSION_MINOR 2
   3.138 --#define VERSION_BUILD 1123950310
   3.139 -+#define VERSION_BUILD 1124301353
   3.140 - #endif /* _TPM_VERSION_H_ */
     4.1 --- a/tools/vtpm/vtpm.patch	Tue Sep 20 09:05:03 2005 +0000
     4.2 +++ b/tools/vtpm/vtpm.patch	Tue Sep 20 09:08:26 2005 +0000
     4.3 @@ -1,12 +1,12 @@
     4.4 -diff -uprN orig/tpm_emulator-0.2/AUTHORS vtpm/AUTHORS
     4.5 ---- orig/tpm_emulator-0.2/AUTHORS	2005-08-17 10:58:36.000000000 -0700
     4.6 -+++ vtpm/AUTHORS	2005-08-17 10:55:52.000000000 -0700
     4.7 +diff -uprN orig/tpm_emulator-0.2-x86_64/AUTHORS vtpm/AUTHORS
     4.8 +--- orig/tpm_emulator-0.2-x86_64/AUTHORS	2005-08-15 00:58:57.000000000 -0700
     4.9 ++++ vtpm/AUTHORS	2005-09-14 20:27:22.000000000 -0700
    4.10  @@ -1 +1,2 @@
    4.11   Mario Strasser <mast@gmx.net>
    4.12  +INTEL Corp <>
    4.13 -diff -uprN orig/tpm_emulator-0.2/ChangeLog vtpm/ChangeLog
    4.14 ---- orig/tpm_emulator-0.2/ChangeLog	2005-08-17 10:58:36.000000000 -0700
    4.15 -+++ vtpm/ChangeLog	2005-08-17 10:55:52.000000000 -0700
    4.16 +diff -uprN orig/tpm_emulator-0.2-x86_64/ChangeLog vtpm/ChangeLog
    4.17 +--- orig/tpm_emulator-0.2-x86_64/ChangeLog	2005-08-15 00:58:57.000000000 -0700
    4.18 ++++ vtpm/ChangeLog	2005-09-14 20:27:22.000000000 -0700
    4.19  @@ -1,3 +1,7 @@
    4.20  +2005-08-16 Intel Corp
    4.21  +	Moved module out of kernel to run as a ring 3 app
    4.22 @@ -15,115 +15,9 @@ diff -uprN orig/tpm_emulator-0.2/ChangeL
    4.23   2005-08-15  Mario Strasser <mast@gmx.net>
    4.24   	* all: some typos corrected
    4.25   	* tpm_integrity.c: bug in TPM_Extend fixed
    4.26 -diff -uprN orig/tpm_emulator-0.2/Makefile vtpm/Makefile
    4.27 ---- orig/tpm_emulator-0.2/Makefile	2005-08-17 10:58:36.000000000 -0700
    4.28 -+++ vtpm/Makefile	2005-08-17 10:55:52.000000000 -0700
    4.29 -@@ -1,21 +1,29 @@
    4.30 - # Software-Based Trusted Platform Module (TPM) Emulator for Linux
    4.31 - # Copyright (C) 2004 Mario Strasser <mast@gmx.net>
    4.32 -+# Copyright (C) 2005 INTEL Corp.
    4.33 - #
    4.34 - # $Id: Makefile 10 2005-04-26 20:59:50Z mast $
    4.35 - 
    4.36 --# kernel settings
    4.37 --KERNEL_RELEASE := $(shell uname -r)
    4.38 --KERNEL_BUILD   := /lib/modules/$(KERNEL_RELEASE)/build
    4.39 --MOD_SUBDIR     := misc
    4.40 --
    4.41 - # module settings
    4.42 --MODULE_NAME    := tpm_emulator
    4.43 -+BIN            := vtpmd
    4.44 - VERSION_MAJOR  := 0
    4.45 - VERSION_MINOR  := 2
    4.46 - VERSION_BUILD  := $(shell date +"%s")
    4.47 - 
    4.48 --# enable/disable DEBUG messages
    4.49 --EXTRA_CFLAGS   += -DDEBUG -g  
    4.50 -+# Installation program and options
    4.51 -+INSTALL         = install
    4.52 -+INSTALL_PROG    = $(INSTALL) -m0755
    4.53 -+INSTALL_DIR     = $(INSTALL) -d -m0755
    4.54 -+
    4.55 -+# Xen tools installation directory
    4.56 -+TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin
    4.57 -+
    4.58 -+CC      := gcc
    4.59 -+CFLAGS  += -g -Wall $(INCLUDE) -DDEBUG
    4.60 -+CFLAGS  += -I. -Itpm
    4.61 -+
    4.62 -+# Is the simulator running in it's own vm?
    4.63 -+#CFLAGS += -DVTPM_MULTI_VM
    4.64 - 
    4.65 - # GNU MP configuration
    4.66 - GMP_LIB        := /usr/lib/libgmp.a
    4.67 -@@ -27,38 +35,31 @@ DIRS           := . crypto tpm 
    4.68 - SRCS           := $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.c))
    4.69 - OBJS           := $(patsubst %.c, %.o, $(SRCS))
    4.70 - SRCS           += $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.h))
    4.71 --DISTSRC        := ./README ./AUTHORS ./ChangeLog ./Makefile $(SRCS)
    4.72 --DISTDIR        := tpm_emulator-$(VERSION_MAJOR).$(VERSION_MINOR)
    4.73 - 
    4.74 --obj-m               := $(MODULE_NAME).o
    4.75 --$(MODULE_NAME)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
    4.76 -+obj-m               := $(BIN)
    4.77 -+$(BIN)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
    4.78 - 
    4.79 - EXTRA_CFLAGS   += -I$(src) -I$(src)/crypto -I$(src)/tpm 
    4.80 - 
    4.81 - # do not print "Entering directory ..."
    4.82 - MAKEFLAGS      += --no-print-directory
    4.83 - 
    4.84 --all:	$(src)/crypto/gmp.h $(src)/crypto/libgmp.a version
    4.85 --	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules
    4.86 -+all: $(BIN)
    4.87 -+
    4.88 -+$(BIN):	$(src)/crypto/gmp.h $(src)/crypto/libgmp.a version $(SRCS) $(OBJS)
    4.89 -+	$(CC) $(CFLAGS) $(OBJS) $(src)/crypto/libgmp.a -o $(BIN)
    4.90 -+
    4.91 -+%.o: %.c
    4.92 -+	$(CC) $(CFLAGS) -c $< -o $@
    4.93 - 
    4.94 - install:
    4.95 --	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules_install
    4.96 --	test -d /var/tpm || mkdir /var/tpm
    4.97 --	test -c /dev/tpm || mknod /dev/tpm c 10 224
    4.98 --	chmod 666 /dev/tpm
    4.99 --	depmod -a
   4.100 -+	$(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR)
   4.101 - 
   4.102 - clean:
   4.103 --	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean
   4.104 --	rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a
   4.105 -+	rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a $(OBJS)
   4.106 - 
   4.107 --dist:	$(DISTSRC)
   4.108 --	rm -rf $(DISTDIR)
   4.109 --	mkdir $(DISTDIR)
   4.110 --	cp --parents $(DISTSRC) $(DISTDIR)/
   4.111 --	rm -f $(DISTDIR)/crypto/gmp.h 
   4.112 --	tar -chzf $(DISTDIR).tar.gz $(DISTDIR)
   4.113 --	rm -rf $(DISTDIR)
   4.114 -+mrproper: clean
   4.115 -+	rm -f $(BIN)
   4.116 - 
   4.117 - $(src)/crypto/libgmp.a:
   4.118 - 	test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB) $(src)/crypto/libgmp.a
   4.119 -diff -uprN orig/tpm_emulator-0.2/README vtpm/README
   4.120 ---- orig/tpm_emulator-0.2/README	2005-08-17 10:58:36.000000000 -0700
   4.121 -+++ vtpm/README	2005-08-17 10:55:52.000000000 -0700
   4.122 -@@ -13,7 +13,8 @@ $Id: README 8 2005-01-25 21:11:45Z jmoli
   4.123 - Copyright
   4.124 - --------------------------------------------------------------------------
   4.125 - Copyright (C) 2004 Mario Strasser <mast@gmx.net> and Swiss Federal 
   4.126 --Institute of Technology (ETH) Zurich.
   4.127 -+                   Institute of Technology (ETH) Zurich.
   4.128 -+Copyright (C) 2005 INTEL Corp 
   4.129 -               
   4.130 - This program is free software; you can redistribute it and/or modify
   4.131 - it under the terms of the GNU General Public License as published by
   4.132 -diff -uprN orig/tpm_emulator-0.2/crypto/gmp_kernel_wrapper.c vtpm/crypto/gmp_kernel_wrapper.c
   4.133 ---- orig/tpm_emulator-0.2/crypto/gmp_kernel_wrapper.c	2005-08-17 10:58:36.000000000 -0700
   4.134 -+++ vtpm/crypto/gmp_kernel_wrapper.c	2005-08-17 10:55:52.000000000 -0700
   4.135 +diff -uprN orig/tpm_emulator-0.2-x86_64/crypto/gmp_kernel_wrapper.c vtpm/crypto/gmp_kernel_wrapper.c
   4.136 +--- orig/tpm_emulator-0.2-x86_64/crypto/gmp_kernel_wrapper.c	2005-09-15 19:21:42.508873032 -0700
   4.137 ++++ vtpm/crypto/gmp_kernel_wrapper.c	2005-09-15 19:25:37.319176440 -0700
   4.138  @@ -1,5 +1,6 @@
   4.139   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   4.140    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
   4.141 @@ -154,9 +48,9 @@ diff -uprN orig/tpm_emulator-0.2/crypto/
   4.142   {
   4.143  -  void *ret  = (void*)kmalloc(size, GFP_KERNEL);
   4.144  -  if (!ret) panic(KERN_CRIT TPM_MODULE_NAME 
   4.145 --    "GMP: cannot allocate memory (size=%u)\n", size);
   4.146 +-    "GMP: cannot allocate memory (size=%Zu)\n", size);
   4.147  +  void *ret  = (void*)malloc(size);
   4.148 -+  if (!ret) error("GMP: cannot allocate memory (size=%u)\n", size);
   4.149 ++  if (!ret) error("GMP: cannot allocate memory (size=%Zu)\n", size);
   4.150     return ret;
   4.151   }
   4.152   
   4.153 @@ -165,9 +59,10 @@ diff -uprN orig/tpm_emulator-0.2/crypto/
   4.154   {
   4.155  -  void *ret = (void*)kmalloc(new_size, GFP_KERNEL);
   4.156  -  if (!ret) panic(KERN_CRIT TPM_MODULE_NAME "GMP: Cannot reallocate memory "
   4.157 +-    "(old_size=%Zu new_size=%Zu)\n", old_size, new_size);
   4.158  +  void *ret = (void*)malloc(new_size);
   4.159  +  if (!ret) error("GMP: Cannot reallocate memory "
   4.160 -     "(old_size=%u new_size=%u)\n", old_size, new_size);
   4.161 ++    "(old_size=%Zu new_size=%Zu)\n", old_size, new_size);
   4.162     memcpy(ret, oldptr, old_size);
   4.163  -  kfree(oldptr);
   4.164  +  free(oldptr);
   4.165 @@ -183,9 +78,9 @@ diff -uprN orig/tpm_emulator-0.2/crypto/
   4.166     }
   4.167   }
   4.168   
   4.169 -diff -uprN orig/tpm_emulator-0.2/crypto/rsa.c vtpm/crypto/rsa.c
   4.170 ---- orig/tpm_emulator-0.2/crypto/rsa.c	2005-08-17 10:58:36.000000000 -0700
   4.171 -+++ vtpm/crypto/rsa.c	2005-08-17 10:55:52.000000000 -0700
   4.172 +diff -uprN orig/tpm_emulator-0.2-x86_64/crypto/rsa.c vtpm/crypto/rsa.c
   4.173 +--- orig/tpm_emulator-0.2-x86_64/crypto/rsa.c	2005-08-15 00:58:57.000000000 -0700
   4.174 ++++ vtpm/crypto/rsa.c	2005-09-14 20:27:22.000000000 -0700
   4.175  @@ -1,5 +1,6 @@
   4.176   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   4.177    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
   4.178 @@ -211,8 +106,8 @@ diff -uprN orig/tpm_emulator-0.2/crypto/
   4.179         sha1_final(&ctx, &msg[1]);
   4.180         if (memcmp(&msg[1], &msg[1 + SHA1_DIGEST_LENGTH], 
   4.181             SHA1_DIGEST_LENGTH) != 0) return -1;
   4.182 -diff -uprN orig/tpm_emulator-0.2/linux_module.c vtpm/linux_module.c
   4.183 ---- orig/tpm_emulator-0.2/linux_module.c	2005-08-17 10:58:36.000000000 -0700
   4.184 +diff -uprN orig/tpm_emulator-0.2-x86_64/linux_module.c vtpm/linux_module.c
   4.185 +--- orig/tpm_emulator-0.2-x86_64/linux_module.c	2005-09-15 19:22:40.343080896 -0700
   4.186  +++ vtpm/linux_module.c	1969-12-31 16:00:00.000000000 -0800
   4.187  @@ -1,163 +0,0 @@
   4.188  -/* Software-Based Trusted Platform Module (TPM) Emulator for Linux 
   4.189 @@ -283,7 +178,7 @@ diff -uprN orig/tpm_emulator-0.2/linux_m
   4.190  -
   4.191  -static ssize_t tpm_read(struct file *file, char *buf, size_t count, loff_t *ppos)
   4.192  -{
   4.193 --  debug("%s(%d)", __FUNCTION__, count);
   4.194 +-  debug("%s(%Zu)", __FUNCTION__, count);
   4.195  -  down(&tpm_mutex);
   4.196  -  if (tpm_response.data != NULL) {
   4.197  -    count = min(count, (size_t)tpm_response.size - (size_t)*ppos);
   4.198 @@ -298,7 +193,7 @@ diff -uprN orig/tpm_emulator-0.2/linux_m
   4.199  -
   4.200  -static ssize_t tpm_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
   4.201  -{
   4.202 --  debug("%s(%d)", __FUNCTION__, count);
   4.203 +-  debug("%s(%Zu)", __FUNCTION__, count);
   4.204  -  down(&tpm_mutex);
   4.205  -  *ppos = 0;
   4.206  -  if (tpm_response.data != NULL) kfree(tpm_response.data);
   4.207 @@ -378,9 +273,9 @@ diff -uprN orig/tpm_emulator-0.2/linux_m
   4.208  -  return (ticks > 0) ? ticks : 1;
   4.209  -}
   4.210  -
   4.211 -diff -uprN orig/tpm_emulator-0.2/linux_module.h vtpm/linux_module.h
   4.212 ---- orig/tpm_emulator-0.2/linux_module.h	2005-08-17 10:58:36.000000000 -0700
   4.213 -+++ vtpm/linux_module.h	2005-08-17 10:55:52.000000000 -0700
   4.214 +diff -uprN orig/tpm_emulator-0.2-x86_64/linux_module.h vtpm/linux_module.h
   4.215 +--- orig/tpm_emulator-0.2-x86_64/linux_module.h	2005-09-15 19:21:14.844078720 -0700
   4.216 ++++ vtpm/linux_module.h	2005-09-14 20:27:22.000000000 -0700
   4.217  @@ -1,5 +1,6 @@
   4.218   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   4.219    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
   4.220 @@ -416,17 +311,20 @@ diff -uprN orig/tpm_emulator-0.2/linux_m
   4.221   
   4.222  +/* module settings */
   4.223  +#define min(A,B) ((A)<(B)?(A):(B))
   4.224 + #ifndef STR
   4.225   #define STR(s) __STR__(s)
   4.226   #define __STR__(s) #s
   4.227 - #include "tpm_version.h"
   4.228 -@@ -39,32 +45,35 @@
   4.229 +@@ -39,34 +45,38 @@
   4.230 + #define TPM_MODULE_NAME 	"tpm_emulator"
   4.231 + 
   4.232   /* debug and log output functions */
   4.233 ++extern int dmi_id; 
   4.234   
   4.235   #ifdef DEBUG
   4.236  -#define debug(fmt, ...) printk(KERN_DEBUG "%s %s:%d: Debug: " fmt "\n", \
   4.237  -                        TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
   4.238 -+#define debug(fmt, ...) printf("%s:%d: Debug: " fmt "\n", \
   4.239 -+                        __FILE__, __LINE__, ## __VA_ARGS__)
   4.240 ++#define debug(fmt, ...) printf("TPMD[%d]: %s:%d: Debug: " fmt "\n", \
   4.241 ++                        dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
   4.242   #else
   4.243   #define debug(fmt, ...) 
   4.244   #endif
   4.245 @@ -436,12 +334,12 @@ diff -uprN orig/tpm_emulator-0.2/linux_m
   4.246  -                        TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
   4.247  -#define alert(fmt, ...) printk(KERN_ALERT "%s %s:%d: Alert: " fmt "\n", \
   4.248  -                        TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
   4.249 -+#define info(fmt, ...)  printf("%s:%d: Info: " fmt "\n", \
   4.250 -+                        __FILE__, __LINE__, ## __VA_ARGS__)
   4.251 -+#define error(fmt, ...) printf("%s:%d: Error: " fmt "\n", \
   4.252 -+                        __FILE__, __LINE__, ## __VA_ARGS__)
   4.253 -+#define alert(fmt, ...) printf("%s:%d: Alert: " fmt "\n", \
   4.254 -+                        __FILE__, __LINE__, ## __VA_ARGS__)
   4.255 ++#define info(fmt, ...)  printf("TPMD[%d]: %s:%d: Info: " fmt "\n", \
   4.256 ++                        dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
   4.257 ++#define error(fmt, ...) printf("TPMD[%d]: %s:%d: Error: " fmt "\n", \
   4.258 ++                        dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
   4.259 ++#define alert(fmt, ...) printf("TPMD[%d]: %s:%d: Alert: " fmt "\n", \
   4.260 ++                        dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
   4.261   
   4.262   /* memory allocation */
   4.263   
   4.264 @@ -465,7 +363,7 @@ diff -uprN orig/tpm_emulator-0.2/linux_m
   4.265   static inline void tpm_get_random_bytes(void *buf, int nbytes)
   4.266   {
   4.267     get_random_bytes(buf, nbytes);
   4.268 -@@ -84,9 +93,9 @@ uint64_t tpm_get_ticks(void);
   4.269 +@@ -86,9 +96,9 @@ uint64_t tpm_get_ticks(void);
   4.270   #define CPU_TO_LE16(x) __cpu_to_le16(x)
   4.271   
   4.272   #define BE64_TO_CPU(x) __be64_to_cpu(x)
   4.273 @@ -477,9 +375,116 @@ diff -uprN orig/tpm_emulator-0.2/linux_m
   4.274   #define BE16_TO_CPU(x) __be16_to_cpu(x)
   4.275   #define LE16_TO_CPU(x) __le16_to_cpu(x)
   4.276   
   4.277 -diff -uprN orig/tpm_emulator-0.2/tpm/tpm_audit.c vtpm/tpm/tpm_audit.c
   4.278 ---- orig/tpm_emulator-0.2/tpm/tpm_audit.c	2005-08-17 10:58:36.000000000 -0700
   4.279 -+++ vtpm/tpm/tpm_audit.c	2005-08-17 10:55:52.000000000 -0700
   4.280 +diff -uprN orig/tpm_emulator-0.2-x86_64/Makefile vtpm/Makefile
   4.281 +--- orig/tpm_emulator-0.2-x86_64/Makefile	2005-09-15 19:21:14.845078568 -0700
   4.282 ++++ vtpm/Makefile	2005-09-14 20:27:22.000000000 -0700
   4.283 +@@ -1,22 +1,31 @@
   4.284 + # Software-Based Trusted Platform Module (TPM) Emulator for Linux
   4.285 + # Copyright (C) 2004 Mario Strasser <mast@gmx.net>
   4.286 ++# Copyright (C) 2005 INTEL Corp.
   4.287 + #
   4.288 + # $Id: Makefile 10 2005-04-26 20:59:50Z mast $
   4.289 + 
   4.290 +-# kernel settings
   4.291 +-KERNEL_RELEASE := $(shell uname -r)
   4.292 +-KERNEL_BUILD   := /lib/modules/$(KERNEL_RELEASE)/build
   4.293 +-MOD_SUBDIR     := misc
   4.294 + COMPILE_ARCH    ?= $(shell uname -m | sed -e s/i.86/x86_32/)
   4.295 + 
   4.296 + # module settings
   4.297 +-MODULE_NAME    := tpm_emulator
   4.298 ++BIN            := vtpmd
   4.299 + VERSION_MAJOR  := 0
   4.300 + VERSION_MINOR  := 2
   4.301 + VERSION_BUILD  := $(shell date +"%s")
   4.302 + 
   4.303 +-# enable/disable DEBUG messages
   4.304 +-EXTRA_CFLAGS   += -DDEBUG -g  
   4.305 ++# Installation program and options
   4.306 ++INSTALL         = install
   4.307 ++INSTALL_PROG    = $(INSTALL) -m0755
   4.308 ++INSTALL_DIR     = $(INSTALL) -d -m0755
   4.309 ++
   4.310 ++# Xen tools installation directory
   4.311 ++TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin
   4.312 ++
   4.313 ++CC      := gcc
   4.314 ++CFLAGS  += -g -Wall $(INCLUDE) -DDEBUG
   4.315 ++CFLAGS  += -I. -Itpm
   4.316 ++
   4.317 ++# Is the simulator running in it's own vm?
   4.318 ++#CFLAGS += -DVTPM_MULTI_VM
   4.319 + 
   4.320 + ifeq ($(COMPILE_ARCH),x86_64)
   4.321 + LIBDIR = lib64
   4.322 +@@ -34,38 +43,31 @@ DIRS           := . crypto tpm 
   4.323 + SRCS           := $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.c))
   4.324 + OBJS           := $(patsubst %.c, %.o, $(SRCS))
   4.325 + SRCS           += $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.h))
   4.326 +-DISTSRC        := ./README ./AUTHORS ./ChangeLog ./Makefile $(SRCS)
   4.327 +-DISTDIR        := tpm_emulator-$(VERSION_MAJOR).$(VERSION_MINOR)
   4.328 + 
   4.329 +-obj-m               := $(MODULE_NAME).o
   4.330 +-$(MODULE_NAME)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
   4.331 ++obj-m               := $(BIN)
   4.332 ++$(BIN)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
   4.333 + 
   4.334 + EXTRA_CFLAGS   += -I$(src) -I$(src)/crypto -I$(src)/tpm 
   4.335 + 
   4.336 + # do not print "Entering directory ..."
   4.337 + MAKEFLAGS      += --no-print-directory
   4.338 + 
   4.339 +-all:	$(src)/crypto/gmp.h $(src)/crypto/libgmp.a version
   4.340 +-	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules
   4.341 ++all: $(BIN)
   4.342 ++
   4.343 ++$(BIN):	$(src)/crypto/gmp.h $(src)/crypto/libgmp.a version $(SRCS) $(OBJS)
   4.344 ++	$(CC) $(CFLAGS) $(OBJS) $(src)/crypto/libgmp.a -o $(BIN)
   4.345 ++
   4.346 ++%.o: %.c
   4.347 ++	$(CC) $(CFLAGS) -c $< -o $@
   4.348 + 
   4.349 + install:
   4.350 +-	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules_install
   4.351 +-	test -d /var/tpm || mkdir /var/tpm
   4.352 +-	test -c /dev/tpm || mknod /dev/tpm c 10 224
   4.353 +-	chmod 666 /dev/tpm
   4.354 +-	depmod -a
   4.355 ++	$(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR)
   4.356 + 
   4.357 + clean:
   4.358 +-	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean
   4.359 +-	rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a
   4.360 ++	rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a $(OBJS)
   4.361 + 
   4.362 +-dist:	$(DISTSRC)
   4.363 +-	rm -rf $(DISTDIR)
   4.364 +-	mkdir $(DISTDIR)
   4.365 +-	cp --parents $(DISTSRC) $(DISTDIR)/
   4.366 +-	rm -f $(DISTDIR)/crypto/gmp.h 
   4.367 +-	tar -chzf $(DISTDIR).tar.gz $(DISTDIR)
   4.368 +-	rm -rf $(DISTDIR)
   4.369 ++mrproper: clean
   4.370 ++	rm -f $(BIN) tpm_version.h
   4.371 + 
   4.372 + $(src)/crypto/libgmp.a:
   4.373 + 	test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB) $(src)/crypto/libgmp.a
   4.374 +diff -uprN orig/tpm_emulator-0.2-x86_64/README vtpm/README
   4.375 +--- orig/tpm_emulator-0.2-x86_64/README	2005-08-15 00:58:57.000000000 -0700
   4.376 ++++ vtpm/README	2005-09-14 20:27:22.000000000 -0700
   4.377 +@@ -13,7 +13,8 @@ $Id: README 8 2005-01-25 21:11:45Z jmoli
   4.378 + Copyright
   4.379 + --------------------------------------------------------------------------
   4.380 + Copyright (C) 2004 Mario Strasser <mast@gmx.net> and Swiss Federal 
   4.381 +-Institute of Technology (ETH) Zurich.
   4.382 ++                   Institute of Technology (ETH) Zurich.
   4.383 ++Copyright (C) 2005 INTEL Corp 
   4.384 +               
   4.385 + This program is free software; you can redistribute it and/or modify
   4.386 + it under the terms of the GNU General Public License as published by
   4.387 +diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_audit.c vtpm/tpm/tpm_audit.c
   4.388 +--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_audit.c	2005-08-15 00:58:57.000000000 -0700
   4.389 ++++ vtpm/tpm/tpm_audit.c	2005-09-14 20:27:22.000000000 -0700
   4.390  @@ -1,6 +1,7 @@
   4.391   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   4.392    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
   4.393 @@ -542,9 +547,9 @@ diff -uprN orig/tpm_emulator-0.2/tpm/tpm
   4.394     return TPM_SUCCESS;
   4.395   }
   4.396  -
   4.397 -diff -uprN orig/tpm_emulator-0.2/tpm/tpm_authorization.c vtpm/tpm/tpm_authorization.c
   4.398 ---- orig/tpm_emulator-0.2/tpm/tpm_authorization.c	2005-08-17 10:58:36.000000000 -0700
   4.399 -+++ vtpm/tpm/tpm_authorization.c	2005-08-17 10:55:52.000000000 -0700
   4.400 +diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_authorization.c vtpm/tpm/tpm_authorization.c
   4.401 +--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_authorization.c	2005-08-15 00:58:57.000000000 -0700
   4.402 ++++ vtpm/tpm/tpm_authorization.c	2005-09-14 20:27:22.000000000 -0700
   4.403  @@ -1,6 +1,7 @@
   4.404   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   4.405    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
   4.406 @@ -568,9 +573,9 @@ diff -uprN orig/tpm_emulator-0.2/tpm/tpm
   4.407   }
   4.408  -
   4.409  -
   4.410 -diff -uprN orig/tpm_emulator-0.2/tpm/tpm_capability.c vtpm/tpm/tpm_capability.c
   4.411 ---- orig/tpm_emulator-0.2/tpm/tpm_capability.c	2005-08-17 10:58:36.000000000 -0700
   4.412 -+++ vtpm/tpm/tpm_capability.c	2005-08-17 10:55:52.000000000 -0700
   4.413 +diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_capability.c vtpm/tpm/tpm_capability.c
   4.414 +--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_capability.c	2005-08-15 00:58:57.000000000 -0700
   4.415 ++++ vtpm/tpm/tpm_capability.c	2005-09-14 20:27:22.000000000 -0700
   4.416  @@ -1,6 +1,7 @@
   4.417   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   4.418    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
   4.419 @@ -593,9 +598,9 @@ diff -uprN orig/tpm_emulator-0.2/tpm/tpm
   4.420     }
   4.421   }
   4.422  -
   4.423 -diff -uprN orig/tpm_emulator-0.2/tpm/tpm_cmd_handler.c vtpm/tpm/tpm_cmd_handler.c
   4.424 ---- orig/tpm_emulator-0.2/tpm/tpm_cmd_handler.c	2005-08-17 10:58:36.000000000 -0700
   4.425 -+++ vtpm/tpm/tpm_cmd_handler.c	2005-08-17 10:55:52.000000000 -0700
   4.426 +diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_cmd_handler.c vtpm/tpm/tpm_cmd_handler.c
   4.427 +--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_cmd_handler.c	2005-08-15 00:58:57.000000000 -0700
   4.428 ++++ vtpm/tpm/tpm_cmd_handler.c	2005-09-14 20:27:22.000000000 -0700
   4.429  @@ -1,6 +1,7 @@
   4.430   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   4.431    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
   4.432 @@ -658,9 +663,9 @@ diff -uprN orig/tpm_emulator-0.2/tpm/tpm
   4.433     return 0;
   4.434   }
   4.435  -
   4.436 -diff -uprN orig/tpm_emulator-0.2/tpm/tpm_crypto.c vtpm/tpm/tpm_crypto.c
   4.437 ---- orig/tpm_emulator-0.2/tpm/tpm_crypto.c	2005-08-17 10:58:36.000000000 -0700
   4.438 -+++ vtpm/tpm/tpm_crypto.c	2005-08-17 10:55:52.000000000 -0700
   4.439 +diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_crypto.c vtpm/tpm/tpm_crypto.c
   4.440 +--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_crypto.c	2005-09-15 19:21:14.846078416 -0700
   4.441 ++++ vtpm/tpm/tpm_crypto.c	2005-09-14 20:27:22.000000000 -0700
   4.442  @@ -1,6 +1,7 @@
   4.443   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   4.444    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
   4.445 @@ -678,14 +683,14 @@ diff -uprN orig/tpm_emulator-0.2/tpm/tpm
   4.446       memcpy(&buf[30], areaToSign, areaToSignSize);
   4.447       if (rsa_sign(&key->key, RSA_SSA_PKCS1_SHA1, 
   4.448           buf, areaToSignSize + 30, *sig)) {
   4.449 -@@ -379,4 +380,3 @@ TPM_RESULT TPM_CertifyKey2(TPM_KEY_HANDL
   4.450 +@@ -383,4 +384,3 @@ TPM_RESULT TPM_CertifyKey2(TPM_KEY_HANDL
   4.451     }  
   4.452     return TPM_SUCCESS;
   4.453   }
   4.454  -
   4.455 -diff -uprN orig/tpm_emulator-0.2/tpm/tpm_data.c vtpm/tpm/tpm_data.c
   4.456 ---- orig/tpm_emulator-0.2/tpm/tpm_data.c	2005-08-17 10:58:36.000000000 -0700
   4.457 -+++ vtpm/tpm/tpm_data.c	2005-08-17 10:55:52.000000000 -0700
   4.458 +diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c vtpm/tpm/tpm_data.c
   4.459 +--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c	2005-09-15 19:21:14.847078264 -0700
   4.460 ++++ vtpm/tpm/tpm_data.c	2005-09-14 20:27:22.000000000 -0700
   4.461  @@ -1,6 +1,7 @@
   4.462   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   4.463    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
   4.464 @@ -1005,7 +1010,7 @@ diff -uprN orig/tpm_emulator-0.2/tpm/tpm
   4.465   }
   4.466   
   4.467   #else
   4.468 -@@ -231,7 +431,6 @@ int tpm_restore_permanent_data(void)
   4.469 +@@ -232,7 +432,6 @@ int tpm_restore_permanent_data(void)
   4.470   
   4.471   int tpm_erase_permanent_data(void)
   4.472   {
   4.473 @@ -1014,9 +1019,9 @@ diff -uprN orig/tpm_emulator-0.2/tpm/tpm
   4.474     return res;
   4.475   }
   4.476  -
   4.477 -diff -uprN orig/tpm_emulator-0.2/tpm/tpm_deprecated.c vtpm/tpm/tpm_deprecated.c
   4.478 ---- orig/tpm_emulator-0.2/tpm/tpm_deprecated.c	2005-08-17 10:58:36.000000000 -0700
   4.479 -+++ vtpm/tpm/tpm_deprecated.c	2005-08-17 10:55:52.000000000 -0700
   4.480 +diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_deprecated.c vtpm/tpm/tpm_deprecated.c
   4.481 +--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_deprecated.c	2005-08-15 00:58:57.000000000 -0700
   4.482 ++++ vtpm/tpm/tpm_deprecated.c	2005-09-14 20:27:22.000000000 -0700
   4.483  @@ -1,6 +1,7 @@
   4.484   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   4.485    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
   4.486 @@ -1043,9 +1048,9 @@ diff -uprN orig/tpm_emulator-0.2/tpm/tpm
   4.487                           authContextSize, &contextBlob);
   4.488     if (res != TPM_SUCCESS) return res;
   4.489     len = *authContextSize;
   4.490 -diff -uprN orig/tpm_emulator-0.2/tpm/tpm_emulator.h vtpm/tpm/tpm_emulator.h
   4.491 ---- orig/tpm_emulator-0.2/tpm/tpm_emulator.h	2005-08-17 10:58:36.000000000 -0700
   4.492 -+++ vtpm/tpm/tpm_emulator.h	2005-08-17 10:55:52.000000000 -0700
   4.493 +diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_emulator.h vtpm/tpm/tpm_emulator.h
   4.494 +--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_emulator.h	2005-08-15 00:58:57.000000000 -0700
   4.495 ++++ vtpm/tpm/tpm_emulator.h	2005-09-14 20:27:22.000000000 -0700
   4.496  @@ -1,5 +1,6 @@
   4.497   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   4.498    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
   4.499 @@ -1063,9 +1068,9 @@ diff -uprN orig/tpm_emulator-0.2/tpm/tpm
   4.500   
   4.501   /**
   4.502    * tpm_emulator_init - initialises and starts the TPM emulator
   4.503 -diff -uprN orig/tpm_emulator-0.2/tpm/tpm_integrity.c vtpm/tpm/tpm_integrity.c
   4.504 ---- orig/tpm_emulator-0.2/tpm/tpm_integrity.c	2005-08-17 10:58:36.000000000 -0700
   4.505 -+++ vtpm/tpm/tpm_integrity.c	2005-08-17 10:55:52.000000000 -0700
   4.506 +diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_integrity.c vtpm/tpm/tpm_integrity.c
   4.507 +--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_integrity.c	2005-08-15 00:58:57.000000000 -0700
   4.508 ++++ vtpm/tpm/tpm_integrity.c	2005-09-14 20:27:22.000000000 -0700
   4.509  @@ -1,6 +1,7 @@
   4.510   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   4.511    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
   4.512 @@ -1079,9 +1084,9 @@ diff -uprN orig/tpm_emulator-0.2/tpm/tpm
   4.513     return TPM_SUCCESS;
   4.514   }
   4.515  -
   4.516 -diff -uprN orig/tpm_emulator-0.2/tpm/tpm_structures.h vtpm/tpm/tpm_structures.h
   4.517 ---- orig/tpm_emulator-0.2/tpm/tpm_structures.h	2005-08-17 10:58:36.000000000 -0700
   4.518 -+++ vtpm/tpm/tpm_structures.h	2005-08-17 10:55:52.000000000 -0700
   4.519 +diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_structures.h vtpm/tpm/tpm_structures.h
   4.520 +--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_structures.h	2005-08-15 00:58:57.000000000 -0700
   4.521 ++++ vtpm/tpm/tpm_structures.h	2005-09-14 20:27:22.000000000 -0700
   4.522  @@ -1,6 +1,7 @@
   4.523   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   4.524    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
   4.525 @@ -1099,9 +1104,9 @@ diff -uprN orig/tpm_emulator-0.2/tpm/tpm
   4.526   #include "crypto/rsa.h"
   4.527   
   4.528   /*
   4.529 -diff -uprN orig/tpm_emulator-0.2/tpm/tpm_testing.c vtpm/tpm/tpm_testing.c
   4.530 ---- orig/tpm_emulator-0.2/tpm/tpm_testing.c	2005-08-17 10:58:36.000000000 -0700
   4.531 -+++ vtpm/tpm/tpm_testing.c	2005-08-17 10:55:52.000000000 -0700
   4.532 +diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_testing.c vtpm/tpm/tpm_testing.c
   4.533 +--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_testing.c	2005-08-15 00:58:57.000000000 -0700
   4.534 ++++ vtpm/tpm/tpm_testing.c	2005-09-14 20:27:22.000000000 -0700
   4.535  @@ -1,6 +1,7 @@
   4.536   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   4.537    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
   4.538 @@ -1217,9 +1222,9 @@ diff -uprN orig/tpm_emulator-0.2/tpm/tpm
   4.539     rsa_private_key_t priv_key;
   4.540     rsa_public_key_t pub_key;
   4.541   
   4.542 -diff -uprN orig/tpm_emulator-0.2/tpm/tpm_ticks.c vtpm/tpm/tpm_ticks.c
   4.543 ---- orig/tpm_emulator-0.2/tpm/tpm_ticks.c	2005-08-17 10:58:36.000000000 -0700
   4.544 -+++ vtpm/tpm/tpm_ticks.c	2005-08-17 10:55:52.000000000 -0700
   4.545 +diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_ticks.c vtpm/tpm/tpm_ticks.c
   4.546 +--- orig/tpm_emulator-0.2-x86_64/tpm/tpm_ticks.c	2005-08-15 00:58:57.000000000 -0700
   4.547 ++++ vtpm/tpm/tpm_ticks.c	2005-09-14 20:27:22.000000000 -0700
   4.548  @@ -1,6 +1,7 @@
   4.549   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   4.550    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
   4.551 @@ -1302,9 +1307,9 @@ diff -uprN orig/tpm_emulator-0.2/tpm/tpm
   4.552   }
   4.553     
   4.554   
   4.555 -diff -uprN orig/tpm_emulator-0.2/tpm/vtpm_manager.h vtpm/tpm/vtpm_manager.h
   4.556 ---- orig/tpm_emulator-0.2/tpm/vtpm_manager.h	1969-12-31 16:00:00.000000000 -0800
   4.557 -+++ vtpm/tpm/vtpm_manager.h	2005-08-17 10:55:52.000000000 -0700
   4.558 +diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/vtpm_manager.h vtpm/tpm/vtpm_manager.h
   4.559 +--- orig/tpm_emulator-0.2-x86_64/tpm/vtpm_manager.h	1969-12-31 16:00:00.000000000 -0800
   4.560 ++++ vtpm/tpm/vtpm_manager.h	2005-09-14 20:27:22.000000000 -0700
   4.561  @@ -0,0 +1,126 @@
   4.562  +// ===================================================================
   4.563  +// 
   4.564 @@ -1432,9 +1437,9 @@ diff -uprN orig/tpm_emulator-0.2/tpm/vtp
   4.565  +*********************************************************************/
   4.566  +
   4.567  +#endif //_VTPM_MANAGER_H_
   4.568 -diff -uprN orig/tpm_emulator-0.2/tpmd.c vtpm/tpmd.c
   4.569 ---- orig/tpm_emulator-0.2/tpmd.c	1969-12-31 16:00:00.000000000 -0800
   4.570 -+++ vtpm/tpmd.c	2005-08-17 10:55:52.000000000 -0700
   4.571 +diff -uprN orig/tpm_emulator-0.2-x86_64/tpmd.c vtpm/tpmd.c
   4.572 +--- orig/tpm_emulator-0.2-x86_64/tpmd.c	1969-12-31 16:00:00.000000000 -0800
   4.573 ++++ vtpm/tpmd.c	2005-09-15 19:28:55.783005352 -0700
   4.574  @@ -0,0 +1,207 @@
   4.575  +/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   4.576  + * Copyright (C) 2005 INTEL Corp
   4.577 @@ -1468,9 +1473,9 @@ diff -uprN orig/tpm_emulator-0.2/tpmd.c 
   4.578  +#else
   4.579  + #define GUEST_RX_FIFO_D "/var/vtpm/fifos/guest-to-%d.fifo"
   4.580  + #define GUEST_TX_FIFO "/var/vtpm/fifos/guest-from-all.fifo"
   4.581 ++#endif
   4.582  +
   4.583  + int dmi_id;
   4.584 -+#endif
   4.585  +						
   4.586  +#define BUFFER_SIZE 2048
   4.587  +
   4.588 @@ -1506,7 +1511,7 @@ diff -uprN orig/tpm_emulator-0.2/tpmd.c 
   4.589  +{
   4.590  +  uint8_t in[BUFFER_SIZE], *out, *addressed_out;
   4.591  +  uint32_t out_size;
   4.592 -+  int in_size, written ;
   4.593 ++  int in_size, written;
   4.594  +  int i, guest_id=-1;
   4.595  + 
   4.596  +  int vtpm_tx_fh=-1, vtpm_rx_fh=-1;
   4.597 @@ -1602,7 +1607,7 @@ diff -uprN orig/tpm_emulator-0.2/tpmd.c 
   4.598  +      written = write(vtpm_tx_fh, ctrl_msg, sizeof(ctrl_msg));
   4.599  +
   4.600  +      if (written != sizeof(ctrl_msg)) {
   4.601 -+        printf("ERROR: Part of response not written %d/%d.\n", written, sizeof(ctrl_msg));
   4.602 ++        printf("ERROR: Part of response not written %d/%Zu.\n", written, sizeof(ctrl_msg));
   4.603  +      } else {
   4.604  +        printf("Send Ctrl Message confermation\n");
   4.605  +      }
   4.606 @@ -1623,7 +1628,7 @@ diff -uprN orig/tpm_emulator-0.2/tpmd.c 
   4.607  +          printf("%x ", addressed_out[i]);
   4.608  +        printf("\n");
   4.609  +      } else {
   4.610 -+        printf("Sent[%d]: ", out_size + sizeof(uint32_t));
   4.611 ++        printf("Sent[%Zu]: ", out_size + sizeof(uint32_t));
   4.612  +        for (i=0; i< out_size+ sizeof(uint32_t); i++)
   4.613  +          printf("%x ", addressed_out[i]);
   4.614  +        printf("\n");
     5.1 --- a/tools/vtpm_manager/README	Tue Sep 20 09:05:03 2005 +0000
     5.2 +++ b/tools/vtpm_manager/README	Tue Sep 20 09:08:26 2005 +0000
     5.3 @@ -51,14 +51,24 @@ VTPM_MULTI_VM                -> Defined:
     5.4  DUMMY_BACKEND                -> vtpm_manager listens on /tmp/in.fifo and 
     5.5                                  /tmp/out.fifo rather than backend
     5.6  
     5.7 -MANUAL_DM_LAUNCH             -> User must manually launch & kill VTPMs
     5.8 +MANUAL_DM_LAUNCH             -> Must manually launch & kill VTPMs
     5.9  
    5.10 -USE_FIXED_SRK_AUTH           -> Do not randomly generate a random SRK & Owner auth
    5.11 +WELL_KNOWN_SRK_AUTH          -> Rather than randomly generating the password for the SRK,
    5.12 +                                use a well known value. This is necessary for sharing use
    5.13 +                                of the SRK across applications. Such as VTPM and Dom0
    5.14 +                                measurement software.
    5.15 +
    5.16 +WELL_KNOWN_OWNER_AUTH        -> Rather than randomly generating the password for the owner,
    5.17 +                                use a well known value. This is useful for debugging and for
    5.18 +                                poor bios which do not support clearing TPM if OwnerAuth is
    5.19 +                                lost. However this has no protection from malicious app
    5.20 +                                issuing a TPM_OwnerClear to wipe the TPM 
    5.21  
    5.22  Requirements
    5.23  ============
    5.24  - xen-unstable 
    5.25 -- IBM frontend/backend vtpm driver patch
    5.26 +- vtpm frontend/backend driver patch
    5.27 +- OpenSSL Library
    5.28  
    5.29  Single-VM Flow
    5.30  ============================
     6.1 --- a/tools/vtpm_manager/Rules.mk	Tue Sep 20 09:05:03 2005 +0000
     6.2 +++ b/tools/vtpm_manager/Rules.mk	Tue Sep 20 09:08:26 2005 +0000
     6.3 @@ -57,7 +57,8 @@ CFLAGS += -DLOGGING_MODULES="(BITMASK(VT
     6.4  #CFLAGS += -DMANUAL_DM_LAUNCH
     6.5  
     6.6  # Fixed SRK
     6.7 -CFLAGS += -DUSE_FIXED_SRK_AUTH
     6.8 +CFLAGS += -DWELL_KNOWN_SRK_AUTH
     6.9 +#CFLAGS += -DWELL_KNOWN_OWNER_AUTH
    6.10  
    6.11  # TPM Hardware Device or TPM Simulator
    6.12  #CFLAGS += -DTPM_HWDEV
     7.1 --- a/tools/vtpm_manager/crypto/Makefile	Tue Sep 20 09:05:03 2005 +0000
     7.2 +++ b/tools/vtpm_manager/crypto/Makefile	Tue Sep 20 09:08:26 2005 +0000
     7.3 @@ -13,6 +13,7 @@ clean:
     7.4  	rm -f *.a *.so *.o *.rpm $(DEP_FILES)
     7.5  
     7.6  mrproper: clean
     7.7 +	rm -f *~
     7.8  
     7.9  $(BIN): $(OBJS)
    7.10  	$(AR) rcs $(BIN) $(OBJS)
     8.1 --- a/tools/vtpm_manager/manager/Makefile	Tue Sep 20 09:05:03 2005 +0000
     8.2 +++ b/tools/vtpm_manager/manager/Makefile	Tue Sep 20 09:08:26 2005 +0000
     8.3 @@ -17,7 +17,7 @@ clean:
     8.4  	rm -f *.a *.so *.o *.rpm $(DEP_FILES)
     8.5  
     8.6  mrproper: clean
     8.7 -	rm -f $(BIN)
     8.8 +	rm -f $(BIN) *~
     8.9  
    8.10  $(BIN): $(OBJS)
    8.11  	$(CC) $(LDFLAGS) $^ $(LIBS) -o $@
     9.1 --- a/tools/vtpm_manager/manager/dmictl.c	Tue Sep 20 09:05:03 2005 +0000
     9.2 +++ b/tools/vtpm_manager/manager/dmictl.c	Tue Sep 20 09:08:26 2005 +0000
     9.3 @@ -1,339 +1,344 @@
     9.4 -// ===================================================================
     9.5 -// 
     9.6 -// Copyright (c) 2005, Intel Corp.
     9.7 -// All rights reserved.
     9.8 -//
     9.9 -// Redistribution and use in source and binary forms, with or without 
    9.10 -// modification, are permitted provided that the following conditions 
    9.11 -// are met:
    9.12 -//
    9.13 -//   * Redistributions of source code must retain the above copyright 
    9.14 -//     notice, this list of conditions and the following disclaimer.
    9.15 -//   * Redistributions in binary form must reproduce the above 
    9.16 -//     copyright notice, this list of conditions and the following 
    9.17 -//     disclaimer in the documentation and/or other materials provided 
    9.18 -//     with the distribution.
    9.19 -//   * Neither the name of Intel Corporation nor the names of its 
    9.20 -//     contributors may be used to endorse or promote products derived
    9.21 -//     from this software without specific prior written permission.
    9.22 -//
    9.23 -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    9.24 -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    9.25 -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
    9.26 -// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
    9.27 -// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
    9.28 -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    9.29 -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
    9.30 -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    9.31 -// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
    9.32 -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
    9.33 -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
    9.34 -// OF THE POSSIBILITY OF SUCH DAMAGE.
    9.35 -// ===================================================================
    9.36 -// 
    9.37 -//   dmictl.c
    9.38 -// 
    9.39 -//     Functions for creating and destroying DMIs
    9.40 -//
    9.41 -// ==================================================================
    9.42 -
    9.43 -#include <stdio.h>
    9.44 -#include <unistd.h>
    9.45 -#include <string.h>
    9.46 -
    9.47 -#ifndef VTPM_MUTLI_VM
    9.48 - #include <sys/types.h>
    9.49 - #include <sys/stat.h>
    9.50 - #include <fcntl.h>
    9.51 - #include <signal.h>
    9.52 - #include <wait.h>
    9.53 -#endif
    9.54 -
    9.55 -#include "vtpmpriv.h"
    9.56 -#include "bsg.h"
    9.57 -#include "buffer.h"
    9.58 -#include "log.h"
    9.59 -#include "hashtable.h"
    9.60 -#include "hashtable_itr.h"
    9.61 -
    9.62 -#define TPM_EMULATOR_PATH "/usr/bin/vtpmd"
    9.63 -
    9.64 -TPM_RESULT close_dmi( VTPM_DMI_RESOURCE *dmi_res) {
    9.65 -	TPM_RESULT status = TPM_FAIL;
    9.66 -	
    9.67 -	if (dmi_res == NULL) 
    9.68 -		return TPM_SUCCESS;
    9.69 -	
    9.70 -	status = TCS_CloseContext(dmi_res->TCSContext);
    9.71 -	free ( dmi_res->NVMLocation );
    9.72 -	dmi_res->connected = FALSE;
    9.73 -
    9.74 -#ifndef VTPM_MULTI_VM	
    9.75 -	free(dmi_res->guest_tx_fname);
    9.76 -	free(dmi_res->vtpm_tx_fname);
    9.77 -		
    9.78 -	close(dmi_res->guest_tx_fh); dmi_res->guest_tx_fh = -1;
    9.79 -	close(dmi_res->vtpm_tx_fh);  dmi_res->vtpm_tx_fh = -1; 
    9.80 -	
    9.81 -		
    9.82 - #ifndef MANUAL_DM_LAUNCH
    9.83 -  if (dmi_res->dmi_id != VTPM_CTL_DM) {
    9.84 -    if (dmi_res->dmi_pid != 0) {
    9.85 -      vtpmloginfo(VTPM_LOG_VTPM, "Killing dmi on pid %d.\n", dmi_res->dmi_pid);
    9.86 -      if ((kill(dmi_res->dmi_pid, SIGKILL) !=0) ||
    9.87 -         (waitpid(dmi_res->dmi_pid, NULL, 0) != dmi_res->dmi_pid)){
    9.88 -        vtpmlogerror(VTPM_LOG_VTPM, "Could not kill dmi on pid %d.\n", dmi_res->dmi_pid);
    9.89 -        status = TPM_FAIL;
    9.90 -      }
    9.91 -    } else 
    9.92 -      vtpmlogerror(VTPM_LOG_VTPM, "Could not kill dmi because it's pid was 0.\n");
    9.93 -  }
    9.94 - #endif
    9.95 -#endif
    9.96 -
    9.97 -	return status;
    9.98 -}
    9.99 -	
   9.100 -TPM_RESULT VTPM_Handle_New_DMI( const buffer_t *param_buf) {
   9.101 -  
   9.102 -  VTPM_DMI_RESOURCE *new_dmi=NULL;
   9.103 -  TPM_RESULT status=TPM_FAIL;
   9.104 -  BYTE type;
   9.105 -  UINT32 dmi_id, domain_id, *dmi_id_key; 
   9.106 -  int fh;
   9.107 -
   9.108 -#ifndef VTPM_MUTLI_VM
   9.109 -  char dmi_id_str[11]; // UINT32s are up to 10 digits + NULL
   9.110 -  struct stat file_info;
   9.111 -#endif
   9.112 -  
   9.113 -  if (param_buf == NULL) { // Assume creation of Dom 0 control
   9.114 -    type = 0;
   9.115 -    domain_id = VTPM_CTL_DM;
   9.116 -    dmi_id = VTPM_CTL_DM;
   9.117 -  } else if (buffer_len(param_buf) != sizeof(BYTE) + sizeof(UINT32) *2) {
   9.118 -    vtpmloginfo(VTPM_LOG_VTPM, "New DMI command wrong length: %d.\n", buffer_len(param_buf));
   9.119 -    status = TPM_BAD_PARAMETER;
   9.120 -    goto abort_egress;
   9.121 -  } else {
   9.122 -    BSG_UnpackList( param_buf->bytes, 3,
   9.123 -		    BSG_TYPE_BYTE, &type,
   9.124 -		    BSG_TYPE_UINT32, &domain_id,
   9.125 -		    BSG_TYPE_UINT32,  &dmi_id);
   9.126 -  }
   9.127 -  
   9.128 -  new_dmi = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi_id);
   9.129 -  if (new_dmi == NULL) { 
   9.130 -    vtpmloginfo(VTPM_LOG_VTPM, "Creating new DMI instance %d attached on domain %d.\n", dmi_id, domain_id);
   9.131 -    // Brand New DMI. Initialize the persistent pieces
   9.132 -    if ((new_dmi = (VTPM_DMI_RESOURCE *) malloc (sizeof(VTPM_DMI_RESOURCE))) == NULL) {
   9.133 -      status = TPM_RESOURCES;
   9.134 -      goto abort_egress;
   9.135 -    }
   9.136 -    memset(new_dmi, 0, sizeof(VTPM_DMI_RESOURCE));
   9.137 -    new_dmi->dmi_id = dmi_id;
   9.138 -    new_dmi->connected = FALSE;
   9.139 -    
   9.140 -    if ((dmi_id_key = (UINT32 *) malloc (sizeof(UINT32))) == NULL) {
   9.141 -      status = TPM_RESOURCES;
   9.142 -      goto abort_egress;
   9.143 -    }      
   9.144 -    *dmi_id_key = new_dmi->dmi_id;
   9.145 -    
   9.146 -    // install into map
   9.147 -    if (!hashtable_insert(vtpm_globals->dmi_map, dmi_id_key, new_dmi)){
   9.148 -      free(new_dmi);
   9.149 -      free(dmi_id_key);
   9.150 -      status = TPM_FAIL;
   9.151 -      goto egress;
   9.152 -    }
   9.153 -    
   9.154 -  } else 
   9.155 -    vtpmloginfo(VTPM_LOG_VTPM, "Re-attaching DMI instance %d on domain %d .\n", dmi_id, domain_id);
   9.156 -  
   9.157 -  if (new_dmi->connected) {
   9.158 -    vtpmlogerror(VTPM_LOG_VTPM, "Attempt to re-attach, currently attached instance %d. Ignoring\n", dmi_id);
   9.159 -    status = TPM_BAD_PARAMETER;
   9.160 -    goto egress;
   9.161 -  }
   9.162 -  
   9.163 -  // Initialize the Non-persistent pieces
   9.164 -  new_dmi->dmi_domain_id = domain_id;
   9.165 -  new_dmi->NVMLocation = NULL;
   9.166 -  
   9.167 -  new_dmi->TCSContext = 0;
   9.168 -  TPMTRYRETURN( TCS_OpenContext(&new_dmi->TCSContext) );
   9.169 -  
   9.170 -  new_dmi->NVMLocation = (char *) malloc(11 + strlen(DMI_NVM_FILE));
   9.171 -  sprintf(new_dmi->NVMLocation, DMI_NVM_FILE, (uint32_t) new_dmi->dmi_id);
   9.172 -  
   9.173 -  // Measure DMI
   9.174 -  // FIXME: This will measure DMI. Until then use a fixed DMI_Measurement value
   9.175 -  /*
   9.176 -  fh = open(TPM_EMULATOR_PATH, O_RDONLY);
   9.177 -  stat_ret = fstat(fh, &file_stat);
   9.178 -  if (stat_ret == 0) 
   9.179 -    dmi_size = file_stat.st_size;
   9.180 -  else {
   9.181 -	vtpmlogerror(VTPM_LOG_VTPM, "Could not open tpm_emulator!!\n");
   9.182 -    status = TPM_IOERROR;
   9.183 -    goto abort_egress;
   9.184 -  }
   9.185 -  dmi_buffer
   9.186 -  */
   9.187 -  memset(&new_dmi->DMI_measurement, 0xcc, sizeof(TPM_DIGEST));
   9.188 -  
   9.189 -#ifndef VTPM_MULTI_VM
   9.190 -  if (dmi_id != VTPM_CTL_DM) {
   9.191 -    // Create a pair of fifo pipes
   9.192 -		if( (new_dmi->guest_tx_fname = (char *) malloc(11 + strlen(GUEST_TX_FIFO))) == NULL){ 
   9.193 -			status = TPM_RESOURCES;
   9.194 -			goto abort_egress;
   9.195 -		}
   9.196 -		sprintf(new_dmi->guest_tx_fname, GUEST_TX_FIFO, (uint32_t) dmi_id);
   9.197 -    
   9.198 -		if ((new_dmi->vtpm_tx_fname = (char *) malloc(11 + strlen(VTPM_TX_FIFO))) == NULL) {
   9.199 -			status = TPM_RESOURCES;
   9.200 -			goto abort_egress;
   9.201 -		}
   9.202 -		sprintf(new_dmi->vtpm_tx_fname, VTPM_TX_FIFO, (uint32_t) dmi_id);
   9.203 -    
   9.204 -    new_dmi->guest_tx_fh = -1;
   9.205 -    new_dmi->vtpm_tx_fh= -1;
   9.206 -    
   9.207 -    if ( stat(new_dmi->guest_tx_fname, &file_info) == -1) {
   9.208 -      if ( mkfifo(new_dmi->guest_tx_fname, S_IWUSR | S_IRUSR ) ){
   9.209 -				status = TPM_FAIL;
   9.210 -				goto abort_egress;
   9.211 -      }
   9.212 -    }
   9.213 -            
   9.214 -    if ( (fh = open(new_dmi->vtpm_tx_fname, O_RDWR)) == -1) {
   9.215 -      if ( mkfifo(new_dmi->vtpm_tx_fname, S_IWUSR | S_IRUSR ) ) {
   9.216 -	status = TPM_FAIL;
   9.217 -	goto abort_egress;
   9.218 -      }
   9.219 -    }
   9.220 -                
   9.221 -    // Launch DMI
   9.222 -    sprintf(dmi_id_str, "%d", (int) dmi_id);
   9.223 -#ifdef MANUAL_DM_LAUNCH
   9.224 -    vtpmlogerror(VTPM_LOG_VTPM, "FAKING starting vtpm with dmi=%s\n", dmi_id_str);
   9.225 -    new_dmi->dmi_pid = 0;
   9.226 -#else
   9.227 -    pid_t pid = fork();
   9.228 -    
   9.229 -    if (pid == -1) {
   9.230 -			vtpmlogerror(VTPM_LOG_VTPM, "Could not fork to launch vtpm\n");
   9.231 -		  status = TPM_RESOURCES;
   9.232 -      goto abort_egress;
   9.233 -		} else if (pid == 0) {
   9.234 -		  if ( stat(new_dmi->NVMLocation, &file_info) == -1)
   9.235 -				execl (TPM_EMULATOR_PATH, "vtmpd", "clear", dmi_id_str, NULL);
   9.236 -			else 
   9.237 -				execl (TPM_EMULATOR_PATH, "vtpmd", "save", dmi_id_str, NULL);
   9.238 -			
   9.239 -			// Returning from these at all is an error.
   9.240 -			vtpmlogerror(VTPM_LOG_VTPM, "Could not exec to launch vtpm\n");
   9.241 -    } else {
   9.242 -      new_dmi->dmi_pid = pid;
   9.243 -      vtpmloginfo(VTPM_LOG_VTPM, "Launching DMI on PID = %d\n", pid);
   9.244 -    }
   9.245 -#endif // MANUAL_DM_LAUNCH
   9.246 -  }
   9.247 -#else // VTPM_MUTLI_VM
   9.248 -  // FIXME: Measure DMI through call to Measurement agent in platform.
   9.249 -#endif 
   9.250 -	
   9.251 -  vtpm_globals->DMI_table_dirty = TRUE;
   9.252 -  new_dmi->connected = TRUE;  
   9.253 -  status=TPM_SUCCESS;
   9.254 -  goto egress;
   9.255 -  
   9.256 - abort_egress:
   9.257 -	close_dmi( new_dmi );
   9.258 -	
   9.259 - egress:
   9.260 -  return status;
   9.261 -}
   9.262 -
   9.263 -TPM_RESULT VTPM_Handle_Close_DMI( const buffer_t *param_buf) {
   9.264 -  
   9.265 -  TPM_RESULT status=TPM_FAIL;
   9.266 -  VTPM_DMI_RESOURCE *dmi_res=NULL;
   9.267 -  UINT32 dmi_id;
   9.268 -  
   9.269 -  if ((param_buf == NULL) || (buffer_len(param_buf) != sizeof(UINT32)) ) {
   9.270 -    vtpmlogerror(VTPM_LOG_VTPM, "Closing DMI has bad size.");
   9.271 -    status = TPM_BAD_PARAMETER;
   9.272 -    goto abort_egress;
   9.273 -  }
   9.274 -  
   9.275 -  BSG_UnpackList( param_buf->bytes, 1,
   9.276 -		  BSG_TYPE_UINT32, &dmi_id);
   9.277 -  
   9.278 -  vtpmloginfo(VTPM_LOG_VTPM, "Closing DMI %d.\n", dmi_id);
   9.279 -  
   9.280 -  dmi_res = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi_id);
   9.281 -  if (dmi_res == NULL ) {
   9.282 -    vtpmlogerror(VTPM_LOG_VTPM, "Trying to close nonexistent DMI.\n");
   9.283 -    status = TPM_BAD_PARAMETER;
   9.284 -    goto abort_egress;
   9.285 -  }
   9.286 -	
   9.287 -	if (!dmi_res->connected) {
   9.288 -    vtpmlogerror(VTPM_LOG_VTPM, "Closing non-connected DMI.\n");
   9.289 -    status = TPM_BAD_PARAMETER;
   9.290 -    goto abort_egress;
   9.291 -  }
   9.292 -  
   9.293 -  // Close Dmi
   9.294 -	TPMTRYRETURN(close_dmi( dmi_res ));
   9.295 -  
   9.296 -  status=TPM_SUCCESS;    
   9.297 -  goto egress;
   9.298 -  
   9.299 - abort_egress:
   9.300 - egress:
   9.301 -  
   9.302 -  return status;
   9.303 -}
   9.304 -
   9.305 -TPM_RESULT VTPM_Handle_Delete_DMI( const buffer_t *param_buf) {
   9.306 -  
   9.307 -  TPM_RESULT status=TPM_FAIL;
   9.308 -  VTPM_DMI_RESOURCE *dmi_res=NULL;
   9.309 -  UINT32 dmi_id;
   9.310 -    
   9.311 -  if ((param_buf == NULL) || (buffer_len(param_buf) != sizeof(UINT32)) ) {
   9.312 -    vtpmlogerror(VTPM_LOG_VTPM, "Closing DMI has bad size.\n");
   9.313 -    status = TPM_BAD_PARAMETER;
   9.314 -    goto abort_egress;
   9.315 -  }
   9.316 -  
   9.317 -  BSG_UnpackList( param_buf->bytes, 1,
   9.318 -		  BSG_TYPE_UINT32, &dmi_id);
   9.319 -  
   9.320 -  vtpmloginfo(VTPM_LOG_VTPM, "Deleting DMI %d.\n", dmi_id);    
   9.321 -  
   9.322 -  dmi_res = (VTPM_DMI_RESOURCE *) hashtable_remove(vtpm_globals->dmi_map, &dmi_id);
   9.323 -  if (dmi_res == NULL) {
   9.324 -    vtpmlogerror(VTPM_LOG_VTPM, "Closing non-existent DMI.\n");
   9.325 -    status = TPM_BAD_PARAMETER;
   9.326 -    goto abort_egress;
   9.327 -  }
   9.328 -  
   9.329 -	//TODO: Automatically delete file dmi_res->NVMLocation
   9.330 -  
   9.331 -  // Close DMI first
   9.332 -  TPMTRYRETURN(close_dmi( dmi_res ));
   9.333 -	free ( dmi_res );
   9.334 -	
   9.335 -  status=TPM_SUCCESS;    
   9.336 -  goto egress;
   9.337 -  
   9.338 - abort_egress:
   9.339 - egress:
   9.340 -  
   9.341 -  return status;
   9.342 -}
   9.343 +// ===================================================================
   9.344 +// 
   9.345 +// Copyright (c) 2005, Intel Corp.
   9.346 +// All rights reserved.
   9.347 +//
   9.348 +// Redistribution and use in source and binary forms, with or without 
   9.349 +// modification, are permitted provided that the following conditions 
   9.350 +// are met:
   9.351 +//
   9.352 +//   * Redistributions of source code must retain the above copyright 
   9.353 +//     notice, this list of conditions and the following disclaimer.
   9.354 +//   * Redistributions in binary form must reproduce the above 
   9.355 +//     copyright notice, this list of conditions and the following 
   9.356 +//     disclaimer in the documentation and/or other materials provided 
   9.357 +//     with the distribution.
   9.358 +//   * Neither the name of Intel Corporation nor the names of its 
   9.359 +//     contributors may be used to endorse or promote products derived
   9.360 +//     from this software without specific prior written permission.
   9.361 +//
   9.362 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   9.363 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   9.364 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
   9.365 +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
   9.366 +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   9.367 +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   9.368 +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
   9.369 +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   9.370 +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
   9.371 +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
   9.372 +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   9.373 +// OF THE POSSIBILITY OF SUCH DAMAGE.
   9.374 +// ===================================================================
   9.375 +// 
   9.376 +//   dmictl.c
   9.377 +// 
   9.378 +//     Functions for creating and destroying DMIs
   9.379 +//
   9.380 +// ==================================================================
   9.381 +
   9.382 +#include <stdio.h>
   9.383 +#include <unistd.h>
   9.384 +#include <string.h>
   9.385 +
   9.386 +#ifndef VTPM_MUTLI_VM
   9.387 + #include <sys/types.h>
   9.388 + #include <sys/stat.h>
   9.389 + #include <fcntl.h>
   9.390 + #include <signal.h>
   9.391 + #include <wait.h>
   9.392 +#endif
   9.393 +
   9.394 +#include "vtpmpriv.h"
   9.395 +#include "bsg.h"
   9.396 +#include "buffer.h"
   9.397 +#include "log.h"
   9.398 +#include "hashtable.h"
   9.399 +#include "hashtable_itr.h"
   9.400 +
   9.401 +#define TPM_EMULATOR_PATH "/usr/bin/vtpmd"
   9.402 +
   9.403 +TPM_RESULT close_dmi( VTPM_DMI_RESOURCE *dmi_res) {
   9.404 +  TPM_RESULT status = TPM_FAIL;
   9.405 +  
   9.406 +  if (dmi_res == NULL) 
   9.407 +    return TPM_SUCCESS;
   9.408 +
   9.409 +  status = TCS_CloseContext(dmi_res->TCSContext);
   9.410 +  free ( dmi_res->NVMLocation );
   9.411 +  dmi_res->connected = FALSE;
   9.412 +
   9.413 +#ifndef VTPM_MULTI_VM	
   9.414 +  free(dmi_res->guest_tx_fname);
   9.415 +  free(dmi_res->vtpm_tx_fname);
   9.416 +	  
   9.417 +  close(dmi_res->guest_tx_fh); dmi_res->guest_tx_fh = -1;
   9.418 +  close(dmi_res->vtpm_tx_fh);  dmi_res->vtpm_tx_fh = -1; 
   9.419 +		
   9.420 + #ifndef MANUAL_DM_LAUNCH
   9.421 +  if (dmi_res->dmi_id != VTPM_CTL_DM) {
   9.422 +    if (dmi_res->dmi_pid != 0) {
   9.423 +      vtpmloginfo(VTPM_LOG_VTPM, "Killing dmi on pid %d.\n", dmi_res->dmi_pid);
   9.424 +      if (kill(dmi_res->dmi_pid, SIGKILL) !=0) {
   9.425 +        vtpmloginfo(VTPM_LOG_VTPM, "DMI on pid %d is already dead.\n", dmi_res->dmi_pid);
   9.426 +      } else if (waitpid(dmi_res->dmi_pid, NULL, 0) != dmi_res->dmi_pid) {
   9.427 +        vtpmlogerror(VTPM_LOG_VTPM, "DMI on pid %d failed to stop.\n", dmi_res->dmi_pid);
   9.428 +        status = TPM_FAIL;
   9.429 +      }
   9.430 +    } else { 
   9.431 +      vtpmlogerror(VTPM_LOG_VTPM, "Could not kill dmi because it's pid was 0.\n");
   9.432 +      status = TPM_FAIL;
   9.433 +    }
   9.434 +  }
   9.435 + #endif
   9.436 +#endif
   9.437 +
   9.438 +  return status;
   9.439 +}
   9.440 +	
   9.441 +TPM_RESULT VTPM_Handle_New_DMI( const buffer_t *param_buf) {
   9.442 +  
   9.443 +  VTPM_DMI_RESOURCE *new_dmi=NULL;
   9.444 +  TPM_RESULT status=TPM_FAIL;
   9.445 +  BYTE type;
   9.446 +  UINT32 dmi_id, domain_id, *dmi_id_key; 
   9.447 +
   9.448 +#ifndef VTPM_MULTI_VM
   9.449 +  int fh;
   9.450 +  char dmi_id_str[11]; // UINT32s are up to 10 digits + NULL
   9.451 +  struct stat file_info;
   9.452 +#endif
   9.453 +  
   9.454 +  if (param_buf == NULL) { // Assume creation of Dom 0 control
   9.455 +    type = 0;
   9.456 +    domain_id = VTPM_CTL_DM;
   9.457 +    dmi_id = VTPM_CTL_DM;
   9.458 +  } else if (buffer_len(param_buf) != sizeof(BYTE) + sizeof(UINT32) *2) {
   9.459 +    vtpmloginfo(VTPM_LOG_VTPM, "New DMI command wrong length: %d.\n", buffer_len(param_buf));
   9.460 +    status = TPM_BAD_PARAMETER;
   9.461 +    goto abort_egress;
   9.462 +  } else {
   9.463 +    BSG_UnpackList( param_buf->bytes, 3,
   9.464 +		    BSG_TYPE_BYTE, &type,
   9.465 +		    BSG_TYPE_UINT32, &domain_id,
   9.466 +		    BSG_TYPE_UINT32,  &dmi_id);
   9.467 +  }
   9.468 +  
   9.469 +  new_dmi = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi_id);
   9.470 +  if (new_dmi == NULL) { 
   9.471 +    vtpmloginfo(VTPM_LOG_VTPM, "Creating new DMI instance %d attached on domain %d.\n", dmi_id, domain_id);
   9.472 +    // Brand New DMI. Initialize the persistent pieces
   9.473 +    if ((new_dmi = (VTPM_DMI_RESOURCE *) malloc (sizeof(VTPM_DMI_RESOURCE))) == NULL) {
   9.474 +      status = TPM_RESOURCES;
   9.475 +      goto abort_egress;
   9.476 +    }
   9.477 +    memset(new_dmi, 0, sizeof(VTPM_DMI_RESOURCE));
   9.478 +    new_dmi->dmi_id = dmi_id;
   9.479 +    new_dmi->connected = FALSE;
   9.480 +    
   9.481 +    if ((dmi_id_key = (UINT32 *) malloc (sizeof(UINT32))) == NULL) {
   9.482 +      status = TPM_RESOURCES;
   9.483 +      goto abort_egress;
   9.484 +    }      
   9.485 +    *dmi_id_key = new_dmi->dmi_id;
   9.486 +    
   9.487 +    // install into map
   9.488 +    if (!hashtable_insert(vtpm_globals->dmi_map, dmi_id_key, new_dmi)){
   9.489 +      free(new_dmi);
   9.490 +      free(dmi_id_key);
   9.491 +      status = TPM_FAIL;
   9.492 +      goto egress;
   9.493 +    }
   9.494 +    
   9.495 +  } else 
   9.496 +    vtpmloginfo(VTPM_LOG_VTPM, "Re-attaching DMI instance %d on domain %d .\n", dmi_id, domain_id);
   9.497 +  
   9.498 +  if (new_dmi->connected) {
   9.499 +    vtpmlogerror(VTPM_LOG_VTPM, "Attempt to re-attach, currently attached instance %d. Ignoring\n", dmi_id);
   9.500 +    status = TPM_BAD_PARAMETER;
   9.501 +    goto egress;
   9.502 +  }
   9.503 +  
   9.504 +  // Initialize the Non-persistent pieces
   9.505 +  new_dmi->dmi_domain_id = domain_id;
   9.506 +  new_dmi->NVMLocation = NULL;
   9.507 +  
   9.508 +  new_dmi->TCSContext = 0;
   9.509 +  TPMTRYRETURN( TCS_OpenContext(&new_dmi->TCSContext) );
   9.510 +  
   9.511 +  new_dmi->NVMLocation = (char *) malloc(11 + strlen(DMI_NVM_FILE));
   9.512 +  sprintf(new_dmi->NVMLocation, DMI_NVM_FILE, (uint32_t) new_dmi->dmi_id);
   9.513 +  
   9.514 +  // Measure DMI
   9.515 +  // FIXME: This will measure DMI. Until then use a fixed DMI_Measurement value
   9.516 +  /*
   9.517 +  fh = open(TPM_EMULATOR_PATH, O_RDONLY);
   9.518 +  stat_ret = fstat(fh, &file_stat);
   9.519 +  if (stat_ret == 0) 
   9.520 +    dmi_size = file_stat.st_size;
   9.521 +  else {
   9.522 +      vtpmlogerror(VTPM_LOG_VTPM, "Could not open tpm_emulator!!\n");
   9.523 +    status = TPM_IOERROR;
   9.524 +    goto abort_egress;
   9.525 +  }
   9.526 +  dmi_buffer
   9.527 +  */
   9.528 +  memset(&new_dmi->DMI_measurement, 0xcc, sizeof(TPM_DIGEST));
   9.529 +  
   9.530 +#ifndef VTPM_MULTI_VM
   9.531 +  if (dmi_id != VTPM_CTL_DM) {
   9.532 +    // Create a pair of fifo pipes
   9.533 +    if( (new_dmi->guest_tx_fname = (char *) malloc(11 + strlen(GUEST_TX_FIFO))) == NULL){ 
   9.534 +      status = TPM_RESOURCES;
   9.535 +      goto abort_egress;
   9.536 +    }
   9.537 +    sprintf(new_dmi->guest_tx_fname, GUEST_TX_FIFO, (uint32_t) dmi_id);
   9.538 +    
   9.539 +    if ((new_dmi->vtpm_tx_fname = (char *) malloc(11 + strlen(VTPM_TX_FIFO))) == NULL) {
   9.540 +      status = TPM_RESOURCES;
   9.541 +      goto abort_egress;
   9.542 +    }
   9.543 +    sprintf(new_dmi->vtpm_tx_fname, VTPM_TX_FIFO, (uint32_t) dmi_id);
   9.544 +    
   9.545 +    new_dmi->guest_tx_fh = -1;
   9.546 +    new_dmi->vtpm_tx_fh= -1;
   9.547 +    
   9.548 +    if ( stat(new_dmi->guest_tx_fname, &file_info) == -1) {
   9.549 +      if ( mkfifo(new_dmi->guest_tx_fname, S_IWUSR | S_IRUSR ) ){
   9.550 +	vtpmlogerror(VTPM_LOG_VTPM, "Failed to create dmi fifo.\n");
   9.551 +	status = TPM_IOERROR;
   9.552 +	goto abort_egress;
   9.553 +      }
   9.554 +    }
   9.555 +            
   9.556 +    if ( (fh = open(new_dmi->vtpm_tx_fname, O_RDWR)) == -1) {
   9.557 +      if ( mkfifo(new_dmi->vtpm_tx_fname, S_IWUSR | S_IRUSR ) ) {
   9.558 +	vtpmlogerror(VTPM_LOG_VTPM, "Failed to create dmi fifo.\n");
   9.559 +	status = TPM_IOERROR;
   9.560 +	goto abort_egress;
   9.561 +      }
   9.562 +    }
   9.563 +                
   9.564 +    // Launch DMI
   9.565 +    sprintf(dmi_id_str, "%d", (int) dmi_id);
   9.566 +#ifdef MANUAL_DM_LAUNCH
   9.567 +    vtpmlogerror(VTPM_LOG_VTPM, "FAKING starting vtpm with dmi=%s\n", dmi_id_str);
   9.568 +    new_dmi->dmi_pid = 0;
   9.569 +#else
   9.570 +    pid_t pid = fork();
   9.571 +    
   9.572 +    if (pid == -1) {
   9.573 +      vtpmlogerror(VTPM_LOG_VTPM, "Could not fork to launch vtpm\n");
   9.574 +      status = TPM_RESOURCES;
   9.575 +      goto abort_egress;
   9.576 +    } else if (pid == 0) {
   9.577 +      if ( stat(new_dmi->NVMLocation, &file_info) == -1)
   9.578 +	execl (TPM_EMULATOR_PATH, "vtmpd", "clear", dmi_id_str, NULL);
   9.579 +      else 
   9.580 +	execl (TPM_EMULATOR_PATH, "vtpmd", "save", dmi_id_str, NULL);
   9.581 +			
   9.582 +      // Returning from these at all is an error.
   9.583 +      vtpmlogerror(VTPM_LOG_VTPM, "Could not exec to launch vtpm\n");
   9.584 +    } else {
   9.585 +      new_dmi->dmi_pid = pid;
   9.586 +      vtpmloginfo(VTPM_LOG_VTPM, "Launching DMI on PID = %d\n", pid);
   9.587 +    }
   9.588 +#endif // MANUAL_DM_LAUNCH
   9.589 +  }
   9.590 +#else // VTPM_MUTLI_VM
   9.591 +  // FIXME: Measure DMI through call to Measurement agent in platform.
   9.592 +#endif 
   9.593 +	
   9.594 +  vtpm_globals->DMI_table_dirty = TRUE;
   9.595 +  new_dmi->connected = TRUE;  
   9.596 +  status=TPM_SUCCESS;
   9.597 +  goto egress;
   9.598 +  
   9.599 + abort_egress:
   9.600 +  vtpmlogerror(VTPM_LOG_VTPM, "Failed to create DMI id=%d due to status=%s. Cleaning.\n", dmi_id, tpm_get_error_name(status));
   9.601 +  close_dmi( new_dmi );
   9.602 +	
   9.603 + egress:
   9.604 +  return status;
   9.605 +}
   9.606 +
   9.607 +TPM_RESULT VTPM_Handle_Close_DMI( const buffer_t *param_buf) {
   9.608 +  
   9.609 +  TPM_RESULT status=TPM_FAIL;
   9.610 +  VTPM_DMI_RESOURCE *dmi_res=NULL;
   9.611 +  UINT32 dmi_id;
   9.612 +  
   9.613 +  if ((param_buf == NULL) || (buffer_len(param_buf) != sizeof(UINT32)) ) {
   9.614 +    vtpmlogerror(VTPM_LOG_VTPM, "Closing DMI has bad size.");
   9.615 +    status = TPM_BAD_PARAMETER;
   9.616 +    goto abort_egress;
   9.617 +  }
   9.618 +  
   9.619 +  BSG_UnpackList( param_buf->bytes, 1,
   9.620 +		  BSG_TYPE_UINT32, &dmi_id);
   9.621 +  
   9.622 +  vtpmloginfo(VTPM_LOG_VTPM, "Closing DMI %d.\n", dmi_id);
   9.623 +  
   9.624 +  dmi_res = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi_id);
   9.625 +  if (dmi_res == NULL ) {
   9.626 +    vtpmlogerror(VTPM_LOG_VTPM, "Trying to close nonexistent DMI.\n");
   9.627 +    status = TPM_BAD_PARAMETER;
   9.628 +    goto abort_egress;
   9.629 +  }
   9.630 +	
   9.631 +	if (!dmi_res->connected) {
   9.632 +    vtpmlogerror(VTPM_LOG_VTPM, "Closing non-connected DMI.\n");
   9.633 +    status = TPM_BAD_PARAMETER;
   9.634 +    goto abort_egress;
   9.635 +  }
   9.636 +  
   9.637 +  // Close Dmi
   9.638 +	TPMTRYRETURN(close_dmi( dmi_res ));
   9.639 +  
   9.640 +  status=TPM_SUCCESS;    
   9.641 +  goto egress;
   9.642 +  
   9.643 + abort_egress:
   9.644 + egress:
   9.645 +  
   9.646 +  return status;
   9.647 +}
   9.648 +
   9.649 +TPM_RESULT VTPM_Handle_Delete_DMI( const buffer_t *param_buf) {
   9.650 +  
   9.651 +  TPM_RESULT status=TPM_FAIL;
   9.652 +  VTPM_DMI_RESOURCE *dmi_res=NULL;
   9.653 +  UINT32 dmi_id;
   9.654 +    
   9.655 +  if ((param_buf == NULL) || (buffer_len(param_buf) != sizeof(UINT32)) ) {
   9.656 +    vtpmlogerror(VTPM_LOG_VTPM, "Closing DMI has bad size.\n");
   9.657 +    status = TPM_BAD_PARAMETER;
   9.658 +    goto abort_egress;
   9.659 +  }
   9.660 +  
   9.661 +  BSG_UnpackList( param_buf->bytes, 1,
   9.662 +		  BSG_TYPE_UINT32, &dmi_id);
   9.663 +  
   9.664 +  vtpmloginfo(VTPM_LOG_VTPM, "Deleting DMI %d.\n", dmi_id);    
   9.665 +  
   9.666 +  dmi_res = (VTPM_DMI_RESOURCE *) hashtable_remove(vtpm_globals->dmi_map, &dmi_id);
   9.667 +  if (dmi_res == NULL) {
   9.668 +    vtpmlogerror(VTPM_LOG_VTPM, "Closing non-existent DMI.\n");
   9.669 +    status = TPM_BAD_PARAMETER;
   9.670 +    goto abort_egress;
   9.671 +  }
   9.672 +  
   9.673 +	//TODO: Automatically delete file dmi_res->NVMLocation
   9.674 +  
   9.675 +  // Close DMI first
   9.676 +  TPMTRYRETURN(close_dmi( dmi_res ));
   9.677 +	free ( dmi_res );
   9.678 +	
   9.679 +  status=TPM_SUCCESS;    
   9.680 +  goto egress;
   9.681 +  
   9.682 + abort_egress:
   9.683 + egress:
   9.684 +  
   9.685 +  return status;
   9.686 +}
    10.1 --- a/tools/vtpm_manager/manager/securestorage.c	Tue Sep 20 09:05:03 2005 +0000
    10.2 +++ b/tools/vtpm_manager/manager/securestorage.c	Tue Sep 20 09:08:26 2005 +0000
    10.3 @@ -1,401 +1,401 @@
    10.4 -// ===================================================================
    10.5 -// 
    10.6 -// Copyright (c) 2005, Intel Corp.
    10.7 -// All rights reserved.
    10.8 -//
    10.9 -// Redistribution and use in source and binary forms, with or without 
   10.10 -// modification, are permitted provided that the following conditions 
   10.11 -// are met:
   10.12 -//
   10.13 -//   * Redistributions of source code must retain the above copyright 
   10.14 -//     notice, this list of conditions and the following disclaimer.
   10.15 -//   * Redistributions in binary form must reproduce the above 
   10.16 -//     copyright notice, this list of conditions and the following 
   10.17 -//     disclaimer in the documentation and/or other materials provided 
   10.18 -//     with the distribution.
   10.19 -//   * Neither the name of Intel Corporation nor the names of its 
   10.20 -//     contributors may be used to endorse or promote products derived
   10.21 -//     from this software without specific prior written permission.
   10.22 -//
   10.23 -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   10.24 -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   10.25 -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
   10.26 -// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
   10.27 -// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   10.28 -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   10.29 -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
   10.30 -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   10.31 -// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
   10.32 -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
   10.33 -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   10.34 -// OF THE POSSIBILITY OF SUCH DAMAGE.
   10.35 -// ===================================================================
   10.36 -// 
   10.37 -// securestorage.c
   10.38 -// 
   10.39 -//  Functions regarding securely storing DMI secrets.
   10.40 -//
   10.41 -// ==================================================================
   10.42 -
   10.43 -#include <sys/types.h>
   10.44 -#include <sys/stat.h>
   10.45 -#include <fcntl.h>
   10.46 -#include <unistd.h>
   10.47 -#include <string.h>
   10.48 -
   10.49 -#include "tcg.h"
   10.50 -#include "vtpm_manager.h"
   10.51 -#include "vtpmpriv.h"
   10.52 -#include "vtsp.h"
   10.53 -#include "bsg.h"
   10.54 -#include "crypto.h"
   10.55 -#include "hashtable.h"
   10.56 -#include "hashtable_itr.h"
   10.57 -#include "buffer.h"
   10.58 -#include "log.h"
   10.59 -
   10.60 -TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI_RESOURCE *myDMI, 
   10.61 -				const buffer_t *inbuf, 
   10.62 -				buffer_t *outbuf) {
   10.63 -  
   10.64 -  TPM_RESULT status = TPM_SUCCESS;
   10.65 -  symkey_t    symkey;
   10.66 -  buffer_t    state_cipher = NULL_BUF,
   10.67 -              symkey_cipher = NULL_BUF;
   10.68 -  int fh;
   10.69 -  long bytes_written;
   10.70 -  BYTE *sealed_NVM=NULL;
   10.71 -  UINT32 sealed_NVM_size, i;
   10.72 -  struct pack_constbuf_t symkey_cipher32, state_cipher32;
   10.73 -  
   10.74 -  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Save_NVMing[%d]: 0x", buffer_len(inbuf));
   10.75 -  for (i=0; i< buffer_len(inbuf); i++)
   10.76 -    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", inbuf->bytes[i]);
   10.77 -  vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
   10.78 -  
   10.79 -  // Generate a sym key and encrypt state with it
   10.80 -  TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_genkey (&symkey) );
   10.81 -  TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_encrypt (&symkey, inbuf, &state_cipher) );
   10.82 -  
   10.83 -  // Encrypt symmetric key
   10.84 -  TPMTRYRETURN( VTSP_Bind(    &vtpm_globals->storageKey, 
   10.85 -			      &symkey.key, 
   10.86 -			      &symkey_cipher) );
   10.87 -  
   10.88 -  // Create output blob: symkey_size + symkey_cipher + state_cipher_size + state_cipher
   10.89 -  
   10.90 -  symkey_cipher32.size = buffer_len(&symkey_cipher);
   10.91 -  symkey_cipher32.data = symkey_cipher.bytes;
   10.92 -  
   10.93 -  state_cipher32.size = buffer_len(&state_cipher);
   10.94 -  state_cipher32.data = state_cipher.bytes;
   10.95 -  
   10.96 -  sealed_NVM = (BYTE *) malloc( 2 * sizeof(UINT32) + symkey_cipher32.size + state_cipher32.size);
   10.97 -  
   10.98 -  sealed_NVM_size = BSG_PackList(sealed_NVM, 2,
   10.99 -				 BSG_TPM_SIZE32_DATA, &symkey_cipher32,
  10.100 -				 BSG_TPM_SIZE32_DATA, &state_cipher32);
  10.101 -  
  10.102 -  // Mark DMI Table so new save state info will get pushed to disk on return.
  10.103 -  vtpm_globals->DMI_table_dirty = TRUE;
  10.104 -  
  10.105 -  // Write sealed blob off disk from NVMLocation
  10.106 -  // TODO: How to properly return from these. Do we care if we return failure
  10.107 -  //       after writing the file? We can't get the old one back.
  10.108 -  // TODO: Backup old file and try and recover that way.
  10.109 -  fh = open(myDMI->NVMLocation, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
  10.110 -  if ( (bytes_written = write(fh, sealed_NVM, sealed_NVM_size) ) != (long) sealed_NVM_size) {
  10.111 -    vtpmlogerror(VTPM_LOG_VTPM, "We just overwrote a DMI_NVM and failed to finish. %ld/%ld bytes.\n", bytes_written, (long)sealed_NVM_size);
  10.112 -    status = TPM_IOERROR;
  10.113 -    goto abort_egress;
  10.114 -  }
  10.115 -  close(fh);
  10.116 -  
  10.117 -  Crypto_SHA1Full (sealed_NVM, sealed_NVM_size, (BYTE *) &myDMI->NVM_measurement);   
  10.118 -  
  10.119 -  vtpmloginfo(VTPM_LOG_VTPM, "Saved %d bytes of E(symkey) + %d bytes of E(NVM)\n", buffer_len(&symkey_cipher), buffer_len(&state_cipher));
  10.120 -  goto egress;
  10.121 -  
  10.122 - abort_egress:
  10.123 -  vtpmlogerror(VTPM_LOG_VTPM, "Failed to load NVM\n.");
  10.124 -  
  10.125 - egress:
  10.126 -  
  10.127 -  buffer_free ( &state_cipher);
  10.128 -  buffer_free ( &symkey_cipher);
  10.129 -  free(sealed_NVM);
  10.130 -  Crypto_symcrypto_freekey (&symkey);
  10.131 -  
  10.132 -  return status;
  10.133 -}
  10.134 -
  10.135 -
  10.136 -/* inbuf = null outbuf = sealed blob size, sealed blob.*/
  10.137 -TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI_RESOURCE *myDMI, 
  10.138 -				const buffer_t *inbuf, 
  10.139 -				buffer_t *outbuf) {
  10.140 -  
  10.141 -  TPM_RESULT status = TPM_SUCCESS;
  10.142 -  symkey_t    symkey;
  10.143 -  buffer_t    state_cipher = NULL_BUF, 
  10.144 -              symkey_clear = NULL_BUF, 
  10.145 -              symkey_cipher = NULL_BUF;
  10.146 -  struct pack_buf_t symkey_cipher32, state_cipher32;
  10.147 -  
  10.148 -  UINT32 sealed_NVM_size;
  10.149 -  BYTE *sealed_NVM = NULL;
  10.150 -  long fh_size;
  10.151 -  int fh, stat_ret, i;
  10.152 -  struct stat file_stat;
  10.153 -  TPM_DIGEST sealedNVMHash;
  10.154 -  
  10.155 -  memset(&symkey, 0, sizeof(symkey_t));
  10.156 -  
  10.157 -  if (myDMI->NVMLocation == NULL) {
  10.158 -    vtpmlogerror(VTPM_LOG_VTPM, "Unable to load NVM because the file name NULL.\n");
  10.159 -    status = TPM_AUTHFAIL;
  10.160 -    goto abort_egress;
  10.161 -  }
  10.162 -  
  10.163 -  //Read sealed blob off disk from NVMLocation
  10.164 -  fh = open(myDMI->NVMLocation, O_RDONLY);
  10.165 -  stat_ret = fstat(fh, &file_stat);
  10.166 -  if (stat_ret == 0) 
  10.167 -    fh_size = file_stat.st_size;
  10.168 -  else {
  10.169 -    status = TPM_IOERROR;
  10.170 -    goto abort_egress;
  10.171 -  }
  10.172 -  
  10.173 -  sealed_NVM = (BYTE *) malloc(fh_size);
  10.174 -  if (read(fh, sealed_NVM, fh_size) != fh_size) {
  10.175 -    status = TPM_IOERROR;
  10.176 -    goto abort_egress;
  10.177 -  }
  10.178 -  close(fh);
  10.179 -  
  10.180 -  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Load_NVMing[%ld]: 0x", fh_size);
  10.181 -  for (i=0; i< fh_size; i++)
  10.182 -    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", sealed_NVM[i]);
  10.183 -  vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
  10.184 -  
  10.185 -  sealed_NVM_size = BSG_UnpackList(sealed_NVM, 2,
  10.186 -				   BSG_TPM_SIZE32_DATA, &symkey_cipher32,
  10.187 -				   BSG_TPM_SIZE32_DATA, &state_cipher32);
  10.188 -  
  10.189 -  TPMTRYRETURN( buffer_init_convert (&symkey_cipher, 
  10.190 -				     symkey_cipher32.size, 
  10.191 -				     symkey_cipher32.data) );
  10.192 -  
  10.193 -  TPMTRYRETURN( buffer_init_convert (&state_cipher, 
  10.194 -				     state_cipher32.size, 
  10.195 -				     state_cipher32.data) );
  10.196 -  
  10.197 -  Crypto_SHA1Full(sealed_NVM, sealed_NVM_size, (BYTE *) &sealedNVMHash);    
  10.198 -  
  10.199 -  // Verify measurement of sealed blob.
  10.200 -  if (memcmp(&sealedNVMHash, &myDMI->NVM_measurement, sizeof(TPM_DIGEST)) ) {
  10.201 -    vtpmlogerror(VTPM_LOG_VTPM, "VTPM LoadNVM NVM measurement check failed.\n");
  10.202 -    vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Correct hash: ");
  10.203 -    for (i=0; i< sizeof(TPM_DIGEST); i++)
  10.204 -      vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", ((BYTE*)&myDMI->NVM_measurement)[i]);
  10.205 -    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
  10.206 -
  10.207 -    vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Measured hash: ");
  10.208 -    for (i=0; i< sizeof(TPM_DIGEST); i++)
  10.209 -      vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", ((BYTE*)&sealedNVMHash)[i]);
  10.210 -    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
  10.211 -    
  10.212 -    status = TPM_AUTHFAIL;
  10.213 -    goto abort_egress;
  10.214 -  }
  10.215 -  
  10.216 -  // Decrypt Symmetric Key
  10.217 -  TPMTRYRETURN( VTSP_Unbind(  myDMI->TCSContext,
  10.218 -			      vtpm_globals->storageKeyHandle,
  10.219 -			      &symkey_cipher,
  10.220 -			      (const TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
  10.221 -			      &symkey_clear,
  10.222 -			      &(vtpm_globals->keyAuth) ) );
  10.223 -  
  10.224 -  // create symmetric key using saved bits
  10.225 -  Crypto_symcrypto_initkey (&symkey, &symkey_clear);
  10.226 -  
  10.227 -  // Decrypt State
  10.228 -  TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (&symkey, &state_cipher, outbuf) );
  10.229 -  
  10.230 -  goto egress;
  10.231 -  
  10.232 - abort_egress:
  10.233 -  vtpmlogerror(VTPM_LOG_VTPM, "Failed to load NVM\n.");
  10.234 -  
  10.235 - egress:
  10.236 -  
  10.237 -  buffer_free ( &state_cipher);
  10.238 -  buffer_free ( &symkey_clear);
  10.239 -  buffer_free ( &symkey_cipher);
  10.240 -  free( sealed_NVM );
  10.241 -  Crypto_symcrypto_freekey (&symkey);
  10.242 -  
  10.243 -  return status;
  10.244 -}
  10.245 -
  10.246 -TPM_RESULT VTPM_SaveService(void) {
  10.247 -  TPM_RESULT status=TPM_SUCCESS;
  10.248 -  int fh, dmis=-1;
  10.249 -  
  10.250 -  BYTE *flat_global;
  10.251 -  int flat_global_size, bytes_written;
  10.252 -  UINT32 storageKeySize = buffer_len(&vtpm_globals->storageKeyWrap);
  10.253 -  struct pack_buf_t storage_key_pack = {storageKeySize, vtpm_globals->storageKeyWrap.bytes};
  10.254 -  
  10.255 -  struct hashtable_itr *dmi_itr;
  10.256 -  VTPM_DMI_RESOURCE *dmi_res;
  10.257 -  
  10.258 -  UINT32 flat_global_full_size;
  10.259 -  
  10.260 -  // Global Values needing to be saved
  10.261 -  flat_global_full_size = 3*sizeof(TPM_DIGEST) + // Auths
  10.262 -    sizeof(UINT32) +       // storagekeysize
  10.263 -    storageKeySize +       // storage key
  10.264 -    hashtable_count(vtpm_globals->dmi_map) * // num DMIS
  10.265 -    (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)); // Per DMI info
  10.266 -  
  10.267 -  
  10.268 -  flat_global = (BYTE *) malloc( flat_global_full_size);
  10.269 -  
  10.270 -  flat_global_size = BSG_PackList(flat_global, 4,
  10.271 -				  BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
  10.272 -				  BSG_TPM_AUTHDATA, &vtpm_globals->srk_usage_auth,
  10.273 -				  BSG_TPM_SECRET,   &vtpm_globals->storage_key_usage_auth,
  10.274 -				  BSG_TPM_SIZE32_DATA, &storage_key_pack);
  10.275 -  
  10.276 -  // Per DMI values to be saved
  10.277 -  if (hashtable_count(vtpm_globals->dmi_map) > 0) {
  10.278 -    
  10.279 -    dmi_itr = hashtable_iterator(vtpm_globals->dmi_map);
  10.280 -    do {
  10.281 -      dmi_res = (VTPM_DMI_RESOURCE *) hashtable_iterator_value(dmi_itr);
  10.282 -      dmis++;
  10.283 -
  10.284 -      // No need to save dmi0.
  10.285 -      if (dmi_res->dmi_id == 0) 	
  10.286 -	continue;
  10.287 -      
  10.288 -      
  10.289 -      flat_global_size += BSG_PackList( flat_global + flat_global_size, 3,
  10.290 -					BSG_TYPE_UINT32, &dmi_res->dmi_id,
  10.291 -					BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
  10.292 -					BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
  10.293 -      
  10.294 -    } while (hashtable_iterator_advance(dmi_itr));
  10.295 -  }
  10.296 -  
  10.297 -  //FIXME: Once we have a way to protect a TPM key, we should use it to 
  10.298 -  //       encrypt this blob. BUT, unless there is a way to ensure the key is
  10.299 -  //       not used by other apps, this encryption is useless.
  10.300 -  fh = open(STATE_FILE, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
  10.301 -  if (fh == -1) {
  10.302 -    vtpmlogerror(VTPM_LOG_VTPM, "Unable to open %s file for write.\n", STATE_FILE);
  10.303 -    status = TPM_IOERROR;
  10.304 -    goto abort_egress;
  10.305 -  }
  10.306 -  
  10.307 -  if ( (bytes_written = write(fh, flat_global, flat_global_size)) != flat_global_size ) {
  10.308 -    vtpmlogerror(VTPM_LOG_VTPM, "Failed to save service data. %d/%d bytes written.\n", bytes_written, flat_global_size);
  10.309 -    status = TPM_IOERROR;
  10.310 -    goto abort_egress;
  10.311 -  }
  10.312 -  vtpm_globals->DMI_table_dirty = FALSE; 
  10.313 -  
  10.314 -  goto egress;
  10.315 -  
  10.316 - abort_egress:
  10.317 - egress:
  10.318 -  
  10.319 -  free(flat_global);
  10.320 -  close(fh);
  10.321 -  
  10.322 -  vtpmloginfo(VTPM_LOG_VTPM, "Saved VTPM Service state (status = %d, dmis = %d)\n", (int) status, dmis);
  10.323 -  return status;
  10.324 -}
  10.325 -
  10.326 -TPM_RESULT VTPM_LoadService(void) {
  10.327 -  
  10.328 -  TPM_RESULT status=TPM_SUCCESS;
  10.329 -  int fh, stat_ret, dmis=0;
  10.330 -  long fh_size = 0, step_size;
  10.331 -  BYTE *flat_global=NULL;
  10.332 -  struct pack_buf_t storage_key_pack;
  10.333 -  UINT32 *dmi_id_key;
  10.334 -  
  10.335 -  VTPM_DMI_RESOURCE *dmi_res;
  10.336 -  struct stat file_stat;
  10.337 -  
  10.338 -  fh = open(STATE_FILE, O_RDONLY );
  10.339 -  stat_ret = fstat(fh, &file_stat);
  10.340 -  if (stat_ret == 0) 
  10.341 -    fh_size = file_stat.st_size;
  10.342 -  else {
  10.343 -    status = TPM_IOERROR;
  10.344 -    goto abort_egress;
  10.345 -  }
  10.346 -  
  10.347 -  flat_global = (BYTE *) malloc(fh_size);
  10.348 -  
  10.349 -  if ((long) read(fh, flat_global, fh_size) != fh_size ) {
  10.350 -    status = TPM_IOERROR;
  10.351 -    goto abort_egress;
  10.352 -  }
  10.353 -  
  10.354 -  // Global Values needing to be saved
  10.355 -  step_size = BSG_UnpackList( flat_global, 4,
  10.356 -			      BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
  10.357 -			      BSG_TPM_AUTHDATA, &vtpm_globals->srk_usage_auth,
  10.358 -			      BSG_TPM_SECRET,   &vtpm_globals->storage_key_usage_auth,
  10.359 -			      BSG_TPM_SIZE32_DATA, &storage_key_pack);
  10.360 -  
  10.361 -  TPMTRYRETURN(buffer_init(&vtpm_globals->storageKeyWrap, 0, 0) );
  10.362 -  TPMTRYRETURN(buffer_append_raw(&vtpm_globals->storageKeyWrap, storage_key_pack.size, storage_key_pack.data) );
  10.363 -  
  10.364 -  // Per DMI values to be saved
  10.365 -  while ( step_size < fh_size ){
  10.366 -    if (fh_size - step_size < (long) (sizeof(UINT32) + 2*sizeof(TPM_DIGEST))) {
  10.367 -      vtpmlogerror(VTPM_LOG_VTPM, "Encountered %ld extra bytes at end of manager state.\n", fh_size-step_size);
  10.368 -      step_size = fh_size;
  10.369 -    } else {
  10.370 -      dmi_res = (VTPM_DMI_RESOURCE *) malloc(sizeof(VTPM_DMI_RESOURCE));
  10.371 -      dmis++;
  10.372 -      
  10.373 -      dmi_res->connected = FALSE;
  10.374 -      
  10.375 -      step_size += BSG_UnpackList(flat_global + step_size, 3,
  10.376 -				  BSG_TYPE_UINT32, &dmi_res->dmi_id, 
  10.377 -				  BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
  10.378 -				  BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
  10.379 -      
  10.380 -      // install into map
  10.381 -      dmi_id_key = (UINT32 *) malloc (sizeof(UINT32));
  10.382 -      *dmi_id_key = dmi_res->dmi_id;
  10.383 -      if (!hashtable_insert(vtpm_globals->dmi_map, dmi_id_key, dmi_res)) {
  10.384 -	status = TPM_FAIL;
  10.385 -	goto abort_egress;
  10.386 -      }
  10.387 -      
  10.388 -    }
  10.389 -    
  10.390 -  }
  10.391 -  
  10.392 -  goto egress;
  10.393 -  
  10.394 - abort_egress:
  10.395 -  vtpmlogerror(VTPM_LOG_VTPM, "Failed to save service data\n");
  10.396 - egress:
  10.397 -  
  10.398 -  if (flat_global)
  10.399 -    free(flat_global);
  10.400 -  close(fh);
  10.401 -  
  10.402 -  vtpmloginfo(VTPM_LOG_VTPM, "Previously saved state reloaded (status = %d, dmis = %d).\n", (int) status, dmis);
  10.403 -  return status;
  10.404 -}
  10.405 +// ===================================================================
  10.406 +// 
  10.407 +// Copyright (c) 2005, Intel Corp.
  10.408 +// All rights reserved.
  10.409 +//
  10.410 +// Redistribution and use in source and binary forms, with or without 
  10.411 +// modification, are permitted provided that the following conditions 
  10.412 +// are met:
  10.413 +//
  10.414 +//   * Redistributions of source code must retain the above copyright 
  10.415 +//     notice, this list of conditions and the following disclaimer.
  10.416 +//   * Redistributions in binary form must reproduce the above 
  10.417 +//     copyright notice, this list of conditions and the following 
  10.418 +//     disclaimer in the documentation and/or other materials provided 
  10.419 +//     with the distribution.
  10.420 +//   * Neither the name of Intel Corporation nor the names of its 
  10.421 +//     contributors may be used to endorse or promote products derived
  10.422 +//     from this software without specific prior written permission.
  10.423 +//
  10.424 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  10.425 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  10.426 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
  10.427 +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
  10.428 +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  10.429 +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  10.430 +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
  10.431 +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  10.432 +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
  10.433 +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
  10.434 +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  10.435 +// OF THE POSSIBILITY OF SUCH DAMAGE.
  10.436 +// ===================================================================
  10.437 +// 
  10.438 +// securestorage.c
  10.439 +// 
  10.440 +//  Functions regarding securely storing DMI secrets.
  10.441 +//
  10.442 +// ==================================================================
  10.443 +
  10.444 +#include <sys/types.h>
  10.445 +#include <sys/stat.h>
  10.446 +#include <fcntl.h>
  10.447 +#include <unistd.h>
  10.448 +#include <string.h>
  10.449 +
  10.450 +#include "tcg.h"
  10.451 +#include "vtpm_manager.h"
  10.452 +#include "vtpmpriv.h"
  10.453 +#include "vtsp.h"
  10.454 +#include "bsg.h"
  10.455 +#include "crypto.h"
  10.456 +#include "hashtable.h"
  10.457 +#include "hashtable_itr.h"
  10.458 +#include "buffer.h"
  10.459 +#include "log.h"
  10.460 +
  10.461 +TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI_RESOURCE *myDMI, 
  10.462 +				const buffer_t *inbuf, 
  10.463 +				buffer_t *outbuf) {
  10.464 +  
  10.465 +  TPM_RESULT status = TPM_SUCCESS;
  10.466 +  symkey_t    symkey;
  10.467 +  buffer_t    state_cipher = NULL_BUF,
  10.468 +              symkey_cipher = NULL_BUF;
  10.469 +  int fh;
  10.470 +  long bytes_written;
  10.471 +  BYTE *sealed_NVM=NULL;
  10.472 +  UINT32 sealed_NVM_size, i;
  10.473 +  struct pack_constbuf_t symkey_cipher32, state_cipher32;
  10.474 +  
  10.475 +  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Save_NVMing[%d]: 0x", buffer_len(inbuf));
  10.476 +  for (i=0; i< buffer_len(inbuf); i++)
  10.477 +    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", inbuf->bytes[i]);
  10.478 +  vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
  10.479 +  
  10.480 +  // Generate a sym key and encrypt state with it
  10.481 +  TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_genkey (&symkey) );
  10.482 +  TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_encrypt (&symkey, inbuf, &state_cipher) );
  10.483 +  
  10.484 +  // Encrypt symmetric key
  10.485 +  TPMTRYRETURN( VTSP_Bind(    &vtpm_globals->storageKey, 
  10.486 +			      &symkey.key, 
  10.487 +			      &symkey_cipher) );
  10.488 +  
  10.489 +  // Create output blob: symkey_size + symkey_cipher + state_cipher_size + state_cipher
  10.490 +  
  10.491 +  symkey_cipher32.size = buffer_len(&symkey_cipher);
  10.492 +  symkey_cipher32.data = symkey_cipher.bytes;
  10.493 +  
  10.494 +  state_cipher32.size = buffer_len(&state_cipher);
  10.495 +  state_cipher32.data = state_cipher.bytes;
  10.496 +  
  10.497 +  sealed_NVM = (BYTE *) malloc( 2 * sizeof(UINT32) + symkey_cipher32.size + state_cipher32.size);
  10.498 +  
  10.499 +  sealed_NVM_size = BSG_PackList(sealed_NVM, 2,
  10.500 +				 BSG_TPM_SIZE32_DATA, &symkey_cipher32,
  10.501 +				 BSG_TPM_SIZE32_DATA, &state_cipher32);
  10.502 +  
  10.503 +  // Mark DMI Table so new save state info will get pushed to disk on return.
  10.504 +  vtpm_globals->DMI_table_dirty = TRUE;
  10.505 +  
  10.506 +  // Write sealed blob off disk from NVMLocation
  10.507 +  // TODO: How to properly return from these. Do we care if we return failure
  10.508 +  //       after writing the file? We can't get the old one back.
  10.509 +  // TODO: Backup old file and try and recover that way.
  10.510 +  fh = open(myDMI->NVMLocation, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
  10.511 +  if ( (bytes_written = write(fh, sealed_NVM, sealed_NVM_size) ) != (long) sealed_NVM_size) {
  10.512 +    vtpmlogerror(VTPM_LOG_VTPM, "We just overwrote a DMI_NVM and failed to finish. %ld/%ld bytes.\n", bytes_written, (long)sealed_NVM_size);
  10.513 +    status = TPM_IOERROR;
  10.514 +    goto abort_egress;
  10.515 +  }
  10.516 +  close(fh);
  10.517 +  
  10.518 +  Crypto_SHA1Full (sealed_NVM, sealed_NVM_size, (BYTE *) &myDMI->NVM_measurement);   
  10.519 +  
  10.520 +  vtpmloginfo(VTPM_LOG_VTPM, "Saved %d bytes of E(symkey) + %d bytes of E(NVM)\n", buffer_len(&symkey_cipher), buffer_len(&state_cipher));
  10.521 +  goto egress;
  10.522 +  
  10.523 + abort_egress:
  10.524 +  vtpmlogerror(VTPM_LOG_VTPM, "Failed to load NVM\n.");
  10.525 +  
  10.526 + egress:
  10.527 +  
  10.528 +  buffer_free ( &state_cipher);
  10.529 +  buffer_free ( &symkey_cipher);
  10.530 +  free(sealed_NVM);
  10.531 +  Crypto_symcrypto_freekey (&symkey);
  10.532 +  
  10.533 +  return status;
  10.534 +}
  10.535 +
  10.536 +
  10.537 +/* inbuf = null outbuf = sealed blob size, sealed blob.*/
  10.538 +TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI_RESOURCE *myDMI, 
  10.539 +				const buffer_t *inbuf, 
  10.540 +				buffer_t *outbuf) {
  10.541 +  
  10.542 +  TPM_RESULT status = TPM_SUCCESS;
  10.543 +  symkey_t    symkey;
  10.544 +  buffer_t    state_cipher = NULL_BUF, 
  10.545 +              symkey_clear = NULL_BUF, 
  10.546 +              symkey_cipher = NULL_BUF;
  10.547 +  struct pack_buf_t symkey_cipher32, state_cipher32;
  10.548 +  
  10.549 +  UINT32 sealed_NVM_size;
  10.550 +  BYTE *sealed_NVM = NULL;
  10.551 +  long fh_size;
  10.552 +  int fh, stat_ret, i;
  10.553 +  struct stat file_stat;
  10.554 +  TPM_DIGEST sealedNVMHash;
  10.555 +  
  10.556 +  memset(&symkey, 0, sizeof(symkey_t));
  10.557 +  
  10.558 +  if (myDMI->NVMLocation == NULL) {
  10.559 +    vtpmlogerror(VTPM_LOG_VTPM, "Unable to load NVM because the file name NULL.\n");
  10.560 +    status = TPM_AUTHFAIL;
  10.561 +    goto abort_egress;
  10.562 +  }
  10.563 +  
  10.564 +  //Read sealed blob off disk from NVMLocation
  10.565 +  fh = open(myDMI->NVMLocation, O_RDONLY);
  10.566 +  stat_ret = fstat(fh, &file_stat);
  10.567 +  if (stat_ret == 0) 
  10.568 +    fh_size = file_stat.st_size;
  10.569 +  else {
  10.570 +    status = TPM_IOERROR;
  10.571 +    goto abort_egress;
  10.572 +  }
  10.573 +  
  10.574 +  sealed_NVM = (BYTE *) malloc(fh_size);
  10.575 +  if (read(fh, sealed_NVM, fh_size) != fh_size) {
  10.576 +    status = TPM_IOERROR;
  10.577 +    goto abort_egress;
  10.578 +  }
  10.579 +  close(fh);
  10.580 +  
  10.581 +  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Load_NVMing[%ld]: 0x", fh_size);
  10.582 +  for (i=0; i< fh_size; i++)
  10.583 +    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", sealed_NVM[i]);
  10.584 +  vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
  10.585 +  
  10.586 +  sealed_NVM_size = BSG_UnpackList(sealed_NVM, 2,
  10.587 +				   BSG_TPM_SIZE32_DATA, &symkey_cipher32,
  10.588 +				   BSG_TPM_SIZE32_DATA, &state_cipher32);
  10.589 +  
  10.590 +  TPMTRYRETURN( buffer_init_convert (&symkey_cipher, 
  10.591 +				     symkey_cipher32.size, 
  10.592 +				     symkey_cipher32.data) );
  10.593 +  
  10.594 +  TPMTRYRETURN( buffer_init_convert (&state_cipher, 
  10.595 +				     state_cipher32.size, 
  10.596 +				     state_cipher32.data) );
  10.597 +  
  10.598 +  Crypto_SHA1Full(sealed_NVM, sealed_NVM_size, (BYTE *) &sealedNVMHash);    
  10.599 +  
  10.600 +  // Verify measurement of sealed blob.
  10.601 +  if (memcmp(&sealedNVMHash, &myDMI->NVM_measurement, sizeof(TPM_DIGEST)) ) {
  10.602 +    vtpmlogerror(VTPM_LOG_VTPM, "VTPM LoadNVM NVM measurement check failed.\n");
  10.603 +    vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Correct hash: ");
  10.604 +    for (i=0; i< sizeof(TPM_DIGEST); i++)
  10.605 +      vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", ((BYTE*)&myDMI->NVM_measurement)[i]);
  10.606 +    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
  10.607 +
  10.608 +    vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Measured hash: ");
  10.609 +    for (i=0; i< sizeof(TPM_DIGEST); i++)
  10.610 +      vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", ((BYTE*)&sealedNVMHash)[i]);
  10.611 +    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
  10.612 +    
  10.613 +    status = TPM_AUTHFAIL;
  10.614 +    goto abort_egress;
  10.615 +  }
  10.616 +  
  10.617 +  // Decrypt Symmetric Key
  10.618 +  TPMTRYRETURN( VTSP_Unbind(  myDMI->TCSContext,
  10.619 +			      vtpm_globals->storageKeyHandle,
  10.620 +			      &symkey_cipher,
  10.621 +			      (const TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
  10.622 +			      &symkey_clear,
  10.623 +			      &(vtpm_globals->keyAuth) ) );
  10.624 +  
  10.625 +  // create symmetric key using saved bits
  10.626 +  Crypto_symcrypto_initkey (&symkey, &symkey_clear);
  10.627 +  
  10.628 +  // Decrypt State
  10.629 +  TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (&symkey, &state_cipher, outbuf) );
  10.630 +  
  10.631 +  goto egress;
  10.632 +  
  10.633 + abort_egress:
  10.634 +  vtpmlogerror(VTPM_LOG_VTPM, "Failed to load NVM\n.");
  10.635 +  
  10.636 + egress:
  10.637 +  
  10.638 +  buffer_free ( &state_cipher);
  10.639 +  buffer_free ( &symkey_clear);
  10.640 +  buffer_free ( &symkey_cipher);
  10.641 +  free( sealed_NVM );
  10.642 +  Crypto_symcrypto_freekey (&symkey);
  10.643 +  
  10.644 +  return status;
  10.645 +}
  10.646 +
  10.647 +TPM_RESULT VTPM_SaveService(void) {
  10.648 +  TPM_RESULT status=TPM_SUCCESS;
  10.649 +  int fh, dmis=-1;
  10.650 +  
  10.651 +  BYTE *flat_global;
  10.652 +  int flat_global_size, bytes_written;
  10.653 +  UINT32 storageKeySize = buffer_len(&vtpm_globals->storageKeyWrap);
  10.654 +  struct pack_buf_t storage_key_pack = {storageKeySize, vtpm_globals->storageKeyWrap.bytes};
  10.655 +  
  10.656 +  struct hashtable_itr *dmi_itr;
  10.657 +  VTPM_DMI_RESOURCE *dmi_res;
  10.658 +  
  10.659 +  UINT32 flat_global_full_size;
  10.660 +  
  10.661 +  // Global Values needing to be saved
  10.662 +  flat_global_full_size = 3*sizeof(TPM_DIGEST) + // Auths
  10.663 +    sizeof(UINT32) +       // storagekeysize
  10.664 +    storageKeySize +       // storage key
  10.665 +    hashtable_count(vtpm_globals->dmi_map) * // num DMIS
  10.666 +    (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)); // Per DMI info
  10.667 +  
  10.668 +  
  10.669 +  flat_global = (BYTE *) malloc( flat_global_full_size);
  10.670 +  
  10.671 +  flat_global_size = BSG_PackList(flat_global, 4,
  10.672 +				  BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
  10.673 +				  BSG_TPM_AUTHDATA, &vtpm_globals->srk_usage_auth,
  10.674 +				  BSG_TPM_SECRET,   &vtpm_globals->storage_key_usage_auth,
  10.675 +				  BSG_TPM_SIZE32_DATA, &storage_key_pack);
  10.676 +  
  10.677 +  // Per DMI values to be saved
  10.678 +  if (hashtable_count(vtpm_globals->dmi_map) > 0) {
  10.679 +    
  10.680 +    dmi_itr = hashtable_iterator(vtpm_globals->dmi_map);
  10.681 +    do {
  10.682 +      dmi_res = (VTPM_DMI_RESOURCE *) hashtable_iterator_value(dmi_itr);
  10.683 +      dmis++;
  10.684 +
  10.685 +      // No need to save dmi0.
  10.686 +      if (dmi_res->dmi_id == 0) 	
  10.687 +	continue;
  10.688 +      
  10.689 +      
  10.690 +      flat_global_size += BSG_PackList( flat_global + flat_global_size, 3,
  10.691 +					BSG_TYPE_UINT32, &dmi_res->dmi_id,
  10.692 +					BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
  10.693 +					BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
  10.694 +      
  10.695 +    } while (hashtable_iterator_advance(dmi_itr));
  10.696 +  }
  10.697 +  
  10.698 +  //FIXME: Once we have a way to protect a TPM key, we should use it to 
  10.699 +  //       encrypt this blob. BUT, unless there is a way to ensure the key is
  10.700 +  //       not used by other apps, this encryption is useless.
  10.701 +  fh = open(STATE_FILE, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
  10.702 +  if (fh == -1) {
  10.703 +    vtpmlogerror(VTPM_LOG_VTPM, "Unable to open %s file for write.\n", STATE_FILE);
  10.704 +    status = TPM_IOERROR;
  10.705 +    goto abort_egress;
  10.706 +  }
  10.707 +  
  10.708 +  if ( (bytes_written = write(fh, flat_global, flat_global_size)) != flat_global_size ) {
  10.709 +    vtpmlogerror(VTPM_LOG_VTPM, "Failed to save service data. %d/%d bytes written.\n", bytes_written, flat_global_size);
  10.710 +    status = TPM_IOERROR;
  10.711 +    goto abort_egress;
  10.712 +  }
  10.713 +  vtpm_globals->DMI_table_dirty = FALSE; 
  10.714 +  
  10.715 +  goto egress;
  10.716 +  
  10.717 + abort_egress:
  10.718 + egress:
  10.719 +  
  10.720 +  free(flat_global);
  10.721 +  close(fh);
  10.722 +  
  10.723 +  vtpmloginfo(VTPM_LOG_VTPM, "Saved VTPM Service state (status = %d, dmis = %d)\n", (int) status, dmis);
  10.724 +  return status;
  10.725 +}
  10.726 +
  10.727 +TPM_RESULT VTPM_LoadService(void) {
  10.728 +  
  10.729 +  TPM_RESULT status=TPM_SUCCESS;
  10.730 +  int fh, stat_ret, dmis=0;
  10.731 +  long fh_size = 0, step_size;
  10.732 +  BYTE *flat_global=NULL;
  10.733 +  struct pack_buf_t storage_key_pack;
  10.734 +  UINT32 *dmi_id_key;
  10.735 +  
  10.736 +  VTPM_DMI_RESOURCE *dmi_res;
  10.737 +  struct stat file_stat;
  10.738 +  
  10.739 +  fh = open(STATE_FILE, O_RDONLY );
  10.740 +  stat_ret = fstat(fh, &file_stat);
  10.741 +  if (stat_ret == 0) 
  10.742 +    fh_size = file_stat.st_size;
  10.743 +  else {
  10.744 +    status = TPM_IOERROR;
  10.745 +    goto abort_egress;
  10.746 +  }
  10.747 +  
  10.748 +  flat_global = (BYTE *) malloc(fh_size);
  10.749 +  
  10.750 +  if ((long) read(fh, flat_global, fh_size) != fh_size ) {
  10.751 +    status = TPM_IOERROR;
  10.752 +    goto abort_egress;
  10.753 +  }
  10.754 +  
  10.755 +  // Global Values needing to be saved
  10.756 +  step_size = BSG_UnpackList( flat_global, 4,
  10.757 +			      BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
  10.758 +			      BSG_TPM_AUTHDATA, &vtpm_globals->srk_usage_auth,
  10.759 +			      BSG_TPM_SECRET,   &vtpm_globals->storage_key_usage_auth,
  10.760 +			      BSG_TPM_SIZE32_DATA, &storage_key_pack);
  10.761 +  
  10.762 +  TPMTRYRETURN(buffer_init(&vtpm_globals->storageKeyWrap, 0, 0) );
  10.763 +  TPMTRYRETURN(buffer_append_raw(&vtpm_globals->storageKeyWrap, storage_key_pack.size, storage_key_pack.data) );
  10.764 +  
  10.765 +  // Per DMI values to be saved
  10.766 +  while ( step_size < fh_size ){
  10.767 +    if (fh_size - step_size < (long) (sizeof(UINT32) + 2*sizeof(TPM_DIGEST))) {
  10.768 +      vtpmlogerror(VTPM_LOG_VTPM, "Encountered %ld extra bytes at end of manager state.\n", fh_size-step_size);
  10.769 +      step_size = fh_size;
  10.770 +    } else {
  10.771 +      dmi_res = (VTPM_DMI_RESOURCE *) malloc(sizeof(VTPM_DMI_RESOURCE));
  10.772 +      dmis++;
  10.773 +      
  10.774 +      dmi_res->connected = FALSE;
  10.775 +      
  10.776 +      step_size += BSG_UnpackList(flat_global + step_size, 3,
  10.777 +				  BSG_TYPE_UINT32, &dmi_res->dmi_id, 
  10.778 +				  BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
  10.779 +				  BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
  10.780 +      
  10.781 +      // install into map
  10.782 +      dmi_id_key = (UINT32 *) malloc (sizeof(UINT32));
  10.783 +      *dmi_id_key = dmi_res->dmi_id;
  10.784 +      if (!hashtable_insert(vtpm_globals->dmi_map, dmi_id_key, dmi_res)) {
  10.785 +	status = TPM_FAIL;
  10.786 +	goto abort_egress;
  10.787 +      }
  10.788 +      
  10.789 +    }
  10.790 +    
  10.791 +  }
  10.792 +  
  10.793 +  vtpmloginfo(VTPM_LOG_VTPM, "Loaded saved state (dmis = %d).\n", dmis);
  10.794 +  goto egress;
  10.795 +  
  10.796 + abort_egress:
  10.797 +  vtpmlogerror(VTPM_LOG_VTPM, "Failed to load service data with error = %s\n", tpm_get_error_name(status));
  10.798 + egress:
  10.799 +  
  10.800 +  if (flat_global)
  10.801 +    free(flat_global);
  10.802 +  close(fh);
  10.803 +  
  10.804 +  return status;
  10.805 +}
    11.1 --- a/tools/vtpm_manager/manager/vtpm_manager.c	Tue Sep 20 09:05:03 2005 +0000
    11.2 +++ b/tools/vtpm_manager/manager/vtpm_manager.c	Tue Sep 20 09:08:26 2005 +0000
    11.3 @@ -1,735 +1,811 @@
    11.4 -// ===================================================================
    11.5 -// 
    11.6 -// Copyright (c) 2005, Intel Corp.
    11.7 -// All rights reserved.
    11.8 -//
    11.9 -// Redistribution and use in source and binary forms, with or without 
   11.10 -// modification, are permitted provided that the following conditions 
   11.11 -// are met:
   11.12 -//
   11.13 -//   * Redistributions of source code must retain the above copyright 
   11.14 -//     notice, this list of conditions and the following disclaimer.
   11.15 -//   * Redistributions in binary form must reproduce the above 
   11.16 -//     copyright notice, this list of conditions and the following 
   11.17 -//     disclaimer in the documentation and/or other materials provided 
   11.18 -//     with the distribution.
   11.19 -//   * Neither the name of Intel Corporation nor the names of its 
   11.20 -//     contributors may be used to endorse or promote products derived
   11.21 -//     from this software without specific prior written permission.
   11.22 -//
   11.23 -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   11.24 -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   11.25 -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
   11.26 -// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
   11.27 -// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   11.28 -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   11.29 -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
   11.30 -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   11.31 -// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
   11.32 -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
   11.33 -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   11.34 -// OF THE POSSIBILITY OF SUCH DAMAGE.
   11.35 -// ===================================================================
   11.36 -// 
   11.37 -// vtpm_manager.c
   11.38 -// 
   11.39 -//  This file will house the main logic of the VTPM Manager
   11.40 -//
   11.41 -// ==================================================================
   11.42 -
   11.43 -#include <stdio.h>
   11.44 -#include <unistd.h>
   11.45 -#include <sys/types.h>
   11.46 -#include <sys/stat.h>
   11.47 -#include <fcntl.h>
   11.48 -#include <string.h>
   11.49 -
   11.50 -#ifndef VTPM_MULTI_VM
   11.51 -#include <pthread.h>
   11.52 -#include <errno.h>
   11.53 -#include <aio.h>
   11.54 -#include <time.h>
   11.55 -#endif
   11.56 -
   11.57 -#include "vtpm_manager.h"
   11.58 -#include "vtpmpriv.h"
   11.59 -#include "vtsp.h"
   11.60 -#include "bsg.h"
   11.61 -#include "hashtable.h"
   11.62 -#include "hashtable_itr.h"
   11.63 -
   11.64 -#include "log.h"
   11.65 -#include "buffer.h"
   11.66 -
   11.67 -VTPM_GLOBALS *vtpm_globals=NULL;
   11.68 -
   11.69 -#ifdef VTPM_MULTI_VM
   11.70 - #define vtpmhandlerloginfo(module,fmt,args...) vtpmloginfo (module, fmt, ##args );
   11.71 - #define vtpmhandlerloginfomore(module,fmt,args...) vtpmloginfomore (module, fmt, ##args );
   11.72 - #define vtpmhandlerlogerror(module,fmt,args...) vtpmlogerror (module, fmt, ##args );
   11.73 -#else 
   11.74 - #define vtpmhandlerloginfo(module,fmt,args...) vtpmloginfo (module, "[%d]: " fmt, threadType, ##args );
   11.75 - #define vtpmhandlerloginfomore(module,fmt,args...) vtpmloginfomore (module, fmt, ##args );
   11.76 - #define vtpmhandlerlogerror(module,fmt,args...) vtpmlogerror (module, "[%d]: " fmt, threadType, ##args );
   11.77 -#endif
   11.78 -
   11.79 -// --------------------------- Static Auths --------------------------
   11.80 -#ifdef USE_FIXED_SRK_AUTH
   11.81 -
   11.82 -static BYTE FIXED_SRK_AUTH[20] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   11.83 -                                  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
   11.84 -
   11.85 -static BYTE FIXED_EK_AUTH[20] =  {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   11.86 -                                  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
   11.87 -
   11.88 -#endif
   11.89 -                                  
   11.90 -// -------------------------- Hash table functions --------------------
   11.91 -
   11.92 -static unsigned int hashfunc32(void *ky) {
   11.93 -  return (* (UINT32 *) ky);
   11.94 -}
   11.95 -
   11.96 -static int equals32(void *k1, void *k2) {
   11.97 -  return (*(UINT32 *) k1 == *(UINT32 *) k2);
   11.98 -}
   11.99 -
  11.100 -// --------------------------- Functions ------------------------------
  11.101 -
  11.102 -TPM_RESULT VTPM_Create_Service(){
  11.103 -  
  11.104 -  TPM_RESULT status = TPM_SUCCESS;
  11.105 -  
  11.106 -  // Generate Auth's for SRK & Owner
  11.107 -#ifdef USE_FIXED_SRK_AUTH
  11.108 -  memcpy(vtpm_globals->owner_usage_auth, FIXED_SRK_AUTH, sizeof(TPM_AUTHDATA));
  11.109 -  memcpy(vtpm_globals->srk_usage_auth, FIXED_EK_AUTH, sizeof(TPM_AUTHDATA));
  11.110 -#else    
  11.111 -  Crypto_GetRandom(vtpm_globals->owner_usage_auth, sizeof(TPM_AUTHDATA) );
  11.112 -  Crypto_GetRandom(vtpm_globals->srk_usage_auth, sizeof(TPM_AUTHDATA) );  
  11.113 -#endif
  11.114 -  
  11.115 -  // Take Owership of TPM
  11.116 -  CRYPTO_INFO ek_cryptoInfo;
  11.117 -  
  11.118 -  vtpmloginfo(VTPM_LOG_VTPM, "Attempting Pubek Read. NOTE: Failure is ok.\n");
  11.119 -  status = VTSP_ReadPubek(vtpm_globals->manager_tcs_handle, &ek_cryptoInfo);
  11.120 -  
  11.121 -  // If we can read PubEK then there is no owner and we should take it.
  11.122 -  if (status == TPM_SUCCESS) { 
  11.123 -    TPMTRYRETURN(VTSP_TakeOwnership(vtpm_globals->manager_tcs_handle,
  11.124 -				    (const TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth, 
  11.125 -				    (const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
  11.126 -				    &ek_cryptoInfo,
  11.127 -				    &vtpm_globals->keyAuth)); 
  11.128 -  
  11.129 -    TPMTRYRETURN(VTSP_DisablePubekRead(vtpm_globals->manager_tcs_handle,
  11.130 -                                       (const TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth,  
  11.131 -                                       &vtpm_globals->keyAuth));     
  11.132 -  }
  11.133 -  
  11.134 -  // Generate storage key's auth
  11.135 -  Crypto_GetRandom(  &vtpm_globals->storage_key_usage_auth, 
  11.136 -		     sizeof(TPM_AUTHDATA) );
  11.137 -  
  11.138 -  TCS_AUTH osap;
  11.139 -  TPM_AUTHDATA sharedsecret;
  11.140 -  
  11.141 -  TPMTRYRETURN( VTSP_OSAP(vtpm_globals->manager_tcs_handle,
  11.142 -			  TPM_ET_SRK,
  11.143 -			  0, 
  11.144 -			  (const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
  11.145 -			  &sharedsecret, 
  11.146 -			  &osap) ); 
  11.147 -  
  11.148 -  TPMTRYRETURN( VTSP_CreateWrapKey( vtpm_globals->manager_tcs_handle,
  11.149 -				    TPM_KEY_BIND,
  11.150 -				    (const TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
  11.151 -				    TPM_SRK_KEYHANDLE, 
  11.152 -				    (const TPM_AUTHDATA*)&sharedsecret,
  11.153 -				    &vtpm_globals->storageKeyWrap,
  11.154 -				    &osap) );
  11.155 -  
  11.156 -  vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
  11.157 -  
  11.158 -  goto egress;
  11.159 -  
  11.160 - abort_egress:
  11.161 -  exit(1);
  11.162 -  
  11.163 - egress:
  11.164 -  vtpmloginfo(VTPM_LOG_VTPM, "New VTPM Service initialized (Status = %d).\n", status);
  11.165 -  return status;
  11.166 -  
  11.167 -}
  11.168 -
  11.169 -
  11.170 -//////////////////////////////////////////////////////////////////////////////
  11.171 -#ifdef VTPM_MULTI_VM
  11.172 -int VTPM_Service_Handler(){
  11.173 -#else
  11.174 -void *VTPM_Service_Handler(void *threadTypePtr){
  11.175 -#endif
  11.176 -  TPM_RESULT      status =  TPM_FAIL; // Should never return
  11.177 -  UINT32          dmi, in_param_size, cmd_size, out_param_size, out_message_size, out_message_size_full, dmi_cmd_size;
  11.178 -  BYTE            *cmd_header, *in_param, *out_message, *dmi_cmd;
  11.179 -  buffer_t        *command_buf=NULL, *result_buf=NULL;
  11.180 -  TPM_TAG         tag;
  11.181 -  TPM_COMMAND_CODE ord;
  11.182 -  VTPM_DMI_RESOURCE *dmi_res;
  11.183 -  int  size_read, size_write, i;
  11.184 -  
  11.185 -#ifndef VTPM_MULTI_VM
  11.186 -  int threadType = *(int *) threadTypePtr;
  11.187 -  
  11.188 -  // async io structures
  11.189 -  struct aiocb dmi_aio;
  11.190 -  struct aiocb *dmi_aio_a[1];
  11.191 -  dmi_aio_a[0] = &dmi_aio;
  11.192 -#endif
  11.193 -  
  11.194 -#ifdef DUMMY_BACKEND
  11.195 -  int dummy_rx;  
  11.196 -#endif
  11.197 -  
  11.198 -  // TODO: Reinsert ifdefs to enable support for MULTI-VM 
  11.199 -  
  11.200 -  cmd_header = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV);
  11.201 -  command_buf = (buffer_t *) malloc(sizeof(buffer_t));
  11.202 -  result_buf = (buffer_t *) malloc(sizeof(buffer_t));
  11.203 -  
  11.204 -#ifndef VTPM_MULTI_VM
  11.205 -  TPM_RESULT *ret_value = (TPM_RESULT *) malloc(sizeof(TPM_RESULT));
  11.206 -#endif
  11.207 -  
  11.208 -  int *tx_fh, *rx_fh;
  11.209 -  
  11.210 -#ifdef VTPM_MULTI_VM
  11.211 -  rx_fh = &vtpm_globals->be_fh;
  11.212 -#else
  11.213 -  if (threadType == BE_LISTENER_THREAD) {
  11.214 -#ifdef DUMMY_BACKEND    
  11.215 -    dummy_rx = -1;
  11.216 -    rx_fh = &dummy_rx;
  11.217 -#else
  11.218 -    rx_fh = &vtpm_globals->be_fh;
  11.219 -#endif
  11.220 -  } else { // DMI_LISTENER_THREAD
  11.221 -    rx_fh = &vtpm_globals->vtpm_rx_fh;
  11.222 -  }
  11.223 -#endif
  11.224 -  
  11.225 -#ifndef VTPM_MULTI_VM
  11.226 -  int fh;
  11.227 -  if (threadType == BE_LISTENER_THREAD) {
  11.228 -    tx_fh = &vtpm_globals->be_fh;
  11.229 -    if ( (fh = open(GUEST_RX_FIFO, O_RDWR)) == -1) {
  11.230 -      if ( mkfifo(GUEST_RX_FIFO, S_IWUSR | S_IRUSR ) ){
  11.231 -				*ret_value = TPM_FAIL;
  11.232 -				pthread_exit(ret_value);
  11.233 -      }
  11.234 -    } else 
  11.235 -      close(fh);
  11.236 -    
  11.237 -  } else { // else DMI_LISTENER_THREAD
  11.238 -    // tx_fh will be set once the DMI is identified
  11.239 -    // But we need to make sure the read pip is created.
  11.240 -    if ( (fh = open(VTPM_RX_FIFO, O_RDWR)) == -1) {
  11.241 -      if ( mkfifo(VTPM_RX_FIFO, S_IWUSR | S_IRUSR ) ){
  11.242 -	*ret_value = TPM_FAIL;
  11.243 -	pthread_exit(ret_value);
  11.244 -      }
  11.245 -    } else 
  11.246 -      close(fh);
  11.247 -    
  11.248 -  }
  11.249 -#endif
  11.250 -  
  11.251 -  while(1) {
  11.252 -    
  11.253 -    if (threadType == BE_LISTENER_THREAD) {
  11.254 -      vtpmhandlerloginfo(VTPM_LOG_VTPM, "Waiting for Guest requests & ctrl messages.\n");
  11.255 -    } else 
  11.256 -      vtpmhandlerloginfo(VTPM_LOG_VTPM, "Waiting for DMI messages.\n");
  11.257 -    
  11.258 -    
  11.259 -    if (*rx_fh < 0) {
  11.260 -      if (threadType == BE_LISTENER_THREAD) 
  11.261 -#ifdef DUMMY_BACKEND
  11.262 -	*rx_fh = open("/tmp/in.fifo", O_RDWR);
  11.263 -#else
  11.264 -        *rx_fh = open(VTPM_BE_DEV, O_RDWR);
  11.265 -#endif
  11.266 -      else  // DMI Listener   
  11.267 -	*rx_fh = open(VTPM_RX_FIFO, O_RDWR);
  11.268 -      
  11.269 -    }
  11.270 -    
  11.271 -    if (*rx_fh < 0) {
  11.272 -      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't open inbound fh.\n");
  11.273 -#ifdef VTPM_MULTI_VM
  11.274 -      return TPM_IOERROR; 
  11.275 -#else
  11.276 -      *ret_value = TPM_IOERROR;
  11.277 -      pthread_exit(ret_value);
  11.278 -#endif
  11.279 -    }
  11.280 -    
  11.281 -    size_read = read(*rx_fh, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
  11.282 -    if (size_read > 0) {
  11.283 -      vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV[%d}: 0x", size_read);
  11.284 -      for (i=0; i<size_read; i++) 
  11.285 -		vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
  11.286 -    } else {
  11.287 -      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't read from BE. Aborting... \n");
  11.288 -      close(*rx_fh);
  11.289 -      *rx_fh = -1;
  11.290 -      goto abort_command;
  11.291 -    }
  11.292 -
  11.293 -    if (size_read < (int) VTPM_COMMAND_HEADER_SIZE_SRV) {
  11.294 -      vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "\n");
  11.295 -      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command shorter than normal header (%d bytes). Aborting...\n", size_read);
  11.296 -      goto abort_command;
  11.297 -    }
  11.298 -    
  11.299 -    BSG_UnpackList(cmd_header, 4,
  11.300 -		   BSG_TYPE_UINT32, &dmi,
  11.301 -		   BSG_TPM_TAG, &tag,
  11.302 -		   BSG_TYPE_UINT32, &in_param_size,
  11.303 -		   BSG_TPM_COMMAND_CODE, &ord );
  11.304 -    
  11.305 -    // Note that in_param_size is in the client's context
  11.306 -    cmd_size = in_param_size - VTPM_COMMAND_HEADER_SIZE_CLT;
  11.307 -    if (cmd_size > 0) {
  11.308 -      in_param = (BYTE *) malloc(cmd_size);
  11.309 -      size_read = read( *rx_fh, in_param, cmd_size);
  11.310 -      if (size_read > 0) {
  11.311 -	for (i=0; i<size_read; i++) 
  11.312 -	  vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]);
  11.313 -	
  11.314 -      } else {
  11.315 -        vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error reading from BE. Aborting... \n");
  11.316 -	close(*rx_fh);
  11.317 -	*rx_fh = -1;
  11.318 -	goto abort_command;
  11.319 -      }
  11.320 -      vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
  11.321 -      
  11.322 -      if (size_read < (int) cmd_size) {
  11.323 -	vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
  11.324 -	vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command read(%d) is shorter than header indicates(%d). Aborting...\n", size_read, cmd_size);
  11.325 -	goto abort_command;
  11.326 -      }
  11.327 -    } else {
  11.328 -      in_param = NULL;
  11.329 -      vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
  11.330 -    }            
  11.331 -    
  11.332 -    if ((threadType != BE_LISTENER_THREAD) && (dmi == 0)) {
  11.333 -      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempt to access dom0 commands from DMI interface. Aborting...\n");
  11.334 -      goto abort_command;
  11.335 -    }
  11.336 -    
  11.337 -    dmi_res = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi);
  11.338 -    if (dmi_res == NULL) {
  11.339 -      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempted access to non-existent DMI in domain: %d. Aborting...\n", dmi);
  11.340 -      goto abort_command;
  11.341 -    }
  11.342 -    if (!dmi_res->connected) {
  11.343 -      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempted access to disconnected DMI in domain: %d. Aborting...\n", dmi);
  11.344 -      goto abort_command;
  11.345 -    }
  11.346 -    
  11.347 -    if (threadType != BE_LISTENER_THREAD) 
  11.348 -      tx_fh = &dmi_res->vtpm_tx_fh;
  11.349 -    // else we set this before the while loop since it doesn't change.
  11.350 -    
  11.351 -    if ( (buffer_init_convert(command_buf, cmd_size, in_param) != TPM_SUCCESS) || 
  11.352 -	 (buffer_init(result_buf, 0, 0) != TPM_SUCCESS) ) {
  11.353 -      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Failed to setup buffers. Aborting...\n");
  11.354 -      goto abort_command;
  11.355 -    }
  11.356 -    
  11.357 -    // Dispatch it as either control or user request.
  11.358 -    if (tag == VTPM_TAG_REQ) { 
  11.359 -      if (dmi_res->dmi_id == VTPM_CTL_DM){ 
  11.360 -	switch (ord) {
  11.361 -	case VTPM_ORD_OPEN:
  11.362 -	  status = VTPM_Handle_New_DMI(command_buf);
  11.363 -	  break;
  11.364 -          
  11.365 -	case VTPM_ORD_CLOSE:
  11.366 -	  status = VTPM_Handle_Close_DMI(command_buf);
  11.367 -	  break;
  11.368 -          
  11.369 -	case VTPM_ORD_DELETE:
  11.370 -	  status = VTPM_Handle_Delete_DMI(command_buf);
  11.371 -	  break;
  11.372 -	default:
  11.373 -	  status = TPM_BAD_ORDINAL; 
  11.374 -	} // switch
  11.375 -      } else {
  11.376 -	
  11.377 -	switch (ord) {                
  11.378 -	case VTPM_ORD_SAVENVM:
  11.379 -	  status= VTPM_Handle_Save_NVM(dmi_res,
  11.380 -				       command_buf, 
  11.381 -				       result_buf);
  11.382 -	  break;
  11.383 -	case VTPM_ORD_LOADNVM:
  11.384 -	  status= VTPM_Handle_Load_NVM(dmi_res, 
  11.385 -				       command_buf, 
  11.386 -				       result_buf);
  11.387 -	  break;
  11.388 -	  
  11.389 -	case VTPM_ORD_TPMCOMMAND:
  11.390 -	  status= VTPM_Handle_TPM_Command(dmi_res, 
  11.391 -					  command_buf, 
  11.392 -					  result_buf);
  11.393 -	  break;
  11.394 -	  
  11.395 -	default:
  11.396 -	  status = TPM_BAD_ORDINAL; 
  11.397 -	} // switch
  11.398 -      }
  11.399 -    } else { // This is not a VTPM Command at all
  11.400 -      
  11.401 -      if (threadType == BE_LISTENER_THREAD) {
  11.402 -	if (dmi == 0) {
  11.403 -	  // This usually indicates a FE/BE driver.
  11.404 -	  vtpmhandlerlogerror(VTPM_LOG_VTPM, "Illegal use of TPM command from dom0\n");
  11.405 -	  status = TPM_FAIL;
  11.406 -	} else {
  11.407 -	  vtpmhandlerloginfo(VTPM_LOG_VTPM, "Forwarding command to DMI.\n");
  11.408 -	  
  11.409 -	  if (dmi_res->guest_tx_fh < 0)
  11.410 -	    dmi_res->guest_tx_fh = open(dmi_res->guest_tx_fname, O_WRONLY | O_NONBLOCK);
  11.411 -          
  11.412 -	  if (dmi_res->guest_tx_fh < 0){
  11.413 -	    vtpmhandlerlogerror(VTPM_LOG_VTPM, "VTPM ERROR: Can't open outbound fh to dmi.\n");
  11.414 -	    status = TPM_IOERROR;
  11.415 -	    goto abort_with_error;
  11.416 -	  }        
  11.417 -          
  11.418 -	  //Note: Send message + dmi_id
  11.419 -	  if (cmd_size) {
  11.420 -	    dmi_cmd = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV + cmd_size);
  11.421 -	    dmi_cmd_size = VTPM_COMMAND_HEADER_SIZE_SRV + cmd_size;
  11.422 -	    memcpy(dmi_cmd, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
  11.423 -	    memcpy(dmi_cmd + VTPM_COMMAND_HEADER_SIZE_SRV, in_param, cmd_size);
  11.424 -	    size_write = write(dmi_res->guest_tx_fh, dmi_cmd, dmi_cmd_size);
  11.425 -	    
  11.426 -	    if (size_write > 0) {
  11.427 -	      vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT (DMI): 0x");
  11.428 -	      for (i=0; i<VTPM_COMMAND_HEADER_SIZE_SRV + cmd_size; i++) {
  11.429 -		vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", dmi_cmd[i]);
  11.430 -	      }
  11.431 -	      vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
  11.432 -	    } else {
  11.433 -              vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error writing to DMI. Aborting... \n");
  11.434 -	      close(dmi_res->guest_tx_fh);
  11.435 -	      dmi_res->guest_tx_fh = -1;
  11.436 -              status = TPM_IOERROR;
  11.437 -	      goto abort_with_error;
  11.438 -	    }
  11.439 -	    free(dmi_cmd);
  11.440 -	  } else {
  11.441 -	    dmi_cmd_size = VTPM_COMMAND_HEADER_SIZE_SRV;
  11.442 -	    size_write = write(dmi_res->guest_tx_fh, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV );
  11.443 -	    if (size_write > 0) {
  11.444 -	      for (i=0; i<VTPM_COMMAND_HEADER_SIZE_SRV; i++) 
  11.445 -		vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
  11.446 -	      
  11.447 -	      vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
  11.448 -	    } else {
  11.449 -              vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error writing to DMI. Aborting... \n");
  11.450 -	      close(dmi_res->guest_tx_fh);
  11.451 -	      dmi_res->guest_tx_fh = -1;
  11.452 -              status = TPM_IOERROR;
  11.453 -	      goto abort_with_error;
  11.454 -	    }
  11.455 -	  }
  11.456 -          
  11.457 -	  if (size_write != (int) dmi_cmd_size) 
  11.458 -	    vtpmhandlerlogerror(VTPM_LOG_VTPM, "Could not write entire command to DMI (%d/%d)\n", size_write, dmi_cmd_size);
  11.459 -	  buffer_free(command_buf);
  11.460 -	  
  11.461 -	  if (vtpm_globals->guest_rx_fh < 0) 
  11.462 -	    vtpm_globals->guest_rx_fh = open(GUEST_RX_FIFO, O_RDONLY);
  11.463 -          
  11.464 -	  if (vtpm_globals->guest_rx_fh < 0){
  11.465 -	    vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't open inbound fh to dmi.\n");
  11.466 -            status = TPM_IOERROR;
  11.467 -	    goto abort_with_error;
  11.468 -	  }                  
  11.469 -	  
  11.470 -          size_read = read( vtpm_globals->guest_rx_fh, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
  11.471 -	  if (size_read > 0) {
  11.472 -	    vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV (DMI): 0x");
  11.473 -	    for (i=0; i<size_read; i++) 
  11.474 -	      vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
  11.475 -	    
  11.476 -	  } else {
  11.477 -            vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error reading from DMI. Aborting... \n");
  11.478 -	    close(vtpm_globals->guest_rx_fh);
  11.479 -	    vtpm_globals->guest_rx_fh = -1;
  11.480 -            status = TPM_IOERROR;
  11.481 -	    goto abort_with_error;
  11.482 -	  }
  11.483 -          
  11.484 -	  if (size_read < (int) VTPM_COMMAND_HEADER_SIZE_SRV) {
  11.485 -	    //vtpmdeepsublog("\n");
  11.486 -	    vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command from DMI shorter than normal header. Aborting...\n");
  11.487 -            status = TPM_IOERROR;
  11.488 -	    goto abort_with_error;
  11.489 -	  }
  11.490 -          
  11.491 -	  BSG_UnpackList(cmd_header, 4,
  11.492 -			 BSG_TYPE_UINT32, &dmi,
  11.493 -			 BSG_TPM_TAG, &tag,
  11.494 -			 BSG_TYPE_UINT32, &in_param_size,
  11.495 -			 BSG_TPM_COMMAND_CODE, &status );
  11.496 -        
  11.497 -	  // Note that in_param_size is in the client's context
  11.498 -	  cmd_size = in_param_size - VTPM_COMMAND_HEADER_SIZE_CLT;
  11.499 -	  if (cmd_size > 0) {
  11.500 -	    in_param = (BYTE *) malloc(cmd_size);
  11.501 -	    size_read = read( vtpm_globals->guest_rx_fh, in_param, cmd_size);
  11.502 -	    if (size_read > 0) {
  11.503 -	      for (i=0; i<size_read; i++) 
  11.504 -		vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]);
  11.505 -	      
  11.506 -	    } else {
  11.507 -              vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error reading from BE. Aborting... \n");
  11.508 -	      close(vtpm_globals->guest_rx_fh);
  11.509 -	      vtpm_globals->guest_rx_fh = -1;
  11.510 -              status = TPM_IOERROR;
  11.511 -	      goto abort_with_error;
  11.512 -	    }
  11.513 -	    vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n");
  11.514 -            
  11.515 -	    if (size_read < (int)cmd_size) {
  11.516 -	      vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n");
  11.517 -	      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command read(%d) from DMI is shorter than header indicates(%d). Aborting...\n", size_read, cmd_size);
  11.518 -              status = TPM_IOERROR;
  11.519 -	      goto abort_with_error;
  11.520 -	    }
  11.521 -	  } else {
  11.522 -	    in_param = NULL;
  11.523 -	    vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n");
  11.524 -	  }
  11.525 -                           
  11.526 -	  if (buffer_init_convert(result_buf, cmd_size, in_param) != TPM_SUCCESS) {
  11.527 -	    vtpmhandlerlogerror(VTPM_LOG_VTPM, "Failed to setup buffers. Aborting...\n");
  11.528 -            status = TPM_FAIL;
  11.529 -	    goto abort_with_error;
  11.530 -	  }
  11.531 -	  
  11.532 -	  vtpmhandlerloginfo(VTPM_LOG_VTPM, "Sending DMI's response to guest.\n");
  11.533 -	} // end else for if (dmi==0)
  11.534 -        
  11.535 -      } else { // This is a DMI lister thread. Thus this is from a DMI
  11.536 -#ifdef VTPM_MULTI_VM
  11.537 -	vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempt to use unsupported direct access to TPM.\n");
  11.538 -	vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "Bad Command. dmi:%d, tag:%d, size:%d, ord:%d, Params: ", dmi, tag, in_param_size, ord);
  11.539 -	for (UINT32 q=0; q<cmd_size; q++) 
  11.540 -	  vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[q]);
  11.541 -	
  11.542 -	vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
  11.543 -        
  11.544 -	status = TPM_FAIL;
  11.545 -#else
  11.546 -	
  11.547 -#endif
  11.548 -      } // end else for if BE Listener
  11.549 -    } // end else for is VTPM Command
  11.550 -    
  11.551 -    // Send response to Backend
  11.552 -    if (*tx_fh < 0) {
  11.553 -      if (threadType == BE_LISTENER_THREAD) 
  11.554 -#ifdef DUMMY_BACKEND
  11.555 -	*tx_fh = open("/tmp/out.fifo", O_RDWR);
  11.556 -#else
  11.557 -        *tx_fh = open(VTPM_BE_DEV, O_RDWR);
  11.558 -#endif
  11.559 -      else  // DMI Listener
  11.560 -	*tx_fh = open(dmi_res->vtpm_tx_fname, O_WRONLY);
  11.561 -    }
  11.562 -    
  11.563 -    if (*tx_fh < 0) {
  11.564 -      vtpmhandlerlogerror(VTPM_LOG_VTPM, "VTPM ERROR: Can't open outbound fh.\n");
  11.565 -#ifdef VTPM_MULTI_VM
  11.566 -      return TPM_IOERROR; 
  11.567 -#else
  11.568 -      *ret_value = TPM_IOERROR;
  11.569 -      pthread_exit(ret_value);
  11.570 -#endif
  11.571 -    }        
  11.572 -    
  11.573 - abort_with_error:
  11.574 -    // Prepend VTPM header with destination DM stamped
  11.575 -    out_param_size = buffer_len(result_buf);
  11.576 -    out_message_size = VTPM_COMMAND_HEADER_SIZE_CLT + out_param_size;
  11.577 -    out_message_size_full = VTPM_COMMAND_HEADER_SIZE_SRV + out_param_size;
  11.578 -    out_message = (BYTE *) malloc (out_message_size_full);
  11.579 -    
  11.580 -    BSG_PackList(out_message, 4,
  11.581 -		 BSG_TYPE_UINT32, (BYTE *) &dmi,
  11.582 -		 BSG_TPM_TAG, (BYTE *) &tag,
  11.583 -		 BSG_TYPE_UINT32, (BYTE *) &out_message_size,
  11.584 -		 BSG_TPM_RESULT, (BYTE *) &status);
  11.585 -    
  11.586 -    if (buffer_len(result_buf) > 0) 
  11.587 -      memcpy(out_message + VTPM_COMMAND_HEADER_SIZE_SRV, result_buf->bytes, out_param_size);
  11.588 -    
  11.589 -    
  11.590 -    //Note: Send message + dmi_id
  11.591 -    size_write = write(*tx_fh, out_message, out_message_size_full );
  11.592 -    if (size_write > 0) {
  11.593 -      vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT: 0x");
  11.594 -      for (i=0; i < out_message_size_full; i++) 
  11.595 -	vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", out_message[i]);
  11.596 -      
  11.597 -      vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");            
  11.598 -    } else {
  11.599 -      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error writing to BE. Aborting... \n");
  11.600 -      close(*tx_fh);
  11.601 -      *tx_fh = -1;
  11.602 -      goto abort_command;
  11.603 -    }
  11.604 -    free(out_message);
  11.605 -    
  11.606 -    if (size_write < (int)out_message_size_full) {
  11.607 -      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Unable to write full command to BE (%d/%d)\n", size_write, out_message_size_full);
  11.608 -      goto abort_command;
  11.609 -    }
  11.610 -    
  11.611 -  abort_command:
  11.612 -    //free buffers
  11.613 -    bzero(cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
  11.614 -    //free(in_param); // This was converted to command_buf. No need to free 
  11.615 -    if (command_buf != result_buf) 
  11.616 -      buffer_free(result_buf);
  11.617 -    
  11.618 -    buffer_free(command_buf);
  11.619 -    
  11.620 -#ifndef VTPM_MULTI_VM
  11.621 -    if (threadType != BE_LISTENER_THREAD) {
  11.622 -#endif
  11.623 -      if ( (vtpm_globals->DMI_table_dirty) &&
  11.624 -	   (VTPM_SaveService() != TPM_SUCCESS) ) {
  11.625 -	vtpmhandlerlogerror(VTPM_LOG_VTPM, "ERROR: Unable to save manager data.\n");
  11.626 -      }
  11.627 -#ifndef VTPM_MULTI_VM
  11.628 -    }
  11.629 -#endif
  11.630 -    
  11.631 -  } // End while(1)
  11.632 -  
  11.633 -}
  11.634 -
  11.635 -
  11.636 -///////////////////////////////////////////////////////////////////////////////
  11.637 -TPM_RESULT VTPM_Init_Service() {
  11.638 -  TPM_RESULT status = TPM_FAIL;   
  11.639 -  BYTE *randomsead;
  11.640 -	UINT32 randomsize;
  11.641 -	
  11.642 -  if ((vtpm_globals = (VTPM_GLOBALS *) malloc(sizeof(VTPM_GLOBALS))) == NULL){
  11.643 -		status = TPM_FAIL;
  11.644 -		goto abort_egress;
  11.645 -	}
  11.646 -	memset(vtpm_globals, 0, sizeof(VTPM_GLOBALS));
  11.647 -  vtpm_globals->be_fh = -1;
  11.648 -
  11.649 -#ifndef VTPM_MULTI_VM
  11.650 -  vtpm_globals->vtpm_rx_fh = -1;
  11.651 -  vtpm_globals->guest_rx_fh = -1;
  11.652 -#endif
  11.653 -  if ((vtpm_globals->dmi_map = create_hashtable(10, hashfunc32, equals32)) == NULL){
  11.654 -		status = TPM_FAIL;
  11.655 -		goto abort_egress;
  11.656 -	}
  11.657 -  
  11.658 -  vtpm_globals->DMI_table_dirty = FALSE;
  11.659 -  
  11.660 -  // Create new TCS Object
  11.661 -  vtpm_globals->manager_tcs_handle = 0;
  11.662 -  
  11.663 -  TPMTRYRETURN(TCS_create());
  11.664 -  
  11.665 -  // Create TCS Context for service
  11.666 -  TPMTRYRETURN( TCS_OpenContext(&vtpm_globals->manager_tcs_handle ) );
  11.667 -
  11.668 -	TPMTRYRETURN( TCSP_GetRandom(vtpm_globals->manager_tcs_handle, 
  11.669 -															 &randomsize, 
  11.670 -															 &randomsead));
  11.671 -
  11.672 -	Crypto_Init(randomsead, randomsize);
  11.673 -	TPMTRYRETURN( TCS_FreeMemory (vtpm_globals->manager_tcs_handle, randomsead)); 
  11.674 -	
  11.675 -  // Create OIAP session for service's authorized commands
  11.676 -  TPMTRYRETURN( VTSP_OIAP( vtpm_globals->manager_tcs_handle, 
  11.677 -			   &vtpm_globals->keyAuth) );
  11.678 -  vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
  11.679 -
  11.680 -	// If failed, create new Service.
  11.681 -  if (VTPM_LoadService() != TPM_SUCCESS)
  11.682 -    TPMTRYRETURN( VTPM_Create_Service() );    
  11.683 -
  11.684 -  
  11.685 -  //Load Storage Key 
  11.686 -  TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
  11.687 -			      TPM_SRK_KEYHANDLE,
  11.688 -			      &vtpm_globals->storageKeyWrap,
  11.689 -			      (const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
  11.690 -			      &vtpm_globals->storageKeyHandle,
  11.691 -			      &vtpm_globals->keyAuth,
  11.692 -			      &vtpm_globals->storageKey) );
  11.693 -  
  11.694 -  // Create entry for Dom0 for control messages
  11.695 -  TPMTRYRETURN( VTPM_Handle_New_DMI(NULL) );
  11.696 -  
  11.697 -  // --------------------- Command handlers ---------------------------
  11.698 -  
  11.699 -  goto egress;
  11.700 -  
  11.701 - abort_egress:
  11.702 - egress:
  11.703 -  
  11.704 -  return(status);
  11.705 -}
  11.706 - 
  11.707 -void VTPM_Stop_Service() {
  11.708 -  VTPM_DMI_RESOURCE *dmi_res;
  11.709 -  struct hashtable_itr *dmi_itr;
  11.710 -  
  11.711 -  // Close all the TCS contexts. TCS should evict keys based on this
  11.712 -  if (hashtable_count(vtpm_globals->dmi_map) > 0) {
  11.713 -    dmi_itr = hashtable_iterator(vtpm_globals->dmi_map);
  11.714 -    do {
  11.715 -      dmi_res = (VTPM_DMI_RESOURCE *) hashtable_iterator_value(dmi_itr);
  11.716 -      if (dmi_res->connected) 
  11.717 -				if (close_dmi( dmi_res ) != TPM_SUCCESS) 
  11.718 -					vtpmlogerror(VTPM_LOG_VTPM, "Failed to close dmi %d properly.\n", dmi_res->dmi_id);
  11.719 -      
  11.720 -    } while (hashtable_iterator_advance(dmi_itr));
  11.721 -		free (dmi_itr);
  11.722 -  }
  11.723 -  
  11.724 -	
  11.725 -  TCS_CloseContext(vtpm_globals->manager_tcs_handle);
  11.726 -  
  11.727 -  if ( (vtpm_globals->DMI_table_dirty) &&
  11.728 -       (VTPM_SaveService() != TPM_SUCCESS) )
  11.729 -    vtpmlogerror(VTPM_LOG_VTPM, "Unable to save manager data.\n");
  11.730 -  
  11.731 -  hashtable_destroy(vtpm_globals->dmi_map, 1);
  11.732 -  free(vtpm_globals);
  11.733 -  
  11.734 -  close(vtpm_globals->be_fh);
  11.735 -  Crypto_Exit();
  11.736 -	
  11.737 -  vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager stopped.\n");
  11.738 -}
  11.739 +// ===================================================================
  11.740 +// 
  11.741 +// Copyright (c) 2005, Intel Corp.
  11.742 +// All rights reserved.
  11.743 +//
  11.744 +// Redistribution and use in source and binary forms, with or without 
  11.745 +// modification, are permitted provided that the following conditions 
  11.746 +// are met:
  11.747 +//
  11.748 +//   * Redistributions of source code must retain the above copyright 
  11.749 +//     notice, this list of conditions and the following disclaimer.
  11.750 +//   * Redistributions in binary form must reproduce the above 
  11.751 +//     copyright notice, this list of conditions and the following 
  11.752 +//     disclaimer in the documentation and/or other materials provided 
  11.753 +//     with the distribution.
  11.754 +//   * Neither the name of Intel Corporation nor the names of its 
  11.755 +//     contributors may be used to endorse or promote products derived
  11.756 +//     from this software without specific prior written permission.
  11.757 +//
  11.758 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  11.759 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  11.760 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
  11.761 +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
  11.762 +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  11.763 +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  11.764 +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
  11.765 +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  11.766 +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
  11.767 +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
  11.768 +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  11.769 +// OF THE POSSIBILITY OF SUCH DAMAGE.
  11.770 +// ===================================================================
  11.771 +// 
  11.772 +// vtpm_manager.c
  11.773 +// 
  11.774 +//  This file will house the main logic of the VTPM Manager
  11.775 +//
  11.776 +// ==================================================================
  11.777 +
  11.778 +#include <stdio.h>
  11.779 +#include <unistd.h>
  11.780 +#include <sys/types.h>
  11.781 +#include <sys/stat.h>
  11.782 +#include <fcntl.h>
  11.783 +#include <string.h>
  11.784 +
  11.785 +#ifndef VTPM_MULTI_VM
  11.786 +#include <pthread.h>
  11.787 +#include <errno.h>
  11.788 +#include <aio.h>
  11.789 +#include <time.h>
  11.790 +#endif
  11.791 +
  11.792 +#include "vtpm_manager.h"
  11.793 +#include "vtpmpriv.h"
  11.794 +#include "vtsp.h"
  11.795 +#include "bsg.h"
  11.796 +#include "hashtable.h"
  11.797 +#include "hashtable_itr.h"
  11.798 +
  11.799 +#include "log.h"
  11.800 +#include "buffer.h"
  11.801 +
  11.802 +VTPM_GLOBALS *vtpm_globals=NULL;
  11.803 +
  11.804 +#ifdef VTPM_MULTI_VM
  11.805 + #define vtpmhandlerloginfo(module,fmt,args...) vtpmloginfo (module, fmt, ##args );
  11.806 + #define vtpmhandlerloginfomore(module,fmt,args...) vtpmloginfomore (module, fmt, ##args );
  11.807 + #define vtpmhandlerlogerror(module,fmt,args...) vtpmlogerror (module, fmt, ##args );
  11.808 +#else 
  11.809 + #define vtpmhandlerloginfo(module,fmt,args...) vtpmloginfo (module, "[%d]: " fmt, threadType, ##args );
  11.810 + #define vtpmhandlerloginfomore(module,fmt,args...) vtpmloginfomore (module, fmt, ##args );
  11.811 + #define vtpmhandlerlogerror(module,fmt,args...) vtpmlogerror (module, "[%d]: " fmt, threadType, ##args );
  11.812 +#endif
  11.813 +
  11.814 +// --------------------------- Well Known Auths --------------------------
  11.815 +#ifdef WELL_KNOWN_SRK_AUTH
  11.816 +static BYTE FIXED_SRK_AUTH[20] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  11.817 +                                  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  11.818 +#endif
  11.819 +
  11.820 +#ifdef WELL_KNOWN_OWNER_AUTH
  11.821 +static BYTE FIXED_OWNER_AUTH[20] =  {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  11.822 +                                  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  11.823 +#endif
  11.824 +                                  
  11.825 +// -------------------------- Hash table functions --------------------
  11.826 +
  11.827 +static unsigned int hashfunc32(void *ky) {
  11.828 +  return (* (UINT32 *) ky);
  11.829 +}
  11.830 +
  11.831 +static int equals32(void *k1, void *k2) {
  11.832 +  return (*(UINT32 *) k1 == *(UINT32 *) k2);
  11.833 +}
  11.834 +
  11.835 +// --------------------------- Functions ------------------------------
  11.836 +
  11.837 +TPM_RESULT VTPM_Create_Service(){
  11.838 +  
  11.839 +  TPM_RESULT status = TPM_SUCCESS;
  11.840 +  
  11.841 +  // Generate Auth's for SRK & Owner
  11.842 +#ifdef WELL_KNOWN_SRK_AUTH 
  11.843 +  memcpy(vtpm_globals->srk_usage_auth, FIXED_SRK_AUTH, sizeof(TPM_AUTHDATA));
  11.844 +#else    
  11.845 +  Crypto_GetRandom(vtpm_globals->srk_usage_auth, sizeof(TPM_AUTHDATA) );  
  11.846 +#endif
  11.847 +  
  11.848 +#ifdef WELL_KNOWN_OWNER_AUTH 
  11.849 +  memcpy(vtpm_globals->owner_usage_auth, FIXED_OWNER_AUTH, sizeof(TPM_AUTHDATA));
  11.850 +#else    
  11.851 +  Crypto_GetRandom(vtpm_globals->owner_usage_auth, sizeof(TPM_AUTHDATA) );
  11.852 +#endif
  11.853 +
  11.854 +  // Take Owership of TPM
  11.855 +  CRYPTO_INFO ek_cryptoInfo;
  11.856 +  
  11.857 +  vtpmloginfo(VTPM_LOG_VTPM, "Attempting Pubek Read. NOTE: Failure is ok.\n");
  11.858 +  status = VTSP_ReadPubek(vtpm_globals->manager_tcs_handle, &ek_cryptoInfo);
  11.859 +  
  11.860 +  // If we can read PubEK then there is no owner and we should take it.
  11.861 +  if (status == TPM_SUCCESS) { 
  11.862 +    TPMTRYRETURN(VTSP_TakeOwnership(vtpm_globals->manager_tcs_handle,
  11.863 +				    (const TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth, 
  11.864 +				    (const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
  11.865 +				    &ek_cryptoInfo,
  11.866 +				    &vtpm_globals->keyAuth)); 
  11.867 +  
  11.868 +    TPMTRYRETURN(VTSP_DisablePubekRead(vtpm_globals->manager_tcs_handle,
  11.869 +                                       (const TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth,  
  11.870 +                                       &vtpm_globals->keyAuth));     
  11.871 +  }
  11.872 +  
  11.873 +  // Generate storage key's auth
  11.874 +  Crypto_GetRandom(  &vtpm_globals->storage_key_usage_auth, 
  11.875 +		     sizeof(TPM_AUTHDATA) );
  11.876 +  
  11.877 +  TCS_AUTH osap;
  11.878 +  TPM_AUTHDATA sharedsecret;
  11.879 +  
  11.880 +  TPMTRYRETURN( VTSP_OSAP(vtpm_globals->manager_tcs_handle,
  11.881 +			  TPM_ET_SRK,
  11.882 +			  0, 
  11.883 +			  (const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
  11.884 +			  &sharedsecret, 
  11.885 +			  &osap) ); 
  11.886 +  
  11.887 +  TPMTRYRETURN( VTSP_CreateWrapKey( vtpm_globals->manager_tcs_handle,
  11.888 +				    TPM_KEY_BIND,
  11.889 +				    (const TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
  11.890 +				    TPM_SRK_KEYHANDLE, 
  11.891 +				    (const TPM_AUTHDATA*)&sharedsecret,
  11.892 +				    &vtpm_globals->storageKeyWrap,
  11.893 +				    &osap) );
  11.894 +  
  11.895 +  vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
  11.896 +  
  11.897 +  goto egress;
  11.898 +  
  11.899 + abort_egress:
  11.900 +  exit(1);
  11.901 +  
  11.902 + egress:
  11.903 +  vtpmloginfo(VTPM_LOG_VTPM, "Finished initialized new VTPM service (Status = %d).\n", status);
  11.904 +  return status;
  11.905 +  
  11.906 +}
  11.907 +
  11.908 +
  11.909 +//////////////////////////////////////////////////////////////////////////////
  11.910 +#ifdef VTPM_MULTI_VM
  11.911 +int VTPM_Service_Handler(){
  11.912 +#else
  11.913 +void *VTPM_Service_Handler(void *threadTypePtr){
  11.914 +#endif
  11.915 +  TPM_RESULT      status =  TPM_FAIL; // Should never return
  11.916 +  UINT32          dmi, in_param_size, cmd_size, out_param_size, out_message_size, out_message_size_full;
  11.917 +  BYTE            *cmd_header, *in_param, *out_message;
  11.918 +  buffer_t        *command_buf=NULL, *result_buf=NULL;
  11.919 +  TPM_TAG         tag;
  11.920 +  TPM_COMMAND_CODE ord;
  11.921 +  VTPM_DMI_RESOURCE *dmi_res;
  11.922 +  int  size_read, size_write, i;
  11.923 +  
  11.924 +#ifndef VTPM_MULTI_VM
  11.925 +  UINT32 dmi_cmd_size;
  11.926 +  BYTE *dmi_cmd;
  11.927 +  int threadType = *(int *) threadTypePtr;
  11.928 +  
  11.929 +  // async io structures
  11.930 +  struct aiocb dmi_aio;
  11.931 +  struct aiocb *dmi_aio_a[1];
  11.932 +  dmi_aio_a[0] = &dmi_aio;
  11.933 +#endif
  11.934 +  
  11.935 +#ifdef DUMMY_BACKEND
  11.936 +  int dummy_rx;  
  11.937 +#endif
  11.938 +  
  11.939 +  cmd_header = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV);
  11.940 +  command_buf = (buffer_t *) malloc(sizeof(buffer_t));
  11.941 +  result_buf = (buffer_t *) malloc(sizeof(buffer_t));
  11.942 +  
  11.943 +#ifndef VTPM_MULTI_VM
  11.944 +  TPM_RESULT *ret_value = (TPM_RESULT *) malloc(sizeof(TPM_RESULT));
  11.945 +#endif
  11.946 +  
  11.947 +  int *tx_fh, // Pointer to the filehandle this function will write to
  11.948 +      *rx_fh; // Pointer to the filehandle this function will read from
  11.949 +              // For a multi VM VTPM system, this function tx/rx with the BE
  11.950 +              //   via vtpm_globals->be_fh.
  11.951 +              // For a single VM system, the BE_LISTENER_THREAD tx/rx with theBE
  11.952 +              //   via vtpm_globals->be_fh, and the DMI_LISTENER_THREAD rx from
  11.953 +	      //   vtpm_globals->vtpm_rx_fh and tx to dmi_res->vtpm_tx_fh
  11.954 +
  11.955 +  // Set rx_fh to point to the correct fh based on this mode.
  11.956 +#ifdef VTPM_MULTI_VM
  11.957 +  rx_fh = &vtpm_globals->be_fh;
  11.958 +#else
  11.959 +  if (threadType == BE_LISTENER_THREAD) {
  11.960 + #ifdef DUMMY_BACKEND    
  11.961 +    dummy_rx = -1;
  11.962 +    rx_fh = &dummy_rx;
  11.963 + #else
  11.964 +    rx_fh = &vtpm_globals->be_fh;
  11.965 + #endif
  11.966 +  } else { // DMI_LISTENER_THREAD
  11.967 +    rx_fh = &vtpm_globals->vtpm_rx_fh;
  11.968 +  }
  11.969 +#endif
  11.970 +  
  11.971 +  // Set tx_fh to point to the correct fh based on this mode (If static)
  11.972 +  // Create any fifos that these fh will use.  
  11.973 +#ifndef VTPM_MULTI_VM
  11.974 +  int fh;
  11.975 +  if (threadType == BE_LISTENER_THREAD) {
  11.976 +    tx_fh = &vtpm_globals->be_fh;
  11.977 +    if ( (fh = open(GUEST_RX_FIFO, O_RDWR)) == -1) {
  11.978 +      if ( mkfifo(GUEST_RX_FIFO, S_IWUSR | S_IRUSR ) ){
  11.979 +        vtpmlogerror(VTPM_LOG_VTPM, "Unable to create FIFO: %s.\n", GUEST_RX_FIFO);        
  11.980 +	*ret_value = TPM_FAIL;
  11.981 +	pthread_exit(ret_value);
  11.982 +      }
  11.983 +    } else 
  11.984 +      close(fh);
  11.985 +    
  11.986 +  } else { // else DMI_LISTENER_THREAD
  11.987 +    // tx_fh will be set once the DMI is identified
  11.988 +    // But we need to make sure the read pip is created.
  11.989 +    if ( (fh = open(VTPM_RX_FIFO, O_RDWR)) == -1) {
  11.990 +      if ( mkfifo(VTPM_RX_FIFO, S_IWUSR | S_IRUSR ) ){
  11.991 +        vtpmlogerror(VTPM_LOG_VTPM, "Unable to create FIFO: %s.\n", VTPM_RX_FIFO);
  11.992 +	*ret_value = TPM_FAIL;
  11.993 +	pthread_exit(ret_value);
  11.994 +      }
  11.995 +    } else 
  11.996 +      close(fh);
  11.997 +    
  11.998 +  }
  11.999 +#else
 11.1000 +  tx_fh = &vtpm_globals->be_fh;
 11.1001 +#endif
 11.1002 +  
 11.1003 +  ////////////////////////// Main Loop //////////////////////////////////
 11.1004 +  while(1) {
 11.1005 +    
 11.1006 +#ifdef VTPM_MULTI_VM
 11.1007 +    vtpmhandlerloginfo(VTPM_LOG_VTPM, "Waiting for DMI messages.\n");
 11.1008 +#else
 11.1009 +    if (threadType == BE_LISTENER_THREAD) {
 11.1010 +      vtpmhandlerloginfo(VTPM_LOG_VTPM, "Waiting for Guest requests & ctrl messages.\n");
 11.1011 +    } else    
 11.1012 +      vtpmhandlerloginfo(VTPM_LOG_VTPM, "Waiting for DMI messages.\n");
 11.1013 +#endif
 11.1014 +
 11.1015 +    // Check status of rx_fh. If necessary attempt to re-open it.    
 11.1016 +    if (*rx_fh < 0) {
 11.1017 +#ifdef VTPM_MULTI_VM
 11.1018 +      *rx_fh = open(VTPM_BE_DEV, O_RDWR);
 11.1019 +#else
 11.1020 +      if (threadType == BE_LISTENER_THREAD) 
 11.1021 +  #ifdef DUMMY_BACKEND
 11.1022 +	*rx_fh = open("/tmp/in.fifo", O_RDWR);
 11.1023 +  #else
 11.1024 +        *rx_fh = open(VTPM_BE_DEV, O_RDWR);
 11.1025 +  #endif
 11.1026 +      else  // DMI Listener   
 11.1027 +	*rx_fh = open(VTPM_RX_FIFO, O_RDWR);
 11.1028 +#endif    
 11.1029 +    }
 11.1030 +    
 11.1031 +    // Respond to failures to open rx_fh
 11.1032 +    if (*rx_fh < 0) {
 11.1033 +      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't open inbound fh.\n");
 11.1034 +#ifdef VTPM_MULTI_VM
 11.1035 +      return TPM_IOERROR; 
 11.1036 +#else
 11.1037 +      *ret_value = TPM_IOERROR;
 11.1038 +      pthread_exit(ret_value);
 11.1039 +#endif
 11.1040 +    }
 11.1041 +    
 11.1042 +    // Read command header from rx_fh
 11.1043 +    size_read = read(*rx_fh, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
 11.1044 +    if (size_read > 0) {
 11.1045 +      vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV[%d}: 0x", size_read);
 11.1046 +      for (i=0; i<size_read; i++) 
 11.1047 +		vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
 11.1048 +    } else {
 11.1049 +      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't read from BE. Aborting... \n");
 11.1050 +      close(*rx_fh);
 11.1051 +      *rx_fh = -1;
 11.1052 +      goto abort_command;
 11.1053 +    }
 11.1054 +
 11.1055 +    if (size_read < (int) VTPM_COMMAND_HEADER_SIZE_SRV) {
 11.1056 +      vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "\n");
 11.1057 +      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command shorter than normal header (%d bytes). Aborting...\n", size_read);
 11.1058 +      goto abort_command;
 11.1059 +    }
 11.1060 +    
 11.1061 +    // Unpack header
 11.1062 +    BSG_UnpackList(cmd_header, 4,
 11.1063 +		   BSG_TYPE_UINT32, &dmi,
 11.1064 +		   BSG_TPM_TAG, &tag,
 11.1065 +		   BSG_TYPE_UINT32, &in_param_size,
 11.1066 +		   BSG_TPM_COMMAND_CODE, &ord );
 11.1067 +    
 11.1068 +    // Using the header info, read from rx_fh the parameters of the command
 11.1069 +    // Note that in_param_size is in the client's context
 11.1070 +    cmd_size = in_param_size - VTPM_COMMAND_HEADER_SIZE_CLT;
 11.1071 +    if (cmd_size > 0) {
 11.1072 +      in_param = (BYTE *) malloc(cmd_size);
 11.1073 +      size_read = read( *rx_fh, in_param, cmd_size);
 11.1074 +      if (size_read > 0) {
 11.1075 +	for (i=0; i<size_read; i++) 
 11.1076 +	  vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]);
 11.1077 +	
 11.1078 +      } else {
 11.1079 +        vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error reading from cmd. Aborting... \n");
 11.1080 +	close(*rx_fh);
 11.1081 +	*rx_fh = -1;
 11.1082 +	goto abort_command;
 11.1083 +      }
 11.1084 +      vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
 11.1085 +      
 11.1086 +      if (size_read < (int) cmd_size) {
 11.1087 +	vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
 11.1088 +	vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command read(%d) is shorter than header indicates(%d). Aborting...\n", size_read, cmd_size);
 11.1089 +	goto abort_command;
 11.1090 +      }
 11.1091 +    } else {
 11.1092 +      in_param = NULL;
 11.1093 +      vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
 11.1094 +    }            
 11.1095 +
 11.1096 +#ifndef VTPM_MULTI_VM
 11.1097 +    // It's illegal to receive a Dom0 command from a DMI.
 11.1098 +    if ((threadType != BE_LISTENER_THREAD) && (dmi == 0)) {
 11.1099 +      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempt to access dom0 commands from DMI interface. Aborting...\n");
 11.1100 +      goto abort_command;
 11.1101 +    }
 11.1102 +#endif
 11.1103 +    
 11.1104 +    // Fetch infomation about the DMI issuing the request.
 11.1105 +    dmi_res = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi);
 11.1106 +    if (dmi_res == NULL) {
 11.1107 +      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempted access to non-existent DMI in domain: %d. Aborting...\n", dmi);
 11.1108 +      goto abort_command;
 11.1109 +    }
 11.1110 +    if (!dmi_res->connected) {
 11.1111 +      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempted access to disconnected DMI in domain: %d. Aborting...\n", dmi);
 11.1112 +      goto abort_command;
 11.1113 +    }
 11.1114 +
 11.1115 +#ifndef VTPM_MULTI_VM
 11.1116 +    // Now that we know which DMI this is, we can set the tx_fh handle.
 11.1117 +    if (threadType != BE_LISTENER_THREAD) 
 11.1118 +      tx_fh = &dmi_res->vtpm_tx_fh;
 11.1119 +    // else we set this before the while loop since it doesn't change.
 11.1120 +#endif 
 11.1121 +   
 11.1122 +    // Init the buffers used to handle the command and the response
 11.1123 +    if ( (buffer_init_convert(command_buf, cmd_size, in_param) != TPM_SUCCESS) || 
 11.1124 +	 (buffer_init(result_buf, 0, 0) != TPM_SUCCESS) ) {
 11.1125 +      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Failed to setup buffers. Aborting...\n");
 11.1126 +      goto abort_command;
 11.1127 +    }
 11.1128 +    
 11.1129 +    // Dispatch it as either control or user request.
 11.1130 +    if (tag == VTPM_TAG_REQ) { 
 11.1131 +      if (dmi_res->dmi_id == VTPM_CTL_DM){ 
 11.1132 +	switch (ord) {
 11.1133 +	case VTPM_ORD_OPEN:
 11.1134 +	  status = VTPM_Handle_New_DMI(command_buf);
 11.1135 +	  break;
 11.1136 +          
 11.1137 +	case VTPM_ORD_CLOSE:
 11.1138 +	  status = VTPM_Handle_Close_DMI(command_buf);
 11.1139 +	  break;
 11.1140 +          
 11.1141 +	case VTPM_ORD_DELETE:
 11.1142 +	  status = VTPM_Handle_Delete_DMI(command_buf);
 11.1143 +	  break;
 11.1144 +	default:
 11.1145 +	  status = TPM_BAD_ORDINAL; 
 11.1146 +	} // switch
 11.1147 +      } else {
 11.1148 +	
 11.1149 +	switch (ord) {                
 11.1150 +	case VTPM_ORD_SAVENVM:
 11.1151 +	  status= VTPM_Handle_Save_NVM(dmi_res,
 11.1152 +				       command_buf, 
 11.1153 +				       result_buf);
 11.1154 +	  break;
 11.1155 +	case VTPM_ORD_LOADNVM:
 11.1156 +	  status= VTPM_Handle_Load_NVM(dmi_res, 
 11.1157 +				       command_buf, 
 11.1158 +				       result_buf);
 11.1159 +	  break;
 11.1160 +	  
 11.1161 +	case VTPM_ORD_TPMCOMMAND:
 11.1162 +	  status= VTPM_Handle_TPM_Command(dmi_res, 
 11.1163 +					  command_buf, 
 11.1164 +					  result_buf);
 11.1165 +	  break;
 11.1166 +	  
 11.1167 +	default:
 11.1168 +	  status = TPM_BAD_ORDINAL; 
 11.1169 +	} // switch
 11.1170 +      }
 11.1171 +    } else { // This is not a VTPM Command at all.
 11.1172 +	     // This happens in two cases. 
 11.1173 +	     // MULTI_VM = A DMI illegally sent a raw TPM command to the manager
 11.1174 +	     // Single VM:
 11.1175 +	     //   BE_LISTENER_THREAD: Guest issued a TPM command.
 11.1176 +	     //                       Send this to DMI and wait for response
 11.1177 +	     //   DMI_LISTENER_THREAD: A DMI illegally sent a raw TPM command.
 11.1178 +    
 11.1179 +#ifdef VTPM_MULTI_VM
 11.1180 +      // Raw TPM commands are not supported from the DMI
 11.1181 +      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempt to use unsupported direct access to TPM.\n");
 11.1182 +      vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "Bad Command. dmi:%d, tag:%d, size:%d, ord:%d, Params: ", dmi, tag, in_param_size, ord);
 11.1183 +      for (i=0; i<cmd_size; i++) 
 11.1184 +	vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]);
 11.1185 +      
 11.1186 +      vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
 11.1187 +      status = TPM_FAIL;
 11.1188 +    
 11.1189 +#else
 11.1190 +      // If BE_LISTENER_THREAD then this is a TPM command from a guest
 11.1191 +      if (threadType == BE_LISTENER_THREAD) {
 11.1192 +	// Dom0 can't talk to the BE, so this must be a broken FE/BE or badness
 11.1193 +	if (dmi == 0) {
 11.1194 +	  vtpmhandlerlogerror(VTPM_LOG_VTPM, "Illegal use of TPM command from dom0\n");
 11.1195 +	  status = TPM_FAIL;
 11.1196 +	} else {
 11.1197 +	  vtpmhandlerloginfo(VTPM_LOG_VTPM, "Forwarding command to DMI.\n");
 11.1198 +	  
 11.1199 +	  // open the dmi_res->guest_tx_fh to send command to DMI
 11.1200 +	  if (dmi_res->guest_tx_fh < 0)
 11.1201 +	    dmi_res->guest_tx_fh = open(dmi_res->guest_tx_fname, O_WRONLY | O_NONBLOCK);
 11.1202 +
 11.1203 +	  // handle failed opens dmi_res->guest_tx_fh        
 11.1204 +	  if (dmi_res->guest_tx_fh < 0){
 11.1205 +	    vtpmhandlerlogerror(VTPM_LOG_VTPM, "VTPM ERROR: Can't open outbound fh to dmi.\n");
 11.1206 +	    status = TPM_IOERROR;
 11.1207 +	    goto abort_with_error;
 11.1208 +	  }        
 11.1209 +          
 11.1210 +	  //Forward TPM CMD stamped with dmi_id to DMI for handling
 11.1211 +	  if (cmd_size) {
 11.1212 +	    dmi_cmd = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV + cmd_size);
 11.1213 +	    dmi_cmd_size = VTPM_COMMAND_HEADER_SIZE_SRV + cmd_size;
 11.1214 +	    memcpy(dmi_cmd, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
 11.1215 +	    memcpy(dmi_cmd + VTPM_COMMAND_HEADER_SIZE_SRV, in_param, cmd_size);
 11.1216 +	    size_write = write(dmi_res->guest_tx_fh, dmi_cmd, dmi_cmd_size);
 11.1217 +	    
 11.1218 +	    if (size_write > 0) {
 11.1219 +	      vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT (DMI): 0x");
 11.1220 +	      for (i=0; i<VTPM_COMMAND_HEADER_SIZE_SRV + cmd_size; i++) {
 11.1221 +		vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", dmi_cmd[i]);
 11.1222 +	      }
 11.1223 +	      vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
 11.1224 +	    } else {
 11.1225 +              vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error writing to DMI. Aborting... \n");
 11.1226 +	      close(dmi_res->guest_tx_fh);
 11.1227 +	      dmi_res->guest_tx_fh = -1;
 11.1228 +              status = TPM_IOERROR;
 11.1229 +	      goto abort_with_error;
 11.1230 +	    }
 11.1231 +	    free(dmi_cmd);
 11.1232 +	  } else {
 11.1233 +	    dmi_cmd_size = VTPM_COMMAND_HEADER_SIZE_SRV;
 11.1234 +	    size_write = write(dmi_res->guest_tx_fh, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV );
 11.1235 +	    if (size_write > 0) {
 11.1236 +	      for (i=0; i<VTPM_COMMAND_HEADER_SIZE_SRV; i++) 
 11.1237 +		vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
 11.1238 +	      
 11.1239 +	      vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
 11.1240 +	    } else {
 11.1241 +              vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error writing to DMI. Aborting... \n");
 11.1242 +	      close(dmi_res->guest_tx_fh);
 11.1243 +	      dmi_res->guest_tx_fh = -1;
 11.1244 +              status = TPM_IOERROR;
 11.1245 +	      goto abort_with_error;
 11.1246 +	    }
 11.1247 +	  }
 11.1248 +         
 11.1249 +	  if (size_write != (int) dmi_cmd_size) 
 11.1250 +	    vtpmhandlerlogerror(VTPM_LOG_VTPM, "Could not write entire command to DMI (%d/%d)\n", size_write, dmi_cmd_size);
 11.1251 +	  buffer_free(command_buf);
 11.1252 +	 
 11.1253 +	  // Open vtpm_globals->guest_rx_fh to receive DMI response	  
 11.1254 +	  if (vtpm_globals->guest_rx_fh < 0) 
 11.1255 +	    vtpm_globals->guest_rx_fh = open(GUEST_RX_FIFO, O_RDONLY);
 11.1256 +          
 11.1257 +	  // Handle open failures
 11.1258 +	  if (vtpm_globals->guest_rx_fh < 0){
 11.1259 +	    vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't open inbound fh to dmi.\n");
 11.1260 +            status = TPM_IOERROR;
 11.1261 +	    goto abort_with_error;
 11.1262 +	  }                  
 11.1263 +	  
 11.1264 +	  // Read header for response to TPM command from DMI
 11.1265 +          size_read = read( vtpm_globals->guest_rx_fh, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
 11.1266 +	  if (size_read > 0) {
 11.1267 +	    vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV (DMI): 0x");
 11.1268 +	    for (i=0; i<size_read; i++) 
 11.1269 +	      vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
 11.1270 +	    
 11.1271 +	  } else {
 11.1272 +            vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error reading from DMI. Aborting... \n");
 11.1273 +	    close(vtpm_globals->guest_rx_fh);
 11.1274 +	    vtpm_globals->guest_rx_fh = -1;
 11.1275 +            status = TPM_IOERROR;
 11.1276 +	    goto abort_with_error;
 11.1277 +	  }
 11.1278 +          
 11.1279 +	  if (size_read < (int) VTPM_COMMAND_HEADER_SIZE_SRV) {
 11.1280 +	    //vtpmdeepsublog("\n");
 11.1281 +	    vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command from DMI shorter than normal header. Aborting...\n");
 11.1282 +            status = TPM_IOERROR;
 11.1283 +	    goto abort_with_error;
 11.1284 +	  }
 11.1285 +          
 11.1286 +	  // Unpack response from DMI for TPM command
 11.1287 +	  BSG_UnpackList(cmd_header, 4,
 11.1288 +			 BSG_TYPE_UINT32, &dmi,
 11.1289 +			 BSG_TPM_TAG, &tag,
 11.1290 +			 BSG_TYPE_UINT32, &in_param_size,
 11.1291 +			 BSG_TPM_COMMAND_CODE, &status );
 11.1292 +        
 11.1293 +	  // If response has parameters, read them.
 11.1294 +	  // Note that in_param_size is in the client's context
 11.1295 +	  cmd_size = in_param_size - VTPM_COMMAND_HEADER_SIZE_CLT;
 11.1296 +	  if (cmd_size > 0) {
 11.1297 +	    in_param = (BYTE *) malloc(cmd_size);
 11.1298 +	    size_read = read( vtpm_globals->guest_rx_fh, in_param, cmd_size);
 11.1299 +	    if (size_read > 0) {
 11.1300 +	      for (i=0; i<size_read; i++) 
 11.1301 +		vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]);
 11.1302 +	      
 11.1303 +	    } else {
 11.1304 +              vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error reading from BE. Aborting... \n");
 11.1305 +	      close(vtpm_globals->guest_rx_fh);
 11.1306 +	      vtpm_globals->guest_rx_fh = -1;
 11.1307 +              status = TPM_IOERROR;
 11.1308 +	      goto abort_with_error;
 11.1309 +	    }
 11.1310 +	    vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n");
 11.1311 +            
 11.1312 +	    if (size_read < (int)cmd_size) {
 11.1313 +	      vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n");
 11.1314 +	      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command read(%d) from DMI is shorter than header indicates(%d). Aborting...\n", size_read, cmd_size);
 11.1315 +              status = TPM_IOERROR;
 11.1316 +	      goto abort_with_error;
 11.1317 +	    }
 11.1318 +	  } else {
 11.1319 +	    in_param = NULL;
 11.1320 +	    vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n");
 11.1321 +	  }
 11.1322 +          
 11.1323 +	  if (buffer_init_convert(result_buf, cmd_size, in_param) != TPM_SUCCESS) {
 11.1324 +	    vtpmhandlerlogerror(VTPM_LOG_VTPM, "Failed to setup buffers. Aborting...\n");
 11.1325 +            status = TPM_FAIL;
 11.1326 +	    goto abort_with_error;
 11.1327 +	  }
 11.1328 +	  
 11.1329 +	  vtpmhandlerloginfo(VTPM_LOG_VTPM, "Sending DMI's response to guest.\n");
 11.1330 +	} // end else for if (dmi==0)
 11.1331 +        
 11.1332 +      } else { // This is a DMI lister thread. Thus this is from a DMI
 11.1333 +	// Raw TPM commands are not supported from the DMI
 11.1334 +	vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempt to use unsupported direct access to TPM.\n");
 11.1335 +	vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "Bad Command. dmi:%d, tag:%d, size:%d, ord:%d, Params: ", dmi, tag, in_param_size, ord);
 11.1336 +	for (i=0; i<cmd_size; i++) 
 11.1337 +	  vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]);
 11.1338 +	
 11.1339 +	vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
 11.1340 +        
 11.1341 +	status = TPM_FAIL;
 11.1342 +      } // end else for if BE Listener
 11.1343 +#endif
 11.1344 +      
 11.1345 +    } // end else for is VTPM Command
 11.1346 +
 11.1347 +    // This marks the beginning of preparing response to be sent out.
 11.1348 +    // Errors while handling responses jump here to reply with error messages
 11.1349 +    // NOTE: Currently there are no recoverable errors in multi-VM mode. If one
 11.1350 +    //       is added to the code, this ifdef should be removed.
 11.1351 +    //       Also note this is NOT referring to errors in commands, but rather
 11.1352 +    //       this is about I/O errors and such.
 11.1353 +#ifndef VTPM_MULTI_VM
 11.1354 + abort_with_error:
 11.1355 +#endif
 11.1356 +    
 11.1357 +    // Open tx_fh in preperation to send reponse back
 11.1358 +    if (*tx_fh < 0) {
 11.1359 +#ifdef VTPM_MULTI_VM
 11.1360 +      *tx_fh = open(VTPM_BE_DEV, O_RDWR);
 11.1361 +#else
 11.1362 +      if (threadType == BE_LISTENER_THREAD) 
 11.1363 + #ifdef DUMMY_BACKEND
 11.1364 +	*tx_fh = open("/tmp/out.fifo", O_RDWR);
 11.1365 + #else
 11.1366 +        *tx_fh = open(VTPM_BE_DEV, O_RDWR);
 11.1367 + #endif
 11.1368 +      else  // DMI Listener
 11.1369 +	*tx_fh = open(dmi_res->vtpm_tx_fname, O_WRONLY);
 11.1370 +#endif
 11.1371 +      }
 11.1372 +
 11.1373 +    
 11.1374 +    // Handle failed open
 11.1375 +    if (*tx_fh < 0) {
 11.1376 +      vtpmhandlerlogerror(VTPM_LOG_VTPM, "VTPM ERROR: Can't open outbound fh.\n");
 11.1377 +#ifdef VTPM_MULTI_VM
 11.1378 +      return TPM_IOERROR; 
 11.1379 +#else
 11.1380 +      *ret_value = TPM_IOERROR;
 11.1381 +      pthread_exit(ret_value);
 11.1382 +#endif
 11.1383 +    }        
 11.1384 +    
 11.1385 +    // Prepend VTPM header with destination DM stamped
 11.1386 +    out_param_size = buffer_len(result_buf);
 11.1387 +    out_message_size = VTPM_COMMAND_HEADER_SIZE_CLT + out_param_size;
 11.1388 +    out_message_size_full = VTPM_COMMAND_HEADER_SIZE_SRV + out_param_size;
 11.1389 +    out_message = (BYTE *) malloc (out_message_size_full);
 11.1390 +    
 11.1391 +    BSG_PackList(out_message, 4,
 11.1392 +		 BSG_TYPE_UINT32, (BYTE *) &dmi,
 11.1393 +		 BSG_TPM_TAG, (BYTE *) &tag,
 11.1394 +		 BSG_TYPE_UINT32, (BYTE *) &out_message_size,
 11.1395 +		 BSG_TPM_RESULT, (BYTE *) &status);
 11.1396 +    
 11.1397 +    if (buffer_len(result_buf) > 0) 
 11.1398 +      memcpy(out_message + VTPM_COMMAND_HEADER_SIZE_SRV, result_buf->bytes, out_param_size);
 11.1399 +    
 11.1400 +    
 11.1401 +    //Note: Send message + dmi_id
 11.1402 +    size_write = write(*tx_fh, out_message, out_message_size_full );
 11.1403 +    if (size_write > 0) {
 11.1404 +      vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT: 0x");
 11.1405 +      for (i=0; i < out_message_size_full; i++) 
 11.1406 +	vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", out_message[i]);
 11.1407 +      
 11.1408 +      vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");            
 11.1409 +    } else {
 11.1410 +      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error writing to BE. Aborting... \n");
 11.1411 +      close(*tx_fh);
 11.1412 +      *tx_fh = -1;
 11.1413 +      goto abort_command;
 11.1414 +    }
 11.1415 +    free(out_message);
 11.1416 +    
 11.1417 +    if (size_write < (int)out_message_size_full) {
 11.1418 +      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Unable to write full command to BE (%d/%d)\n", size_write, out_message_size_full);
 11.1419 +      goto abort_command;
 11.1420 +    }
 11.1421 +    
 11.1422 +    // On certain failures an error message cannot be sent. 
 11.1423 +    // This marks the beginning of cleanup in preperation for the next command.
 11.1424 +  abort_command:
 11.1425 +    //free buffers
 11.1426 +    bzero(cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
 11.1427 +    //free(in_param); // This was converted to command_buf. No need to free 
 11.1428 +    if (command_buf != result_buf) 
 11.1429 +      buffer_free(result_buf);
 11.1430 +    
 11.1431 +    buffer_free(command_buf);
 11.1432 +    
 11.1433 +#ifndef VTPM_MULTI_VM
 11.1434 +    if (threadType != BE_LISTENER_THREAD) {
 11.1435 +#endif
 11.1436 +      if ( (vtpm_globals->DMI_table_dirty) &&
 11.1437 +	   (VTPM_SaveService() != TPM_SUCCESS) ) {
 11.1438 +	vtpmhandlerlogerror(VTPM_LOG_VTPM, "ERROR: Unable to save manager data.\n");
 11.1439 +      }
 11.1440 +#ifndef VTPM_MULTI_VM
 11.1441 +    }
 11.1442 +#endif
 11.1443 +    
 11.1444 +  } // End while(1)
 11.1445 +  
 11.1446 +}
 11.1447 +
 11.1448 +
 11.1449 +///////////////////////////////////////////////////////////////////////////////
 11.1450 +TPM_RESULT VTPM_Init_Service() {
 11.1451 +  TPM_RESULT status = TPM_FAIL;   
 11.1452 +  BYTE *randomsead;
 11.1453 +  UINT32 randomsize;
 11.1454 +
 11.1455 +  if ((vtpm_globals = (VTPM_GLOBALS *) malloc(sizeof(VTPM_GLOBALS))) == NULL){
 11.1456 +    status = TPM_FAIL;
 11.1457 +    goto abort_egress;
 11.1458 +  }
 11.1459 +  memset(vtpm_globals, 0, sizeof(VTPM_GLOBALS));
 11.1460 +  vtpm_globals->be_fh = -1;
 11.1461 +
 11.1462 +#ifndef VTPM_MULTI_VM
 11.1463 +  vtpm_globals->vtpm_rx_fh = -1;
 11.1464 +  vtpm_globals->guest_rx_fh = -1;
 11.1465 +#endif
 11.1466 +  if ((vtpm_globals->dmi_map = create_hashtable(10, hashfunc32, equals32)) == NULL){
 11.1467 +    status = TPM_FAIL;
 11.1468 +    goto abort_egress;
 11.1469 +  }
 11.1470 +  
 11.1471 +  vtpm_globals->DMI_table_dirty = FALSE;
 11.1472 +  
 11.1473 +  // Create new TCS Object
 11.1474 +  vtpm_globals->manager_tcs_handle = 0;
 11.1475 +  
 11.1476 +  TPMTRYRETURN(TCS_create());
 11.1477 +  
 11.1478 +  // Create TCS Context for service
 11.1479 +  TPMTRYRETURN( TCS_OpenContext(&vtpm_globals->manager_tcs_handle ) );
 11.1480 +
 11.1481 +  TPMTRYRETURN( TCSP_GetRandom(vtpm_globals->manager_tcs_handle, 
 11.1482 +			       &randomsize, 
 11.1483 +			       &randomsead));
 11.1484 +  
 11.1485 +  Crypto_Init(randomsead, randomsize);
 11.1486 +  TPMTRYRETURN( TCS_FreeMemory (vtpm_globals->manager_tcs_handle, randomsead)); 
 11.1487 +	
 11.1488 +  // Create OIAP session for service's authorized commands
 11.1489 +  TPMTRYRETURN( VTSP_OIAP( vtpm_globals->manager_tcs_handle, 
 11.1490 +			   &vtpm_globals->keyAuth) );
 11.1491 +  vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
 11.1492 +
 11.1493 +	// If failed, create new Service.
 11.1494 +  if (VTPM_LoadService() != TPM_SUCCESS)
 11.1495 +    TPMTRYRETURN( VTPM_Create_Service() );    
 11.1496 +
 11.1497 +  //Load Storage Key 
 11.1498 +  TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
 11.1499 +			      TPM_SRK_KEYHANDLE,
 11.1500 +			      &vtpm_globals->storageKeyWrap,
 11.1501 +			      (const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
 11.1502 +			      &vtpm_globals->storageKeyHandle,
 11.1503 +			      &vtpm_globals->keyAuth,
 11.1504 +			      &vtpm_globals->storageKey) );
 11.1505 +
 11.1506 +  // Create entry for Dom0 for control messages
 11.1507 +  TPMTRYRETURN( VTPM_Handle_New_DMI(NULL) );
 11.1508 +    
 11.1509 +  // --------------------- Command handlers ---------------------------
 11.1510 +  
 11.1511 +  goto egress;
 11.1512 +  
 11.1513 + abort_egress:
 11.1514 + egress:
 11.1515 +  
 11.1516 +  return(status);
 11.1517 +}
 11.1518 + 
 11.1519 +void VTPM_Stop_Service() {
 11.1520 +  VTPM_DMI_RESOURCE *dmi_res;
 11.1521 +  struct hashtable_itr *dmi_itr;
 11.1522 +  
 11.1523 +  // Close all the TCS contexts. TCS should evict keys based on this
 11.1524 +  if (hashtable_count(vtpm_globals->dmi_map) > 0) {
 11.1525 +    dmi_itr = hashtable_iterator(vtpm_globals->dmi_map);
 11.1526 +    do {
 11.1527 +      dmi_res = (VTPM_DMI_RESOURCE *) hashtable_iterator_value(dmi_itr);
 11.1528 +      if (dmi_res->connected) 
 11.1529 +	close_dmi( dmi_res ); // Not really interested in return code
 11.1530 +      
 11.1531 +    } while (hashtable_iterator_advance(dmi_itr));
 11.1532 +		free (dmi_itr);
 11.1533 +  }
 11.1534 +  
 11.1535 +	
 11.1536 +  TCS_CloseContext(vtpm_globals->manager_tcs_handle);
 11.1537 +  
 11.1538 +  if ( (vtpm_globals->DMI_table_dirty) &&
 11.1539 +       (VTPM_SaveService() != TPM_SUCCESS) )
 11.1540 +    vtpmlogerror(VTPM_LOG_VTPM, "Unable to save manager data.\n");
 11.1541 +  
 11.1542 +  hashtable_destroy(vtpm_globals->dmi_map, 1);
 11.1543 +  free(vtpm_globals);
 11.1544 +  
 11.1545 +  close(vtpm_globals->be_fh);
 11.1546 +  Crypto_Exit();
 11.1547 +	
 11.1548 +  vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager stopped.\n");
 11.1549 +}
    12.1 --- a/tools/vtpm_manager/manager/vtpmpriv.h	Tue Sep 20 09:05:03 2005 +0000
    12.2 +++ b/tools/vtpm_manager/manager/vtpmpriv.h	Tue Sep 20 09:08:26 2005 +0000
    12.3 @@ -47,8 +47,8 @@
    12.4  
    12.5  #define STATE_FILE    "/var/vtpm/VTPM"
    12.6  #define DMI_NVM_FILE  "/var/vtpm/vtpm_dm_%d.data"
    12.7 -#define VTPM_BE_DEV   "/dev/vtpm"
    12.8 -#define VTPM_CTL_DM         0
    12.9 +#define VTPM_BE_DEV   "/dev/vtpm0"
   12.10 +#define VTPM_CTL_DM   0
   12.11  
   12.12  #ifndef VTPM_MUTLI_VM
   12.13   #include <sys/types.h>
    13.1 --- a/tools/vtpm_manager/tcs/Makefile	Tue Sep 20 09:05:03 2005 +0000
    13.2 +++ b/tools/vtpm_manager/tcs/Makefile	Tue Sep 20 09:08:26 2005 +0000
    13.3 @@ -13,6 +13,7 @@ clean:
    13.4  	rm -f *.a *.so *.o *.rpm $(DEP_FILES)
    13.5  
    13.6  mrproper: clean
    13.7 +	rm -f *~
    13.8  
    13.9  $(BIN): $(OBJS)
   13.10  	$(AR) rcs $(BIN) $(OBJS)
    14.1 --- a/tools/vtpm_manager/tcs/contextmgr.c	Tue Sep 20 09:05:03 2005 +0000
    14.2 +++ b/tools/vtpm_manager/tcs/contextmgr.c	Tue Sep 20 09:08:26 2005 +0000
    14.3 @@ -43,6 +43,7 @@
    14.4  #include "tcs.h"
    14.5  #include "contextmgr.h"
    14.6  #include "log.h"
    14.7 +#include "hashtable.h"
    14.8  
    14.9  BYTE* AddMemBlock(CONTEXT_HANDLE* pContextHandle, // in
   14.10  		  int    BlockSize)  { // in
   14.11 @@ -131,12 +132,14 @@ BOOL DeleteMemBlock(CONTEXT_HANDLE* pCon
   14.12    return bFound;
   14.13  }
   14.14  
   14.15 -BOOL AddHandleToList(CONTEXT_HANDLE* pContextHandle, // in
   14.16 +BOOL AddHandleToList(TCS_CONTEXT_HANDLE hContext, // in
   14.17  		     TPM_RESOURCE_TYPE type, // in
   14.18  		     TPM_HANDLE    handle)  { // in
   14.19    HANDLE_LIST* pNewHandle = NULL;
   14.20 -  
   14.21 +
   14.22    vtpmloginfo(VTPM_LOG_TCS_DEEP, "Adding Handle to list\n");
   14.23 +  CONTEXT_HANDLE* pContextHandle = LookupContext(hContext);
   14.24 +
   14.25    if (pContextHandle == NULL)
   14.26      return 0;
   14.27    
   14.28 @@ -154,11 +157,13 @@ BOOL AddHandleToList(CONTEXT_HANDLE* pCo
   14.29    return 1;
   14.30  }
   14.31  
   14.32 -BOOL DeleteHandleFromList(   CONTEXT_HANDLE*     pContextHandle, // in
   14.33 +BOOL DeleteHandleFromList(   TCS_CONTEXT_HANDLE hContext, // in		     
   14.34                               TPM_HANDLE          handle) { // in
   14.35      
   14.36 +  CONTEXT_HANDLE* pContextHandle = LookupContext(hContext);
   14.37 +
   14.38    HANDLE_LIST *pCurrentHandle = pContextHandle->pHandleList, 
   14.39 -    *pLastHandle = pCurrentHandle;
   14.40 +              *pLastHandle = pCurrentHandle;
   14.41    
   14.42    vtpmloginfo(VTPM_LOG_TCS_DEEP, "Deleting Handle from list\n");
   14.43    
   14.44 @@ -202,10 +207,10 @@ BOOL FreeHandleList(    CONTEXT_HANDLE* 
   14.45      
   14.46      switch (pCurrentHandle->type) {
   14.47      case TPM_RT_KEY:
   14.48 -      returncode = returncode && !TCSP_EvictKey((TCS_CONTEXT_HANDLE) pContextHandle, pCurrentHandle->handle);
   14.49 +      returncode = returncode && !TCSP_EvictKey(pContextHandle->handle, pCurrentHandle->handle);
   14.50        break;
   14.51      case TPM_RT_AUTH:
   14.52 -      returncode = returncode && !TCSP_TerminateHandle((TCS_CONTEXT_HANDLE) pContextHandle, pCurrentHandle->handle);
   14.53 +      returncode = returncode && !TCSP_TerminateHandle(pContextHandle->handle, pCurrentHandle->handle);
   14.54        break;
   14.55      default:
   14.56        returncode = FALSE;
    15.1 --- a/tools/vtpm_manager/tcs/contextmgr.h	Tue Sep 20 09:05:03 2005 +0000
    15.2 +++ b/tools/vtpm_manager/tcs/contextmgr.h	Tue Sep 20 09:08:26 2005 +0000
    15.3 @@ -57,6 +57,7 @@ typedef struct handle_List {
    15.4  } HANDLE_LIST;
    15.5  
    15.6  typedef struct context_handle {
    15.7 +  TCS_CONTEXT_HANDLE handle;
    15.8    int nBlockCount;
    15.9    BLOCK* pTopBlock;
   15.10    HANDLE_LIST* pHandleList;
   15.11 @@ -69,11 +70,11 @@ BOOL DeleteMemBlock(CONTEXT_HANDLE* pCon
   15.12                      BYTE*           pTCPA_BYTEs); // in
   15.13  
   15.14  
   15.15 -BOOL AddHandleToList(   CONTEXT_HANDLE*     pContextHandle, // in
   15.16 +BOOL AddHandleToList(   TCS_CONTEXT_HANDLE hContext, // in	
   15.17                          TPM_RESOURCE_TYPE   type, // in
   15.18                          TPM_HANDLE          handle); // in
   15.19  
   15.20 -BOOL DeleteHandleFromList(   CONTEXT_HANDLE*     pContextHandle, // in
   15.21 +BOOL DeleteHandleFromList(   TCS_CONTEXT_HANDLE hContext, // in	
   15.22                               TPM_HANDLE          handle); // in
   15.23  
   15.24  BOOL FreeHandleList(    CONTEXT_HANDLE*     pContextHandle); // in
    16.1 --- a/tools/vtpm_manager/tcs/tcs.c	Tue Sep 20 09:05:03 2005 +0000
    16.2 +++ b/tools/vtpm_manager/tcs/tcs.c	Tue Sep 20 09:08:26 2005 +0000
    16.3 @@ -47,9 +47,10 @@
    16.4  #include "contextmgr.h"
    16.5  #include "tpmddl.h"
    16.6  #include "log.h"
    16.7 +#include "hashtable.h"
    16.8 +#include "hashtable_itr.h"
    16.9  
   16.10  // Static Global Vars for the TCS
   16.11 -static BOOL TCS_m_bConnected;
   16.12  static int TCS_m_nCount = 0;
   16.13  
   16.14  #define TCPA_MAX_BUFFER_LENGTH 0x2000
   16.15 @@ -57,6 +58,21 @@ static int TCS_m_nCount = 0;
   16.16  static BYTE InBuf [TCPA_MAX_BUFFER_LENGTH];
   16.17  static BYTE OutBuf[TCPA_MAX_BUFFER_LENGTH];
   16.18  
   16.19 +struct hashtable *context_ht;
   16.20 +
   16.21 +// -------------------------- Hash table functions --------------------
   16.22 +
   16.23 +static unsigned int hashfunc32(void *ky) {
   16.24 +  return (* (UINT32 *) ky);
   16.25 +}
   16.26 +
   16.27 +static int equals32(void *k1, void *k2) {
   16.28 +  return (*(UINT32 *) k1 == *(UINT32 *) k2);
   16.29 +}
   16.30 +
   16.31 +CONTEXT_HANDLE *LookupContext( TCS_CONTEXT_HANDLE  hContext) {
   16.32 +  return( (CONTEXT_HANDLE *) hashtable_search(context_ht, &hContext) );
   16.33 +}
   16.34  
   16.35  // ---------------------------------------------------------------------------------
   16.36  // Initialization/Uninitialization SubComponent API
   16.37 @@ -64,34 +80,50 @@ static BYTE OutBuf[TCPA_MAX_BUFFER_LENGT
   16.38  TPM_RESULT TCS_create() {
   16.39    TDDL_RESULT hRes = TDDL_E_FAIL;
   16.40    TPM_RESULT result = TPM_FAIL;
   16.41 -  TCS_m_bConnected = FALSE;
   16.42    
   16.43    if (TCS_m_nCount == 0) {
   16.44      vtpmloginfo(VTPM_LOG_TCS, "Constructing new TCS:\n");
   16.45      hRes = TDDL_Open();
   16.46 -    
   16.47 -    if (hRes == TDDL_SUCCESS) {
   16.48 -      TCS_m_bConnected = TRUE;
   16.49 +
   16.50 +    context_ht = create_hashtable(10, hashfunc32, equals32);
   16.51 +	  
   16.52 +    if ((hRes == TDDL_SUCCESS) && (context_ht != NULL)) {
   16.53        result = TPM_SUCCESS;
   16.54 +      TCS_m_nCount++;
   16.55 +    } else {
   16.56 +      result = TPM_IOERROR;
   16.57 +      hashtable_destroy(context_ht, 1);
   16.58      }
   16.59    } else
   16.60 -    TCS_m_bConnected = TRUE;
   16.61 -  
   16.62 -  TCS_m_nCount++;
   16.63 -  
   16.64 +    TCS_m_nCount++;
   16.65 +    
   16.66    return(result);
   16.67  }
   16.68  
   16.69  
   16.70  void TCS_destroy()
   16.71  {
   16.72 -  // FIXME: Should iterate through all open contexts and close them.
   16.73    TCS_m_nCount--;
   16.74    
   16.75 -  if (TCS_m_bConnected == TRUE && TCS_m_nCount == 0) {
   16.76 +  if (TCS_m_nCount == 0) {
   16.77      vtpmloginfo(VTPM_LOG_TCS, "Destructing TCS:\n");
   16.78      TDDL_Close();
   16.79 -    TCS_m_bConnected = FALSE;
   16.80 +
   16.81 +    struct hashtable_itr *context_itr;
   16.82 +    TCS_CONTEXT_HANDLE  *hContext;
   16.83 +    
   16.84 +    // Close all the TCS contexts. TCS should evict keys based on this
   16.85 +    if (hashtable_count(context_ht) > 0) {
   16.86 +      context_itr = hashtable_iterator(context_ht);
   16.87 +      do {
   16.88 +        hContext = (TCS_CONTEXT_HANDLE *) hashtable_iterator_key(context_itr);
   16.89 +	if (TCS_CloseContext(*hContext) != TPM_SUCCESS) 
   16.90 +	    vtpmlogerror(VTPM_LOG_TCS, "Failed to close context %d properly.\n", *hContext);
   16.91 +      
   16.92 +      } while (hashtable_iterator_advance(context_itr));
   16.93 +      free(context_itr);
   16.94 +    }
   16.95 +    hashtable_destroy(context_ht, 1);
   16.96    }
   16.97    
   16.98  }
   16.99 @@ -101,7 +133,7 @@ TPM_RESULT TCS_Malloc(  TCS_CONTEXT_HAND
  16.100                          BYTE**              ppMemPtr) {// out
  16.101  
  16.102    TPM_RESULT returnCode = TPM_FAIL;
  16.103 -  CONTEXT_HANDLE* pContextHandle = (CONTEXT_HANDLE*)hContext;
  16.104 +  CONTEXT_HANDLE* pContextHandle = LookupContext(hContext);
  16.105    
  16.106    if (pContextHandle != NULL && ppMemPtr != NULL) {
  16.107      *ppMemPtr = (BYTE *)AddMemBlock(pContextHandle, MemSize);
  16.108 @@ -114,7 +146,7 @@ TPM_RESULT TCS_Malloc(  TCS_CONTEXT_HAND
  16.109  TPM_RESULT TCS_FreeMemory(  TCS_CONTEXT_HANDLE  hContext, // in
  16.110                              BYTE*               pMemory) { // in
  16.111    TPM_RESULT returnCode = TPM_FAIL;
  16.112 -  CONTEXT_HANDLE* pContextHandle = (CONTEXT_HANDLE*)hContext;
  16.113 +  CONTEXT_HANDLE* pContextHandle = LookupContext(hContext);
  16.114    
  16.115    if ( (pContextHandle != NULL && pMemory != NULL) &&
  16.116         (DeleteMemBlock(pContextHandle, pMemory) == TRUE) )
  16.117 @@ -126,16 +158,16 @@ TPM_RESULT TCS_FreeMemory(  TCS_CONTEXT_
  16.118  
  16.119  TPM_RESULT TCS_OpenContext(TCS_CONTEXT_HANDLE* hContext) { // out
  16.120    TPM_RESULT returnCode = TPM_FAIL;
  16.121 +  TCS_CONTEXT_HANDLE *newContext;
  16.122    
  16.123    vtpmloginfo(VTPM_LOG_TCS, "Calling TCS_OpenContext:\n");
  16.124    
  16.125    // hContext must point to a null memory context handle
  16.126    if(*hContext == HANDLE_NULL) {
  16.127 -    CONTEXT_HANDLE* pContextHandle = (CONTEXT_HANDLE *)malloc(sizeof(CONTEXT_HANDLE));
  16.128 +    CONTEXT_HANDLE* pContextHandle = (CONTEXT_HANDLE *) malloc(sizeof(CONTEXT_HANDLE));
  16.129      if (pContextHandle == NULL) 
  16.130        return TPM_SIZE;
  16.131      
  16.132 -    
  16.133      // initialize to 0
  16.134      pContextHandle->nBlockCount = 0;
  16.135      pContextHandle->pTopBlock = NULL;
  16.136 @@ -144,19 +176,32 @@ TPM_RESULT TCS_OpenContext(TCS_CONTEXT_H
  16.137      // Create New Block
  16.138      AddMemBlock(pContextHandle, BLOCK_SIZE);
  16.139      
  16.140 -    *hContext = (TCS_CONTEXT_HANDLE)pContextHandle;
  16.141 -    returnCode = TPM_SUCCESS;
  16.142 +    newContext = (TCS_CONTEXT_HANDLE *) malloc(sizeof(TCS_CONTEXT_HANDLE));
  16.143 +    *newContext = (TCS_CONTEXT_HANDLE) (((uintptr_t) pContextHandle >> 2) & 0xffffffff);
  16.144 +    
  16.145 +    if (hashtable_search(context_ht, &newContext) !=NULL)
  16.146 +    	*newContext += 1;
  16.147 +    
  16.148 +    pContextHandle->handle = *newContext;
  16.149 +    if (!hashtable_insert(context_ht, newContext, pContextHandle)) {
  16.150 +        free(newContext);
  16.151 +        free(pContextHandle);
  16.152 +    	returnCode = TPM_FAIL;
  16.153 +    } else {
  16.154 +    	*hContext = *newContext;
  16.155 +    	returnCode = TPM_SUCCESS;
  16.156 +    }
  16.157    }
  16.158    
  16.159    return(returnCode);
  16.160  }
  16.161  
  16.162  TPM_RESULT TCS_CloseContext(TCS_CONTEXT_HANDLE hContext) {// in
  16.163 -  //FIXME: TCS SHOULD Track track failed auths and make sure
  16.164 +  //FIXME: TCS SHOULD Track failed auths and make sure
  16.165    //we don't try and re-free them here.
  16.166    TPM_RESULT returnCode = TPM_FAIL;
  16.167    
  16.168 -  CONTEXT_HANDLE* pContextHandle = (CONTEXT_HANDLE*)hContext;
  16.169 +  CONTEXT_HANDLE* pContextHandle = LookupContext(hContext);
  16.170    
  16.171    if(pContextHandle != NULL) {
  16.172      // Print test info
  16.173 @@ -171,6 +216,9 @@ TPM_RESULT TCS_CloseContext(TCS_CONTEXT_
  16.174        vtpmlogerror(VTPM_LOG_TCS, "Not all handles evicted from TPM.\n");
  16.175      
  16.176      // Release the TPM's resources
  16.177 +    if (hashtable_remove(context_ht, &hContext) == NULL) 
  16.178 +      vtpmlogerror(VTPM_LOG_TCS, "Not all handles evicted from TPM.\n");
  16.179 +    
  16.180      free(pContextHandle);
  16.181      returnCode = TPM_SUCCESS;
  16.182    }
  16.183 @@ -255,7 +303,7 @@ TPM_RESULT TCSP_OIAP(TCS_CONTEXT_HANDLE 
  16.184  		     BSG_TYPE_UINT32, authHandle, 
  16.185  		     BSG_TPM_NONCE, nonce0);
  16.186        
  16.187 -      if (!AddHandleToList((CONTEXT_HANDLE *)hContext, TPM_RT_AUTH, *authHandle)) 
  16.188 +      if (!AddHandleToList(hContext, TPM_RT_AUTH, *authHandle)) 
  16.189          vtpmlogerror(VTPM_LOG_TCS, "New AuthHandle not recorded\n");
  16.190        
  16.191        vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n", paramSize);
  16.192 @@ -321,7 +369,7 @@ TPM_RESULT TCSP_OSAP(TCS_CONTEXT_HANDLE 
  16.193  		     BSG_TPM_NONCE, nonceEven, 
  16.194  		     BSG_TPM_NONCE, nonceEvenOSAP);
  16.195        
  16.196 -      if (!AddHandleToList((CONTEXT_HANDLE *)hContext, TPM_RT_AUTH, *authHandle)) {
  16.197 +      if (!AddHandleToList(hContext, TPM_RT_AUTH, *authHandle)) {
  16.198  	    vtpmlogerror(VTPM_LOG_TCS, "New AuthHandle not recorded\n");
  16.199        }
  16.200        
  16.201 @@ -498,7 +546,7 @@ TPM_RESULT TCSP_TerminateHandle(TCS_CONT
  16.202  			   BSG_TYPE_UINT32, &paramSize, 
  16.203  			   BSG_TPM_COMMAND_CODE, &returnCode);
  16.204      
  16.205 -    if (!DeleteHandleFromList((CONTEXT_HANDLE *)hContext, handle)) 
  16.206 +    if (!DeleteHandleFromList(hContext, handle)) 
  16.207        vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n");
  16.208         
  16.209      
  16.210 @@ -897,7 +945,7 @@ TPM_RESULT TCSP_LoadKeyByBlob(TCS_CONTEX
  16.211  		      phKeyTCSI);
  16.212        unpackAuth(pAuth, OutBuf+i);
  16.213        
  16.214 -      if (!AddHandleToList((CONTEXT_HANDLE *)hContext, TPM_RT_KEY, *phKeyTCSI)) {
  16.215 +      if (!AddHandleToList(hContext, TPM_RT_KEY, *phKeyTCSI)) {
  16.216          vtpmlogerror(VTPM_LOG_TCS, "New KeyHandle not recorded\n");
  16.217        }
  16.218        
  16.219 @@ -942,7 +990,7 @@ TPM_RESULT TCSP_EvictKey(TCS_CONTEXT_HAN
  16.220  			   BSG_TYPE_UINT32, &paramSize, 
  16.221  			   BSG_TPM_COMMAND_CODE, &returnCode);
  16.222      
  16.223 -    if (!DeleteHandleFromList((CONTEXT_HANDLE *)hContext, hKey)) {
  16.224 +    if (!DeleteHandleFromList(hContext, hKey)) {
  16.225        vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n");
  16.226      }	 
  16.227      
    17.1 --- a/tools/vtpm_manager/tcs/tcs.h	Tue Sep 20 09:05:03 2005 +0000
    17.2 +++ b/tools/vtpm_manager/tcs/tcs.h	Tue Sep 20 09:08:26 2005 +0000
    17.3 @@ -41,6 +41,7 @@
    17.4  #define __TCS_H__
    17.5  
    17.6  #include "tcg.h"
    17.7 +#include "contextmgr.h"
    17.8  #include "buffer.h"
    17.9  
   17.10  #define HANDLE_NULL 0
   17.11 @@ -235,4 +236,7 @@ TPM_RESULT TCSP_RawTransmitData(UINT32 i
   17.12  				UINT32 *outDataSize,// in/out
   17.13  				BYTE *outData);     // out
   17.14  
   17.15 +///////////// Private Functions ////////////////////
   17.16 +CONTEXT_HANDLE* LookupContext( TCS_CONTEXT_HANDLE hContext);
   17.17 +
   17.18  #endif //TCS_H
    18.1 --- a/tools/vtpm_manager/tcs/transmit.c	Tue Sep 20 09:05:03 2005 +0000
    18.2 +++ b/tools/vtpm_manager/tcs/transmit.c	Tue Sep 20 09:08:26 2005 +0000
    18.3 @@ -69,7 +69,7 @@ TDDL_TransmitData( TDDL_BYTE* in,
    18.4      ERRORDIE (TPM_IOERROR);
    18.5    }
    18.6    else if ((TDDL_UINT32) size < insize) {
    18.7 -    vtpmlogerror(VTPM_LOG_TXDATA, "Wrote %d instead of %d bytes!\n", size, insize);
    18.8 +    vtpmlogerror(VTPM_LOG_TXDATA, "Wrote %d instead of %d bytes!\n", (int) size, insize);
    18.9      // ... ?
   18.10    }
   18.11  
    19.1 --- a/tools/vtpm_manager/util/Makefile	Tue Sep 20 09:05:03 2005 +0000
    19.2 +++ b/tools/vtpm_manager/util/Makefile	Tue Sep 20 09:08:26 2005 +0000
    19.3 @@ -13,6 +13,7 @@ clean:
    19.4  	rm -f *.a *.so *.o *.rpm $(DEP_FILES)
    19.5  
    19.6  mrproper: clean
    19.7 +	rm -f *~
    19.8  
    19.9  $(BIN): $(OBJS)
   19.10  	$(AR) rcs $(BIN) $(OBJS)
    20.1 --- a/tools/vtpm_manager/util/tcg.h	Tue Sep 20 09:05:03 2005 +0000
    20.2 +++ b/tools/vtpm_manager/util/tcg.h	Tue Sep 20 09:08:26 2005 +0000
    20.3 @@ -453,14 +453,14 @@ typedef struct TCS_AUTH {
    20.4  // DEPENDS: local var 'status' of type TPM_RESULT
    20.5  // DEPENDS: label 'abort_egress' which cleans up and returns the status
    20.6  #define ERRORDIE(s) do { status = s; \
    20.7 -                         fprintf (stderr, "*** ERRORDIE in %s, line %i\n", __func__, __LINE__); \
    20.8 +                         fprintf (stderr, "*** ERRORDIE in %s at %s: %i\n", __func__, __FILE__, __LINE__); \
    20.9                           goto abort_egress; } \
   20.10                      while (0)
   20.11  
   20.12  // ASSUME: the return value used after the abort_egress label has been set
   20.13  // already (eg. the 'status' local var)
   20.14  #define STATUSCHECK(s) if (s != TPM_SUCCESS) { \
   20.15 -                            fprintf (stderr, "*** ERR in %s, line %i\n", __func__, __LINE__); \
   20.16 +                            fprintf (stderr, "*** ERR in %s at %s:%i\n", __func__, __FILE__, __LINE__); \
   20.17                              goto abort_egress; \
   20.18                          }
   20.19  
   20.20 @@ -475,7 +475,7 @@ typedef struct TCS_AUTH {
   20.21  // Try command c. If it fails, print error message, set status to actual return code. Goto shame
   20.22  #define TPMTRYRETURN(c) do { status = c; \
   20.23                               if (status != TPM_SUCCESS) { \
   20.24 -                               printf("ERROR in %s:%i code: %s.\n", __func__, __LINE__, tpm_get_error_name(status)); \
   20.25 +                               printf("ERROR in %s at %s:%i code: %s.\n", __func__, __FILE__, __LINE__, tpm_get_error_name(status)); \
   20.26                                 goto abort_egress; \
   20.27                               } \
   20.28                          } while(0)