[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] merge?



# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID dd668f7527cb35b4e2c2434720d65ce7e9eeceaa
# Parent  84ab93e1ee05015bcc1c3218fac5b3cfd9fb2ffb
# Parent  e02a45b9104380bc7593c54554469bbb6e92e56d
merge?

diff -r 84ab93e1ee05 -r dd668f7527cb .hgignore
--- a/.hgignore Thu Sep  1 10:08:53 2005
+++ b/.hgignore Thu Sep  1 10:16:14 2005
@@ -141,6 +141,9 @@
 ^tools/vnet/vnet-module/\.tmp_versions/.*$
 ^tools/vnet/vnet-module/vnet_module\.mod\..*$
 ^tools/vnetd/vnetd$
+^tools/vtpm/vtpm*
+^tools/vtpm/tpm_emulator-*
+^tools/vtpm_manager/manager/vtpm_managerd
 ^tools/web-shutdown\.tap$
 ^tools/x2d2/minixend$
 ^tools/xcs/xcs$
diff -r 84ab93e1ee05 -r dd668f7527cb Config.mk
--- a/Config.mk Thu Sep  1 10:08:53 2005
+++ b/Config.mk Thu Sep  1 10:16:14 2005
@@ -48,3 +48,4 @@
 # Optional components
 XENSTAT_XENTOP ?= y
 
+VTPM_TOOLS ?= n
diff -r 84ab93e1ee05 -r dd668f7527cb Makefile
--- a/Makefile  Thu Sep  1 10:08:53 2005
+++ b/Makefile  Thu Sep  1 10:16:14 2005
@@ -35,11 +35,11 @@
 export pae=y
 endif
 
-.PHONY:        all dist install xen tools kernels docs world clean mkpatches 
mrproper
+.PHONY:        all dist install xen kernels tools docs world clean mkpatches 
mrproper
 .PHONY:        kbuild kdelete kclean
 
 # build and install everything into the standard system directories
-install: install-xen install-tools install-kernels install-docs
+install: install-xen install-kernels install-tools install-docs
 
 build: kernels
        $(MAKE) -C xen build
@@ -47,7 +47,7 @@
        $(MAKE) -C docs build
 
 # build and install everything into local dist directory
-dist: xen tools kernels docs
+dist: xen kernels tools docs
        $(INSTALL_DIR) $(DISTDIR)/check
        $(INSTALL_DATA) ./COPYING $(DISTDIR)
        $(INSTALL_DATA) ./README $(DISTDIR)
diff -r 84ab93e1ee05 -r dd668f7527cb linux-2.6-xen-sparse/arch/xen/Kconfig
--- a/linux-2.6-xen-sparse/arch/xen/Kconfig     Thu Sep  1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/arch/xen/Kconfig     Thu Sep  1 10:16:14 2005
@@ -69,6 +69,27 @@
          The network-device backend driver allows the kernel to export its
          network devices to other guests via a high-performance shared-memory
          interface.
+
+config XEN_TPMDEV_FRONTEND
+        bool "TPM-device frontend driver"
+        default n
+        help
+          The TPM-device frontend driver.
+
+config XEN_TPMDEV_BACKEND
+        bool "TPM-device backend driver"
+        default n
+        help
+          The TPM-device backend driver
+
+config XEN_TPMDEV_CLOSE_IF_VTPM_FAILS
+        bool "TPM backend closes upon vTPM failure"
+        depends on XEN_TPMDEV_BACKEND
+        default n
+        help
+          The TPM backend closes the channel if the vTPM in userspace indicates
+          a failure. The corresponding domain's channel will be closed.
+          Say Y if you want this feature.
 
 config XEN_BLKDEV_FRONTEND
        bool "Block-device frontend driver"
diff -r 84ab93e1ee05 -r dd668f7527cb 
linux-2.6-xen-sparse/arch/xen/Kconfig.drivers
--- a/linux-2.6-xen-sparse/arch/xen/Kconfig.drivers     Thu Sep  1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/arch/xen/Kconfig.drivers     Thu Sep  1 10:16:14 2005
@@ -49,6 +49,10 @@
 endif
 
 if !XEN_PHYSDEV_ACCESS
+source "drivers/char/tpm/Kconfig.domU"
+endif
+
+if !XEN_PHYSDEV_ACCESS
 
 menu "Character devices"
 
diff -r 84ab93e1ee05 -r dd668f7527cb 
linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32
--- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32       Thu Sep 
 1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32       Thu Sep 
 1 10:16:14 2005
@@ -15,6 +15,8 @@
 CONFIG_XEN_BLKDEV_BACKEND=y
 # CONFIG_XEN_BLKDEV_TAP_BE is not set
 CONFIG_XEN_NETDEV_BACKEND=y
+# CONFIG_XEN_TPMDEV_FRONTEND is not set
+# CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_GRANT_TX=y
diff -r 84ab93e1ee05 -r dd668f7527cb 
linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64
--- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64       Thu Sep 
 1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64       Thu Sep 
 1 10:16:14 2005
@@ -15,6 +15,8 @@
 CONFIG_XEN_BLKDEV_BACKEND=y
 # CONFIG_XEN_BLKDEV_TAP_BE is not set
 CONFIG_XEN_NETDEV_BACKEND=y
+# CONFIG_XEN_TPMDEV_FRONTEND is not set
+# CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_GRANT_TX=y
diff -r 84ab93e1ee05 -r dd668f7527cb 
linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32
--- a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32       Thu Sep 
 1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32       Thu Sep 
 1 10:16:14 2005
@@ -12,6 +12,8 @@
 #
 # CONFIG_XEN_PRIVILEGED_GUEST is not set
 # CONFIG_XEN_PHYSDEV_ACCESS is not set
+# CONFIG_XEN_TPMDEV_FRONTEND is not set
+# CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_GRANT_TX=y
@@ -336,6 +338,7 @@
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_TCG_TPM is not set
 
 #
 # Character devices
diff -r 84ab93e1ee05 -r dd668f7527cb 
linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64
--- a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64       Thu Sep 
 1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64       Thu Sep 
 1 10:16:14 2005
@@ -12,6 +12,8 @@
 #
 # CONFIG_XEN_PRIVILEGED_GUEST is not set
 # CONFIG_XEN_PHYSDEV_ACCESS is not set
+# CONFIG_XEN_TPMDEV_FRONTEND is not set
+# CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_GRANT_TX=y
@@ -662,6 +664,7 @@
 CONFIG_INPUT=m
 CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
+# CONFIG_TCG_TPM is not set
 
 #
 # Character devices
diff -r 84ab93e1ee05 -r dd668f7527cb 
linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32
--- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32        Thu Sep 
 1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32        Thu Sep 
 1 10:16:14 2005
@@ -15,6 +15,8 @@
 CONFIG_XEN_BLKDEV_BACKEND=y
 # CONFIG_XEN_BLKDEV_TAP_BE is not set
 CONFIG_XEN_NETDEV_BACKEND=y
+# CONFIG_XEN_TPMDEV_FRONTEND is not set
+# CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_GRANT_TX=y
@@ -1855,9 +1857,7 @@
 #
 # TPM devices
 #
-CONFIG_TCG_TPM=m
-CONFIG_TCG_NSC=m
-CONFIG_TCG_ATMEL=m
+# CONFIG_TCG_TPM is not set
 
 #
 # I2C support
diff -r 84ab93e1ee05 -r dd668f7527cb 
linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64
--- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64        Thu Sep 
 1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64        Thu Sep 
 1 10:16:14 2005
@@ -15,6 +15,8 @@
 CONFIG_XEN_BLKDEV_BACKEND=y
 # CONFIG_XEN_BLKDEV_TAP_BE is not set
 CONFIG_XEN_NETDEV_BACKEND=y
+# CONFIG_XEN_TPMDEV_FRONTEND is not set
+# CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_GRANT_TX=y
diff -r 84ab93e1ee05 -r dd668f7527cb linux-2.6-xen-sparse/drivers/xen/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/Makefile Thu Sep  1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/Makefile Thu Sep  1 10:16:14 2005
@@ -8,7 +8,9 @@
 
 obj-$(CONFIG_XEN_BLKDEV_BACKEND)       += blkback/
 obj-$(CONFIG_XEN_NETDEV_BACKEND)       += netback/
+obj-$(CONFIG_XEN_TPMDEV_BACKEND)       += tpmback/
 obj-$(CONFIG_XEN_BLKDEV_FRONTEND)      += blkfront/
 obj-$(CONFIG_XEN_NETDEV_FRONTEND)      += netfront/
 obj-$(CONFIG_XEN_BLKDEV_TAP)           += blktap/
+obj-$(CONFIG_XEN_TPMDEV_FRONTEND)      += tpmfront/
 
diff -r 84ab93e1ee05 -r dd668f7527cb 
linux-2.6-xen-sparse/include/asm-xen/asm-i386/system.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/system.h    Thu Sep  1 
10:08:53 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/system.h    Thu Sep  1 
10:16:14 2005
@@ -561,8 +561,14 @@
 #define local_irq_disable()    __cli()
 #define local_irq_enable()     __sti()
 
+/* Don't use smp_processor_id: this is called in debug versions of that fn. */
+#ifdef CONFIG_SMP
 #define irqs_disabled()                        \
-    HYPERVISOR_shared_info->vcpu_data[smp_processor_id()].evtchn_upcall_mask
+    HYPERVISOR_shared_info->vcpu_data[__smp_processor_id()].evtchn_upcall_mask
+#else
+#define irqs_disabled()                        \
+    HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_mask
+#endif
 
 /*
  * disable hlt during certain critical i/o operations
diff -r 84ab93e1ee05 -r dd668f7527cb 
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/system.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/system.h  Thu Sep  1 
10:08:53 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/system.h  Thu Sep  1 
10:16:14 2005
@@ -387,8 +387,14 @@
 #define local_irq_disable()    __cli()
 #define local_irq_enable()     __sti()
 
+/* Don't use smp_processor_id: this is called in debug versions of that fn. */
+#ifdef CONFIG_SMP
 #define irqs_disabled()                        \
-    HYPERVISOR_shared_info->vcpu_data[smp_processor_id()].evtchn_upcall_mask
+    HYPERVISOR_shared_info->vcpu_data[__smp_processor_id()].evtchn_upcall_mask
+#else
+#define irqs_disabled()                        \
+    HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_mask
+#endif
 
 /*
  * disable hlt during certain critical i/o operations
diff -r 84ab93e1ee05 -r dd668f7527cb tools/Makefile
--- a/tools/Makefile    Thu Sep  1 10:08:53 2005
+++ b/tools/Makefile    Thu Sep  1 10:16:14 2005
@@ -12,7 +12,13 @@
 SUBDIRS += firmware
 SUBDIRS += security
 SUBDIRS += console
+ifeq ($(VTPM_TOOLS),y)
+SUBDIRS += vtpm_manager
+SUBDIRS += vtpm
+endif
 SUBDIRS += xenstat
+
+.PHONY: all install clean check check_clean ioemu eioemuinstall ioemuclean
 
 # These don't cross-compile
 ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH))
diff -r 84ab93e1ee05 -r dd668f7527cb tools/examples/xmexample1
--- a/tools/examples/xmexample1 Thu Sep  1 10:08:53 2005
+++ b/tools/examples/xmexample1 Thu Sep  1 10:16:14 2005
@@ -48,6 +48,20 @@
 disk = [ 'phy:hda1,hda1,w' ]
 
 #----------------------------------------------------------------------------
+# Define to which TPM instance the user domain should communicate.
+# The vtpm entry is of the form 'instance=INSTANCE,backend=DOM'
+# where INSTANCE indicates the instance number of the TPM the VM
+# should be talking to and DOM provides the domain where the backend
+# is located.
+# Note that no two virtual machines should try to connect to the same
+# TPM instance. The handling of all TPM instances does require
+# some management effort in so far that VM configration files (and thus
+# a VM) should be associated with a TPM instance throughout the lifetime
+# of the VM / VM configuration file. The instance number must be
+# greater or equal to 1.
+#vtpm = [ 'instance=1,backend=0' ]
+
+#----------------------------------------------------------------------------
 # Set the kernel command line for the new domain.
 # You only need to define the IP parameters and hostname if the domain's
 # IP config doesn't, e.g. in ifcfg-eth0 or via DHCP.
diff -r 84ab93e1ee05 -r dd668f7527cb tools/examples/xmexample2
--- a/tools/examples/xmexample2 Thu Sep  1 10:08:53 2005
+++ b/tools/examples/xmexample2 Thu Sep  1 10:16:14 2005
@@ -84,6 +84,20 @@
          'phy:sda6,sda6,r' ]
 
 #----------------------------------------------------------------------------
+# Define to which TPM instance the user domain should communicate.
+# The vtpm entry is of the form 'instance=INSTANCE,backend=DOM'
+# where INSTANCE indicates the instance number of the TPM the VM
+# should be talking to and DOM provides the domain where the backend
+# is located.
+# Note that no two virtual machines should try to connect to the same
+# TPM instance. The handling of all TPM instances does require
+# some management effort in so far that VM configration files (and thus
+# a VM) should be associated with a TPM instance throughout the lifetime
+# of the VM / VM configuration file. The instance number must be
+# greater or equal to 1.
+#vtpm = ['instance=%d,backend=0' % (vmid) ]
+
+#----------------------------------------------------------------------------
 # Set the kernel command line for the new domain.
 # You only need to define the IP parameters and hostname if the domain's
 # IP config doesn't, e.g. in ifcfg-eth0 or via DHCP.
diff -r 84ab93e1ee05 -r dd668f7527cb tools/examples/xmexample3
--- a/tools/examples/xmexample3 Thu Sep  1 10:08:53 2005
+++ b/tools/examples/xmexample3 Thu Sep  1 10:16:14 2005
@@ -80,6 +80,20 @@
 disk = [ 'phy:hda%d,hda1,w' % (vmid)]
 
 #----------------------------------------------------------------------------
+# Define to which TPM instance the user domain should communicate.
+# The vtpm entry is of the form 'instance=INSTANCE,backend=DOM'
+# where INSTANCE indicates the instance number of the TPM the VM
+# should be talking to and DOM provides the domain where the backend
+# is located.
+# Note that no two virtual machines should try to connect to the same
+# TPM instance. The handling of all TPM instances does require
+# some management effort in so far that VM configration files (and thus
+# a VM) should be associated with a TPM instance throughout the lifetime
+# of the VM / VM configuration file. The instance number must be
+# greater or equal to 1.
+#vtpm = ['instance=%d,backend=0' % (vmid) ]
+
+#----------------------------------------------------------------------------
 # Set the kernel command line for the new domain.
 # You only need to define the IP parameters and hostname if the domain's
 # IP config doesn't, e.g. in ifcfg-eth0 or via DHCP.
diff -r 84ab93e1ee05 -r dd668f7527cb tools/libxc/xc_private.c
--- a/tools/libxc/xc_private.c  Thu Sep  1 10:08:53 2005
+++ b/tools/libxc/xc_private.c  Thu Sep  1 10:16:14 2005
@@ -422,3 +422,8 @@
 {
     return do_dom0_op(xc_handle, op);
 }
+
+int xc_version(int xc_handle, int cmd, void *arg)
+{
+    return do_xen_version(xc_handle, cmd, arg);
+}
diff -r 84ab93e1ee05 -r dd668f7527cb tools/libxc/xc_private.h
--- a/tools/libxc/xc_private.h  Thu Sep  1 10:08:53 2005
+++ b/tools/libxc/xc_private.h  Thu Sep  1 10:16:14 2005
@@ -59,6 +59,17 @@
                       (unsigned long)hypercall);
 }
 
+static inline int do_xen_version(int xc_handle, int cmd, void *dest)
+{
+    privcmd_hypercall_t hypercall;
+
+    hypercall.op     = __HYPERVISOR_xen_version;
+    hypercall.arg[0] = (unsigned long) cmd;
+    hypercall.arg[1] = (unsigned long) dest;
+    
+    return do_xen_hypercall(xc_handle, &hypercall);
+}
+
 static inline int do_dom0_op(int xc_handle, dom0_op_t *op)
 {
     int ret = -1;
diff -r 84ab93e1ee05 -r dd668f7527cb tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Thu Sep  1 10:08:53 2005
+++ b/tools/libxc/xenctrl.h     Thu Sep  1 10:16:14 2005
@@ -23,6 +23,7 @@
 #include <sys/ptrace.h>
 #include <xen/xen.h>
 #include <xen/dom0_ops.h>
+#include <xen/version.h>
 #include <xen/event_channel.h>
 #include <xen/sched_ctl.h>
 #include <xen/acm.h>
@@ -497,6 +498,8 @@
 /* Execute a privileged dom0 operation. */
 int xc_dom0_op(int xc_handle, dom0_op_t *op);
 
+int xc_version(int xc_handle, int cmd, void *arg);
+
 /* Initializes the store (for dom0)
    remote_port should be the remote end of a bound interdomain channel between
    the store and dom0.
diff -r 84ab93e1ee05 -r dd668f7527cb tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Thu Sep  1 10:08:53 2005
+++ b/tools/python/xen/lowlevel/xc/xc.c Thu Sep  1 10:16:14 2005
@@ -707,6 +707,39 @@
                          "cpu_khz",          info.cpu_khz);
 }
 
+static PyObject *pyxc_xeninfo(PyObject *self,
+                              PyObject *args,
+                              PyObject *kwds)
+{
+    XcObject *xc = (XcObject *)self;
+    xen_extraversion_t xen_extra;
+    xen_compile_info_t xen_cc;
+    xen_changeset_info_t xen_chgset;
+    long xen_version;
+
+    xen_version = xc_version(xc->xc_handle, XENVER_version, NULL);
+
+    if ( xc_version(xc->xc_handle, XENVER_extraversion, &xen_extra) != 0 )
+        return PyErr_SetFromErrno(xc_error);
+
+    if ( xc_version(xc->xc_handle, XENVER_compile_info, &xen_cc) != 0 )
+        return PyErr_SetFromErrno(xc_error);
+
+    if ( xc_version(xc->xc_handle, XENVER_changeset, &xen_chgset) != 0 )
+        return PyErr_SetFromErrno(xc_error);
+
+    return Py_BuildValue("{s:i,s:i,s:s,s:s,s:s,s:s,s:s,s:s}",
+                         "xen_major", xen_version >> 16,
+                         "xen_minor", (xen_version & 0xffff),
+                         "xen_extra", xen_extra,
+                         "xen_changeset", xen_chgset,
+                         "cc_compiler", xen_cc.compiler,
+                         "cc_compile_by", xen_cc.compile_by,
+                         "cc_compile_domain", xen_cc.compile_domain,
+                         "cc_compile_date", xen_cc.compile_date);
+}
+
+
 static PyObject *pyxc_sedf_domain_set(PyObject *self,
                                          PyObject *args,
                                          PyObject *kwds)
@@ -1089,6 +1122,13 @@
       "Returns [dict]: information about the hardware"
       "        [None]: on failure.\n" },
 
+    { "xeninfo",
+      (PyCFunction)pyxc_xeninfo,
+      METH_VARARGS, "\n"
+      "Get information about the Xen host\n"
+      "Returns [dict]: information about Xen"
+      "        [None]: on failure.\n" },
+
     { "shadow_control", 
       (PyCFunction)pyxc_shadow_control, 
       METH_VARARGS | METH_KEYWORDS, "\n"
diff -r 84ab93e1ee05 -r dd668f7527cb tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Thu Sep  1 10:08:53 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py   Thu Sep  1 10:16:14 2005
@@ -269,6 +269,7 @@
         self.blkif_backend = False
         self.netif_backend = False
         self.netif_idx = 0
+        self.tpmif_backend = False
         
         #todo: state: running, suspended
         self.state = STATE_VM_OK
@@ -458,6 +459,31 @@
 
             return
         
+        if type == 'vtpm':
+            backdom = domain_exists(sxp.child_value(devconfig, 'backend', '0'))
+
+            devnum = int(sxp.child_value(devconfig, 'instance', '0'))
+            log.error("The domain has a TPM with instance %d." % devnum)
+
+            # create backend db
+            backdb = backdom.db.addChild("/backend/%s/%s/%d" %
+                                         (type, self.uuid, devnum))
+            # create frontend db
+            db = self.db.addChild("/device/%s/%d" % (type, devnum))
+
+            backdb['frontend'] = db.getPath()
+            backdb['frontend-id'] = "%i" % self.id
+            backdb['instance'] = sxp.child_value(devconfig, 'instance', '0')
+            backdb.saveDB(save=True)
+
+            db['handle'] = "%i" % devnum
+            db['backend'] = backdb.getPath()
+            db['backend-id'] = "%i" % int(sxp.child_value(devconfig,
+                                                          'backend', '0'))
+            db.saveDB(save=True)
+
+            return
+
         ctrl = self.findDeviceController(type)
         return ctrl.createDevice(devconfig, recreate=self.recreate,
                                  change=change)
@@ -779,6 +805,11 @@
                 for dev in typedb.keys():
                     typedb[dev].delete()
                 typedb.saveDB(save=True)
+            if type == 'vtpm':
+                typedb = ddb.addChild(type)
+                for dev in typedb.keys():
+                    typedb[dev].delete()
+                typedb.saveDB(save=True)
 
     def show(self):
         """Print virtual machine info.
@@ -1018,6 +1049,8 @@
                 self.netif_backend = True
             elif name == 'usbif':
                 self.usbif_backend = True
+            elif name == 'tpmif':
+                self.tpmif_backend = True
             else:
                 raise VmError('invalid backend type:' + str(name))
 
@@ -1189,6 +1222,10 @@
 controller.addDevControllerClass("vif", netif.NetifController)
 add_device_handler("vif", "vif")
 
+from server import tpmif
+controller.addDevControllerClass("vtpm", tpmif.TPMifController)
+add_device_handler("vtpm", "vtpm")
+
 from server import pciif
 controller.addDevControllerClass("pci", pciif.PciController)
 add_device_handler("pci", "pci")
diff -r 84ab93e1ee05 -r dd668f7527cb tools/python/xen/xend/XendNode.py
--- a/tools/python/xen/xend/XendNode.py Thu Sep  1 10:08:53 2005
+++ b/tools/python/xen/xend/XendNode.py Thu Sep  1 10:16:14 2005
@@ -46,7 +46,7 @@
         return self.xc.bvtsched_global_get()
     
     def info(self):
-        return self.nodeinfo() + self.physinfo()
+        return self.nodeinfo() + self.physinfo() + self.xeninfo()
 
     def nodeinfo(self):
         (sys, host, rel, ver, mch) = os.uname()
@@ -65,7 +65,16 @@
                 ['free_memory', pinfo['free_pages']/256]]
         return info
         
-        
+    def xeninfo(self):
+        xinfo = self.xc.xeninfo()
+       return [['xen_major', xinfo['xen_major']],
+               ['xen_minor', xinfo['xen_minor']],
+               ['xen_extra', xinfo['xen_extra']],
+               ['xen_changeset', xinfo['xen_changeset']],
+               ['cc_compiler', xinfo['cc_compiler']],
+                ['cc_compile_by', xinfo['cc_compile_by']],
+                ['cc_compile_domain', xinfo['cc_compile_domain']],
+                ['cc_compile_date', xinfo['cc_compile_date']]]
 
 def instance():
     global inst
diff -r 84ab93e1ee05 -r dd668f7527cb tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Thu Sep  1 10:08:53 2005
+++ b/tools/python/xen/xend/image.py    Thu Sep  1 10:16:14 2005
@@ -31,6 +31,9 @@
 
 """Flag for a net device backend domain."""
 SIF_NET_BE_DOMAIN = (1<<5)
+
+"""Flag for a TPM device backend domain."""
+SIF_TPM_BE_DOMAIN = (1<<7)
 
 class ImageHandler:
     """Abstract base class for image handlers.
@@ -194,6 +197,7 @@
         self.flags = 0
         if self.vm.netif_backend: self.flags |= SIF_NET_BE_DOMAIN
         if self.vm.blkif_backend: self.flags |= SIF_BLK_BE_DOMAIN
+        if self.vm.tpmif_backend: self.flags |= SIF_TPM_BE_DOMAIN
 
         if self.vm.recreate or self.vm.restore:
             return
@@ -366,6 +370,11 @@
                mac = sxp.child_value(vifinfo, 'mac')
                ret.append("-macaddr")
                ret.append("%s" % mac)
+            if name == 'vtpm':
+               vtpminfo = sxp.child(device, 'vtpm')
+               instance = sxp.child_value(vtpminfo, 'instance')
+               ret.append("-instance")
+               ret.append("%s" % instance)
 
        # Handle graphics library related options
        vnc = sxp.child_value(self.vm.config, 'vnc')
diff -r 84ab93e1ee05 -r dd668f7527cb tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Thu Sep  1 10:08:53 2005
+++ b/tools/python/xen/xm/create.py     Thu Sep  1 10:16:14 2005
@@ -176,6 +176,12 @@
           fn=set_bool, default=0,
           use="Make the domain a network interface backend.")
 
+gopts.var('tpmif', val='frontend=DOM',
+          fn=append_value, default=[],
+          use="""Make the domain a TPM interface backend. If frontend is given,
+          the frontend in that domain is connected to this backend (not
+          completely implemented, yet)""")
+
 gopts.var('disk', val='phy:DEV,VDEV,MODE[,DOM]',
           fn=append_value, default=[],
           use="""Add a disk device to a domain. The physical device is DEV,
@@ -213,6 +219,12 @@
           where D is the domain id and N is the interface id.
           This option may be repeated to add more than one vif.
           Specifying vifs will increase the number of interfaces as needed.""")
+
+gopts.var('vtpm', val="instance=INSTANCE,backend=DOM",
+          fn=append_value, default=[],
+          use="""Add a tpm interface. On the backend side us the the given
+          instance as virtual TPM instance. Use the backend in the given
+          domain.""")
 
 gopts.var('nics', val="NUM",
           fn=set_int, default=1,
@@ -373,6 +385,46 @@
     for path in vals.usb:
         config_usb = ['usb', ['path', path]]
         config_devs.append(['device', config_usb])
+
+def configure_vtpm(opts, config_devs, vals):
+    """Create the config for virtual TPM interfaces.
+    """
+    vtpm = vals.vtpm
+    vtpm_n = 1
+    for idx in range(0, vtpm_n):
+        if idx < len(vtpm):
+            d = vtpm[idx]
+            instance = d.get('instance')
+            if instance == "VTPMD":
+                instance = "0"
+            else:
+                try:
+                    if int(instance) == 0:
+                        opts.err('VM config error: vTPM instance must not be 
0.')
+                except ValueError:
+                    opts.err('Vm config error: could not parse instance 
number.')
+            backend = d.get('backend')
+            config_vtpm = ['vtpm']
+            if instance:
+                config_vtpm.append(['instance', instance])
+            if backend:
+                config_vtpm.append(['backend', backend])
+            config_devs.append(['device', config_vtpm])
+
+def configure_tpmif(opts, config_devs, vals):
+    """Create the config for virtual TPM interfaces.
+    """
+    tpmif = vals.tpmif
+    tpmif_n = 1
+    for idx in range(0, tpmif_n):
+        if idx < len(tpmif):
+            d = tpmif[idx]
+            frontend = d.get('frontend')
+            config_tpmif = ['tpmif']
+            if frontend:
+                config_tpmif.append(['frontend', frontend])
+            config_devs.append(['device', config_tpmif])
+
 
 def randomMAC():
     """Generate a random MAC address.
@@ -484,6 +536,8 @@
         config.append(['backend', ['blkif']])
     if vals.netif:
         config.append(['backend', ['netif']])
+    if vals.tpmif:
+        config.append(['backend', ['tpmif']])
     if vals.restart:
         config.append(['restart', vals.restart])
 
@@ -496,6 +550,7 @@
     configure_pci(opts, config_devs, vals)
     configure_vifs(opts, config_devs, vals)
     configure_usb(opts, config_devs, vals)
+    configure_vtpm(opts, config_devs, vals)
     configure_vmx(opts, config_devs, vals)
     config += config_devs
 
@@ -543,6 +598,38 @@
             d[k] = v
         vifs.append(d)
     vals.vif = vifs
+
+def preprocess_vtpm(opts, vals):
+    if not vals.vtpm: return
+    vtpms = []
+    for vtpm in vals.vtpm:
+        d = {}
+        a = vtpm.split(',')
+        for b in a:
+            (k, v) = b.strip().split('=', 1)
+            k = k.strip()
+            v = v.strip()
+            if k not in ['backend', 'instance']:
+                opts.err('Invalid vtpm specifier: ' + vtpm)
+            d[k] = v
+        vtpms.append(d)
+    vals.vtpm = vtpms
+
+def preprocess_tpmif(opts, vals):
+    if not vals.tpmif: return
+    tpmifs = []
+    for tpmif in vals.tpmif:
+        d = {}
+        a = tpmif.split(',')
+        for b in a:
+            (k, v) = b.strip().split('=', 1)
+            k = k.strip()
+            v = v.strip()
+            if k not in ['frontend']:
+                opts.err('Invalid tpmif specifier: ' + vtpm)
+            d[k] = v
+        tpmifs.append(d)
+    vals.tpmif = tpmifs
 
 def preprocess_ip(opts, vals):
     if vals.ip or vals.dhcp != 'off':
@@ -632,6 +719,8 @@
     preprocess_ip(opts, vals)
     preprocess_nfs(opts, vals)
     preprocess_vnc(opts, vals)
+    preprocess_vtpm(opts, vals)
+    preprocess_tpmif(opts, vals)
          
 def make_domain(opts, config):
     """Create, build and start a domain.
diff -r 84ab93e1ee05 -r dd668f7527cb xen/arch/x86/cdb.c
--- a/xen/arch/x86/cdb.c        Thu Sep  1 10:08:53 2005
+++ b/xen/arch/x86/cdb.c        Thu Sep  1 10:16:14 2005
@@ -21,7 +21,7 @@
    debugger. so avoid it. */
 #define dbg_printk(...)
 
-static unsigned char opt_cdb[30] = "none";
+static char opt_cdb[30] = "none";
 string_param("cdb", opt_cdb);
 
 struct xendbg_context {
diff -r 84ab93e1ee05 -r dd668f7527cb xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c       Thu Sep  1 10:08:53 2005
+++ b/xen/arch/x86/domain_build.c       Thu Sep  1 10:16:14 2005
@@ -20,6 +20,7 @@
 #include <asm/processor.h>
 #include <asm/desc.h>
 #include <asm/i387.h>
+#include <asm/physdev.h>
 #include <asm/shadow.h>
 
 static long dom0_nrpages;
@@ -707,6 +708,18 @@
         printk("dom0: shadow setup done\n");
     }
 
+    /*
+     * Modify I/O port access permissions.
+     */
+    /* Master Interrupt Controller (PIC). */
+    physdev_modify_ioport_access_range(dom0, 0, 0x20, 2);
+    /* Slave Interrupt Controller (PIC). */
+    physdev_modify_ioport_access_range(dom0, 0, 0xA0, 2);
+    /* Interval Timer (PIT). */
+    physdev_modify_ioport_access_range(dom0, 0, 0x40, 4);
+    /* PIT Channel 2 / PC Speaker Control. */
+    physdev_modify_ioport_access_range(dom0, 0, 0x61, 1);
+
     return 0;
 }
 
diff -r 84ab93e1ee05 -r dd668f7527cb xen/common/kernel.c
--- a/xen/common/kernel.c       Thu Sep  1 10:08:53 2005
+++ b/xen/common/kernel.c       Thu Sep  1 10:16:14 2005
@@ -110,6 +110,27 @@
             return -EFAULT;
         return 0;
     }
+
+    case XENVER_capabilities:
+    {
+        struct xen_capabilities_info info;
+        
+        /* FIXME */
+        info.arch = 0;
+        info.pae = 0;
+        if ( copy_to_user(arg, &info, sizeof(info)) )
+            return -EFAULT;
+        return 0;
+    }
+    
+    case XENVER_changeset:
+    {
+        xen_changeset_info_t chgset;
+        safe_strcpy(chgset, XEN_CHANGESET);
+        if ( copy_to_user(arg, chgset, sizeof(chgset)) )
+            return -EFAULT;
+        return 0;
+    }
     }
 
     return -ENOSYS;
diff -r 84ab93e1ee05 -r dd668f7527cb xen/include/asm-x86/asm_defns.h
--- a/xen/include/asm-x86/asm_defns.h   Thu Sep  1 10:08:53 2005
+++ b/xen/include/asm-x86/asm_defns.h   Thu Sep  1 10:16:14 2005
@@ -6,11 +6,6 @@
 #include <asm/asm-offsets.h>
 #include <asm/processor.h>
 
-#ifndef STR
-#define __STR(x) #x
-#define STR(x) __STR(x)
-#endif
-
 #ifdef __x86_64__
 #include <asm/x86_64/asm_defns.h>
 #else
diff -r 84ab93e1ee05 -r dd668f7527cb xen/include/asm-x86/bitops.h
--- a/xen/include/asm-x86/bitops.h      Thu Sep  1 10:08:53 2005
+++ b/xen/include/asm-x86/bitops.h      Thu Sep  1 10:16:14 2005
@@ -6,11 +6,6 @@
  */
 
 #include <xen/config.h>
-
-#ifndef STR
-#define __STR(x) #x
-#define STR(x) __STR(x)
-#endif
 
 /*
  * These have to be done with inline assembly: that way the bit-setting
diff -r 84ab93e1ee05 -r dd668f7527cb xen/include/asm-x86/shadow_64.h
--- a/xen/include/asm-x86/shadow_64.h   Thu Sep  1 10:08:53 2005
+++ b/xen/include/asm-x86/shadow_64.h   Thu Sep  1 10:16:14 2005
@@ -450,7 +450,9 @@
        /*
         * If it's not external mode, then mfn should be machine physical.
         */
-       mfn = __gpfn_to_mfn(d, (entry_get_value(gle) >> PAGE_SHIFT));
+       mfn = __gpfn_to_mfn(d, (entry_get_paddr(gle) >> PAGE_SHIFT));
+        if (mfn == -1)
+            return 1;
 
         lva = (pgentry_64_t *) phys_to_virt(
            mfn << PAGE_SHIFT);
diff -r 84ab93e1ee05 -r dd668f7527cb xen/include/asm-x86/x86_32/asm_defns.h
--- a/xen/include/asm-x86/x86_32/asm_defns.h    Thu Sep  1 10:08:53 2005
+++ b/xen/include/asm-x86/x86_32/asm_defns.h    Thu Sep  1 10:16:14 2005
@@ -1,45 +1,5 @@
 #ifndef __X86_32_ASM_DEFNS_H__
 #define __X86_32_ASM_DEFNS_H__
-
-/* Maybe auto-generate the following two cases (quoted vs. unquoted). */
-#ifndef __ASSEMBLY__
-
-#define __SAVE_ALL_PRE                                                  \
-        "cld;"                                                          \
-        "pushl %eax;"                                                   \
-        "pushl %ebp;"                                                   \
-        "pushl %edi;"                                                   \
-        "pushl %esi;"                                                   \
-        "pushl %edx;"                                                   \
-        "pushl %ecx;"                                                   \
-        "pushl %ebx;"                                                   \
-        "testl $"STR(X86_EFLAGS_VM)","STR(UREGS_eflags)"(%esp);"        \
-        "jz 2f;"                                                        \
-        "call setup_vm86_frame;"                                        \
-        "jmp 3f;"                                                       \
-        "2:testb $3,"STR(UREGS_cs)"(%esp);"                             \
-        "jz 1f;"                                                        \
-        "mov %ds,"STR(UREGS_ds)"(%esp);"                                \
-        "mov %es,"STR(UREGS_es)"(%esp);"                                \
-        "mov %fs,"STR(UREGS_fs)"(%esp);"                                \
-        "mov %gs,"STR(UREGS_gs)"(%esp);"                                \
-        "3:"
-
-#define SAVE_ALL_NOSEGREGS(_reg)                \
-        __SAVE_ALL_PRE                          \
-        "1:"
-
-#define SET_XEN_SEGMENTS(_reg)                                  \
-        "movl $("STR(__HYPERVISOR_DS)"),%e"STR(_reg)"x;"        \
-        "mov %e"STR(_reg)"x,%ds;"                              \
-        "mov %e"STR(_reg)"x,%es;"
-
-#define SAVE_ALL(_reg)                          \
-        __SAVE_ALL_PRE                          \
-        SET_XEN_SEGMENTS(_reg)                  \
-        "1:"
-
-#else
 
 #define __SAVE_ALL_PRE                                  \
         cld;                                            \
@@ -50,7 +10,7 @@
         pushl %edx;                                     \
         pushl %ecx;                                     \
         pushl %ebx;                                     \
-        testl $X86_EFLAGS_VM,UREGS_eflags(%esp);        \
+        testl $(X86_EFLAGS_VM),UREGS_eflags(%esp);      \
         jz 2f;                                          \
         call setup_vm86_frame;                          \
         jmp 3f;                                         \
@@ -83,8 +43,6 @@
 #define PERFC_INCR(_name,_idx)
 #endif
 
-#endif
-
 #define BUILD_SMP_INTERRUPT(x,v) XBUILD_SMP_INTERRUPT(x,v)
 #define XBUILD_SMP_INTERRUPT(x,v)               \
 asmlinkage void x(void);                        \
@@ -92,7 +50,7 @@
     "\n"__ALIGN_STR"\n"                         \
     STR(x) ":\n\t"                              \
     "pushl $"#v"<<16\n\t"                       \
-    SAVE_ALL(a)                                 \
+    STR(SAVE_ALL(a))                            \
     "call "STR(smp_##x)"\n\t"                   \
     "jmp ret_from_intr\n");
 
@@ -103,7 +61,7 @@
 "\n"__ALIGN_STR"\n"                             \
 STR(x) ":\n\t"                                  \
     "pushl $"#v"<<16\n\t"                       \
-    SAVE_ALL(a)                                 \
+    STR(SAVE_ALL(a))                            \
     "movl %esp,%eax\n\t"                        \
     "pushl %eax\n\t"                            \
     "call "STR(smp_##x)"\n\t"                   \
@@ -114,7 +72,7 @@
 __asm__(                                        \
     "\n" __ALIGN_STR"\n"                        \
     "common_interrupt:\n\t"                     \
-    SAVE_ALL(a)                                 \
+    STR(SAVE_ALL(a))                            \
     "movl %esp,%eax\n\t"                        \
     "pushl %eax\n\t"                            \
     "call " STR(do_IRQ) "\n\t"                  \
diff -r 84ab93e1ee05 -r dd668f7527cb xen/include/asm-x86/x86_64/asm_defns.h
--- a/xen/include/asm-x86/x86_64/asm_defns.h    Thu Sep  1 10:08:53 2005
+++ b/xen/include/asm-x86/x86_64/asm_defns.h    Thu Sep  1 10:16:14 2005
@@ -1,49 +1,5 @@
 #ifndef __X86_64_ASM_DEFNS_H__
 #define __X86_64_ASM_DEFNS_H__
-
-/* Maybe auto-generate the following two cases (quoted vs. unquoted). */
-#ifndef __ASSEMBLY__
-
-#define SAVE_ALL                                \
-        "cld;"                                  \
-        "pushq %rdi;"                           \
-        "pushq %rsi;"                           \
-        "pushq %rdx;"                           \
-        "pushq %rcx;"                           \
-        "pushq %rax;"                           \
-        "pushq %r8;"                            \
-        "pushq %r9;"                            \
-        "pushq %r10;"                           \
-        "pushq %r11;"                           \
-        "pushq %rbx;"                           \
-        "pushq %rbp;"                           \
-        "pushq %r12;"                           \
-        "pushq %r13;"                           \
-        "pushq %r14;"                           \
-        "pushq %r15;"
-
-#define RESTORE_ALL                             \
-        "popq  %r15;"                           \
-        "popq  %r14;"                           \
-        "popq  %r13;"                           \
-        "popq  %r12;"                           \
-        "popq  %rbp;"                           \
-        "popq  %rbx;"                           \
-        "popq  %r11;"                           \
-        "popq  %r10;"                           \
-        "popq  %r9;"                            \
-        "popq  %r8;"                            \
-        "popq  %rax;"                           \
-        "popq  %rcx;"                           \
-        "popq  %rdx;"                           \
-        "popq  %rsi;"                           \
-        "popq  %rdi;"
-
-/* Work around AMD erratum #88 */
-#define safe_swapgs                             \
-        "mfence; swapgs;"
-
-#else
 
 #define SAVE_ALL                                \
         cld;                                    \
@@ -90,7 +46,9 @@
 #define PERFC_INCR(_name,_idx)
 #endif
 
-#endif
+/* Work around AMD erratum #88 */
+#define safe_swapgs                             \
+        "mfence; swapgs;"
 
 #define BUILD_SMP_INTERRUPT(x,v) XBUILD_SMP_INTERRUPT(x,v)
 #define XBUILD_SMP_INTERRUPT(x,v)               \
@@ -100,7 +58,7 @@
     STR(x) ":\n\t"                              \
     "pushq $0\n\t"                              \
     "movl $"#v",4(%rsp)\n\t"                    \
-    SAVE_ALL                                    \
+    STR(SAVE_ALL)                               \
     "callq "STR(smp_##x)"\n\t"                  \
     "jmp ret_from_intr\n");
 
@@ -112,7 +70,7 @@
 STR(x) ":\n\t"                                  \
     "pushq $0\n\t"                              \
     "movl $"#v",4(%rsp)\n\t"                    \
-    SAVE_ALL                                    \
+    STR(SAVE_ALL)                               \
     "movq %rsp,%rdi\n\t"                        \
     "callq "STR(smp_##x)"\n\t"                  \
     "jmp ret_from_intr\n");
@@ -121,7 +79,7 @@
 __asm__(                                        \
     "\n" __ALIGN_STR"\n"                        \
     "common_interrupt:\n\t"                     \
-    SAVE_ALL                                    \
+    STR(SAVE_ALL)                               \
     "movq %rsp,%rdi\n\t"                        \
     "callq " STR(do_IRQ) "\n\t"                 \
     "jmp ret_from_intr\n");
diff -r 84ab93e1ee05 -r dd668f7527cb xen/include/public/version.h
--- a/xen/include/public/version.h      Thu Sep  1 10:08:53 2005
+++ b/xen/include/public/version.h      Thu Sep  1 10:16:14 2005
@@ -28,4 +28,13 @@
     char compile_date[32];
 } xen_compile_info_t;
 
+#define XENVER_capabilities 3
+typedef struct xen_capabilities_info {
+    int pae;
+    int arch;
+} xen_capabilities_info_t;
+
+#define XENVER_changeset 4
+typedef char xen_changeset_info_t[64];
+
 #endif /* __XEN_PUBLIC_VERSION_H__ */
diff -r 84ab93e1ee05 -r dd668f7527cb xen/include/public/xen.h
--- a/xen/include/public/xen.h  Thu Sep  1 10:08:53 2005
+++ b/xen/include/public/xen.h  Thu Sep  1 10:16:14 2005
@@ -455,6 +455,7 @@
 #define SIF_BLK_BE_DOMAIN (1<<4)  /* Is this a block backend domain? */
 #define SIF_NET_BE_DOMAIN (1<<5)  /* Is this a net backend domain? */
 #define SIF_USB_BE_DOMAIN (1<<6)  /* Is this a usb backend domain? */
+#define SIF_TPM_BE_DOMAIN (1<<7)  /* Is this a TPM backend domain? */
 /* For use in guest OSes. */
 extern shared_info_t *HYPERVISOR_shared_info;
 
diff -r 84ab93e1ee05 -r dd668f7527cb xen/include/xen/config.h
--- a/xen/include/xen/config.h  Thu Sep  1 10:08:53 2005
+++ b/xen/include/xen/config.h  Thu Sep  1 10:16:14 2005
@@ -40,4 +40,7 @@
 #include <xen/compiler.h>
 #endif
 
+#define __STR(...) #__VA_ARGS__
+#define STR(...) __STR(__VA_ARGS__)
+
 #endif /* __XEN_CONFIG_H__ */
diff -r 84ab93e1ee05 -r dd668f7527cb MSG
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/MSG       Thu Sep  1 10:16:14 2005
@@ -0,0 +1,7 @@
+TPM FE/BE code using xenbus (some control message stuff still there; to 
+be removed soon). 
+
+Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxx>
+Signed-off-by: Kylene Hall <kjhall@xxxxxxxxxx>
+Signed-off-by: Mahadevan Gomathisankaran <gmdev@xxxxxxxxxxx>
+Signed-off-by: Steven Hand <steven@xxxxxxxxxxxxx>
diff -r 84ab93e1ee05 -r dd668f7527cb docs/misc/vtpm.txt
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/docs/misc/vtpm.txt        Thu Sep  1 10:16:14 2005
@@ -0,0 +1,122 @@
+Copyright: IBM Corporation (C), Intel Corporation
+17 August 2005
+Authors: Stefan Berger <stefanb@xxxxxxxxxx> (IBM), 
+         Employees of Intel Corp
+
+This document gives a short introduction to the virtual TPM support
+in XEN and goes as far as connecting a user domain to a virtual TPM
+instance and doing a short test to verify success. It is assumed
+that the user is fairly familiar with compiling and installing XEN
+and Linux on a machine. 
+ 
+Production Prerequisites: An x86-based machine machine with an ATMEL or
+National Semiconductor (NSC) TPM on the motherboard.
+Development Prerequisites: An emulator for TESTING ONLY is provided
+
+
+Compiling XEN tree:
+-------------------
+
+Compile the XEN tree as usual.
+
+make uninstall; make mrproper; make install 
+
+After compiling the tree, verify that in the linux-2.6.XX-xen0/.config 
+file at least the following entries are set as below (they should be set
+by default):
+
+CONFIG_XEN_TPMDEV_BACKEND=y
+CONFIG_XEN_TPMDEV_GRANT=y
+
+CONFIG_TCG_TPM=m
+CONFIG_TCG_NSC=m
+CONFIG_TCG_ATMEL=m
+
+
+Verify that in the linux-2.6.XX-xenU/.config file at least the 
+Following entries are set as below (they should be set by default):
+
+CONFIG_XEN_TPMDEV_FRONTEND=y
+CONFIG_XEN_TPMDEV_GRANT=y
+
+CONFIG_TCG_TPM=y
+CONFIG_TCG_XEN=y
+
+
+Reboot the machine with the created XEN-0 kernel.
+
+Note: If you do not want any TPM-related code compiled into your
+kernel or built as module then comment all the above lines like
+this example:
+# CONFIG_TCG_TPM is not set
+
+
+Modifying VM Configuration files:
+---------------------------------
+
+VM configuration files need to be adapted to make a TPM instance
+available to a user domain. The following VM configuration file is
+an example of how a user domain can be configured to have a TPM
+available. It works similar to making a network interface
+available to a domain.
+
+kernel = "/boot/vmlinuz-2.6.12-xenU"
+ramdisk = "/xen/initrd_domU/U1_ramdisk.img"
+memory = 32
+name = "TPMUserDomain0"
+vtpm = ['instance=1,backend=0']
+root = "/dev/ram0 cosole=tty ro"
+vif = ['backend=0']
+
+In the above configuration file the line 'vtpm = ...' provides
+information about the domain where the virtual TPM is running and
+where the TPM backend has been compiled into - this has to be 
+domain 0  at the moment - and which TPM instance the user domain
+is supposed to talk to. Note that each running VM must use a 
+different instance and that using instance 0 is NOT allowed.
+
+Note: If you do not want TPM functionality for your user domain simply
+leave out the 'vtpm' line in the configuration file.
+
+
+Running the TPM:
+----------------
+
+To run the vTPM, dev device /dev/vtpm must be available.
+Verify that 'ls -l /dev/vtpm' shows the following output:
+
+crw-------  1 root root 10, 225 Aug 11 06:58 /dev/vtpm
+
+If it is not available, run the following command as 'root'.
+mknod /dev/vtpm c 10 225
+
+Make sure that the vTPM is running in domain 0. To do this run the
+following
+
+/usr/bin/vtpm_managerd
+
+Start a user domain using the 'xm create' command. Once you are in the
+shell of the user domain, you should be able to do the following:
+
+> cd /sys/devices/vtpm
+> ls
+cancel  caps   pcrs    pubek
+> cat pcrs
+PCR-00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+PCR-01: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+PCR-02: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+PCR-03: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+PCR-04: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+PCR-05: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+PCR-06: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+PCR-07: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+PCR-08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[...]
+
+At this point the user domain has been sucessfully connected to its
+virtual TPM instance.
+
+For further information please read the documentation in 
+tools/vtpm_manager/README and tools/vtpm/README
+
+Stefan Berger and Employees of the Intel Corp
diff -r 84ab93e1ee05 -r dd668f7527cb 
linux-2.6-xen-sparse/drivers/char/tpm/Kconfig.domU
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig.domU        Thu Sep  1 
10:16:14 2005
@@ -0,0 +1,30 @@
+#
+# TPM device configuration
+#
+
+menu "TPM devices"
+
+config TCG_TPM
+       tristate "TPM Support for XEN"
+       depends on ARCH_XEN && !XEN_PHYSDEV_ACCESS
+       ---help---
+         If you want to make TPM security available in your system,
+         say Yes and it will be accessible from within a user domain.  For
+         more information see <http://www.trustedcomputinggroup.org>.
+         An implementation of the Trusted Software Stack (TSS), the
+         userspace enablement piece of the specification, can be
+         obtained at: <http://sourceforge.net/projects/trousers>.  To
+         compile this driver as a module, choose M here; the module
+         will be called tpm. If unsure, say N.
+
+config TCG_XEN
+       tristate "XEN TPM Interface"
+       depends on TCG_TPM && ARCH_XEN
+       ---help---
+         If you want to make TPM support available to a Xen
+         user domain, say Yes and it will
+          be accessible from within Linux. To compile this driver
+          as a module, choose M here; the module will be called
+          tpm_xen.
+
+endmenu
diff -r 84ab93e1ee05 -r dd668f7527cb 
linux-2.6-xen-sparse/drivers/char/tpm/Makefile
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/Makefile    Thu Sep  1 10:16:14 2005
@@ -0,0 +1,12 @@
+#
+# Makefile for the kernel tpm device drivers.
+#
+ifeq ($(CONFIG_XEN_PHYSDEV_ACCESS),y)
+obj-$(CONFIG_TCG_TPM) += tpm.o
+obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
+obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o
+obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o
+else
+obj-$(CONFIG_TCG_TPM) += tpm_nopci.o
+obj-$(CONFIG_TCG_XEN) += tpm_xen.o
+endif
diff -r 84ab93e1ee05 -r dd668f7527cb linux-2.6-xen-sparse/drivers/char/tpm/tpm.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c       Thu Sep  1 10:16:14 2005
@@ -0,0 +1,627 @@
+/*
+ * Copyright (C) 2004 IBM Corporation
+ *
+ * Authors:
+ * Leendert van Doorn <leendert@xxxxxxxxxxxxxx>
+ * Dave Safford <safford@xxxxxxxxxxxxxx>
+ * Reiner Sailer <sailer@xxxxxxxxxxxxxx>
+ * Kylene Hall <kjhall@xxxxxxxxxx>
+ *
+ * Maintained by: <tpmdd_devel@xxxxxxxxxxxxxxxxxxxxx>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * Note, the TPM chip is not interrupt driven (only polling)
+ * and can have very long timeouts (minutes!). Hence the unusual
+ * calls to schedule_timeout.
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/spinlock.h>
+#include "tpm.h"
+
+#define        TPM_MINOR                       224     /* officially assigned 
*/
+
+#define        TPM_BUFSIZE                     2048
+
+static LIST_HEAD(tpm_chip_list);
+static DEFINE_SPINLOCK(driver_lock);
+static int dev_mask[32];
+
+static void user_reader_timeout(unsigned long ptr)
+{
+       struct tpm_chip *chip = (struct tpm_chip *) ptr;
+
+       down(&chip->buffer_mutex);
+       atomic_set(&chip->data_pending, 0);
+       memset(chip->data_buffer, 0, TPM_BUFSIZE);
+       up(&chip->buffer_mutex);
+}
+
+void tpm_time_expired(unsigned long ptr)
+{
+       int *exp = (int *) ptr;
+       *exp = 1;
+}
+
+EXPORT_SYMBOL_GPL(tpm_time_expired);
+
+/*
+ * Internal kernel interface to transmit TPM commands
+ */
+static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
+                           size_t bufsiz)
+{
+       ssize_t len;
+       u32 count;
+       __be32 *native_size;
+
+       native_size = (__force __be32 *) (buf + 2);
+       count = be32_to_cpu(*native_size);
+
+       if (count == 0)
+               return -ENODATA;
+       if (count > bufsiz) {
+               dev_err(&chip->pci_dev->dev,
+                       "invalid count value %x %zx \n", count, bufsiz);
+               return -E2BIG;
+       }
+
+       down(&chip->tpm_mutex);
+
+       if ((len = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
+               dev_err(&chip->pci_dev->dev,
+                       "tpm_transmit: tpm_send: error %zd\n", len);
+               return len;
+       }
+
+       down(&chip->timer_manipulation_mutex);
+       chip->time_expired = 0;
+       init_timer(&chip->device_timer);
+       chip->device_timer.function = tpm_time_expired;
+       chip->device_timer.expires = jiffies + 2 * 60 * HZ;
+       chip->device_timer.data = (unsigned long) &chip->time_expired;
+       add_timer(&chip->device_timer);
+       up(&chip->timer_manipulation_mutex);
+
+       do {
+               u8 status = inb(chip->vendor->base + 1);
+               if ((status & chip->vendor->req_complete_mask) ==
+                   chip->vendor->req_complete_val) {
+                       down(&chip->timer_manipulation_mutex);
+                       del_singleshot_timer_sync(&chip->device_timer);
+                       up(&chip->timer_manipulation_mutex);
+                       goto out_recv;
+               }
+               set_current_state(TASK_UNINTERRUPTIBLE);
+               schedule_timeout(TPM_TIMEOUT);
+               rmb();
+       } while (!chip->time_expired);
+
+
+       chip->vendor->cancel(chip);
+       dev_err(&chip->pci_dev->dev, "Time expired\n");
+       up(&chip->tpm_mutex);
+       return -EIO;
+
+out_recv:
+       len = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
+       if (len < 0)
+               dev_err(&chip->pci_dev->dev,
+                       "tpm_transmit: tpm_recv: error %zd\n", len);
+       up(&chip->tpm_mutex);
+       return len;
+}
+
+#define TPM_DIGEST_SIZE 20
+#define CAP_PCR_RESULT_SIZE 18
+static u8 cap_pcr[] = {
+       0, 193,                 /* TPM_TAG_RQU_COMMAND */
+       0, 0, 0, 22,            /* length */
+       0, 0, 0, 101,           /* TPM_ORD_GetCapability */
+       0, 0, 0, 5,
+       0, 0, 0, 4,
+       0, 0, 1, 1
+};
+
+#define READ_PCR_RESULT_SIZE 30
+static u8 pcrread[] = {
+       0, 193,                 /* TPM_TAG_RQU_COMMAND */
+       0, 0, 0, 14,            /* length */
+       0, 0, 0, 21,            /* TPM_ORD_PcrRead */
+       0, 0, 0, 0              /* PCR index */
+};
+
+static ssize_t show_pcrs(struct device *dev, char *buf)
+{
+       u8 data[READ_PCR_RESULT_SIZE];
+       ssize_t len;
+       int i, j, index, num_pcrs;
+       char *str = buf;
+
+       struct tpm_chip *chip =
+           pci_get_drvdata(container_of(dev, struct pci_dev, dev));
+       if (chip == NULL)
+               return -ENODEV;
+
+       memcpy(data, cap_pcr, sizeof(cap_pcr));
+       if ((len = tpm_transmit(chip, data, sizeof(data)))
+           < CAP_PCR_RESULT_SIZE)
+               return len;
+
+       num_pcrs = be32_to_cpu(*((__force __be32 *) (data + 14)));
+
+       for (i = 0; i < num_pcrs; i++) {
+               memcpy(data, pcrread, sizeof(pcrread));
+               index = cpu_to_be32(i);
+               memcpy(data + 10, &index, 4);
+               if ((len = tpm_transmit(chip, data, sizeof(data)))
+                   < READ_PCR_RESULT_SIZE)
+                       return len;
+               str += sprintf(str, "PCR-%02d: ", i);
+               for (j = 0; j < TPM_DIGEST_SIZE; j++)
+                       str += sprintf(str, "%02X ", *(data + 10 + j));
+               str += sprintf(str, "\n");
+       }
+       return str - buf;
+}
+
+static DEVICE_ATTR(pcrs, S_IRUGO, show_pcrs, NULL);
+
+#define  READ_PUBEK_RESULT_SIZE 314
+static u8 readpubek[] = {
+       0, 193,                 /* TPM_TAG_RQU_COMMAND */
+       0, 0, 0, 30,            /* length */
+       0, 0, 0, 124,           /* TPM_ORD_ReadPubek */
+};
+
+static ssize_t show_pubek(struct device *dev, char *buf)
+{
+       u8 data[READ_PUBEK_RESULT_SIZE];
+       ssize_t len;
+       __be32 *native_val;
+       int i;
+       char *str = buf;
+
+       struct tpm_chip *chip =
+           pci_get_drvdata(container_of(dev, struct pci_dev, dev));
+       if (chip == NULL)
+               return -ENODEV;
+
+       memcpy(data, readpubek, sizeof(readpubek));
+       memset(data + sizeof(readpubek), 0, 20);        /* zero nonce */
+
+       if ((len = tpm_transmit(chip, data, sizeof(data))) <
+           READ_PUBEK_RESULT_SIZE)
+               return len;
+
+       /*
+          ignore header 10 bytes
+          algorithm 32 bits (1 == RSA )
+          encscheme 16 bits
+          sigscheme 16 bits
+          parameters (RSA 12->bytes: keybit, #primes, expbit)
+          keylenbytes 32 bits
+          256 byte modulus
+          ignore checksum 20 bytes
+        */
+
+       native_val = (__force __be32 *) (data + 34);
+
+       str +=
+           sprintf(str,
+                   "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n"
+                   "Sigscheme: %02X %02X\nParameters: %02X %02X %02X %02X"
+                   " %02X %02X %02X %02X %02X %02X %02X %02X\n"
+                   "Modulus length: %d\nModulus: \n",
+                   data[10], data[11], data[12], data[13], data[14],
+                   data[15], data[16], data[17], data[22], data[23],
+                   data[24], data[25], data[26], data[27], data[28],
+                   data[29], data[30], data[31], data[32], data[33],
+                   be32_to_cpu(*native_val)
+           );
+
+       for (i = 0; i < 256; i++) {
+               str += sprintf(str, "%02X ", data[i + 39]);
+               if ((i + 1) % 16 == 0)
+                       str += sprintf(str, "\n");
+       }
+       return str - buf;
+}
+
+static DEVICE_ATTR(pubek, S_IRUGO, show_pubek, NULL);
+
+#define CAP_VER_RESULT_SIZE 18
+static u8 cap_version[] = {
+       0, 193,                 /* TPM_TAG_RQU_COMMAND */
+       0, 0, 0, 18,            /* length */
+       0, 0, 0, 101,           /* TPM_ORD_GetCapability */
+       0, 0, 0, 6,
+       0, 0, 0, 0
+};
+
+#define CAP_MANUFACTURER_RESULT_SIZE 18
+static u8 cap_manufacturer[] = {
+       0, 193,                 /* TPM_TAG_RQU_COMMAND */
+       0, 0, 0, 22,            /* length */
+       0, 0, 0, 101,           /* TPM_ORD_GetCapability */
+       0, 0, 0, 5,
+       0, 0, 0, 4,
+       0, 0, 1, 3
+};
+
+static ssize_t show_caps(struct device *dev, char *buf)
+{
+       u8 data[READ_PUBEK_RESULT_SIZE];
+       ssize_t len;
+       char *str = buf;
+
+       struct tpm_chip *chip =
+           pci_get_drvdata(container_of(dev, struct pci_dev, dev));
+       if (chip == NULL)
+               return -ENODEV;
+
+       memcpy(data, cap_manufacturer, sizeof(cap_manufacturer));
+
+       if ((len = tpm_transmit(chip, data, sizeof(data))) <
+           CAP_MANUFACTURER_RESULT_SIZE)
+               return len;
+
+       str += sprintf(str, "Manufacturer: 0x%x\n",
+                      be32_to_cpu(*(data + 14)));
+
+       memcpy(data, cap_version, sizeof(cap_version));
+
+       if ((len = tpm_transmit(chip, data, sizeof(data))) <
+           CAP_VER_RESULT_SIZE)
+               return len;
+
+       str +=
+           sprintf(str, "TCG version: %d.%d\nFirmware version: %d.%d\n",
+                   (int) data[14], (int) data[15], (int) data[16],
+                   (int) data[17]);
+
+       return str - buf;
+}
+
+static DEVICE_ATTR(caps, S_IRUGO, show_caps, NULL);
+
+/*
+ * Device file system interface to the TPM
+ */
+int tpm_open(struct inode *inode, struct file *file)
+{
+       int rc = 0, minor = iminor(inode);
+       struct tpm_chip *chip = NULL, *pos;
+
+       spin_lock(&driver_lock);
+
+       list_for_each_entry(pos, &tpm_chip_list, list) {
+               if (pos->vendor->miscdev.minor == minor) {
+                       chip = pos;
+                       break;
+               }
+       }
+
+       if (chip == NULL) {
+               rc = -ENODEV;
+               goto err_out;
+       }
+
+       if (chip->num_opens) {
+               dev_dbg(&chip->pci_dev->dev,
+                       "Another process owns this TPM\n");
+               rc = -EBUSY;
+               goto err_out;
+       }
+
+       chip->num_opens++;
+       pci_dev_get(chip->pci_dev);
+
+       spin_unlock(&driver_lock);
+
+       chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
+       if (chip->data_buffer == NULL) {
+               chip->num_opens--;
+               pci_dev_put(chip->pci_dev);
+               return -ENOMEM;
+       }
+
+       atomic_set(&chip->data_pending, 0);
+
+       file->private_data = chip;
+       return 0;
+
+err_out:
+       spin_unlock(&driver_lock);
+       return rc;
+}
+
+EXPORT_SYMBOL_GPL(tpm_open);
+
+int tpm_release(struct inode *inode, struct file *file)
+{
+       struct tpm_chip *chip = file->private_data;
+
+       file->private_data = NULL;
+
+       spin_lock(&driver_lock);
+       chip->num_opens--;
+       spin_unlock(&driver_lock);
+
+       down(&chip->timer_manipulation_mutex);
+       if (timer_pending(&chip->user_read_timer))
+               del_singleshot_timer_sync(&chip->user_read_timer);
+       else if (timer_pending(&chip->device_timer))
+               del_singleshot_timer_sync(&chip->device_timer);
+       up(&chip->timer_manipulation_mutex);
+
+       kfree(chip->data_buffer);
+       atomic_set(&chip->data_pending, 0);
+
+       pci_dev_put(chip->pci_dev);
+       return 0;
+}
+
+EXPORT_SYMBOL_GPL(tpm_release);
+
+ssize_t tpm_write(struct file * file, const char __user * buf,
+                 size_t size, loff_t * off)
+{
+       struct tpm_chip *chip = file->private_data;
+       int in_size = size, out_size;
+
+       /* cannot perform a write until the read has cleared
+          either via tpm_read or a user_read_timer timeout */
+       while (atomic_read(&chip->data_pending) != 0) {
+               set_current_state(TASK_UNINTERRUPTIBLE);
+               schedule_timeout(TPM_TIMEOUT);
+       }
+
+       down(&chip->buffer_mutex);
+
+       if (in_size > TPM_BUFSIZE)
+               in_size = TPM_BUFSIZE;
+
+       if (copy_from_user
+           (chip->data_buffer, (void __user *) buf, in_size)) {
+               up(&chip->buffer_mutex);
+               return -EFAULT;
+       }
+
+       /* atomic tpm command send and result receive */
+       out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
+
+       atomic_set(&chip->data_pending, out_size);
+       atomic_set(&chip->data_position, 0);
+       up(&chip->buffer_mutex);
+
+       /* Set a timeout by which the reader must come claim the result */
+       down(&chip->timer_manipulation_mutex);
+       init_timer(&chip->user_read_timer);
+       chip->user_read_timer.function = user_reader_timeout;
+       chip->user_read_timer.data = (unsigned long) chip;
+       chip->user_read_timer.expires = jiffies + (60 * HZ);
+       add_timer(&chip->user_read_timer);
+       up(&chip->timer_manipulation_mutex);
+
+       return in_size;
+}
+
+EXPORT_SYMBOL_GPL(tpm_write);
+
+ssize_t tpm_read(struct file * file, char __user * buf,
+                size_t size, loff_t * off)
+{
+       struct tpm_chip *chip = file->private_data;
+       int ret_size = -ENODATA;
+       int pos, pending = 0;
+
+       down(&chip->buffer_mutex);
+       ret_size = atomic_read(&chip->data_pending);
+       if ( ret_size > 0 ) {   /* Result available */
+               if (size < ret_size)
+                       ret_size = size;
+
+               pos = atomic_read(&chip->data_position);
+
+               if (copy_to_user((void __user *) buf,
+                                &chip->data_buffer[pos], ret_size)) {
+                       ret_size = -EFAULT;
+               } else {
+                       pending = atomic_read(&chip->data_pending) - ret_size;
+                       if ( pending ) {
+                               atomic_set( &chip->data_pending, pending );
+                               atomic_set( &chip->data_position, pos+ret_size 
);
+                       }
+               }
+       }
+       up(&chip->buffer_mutex);
+
+       if ( ret_size <= 0 || pending == 0 ) {
+               atomic_set( &chip->data_pending, 0 );
+               down(&chip->timer_manipulation_mutex);
+               del_singleshot_timer_sync(&chip->user_read_timer);
+               up(&chip->timer_manipulation_mutex);
+       }
+
+       return ret_size;
+}
+
+EXPORT_SYMBOL_GPL(tpm_read);
+
+void __devexit tpm_remove(struct pci_dev *pci_dev)
+{
+       struct tpm_chip *chip = pci_get_drvdata(pci_dev);
+
+       if (chip == NULL) {
+               dev_err(&pci_dev->dev, "No device data found\n");
+               return;
+       }
+
+       spin_lock(&driver_lock);
+
+       list_del(&chip->list);
+
+       spin_unlock(&driver_lock);
+
+       pci_set_drvdata(pci_dev, NULL);
+       misc_deregister(&chip->vendor->miscdev);
+
+       device_remove_file(&pci_dev->dev, &dev_attr_pubek);
+       device_remove_file(&pci_dev->dev, &dev_attr_pcrs);
+       device_remove_file(&pci_dev->dev, &dev_attr_caps);
+
+       pci_disable_device(pci_dev);
+
+       dev_mask[chip->dev_num / 32] &= !(1 << (chip->dev_num % 32));
+
+       kfree(chip);
+
+       pci_dev_put(pci_dev);
+}
+
+EXPORT_SYMBOL_GPL(tpm_remove);
+
+static u8 savestate[] = {
+       0, 193,                 /* TPM_TAG_RQU_COMMAND */
+       0, 0, 0, 10,            /* blob length (in bytes) */
+       0, 0, 0, 152            /* TPM_ORD_SaveState */
+};
+
+/*
+ * We are about to suspend. Save the TPM state
+ * so that it can be restored.
+ */
+int tpm_pm_suspend(struct pci_dev *pci_dev, pm_message_t pm_state)
+{
+       struct tpm_chip *chip = pci_get_drvdata(pci_dev);
+       if (chip == NULL)
+               return -ENODEV;
+
+       tpm_transmit(chip, savestate, sizeof(savestate));
+       return 0;
+}
+
+EXPORT_SYMBOL_GPL(tpm_pm_suspend);
+
+/*
+ * Resume from a power safe. The BIOS already restored
+ * the TPM state.
+ */
+int tpm_pm_resume(struct pci_dev *pci_dev)
+{
+       struct tpm_chip *chip = pci_get_drvdata(pci_dev);
+
+       if (chip == NULL)
+               return -ENODEV;
+
+       return 0;
+}
+
+EXPORT_SYMBOL_GPL(tpm_pm_resume);
+
+/*
+ * Called from tpm_<specific>.c probe function only for devices
+ * the driver has determined it should claim.  Prior to calling
+ * this function the specific probe function has called pci_enable_device
+ * upon errant exit from this function specific probe function should call
+ * pci_disable_device
+ */
+int tpm_register_hardware(struct pci_dev *pci_dev,
+                         struct tpm_vendor_specific *entry)
+{
+       char devname[7];
+       struct tpm_chip *chip;
+       int i, j;
+
+       /* Driver specific per-device data */
+       chip = kmalloc(sizeof(*chip), GFP_KERNEL);
+       if (chip == NULL)
+               return -ENOMEM;
+
+       memset(chip, 0, sizeof(struct tpm_chip));
+
+       init_MUTEX(&chip->buffer_mutex);
+       init_MUTEX(&chip->tpm_mutex);
+       init_MUTEX(&chip->timer_manipulation_mutex);
+       INIT_LIST_HEAD(&chip->list);
+
+       chip->vendor = entry;
+
+       chip->dev_num = -1;
+
+       for (i = 0; i < 32; i++)
+               for (j = 0; j < 8; j++)
+                       if ((dev_mask[i] & (1 << j)) == 0) {
+                               chip->dev_num = i * 32 + j;
+                               dev_mask[i] |= 1 << j;
+                               goto dev_num_search_complete;
+                       }
+
+dev_num_search_complete:
+       if (chip->dev_num < 0) {
+               dev_err(&pci_dev->dev,
+                       "No available tpm device numbers\n");
+               kfree(chip);
+               return -ENODEV;
+       } else if (chip->dev_num == 0)
+               chip->vendor->miscdev.minor = TPM_MINOR;
+       else
+               chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
+
+       snprintf(devname, sizeof(devname), "%s%d", "tpm", chip->dev_num);
+       chip->vendor->miscdev.name = devname;
+
+       chip->vendor->miscdev.dev = &(pci_dev->dev);
+       chip->pci_dev = pci_dev_get(pci_dev);
+
+       if (misc_register(&chip->vendor->miscdev)) {
+               dev_err(&chip->pci_dev->dev,
+                       "unable to misc_register %s, minor %d\n",
+                       chip->vendor->miscdev.name,
+                       chip->vendor->miscdev.minor);
+               pci_dev_put(pci_dev);
+               kfree(chip);
+               dev_mask[i] &= !(1 << j);
+               return -ENODEV;
+       }
+
+       pci_set_drvdata(pci_dev, chip);
+
+       list_add(&chip->list, &tpm_chip_list);
+
+       device_create_file(&pci_dev->dev, &dev_attr_pubek);
+       device_create_file(&pci_dev->dev, &dev_attr_pcrs);
+       device_create_file(&pci_dev->dev, &dev_attr_caps);
+
+       return 0;
+}
+
+EXPORT_SYMBOL_GPL(tpm_register_hardware);
+
+static int __init init_tpm(void)
+{
+       return 0;
+}
+
+static void __exit cleanup_tpm(void)
+{
+
+}
+
+module_init(init_tpm);
+module_exit(cleanup_tpm);
+
+MODULE_AUTHOR("Leendert van Doorn (leendert@xxxxxxxxxxxxxx)");
+MODULE_DESCRIPTION("TPM Driver");
+MODULE_VERSION("2.0");
+MODULE_LICENSE("GPL");
diff -r 84ab93e1ee05 -r dd668f7527cb linux-2.6-xen-sparse/drivers/char/tpm/tpm.h
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h       Thu Sep  1 10:16:14 2005
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2004 IBM Corporation
+ *
+ * Authors:
+ * Leendert van Doorn <leendert@xxxxxxxxxxxxxx>
+ * Dave Safford <safford@xxxxxxxxxxxxxx>
+ * Reiner Sailer <sailer@xxxxxxxxxxxxxx>
+ * Kylene Hall <kjhall@xxxxxxxxxx>
+ *
+ * Maintained by: <tpmdd_devel@xxxxxxxxxxxxxxxxxxxxx>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ */
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+
+#define TPM_TIMEOUT msecs_to_jiffies(5)
+
+/* TPM addresses */
+#define        TPM_ADDR                        0x4E
+#define        TPM_DATA                        0x4F
+
+struct tpm_chip;
+
+struct tpm_vendor_specific {
+       u8 req_complete_mask;
+       u8 req_complete_val;
+       u16 base;               /* TPM base address */
+
+       int (*recv) (struct tpm_chip *, u8 *, size_t);
+       int (*send) (struct tpm_chip *, u8 *, size_t);
+       void (*cancel) (struct tpm_chip *);
+       struct miscdevice miscdev;
+};
+
+struct tpm_chip {
+       struct pci_dev *pci_dev;        /* PCI device stuff */
+
+       int dev_num;            /* /dev/tpm# */
+       int num_opens;          /* only one allowed */
+       int time_expired;
+
+       /* Data passed to and from the tpm via the read/write calls */
+       u8 *data_buffer;
+       atomic_t data_pending;
+       atomic_t data_position;
+       struct semaphore buffer_mutex;
+
+       struct timer_list user_read_timer;      /* user needs to claim result */
+       struct semaphore tpm_mutex;     /* tpm is processing */
+       struct timer_list device_timer; /* tpm is processing */
+       struct semaphore timer_manipulation_mutex;
+
+       struct tpm_vendor_specific *vendor;
+
+       struct list_head list;
+};
+
+static inline int tpm_read_index(int index)
+{
+       outb(index, TPM_ADDR);
+       return inb(TPM_DATA) & 0xFF;
+}
+
+static inline void tpm_write_index(int index, int value)
+{
+       outb(index, TPM_ADDR);
+       outb(value & 0xFF, TPM_DATA);
+}
+
+extern void tpm_time_expired(unsigned long);
+extern int tpm_register_hardware(struct pci_dev *,
+                                struct tpm_vendor_specific *);
+extern int tpm_open(struct inode *, struct file *);
+extern int tpm_release(struct inode *, struct file *);
+extern ssize_t tpm_write(struct file *, const char __user *, size_t,
+                        loff_t *);
+extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *);
+extern void __devexit tpm_remove(struct pci_dev *);
+extern int tpm_pm_suspend(struct pci_dev *, pm_message_t);
+extern int tpm_pm_resume(struct pci_dev *);
diff -r 84ab93e1ee05 -r dd668f7527cb 
linux-2.6-xen-sparse/drivers/char/tpm/tpm_atmel.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_atmel.c Thu Sep  1 10:16:14 2005
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2004 IBM Corporation
+ *
+ * Authors:
+ * Leendert van Doorn <leendert@xxxxxxxxxxxxxx>
+ * Dave Safford <safford@xxxxxxxxxxxxxx>
+ * Reiner Sailer <sailer@xxxxxxxxxxxxxx>
+ * Kylene Hall <kjhall@xxxxxxxxxx>
+ *
+ * Maintained by: <tpmdd_devel@xxxxxxxxxxxxxxxxxxxxx>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ */
+
+#include "tpm.h"
+
+/* Atmel definitions */
+enum tpm_atmel_addr {
+       TPM_ATMEL_BASE_ADDR_LO = 0x08,
+       TPM_ATMEL_BASE_ADDR_HI = 0x09
+};
+
+/* write status bits */
+#define        ATML_STATUS_ABORT               0x01
+#define        ATML_STATUS_LASTBYTE            0x04
+
+/* read status bits */
+#define        ATML_STATUS_BUSY                0x01
+#define        ATML_STATUS_DATA_AVAIL          0x02
+#define        ATML_STATUS_REWRITE             0x04
+
+
+static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
+{
+       u8 status, *hdr = buf;
+       u32 size;
+       int i;
+       __be32 *native_size;
+
+       /* start reading header */
+       if (count < 6)
+               return -EIO;
+
+       for (i = 0; i < 6; i++) {
+               status = inb(chip->vendor->base + 1);
+               if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
+                       dev_err(&chip->pci_dev->dev,
+                               "error reading header\n");
+                       return -EIO;
+               }
+               *buf++ = inb(chip->vendor->base);
+       }
+
+       /* size of the data received */
+       native_size = (__force __be32 *) (hdr + 2);
+       size = be32_to_cpu(*native_size);
+
+       if (count < size) {
+               dev_err(&chip->pci_dev->dev,
+                       "Recv size(%d) less than available space\n", size);
+               for (; i < size; i++) { /* clear the waiting data anyway */
+                       status = inb(chip->vendor->base + 1);
+                       if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
+                               dev_err(&chip->pci_dev->dev,
+                                       "error reading data\n");
+                               return -EIO;
+                       }
+               }
+               return -EIO;
+       }
+
+       /* read all the data available */
+       for (; i < size; i++) {
+               status = inb(chip->vendor->base + 1);
+               if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
+                       dev_err(&chip->pci_dev->dev,
+                               "error reading data\n");
+                       return -EIO;
+               }
+               *buf++ = inb(chip->vendor->base);
+       }
+
+       /* make sure data available is gone */
+       status = inb(chip->vendor->base + 1);
+       if (status & ATML_STATUS_DATA_AVAIL) {
+               dev_err(&chip->pci_dev->dev, "data available is stuck\n");
+               return -EIO;
+       }
+
+       return size;
+}
+
+static int tpm_atml_send(struct tpm_chip *chip, u8 * buf, size_t count)
+{
+       int i;
+
+       dev_dbg(&chip->pci_dev->dev, "tpm_atml_send: ");
+       for (i = 0; i < count; i++) {
+               dev_dbg(&chip->pci_dev->dev, "0x%x(%d) ", buf[i], buf[i]);
+               outb(buf[i], chip->vendor->base);
+       }
+
+       return count;
+}
+
+static void tpm_atml_cancel(struct tpm_chip *chip)
+{
+       outb(ATML_STATUS_ABORT, chip->vendor->base + 1);
+}
+
+static struct file_operations atmel_ops = {
+       .owner = THIS_MODULE,
+       .llseek = no_llseek,
+       .open = tpm_open,
+       .read = tpm_read,
+       .write = tpm_write,
+       .release = tpm_release,
+};
+
+static struct tpm_vendor_specific tpm_atmel = {
+       .recv = tpm_atml_recv,
+       .send = tpm_atml_send,
+       .cancel = tpm_atml_cancel,
+       .req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL,
+       .req_complete_val = ATML_STATUS_DATA_AVAIL,
+       .miscdev = { .fops = &atmel_ops, },
+};
+
+static int __devinit tpm_atml_init(struct pci_dev *pci_dev,
+                                  const struct pci_device_id *pci_id)
+{
+       u8 version[4];
+       int rc = 0;
+       int lo, hi;
+
+       if (pci_enable_device(pci_dev))
+               return -EIO;
+
+       lo = tpm_read_index( TPM_ATMEL_BASE_ADDR_LO );
+       hi = tpm_read_index( TPM_ATMEL_BASE_ADDR_HI );
+
+       tpm_atmel.base = (hi<<8)|lo;
+       dev_dbg( &pci_dev->dev, "Operating with base: 0x%x\n", tpm_atmel.base);
+
+       /* verify that it is an Atmel part */
+       if (tpm_read_index(4) != 'A' || tpm_read_index(5) != 'T'
+           || tpm_read_index(6) != 'M' || tpm_read_index(7) != 'L') {
+               rc = -ENODEV;
+               goto out_err;
+       }
+
+       /* query chip for its version number */
+       if ((version[0] = tpm_read_index(0x00)) != 0xFF) {
+               version[1] = tpm_read_index(0x01);
+               version[2] = tpm_read_index(0x02);
+               version[3] = tpm_read_index(0x03);
+       } else {
+               dev_info(&pci_dev->dev, "version query failed\n");
+               rc = -ENODEV;
+               goto out_err;
+       }
+
+       if ((rc = tpm_register_hardware(pci_dev, &tpm_atmel)) < 0)
+               goto out_err;
+
+       dev_info(&pci_dev->dev,
+                "Atmel TPM version %d.%d.%d.%d\n", version[0], version[1],
+                version[2], version[3]);
+
+       return 0;
+out_err:
+       pci_disable_device(pci_dev);
+       return rc;
+}
+
+static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
+       {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
+       {0,}
+};
+
+MODULE_DEVICE_TABLE(pci, tpm_pci_tbl);
+
+static struct pci_driver atmel_pci_driver = {
+       .name = "tpm_atmel",
+       .id_table = tpm_pci_tbl,
+       .probe = tpm_atml_init,
+       .remove = __devexit_p(tpm_remove),
+       .suspend = tpm_pm_suspend,
+       .resume = tpm_pm_resume,
+};
+
+static int __init init_atmel(void)
+{
+       return pci_register_driver(&atmel_pci_driver);
+}
+
+static void __exit cleanup_atmel(void)
+{
+       pci_unregister_driver(&atmel_pci_driver);
+}
+
+module_init(init_atmel);
+module_exit(cleanup_atmel);
+
+MODULE_AUTHOR("Leendert van Doorn (leendert@xxxxxxxxxxxxxx)");
+MODULE_DESCRIPTION("TPM Driver");
+MODULE_VERSION("2.0");
+MODULE_LICENSE("GPL");
diff -r 84ab93e1ee05 -r dd668f7527cb 
linux-2.6-xen-sparse/drivers/char/tpm/tpm_nopci.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_nopci.c Thu Sep  1 10:16:14 2005
@@ -0,0 +1,741 @@
+/*
+ * Copyright (C) 2004 IBM Corporation
+ *
+ * Authors:
+ * Leendert van Doorn <leendert@xxxxxxxxxxxxxx>
+ * Dave Safford <safford@xxxxxxxxxxxxxx>
+ * Reiner Sailer <sailer@xxxxxxxxxxxxxx>
+ * Kylene Hall <kjhall@xxxxxxxxxx>
+ *
+ * Maintained by: <tpmdd_devel@xxxxxxxxxxxxxxxxxxxxx>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * Note, the TPM chip is not interrupt driven (only polling)
+ * and can have very long timeouts (minutes!). Hence the unusual
+ * calls to schedule_timeout.
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/spinlock.h>
+#include "tpm_nopci.h"
+
+enum {
+       TPM_MINOR = 224,        /* officially assigned */
+       TPM_BUFSIZE = 2048,
+       TPM_NUM_DEVICES = 256,
+       TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int))
+};
+
+  /* PCI configuration addresses */
+enum {
+       PCI_GEN_PMCON_1 = 0xA0,
+       PCI_GEN1_DEC = 0xE4,
+       PCI_LPC_EN = 0xE6,
+       PCI_GEN2_DEC = 0xEC
+};
+
+enum {
+       TPM_LOCK_REG = 0x0D,
+       TPM_INTERUPT_REG = 0x0A,
+       TPM_BASE_ADDR_LO = 0x08,
+       TPM_BASE_ADDR_HI = 0x09,
+       TPM_UNLOCK_VALUE = 0x55,
+       TPM_LOCK_VALUE = 0xAA,
+       TPM_DISABLE_INTERUPT_VALUE = 0x00
+};
+
+static LIST_HEAD(tpm_chip_list);
+static spinlock_t driver_lock = SPIN_LOCK_UNLOCKED;
+static int dev_mask[32];
+
+static void user_reader_timeout(unsigned long ptr)
+{
+       struct tpm_chip *chip = (struct tpm_chip *) ptr;
+
+       down(&chip->buffer_mutex);
+       atomic_set(&chip->data_pending, 0);
+       memset(chip->data_buffer, 0, TPM_BUFSIZE);
+       up(&chip->buffer_mutex);
+}
+
+void tpm_time_expired(unsigned long ptr)
+{
+       int *exp = (int *) ptr;
+       *exp = 1;
+}
+
+EXPORT_SYMBOL_GPL(tpm_time_expired);
+
+
+/*
+ * This function should be used by other kernel subsystems attempting to use 
the tpm through the tpm_transmit interface.
+ * A call to this function will return the chip structure corresponding to the 
TPM you are looking for that can then be sent with your command to tpm_transmit.
+ * Passing 0 as the argument corresponds to /dev/tpm0 and thus the first and 
probably primary TPM on the system.  Passing 1 corresponds to /dev/tpm1 and the 
next TPM discovered.  If a TPM with the given chip_num does not exist NULL will 
be returned.
+ */
+struct tpm_chip* tpm_chip_lookup(int chip_num)
+{
+
+       struct tpm_chip *pos;
+       list_for_each_entry(pos, &tpm_chip_list, list)
+               if (pos->dev_num == chip_num ||
+                   chip_num == TPM_ANY_NUM)
+                       return pos;
+
+       return NULL;
+
+}
+
+/*
+ * Internal kernel interface to transmit TPM commands
+ */
+ssize_t tpm_transmit(struct tpm_chip * chip, const char *buf,
+                    size_t bufsiz)
+{
+       ssize_t rc;
+       u32 count;
+       unsigned long stop;
+
+       count = be32_to_cpu(*((__be32 *) (buf + 2)));
+
+       if (count == 0)
+               return -ENODATA;
+       if (count > bufsiz) {
+               dev_err(chip->dev,
+                       "invalid count value %x %x \n", count, bufsiz);
+               return -E2BIG;
+       }
+
+       dev_dbg(chip->dev, "TPM Ordinal: %d\n",
+               be32_to_cpu(*((__be32 *) (buf + 6))));
+       dev_dbg(chip->dev, "Chip Status: %x\n",
+               inb(chip->vendor->base + 1));
+
+       down(&chip->tpm_mutex);
+
+       if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
+               dev_err(chip->dev,
+                       "tpm_transmit: tpm_send: error %d\n", rc);
+               goto out;
+       }
+
+       stop = jiffies + 2 * 60 * HZ;
+       do {
+               u8 status = chip->vendor->status(chip);
+               if ((status & chip->vendor->req_complete_mask) ==
+                   chip->vendor->req_complete_val) {
+                       goto out_recv;
+               }
+
+               if ((status == chip->vendor->req_canceled)) {
+                       dev_err(chip->dev, "Operation Canceled\n");
+                       rc = -ECANCELED;
+                       goto out;
+               }
+
+               msleep(TPM_TIMEOUT);    /* CHECK */
+               rmb();
+       }
+       while (time_before(jiffies, stop));
+
+
+       chip->vendor->cancel(chip);
+       dev_err(chip->dev, "Operation Timed out\n");
+       rc = -ETIME;
+       goto out;
+
+out_recv:
+       rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
+       if (rc < 0)
+               dev_err(chip->dev,
+                       "tpm_transmit: tpm_recv: error %d\n", rc);
+       atomic_set(&chip->data_position, 0);
+
+out:
+       up(&chip->tpm_mutex);
+       return rc;
+}
+
+EXPORT_SYMBOL_GPL(tpm_transmit);
+
+#define TPM_DIGEST_SIZE 20
+#define CAP_PCR_RESULT_SIZE 18
+static const u8 cap_pcr[] = {
+       0, 193,                 /* TPM_TAG_RQU_COMMAND */
+       0, 0, 0, 22,            /* length */
+       0, 0, 0, 101,           /* TPM_ORD_GetCapability */
+       0, 0, 0, 5,
+       0, 0, 0, 4,
+       0, 0, 1, 1
+};
+
+#define READ_PCR_RESULT_SIZE 30
+static const u8 pcrread[] = {
+       0, 193,                 /* TPM_TAG_RQU_COMMAND */
+       0, 0, 0, 14,            /* length */
+       0, 0, 0, 21,            /* TPM_ORD_PcrRead */
+       0, 0, 0, 0              /* PCR index */
+};
+
+ssize_t tpm_show_pcrs(struct device *dev, char *buf)
+{
+       u8 data[READ_PCR_RESULT_SIZE];
+       ssize_t len;
+       int i, j, num_pcrs;
+       __be32 index;
+       char *str = buf;
+
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       if (chip == NULL)
+               return -ENODEV;
+
+       memcpy(data, cap_pcr, sizeof(cap_pcr));
+       if ((len = tpm_transmit(chip, data, sizeof(data)))
+           < CAP_PCR_RESULT_SIZE)
+               return len;
+
+       num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
+
+       for (i = 0; i < num_pcrs; i++) {
+               memcpy(data, pcrread, sizeof(pcrread));
+               index = cpu_to_be32(i);
+               memcpy(data + 10, &index, 4);
+               if ((len = tpm_transmit(chip, data, sizeof(data)))
+                   < READ_PCR_RESULT_SIZE)
+                       return len;
+               str += sprintf(str, "PCR-%02d: ", i);
+               for (j = 0; j < TPM_DIGEST_SIZE; j++)
+                       str += sprintf(str, "%02X ", *(data + 10 + j));
+               str += sprintf(str, "\n");
+       }
+       return str - buf;
+}
+
+EXPORT_SYMBOL_GPL(tpm_show_pcrs);
+
+/*
+ * Return 0 on success.  On error pass along error code.
+ * chip_id Upper 2 bytes equal ANY, HW_ONLY or SW_ONLY
+ * Lower 2 bytes equal tpm idx # or AN&
+ * res_buf must fit a TPM_PCR (20 bytes) or NULL if you don't care
+ */
+int tpm_pcr_read( u32 chip_id, int pcr_idx, u8* res_buf, int res_buf_size )
+{
+       u8 data[READ_PCR_RESULT_SIZE];
+       int rc;
+       __be32 index;
+       int chip_num = chip_id & TPM_CHIP_NUM_MASK;
+       struct tpm_chip* chip;
+
+       if ( res_buf && res_buf_size < TPM_DIGEST_SIZE )
+               return -ENOSPC;
+       if ( (chip = tpm_chip_lookup( chip_num /*,
+                                      chip_id >> TPM_CHIP_TYPE_SHIFT*/ ) ) == 
NULL ) {
+               printk("chip %d not found.\n",chip_num);
+               return -ENODEV;
+       }
+       memcpy(data, pcrread, sizeof(pcrread));
+       index = cpu_to_be32(pcr_idx);
+       memcpy(data + 10, &index, 4);
+       if ((rc = tpm_transmit(chip, data, sizeof(data))) > 0 )
+               rc = be32_to_cpu(*((u32*)(data+6)));
+
+       if ( rc == 0 && res_buf )
+               memcpy(res_buf, data+10, TPM_DIGEST_SIZE);
+       return rc;
+}
+EXPORT_SYMBOL_GPL(tpm_pcr_read);
+
+#define EXTEND_PCR_SIZE 34
+static const u8 pcrextend[] = {
+       0, 193,                                          /* TPM_TAG_RQU_COMMAND 
*/
+       0, 0, 0, 34,                             /* length */
+       0, 0, 0, 20,                             /* TPM_ORD_Extend */
+       0, 0, 0, 0                               /* PCR index */
+};
+
+/*
+ * Return 0 on success.  On error pass along error code.
+ * chip_id Upper 2 bytes equal ANY, HW_ONLY or SW_ONLY
+ * Lower 2 bytes equal tpm idx # or ANY
+ */
+int tpm_pcr_extend(u32 chip_id, int pcr_idx, const u8* hash)
+{
+       u8 data[EXTEND_PCR_SIZE];
+       int rc;
+       __be32 index;
+       int chip_num = chip_id & TPM_CHIP_NUM_MASK;
+       struct tpm_chip* chip;
+
+       if ( (chip = tpm_chip_lookup( chip_num /*,
+                                     chip_id >> TPM_CHIP_TYPE_SHIFT */)) == 
NULL )
+               return -ENODEV;
+
+       memcpy(data, pcrextend, sizeof(pcrextend));
+       index = cpu_to_be32(pcr_idx);
+       memcpy(data + 10, &index, 4);
+       memcpy( data + 14, hash, TPM_DIGEST_SIZE );
+       if ((rc = tpm_transmit(chip, data, sizeof(data))) > 0 )
+               rc = be32_to_cpu(*((u32*)(data+6)));
+       return rc;
+}
+EXPORT_SYMBOL_GPL(tpm_pcr_extend);
+
+
+
+#define  READ_PUBEK_RESULT_SIZE 314
+static const u8 readpubek[] = {
+       0, 193,                 /* TPM_TAG_RQU_COMMAND */
+       0, 0, 0, 30,            /* length */
+       0, 0, 0, 124,           /* TPM_ORD_ReadPubek */
+};
+
+ssize_t tpm_show_pubek(struct device *dev, char *buf)
+{
+       u8 *data;
+       ssize_t len;
+       int i, rc;
+       char *str = buf;
+
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       if (chip == NULL)
+               return -ENODEV;
+
+       data = kmalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       memcpy(data, readpubek, sizeof(readpubek));
+       memset(data + sizeof(readpubek), 0, 20);        /* zero nonce */
+
+       if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) <
+           READ_PUBEK_RESULT_SIZE) {
+               rc = len;
+               goto out;
+       }
+
+       /*
+          ignore header 10 bytes
+          algorithm 32 bits (1 == RSA )
+          encscheme 16 bits
+          sigscheme 16 bits
+          parameters (RSA 12->bytes: keybit, #primes, expbit)
+          keylenbytes 32 bits
+          256 byte modulus
+          ignore checksum 20 bytes
+        */
+
+       str +=
+           sprintf(str,
+                   "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n"
+                   "Sigscheme: %02X %02X\nParameters: %02X %02X %02X %02X"
+                   " %02X %02X %02X %02X %02X %02X %02X %02X\n"
+                   "Modulus length: %d\nModulus: \n",
+                   data[10], data[11], data[12], data[13], data[14],
+                   data[15], data[16], data[17], data[22], data[23],
+                   data[24], data[25], data[26], data[27], data[28],
+                   data[29], data[30], data[31], data[32], data[33],
+                   be32_to_cpu(*((__be32 *) (data + 32))));
+
+       for (i = 0; i < 256; i++) {
+               str += sprintf(str, "%02X ", data[i + 39]);
+               if ((i + 1) % 16 == 0)
+                       str += sprintf(str, "\n");
+       }
+       rc = str - buf;
+out:
+       kfree(data);
+       return rc;
+}
+
+EXPORT_SYMBOL_GPL(tpm_show_pubek);
+
+#define CAP_VER_RESULT_SIZE 18
+static const u8 cap_version[] = {
+       0, 193,                 /* TPM_TAG_RQU_COMMAND */
+       0, 0, 0, 18,            /* length */
+       0, 0, 0, 101,           /* TPM_ORD_GetCapability */
+       0, 0, 0, 6,
+       0, 0, 0, 0
+};
+
+#define CAP_MANUFACTURER_RESULT_SIZE 18
+static const u8 cap_manufacturer[] = {
+       0, 193,                 /* TPM_TAG_RQU_COMMAND */
+       0, 0, 0, 22,            /* length */
+       0, 0, 0, 101,           /* TPM_ORD_GetCapability */
+       0, 0, 0, 5,
+       0, 0, 0, 4,
+       0, 0, 1, 3
+};
+
+ssize_t tpm_show_caps(struct device *dev, char *buf)
+{
+       u8 data[sizeof(cap_manufacturer)];
+       ssize_t len;
+       char *str = buf;
+
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       if (chip == NULL)
+               return -ENODEV;
+
+       memcpy(data, cap_manufacturer, sizeof(cap_manufacturer));
+
+       if ((len = tpm_transmit(chip, data, sizeof(data))) <
+           CAP_MANUFACTURER_RESULT_SIZE)
+               return len;
+
+       str += sprintf(str, "Manufacturer: 0x%x\n",
+                      be32_to_cpu(*((__be32 *)(data + 14))));
+
+       memcpy(data, cap_version, sizeof(cap_version));
+
+       if ((len = tpm_transmit(chip, data, sizeof(data))) <
+           CAP_VER_RESULT_SIZE)
+               return len;
+
+       str +=
+           sprintf(str, "TCG version: %d.%d\nFirmware version: %d.%d\n",
+                   (int) data[14], (int) data[15], (int) data[16],
+                   (int) data[17]);
+
+       return str - buf;
+}
+
+EXPORT_SYMBOL_GPL(tpm_show_caps);
+
+ssize_t tpm_store_cancel(struct device * dev, const char *buf,
+                        size_t count)
+{
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       if (chip == NULL)
+               return 0;
+
+       chip->vendor->cancel(chip);
+       return count;
+}
+
+EXPORT_SYMBOL_GPL(tpm_store_cancel);
+
+/*
+ * Device file system interface to the TPM
+ */
+int tpm_open(struct inode *inode, struct file *file)
+{
+       int rc = 0, minor = iminor(inode);
+       struct tpm_chip *chip = NULL, *pos;
+
+       spin_lock(&driver_lock);
+
+       list_for_each_entry(pos, &tpm_chip_list, list) {
+               if (pos->vendor->miscdev.minor == minor) {
+                       chip = pos;
+                       break;
+               }
+       }
+
+       if (chip == NULL) {
+               rc = -ENODEV;
+               goto err_out;
+       }
+
+       if (chip->num_opens) {
+               dev_dbg(chip->dev, "Another process owns this TPM\n");
+               rc = -EBUSY;
+               goto err_out;
+       }
+
+       chip->num_opens++;
+       get_device(chip->dev);
+
+       spin_unlock(&driver_lock);
+
+       chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
+       if (chip->data_buffer == NULL) {
+               chip->num_opens--;
+               put_device(chip->dev);
+               return -ENOMEM;
+       }
+
+       atomic_set(&chip->data_pending, 0);
+
+       file->private_data = chip;
+       return 0;
+
+err_out:
+       spin_unlock(&driver_lock);
+       return rc;
+}
+
+EXPORT_SYMBOL_GPL(tpm_open);
+
+int tpm_release(struct inode *inode, struct file *file)
+{
+       struct tpm_chip *chip = file->private_data;
+
+       spin_lock(&driver_lock);
+       file->private_data = NULL;
+       chip->num_opens--;
+       del_singleshot_timer_sync(&chip->user_read_timer);
+       atomic_set(&chip->data_pending, 0);
+       put_device(chip->dev);
+       kfree(chip->data_buffer);
+       spin_unlock(&driver_lock);
+       return 0;
+}
+
+EXPORT_SYMBOL_GPL(tpm_release);
+
+ssize_t tpm_write(struct file * file, const char __user * buf,
+                 size_t size, loff_t * off)
+{
+       struct tpm_chip *chip = file->private_data;
+       int in_size = size, out_size;
+
+       /* cannot perform a write until the read has cleared
+          either via tpm_read or a user_read_timer timeout */
+       while (atomic_read(&chip->data_pending) != 0)
+               msleep(TPM_TIMEOUT);
+
+       down(&chip->buffer_mutex);
+
+       if (in_size > TPM_BUFSIZE)
+               in_size = TPM_BUFSIZE;
+
+       if (copy_from_user
+           (chip->data_buffer, (void __user *) buf, in_size)) {
+               up(&chip->buffer_mutex);
+               return -EFAULT;
+       }
+
+       /* atomic tpm command send and result receive */
+       out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
+
+       atomic_set(&chip->data_pending, out_size);
+       up(&chip->buffer_mutex);
+
+       /* Set a timeout by which the reader must come claim the result */
+       mod_timer(&chip->user_read_timer, jiffies + (60 * HZ));
+
+       return in_size;
+}
+
+EXPORT_SYMBOL_GPL(tpm_write);
+
+ssize_t tpm_read(struct file * file, char __user * buf,
+                size_t size, loff_t * off)
+{
+       struct tpm_chip *chip = file->private_data;
+       int ret_size;
+
+       del_singleshot_timer_sync(&chip->user_read_timer);
+       ret_size = atomic_read(&chip->data_pending);
+
+       if (ret_size > 0) {     /* relay data */
+               int position = atomic_read(&chip->data_position);
+
+               if (size < ret_size)
+                       ret_size = size;
+
+               down(&chip->buffer_mutex);
+
+               if (copy_to_user((void __user *) buf,
+                                &chip->data_buffer[position],
+                                ret_size)) {
+                       ret_size = -EFAULT;
+               } else {
+                       int pending = atomic_read(&chip->data_pending) - 
ret_size;
+                       atomic_set(&chip->data_pending,
+                                  pending);
+                       atomic_set(&chip->data_position,
+                                  position + ret_size);
+               }
+               up(&chip->buffer_mutex);
+       }
+
+       return ret_size;
+}
+
+EXPORT_SYMBOL_GPL(tpm_read);
+
+void tpm_remove_hardware(struct device *dev)
+{
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       int i;
+
+       if (chip == NULL) {
+               dev_err(dev, "No device data found\n");
+               return;
+       }
+
+       spin_lock(&driver_lock);
+
+       list_del(&chip->list);
+
+       spin_unlock(&driver_lock);
+
+       dev_set_drvdata(dev, NULL);
+       misc_deregister(&chip->vendor->miscdev);
+
+       for (i = 0; i < TPM_NUM_ATTR; i++)
+               device_remove_file(dev, &chip->vendor->attr[i]);
+
+       dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES] &=
+           !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
+
+       kfree(chip);
+
+       put_device(dev);
+}
+
+EXPORT_SYMBOL_GPL(tpm_remove_hardware);
+
+static const u8 savestate[] = {
+       0, 193,                 /* TPM_TAG_RQU_COMMAND */
+       0, 0, 0, 10,            /* blob length (in bytes) */
+       0, 0, 0, 152            /* TPM_ORD_SaveState */
+};
+
+/*
+ * We are about to suspend. Save the TPM state
+ * so that it can be restored.
+ */
+int tpm_pm_suspend(struct pci_dev *pci_dev, u32 pm_state)
+{
+       struct tpm_chip *chip = pci_get_drvdata(pci_dev);
+       if (chip == NULL)
+               return -ENODEV;
+
+       tpm_transmit(chip, savestate, sizeof(savestate));
+       return 0;
+}
+
+EXPORT_SYMBOL_GPL(tpm_pm_suspend);
+
+/*
+ * Resume from a power safe. The BIOS already restored
+ * the TPM state.
+ */
+int tpm_pm_resume(struct pci_dev *pci_dev)
+{
+       struct tpm_chip *chip = pci_get_drvdata(pci_dev);
+
+       if (chip == NULL)
+               return -ENODEV;
+
+       return 0;
+}
+
+EXPORT_SYMBOL_GPL(tpm_pm_resume);
+
+/*
+ * Called from tpm_<specific>.c probe function only for devices
+ * the driver has determined it should claim.  Prior to calling
+ * this function the specific probe function has called pci_enable_device
+ * upon errant exit from this function specific probe function should call
+ * pci_disable_device
+ */
+int tpm_register_hardware_nopci(struct device *dev,
+                               struct tpm_vendor_specific *entry)
+{
+       char devname[7];
+       struct tpm_chip *chip;
+       int i, j;
+
+       /* Driver specific per-device data */
+       chip = kmalloc(sizeof(*chip), GFP_KERNEL);
+       if (chip == NULL)
+               return -ENOMEM;
+
+       memset(chip, 0, sizeof(struct tpm_chip));
+
+       init_MUTEX(&chip->buffer_mutex);
+       init_MUTEX(&chip->tpm_mutex);
+       INIT_LIST_HEAD(&chip->list);
+
+       init_timer(&chip->user_read_timer);
+       chip->user_read_timer.function = user_reader_timeout;
+       chip->user_read_timer.data = (unsigned long) chip;
+
+       chip->vendor = entry;
+
+       chip->dev_num = -1;
+
+       for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++)
+               for (j = 0; j < 8 * sizeof(int); j++)
+                       if ((dev_mask[i] & (1 << j)) == 0) {
+                               chip->dev_num =
+                                   i * TPM_NUM_MASK_ENTRIES + j;
+                               dev_mask[i] |= 1 << j;
+                               goto dev_num_search_complete;
+                       }
+
+dev_num_search_complete:
+       if (chip->dev_num < 0) {
+               dev_err(dev, "No available tpm device numbers\n");
+               kfree(chip);
+               return -ENODEV;
+       } else if (chip->dev_num == 0)
+               chip->vendor->miscdev.minor = TPM_MINOR;
+       else
+               chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
+
+       snprintf(devname, sizeof(devname), "%s%d", "tpm", chip->dev_num);
+       chip->vendor->miscdev.name = devname;
+
+       chip->vendor->miscdev.dev = dev;
+       chip->dev = get_device(dev);
+
+
+       if (misc_register(&chip->vendor->miscdev)) {
+               dev_err(chip->dev,
+                       "unable to misc_register %s, minor %d\n",
+                       chip->vendor->miscdev.name,
+                       chip->vendor->miscdev.minor);
+               put_device(dev);
+               kfree(chip);
+               dev_mask[i] &= !(1 << j);
+               return -ENODEV;
+       }
+
+       spin_lock(&driver_lock);
+
+       dev_set_drvdata(dev, chip);
+
+       list_add(&chip->list, &tpm_chip_list);
+
+       spin_unlock(&driver_lock);
+
+       for (i = 0; i < TPM_NUM_ATTR; i++)
+               device_create_file(dev, &chip->vendor->attr[i]);
+
+       return 0;
+}
+
+EXPORT_SYMBOL_GPL(tpm_register_hardware_nopci);
+
+static int __init init_tpm(void)
+{
+       return 0;
+}
+
+static void __exit cleanup_tpm(void)
+{
+
+}
+
+module_init(init_tpm);
+module_exit(cleanup_tpm);
+
+MODULE_AUTHOR("Leendert van Doorn (leendert@xxxxxxxxxxxxxx)");
+MODULE_DESCRIPTION("TPM Driver");
+MODULE_VERSION("2.0");
+MODULE_LICENSE("GPL");
diff -r 84ab93e1ee05 -r dd668f7527cb 
linux-2.6-xen-sparse/drivers/char/tpm/tpm_nopci.h
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_nopci.h Thu Sep  1 10:16:14 2005
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2004 IBM Corporation
+ *
+ * Authors:
+ * Leendert van Doorn <leendert@xxxxxxxxxxxxxx>
+ * Dave Safford <safford@xxxxxxxxxxxxxx>
+ * Reiner Sailer <sailer@xxxxxxxxxxxxxx>
+ * Kylene Hall <kjhall@xxxxxxxxxx>
+ *
+ * Maintained by: <tpmdd_devel@xxxxxxxxxxxxxxxxxxxxx>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ */
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/miscdevice.h>
+
+enum {
+       TPM_TIMEOUT = 5,        /* msecs */
+       TPM_NUM_ATTR = 4
+};
+
+/* TPM addresses */
+enum {
+       TPM_ADDR = 0x4E,
+       TPM_DATA = 0x4F
+};
+
+/*
+ * Chip num is this value or a valid tpm idx in lower two bytes of chip_id
+ */
+enum tpm_chip_num {
+       TPM_ANY_NUM = 0xFFFF,
+};
+
+#define TPM_CHIP_NUM_MASK      0x0000ffff
+
+extern ssize_t tpm_show_pubek(struct device *, char *);
+extern ssize_t tpm_show_pcrs(struct device *, char *);
+extern ssize_t tpm_show_caps(struct device *, char *);
+extern ssize_t tpm_store_cancel(struct device *, const char *, size_t);
+
+#define TPM_DEVICE_ATTRS { \
+       __ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL), \
+       __ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL), \
+       __ATTR(caps, S_IRUGO, tpm_show_caps, NULL), \
+       __ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel) }
+
+struct tpm_chip;
+
+struct tpm_vendor_specific {
+       u8 req_complete_mask;
+       u8 req_complete_val;
+       u8 req_canceled;
+       u16 base;               /* TPM base address */
+
+       int (*recv) (struct tpm_chip *, u8 *, size_t);
+       int (*send) (struct tpm_chip *, u8 *, size_t);
+       void (*cancel) (struct tpm_chip *);
+        u8(*status) (struct tpm_chip *);
+       struct miscdevice miscdev;
+       struct device_attribute attr[TPM_NUM_ATTR];
+};
+
+struct tpm_chip {
+       struct device *dev;     /* PCI device stuff */
+
+       int dev_num;            /* /dev/tpm# */
+       int num_opens;          /* only one allowed */
+       int time_expired;
+
+       /* Data passed to and from the tpm via the read/write calls */
+       u8 *data_buffer;
+       atomic_t data_pending;
+       atomic_t data_position;
+       struct semaphore buffer_mutex;
+
+       struct timer_list user_read_timer;      /* user needs to claim result */
+       struct semaphore tpm_mutex;     /* tpm is processing */
+
+       struct tpm_vendor_specific *vendor;
+
+       struct list_head list;
+};
+
+static inline int tpm_read_index(int index)
+{
+       outb(index, TPM_ADDR);
+       return inb(TPM_DATA) & 0xFF;
+}
+
+static inline void tpm_write_index(int index, int value)
+{
+       outb(index, TPM_ADDR);
+       outb(value & 0xFF, TPM_DATA);
+}
+
+extern void tpm_time_expired(unsigned long);
+extern int tpm_lpc_bus_init(struct pci_dev *, u16);
+
+extern int tpm_register_hardware_nopci(struct device *,
+                                      struct tpm_vendor_specific *);
+extern void tpm_remove_hardware(struct device *);
+extern int tpm_open(struct inode *, struct file *);
+extern int tpm_release(struct inode *, struct file *);
+extern ssize_t tpm_write(struct file *, const char __user *, size_t,
+                        loff_t *);
+extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *);
+extern int tpm_pcr_extend(u32 chip_id, int pcr_idx, const u8* hash);
+extern int tpm_pcr_read( u32 chip_id, int pcr_idx, u8* res_buf, int 
res_buf_size );
+
+extern int tpm_pm_suspend(struct pci_dev *, u32);
+extern int tpm_pm_resume(struct pci_dev *);
+
+/* internal kernel interface */
+extern ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
+                           size_t bufsiz);
+extern struct tpm_chip *tpm_chip_lookup(int chip_num);
diff -r 84ab93e1ee05 -r dd668f7527cb 
linux-2.6-xen-sparse/drivers/char/tpm/tpm_nsc.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_nsc.c   Thu Sep  1 10:16:14 2005
@@ -0,0 +1,377 @@
+/*
+ * Copyright (C) 2004 IBM Corporation
+ *
+ * Authors:
+ * Leendert van Doorn <leendert@xxxxxxxxxxxxxx>
+ * Dave Safford <safford@xxxxxxxxxxxxxx>
+ * Reiner Sailer <sailer@xxxxxxxxxxxxxx>
+ * Kylene Hall <kjhall@xxxxxxxxxx>
+ *
+ * Maintained by: <tpmdd_devel@xxxxxxxxxxxxxxxxxxxxx>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ */
+
+#include "tpm.h"
+
+/* National definitions */
+#define        TPM_NSC_BASE                    0x360
+#define        TPM_NSC_IRQ                     0x07
+#define        TPM_NSC_BASE0_HI                0x60
+#define        TPM_NSC_BASE0_LO                0x61
+#define        TPM_NSC_BASE1_HI                0x62
+#define        TPM_NSC_BASE1_LO                0x63
+
+#define        NSC_LDN_INDEX                   0x07
+#define        NSC_SID_INDEX                   0x20
+#define        NSC_LDC_INDEX                   0x30
+#define        NSC_DIO_INDEX                   0x60
+#define        NSC_CIO_INDEX                   0x62
+#define        NSC_IRQ_INDEX                   0x70
+#define        NSC_ITS_INDEX                   0x71
+
+#define        NSC_STATUS                      0x01
+#define        NSC_COMMAND                     0x01
+#define        NSC_DATA                        0x00
+
+/* status bits */
+#define        NSC_STATUS_OBF                  0x01    /* output buffer full */
+#define        NSC_STATUS_IBF                  0x02    /* input buffer full */
+#define        NSC_STATUS_F0                   0x04    /* F0 */
+#define        NSC_STATUS_A2                   0x08    /* A2 */
+#define        NSC_STATUS_RDY                  0x10    /* ready to receive 
command */
+#define        NSC_STATUS_IBR                  0x20    /* ready to receive 
data */
+
+/* command bits */
+#define        NSC_COMMAND_NORMAL              0x01    /* normal mode */
+#define        NSC_COMMAND_EOC                 0x03
+#define        NSC_COMMAND_CANCEL              0x22
+
+/*
+ * Wait for a certain status to appear
+ */
+static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data)
+{
+       int expired = 0;
+       struct timer_list status_timer =
+           TIMER_INITIALIZER(tpm_time_expired, jiffies + 10 * HZ,
+                             (unsigned long) &expired);
+
+       /* status immediately available check */
+       *data = inb(chip->vendor->base + NSC_STATUS);
+       if ((*data & mask) == val)
+               return 0;
+
+       /* wait for status */
+       add_timer(&status_timer);
+       do {
+               set_current_state(TASK_UNINTERRUPTIBLE);
+               schedule_timeout(TPM_TIMEOUT);
+               *data = inb(chip->vendor->base + 1);
+               if ((*data & mask) == val) {
+                       del_singleshot_timer_sync(&status_timer);
+                       return 0;
+               }
+       }
+       while (!expired);
+
+       return -EBUSY;
+}
+
+static int nsc_wait_for_ready(struct tpm_chip *chip)
+{
+       int status;
+       int expired = 0;
+       struct timer_list status_timer =
+           TIMER_INITIALIZER(tpm_time_expired, jiffies + 100,
+                             (unsigned long) &expired);
+
+       /* status immediately available check */
+       status = inb(chip->vendor->base + NSC_STATUS);
+       if (status & NSC_STATUS_OBF)
+               status = inb(chip->vendor->base + NSC_DATA);
+       if (status & NSC_STATUS_RDY)
+               return 0;
+
+       /* wait for status */
+       add_timer(&status_timer);
+       do {
+               set_current_state(TASK_UNINTERRUPTIBLE);
+               schedule_timeout(TPM_TIMEOUT);
+               status = inb(chip->vendor->base + NSC_STATUS);
+               if (status & NSC_STATUS_OBF)
+                       status = inb(chip->vendor->base + NSC_DATA);
+               if (status & NSC_STATUS_RDY) {
+                       del_singleshot_timer_sync(&status_timer);
+                       return 0;
+               }
+       }
+       while (!expired);
+
+       dev_info(&chip->pci_dev->dev, "wait for ready failed\n");
+       return -EBUSY;
+}
+
+
+static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
+{
+       u8 *buffer = buf;
+       u8 data, *p;
+       u32 size;
+       __be32 *native_size;
+
+       if (count < 6)
+               return -EIO;
+
+       if (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0) {
+               dev_err(&chip->pci_dev->dev, "F0 timeout\n");
+               return -EIO;
+       }
+       if ((data =
+            inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
+               dev_err(&chip->pci_dev->dev, "not in normal mode (0x%x)\n",
+                       data);
+               return -EIO;
+       }
+
+       /* read the whole packet */
+       for (p = buffer; p < &buffer[count]; p++) {
+               if (wait_for_stat
+                   (chip, NSC_STATUS_OBF, NSC_STATUS_OBF, &data) < 0) {
+                       dev_err(&chip->pci_dev->dev,
+                               "OBF timeout (while reading data)\n");
+                       return -EIO;
+               }
+               if (data & NSC_STATUS_F0)
+                       break;
+               *p = inb(chip->vendor->base + NSC_DATA);
+       }
+
+       if ((data & NSC_STATUS_F0) == 0) {
+               dev_err(&chip->pci_dev->dev, "F0 not set\n");
+               return -EIO;
+       }
+       if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) {
+               dev_err(&chip->pci_dev->dev,
+                       "expected end of command(0x%x)\n", data);
+               return -EIO;
+       }
+
+       native_size = (__force __be32 *) (buf + 2);
+       size = be32_to_cpu(*native_size);
+
+       if (count < size)
+               return -EIO;
+
+       return size;
+}
+
+static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
+{
+       u8 data;
+       int i;
+
+       /*
+        * If we hit the chip with back to back commands it locks up
+        * and never set IBF. Hitting it with this "hammer" seems to
+        * fix it. Not sure why this is needed, we followed the flow
+        * chart in the manual to the letter.
+        */
+       outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
+
+       if (nsc_wait_for_ready(chip) != 0)
+               return -EIO;
+
+       if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
+               dev_err(&chip->pci_dev->dev, "IBF timeout\n");
+               return -EIO;
+       }
+
+       outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND);
+       if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) {
+               dev_err(&chip->pci_dev->dev, "IBR timeout\n");
+               return -EIO;
+       }
+
+       for (i = 0; i < count; i++) {
+               if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
+                       dev_err(&chip->pci_dev->dev,
+                               "IBF timeout (while writing data)\n");
+                       return -EIO;
+               }
+               outb(buf[i], chip->vendor->base + NSC_DATA);
+       }
+
+       if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
+               dev_err(&chip->pci_dev->dev, "IBF timeout\n");
+               return -EIO;
+       }
+       outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND);
+
+       return count;
+}
+
+static void tpm_nsc_cancel(struct tpm_chip *chip)
+{
+       outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
+}
+
+static struct file_operations nsc_ops = {
+       .owner = THIS_MODULE,
+       .llseek = no_llseek,
+       .open = tpm_open,
+       .read = tpm_read,
+       .write = tpm_write,
+       .release = tpm_release,
+};
+
+static struct tpm_vendor_specific tpm_nsc = {
+       .recv = tpm_nsc_recv,
+       .send = tpm_nsc_send,
+       .cancel = tpm_nsc_cancel,
+       .req_complete_mask = NSC_STATUS_OBF,
+       .req_complete_val = NSC_STATUS_OBF,
+       .miscdev = { .fops = &nsc_ops, },
+
+};
+
+static int __devinit tpm_nsc_init(struct pci_dev *pci_dev,
+                                 const struct pci_device_id *pci_id)
+{
+       int rc = 0;
+       int lo, hi;
+
+       hi = tpm_read_index(TPM_NSC_BASE0_HI);
+       lo = tpm_read_index(TPM_NSC_BASE0_LO);
+
+       tpm_nsc.base = (hi<<8) | lo;
+
+       if (pci_enable_device(pci_dev))
+               return -EIO;
+
+       /* verify that it is a National part (SID) */
+       if (tpm_read_index(NSC_SID_INDEX) != 0xEF) {
+               rc = -ENODEV;
+               goto out_err;
+       }
+
+       dev_dbg(&pci_dev->dev, "NSC TPM detected\n");
+       dev_dbg(&pci_dev->dev,
+               "NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n",
+               tpm_read_index(0x07), tpm_read_index(0x20),
+               tpm_read_index(0x27));
+       dev_dbg(&pci_dev->dev,
+               "NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n",
+               tpm_read_index(0x21), tpm_read_index(0x25),
+               tpm_read_index(0x26), tpm_read_index(0x28));
+       dev_dbg(&pci_dev->dev, "NSC IO Base0 0x%x\n",
+               (tpm_read_index(0x60) << 8) | tpm_read_index(0x61));
+       dev_dbg(&pci_dev->dev, "NSC IO Base1 0x%x\n",
+               (tpm_read_index(0x62) << 8) | tpm_read_index(0x63));
+       dev_dbg(&pci_dev->dev, "NSC Interrupt number and wakeup 0x%x\n",
+               tpm_read_index(0x70));
+       dev_dbg(&pci_dev->dev, "NSC IRQ type select 0x%x\n",
+               tpm_read_index(0x71));
+       dev_dbg(&pci_dev->dev,
+               "NSC DMA channel select0 0x%x, select1 0x%x\n",
+               tpm_read_index(0x74), tpm_read_index(0x75));
+       dev_dbg(&pci_dev->dev,
+               "NSC Config "
+               "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+               tpm_read_index(0xF0), tpm_read_index(0xF1),
+               tpm_read_index(0xF2), tpm_read_index(0xF3),
+               tpm_read_index(0xF4), tpm_read_index(0xF5),
+               tpm_read_index(0xF6), tpm_read_index(0xF7),
+               tpm_read_index(0xF8), tpm_read_index(0xF9));
+
+       dev_info(&pci_dev->dev,
+                "NSC PC21100 TPM revision %d\n",
+                tpm_read_index(0x27) & 0x1F);
+
+       if (tpm_read_index(NSC_LDC_INDEX) == 0)
+               dev_info(&pci_dev->dev, ": NSC TPM not active\n");
+
+       /* select PM channel 1 */
+       tpm_write_index(NSC_LDN_INDEX, 0x12);
+       tpm_read_index(NSC_LDN_INDEX);
+
+       /* disable the DPM module */
+       tpm_write_index(NSC_LDC_INDEX, 0);
+       tpm_read_index(NSC_LDC_INDEX);
+
+       /* set the data register base addresses */
+       tpm_write_index(NSC_DIO_INDEX, TPM_NSC_BASE >> 8);
+       tpm_write_index(NSC_DIO_INDEX + 1, TPM_NSC_BASE);
+       tpm_read_index(NSC_DIO_INDEX);
+       tpm_read_index(NSC_DIO_INDEX + 1);
+
+       /* set the command register base addresses */
+       tpm_write_index(NSC_CIO_INDEX, (TPM_NSC_BASE + 1) >> 8);
+       tpm_write_index(NSC_CIO_INDEX + 1, (TPM_NSC_BASE + 1));
+       tpm_read_index(NSC_DIO_INDEX);
+       tpm_read_index(NSC_DIO_INDEX + 1);
+
+       /* set the interrupt number to be used for the host interface */
+       tpm_write_index(NSC_IRQ_INDEX, TPM_NSC_IRQ);
+       tpm_write_index(NSC_ITS_INDEX, 0x00);
+       tpm_read_index(NSC_IRQ_INDEX);
+
+       /* enable the DPM module */
+       tpm_write_index(NSC_LDC_INDEX, 0x01);
+       tpm_read_index(NSC_LDC_INDEX);
+
+       if ((rc = tpm_register_hardware(pci_dev, &tpm_nsc)) < 0)
+               goto out_err;
+
+       return 0;
+
+out_err:
+       pci_disable_device(pci_dev);
+       return rc;
+}
+
+static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
+       {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
+       {0,}
+};
+
+MODULE_DEVICE_TABLE(pci, tpm_pci_tbl);
+
+static struct pci_driver nsc_pci_driver = {
+       .name = "tpm_nsc",
+       .id_table = tpm_pci_tbl,
+       .probe = tpm_nsc_init,
+       .remove = __devexit_p(tpm_remove),
+       .suspend = tpm_pm_suspend,
+       .resume = tpm_pm_resume,
+};
+
+static int __init init_nsc(void)
+{
+       return pci_register_driver(&nsc_pci_driver);
+}
+
+static void __exit cleanup_nsc(void)
+{
+       pci_unregister_driver(&nsc_pci_driver);
+}
+
+module_init(init_nsc);
+module_exit(cleanup_nsc);
+
+MODULE_AUTHOR("Leendert van Doorn (leendert@xxxxxxxxxxxxxx)");
+MODULE_DESCRIPTION("TPM Driver");
+MODULE_VERSION("2.0");
+MODULE_LICENSE("GPL");
diff -r 84ab93e1ee05 -r dd668f7527cb 
linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c   Thu Sep  1 10:16:14 2005
@@ -0,0 +1,513 @@
+/*
+ * Copyright (C) 2004 IBM Corporation
+ *
+ * Authors:
+ * Leendert van Doorn <leendert@xxxxxxxxxxxxxx>
+ * Dave Safford <safford@xxxxxxxxxxxxxx>
+ * Reiner Sailer <sailer@xxxxxxxxxxxxxx>
+ * Kylene Hall <kjhall@xxxxxxxxxx>
+ * Stefan Berger <stefanb@xxxxxxxxxx>
+ *
+ * Maintained by: <tpmdd_devel@xxxxxxxxxxxxxxxxxxxxx>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module) for XEN.
+ * Specifications at www.trustedcomputinggroup.org
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ */
+
+#include <asm/uaccess.h>
+#include <linux/list.h>
+#include <linux/tpmfe.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include "tpm_nopci.h"
+
+/* read status bits */
+enum {
+       STATUS_BUSY = 0x01,
+       STATUS_DATA_AVAIL = 0x02,
+       STATUS_READY = 0x04
+};
+
+#define MIN(x,y)  ((x) < (y)) ? (x) : (y)
+
+struct transmission {
+       struct list_head next;
+       unsigned char *request;
+       unsigned int request_len;
+       unsigned char *rcv_buffer;
+       unsigned int  buffersize;
+       struct tpm_chip     *chip;
+       unsigned int flags;
+};
+
+enum {
+       TRANSMISSION_FLAG_WAS_QUEUED = 0x1
+};
+
+struct data_exchange {
+       struct transmission *current_request;
+       spinlock_t           req_list_lock;
+       wait_queue_head_t    req_wait_queue;
+
+       struct list_head     queued_requests;
+
+       struct transmission *current_response;
+       spinlock_t           resp_list_lock;
+       wait_queue_head_t    resp_wait_queue;     // processes waiting for 
responses
+
+       struct transmission *req_cancelled;       // if a cancellation was 
encounterd
+
+       unsigned int         fe_status;
+       unsigned int         flags;
+};
+
+enum {
+       DATAEX_FLAG_QUEUED_ONLY = 0x1
+};
+
+static struct data_exchange dataex;
+
+static unsigned long disconnect_time;
+
+/* local function prototypes */
+static void __exit cleanup_xen(void);
+
+
+/* =============================================================
+ * Some utility functions
+ * =============================================================
+ */
+static inline struct transmission *
+transmission_alloc(void)
+{
+       struct transmission *t = kmalloc(sizeof(*t), GFP_KERNEL);
+       if (t) {
+               memset(t, 0x0, sizeof(*t));
+       }
+       return t;
+}
+
+static inline unsigned char *
+transmission_set_buffer(struct transmission *t,
+                        unsigned char *buffer, unsigned int len)
+{
+       if (NULL != t->request) {
+               kfree(t->request);
+       }
+       t->request = kmalloc(len, GFP_KERNEL);
+       if (t->request) {
+               memcpy(t->request,
+                      buffer,
+                      len);
+               t->request_len = len;
+       }
+       return t->request;
+}
+
+static inline void
+transmission_free(struct transmission *t)
+{
+       if (t->request) {
+               kfree(t->request);
+       }
+       if (t->rcv_buffer) {
+               kfree(t->rcv_buffer);
+       }
+       kfree(t);
+}
+
+/* =============================================================
+ * Interface with the TPM shared memory driver for XEN
+ * =============================================================
+ */
+static int tpm_recv(const u8 *buffer, size_t count, const void *ptr)
+{
+       int ret_size = 0;
+       struct transmission *t, *temp;
+
+       /*
+        * The list with requests must contain one request
+        * only and the element there must be the one that
+        * was passed to me from the front-end.
+        */
+       if (dataex.current_request != ptr) {
+               printk("WARNING: The request pointer is different than the 
pointer "
+                      "the shared memory driver returned to me. %p != %p\n",
+                      dataex.current_request, ptr);
+       }
+
+       /*
+        * If the request has been cancelled, just quit here
+        */
+       if (dataex.req_cancelled == (struct transmission *)ptr) {
+               if (dataex.current_request == dataex.req_cancelled) {
+                       dataex.current_request = NULL;
+               }
+               transmission_free(dataex.req_cancelled);
+               dataex.req_cancelled = NULL;
+               return 0;
+       }
+
+       if (NULL != (temp = dataex.current_request)) {
+               transmission_free(temp);
+               dataex.current_request = NULL;
+       }
+
+       t = transmission_alloc();
+       if (NULL != t) {
+               unsigned long flags;
+               t->rcv_buffer = kmalloc(count, GFP_KERNEL);
+               if (NULL == t->rcv_buffer) {
+                       transmission_free(t);
+                       return -ENOMEM;
+               }
+               t->buffersize = count;
+               memcpy(t->rcv_buffer, buffer, count);
+               ret_size = count;
+
+               spin_lock_irqsave(&dataex.resp_list_lock ,flags);
+               dataex.current_response = t;
+               spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
+               wake_up_interruptible(&dataex.resp_wait_queue);
+       }
+       return ret_size;
+}
+
+
+static void tpm_fe_status(unsigned int flags)
+{
+       dataex.fe_status = flags;
+       if ((dataex.fe_status & TPMFE_STATUS_CONNECTED) == 0) {
+               disconnect_time = jiffies;
+       }
+}
+
+/* =============================================================
+ * Interface with the generic TPM driver
+ * =============================================================
+ */
+static int tpm_xen_recv(struct tpm_chip *chip, u8 * buf, size_t count)
+{
+       unsigned long flags;
+       int rc = 0;
+
+       spin_lock_irqsave(&dataex.resp_list_lock, flags);
+       /*
+        * Check if the previous operation only queued the command
+        * In this case there won't be a response, so I just
+        * return from here and reset that flag. In any other
+        * case I should receive a response from the back-end.
+        */
+       if ((dataex.flags & DATAEX_FLAG_QUEUED_ONLY) != 0) {
+               dataex.flags &= ~DATAEX_FLAG_QUEUED_ONLY;
+               spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
+               /*
+                * a little hack here. The first few measurements
+                * are queued since there's no way to talk to the
+                * TPM yet (due to slowness of the control channel)
+                * So we just make IMA happy by giving it 30 NULL
+                * bytes back where the most important part is
+                * that the result code is '0'.
+                */
+
+               count = MIN(count, 30);
+               memset(buf, 0x0, count);
+               return count;
+       }
+       /*
+        * Check whether something is in the responselist and if
+        * there's nothing in the list wait for something to appear.
+        */
+
+       if (NULL == dataex.current_response) {
+               spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
+               interruptible_sleep_on_timeout(&dataex.resp_wait_queue,
+                                              1000);
+               spin_lock_irqsave(&dataex.resp_list_lock ,flags);
+       }
+
+       if (NULL != dataex.current_response) {
+               struct transmission *t = dataex.current_response;
+               dataex.current_response = NULL;
+               rc = MIN(count, t->buffersize);
+               memcpy(buf, t->rcv_buffer, rc);
+               transmission_free(t);
+       }
+
+       spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
+       return rc;
+}
+
+static int tpm_xen_send(struct tpm_chip *chip, u8 * buf, size_t count)
+{
+       /*
+        * We simply pass the packet onto the XEN shared
+        * memory driver.
+        */
+       unsigned long flags;
+       int rc;
+       struct transmission *t = transmission_alloc();
+
+       spin_lock_irqsave(&dataex.req_list_lock, flags);
+       /*
+        * If there's a current request, it must be the
+        * previous request that has timed out.
+        */
+       if (dataex.current_request != NULL) {
+               printk("WARNING: Sending although there is a request 
outstanding.\n"
+                      "         Previous request must have timed out.\n");
+               transmission_free(dataex.current_request);
+               dataex.current_request = NULL;
+       }
+
+       if (t != NULL) {
+               unsigned int error = 0;
+               t->rcv_buffer = NULL;
+               t->buffersize = 0;
+               t->chip = chip;
+
+               /*
+                * Queue the packet if the driver below is not
+                * ready, yet, or there is any packet already
+                * in the queue.
+                * If the driver below is ready, unqueue all
+                * packets first before sending our current
+                * packet.
+                * For each unqueued packet, except for the
+                * last (=current) packet, call the function
+                * tpm_xen_recv to wait for the response to come
+                * back.
+                */
+               if ((dataex.fe_status & TPMFE_STATUS_CONNECTED) == 0) {
+                       if (time_after(jiffies, disconnect_time + HZ * 10)) {
+                               rc = -ENOENT;
+                       } else {
+                               /*
+                                * copy the request into the buffer
+                                */
+                               if (transmission_set_buffer(t, buf, count)
+                                   == NULL) {
+                                       transmission_free(t);
+                                       rc = -ENOMEM;
+                                       goto exit;
+                               }
+                               dataex.flags |= DATAEX_FLAG_QUEUED_ONLY;
+                               list_add_tail(&t->next, 
&dataex.queued_requests);
+                               rc = 0;
+                       }
+               } else {
+                       /*
+                        * Check whether there are any packets in the queue
+                        */
+                       while (!list_empty(&dataex.queued_requests)) {
+                               /*
+                                * Need to dequeue them.
+                                * Read the result into a dummy buffer.
+                                */
+                               unsigned char buffer[1];
+                               struct transmission *qt = (struct transmission 
*) dataex.queued_requests.next;
+                               list_del(&qt->next);
+                               dataex.current_request = qt;
+                               spin_unlock_irqrestore(&dataex.req_list_lock, 
flags);
+
+                               rc = tpm_fe_send(qt->request,
+                                                qt->request_len,
+                                                qt);
+
+                               if (rc < 0) {
+                                       
spin_lock_irqsave(&dataex.req_list_lock, flags);
+                                       if ((qt = dataex.current_request) != 
NULL) {
+                                               /*
+                                                * requeue it at the beginning
+                                                * of the list
+                                                */
+                                               list_add(&qt->next,
+                                                        
&dataex.queued_requests);
+                                       }
+                                       dataex.current_request = NULL;
+                                       error = 1;
+                                       break;
+                               }
+                               /*
+                                * After this point qt is not valid anymore!
+                                * It is freed when the front-end is delivering 
the data
+                                * by calling tpm_recv
+                                */
+
+                               /*
+                                * Try to receive the response now into the 
provided dummy
+                                * buffer (I don't really care about this 
response since
+                                * there is no receiver anymore for this 
response)
+                                */
+                               rc = tpm_xen_recv(chip, buffer, sizeof(buffer));
+
+                               spin_lock_irqsave(&dataex.req_list_lock, flags);
+                       }
+
+                       if (error == 0) {
+                               /*
+                                * Finally, send the current request.
+                                */
+                               dataex.current_request = t;
+                               /*
+                                * Call the shared memory driver
+                                * Pass to it the buffer with the request, the
+                                * amount of bytes in the request and
+                                * a void * pointer (here: transmission 
structure)
+                                */
+                               rc = tpm_fe_send(buf, count, t);
+                               /*
+                                * The generic TPM driver will call
+                                * the function to receive the response.
+                                */
+                               if (rc < 0) {
+                                       dataex.current_request = NULL;
+                                       goto queue_it;
+                               }
+                       } else {
+queue_it:
+                               if (transmission_set_buffer(t, buf, count) == 
NULL) {
+                                       transmission_free(t);
+                                       rc = -ENOMEM;
+                                       goto exit;
+                               }
+                               /*
+                                * An error occurred. Don't event try
+                                * to send the current request. Just
+                                * queue it.
+                                */
+                               dataex.flags |= DATAEX_FLAG_QUEUED_ONLY;
+                               list_add_tail(&t->next, 
&dataex.queued_requests);
+                               rc = 0;
+                       }
+               }
+       } else {
+               rc = -ENOMEM;
+       }
+
+exit:
+       spin_unlock_irqrestore(&dataex.req_list_lock, flags);
+       return rc;
+}
+
+static void tpm_xen_cancel(struct tpm_chip *chip)
+{
+       unsigned long flags;
+       spin_lock_irqsave(&dataex.resp_list_lock,flags);
+
+       dataex.req_cancelled = dataex.current_request;
+
+       spin_unlock_irqrestore(&dataex.resp_list_lock,flags);
+}
+
+static u8 tpm_xen_status(struct tpm_chip *chip)
+{
+       unsigned long flags;
+       u8 rc = 0;
+       spin_lock_irqsave(&dataex.resp_list_lock, flags);
+       /*
+        * Data are available if:
+        *  - there's a current response
+        *  - the last packet was queued only (this is fake, but necessary to
+        *      get the generic TPM layer to call the receive function.)
+        */
+       if (NULL != dataex.current_response ||
+           0 != (dataex.flags & DATAEX_FLAG_QUEUED_ONLY)) {
+               rc = STATUS_DATA_AVAIL;
+       }
+       spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
+       return rc;
+}
+
+static struct file_operations tpm_xen_ops = {
+       .owner = THIS_MODULE,
+       .llseek = no_llseek,
+       .open = tpm_open,
+       .read = tpm_read,
+       .write = tpm_write,
+       .release = tpm_release,
+};
+
+static struct tpm_vendor_specific tpm_xen = {
+       .recv = tpm_xen_recv,
+       .send = tpm_xen_send,
+       .cancel = tpm_xen_cancel,
+       .status = tpm_xen_status,
+       .req_complete_mask = STATUS_BUSY | STATUS_DATA_AVAIL,
+       .req_complete_val  = STATUS_DATA_AVAIL,
+       .req_canceled = STATUS_READY,
+       .base = 0,
+       .attr = TPM_DEVICE_ATTRS,
+       .miscdev.fops = &tpm_xen_ops,
+};
+
+static struct device tpm_device = {
+       .bus_id = "vtpm",
+};
+
+static struct tpmfe_device tpmfe = {
+       .receive = tpm_recv,
+       .status  = tpm_fe_status,
+};
+
+
+static int __init init_xen(void)
+{
+       int rc;
+
+       /*
+        * Register device with the low lever front-end
+        * driver
+        */
+       if ((rc = tpm_fe_register_receiver(&tpmfe)) < 0) {
+               return rc;
+       }
+
+       /*
+        * Register our device with the system.
+        */
+       if ((rc = device_register(&tpm_device)) < 0) {
+               tpm_fe_unregister_receiver();
+               return rc;
+       }
+
+       if ((rc = tpm_register_hardware_nopci(&tpm_device, &tpm_xen)) < 0) {
+               device_unregister(&tpm_device);
+               tpm_fe_unregister_receiver();
+               return rc;
+       }
+
+       dataex.current_request = NULL;
+       spin_lock_init(&dataex.req_list_lock);
+       init_waitqueue_head(&dataex.req_wait_queue);
+       INIT_LIST_HEAD(&dataex.queued_requests);
+
+       dataex.current_response = NULL;
+       spin_lock_init(&dataex.resp_list_lock);
+       init_waitqueue_head(&dataex.resp_wait_queue);
+
+       disconnect_time = jiffies;
+
+       return 0;
+}
+
+static void __exit cleanup_xen(void)
+{
+       tpm_remove_hardware(&tpm_device);
+       device_unregister(&tpm_device);
+       tpm_fe_unregister_receiver();
+}
+
+fs_initcall(init_xen);
+module_exit(cleanup_xen);
+
+MODULE_AUTHOR("Stefan Berger (stefanb@xxxxxxxxxx)");
+MODULE_DESCRIPTION("TPM Driver for XEN (shared memory)");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff -r 84ab93e1ee05 -r dd668f7527cb 
linux-2.6-xen-sparse/drivers/xen/tpmback/Makefile
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/Makefile Thu Sep  1 10:16:14 2005
@@ -0,0 +1,4 @@
+
+obj-$(CONFIG_XEN_TPMDEV_BACKEND)       += tpmbk.o
+
+tpmbk-y += tpmback.o interface.o xenbus.o
diff -r 84ab93e1ee05 -r dd668f7527cb 
linux-2.6-xen-sparse/drivers/xen/tpmback/common.h
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Thu Sep  1 10:16:14 2005
@@ -0,0 +1,89 @@
+/******************************************************************************
+ * drivers/xen/tpmback/common.h
+ */
+
+#ifndef __NETIF__BACKEND__COMMON_H__
+#define __NETIF__BACKEND__COMMON_H__
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <asm-xen/ctrl_if.h>
+#include <asm-xen/evtchn.h>
+#include <asm-xen/xen-public/io/tpmif.h>
+#include <asm/io.h>
+#include <asm/pgalloc.h>
+#include <asm-xen/xen-public/io/domain_controller.h>
+
+#if 0
+#define ASSERT(_p) \
+    if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
+    __LINE__, __FILE__); *(int*)0=0; }
+#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
+                           __FILE__ , __LINE__ , ## _a )
+#else
+#define ASSERT(_p) ((void)0)
+#define DPRINTK(_f, _a...) ((void)0)
+#endif
+
+typedef struct tpmif_st {
+        struct list_head tpmif_list;
+       /* Unique identifier for this interface. */
+       domid_t domid;
+       unsigned int handle;
+
+       /* Physical parameters of the comms window. */
+       unsigned long tx_shmem_frame;
+       unsigned int evtchn;
+       unsigned int remote_evtchn;
+
+       /* The shared rings and indexes. */
+       tpmif_tx_interface_t *tx;
+
+       /* Miscellaneous private stuff. */
+       enum { DISCONNECTED, DISCONNECTING, CONNECTED } status;
+       int active;
+
+       struct tpmif_st *hash_next;
+       struct list_head list;  /* scheduling list */
+       atomic_t refcnt;
+
+       long int tpm_instance;
+       unsigned long mmap_vstart;
+
+       struct work_struct work;
+
+       u16 shmem_handle;
+       unsigned long shmem_vaddr;
+       grant_ref_t shmem_ref;
+
+} tpmif_t;
+
+void tpmif_disconnect_complete(tpmif_t * tpmif);
+tpmif_t *tpmif_find(domid_t domid, long int instance);
+void tpmif_interface_init(void);
+void tpmif_schedule_work(tpmif_t * tpmif);
+void tpmif_deschedule_work(tpmif_t * tpmif);
+void tpmif_xenbus_init(void);
+int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn);
+irqreturn_t tpmif_be_int(int irq, void *dev_id, struct pt_regs *regs);
+int tpmif_vtpm_open(tpmif_t *tpmif, domid_t domain, u32 instance);
+int tpmif_vtpm_close(u32 instance);
+
+int vtpm_release_packets(tpmif_t * tpmif, int send_msgs);
+
+#define tpmif_get(_b) (atomic_inc(&(_b)->refcnt))
+#define tpmif_put(_b)                             \
+    do {                                          \
+        if ( atomic_dec_and_test(&(_b)->refcnt) ) \
+            tpmif_disconnect_complete(_b);        \
+    } while (0)
+
+
+extern int num_frontends;
+
+#define MMAP_VADDR(t,_req) ((t)->mmap_vstart + ((_req) * PAGE_SIZE))
+
+#endif /* __TPMIF__BACKEND__COMMON_H__ */
diff -r 84ab93e1ee05 -r dd668f7527cb 
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Thu Sep  1 
10:16:14 2005
@@ -0,0 +1,200 @@
+/******************************************************************************
+ * drivers/xen/tpmback/interface.c
+ *
+ * Vritual TPM interface management.
+ *
+ * Copyright (c) 2005, IBM Corporation
+ *
+ * Author: Stefan Berger, stefanb@xxxxxxxxxx
+ *
+ * This code has been derived from drivers/xen/netback/interface.c
+ * Copyright (c) 2004, Keir Fraser
+ */
+
+#include "common.h"
+#include <asm-xen/balloon.h>
+
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+
+#define TPMIF_HASHSZ (2 << 5)
+#define TPMIF_HASH(_d,_h) (((int)(_d)^(int)(_h))&(TPMIF_HASHSZ-1))
+
+static kmem_cache_t *tpmif_cachep;
+int num_frontends = 0;
+LIST_HEAD(tpmif_list);
+
+
+tpmif_t *alloc_tpmif(domid_t domid, long int instance)
+{
+    struct page *page;
+    tpmif_t *tpmif;
+
+    tpmif = kmem_cache_alloc(tpmif_cachep, GFP_KERNEL);
+    if (!tpmif)
+        return ERR_PTR(-ENOMEM);
+
+    memset(tpmif, 0, sizeof(*tpmif));
+    tpmif->domid        = domid;
+    tpmif->status       = DISCONNECTED;
+    tpmif->tpm_instance = instance;
+    atomic_set(&tpmif->refcnt, 1);
+
+    page = balloon_alloc_empty_page_range(TPMIF_TX_RING_SIZE);
+    BUG_ON(page == NULL);
+    tpmif->mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
+
+    list_add(&tpmif->tpmif_list, &tpmif_list);
+    num_frontends++;
+
+    return tpmif;
+}
+
+
+void free_tpmif(tpmif_t *tpmif)
+{
+    num_frontends--;
+    list_del(&tpmif->tpmif_list);
+    kmem_cache_free(tpmif_cachep, tpmif);
+}
+
+
+tpmif_t *tpmif_find(domid_t domid, long int instance)
+{
+    tpmif_t *tpmif;
+
+    list_for_each_entry(tpmif, &tpmif_list, tpmif_list) {
+        if (tpmif->tpm_instance == instance) {
+            if (tpmif->domid == domid) {
+                tpmif_get(tpmif);
+                return tpmif;
+           } else {
+               return NULL;
+           }
+        }
+    }
+
+    return alloc_tpmif(domid, instance);
+}
+
+
+static int map_frontend_page(tpmif_t *tpmif, unsigned long localaddr,
+                            unsigned long shared_page)
+{
+    struct gnttab_map_grant_ref op = {
+        .host_addr = localaddr,
+        .flags     = GNTMAP_host_map,
+        .ref       = shared_page,
+        .dom       = tpmif->domid,
+    };
+
+    BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
+
+    if (op.handle < 0) {
+       DPRINTK(" Grant table operation failure !\n");
+       return op.handle;
+    }
+
+    tpmif->shmem_ref    = shared_page;
+    tpmif->shmem_handle = op.handle;
+    tpmif->shmem_vaddr  = localaddr;
+    return 0;
+}
+
+
+static void unmap_frontend_page(tpmif_t *tpmif)
+{
+    struct gnttab_unmap_grant_ref op;
+
+    op.host_addr = tpmif->shmem_vaddr;
+    op.handle = tpmif->shmem_handle;
+    op.dev_bus_addr = 0;
+
+    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
+}
+
+
+int tpmif_map(tpmif_t *tpmif,
+              unsigned long shared_page, unsigned int evtchn)
+{
+    struct vm_struct *vma;
+    evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
+    int err;
+
+    BUG_ON(tpmif->remote_evtchn);
+
+    if ( (vma = get_vm_area(PAGE_SIZE, VM_IOREMAP)) == NULL )
+       return -ENOMEM;
+
+    err = map_frontend_page(tpmif,
+                            VMALLOC_VMADDR(vma->addr),
+                            shared_page);
+    if (err) {
+        vfree(vma->addr);
+       return err;
+    }
+
+    op.u.bind_interdomain.dom1 = DOMID_SELF;
+    op.u.bind_interdomain.dom2 = tpmif->domid;
+    op.u.bind_interdomain.port1 = 0;
+    op.u.bind_interdomain.port2 = evtchn;
+    err = HYPERVISOR_event_channel_op(&op);
+    if (err) {
+       unmap_frontend_page(tpmif);
+       vfree(vma->addr);
+       return err;
+    }
+
+    tpmif->evtchn = op.u.bind_interdomain.port1;
+    tpmif->remote_evtchn = evtchn;
+
+    tpmif->tx = (tpmif_tx_interface_t *) vma->addr;
+
+    bind_evtchn_to_irqhandler(tpmif->evtchn,
+                              tpmif_be_int,
+                              0,
+                              "tpmif-backend",
+                             tpmif);
+    tpmif->status        = CONNECTED;
+    tpmif->shmem_ref     = shared_page;
+    tpmif->active        = 1;
+
+    return 0;
+}
+
+
+static void __tpmif_disconnect_complete(void *arg)
+{
+    evtchn_op_t op = { .cmd = EVTCHNOP_close };
+    tpmif_t *tpmif = (tpmif_t *) arg;
+
+    op.u.close.port = tpmif->evtchn;
+    op.u.close.dom  = DOMID_SELF;
+    HYPERVISOR_event_channel_op(&op);
+    op.u.close.port = tpmif->remote_evtchn;
+    op.u.close.dom  = tpmif->domid;
+    HYPERVISOR_event_channel_op(&op);
+
+    if (tpmif->evtchn)
+         unbind_evtchn_from_irqhandler(tpmif->evtchn, tpmif);
+
+    if (tpmif->tx) {
+        unmap_frontend_page(tpmif);
+        vfree(tpmif->tx);
+    }
+
+    free_tpmif(tpmif);
+}
+
+
+void tpmif_disconnect_complete(tpmif_t * tpmif)
+{
+    INIT_WORK(&tpmif->work, __tpmif_disconnect_complete, (void *)tpmif);
+    schedule_work(&tpmif->work);
+}
+
+
+void __init tpmif_interface_init(void)
+{
+    tpmif_cachep = kmem_cache_create("tpmif_cache", sizeof(tpmif_t),
+                                     0, 0, NULL, NULL);
+}
diff -r 84ab93e1ee05 -r dd668f7527cb 
linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c        Thu Sep  1 
10:16:14 2005
@@ -0,0 +1,1078 @@
+/******************************************************************************
+ * drivers/xen/tpmback/tpmback.c
+ *
+ * Copyright (c) 2005, IBM Corporation
+ *
+ * Author: Stefan Berger, stefanb@xxxxxxxxxx
+ * Grant table support: Mahadevan Gomathisankaran
+ *
+ * This code has been derived from drivers/xen/netback/netback.c
+ * Copyright (c) 2002-2004, K A Fraser
+ *
+ */
+
+#include "common.h"
+#include <asm-xen/evtchn.h>
+
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/miscdevice.h>
+#include <asm/uaccess.h>
+#include <asm-xen/xenbus.h>
+#include <asm-xen/xen-public/grant_table.h>
+
+
+struct data_exchange {
+       struct list_head pending_pak;
+       struct list_head current_pak;
+       unsigned int copied_so_far;
+       u8 has_opener;
+       rwlock_t pak_lock;  // protects all of the previous fields
+       wait_queue_head_t wait_queue;
+};
+
+struct packet {
+       struct list_head next;
+       unsigned int data_len;
+       u8 *data_buffer;
+       tpmif_t *tpmif;
+       u32 tpm_instance;
+       u8 req_tag;
+       u32 last_read;
+       u8 flags;
+       ctrl_msg_t ctrl_msg;
+       struct timer_list processing_timer;
+};
+
+enum {
+       PACKET_FLAG_DISCARD_RESPONSE = 1,
+       PACKET_FLAG_SEND_CONTROLMESSAGE = 2,
+};
+
+static struct data_exchange dataex;
+
+/* local function prototypes */
+static int vtpm_queue_packet(struct packet *pak);
+static int _packet_write(struct packet *pak,
+                         const char *data, size_t size,
+                         int userbuffer);
+static void processing_timeout(unsigned long ptr);
+static int  packet_read_shmem(struct packet *pak,
+                              tpmif_t *tpmif,
+                              u32 offset,
+                              char *buffer,
+                              int isuserbuffer,
+                              u32 left);
+
+
+#define MAX_PENDING_REQS TPMIF_TX_RING_SIZE
+
+static multicall_entry_t tx_mcl[MAX_PENDING_REQS];
+
+#define MIN(x,y)  (x) < (y) ? (x) : (y)
+
+/***************************************************************
+ Packet-related functions
+***************************************************************/
+
+static struct packet *
+packet_find_instance(struct list_head *head, u32 tpm_instance)
+{
+       struct packet *pak;
+       struct list_head *p;
+       /*
+        * traverse the list of packets and return the first
+        * one with the given instance number
+        */
+       list_for_each(p, head) {
+               pak = list_entry(p, struct packet, next);
+               if (pak->tpm_instance == tpm_instance) {
+                       return pak;
+               }
+       }
+       return NULL;
+}
+
+static struct packet *
+packet_find_packet(struct list_head *head, void *packet)
+{
+       struct packet *pak;
+       struct list_head *p;
+       /*
+        * traverse the list of packets and return the first
+        * one with the given instance number
+        */
+       list_for_each(p, head) {
+               pak = list_entry(p, struct packet, next);
+               if (pak == packet) {
+                       return pak;
+               }
+       }
+       return NULL;
+}
+
+static struct packet *
+packet_alloc(tpmif_t *tpmif, u32 size, u8 req_tag, u8 flags)
+{
+       struct packet *pak = NULL;
+       pak = kmalloc(sizeof(struct packet),
+                      GFP_KERNEL);
+       if (NULL != pak) {
+               memset(pak, 0x0, sizeof(*pak));
+               if (tpmif) {
+                       pak->tpmif = tpmif;
+                       pak->tpm_instance = tpmif->tpm_instance;
+               }
+               pak->data_len  = size;
+               pak->req_tag   = req_tag;
+               pak->last_read = 0;
+               pak->flags     = flags;
+
+               /*
+                * cannot do tpmif_get(tpmif); bad things happen
+                * on the last tpmif_put()
+                */
+               init_timer(&pak->processing_timer);
+               pak->processing_timer.function = processing_timeout;
+               pak->processing_timer.data = (unsigned long)pak;
+       }
+       return pak;
+}
+
+static void inline
+packet_reset(struct packet *pak)
+{
+       pak->last_read = 0;
+}
+
+static void inline
+packet_free(struct packet *pak)
+{
+       del_singleshot_timer_sync(&pak->processing_timer);
+       if (pak->data_buffer) {
+               kfree(pak->data_buffer);
+       }
+       /*
+        * cannot do tpmif_put(pak->tpmif); bad things happen
+        * on the last tpmif_put()
+        */
+       kfree(pak);
+}
+
+static int
+packet_set(struct packet *pak,
+           const unsigned char *buffer, u32 size)
+{
+       int rc = 0;
+       unsigned char *buf = kmalloc(size, GFP_KERNEL);
+       if (NULL != buf) {
+               pak->data_buffer = buf;
+               memcpy(buf, buffer, size);
+               pak->data_len = size;
+       } else {
+               rc = -ENOMEM;
+       }
+       return rc;
+}
+
+
+/*
+ * Write data to the shared memory and send it to the FE.
+ */
+static int
+packet_write(struct packet *pak,
+             const char *data, size_t size,
+             int userbuffer)
+{
+       int rc = 0;
+
+       DPRINTK("Supposed to send %d bytes to front-end!\n",
+               size);
+
+       if (0 != (pak->flags & PACKET_FLAG_SEND_CONTROLMESSAGE)) {
+#ifdef CONFIG_XEN_TPMDEV_CLOSE_IF_VTPM_FAILS
+               u32 res;
+               memcpy(&res, &data[2+4], sizeof(res));
+               if (res != 0) {
+                       /*
+                        * Will close down this device and have the
+                        * FE notified about closure.
+                        */
+               }
+#endif
+       }
+
+       if (0 != (pak->flags & PACKET_FLAG_DISCARD_RESPONSE)) {
+               /* Don't send a respone to this packet. Just acknowledge it. */
+               rc = size;
+       } else {
+               rc = _packet_write(pak, data, size, userbuffer);
+       }
+
+       return rc;
+}
+
+
+static int
+_packet_write(struct packet *pak,
+              const char *data, size_t size,
+              int userbuffer)
+{
+       /*
+        * Write into the shared memory pages directly
+        * and send it to the front end.
+        */
+       tpmif_t *tpmif = pak->tpmif;
+       u16 handle;
+       int rc = 0;
+       unsigned int i = 0;
+       unsigned int offset = 0;
+       multicall_entry_t *mcl;
+
+       if (tpmif == NULL)
+               return -EFAULT;
+
+       if (tpmif->status != CONNECTED) {
+               return size;
+       }
+
+       mcl = tx_mcl;
+       while (offset < size && i < TPMIF_TX_RING_SIZE) {
+               unsigned int tocopy;
+               struct gnttab_map_grant_ref map_op;
+               struct gnttab_unmap_grant_ref unmap_op;
+               tpmif_tx_request_t *tx;
+
+               tx = &tpmif->tx->ring[i].req;
+
+               if (0 == tx->addr) {
+                       DPRINTK("ERROR: Buffer for outgoing packet NULL?! 
i=%d\n", i);
+                       return 0;
+               }
+
+               map_op.host_addr  = MMAP_VADDR(tpmif, i);
+               map_op.flags      = GNTMAP_host_map;
+               map_op.ref        = tx->ref;
+               map_op.dom        = tpmif->domid;
+
+               if(unlikely(
+                   HYPERVISOR_grant_table_op(
+                       GNTTABOP_map_grant_ref,
+                       &map_op,
+                       1))) {
+                       BUG();
+               }
+
+               handle = map_op.handle;
+
+               if (map_op.handle < 0) {
+                       DPRINTK(" Grant table operation failure !\n");
+                       return 0;
+               }
+               phys_to_machine_mapping[__pa(MMAP_VADDR(tpmif,i)) >>
+                                       PAGE_SHIFT] =
+                       FOREIGN_FRAME(map_op.dev_bus_addr >> PAGE_SHIFT);
+
+               tocopy = size - offset;
+               if (tocopy > PAGE_SIZE) {
+                       tocopy = PAGE_SIZE;
+               }
+               if (userbuffer) {
+                       if (copy_from_user((void *)(MMAP_VADDR(tpmif,i) |
+                                                  (tx->addr & ~PAGE_MASK)),
+                                          (void __user *)&data[offset],
+                                          tocopy)) {
+                               tpmif_put(tpmif);
+                               return -EFAULT;
+                       }
+               } else {
+                       memcpy((void *)(MMAP_VADDR(tpmif,i) |
+                                       (tx->addr & ~PAGE_MASK)),
+                              &data[offset], tocopy);
+               }
+               tx->size = tocopy;
+
+               unmap_op.host_addr    = MMAP_VADDR(tpmif, i);
+               unmap_op.handle       = handle;
+               unmap_op.dev_bus_addr = 0;
+
+               if(unlikely(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref,
+                                                     &unmap_op,
+                                                     1))) {
+                       BUG();
+               }
+
+               offset += tocopy;
+               i++;
+       }
+
+       rc = offset;
+       DPRINTK("Notifying frontend via event channel %d\n",
+               tpmif->evtchn);
+       notify_via_evtchn(tpmif->evtchn);
+
+       return rc;
+}
+
+/*
+ * Read data from the shared memory and copy it directly into the
+ * provided buffer. Advance the read_last indicator which tells
+ * how many bytes have already been read.
+ */
+static int
+packet_read(struct packet *pak, size_t numbytes,
+            char *buffer, size_t buffersize,
+            int userbuffer)
+{
+       tpmif_t *tpmif = pak->tpmif;
+       /*
+        * I am supposed to read 'numbytes' of data from the
+        * buffer.
+        * The first 4 bytes that are read are the instance number in
+        * network byte order, after that comes the data from the
+        * shared memory buffer.
+        */
+       u32 to_copy;
+       u32 offset = 0;
+       u32 room_left = buffersize;
+       /*
+        * Ensure that we see the request when we copy it.
+        */
+       mb();
+
+       if (pak->last_read < 4) {
+               /*
+                * copy the instance number into the buffer
+                */
+               u32 instance_no = htonl(pak->tpm_instance);
+               u32 last_read = pak->last_read;
+               to_copy = MIN(4 - last_read, numbytes);
+
+               if (userbuffer) {
+                       if (copy_to_user(&buffer[0],
+                                        &(((u8 *)&instance_no)[last_read]),
+                                        to_copy)) {
+                               return -EFAULT;
+                       }
+               } else {
+                       memcpy(&buffer[0],
+                              &(((u8 *)&instance_no)[last_read]),
+                              to_copy);
+               }
+
+               pak->last_read += to_copy;
+               offset += to_copy;
+               room_left -= to_copy;
+       }
+
+       /*
+        * If the packet has a data buffer appended, read from it...
+        */
+
+       if (room_left > 0) {
+               if (pak->data_buffer) {
+                       u32 to_copy = MIN(pak->data_len - offset, room_left);
+                       u32 last_read = pak->last_read - 4;
+                       if (userbuffer) {
+                               if (copy_to_user(&buffer[offset],
+                                                &pak->data_buffer[last_read],
+                                                to_copy)) {
+                                       return -EFAULT;
+                               }
+                       } else {
+                               memcpy(&buffer[offset],
+                                      &pak->data_buffer[last_read],
+                                      to_copy);
+                       }
+                       pak->last_read += to_copy;
+                       offset += to_copy;
+               } else {
+                       offset = packet_read_shmem(pak,
+                                                  tpmif,
+                                                  offset,
+                                                  buffer,
+                                                  userbuffer,
+                                                  room_left);
+               }
+       }
+       return offset;
+}
+
+
+static int
+packet_read_shmem(struct packet *pak,
+                  tpmif_t *tpmif,
+                  u32 offset,
+                  char *buffer,
+                  int isuserbuffer,
+                  u32 room_left) {
+       u32 last_read = pak->last_read - 4;
+       u32 i = (last_read / PAGE_SIZE);
+       u32 pg_offset = last_read & (PAGE_SIZE - 1);
+       u32 to_copy;
+       u16 handle;
+
+       tpmif_tx_request_t *tx;
+       tx = &tpmif->tx->ring[0].req;
+       /*
+        * Start copying data at the page with index 'index'
+        * and within that page at offset 'offset'.
+        * Copy a maximum of 'room_left' bytes.
+        */
+       to_copy = MIN(PAGE_SIZE - pg_offset, room_left);
+       while (to_copy > 0) {
+               void *src;
+               struct gnttab_map_grant_ref map_op;
+               struct gnttab_unmap_grant_ref unmap_op;
+
+               tx = &tpmif->tx->ring[i].req;
+
+               map_op.host_addr = MMAP_VADDR(tpmif, i);
+               map_op.flags     = GNTMAP_host_map;
+               map_op.ref       = tx->ref;
+               map_op.dom       = tpmif->domid;
+
+               if(unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
+                                                     &map_op,
+                                                     1))) {
+                       BUG();
+               }
+
+               if (map_op.handle < 0) {
+                       DPRINTK(" Grant table operation failure !\n");
+                       return -EFAULT;
+               }
+
+               handle = map_op.handle;
+
+               if (to_copy > tx->size) {
+                       /*
+                        * This is the case when the user wants to read more
+                        * than what we have. So we just give him what we
+                        * have.
+                        */
+                       to_copy = MIN(tx->size, to_copy);
+               }
+
+               DPRINTK("Copying from mapped memory at %08lx\n",
+                       (unsigned long)(MMAP_VADDR(tpmif,i) |
+                       (tx->addr & ~PAGE_MASK)));
+
+               src = (void *)(MMAP_VADDR(tpmif,i) | ((tx->addr & ~PAGE_MASK) + 
pg_offset));
+               if (isuserbuffer) {
+                       if (copy_to_user(&buffer[offset],
+                                        src,
+                                        to_copy)) {
+                               return -EFAULT;
+                       }
+               } else {
+                       memcpy(&buffer[offset],
+                              src,
+                              to_copy);
+               }
+
+
+               DPRINTK("Data from TPM-FE of domain %d are %d %d %d %d\n",
+                       tpmif->domid, buffer[offset], 
buffer[offset+1],buffer[offset+2],buffer[offset+3]);
+
+               unmap_op.host_addr    = MMAP_VADDR(tpmif, i);
+               unmap_op.handle       = handle;
+               unmap_op.dev_bus_addr = 0;
+
+               if(unlikely(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref,
+                                                     &unmap_op,
+                                                     1))) {
+                       BUG();
+               }
+
+               offset += to_copy;
+               pg_offset = 0;
+               last_read += to_copy;
+               room_left -= to_copy;
+
+               to_copy = MIN(PAGE_SIZE, room_left);
+               i++;
+       } /* while (to_copy > 0) */
+       /*
+        * Adjust the last_read pointer
+        */
+       pak->last_read = last_read + 4;
+       return offset;
+}
+
+
+/* ============================================================
+ * The file layer for reading data from this device
+ * ============================================================
+ */
+static int
+vtpm_op_open(struct inode *inode, struct file *f)
+{
+       int rc = 0;
+       unsigned long flags;
+
+       write_lock_irqsave(&dataex.pak_lock, flags);
+       if (dataex.has_opener == 0) {
+               dataex.has_opener = 1;
+       } else {
+               rc = -EPERM;
+       }
+       write_unlock_irqrestore(&dataex.pak_lock, flags);
+       return rc;
+}
+
+static ssize_t
+vtpm_op_read(struct file *file,
+            char __user * data, size_t size, loff_t * offset)
+{
+       int ret_size = -ENODATA;
+       struct packet *pak = NULL;
+       unsigned long flags;
+
+       write_lock_irqsave(&dataex.pak_lock, flags);
+
+       if (list_empty(&dataex.pending_pak)) {
+               write_unlock_irqrestore(&dataex.pak_lock, flags);
+               wait_event_interruptible(dataex.wait_queue,
+                                        !list_empty(&dataex.pending_pak));
+               write_lock_irqsave(&dataex.pak_lock, flags);
+       }
+
+       if (!list_empty(&dataex.pending_pak)) {
+               unsigned int left;
+               pak = list_entry(dataex.pending_pak.next, struct packet, next);
+
+               left = pak->data_len - dataex.copied_so_far;
+
+               DPRINTK("size given by app: %d, available: %d\n", size, left);
+
+               ret_size = MIN(size,left);
+
+               ret_size = packet_read(pak, ret_size, data, size, 1);
+               if (ret_size < 0) {
+                       ret_size = -EFAULT;
+               } else {
+                       DPRINTK("Copied %d bytes to user buffer\n", ret_size);
+
+                       dataex.copied_so_far += ret_size;
+                       if (dataex.copied_so_far >= pak->data_len + 4) {
+                               DPRINTK("All data from this packet given to 
app.\n");
+                               /* All data given to app */
+
+                               
del_singleshot_timer_sync(&pak->processing_timer);
+                               list_del(&pak->next);
+                               list_add_tail(&pak->next, &dataex.current_pak);
+                               /*
+                                * The more fontends that are handled at the 
same time,
+                                * the more time we give the TPM to process the 
request.
+                                */
+                               mod_timer(&pak->processing_timer,
+                                         jiffies + (num_frontends * 10 * HZ));
+                               dataex.copied_so_far = 0;
+                       }
+               }
+       }
+       write_unlock_irqrestore(&dataex.pak_lock, flags);
+
+       DPRINTK("Returning result from read to app: %d\n", ret_size);
+
+       return ret_size;
+}
+
+/*
+ * Write operation - only works after a previous read operation!
+ */
+static ssize_t
+vtpm_op_write(struct file *file, const char __user * data, size_t size,
+             loff_t * offset)
+{
+       struct packet *pak;
+       int rc = 0;
+       unsigned int off = 4;
+       unsigned long flags;
+       u32 instance_no = 0;
+       u32 len_no = 0;
+
+       /*
+        * Minimum required packet size is:
+        * 4 bytes for instance number
+        * 2 bytes for tag
+        * 4 bytes for paramSize
+        * 4 bytes for the ordinal
+        * sum: 14 bytes
+        */
+       if ( size < off + 10 ) {
+               return -EFAULT;
+       }
+
+       if (copy_from_user(&instance_no,
+                          (void __user *)&data[0],
+                          4)) {
+               return -EFAULT;
+       }
+
+       if (copy_from_user(&len_no,
+                          (void __user *)&data[off+2],
+                          4) ||
+           (off + ntohl(len_no) != size)) {
+               return -EFAULT;
+       }
+
+       write_lock_irqsave(&dataex.pak_lock, flags);
+       pak = packet_find_instance(&dataex.current_pak, ntohl(instance_no));
+
+       if (pak == NULL) {
+               write_unlock_irqrestore(&dataex.pak_lock, flags);
+               printk(KERN_ALERT "No associated packet!\n");
+               return -EFAULT;
+       } else {
+               del_singleshot_timer_sync(&pak->processing_timer);
+               list_del(&pak->next);
+       }
+
+       write_unlock_irqrestore(&dataex.pak_lock, flags);
+
+       /*
+        * The first 'offset' bytes must be the instance number.
+        * I will just pull that from the packet.
+        */
+       size -= off;
+       data = &data[off];
+
+       rc = packet_write(pak, data, size, 1);
+
+       if (rc > 0) {
+               /* I neglected the first 4 bytes */
+               rc += off;
+       }
+       packet_free(pak);
+       return rc;
+}
+
+static int
+vtpm_op_release(struct inode *inode, struct file *file)
+{
+       unsigned long flags;
+       vtpm_release_packets(NULL, 1);
+       write_lock_irqsave(&dataex.pak_lock, flags);
+       dataex.has_opener = 0;
+       write_unlock_irqrestore(&dataex.pak_lock, flags);
+       return 0;
+}
+
+static unsigned int
+vtpm_op_poll(struct file *file, struct poll_table_struct *pst)
+{
+       return 0;
+}
+
+static struct file_operations vtpm_ops = {
+       .owner = THIS_MODULE,
+       .llseek = no_llseek,
+       .open = vtpm_op_open,
+       .read = vtpm_op_read,
+       .write = vtpm_op_write,
+       .release = vtpm_op_release,
+       .poll = vtpm_op_poll,
+};
+
+static struct miscdevice ibmvtpms_miscdevice = {
+       .minor = 225,
+       .name = "vtpm",
+       .fops = &vtpm_ops,
+};
+
+
+/***************************************************************
+ Virtual TPM functions and data stuctures
+***************************************************************/
+
+static u8 create_cmd[] = {
+        1,193,         /* 0: TPM_TAG_RQU_COMMAMD */
+        0,0,0,19,      /* 2: length */
+        0,0,0,0x1,     /* 6: VTPM_ORD_OPEN */
+        0,             /* 10: VTPM type */
+        0,0,0,0,       /* 11: domain id */
+        0,0,0,0                /* 15: instance id */
+};
+
+static u8 destroy_cmd[] = {
+        1,193,         /* 0: TPM_TAG_RQU_COMMAMD */
+        0,0,0,14,      /* 2: length */
+        0,0,0,0x2,     /* 6: VTPM_ORD_CLOSE */
+        0,0,0,0                /* 10: instance id */
+};
+
+int tpmif_vtpm_open(tpmif_t *tpmif, domid_t domid, u32 instance)
+{
+       int rc = 0;
+       struct packet *pak = packet_alloc(tpmif, sizeof(create_cmd), 
create_cmd[0],
+           PACKET_FLAG_DISCARD_RESPONSE|
+           PACKET_FLAG_SEND_CONTROLMESSAGE);
+       if (pak) {
+               u8 buf[sizeof(create_cmd)];
+               u32 domid_no = htonl((u32)domid);
+               u32 instance_no = htonl(instance);
+               memcpy(buf, create_cmd, sizeof(create_cmd));
+
+               memcpy(&buf[11], &domid_no, sizeof(u32));
+               memcpy(&buf[15], &instance_no, sizeof(u32));
+
+               /* copy the buffer into the packet */
+               rc = packet_set(pak, buf, sizeof(buf));
+
+               if (rc == 0) {
+                       pak->tpm_instance = 0;
+                       rc = vtpm_queue_packet(pak);
+               }
+               if (rc < 0) {
+                       /* could not be queued or built */
+                       packet_free(pak);
+               }
+       } else {
+               rc = -ENOMEM;
+       }
+       return rc;
+}
+
+int tpmif_vtpm_close(u32 instid)
+{
+       int rc = 0;
+       struct packet *pak;
+
+       pak = packet_alloc(NULL,
+                          sizeof(create_cmd),
+                          create_cmd[0],
+                          PACKET_FLAG_DISCARD_RESPONSE|
+                          PACKET_FLAG_SEND_CONTROLMESSAGE);
+       if (pak) {
+               u8 buf[sizeof(destroy_cmd)];
+               u32 instid_no = htonl(instid);
+               memcpy(buf, destroy_cmd, sizeof(destroy_cmd));
+               memcpy(&buf[10], &instid_no, sizeof(u32));
+
+               /* copy the buffer into the packet */
+               rc = packet_set(pak, buf, sizeof(buf));
+
+               if (rc == 0) {
+                       pak->tpm_instance = 0;
+                       rc = vtpm_queue_packet(pak);
+               }
+               if (rc < 0) {
+                       /* could not be queued or built */
+                       packet_free(pak);
+               }
+       } else {
+               rc = -ENOMEM;
+       }
+       return rc;
+}
+
+
+/***************************************************************
+ Utility functions
+***************************************************************/
+
+static int
+tpm_send_fail_message(struct packet *pak, u8 req_tag)
+{
+       int rc;
+       static const unsigned char tpm_error_message_fail[] = {
+               0x00, 0x00,
+               0x00, 0x00, 0x00, 0x0a,
+               0x00, 0x00, 0x00, 0x09 /* TPM_FAIL */
+       };
+       unsigned char buffer[sizeof(tpm_error_message_fail)];
+
+       memcpy(buffer, tpm_error_message_fail, sizeof(tpm_error_message_fail));
+       /*
+        * Insert the right response tag depending on the given tag
+        * All response tags are '+3' to the request tag.
+        */
+       buffer[1] = req_tag + 3;
+
+       /*
+        * Write the data to shared memory and notify the front-end
+        */
+       rc = packet_write(pak, buffer, sizeof(buffer), 0);
+
+       return rc;
+}
+
+
+static void
+_vtpm_release_packets(struct list_head *head, tpmif_t *tpmif,
+                      int send_msgs)
+{
+       struct packet *pak;
+       struct list_head *pos, *tmp;
+
+       list_for_each_safe(pos, tmp, head) {
+               pak = list_entry(pos, struct packet, next);
+               if (tpmif == NULL || pak->tpmif == tpmif) {
+                       int can_send = 0;
+                       del_singleshot_timer_sync(&pak->processing_timer);
+                       list_del(&pak->next);
+
+                       if (pak->tpmif && pak->tpmif->status == CONNECTED) {
+                               can_send = 1;
+                       }
+
+                       if (send_msgs && can_send) {
+                               tpm_send_fail_message(pak, pak->req_tag);
+                       }
+                       packet_free(pak);
+               }
+       }
+}
+
+
+int
+vtpm_release_packets(tpmif_t *tpmif, int send_msgs)
+{
+       unsigned long flags;
+
+       write_lock_irqsave(&dataex.pak_lock, flags);
+
+       _vtpm_release_packets(&dataex.pending_pak, tpmif, send_msgs);
+       _vtpm_release_packets(&dataex.current_pak, tpmif, send_msgs);
+
+       write_unlock_irqrestore(&dataex.pak_lock,
+                               flags);
+       return 0;
+}
+
+
+static int vtpm_queue_packet(struct packet *pak)
+{
+       int rc = 0;
+       if (dataex.has_opener) {
+               unsigned long flags;
+               write_lock_irqsave(&dataex.pak_lock, flags);
+               list_add_tail(&pak->next, &dataex.pending_pak);
+               /* give the TPM some time to pick up the request */
+               mod_timer(&pak->processing_timer, jiffies + (10 * HZ));
+               write_unlock_irqrestore(&dataex.pak_lock,
+                                       flags);
+
+               wake_up_interruptible(&dataex.wait_queue);
+       } else {
+               rc = -EFAULT;
+       }
+       return rc;
+}
+
+
+static int vtpm_receive(tpmif_t *tpmif, u32 size)
+{
+       int rc = 0;
+       unsigned char buffer[10];
+       __be32 *native_size;
+
+       struct packet *pak = packet_alloc(tpmif, size, buffer[4], 0);
+       if (NULL == pak) {
+               return -ENOMEM;
+       }
+       /*
+        * Read 10 bytes from the received buffer to test its
+        * content for validity.
+        */
+       if (sizeof(buffer) != packet_read(pak,
+                                         sizeof(buffer), buffer,
+                                         sizeof(buffer), 0)) {
+               goto failexit;
+       }
+       /*
+        * Reset the packet read pointer so we can read all its
+        * contents again.
+        */
+       packet_reset(pak);
+
+       native_size = (__force __be32 *)(&buffer[4+2]);
+       /*
+        * Verify that the size of the packet is correct
+        * as indicated and that there's actually someone reading packets.
+        * The minimum size of the packet is '10' for tag, size indicator
+        * and ordinal.
+        */
+       if (size < 10 ||
+           be32_to_cpu(*native_size) != size ||
+           0 == dataex.has_opener) {
+               rc = -EINVAL;
+               goto failexit;
+       } else {
+               if ((rc = vtpm_queue_packet(pak)) < 0) {
+                       goto failexit;
+               }
+       }
+       return 0;
+
+failexit:
+       if (pak) {
+               tpm_send_fail_message(pak, buffer[4+1]);
+               packet_free(pak);
+       }
+       return rc;
+}
+
+
+/*
+ * Timeout function that gets invoked when a packet has not been processed
+ * during the timeout period.
+ * The packet must be on a list when this function is invoked. This
+ * also means that once its taken off a list, the timer must be
+ * destroyed as well.
+ */
+static void processing_timeout(unsigned long ptr)
+{
+       struct packet *pak = (struct packet *)ptr;
+       unsigned long flags;
+       write_lock_irqsave(&dataex.pak_lock, flags);
+       /*
+        * The packet needs to be searched whether it
+        * is still on the list.
+        */
+       if (pak == packet_find_packet(&dataex.pending_pak, pak) ||
+           pak == packet_find_packet(&dataex.current_pak, pak) ) {
+               list_del(&pak->next);
+               tpm_send_fail_message(pak, pak->req_tag);
+               packet_free(pak);
+       }
+
+       write_unlock_irqrestore(&dataex.pak_lock, flags);
+}
+
+
+
+static void tpm_tx_action(unsigned long unused);
+static DECLARE_TASKLET(tpm_tx_tasklet, tpm_tx_action, 0);
+
+#define MAX_PENDING_REQS TPMIF_TX_RING_SIZE
+
+static struct list_head tpm_schedule_list;
+static spinlock_t tpm_schedule_list_lock;
+
+static inline void
+maybe_schedule_tx_action(void)
+{
+       smp_mb();
+       tasklet_schedule(&tpm_tx_tasklet);
+}
+
+static inline int
+__on_tpm_schedule_list(tpmif_t * tpmif)
+{
+       return tpmif->list.next != NULL;
+}
+
+static void
+remove_from_tpm_schedule_list(tpmif_t * tpmif)
+{
+       spin_lock_irq(&tpm_schedule_list_lock);
+       if (likely(__on_tpm_schedule_list(tpmif))) {
+               list_del(&tpmif->list);
+               tpmif->list.next = NULL;
+               tpmif_put(tpmif);
+       }
+       spin_unlock_irq(&tpm_schedule_list_lock);
+}
+
+static void
+add_to_tpm_schedule_list_tail(tpmif_t * tpmif)
+{
+       if (__on_tpm_schedule_list(tpmif))
+               return;
+
+       spin_lock_irq(&tpm_schedule_list_lock);
+       if (!__on_tpm_schedule_list(tpmif) && tpmif->active) {
+               list_add_tail(&tpmif->list, &tpm_schedule_list);
+               tpmif_get(tpmif);
+       }
+       spin_unlock_irq(&tpm_schedule_list_lock);
+}
+
+void
+tpmif_schedule_work(tpmif_t * tpmif)
+{
+       add_to_tpm_schedule_list_tail(tpmif);
+       maybe_schedule_tx_action();
+}
+
+void
+tpmif_deschedule_work(tpmif_t * tpmif)
+{
+       remove_from_tpm_schedule_list(tpmif);
+}
+
+
+static void
+tpm_tx_action(unsigned long unused)
+{
+       struct list_head *ent;
+       tpmif_t *tpmif;
+       tpmif_tx_request_t *tx;
+
+       DPRINTK("%s: Getting data from front-end(s)!\n", __FUNCTION__);
+
+       while (!list_empty(&tpm_schedule_list)) {
+               /* Get a tpmif from the list with work to do. */
+               ent = tpm_schedule_list.next;
+               tpmif = list_entry(ent, tpmif_t, list);
+               tpmif_get(tpmif);
+               remove_from_tpm_schedule_list(tpmif);
+               /*
+                * Ensure that we see the request when we read from it.
+                */
+               mb();
+
+               tx = &tpmif->tx->ring[0].req;
+
+               /* pass it up */
+               vtpm_receive(tpmif, tx->size);
+
+               tpmif_put(tpmif);
+       }
+}
+
+irqreturn_t
+tpmif_be_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+       tpmif_t *tpmif = dev_id;
+       add_to_tpm_schedule_list_tail(tpmif);
+       maybe_schedule_tx_action();
+       return IRQ_HANDLED;
+}
+
+static int __init
+tpmback_init(void)
+{
+       int rc;
+       if (!(xen_start_info.flags & SIF_TPM_BE_DOMAIN) &&
+           !(xen_start_info.flags & SIF_INITDOMAIN)) {
+               printk(KERN_ALERT "Neither TPM-BE Domain nor INIT domain!\n");
+               return 0;
+       }
+
+       if ((rc = misc_register(&ibmvtpms_miscdevice)) != 0) {
+               printk(KERN_ALERT "Could not register misc device for TPM 
BE.\n");
+               return rc;
+       }
+
+       INIT_LIST_HEAD(&dataex.pending_pak);
+       INIT_LIST_HEAD(&dataex.current_pak);
+       dataex.has_opener = 0;
+       rwlock_init(&dataex.pak_lock);
+       init_waitqueue_head(&dataex.wait_queue);
+
+       spin_lock_init(&tpm_schedule_list_lock);
+       INIT_LIST_HEAD(&tpm_schedule_list);
+
+       tpmif_interface_init();
+       tpmif_xenbus_init();
+
+       printk(KERN_ALERT "Successfully initialized TPM backend driver.\n");
+
+       return 0;
+}
+
+__initcall(tpmback_init);
diff -r 84ab93e1ee05 -r dd668f7527cb 
linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Thu Sep  1 10:16:14 2005
@@ -0,0 +1,271 @@
+/*  Xenbus code for tpmif backend
+    Copyright (C) 2005 Rusty Russell <rusty@xxxxxxxxxxxxxxx>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+#include <stdarg.h>
+#include <linux/module.h>
+#include <asm-xen/xenbus.h>
+#include "common.h"
+
+struct backend_info
+{
+       struct xenbus_device *dev;
+
+       /* our communications channel */
+       tpmif_t *tpmif;
+
+       long int frontend_id;
+       long int instance; // instance of TPM
+
+       /* watch front end for changes */
+       struct xenbus_watch backend_watch;
+
+       struct xenbus_watch watch;
+       char * frontpath;
+};
+
+static int tpmback_remove(struct xenbus_device *dev)
+{
+       struct backend_info *be = dev->data;
+
+       if (be->watch.node) {
+               unregister_xenbus_watch(&be->watch);
+       }
+       unregister_xenbus_watch(&be->backend_watch);
+
+       tpmif_vtpm_close(be->instance);
+
+       if (be->tpmif) {
+               tpmif_put(be->tpmif);
+       }
+
+       if (be->frontpath)
+               kfree(be->frontpath);
+       kfree(be);
+       return 0;
+}
+
+
+static void frontend_changed(struct xenbus_watch *watch, const char *node)
+{
+       unsigned long ringref;
+       unsigned int evtchn;
+       unsigned long ready = 1;
+       int err;
+       struct backend_info *be
+               = container_of(watch, struct backend_info, watch);
+
+       /* If other end is gone, delete ourself. */
+       if (node && !xenbus_exists(be->frontpath, "")) {
+               xenbus_rm(be->dev->nodename, "");
+               device_unregister(&be->dev->dev);
+               return;
+       }
+
+       if (be->tpmif == NULL || be->tpmif->status == CONNECTED)
+               return;
+
+       err = xenbus_gather(be->frontpath,
+                           "ring-ref", "%lu", &ringref,
+                           "event-channel", "%u", &evtchn, NULL);
+       if (err) {
+               xenbus_dev_error(be->dev, err,
+                                "reading %s/grant-id and event-channel",
+                                be->frontpath);
+               return;
+       }
+
+
+       /*
+        * Tell the front-end that we are ready to go -
+        * unless something bad happens
+        */
+       err = xenbus_transaction_start(be->dev->nodename);
+       if (err) {
+               xenbus_dev_error(be->dev, err, "starting transaction");
+               return;
+       }
+
+       err = xenbus_printf(be->dev->nodename,
+                           "ready", "%lu", ready);
+       if (err) {
+               xenbus_dev_error(be->dev, err, "writing 'ready'");
+               goto abort;
+       }
+
+       err = tpmif_map(be->tpmif, ringref, evtchn);
+       if (err) {
+               xenbus_dev_error(be->dev, err,
+                                "mapping shared-frame %lu port %u",
+                                ringref, evtchn);
+               goto abort;
+       }
+
+       err = tpmif_vtpm_open(be->tpmif,
+                             be->frontend_id,
+                             be->instance);
+       if (err) {
+               xenbus_dev_error(be->dev, err,
+                                "queueing vtpm open packet");
+               /*
+                * Should close down this device and notify FE
+                * about closure.
+                */
+               goto abort;
+       }
+
+       xenbus_transaction_end(0);
+       xenbus_dev_ok(be->dev);
+       return;
+abort:
+       xenbus_transaction_end(1);
+}
+
+
+static void backend_changed(struct xenbus_watch *watch, const char *node)
+{
+       int err;
+       long int instance;
+       struct backend_info *be
+               = container_of(watch, struct backend_info, backend_watch);
+       struct xenbus_device *dev = be->dev;
+
+       err = xenbus_scanf(dev->nodename, "instance", "%li", &instance);
+       if (XENBUS_EXIST_ERR(err))
+               return;
+       if (err < 0) {
+               xenbus_dev_error(dev, err, "reading 'instance' variable");
+               return;
+       }
+
+       if (be->instance != -1 && be->instance != instance) {
+               printk(KERN_WARNING
+                      "cannot change the instance\n");
+               return;
+       }
+       be->instance = instance;
+
+       if (be->tpmif == NULL) {
+               be->tpmif = tpmif_find(be->frontend_id,
+                                      instance);
+               if (IS_ERR(be->tpmif)) {
+                       err = PTR_ERR(be->tpmif);
+                       be->tpmif = NULL;
+                       xenbus_dev_error(dev, err, "creating interface");
+                       return;
+               }
+
+               /* Pass in NULL node to skip exist test. */
+               frontend_changed(&be->watch, be->frontpath);
+       }
+}
+
+
+static int tpmback_probe(struct xenbus_device *dev,
+                        const struct xenbus_device_id *id)
+{
+       struct backend_info *be;
+       char *frontend;
+       int err;
+
+       be = kmalloc(sizeof(*be), GFP_KERNEL);
+       if (!be) {
+               xenbus_dev_error(dev, -ENOMEM, "allocating backend structure");
+               err = -ENOMEM;
+       }
+
+       memset(be, 0, sizeof(*be));
+
+       frontend = NULL;
+       err = xenbus_gather(dev->nodename,
+                           "frontend-id", "%li", &be->frontend_id,
+                           "frontend", NULL, &frontend,
+                           NULL);
+       if (XENBUS_EXIST_ERR(err))
+               goto free_be;
+       if (err < 0) {
+               xenbus_dev_error(dev, err,
+                                "reading %s/frontend or frontend-id",
+                                dev->nodename);
+               goto free_be;
+       }
+       if (strlen(frontend) == 0 || !xenbus_exists(frontend, "")) {
+               /* If we can't get a frontend path and a frontend-id,
+                * then our bus-id is no longer valid and we need to
+                * destroy the backend device.
+                */
+               err = -ENOENT;
+               goto free_be;
+       }
+
+       be->dev = dev;
+       be->backend_watch.node     = dev->nodename;
+       be->backend_watch.callback = backend_changed;
+       be->instance = -1;
+       err = register_xenbus_watch(&be->backend_watch);
+       if (err) {
+               be->backend_watch.node = NULL;
+               xenbus_dev_error(dev, err, "adding backend watch on %s",
+                                dev->nodename);
+               goto free_be;
+       }
+
+       be->frontpath = frontend;
+       be->watch.node = be->frontpath;
+       be->watch.callback = frontend_changed;
+       err = register_xenbus_watch(&be->watch);
+       if (err) {
+               be->watch.node = NULL;
+               xenbus_dev_error(dev, err,
+                                "adding frontend watch on %s",
+                                be->frontpath);
+               goto free_be;
+       }
+
+       dev->data = be;
+
+       backend_changed(&be->backend_watch, dev->nodename);
+       return err;
+
+free_be:
+       if (be->backend_watch.node)
+               unregister_xenbus_watch(&be->backend_watch);
+       if (frontend)
+               kfree(frontend);
+       kfree(be);
+       return err;
+}
+
+
+static struct xenbus_device_id tpmback_ids[] = {
+       { "vtpm" },
+       { "" }
+};
+
+
+static struct xenbus_driver tpmback = {
+       .name = "vtpm",
+       .owner = THIS_MODULE,
+       .ids = tpmback_ids,
+       .probe = tpmback_probe,
+       .remove = tpmback_remove,
+};
+
+
+void tpmif_xenbus_init(void)
+{
+       xenbus_register_backend(&tpmback);
+}
diff -r 84ab93e1ee05 -r dd668f7527cb 
linux-2.6-xen-sparse/drivers/xen/tpmfront/Makefile
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/Makefile        Thu Sep  1 
10:16:14 2005
@@ -0,0 +1,2 @@
+
+obj-$(CONFIG_XEN_TPMDEV_FRONTEND)      += tpmfront.o
diff -r 84ab93e1ee05 -r dd668f7527cb 
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Thu Sep  1 
10:16:14 2005
@@ -0,0 +1,739 @@
+/*
+ * Copyright (c) 2005, IBM Corporation
+ *
+ * Author: Stefan Berger, stefanb@xxxxxxxxxx
+ * Grant table support: Mahadevan Gomathisankaran
+ *
+ * This code has been derived from drivers/xen/netfront/netfront.c
+ *
+ * Copyright (c) 2002-2004, K A Fraser
+ *
+ * This file may be distributed separately from the Linux kernel, or
+ * incorporated into other software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/tpmfe.h>
+
+#include <asm/semaphore.h>
+#include <asm/io.h>
+#include <asm-xen/evtchn.h>
+#include <asm-xen/ctrl_if.h>
+#include <asm-xen/xen-public/io/tpmif.h>
+#include <asm/uaccess.h>
+#include <asm-xen/xenbus.h>
+#include <asm-xen/xen-public/io/domain_controller.h>
+#include <asm-xen/xen-public/grant_table.h>
+
+#include "tpmfront.h"
+
+#undef DEBUG
+
+#if 1
+#define ASSERT(_p) \
+    if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
+        __LINE__, __FILE__); *(int*)0=0; }
+#else
+#define ASSERT(_p)
+#endif
+
+/* locally visible variables */
+static grant_ref_t gref_head;
+static struct tpm_private my_private;
+
+/* local function prototypes */
+static irqreturn_t tpmif_int(int irq,
+                             void *tpm_priv,
+                             struct pt_regs *ptregs);
+static void tpmif_rx_action(unsigned long unused);
+static void tpmif_connect(u16 evtchn, domid_t domid);
+static DECLARE_TASKLET(tpmif_rx_tasklet, tpmif_rx_action, 0);
+static int tpm_allocate_buffers(struct tpm_private *tp);
+static void tpmif_set_connected_state(struct tpm_private *tp, int newstate);
+static int tpm_xmit(struct tpm_private *tp,
+                    const u8 * buf, size_t count, int userbuffer,
+                    void *remember);
+
+#if DEBUG
+#define DPRINTK(fmt, args...) \
+    printk(KERN_ALERT "xen_tpm_fr (%s:%d) " fmt, __FUNCTION__, __LINE__, 
##args)
+#else
+#define DPRINTK(fmt, args...) ((void)0)
+#endif
+#define IPRINTK(fmt, args...) \
+    printk(KERN_INFO "xen_tpm_fr: " fmt, ##args)
+#define WPRINTK(fmt, args...) \
+    printk(KERN_WARNING "xen_tpm_fr: " fmt, ##args)
+
+
+static inline int
+tx_buffer_copy(struct tx_buffer *txb, const u8 * src, int len,
+               int isuserbuffer)
+{
+       int copied = len;
+
+       if (len > txb->size) {
+               copied = txb->size;
+       }
+       if (isuserbuffer) {
+               if (copy_from_user(txb->data,
+                                  src,
+                                  copied)) {
+                       return -EFAULT;
+               }
+       } else {
+               memcpy(txb->data, src, copied);
+       }
+       txb->len = len;
+       return copied;
+}
+
+static inline struct tx_buffer *tx_buffer_alloc(void)
+{
+       struct tx_buffer *txb = kmalloc(sizeof (struct tx_buffer),
+                                       GFP_KERNEL);
+
+       if (txb) {
+               txb->len = 0;
+               txb->size = PAGE_SIZE;
+               txb->data = (unsigned char *)__get_free_page(GFP_KERNEL);
+               if (txb->data == NULL) {
+                       kfree(txb);
+                       txb = NULL;
+               }
+       }
+       return txb;
+}
+
+
+/**************************************************************
+
+ The interface to let the tpm plugin register its callback
+ function and send data to another partition using this module
+
+**************************************************************/
+
+static DECLARE_MUTEX(upperlayer_lock);
+static DECLARE_MUTEX(suspend_lock);
+static struct tpmfe_device *upperlayer_tpmfe;
+
+/*
+ * Send data via this module by calling this function
+ */
+int tpm_fe_send(const u8 * buf, size_t count, void *ptr)
+{
+       int sent = 0;
+       struct tpm_private *tp = &my_private;
+
+       down(&suspend_lock);
+       sent = tpm_xmit(tp, buf, count, 0, ptr);
+       up(&suspend_lock);
+
+       return sent;
+}
+EXPORT_SYMBOL(tpm_fe_send);
+
+/*
+ * Register a callback for receiving data from this module
+ */
+int tpm_fe_register_receiver(struct tpmfe_device *tpmfe_dev)
+{
+       int rc = 0;
+
+       down(&upperlayer_lock);
+       if (NULL == upperlayer_tpmfe) {
+               upperlayer_tpmfe = tpmfe_dev;
+               tpmfe_dev->max_tx_size = TPMIF_TX_RING_SIZE * PAGE_SIZE;
+       } else {
+               rc = -EBUSY;
+       }
+       up(&upperlayer_lock);
+       return rc;
+}
+EXPORT_SYMBOL(tpm_fe_register_receiver);
+
+/*
+ * Unregister the callback for receiving data from this module
+ */
+void tpm_fe_unregister_receiver(void)
+{
+       down(&upperlayer_lock);
+       upperlayer_tpmfe = NULL;
+       up(&upperlayer_lock);
+}
+EXPORT_SYMBOL(tpm_fe_unregister_receiver);
+
+/*
+ * Call this function to send data to the upper layer's
+ * registered receiver function.
+ */
+static int tpm_fe_send_upperlayer(const u8 * buf, size_t count,
+                                  const void *ptr)
+{
+       int rc;
+
+       down(&upperlayer_lock);
+
+       if (upperlayer_tpmfe && upperlayer_tpmfe->receive) {
+               rc = upperlayer_tpmfe->receive(buf, count, ptr);
+       } else {
+               rc = 0;
+       }
+
+       up(&upperlayer_lock);
+       return rc;
+}
+
+/**************************************************************
+ XENBUS support code
+**************************************************************/
+
+static void watch_for_status(struct xenbus_watch *watch, const char *node)
+{
+       struct tpmfront_info *info;
+       int err;
+       unsigned long ready;
+       struct tpm_private *tp = &my_private;
+
+       info = container_of(watch, struct tpmfront_info, watch);
+       node += strlen(watch->node);
+
+       if (tp->connected)
+               return;
+
+       err = xenbus_gather(watch->node,
+                           "ready", "%lu", &ready,
+                           NULL);
+       if (err) {
+               xenbus_dev_error(info->dev, err, "reading 'ready' field");
+               return;
+       }
+
+       tpmif_set_connected_state(tp, 1);
+
+       xenbus_dev_ok(info->dev);
+}
+
+
+static int setup_tpmring(struct xenbus_device *dev,
+                         struct tpmfront_info * info,
+                         domid_t backend_id)
+{
+       tpmif_tx_interface_t *sring;
+       struct tpm_private *tp = &my_private;
+
+       evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
+       int err;
+
+       sring = (void *)__get_free_page(GFP_KERNEL);
+       if (!sring) {
+               xenbus_dev_error(dev, -ENOMEM, "allocating shared ring");
+               return -ENOMEM;
+       }
+       tp->tx = sring;
+
+       tpm_allocate_buffers(tp);
+
+       info->ring_ref = gnttab_claim_grant_reference(&gref_head);
+       ASSERT(info->ring_ref != -ENOSPC);
+       gnttab_grant_foreign_access_ref(info->ring_ref,
+                                       backend_id,
+                                       (virt_to_machine(tp->tx) >> PAGE_SHIFT),
+                                       0);
+
+       op.u.alloc_unbound.dom = backend_id;
+       err = HYPERVISOR_event_channel_op(&op);
+       if (err) {
+               free_page((unsigned long)sring);
+               tp->tx = 0;
+               xenbus_dev_error(dev, err, "allocating event channel");
+               return err;
+       }
+       tpmif_connect(op.u.alloc_unbound.port, backend_id);
+       return 0;
+}
+
+
+static void destroy_tpmring(struct tpmfront_info *info, struct tpm_private *tp)
+{
+       tpmif_set_connected_state(tp,0);
+
+       if ( tp->tx != NULL ) {
+               free_page((unsigned long)tp->tx);
+               tp->tx = NULL;
+       }
+       unbind_evtchn_from_irqhandler(tp->evtchn, NULL);
+       tp->evtchn = 0;
+}
+
+
+static int talk_to_backend(struct xenbus_device *dev,
+                           struct tpmfront_info *info)
+{
+       char *backend;
+       const char *message;
+       int err;
+       int backend_id;
+
+       backend = NULL;
+       err = xenbus_gather(dev->nodename,
+                           "backend-id", "%i", &backend_id,
+                           "backend", NULL, &backend,
+                           NULL);
+       if (XENBUS_EXIST_ERR(err))
+               goto out;
+       if (backend && strlen(backend) == 0) {
+               err = -ENOENT;
+               goto out;
+       }
+       if (err < 0) {
+               xenbus_dev_error(dev, err, "reading %s/backend or backend-id",
+                                dev->nodename);
+               goto out;
+       }
+
+       info->backend_id      = backend_id;
+       my_private.backend_id = backend_id;
+
+       err = setup_tpmring(dev, info, backend_id);
+       if (err) {
+               xenbus_dev_error(dev, err, "setting up ring");
+               goto out;
+       }
+
+       err = xenbus_transaction_start(dev->nodename);
+       if (err) {
+               xenbus_dev_error(dev, err, "starting transaction");
+               goto destroy_tpmring;
+       }
+
+       err = xenbus_printf(dev->nodename,
+                           "ring-ref","%u", info->ring_ref);
+       if (err) {
+               message = "writing ring-ref";
+               goto abort_transaction;
+       }
+
+       err = xenbus_printf(dev->nodename,
+                           "event-channel", "%u", my_private.evtchn);
+       if (err) {
+               message = "writing event-channel";
+               goto abort_transaction;
+       }
+
+       info->backend = backend;
+       backend = NULL;
+
+       info->watch.node = info->backend;
+       info->watch.callback = watch_for_status;
+       err = register_xenbus_watch(&info->watch);
+       if (err) {
+               message = "registering watch on backend";
+               goto abort_transaction;
+       }
+
+       err = xenbus_transaction_end(0);
+       if (err) {
+               xenbus_dev_error(dev, err, "completing transaction");
+               goto destroy_tpmring;
+       }
+
+out:
+       if (backend)
+               kfree(backend);
+       return err;
+
+abort_transaction:
+       xenbus_transaction_end(1);
+       /* Have to do this *outside* transaction.  */
+       xenbus_dev_error(dev, err, "%s", message);
+destroy_tpmring:
+       destroy_tpmring(info, &my_private);
+       goto out;
+}
+
+
+static int tpmfront_probe(struct xenbus_device *dev,
+                          const struct xenbus_device_id *id)
+{
+       int err;
+       struct tpmfront_info *info;
+       int handle;
+
+       err = xenbus_scanf(dev->nodename,
+                          "handle", "%i", &handle);
+       if (XENBUS_EXIST_ERR(err))
+               return err;
+
+       if (err < 0) {
+               xenbus_dev_error(dev,err,"reading virtual-device");
+               return err;
+       }
+
+       info = kmalloc(sizeof(*info), GFP_KERNEL);
+       if (!info) {
+               xenbus_dev_error(dev,err,"allocating info structure");
+               return err;
+       }
+       memset(info, 0x0, sizeof(*info));
+
+       info->dev = dev;
+       info->handle = handle;
+       dev->data = info;
+
+       err = talk_to_backend(dev, info);
+       if (err) {
+               kfree(info);
+               dev->data = NULL;
+               return err;
+       }
+
+       watch_for_status(&info->watch, info->watch.node);
+       return 0;
+}
+
+static int tpmfront_remove(struct xenbus_device *dev)
+{
+       struct tpmfront_info *info = dev->data;
+       if (info->backend)
+               unregister_xenbus_watch(&info->watch);
+
+       destroy_tpmring(info, &my_private);
+
+       kfree(info->backend);
+       kfree(info);
+
+       return 0;
+}
+
+static int tpmfront_suspend(struct xenbus_device *dev)
+{
+       struct tpmfront_info *info = dev->data;
+       struct tpm_private *tp = &my_private;
+
+       /* lock so no app can send */
+       down(&suspend_lock);
+
+       while (atomic_read(&tp->tx_busy)) {
+               printk("---- TPMIF: Outstanding request.\n");
+#if 0
+               /*
+                * Would like to wait until the outstanding request
+                * has come back, but this does not work properly, yet.
+                */
+               interruptible_sleep_on_timeout(&tp->wait_q,
+                                              100);
+#else
+               break;
+#endif
+       }
+
+       unregister_xenbus_watch(&info->watch);
+
+       kfree(info->backend);
+       info->backend = NULL;
+
+       destroy_tpmring(info, tp);
+
+       return 0;
+}
+
+static int tpmif_recover(void)
+{
+       return 0;
+}
+
+static int tpmfront_resume(struct xenbus_device *dev)
+{
+       struct tpmfront_info *info = dev->data;
+       int err;
+
+       err = talk_to_backend(dev, info);
+       if (!err) {
+               tpmif_recover();
+       }
+
+       /* unlock so apps can resume */
+       up(&suspend_lock);
+
+       return err;
+}
+
+static void tpmif_connect(u16 evtchn, domid_t domid)
+{
+       int err = 0;
+       struct tpm_private *tp = &my_private;
+
+       tp->evtchn = evtchn;
+       tp->backend_id  = domid;
+
+       err = bind_evtchn_to_irqhandler(
+               tp->evtchn,
+               tpmif_int, SA_SAMPLE_RANDOM, "tpmif", tp);
+       if ( err != 0 ) {
+               WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
+               return;
+       }
+}
+
+static struct xenbus_device_id tpmfront_ids[] = {
+       { "vtpm" },
+       { "" }
+};
+
+static struct xenbus_driver tpmfront = {
+       .name = "vtpm",
+       .owner = THIS_MODULE,
+       .ids = tpmfront_ids,
+       .probe = tpmfront_probe,
+       .remove =  tpmfront_remove,
+       .resume = tpmfront_resume,
+       .suspend = tpmfront_suspend,
+};
+
+static void __init init_tpm_xenbus(void)
+{
+       xenbus_register_device(&tpmfront);
+}
+
+
+static int
+tpm_allocate_buffers(struct tpm_private *tp)
+{
+       unsigned int i;
+
+       i = 0;
+       while (i < TPMIF_TX_RING_SIZE) {
+               tp->tx_buffers[i] = tx_buffer_alloc();
+               i++;
+       }
+
+       return 1;
+}
+
+static void
+tpmif_rx_action(unsigned long unused)
+{
+       struct tpm_private *tp = &my_private;
+
+       int i = 0;
+       unsigned int received;
+       unsigned int offset = 0;
+       u8 *buffer;
+       tpmif_tx_request_t *tx;
+       tx = &tp->tx->ring[i].req;
+
+       received = tx->size;
+
+       buffer = kmalloc(received, GFP_KERNEL);
+       if (NULL == buffer) {
+               goto exit;
+       }
+
+       i = 0;
+       while (i < TPMIF_TX_RING_SIZE &&
+              offset < received) {
+               struct tx_buffer *txb = tp->tx_buffers[i];
+               tpmif_tx_request_t *tx;
+               unsigned int tocopy;
+
+               tx = &tp->tx->ring[i].req;
+               tocopy = tx->size;
+               if (tocopy > PAGE_SIZE) {
+                       tocopy = PAGE_SIZE;
+               }
+
+               memcpy(&buffer[offset], txb->data, tocopy);
+
+               gnttab_release_grant_reference(&gref_head, tx->ref);
+
+               offset += tocopy;
+               i++;
+       }
+
+       tpm_fe_send_upperlayer(buffer, received, tp->tx_remember);
+       kfree(buffer);
+
+exit:
+       atomic_set(&tp->tx_busy, 0);
+       wake_up_interruptible(&tp->wait_q);
+}
+
+
+static irqreturn_t
+tpmif_int(int irq, void *tpm_priv, struct pt_regs *ptregs)
+{
+       struct tpm_private *tp = tpm_priv;
+       unsigned long flags;
+
+       spin_lock_irqsave(&tp->tx_lock, flags);
+       tasklet_schedule(&tpmif_rx_tasklet);
+       spin_unlock_irqrestore(&tp->tx_lock, flags);
+
+       return IRQ_HANDLED;
+}
+
+
+static int
+tpm_xmit(struct tpm_private *tp,
+         const u8 * buf, size_t count, int isuserbuffer,
+         void *remember)
+{
+       tpmif_tx_request_t *tx;
+       TPMIF_RING_IDX i;
+       unsigned int offset = 0;
+
+       spin_lock_irq(&tp->tx_lock);
+
+       if (unlikely(atomic_read(&tp->tx_busy))) {
+               printk("There's an outstanding request/response on the way!\n");
+               spin_unlock_irq(&tp->tx_lock);
+               return -EBUSY;
+       }
+
+       if (tp->connected != 1) {
+               spin_unlock_irq(&tp->tx_lock);
+               return -EIO;
+       }
+
+       i = 0;
+       while (count > 0 && i < TPMIF_TX_RING_SIZE) {
+               struct tx_buffer *txb = tp->tx_buffers[i];
+               int copied;
+
+               if (NULL == txb) {
+                       DPRINTK("txb (i=%d) is NULL. buffers initilized?\n", i);
+                       DPRINTK("Not transmittin anything!\n");
+                       spin_unlock_irq(&tp->tx_lock);
+                       return -EFAULT;
+               }
+               copied = tx_buffer_copy(txb, &buf[offset], count,
+                                       isuserbuffer);
+               if (copied < 0) {
+                       /* An error occurred */
+                       return copied;
+               }
+               count -= copied;
+               offset += copied;
+
+               tx = &tp->tx->ring[i].req;
+
+               tx->id = i;
+               tx->addr = virt_to_machine(txb->data);
+               tx->size = txb->len;
+
+               DPRINTK("First 4 characters sent by TPM-FE are 0x%02x 0x%02x 
0x%02x 0x%02x\n",
+                       txb->data[0],txb->data[1],txb->data[2],txb->data[3]);
+
+               /* get the granttable reference for this page */
+               tx->ref = gnttab_claim_grant_reference( &gref_head );
+
+               if(-ENOSPC == tx->ref ) {
+                       DPRINTK(" Grant table claim reference failed in func:%s 
line:%d file:%s\n", __FUNCTION__, __LINE__, __FILE__);
+                       return -ENOSPC;
+               }
+               gnttab_grant_foreign_access_ref( tx->ref,
+                                                tp->backend_id,
+                                                (tx->addr >> PAGE_SHIFT),
+                                                0 /*RW*/);
+               i++;
+               wmb();
+       }
+
+       atomic_set(&tp->tx_busy, 1);
+       tp->tx_remember = remember;
+       mb();
+
+       DPRINTK("Notifying backend via event channel %d\n",
+               tp->evtchn);
+
+       notify_via_evtchn(tp->evtchn);
+
+       spin_unlock_irq(&tp->tx_lock);
+       return offset;
+}
+
+
+static void tpmif_notify_upperlayer(struct tpm_private *tp)
+{
+       /*
+        * Notify upper layer about the state of the connection
+        * to the BE.
+        */
+       down(&upperlayer_lock);
+
+       if (upperlayer_tpmfe != NULL) {
+               switch (tp->connected) {
+                       case 1:
+                               
upperlayer_tpmfe->status(TPMFE_STATUS_CONNECTED);
+                       break;
+
+                       default:
+                               upperlayer_tpmfe->status(0);
+                       break;
+               }
+       }
+       up(&upperlayer_lock);
+}
+
+
+static void tpmif_set_connected_state(struct tpm_private *tp, int newstate)
+{
+       if (newstate != tp->connected) {
+               tp->connected = newstate;
+               tpmif_notify_upperlayer(tp);
+       }
+}
+
+
+/* =================================================================
+ * Initialization function.
+ * =================================================================
+ */
+
+static int __init
+tpmif_init(void)
+{
+       IPRINTK("Initialising the vTPM driver.\n");
+       if ( gnttab_alloc_grant_references ( TPMIF_TX_RING_SIZE,
+                                            &gref_head ) < 0) {
+               return -EFAULT;
+       }
+       /*
+        * Only don't send the driver status when we are in the
+        * INIT domain.
+        */
+       spin_lock_init(&my_private.tx_lock);
+       init_waitqueue_head(&my_private.wait_q);
+
+       init_tpm_xenbus();
+
+       return 0;
+}
+
+__initcall(tpmif_init);
diff -r 84ab93e1ee05 -r dd668f7527cb 
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h      Thu Sep  1 
10:16:14 2005
@@ -0,0 +1,38 @@
+#ifndef TPM_FRONT_H
+#define TPM_FRONT_H
+
+
+struct tpm_private {
+       tpmif_tx_interface_t *tx;
+       unsigned int evtchn;
+       int connected;
+
+       spinlock_t tx_lock;
+
+       struct tx_buffer *tx_buffers[TPMIF_TX_RING_SIZE];
+
+       atomic_t tx_busy;
+       void *tx_remember;
+       domid_t backend_id;
+       wait_queue_head_t wait_q;
+};
+
+
+struct tpmfront_info
+{
+       struct xenbus_watch watch;
+       int handle;
+       struct xenbus_device *dev;
+       char *backend;
+       int ring_ref;
+       domid_t backend_id;
+};
+
+
+struct tx_buffer {
+       unsigned int size;      // available space in data
+       unsigned int len;       // used space in data
+       unsigned char *data;    // pointer to a page
+};
+
+#endif
diff -r 84ab93e1ee05 -r dd668f7527cb linux-2.6-xen-sparse/include/linux/tpmfe.h
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/linux-2.6-xen-sparse/include/linux/tpmfe.h        Thu Sep  1 10:16:14 2005
@@ -0,0 +1,33 @@
+#ifndef TPM_FE_H
+#define TPM_FE_H
+
+struct tpmfe_device {
+       /*
+        * Let upper layer receive data from front-end
+        */
+       int (*receive)(const u8 *buffer, size_t count, const void *ptr);
+       /*
+        * Indicate the status of the front-end to the upper
+        * layer.
+        */
+       void (*status)(unsigned int flags);
+
+       /*
+        * This field indicates the maximum size the driver can
+        * transfer in one chunk. It is filled out by the front-end
+        * driver and should be propagated to the generic tpm driver
+        * for allocation of buffers.
+        */
+       unsigned int max_tx_size;
+};
+
+enum {
+       TPMFE_STATUS_DISCONNECTED = 0x0,
+       TPMFE_STATUS_CONNECTED = 0x1
+};
+
+int tpm_fe_send(const u8 * buf, size_t count, void *ptr);
+int tpm_fe_register_receiver(struct tpmfe_device *);
+void tpm_fe_unregister_receiver(void);
+
+#endif
diff -r 84ab93e1ee05 -r dd668f7527cb tools/python/xen/xend/server/tpmif.py
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/python/xen/xend/server/tpmif.py     Thu Sep  1 10:16:14 2005
@@ -0,0 +1,52 @@
+# Copyright (C) 2005 IBM Corporation
+#   Authort: Stefan Berger, stefanb@xxxxxxxxxx
+# Derived from netif.py:
+# Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>
+"""Support for virtual TPM interfaces.
+"""
+
+import random
+
+from xen.xend import sxp
+from xen.xend.XendError import XendError, VmError
+from xen.xend.XendLogging import log
+from xen.xend.XendRoot import get_component
+from xen.xend.xenstore import DBVar
+
+from xen.xend.server import channel
+from xen.xend.server.controller import CtrlMsgRcvr, Dev, DevController
+from xen.xend.server.messages import *
+
+class TPMifController(DevController):
+    """TPM interface controller. Handles all TPM devices for a domain.
+    """
+
+    def __init__(self, vm, recreate=False):
+        DevController.__init__(self, vm, recreate=recreate)
+        self.rcvr = None
+        self.channel = None
+
+    def initController(self, recreate=False, reboot=False):
+        self.destroyed = False
+        self.channel = self.getChannel()
+
+    def destroyController(self, reboot=False):
+        """Destroy the controller and all devices.
+        """
+        self.destroyed = True
+        self.destroyDevices(reboot=reboot)
+        if self.rcvr:
+            self.rcvr.deregisterChannel()
+
+    def sxpr(self):
+        val = ['tpmif', ['dom', self.getDomain()]]
+        return val
+
+    def newDevice(self, id, config, recreate=False):
+        """Create a TPM device.
+
+        @param id: interface id
+        @param config: device configuration
+        @param recreate: recreate flag (true after xend restart)
+        """
+        return None
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm/Makefile
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm/Makefile       Thu Sep  1 10:16:14 2005
@@ -0,0 +1,63 @@
+XEN_ROOT = ../..
+
+# Base definitions and rules
+include $(XEN_ROOT)/tools/vtpm/Rules.mk
+
+# Dir name for emulator (as dom0 tpm driver)
+TPM_EMULATOR_DIR = tpm_emulator-0.2
+# Dir name for vtpm instance
+VTPM_DIR = vtpm
+
+# Emulator tarball name
+TPM_EMULATOR_TARFILE = tpm_emulator-0.2b.tar.gz
+
+all: build
+
+build: $(TPM_EMULATOR_TARFILE) extract patch build_sub
+
+install: build
+       $(MAKE) -C $(TPM_EMULATOR_DIR) $@
+       $(MAKE) -C $(VTPM_DIR) $@
+
+clean:
+       if [ -d $(TPM_EMULATOR_DIR) ]; \
+               then $(MAKE) -C $(TPM_EMULATOR_DIR) clean; \
+       fi
+       if [ -d $(VTPM_DIR) ]; \
+               then $(MAKE) -C $(VTPM_DIR) clean; \
+       fi
+       rm -rf $(TPM_EMULATOR_DIR)
+       rm -rf $(VTPM_DIR)
+
+mrproper: clean
+       rm -f $(TPM_EMULATOR_TARFILE)
+
+# Download Swiss emulator
+$(TPM_EMULATOR_TARFILE):
+       wget http://download.berlios.de/tpm-emulator/$(TPM_EMULATOR_TARFILE)
+
+# Create vtpm and TPM emulator dirs
+extract: $(TPM_EMULATOR_DIR)/README $(VTPM_DIR)/README
+
+$(TPM_EMULATOR_DIR)/README:
+       -rm -rf $(TPM_EMULATOR_DIR)
+       tar -xzf $(TPM_EMULATOR_TARFILE)
+
+$(VTPM_DIR)/README:
+       -rm -rf $(VTPM_DIR)
+       cp -r --preserve $(TPM_EMULATOR_DIR) $(VTPM_DIR)
+
+# apply patches for 1) used as dom0 tpm driver 2) used as vtpm device instance
+patch: $(TPM_EMULATOR_DIR)/Makefile $(VTPM_DIR)/Makefile
+
+$(TPM_EMULATOR_DIR)/Makefile: tpm_emulator.patch
+       -cd $(TPM_EMULATOR_DIR); \
+       patch -p1 <../tpm_emulator.patch
+
+$(VTPM_DIR)/Makefile: vtpm.patch
+       -cd $(VTPM_DIR); \
+       patch -p1 <../vtpm.patch
+
+build_sub:
+       $(MAKE) -C $(TPM_EMULATOR_DIR)
+       $(MAKE) -C $(VTPM_DIR)
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm/README
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm/README Thu Sep  1 10:16:14 2005
@@ -0,0 +1,44 @@
+
+Directory Structure
+===================
+tools/vtpm/tpm_emulator-0.2b.tar.gz    -> TPM Emulator downloaded at build 
time that will
+                                          be patched and used for our vtpms
+tools/vtpm/vtpm.patch                  -> patch applied to tpm_emulator to 
make vtpm
+tools/vtpm/vtpm/                       -> (created on build) tpm_emulator 
moved to ring 3,
+                                          listens on a pair of fifos for TPM 
commands,
+                                          persistent state is sent via named 
fifo to vtpm
+                                            manager, which encrypts it and 
protects it.
+tools/vtpm/tpm_emulator.patch          -> To allow for debugging and testing 
on non-TPM
+                                          platforms, this patches the emulator 
to allow
+                                          it to be inserted into the dom0 
kernel
+tools/vtpm/tpm_emulator-0.2            -> (created on build) directory 
containing patched emulator
+
+Compile Flags
+===================
+VTPM_MULTI_VM                -> Defined (not finished): VTPMs run in their own 
VMs
+                                Not Defined (default): VTPMs are processes
+
+Requirements
+============
+- xen-unstable 
+- IBM frontend/backend vtpm driver patch
+- vtpm_managerd
+
+vtpmd Flow (for vtpm_manager. vtpmd never run by default)
+============================
+- Launch the VTPM manager (vtpm_managerd) which which begins listening to the 
BE with one thread
+  and listens to a named fifo that is shared by the vtpms to commuincate with 
the manager.
+- VTPM Manager listens to TPM BE.
+- When xend launches a tpm frontend equipped VM it contacts the manager over 
the vtpm backend. 
+- When the manager receives the open message from the BE, it launches a vtpm
+- Xend allows the VM to continue booting. 
+- When a TPM request is issued to the front end, the front end transmits the 
TPM request to the backend.
+- The manager receives the TPM requests and uses a named fifo to forward the 
request to the vtpm.
+- The fifo listener begins listening for the reply from vtpm for the request.
+- Vtpm processes request and replies to manager over shared named fifo.
+- If needed, the vtpm may send a request to the vtpm_manager at any time to 
save it's secrets to disk.
+- Manager receives response from vtpm and passes it back to backend for 
forwarding to guest.
+
+tpm_emulator flow
+==================
+Read documentation in tpm_emulator-0.2 directory
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm/Rules.mk
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm/Rules.mk       Thu Sep  1 10:16:14 2005
@@ -0,0 +1,37 @@
+# Base definitions and rules (XEN_ROOT must be defined in including Makefile)
+include $(XEN_ROOT)/tools/Rules.mk
+
+#
+# Tool definitions
+#
+
+# Installation program and options
+INSTALL         = install
+INSTALL_PROG    = $(INSTALL) -m0755
+INSTALL_DIR     = $(INSTALL) -d -m0755
+
+# Xen tools installation directory
+TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin
+
+# General compiler flags
+CFLAGS   = -Wall -Werror -g3 -I.
+
+# For generating dependencies
+CFLAGS += -Wp,-MD,.$(@F).d
+
+DEP_FILES      = .*.d
+
+# Generic project files
+HDRS   = $(wildcard *.h)
+SRCS   = $(wildcard *.c)
+OBJS   = $(patsubst %.c,%.o,$(SRCS))
+
+# Generic (non-header) dependencies
+$(SRCS): Makefile $(XEN_ROOT)/tools/Rules.mk $(XEN_ROOT)/tools/vtpm/Rules.mk
+
+$(OBJS): $(SRCS)
+
+-include $(DEP_FILES)
+
+# Make sure these are just rules
+.PHONY : all build install clean
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm/tpm_emulator.patch
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm/tpm_emulator.patch     Thu Sep  1 10:16:14 2005
@@ -0,0 +1,151 @@
+diff -uprN orig/tpm_emulator-0.2/AUTHORS tpm_emulator-0.2/AUTHORS
+--- orig/tpm_emulator-0.2/AUTHORS      2005-08-17 10:58:36.000000000 -0700
++++ tpm_emulator-0.2/AUTHORS   2005-08-17 10:55:52.000000000 -0700
+@@ -1 +1,2 @@
+ Mario Strasser <mast@xxxxxxx>
++INTEL Corp <>
+diff -uprN orig/tpm_emulator-0.2/ChangeLog tpm_emulator-0.2/ChangeLog
+--- orig/tpm_emulator-0.2/ChangeLog    2005-08-17 10:58:36.000000000 -0700
++++ tpm_emulator-0.2/ChangeLog 2005-08-17 10:55:52.000000000 -0700
+@@ -1,3 +1,7 @@
++2005-08-16: INTEL Corp
++      * Set default permissions to PCRs
++      * Changed device to /dev/tpm0
++
+ 2005-08-15  Mario Strasser <mast@xxxxxxx>
+       * all: some typos corrected
+       * tpm_integrity.c: bug in TPM_Extend fixed
+diff -uprN orig/tpm_emulator-0.2/Makefile tpm_emulator-0.2/Makefile
+--- orig/tpm_emulator-0.2/Makefile     2005-08-17 10:58:36.000000000 -0700
++++ tpm_emulator-0.2/Makefile  2005-08-17 10:55:52.000000000 -0700
+@@ -1,15 +1,19 @@
+ # Software-Based Trusted Platform Module (TPM) Emulator for Linux
+ # Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>
++# Copyright (C) 2005 INTEL Corp.
+ #
+ # $Id: Makefile 10 2005-04-26 20:59:50Z mast $
+ 
++XEN_ROOT       := ../../..
++EUID           := $(shell id -u)
++
+ # kernel settings
+ KERNEL_RELEASE := $(shell uname -r)
+-KERNEL_BUILD   := /lib/modules/$(KERNEL_RELEASE)/build
++KERNEL_BUILD   := $(XEN_ROOT)/linux-2.6.12-xen0
+ MOD_SUBDIR     := misc
+ 
+ # module settings
+-MODULE_NAME    := tpm_emulator
++BIN            := tpm_emulator
+ VERSION_MAJOR  := 0
+ VERSION_MINOR  := 2
+ VERSION_BUILD  := $(shell date +"%s")
+@@ -27,11 +30,9 @@ DIRS           := . crypto tpm 
+ SRCS           := $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.c))
+ OBJS           := $(patsubst %.c, %.o, $(SRCS))
+ SRCS           += $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.h))
+-DISTSRC        := ./README ./AUTHORS ./ChangeLog ./Makefile $(SRCS)
+-DISTDIR        := tpm_emulator-$(VERSION_MAJOR).$(VERSION_MINOR)
+ 
+-obj-m               := $(MODULE_NAME).o
+-$(MODULE_NAME)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
++obj-m               := $(BIN).o
++$(BIN)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
+ 
+ EXTRA_CFLAGS   += -I$(src) -I$(src)/crypto -I$(src)/tpm 
+ 
+@@ -42,23 +43,17 @@ all:       $(src)/crypto/gmp.h $(src)/crypto/l
+       @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules
+ 
+ install:
+-      @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules_install
+-      test -d /var/tpm || mkdir /var/tpm
+-      test -c /dev/tpm || mknod /dev/tpm c 10 224
+-      chmod 666 /dev/tpm
+-      depmod -a
++      @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) INSTALL_MOD_PATH=$(DESTDIR) 
modules_install
++      test -d $(DESTDIR)/var/tpm || mkdir $(DESTDIR)/var/tpm
++      test -d $(DESTDIR)/dev || mkdir $(DESTDIR)/dev
++      test -c $(DESTDIR)/dev/tpm0 || [ $(EUID) -ne 0 ] || mknod 
$(DESTDIR)/dev/tpm0 c 10 224
++      [ $(EUID) -ne 0 ] || chmod 666 $(DESTDIR)/dev/tpm0
+ 
+ clean:
+       @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean
+       rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a
+ 
+-dist: $(DISTSRC)
+-      rm -rf $(DISTDIR)
+-      mkdir $(DISTDIR)
+-      cp --parents $(DISTSRC) $(DISTDIR)/
+-      rm -f $(DISTDIR)/crypto/gmp.h 
+-      tar -chzf $(DISTDIR).tar.gz $(DISTDIR)
+-      rm -rf $(DISTDIR)
++mrproper: clean
+ 
+ $(src)/crypto/libgmp.a:
+       test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB) 
$(src)/crypto/libgmp.a
+diff -uprN orig/tpm_emulator-0.2/README tpm_emulator-0.2/README
+--- orig/tpm_emulator-0.2/README       2005-08-17 10:58:36.000000000 -0700
++++ tpm_emulator-0.2/README    2005-08-17 10:55:52.000000000 -0700
+@@ -13,7 +13,8 @@ $Id: README 8 2005-01-25 21:11:45Z jmoli
+ Copyright
+ --------------------------------------------------------------------------
+ Copyright (C) 2004 Mario Strasser <mast@xxxxxxx> and Swiss Federal 
+-Institute of Technology (ETH) Zurich.
++                   Institute of Technology (ETH) Zurich.
++Copyright (C) 2005 
+               
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+diff -uprN orig/tpm_emulator-0.2/linux_module.h tpm_emulator-0.2/linux_module.h
+--- orig/tpm_emulator-0.2/linux_module.h       2005-08-17 10:58:36.000000000 
-0700
++++ tpm_emulator-0.2/linux_module.h    2005-08-17 10:55:52.000000000 -0700
+@@ -1,5 +1,6 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
++ * Copyright (C) 2005 INTEL Corp.
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -33,7 +34,7 @@
+ #include "tpm_version.h"
+ 
+ #define TPM_DEVICE_MINOR      224
+-#define TPM_DEVICE_NAME         "tpm"
++#define TPM_DEVICE_NAME         "tpm0"
+ #define TPM_MODULE_NAME       "tpm_emulator"
+ 
+ /* debug and log output functions */
+diff -uprN orig/tpm_emulator-0.2/tpm/tpm_data.c tpm_emulator-0.2/tpm/tpm_data.c
+--- orig/tpm_emulator-0.2/tpm/tpm_data.c       2005-08-17 10:58:36.000000000 
-0700
++++ tpm_emulator-0.2/tpm/tpm_data.c    2005-08-17 10:55:52.000000000 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+  *                    Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -85,6 +86,11 @@ void tpm_init_data(void)
+   tpmData.permanent.data.version.revMinor = VERSION_MINOR;
+   /* setup PCR attributes */
+   for (i = 0; i < TPM_NUM_PCR; i++) {
++    int j;
++    for (j=0; j < TPM_NUM_LOCALITY; j++) {
++      tpmData.permanent.data.pcrAttrib[i].pcrExtendLocal[j] = TRUE;
++    }
++
+     tpmData.permanent.data.pcrAttrib[i].pcrReset = TRUE;
+   }
+   /* set tick type */
+diff -uprN orig/tpm_emulator-0.2/tpm_version.h tpm_emulator-0.2/tpm_version.h
+--- orig/tpm_emulator-0.2/tpm_version.h        2005-08-17 10:58:36.000000000 
-0700
++++ tpm_emulator-0.2/tpm_version.h     2005-08-17 10:55:53.000000000 -0700
+@@ -2,5 +2,5 @@
+ #define _TPM_VERSION_H_
+ #define VERSION_MAJOR 0
+ #define VERSION_MINOR 2
+-#define VERSION_BUILD 1123950310
++#define VERSION_BUILD 1124301353
+ #endif /* _TPM_VERSION_H_ */
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm/vtpm.patch
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm/vtpm.patch     Thu Sep  1 10:16:14 2005
@@ -0,0 +1,1645 @@
+diff -uprN orig/tpm_emulator-0.2/AUTHORS vtpm/AUTHORS
+--- orig/tpm_emulator-0.2/AUTHORS      2005-08-17 10:58:36.000000000 -0700
++++ vtpm/AUTHORS       2005-08-17 10:55:52.000000000 -0700
+@@ -1 +1,2 @@
+ Mario Strasser <mast@xxxxxxx>
++INTEL Corp <>
+diff -uprN orig/tpm_emulator-0.2/ChangeLog vtpm/ChangeLog
+--- orig/tpm_emulator-0.2/ChangeLog    2005-08-17 10:58:36.000000000 -0700
++++ vtpm/ChangeLog     2005-08-17 10:55:52.000000000 -0700
+@@ -1,3 +1,7 @@
++2005-08-16 Intel Corp
++      Moved module out of kernel to run as a ring 3 app
++      Modified save_to_file and load_from_file to call a xen backend driver 
to call a VTPM manager
++
+ 2005-08-15  Mario Strasser <mast@xxxxxxx>
+       * all: some typos corrected
+       * tpm_integrity.c: bug in TPM_Extend fixed
+diff -uprN orig/tpm_emulator-0.2/Makefile vtpm/Makefile
+--- orig/tpm_emulator-0.2/Makefile     2005-08-17 10:58:36.000000000 -0700
++++ vtpm/Makefile      2005-08-17 10:55:52.000000000 -0700
+@@ -1,21 +1,29 @@
+ # Software-Based Trusted Platform Module (TPM) Emulator for Linux
+ # Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>
++# Copyright (C) 2005 INTEL Corp.
+ #
+ # $Id: Makefile 10 2005-04-26 20:59:50Z mast $
+ 
+-# kernel settings
+-KERNEL_RELEASE := $(shell uname -r)
+-KERNEL_BUILD   := /lib/modules/$(KERNEL_RELEASE)/build
+-MOD_SUBDIR     := misc
+-
+ # module settings
+-MODULE_NAME    := tpm_emulator
++BIN            := vtpmd
+ VERSION_MAJOR  := 0
+ VERSION_MINOR  := 2
+ VERSION_BUILD  := $(shell date +"%s")
+ 
+-# enable/disable DEBUG messages
+-EXTRA_CFLAGS   += -DDEBUG -g  
++# Installation program and options
++INSTALL         = install
++INSTALL_PROG    = $(INSTALL) -m0755
++INSTALL_DIR     = $(INSTALL) -d -m0755
++
++# Xen tools installation directory
++TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin
++
++CC      := gcc
++CFLAGS  += -g -Wall $(INCLUDE) -DDEBUG
++CFLAGS  += -I. -Itpm
++
++# Is the simulator running in it's own vm?
++#CFLAGS += -DVTPM_MULTI_VM
+ 
+ # GNU MP configuration
+ GMP_LIB        := /usr/lib/libgmp.a
+@@ -27,38 +35,31 @@ DIRS           := . crypto tpm 
+ SRCS           := $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.c))
+ OBJS           := $(patsubst %.c, %.o, $(SRCS))
+ SRCS           += $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.h))
+-DISTSRC        := ./README ./AUTHORS ./ChangeLog ./Makefile $(SRCS)
+-DISTDIR        := tpm_emulator-$(VERSION_MAJOR).$(VERSION_MINOR)
+ 
+-obj-m               := $(MODULE_NAME).o
+-$(MODULE_NAME)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
++obj-m               := $(BIN)
++$(BIN)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
+ 
+ EXTRA_CFLAGS   += -I$(src) -I$(src)/crypto -I$(src)/tpm 
+ 
+ # do not print "Entering directory ..."
+ MAKEFLAGS      += --no-print-directory
+ 
+-all:  $(src)/crypto/gmp.h $(src)/crypto/libgmp.a version
+-      @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules
++all: $(BIN)
++
++$(BIN):       $(src)/crypto/gmp.h $(src)/crypto/libgmp.a version $(SRCS) 
$(OBJS)
++      $(CC) $(CFLAGS) $(OBJS) $(src)/crypto/libgmp.a -o $(BIN)
++
++%.o: %.c
++      $(CC) $(CFLAGS) -c $< -o $@
+ 
+ install:
+-      @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules_install
+-      test -d /var/tpm || mkdir /var/tpm
+-      test -c /dev/tpm || mknod /dev/tpm c 10 224
+-      chmod 666 /dev/tpm
+-      depmod -a
++      $(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR)
+ 
+ clean:
+-      @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean
+-      rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a
++      rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a $(OBJS)
+ 
+-dist: $(DISTSRC)
+-      rm -rf $(DISTDIR)
+-      mkdir $(DISTDIR)
+-      cp --parents $(DISTSRC) $(DISTDIR)/
+-      rm -f $(DISTDIR)/crypto/gmp.h 
+-      tar -chzf $(DISTDIR).tar.gz $(DISTDIR)
+-      rm -rf $(DISTDIR)
++mrproper: clean
++      rm -f $(BIN)
+ 
+ $(src)/crypto/libgmp.a:
+       test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB) 
$(src)/crypto/libgmp.a
+diff -uprN orig/tpm_emulator-0.2/README vtpm/README
+--- orig/tpm_emulator-0.2/README       2005-08-17 10:58:36.000000000 -0700
++++ vtpm/README        2005-08-17 10:55:52.000000000 -0700
+@@ -13,7 +13,8 @@ $Id: README 8 2005-01-25 21:11:45Z jmoli
+ Copyright
+ --------------------------------------------------------------------------
+ Copyright (C) 2004 Mario Strasser <mast@xxxxxxx> and Swiss Federal 
+-Institute of Technology (ETH) Zurich.
++                   Institute of Technology (ETH) Zurich.
++Copyright (C) 2005 INTEL Corp 
+               
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+diff -uprN orig/tpm_emulator-0.2/crypto/gmp_kernel_wrapper.c 
vtpm/crypto/gmp_kernel_wrapper.c
+--- orig/tpm_emulator-0.2/crypto/gmp_kernel_wrapper.c  2005-08-17 
10:58:36.000000000 -0700
++++ vtpm/crypto/gmp_kernel_wrapper.c   2005-08-17 10:55:52.000000000 -0700
+@@ -1,5 +1,6 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -24,15 +25,10 @@ int __gmp_junk;
+ void __attribute__ ((regparm(0))) __gmp_assert_fail(const char *filename, 
+   int linenum, const char *expr) 
+ {
+-  panic(KERN_CRIT TPM_MODULE_NAME "%s:%d: GNU MP assertion failed: %s\n", 
++  error("%s:%d: GNU MP assertion failed: %s\n", 
+     filename, linenum, expr);
+ }
+ 
+-void __attribute__ ((regparm(0))) abort(void)
+-{
+-  panic(KERN_CRIT TPM_MODULE_NAME "GNU MP abort() was called\n");
+-}
+-
+ /* overwrite GNU MP random functions (used by mpz/millerrabin.c) */ 
+ 
+ void __attribute__ ((regparm(0))) gmp_randinit(gmp_randstate_t rstate, 
+@@ -77,20 +73,19 @@ void __attribute__ ((regparm(0))) mpz_ur
+ 
+ void __attribute__ ((regparm(0))) *kernel_allocate(size_t size)
+ {
+-  void *ret  = (void*)kmalloc(size, GFP_KERNEL);
+-  if (!ret) panic(KERN_CRIT TPM_MODULE_NAME 
+-    "GMP: cannot allocate memory (size=%u)\n", size);
++  void *ret  = (void*)malloc(size);
++  if (!ret) error("GMP: cannot allocate memory (size=%u)\n", size);
+   return ret;
+ }
+ 
+ void __attribute__ ((regparm(0))) *kernel_reallocate(void *oldptr, 
+   size_t old_size, size_t new_size)
+ {
+-  void *ret = (void*)kmalloc(new_size, GFP_KERNEL);
+-  if (!ret) panic(KERN_CRIT TPM_MODULE_NAME "GMP: Cannot reallocate memory "
++  void *ret = (void*)malloc(new_size);
++  if (!ret) error("GMP: Cannot reallocate memory "
+     "(old_size=%u new_size=%u)\n", old_size, new_size);
+   memcpy(ret, oldptr, old_size);
+-  kfree(oldptr);
++  free(oldptr);
+   return ret;
+ }
+ 
+@@ -99,7 +94,7 @@ void __attribute__ ((regparm(0))) kernel
+   /* overwrite used memory */
+   if (blk_ptr != NULL) { 
+     memset(blk_ptr, 0, blk_size);
+-    kfree(blk_ptr);
++    free(blk_ptr);
+   }
+ }
+ 
+diff -uprN orig/tpm_emulator-0.2/crypto/rsa.c vtpm/crypto/rsa.c
+--- orig/tpm_emulator-0.2/crypto/rsa.c 2005-08-17 10:58:36.000000000 -0700
++++ vtpm/crypto/rsa.c  2005-08-17 10:55:52.000000000 -0700
+@@ -1,5 +1,6 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -363,7 +364,7 @@ static int encode_message(int type, uint
+       msg[0] = 0x00;
+       get_random_bytes(&msg[1], SHA1_DIGEST_LENGTH);
+       sha1_init(&ctx);
+-      sha1_update(&ctx, "TCPA", 4);
++      sha1_update(&ctx, (uint8_t *) "TCPA", 4);
+       sha1_final(&ctx, &msg[1 + SHA1_DIGEST_LENGTH]);
+       memset(&msg[1 + 2 * SHA1_DIGEST_LENGTH], 0x00, 
+         msg_len - data_len - 2 * SHA1_DIGEST_LENGTH - 2);
+@@ -411,7 +412,7 @@ static int decode_message(int type, uint
+       mask_generation(&msg[1], SHA1_DIGEST_LENGTH,
+         &msg[1 + SHA1_DIGEST_LENGTH], msg_len - SHA1_DIGEST_LENGTH - 1);
+       sha1_init(&ctx);
+-      sha1_update(&ctx, "TCPA", 4);
++      sha1_update(&ctx, (uint8_t *) "TCPA", 4);
+       sha1_final(&ctx, &msg[1]);
+       if (memcmp(&msg[1], &msg[1 + SHA1_DIGEST_LENGTH], 
+           SHA1_DIGEST_LENGTH) != 0) return -1;
+diff -uprN orig/tpm_emulator-0.2/linux_module.c vtpm/linux_module.c
+--- orig/tpm_emulator-0.2/linux_module.c       2005-08-17 10:58:36.000000000 
-0700
++++ vtpm/linux_module.c        1969-12-31 16:00:00.000000000 -0800
+@@ -1,163 +0,0 @@
+-/* Software-Based Trusted Platform Module (TPM) Emulator for Linux 
+- * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+- *
+- * This module is free software; you can redistribute it and/or modify 
+- * it under the terms of the GNU General Public License as published 
+- * by the Free Software Foundation; either version 2 of the License, 
+- * or (at your option) any later version.  
+- *
+- * This module is distributed in the hope that it will be useful, 
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of 
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
+- * GNU General Public License for more details.
+- *
+- * $Id: linux_module.c 19 2005-05-18 08:29:37Z mast $
+- */
+-
+-#include <linux/module.h>
+-#include <linux/kernel.h>
+-#include <linux/init.h>
+-#include <linux/miscdevice.h>
+-#include <linux/poll.h>
+-#include "linux_module.h"
+-#include "tpm/tpm_emulator.h"
+-
+-MODULE_LICENSE("GPL");
+-MODULE_AUTHOR("Mario Strasser <mast@xxxxxxx>");
+-MODULE_DESCRIPTION("Trusted Platform Module (TPM) Emulator");
+-MODULE_SUPPORTED_DEVICE(TPM_DEVICE_NAME);
+-
+-/* module startup parameters */
+-char *startup = "save";
+-MODULE_PARM(startup, "s");
+-MODULE_PARM_DESC(startup, " Sets the startup mode of the TPM. "
+-  "Possible values are 'clear', 'save' (default) and 'deactivated.");
+-char *storage_file = "/var/tpm/tpm_emulator-1.2.0.1";
+-MODULE_PARM(storage_file, "s");
+-MODULE_PARM_DESC(storage_file, " Sets the persistent-data storage " 
+-  "file of the TPM.");
+-
+-/* TPM lock */
+-static struct semaphore tpm_mutex;
+-
+-/* TPM command response */
+-static struct {
+-  uint8_t *data;
+-  uint32_t size;
+-} tpm_response;
+-
+-/* module state */
+-#define STATE_IS_OPEN 0
+-static uint32_t module_state;
+-
+-static int tpm_open(struct inode *inode, struct file *file)
+-{
+-  debug("%s()", __FUNCTION__);
+-  if (test_and_set_bit(STATE_IS_OPEN, (void*)&module_state)) return -EBUSY;
+-  return 0;
+-}
+-
+-static int tpm_release(struct inode *inode, struct file *file)
+-{
+-  debug("%s()", __FUNCTION__);
+-  clear_bit(STATE_IS_OPEN, (void*)&module_state);
+-  return 0;
+-}
+-
+-static ssize_t tpm_read(struct file *file, char *buf, size_t count, loff_t 
*ppos)
+-{
+-  debug("%s(%d)", __FUNCTION__, count);
+-  down(&tpm_mutex);
+-  if (tpm_response.data != NULL) {
+-    count = min(count, (size_t)tpm_response.size - (size_t)*ppos);
+-    count -= copy_to_user(buf, &tpm_response.data[*ppos], count);
+-    *ppos += count;
+-  } else {
+-    count = 0;
+-  }
+-  up(&tpm_mutex);
+-  return count;
+-}
+-
+-static ssize_t tpm_write(struct file *file, const char *buf, size_t count, 
loff_t *ppos)
+-{
+-  debug("%s(%d)", __FUNCTION__, count);
+-  down(&tpm_mutex);
+-  *ppos = 0;
+-  if (tpm_response.data != NULL) kfree(tpm_response.data);
+-  if (tpm_handle_command(buf, count, &tpm_response.data, 
+-                         &tpm_response.size) != 0) { 
+-    count = -EILSEQ;
+-    tpm_response.data = NULL;
+-  }
+-  up(&tpm_mutex);
+-  return count;
+-}
+-
+-static int tpm_ioctl(struct inode *inode, struct file *file, unsigned int 
cmd, unsigned long arg)
+-{
+-  debug("%s(%d, %ld)", __FUNCTION__, cmd, arg);
+-  return -1;
+-}
+-
+-struct file_operations fops = {
+-  .owner   = THIS_MODULE,
+-  .open    = tpm_open,
+-  .release = tpm_release,
+-  .read    = tpm_read,
+-  .write   = tpm_write,
+-  .ioctl   = tpm_ioctl,
+-};
+-
+-static struct miscdevice tpm_dev = {
+-  .minor      = TPM_DEVICE_MINOR, 
+-  .name       = TPM_DEVICE_NAME, 
+-  .fops       = &fops,
+-};
+-
+-int __init init_tpm_module(void)
+-{
+-  int res = misc_register(&tpm_dev);
+-  if (res != 0) {
+-    error("misc_register() failed for minor %d\n", TPM_DEVICE_MINOR);
+-    return res;
+-  }
+-  /* initialize variables */
+-  sema_init(&tpm_mutex, 1);
+-  module_state = 0;
+-  tpm_response.data = NULL;    
+-  /* initialize TPM emulator */
+-  if (!strcmp(startup, "clear")) {
+-    tpm_emulator_init(1);
+-  } else if (!strcmp(startup, "save")) { 
+-    tpm_emulator_init(2);
+-  } else if (!strcmp(startup, "deactivated")) {
+-    tpm_emulator_init(3);
+-  } else {
+-    error("invalid startup mode '%s'; must be 'clear', "
+-      "'save' (default) or 'deactivated", startup);
+-    misc_deregister(&tpm_dev);
+-    return -EINVAL;
+-  }
+-  return 0;
+-}
+-
+-void __exit cleanup_tpm_module(void)
+-{
+-  tpm_emulator_shutdown();
+-  misc_deregister(&tpm_dev);
+-}
+-
+-module_init(init_tpm_module);
+-module_exit(cleanup_tpm_module);
+-
+-uint64_t tpm_get_ticks(void)
+-{
+-  static struct timespec old_time = {0, 0}; 
+-  struct timespec new_time = current_kernel_time();
+-  uint64_t ticks = (uint64_t)(old_time.tv_sec - new_time.tv_sec) * 1000000
+-                   + (old_time.tv_nsec - new_time.tv_nsec) / 1000;
+-  old_time = new_time;
+-  return (ticks > 0) ? ticks : 1;
+-}
+-
+diff -uprN orig/tpm_emulator-0.2/linux_module.h vtpm/linux_module.h
+--- orig/tpm_emulator-0.2/linux_module.h       2005-08-17 10:58:36.000000000 
-0700
++++ vtpm/linux_module.h        2005-08-17 10:55:52.000000000 -0700
+@@ -1,5 +1,6 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -17,17 +18,22 @@
+ #ifndef _LINUX_MODULE_H_
+ #define _LINUX_MODULE_H_
+ 
+-#include <linux/version.h>
+-#include <linux/kernel.h>
+-#include <linux/slab.h>
++#include <malloc.h>
++#include <stdint.h>
++#include <stdio.h>
++#include <string.h>
+ #include <linux/types.h>
+-#include <linux/string.h>
+-#include <linux/random.h>
+-#include <linux/time.h>
+-#include <asm/byteorder.h>
+ 
+-/* module settings */
++#include <endian.h>
++#define __BYTEORDER_HAS_U64__
++#ifdef LITTLE_ENDIAN
++ #include <linux/byteorder/little_endian.h>
++#else
++ #include <linux/byteorder/big_endian.h>
++#endif
+ 
++/* module settings */
++#define min(A,B) ((A)<(B)?(A):(B))
+ #define STR(s) __STR__(s)
+ #define __STR__(s) #s
+ #include "tpm_version.h"
+@@ -39,32 +45,35 @@
+ /* debug and log output functions */
+ 
+ #ifdef DEBUG
+-#define debug(fmt, ...) printk(KERN_DEBUG "%s %s:%d: Debug: " fmt "\n", \
+-                        TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
++#define debug(fmt, ...) printf("%s:%d: Debug: " fmt "\n", \
++                        __FILE__, __LINE__, ## __VA_ARGS__)
+ #else
+ #define debug(fmt, ...) 
+ #endif
+-#define info(fmt, ...)  printk(KERN_INFO "%s %s:%d: Info: " fmt "\n", \
+-                        TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
+-#define error(fmt, ...) printk(KERN_ERR "%s %s:%d: Error: " fmt "\n", \
+-                        TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
+-#define alert(fmt, ...) printk(KERN_ALERT "%s %s:%d: Alert: " fmt "\n", \
+-                        TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
++#define info(fmt, ...)  printf("%s:%d: Info: " fmt "\n", \
++                        __FILE__, __LINE__, ## __VA_ARGS__)
++#define error(fmt, ...) printf("%s:%d: Error: " fmt "\n", \
++                        __FILE__, __LINE__, ## __VA_ARGS__)
++#define alert(fmt, ...) printf("%s:%d: Alert: " fmt "\n", \
++                        __FILE__, __LINE__, ## __VA_ARGS__)
+ 
+ /* memory allocation */
+ 
+ static inline void *tpm_malloc(size_t size) 
+ {
+-  return kmalloc(size, GFP_KERNEL);  
++  return malloc(size);  
+ }
+ 
+ static inline void tpm_free(const void *ptr)
+ {
+-  if (ptr != NULL) kfree(ptr);
++  if (ptr != NULL) free( (void *) ptr);
+ }
+ 
+ /* random numbers */
+ 
++//FIXME;
++void get_random_bytes(void *buf, int nbytes);
++
+ static inline void tpm_get_random_bytes(void *buf, int nbytes)
+ {
+   get_random_bytes(buf, nbytes);
+@@ -84,9 +93,9 @@ uint64_t tpm_get_ticks(void);
+ #define CPU_TO_LE16(x) __cpu_to_le16(x)
+ 
+ #define BE64_TO_CPU(x) __be64_to_cpu(x)
+-#define LE64_TO_CPU(x) __be64_to_cpu(x)
++#define LE64_TO_CPU(x) __le64_to_cpu(x)
+ #define BE32_TO_CPU(x) __be32_to_cpu(x)
+-#define LE32_TO_CPU(x) __be32_to_cpu(x)
++#define LE32_TO_CPU(x) __le32_to_cpu(x)
+ #define BE16_TO_CPU(x) __be16_to_cpu(x)
+ #define LE16_TO_CPU(x) __le16_to_cpu(x)
+ 
+diff -uprN orig/tpm_emulator-0.2/tpm/tpm_audit.c vtpm/tpm/tpm_audit.c
+--- orig/tpm_emulator-0.2/tpm/tpm_audit.c      2005-08-17 10:58:36.000000000 
-0700
++++ vtpm/tpm/tpm_audit.c       2005-08-17 10:55:52.000000000 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+  *                    Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -45,14 +46,14 @@ void tpm_audit_request(TPM_COMMAND_CODE 
+       tpmData.permanent.data.auditMonotonicCounter++;
+     }
+     /* update audit digest */
+-    *((UINT16*)&buf[0])  = cpu_to_be16(TPM_TAG_AUDIT_EVENT_IN);
+-    *((UINT32*)&buf[2]) = cpu_to_be32(ordinal);
++    *((UINT16*)&buf[0])  = CPU_TO_BE16(TPM_TAG_AUDIT_EVENT_IN);
++    *((UINT32*)&buf[2]) = CPU_TO_BE32(ordinal);
+     sha1_init(&sha1_ctx);
+     sha1_update(&sha1_ctx, req->param, req->paramSize);
+     sha1_final(&sha1_ctx, &buf[6]);
+-    *((UINT16*)&buf[26])  = cpu_to_be16(TPM_TAG_COUNTER_VALUE);
++    *((UINT16*)&buf[26])  = CPU_TO_BE16(TPM_TAG_COUNTER_VALUE);
+     memset(&buf[30], 0, 4);
+-    *((UINT32*)&buf[34]) = 
cpu_to_be32(tpmData.permanent.data.auditMonotonicCounter);
++    *((UINT32*)&buf[34]) = 
CPU_TO_BE32(tpmData.permanent.data.auditMonotonicCounter);
+     sha1_init(&sha1_ctx);
+     sha1_update(&sha1_ctx, tpmData.stany.data.auditDigest.digest, 
+       sizeof(TPM_DIGEST));
+@@ -70,15 +71,15 @@ void tpm_audit_response(TPM_COMMAND_CODE
+       && (AUDIT_STATUS[ord / 8] & (1 << (ord & 0x07)))) {
+     info("tpm_audit_response()");
+     /* update audit digest */
+-    *((UINT16*)&buf[0])  = cpu_to_be16(TPM_TAG_AUDIT_EVENT_OUT);
+-    *((UINT32*)&buf[2]) = cpu_to_be32(ordinal);
++    *((UINT16*)&buf[0])  = CPU_TO_BE16(TPM_TAG_AUDIT_EVENT_OUT);
++    *((UINT32*)&buf[2]) = CPU_TO_BE32(ordinal);
+     sha1_init(&sha1_ctx);
+     sha1_update(&sha1_ctx, rsp->param, rsp->paramSize);
+     sha1_final(&sha1_ctx, &buf[6]);
+-    *((UINT16*)&buf[26])  = cpu_to_be16(TPM_TAG_COUNTER_VALUE);
++    *((UINT16*)&buf[26])  = CPU_TO_BE16(TPM_TAG_COUNTER_VALUE);
+     memset(&buf[30], 0, 4);
+-    *((UINT32*)&buf[34]) = 
cpu_to_be32(tpmData.permanent.data.auditMonotonicCounter);
+-    *((UINT32*)&buf[34]) = cpu_to_be32(rsp->result);
++    *((UINT32*)&buf[34]) = 
CPU_TO_BE32(tpmData.permanent.data.auditMonotonicCounter);
++    *((UINT32*)&buf[34]) = CPU_TO_BE32(rsp->result);
+     sha1_init(&sha1_ctx);
+     sha1_update(&sha1_ctx, tpmData.stany.data.auditDigest.digest, 
+       sizeof(TPM_DIGEST));
+@@ -158,7 +159,7 @@ TPM_RESULT TPM_GetAuditDigestSigned(TPM_
+   }
+   memcpy(&buf[0], "\x05\x00ADIG", 6);
+   memcpy(&buf[6], antiReplay->nonce, 20);
+-  *(UINT32*)&buf[26] = cpu_to_be32(buf_size - 30);
++  *(UINT32*)&buf[26] = CPU_TO_BE32(buf_size - 30);
+   memcpy(&buf[30], auditDigest->digest, 20);
+   ptr = &buf[50];
+   len = buf_size - 50;
+@@ -198,4 +199,3 @@ TPM_RESULT TPM_SetOrdinalAuditStatus(TPM
+   }
+   return TPM_SUCCESS;
+ }
+-
+diff -uprN orig/tpm_emulator-0.2/tpm/tpm_authorization.c 
vtpm/tpm/tpm_authorization.c
+--- orig/tpm_emulator-0.2/tpm/tpm_authorization.c      2005-08-17 
10:58:36.000000000 -0700
++++ vtpm/tpm/tpm_authorization.c       2005-08-17 10:55:52.000000000 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+  *                    Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -268,7 +269,7 @@ TPM_RESULT tpm_verify_auth(TPM_AUTH *aut
+ {
+   hmac_ctx_t ctx;
+   TPM_SESSION_DATA *session;
+-  UINT32 auth_handle = cpu_to_be32(auth->authHandle);
++  UINT32 auth_handle = CPU_TO_BE32(auth->authHandle);
+   
+   info("tpm_verify_auth(%08x)", auth->authHandle);
+   /* get dedicated authorization session */
+@@ -316,5 +317,3 @@ void tpm_decrypt_auth_secret(TPM_ENCAUTH
+   for (i = 0; i < sizeof(TPM_SECRET); i++)
+     plainAuth[i] ^= encAuth[i];
+ }
+-
+-
+diff -uprN orig/tpm_emulator-0.2/tpm/tpm_capability.c vtpm/tpm/tpm_capability.c
+--- orig/tpm_emulator-0.2/tpm/tpm_capability.c 2005-08-17 10:58:36.000000000 
-0700
++++ vtpm/tpm/tpm_capability.c  2005-08-17 10:55:52.000000000 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+  *                    Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -398,7 +399,7 @@ TPM_RESULT TPM_GetCapability(TPM_CAPABIL
+ 
+     case TPM_CAP_KEY_HANDLE:
+       debug("[TPM_CAP_KEY_HANDLE]");
+-      subCapSize = cpu_to_be32(TPM_RT_KEY);
++      subCapSize = CPU_TO_BE32(TPM_RT_KEY);
+       return cap_handle(4, (BYTE*)&subCapSize, respSize, resp);
+ 
+     case TPM_CAP_CHECK_LOADED:
+@@ -472,4 +473,3 @@ TPM_RESULT TPM_GetCapability(TPM_CAPABIL
+       return TPM_BAD_MODE;
+   }
+ }
+-
+diff -uprN orig/tpm_emulator-0.2/tpm/tpm_cmd_handler.c 
vtpm/tpm/tpm_cmd_handler.c
+--- orig/tpm_emulator-0.2/tpm/tpm_cmd_handler.c        2005-08-17 
10:58:36.000000000 -0700
++++ vtpm/tpm/tpm_cmd_handler.c 2005-08-17 10:55:52.000000000 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+  *                    Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -26,7 +27,7 @@ static void tpm_compute_in_param_digest(
+ {
+   sha1_ctx_t sha1;
+   UINT32 offset;
+-  UINT32 ord = cpu_to_be32(req->ordinal);
++  UINT32 ord = CPU_TO_BE32(req->ordinal);
+ 
+   /* skip all key-handles at the beginning */
+   switch (req->ordinal) {
+@@ -82,8 +83,8 @@ static void tpm_compute_in_param_digest(
+ static void tpm_compute_out_param_digest(TPM_COMMAND_CODE ordinal, 
TPM_RESPONSE *rsp)
+ {
+   sha1_ctx_t sha1;
+-  UINT32 res = cpu_to_be32(rsp->result);
+-  UINT32 ord = cpu_to_be32(ordinal);
++  UINT32 res = CPU_TO_BE32(rsp->result);
++  UINT32 ord = CPU_TO_BE32(ordinal);
+ 
+   /* compute SHA1 hash */
+   sha1_init(&sha1);
+@@ -3081,7 +3082,7 @@ static void tpm_setup_rsp_auth(TPM_COMMA
+       hmac_update(&hmac, rsp->auth2->digest, sizeof(rsp->auth2->digest));
+ #if 0
+       if (tpm_get_auth(rsp->auth2->authHandle)->type == TPM_ST_OIAP) {
+-        UINT32 handle = cpu_to_be32(rsp->auth2->authHandle);
++        UINT32 handle = CPU_TO_BE32(rsp->auth2->authHandle);
+         hmac_update(&hmac, (BYTE*)&handle, 4);
+       }
+ #endif
+@@ -3096,7 +3097,7 @@ static void tpm_setup_rsp_auth(TPM_COMMA
+       hmac_update(&hmac, rsp->auth1->digest, sizeof(rsp->auth1->digest));
+ #if 0
+       if (tpm_get_auth(rsp->auth1->authHandle)->type == TPM_ST_OIAP) {
+-        UINT32 handle = cpu_to_be32(rsp->auth1->authHandle);
++        UINT32 handle = CPU_TO_BE32(rsp->auth1->authHandle);
+         hmac_update(&hmac, (BYTE*)&handle, 4);
+       }
+ #endif
+@@ -3179,7 +3180,9 @@ extern const char *tpm_error_to_string(T
+ static void tpm_execute_command(TPM_REQUEST *req, TPM_RESPONSE *rsp)
+ {
+   TPM_RESULT res;
+-  
++
++  req->tag = (BYTE) req->tag;  // VIN HACK!!! 
++
+   /* setup authorisation as well as response tag and size */
+   memset(rsp, 0, sizeof(*rsp));
+   switch (req->tag) {
+@@ -3878,4 +3881,3 @@ int tpm_handle_command(const uint8_t *in
+   tpm_free(rsp.param);
+   return 0;
+ }
+-
+diff -uprN orig/tpm_emulator-0.2/tpm/tpm_crypto.c vtpm/tpm/tpm_crypto.c
+--- orig/tpm_emulator-0.2/tpm/tpm_crypto.c     2005-08-17 10:58:36.000000000 
-0700
++++ vtpm/tpm/tpm_crypto.c      2005-08-17 10:55:52.000000000 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+  *                    Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -106,7 +107,7 @@ TPM_RESULT tpm_sign(TPM_KEY_DATA *key, T
+     /* setup TPM_SIGN_INFO structure */
+     memcpy(&buf[0], "\x05\x00SIGN", 6);
+     memcpy(&buf[6], auth->nonceOdd.nonce, 20);
+-    *(UINT32*)&buf[26] = cpu_to_be32(areaToSignSize);
++    *(UINT32*)&buf[26] = CPU_TO_BE32(areaToSignSize);
+     memcpy(&buf[30], areaToSign, areaToSignSize);
+     if (rsa_sign(&key->key, RSA_SSA_PKCS1_SHA1, 
+         buf, areaToSignSize + 30, *sig)) {
+@@ -379,4 +380,3 @@ TPM_RESULT TPM_CertifyKey2(TPM_KEY_HANDL
+   }  
+   return TPM_SUCCESS;
+ }
+-
+diff -uprN orig/tpm_emulator-0.2/tpm/tpm_data.c vtpm/tpm/tpm_data.c
+--- orig/tpm_emulator-0.2/tpm/tpm_data.c       2005-08-17 10:58:36.000000000 
-0700
++++ vtpm/tpm/tpm_data.c        2005-08-17 10:55:52.000000000 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+  *                    Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -15,9 +16,15 @@
+  * $Id: tpm_data.c 9 2005-04-26 18:15:31Z mast $
+  */
+ 
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <unistd.h>
++
+ #include "tpm_emulator.h"
+ #include "tpm_structures.h"
+ #include "tpm_marshalling.h"
++#include "vtpm_manager.h"
+ 
+ TPM_DATA tpmData;
+ 
+@@ -28,6 +35,7 @@ BOOL tpm_get_physical_presence(void)
+ 
+ void tpm_init_data(void)
+ {
++#ifndef TPM_GENERATE_EK
+   /* endorsement key */
+   uint8_t ek_n[] =  "\xa8\xdb\xa9\x42\xa8\xf3\xb8\x06\x85\x90\x76\x93\xad\xf7"
+     "\x74\xec\x3f\xd3\x3d\x9d\xe8\x2e\xff\x15\xed\x0e\xce\x5f\x93"
+@@ -66,6 +74,8 @@ void tpm_init_data(void)
+     "\xd1\xc0\x8b\x5b\xa2\x2e\xa7\x15\xca\x50\x75\x10\x48\x9c\x2b"
+     "\x18\xb9\x67\x8f\x5d\x64\xc3\x28\x9f\x2f\x16\x2f\x08\xda\x47"
+     "\xec\x86\x43\x0c\x80\x99\x07\x34\x0f";
++#endif
++
+   int i;
+   /* reset all data to NULL, FALSE or 0 */
+   memset(&tpmData, 0, sizeof(tpmData));
+@@ -85,6 +95,10 @@ void tpm_init_data(void)
+   tpmData.permanent.data.version.revMinor = VERSION_MINOR;
+   /* setup PCR attributes */
+   for (i = 0; i < TPM_NUM_PCR; i++) {
++    int j;
++    for (j=0; j < TPM_NUM_LOCALITY; j++) {
++      tpmData.permanent.data.pcrAttrib[i].pcrExtendLocal[j] = TRUE;
++    }
+     tpmData.permanent.data.pcrAttrib[i].pcrReset = TRUE;
+   }
+   /* set tick type */
+@@ -115,49 +129,235 @@ void tpm_release_data(void)
+ 
+ #ifdef TPM_STORE_TO_FILE
+ 
+-#include <linux/fs.h>
+-#include <linux/unistd.h>
+-#include <asm/uaccess.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++
++ static int vtpm_tx_fh=-1, vtpm_rx_fh=-1;
+ 
+-#define TPM_STORAGE_FILE "/var/tpm/tpm_emulator-1.2." STR(VERSION_MAJOR) "." 
STR(VERSION_MINOR) 
++#ifdef VTPM_MUTLI_VM
++ #define DEV_FE "/dev/tpm"
++#else
++ #define VTPM_RX_FIFO_D  "/var/vtpm/fifos/vtpm-to-%d.fifo"
++ #define VTPM_TX_FIFO  "/var/vtpm/fifos/vtpm-from-all.fifo"
++
++ extern int dmi_id;
++ static char *vtpm_rx_name=NULL; 
++#endif
+ 
+ static int write_to_file(uint8_t *data, size_t data_length)
+ {
+-  int res;
+-  struct file *fp;
+-  mm_segment_t old_fs = get_fs();
+-  fp = filp_open(TPM_STORAGE_FILE, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | 
S_IWUSR);
+-  if (IS_ERR(fp)) return -1;
+-  set_fs(get_ds());
+-  res = fp->f_op->write(fp, data, data_length, &fp->f_pos);
+-  set_fs(old_fs);
+-  filp_close(fp, NULL);
+-  return (res == data_length) ? 0 : -1;
++  int res, out_data_size, in_header_size;
++  BYTE *ptr, *out_data, *in_header;
++  UINT32 result, len, in_rsp_size;
++  UINT16 tag = VTPM_TAG_REQ;
++      
++  printf("Saving NVM\n");
++  if (vtpm_tx_fh < 0) {
++#ifdef VTPM_MUTLI_VM
++    vtpm_tx_fh = open(DEV_FE, O_RDWR);
++#else
++      vtpm_tx_fh = open(VTPM_TX_FIFO, O_WRONLY);
++#endif
++  }
++
++  if (vtpm_tx_fh < 0) {
++              return -1;
++  }
++ 
++  // Send request to VTPM Manager to encrypt data
++#ifdef VTPM_MUTLI_VM
++  out_data_size = len = VTPM_COMMAND_HEADER_SIZE_CLT + data_length;
++#else
++  out_data_size = len = VTPM_COMMAND_HEADER_SIZE_SRV + data_length;
++#endif
++  
++  out_data = ptr = (BYTE *) malloc(len);
++
++  if (ptr == NULL
++#ifndef VTPM_MUTLI_VM
++      || tpm_marshal_UINT32(&ptr, &len, dmi_id)
++#endif
++        || tpm_marshal_UINT16(&ptr, &len, tag)
++#ifdef VTPM_MUTLI_VM
++        || tpm_marshal_UINT32(&ptr, &len, out_data_size)
++#else
++        || tpm_marshal_UINT32(&ptr, &len, out_data_size - sizeof(uint32_t))
++#endif  
++        || tpm_marshal_UINT32(&ptr, &len, VTPM_ORD_SAVENVM)
++        || tpm_marshal_BYTE_ARRAY(&ptr, &len, data, data_length)) {
++      free(out_data);
++      return -1;
++  }
++  
++  printf("\tSending SaveNVM Command.\n");
++  res = write(vtpm_tx_fh, out_data, out_data_size);
++  free(out_data);
++  if (res != out_data_size) return -1;
++
++  if (vtpm_rx_fh < 0) {
++#ifdef VTPM_MUTLI_VM
++    vtpm_rx_fh = vtpm_tx_fh
++#else
++    if (vtpm_rx_name == NULL) {
++      vtpm_rx_name = malloc(10 + strlen(VTPM_RX_FIFO_D));
++      sprintf(vtpm_rx_name, VTPM_RX_FIFO_D, (uint32_t) dmi_id);
++    }
++      vtpm_rx_fh = open(vtpm_rx_name, O_RDONLY);
++#endif
++  }
++
++  if (vtpm_rx_fh < 0) {
++              return -1;
++  }
++  
++  // Read Header of response so we can get the size & status
++#ifdef VTPM_MUTLI_VM
++  in_header_size = len = VTPM_COMMAND_HEADER_SIZE_CLT;
++#else
++  in_header_size = len = VTPM_COMMAND_HEADER_SIZE_SRV;
++#endif
++  in_header = ptr = malloc(in_header_size);
++  
++  printf("\tReading SaveNVM header.\n");
++  res = read(vtpm_rx_fh, in_header, in_header_size);
++
++  if ( (res != in_header_size)
++#ifndef VTPM_MUTLI_VM
++       || tpm_unmarshal_UINT32(&ptr, &len, (UINT32*)&dmi_id)
++#endif
++         || tpm_unmarshal_UINT16(&ptr, &len, &tag)
++         || tpm_unmarshal_UINT32(&ptr, &len, &in_rsp_size)
++         || tpm_unmarshal_UINT32(&ptr, &len, &result) ) {
++        free(in_header);
++        return -1;
++  }
++  free(in_header);
++  
++  if (result != VTPM_SUCCESS) {
++      return -1;  
++  }
++
++#ifdef VTPM_MUTLI_VM
++  close(vtpm_tx_fh); close(vtpm_rx_fh);
++#endif
++        
++  printf("\tFinishing up SaveNVM\n");
++  return (0);
+ }
+ 
+ static int read_from_file(uint8_t **data, size_t *data_length)
+ {
+-  int res;
+-  struct file *fp;
+-  mm_segment_t old_fs = get_fs();
+-  fp = filp_open(TPM_STORAGE_FILE, O_RDONLY, 0);
+-  if (IS_ERR(fp)) return -1;
+-  *data_length = (size_t)fp->f_dentry->d_inode->i_size;
+-  /* *data_length = i_size_read(fp->f_dentry->d_inode); */
+-  *data = tpm_malloc(*data_length);
+-  if (*data == NULL) {
+-    filp_close(fp, NULL);
++  int res, out_data_size, in_header_size;
++  uint8_t *ptr, *out_data, *in_header;
++  UINT16 tag = VTPM_TAG_REQ;
++  UINT32 len, in_rsp_size, result;
++#ifdef VTPM_MUTLI_VM
++      int vtpm_rx_fh, vtpm_tx_fh;
++#endif
++      
++  printf("Loading NVM.\n");
++  if (vtpm_tx_fh < 0) {
++#ifdef VTPM_MUTLI_VM
++    vtpm_tx_fh = open(DEV_FE, O_RDWR);
++#else
++      vtpm_tx_fh = open(VTPM_TX_FIFO, O_WRONLY);
++#endif
++  }
++
++  if (vtpm_tx_fh < 0) {
++              return -1;
++  }
++ 
++  // Send request to VTPM Manager to encrypt data
++#ifdef VTPM_MUTLI_VM
++  out_data_size = len = VTPM_COMMAND_HEADER_SIZE_CLT;
++#else
++  out_data_size = len = VTPM_COMMAND_HEADER_SIZE_SRV;
++#endif
++  out_data = ptr = (BYTE *) malloc(len);
++
++  if (ptr == NULL
++#ifndef VTPM_MUTLI_VM
++      || tpm_marshal_UINT32(&ptr, &len, dmi_id)
++#endif  
++      || tpm_marshal_UINT16(&ptr, &len, tag)
++#ifdef VTPM_MUTLI_VM
++      || tpm_marshal_UINT32(&ptr, &len, out_data_size)
++#else
++      || tpm_marshal_UINT32(&ptr, &len, out_data_size - sizeof(uint32_t))
++#endif
++      || tpm_marshal_UINT32(&ptr, &len, VTPM_ORD_LOADNVM)) {
++    free(out_data);
+     return -1;
+   }
+-  set_fs(get_ds());
+-  res = fp->f_op->read(fp, *data, *data_length, &fp->f_pos);
+-  set_fs(old_fs);
+-  filp_close(fp, NULL);
++
++  printf("\tSending LoadNVM command\n");
++  res = write(vtpm_tx_fh, out_data, out_data_size);
++  free(out_data);
++  if (res != out_data_size) return -1;
++
++    if (vtpm_rx_fh < 0) {
++#ifdef VTPM_MUTLI_VM
++    vtpm_rx_fh = vtpm_tx_fh;
++#else
++    if (vtpm_rx_name == NULL) {
++      vtpm_rx_name = malloc(10 + strlen(VTPM_RX_FIFO_D));
++      sprintf(vtpm_rx_name, VTPM_RX_FIFO_D, (uint32_t) dmi_id);
++    }
++      vtpm_rx_fh = open(vtpm_rx_name, O_RDONLY);
++#endif
++  }
++
++  if (vtpm_rx_fh < 0) {
++              return -1;
++  }
++  
++  // Read Header of response so we can get the size & status
++#ifdef VTPM_MUTLI_VM
++  in_header_size = len = VTPM_COMMAND_HEADER_SIZE_CLT;
++#else
++  in_header_size = len = VTPM_COMMAND_HEADER_SIZE_SRV;
++#endif
++  in_header = ptr = malloc(in_header_size);
++  
++  printf("\tReading LoadNVM header\n");
++  res = read(vtpm_rx_fh, in_header, in_header_size);
++
++  if ( (res != in_header_size)
++#ifndef VTPM_MUTLI_VM
++       || tpm_unmarshal_UINT32(&ptr, &len, (UINT32*)&dmi_id)
++#endif
++       || tpm_unmarshal_UINT16(&ptr, &len, &tag)
++       || tpm_unmarshal_UINT32(&ptr, &len, &in_rsp_size)
++       || tpm_unmarshal_UINT32(&ptr, &len, &result) ) {
++      free(in_header);
++      return -1;
++  }
++  free(in_header);
++  
++  if (result != VTPM_SUCCESS) {
++      return -1;  
++  }
++
++  // Read Encrypted data from VTPM Manager
++  *data_length = in_rsp_size - VTPM_COMMAND_HEADER_SIZE_CLT;
++  *data = (uint8_t *) malloc(*data_length);
++
++  printf("\tReading clear data from LoadNVM.\n");
++  res = read(vtpm_rx_fh, *data, *data_length);
++#ifdef VTPM_MUTLI_VM
++  close(vtpm_rx_fh);close(vtpm_tx_fh);
++#endif 
++      
++  printf("\tReturing from loading NVM\n");
+   if (res != *data_length) {
+-    tpm_free(*data);
+-    return -1;
++      free(*data);
++      return -1;
++  } else {
++      return 0;
+   }
+-  return 0;
++
+ }
+ 
+ #else
+@@ -231,7 +431,6 @@ int tpm_restore_permanent_data(void)
+ 
+ int tpm_erase_permanent_data(void)
+ {
+-  int res = write_to_file("", 0);
++  int res = write_to_file((uint8_t*)"", 0);
+   return res;
+ }
+-
+diff -uprN orig/tpm_emulator-0.2/tpm/tpm_deprecated.c vtpm/tpm/tpm_deprecated.c
+--- orig/tpm_emulator-0.2/tpm/tpm_deprecated.c 2005-08-17 10:58:36.000000000 
-0700
++++ vtpm/tpm/tpm_deprecated.c  2005-08-17 10:55:52.000000000 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+  *                    Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -50,7 +51,7 @@ TPM_RESULT TPM_SaveKeyContext(TPM_KEY_HA
+   BYTE *ptr;
+   UINT32 len;
+   info("TPM_SaveKeyContext()");
+-  res = TPM_SaveContext(keyHandle, TPM_RT_KEY, "SaveKeyContext..", 
++  res = TPM_SaveContext(keyHandle, TPM_RT_KEY, (BYTE*)"SaveKeyContext..", 
+                         keyContextSize, &contextBlob);
+   if (res != TPM_SUCCESS) return res;
+   len = *keyContextSize;
+@@ -82,7 +83,7 @@ TPM_RESULT TPM_SaveAuthContext(TPM_AUTHH
+   BYTE *ptr;
+   UINT32 len;
+   info("TPM_SaveAuthContext()");
+-  res = TPM_SaveContext(authHandle, TPM_RT_KEY, "SaveAuthContext.", 
++  res = TPM_SaveContext(authHandle, TPM_RT_KEY, (BYTE*)"SaveAuthContext.", 
+                         authContextSize, &contextBlob);
+   if (res != TPM_SUCCESS) return res;
+   len = *authContextSize;
+diff -uprN orig/tpm_emulator-0.2/tpm/tpm_emulator.h vtpm/tpm/tpm_emulator.h
+--- orig/tpm_emulator-0.2/tpm/tpm_emulator.h   2005-08-17 10:58:36.000000000 
-0700
++++ vtpm/tpm/tpm_emulator.h    2005-08-17 10:55:52.000000000 -0700
+@@ -1,5 +1,6 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -22,7 +23,8 @@
+ /* TPM configuration */
+ #define TPM_STORE_TO_FILE       1
+ #undef  TPM_STRONG_PERSISTENCE
+-#undef  TPM_GENERATE_EK
++//#undef  TPM_GENERATE_EK
++#define  TPM_GENERATE_EK
+ 
+ /**
+  * tpm_emulator_init - initialises and starts the TPM emulator
+diff -uprN orig/tpm_emulator-0.2/tpm/tpm_integrity.c vtpm/tpm/tpm_integrity.c
+--- orig/tpm_emulator-0.2/tpm/tpm_integrity.c  2005-08-17 10:58:36.000000000 
-0700
++++ vtpm/tpm/tpm_integrity.c   2005-08-17 10:55:52.000000000 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+  *                    Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -194,4 +195,3 @@ TPM_RESULT tpm_verify_pcr(TPM_KEY_DATA *
+   }
+   return TPM_SUCCESS;
+ }
+-
+diff -uprN orig/tpm_emulator-0.2/tpm/tpm_structures.h vtpm/tpm/tpm_structures.h
+--- orig/tpm_emulator-0.2/tpm/tpm_structures.h 2005-08-17 10:58:36.000000000 
-0700
++++ vtpm/tpm/tpm_structures.h  2005-08-17 10:55:52.000000000 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+  *                    Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -18,7 +19,7 @@
+ #ifndef _TPM_STRUCTURES_H_
+ #define _TPM_STRUCTURES_H_
+ 
+-#include <linux/types.h>
++//#include <linux/types.h>
+ #include "crypto/rsa.h"
+ 
+ /*
+diff -uprN orig/tpm_emulator-0.2/tpm/tpm_testing.c vtpm/tpm/tpm_testing.c
+--- orig/tpm_emulator-0.2/tpm/tpm_testing.c    2005-08-17 10:58:36.000000000 
-0700
++++ vtpm/tpm/tpm_testing.c     2005-08-17 10:55:52.000000000 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+  *                    Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -95,24 +96,24 @@ static int tpm_test_sha1(void)
+   struct {
+     uint8_t *data; uint32_t repetitions; uint8_t *digest;
+   } test_cases[] =  {{
+-    "abc", 1,
+-    
"\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D"
++      (uint8_t*)"abc", 1,
++    
(uint8_t*)"\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D"
+   }, {
+-    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
+-    
"\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1"
++    (uint8_t*)"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
++    
(uint8_t*)"\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1"
+   }, {
+-    "a", 1000000,
+-    
"\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F"
++    (uint8_t*)"a", 1000000,
++    
(uint8_t*)"\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F"
+   }, {
+-    "0123456701234567012345670123456701234567012345670123456701234567", 10,
+-    
"\xDE\xA3\x56\xA2\xCD\xDD\x90\xC7\xA7\xEC\xED\xC5\xEB\xB5\x63\x93\x4F\x46\x04\x52"
++    
(uint8_t*)"0123456701234567012345670123456701234567012345670123456701234567", 
10,
++    
(uint8_t*)"\xDE\xA3\x56\xA2\xCD\xDD\x90\xC7\xA7\xEC\xED\xC5\xEB\xB5\x63\x93\x4F\x46\x04\x52"
+   }};
+ 
+   debug("tpm_test_sha1()");
+   for (i = 0; i < sizeof(test_cases) / sizeof(test_cases[0]); i++) {
+     sha1_init(&ctx);
+     for (j = 0; j < test_cases[i].repetitions; j++)
+-      sha1_update(&ctx, test_cases[i].data, strlen(test_cases[i].data));
++      sha1_update(&ctx, test_cases[i].data, 
strlen((char*)test_cases[i].data));
+     sha1_final(&ctx, digest);
+     if (memcmp(digest, test_cases[i].digest, SHA1_DIGEST_LENGTH) != 0) return 
-1;
+   }
+@@ -128,41 +129,41 @@ static int tpm_test_hmac(void)
+   struct {
+     uint8_t *key, key_len, *data, data_len, *digest;
+   } test_cases[] = {{
+-    "\x0b", 20, "Hi There", 8,
+-    
"\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00"
++    (uint8_t*)"\x0b", 20, (uint8_t*)"Hi There", 8,
++    
(uint8_t*)"\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00"
+   }, {
+-    "Jefe", 4, "what do ya want for nothing?", 28,
+-    
"\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79"
++    (uint8_t*)"Jefe", 4, (uint8_t*)"what do ya want for nothing?", 28,
++    
(uint8_t*)"\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79"
+   }, {
+-    "\xaa", 20, "\xdd", 50,
+-    
"\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3"
++    (uint8_t*)"\xaa", 20, (uint8_t*)"\xdd", 50,
++    
(uint8_t*)"\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3"
+   }, {
+-    
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
+-    "\x15\x16\x17\x18\x19", 25, "\xcd", 50,
+-    
"\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda"
++    
(uint8_t*)"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
++    "\x15\x16\x17\x18\x19", 25, (uint8_t*)"\xcd", 50,
++    
(uint8_t*)"\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda"
+   }, {
+-    "\x0c", 20, "Test With Truncation", 20,
+-    
"\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32\x4a\x9a\x5a\x04"
++    (uint8_t*)"\x0c", 20, (uint8_t*)"Test With Truncation", 20,
++    
(uint8_t*)"\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32\x4a\x9a\x5a\x04"
+   }, {
+-    "\xaa", 80, "Test Using Larger Than Block-Size Key - Hash Key First", 54,
+-    
"\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12"
++    (uint8_t*)"\xaa", 80, (uint8_t*)"Test Using Larger Than Block-Size Key - 
Hash Key First", 54,
++    
(uint8_t*)"\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12"
+   }, {
+-    "\xaa", 80,
+-    "Test Using Larger Than Block-Size Key and Larger Than One Block-Size 
Data", 73,
+-    
"\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91"
++    (uint8_t*)"\xaa", 80,
++    (uint8_t*)"Test Using Larger Than Block-Size Key and Larger Than One 
Block-Size Data", 73,
++    
(uint8_t*)"\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91"
+   }};
+ 
+   debug("tpm_test_hmac()");
+   for (i = 0; i < sizeof(test_cases) / sizeof(test_cases[0]); i++) {
+-    if (strlen(test_cases[i].key) < test_cases[i].key_len) {
++    if (strlen((char*)test_cases[i].key) < test_cases[i].key_len) {
+       uint8_t key[test_cases[i].key_len];
+       memset(key, test_cases[i].key[0], test_cases[i].key_len);
+       hmac_init(&ctx, key, test_cases[i].key_len);
+     } else {
+       hmac_init(&ctx, test_cases[i].key, test_cases[i].key_len);
+     }
+-    for (j = 0; j < test_cases[i].data_len; j += strlen(test_cases[i].data)) {
+-      hmac_update(&ctx, test_cases[i].data, strlen(test_cases[i].data));
++    for (j = 0; j < test_cases[i].data_len; j += 
strlen((char*)test_cases[i].data)) {
++      hmac_update(&ctx, test_cases[i].data, 
strlen((char*)test_cases[i].data));
+     }
+     hmac_final(&ctx, digest);
+     if (memcmp(digest, test_cases[i].digest, SHA1_DIGEST_LENGTH) != 0) return 
-1;
+@@ -173,9 +174,9 @@ static int tpm_test_hmac(void)
+ static int tpm_test_rsa_EK(void)
+ {
+   int res = 0;
+-  char *data = "RSA PKCS #1 v1.5 Test-String";
++  uint8_t *data = (uint8_t*)"RSA PKCS #1 v1.5 Test-String";
+   uint8_t buf[256];
+-  size_t buf_len, data_len = strlen(data);
++  size_t buf_len, data_len = strlen((char*)data);
+   rsa_private_key_t priv_key;
+   rsa_public_key_t pub_key;
+ 
+diff -uprN orig/tpm_emulator-0.2/tpm/tpm_ticks.c vtpm/tpm/tpm_ticks.c
+--- orig/tpm_emulator-0.2/tpm/tpm_ticks.c      2005-08-17 10:58:36.000000000 
-0700
++++ vtpm/tpm/tpm_ticks.c       2005-08-17 10:55:52.000000000 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+  *                    Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -37,9 +38,7 @@ TPM_RESULT TPM_SetTickType(TPM_TICKTYPE 
+ TPM_RESULT TPM_GetTicks(TPM_CURRENT_TICKS *currentTime)
+ {
+   info("TPM_GetTicks()");
+-  memcpy(currentTime, &tpmData.stany.data.currentTicks, 
+-    sizeof(TPM_CURRENT_TICKS));
+-  return TPM_SUCCESS;
++  return TPM_DISABLED_CMD;
+ }
+ 
+ TPM_RESULT TPM_TickStampBlob(TPM_KEY_HANDLE keyHandle, TPM_NONCE *antiReplay,
+@@ -47,61 +46,12 @@ TPM_RESULT TPM_TickStampBlob(TPM_KEY_HAN
+                              TPM_CURRENT_TICKS *currentTicks, 
+                              UINT32 *sigSize, BYTE **sig)
+ {
+-  TPM_RESULT res;
+-  TPM_KEY_DATA *key;
+-  BYTE *info, *p;
+-  UINT32 info_length, length;
+   info("TPM_TickStampBlob()");
+-  /* get key */
+-  key = tpm_get_key(keyHandle);
+-  if (key == NULL) return TPM_INVALID_KEYHANDLE;
+-  /* verify authorization */ 
+-  res = tpm_verify_auth(auth1, key->usageAuth, keyHandle);
+-  if (res != TPM_SUCCESS) return res;
+-  if (key->keyUsage != TPM_KEY_SIGNING && key->keyUsage != TPM_KEY_LEGACY
+-      && key->keyUsage != TPM_KEY_IDENTITY) return TPM_INVALID_KEYUSAGE;
+-  /* get current ticks */
+-  TPM_GetTicks(currentTicks);
+-  /* sign data using signature scheme PKCS1_SHA1 and TPM_SIGN_INFO container 
*/
+-  *sigSize = key->key.size >> 3;
+-  *sig = tpm_malloc(*sigSize);
+-  if (*sig == NULL) return TPM_FAIL; 
+-  /* setup TPM_SIGN_INFO structure */
+-  info_length = 30 + sizeof(TPM_DIGEST) + 
sizeof_TPM_CURRENT_TICKS(currentTicks);
+-  info = tpm_malloc(info_length);
+-  if (info == NULL) {
+-    tpm_free(*sig);
+-    return TPM_FAIL;
+-  }
+-  memcpy(&info[0], "\x05\x00TSTP", 6);
+-  memcpy(&info[6], antiReplay->nonce, 20);
+-  *(UINT32*)&info[26] = cpu_to_be32(20
+-                        + sizeof_TPM_CURRENT_TICKS(currentTicks));
+-  memcpy(&info[30], digestToStamp->digest, sizeof(TPM_DIGEST));
+-  p = &info[30 + sizeof(TPM_DIGEST)]; 
+-  length = sizeof_TPM_CURRENT_TICKS(currentTicks);
+-  if (tpm_marshal_TPM_CURRENT_TICKS(&p, &length, currentTicks)
+-      || rsa_sign(&key->key, RSA_SSA_PKCS1_SHA1, info, info_length, *sig)) {  
 
+-    tpm_free(*sig);
+-    tpm_free(info);
+-    return TPM_FAIL;
+-  } 
+-  return TPM_SUCCESS;
++  return TPM_DISABLED_CMD;
+ }
+ 
+ void tpm_update_ticks(void)
+ {
+-  if (tpmData.stany.data.currentTicks.tag == 0) {
+-    tpmData.stany.data.currentTicks.tag = TPM_TAG_CURRENT_TICKS;
+-    tpmData.stany.data.currentTicks.currentTicks += tpm_get_ticks();
+-    tpmData.stany.data.currentTicks.tickType = 
tpmData.permanent.data.tickType;
+-    tpm_get_random_bytes(tpmData.stany.data.currentTicks.tickNonce.nonce, 
+-      sizeof(TPM_NONCE));
+-    tpmData.stany.data.currentTicks.tickRate = 1;
+-    tpmData.stany.data.currentTicks.tickSecurity = TICK_SEC_NO_CHECK;
+-  } else {
+-    tpmData.stany.data.currentTicks.currentTicks += tpm_get_ticks();   
+-  }
+ }
+   
+ 
+diff -uprN orig/tpm_emulator-0.2/tpm/vtpm_manager.h vtpm/tpm/vtpm_manager.h
+--- orig/tpm_emulator-0.2/tpm/vtpm_manager.h   1969-12-31 16:00:00.000000000 
-0800
++++ vtpm/tpm/vtpm_manager.h    2005-08-17 10:55:52.000000000 -0700
+@@ -0,0 +1,126 @@
++// ===================================================================
++// 
++// Copyright (c) 2005, Intel Corp.
++// All rights reserved.
++//
++// Redistribution and use in source and binary forms, with or without 
++// modification, are permitted provided that the following conditions 
++// are met:
++//
++//   * Redistributions of source code must retain the above copyright 
++//     notice, this list of conditions and the following disclaimer.
++//   * Redistributions in binary form must reproduce the above 
++//     copyright notice, this list of conditions and the following 
++//     disclaimer in the documentation and/or other materials provided 
++//     with the distribution.
++//   * Neither the name of Intel Corporation nor the names of its 
++//     contributors may be used to endorse or promote products derived
++//     from this software without specific prior written permission.
++//
++// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
++// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
++// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
++// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
++// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
++// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
++// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
++// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
++// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
++// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++// OF THE POSSIBILITY OF SUCH DAMAGE.
++// ===================================================================
++// 
++// vtpm_manager.h
++// 
++//  Public Interface header for VTPM Manager
++//
++// ==================================================================
++
++#ifndef __VTPM_MANAGER_H__
++#define __VTPM_MANAGER_H__
++
++#define VTPM_TAG_REQ 0x01c1
++#define VTPM_TAG_RSP 0x01c4
++#define COMMAND_BUFFER_SIZE 4096
++
++// Header sizes. Note Header MAY include the DMI
++#define VTPM_COMMAND_HEADER_SIZE_SRV ( sizeof(UINT32) + sizeof(TPM_TAG) + 
sizeof(UINT32) + sizeof(TPM_COMMAND_CODE))
++#define VTPM_COMMAND_HEADER_SIZE_CLT (                  sizeof(TPM_TAG) + 
sizeof(UINT32) + sizeof(TPM_COMMAND_CODE))
++
++//************************ Command Codes ****************************
++#define VTPM_ORD_OPEN              1   // ULM Creates New DMI
++#define VTPM_ORD_CLOSE             2   // ULM Closes a DMI
++#define VTPM_ORD_DELETE            3   // ULM Permemently Deletes DMI
++#define VTPM_ORD_SAVENVM          4   // DMI requests Secrets Unseal
++#define VTPM_ORD_LOADNVM          5   // DMI requests Secrets Saved
++#define VTPM_ORD_TPMCOMMAND       6   // DMI issues HW TPM Command
++
++//************************ Return Codes ****************************
++#define VTPM_SUCCESS               0
++#define VTPM_FAIL                  1
++#define VTPM_UNSUPPORTED           2
++#define VTPM_FORBIDDEN             3
++#define VTPM_RESTORE_CONTEXT_FAILED    4
++#define VTPM_INVALID_REQUEST       5
++
++/******************* Command Parameter API *************************
++
++VTPM Command Format
++  dmi: 4 bytes                  // Source of message. 
++                                // WARNING: This is prepended by the channel. 
++                                // Thus it is received by VTPM Manager, 
++                                // but not sent by DMI
++  tpm tag: 2 bytes
++  command size: 4 bytes         // Size of command including header but not 
DMI
++  ord: 4 bytes                  // Command ordinal above
++  parameters: size - 10 bytes   // Command Parameter
++
++VTPM Response Format
++  tpm tag: 2 bytes
++  response_size: 4 bytes
++  status: 4 bytes         
++  parameters: size - 10 bytes
++
++
++VTPM_Open:
++  Input Parameters:
++    Domain_type: 1 byte
++    domain_id: 4 bytes
++    instance_id: 4 bytes
++  Output Parameters:
++    None
++    
++VTPM_Close
++  Input Parameters:
++    instance_id: 4 bytes
++  Output Parameters:
++    None
++
++VTPM_Delete
++  Input Parameters:
++    instance_id: 4 bytes
++  Output Parameters:
++    None
++
++VTPM_SaveNVM
++  Input Parameters:
++    data: n bytes (Header indicates size of data)
++  Output Parameters:
++    None
++
++VTPM_LoadNVM
++  Input Parameters:
++    None
++  Output Parameters:
++    data: n bytes (Header indicates size of data)
++
++VTPM_TPMCommand
++  Input Parameters:
++    TPM Command Byte Stream: n bytes 
++  Output Parameters:
++    TPM Reponse Byte Stream: n bytes 
++
++*********************************************************************/
++
++#endif //_VTPM_MANAGER_H_
+diff -uprN orig/tpm_emulator-0.2/tpmd.c vtpm/tpmd.c
+--- orig/tpm_emulator-0.2/tpmd.c       1969-12-31 16:00:00.000000000 -0800
++++ vtpm/tpmd.c        2005-08-17 10:55:52.000000000 -0700
+@@ -0,0 +1,207 @@
++/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
++ * Copyright (C) 2005 INTEL Corp
++ *
++ * This module is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published
++ * by the Free Software Foundation; either version 2 of the License,
++ * or (at your option) any later version.
++ *
++ * This module is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <string.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <sys/time.h>
++
++#include "tpm_emulator.h"
++#include "vtpm_manager.h"
++
++#ifdef VTPM_MULTI_VM
++ #define DEV_BE "/dev/vtpm"
++#else
++ #define GUEST_RX_FIFO_D "/var/vtpm/fifos/guest-to-%d.fifo"
++ #define GUEST_TX_FIFO "/var/vtpm/fifos/guest-from-all.fifo"
++
++ int dmi_id;
++#endif
++                                              
++#define BUFFER_SIZE 2048
++
++static uint8_t ctrl_msg[] = { 0, 0, 0, 0,   // destination
++                              1, 193,       // VTPM_TAG
++                              0, 0, 0, 10,  // Size
++                              0, 0, 0, 0};  // TPM_SUCCESS
++                            
++
++static int devurandom=0;
++
++        
++void get_random_bytes(void *buf, int nbytes) {
++  
++  if (devurandom == 0) {
++    devurandom = open("/dev/urandom", O_RDONLY);
++  }
++
++  if (read(devurandom, buf, nbytes) != nbytes) {
++      printf("Can't get random number.\n");
++      exit(-1);
++  }
++}
++
++uint64_t tpm_get_ticks(void)
++{
++  //struct timeval tv;
++  //int gettimeofday(&tv, struct timezone *tz);
++  return 0;
++}
++
++int main(int argc, char **argv)
++{
++  uint8_t in[BUFFER_SIZE], *out, *addressed_out;
++  uint32_t out_size;
++  int in_size, written ;
++  int i, guest_id=-1;
++ 
++  int vtpm_tx_fh=-1, vtpm_rx_fh=-1;
++#ifdef VTPM_MULTI_VM
++  if (argc < 2) {
++    printf("Usage: tpmd clear|save|deactivated\n" );
++#else
++  if (argc < 3) {
++    printf("Usage: tpmd clear|save|deactivated vtpmid\n" );
++#endif
++        return -1;
++  }
++
++#ifndef VTPM_MULTI_VM
++  dmi_id = atoi(argv[2]);
++#endif
++
++  /* initialize TPM emulator */
++  if (!strcmp(argv[1], "clear")) {
++    printf("Initializing tpm: %s\n", argv[1]);
++    tpm_emulator_init(1);
++  } else if (!strcmp(argv[1], "save")) { 
++    printf("Initializing tpm: %s\n", argv[1]);
++    tpm_emulator_init(2);
++  } else if (!strcmp(argv[1], "deactivated")) {
++    printf("Initializing tpm: %s\n", argv[1]);
++    tpm_emulator_init(3);
++  } else {
++    printf("invalid startup mode '%s'; must be 'clear', "
++      "'save' (default) or 'deactivated", argv[1]);
++    return -1;
++  }
++
++  char *guest_rx_file = malloc(10 + strlen(GUEST_RX_FIFO_D));
++  sprintf(guest_rx_file, GUEST_RX_FIFO_D, (uint32_t) dmi_id);
++  
++  while (1) {
++abort_command:
++    if (vtpm_rx_fh < 0) {
++#ifdef VTPM_MUTLI_VM
++        vtpm_rx_fh = open(DEV_BE, O_RDWR);
++#else
++      vtpm_rx_fh = open(guest_rx_file, O_RDONLY);
++#endif
++    }
++    
++    if (vtpm_rx_fh < 0) {
++      printf("ERROR: failed to open devices to listen to guest.\n");
++      return -1;
++    }
++    
++    in_size = read(vtpm_rx_fh, in, BUFFER_SIZE);
++    if (in_size < 6) { // Magic size of minium TPM command
++      printf("Recv[%d] to small: 0x", in_size);
++      if (in_size <= 0) {
++          close(vtpm_rx_fh);
++          vtpm_rx_fh = -1;
++          goto abort_command;
++      }
++    } else { 
++      printf("Recv[%d]: 0x", in_size);
++      for (i=0; i< in_size; i++) 
++        printf("%x ", in[i]);
++      printf("\n");
++    }
++
++    if (guest_id == -1) {
++        guest_id = *((uint32_t *) in);
++        *((uint32_t *) ctrl_msg) = *((uint32_t *) in);
++    } else {
++        if (guest_id != *((uint32_t *) in) ) {
++            printf("WARNING: More than one guest attached\n");
++        }
++    }
++
++    if (vtpm_tx_fh < 0) {
++#ifdef VTPM_MUTLI_VM
++        vtpm_tx_fh = open(DEV_BE, O_RDWR);
++        vtpm_rx_fh = vtpm_tx_fh;
++#else
++      vtpm_tx_fh = open(GUEST_TX_FIFO, O_WRONLY);
++#endif
++    }
++
++    if (vtpm_tx_fh < 0) {
++      printf("ERROR: failed to open devices to respond to guest.\n");
++      return -1;
++    }
++    
++    // Handle command, but we need to skip the identifier
++    if (  BE16_TO_CPU( ((uint16_t *) in)[2] ) == VTPM_TAG_REQ ) { // Control 
message from xend
++      // This DM doesn't really care about ctrl messages. Just ACK the message
++      written = write(vtpm_tx_fh, ctrl_msg, sizeof(ctrl_msg));
++
++      if (written != sizeof(ctrl_msg)) {
++        printf("ERROR: Part of response not written %d/%d.\n", written, 
sizeof(ctrl_msg));
++      } else {
++        printf("Send Ctrl Message confermation\n");
++      }
++    } else { // Message from Guest
++      if (tpm_handle_command(in + sizeof(uint32_t), in_size - 
sizeof(uint32_t), &out, &out_size) != 0) { 
++        printf("ERROR: Handler Failed.\n");
++      }
++
++      addressed_out = (uint8_t *) tpm_malloc(sizeof(uint32_t) + out_size);
++      *(uint32_t *) addressed_out = *(uint32_t *) in;
++      memcpy(addressed_out + sizeof(uint32_t), out, out_size);
++
++      written = write(vtpm_tx_fh, addressed_out, out_size + sizeof(uint32_t));
++
++      if (written != out_size + sizeof(uint32_t)) {
++        printf("ERROR: Part of response not written %d/%d.\n", written, 
out_size);
++        for (i=0; i< out_size+ sizeof(uint32_t); i++)
++          printf("%x ", addressed_out[i]);
++        printf("\n");
++      } else {
++        printf("Sent[%d]: ", out_size + sizeof(uint32_t));
++        for (i=0; i< out_size+ sizeof(uint32_t); i++)
++          printf("%x ", addressed_out[i]);
++        printf("\n");
++      }
++      tpm_free(out);
++      tpm_free(addressed_out);
++    }
++
++  } // loop
++
++  tpm_emulator_shutdown();
++
++  close(vtpm_tx_fh);
++#ifndef VTPM_MUTLI_VM
++  close(vtpm_rx_fh);
++  free (guest_rx_file);
++#endif
++
++}
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/COPYING
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/COPYING        Thu Sep  1 10:16:14 2005
@@ -0,0 +1,32 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/Makefile
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/Makefile       Thu Sep  1 10:16:14 2005
@@ -0,0 +1,31 @@
+XEN_ROOT = ../..
+
+# Base definitions and rules
+include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
+
+SUBDIRS                = crypto tcs util manager
+
+all: build
+
+build:
+       @set -e; for subdir in $(SUBDIRS); do \
+               $(MAKE) -C $$subdir $@; \
+       done
+
+install: build
+       @set -e; for subdir in $(SUBDIRS); do \
+               $(MAKE) -C $$subdir $@; \
+       done
+
+clean:
+       @set -e; for subdir in $(SUBDIRS); do \
+               $(MAKE) -C $$subdir $@; \
+       done
+
+
+mrproper:
+       @set -e; for subdir in $(SUBDIRS); do \
+               $(MAKE) -C $$subdir $@; \
+       done
+
+
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/README
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/README Thu Sep  1 10:16:14 2005
@@ -0,0 +1,89 @@
+// ===================================================================
+//
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above
+//     copyright notice, this list of conditions and the following
+//     disclaimer in the documentation and/or other materials provided
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+
+Directory Structure
+===================
+tools/vtpm_manager/crypto    -> crypto files
+tools/vtpm_manager/TCS       -> TCS implementation
+tools/vtpm_manager/util      -> Utility Library. Include disk-io and buffers.
+tools/vtpm_manager/manager   -> VTPM Manager
+
+Compile Flags
+===================
+LOGGING_MODULES              -> How extensive logging happens
+                                see util/log.h for more info
+
+VTPM_MULTI_VM                -> Defined: VTPMs run in their own VMs
+                                Not Defined (default): VTPMs are processes
+
+# Debugging flags that may disappear without notice in the future
+
+DUMMY_BACKEND                -> vtpm_manager listens on /tmp/in.fifo and 
+                                /tmp/out.fifo rather than backend
+
+MANUAL_DM_LAUNCH             -> User must manually launch & kill VTPMs
+
+USE_FIXED_SRK_AUTH           -> Do not randomly generate a random SRK & Owner 
auth
+
+Requirements
+============
+- xen-unstable 
+- IBM frontend/backend vtpm driver patch
+
+Single-VM Flow
+============================
+- Launch the VTPM manager (vtpm_managerd) which which begins listening to the 
BE with one thread
+  and listens to a named fifo that is shared by the vtpms to commuincate with 
the manager.
+- VTPM Manager listens to TPM BE.
+- When xend launches a tpm frontend equipped VM it contacts the manager over 
the vtpm backend. 
+- When the manager receives the open message from the BE, it launches a vtpm
+- Xend allows the VM to continue booting. 
+- When a TPM request is issued to the front end, the front end transmits the 
TPM request to the backend.
+- The manager receives the TPM requests and uses a named fifo to forward the 
request to the vtpm.
+- The fifo listener begins listening for the reply from vtpm for the request.
+- Vtpm processes request and replies to manager over shared named fifo.
+- If needed, the vtpm may send a request to the vtpm_manager at any time to 
save it's secrets to disk.
+- Manager receives response from vtpm and passes it back to backend for 
forwarding to guest.
+
+NOTES:
+* SaveService SHOULD seal it's table before saving it to disk. However,
+  the current Xen infrastructure does not provide a mechanism for this to be
+  unsealed later. Specifically, the auth and wrapped key must be available ONLY
+  to the service, or it's not even worth encrypting
+
+  In the future the vtpm manager will be protected by an early boot mechanism
+  that will allow for better protection of it's data.
+
+TODO:
+- Timeout on crashed vtpms
+- create lock for shared fifo for talking to vtpms.
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/Rules.mk
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/Rules.mk       Thu Sep  1 10:16:14 2005
@@ -0,0 +1,68 @@
+# Base definitions and rules (XEN_ROOT must be defined in including Makefile)
+include $(XEN_ROOT)/tools/Rules.mk
+
+#
+# Tool definitions
+#
+
+# Installation program and options
+INSTALL         = install
+INSTALL_PROG    = $(INSTALL) -m0755
+INSTALL_DIR     = $(INSTALL) -d -m0755
+
+# Xen tools installation directory
+TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin
+
+# General compiler flags
+CFLAGS = -Wall -Werror -g3 -I.
+
+# For generating dependencies
+CFLAGS += -Wp,-MD,.$(@F).d
+
+DEP_FILES      = .*.d
+
+# Generic project files
+HDRS   = $(wildcard *.h)
+SRCS   = $(wildcard *.c)
+OBJS   = $(patsubst %.c,%.o,$(SRCS))
+
+# Generic (non-header) dependencies
+$(SRCS): Makefile $(XEN_ROOT)/tools/Rules.mk 
$(XEN_ROOT)/tools/vtpm_manager/Rules.mk
+
+$(OBJS): $(SRCS)
+
+-include $(DEP_FILES)
+
+# Make sure these are just rules
+.PHONY : all build install clean
+
+#
+# Project-specific definitions
+#
+
+# Logging Level. See utils/tools.h for usage
+CFLAGS += 
-DLOGGING_MODULES="(BITMASK(VTPM_LOG_TCS)|BITMASK(VTPM_LOG_VTSP)|BITMASK(VTPM_LOG_VTPM)|BITMASK(VTPM_LOG_VTPM_DEEP))"
+
+# Silent Mode
+#CFLAGS += -DLOGGING_MODULES=0x0
+#CFLAGS += -DLOGGING_MODULES=0xff
+
+# Use frontend/backend pairs between manager & DMs?
+#CFLAGS += -DVTPM_MULTI_VM
+
+# vtpm_manager listens on /tmp/in.fifo and /tmp/out.fifo rather than backend
+#CFLAGS += -DDUMMY_BACKEND
+
+# Do not have manager launch DMs.
+#CFLAGS += -DMANUAL_DM_LAUNCH
+
+# Fixed SRK
+CFLAGS += -DUSE_FIXED_SRK_AUTH
+
+# TPM Hardware Device or TPM Simulator
+#CFLAGS += -DTPM_HWDEV
+
+# Include
+CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/crypto
+CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/util
+CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/tcs
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/crypto/Makefile
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/crypto/Makefile        Thu Sep  1 10:16:14 2005
@@ -0,0 +1,18 @@
+XEN_ROOT = ../../..
+include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
+
+BIN            = libtcpaCrypto.a
+
+all: build
+
+build: $(BIN)
+
+install: build
+
+clean:
+       rm -f *.a *.so *.o *.rpm $(DEP_FILES)
+
+mrproper: clean
+
+$(BIN): $(OBJS)
+       $(AR) rcs $(BIN) $(OBJS)
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/crypto/crypto.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/crypto/crypto.c        Thu Sep  1 10:16:14 2005
@@ -0,0 +1,88 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// crypto.c
+// 
+//  This file will handle all the TPM Crypto functionality
+// 
+// ==================================================================
+
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include "crypto.h"
+#include "log.h"
+
+/**
+ * Initialize cryptography library
+ * @rand: random seed
+ * @size: size of @rand
+ */
+void Crypto_Init(const BYTE* rand, int size) {
+       ERR_load_crypto_strings();
+  CRYPTO_malloc_init();
+  OpenSSL_add_all_algorithms();
+  SYM_CIPHER = EVP_aes_128_cbc();
+  RAND_poll();
+  if (rand == NULL)
+    return;
+
+  RAND_add(rand, size, size);
+}
+
+/**
+ * Shutdown cryptography library
+ */
+void Crypto_Exit() {
+  ERR_free_strings();
+  ERR_remove_state(0);
+  EVP_cleanup();
+}
+
+
+/**
+ * Get random data
+ * @data: (OUT) Random data
+ * @size: Size of @data
+ */
+void Crypto_GetRandom(void* data, int size) {
+  int result;
+  
+  result = RAND_pseudo_bytes((BYTE*) data, size);
+  
+  if (result <= 0) 
+    vtpmlogerror (VTPM_LOG_CRYPTO, "RAND_pseudo_bytes failed: %s\n",
+            ERR_error_string (ERR_get_error(), NULL));
+}
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/crypto/crypto.h
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/crypto/crypto.h        Thu Sep  1 10:16:14 2005
@@ -0,0 +1,175 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// crypto.h
+// 
+//  This file defines the TPM Crypto API
+//
+// ==================================================================
+
+#ifndef __CRYPTO_H__
+#define __CRYPTO_H__
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "tcg.h"
+#include "sym_crypto.h"
+
+#define CRYPTO_MAX_SIG_SIZE (2048 / 8)
+#define CRYPTO_MAX_RSA_KEY_SIZE (4096 / 8) //in bytes
+
+#define OAEP_P "TCPA"
+#define OAEP_P_SIZE 4
+
+// Algorithms supported by crypto. Stored in CRYPTO_INFO.algorithmID
+#define CRYPTO_ALGORITH_RSA 0x01
+
+// Supported Encryption Schemes CRYPTO_INFO.encScheme
+#define CRYPTO_ES_NONE 0x0001
+#define CRYPTO_ES_RSAESPKCSv15 0x0002
+#define CRYPTO_ES_RSAESOAEP_SHA1_MGF1 0x0003
+
+// Supported Signature schemes CRYPTO_INFO.sigScheme
+#define CRYPTO_SS_NONE 0x0001
+#define CRYPTO_SS_RSASSAPKCS1v15_SHA1 0x0002
+#define CRYPTO_SS_RSASSAPKCS1v15_DER 0x0003
+
+typedef struct CRYPTO_INFO {
+  void *keyInfo;
+  UINT32 algorithmID;
+  UINT32 encScheme;
+  UINT32 sigScheme;
+} CRYPTO_INFO;
+
+
+void Crypto_Init(const BYTE* rand, int size);
+
+void Crypto_Exit();
+
+void Crypto_GetRandom(void* data, int size);
+
+void Crypto_HMAC(   const BYTE* text, 
+                    int text_len, 
+                    const BYTE* key, 
+                    int key_len,
+                    BYTE* digest);
+
+TPM_RESULT Crypto_HMAC_buf (const buffer_t * text,
+                            const buffer_t * key,
+                            BYTE * o_digest); /* presumably of 20 bytes */
+    
+void Crypto_SHA1Full(   const BYTE* text, 
+                        UINT32 size,
+                        BYTE* hash); //Complete 3part SHA1
+
+// o_hash needs to be large enough to hold the digest, ie 20 bytes
+TPM_RESULT Crypto_SHA1Full_buf (const buffer_t * buf,
+                                BYTE * o_hash);
+    
+void Crypto_SHA1Start(UINT32* maxNumBytes);
+void Crypto_SHA1Update(int numBytes, const BYTE* hashData);
+void Crypto_SHA1Complete(   int hashDataSize, 
+                            const BYTE* hashData, 
+                            BYTE* hashValue);
+
+void Crypto_RSACreateKey(   /*in*/ UINT32 keySize,
+                            /*in*/ UINT32 pubExpSize, 
+                            /*in*/ BYTE *pubExp,
+                            /*out*/ UINT32 *privExpSize, 
+                            /*out*/ BYTE *privExp,
+                            /*out*/ UINT32 *modulusSize,
+                            /*out*/ BYTE *modulus,
+                            /*out*/ CRYPTO_INFO *keys);
+                            
+void Crypto_RSABuildCryptoInfo( /*[IN]*/ UINT32 pubExpSize, 
+                                /*[IN]*/ BYTE *pubExp,
+                                /*[IN]*/ UINT32 privExpSize, 
+                                /*[IN]*/ BYTE *privExp,
+                                /*[IN]*/ UINT32 modulusSize, 
+                                /*[IN]*/ BYTE *modulus, 
+                                /*[OUT]*/ CRYPTO_INFO* cryptoInfo);
+                                
+void Crypto_RSABuildCryptoInfoPublic(   /*[IN]*/ UINT32 pubExpSize, 
+                                        /*[IN]*/ BYTE *pubExp,
+                                        /*[IN]*/ UINT32 modulusSize, 
+                                        /*[IN]*/ BYTE *modulus, 
+                                        CRYPTO_INFO* cryptoInfo);
+
+//
+// symmetric pack and unpack operations
+//
+TPM_RESULT Crypto_RSAPackCryptoInfo (const CRYPTO_INFO* cryptoInfo,
+                                     BYTE ** io_buf, UINT32 * io_buflen);
+
+TPM_RESULT Crypto_RSAUnpackCryptoInfo (CRYPTO_INFO * ci,
+                                       BYTE * in, UINT32 len,
+                                       UINT32 * o_lenread);
+
+                             
+// return 0 on success, -1 on error
+int Crypto_RSAEnc(  CRYPTO_INFO *keys,
+                    UINT32 inDataSize,
+                    BYTE *inData,
+                    /*out*/ UINT32 *outDataSize,
+                    /*out*/ BYTE *outData);
+
+// return 0 on success, -1 on error
+int Crypto_RSADec(  CRYPTO_INFO *keys,
+                    UINT32 inDataSize,
+                    BYTE *inData,
+                    /*out*/ UINT32 *outDataSize,
+                    /*out*/ BYTE *outData);
+
+// return 0 on success, -1 on error
+int Crypto_RSASign( CRYPTO_INFO *keys,
+                    UINT32 inDataSize,
+                    BYTE *inData,
+                    /*out*/ UINT32 *sigSize,
+                    /*out*/ BYTE *sig);
+
+bool Crypto_RSAVerify(  CRYPTO_INFO *keys,
+                        UINT32 inDataSize,
+                        BYTE *inData,
+                        UINT32 sigSize,
+                        BYTE *sig);
+
+//private:
+int RSA_verify_DER(int dtype, unsigned char *m, unsigned int m_len,
+                   unsigned char *sigbuf, unsigned int siglen, CRYPTO_INFO 
*key);
+
+int RSA_sign_DER(int type, unsigned char *m, unsigned int m_len,
+              unsigned char *sigret, unsigned int *siglen, CRYPTO_INFO *key);
+
+#endif // __CRYPTO_H__
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/crypto/hash.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/crypto/hash.c  Thu Sep  1 10:16:14 2005
@@ -0,0 +1,153 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// hash.c
+// 
+//  This file will handle all the TPM Hash functionality
+//
+// ==================================================================
+
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/hmac.h>
+#include <openssl/sha.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+
+#include "tcg.h"         // for TPM_SUCCESS
+#include "crypto.h"
+
+static SHA_CTX g_shaContext;
+
+void Crypto_HMAC(   const BYTE* text, 
+                    int text_len, 
+                    const BYTE* key, 
+                    int key_len, 
+                    BYTE* digest) {
+  if (text == NULL || key == NULL || text_len == 0 || key_len == 0) 
+    return;
+  
+  HMAC(EVP_sha1(), key, key_len, text, text_len, digest, NULL);
+}
+
+TPM_RESULT Crypto_HMAC_buf (const buffer_t * text,
+                           const buffer_t * key,
+                           BYTE * o_digest) { /* presumably of 20 bytes */
+  
+  Crypto_HMAC (text->bytes, text->size, 
+              key->bytes, key->size,
+              o_digest);
+  
+  return TPM_SUCCESS;
+}
+
+
+/*
+ * SHA1
+ * (OUT) Create a SHA1 hash of text. Calls all three SHA1 steps internally
+ */
+void Crypto_SHA1Full( const BYTE* text, 
+      uint32_t size, 
+      BYTE* hash) {
+
+  if (text == NULL || size == 0) 
+    return;
+  
+  // Run SHA1Start + SHAUpdate (if necessary) + SHAComplete
+  uint32_t maxBytes; // Not used for anything
+  Crypto_SHA1Start(&maxBytes);
+  
+  while (size > 64){
+    Crypto_SHA1Update(64, text); 
+    size -= 64;
+    text += 64;
+  }
+  
+  Crypto_SHA1Complete(size, text, hash);
+}
+
+// same thing using buffer_t
+TPM_RESULT Crypto_SHA1Full_buf (const buffer_t * buf,
+                                 BYTE * o_digest) {
+
+  if (buf->bytes == NULL || buf->size == 0) 
+    return TPM_BAD_PARAMETER;
+  
+  Crypto_SHA1Full (buf->bytes, buf->size, o_digest);
+  
+  return TPM_SUCCESS;
+}
+
+
+/*
+ * Initialize SHA1
+ * (OUT) Maximum number of bytes that can be sent to SHA1Update. 
+ *   Must be a multiple of 64 bytes.
+ */
+void Crypto_SHA1Start(uint32_t* maxNumBytes) {
+  int max = SHA_CBLOCK;
+  // Initialize the crypto library
+  SHA1_Init(&g_shaContext);
+  *maxNumBytes = max;
+}
+
+/*
+ * Process SHA1
+ * @numBytes: (IN) The number of bytes in hashData. 
+ *       Must be a multiple of 64 bytes.
+ * @hashData: (IN) Bytes to be hashed.
+ */
+void Crypto_SHA1Update(int numBytes, const BYTE* hashData) {
+
+  if (hashData == NULL || numBytes == 0 || numBytes%64 != 0) 
+    return;
+  
+  SHA1_Update(&g_shaContext, hashData, numBytes); 
+}
+
+/*
+ * Complete the SHA1 process
+ * @hashDataSize: (IN) Number of bytes in hashData.
+ *       Must be a multiple of 64 bytes.
+ * @hashData: (IN) Final bytes to be hashed.
+ * @hashValue: (OUT) The output of the SHA-1 hash.
+ */
+void Crypto_SHA1Complete(int hashDataSize, 
+                        const BYTE* hashData, 
+                        BYTE* hashValue) {
+  SHA1_Update(&g_shaContext, hashData, hashDataSize);
+  SHA1_Final(hashValue, &g_shaContext);
+}
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/crypto/rsa.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/crypto/rsa.c   Thu Sep  1 10:16:14 2005
@@ -0,0 +1,434 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// rsa.c
+// 
+//  This file will handle all the TPM RSA crypto functionality
+// 
+// ==================================================================
+
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+
+#include <openssl/err.h>
+#include <stdio.h>
+
+#include "tcg.h"
+#include "buffer.h"
+#include "crypto.h"
+#include "log.h"
+
+void Crypto_RSACreateKey(   /*in*/ UINT32 keySize,
+                            /*in*/ UINT32 pubExpSize, 
+                            /*in*/ BYTE *pubExp,
+                            /*out*/ UINT32 *privExpSize, 
+                            /*out*/ BYTE *privExp,
+                            /*out*/ UINT32 *modulusSize,        
+                            /*out*/ BYTE *modulus,
+                            /*out*/ CRYPTO_INFO *keys) {
+  unsigned long e_value;
+  
+  if (pubExpSize == 0) // Default e = 2^16+1
+    e_value = (0x01 << 16) + 1;
+  else {
+    // This is not supported, but the following line MIGHT work
+    // under then assumption that the format is BigNum compatable
+    // Though it's not in the spec, so who knows what it is.
+    // Forcing the default.
+    //BN_bin2bn(pubExp, pubExpSize, NULL);
+    e_value = (0x01 << 16) + 1;
+  }
+
+  RSA *rsa = RSA_generate_key(keySize, e_value, NULL, NULL);
+  
+  if (keys) {
+    keys->keyInfo = rsa;
+    keys->algorithmID = CRYPTO_ALGORITH_RSA;
+  }
+  
+  if (modulus)   *modulusSize   = BN_bn2bin(rsa->n, modulus);
+  if (privExp)   *privExpSize   = BN_bn2bin(rsa->d, privExp);
+}
+
+// Create a CRYPTO_INFO struct from the BYTE * key parts. 
+// If pubExp info is NULL, use TCG default.
+// If there is a remainder while calculating the privExp, return FALSE.
+
+void Crypto_RSABuildCryptoInfo( /*[IN]*/ UINT32 pubExpSize, 
+                                /*[IN]*/ BYTE *pubExp,
+                                /*[IN]*/ UINT32 privExpSize, 
+                                /*[IN]*/ BYTE *privExp,
+                                /*[IN]*/ UINT32 modulusSize, 
+                                /*[IN]*/ BYTE *modulus, 
+                                CRYPTO_INFO* cryptoInfo) {
+  cryptoInfo->keyInfo = RSA_new();
+  RSA *rsa = (RSA *) cryptoInfo->keyInfo;
+  
+  rsa->e = BN_new();
+  
+  if (pubExpSize == 0) { // Default e = 2^16+1
+    BN_set_bit(rsa->e, 16);
+    BN_set_bit(rsa->e, 0);
+  } else {
+    // This is not supported, but the following line MIGHT work
+    // under then assumption that the format is BigNum compatable
+    // Though it's not in the spec, so who knows what it is.
+    // Forcing the default.
+    //BN_bin2bn(pubExp, pubExpSize, NULL);
+    BN_set_bit(rsa->e, 16);
+    BN_set_bit(rsa->e, 0);
+  }
+  
+  rsa->n = BN_bin2bn(modulus, modulusSize, NULL);
+  rsa->d = BN_bin2bn(privExp, privExpSize, NULL);
+}
+
+// Create a CRYPTO_INFO struct from the BYTE * key parts. 
+// If pubExp info is NULL, use TCG default.
+// If there is a remainder while calculating the privExp, return FALSE.
+
+void Crypto_RSABuildCryptoInfoPublic(   /*[IN]*/ UINT32 pubExpSize, 
+                                        /*[IN]*/ BYTE *pubExp,
+                                        /*[IN]*/ UINT32 modulusSize, 
+                                        /*[IN]*/ BYTE *modulus, 
+                                        CRYPTO_INFO* cryptoInfo) {
+  cryptoInfo->keyInfo = RSA_new();
+  RSA *rsa = (RSA *) cryptoInfo->keyInfo;
+  
+  rsa->e = BN_new();
+  
+  if (pubExpSize == 0) { // Default e = 2^16+1
+    BN_set_bit(rsa->e, 16);
+    BN_set_bit(rsa->e, 0);
+  } else {
+    // This is not supported, but the following line MIGHT work
+    // under then assumption that the format is BigNum compatable
+    // Though it's not in the spec, so who knows what it is.
+    // Forcing the default.
+    //BN_bin2bn(pubExp, pubExpSize, NULL);
+    BN_set_bit(rsa->e, 16);
+    BN_set_bit(rsa->e, 0);
+  }
+  
+  rsa->n = BN_bin2bn(modulus, modulusSize, NULL);
+  
+}
+
+int Crypto_RSAEnc(  CRYPTO_INFO *key,
+                   UINT32 inDataSize,
+                   BYTE *inData,
+                   /*out*/ UINT32 *outDataSize,
+                   /*out*/ BYTE *outData) {
+  RSA *rsa = (RSA *) key->keyInfo;
+  UINT32 paddedDataSize = RSA_size (rsa);
+  BYTE *paddedData = (BYTE *)malloc(sizeof(BYTE) * paddedDataSize);
+  int rc;
+    
+  if (paddedData == NULL) 
+    return -1;
+
+  *outDataSize = 0;
+  
+  switch (key->encScheme) {
+  case CRYPTO_ES_RSAESPKCSv15:
+    if (RSA_padding_add_PKCS1_type_2(paddedData, paddedDataSize, inData, 
inDataSize) <= 0) {
+      rc = -1; 
+      goto abort_egress;
+    }
+    break;
+  case CRYPTO_ES_RSAESOAEP_SHA1_MGF1:
+    if 
(RSA_padding_add_PKCS1_OAEP(paddedData,paddedDataSize,inData,inDataSize, (BYTE 
*) OAEP_P,OAEP_P_SIZE) <= 0 ) {
+      rc = -1; 
+      goto abort_egress;
+    }
+    break;
+  default:
+    rc = -1; 
+    goto abort_egress;
+  }
+  
+  rc = RSA_public_encrypt(paddedDataSize, paddedData, outData, rsa, 
RSA_NO_PADDING);
+  if (rc == -1)
+    goto abort_egress; 
+   
+  *outDataSize = rc;
+  
+  if (rc > 0) rc = 0;
+  
+  goto egress;
+  
+ abort_egress:
+ egress:
+  
+  if (paddedData) 
+    free (paddedData);
+  return rc;
+  
+}
+
+int Crypto_RSADec(  CRYPTO_INFO *key,
+                    UINT32 inDataSize,
+                    BYTE *inData,
+                    /*out*/ UINT32 *outDataSize,
+                    /*out*/ BYTE *outData) {
+  
+  RSA *rsa = (RSA *) key->keyInfo;
+  UINT32 paddedDataSize = RSA_size (rsa);
+  BYTE *paddedData = (BYTE *)malloc(sizeof(BYTE) * paddedDataSize);
+  int rc;
+  
+  if (paddedData == NULL)
+    goto abort_egress;
+  
+  rc = RSA_private_decrypt(inDataSize, inData, paddedData, rsa, 
RSA_NO_PADDING);
+  if (rc == -1) {
+    vtpmlogerror(VTPM_LOG_CRYPTO, "RSA_private_decrypt: %s\n", 
ERR_error_string(ERR_get_error(), NULL));
+    goto abort_egress;
+  }
+  
+  paddedDataSize = rc;
+  
+  switch (key->encScheme) {
+  case CRYPTO_ES_RSAESPKCSv15:
+    rc = RSA_padding_check_PKCS1_type_2 (outData, paddedDataSize,
+                                        paddedData + 1, paddedDataSize - 1,
+                                        RSA_size(rsa));
+    if (rc == -1) {
+      vtpmlogerror(VTPM_LOG_CRYPTO, "RSA_padding_check_PKCS1_type_2: %s\n", 
+             ERR_error_string(ERR_get_error(), NULL));
+      goto abort_egress;
+    }
+    *outDataSize = rc;
+    break;
+  case CRYPTO_ES_RSAESOAEP_SHA1_MGF1:
+    rc = RSA_padding_check_PKCS1_OAEP(outData, paddedDataSize,
+                                     paddedData + 1, paddedDataSize - 1,
+                                     RSA_size(rsa),
+                                     (BYTE *) OAEP_P, OAEP_P_SIZE);
+    if (rc == -1) {
+      vtpmlogerror(VTPM_LOG_CRYPTO, "RSA_padding_check_PKCS1_OAEP: %s\n",
+             ERR_error_string(ERR_get_error(), NULL));
+      goto abort_egress;
+    }
+    *outDataSize = rc;
+    break;
+  default:
+    *outDataSize = 0;
+  }
+  
+  free(paddedData); paddedData = NULL;
+  goto egress;
+  
+ abort_egress:
+  
+  if (paddedData) 
+    free (paddedData);
+  return -1;
+  
+ egress:
+  return 0;
+}
+
+// Signs either a SHA1 digest of a message or a DER encoding of a message
+// Textual messages MUST be encoded or Hashed before sending into this function
+// It will NOT SHA the message.
+int Crypto_RSASign( CRYPTO_INFO *key,
+                    UINT32 inDataSize,
+                    BYTE *inData,
+                    /*out*/ UINT32 *sigSize,
+                    /*out*/ BYTE *sig) {
+  int status;
+  unsigned int intSigSize;
+  
+  switch(key->sigScheme) {
+  case CRYPTO_SS_RSASSAPKCS1v15_SHA1: 
+    status = RSA_sign(NID_sha1, inData, inDataSize, sig, &intSigSize, (RSA *) 
key->keyInfo);
+    break;
+  case CRYPTO_SS_RSASSAPKCS1v15_DER:
+    //        status = Crypto_RSA_sign_DER(NID_md5_sha1, inData, inDataSize, 
sig, &intSigSize, key);
+    vtpmlogerror(VTPM_LOG_CRYPTO, "Crypto: Unimplemented sign type (%d)\n", 
key->sigScheme);
+    status = 0;
+    break;
+  default:
+    status = 0;
+  }
+  
+  if (status == 0) {
+    *sigSize = 0;
+    vtpmlogerror(VTPM_LOG_CRYPTO, "%s\n", ERR_error_string(ERR_get_error(), 
NULL));
+    return -1;
+  }
+  
+  *sigSize = (UINT32) intSigSize;
+  return 0;
+}
+
+bool Crypto_RSAVerify(  CRYPTO_INFO *key,
+                        UINT32 inDataSize,
+                        BYTE *inData,
+                        UINT32 sigSize,
+                        BYTE *sig) {
+  int status;
+  
+  switch(key->sigScheme){
+  case CRYPTO_SS_RSASSAPKCS1v15_SHA1: 
+    status = RSA_verify(NID_sha1, inData, inDataSize, sig, sigSize, (RSA *) 
key->keyInfo);
+    break;
+  case CRYPTO_SS_RSASSAPKCS1v15_DER:
+    //status = Crypto_RSA_verify_DER(NID_md5_sha1, inData, inDataSize, sig, 
sigSize, key);
+    vtpmlogerror(VTPM_LOG_CRYPTO, "Crypto: Unimplemented sign type (%d)\n", 
key->sigScheme);
+    status = 0;
+    break;
+  default:
+    status = 0;
+  }
+  
+  if (status) 
+    return(1);
+  else {
+    vtpmlogerror(VTPM_LOG_CRYPTO, "RSA verify: %s\n", 
ERR_error_string(ERR_get_error(), NULL));
+    return(0);
+  }
+  
+}
+
+// helper which packs everything into a BIO!
+
+// packs the parameters first, then the private key, then the public key
+// if *io_buf is NULL, allocate it here as needed. otherwise its size is in
+// *io_buflen
+TPM_RESULT Crypto_RSAPackCryptoInfo (const CRYPTO_INFO* cryptoInfo,
+                                      BYTE ** io_buf, UINT32 * io_buflen) {
+  TPM_RESULT status = TPM_SUCCESS;
+  BYTE * buf;
+  long len, outlen = *io_buflen;
+  
+  const long PARAMSLEN = 3*sizeof(UINT32);
+  
+  RSA *rsa = (RSA *) cryptoInfo->keyInfo;
+  
+  BIO *mem = BIO_new(BIO_s_mem());
+  
+  
+  // write the openssl keys to the BIO
+  if ( i2d_RSAPrivateKey_bio (mem, rsa) == 0 ) {
+    ERR_print_errors_fp (stderr);
+    ERRORDIE (TPM_SIZE);
+  }
+  if ( i2d_RSAPublicKey_bio (mem, rsa) == 0 ) {
+    ERR_print_errors_fp (stderr);
+    ERRORDIE (TPM_SIZE);
+  }
+  
+  // get the buffer out
+  len = BIO_get_mem_data (mem, &buf);
+  
+  // see if we need to allocate a return buffer
+  if (*io_buf == NULL) {
+    *io_buf = (BYTE*) malloc (PARAMSLEN + len);
+    if (*io_buf == NULL) 
+      ERRORDIE (TPM_SIZE);
+  } else {                      // *io_buf is already allocated
+    if (outlen < len + PARAMSLEN) 
+      ERRORDIE (TPM_SIZE); // but not large enough!  
+  }
+  
+  // copy over the parameters (three UINT32's starting at algorithmID)
+  memcpy (*io_buf, &cryptoInfo->algorithmID, PARAMSLEN);
+  
+  // copy over the DER keys
+  memcpy (*io_buf + PARAMSLEN, buf, len);
+  
+  *io_buflen = len + PARAMSLEN;
+  
+  goto egress;
+  
+  
+ abort_egress:
+ egress:
+  
+  BIO_free (mem);
+  
+  return status;
+}
+
+
+
+// sets up ci, and returns the number of bytes read in o_lenread
+TPM_RESULT Crypto_RSAUnpackCryptoInfo (CRYPTO_INFO * ci,
+                                        BYTE * in, UINT32 len,
+                                        UINT32 * o_lenread) {
+  
+  TPM_RESULT status = TPM_SUCCESS;
+  long l;
+  BIO *mem;
+  RSA *rsa;
+  
+  // first load up the params
+  l = 3 * sizeof(UINT32);
+  memcpy (&ci->algorithmID, in, l);
+  len -= l;
+  in += l;
+  
+  // and now the openssl keys, private first
+  mem = BIO_new_mem_buf (in, len);
+  
+  if ( (rsa = d2i_RSAPrivateKey_bio (mem, NULL)) == NULL ) {
+    ERR_print_errors_fp (stderr);
+    ERRORDIE (TPM_BAD_PARAMETER);
+  }
+  // now use the same RSA object and fill in the private key
+  if ( d2i_RSAPublicKey_bio (mem, &rsa) == NULL ) {
+    ERR_print_errors_fp (stderr);
+    ERRORDIE (TPM_BAD_PARAMETER);
+  }
+  
+  ci->keyInfo = rsa;          // needs to be freed somehow later
+  
+  // FIXME: havent figured out yet how to tell how many bytes were read in the
+  // above oprations! so o_lenread is not set
+  
+  goto egress;
+  
+ abort_egress:
+ egress:
+  
+  BIO_free (mem);
+ 
+  return status;  
+}
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/crypto/sym_crypto.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/crypto/sym_crypto.c    Thu Sep  1 10:16:14 2005
@@ -0,0 +1,242 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// sym_crypto.c
+// 
+//     Symmetric crypto portion of crypto 
+// 
+// ==================================================================
+
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+
+#include "tcg.h"
+#include "sym_crypto.h"
+
+typedef enum crypt_op_type_t {
+  CRYPT_ENCRYPT,
+  CRYPT_DECRYPT
+} crypt_op_type_t;
+
+TPM_RESULT ossl_symcrypto_op (symkey_t* key,
+                              const buffer_t* in,
+                              const buffer_t* iv,
+                              buffer_t * out,
+                              crypt_op_type_t optype);
+
+
+// this is initialized in Crypto_Init()
+const EVP_CIPHER * SYM_CIPHER = NULL;
+
+const BYTE ZERO_IV[EVP_MAX_IV_LENGTH] = {0};
+
+
+TPM_RESULT Crypto_symcrypto_initkey (symkey_t * key, const buffer_t* keybits) {
+  TPM_RESULT status = TPM_SUCCESS;
+  
+  EVP_CIPHER_CTX_init (&key->context);
+  
+  key->cipher = SYM_CIPHER;
+  
+  status = buffer_init_copy (&key->key, keybits);
+  STATUSCHECK(status);
+    
+  goto egress;
+  
+ abort_egress:
+  EVP_CIPHER_CTX_cleanup (&key->context);
+  
+ egress:
+  
+  return status;
+}
+
+
+
+TPM_RESULT Crypto_symcrypto_genkey (symkey_t * key) {
+  int res;
+  TPM_RESULT status = TPM_SUCCESS;
+  
+  // hmm, EVP_CIPHER_CTX_init does not return a value
+  EVP_CIPHER_CTX_init (&key->context);
+  
+  key->cipher = SYM_CIPHER;
+  
+  status = buffer_init (&key->key, EVP_CIPHER_key_length(key->cipher), NULL);
+  STATUSCHECK (status);
+  
+  // and generate the key material
+  res = RAND_pseudo_bytes (key->key.bytes, key->key.size);
+  if (res < 0) 
+    ERRORDIE (TPM_SHORTRANDOM);
+  
+  
+  goto egress;
+  
+ abort_egress:
+  EVP_CIPHER_CTX_cleanup (&key->context);
+  buffer_free (&key->key);
+  
+ egress:
+  return status;  
+}
+
+
+TPM_RESULT Crypto_symcrypto_encrypt (symkey_t* key,
+                              const buffer_t* clear,
+                              buffer_t* o_cipher) {
+  TPM_RESULT status = TPM_SUCCESS;
+  
+  buffer_t iv, cipher_alias;
+  
+  buffer_init_const (&iv, EVP_MAX_IV_LENGTH, ZERO_IV);
+  
+  buffer_init (o_cipher,
+              clear->size +
+              EVP_CIPHER_iv_length(key->cipher) +
+              EVP_CIPHER_block_size (key->cipher),
+                                0);
+  
+  // copy the IV into the front
+  buffer_copy (o_cipher, &iv);
+  
+  // make an alias into which we'll put the ciphertext
+  buffer_init_alias (&cipher_alias, o_cipher, 
EVP_CIPHER_iv_length(key->cipher), 0);
+  
+  status = ossl_symcrypto_op (key, clear, &iv, &cipher_alias, CRYPT_ENCRYPT);
+  STATUSCHECK (status);
+
+  // set the output size correctly
+  o_cipher->size += cipher_alias.size;
+  
+  goto egress;
+  
+ abort_egress:
+  
+ egress:
+  
+  return status;
+  
+}
+
+
+
+TPM_RESULT Crypto_symcrypto_decrypt (symkey_t* key,
+                              const buffer_t* cipher,
+                              buffer_t* o_clear) {
+  TPM_RESULT status = TPM_SUCCESS;
+  
+  buffer_t iv, cipher_alias;
+  
+  // alias for the IV
+  buffer_init_alias (&iv, cipher, 0, EVP_CIPHER_iv_length(key->cipher));
+  
+  // make an alias to where the ciphertext is, after the IV
+  buffer_init_alias (&cipher_alias, cipher, EVP_CIPHER_iv_length(key->cipher), 
0);
+  
+  // prepare the output buffer
+  status = buffer_init (o_clear,
+                       cipher->size
+                       - EVP_CIPHER_iv_length(key->cipher)
+                       + EVP_CIPHER_block_size(key->cipher), 
+                       0);
+  STATUSCHECK(status);
+  
+  // and decrypt
+  status = ossl_symcrypto_op (key, &cipher_alias, &iv, o_clear, CRYPT_DECRYPT);
+  STATUSCHECK (status);
+  
+  goto egress;
+  
+ abort_egress:
+  buffer_free (o_clear);
+  
+ egress:
+  
+  return status;
+}
+
+
+
+TPM_RESULT Crypto_symcrypto_freekey (symkey_t * key) {
+  buffer_memset (&key->key, 0);
+  buffer_free (&key->key);
+  
+  EVP_CIPHER_CTX_cleanup (&key->context);
+  
+  return TPM_SUCCESS;
+}
+
+
+TPM_RESULT ossl_symcrypto_op (symkey_t* key,
+                              const buffer_t* in,
+                              const buffer_t* iv,
+                              buffer_t * out,
+                              crypt_op_type_t optype) {
+  TPM_RESULT status = TPM_SUCCESS;
+  
+  int inlen, outlen;
+  tpm_size_t running;
+  
+  if ( ! EVP_CipherInit_ex (&key->context,
+                           key->cipher, NULL, key->key.bytes, iv->bytes,
+                           optype == CRYPT_ENCRYPT ? 1 : 0) ) 
+    ERRORDIE (TPM_FAIL);
+  
+  
+  
+  inlen = in->size;
+  
+  outlen  = 0;
+  running = 0;
+  
+  
+  if ( ! EVP_CipherUpdate (&key->context, out->bytes, &outlen, in->bytes, 
inlen) )
+    ERRORDIE (TPM_FAIL);
+
+  running += outlen;
+  
+  if ( ! EVP_CipherFinal_ex (&key->context, out->bytes + running, &outlen) )
+    ERRORDIE (TPM_FAIL);
+  
+  running += outlen;
+  
+  out->size = running;
+  
+  goto egress;
+  
+ abort_egress:
+ egress:
+  
+  return status;
+}
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/crypto/sym_crypto.h
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/crypto/sym_crypto.h    Thu Sep  1 10:16:14 2005
@@ -0,0 +1,72 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// sym_crypto.h
+// 
+//     Symmetric Crypto 
+// 
+// ==================================================================
+
+#ifndef _SYM_CRYPTO_H
+#define _SYM_CRYPTO_H
+
+#include <openssl/evp.h>
+#include "buffer.h"
+
+typedef struct symkey_t {
+  buffer_t key;
+  
+  EVP_CIPHER_CTX context;
+  const EVP_CIPHER * cipher;
+} symkey_t;
+
+extern const EVP_CIPHER * SYM_CIPHER;
+
+TPM_RESULT Crypto_symcrypto_genkey (symkey_t * key);
+
+TPM_RESULT Crypto_symcrypto_initkey (symkey_t * key, const buffer_t* keybits);
+
+
+// these functions will allocate their output buffers
+TPM_RESULT Crypto_symcrypto_encrypt (symkey_t* key,
+                              const buffer_t* clear,
+                              buffer_t* o_cipher);
+
+TPM_RESULT Crypto_symcrypto_decrypt (symkey_t* key,
+                              const buffer_t* cipher,
+                              buffer_t* o_clear);
+
+// only free the internal parts, not the 'key' ptr
+TPM_RESULT Crypto_symcrypto_freekey (symkey_t * key);
+
+#endif /* _SYM_CRYPTO_H */
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/manager/Makefile
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/manager/Makefile       Thu Sep  1 10:16:14 2005
@@ -0,0 +1,27 @@
+XEN_ROOT = ../../..
+include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
+
+BIN            = vtpm_managerd
+
+all: build
+
+build: $(BIN)
+
+install: build
+       if [ ! -d "$(DESTDIR)/var/vtpm/fifos" ]; \
+               then mkdir -p $(DESTDIR)/var/vtpm/fifos; \
+       fi
+       $(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR)
+
+clean:
+       rm -f *.a *.so *.o *.rpm $(DEP_FILES)
+
+mrproper: clean
+       rm -f $(BIN)
+
+$(BIN): $(OBJS)
+       $(CC) $(LDFLAGS) $^ $(LIBS) -o $@
+
+# libraries
+LIBS += ../tcs/libTCS.a ../util/libTCGUtils.a ../crypto/libtcpaCrypto.a
+LIBS += -lcrypto -lpthread -lrt -lm
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/manager/dmictl.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/manager/dmictl.c       Thu Sep  1 10:16:14 2005
@@ -0,0 +1,339 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+//   dmictl.c
+// 
+//     Functions for creating and destroying DMIs
+//
+// ==================================================================
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+#ifndef VTPM_MUTLI_VM
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <signal.h>
+ #include <wait.h>
+#endif
+
+#include "vtpmpriv.h"
+#include "bsg.h"
+#include "buffer.h"
+#include "log.h"
+#include "hashtable.h"
+#include "hashtable_itr.h"
+
+#define TPM_EMULATOR_PATH "/usr/bin/vtpmd"
+
+TPM_RESULT close_dmi( VTPM_DMI_RESOURCE *dmi_res) {
+       TPM_RESULT status = TPM_FAIL;
+       
+       if (dmi_res == NULL) 
+               return TPM_SUCCESS;
+       
+       status = TCS_CloseContext(dmi_res->TCSContext);
+       free ( dmi_res->NVMLocation );
+       dmi_res->connected = FALSE;
+
+#ifndef VTPM_MULTI_VM  
+       free(dmi_res->guest_tx_fname);
+       free(dmi_res->vtpm_tx_fname);
+               
+       close(dmi_res->guest_tx_fh); dmi_res->guest_tx_fh = -1;
+       close(dmi_res->vtpm_tx_fh);  dmi_res->vtpm_tx_fh = -1; 
+       
+               
+ #ifndef MANUAL_DM_LAUNCH
+  if (dmi_res->dmi_id != VTPM_CTL_DM) {
+    if (dmi_res->dmi_pid != 0) {
+      vtpmloginfo(VTPM_LOG_VTPM, "Killing dmi on pid %d.\n", dmi_res->dmi_pid);
+      if ((kill(dmi_res->dmi_pid, SIGKILL) !=0) ||
+         (waitpid(dmi_res->dmi_pid, NULL, 0) != dmi_res->dmi_pid)){
+        vtpmlogerror(VTPM_LOG_VTPM, "Could not kill dmi on pid %d.\n", 
dmi_res->dmi_pid);
+        status = TPM_FAIL;
+      }
+    } else 
+      vtpmlogerror(VTPM_LOG_VTPM, "Could not kill dmi because it's pid was 
0.\n");
+  }
+ #endif
+#endif
+
+       return status;
+}
+       
+TPM_RESULT VTPM_Handle_New_DMI( const buffer_t *param_buf) {
+  
+  VTPM_DMI_RESOURCE *new_dmi=NULL;
+  TPM_RESULT status=TPM_FAIL;
+  BYTE type;
+  UINT32 dmi_id, domain_id, *dmi_id_key; 
+  int fh;
+
+#ifndef VTPM_MUTLI_VM
+  char dmi_id_str[11]; // UINT32s are up to 10 digits + NULL
+  struct stat file_info;
+#endif
+  
+  if (param_buf == NULL) { // Assume creation of Dom 0 control
+    type = 0;
+    domain_id = VTPM_CTL_DM;
+    dmi_id = VTPM_CTL_DM;
+  } else if (buffer_len(param_buf) != sizeof(BYTE) + sizeof(UINT32) *2) {
+    vtpmloginfo(VTPM_LOG_VTPM, "New DMI command wrong length: %d.\n", 
buffer_len(param_buf));
+    status = TPM_BAD_PARAMETER;
+    goto abort_egress;
+  } else {
+    BSG_UnpackList( param_buf->bytes, 3,
+                   BSG_TYPE_BYTE, &type,
+                   BSG_TYPE_UINT32, &domain_id,
+                   BSG_TYPE_UINT32,  &dmi_id);
+  }
+  
+  new_dmi = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, 
&dmi_id);
+  if (new_dmi == NULL) { 
+    vtpmloginfo(VTPM_LOG_VTPM, "Creating new DMI instance %d attached on 
domain %d.\n", dmi_id, domain_id);
+    // Brand New DMI. Initialize the persistent pieces
+    if ((new_dmi = (VTPM_DMI_RESOURCE *) malloc (sizeof(VTPM_DMI_RESOURCE))) 
== NULL) {
+      status = TPM_RESOURCES;
+      goto abort_egress;
+    }
+    memset(new_dmi, 0, sizeof(VTPM_DMI_RESOURCE));
+    new_dmi->dmi_id = dmi_id;
+    new_dmi->connected = FALSE;
+    
+    if ((dmi_id_key = (UINT32 *) malloc (sizeof(UINT32))) == NULL) {
+      status = TPM_RESOURCES;
+      goto abort_egress;
+    }      
+    *dmi_id_key = new_dmi->dmi_id;
+    
+    // install into map
+    if (!hashtable_insert(vtpm_globals->dmi_map, dmi_id_key, new_dmi)){
+      free(new_dmi);
+      free(dmi_id_key);
+      status = TPM_FAIL;
+      goto egress;
+    }
+    
+  } else 
+    vtpmloginfo(VTPM_LOG_VTPM, "Re-attaching DMI instance %d on domain %d 
.\n", dmi_id, domain_id);
+  
+  if (new_dmi->connected) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Attempt to re-attach, currently attached 
instance %d. Ignoring\n", dmi_id);
+    status = TPM_BAD_PARAMETER;
+    goto egress;
+  }
+  
+  // Initialize the Non-persistent pieces
+  new_dmi->dmi_domain_id = domain_id;
+  new_dmi->NVMLocation = NULL;
+  
+  new_dmi->TCSContext = 0;
+  TPMTRYRETURN( TCS_OpenContext(&new_dmi->TCSContext) );
+  
+  new_dmi->NVMLocation = (char *) malloc(11 + strlen(DMI_NVM_FILE));
+  sprintf(new_dmi->NVMLocation, DMI_NVM_FILE, (uint32_t) new_dmi->dmi_id);
+  
+  // Measure DMI
+  // FIXME: This will measure DMI. Until then use a fixed DMI_Measurement value
+  /*
+  fh = open(TPM_EMULATOR_PATH, O_RDONLY);
+  stat_ret = fstat(fh, &file_stat);
+  if (stat_ret == 0) 
+    dmi_size = file_stat.st_size;
+  else {
+       vtpmlogerror(VTPM_LOG_VTPM, "Could not open tpm_emulator!!\n");
+    status = TPM_IOERROR;
+    goto abort_egress;
+  }
+  dmi_buffer
+  */
+  memset(&new_dmi->DMI_measurement, 0xcc, sizeof(TPM_DIGEST));
+  
+#ifndef VTPM_MULTI_VM
+  if (dmi_id != VTPM_CTL_DM) {
+    // Create a pair of fifo pipes
+               if( (new_dmi->guest_tx_fname = (char *) malloc(11 + 
strlen(GUEST_TX_FIFO))) == NULL){ 
+                       status = TPM_RESOURCES;
+                       goto abort_egress;
+               }
+               sprintf(new_dmi->guest_tx_fname, GUEST_TX_FIFO, (uint32_t) 
dmi_id);
+    
+               if ((new_dmi->vtpm_tx_fname = (char *) malloc(11 + 
strlen(VTPM_TX_FIFO))) == NULL) {
+                       status = TPM_RESOURCES;
+                       goto abort_egress;
+               }
+               sprintf(new_dmi->vtpm_tx_fname, VTPM_TX_FIFO, (uint32_t) 
dmi_id);
+    
+    new_dmi->guest_tx_fh = -1;
+    new_dmi->vtpm_tx_fh= -1;
+    
+    if ( stat(new_dmi->guest_tx_fname, &file_info) == -1) {
+      if ( mkfifo(new_dmi->guest_tx_fname, S_IWUSR | S_IRUSR ) ){
+                               status = TPM_FAIL;
+                               goto abort_egress;
+      }
+    }
+            
+    if ( (fh = open(new_dmi->vtpm_tx_fname, O_RDWR)) == -1) {
+      if ( mkfifo(new_dmi->vtpm_tx_fname, S_IWUSR | S_IRUSR ) ) {
+       status = TPM_FAIL;
+       goto abort_egress;
+      }
+    }
+                
+    // Launch DMI
+    sprintf(dmi_id_str, "%d", (int) dmi_id);
+#ifdef MANUAL_DM_LAUNCH
+    vtpmlogerror(VTPM_LOG_VTPM, "FAKING starting vtpm with dmi=%s\n", 
dmi_id_str);
+    new_dmi->dmi_pid = 0;
+#else
+    pid_t pid = fork();
+    
+    if (pid == -1) {
+                       vtpmlogerror(VTPM_LOG_VTPM, "Could not fork to launch 
vtpm\n");
+                 status = TPM_RESOURCES;
+      goto abort_egress;
+               } else if (pid == 0) {
+                 if ( stat(new_dmi->NVMLocation, &file_info) == -1)
+                               execl (TPM_EMULATOR_PATH, "vtmpd", "clear", 
dmi_id_str, NULL);
+                       else 
+                               execl (TPM_EMULATOR_PATH, "vtpmd", "save", 
dmi_id_str, NULL);
+                       
+                       // Returning from these at all is an error.
+                       vtpmlogerror(VTPM_LOG_VTPM, "Could not exec to launch 
vtpm\n");
+    } else {
+      new_dmi->dmi_pid = pid;
+      vtpmloginfo(VTPM_LOG_VTPM, "Launching DMI on PID = %d\n", pid);
+    }
+#endif // MANUAL_DM_LAUNCH
+  }
+#else // VTPM_MUTLI_VM
+  // FIXME: Measure DMI through call to Measurement agent in platform.
+#endif 
+       
+  vtpm_globals->DMI_table_dirty = TRUE;
+  new_dmi->connected = TRUE;  
+  status=TPM_SUCCESS;
+  goto egress;
+  
+ abort_egress:
+       close_dmi( new_dmi );
+       
+ egress:
+  return status;
+}
+
+TPM_RESULT VTPM_Handle_Close_DMI( const buffer_t *param_buf) {
+  
+  TPM_RESULT status=TPM_FAIL;
+  VTPM_DMI_RESOURCE *dmi_res=NULL;
+  UINT32 dmi_id;
+  
+  if ((param_buf == NULL) || (buffer_len(param_buf) != sizeof(UINT32)) ) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Closing DMI has bad size.");
+    status = TPM_BAD_PARAMETER;
+    goto abort_egress;
+  }
+  
+  BSG_UnpackList( param_buf->bytes, 1,
+                 BSG_TYPE_UINT32, &dmi_id);
+  
+  vtpmloginfo(VTPM_LOG_VTPM, "Closing DMI %d.\n", dmi_id);
+  
+  dmi_res = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, 
&dmi_id);
+  if (dmi_res == NULL ) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Trying to close nonexistent DMI.\n");
+    status = TPM_BAD_PARAMETER;
+    goto abort_egress;
+  }
+       
+       if (!dmi_res->connected) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Closing non-connected DMI.\n");
+    status = TPM_BAD_PARAMETER;
+    goto abort_egress;
+  }
+  
+  // Close Dmi
+       TPMTRYRETURN(close_dmi( dmi_res ));
+  
+  status=TPM_SUCCESS;    
+  goto egress;
+  
+ abort_egress:
+ egress:
+  
+  return status;
+}
+
+TPM_RESULT VTPM_Handle_Delete_DMI( const buffer_t *param_buf) {
+  
+  TPM_RESULT status=TPM_FAIL;
+  VTPM_DMI_RESOURCE *dmi_res=NULL;
+  UINT32 dmi_id;
+    
+  if ((param_buf == NULL) || (buffer_len(param_buf) != sizeof(UINT32)) ) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Closing DMI has bad size.\n");
+    status = TPM_BAD_PARAMETER;
+    goto abort_egress;
+  }
+  
+  BSG_UnpackList( param_buf->bytes, 1,
+                 BSG_TYPE_UINT32, &dmi_id);
+  
+  vtpmloginfo(VTPM_LOG_VTPM, "Deleting DMI %d.\n", dmi_id);    
+  
+  dmi_res = (VTPM_DMI_RESOURCE *) hashtable_remove(vtpm_globals->dmi_map, 
&dmi_id);
+  if (dmi_res == NULL) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Closing non-existent DMI.\n");
+    status = TPM_BAD_PARAMETER;
+    goto abort_egress;
+  }
+  
+       //TODO: Automatically delete file dmi_res->NVMLocation
+  
+  // Close DMI first
+  TPMTRYRETURN(close_dmi( dmi_res ));
+       free ( dmi_res );
+       
+  status=TPM_SUCCESS;    
+  goto egress;
+  
+ abort_egress:
+ egress:
+  
+  return status;
+}
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/manager/securestorage.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/manager/securestorage.c        Thu Sep  1 10:16:14 2005
@@ -0,0 +1,401 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// securestorage.c
+// 
+//  Functions regarding securely storing DMI secrets.
+//
+// ==================================================================
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "tcg.h"
+#include "vtpm_manager.h"
+#include "vtpmpriv.h"
+#include "vtsp.h"
+#include "bsg.h"
+#include "crypto.h"
+#include "hashtable.h"
+#include "hashtable_itr.h"
+#include "buffer.h"
+#include "log.h"
+
+TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI_RESOURCE *myDMI, 
+                               const buffer_t *inbuf, 
+                               buffer_t *outbuf) {
+  
+  TPM_RESULT status = TPM_SUCCESS;
+  symkey_t    symkey;
+  buffer_t    state_cipher = NULL_BUF,
+              symkey_cipher = NULL_BUF;
+  int fh;
+  long bytes_written;
+  BYTE *sealed_NVM=NULL;
+  UINT32 sealed_NVM_size, i;
+  struct pack_constbuf_t symkey_cipher32, state_cipher32;
+  
+  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Save_NVMing[%d]: 0x", buffer_len(inbuf));
+  for (i=0; i< buffer_len(inbuf); i++)
+    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", inbuf->bytes[i]);
+  vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+  
+  // Generate a sym key and encrypt state with it
+  TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_genkey (&symkey) );
+  TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_encrypt (&symkey, inbuf, 
&state_cipher) );
+  
+  // Encrypt symmetric key
+  TPMTRYRETURN( VTSP_Bind(    &vtpm_globals->storageKey, 
+                             &symkey.key, 
+                             &symkey_cipher) );
+  
+  // Create output blob: symkey_size + symkey_cipher + state_cipher_size + 
state_cipher
+  
+  symkey_cipher32.size = buffer_len(&symkey_cipher);
+  symkey_cipher32.data = symkey_cipher.bytes;
+  
+  state_cipher32.size = buffer_len(&state_cipher);
+  state_cipher32.data = state_cipher.bytes;
+  
+  sealed_NVM = (BYTE *) malloc( 2 * sizeof(UINT32) + symkey_cipher32.size + 
state_cipher32.size);
+  
+  sealed_NVM_size = BSG_PackList(sealed_NVM, 2,
+                                BSG_TPM_SIZE32_DATA, &symkey_cipher32,
+                                BSG_TPM_SIZE32_DATA, &state_cipher32);
+  
+  // Mark DMI Table so new save state info will get pushed to disk on return.
+  vtpm_globals->DMI_table_dirty = TRUE;
+  
+  // Write sealed blob off disk from NVMLocation
+  // TODO: How to properly return from these. Do we care if we return failure
+  //       after writing the file? We can't get the old one back.
+  // TODO: Backup old file and try and recover that way.
+  fh = open(myDMI->NVMLocation, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
+  if ( (bytes_written = write(fh, sealed_NVM, sealed_NVM_size) ) != (long) 
sealed_NVM_size) {
+    vtpmlogerror(VTPM_LOG_VTPM, "We just overwrote a DMI_NVM and failed to 
finish. %ld/%ld bytes.\n", bytes_written, (long)sealed_NVM_size);
+    status = TPM_IOERROR;
+    goto abort_egress;
+  }
+  close(fh);
+  
+  Crypto_SHA1Full (sealed_NVM, sealed_NVM_size, (BYTE *) 
&myDMI->NVM_measurement);   
+  
+  vtpmloginfo(VTPM_LOG_VTPM, "Saved %d bytes of E(symkey) + %d bytes of 
E(NVM)\n", buffer_len(&symkey_cipher), buffer_len(&state_cipher));
+  goto egress;
+  
+ abort_egress:
+  vtpmlogerror(VTPM_LOG_VTPM, "Failed to load NVM\n.");
+  
+ egress:
+  
+  buffer_free ( &state_cipher);
+  buffer_free ( &symkey_cipher);
+  free(sealed_NVM);
+  Crypto_symcrypto_freekey (&symkey);
+  
+  return status;
+}
+
+
+/* inbuf = null outbuf = sealed blob size, sealed blob.*/
+TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI_RESOURCE *myDMI, 
+                               const buffer_t *inbuf, 
+                               buffer_t *outbuf) {
+  
+  TPM_RESULT status = TPM_SUCCESS;
+  symkey_t    symkey;
+  buffer_t    state_cipher = NULL_BUF, 
+              symkey_clear = NULL_BUF, 
+              symkey_cipher = NULL_BUF;
+  struct pack_buf_t symkey_cipher32, state_cipher32;
+  
+  UINT32 sealed_NVM_size;
+  BYTE *sealed_NVM = NULL;
+  long fh_size;
+  int fh, stat_ret, i;
+  struct stat file_stat;
+  TPM_DIGEST sealedNVMHash;
+  
+  memset(&symkey, 0, sizeof(symkey_t));
+  
+  if (myDMI->NVMLocation == NULL) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Unable to load NVM because the file name 
NULL.\n");
+    status = TPM_AUTHFAIL;
+    goto abort_egress;
+  }
+  
+  //Read sealed blob off disk from NVMLocation
+  fh = open(myDMI->NVMLocation, O_RDONLY);
+  stat_ret = fstat(fh, &file_stat);
+  if (stat_ret == 0) 
+    fh_size = file_stat.st_size;
+  else {
+    status = TPM_IOERROR;
+    goto abort_egress;
+  }
+  
+  sealed_NVM = (BYTE *) malloc(fh_size);
+  if (read(fh, sealed_NVM, fh_size) != fh_size) {
+    status = TPM_IOERROR;
+    goto abort_egress;
+  }
+  close(fh);
+  
+  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Load_NVMing[%ld]: 0x", fh_size);
+  for (i=0; i< fh_size; i++)
+    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", sealed_NVM[i]);
+  vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+  
+  sealed_NVM_size = BSG_UnpackList(sealed_NVM, 2,
+                                  BSG_TPM_SIZE32_DATA, &symkey_cipher32,
+                                  BSG_TPM_SIZE32_DATA, &state_cipher32);
+  
+  TPMTRYRETURN( buffer_init_convert (&symkey_cipher, 
+                                    symkey_cipher32.size, 
+                                    symkey_cipher32.data) );
+  
+  TPMTRYRETURN( buffer_init_convert (&state_cipher, 
+                                    state_cipher32.size, 
+                                    state_cipher32.data) );
+  
+  Crypto_SHA1Full(sealed_NVM, sealed_NVM_size, (BYTE *) &sealedNVMHash);    
+  
+  // Verify measurement of sealed blob.
+  if (memcmp(&sealedNVMHash, &myDMI->NVM_measurement, sizeof(TPM_DIGEST)) ) {
+    vtpmlogerror(VTPM_LOG_VTPM, "VTPM LoadNVM NVM measurement check 
failed.\n");
+    vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Correct hash: ");
+    for (i=0; i< sizeof(TPM_DIGEST); i++)
+      vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", 
((BYTE*)&myDMI->NVM_measurement)[i]);
+    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+
+    vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Measured hash: ");
+    for (i=0; i< sizeof(TPM_DIGEST); i++)
+      vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", ((BYTE*)&sealedNVMHash)[i]);
+    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+    
+    status = TPM_AUTHFAIL;
+    goto abort_egress;
+  }
+  
+  // Decrypt Symmetric Key
+  TPMTRYRETURN( VTSP_Unbind(  myDMI->TCSContext,
+                             vtpm_globals->storageKeyHandle,
+                             &symkey_cipher,
+                             (const 
TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
+                             &symkey_clear,
+                             &(vtpm_globals->keyAuth) ) );
+  
+  // create symmetric key using saved bits
+  Crypto_symcrypto_initkey (&symkey, &symkey_clear);
+  
+  // Decrypt State
+  TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (&symkey, &state_cipher, 
outbuf) );
+  
+  goto egress;
+  
+ abort_egress:
+  vtpmlogerror(VTPM_LOG_VTPM, "Failed to load NVM\n.");
+  
+ egress:
+  
+  buffer_free ( &state_cipher);
+  buffer_free ( &symkey_clear);
+  buffer_free ( &symkey_cipher);
+  free( sealed_NVM );
+  Crypto_symcrypto_freekey (&symkey);
+  
+  return status;
+}
+
+TPM_RESULT VTPM_SaveService(void) {
+  TPM_RESULT status=TPM_SUCCESS;
+  int fh, dmis=-1;
+  
+  BYTE *flat_global;
+  int flat_global_size, bytes_written;
+  UINT32 storageKeySize = buffer_len(&vtpm_globals->storageKeyWrap);
+  struct pack_buf_t storage_key_pack = {storageKeySize, 
vtpm_globals->storageKeyWrap.bytes};
+  
+  struct hashtable_itr *dmi_itr;
+  VTPM_DMI_RESOURCE *dmi_res;
+  
+  UINT32 flat_global_full_size;
+  
+  // Global Values needing to be saved
+  flat_global_full_size = 3*sizeof(TPM_DIGEST) + // Auths
+    sizeof(UINT32) +       // storagekeysize
+    storageKeySize +       // storage key
+    hashtable_count(vtpm_globals->dmi_map) * // num DMIS
+    (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)); // Per DMI info
+  
+  
+  flat_global = (BYTE *) malloc( flat_global_full_size);
+  
+  flat_global_size = BSG_PackList(flat_global, 4,
+                                 BSG_TPM_AUTHDATA, 
&vtpm_globals->owner_usage_auth,
+                                 BSG_TPM_AUTHDATA, 
&vtpm_globals->srk_usage_auth,
+                                 BSG_TPM_SECRET,   
&vtpm_globals->storage_key_usage_auth,
+                                 BSG_TPM_SIZE32_DATA, &storage_key_pack);
+  
+  // Per DMI values to be saved
+  if (hashtable_count(vtpm_globals->dmi_map) > 0) {
+    
+    dmi_itr = hashtable_iterator(vtpm_globals->dmi_map);
+    do {
+      dmi_res = (VTPM_DMI_RESOURCE *) hashtable_iterator_value(dmi_itr);
+      dmis++;
+
+      // No need to save dmi0.
+      if (dmi_res->dmi_id == 0)        
+       continue;
+      
+      
+      flat_global_size += BSG_PackList( flat_global + flat_global_size, 3,
+                                       BSG_TYPE_UINT32, &dmi_res->dmi_id,
+                                       BSG_TPM_DIGEST, 
&dmi_res->NVM_measurement,
+                                       BSG_TPM_DIGEST, 
&dmi_res->DMI_measurement);
+      
+    } while (hashtable_iterator_advance(dmi_itr));
+  }
+  
+  //FIXME: Once we have a way to protect a TPM key, we should use it to 
+  //       encrypt this blob. BUT, unless there is a way to ensure the key is
+  //       not used by other apps, this encryption is useless.
+  fh = open(STATE_FILE, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
+  if (fh == -1) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Unable to open %s file for write.\n", 
STATE_FILE);
+    status = TPM_IOERROR;
+    goto abort_egress;
+  }
+  
+  if ( (bytes_written = write(fh, flat_global, flat_global_size)) != 
flat_global_size ) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Failed to save service data. %d/%d bytes 
written.\n", bytes_written, flat_global_size);
+    status = TPM_IOERROR;
+    goto abort_egress;
+  }
+  vtpm_globals->DMI_table_dirty = FALSE; 
+  
+  goto egress;
+  
+ abort_egress:
+ egress:
+  
+  free(flat_global);
+  close(fh);
+  
+  vtpmloginfo(VTPM_LOG_VTPM, "Saved VTPM Service state (status = %d, dmis = 
%d)\n", (int) status, dmis);
+  return status;
+}
+
+TPM_RESULT VTPM_LoadService(void) {
+  
+  TPM_RESULT status=TPM_SUCCESS;
+  int fh, stat_ret, dmis=0;
+  long fh_size = 0, step_size;
+  BYTE *flat_global=NULL;
+  struct pack_buf_t storage_key_pack;
+  UINT32 *dmi_id_key;
+  
+  VTPM_DMI_RESOURCE *dmi_res;
+  struct stat file_stat;
+  
+  fh = open(STATE_FILE, O_RDONLY );
+  stat_ret = fstat(fh, &file_stat);
+  if (stat_ret == 0) 
+    fh_size = file_stat.st_size;
+  else {
+    status = TPM_IOERROR;
+    goto abort_egress;
+  }
+  
+  flat_global = (BYTE *) malloc(fh_size);
+  
+  if ((long) read(fh, flat_global, fh_size) != fh_size ) {
+    status = TPM_IOERROR;
+    goto abort_egress;
+  }
+  
+  // Global Values needing to be saved
+  step_size = BSG_UnpackList( flat_global, 4,
+                             BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
+                             BSG_TPM_AUTHDATA, &vtpm_globals->srk_usage_auth,
+                             BSG_TPM_SECRET,   
&vtpm_globals->storage_key_usage_auth,
+                             BSG_TPM_SIZE32_DATA, &storage_key_pack);
+  
+  TPMTRYRETURN(buffer_init(&vtpm_globals->storageKeyWrap, 0, 0) );
+  TPMTRYRETURN(buffer_append_raw(&vtpm_globals->storageKeyWrap, 
storage_key_pack.size, storage_key_pack.data) );
+  
+  // Per DMI values to be saved
+  while ( step_size < fh_size ){
+    if (fh_size - step_size < (long) (sizeof(UINT32) + 2*sizeof(TPM_DIGEST))) {
+      vtpmlogerror(VTPM_LOG_VTPM, "Encountered %ld extra bytes at end of 
manager state.\n", fh_size-step_size);
+      step_size = fh_size;
+    } else {
+      dmi_res = (VTPM_DMI_RESOURCE *) malloc(sizeof(VTPM_DMI_RESOURCE));
+      dmis++;
+      
+      dmi_res->connected = FALSE;
+      
+      step_size += BSG_UnpackList(flat_global + step_size, 3,
+                                 BSG_TYPE_UINT32, &dmi_res->dmi_id, 
+                                 BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
+                                 BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
+      
+      // install into map
+      dmi_id_key = (UINT32 *) malloc (sizeof(UINT32));
+      *dmi_id_key = dmi_res->dmi_id;
+      if (!hashtable_insert(vtpm_globals->dmi_map, dmi_id_key, dmi_res)) {
+       status = TPM_FAIL;
+       goto abort_egress;
+      }
+      
+    }
+    
+  }
+  
+  goto egress;
+  
+ abort_egress:
+  vtpmlogerror(VTPM_LOG_VTPM, "Failed to save service data\n");
+ egress:
+  
+  if (flat_global)
+    free(flat_global);
+  close(fh);
+  
+  vtpmloginfo(VTPM_LOG_VTPM, "Previously saved state reloaded (status = %d, 
dmis = %d).\n", (int) status, dmis);
+  return status;
+}
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/manager/tpmpassthrough.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/manager/tpmpassthrough.c       Thu Sep  1 10:16:14 2005
@@ -0,0 +1,110 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// tpmpassthrough.c
+// 
+//  Functions regarding passing DMI requests to HWTPM
+//
+// ==================================================================
+
+#include "tcg.h"
+#include "vtpm_manager.h"
+#include "vtpmpriv.h"
+#include "vtsp.h"
+#include "log.h"
+
+TPM_RESULT VTPM_Handle_TPM_Command( VTPM_DMI_RESOURCE *dmi,
+                                   buffer_t *inbuf,  
+                                   buffer_t *outbuf) {
+  
+  TPM_RESULT status = TPM_SUCCESS;
+  TPM_COMMAND_CODE *ord;               
+  
+  ord = (TPM_COMMAND_CODE *) (inbuf->bytes + sizeof(TPM_TAG) + sizeof(UINT32));
+  
+  switch (*ord) {
+    
+    // Forbidden for DMI use
+  case TPM_ORD_TakeOwnership:
+  case TPM_ORD_ChangeAuthOwner:
+  case TPM_ORD_DirWriteAuth:
+  case TPM_ORD_DirRead:
+  case TPM_ORD_AuthorizeMigrationKey:
+  case TPM_ORD_CreateMaintenanceArchive:
+  case TPM_ORD_LoadMaintenanceArchive:
+  case TPM_ORD_KillMaintenanceFeature:
+  case TPM_ORD_LoadManuMaintPub:
+  case TPM_ORD_ReadManuMaintPub:
+  case TPM_ORD_SelfTestFull:
+  case TPM_ORD_SelfTestStartup:
+  case TPM_ORD_CertifySelfTest:
+  case TPM_ORD_ContinueSelfTest:
+  case TPM_ORD_GetTestResult:
+  case TPM_ORD_Reset:
+  case TPM_ORD_OwnerClear:
+  case TPM_ORD_DisableOwnerClear:
+  case TPM_ORD_ForceClear:
+  case TPM_ORD_DisableForceClear:
+  case TPM_ORD_GetCapabilityOwner:
+  case TPM_ORD_OwnerSetDisable:
+  case TPM_ORD_PhysicalEnable:
+  case TPM_ORD_PhysicalDisable:
+  case TPM_ORD_SetOwnerInstall:
+  case TPM_ORD_PhysicalSetDeactivated:
+  case TPM_ORD_SetTempDeactivated:
+  case TPM_ORD_CreateEndorsementKeyPair:
+  case TPM_ORD_GetAuditEvent:
+  case TPM_ORD_GetAuditEventSigned:
+  case TPM_ORD_GetOrdinalAuditStatus:
+  case TPM_ORD_SetOrdinalAuditStatus:
+  case TPM_ORD_SetRedirection:
+  case TPM_ORD_FieldUpgrade:
+  case TSC_ORD_PhysicalPresence:
+    status = TPM_DISABLED_CMD;
+    goto abort_egress;
+    break;
+    
+  } // End ORD Switch
+  
+  // Call TCS with command
+  
+  TPMTRY(TPM_IOERROR, VTSP_RawTransmit( dmi->TCSContext,inbuf, outbuf) );
+  
+  goto egress;
+  
+ abort_egress:
+  vtpmloginfo(VTPM_LOG_VTPM, "TPM Command Failed in tpmpassthrough.\n");
+ egress:
+  
+  return status;
+}
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/manager/vtpm_manager.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/manager/vtpm_manager.c Thu Sep  1 10:16:14 2005
@@ -0,0 +1,735 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// vtpm_manager.c
+// 
+//  This file will house the main logic of the VTPM Manager
+//
+// ==================================================================
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+
+#ifndef VTPM_MULTI_VM
+#include <pthread.h>
+#include <errno.h>
+#include <aio.h>
+#include <time.h>
+#endif
+
+#include "vtpm_manager.h"
+#include "vtpmpriv.h"
+#include "vtsp.h"
+#include "bsg.h"
+#include "hashtable.h"
+#include "hashtable_itr.h"
+
+#include "log.h"
+#include "buffer.h"
+
+VTPM_GLOBALS *vtpm_globals=NULL;
+
+#ifdef VTPM_MULTI_VM
+ #define vtpmhandlerloginfo(module,fmt,args...) vtpmloginfo (module, fmt, 
##args );
+ #define vtpmhandlerloginfomore(module,fmt,args...) vtpmloginfomore (module, 
fmt, ##args );
+ #define vtpmhandlerlogerror(module,fmt,args...) vtpmlogerror (module, fmt, 
##args );
+#else 
+ #define vtpmhandlerloginfo(module,fmt,args...) vtpmloginfo (module, "[%d]: " 
fmt, threadType, ##args );
+ #define vtpmhandlerloginfomore(module,fmt,args...) vtpmloginfomore (module, 
fmt, ##args );
+ #define vtpmhandlerlogerror(module,fmt,args...) vtpmlogerror (module, "[%d]: 
" fmt, threadType, ##args );
+#endif
+
+// --------------------------- Static Auths --------------------------
+#ifdef USE_FIXED_SRK_AUTH
+
+static BYTE FIXED_SRK_AUTH[20] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
0xff, 0xff, 0xff,
+                                  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
0xff, 0xff, 0xff};
+
+static BYTE FIXED_EK_AUTH[20] =  {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
0xff, 0xff, 0xff,
+                                  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
0xff, 0xff, 0xff};
+
+#endif
+                                  
+// -------------------------- Hash table functions --------------------
+
+static unsigned int hashfunc32(void *ky) {
+  return (* (UINT32 *) ky);
+}
+
+static int equals32(void *k1, void *k2) {
+  return (*(UINT32 *) k1 == *(UINT32 *) k2);
+}
+
+// --------------------------- Functions ------------------------------
+
+TPM_RESULT VTPM_Create_Service(){
+  
+  TPM_RESULT status = TPM_SUCCESS;
+  
+  // Generate Auth's for SRK & Owner
+#ifdef USE_FIXED_SRK_AUTH
+  memcpy(vtpm_globals->owner_usage_auth, FIXED_SRK_AUTH, sizeof(TPM_AUTHDATA));
+  memcpy(vtpm_globals->srk_usage_auth, FIXED_EK_AUTH, sizeof(TPM_AUTHDATA));
+#else    
+  Crypto_GetRandom(vtpm_globals->owner_usage_auth, sizeof(TPM_AUTHDATA) );
+  Crypto_GetRandom(vtpm_globals->srk_usage_auth, sizeof(TPM_AUTHDATA) );  
+#endif
+  
+  // Take Owership of TPM
+  CRYPTO_INFO ek_cryptoInfo;
+  
+  vtpmloginfo(VTPM_LOG_VTPM, "Attempting Pubek Read. NOTE: Failure is ok.\n");
+  status = VTSP_ReadPubek(vtpm_globals->manager_tcs_handle, &ek_cryptoInfo);
+  
+  // If we can read PubEK then there is no owner and we should take it.
+  if (status == TPM_SUCCESS) { 
+    TPMTRYRETURN(VTSP_TakeOwnership(vtpm_globals->manager_tcs_handle,
+                                   (const 
TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth, 
+                                   (const 
TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
+                                   &ek_cryptoInfo,
+                                   &vtpm_globals->keyAuth)); 
+  
+    TPMTRYRETURN(VTSP_DisablePubekRead(vtpm_globals->manager_tcs_handle,
+                                       (const 
TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth,  
+                                       &vtpm_globals->keyAuth));     
+  }
+  
+  // Generate storage key's auth
+  Crypto_GetRandom(  &vtpm_globals->storage_key_usage_auth, 
+                    sizeof(TPM_AUTHDATA) );
+  
+  TCS_AUTH osap;
+  TPM_AUTHDATA sharedsecret;
+  
+  TPMTRYRETURN( VTSP_OSAP(vtpm_globals->manager_tcs_handle,
+                         TPM_ET_SRK,
+                         0, 
+                         (const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
+                         &sharedsecret, 
+                         &osap) ); 
+  
+  TPMTRYRETURN( VTSP_CreateWrapKey( vtpm_globals->manager_tcs_handle,
+                                   TPM_KEY_BIND,
+                                   (const 
TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
+                                   TPM_SRK_KEYHANDLE, 
+                                   (const TPM_AUTHDATA*)&sharedsecret,
+                                   &vtpm_globals->storageKeyWrap,
+                                   &osap) );
+  
+  vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
+  
+  goto egress;
+  
+ abort_egress:
+  exit(1);
+  
+ egress:
+  vtpmloginfo(VTPM_LOG_VTPM, "New VTPM Service initialized (Status = %d).\n", 
status);
+  return status;
+  
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+#ifdef VTPM_MULTI_VM
+int VTPM_Service_Handler(){
+#else
+void *VTPM_Service_Handler(void *threadTypePtr){
+#endif
+  TPM_RESULT      status =  TPM_FAIL; // Should never return
+  UINT32          dmi, in_param_size, cmd_size, out_param_size, 
out_message_size, out_message_size_full, dmi_cmd_size;
+  BYTE            *cmd_header, *in_param, *out_message, *dmi_cmd;
+  buffer_t        *command_buf=NULL, *result_buf=NULL;
+  TPM_TAG         tag;
+  TPM_COMMAND_CODE ord;
+  VTPM_DMI_RESOURCE *dmi_res;
+  int  size_read, size_write, i;
+  
+#ifndef VTPM_MULTI_VM
+  int threadType = *(int *) threadTypePtr;
+  
+  // async io structures
+  struct aiocb dmi_aio;
+  struct aiocb *dmi_aio_a[1];
+  dmi_aio_a[0] = &dmi_aio;
+#endif
+  
+#ifdef DUMMY_BACKEND
+  int dummy_rx;  
+#endif
+  
+  // TODO: Reinsert ifdefs to enable support for MULTI-VM 
+  
+  cmd_header = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV);
+  command_buf = (buffer_t *) malloc(sizeof(buffer_t));
+  result_buf = (buffer_t *) malloc(sizeof(buffer_t));
+  
+#ifndef VTPM_MULTI_VM
+  TPM_RESULT *ret_value = (TPM_RESULT *) malloc(sizeof(TPM_RESULT));
+#endif
+  
+  int *tx_fh, *rx_fh;
+  
+#ifdef VTPM_MULTI_VM
+  rx_fh = &vtpm_globals->be_fh;
+#else
+  if (threadType == BE_LISTENER_THREAD) {
+#ifdef DUMMY_BACKEND    
+    dummy_rx = -1;
+    rx_fh = &dummy_rx;
+#else
+    rx_fh = &vtpm_globals->be_fh;
+#endif
+  } else { // DMI_LISTENER_THREAD
+    rx_fh = &vtpm_globals->vtpm_rx_fh;
+  }
+#endif
+  
+#ifndef VTPM_MULTI_VM
+  int fh;
+  if (threadType == BE_LISTENER_THREAD) {
+    tx_fh = &vtpm_globals->be_fh;
+    if ( (fh = open(GUEST_RX_FIFO, O_RDWR)) == -1) {
+      if ( mkfifo(GUEST_RX_FIFO, S_IWUSR | S_IRUSR ) ){
+                               *ret_value = TPM_FAIL;
+                               pthread_exit(ret_value);
+      }
+    } else 
+      close(fh);
+    
+  } else { // else DMI_LISTENER_THREAD
+    // tx_fh will be set once the DMI is identified
+    // But we need to make sure the read pip is created.
+    if ( (fh = open(VTPM_RX_FIFO, O_RDWR)) == -1) {
+      if ( mkfifo(VTPM_RX_FIFO, S_IWUSR | S_IRUSR ) ){
+       *ret_value = TPM_FAIL;
+       pthread_exit(ret_value);
+      }
+    } else 
+      close(fh);
+    
+  }
+#endif
+  
+  while(1) {
+    
+    if (threadType == BE_LISTENER_THREAD) {
+      vtpmhandlerloginfo(VTPM_LOG_VTPM, "Waiting for Guest requests & ctrl 
messages.\n");
+    } else 
+      vtpmhandlerloginfo(VTPM_LOG_VTPM, "Waiting for DMI messages.\n");
+    
+    
+    if (*rx_fh < 0) {
+      if (threadType == BE_LISTENER_THREAD) 
+#ifdef DUMMY_BACKEND
+       *rx_fh = open("/tmp/in.fifo", O_RDWR);
+#else
+        *rx_fh = open(VTPM_BE_DEV, O_RDWR);
+#endif
+      else  // DMI Listener   
+       *rx_fh = open(VTPM_RX_FIFO, O_RDWR);
+      
+    }
+    
+    if (*rx_fh < 0) {
+      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't open inbound fh.\n");
+#ifdef VTPM_MULTI_VM
+      return TPM_IOERROR; 
+#else
+      *ret_value = TPM_IOERROR;
+      pthread_exit(ret_value);
+#endif
+    }
+    
+    size_read = read(*rx_fh, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
+    if (size_read > 0) {
+      vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV[%d}: 0x", size_read);
+      for (i=0; i<size_read; i++) 
+               vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", 
cmd_header[i]);
+    } else {
+      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't read from BE. Aborting... \n");
+      close(*rx_fh);
+      *rx_fh = -1;
+      goto abort_command;
+    }
+
+    if (size_read < (int) VTPM_COMMAND_HEADER_SIZE_SRV) {
+      vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "\n");
+      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command shorter than normal header 
(%d bytes). Aborting...\n", size_read);
+      goto abort_command;
+    }
+    
+    BSG_UnpackList(cmd_header, 4,
+                  BSG_TYPE_UINT32, &dmi,
+                  BSG_TPM_TAG, &tag,
+                  BSG_TYPE_UINT32, &in_param_size,
+                  BSG_TPM_COMMAND_CODE, &ord );
+    
+    // Note that in_param_size is in the client's context
+    cmd_size = in_param_size - VTPM_COMMAND_HEADER_SIZE_CLT;
+    if (cmd_size > 0) {
+      in_param = (BYTE *) malloc(cmd_size);
+      size_read = read( *rx_fh, in_param, cmd_size);
+      if (size_read > 0) {
+       for (i=0; i<size_read; i++) 
+         vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]);
+       
+      } else {
+        vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error reading from BE. Aborting... 
\n");
+       close(*rx_fh);
+       *rx_fh = -1;
+       goto abort_command;
+      }
+      vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+      
+      if (size_read < (int) cmd_size) {
+       vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+       vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command read(%d) is shorter than 
header indicates(%d). Aborting...\n", size_read, cmd_size);
+       goto abort_command;
+      }
+    } else {
+      in_param = NULL;
+      vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+    }            
+    
+    if ((threadType != BE_LISTENER_THREAD) && (dmi == 0)) {
+      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempt to access dom0 commands from 
DMI interface. Aborting...\n");
+      goto abort_command;
+    }
+    
+    dmi_res = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, 
&dmi);
+    if (dmi_res == NULL) {
+      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempted access to non-existent DMI 
in domain: %d. Aborting...\n", dmi);
+      goto abort_command;
+    }
+    if (!dmi_res->connected) {
+      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempted access to disconnected DMI 
in domain: %d. Aborting...\n", dmi);
+      goto abort_command;
+    }
+    
+    if (threadType != BE_LISTENER_THREAD) 
+      tx_fh = &dmi_res->vtpm_tx_fh;
+    // else we set this before the while loop since it doesn't change.
+    
+    if ( (buffer_init_convert(command_buf, cmd_size, in_param) != TPM_SUCCESS) 
|| 
+        (buffer_init(result_buf, 0, 0) != TPM_SUCCESS) ) {
+      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Failed to setup buffers. 
Aborting...\n");
+      goto abort_command;
+    }
+    
+    // Dispatch it as either control or user request.
+    if (tag == VTPM_TAG_REQ) { 
+      if (dmi_res->dmi_id == VTPM_CTL_DM){ 
+       switch (ord) {
+       case VTPM_ORD_OPEN:
+         status = VTPM_Handle_New_DMI(command_buf);
+         break;
+          
+       case VTPM_ORD_CLOSE:
+         status = VTPM_Handle_Close_DMI(command_buf);
+         break;
+          
+       case VTPM_ORD_DELETE:
+         status = VTPM_Handle_Delete_DMI(command_buf);
+         break;
+       default:
+         status = TPM_BAD_ORDINAL; 
+       } // switch
+      } else {
+       
+       switch (ord) {                
+       case VTPM_ORD_SAVENVM:
+         status= VTPM_Handle_Save_NVM(dmi_res,
+                                      command_buf, 
+                                      result_buf);
+         break;
+       case VTPM_ORD_LOADNVM:
+         status= VTPM_Handle_Load_NVM(dmi_res, 
+                                      command_buf, 
+                                      result_buf);
+         break;
+         
+       case VTPM_ORD_TPMCOMMAND:
+         status= VTPM_Handle_TPM_Command(dmi_res, 
+                                         command_buf, 
+                                         result_buf);
+         break;
+         
+       default:
+         status = TPM_BAD_ORDINAL; 
+       } // switch
+      }
+    } else { // This is not a VTPM Command at all
+      
+      if (threadType == BE_LISTENER_THREAD) {
+       if (dmi == 0) {
+         // This usually indicates a FE/BE driver.
+         vtpmhandlerlogerror(VTPM_LOG_VTPM, "Illegal use of TPM command from 
dom0\n");
+         status = TPM_FAIL;
+       } else {
+         vtpmhandlerloginfo(VTPM_LOG_VTPM, "Forwarding command to DMI.\n");
+         
+         if (dmi_res->guest_tx_fh < 0)
+           dmi_res->guest_tx_fh = open(dmi_res->guest_tx_fname, O_WRONLY | 
O_NONBLOCK);
+          
+         if (dmi_res->guest_tx_fh < 0){
+           vtpmhandlerlogerror(VTPM_LOG_VTPM, "VTPM ERROR: Can't open outbound 
fh to dmi.\n");
+           status = TPM_IOERROR;
+           goto abort_with_error;
+         }        
+          
+         //Note: Send message + dmi_id
+         if (cmd_size) {
+           dmi_cmd = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV + cmd_size);
+           dmi_cmd_size = VTPM_COMMAND_HEADER_SIZE_SRV + cmd_size;
+           memcpy(dmi_cmd, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
+           memcpy(dmi_cmd + VTPM_COMMAND_HEADER_SIZE_SRV, in_param, cmd_size);
+           size_write = write(dmi_res->guest_tx_fh, dmi_cmd, dmi_cmd_size);
+           
+           if (size_write > 0) {
+             vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT (DMI): 0x");
+             for (i=0; i<VTPM_COMMAND_HEADER_SIZE_SRV + cmd_size; i++) {
+               vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", dmi_cmd[i]);
+             }
+             vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+           } else {
+              vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error writing to DMI. 
Aborting... \n");
+             close(dmi_res->guest_tx_fh);
+             dmi_res->guest_tx_fh = -1;
+              status = TPM_IOERROR;
+             goto abort_with_error;
+           }
+           free(dmi_cmd);
+         } else {
+           dmi_cmd_size = VTPM_COMMAND_HEADER_SIZE_SRV;
+           size_write = write(dmi_res->guest_tx_fh, cmd_header, 
VTPM_COMMAND_HEADER_SIZE_SRV );
+           if (size_write > 0) {
+             for (i=0; i<VTPM_COMMAND_HEADER_SIZE_SRV; i++) 
+               vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", 
cmd_header[i]);
+             
+             vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+           } else {
+              vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error writing to DMI. 
Aborting... \n");
+             close(dmi_res->guest_tx_fh);
+             dmi_res->guest_tx_fh = -1;
+              status = TPM_IOERROR;
+             goto abort_with_error;
+           }
+         }
+          
+         if (size_write != (int) dmi_cmd_size) 
+           vtpmhandlerlogerror(VTPM_LOG_VTPM, "Could not write entire command 
to DMI (%d/%d)\n", size_write, dmi_cmd_size);
+         buffer_free(command_buf);
+         
+         if (vtpm_globals->guest_rx_fh < 0) 
+           vtpm_globals->guest_rx_fh = open(GUEST_RX_FIFO, O_RDONLY);
+          
+         if (vtpm_globals->guest_rx_fh < 0){
+           vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't open inbound fh to 
dmi.\n");
+            status = TPM_IOERROR;
+           goto abort_with_error;
+         }                  
+         
+          size_read = read( vtpm_globals->guest_rx_fh, cmd_header, 
VTPM_COMMAND_HEADER_SIZE_SRV);
+         if (size_read > 0) {
+           vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV (DMI): 0x");
+           for (i=0; i<size_read; i++) 
+             vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
+           
+         } else {
+            vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error reading from DMI. 
Aborting... \n");
+           close(vtpm_globals->guest_rx_fh);
+           vtpm_globals->guest_rx_fh = -1;
+            status = TPM_IOERROR;
+           goto abort_with_error;
+         }
+          
+         if (size_read < (int) VTPM_COMMAND_HEADER_SIZE_SRV) {
+           //vtpmdeepsublog("\n");
+           vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command from DMI shorter than 
normal header. Aborting...\n");
+            status = TPM_IOERROR;
+           goto abort_with_error;
+         }
+          
+         BSG_UnpackList(cmd_header, 4,
+                        BSG_TYPE_UINT32, &dmi,
+                        BSG_TPM_TAG, &tag,
+                        BSG_TYPE_UINT32, &in_param_size,
+                        BSG_TPM_COMMAND_CODE, &status );
+        
+         // Note that in_param_size is in the client's context
+         cmd_size = in_param_size - VTPM_COMMAND_HEADER_SIZE_CLT;
+         if (cmd_size > 0) {
+           in_param = (BYTE *) malloc(cmd_size);
+           size_read = read( vtpm_globals->guest_rx_fh, in_param, cmd_size);
+           if (size_read > 0) {
+             for (i=0; i<size_read; i++) 
+               vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]);
+             
+           } else {
+              vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error reading from BE. 
Aborting... \n");
+             close(vtpm_globals->guest_rx_fh);
+             vtpm_globals->guest_rx_fh = -1;
+              status = TPM_IOERROR;
+             goto abort_with_error;
+           }
+           vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n");
+            
+           if (size_read < (int)cmd_size) {
+             vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n");
+             vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command read(%d) from DMI is 
shorter than header indicates(%d). Aborting...\n", size_read, cmd_size);
+              status = TPM_IOERROR;
+             goto abort_with_error;
+           }
+         } else {
+           in_param = NULL;
+           vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n");
+         }
+                           
+         if (buffer_init_convert(result_buf, cmd_size, in_param) != 
TPM_SUCCESS) {
+           vtpmhandlerlogerror(VTPM_LOG_VTPM, "Failed to setup buffers. 
Aborting...\n");
+            status = TPM_FAIL;
+           goto abort_with_error;
+         }
+         
+         vtpmhandlerloginfo(VTPM_LOG_VTPM, "Sending DMI's response to 
guest.\n");
+       } // end else for if (dmi==0)
+        
+      } else { // This is a DMI lister thread. Thus this is from a DMI
+#ifdef VTPM_MULTI_VM
+       vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempt to use unsupported direct 
access to TPM.\n");
+       vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "Bad Command. dmi:%d, tag:%d, 
size:%d, ord:%d, Params: ", dmi, tag, in_param_size, ord);
+       for (UINT32 q=0; q<cmd_size; q++) 
+         vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[q]);
+       
+       vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+        
+       status = TPM_FAIL;
+#else
+       
+#endif
+      } // end else for if BE Listener
+    } // end else for is VTPM Command
+    
+    // Send response to Backend
+    if (*tx_fh < 0) {
+      if (threadType == BE_LISTENER_THREAD) 
+#ifdef DUMMY_BACKEND
+       *tx_fh = open("/tmp/out.fifo", O_RDWR);
+#else
+        *tx_fh = open(VTPM_BE_DEV, O_RDWR);
+#endif
+      else  // DMI Listener
+       *tx_fh = open(dmi_res->vtpm_tx_fname, O_WRONLY);
+    }
+    
+    if (*tx_fh < 0) {
+      vtpmhandlerlogerror(VTPM_LOG_VTPM, "VTPM ERROR: Can't open outbound 
fh.\n");
+#ifdef VTPM_MULTI_VM
+      return TPM_IOERROR; 
+#else
+      *ret_value = TPM_IOERROR;
+      pthread_exit(ret_value);
+#endif
+    }        
+    
+ abort_with_error:
+    // Prepend VTPM header with destination DM stamped
+    out_param_size = buffer_len(result_buf);
+    out_message_size = VTPM_COMMAND_HEADER_SIZE_CLT + out_param_size;
+    out_message_size_full = VTPM_COMMAND_HEADER_SIZE_SRV + out_param_size;
+    out_message = (BYTE *) malloc (out_message_size_full);
+    
+    BSG_PackList(out_message, 4,
+                BSG_TYPE_UINT32, (BYTE *) &dmi,
+                BSG_TPM_TAG, (BYTE *) &tag,
+                BSG_TYPE_UINT32, (BYTE *) &out_message_size,
+                BSG_TPM_RESULT, (BYTE *) &status);
+    
+    if (buffer_len(result_buf) > 0) 
+      memcpy(out_message + VTPM_COMMAND_HEADER_SIZE_SRV, result_buf->bytes, 
out_param_size);
+    
+    
+    //Note: Send message + dmi_id
+    size_write = write(*tx_fh, out_message, out_message_size_full );
+    if (size_write > 0) {
+      vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT: 0x");
+      for (i=0; i < out_message_size_full; i++) 
+       vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", out_message[i]);
+      
+      vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");            
+    } else {
+      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error writing to BE. Aborting... 
\n");
+      close(*tx_fh);
+      *tx_fh = -1;
+      goto abort_command;
+    }
+    free(out_message);
+    
+    if (size_write < (int)out_message_size_full) {
+      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Unable to write full command to BE 
(%d/%d)\n", size_write, out_message_size_full);
+      goto abort_command;
+    }
+    
+  abort_command:
+    //free buffers
+    bzero(cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
+    //free(in_param); // This was converted to command_buf. No need to free 
+    if (command_buf != result_buf) 
+      buffer_free(result_buf);
+    
+    buffer_free(command_buf);
+    
+#ifndef VTPM_MULTI_VM
+    if (threadType != BE_LISTENER_THREAD) {
+#endif
+      if ( (vtpm_globals->DMI_table_dirty) &&
+          (VTPM_SaveService() != TPM_SUCCESS) ) {
+       vtpmhandlerlogerror(VTPM_LOG_VTPM, "ERROR: Unable to save manager 
data.\n");
+      }
+#ifndef VTPM_MULTI_VM
+    }
+#endif
+    
+  } // End while(1)
+  
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+TPM_RESULT VTPM_Init_Service() {
+  TPM_RESULT status = TPM_FAIL;   
+  BYTE *randomsead;
+       UINT32 randomsize;
+       
+  if ((vtpm_globals = (VTPM_GLOBALS *) malloc(sizeof(VTPM_GLOBALS))) == NULL){
+               status = TPM_FAIL;
+               goto abort_egress;
+       }
+       memset(vtpm_globals, 0, sizeof(VTPM_GLOBALS));
+  vtpm_globals->be_fh = -1;
+
+#ifndef VTPM_MULTI_VM
+  vtpm_globals->vtpm_rx_fh = -1;
+  vtpm_globals->guest_rx_fh = -1;
+#endif
+  if ((vtpm_globals->dmi_map = create_hashtable(10, hashfunc32, equals32)) == 
NULL){
+               status = TPM_FAIL;
+               goto abort_egress;
+       }
+  
+  vtpm_globals->DMI_table_dirty = FALSE;
+  
+  // Create new TCS Object
+  vtpm_globals->manager_tcs_handle = 0;
+  
+  TPMTRYRETURN(TCS_create());
+  
+  // Create TCS Context for service
+  TPMTRYRETURN( TCS_OpenContext(&vtpm_globals->manager_tcs_handle ) );
+
+       TPMTRYRETURN( TCSP_GetRandom(vtpm_globals->manager_tcs_handle, 
+                                                                               
                                         &randomsize, 
+                                                                               
                                         &randomsead));
+
+       Crypto_Init(randomsead, randomsize);
+       TPMTRYRETURN( TCS_FreeMemory (vtpm_globals->manager_tcs_handle, 
randomsead)); 
+       
+  // Create OIAP session for service's authorized commands
+  TPMTRYRETURN( VTSP_OIAP( vtpm_globals->manager_tcs_handle, 
+                          &vtpm_globals->keyAuth) );
+  vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
+
+       // If failed, create new Service.
+  if (VTPM_LoadService() != TPM_SUCCESS)
+    TPMTRYRETURN( VTPM_Create_Service() );    
+
+  
+  //Load Storage Key 
+  TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
+                             TPM_SRK_KEYHANDLE,
+                             &vtpm_globals->storageKeyWrap,
+                             (const 
TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
+                             &vtpm_globals->storageKeyHandle,
+                             &vtpm_globals->keyAuth,
+                             &vtpm_globals->storageKey) );
+  
+  // Create entry for Dom0 for control messages
+  TPMTRYRETURN( VTPM_Handle_New_DMI(NULL) );
+  
+  // --------------------- Command handlers ---------------------------
+  
+  goto egress;
+  
+ abort_egress:
+ egress:
+  
+  return(status);
+}
+ 
+void VTPM_Stop_Service() {
+  VTPM_DMI_RESOURCE *dmi_res;
+  struct hashtable_itr *dmi_itr;
+  
+  // Close all the TCS contexts. TCS should evict keys based on this
+  if (hashtable_count(vtpm_globals->dmi_map) > 0) {
+    dmi_itr = hashtable_iterator(vtpm_globals->dmi_map);
+    do {
+      dmi_res = (VTPM_DMI_RESOURCE *) hashtable_iterator_value(dmi_itr);
+      if (dmi_res->connected) 
+                               if (close_dmi( dmi_res ) != TPM_SUCCESS) 
+                                       vtpmlogerror(VTPM_LOG_VTPM, "Failed to 
close dmi %d properly.\n", dmi_res->dmi_id);
+      
+    } while (hashtable_iterator_advance(dmi_itr));
+               free (dmi_itr);
+  }
+  
+       
+  TCS_CloseContext(vtpm_globals->manager_tcs_handle);
+  
+  if ( (vtpm_globals->DMI_table_dirty) &&
+       (VTPM_SaveService() != TPM_SUCCESS) )
+    vtpmlogerror(VTPM_LOG_VTPM, "Unable to save manager data.\n");
+  
+  hashtable_destroy(vtpm_globals->dmi_map, 1);
+  free(vtpm_globals);
+  
+  close(vtpm_globals->be_fh);
+  Crypto_Exit();
+       
+  vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager stopped.\n");
+}
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/manager/vtpm_manager.h
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/manager/vtpm_manager.h Thu Sep  1 10:16:14 2005
@@ -0,0 +1,137 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// vtpm_manager.h
+// 
+//  Public Interface header for VTPM Manager
+//
+// ==================================================================
+
+#ifndef __VTPM_MANAGER_H__
+#define __VTPM_MANAGER_H__
+
+#include "tcg.h"
+
+#define VTPM_TAG_REQ 0x01c1
+#define VTPM_TAG_RSP 0x01c4
+#define COMMAND_BUFFER_SIZE 4096
+
+// Header sizes. Note Header MAY include the DMI
+#define VTPM_COMMAND_HEADER_SIZE_SRV ( sizeof(UINT32) + sizeof(TPM_TAG) + 
sizeof(UINT32) + sizeof(TPM_COMMAND_CODE))
+#define VTPM_COMMAND_HEADER_SIZE_CLT (                  sizeof(TPM_TAG) + 
sizeof(UINT32) + sizeof(TPM_COMMAND_CODE))
+
+// ********************** Public Functions *************************
+TPM_RESULT VTPM_Init_Service(); // Start VTPM Service
+void VTPM_Stop_Service();  // Stop VTPM Service
+#ifdef VTPM_MULTI_VM
+int VTPM_Service_Handler();
+#else
+void *VTPM_Service_Handler(void *threadTypePtr);
+#endif
+
+//************************ Command Codes ****************************
+#define VTPM_ORD_OPEN              1   // ULM Creates New DMI
+#define VTPM_ORD_CLOSE             2   // ULM Closes a DMI
+#define VTPM_ORD_DELETE            3   // ULM Permemently Deletes DMI
+#define VTPM_ORD_SAVENVM          4   // DMI requests Secrets Unseal
+#define VTPM_ORD_LOADNVM          5   // DMI requests Secrets Saved
+#define VTPM_ORD_TPMCOMMAND       6   // DMI issues HW TPM Command
+
+//************************ Return Codes ****************************
+#define VTPM_SUCCESS               0
+#define VTPM_FAIL                  1
+#define VTPM_UNSUPPORTED           2
+#define VTPM_FORBIDDEN             3
+#define VTPM_RESTORE_CONTEXT_FAILED    4
+#define VTPM_INVALID_REQUEST       5
+
+/******************* Command Parameter API *************************
+
+VTPM Command Format
+  dmi: 4 bytes                  // Source of message. 
+                                // WARNING: This is prepended by the channel. 
+                                // Thus it is received by VTPM Manager, 
+                                // but not sent by DMI
+  tpm tag: 2 bytes
+  command size: 4 bytes         // Size of command including header but not DMI
+  ord: 4 bytes                  // Command ordinal above
+  parameters: size - 10 bytes   // Command Parameter
+
+VTPM Response Format
+  tpm tag: 2 bytes
+  response_size: 4 bytes
+  status: 4 bytes         
+  parameters: size - 10 bytes
+
+
+VTPM_Open:
+  Input Parameters:
+    Domain_type: 1 byte
+    domain_id: 4 bytes
+    instance_id: 4 bytes
+  Output Parameters:
+    None
+    
+VTPM_Close
+  Input Parameters:
+    instance_id: 4 bytes
+  Output Parameters:
+    None
+
+VTPM_Delete
+  Input Parameters:
+    instance_id: 4 bytes
+  Output Parameters:
+    None
+
+VTPM_SaveNVM
+  Input Parameters:
+    data: n bytes (Header indicates size of data)
+  Output Parameters:
+    None
+
+VTPM_LoadNVM
+  Input Parameters:
+    None
+  Output Parameters:
+    data: n bytes (Header indicates size of data)
+
+VTPM_TPMCommand
+  Input Parameters:
+    TPM Command Byte Stream: n bytes 
+  Output Parameters:
+    TPM Reponse Byte Stream: n bytes 
+
+*********************************************************************/
+
+#endif //_VTPM_MANAGER_H_
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/manager/vtpmd.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/manager/vtpmd.c        Thu Sep  1 10:16:14 2005
@@ -0,0 +1,134 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// vtpmd.c
+// 
+//  Application
+//
+// ===================================================================
+
+#include <stdio.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include "vtpm_manager.h"
+#include "vtpmpriv.h"
+#include "tcg.h"
+#include "log.h"
+
+#ifndef VTPM_MULTI_VM
+ #include <pthread.h>
+#endif
+
+void signal_handler(int reason) {
+#ifndef VTPM_MULTI_VM
+
+  if (pthread_equal(pthread_self(), vtpm_globals->master_pid)) {
+    if (reason >= 0) { // Reason is a signal
+      vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager shutting down for signal 
%d.\n", reason);
+    } else  {// Reason is a TPM_RESULT * -1
+      vtpmloginfo(VTPM_LOG_VTPM,"VTPM Manager shuting down for: %s\n", 
tpm_get_error_name(-1 * reason) );
+    }
+    
+    return;
+  } else {
+    vtpmloginfo(VTPM_LOG_VTPM, "Child shutting down\n");
+    pthread_exit(NULL);
+  }
+#else
+  VTPM_Stop_Service();
+  exit(-1);
+#endif
+}
+
+struct sigaction ctl_c_handler;
+
+int main(int argc, char **argv) {
+
+  vtpmloginfo(VTPM_LOG_VTPM, "Starting VTPM.\n");
+  
+  if (VTPM_Init_Service() != TPM_SUCCESS) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Closing vtpmd due to error during 
startup.\n");
+    return -1;
+  }
+  
+  ctl_c_handler.sa_handler = signal_handler;
+  sigemptyset(&ctl_c_handler.sa_mask);
+  ctl_c_handler.sa_flags = 0;    
+  
+  if (sigaction(SIGINT, &ctl_c_handler, NULL) == -1) 
+    vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGINT handler. Ctl+break 
will not stop service gently.\n");
+  
+  // For easier debuggin with gdb
+  if (sigaction(SIGHUP, &ctl_c_handler, NULL) == -1) 
+    vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGHUP handler. Ctl+break 
will not stop service gently.\n");    
+  
+#ifdef VTPM_MULTI_VM
+  TPM_RESULT status = VTPM_Service_Handler();
+    
+  if (status != TPM_SUCCESS) 
+    vtpmlogerror(VTPM_LOG_VTPM, "VTPM Manager exited with status %s. It never 
should exit.\n", tpm_get_error_name(status));
+  
+  return -1;
+#else
+  sigset_t sig_mask;
+      
+  sigemptyset(&sig_mask);
+  sigaddset(&sig_mask, SIGPIPE);
+  sigprocmask(SIG_BLOCK, &sig_mask, NULL);
+  //pthread_mutex_init(&vtpm_globals->dmi_mutex, NULL);
+  pthread_t be_thread, dmi_thread;
+  int betype_be, dmitype_dmi;
+  
+  vtpm_globals->master_pid = pthread_self();
+  
+  betype_be = BE_LISTENER_THREAD;
+  if (pthread_create(&be_thread, NULL, VTPM_Service_Handler, &betype_be) != 0) 
{
+    vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch BE Thread.\n");
+    exit(-1);
+  }
+  
+  dmitype_dmi = DMI_LISTENER_THREAD;
+  if (pthread_create(&dmi_thread, NULL, VTPM_Service_Handler, &dmitype_dmi) != 
0) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch DMI Thread.\n");
+    exit(-1);
+  }
+  
+  //Join the other threads until exit time.
+  pthread_join(be_thread, NULL);
+  pthread_join(dmi_thread, NULL);
+  
+  VTPM_Stop_Service();
+  return 0;
+#endif
+}
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/manager/vtpmpriv.h
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/manager/vtpmpriv.h     Thu Sep  1 10:16:14 2005
@@ -0,0 +1,151 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// vtpmpriv.h
+// 
+//  Structures and functions private to the manager
+//
+// ==================================================================
+
+#ifndef __VTPMPRIV_H__
+#define __VTPMPRIV_H__
+
+#include "tcg.h"
+#include "tcs.h"
+#include "buffer.h"
+#include "crypto.h"
+
+#define STATE_FILE    "/var/vtpm/VTPM"
+#define DMI_NVM_FILE  "/var/vtpm/vtpm_dm_%d.data"
+#define VTPM_BE_DEV   "/dev/vtpm"
+#define VTPM_CTL_DM         0
+
+#ifndef VTPM_MUTLI_VM
+ #include <sys/types.h>
+ #define GUEST_TX_FIFO "/var/vtpm/fifos/guest-to-%d.fifo"
+ #define GUEST_RX_FIFO "/var/vtpm/fifos/guest-from-all.fifo"
+
+ #define VTPM_TX_FIFO  "/var/vtpm/fifos/vtpm-to-%d.fifo"
+ #define VTPM_RX_FIFO  "/var/vtpm/fifos/vtpm-from-all.fifo"
+
+ #define BE_LISTENER_THREAD 1
+ #define DMI_LISTENER_THREAD 2
+
+ // Seconds until DMI timeout. Timeouts result in DMI being out
+ // of sync, which may require a reboot of DMI and guest to recover
+ // from. Don't set this to low. Also note that DMI may issue a TPM
+ // call so we should expect time to process at DMI + TPM processing.
+ #define DMI_TIMEOUT 90 
+#endif
+
+
+// ------------------------ Private Structures -----------------------
+typedef struct VTPM_DMI_RESOURCE_T {
+  // I/O info for Manager to talk to DMI's over FIFOs
+#ifndef VTPM_MUTLI_VM
+  int                   guest_tx_fh;          // open GUEST_TX_FIFO
+  int                   vtpm_tx_fh;           // open VTPM_TX_FIFO
+  char                  *guest_tx_fname;      // open GUEST_TX_FIFO
+  char                  *vtpm_tx_fname;       // open VTPM_TX_FIFO
+  
+  pid_t                 dmi_pid;
+#endif
+  // Non-persistent Information
+  bool                  connected;
+  UINT32                dmi_domain_id;
+  TCS_CONTEXT_HANDLE    TCSContext;     // TCS Handle
+  char                  *NVMLocation;   // NULL term string indicating location
+                                        // of NVM.
+  // Persistent Information about DMI
+  UINT32                dmi_id;
+  TPM_DIGEST            NVM_measurement;  // Equal to the SHA1 of the blob
+  TPM_DIGEST            DMI_measurement;  // Correct measurement of the owning 
DMI
+} VTPM_DMI_RESOURCE;
+
+typedef struct tdVTPM_GLOBALS {
+  // Non-persistent data
+  int                 be_fh;                  // File handle to ipc used to 
communicate with backend
+#ifndef VTPM_MULTI_VM
+  int                 vtpm_rx_fh;
+  int                 guest_rx_fh;
+  
+  pid_t               master_pid;
+#endif
+  struct hashtable    *dmi_map;               // Table of all DMI's known 
indexed by persistent instance #
+#ifndef VTPM_MULTI_VM
+  pthread_mutex_t     dmi_map_mutex;          // 
+#endif
+  TCS_CONTEXT_HANDLE  manager_tcs_handle;     // TCS Handle used by manager
+  TPM_HANDLE          storageKeyHandle;       // Key used by persistent store
+  CRYPTO_INFO         storageKey;             // For software encryption
+  TCS_AUTH            keyAuth;                // OIAP session for storageKey 
+  BOOL                DMI_table_dirty;        // Indicates that a command
+                                              // has updated the DMI table
+
+    
+  // Persistent Data
+  TPM_AUTHDATA        owner_usage_auth;       // OwnerAuth of real TPM
+  TPM_AUTHDATA        srk_usage_auth;         // SRK Auth of real TPM    
+  buffer_t            storageKeyWrap;         // Wrapped copy of storageKey
+
+  TPM_AUTHDATA        storage_key_usage_auth; 
+    
+}VTPM_GLOBALS;
+
+//Global dmi map
+extern VTPM_GLOBALS *vtpm_globals;
+
+// ********************** Command Handler Prototypes ***********************
+TPM_RESULT VTPM_Handle_Load_NVM(       VTPM_DMI_RESOURCE *myDMI, 
+                                        const buffer_t *inbuf, 
+                                        buffer_t *outbuf);
+
+TPM_RESULT VTPM_Handle_Save_NVM(       VTPM_DMI_RESOURCE *myDMI, 
+                                        const buffer_t *inbuf, 
+                                        buffer_t *outbuf);
+
+TPM_RESULT VTPM_Handle_TPM_Command(    VTPM_DMI_RESOURCE *dmi, 
+                                        buffer_t *inbuf, 
+                                        buffer_t *outbuf);
+
+TPM_RESULT VTPM_Handle_New_DMI(const buffer_t *param_buf);
+                                
+TPM_RESULT VTPM_Handle_Close_DMI(const buffer_t *param_buf);
+                                   
+TPM_RESULT VTPM_Handle_Delete_DMI(const buffer_t *param_buf);
+
+TPM_RESULT VTPM_SaveService(void);
+TPM_RESULT VTPM_LoadService(void);
+
+TPM_RESULT close_dmi( VTPM_DMI_RESOURCE *dmi_res);
+#endif // __VTPMPRIV_H__
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/manager/vtsp.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/manager/vtsp.c Thu Sep  1 10:16:14 2005
@@ -0,0 +1,810 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// vtsp.c
+// 
+//  Higher level interface to TCS for use in service.
+//
+// ==================================================================
+
+#include <string.h>
+#include "tcg.h"
+#include "tcs.h"
+#include "bsg.h"
+#include "log.h"
+#include "crypto.h"
+#include "vtsp.h"
+#include "buffer.h"
+
+#define  RSA_KEY_SIZE 0x0800
+
+/***********************************************************************************
+ * GenerateAuth: Generate authorization info to be sent back to application
+ *
+ * Parameters: outParamDigestText  The concatenation of output parameters to 
be SHA1ed
+ *    outParamDigestTextSize Size of inParamDigestText
+ *    HMACkey     Key to be used for HMACing
+ *          For OIAP use key.authUsage or PersistStore.ownerAuth
+ *          For OSAP use shared secret
+ *    pAuth     Authorization information from the application
+ *
+ * Return:  TPM_SUCCESS   Authorization data created
+ *    TPM_AUTHFAIL   Invalid (NULL) HMACkey presented for OSAP
+ 
*************************************************************************************/
+TPM_RESULT GenerateAuth( /*[IN]*/ const BYTE *inParamDigestText,
+                        /*[IN]*/ UINT32 inParamDigestTextSize,
+                        /*[IN]*/ const TPM_SECRET *HMACkey,  
+                        /*[IN,OUT]*/ TCS_AUTH *auth) {
+    
+  if (inParamDigestText == NULL || auth == NULL) 
+    return (TPM_AUTHFAIL);
+  else {
+    
+    //Generate new OddNonce
+    Crypto_GetRandom(auth->NonceOdd.nonce, sizeof(TPM_NONCE));
+    
+    // Create SHA1 inParamDigest
+    TPM_DIGEST inParamDigest;
+    Crypto_SHA1Full(inParamDigestText, inParamDigestTextSize, (BYTE *) 
&inParamDigest);
+    
+    // Create HMAC text. (Concat inParamsDigest with inAuthSetupParams).
+    BYTE hmacText[sizeof(TPM_DIGEST) + (2 * sizeof(TPM_NONCE)) + sizeof(BOOL)];
+    
+    BSG_PackList(   hmacText, 4, 
+                   BSG_TPM_DIGEST, &inParamDigest,
+                   BSG_TPM_NONCE, &(auth->NonceEven),
+                   BSG_TPM_NONCE, &(auth->NonceOdd), 
+                   BSG_TYPE_BOOL, &(auth->fContinueAuthSession) );
+    
+    Crypto_HMAC((BYTE *) hmacText, sizeof(hmacText), (BYTE *) HMACkey, 
sizeof(TPM_DIGEST), (BYTE *) &(auth->HMAC));
+    
+    return(TPM_SUCCESS);
+    
+  }
+}
+
+/***********************************************************************************
+ * VerifyAuth: Verify the authdata for a command requiring authorization
+ *
+ * Parameters: inParamDigestText  The concatenation of parameters to be SHA1ed
+ *    inParamDigestTextSize Size of inParamDigestText
+ *    authDataUsage   AuthDataUsage for the Entity being used
+ *          Key->authDataUsage or TPM_AUTH_OWNER
+ *    HMACkey     Key to be used for HMACing
+ *          For OIAP use key.authUsage or PersistStore.ownerAuth
+ *          For OSAP use NULL (It will be aquired from the Auth Session)
+ *          If unknown (default), assume OIAP
+ *    sessionAuth    A TCS_AUTH info for the session
+ *    pAuth     Authorization information from the application
+ *              hContext        If specified, on failed Auth, VerifyAuth will
+ *                                      generate a new OIAP session in place 
of themselves
+ *                                      destroyed session.
+ *
+ * Return:  TPM_SUCCESS   Authorization Verified
+ *    TPM_AUTHFAIL   Authorization Failed
+ *    TPM_FAIL    Failure during SHA1 routines
+ 
*************************************************************************************/
+TPM_RESULT VerifyAuth( /*[IN]*/ const BYTE *outParamDigestText,
+                      /*[IN]*/ UINT32 outParamDigestTextSize,
+                      /*[IN]*/ const TPM_SECRET *HMACkey,  
+                      /*[IN,OUT]*/ TCS_AUTH *auth,
+                      /*[IN]*/  TCS_CONTEXT_HANDLE hContext) {
+  if (outParamDigestText == NULL || auth == NULL) 
+    return (TPM_AUTHFAIL);
+  
+  
+  // Create SHA1 inParamDigest
+  TPM_DIGEST outParamDigest;
+  Crypto_SHA1Full(outParamDigestText, outParamDigestTextSize, (BYTE *) 
&outParamDigest);
+  
+  // Create HMAC text. (Concat inParamsDigest with inAuthSetupParams).
+  TPM_DIGEST hm;
+  BYTE hmacText[sizeof(TPM_DIGEST) + (2 * sizeof(TPM_NONCE)) + sizeof(BOOL)];
+  
+  BSG_PackList(   hmacText, 4, 
+                 BSG_TPM_DIGEST, &outParamDigest,
+                 BSG_TPM_NONCE, &(auth->NonceEven),
+                 BSG_TPM_NONCE, &(auth->NonceOdd), 
+                 BSG_TYPE_BOOL, &(auth->fContinueAuthSession) );
+  
+  Crypto_HMAC((BYTE *) hmacText, sizeof(hmacText),
+             (BYTE *) HMACkey, sizeof(TPM_DIGEST), (BYTE *) &hm);
+    
+  // Compare correct HMAC with provided one.
+  if (memcmp (&hm, &(auth->HMAC), sizeof(TPM_DIGEST)) == 0)  // 0 indicates 
equality
+    return (TPM_SUCCESS);
+  else {
+    VTSP_OIAP( hContext, auth);
+    return (TPM_AUTHFAIL);
+  }
+}
+
+TPM_RESULT VTSP_OIAP(const TCS_CONTEXT_HANDLE hContext,
+                    TCS_AUTH *auth) {
+  
+  vtpmloginfo(VTPM_LOG_VTSP, "OIAP.\n");
+  TPM_RESULT status = TPM_SUCCESS;                           
+  TPMTRYRETURN( TCSP_OIAP(hContext,
+                         &auth->AuthHandle,
+                         &auth->NonceEven) );
+  goto egress;
+  
+ abort_egress:
+  
+ egress:
+  
+  return status;
+}
+
+TPM_RESULT VTSP_OSAP(const TCS_CONTEXT_HANDLE hContext,
+                    const TPM_ENTITY_TYPE entityType,
+                    const UINT32 entityValue,
+                    const TPM_AUTHDATA *usageAuth,
+                    TPM_SECRET *sharedSecret, 
+                    TCS_AUTH *auth) {
+  
+  vtpmloginfo(VTPM_LOG_VTSP, "OSAP.\n");
+  TPM_RESULT status = TPM_SUCCESS;
+  TPM_NONCE nonceEvenOSAP, nonceOddOSAP;
+  
+  Crypto_GetRandom((BYTE *) &nonceOddOSAP, sizeof(TPM_NONCE) ); 
+  
+  TPMTRYRETURN( TCSP_OSAP(    hContext,
+                             TPM_ET_SRK,
+                             0, 
+                             nonceOddOSAP,
+                             &auth->AuthHandle, 
+                             &auth->NonceEven, 
+                             &nonceEvenOSAP) );
+  
+  // Calculating Session Secret
+  BYTE sharedSecretText[TPM_DIGEST_SIZE * 2];
+  
+  BSG_PackList(  sharedSecretText, 2,
+                BSG_TPM_NONCE, &nonceEvenOSAP,
+                BSG_TPM_NONCE, &nonceOddOSAP);
+  
+  Crypto_HMAC(sharedSecretText, sizeof(sharedSecretText), (BYTE *) usageAuth, 
TPM_DIGEST_SIZE, (BYTE *) sharedSecret);       
+    
+  goto egress;
+  
+ abort_egress:
+  
+ egress:
+  
+  return status;
+}
+
+
+
+TPM_RESULT VTSP_ReadPubek(   const TCS_CONTEXT_HANDLE hContext,
+                             CRYPTO_INFO *crypto_info) {
+  
+  TPM_RESULT status;
+  TPM_NONCE antiReplay;
+  TPM_DIGEST   checksum;
+  BYTE *pubEKtext;
+  UINT32 pubEKtextsize;
+  
+  vtpmloginfo(VTPM_LOG_VTSP, "Reading Public EK.\n");
+  
+  // GenerateAuth new nonceOdd    
+  Crypto_GetRandom(&antiReplay, sizeof(TPM_NONCE) );
+  
+  
+  TPMTRYRETURN( TCSP_ReadPubek(  hContext,
+                                antiReplay,
+                                &pubEKtextsize,
+                                &pubEKtext,
+                                &checksum) );
+  
+  
+  // Extract the remaining output parameters
+  TPM_PUBKEY pubEK;
+  
+  BSG_Unpack(BSG_TPM_PUBKEY, pubEKtext, (BYTE *) &pubEK);
+  
+  // Build CryptoInfo for the bindingKey
+  TPM_RSA_KEY_PARMS rsaKeyParms;
+  
+  BSG_Unpack(BSG_TPM_RSA_KEY_PARMS, 
+            pubEK.algorithmParms.parms, 
+            &rsaKeyParms);
+  
+  Crypto_RSABuildCryptoInfoPublic(rsaKeyParms.exponentSize, 
+                                 rsaKeyParms.exponent, 
+                                 pubEK.pubKey.keyLength, 
+                                 pubEK.pubKey.key, 
+                                 crypto_info);
+    
+  // Destroy rsaKeyParms
+  BSG_Destroy(BSG_TPM_RSA_KEY_PARMS, &rsaKeyParms);
+
+  // Set encryption scheme
+  crypto_info->encScheme = CRYPTO_ES_RSAESOAEP_SHA1_MGF1;
+  //crypto_info->encScheme = pubEK.algorithmParms.encScheme;
+  crypto_info->algorithmID = pubEK.algorithmParms.algorithmID;
+  
+  goto egress;
+  
+ abort_egress:
+  
+ egress:
+  
+  return status;
+}
+
+TPM_RESULT VTSP_TakeOwnership(   const TCS_CONTEXT_HANDLE hContext,
+                                 const TPM_AUTHDATA *ownerAuth, 
+                                 const TPM_AUTHDATA *srkAuth,
+                                 CRYPTO_INFO *ek_cryptoInfo,
+                                 TCS_AUTH *auth) {
+  
+  vtpmloginfo(VTPM_LOG_VTSP, "Taking Ownership of TPM.\n");
+  
+  TPM_RESULT status = TPM_SUCCESS;
+  TPM_COMMAND_CODE command = TPM_ORD_TakeOwnership;
+  TPM_PROTOCOL_ID proto_id = TPM_PID_OWNER;
+  BYTE *new_srk;
+  
+  BYTE *paramText;        // Digest to make Auth.
+  UINT32 paramTextSize;
+  
+  // vars for srkpubkey parameter
+  TPM_KEY srkPub;
+  TPM_KEY_PARMS srkKeyInfo = {TPM_ALG_RSA, TPM_ES_RSAESOAEP_SHA1_MGF1, 
TPM_SS_NONE, 12, 0};
+  BYTE srkRSAkeyInfo[12] = { 0x00, 0x00, (RSA_KEY_SIZE >> 8), 0x00,   0x00, 
0x00, 0x00, 0x02,   0x00, 0x00, 0x00, 0x00};
+  srkKeyInfo.parms = (BYTE *) &srkRSAkeyInfo;
+  
+  struct pack_buf_t srkText;
+  
+  // GenerateAuth new nonceOdd    
+  Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
+  
+  //These values are accurate for an enc(AuthData).
+  struct pack_buf_t encOwnerAuth, encSrkAuth;
+  
+  encOwnerAuth.data = (BYTE *)malloc(sizeof(BYTE) * 256);
+  encSrkAuth.data = (BYTE *)malloc(sizeof(BYTE) * 256);
+  
+  if (encOwnerAuth.data == NULL || encSrkAuth.data == NULL) {
+    vtpmloginfo(VTPM_LOG_VTSP, "Could not malloc encrypted auths.\n");
+    status = TPM_RESOURCES;
+    goto abort_egress;
+  }
+  
+  Crypto_RSAEnc(ek_cryptoInfo, sizeof(TPM_SECRET), (BYTE *) ownerAuth, 
&encOwnerAuth.size, encOwnerAuth.data);
+  Crypto_RSAEnc(ek_cryptoInfo, sizeof(TPM_SECRET), (BYTE *) srkAuth, 
&encSrkAuth.size, encSrkAuth.data);
+  
+  
+  // Build srk public key struct
+  srkPub.ver = TPM_STRUCT_VER_1_1;
+  srkPub.keyUsage = TPM_KEY_STORAGE;
+  srkPub.keyFlags = 0x00;
+  srkPub.authDataUsage = TPM_AUTH_ALWAYS;
+  memcpy(&srkPub.algorithmParms, &srkKeyInfo, sizeof(TPM_KEY_PARMS));
+  srkPub.PCRInfoSize = 0;
+  srkPub.PCRInfo = 0;
+  srkPub.pubKey.keyLength= 0;
+  srkPub.encDataSize = 0;
+  
+  srkText.data = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
+  srkText.size = BSG_Pack(BSG_TPM_KEY, (BYTE *) &srkPub, srkText.data);
+  
+  paramText = (BYTE *) malloc(sizeof(BYTE) *  TCPA_MAX_BUFFER_LENGTH);
+  
+  paramTextSize = BSG_PackList(paramText, 5,
+                              BSG_TPM_COMMAND_CODE,&command,
+                              BSG_TPM_PROTOCOL_ID, &proto_id,
+                              BSG_TPM_SIZE32_DATA, &encOwnerAuth,
+                              BSG_TPM_SIZE32_DATA, &encSrkAuth,
+                              BSG_TPM_KEY, &srkPub);
+  
+  TPMTRYRETURN( GenerateAuth( paramText, paramTextSize, ownerAuth, auth) );
+  
+  new_srk = srkText.data;
+  TPMTRYRETURN( TCSP_TakeOwnership ( hContext,
+                                    proto_id,
+                                    encOwnerAuth.size, 
+                                    encOwnerAuth.data,
+                                    encSrkAuth.size,
+                                    encSrkAuth.data,
+                                    &srkText.size,
+                                    &new_srk, 
+                                    auth ) );
+  
+  
+  paramTextSize = BSG_PackList(paramText, 2, 
+                              BSG_TPM_RESULT, &status,
+                              BSG_TPM_COMMAND_CODE, &command);
+  memcpy(paramText + paramTextSize, new_srk, srkText.size);
+  paramTextSize += srkText.size;
+  
+  
+  TPMTRYRETURN( VerifyAuth(  paramText, paramTextSize,
+                            ownerAuth, auth, 
+                            hContext) );
+  
+  goto egress;
+  
+ abort_egress:
+  
+ egress:
+  
+  free(srkText.data);
+  free(encSrkAuth.data);
+  free(encOwnerAuth.data);
+  free(paramText);
+  
+  TCS_FreeMemory(hContext, new_srk);
+  
+  return status;
+}
+
+TPM_RESULT VTSP_DisablePubekRead( const TCS_CONTEXT_HANDLE    hContext,
+                                  const TPM_AUTHDATA          *ownerAuth, 
+                                  TCS_AUTH                    *auth) {
+  
+  vtpmloginfo(VTPM_LOG_VTSP, "Disabling Pubek Read.\n");
+  
+  TPM_RESULT status = TPM_SUCCESS;
+  TPM_COMMAND_CODE command = TPM_ORD_DisablePubekRead;
+  
+  BYTE *paramText;        // Digest to make Auth.
+  UINT32 paramTextSize;
+    
+  // Generate HMAC   
+  Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
+  
+  paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
+  
+  paramTextSize = BSG_PackList(paramText, 1,
+                              BSG_TPM_COMMAND_CODE, &command);
+  
+  TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
+                             ownerAuth, auth) );
+  
+  // Call TCS
+  TPMTRYRETURN( TCSP_DisablePubekRead ( hContext, // in
+                                        auth) );
+  
+  // Verify Auth
+  paramTextSize = BSG_PackList(paramText, 2,
+                              BSG_TPM_RESULT, &status,
+                              BSG_TPM_COMMAND_CODE, &command);
+  
+  TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
+                           ownerAuth, auth, 
+                           hContext) );
+  goto egress;
+  
+ abort_egress:
+ egress:
+  free(paramText);
+  return status;
+}
+
+TPM_RESULT VTSP_CreateWrapKey(  const TCS_CONTEXT_HANDLE hContext,
+                                const TPM_KEY_USAGE      usage,
+                                const TPM_AUTHDATA       *newKeyAuth,
+                                const TCS_KEY_HANDLE     parentHandle, 
+                                const TPM_AUTHDATA       *osapSharedSecret,
+                                buffer_t                 *pubKeyBuf,
+                                TCS_AUTH                 *auth) {
+  
+  int i;
+  TPM_RESULT status = TPM_SUCCESS;
+  TPM_COMMAND_CODE command = TPM_ORD_CreateWrapKey;
+  
+  vtpmloginfo(VTPM_LOG_VTSP, "Creating new key of type %d.\n", usage);
+  
+  // vars for Calculate encUsageAuth
+  BYTE *paramText;      
+  UINT32 paramTextSize;
+  
+  // vars for Calculate encUsageAuth
+  BYTE XORbuffer[sizeof(TPM_SECRET) + sizeof(TPM_NONCE)];
+  TPM_DIGEST XORKey1;
+  UINT32 XORbufferSize;
+  TPM_SECRET encUsageAuth, encMigrationAuth;
+  
+  // vars for Flatten newKey prototype
+  BYTE *flatKey = (BYTE *) malloc(sizeof(BYTE) *  TCPA_MAX_BUFFER_LENGTH);
+  UINT32 flatKeySize = TCPA_MAX_BUFFER_LENGTH;                                 
   
+  struct pack_buf_t newKeyText;
+  
+  // Fill in newKey
+  TPM_KEY newKey;
+  
+  BYTE RSAkeyInfo[12] = { 0x00, 0x00, (RSA_KEY_SIZE >> 8), 0x00,   0x00, 0x00, 
0x00, 0x02,   0x00, 0x00, 0x00, 0x00};
+  newKey.algorithmParms.algorithmID = TPM_ALG_RSA;
+  newKey.algorithmParms.parms = (BYTE *) &RSAkeyInfo;
+  newKey.algorithmParms.parmSize = 12;
+  
+  switch (usage) {
+  case TPM_KEY_SIGNING:
+    vtpmloginfo(VTPM_LOG_VTSP, "Creating Signing Key...\n");
+    newKey.keyUsage = TPM_KEY_SIGNING;
+    newKey.algorithmParms.encScheme = TPM_ES_NONE;
+    newKey.algorithmParms.sigScheme = TPM_SS_RSASSAPKCS1v15_SHA1;
+    break;
+  case TPM_KEY_STORAGE:
+    vtpmloginfo(VTPM_LOG_VTSP, "Creating Storage Key...\n");
+    newKey.keyUsage = TPM_KEY_STORAGE;
+    newKey.algorithmParms.encScheme = TPM_ES_RSAESOAEP_SHA1_MGF1;
+    newKey.algorithmParms.sigScheme = TPM_SS_NONE;
+    break;
+  case TPM_KEY_BIND:
+    vtpmloginfo(VTPM_LOG_VTSP, "Creating Binding Key...\n");
+    newKey.keyUsage = TPM_KEY_BIND;
+    newKey.algorithmParms.encScheme = TPM_ES_RSAESOAEP_SHA1_MGF1;
+    newKey.algorithmParms.sigScheme = TPM_SS_NONE;
+    break;
+  default:
+    vtpmloginfo(VTPM_LOG_VTSP, "Cannot create key. Invalid Key Type.\n");
+    status = TPM_BAD_PARAMETER;
+    goto abort_egress;
+  }
+  
+  
+  newKey.ver = TPM_STRUCT_VER_1_1;
+  
+  newKey.keyFlags = 0;
+  newKey.authDataUsage = TPM_AUTH_ALWAYS;
+  newKey.pubKey.keyLength= 0;
+  newKey.encDataSize = 0;
+  newKey.encData = NULL;
+  
+  // FIXME: Support PCR bindings
+  newKey.PCRInfoSize = 0;
+  newKey.PCRInfo = NULL;
+  
+  // Calculate encUsageAuth                                    
+  XORbufferSize = BSG_PackList(  XORbuffer, 2, 
+                                BSG_TPM_SECRET, osapSharedSecret,
+                                BSG_TPM_NONCE, &auth->NonceEven);
+  Crypto_SHA1Full(XORbuffer, XORbufferSize, (BYTE *) &XORKey1);
+  
+  // FIXME: No support for migratable keys.
+  for (i=0; i < TPM_DIGEST_SIZE; i++) 
+    ((BYTE *) &encUsageAuth)[i] = ((BYTE *) &XORKey1)[i] ^ ((BYTE *) 
newKeyAuth)[i];
+  
+  // Flatten newKey prototype
+  flatKeySize = BSG_Pack(BSG_TPM_KEY, (BYTE *) &newKey, flatKey);
+  newKeyText.data = flatKey;
+  newKeyText.size = flatKeySize;
+  
+  // GenerateAuth new nonceOdd    
+  Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
+  
+  // Generate HMAC
+  paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
+  
+  paramTextSize = BSG_PackList(paramText, 3,
+                              BSG_TPM_COMMAND_CODE, &command,
+                              BSG_TPM_AUTHDATA, &encUsageAuth,
+                              BSG_TPM_AUTHDATA, &encMigrationAuth);
+  memcpy(paramText + paramTextSize, newKeyText.data, newKeyText.size);
+  paramTextSize += newKeyText.size;
+  
+  
+  TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
+                             osapSharedSecret, auth) );
+  
+  // Call TCS
+  TPMTRYRETURN( TCSP_CreateWrapKey(  hContext, 
+                                    parentHandle,
+                                    encUsageAuth,
+                                    encMigrationAuth,
+                                    &newKeyText.size,
+                                    &newKeyText.data,
+                                    auth) );
+  
+  // Verify Auth
+  paramTextSize = BSG_PackList(paramText, 2,
+                              BSG_TPM_RESULT, &status,
+                              BSG_TPM_COMMAND_CODE, &command);
+  memcpy(paramText + paramTextSize, newKeyText.data, newKeyText.size);
+  paramTextSize += newKeyText.size;
+  
+  TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
+                           osapSharedSecret, auth, 0) );
+  
+  // Unpack/return key structure
+  TPMTRYRETURN(buffer_init(pubKeyBuf, 0, 0) );
+  TPMTRYRETURN(buffer_append_raw(pubKeyBuf, newKeyText.size, newKeyText.data) 
);
+  
+  goto egress;
+  
+ abort_egress:
+  
+ egress:
+  
+  free(flatKey);
+  free(paramText);
+  TCS_FreeMemory(hContext, newKeyText.data);
+  
+  return status;
+}
+
+TPM_RESULT VTSP_LoadKey(const TCS_CONTEXT_HANDLE    hContext,
+                        const TCS_KEY_HANDLE        hUnwrappingKey,
+                        const buffer_t              *rgbWrappedKeyBlob,
+                        const TPM_AUTHDATA          *parentAuth,
+                        TPM_HANDLE                  *newKeyHandle,
+                        TCS_AUTH                    *auth,
+                        CRYPTO_INFO                 *cryptoinfo /*= NULL*/) {
+  
+  
+  vtpmloginfo(VTPM_LOG_VTSP, "Loading Key.\n%s","");
+  
+  TPM_RESULT status = TPM_SUCCESS;
+  TPM_COMMAND_CODE command = TPM_ORD_LoadKey;
+  
+  BYTE *paramText;        // Digest to make Auth.
+  UINT32 paramTextSize;
+  
+  if ((rgbWrappedKeyBlob == NULL) || (parentAuth == NULL) || 
+      (newKeyHandle==NULL) || (auth==NULL)) {
+    status = TPM_BAD_PARAMETER;
+    goto abort_egress;
+  }
+  
+  // Generate Extra TCS Parameters
+  TPM_HANDLE phKeyHMAC;
+  
+  // Generate HMAC
+  Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
+  
+  paramText = (BYTE *) malloc(sizeof(BYTE) *  TCPA_MAX_BUFFER_LENGTH);
+  
+  paramTextSize = BSG_PackList(paramText, 1,
+                              BSG_TPM_COMMAND_CODE, &command);
+  
+  memcpy(paramText + paramTextSize, rgbWrappedKeyBlob->bytes, 
buffer_len(rgbWrappedKeyBlob));
+  paramTextSize += buffer_len(rgbWrappedKeyBlob);
+  
+  TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
+                             parentAuth, auth) );
+  
+  // Call TCS
+  TPMTRYRETURN( TCSP_LoadKeyByBlob(  hContext,
+                                    hUnwrappingKey,
+                                    buffer_len(rgbWrappedKeyBlob),
+                                    rgbWrappedKeyBlob->bytes,
+                                    auth,
+                                    newKeyHandle,
+                                    &phKeyHMAC) );
+  
+  // Verify Auth
+  paramTextSize = BSG_PackList(paramText, 3,
+                              BSG_TPM_RESULT, &status,
+                              BSG_TPM_COMMAND_CODE, &command,
+                              BSG_TPM_HANDLE, newKeyHandle);
+  
+  TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
+                           parentAuth, auth, 
+                           hContext) );
+  
+  // Unpack/return key structure
+  if (cryptoinfo != NULL) {
+    TPM_KEY newKey;
+    
+    BSG_Unpack(BSG_TPM_KEY, rgbWrappedKeyBlob->bytes , &newKey);
+    TPM_RSA_KEY_PARMS rsaKeyParms;
+    
+    BSG_Unpack(BSG_TPM_RSA_KEY_PARMS, 
+              newKey.algorithmParms.parms, 
+              &rsaKeyParms);
+    
+    Crypto_RSABuildCryptoInfoPublic(rsaKeyParms.exponentSize, 
+                                   rsaKeyParms.exponent, 
+                                   newKey.pubKey.keyLength, 
+                                   newKey.pubKey.key, 
+                                   cryptoinfo);
+    
+    // Destroy rsaKeyParms
+    BSG_Destroy(BSG_TPM_RSA_KEY_PARMS, &rsaKeyParms);
+    
+    // Set encryption scheme
+    cryptoinfo->encScheme = CRYPTO_ES_RSAESOAEP_SHA1_MGF1;
+  }
+  
+  goto egress;
+  
+ abort_egress:
+  
+ egress:
+  
+  free(paramText);
+  return status;
+}
+
+TPM_RESULT VTSP_Unbind( const TCS_CONTEXT_HANDLE    hContext,
+                        const TPM_KEY_HANDLE        key_handle,
+                        const buffer_t              *bound_data,
+                        const TPM_AUTHDATA          *usage_auth,
+                        buffer_t                    *clear_data,
+                        TCS_AUTH                    *auth) {
+  
+  vtpmloginfo(VTPM_LOG_VTSP, "Unbinding %d bytes of data.\n", 
buffer_len(bound_data));
+  
+  TPM_RESULT status = TPM_SUCCESS;
+  TPM_COMMAND_CODE command = TPM_ORD_UnBind;
+  
+  BYTE *paramText;        // Digest to make Auth.
+  UINT32 paramTextSize;
+  
+  // Generate Extra TCS Parameters
+  struct pack_buf_t clear_data32;
+  BYTE *clear_data_text;
+  UINT32 clear_data_size;
+  
+  // Generate HMAC   
+  Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
+  
+  struct pack_buf_t bound_data32 = {bound_data->size, bound_data->bytes};
+  
+  paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
+  
+  paramTextSize = BSG_PackList(paramText, 2,
+                              BSG_TPM_COMMAND_CODE, &command,
+                              BSG_TPM_SIZE32_DATA, &bound_data32);
+  
+  TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
+                             usage_auth, auth) );
+  
+  // Call TCS
+  TPMTRYRETURN( TCSP_UnBind( hContext,
+                            key_handle,
+                            buffer_len(bound_data),
+                            bound_data->bytes,
+                            auth,
+                            &clear_data_size,
+                            &clear_data_text) );
+  
+  
+  // Verify Auth
+  clear_data32.size = clear_data_size;
+  clear_data32.data = clear_data_text;
+  paramTextSize = BSG_PackList(paramText, 3,
+                              BSG_TPM_RESULT, &status,
+                              BSG_TPM_COMMAND_CODE, &command,
+                              BSG_TPM_SIZE32_DATA, &clear_data32);
+  
+  TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
+                           usage_auth, auth, 
+                           hContext) );
+  
+  // Unpack/return key structure
+  TPMTRYRETURN(buffer_init(clear_data, 0, 0));
+  TPMTRYRETURN(buffer_append_raw (clear_data, clear_data_size, 
clear_data_text) );
+  
+  goto egress;
+  
+ abort_egress:
+  
+ egress:
+  
+  free(paramText);
+  TCS_FreeMemory(hContext, clear_data_text);
+  
+  return status;
+}
+
+TPM_RESULT VTSP_Bind(   CRYPTO_INFO *cryptoInfo, 
+                       const buffer_t *inData, 
+                       buffer_t *outData)               
+{
+  vtpmloginfo(VTPM_LOG_VTSP, "Binding %d bytes of data.\n", 
buffer_len(inData));
+  TPM_BOUND_DATA boundData;
+  UINT32 i;
+  
+  // Fill boundData's accessory information
+  boundData.ver = TPM_STRUCT_VER_1_1;
+  boundData.payload = TPM_PT_BIND;
+  boundData.payloadData = inData->bytes;
+  
+  // Pack boundData before encryption
+  BYTE* flatBoundData = (BYTE *)malloc(sizeof(BYTE) * 
+                                      (sizeof(TPM_VERSION) +
+                                       sizeof(TPM_PAYLOAD_TYPE) +
+                                       buffer_len(inData)));
+  if (flatBoundData == NULL) {
+    return TPM_NOSPACE;
+  }
+  UINT32 flatBoundDataSize = 0;
+  flatBoundDataSize = BSG_PackList(  flatBoundData, 2, 
+                                    BSG_TPM_VERSION, &boundData.ver, 
+                                    BSG_TYPE_BYTE, &boundData.payload);
+  
+  memcpy(flatBoundData+flatBoundDataSize, inData->bytes, buffer_len(inData));
+  flatBoundDataSize += buffer_len(inData);
+  
+  BYTE out_tmp[RSA_KEY_SIZE/8]; // RSAEnc does not do blocking, So this is 
what will come out.
+  UINT32 out_tmp_size;
+  
+  // Encrypt flatBoundData
+  Crypto_RSAEnc( cryptoInfo, 
+                flatBoundDataSize, 
+                flatBoundData, 
+                &out_tmp_size, 
+                out_tmp);
+  
+  if (out_tmp_size > RSA_KEY_SIZE/8) {
+    // The result of RSAEnc should be a fixed size based on key size.
+    vtpmlogerror(VTPM_LOG_VTSP, "Enc buffer just overflowed.\n");
+  }
+  
+  buffer_init(outData, 0, NULL);
+  buffer_append_raw(outData, out_tmp_size, out_tmp);
+  
+  vtpmloginfo(VTPM_LOG_TXDATA, "Bind Generated[%d] = 0x", out_tmp_size);
+  for(i = 0 ; i < out_tmp_size ; i++) {
+    vtpmloginfomore(VTPM_LOG_TXDATA, "%2.2x ", out_tmp[i]);
+  }
+  vtpmloginfomore(VTPM_LOG_TXDATA, "\n");
+  
+  // Free flatBoundData
+  free(flatBoundData);
+  
+  return TPM_SUCCESS;
+}
+
+// Function Reaches into unsupported TCS command, beware.
+TPM_RESULT VTSP_RawTransmit(const TCS_CONTEXT_HANDLE    hContext,
+                            const buffer_t *inbuf,
+                            buffer_t *outbuf ) {
+  
+  vtpmloginfo(VTPM_LOG_VTSP, "Passthrough in use.\n");
+  TPM_RESULT status = TPM_SUCCESS;
+  
+  // Generate Extra TCS Parameters
+  BYTE *resultText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
+  UINT32 resultTextSize =  TCPA_MAX_BUFFER_LENGTH;
+  
+  // Call TCS                          
+  TPMTRYRETURN( TCSP_RawTransmitData(buffer_len(inbuf), inbuf->bytes, 
+                                    &resultTextSize, resultText) );
+  
+  // Unpack/return key structure
+  TPMTRYRETURN(buffer_init (outbuf, resultTextSize, resultText) );             
                   
+  goto egress;
+  
+ abort_egress:
+  
+ egress:
+  TCS_FreeMemory(hContext, resultText);
+  free(resultText);
+  return status;
+}
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/manager/vtsp.h
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/manager/vtsp.h Thu Sep  1 10:16:14 2005
@@ -0,0 +1,102 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// vtsp.h
+// 
+//  Higher level interface to TCS.
+//
+// ==================================================================
+
+#ifndef __VTSP_H__
+#define __VTSP_H__
+
+#include "tcg.h"
+#include "tcs.h"
+
+#define KEY_BUFFER_SIZE 2048
+
+TPM_RESULT VTSP_RawTransmit(const TCS_CONTEXT_HANDLE    hContext,
+                            const buffer_t *inbuf,
+                            buffer_t *outbuf );
+
+TPM_RESULT VTSP_OIAP(  const TCS_CONTEXT_HANDLE hContext,
+                       TCS_AUTH *auth);
+                       
+TPM_RESULT VTSP_OSAP(  const TCS_CONTEXT_HANDLE hContext,
+                       const TPM_ENTITY_TYPE entityType,
+                       const UINT32 entityValue,
+                       const TPM_AUTHDATA *usageAuth,
+                       TPM_SECRET *sharedsecret, 
+                       TCS_AUTH *auth);
+
+TPM_RESULT VTSP_ReadPubek(   const TCS_CONTEXT_HANDLE hContext,
+                             CRYPTO_INFO *cypto_info);
+
+TPM_RESULT VTSP_TakeOwnership(   const TCS_CONTEXT_HANDLE hContext,
+                                 const TPM_AUTHDATA *ownerAuth, 
+                                 const TPM_AUTHDATA *srkAuth,
+                                 CRYPTO_INFO *ek_cryptoInfo,
+                                 TCS_AUTH *auth);
+                               
+TPM_RESULT VTSP_DisablePubekRead( const TCS_CONTEXT_HANDLE    hContext,
+                                  const TPM_AUTHDATA *ownerAuth, 
+                                  TCS_AUTH                    *auth);
+                               
+TPM_RESULT VTSP_CreateWrapKey(  const TCS_CONTEXT_HANDLE hContext,
+                                const TPM_KEY_USAGE      usage,
+                                const TPM_AUTHDATA       *newKeyAuth,
+                                const TCS_KEY_HANDLE     parentHandle, 
+                                const TPM_AUTHDATA       *osapSharedSecret,
+                                buffer_t                 *pubKeyBuf,
+                                TCS_AUTH                 *auth);
+
+TPM_RESULT VTSP_LoadKey(const TCS_CONTEXT_HANDLE    hContext,
+                        const TCS_KEY_HANDLE        hUnwrappingKey,
+                        const buffer_t              *rgbWrappedKeyBlob,
+                        const TPM_AUTHDATA          *parentAuth,
+                        TPM_HANDLE                  *newKeyHandle,
+                        TCS_AUTH                    *pAuth,
+                        CRYPTO_INFO                 *cryptoinfo);
+
+TPM_RESULT VTSP_Unbind( const TCS_CONTEXT_HANDLE    hContext,
+                        const TPM_KEY_HANDLE        key_handle,
+                        const buffer_t              *bound_data,
+                        const TPM_AUTHDATA          *usage_auth,
+                        buffer_t                    *clear_data,
+                        TCS_AUTH                    *auth);
+                        
+TPM_RESULT VTSP_Bind(   CRYPTO_INFO *cryptoInfo,
+            const buffer_t *inData, 
+            buffer_t *outData);
+                        
+#endif //_VTSP_H_
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/tcs/Makefile
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/tcs/Makefile   Thu Sep  1 10:16:14 2005
@@ -0,0 +1,18 @@
+XEN_ROOT = ../../..
+include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
+
+BIN            = libTCS.a
+
+all: build
+
+build: $(BIN)
+
+install: build
+
+clean:
+       rm -f *.a *.so *.o *.rpm $(DEP_FILES)
+
+mrproper: clean
+
+$(BIN): $(OBJS)
+       $(AR) rcs $(BIN) $(OBJS)
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/tcs/contextmgr.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/tcs/contextmgr.c       Thu Sep  1 10:16:14 2005
@@ -0,0 +1,219 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// contextmgr.c
+// 
+//  This file contains the context management functions for TCS.
+// 
+// ==================================================================
+
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+#include "tcs.h"
+#include "contextmgr.h"
+#include "log.h"
+
+BYTE* AddMemBlock(CONTEXT_HANDLE* pContextHandle, // in
+                 int    BlockSize)  { // in
+  
+  BLOCK* pCurrentBlock = NULL;
+  BLOCK* pBlock = NULL;
+                    
+  // check incoming params
+  if (pContextHandle == NULL || BlockSize == 0)
+    return NULL;
+
+  // Create New Block
+  pBlock = (BLOCK *)malloc(sizeof(BLOCK));
+  if (pBlock == NULL)
+    return (0);
+
+  pBlock->aMemory = (BYTE *)malloc(sizeof(BYTE) * BlockSize);
+  if (pBlock->aMemory == NULL)
+    return (0);
+
+  memset(pBlock->aMemory, 0, BlockSize);
+  pBlock->nBlockSize = BlockSize;
+  pBlock->pNextBlock = NULL;
+  
+  // search for the last block created where to add the 
+  // newly created block
+  if(pContextHandle->pTopBlock != NULL) {
+    pCurrentBlock = pContextHandle->pTopBlock;
+    while(pCurrentBlock->pNextBlock != NULL)
+      pCurrentBlock = pCurrentBlock->pNextBlock;
+    
+    
+    pCurrentBlock->pNextBlock= pBlock;
+  } else
+    pContextHandle->pTopBlock = pBlock;
+  
+  
+  pContextHandle->nBlockCount++;
+  
+  return pBlock->aMemory;
+}
+
+
+BOOL DeleteMemBlock(CONTEXT_HANDLE* pContextHandle, // in
+                    BYTE*   pTCPA_BYTEs) { // in
+  BLOCK* pCurrentBlock = NULL;
+  BLOCK* pParentBlock = NULL;
+  BOOL bFound = FALSE;
+  
+  if (pContextHandle == NULL) 
+    return FALSE;
+
+  
+  // Search for the Block in the context by aMemory pointer
+  pParentBlock = NULL;
+  pCurrentBlock = pContextHandle->pTopBlock;
+  
+  while(pCurrentBlock != NULL) {
+    // If aMemory block is found, delete it 
+    if(pCurrentBlock->aMemory == pTCPA_BYTEs || pTCPA_BYTEs == NULL) {
+      // if it is the top Block, remove it from the top, 
+      // otherwise remove it from the ParentBlock and stitch 
+      // the NextBlock to the ParentBlock
+      if(pParentBlock == NULL)
+       pContextHandle->pTopBlock = pContextHandle->pTopBlock->pNextBlock;
+      else
+       pParentBlock->pNextBlock = pCurrentBlock->pNextBlock;
+      
+      // delete memory Block associated with pointer pTCPA_BYTEs
+      free(pCurrentBlock->aMemory);
+      pCurrentBlock->aMemory = NULL;
+      
+      free(pCurrentBlock);
+      pCurrentBlock = pParentBlock;
+      
+      pContextHandle->nBlockCount--;
+      bFound = TRUE;
+    }
+  
+    if(pCurrentBlock != NULL) {
+      pParentBlock = pCurrentBlock;
+      pCurrentBlock = pCurrentBlock->pNextBlock;
+    }
+  }
+  
+  return bFound;
+}
+
+BOOL AddHandleToList(CONTEXT_HANDLE* pContextHandle, // in
+                    TPM_RESOURCE_TYPE type, // in
+                    TPM_HANDLE    handle)  { // in
+  HANDLE_LIST* pNewHandle = NULL;
+  
+  vtpmloginfo(VTPM_LOG_TCS_DEEP, "Adding Handle to list\n");
+  if (pContextHandle == NULL)
+    return 0;
+  
+  pNewHandle = (HANDLE_LIST *)malloc(sizeof(HANDLE_LIST));
+  
+  if (pNewHandle == NULL) 
+    return (0);
+  
+  pNewHandle->handle = handle;
+  pNewHandle->type = type;
+  pNewHandle->pNextHandle = pContextHandle->pHandleList;
+  
+  pContextHandle->pHandleList = pNewHandle;
+  
+  return 1;
+}
+
+BOOL DeleteHandleFromList(   CONTEXT_HANDLE*     pContextHandle, // in
+                             TPM_HANDLE          handle) { // in
+    
+  HANDLE_LIST *pCurrentHandle = pContextHandle->pHandleList, 
+    *pLastHandle = pCurrentHandle;
+  
+  vtpmloginfo(VTPM_LOG_TCS_DEEP, "Deleting Handle from list\n");
+  
+  if (pContextHandle == NULL)
+    return 0;
+  
+  while (1) {
+    
+    if (pCurrentHandle->handle == handle) { // Found element
+      if (pCurrentHandle == pLastHandle) { // First element in list 
+       pContextHandle->pHandleList = pCurrentHandle->pNextHandle;
+       free(pCurrentHandle);
+      } else { // Ordinary element
+       pLastHandle->pNextHandle = pCurrentHandle->pNextHandle;
+       free(pCurrentHandle);
+      }
+      
+      return 1;
+      
+    } else { // Not found yet;
+      pLastHandle = pCurrentHandle;
+      pCurrentHandle = pCurrentHandle->pNextHandle;
+      if (pCurrentHandle == NULL) // Found end of list
+       return 0;
+    }
+    
+  }
+}
+
+BOOL FreeHandleList(    CONTEXT_HANDLE*     pContextHandle) { // in
+  HANDLE_LIST* pCurrentHandle;
+  BOOL returncode = TRUE;
+  
+  vtpmloginfo(VTPM_LOG_TCS_DEEP, "Freeing all handles for context\n");
+  
+  if (pContextHandle == NULL)
+    return 1;
+  
+  pCurrentHandle = pContextHandle->pHandleList;
+  while (pCurrentHandle != NULL) {
+    
+    switch (pCurrentHandle->type) {
+    case TPM_RT_KEY:
+      returncode = returncode && !TCSP_EvictKey((TCS_CONTEXT_HANDLE) 
pContextHandle, pCurrentHandle->handle);
+      break;
+    case TPM_RT_AUTH:
+      returncode = returncode && !TCSP_TerminateHandle((TCS_CONTEXT_HANDLE) 
pContextHandle, pCurrentHandle->handle);
+      break;
+    default:
+      returncode = FALSE;
+    }
+    
+    pCurrentHandle = pCurrentHandle->pNextHandle;
+    
+  }
+  
+  return 1;
+}
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/tcs/contextmgr.h
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/tcs/contextmgr.h       Thu Sep  1 10:16:14 2005
@@ -0,0 +1,81 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// contextmgr.c
+// 
+//  This file contains the context management functions for TCS.
+// 
+// ==================================================================
+
+#ifndef __CONTEXTMGR_H__
+#define __CONTEXTMGR_H__
+
+#include "tcg.h"
+
+#define BLOCK_SIZE 300
+
+typedef struct block {
+  int nBlockSize;
+  BYTE* aMemory;
+  struct block* pNextBlock;
+} BLOCK;
+
+typedef struct handle_List {
+  TPM_HANDLE handle;
+  TPM_RESOURCE_TYPE type;
+  struct handle_List* pNextHandle;
+} HANDLE_LIST;
+
+typedef struct context_handle {
+  int nBlockCount;
+  BLOCK* pTopBlock;
+  HANDLE_LIST* pHandleList;
+} CONTEXT_HANDLE;
+
+BYTE* AddMemBlock(  CONTEXT_HANDLE*     pContextHandle, // in
+                    int                 BlockSize);  // in
+
+BOOL DeleteMemBlock(CONTEXT_HANDLE* pContextHandle, // in
+                    BYTE*           pTCPA_BYTEs); // in
+
+
+BOOL AddHandleToList(   CONTEXT_HANDLE*     pContextHandle, // in
+                        TPM_RESOURCE_TYPE   type, // in
+                        TPM_HANDLE          handle); // in
+
+BOOL DeleteHandleFromList(   CONTEXT_HANDLE*     pContextHandle, // in
+                             TPM_HANDLE          handle); // in
+
+BOOL FreeHandleList(    CONTEXT_HANDLE*     pContextHandle); // in
+
+#endif //_CONTEXTMGR_H_
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/tcs/tcs.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/tcs/tcs.c      Thu Sep  1 10:16:14 2005
@@ -0,0 +1,1102 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// tcs.c
+// 
+//  This file contains the functions that implement a TCS.
+// 
+// ==================================================================
+
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+
+#include "tcg.h"
+#include "bsg.h"
+#include "tcs.h"
+#include "contextmgr.h"
+#include "tpmddl.h"
+#include "log.h"
+
+// Static Global Vars for the TCS
+static BOOL TCS_m_bConnected;
+static int TCS_m_nCount = 0;
+
+#define TCPA_MAX_BUFFER_LENGTH 0x2000
+
+static BYTE InBuf [TCPA_MAX_BUFFER_LENGTH];
+static BYTE OutBuf[TCPA_MAX_BUFFER_LENGTH];
+
+
+// 
---------------------------------------------------------------------------------
+// Initialization/Uninitialization SubComponent API
+// 
---------------------------------------------------------------------------------
+TPM_RESULT TCS_create() {
+  TDDL_RESULT hRes = TDDL_E_FAIL;
+  TPM_RESULT result = TPM_FAIL;
+  TCS_m_bConnected = FALSE;
+  
+  if (TCS_m_nCount == 0) {
+    vtpmloginfo(VTPM_LOG_TCS, "Constructing new TCS:\n");
+    hRes = TDDL_Open();
+    
+    if (hRes == TDDL_SUCCESS) {
+      TCS_m_bConnected = TRUE;
+      result = TPM_SUCCESS;
+    }
+  } else
+    TCS_m_bConnected = TRUE;
+  
+  TCS_m_nCount++;
+  
+  return(result);
+}
+
+
+void TCS_destroy()
+{
+  // FIXME: Should iterate through all open contexts and close them.
+  TCS_m_nCount--;
+  
+  if (TCS_m_bConnected == TRUE && TCS_m_nCount == 0) {
+    vtpmloginfo(VTPM_LOG_TCS, "Destructing TCS:\n");
+    TDDL_Close();
+    TCS_m_bConnected = FALSE;
+  }
+  
+}
+
+TPM_RESULT TCS_Malloc(  TCS_CONTEXT_HANDLE  hContext, // in
+                        UINT32              MemSize, // in
+                        BYTE**              ppMemPtr) {// out
+
+  TPM_RESULT returnCode = TPM_FAIL;
+  CONTEXT_HANDLE* pContextHandle = (CONTEXT_HANDLE*)hContext;
+  
+  if (pContextHandle != NULL && ppMemPtr != NULL) {
+    *ppMemPtr = (BYTE *)AddMemBlock(pContextHandle, MemSize);
+    returnCode = TPM_SUCCESS;
+  }
+  
+  return returnCode;
+}
+
+TPM_RESULT TCS_FreeMemory(  TCS_CONTEXT_HANDLE  hContext, // in
+                            BYTE*               pMemory) { // in
+  TPM_RESULT returnCode = TPM_FAIL;
+  CONTEXT_HANDLE* pContextHandle = (CONTEXT_HANDLE*)hContext;
+  
+  if ( (pContextHandle != NULL && pMemory != NULL) &&
+       (DeleteMemBlock(pContextHandle, pMemory) == TRUE) )
+    returnCode = TPM_SUCCESS;
+ 
+  
+  return returnCode;
+}
+
+TPM_RESULT TCS_OpenContext(TCS_CONTEXT_HANDLE* hContext) { // out
+  TPM_RESULT returnCode = TPM_FAIL;
+  
+  vtpmloginfo(VTPM_LOG_TCS, "Calling TCS_OpenContext:\n");
+  
+  // hContext must point to a null memory context handle
+  if(*hContext == HANDLE_NULL) {
+    CONTEXT_HANDLE* pContextHandle = (CONTEXT_HANDLE 
*)malloc(sizeof(CONTEXT_HANDLE));
+    if (pContextHandle == NULL) 
+      return TPM_SIZE;
+    
+    
+    // initialize to 0
+    pContextHandle->nBlockCount = 0;
+    pContextHandle->pTopBlock = NULL;
+    pContextHandle->pHandleList = NULL;
+    
+    // Create New Block
+    AddMemBlock(pContextHandle, BLOCK_SIZE);
+    
+    *hContext = (TCS_CONTEXT_HANDLE)pContextHandle;
+    returnCode = TPM_SUCCESS;
+  }
+  
+  return(returnCode);
+}
+
+TPM_RESULT TCS_CloseContext(TCS_CONTEXT_HANDLE hContext) {// in
+  //FIXME: TCS SHOULD Track track failed auths and make sure
+  //we don't try and re-free them here.
+  TPM_RESULT returnCode = TPM_FAIL;
+  
+  CONTEXT_HANDLE* pContextHandle = (CONTEXT_HANDLE*)hContext;
+  
+  if(pContextHandle != NULL) {
+    // Print test info
+    vtpmloginfo(VTPM_LOG_TCS, "Calling TCS_CloseContext.\n");
+      
+    // free memory for all the blocks
+    DeleteMemBlock(pContextHandle, NULL );      
+    pContextHandle->pTopBlock = NULL;
+    
+    FreeHandleList(pContextHandle);
+    if (pContextHandle->pHandleList != NULL) 
+      vtpmlogerror(VTPM_LOG_TCS, "Not all handles evicted from TPM.\n");
+    
+    // Release the TPM's resources
+    free(pContextHandle);
+    returnCode = TPM_SUCCESS;
+  }
+  
+  vtpmloginfo(VTPM_LOG_TCS_DEEP, "Finished closing context\n");
+  return(returnCode);
+}
+
+// ------------------------------------------------------------------
+// Internal Functions
+// ------------------------------------------------------------------
+int packAuth(BYTE* dst, TCS_AUTH* auth) {
+  // CHECK: according to the command specs, the outgoing auth params are:
+  // nonceEven
+  // nonceOdd
+  // continueAuthSession
+  // auth digest for return params
+  //
+  // this is a bit different than this code...
+  
+  return BSG_PackList(dst, 4, 
+                     BSG_TYPE_UINT32, &(auth->AuthHandle), 
+                     BSG_TPM_NONCE, &(auth->NonceOdd), 
+                     BSG_TYPE_BOOL, &(auth->fContinueAuthSession), 
+                     BSG_TPM_AUTHDATA, &(auth->HMAC));
+}
+
+int unpackAuth(TCS_AUTH* auth, BYTE* src) {
+  return BSG_UnpackList(src, 3, 
+                       BSG_TPM_NONCE, &(auth->NonceEven), 
+                       BSG_TYPE_BOOL, &(auth->fContinueAuthSession), 
+                       BSG_TPM_AUTHDATA, &(auth->HMAC));
+}
+
+// ------------------------------------------------------------------
+// Authorization Commands
+// ------------------------------------------------------------------
+
+TPM_RESULT TCSP_OIAP(TCS_CONTEXT_HANDLE hContext, // in
+                    TCS_AUTHHANDLE*  authHandle, // out 
+                    TPM_NONCE*   nonce0)  // out
+{
+  // setup input/output parameters block
+  TPM_TAG tag = TPM_TAG_RQU_COMMAND;
+  TPM_COMMAND_CODE ordinal = TPM_ORD_OIAP;
+  UINT32 paramSize = 0;
+  TPM_RESULT returnCode = TPM_SUCCESS;
+  
+  // setup the TPM driver input and output buffers
+  TDDL_RESULT hRes = TDDL_E_FAIL;
+  TDDL_UINT32  InLength = TCPA_MAX_BUFFER_LENGTH;
+  TDDL_UINT32  OutLength = TCPA_MAX_BUFFER_LENGTH;
+  
+  // check input params
+  if (authHandle == NULL || nonce0 == NULL) 
+    return TPM_BAD_PARAMETER;
+  
+  // Convert Byte Input parameter in the input byte stream InBuf
+  InLength = BSG_PackList(InBuf, 3, 
+                         BSG_TPM_TAG, &tag, 
+                         BSG_TYPE_UINT32, &paramSize, 
+                         BSG_TPM_COMMAND_CODE, &ordinal);
+    
+  // fill paramSize again as we now have the correct size
+  BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2);
+  
+  vtpmloginfo(VTPM_LOG_TCS_DEEP, "Sending paramSize = %d\n", InLength);
+  
+  // call the TPM driver
+  if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength)) 
+      == TDDL_SUCCESS) {
+    
+    // unpack to get the tag, paramSize, & returnCode
+    int i = BSG_UnpackList( OutBuf, 3, 
+                           BSG_TPM_TAG, &tag, 
+                           BSG_TYPE_UINT32, &paramSize, 
+                           BSG_TPM_COMMAND_CODE, &returnCode);
+    
+    if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_COMMAND) {
+      // Extract the remaining output parameters
+      BSG_UnpackList(OutBuf+i, 2, 
+                    BSG_TYPE_UINT32, authHandle, 
+                    BSG_TPM_NONCE, nonce0);
+      
+      if (!AddHandleToList((CONTEXT_HANDLE *)hContext, TPM_RT_AUTH, 
*authHandle)) 
+        vtpmlogerror(VTPM_LOG_TCS, "New AuthHandle not recorded\n");
+      
+      vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n", paramSize);
+    } else 
+      vtpmlogerror(VTPM_LOG_TCS, "Failed with return code %s\n", 
tpm_get_error_name(returnCode));
+    
+  }
+  
+  return(returnCode);
+}
+
+TPM_RESULT TCSP_OSAP(TCS_CONTEXT_HANDLE hContext,  // in
+                    TPM_ENTITY_TYPE  entityType,  // in
+                    UINT32    entityValue, // in
+                    TPM_NONCE   nonceOddOSAP, // in
+                    TCS_AUTHHANDLE*  authHandle,  // out 
+                    TPM_NONCE*   nonceEven,  // out
+                    TPM_NONCE*   nonceEvenOSAP) // out
+{
+  // setup input/output parameters block
+  TPM_TAG tag = TPM_TAG_RQU_COMMAND;
+  UINT32 paramSize = 0;
+  TPM_COMMAND_CODE ordinal = TPM_ORD_OSAP;
+  TPM_RESULT returnCode = TPM_SUCCESS;
+  
+  // setup the TPM driver input and output buffers
+  TDDL_RESULT hRes = TDDL_E_FAIL;
+  TDDL_UINT32  InLength = TCPA_MAX_BUFFER_LENGTH;
+  TDDL_UINT32  OutLength = TCPA_MAX_BUFFER_LENGTH;
+  
+  // check input params
+  if (authHandle == NULL || nonceEven == NULL || nonceEvenOSAP == NULL)
+    return TPM_BAD_PARAMETER;
+  
+  // Convert Byte Input parameter in the input byte stream InBuf
+  InLength = BSG_PackList(InBuf, 6, 
+                         BSG_TPM_TAG, &tag, 
+                         BSG_TYPE_UINT32, &paramSize, 
+                         BSG_TPM_COMMAND_CODE, &ordinal, 
+                         BSG_TYPE_UINT16, &entityType, 
+                         BSG_TYPE_UINT32, &entityValue, 
+                         BSG_TPM_NONCE, &nonceOddOSAP);
+  
+  // fill paramSize again as we now have the correct size
+  BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2);
+  
+  vtpmloginfo(VTPM_LOG_TCS_DEEP, "Sending paramSize = %d\n", InLength);
+  
+  // call the TPM driver
+  if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength)) 
+            == TDDL_SUCCESS) {
+
+    // unpack to get the tag, paramSize, & returnCode
+    int i = BSG_UnpackList(OutBuf, 3, 
+                          BSG_TPM_TAG, &tag, 
+                          BSG_TYPE_UINT32, &paramSize, 
+                          BSG_TPM_COMMAND_CODE, &returnCode);
+    
+    if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_COMMAND) {
+      // Extract the remaining output parameters
+      BSG_UnpackList(OutBuf+i, 3, 
+                    BSG_TYPE_UINT32, authHandle, 
+                    BSG_TPM_NONCE, nonceEven, 
+                    BSG_TPM_NONCE, nonceEvenOSAP);
+      
+      if (!AddHandleToList((CONTEXT_HANDLE *)hContext, TPM_RT_AUTH, 
*authHandle)) {
+           vtpmlogerror(VTPM_LOG_TCS, "New AuthHandle not recorded\n");
+      }
+      
+      vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n", paramSize);
+    } else 
+      vtpmlogerror(VTPM_LOG_TCS, "Failed with return code %s\n", 
tpm_get_error_name(returnCode));
+    
+  }
+  
+  return(returnCode);
+}
+
+TPM_RESULT TCSP_TakeOwnership(TCS_CONTEXT_HANDLE hContext,   // in
+                             UINT16    protocolID,   // in
+                             UINT32    encOwnerAuthSize, // in 
+                             BYTE*    encOwnerAuth,  // in
+                             UINT32    encSrkAuthSize,  // in
+                             BYTE*    encSrkAuth,   // in
+                             UINT32*    SrkSize,   // in, out
+                             BYTE**    Srk,    // in, out
+                             TCS_AUTH*   ownerAuth)   // in, out
+{
+  // setup input/output parameters block
+  TPM_TAG tag = TPM_TAG_RQU_AUTH1_COMMAND;
+  UINT32 paramSize = 0;
+  TPM_COMMAND_CODE ordinal = TPM_ORD_TakeOwnership;
+  TPM_RESULT returnCode = TPM_SUCCESS;
+  
+  // setup the TPM driver input and output buffers
+  TDDL_RESULT hRes = TDDL_E_FAIL;
+  TDDL_UINT32 InLength = TCPA_MAX_BUFFER_LENGTH;
+  TDDL_UINT32 OutLength = TCPA_MAX_BUFFER_LENGTH;
+  
+  // check input params
+  if (encOwnerAuth == NULL || encSrkAuth == NULL || SrkSize == NULL || *Srk == 
NULL) 
+    return TPM_BAD_PARAMETER;
+  
+  // Convert Byte Input parameter in the input byte stream InBuf
+  InLength = BSG_PackList(InBuf, 5, 
+                         BSG_TPM_TAG, &tag, 
+                         BSG_TYPE_UINT32, &paramSize, 
+                         BSG_TPM_COMMAND_CODE, &ordinal, 
+                         BSG_TYPE_UINT16, &protocolID, 
+                         BSG_TYPE_UINT32, &encOwnerAuthSize);
+  
+  memcpy(InBuf+InLength, encOwnerAuth, encOwnerAuthSize);
+  InLength += encOwnerAuthSize;
+  InLength += BSG_Pack(   BSG_TYPE_UINT32, 
+                         &encSrkAuthSize, 
+                         InBuf+InLength);
+  memcpy(InBuf+InLength, encSrkAuth, encSrkAuthSize);
+  InLength += encSrkAuthSize;
+  memcpy(InBuf+InLength, *Srk, *SrkSize);
+  InLength += *SrkSize;
+  InLength += packAuth(InBuf+InLength, ownerAuth);
+  // fill paramSize again as we now have the correct size
+  BSG_Pack(BSG_TYPE_UINT32, 
+          &InLength, 
+          InBuf+2);
+  
+  vtpmloginfo(VTPM_LOG_TCS_DEEP, "Sending paramSize = %d\n", InLength);
+  
+  // call the TPM driver
+  if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength)) 
+              == TDDL_SUCCESS){
+    
+    // unpack to get the tag, paramSize, & returnCode
+    int i = BSG_UnpackList( OutBuf, 3, 
+                           BSG_TPM_TAG, &tag, 
+                           BSG_TYPE_UINT32, &paramSize, 
+                           BSG_TPM_COMMAND_CODE, &returnCode);
+    
+    if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_AUTH1_COMMAND) {
+      // Extract the remaining output parameters
+      TPM_KEY srkPub;
+      i += BSG_Unpack(BSG_TPM_KEY,  OutBuf+i,  &srkPub); 
+      unpackAuth(ownerAuth, OutBuf+i);
+      
+      // fill output params
+      BYTE tempBuf[1024];
+      *SrkSize = BSG_Pack(BSG_TPM_KEY,  &srkPub, tempBuf);
+      if (TCS_Malloc(hContext, *SrkSize, Srk) == TPM_FAIL) {
+       return(TPM_SIZE);
+      }
+      memcpy(*Srk, tempBuf, *SrkSize);
+      
+      vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d", paramSize);
+    } else 
+      vtpmlogerror(VTPM_LOG_TCS, "TCSP_TakeOwnership Failed with return code 
%s\n", tpm_get_error_name(returnCode));
+  }
+  
+  return(returnCode);
+}
+
+
+TPM_RESULT TCSP_DisablePubekRead (  TCS_CONTEXT_HANDLE hContext, // in
+                                    TCS_AUTH*   ownerAuth) { // in, out
+ 
+  // setup input/output parameters block
+  TPM_TAG tag = TPM_TAG_RQU_AUTH1_COMMAND;
+  UINT32 paramSize = 0;
+  TPM_COMMAND_CODE ordinal = TPM_ORD_DisablePubekRead;
+  TPM_RESULT returnCode = TPM_SUCCESS;
+  
+  // setup the TPM driver input and output buffers
+  TDDL_RESULT hRes = TDDL_E_FAIL;
+  TDDL_UINT32 InLength = TCPA_MAX_BUFFER_LENGTH;
+  TDDL_UINT32 OutLength = TCPA_MAX_BUFFER_LENGTH;
+    
+  // Convert Byte Input parameter in the input byte stream InBuf
+  InLength = BSG_PackList(InBuf, 3, 
+                         BSG_TPM_TAG, &tag, 
+                         BSG_TYPE_UINT32, &paramSize, 
+                         BSG_TPM_COMMAND_CODE, &ordinal);
+  
+  InLength += packAuth(InBuf+InLength, ownerAuth);
+ 
+  // fill paramSize again as we now have the correct size
+  BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2);
+  
+  vtpmloginfo(VTPM_LOG_TCS_DEEP, "Sending paramSize = %d\n", InLength);
+  
+  // call the TPM driver
+  if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength)) 
+              == TDDL_SUCCESS){
+    
+    // unpack to get the tag, paramSize, & returnCode
+    int i = BSG_UnpackList( OutBuf, 3, 
+                           BSG_TPM_TAG, &tag, 
+                           BSG_TYPE_UINT32, &paramSize, 
+                           BSG_TPM_COMMAND_CODE, &returnCode);
+    
+    if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_AUTH1_COMMAND) {
+      // Extract the remaining output parameters
+      unpackAuth(ownerAuth, OutBuf+i);
+    } else 
+      vtpmlogerror(VTPM_LOG_TCS, "TCSP_DisablePubekRead Failed with return 
code %s\n", tpm_get_error_name(returnCode));
+  }
+  
+  return(returnCode);
+}
+
+
+TPM_RESULT TCSP_TerminateHandle(TCS_CONTEXT_HANDLE hContext, // in
+                                TCS_AUTHHANDLE  handle)  // in
+{
+  // setup input/output parameters block
+  TPM_TAG tag = TPM_TAG_RQU_COMMAND;
+  UINT32 paramSize = 0;
+  TPM_COMMAND_CODE ordinal = TPM_ORD_Terminate_Handle;
+  TPM_RESULT returnCode = TPM_SUCCESS;
+  
+  // setup the TPM driver input and output buffers
+  TDDL_RESULT hRes = TDDL_E_FAIL;
+  TDDL_UINT32  InLength = TCPA_MAX_BUFFER_LENGTH;
+  TDDL_UINT32  OutLength = TCPA_MAX_BUFFER_LENGTH;
+  
+  // Convert Byte Input parameter in the input byte stream InBuf
+  InLength = BSG_PackList(InBuf, 4, 
+                         BSG_TPM_TAG, &tag, 
+                         BSG_TYPE_UINT32, &paramSize, 
+                         BSG_TPM_COMMAND_CODE, &ordinal, 
+                         BSG_TYPE_UINT32, &handle);
+  // fill paramSize again as we now have the correct size
+  BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2);
+  
+  // call the TPM driver
+  if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength)) 
+              == TDDL_SUCCESS) {
+    
+    // unpack to get the tag, paramSize, & returnCode
+    BSG_UnpackList(OutBuf, 3, 
+                          BSG_TPM_TAG, &tag, 
+                          BSG_TYPE_UINT32, &paramSize, 
+                          BSG_TPM_COMMAND_CODE, &returnCode);
+    
+    if (!DeleteHandleFromList((CONTEXT_HANDLE *)hContext, handle)) 
+      vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n");
+       
+    
+    if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_COMMAND) {
+      // Print debug info
+      
+      vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d", paramSize);
+    } else 
+      vtpmlogerror(VTPM_LOG_TCS, "TCSP_TerminateHandle Failed with return code 
%s\n", tpm_get_error_name(returnCode));
+    
+  }
+  
+  return(returnCode);
+}
+
+// TPM Mandatory
+TPM_RESULT TCSP_Extend( TCS_CONTEXT_HANDLE hContext, // in
+                        TPM_PCRINDEX  pcrNum,  // in
+                        TPM_DIGEST  inDigest, // in
+                        TPM_PCRVALUE*  outDigest) // out
+{
+  // setup input/output parameters block
+  TPM_TAG tag = TPM_TAG_RQU_COMMAND;
+  UINT32 paramSize = 0;
+  TPM_COMMAND_CODE ordinal = TPM_ORD_Extend;
+  TPM_RESULT returnCode = TPM_SUCCESS;
+  
+  // setup the TPM driver input and output buffers
+  TDDL_RESULT hRes = TDDL_E_FAIL;
+  TDDL_UINT32  InLength = TCPA_MAX_BUFFER_LENGTH;
+  TDDL_UINT32  OutLength = TCPA_MAX_BUFFER_LENGTH;
+  
+  // Convert Byte Input parameter in the input byte stream InBuf
+  InLength = BSG_PackList(InBuf, 5, 
+                         BSG_TPM_TAG, &tag, 
+                         BSG_TYPE_UINT32, &paramSize, 
+                         BSG_TPM_COMMAND_CODE, &ordinal, 
+                         BSG_TYPE_UINT32, &pcrNum, 
+                         BSG_TPM_DIGEST, &inDigest);
+  // fill paramSize again as we now have the correct size
+  BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2);
+  
+  vtpmloginfo(VTPM_LOG_TCS_DEEP, "Sending paramSize = %d\n", InLength);
+  
+  // call the TPM driver
+  if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength)) 
+              == TDDL_SUCCESS) {
+    
+    // unpack to get the tag, paramSize, & returnCode
+    int i = BSG_UnpackList(OutBuf, 3, 
+                          BSG_TPM_TAG, &tag, 
+                          BSG_TYPE_UINT32, &paramSize, 
+                          BSG_TPM_COMMAND_CODE, &returnCode);
+    
+    if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_COMMAND){
+      // Extract the remaining output parameters
+      BSG_Unpack(BSG_TPM_PCRVALUE, OutBuf+i, outDigest);
+      
+      vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n", paramSize);
+    } else 
+      vtpmlogerror(VTPM_LOG_TCS, "TCSP_Extend Failed with return code %s\n", 
tpm_get_error_name(returnCode));
+  }
+  
+  return(returnCode);
+}
+
+TPM_RESULT TCSP_Seal(   TCS_CONTEXT_HANDLE hContext,  // in
+                        TCS_KEY_HANDLE  keyHandle,  // in
+                        TPM_ENCAUTH   encAuth,  // in
+                        UINT32    pcrInfoSize, // in
+                        BYTE*    PcrInfo,  // in
+                        UINT32    inDataSize,  // in
+                        BYTE*    inData,   // in
+                        TCS_AUTH*   pubAuth,  // in, out
+                        UINT32*    SealedDataSize, // out
+                        BYTE**    SealedData)  // out
+{
+  // setup input/output parameters block
+  TPM_TAG tag = TPM_TAG_RQU_AUTH1_COMMAND;
+  UINT32 paramSize = 0;
+  TPM_COMMAND_CODE ordinal = TPM_ORD_Seal;
+  TPM_RESULT returnCode = TPM_SUCCESS;
+  
+  // setup the TPM driver input and output buffers
+  TDDL_RESULT hRes = TDDL_E_FAIL;
+  TDDL_UINT32  InLength = TCPA_MAX_BUFFER_LENGTH;
+  TDDL_UINT32  OutLength = TCPA_MAX_BUFFER_LENGTH;
+  
+  // check input params
+  if (inData == NULL || pubAuth == NULL || SealedDataSize == NULL || 
*SealedData == NULL)
+    return TPM_BAD_PARAMETER;
+  
+  // Convert Byte Input parameter in the input byte stream InBuf
+  InLength = BSG_PackList(InBuf, 6, 
+                         BSG_TPM_TAG, &tag, 
+                         BSG_TYPE_UINT32, &paramSize, 
+                         BSG_TPM_COMMAND_CODE, &ordinal, 
+                         BSG_TYPE_UINT32, &keyHandle, 
+                         BSG_TPM_ENCAUTH, encAuth, 
+                         BSG_TYPE_UINT32, &pcrInfoSize);
+  memcpy(InBuf+InLength, PcrInfo, pcrInfoSize);
+  InLength += pcrInfoSize;
+  InLength += BSG_Pack(BSG_TYPE_UINT32, &inDataSize, InBuf+InLength);
+  memcpy(InBuf+InLength, inData, inDataSize);
+  InLength += inDataSize;
+  InLength += packAuth(InBuf+InLength, pubAuth);
+  // fill paramSize again as we now have the correct size
+  BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2);
+    
+  // call the TPM driver
+  if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength)) 
+              == TDDL_SUCCESS) {
+    // unpack OutBuf to get the tag, paramSize, & returnCode
+    int i = BSG_UnpackList(OutBuf, 3, 
+                          BSG_TPM_TAG, &tag, 
+                          BSG_TYPE_UINT32, &paramSize, 
+                          BSG_TPM_COMMAND_CODE, &returnCode);
+    
+    if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_AUTH1_COMMAND) {
+      // Extract the remaining output parameters
+      TPM_STORED_DATA sealedData;
+      
+      i += BSG_Unpack(BSG_TPM_STORED_DATA, OutBuf+i, &sealedData); 
+      unpackAuth(pubAuth, OutBuf+i);
+      
+      // fill SealedData
+      BYTE tempBuf[1024];
+      *SealedDataSize = BSG_Pack(BSG_TPM_STORED_DATA, &sealedData, tempBuf);
+      if (TCS_Malloc(hContext, *SealedDataSize, SealedData) == TPM_FAIL) {
+       return TPM_SIZE;
+      }
+      memcpy(*SealedData, tempBuf, *SealedDataSize);
+      
+      vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n", paramSize);
+    } else 
+      vtpmlogerror(VTPM_LOG_TCS, "TCSP_Seal Failed with return code %s\n", 
tpm_get_error_name(returnCode));
+  }
+  
+  return(returnCode);
+}
+
+TPM_RESULT TCSP_Unseal(TCS_CONTEXT_HANDLE hContext,  // in
+                      TCS_KEY_HANDLE  parentHandle, // in
+                      UINT32    SealedDataSize, // in
+                      BYTE*    SealedData,  // in
+                      TCS_AUTH*   parentAuth,  // in, out
+                      TCS_AUTH*   dataAuth,  // in, out
+                      UINT32*   DataSize,  // out
+                      BYTE**    Data)   // out
+{
+  // setup input/output parameters block
+  TPM_TAG tag = TPM_TAG_RQU_AUTH2_COMMAND;
+  UINT32 paramSize = 0;
+  TPM_COMMAND_CODE ordinal = TPM_ORD_Unseal;
+  TPM_RESULT returnCode = TPM_SUCCESS;
+  
+  // setup the TPM driver input and output buffers
+  TDDL_RESULT hRes = TDDL_E_FAIL;
+  TDDL_UINT32 InLength = TCPA_MAX_BUFFER_LENGTH;
+  TDDL_UINT32 OutLength = TCPA_MAX_BUFFER_LENGTH;
+  
+  // check input params
+  if (SealedData == NULL || parentAuth == NULL || dataAuth == NULL || 
+      DataSize == NULL || Data == NULL) 
+    return TPM_BAD_PARAMETER;
+  
+  
+  // Convert Byte Input parameter in the input byte stream InBuf
+  InLength = BSG_PackList(InBuf, 4, 
+                                     BSG_TPM_TAG, &tag, 
+                          BSG_TYPE_UINT32, &paramSize, 
+                          BSG_TPM_COMMAND_CODE, &ordinal, 
+                          BSG_TYPE_UINT32, &parentHandle);
+  memcpy(InBuf+InLength, SealedData, SealedDataSize);
+  InLength += SealedDataSize;
+  InLength += packAuth(InBuf+InLength, parentAuth);
+  InLength += packAuth(InBuf+InLength, dataAuth);
+  // fill paramSize again as we now have the correct size
+  BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2);
+  
+  vtpmloginfo(VTPM_LOG_TCS_DEEP, "Sending paramSize = %d\n", InLength);
+    
+  // call the TPM driver
+  if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength)) == 
TDDL_SUCCESS) {
+    // unpack OutBuf to get the tag, paramSize, & returnCode
+    int i = BSG_UnpackList( OutBuf, 3, 
+                            BSG_TPM_TAG, &tag, 
+                            BSG_TYPE_UINT32, &paramSize, 
+                            BSG_TPM_COMMAND_CODE, &returnCode);
+    
+    if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_AUTH2_COMMAND) {
+      // Extract the remaining output parameters
+      i += BSG_Unpack(BSG_TYPE_UINT32, OutBuf+i, DataSize);
+      if (TCS_Malloc(hContext, *DataSize, Data) == TPM_FAIL) {
+        return TPM_SIZE;
+      }
+      memcpy(*Data, OutBuf+i, *DataSize);
+      i += *DataSize;
+      i += unpackAuth(parentAuth, OutBuf+i);
+      unpackAuth(dataAuth, OutBuf+i);
+      
+      vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n", paramSize);
+    } else 
+      vtpmlogerror(VTPM_LOG_TCS, "TCSP_Unseal Failed with return code %s\n", 
tpm_get_error_name(returnCode));
+  }
+  
+  return(returnCode);
+}
+
+TPM_RESULT TCSP_UnBind(TCS_CONTEXT_HANDLE hContext,  // in
+                      TCS_KEY_HANDLE  keyHandle,  // in
+                      UINT32    inDataSize,  // in
+                      BYTE*    inData,   // in
+                      TCS_AUTH*   privAuth,  // in, out
+                      UINT32*   outDataSize, // out
+                      BYTE**    outData)  // out
+{
+  // setup input/output parameters block
+  TPM_TAG tag = TPM_TAG_RQU_AUTH1_COMMAND;
+  UINT32 paramSize = 0;
+  TPM_COMMAND_CODE ordinal = TPM_ORD_UnBind;
+  TPM_RESULT returnCode = TPM_SUCCESS;
+  
+  // setup the TPM driver input and output buffers
+  TDDL_RESULT hRes = TDDL_E_FAIL;
+  TDDL_UINT32  InLength = TCPA_MAX_BUFFER_LENGTH;
+  TDDL_UINT32  OutLength = TCPA_MAX_BUFFER_LENGTH;
+  
+  // check input params
+  if (inData == NULL || privAuth == NULL || outDataSize == NULL || *outData == 
NULL)
+    return TPM_BAD_PARAMETER;
+  
+  // Convert Byte Input parameter in the input byte stream InBuf
+  InLength = BSG_PackList(InBuf, 5, 
+                         BSG_TPM_TAG, &tag, 
+                         BSG_TYPE_UINT32, &paramSize, 
+                         BSG_TPM_COMMAND_CODE, &ordinal, 
+                         BSG_TYPE_UINT32, &keyHandle, 
+                         BSG_TYPE_UINT32, &inDataSize);
+  memcpy(InBuf+InLength, inData, inDataSize);
+  InLength += inDataSize;
+  InLength += packAuth(InBuf+InLength, privAuth);
+  // fill paramSize again as we now have the correct size
+  BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2);
+  
+  vtpmloginfo(VTPM_LOG_TCS_DEEP, "\n\tSending paramSize = %d", InLength);
+  
+  // call the TPM driver
+  if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength)) == 
TDDL_SUCCESS) {
+    // unpack OutBuf to get the tag, paramSize, & returnCode
+    int i = BSG_UnpackList(OutBuf, 3, 
+                          BSG_TPM_TAG, &tag, 
+                          BSG_TYPE_UINT32, &paramSize, 
+                          BSG_TPM_COMMAND_CODE, &returnCode);
+    
+    if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_AUTH1_COMMAND) {
+      // Extract the remaining output parameters
+      i += BSG_Unpack(BSG_TYPE_UINT32, OutBuf+i, outDataSize);
+      if (TCS_Malloc(hContext, *outDataSize, outData) == TPM_FAIL)
+        return TPM_SIZE;
+    
+      memcpy(*outData, OutBuf+i, *outDataSize);
+      i += *outDataSize;
+      unpackAuth(privAuth, OutBuf+i);
+      
+      vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n", paramSize);
+    } else 
+      vtpmlogerror(VTPM_LOG_TCS, "TCSP_UnBind Failed with return code %s\n", 
tpm_get_error_name(returnCode));
+  }
+  
+  return(returnCode);
+}
+
+TPM_RESULT TCSP_CreateWrapKey(TCS_CONTEXT_HANDLE hContext,   // in
+                             TCS_KEY_HANDLE  hWrappingKey,  // in
+                             TPM_ENCAUTH  KeyUsageAuth,  // in
+                             TPM_ENCAUTH  KeyMigrationAuth, // in
+                             UINT32*    pcKeySize,   // in, out
+                             BYTE**    prgbKey,   // in, out
+                             TCS_AUTH*   pAuth)    // in, out
+{
+  // setup input/output parameters block
+  TPM_TAG tag = TPM_TAG_RQU_AUTH1_COMMAND;
+  UINT32 paramSize = 0;
+  TPM_COMMAND_CODE ordinal = TPM_ORD_CreateWrapKey;
+  TPM_RESULT returnCode = TPM_SUCCESS;
+  
+  // setup the TPM driver input and output buffers
+  TDDL_RESULT hRes = TDDL_E_FAIL;
+  TDDL_UINT32  InLength = TCPA_MAX_BUFFER_LENGTH;
+  TDDL_UINT32  OutLength = TCPA_MAX_BUFFER_LENGTH;
+  
+  // check input params
+  if (pcKeySize == NULL || *prgbKey == NULL || pAuth == NULL)
+    return TPM_BAD_PARAMETER;
+  
+  
+  // Convert Byte Input parameter in the input byte stream InBuf
+  InLength = BSG_PackList(InBuf, 6, 
+                         BSG_TPM_TAG, &tag, 
+                         BSG_TYPE_UINT32, &paramSize, 
+                         BSG_TPM_COMMAND_CODE, &ordinal, 
+                         BSG_TYPE_UINT32, &hWrappingKey, 
+                         BSG_TPM_ENCAUTH, KeyUsageAuth, 
+                         BSG_TPM_ENCAUTH, KeyMigrationAuth); 
+  memcpy(InBuf+InLength, *prgbKey, *pcKeySize);
+  InLength += *pcKeySize;
+  InLength += packAuth(InBuf+InLength, pAuth);
+  // fill paramSize again as we now have the correct size
+  BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2);
+  
+  vtpmloginfo(VTPM_LOG_TCS_DEEP, "Sending paramSize = %d\n", InLength);
+  
+  // call the TPM driver
+  if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength)) == 
TDDL_SUCCESS) {
+    // unpack OutBuf to get the tag, paramSize, & returnCode
+    int i = BSG_UnpackList(OutBuf, 3, 
+                          BSG_TPM_TAG, &tag, 
+                          BSG_TYPE_UINT32, &paramSize, 
+                          BSG_TPM_RESULT, &returnCode);
+    
+    if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_AUTH1_COMMAND) {
+      // Extract the remaining output parameters
+      TPM_KEY wrappedKey;
+      
+      i += BSG_Unpack(BSG_TPM_KEY, OutBuf+i, &wrappedKey);
+      unpackAuth(pAuth, OutBuf+i);
+      
+      // Fill prgbKey
+      BYTE tempBuf[1024];
+      *pcKeySize = BSG_Pack(BSG_TPM_KEY, &wrappedKey, tempBuf);
+      if (TCS_Malloc(hContext, *pcKeySize, prgbKey) == TPM_FAIL) 
+        return TPM_SIZE;
+      
+      memcpy(*prgbKey, tempBuf, *pcKeySize);
+      
+      vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n", paramSize);
+    } else 
+      vtpmlogerror(VTPM_LOG_TCS, "TCSP_CreateWrapKey Failed with return code 
%s\n", tpm_get_error_name(returnCode)); 
+  }
+  
+  return(returnCode);
+}
+
+TPM_RESULT TCSP_LoadKeyByBlob(TCS_CONTEXT_HANDLE hContext,    // in
+                             TCS_KEY_HANDLE  hUnwrappingKey,   // in
+                             UINT32    cWrappedKeyBlobSize, // in
+                             BYTE*    rgbWrappedKeyBlob,  // in
+                             TCS_AUTH*   pAuth,     // in, out
+                             TCS_KEY_HANDLE*  phKeyTCSI,    // out
+                             TCS_KEY_HANDLE*  phKeyHMAC)    // out
+{
+  // setup input/output parameters block
+  TPM_TAG tag = TPM_TAG_RQU_AUTH1_COMMAND;
+  UINT32 paramSize = 0;
+  TPM_COMMAND_CODE ordinal = TPM_ORD_LoadKey;
+  TPM_RESULT returnCode = TPM_SUCCESS;
+  
+  // setup the TPM driver input and output buffers
+  TDDL_RESULT hRes = TDDL_E_FAIL;
+  TDDL_UINT32  InLength = TCPA_MAX_BUFFER_LENGTH;
+  TDDL_UINT32  OutLength = TCPA_MAX_BUFFER_LENGTH;
+  
+  // check input params
+  if (rgbWrappedKeyBlob == NULL || pAuth == NULL || phKeyTCSI == NULL || 
phKeyHMAC == NULL) 
+    return TPM_BAD_PARAMETER; 
+  
+  *phKeyHMAC = hUnwrappingKey; // the parent key is the one that the TPM use 
to make the HMAC calc
+  
+  // Convert Byte Input parameter in the input byte stream InBuf
+  InLength = BSG_PackList(InBuf, 4, 
+                         BSG_TPM_TAG, &tag, 
+                         BSG_TYPE_UINT32, &paramSize, 
+                         BSG_TPM_COMMAND_CODE, &ordinal, 
+                         BSG_TYPE_UINT32, &hUnwrappingKey);
+  memcpy(InBuf+InLength, rgbWrappedKeyBlob, cWrappedKeyBlobSize);
+  InLength += cWrappedKeyBlobSize;
+  InLength += packAuth(InBuf+InLength, pAuth);
+  // fill paramSize again as we now have the correct size
+  BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2);
+  
+  vtpmloginfo(VTPM_LOG_TCS_DEEP, "Sending paramSize = %d\n", InLength);
+  
+  // call the TPM driver
+  if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength)) == 
TDDL_SUCCESS) {
+    // unpack OutBuf to get the tag, paramSize, & returnCode
+    int i = BSG_UnpackList(OutBuf, 3, 
+                          BSG_TPM_TAG, &tag, 
+                          BSG_TYPE_UINT32, &paramSize, 
+                          BSG_TPM_COMMAND_CODE, &returnCode);
+    
+    if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_AUTH1_COMMAND) {
+      // Extract the remaining output parameters
+      i += BSG_Unpack(BSG_TYPE_UINT32, 
+                     OutBuf+i, 
+                     phKeyTCSI);
+      unpackAuth(pAuth, OutBuf+i);
+      
+      if (!AddHandleToList((CONTEXT_HANDLE *)hContext, TPM_RT_KEY, 
*phKeyTCSI)) {
+        vtpmlogerror(VTPM_LOG_TCS, "New KeyHandle not recorded\n");
+      }
+      
+      vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n", paramSize);
+     } else 
+      vtpmlogerror(VTPM_LOG_TCS, "TCSP_LoadKeyByBlob Failed with return code 
%s\n", tpm_get_error_name(returnCode));
+  }
+  
+  return(returnCode);
+}
+
+TPM_RESULT TCSP_EvictKey(TCS_CONTEXT_HANDLE hContext, // in
+                        TCS_KEY_HANDLE  hKey)  // in
+{
+  // setup input/output parameters block
+  TPM_TAG tag = TPM_TAG_RQU_COMMAND;
+  UINT32 paramSize = 0;
+  TPM_COMMAND_CODE ordinal = TPM_ORD_EvictKey;
+  TPM_RESULT returnCode = TPM_SUCCESS;
+  
+  // setup the TPM driver input and output buffers
+  TDDL_RESULT hRes = TDDL_E_FAIL;
+  TDDL_UINT32  InLength = TCPA_MAX_BUFFER_LENGTH;
+  TDDL_UINT32  OutLength = TCPA_MAX_BUFFER_LENGTH;
+  
+  // Convert Byte Input parameter in the input byte stream InBuf
+  InLength = BSG_PackList(InBuf, 4, 
+                         BSG_TPM_TAG, &tag, 
+                         BSG_TYPE_UINT32, &paramSize, 
+                         BSG_TPM_COMMAND_CODE, &ordinal, 
+                         BSG_TYPE_UINT32, &hKey);
+  // fill paramSize again as we now have the correct size
+  BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2);
+  
+  vtpmloginfo(VTPM_LOG_TCS_DEEP, "Sending paramSize = %d\n", InLength);
+  
+  // call the TPM driver
+  if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength)) == 
TDDL_SUCCESS) {
+    // unpack OutBuf to get the tag, paramSize, & returnCode
+    BSG_UnpackList(OutBuf, 3, 
+                          BSG_TPM_TAG, &tag, 
+                          BSG_TYPE_UINT32, &paramSize, 
+                          BSG_TPM_COMMAND_CODE, &returnCode);
+    
+    if (!DeleteHandleFromList((CONTEXT_HANDLE *)hContext, hKey)) {
+      vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n");
+    }   
+    
+    if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_COMMAND) {
+      vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n", paramSize);
+    } else {
+      vtpmlogerror(VTPM_LOG_TCS, "TCSP_EvictKey Failed with return code %s\n", 
tpm_get_error_name(returnCode));
+    }
+  }
+  
+  return(returnCode);
+}
+
+TPM_RESULT TCSP_GetRandom(TCS_CONTEXT_HANDLE hContext,  // in
+                         UINT32*    bytesRequested, // in, out
+                         BYTE**    randomBytes) // out
+{
+  // setup input/output parameters block
+  TPM_TAG tag = TPM_TAG_RQU_COMMAND;
+  UINT32 paramSize = 0;
+  TPM_COMMAND_CODE ordinal = TPM_ORD_GetRandom;
+  TPM_RESULT returnCode = TPM_SUCCESS;
+  
+  // setup the TPM driver input and output buffers
+  TDDL_RESULT hRes = TDDL_E_FAIL;
+  TDDL_UINT32  InLength = TCPA_MAX_BUFFER_LENGTH;
+  TDDL_UINT32  OutLength = TCPA_MAX_BUFFER_LENGTH;
+  
+  // check input params
+  if (bytesRequested == NULL || *randomBytes == NULL){
+    return TPM_BAD_PARAMETER;
+  }
+  
+  // Convert Byte Input parameter in the input byte stream InBuf
+  InLength = BSG_PackList(InBuf, 4, 
+                         BSG_TPM_TAG, &tag, 
+                         BSG_TYPE_UINT32, &paramSize, 
+                         BSG_TPM_COMMAND_CODE, &ordinal, 
+                         BSG_TYPE_UINT32, bytesRequested);
+  // fill paramSize again as we now have the correct size
+  BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2);
+  
+  vtpmloginfo(VTPM_LOG_TCS_DEEP, "Sending paramSize = %d\n", InLength);
+  
+  // call the TPM driver
+  if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength)) == 
TDDL_SUCCESS) {
+    // unpack OutBuf to get the tag, paramSize, & returnCode
+    int i = BSG_UnpackList(OutBuf, 3, 
+                          BSG_TPM_TAG, &tag, 
+                          BSG_TYPE_UINT32, &paramSize, 
+                          BSG_TPM_COMMAND_CODE, &returnCode);
+    
+    if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_COMMAND) {
+      // Extract the remaining output parameters
+      BSG_Unpack(BSG_TYPE_UINT32, OutBuf+i, bytesRequested);
+      if (TCS_Malloc(hContext, *bytesRequested, randomBytes) == TPM_FAIL) {
+        return TPM_SIZE;
+      }
+      memcpy(*randomBytes, OutBuf+i+sizeof(UINT32), *bytesRequested);
+      
+      vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n", paramSize);
+    } else {
+      vtpmlogerror(VTPM_LOG_TCS, "TCSP_GetRandom Failed with return code 
%s\n", tpm_get_error_name(returnCode));
+    }
+  }
+  
+  return(returnCode);
+}
+
+
+TPM_RESULT TCSP_ReadPubek(TCS_CONTEXT_HANDLE   hContext,               // in
+                         TPM_NONCE            antiReplay,             // in
+                         UINT32*              pubEndorsementKeySize,  // out
+                         BYTE**               pubEndorsementKey,      // out
+                         TPM_DIGEST*          checksum)               // out
+{
+  // setup input/output parameters block
+  TPM_TAG tag = TPM_TAG_RQU_COMMAND;
+  UINT32 paramSize = 0;
+  TPM_COMMAND_CODE ordinal = TPM_ORD_ReadPubek;
+  TPM_RESULT returnCode = TPM_SUCCESS;
+  
+  // setup the TPM driver input and output buffers
+  TDDL_RESULT hRes = TDDL_E_FAIL;
+  TDDL_UINT32  InLength = TCPA_MAX_BUFFER_LENGTH;
+  TDDL_UINT32   OutLength = TCPA_MAX_BUFFER_LENGTH;
+  
+  // check input params
+  if (pubEndorsementKeySize == NULL || pubEndorsementKey == NULL || checksum 
== NULL) {
+    return TPM_BAD_PARAMETER;
+  }
+  
+  // Convert Byte Input parameter in the input byte stream InBuf
+  InLength = BSG_PackList(InBuf, 4, 
+                         BSG_TPM_TAG, &tag, 
+                         BSG_TYPE_UINT32, &paramSize, 
+                         BSG_TPM_COMMAND_CODE, &ordinal, 
+                         BSG_TPM_NONCE, &antiReplay);
+  // fill paramSize again as we now have the correct size
+  BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2);
+  
+  vtpmloginfo(VTPM_LOG_TCS_DEEP, "Sending paramSize = %d\n", InLength);
+  
+  // call the TPM driver
+  if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength)) == 
TDDL_SUCCESS) {
+    // unpack OutBuf to get the tag, paramSize, & returnCode
+    int i = BSG_UnpackList(OutBuf, 3, 
+                          BSG_TPM_TAG, &tag, 
+                          BSG_TYPE_UINT32, &paramSize, 
+                          BSG_TPM_COMMAND_CODE, &returnCode);
+    
+    if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_COMMAND) {
+      // Extract the remaining output parameters
+      TPM_PUBKEY pubEK;
+      i += BSG_UnpackList(OutBuf+i, 2, 
+                         BSG_TPM_PUBKEY, &pubEK, 
+                         BSG_TPM_DIGEST, checksum);
+      
+      // fill EndorsementKey
+      BYTE tempBuf[1024];
+      *pubEndorsementKeySize = BSG_Pack(BSG_TPM_PUBKEY, &pubEK, tempBuf);
+      if (TCS_Malloc(hContext, *pubEndorsementKeySize, pubEndorsementKey) == 
TPM_FAIL) {
+        return TPM_SIZE;
+      }
+      memcpy(*pubEndorsementKey, tempBuf, *pubEndorsementKeySize);
+      
+      vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n", paramSize);
+    } else {
+      vtpmlogerror(VTPM_LOG_TCS, "TCSP_ReadPubek Failed with return code 
%s\n", tpm_get_error_name(returnCode));
+    }
+  }
+  
+  return(returnCode);
+}
+
+TPM_RESULT TCSP_RawTransmitData(   UINT32 inDataSize,  // in
+                                  BYTE *inData,       // in
+                                  UINT32 *outDataSize,// in/out
+                                  BYTE *outData) {    // out     
+  
+  TDDL_RESULT hRes;
+  
+  vtpmloginfo(VTPM_LOG_TCS, "Calling TransmitData directly.\n");
+  //FIXME: Add Context Management
+  hRes = TDDL_TransmitData( inData, 
+                           inDataSize, 
+                           outData, 
+                           outDataSize);
+  
+  if (hRes == TDDL_SUCCESS) {
+    return TPM_SUCCESS;
+  } else {
+    vtpmlogerror(VTPM_LOG_TCS, "TCSP_RawTransmitData Failed with return code 
%s\n", tpm_get_error_name(TPM_IOERROR));
+    return TPM_IOERROR;
+  }
+  
+}
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/tcs/tcs.h
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/tcs/tcs.h      Thu Sep  1 10:16:14 2005
@@ -0,0 +1,238 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// tcs.h
+// 
+//  This file declares the TCS API
+// 
+// ==================================================================
+
+#ifndef __TCS_H__
+#define __TCS_H__
+
+#include "tcg.h"
+#include "buffer.h"
+
+#define HANDLE_NULL 0
+
+// ------------------------------------------------------------------
+// Exposed API
+// ------------------------------------------------------------------
+
+TPM_RESULT TCS_create();
+void TCS_destroy();
+
+TPM_RESULT TCS_OpenContext( /* OUT */ TCS_CONTEXT_HANDLE* hContext );
+
+TPM_RESULT TCS_CloseContext ( /* IN */ TCS_CONTEXT_HANDLE hContext );
+
+TPM_RESULT TCS_Malloc ( TCS_CONTEXT_HANDLE hContext, // in
+                       UINT32   MemSize, // in
+                       BYTE**   ppMemPtr ); //out
+
+TPM_RESULT TCS_FreeMemory ( TCS_CONTEXT_HANDLE hContext, // in
+                           BYTE*    pMemory);  // in
+
+// ------------------------------------------------------------------
+// Exposed API
+// ------------------------------------------------------------------
+
+// TPM v1.1B Command Set
+
+// Authorzation
+TPM_RESULT TCSP_OIAP( TCS_CONTEXT_HANDLE hContext, // in
+                     TCS_AUTHHANDLE*  authHandle, // out 
+                     TPM_NONCE*   nonce0  // out
+                     );
+
+TPM_RESULT TCSP_OSAP (  TCS_CONTEXT_HANDLE hContext,  // in
+                       TPM_ENTITY_TYPE entityType,  // in
+                       UINT32    entityValue, // in
+                       TPM_NONCE   nonceOddOSAP, // in
+                       TCS_AUTHHANDLE*  authHandle,  // out 
+                       TPM_NONCE*   nonceEven,  // out
+                       TPM_NONCE*   nonceEvenOSAP // out
+                       );
+
+TPM_RESULT TCSP_TakeOwnership (  TCS_CONTEXT_HANDLE hContext,   // in
+                                UINT16    protocolID,   // in
+                                UINT32    encOwnerAuthSize, // in 
+                                BYTE*    encOwnerAuth,  // in
+                                UINT32    encSrkAuthSize,  // in
+                                BYTE*    encSrkAuth,   // in
+                                UINT32*    SrkSize,   // in, out
+                                BYTE**    Srk,    // in, out
+                                TCS_AUTH*   ownerAuth   // in, out
+                                );
+
+TPM_RESULT TCSP_DisablePubekRead (  TCS_CONTEXT_HANDLE hContext, // in
+                                    TCS_AUTH*   ownerAuth // in, out
+                                    );
+
+TPM_RESULT TCSP_TerminateHandle (  TCS_CONTEXT_HANDLE hContext, // in
+                                  TCS_AUTHHANDLE  handle  // in
+                                  );
+
+TPM_RESULT TCSP_FlushSpecific (  TCS_CONTEXT_HANDLE hContext, // in
+                                TCS_AUTHHANDLE  handle,  // in
+                                TPM_RESOURCE_TYPE resourceType //in 
+                                );
+
+// TPM Mandatory
+TPM_RESULT TCSP_Extend (  TCS_CONTEXT_HANDLE hContext, // in
+                         TPM_PCRINDEX  pcrNum,  // in
+                         TPM_DIGEST   inDigest, // in
+                         TPM_PCRVALUE*   outDigest // out
+                         );
+
+TPM_RESULT TCSP_PcrRead (  TCS_CONTEXT_HANDLE hContext, // in
+                          TPM_PCRINDEX  pcrNum,  // in
+                          TPM_PCRVALUE*  outDigest // out
+                          );
+
+TPM_RESULT TCSP_Quote (  TCS_CONTEXT_HANDLE hContext,  // in
+                        TCS_KEY_HANDLE  keyHandle,  // in
+                        TPM_NONCE   antiReplay,  // in
+                        UINT32*    PcrDataSize, // in, out
+                        BYTE**    PcrData,  // in, out
+                        TCS_AUTH*   privAuth,  // in, out
+                        UINT32*    sigSize,  // out
+                        BYTE**    sig    // out
+                        );
+
+TPM_RESULT TCSP_Seal (  TCS_CONTEXT_HANDLE hContext,  // in
+                       TCS_KEY_HANDLE  keyHandle,  // in
+                       TPM_ENCAUTH  encAuth,  // in
+                       UINT32    pcrInfoSize, // in
+                       BYTE*    PcrInfo,  // in
+                       UINT32    inDataSize,  // in
+                       BYTE*    inData,   // in
+                       TCS_AUTH*   pubAuth,  // in, out
+                       UINT32*    SealedDataSize, // out
+                       BYTE**    SealedData  // out
+                       );
+
+TPM_RESULT TCSP_Unseal (  TCS_CONTEXT_HANDLE hContext,  // in
+                         TCS_KEY_HANDLE  parentHandle, // in
+                         UINT32    SealedDataSize, // in
+                         BYTE*    SealedData,  // in
+                         TCS_AUTH*   parentAuth,  // in, out
+                         TCS_AUTH*   dataAuth,  // in, out
+                         UINT32*    DataSize,  // out
+                         BYTE**    Data   // out
+                         );
+
+TPM_RESULT TCSP_DirWriteAuth (  TCS_CONTEXT_HANDLE hContext,  // in
+                               TPM_DIRINDEX  dirIndex,  // in
+                               TPM_DIRVALUE  newContents, // in
+                               TCS_AUTH*   ownerAuth  // in, out
+                               );
+
+TPM_RESULT TCSP_DirRead (  TCS_CONTEXT_HANDLE hContext, // in
+                          TPM_DIRINDEX  dirIndex, // in
+                          TPM_DIRVALUE*  dirValue // out
+                          );
+
+TPM_RESULT TCSP_UnBind (  TCS_CONTEXT_HANDLE hContext,  // in
+                         TCS_KEY_HANDLE  keyHandle,  // in
+                         UINT32    inDataSize,  // in
+                         BYTE*    inData,   // in
+                         TCS_AUTH*   privAuth,  // in, out
+                         UINT32*    outDataSize, // out
+                         BYTE**    outData   // out
+                         );
+
+TPM_RESULT TCSP_CreateWrapKey (  TCS_CONTEXT_HANDLE hContext,   // in
+                                TCS_KEY_HANDLE  hWrappingKey,  // in
+                                TPM_ENCAUTH  KeyUsageAuth,  // in
+                                TPM_ENCAUTH  KeyMigrationAuth, // in
+                                UINT32*    pcKeySize,   // in, out
+                                BYTE**    prgbKey,   // in, out
+                                TCS_AUTH*   pAuth    // in, out
+                                );
+
+TPM_RESULT TCSP_LoadKeyByBlob (  TCS_CONTEXT_HANDLE hContext,    // in
+                                TCS_KEY_HANDLE  hUnwrappingKey,   // in
+                                UINT32    cWrappedKeyBlobSize, // in
+                                BYTE*    rgbWrappedKeyBlob,  // in
+                                TCS_AUTH*   pAuth,     // in, out
+                                TCS_KEY_HANDLE*  phKeyTCSI,    // out
+                                TCS_KEY_HANDLE*  phKeyHMAC    // out
+                                );
+
+TPM_RESULT TCSP_GetPubKey (  TCS_CONTEXT_HANDLE hContext,  // in
+                            TCS_KEY_HANDLE  hKey,   // in
+                            TCS_AUTH*   pAuth,   // in, out
+                            UINT32*    pcPubKeySize, // out
+                            BYTE**    prgbPubKey  // out
+                            ); 
+
+TPM_RESULT TCSP_EvictKey (  TCS_CONTEXT_HANDLE hContext, // in
+                           TCS_KEY_HANDLE  hKey  // in
+                           );
+
+TPM_RESULT TCSP_Sign (  TCS_CONTEXT_HANDLE hContext,  // in
+                       TCS_KEY_HANDLE  keyHandle,  // in
+                       UINT32    areaToSignSize, // in
+                       BYTE*    areaToSign,  // in
+                       TCS_AUTH*   privAuth,  // in, out
+                       UINT32*    sigSize,  // out
+                       BYTE**    sig    // out
+                       );
+
+TPM_RESULT TCSP_GetRandom (  TCS_CONTEXT_HANDLE hContext,  // in
+                            UINT32*    bytesRequested, // in, out
+                            BYTE**    randomBytes  // out
+                            );
+
+TPM_RESULT TCSP_StirRandom (  TCS_CONTEXT_HANDLE hContext, // in
+                             UINT32    inDataSize, // in
+                             BYTE*    inData  // in
+                             );
+
+TPM_RESULT TCSP_ReadPubek (  TCS_CONTEXT_HANDLE hContext,    // in
+                            TPM_NONCE   antiReplay,    // in
+                            UINT32*    pubEndorsementKeySize, // out
+                            BYTE**    pubEndorsementKey,  // out
+                            TPM_DIGEST*  checksum    // out
+                            );
+
+
+// Non-Standard TCSP call to give direct access to TransmitData.
+// Key and Auth Management is done before transfering command to TDDL.
+TPM_RESULT TCSP_RawTransmitData(UINT32 inDataSize,  // in
+                               BYTE *inData,       // in
+                               UINT32 *outDataSize,// in/out
+                               BYTE *outData);     // out
+
+#endif //TCS_H
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/tcs/tpmddl.h
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/tcs/tpmddl.h   Thu Sep  1 10:16:14 2005
@@ -0,0 +1,69 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// tpmddl.c
+// 
+//  This file defines the TDDLI API
+//
+// ==================================================================
+
+#ifndef __TPMDDL_H__
+#define __TPMDDL_H__
+
+#define TDDL_CAP_PROP_MANUFACTURER 0x0001
+
+#define TDDL_E_FAIL 1
+#define TDDL_E_SUCCESS 0
+#define TDDL_SUCCESS 0
+
+typedef unsigned int TDDL_UINT32;
+typedef TDDL_UINT32 TDDL_RESULT;
+typedef unsigned char TDDL_BYTE;
+
+TDDL_RESULT TDDL_Open();
+void TDDL_Close();
+TDDL_RESULT TDDL_TransmitData( TDDL_BYTE* in,
+                              TDDL_UINT32 insize,
+                              TDDL_BYTE* out,
+                              TDDL_UINT32* outsize);
+TDDL_RESULT TDDL_GetStatus();
+TDDL_RESULT TDDL_GetCapability( TDDL_UINT32 cap,
+                               TDDL_UINT32 sub,
+                               TDDL_BYTE* buffer,
+                               TDDL_UINT32* size);
+TDDL_RESULT TDDL_SetCapability( TDDL_UINT32 cap,
+                               TDDL_UINT32 sub,
+                               TDDL_BYTE* buffer,
+                               TDDL_UINT32* size);
+
+#endif // __TPMDDL_H__
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/tcs/transmit.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/tcs/transmit.c Thu Sep  1 10:16:14 2005
@@ -0,0 +1,131 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include "tcg.h"
+#include "buffer.h"
+#include "log.h"
+#include "tpmddl.h"
+
+// flag to track whether TDDL has been opened
+static int g_TDDL_open = 0;
+static int g_fd = -1;              // the fd to the TPM
+
+TPM_RESULT
+TDDL_TransmitData( TDDL_BYTE* in,
+                  TDDL_UINT32 insize,
+                  TDDL_BYTE* out,
+                  TDDL_UINT32* outsize) {
+  TPM_RESULT status = TPM_SUCCESS;
+  TDDL_UINT32 i;
+  
+  vtpmloginfo(VTPM_LOG_TXDATA, "Sending buffer = 0x");
+  for(i = 0 ; i < insize ; i++) 
+    vtpmloginfomore(VTPM_LOG_TXDATA, "%2.2x ", in[i]);
+
+  vtpmloginfomore(VTPM_LOG_TXDATA, "\n");
+  
+  ssize_t size = 0;
+  int fd = g_fd;
+  
+  // send the request
+  size = write (fd, in, insize);
+  if (size < 0) {
+    vtpmlogerror(VTPM_LOG_TXDATA, "write() failed");
+    ERRORDIE (TPM_IOERROR);
+  }
+  else if ((TDDL_UINT32) size < insize) {
+    vtpmlogerror(VTPM_LOG_TXDATA, "Wrote %d instead of %d bytes!\n", size, 
insize);
+    // ... ?
+  }
+
+  // read the response
+  size = read (fd, out, TCPA_MAX_BUFFER_LENGTH);
+  if (size < 0) {
+    vtpmlogerror(VTPM_LOG_TXDATA, "read() failed");
+    ERRORDIE (TPM_IOERROR);
+  }
+  
+  vtpmloginfo(VTPM_LOG_TXDATA, "Receiving buffer = 0x");
+  for(i = 0 ; i < size ; i++) 
+    vtpmloginfomore(VTPM_LOG_TXDATA, "%2.2x ", out[i]);
+
+  vtpmloginfomore(VTPM_LOG_TXDATA, "\n");
+
+  *outsize = size;
+  // close connection
+  goto egress;
+  
+ abort_egress:
+ egress:
+  return status;
+}
+
+TPM_RESULT TDDL_Open() {
+  
+  TDDL_RESULT status = TDDL_SUCCESS;
+  int fd = -1;
+  
+  if (g_TDDL_open)
+    return TPM_FAIL;
+  
+  fd = open ("/dev/tpm0", O_RDWR);
+  if (fd < 0) {
+    vtpmlogerror(VTPM_LOG_TXDATA, "TPM open failed");
+    return TPM_IOERROR;
+  }
+  
+  g_fd = fd;
+  g_TDDL_open = 1;
+  
+  return status;
+}
+
+void TDDL_Close() {
+  if (! g_TDDL_open)
+        return;
+
+  if (g_fd>= 0) {
+    if (close(g_fd) < 0) 
+      vtpmlogerror(VTPM_LOG_TXDATA, "closeing tpm failed");
+    
+    g_fd = -1;
+  }
+    
+  g_TDDL_open = 0;
+  
+}
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/util/Makefile
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/util/Makefile  Thu Sep  1 10:16:14 2005
@@ -0,0 +1,18 @@
+XEN_ROOT = ../../..
+include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
+
+BIN            = libTCGUtils.a
+
+all: build
+
+build: $(BIN)
+
+install: build
+
+clean:
+       rm -f *.a *.so *.o *.rpm $(DEP_FILES)
+
+mrproper: clean
+
+$(BIN): $(OBJS)
+       $(AR) rcs $(BIN) $(OBJS)
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/util/bsg.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/util/bsg.c     Thu Sep  1 10:16:14 2005
@@ -0,0 +1,830 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// bsg.cpp
+// 
+//  This file will handle all the TPM Byte Stream functions
+// 
+// ==================================================================
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <malloc.h>
+#include "tcg.h"
+#include "crypto.h"
+#include "bsg.h"
+#include "log.h"
+
+static int g_log_recursion_level = 0;
+
+// a largest buffer size. if we get a buf size bigger than this when unpacking,
+// will complain!
+#define BSG_MAX_BUF_SIZE (1<<18)
+
+#define bsglog(fmt, ...) do { \
+    int __i; \
+    for (__i=0; __i < g_log_recursion_level; __i++) {               \
+      vtpmloginfomore (VTPM_LOG_BSG, "%s", "  ");                           \
+    }                                                                 \
+    vtpmloginfomore (VTPM_LOG_BSG, fmt, __VA_ARGS__);                         \
+  } while (0)
+
+
+// FIXME:  trigger the selfcheck--need to use glibc hook to do this
+//BOOL dummy1 = BSG_static_selfcheck();
+
+
+// Interpretting Types
+// -------------------
+// 
+// Incoming Types are composed of two parts {format, info} squished into a
+// BSG_UINT32.  The first 4 bits is a format spec indicating what type of
+// data it is.  If the first 4 bits are zero the info corresponds to a value in
+// BSG_s_fmt[]. This is a structure whose composition is described in
+// BSG_s_fmt[]. If the value is non-zero, info corresponds to the size of the
+// data (in bytes) being passed in. For example a UINT32 being passed in would
+// have a format of (__FMT_CONST | 4). If both, the format and info are zero,
+// this is interpretted as the end of the structure, and the result is 
returned.
+
+// these flags are mutually exclusive, so I'll just make them
+// format values which indicate the semantics of the 'info' part and the source
+// data. The above description has been accordingly adjusted.
+
+// format values for determining what type of data the incoming type is
+// it's a 4 bit value, occupying the high 4 bits
+#define __FMT_CONST (1UL << 28) // Constant sized value
+#define __FMT_DATA  (2UL << 28) // Believed to be raw data NOT {size,data}
+#define __FMT_SIZE  (3UL << 28) // A size. Used in FMT_SIZE??_DATA.
+#define __FMT_HSIZE (4UL << 28) // A number of handles
+#define __FMT_PACKED (5UL << 28) // 'info' is unused; the source data consists
+                                 // of {size32, data} but we're to pack only 
the
+                                 // data as that is already packed, and so
+                                 // can/must be unpacked without
+                                 // explicitly reading it size
+
+#define __FMT_MASK  0x0FFFFFFFUL // this masks out the 4-bit format
+#define __FMT_MASK_SIZE(type)   ((type) & __FMT_MASK)
+#define __FMT_MASK_FORMAT(type) ((type) & (~__FMT_MASK))
+
+// constant (8/16/32-bits)
+#define FMT_U8 (__FMT_CONST | 1UL)
+#define FMT_U16 (__FMT_CONST | 2UL)
+#define FMT_U32 (__FMT_CONST | 4UL)
+
+// const with a compiler-computed size
+#define FMT_SIZEOF(type) (__FMT_CONST | sizeof(type))
+
+// other data (size bytes) 
+// Used primarily for DIGESTS -> FMT_DATA(20)
+#define FMT_DATA(size) (__FMT_DATA | ((BSG_UINT32) (size) & __FMT_MASK))
+
+// 16/32-bit size followed by N bytes of data
+#define FMT_SIZE16_DATA (__FMT_SIZE | 2UL)
+#define FMT_SIZE32_DATA (__FMT_SIZE | 4UL)
+
+// 16-bit size followed by N key handles
+#define FMT_SIZE16_HANDLES (__FMT_HSIZE | 2UL)
+
+#define DIGEST_SIZE 20 
+typedef BSG_UINT32 BSG_HANDLE;
+
+// TCPA_AUTH has 11 fields!
+#define MAX_FIELDS 11
+typedef struct BSG_Format
+{
+  BSG_Type type;
+  const char* name;
+  BSG_UINT32 fields[MAX_FIELDS + 1];
+} BSG_Format;
+
+/*
+ * TCPA structure data formats
+ */
+// this has to be manually kept in sync with the
+// Type enum!! the static_selfcheck() function should be used regularly!
+static BSG_Format s_fmt[] =
+{
+  {BSG_TYPE_UINT32, "BSG_TYPE_UINT32", {FMT_U32, 0}},
+  {BSG_TYPE_UINT16, "BSG_TYPE_UINT16", {FMT_U16, 0}},
+  {BSG_TYPE_BYTE, "BSG_TYPE_BYTE", {FMT_U8, 0}},
+  {BSG_TYPE_BOOL, "BSG_TYPE_BOOL", {FMT_U8, 0}},
+  {BSG_TPM_SIZE32_DATA, "BSG_TPM_SIZE32_DATA", {FMT_SIZE32_DATA, 0}},
+  {BSG_TPM_TAG, "BSG_TPM_TAG", {FMT_SIZEOF(TPM_TAG), 0}},
+  {BSG_TPM_HANDLE, "BSG_TPM_HANDLE", {FMT_SIZEOF(TPM_HANDLE), 0}},
+  {BSG_TPM_RESULT, "BSG_TPM_RESULT", {FMT_SIZEOF(TPM_RESULT), 0}},
+  {BSG_TPM_RESOURCE_TYPE, "BSG_TPM_RESOURCE_TYPE", 
{FMT_SIZEOF(TPM_RESOURCE_TYPE), 0}},
+  {BSG_TPM_COMMAND_CODE, "BSG_TPM_COMMAND_CODE", {FMT_U32, 0}},
+  {BSG_TPM_AUTH_DATA_USAGE, "BSG_TPM_AUTH_DATA_USAGE", {FMT_U8, 0}},
+  {BSG_TPM_ALGORITHM_ID, "BSG_TPM_ALGORITHM_ID", {FMT_U32, 0}},
+  {BSG_TPM_PROTOCOL_ID, "BSG_TPM_PROTOCOL_ID", {FMT_SIZEOF(TPM_PROTOCOL_ID), 
0}},
+  {BSG_TPM_KEY_USAGE, "BSG_TPM_KEY_USAGE", {FMT_U16, 0}},
+  {BSG_TPM_ENC_SCHEME, "BSG_TPM_ENC_SCHEME", {FMT_U16, 0}},
+  {BSG_TPM_SIG_SCHEME, "BSG_TPM_SIG_SCHEME", {FMT_U16, 0}},
+  {BSG_TPM_MIGRATE_SCHEME, "BSG_TPM_MIGRATE_SCHEME", {FMT_U16, 0}},
+  {BSG_TPM_KEY_FLAGS, "BSG_TPM_KEY_FLAGS", {FMT_U32, 0}},
+    
+  {BSG_TPM_AUTHDATA, "BSG_TPM_AUTHDATA", {FMT_DATA(DIGEST_SIZE), 0}},
+  {BSG_TPM_SECRET, "BSG_TPM_SECRET", {BSG_TPM_AUTHDATA, 0}},
+  {BSG_TPM_ENCAUTH, "BSG_TPM_ENCAUTH", {BSG_TPM_AUTHDATA, 0}},
+  {BSG_TPM_PAYLOAD_TYPE, "BSG_TPM_PAYLOAD_TYPE", 
{FMT_SIZEOF(TPM_PAYLOAD_TYPE), 0}},
+  
+  {BSG_TPM_VERSION, "BSG_TPM_VERSION", {FMT_DATA(4), 0}}, // vers 1.2
+  {BSG_TPM_DIGEST, "BSG_TPM_DIGEST", {FMT_DATA(DIGEST_SIZE), 0}},
+  {BSG_TPM_COMPOSITE_HASH, "BSG_TPM_COMPOSITE_HASH", {BSG_TPM_DIGEST, 0}},
+  {BSG_TPM_CHOSENID_HASH, "BSG_TPM_CHOSENID_HASH", {BSG_TPM_DIGEST, 0}},
+  
+  {BSG_TPM_NONCE, "BSG_TPM_NONCE", {FMT_DATA(DIGEST_SIZE), 0}},
+  {BSG_TPM_KEY_HANDLE, "BSG_TPM_KEY_HANDLE", {FMT_SIZEOF(TPM_KEY_HANDLE), 0}},
+  {BSG_TPM_KEY_HANDLE_LIST, "BSG_TPM_KEY_HANDLE_LIST",
+   {FMT_SIZE16_HANDLES, 0}},
+  
+  {BSG_TPM_KEY_PARMS, "BSG_TPM_KEY_PARMS", {
+      BSG_TPM_ALGORITHM_ID,
+      BSG_TPM_ENC_SCHEME,
+      BSG_TPM_SIG_SCHEME,
+      FMT_SIZE32_DATA,
+      0}},
+  {BSG_TPM_RSA_KEY_PARMS, "BSG_TPM_RSA_KEY_PARMS", {
+      FMT_U32, FMT_U32, FMT_SIZE32_DATA, 0}},
+  {BSG_TPM_STORE_PUBKEY, "BSG_TPM_STORE_PUBKEY", {FMT_SIZE32_DATA, 0}},
+  {BSG_TPM_PUBKEY, "BSG_TPM_PUBKEY", {BSG_TPM_KEY_PARMS, BSG_TPM_STORE_PUBKEY, 
0}},
+  {BSG_TPM_KEY, "BSG_TPM_KEY", {
+      BSG_TPM_VERSION,
+      BSG_TPM_KEY_USAGE,
+      BSG_TPM_KEY_FLAGS,
+      BSG_TPM_AUTH_DATA_USAGE,
+      BSG_TPM_KEY_PARMS,
+      FMT_SIZE32_DATA,        // the PCR_INFO
+      BSG_TPM_STORE_PUBKEY,
+      FMT_SIZE32_DATA,        // the encrypted part
+      0}},
+  
+  {BSG_TPM_MIGRATIONKEYAUTH, "BSG_TPM_MIGRATIONKEYAUTH", {
+      BSG_TPM_PUBKEY,
+      BSG_TPM_MIGRATE_SCHEME,
+      BSG_TPM_DIGEST, 0}},
+  
+  {BSG_TCPA_AUDIT_EVENT, "TCPA_AUDIT_EVENT", {
+      BSG_TPM_COMMAND_CODE,
+      BSG_TPM_RESULT, 0 }},
+  
+  {BSG_TCPA_EVENT_CERT, "TCPA_EVENT_CERT", {
+      BSG_TPM_DIGEST,
+      BSG_TPM_DIGEST,
+      FMT_DATA(2),
+      FMT_SIZE32_DATA, 0}},
+  
+  {BSG_TPM_PCR_SELECTION, "BSG_TPM_PCR_SELECTION", {FMT_SIZE16_DATA, 0} },
+  {BSG_TPM_PCR_COMPOSITE, "BSG_TPM_PCR_COMPOSITE", { BSG_TPM_PCR_SELECTION,
+                                                    FMT_SIZE32_DATA,
+                                                    0} },
+
+  {BSG_TPM_PCR_INFO, "BSG_TPM_PCR_INFO", { BSG_TPM_PCR_SELECTION,
+                                          BSG_TPM_COMPOSITE_HASH, 
+                                          BSG_TPM_COMPOSITE_HASH,
+                                          0} },
+  
+  
+  {BSG_TPM_STORED_DATA, "BSG_TPM_STORED_DATA", {
+      BSG_TPM_VERSION,
+      FMT_SIZE32_DATA,
+      FMT_SIZE32_DATA,
+      0}},
+  {BSG_TPM_SYMMETRIC_KEY, "BSG_TPM_SYMMETRIC_KEY", {
+      BSG_TPM_ALGORITHM_ID,
+      BSG_TPM_ENC_SCHEME,
+      FMT_SIZE16_DATA,
+      0}},
+  {BSG_TPM_STORE_PRIVKEY, "BSG_TPM_STORE_PRIVKEY", {FMT_SIZE32_DATA, 0}},
+  {BSG_TPM_STORE_ASYMKEY, "BSG_TPM_STORE_ASYMKEY", {
+      BSG_TPM_PAYLOAD_TYPE,
+      BSG_TPM_SECRET,
+      BSG_TPM_SECRET,
+      BSG_TPM_DIGEST,
+      BSG_TPM_STORE_PRIVKEY,
+      0}},
+  {BSG_TPM_MIGRATE_ASYMKEY, "BSG_TPM_MIGRATE_ASYMKEY", {
+      BSG_TPM_PAYLOAD_TYPE,
+      BSG_TPM_SECRET,
+      BSG_TPM_DIGEST,
+      FMT_U32,
+      BSG_TPM_STORE_PRIVKEY,
+      0}},
+  
+  {BSG_TPM_QUOTE_INFO, "BSG_TPM_QUOTE_INFO", {
+      BSG_TPM_VERSION,
+      FMT_DATA(4),
+      BSG_TPM_COMPOSITE_HASH,
+      BSG_TPM_NONCE,
+      0}},
+  
+  {BSG_TPM_IDENTITY_CONTENTS, "BSG_TPM_IDENTITY_CONTENTS", {
+      BSG_TPM_VERSION,
+      FMT_U32,
+      BSG_TPM_CHOSENID_HASH,
+      BSG_TPM_PUBKEY,
+      0}},
+  
+  {BSG_TPM_PCRVALUE, "BSG_TPM_PCRVALUE", {FMT_DATA(DIGEST_SIZE), 0}},
+  
+  {BSG_TCPA_PCR_FLAGS, "TCPA_PCR_FLAGS", {
+      FMT_U8,
+      FMT_U8,
+      0}},
+  
+  {BSG_TCS_AUTH, "TCS_AUTH", {
+      BSG_TYPE_UINT32, 
+      BSG_TPM_NONCE, 
+      BSG_TPM_NONCE, 
+      BSG_TYPE_BOOL, 
+      BSG_TPM_AUTHDATA, 
+      0}},
+  
+  {BSG_TPM_KEY_NONSENSITIVE, "BSG_TPM_KEY_NONSENSITIVE", {
+      BSG_TPM_VERSION,
+      BSG_TPM_KEY_USAGE,
+      BSG_TPM_KEY_FLAGS,
+      BSG_TPM_AUTH_DATA_USAGE,
+      BSG_TPM_KEY_PARMS,
+      FMT_SIZE32_DATA,
+      BSG_TPM_STORE_PUBKEY,
+      0}},
+  
+  {BSG_PACKED, "BSG_PACKED", {
+      __FMT_PACKED,
+      0 }},
+  
+  {BSG_TYPE_MAX, "", {0}},
+};
+
+
+static const BSG_Format* find_format (BSG_Type t) {
+  BSG_Format * f = s_fmt;
+  
+  if (t >= BSG_TYPE_MAX) {
+    return NULL;
+  }
+  
+  // WARNING: this depends on the enum and s_fmt[] array being in sync! make
+  // sure to run the static_selfcheck() to make sure
+  f = s_fmt + (t - BSG_TYPE_FIRST);
+  
+  return f;
+}
+
+//
+// a consistency-checking routine which can be run at compile time
+// (ie. immediately after compilation)
+//
+// tasks:
+// - verify that s_fmt has one entry per Type t, and that entry is at s_fmt[t]
+//
+// conditions:
+// - need that s_fmt[0] is the first type listed in the Type enum! ie the first
+//   Type has value 0, not 1
+//
+// FIXME: should have a function be passed in here which is called if the test
+// fails. Then the caller can decide what to do: abort, notify, whatever
+// 
+BOOL BSG_static_selfcheck ()
+{
+  int i;
+
+  for (i=BSG_TYPE_FIRST; i <= BSG_TYPE_MAX; i++) {
+    if (s_fmt[i - BSG_TYPE_FIRST].type != i) {
+      bsglog ("%s\n", "BSG: static_selfcheck failed!\n");
+      bsglog ("failure at %i, allegedly %s\n",
+             i, s_fmt[i - BSG_TYPE_FIRST].name);
+      abort();
+      return FALSE;
+    }
+  }
+  
+  bsglog ("%s\n", "BSG: static_selfcheck success!");
+  return TRUE;
+}
+
+
+/**
+ * Flatten a TCPA structure into a buffer in big-endian format
+ * @type: TCPA structure type
+ * @src: (IN) TCPA structure (OUT) end of TCPA structure
+ * @dst: (OUT) flattened data
+ * Returns: Flattened size or -1 for unknown types
+ */
+// make it so that it can just run through the whole process and return
+// the packed size, without packing anything. this will be done if dst is NULL.
+static int BSG_Pack_private(BSG_Type type, const BSG_BYTE** src, BSG_BYTE* dst)
+{
+  // check incoming parameters
+  if (*src == NULL)
+    return 0;
+  
+  const BSG_BYTE* s = *src;
+  BSG_BYTE* d = dst;
+  
+  BSG_UINT32 size   = __FMT_MASK_SIZE(type);
+  BSG_UINT32 format = __FMT_MASK_FORMAT(type);
+  
+  if (format == __FMT_CONST) // We are dealing with a fixed length value eg. 
UINT32
+    {
+      BSG_UINT32 val = 0;
+      switch (size) {
+      case 1: val = * (BYTE*) s; break;
+      case 2: val = * (unsigned short*) s; break;
+      case 4: val = * (BSG_UINT32*) s; break;
+      }
+      if (dst)
+       BSG_PackConst(val, size, d);
+
+      s += size;
+      d += size;
+    } else if (format == __FMT_DATA) { // We are dealing with raw data. Not 
sure when
+    // this is used.
+    
+      if (dst) {
+        bsglog ("BSG: __FMT_DATA size %d, src %p, dst %p\n", size, s, d);
+        memcpy(d, s, size);
+      }
+
+      s += size;
+      d += size;
+  } else if (format == __FMT_SIZE || format == __FMT_HSIZE) { // It's a size, 
followed by that much data or handles
+    
+    BSG_UINT32 psize = 0;
+    switch (size) {
+    case 1: psize = * (BYTE*) s; break;
+    case 2: psize = * (unsigned short*) s; break;
+    case 4: psize = * (BSG_UINT32*) s; break;
+    }
+        
+    if (dst)
+      BSG_PackConst(psize, size, d);
+
+    s += size;
+    d += size;
+    
+    // now 's' points to an address, so cast it to BSG_BYTE**
+    const BSG_BYTE* pdata = * ((BSG_BYTE**) s);
+    s += sizeof(BSG_BYTE*);
+    
+    if (format == __FMT_HSIZE) {// This is a list of psize Handles
+      if (dst) {
+       BSG_HANDLE* d2 = (BSG_HANDLE*) d;
+       BSG_HANDLE* p2 = (BSG_HANDLE*) pdata;
+       BSG_UINT32 i;
+       for (i = 0; i < psize; i++) 
+         d2[i] = BSG_UnpackConst((BSG_BYTE*)(p2 + i), 4);
+       
+      }
+      d += psize * sizeof(BSG_HANDLE);
+    } else {// If it's not psize handles, it's psize data.
+      if (psize > 0) {
+       if (dst) {
+         bsglog ("BSG: __FMT_SIZE, size=%d, src=%p, dst=%p\n",
+                 psize, pdata, d);
+         memcpy(d, pdata, psize);
+       }
+      }
+      d += psize;
+    }
+  } else if (format == __FMT_PACKED) {
+    // the source buffer is a pack_constbuf_t, which has a size and a
+    // pointer. just copy the buffer value, the size is not included in the
+    // output stream.
+    pack_constbuf_t * buf = (pack_constbuf_t*) s;
+    
+    if (dst) {
+      bsglog ("BSG: __FMT_PACKED, size=%d, src=%p, dst=%p\n",
+             buf->size, buf->data, d);
+      memcpy(d, buf->data, buf->size);
+    }
+        
+    s += buf->size;
+    d += buf->size;
+  } else if (format == 0) {// No flags are set. This is a structure & it should
+                          // be looked up in the bsg_s_fmt[]
+    
+    const BSG_Format* x = find_format (type);
+    if (x == NULL) {
+      vtpmloginfo(VTPM_LOG_BSG, "BSG_Pack: cannot find type %d\n", type);
+      return -1;
+    }
+    
+    if (dst)
+      bsglog ("BSG_Pack type %s\n", x->name);
+    
+    
+    // iterate through the fields
+    const BSG_UINT32* f = x->fields;
+    for (; *f; f++) {
+      int fsize;
+      
+      g_log_recursion_level++;
+      fsize = BSG_Pack_private((BSG_Type) *f, &s, dst ? d : NULL);
+      g_log_recursion_level--;
+      
+      if (fsize <= 0)
+       return fsize;
+      
+      d += fsize;
+    }
+  } else {
+    vtpmlogerror(VTPM_LOG_BSG, "BSG_Pack(): Unknown format %d\n", format);
+    return -1;
+  }
+  
+  *src = s;
+  return (d - dst);
+}
+
+/**
+ * Unflatten a TCPA structure from a buffer in big-endian format
+ * @type: TCPA structure type
+ * @src: flattened data
+ * @dst: (IN) TCPA structure (OUT) end of TCPA structure
+ * Returns: Flattened size
+ * Note: Returns flattened size NOT the unpacked structure size
+ */
+static int BSG_Unpack_private(BSG_Type type, const BSG_BYTE* src, BSG_BYTE** 
dst) {
+  // check incoming parameters
+  if (src == NULL)
+    return 0;
+  
+  
+  const BSG_BYTE* s = src;
+  BSG_BYTE* d = dst ? *dst:NULL;
+  if (dst && !d)
+    dst = NULL;
+  
+  BSG_UINT32 size = __FMT_MASK_SIZE(type);
+  BSG_UINT32 format = __FMT_MASK_FORMAT(type);
+  
+  if (format == __FMT_CONST) {// We are dealing with a fixed length value ie. 
UINT32
+
+    BSG_UINT32 val = BSG_UnpackConst(s, size);
+
+    if (dst) {
+      switch (size) {
+      case 1: *(BYTE *) d = (BSG_BYTE) val; break;
+      case 2: *(unsigned short*) d = (unsigned short) val; break;
+      case 4: *(BSG_UINT32*) d = (BSG_UINT32) val; break;
+      }
+    }
+
+    s += size;
+    d += size;
+  } else if (format == __FMT_DATA) {// We are dealing with raw data. Not sure 
when this is used.
+    if (dst)
+      memcpy(d, s, size);
+
+    d += size;
+    s += size;
+  } else if (format == __FMT_SIZE || format == __FMT_HSIZE) {// It's a size, 
followed by that much data or handles
+    
+    BSG_UINT32 psize = BSG_UnpackConst(s, size);
+    
+    if (psize > BSG_MAX_BUF_SIZE) {
+      vtpmlogerror(VTPM_LOG_BSG, "BSG_Unpack runs into var-sized data bigger 
than %u bytes!!\n",
+              BSG_MAX_BUF_SIZE);
+      return -1;
+    }
+    
+    if (dst) {
+      switch (size) {
+      case 1: *(BYTE *) d = (BSG_BYTE) psize; break;
+      case 2: *(unsigned short*) d = (unsigned short) psize; break;
+      case 4: *(BSG_UINT32*) d = (BSG_UINT32) psize; break;
+      }
+    }
+
+    s += size;
+    d += size;
+    
+    BSG_BYTE* pdata = NULL;
+    
+    if (psize) {
+      if (format == __FMT_HSIZE) { // This is a list of psize Handles
+       if (dst) {
+         BSG_HANDLE* s2 = (BSG_HANDLE*) s;
+         pdata = (BSG_BYTE *)malloc(psize * sizeof(BSG_HANDLE));
+          if (!pdata)
+            return -1;
+          
+         BSG_HANDLE* p2 = (BSG_HANDLE*) pdata;
+         BSG_UINT32 i;
+         for (i = 0; i < psize; i++) {
+           BSG_PackConst(s2[i], 4, (BSG_BYTE*)(p2 + i));
+         }
+       }
+       s += psize * sizeof(BSG_HANDLE);
+      } else { // If it's not psize handles, it's psize data.
+       if (dst) {
+         pdata = (BSG_BYTE *)malloc(sizeof(BSG_BYTE) * psize);
+          if (!pdata)
+            return -1;
+         memcpy(pdata, s, psize);
+       }
+       s += psize;
+      }
+    }
+    if (dst)
+      *(void**) d = pdata;
+
+    d += sizeof(void*);
+  } else if (format == __FMT_PACKED) {
+
+    // this doesn't make sense for unpacking!
+    vtpmlogerror(VTPM_LOG_BSG, "BSG_Unpack() called with format __FMT_PACKED. "
+                                                          "This does not make 
sense\n");
+    
+    return -1;
+  } else if (format == 0) {// No flags are set. This is a structure & it should
+                          // be looked up in the bsg_s_fmt[]
+
+    const BSG_Format* x = find_format (type);
+    if (x == NULL) {
+      vtpmlogerror(VTPM_LOG_BSG, "BSG_Unpack: cannot find type %d\n", type);
+      return -1;
+    }
+    
+    const BSG_UINT32* f = x->fields;
+    for (; *f; f++) {
+      int fsize = BSG_Unpack_private((BSG_Type) *f, s, dst ? &d:NULL);
+      if (fsize <= 0)
+       return fsize;
+      s += fsize;
+    }
+  }
+
+  if (dst)
+    *dst = d;
+  return (s - src);
+}
+
+/**
+ * Free memory associated with unpacked TCPA structure
+ * @type: TCPA structure type
+ * @src: (IN) TCPA structure (OUT) end of TCPA structure
+ * Note: Destroy should be called on all structures created with Unpack
+ *       to ensure that any allocated memory is freed
+ */
+static void BSG_Destroy_private(BSG_Type type, BSG_BYTE** src) {
+  BSG_BYTE* s = *src;
+  
+  BSG_UINT32 size = __FMT_MASK_SIZE(type);
+  BSG_UINT32 format = __FMT_MASK_FORMAT(type);
+  
+  if ((src == NULL) || (*src == NULL)) {
+        vtpmlogerror(VTPM_LOG_BSG, "BSG_Destroy() called with NULL src\n");
+    return;
+  }
+
+  if (format == __FMT_CONST || format == __FMT_DATA)
+    s += size;
+  else if (format == __FMT_SIZE || format == __FMT_HSIZE) {
+    s += size;
+    BSG_BYTE* ptr = *(BSG_BYTE**) s;
+    if (ptr)
+      free(ptr);
+    s += sizeof(void*);
+  } else if (format == __FMT_PACKED) {
+
+    // this doesn't make sense for unpacking, hence also for Destroy()
+    vtpmlogerror(VTPM_LOG_BSG, "BSG_Destroy() called with format __FMT_PACKED. 
"
+                                                          "This does not make 
sense\n");
+    
+    return;
+  } else if (format == 0) {
+    const BSG_Format* x = find_format (type);
+    if (x == NULL) {
+      vtpmlogerror(VTPM_LOG_BSG, "BSG_Destroy: cannot find type %d\n", type);
+      return;
+    }
+    
+    const BSG_UINT32* f = x->fields;
+    for (; *f; f++)
+      BSG_Destroy_private((BSG_Type) *f, &s);
+  }
+
+  *src = s;
+}
+
+int BSG_Pack(BSG_Type type, const void* src, BSG_BYTE* dst)
+{
+  const BSG_BYTE* src2 = (const BSG_BYTE*) src;
+  return BSG_Pack_private(type, &src2, dst);
+}
+
+int BSG_Unpack(BSG_Type type, const BSG_BYTE* src, void* dst)
+{
+  BSG_BYTE* dst2 = (BSG_BYTE*) dst;
+  return BSG_Unpack_private(type, src, dst ? &dst2:NULL);
+}
+
+void BSG_Destroy(BSG_Type type, void* src)
+{
+  BSG_BYTE* src2 = (BSG_BYTE*) src;
+  BSG_Destroy_private(type, &src2);
+}
+    
+/**
+ * Pack a 8/16/32-bit constant into a buffer in big-endian format
+ * @val: constant value
+ * @size: constant size in bytes (1, 2, or 4)
+ * @dst: (OUT) buffer
+ */
+void BSG_PackConst(BSG_UINT32 val, int size, BSG_BYTE* dst) {
+  bsglog ("BSG: PackConst on %d of size %i into address %p\n", val, size, dst);
+  
+  switch (size) {
+  case 4:
+    dst[0] = (BSG_BYTE)((val >> 24) & 0xff);
+    dst[1] = (BSG_BYTE)((val >> 16) & 0xff);
+    dst[2] = (BSG_BYTE)((val >> 8) & 0xff);
+    dst[3] = (BSG_BYTE)(val & 0xff);
+    break;
+  case 2:
+    dst[0] = (BSG_BYTE)((val >> 8) & 0xff);
+    dst[1] = (BSG_BYTE)(val & 0xff);
+    break;
+  case 1:
+    dst[0] = (BSG_BYTE)(val & 0xff);
+    break;
+  }
+}
+
+/**
+ * Unpack a 8/16/32-bit constant from a buffer in big-endian format
+ * @src: buffer
+ * @size: constant size in bytes (1, 2, or 4)
+ */
+BSG_UINT32 BSG_UnpackConst(const BSG_BYTE* src, int size) {
+  BSG_UINT32 val = 0;
+  
+  if (src == NULL) 
+    return 0;
+  
+  switch (size) {
+  case 4:
+    val = (((BSG_UINT32) src[0]) << 24
+          | ((BSG_UINT32) src[1]) << 16
+          | ((BSG_UINT32) src[2]) << 8
+          | (BSG_UINT32) src[3]);
+    break;
+  case 2:
+    val = (((BSG_UINT32) src[0]) << 8 | (BSG_UINT32) src[1]);
+    break;
+  case 1:
+    val = (BSG_UINT32) src[0];
+    break;
+  }  
+  return val;
+}
+
+// Pack a list of parameters. Beware not to send values, but rather you must
+// send a pointer to your values Instead. This includes UINT32's.
+int BSG_PackList( BSG_BYTE* dst, int ParamCount, ... ) {
+  int ParamNumber;
+  BSG_Type format; 
+  BSG_BYTE* val = NULL;
+  int size=0;
+  
+  va_list paramList;
+  va_start( paramList, ParamCount );
+
+  for( ParamNumber = 1; ParamNumber <= ParamCount; ParamNumber++) {
+    //Strangeness with int is because gcc wanted an int rather than a enum of 
ints.
+    format =  (BSG_Type) va_arg( paramList, int );
+    val = va_arg( paramList, BSG_BYTE* );    
+    size += BSG_Pack(format, val, dst == NULL ? NULL : dst + size);
+  }
+  
+  va_end (paramList);
+  
+  return size;
+}
+
+// Unpack a list of parameters. 
+int BSG_UnpackList( const BSG_BYTE* src, int ParamCount, ... ) {
+  int ParamNumber = 0;
+  BSG_Type format; 
+  BSG_BYTE* val = NULL;
+  int size = 0;
+  
+  va_list paramList;
+  va_start( paramList, ParamCount );
+  
+  for( ParamNumber = 1; ParamNumber <= ParamCount; ParamNumber++) {
+    format = (BSG_Type) va_arg( paramList, int );
+    val  = va_arg( paramList, BSG_BYTE* );
+    
+    size += BSG_Unpack(format, src + size, val);
+  }
+  
+  va_end( paramList );   
+  
+  return size;
+}
+
+// Destroy any memory allocated by calls to unpack 
+void BSG_DestroyList(int ParamCount, ... ) {
+  int ParamNumber = 0;
+  BSG_Type argType; 
+  BSG_BYTE* paramValue = NULL;
+  
+  va_list paramList;
+  va_start( paramList, ParamCount );
+  
+  for( ParamNumber = 1; ParamNumber <= ParamCount; ParamNumber++) {
+    argType = (BSG_Type) va_arg( paramList, int );
+    paramValue  = va_arg( paramList, BSG_BYTE* );
+    
+    BSG_Destroy(argType, paramValue);
+  }
+  
+  va_end( paramList );   
+  
+  return;
+}
+
+
+// and a tuple version
+TPM_RESULT BSG_DestroyTuple (int numParams, pack_tuple_t params[]) {
+  int i;
+  
+  for (i = 0; i < numParams; i++)
+    BSG_Destroy (params[i].type, params[i].addr);
+
+  return TPM_SUCCESS;
+}
+
+
+//
+// wrappers of Pack and PackList which malloc the ouput buffer. to be freed
+// by the caller later
+//
+
+int BSG_PackMalloc (BSG_Type type, const void* src, BSG_BYTE** o_dst) {
+  int size = BSG_Pack (type, src, NULL);
+  BSG_BYTE * dest = (BSG_BYTE*) malloc (size);
+  if (dest == NULL)
+    return -1;
+
+  size = BSG_Pack(type, src, dest);
+  *o_dst = dest;
+  return size;
+}
+
+
+
+int BSG_PackListMalloc(BSG_BYTE** outBuffer, int ParamCount, ... ) {
+  va_list args;
+  int size;
+  
+  va_start (args, ParamCount);
+  size = BSG_PackList (NULL, ParamCount, args);
+  va_end (args);
+  
+  BSG_BYTE * dest = (BSG_BYTE*) malloc (size);
+  if (dest == NULL)
+    return -1;
+
+  va_start (args, ParamCount);
+  size = BSG_PackList (dest, ParamCount, args);
+  va_end (args);
+  
+  *outBuffer = dest;
+  return size;
+}
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/util/bsg.h
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/util/bsg.h     Thu Sep  1 10:16:14 2005
@@ -0,0 +1,166 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// bsg.h
+// 
+//  This file contains API's for the TPM Byte Stream functions
+//
+// ==================================================================
+
+#ifndef __BSG_H__
+#define __BSG_H__
+
+#include <stdarg.h>
+#include "buffer.h"
+
+typedef unsigned int BSG_UINT32;
+typedef unsigned char BSG_BYTE;
+
+// forward decl
+struct pack_const_tuple_t;
+
+struct pack_tuple_t;
+
+
+/**
+ * Byte stream generator
+ */
+// this has to be manually kept in sync with the
+// s_fmt array!!
+// but now we have a self-check function which can make sure things are well
+// (if used!) 
+typedef enum BSG_Type
+{ 
+  BSG_TYPE_FIRST = 1,
+  BSG_TYPE_UINT32 = 1, // start at 1 so that Type 0 only serves as an
+                       // unused/special value
+  BSG_TYPE_UINT16,
+  BSG_TYPE_BYTE,
+  BSG_TYPE_BOOL,
+  BSG_TPM_SIZE32_DATA,  // a 32 bit unsigned size, followed by
+                        // a pointer to that much data. can pass a
+                        // struct pack_buf_t as the param
+  BSG_TPM_TAG,
+  BSG_TPM_HANDLE,
+  BSG_TPM_RESULT,
+  BSG_TPM_RESOURCE_TYPE,
+  BSG_TPM_COMMAND_CODE,
+  BSG_TPM_AUTH_DATA_USAGE,
+  BSG_TPM_ALGORITHM_ID,
+  BSG_TPM_PROTOCOL_ID,
+  BSG_TPM_KEY_USAGE,
+  BSG_TPM_ENC_SCHEME,
+  BSG_TPM_SIG_SCHEME,
+  BSG_TPM_MIGRATE_SCHEME,
+  BSG_TPM_KEY_FLAGS,
+  BSG_TPM_AUTHDATA,
+  BSG_TPM_SECRET,
+  BSG_TPM_ENCAUTH,
+  BSG_TPM_PAYLOAD_TYPE,
+  
+  BSG_TPM_VERSION,
+  BSG_TPM_DIGEST,
+  BSG_TPM_COMPOSITE_HASH,
+  BSG_TPM_CHOSENID_HASH,
+  BSG_TPM_NONCE,
+  BSG_TPM_KEY_HANDLE,
+  BSG_TPM_KEY_HANDLE_LIST,
+  BSG_TPM_KEY_PARMS,
+  BSG_TPM_RSA_KEY_PARMS,
+  BSG_TPM_STORE_PUBKEY,
+  BSG_TPM_PUBKEY,
+  BSG_TPM_KEY,
+  
+  BSG_TPM_MIGRATIONKEYAUTH,
+  BSG_TCPA_AUDIT_EVENT,
+  BSG_TCPA_EVENT_CERT,
+  BSG_TPM_PCR_SELECTION,
+  BSG_TPM_PCR_COMPOSITE,
+  BSG_TPM_PCR_INFO,
+  BSG_TPM_STORED_DATA,
+  BSG_TPM_SYMMETRIC_KEY,
+  BSG_TPM_STORE_PRIVKEY,
+  BSG_TPM_STORE_ASYMKEY,
+  BSG_TPM_MIGRATE_ASYMKEY,
+  BSG_TPM_QUOTE_INFO,
+  BSG_TPM_IDENTITY_CONTENTS,
+  BSG_TPM_PCRVALUE,
+  BSG_TCPA_PCR_FLAGS,
+  BSG_TCS_AUTH,
+  
+  // this is the BSG_TPM_KEY struct without the encData field
+  BSG_TPM_KEY_NONSENSITIVE,
+  
+  BSG_PACKED,
+  
+  BSG_TYPE_MAX
+} BSG_Type;
+
+struct pack_const_tuple_t {
+  BSG_Type type;
+  const void * addr;
+};
+
+
+typedef struct pack_tuple_t {
+  BSG_Type type;
+  void * addr;
+} pack_tuple_t;
+
+int BSG_Pack(BSG_Type type, const void* src, BSG_BYTE* dst);
+int BSG_Unpack(BSG_Type type, const BSG_BYTE* src, void* dst);
+void BSG_Destroy(BSG_Type type, void* src);
+
+// wrappers of Pack and PackList which malloc the ouput buffer. to be freed
+// by the caller later. returns size of allocated buffer, or -1 in case
+// allocation failed
+int BSG_PackMalloc (BSG_Type type, const void* src, BSG_BYTE** o_dst);
+int BSG_PackListMalloc (BSG_BYTE** outBuffer, int ParamCount, ... );
+
+// a va_list version of PackList
+int BSG_PackList(BSG_BYTE* outBuffer, int ParamCount, ... );
+int BSG_UnpackList(const BSG_BYTE* inBuffer, int ParamCount, ... );
+void BSG_DestroyList(int ParamCount, ... );
+
+// wrapper of PackList which uses a buffer_t
+TPM_RESULT BSG_PackListBuf (buffer_t * o_buf, int ParamCount, ...);
+
+// and a tuple version
+TPM_RESULT BSG_DestroyTuple (int numParams, pack_tuple_t params[]);
+
+void BSG_PackConst(BSG_UINT32 val, int size, BSG_BYTE* dst);
+BSG_UINT32 BSG_UnpackConst(const BSG_BYTE* src, int size);
+
+BOOL BSG_static_selfcheck ();
+
+#endif
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/util/buffer.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/util/buffer.c  Thu Sep  1 10:16:14 2005
@@ -0,0 +1,213 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+
+
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/param.h>
+
+#include "tcg.h"
+#include "bsg.h"
+#include "buffer.h"
+
+static TPM_RESULT buffer_priv_realloc (buffer_t * buf, tpm_size_t newsize);
+
+//
+// buffer functions!
+//
+
+TPM_RESULT buffer_init (buffer_t * buf, tpm_size_t initsize, const BYTE* 
initval) {
+  if (initsize == 0) {
+    memset(buf, 0, sizeof(*buf));
+    return TPM_SUCCESS;
+  }
+  
+  
+  buf->bytes = (BYTE*) malloc (initsize);
+  if (buf->bytes == NULL) 
+    return TPM_RESOURCES;
+  
+  buf->size = initsize;
+  buf->alloc_size = initsize;
+  
+  if (initval)
+    memcpy (buf->bytes, initval, initsize);
+  
+  buf->is_owner = TRUE;
+  
+  return TPM_SUCCESS;
+}
+
+TPM_RESULT buffer_init_convert (buffer_t * buf, tpm_size_t initsize, BYTE* 
initval) {
+  
+  buf->size = initsize;
+  buf->alloc_size = initsize;
+  buf->bytes = initval;
+  
+  buf->is_owner = TRUE;
+  
+  return TPM_SUCCESS;
+}
+
+TPM_RESULT buffer_init_copy (buffer_t * buf, const buffer_t * src) {
+  TPM_RESULT status = buffer_init (buf, src->size, src->bytes);
+  buf->is_owner = TRUE;
+  
+  return status;
+}
+
+
+
+// make an alias to a constant array
+TPM_RESULT buffer_init_const (buffer_t * buf, tpm_size_t size, const BYTE* 
val) {
+  // TODO: try to enforce the const things somehow!
+  buf->bytes = (BYTE*) val;
+  buf->size = size;
+  buf->alloc_size = 0;        // this field is now unneeded
+  
+  buf->is_owner = FALSE;
+  
+  return TPM_SUCCESS;
+}
+
+// make an alias into buf, with given offset and length
+// if len = 0, make the alias go to the end of buf
+TPM_RESULT buffer_init_alias (buffer_t * buf, const buffer_t * b,
+                              tpm_size_t offset, tpm_size_t len) {
+  if (offset + len > b->size) {
+    return TPM_NOSPACE;
+  }
+  
+  buf->bytes = b->bytes + offset;
+  buf->size = len > 0 ? len : b->size - offset;
+  
+  //VS/ buf->alloc_size = 0;
+  if (len ==0)
+    buf->alloc_size = b->alloc_size - offset;
+  else 
+    buf->alloc_size = MIN(b->alloc_size - offset, len);
+  
+        
+  buf->is_owner = FALSE;
+  
+  return TPM_SUCCESS;
+}
+    
+
+// copy into the start of dest
+TPM_RESULT buffer_copy (buffer_t * dest, const buffer_t* src)
+{
+  TPM_RESULT status = TPM_SUCCESS;
+    
+  if (dest->alloc_size < src->size) {  
+    status = buffer_priv_realloc (dest, src->size);
+    STATUSCHECK (status);
+  }
+  
+  memcpy (dest->bytes, src->bytes, src->size);
+  dest->size = src->size;
+  
+  //VS/ dest->is_owner = TRUE;
+  
+ abort_egress:
+
+  return status;
+}
+
+
+
+BOOL buffer_eq (const buffer_t * a, const buffer_t * b) {
+  return (a->size == b->size && memcmp (a->bytes, b->bytes, a->size) == 0);
+}
+
+
+void buffer_memset (buffer_t * buf, BYTE b) {
+  memset (buf->bytes, b, buf->size);
+}
+
+
+TPM_RESULT buffer_append_raw (buffer_t * buf, tpm_size_t len, const BYTE* 
bytes) {
+  TPM_RESULT status = TPM_SUCCESS;
+  
+  if (buf->alloc_size < buf->size + len) {
+    status = buffer_priv_realloc (buf, buf->size + len);
+    STATUSCHECK (status);
+  }
+  
+  memcpy (buf->bytes + buf->size, bytes, len);
+  
+  buf->size += len;
+  
+  goto egress;
+  
+ abort_egress:
+  
+ egress:
+  
+  return status;
+}
+
+tpm_size_t buffer_len (const buffer_t* buf) {
+  return buf->size;
+}
+
+TPM_RESULT buffer_free (buffer_t * buf) {
+  if (buf && buf->is_owner && buf->bytes != NULL) {
+    free (buf->bytes);
+    buf->bytes = NULL;
+  }
+  
+  return TPM_SUCCESS;
+}
+
+TPM_RESULT buffer_priv_realloc (buffer_t * buf, tpm_size_t newsize) {
+  
+  // we want to realloc to twice the size, or the new size, whichever
+  // bigger
+  
+  BYTE * tmpbuf = NULL;
+  
+  newsize = MAX (buf->alloc_size * 2, newsize);
+  
+  tmpbuf = (BYTE*) realloc (buf->bytes, newsize);
+  if (tmpbuf == NULL) 
+    return TPM_SIZE;
+  
+  
+  buf->bytes = tmpbuf;
+  buf->alloc_size = newsize;
+  
+  return TPM_SUCCESS;
+}
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/util/buffer.h
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/util/buffer.h  Thu Sep  1 10:16:14 2005
@@ -0,0 +1,103 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+
+#ifndef __VTPM_BUFFER_H__
+#define __VTPM_BUFFER_H__
+
+#include <stddef.h>             // for pointer NULL
+#include "tcg.h"
+
+// structure to enable use of FMT_SIZE32_DATA in BSG_Unpack
+typedef struct pack_buf_t {
+  UINT32 size;
+  BYTE * data;
+} pack_buf_t;
+
+// and a const version for Pack
+typedef struct pack_constbuf_t {
+  UINT32 size;
+  const BYTE* data;
+} pack_constbuf_t;
+
+typedef UINT32 tpm_size_t;
+
+// first version, probably will be expanded...
+
+#define NULL_BUF {0,0,0,0}
+
+typedef struct {
+  // private!!
+  tpm_size_t size, alloc_size;
+  BYTE * bytes;
+  
+  BOOL is_owner;              // do we own this buffer, and need to free it?
+} buffer_t;
+
+// allocate the buffer if initsize > 0, copying over initval if provided
+TPM_RESULT buffer_init (buffer_t * buf,
+                        tpm_size_t initsize,
+                        const BYTE* initval);
+
+// Create a new buffer from a BYTE *. Use buffer_free to destroy original BYTE 
*
+TPM_RESULT buffer_init_convert (buffer_t * buf, 
+                                tpm_size_t initsize, 
+                                BYTE* initval);
+
+// make an alias to a constant array, no copying
+TPM_RESULT buffer_init_const (buffer_t * buf, tpm_size_t size, const BYTE* 
val);
+
+// make an alias into buf, with given offset and length
+// if len = 0, make the alias go to the end of buf
+TPM_RESULT buffer_init_alias (buffer_t * buf, const buffer_t * b,
+                              tpm_size_t offset, tpm_size_t);
+
+// "copy constructor"
+TPM_RESULT buffer_init_copy (buffer_t * buf, const buffer_t * src);
+
+
+// copy into the start of a
+TPM_RESULT buffer_copy (buffer_t * dest, const buffer_t* src);
+
+// are they equal?
+BOOL buffer_eq (const buffer_t * a, const buffer_t * b);
+
+// set the buffer to a constant byte
+void buffer_memset (buffer_t * buf, BYTE b);
+
+tpm_size_t buffer_len (const buffer_t* buf);
+
+TPM_RESULT buffer_free (buffer_t * buf);
+
+TPM_RESULT buffer_append_raw (buffer_t * buf, tpm_size_t len, const BYTE* 
bytes);
+
+#endif // _TOOLS_H_
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/util/depend
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/util/depend    Thu Sep  1 10:16:14 2005
@@ -0,0 +1,7 @@
+hashtable.o: hashtable.c hashtable.h hashtable_private.h
+hashtable_itr.o: hashtable_itr.c hashtable.h hashtable_private.h \
+  hashtable_itr.h
+bsg.o: bsg.c tcg.h ../crypto/crypto.h ../crypto/sym_crypto.h buffer.h \
+  bsg.h log.h
+log.o: log.c buffer.h tcg.h
+buffer.o: buffer.c tcg.h bsg.h buffer.h
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/util/hashtable.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/util/hashtable.c       Thu Sep  1 10:16:14 2005
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 2005, Intel Corp
+ * Copyright (c) 2002, Christopher Clark <firstname.lastname@xxxxxxxxxxxx> 
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "hashtable.h"
+#include "hashtable_private.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+/*
+Credit for primes table: Aaron Krowne
+ http://br.endernet.org/~akrowne/
+ http://planetmath.org/encyclopedia/GoodHashTablePrimes.html
+*/
+static const unsigned int primes[] = {
+53, 97, 193, 389,
+769, 1543, 3079, 6151,
+12289, 24593, 49157, 98317,
+196613, 393241, 786433, 1572869,
+3145739, 6291469, 12582917, 25165843,
+50331653, 100663319, 201326611, 402653189,
+805306457, 1610612741
+};
+const unsigned int prime_table_length = sizeof(primes)/sizeof(primes[0]);
+const float max_load_factor = 0.65;
+
+/*****************************************************************************/
+struct hashtable *
+create_hashtable(unsigned int minsize,
+                 unsigned int (*hashf) (void*),
+                 int (*eqf) (void*,void*))
+{
+    struct hashtable *h;
+    unsigned int pindex, size = primes[0];
+    /* Check requested hashtable isn't too large */
+    if (minsize > (1u << 30)) return NULL;
+    /* Enforce size as prime */
+    for (pindex=0; pindex < prime_table_length; pindex++) {
+        if (primes[pindex] > minsize) { size = primes[pindex]; break; }
+    }
+    h = (struct hashtable *)malloc(sizeof(struct hashtable));
+    if (NULL == h) return NULL; /*oom*/
+    h->table = (struct entry **)malloc(sizeof(struct entry*) * size);
+    if (NULL == h->table) { free(h); return NULL; } /*oom*/
+    memset(h->table, 0, size * sizeof(struct entry *));
+    h->tablelength  = size;
+    h->primeindex   = pindex;
+    h->entrycount   = 0;
+    h->hashfn       = hashf;
+    h->eqfn         = eqf;
+    h->loadlimit    = (unsigned int) ceil(size * max_load_factor);
+#ifdef HASHTABLE_THREADED    
+    pthread_mutex_init(&h->mutex, NULL);
+#endif
+    return h;
+}
+
+/*****************************************************************************/
+unsigned int
+hash(struct hashtable *h, void *k)
+{
+    unsigned int i = h->hashfn(k);
+    i += ~(i << 9);
+    i ^=  ((i >> 14) | (i << 18)); /* >>> */
+    i +=  (i << 4);
+    i ^=  ((i >> 10) | (i << 22)); /* >>> */
+    return i;
+}
+
+/*****************************************************************************/
+static int
+hashtable_expand(struct hashtable *h)
+{
+    /* Double the size of the table to accomodate more entries */
+    struct entry **newtable;
+    struct entry *e;
+    struct entry **pE;
+    unsigned int newsize, i, index;
+    /* Check we're not hitting max capacity */
+    if (h->primeindex == (prime_table_length - 1)) return 0;
+    newsize = primes[++(h->primeindex)];
+
+    newtable = (struct entry **)malloc(sizeof(struct entry*) * newsize);
+    if (NULL != newtable)
+    {
+        memset(newtable, 0, newsize * sizeof(struct entry *));
+        /* This algorithm is not 'stable'. ie. it reverses the list
+         * when it transfers entries between the tables */
+        for (i = 0; i < h->tablelength; i++) {
+            while (NULL != (e = h->table[i])) {
+                h->table[i] = e->next;
+                index = indexFor(newsize,e->h);
+                e->next = newtable[index];
+                newtable[index] = e;
+            }
+        }
+        free(h->table);
+        h->table = newtable;
+    }
+    /* Plan B: realloc instead */
+    else 
+    {
+        newtable = (struct entry **)
+                   realloc(h->table, newsize * sizeof(struct entry *));
+        if (NULL == newtable) { (h->primeindex)--; return 0; }
+        h->table = newtable;
+        memset(newtable[h->tablelength], 0, newsize - h->tablelength);
+        for (i = 0; i < h->tablelength; i++) {
+            for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {
+                index = indexFor(newsize,e->h);
+                if (index == i)
+                {
+                    pE = &(e->next);
+                }
+                else
+                {
+                    *pE = e->next;
+                    e->next = newtable[index];
+                    newtable[index] = e;
+                }
+            }
+        }
+    }
+    h->tablelength = newsize;
+    h->loadlimit   = (unsigned int) ceil(newsize * max_load_factor);
+    return -1;
+}
+
+/*****************************************************************************/
+unsigned int
+hashtable_count(struct hashtable *h)
+{
+    unsigned int count;
+#ifdef HASHTABLE_THREADED
+    pthread_mutex_lock(&h->mutex);
+#endif    
+    count = h->entrycount;
+#ifdef HASHTABLE_THREADED
+    pthread_mutex_unlock(&h->mutex);
+#endif
+    return count;
+}
+
+/*****************************************************************************/
+int
+hashtable_insert(struct hashtable *h, void *k, void *v)
+{
+    /* This method allows duplicate keys - but they shouldn't be used */
+    unsigned int index;
+    struct entry *e;
+#ifdef HASHTABLE_THREADED
+    pthread_mutex_lock(&h->mutex);
+#endif   
+    if (++(h->entrycount) > h->loadlimit)
+    {
+        /* Ignore the return value. If expand fails, we should
+         * still try cramming just this value into the existing table
+         * -- we may not have memory for a larger table, but one more
+         * element may be ok. Next time we insert, we'll try expanding again.*/
+        hashtable_expand(h);
+    }
+    e = (struct entry *)malloc(sizeof(struct entry));
+    if (NULL == e) { --(h->entrycount); return 0; } /*oom*/
+    e->h = hash(h,k);
+    index = indexFor(h->tablelength,e->h);
+    e->k = k;
+    e->v = v;
+    e->next = h->table[index];
+    h->table[index] = e;
+#ifdef HASHTABLE_THREADED
+    pthread_mutex_unlock(&h->mutex);
+#endif   
+    return -1;
+}
+
+/*****************************************************************************/
+void * /* returns value associated with key */
+hashtable_search(struct hashtable *h, void *k)
+{
+#ifdef HASHTABLE_THREADED
+    pthread_mutex_lock(&h->mutex);
+#endif   
+    struct entry *e;
+    unsigned int hashvalue, index;
+    hashvalue = hash(h,k);
+    index = indexFor(h->tablelength,hashvalue);
+    e = h->table[index];
+    while (NULL != e)
+    {
+        /* Check hash value to short circuit heavier comparison */
+        if ((hashvalue == e->h) && (h->eqfn(k, e->k))) {
+#ifdef HASHTABLE_THREADED
+          pthread_mutex_unlock(&h->mutex);
+#endif   
+          return e->v;
+        }
+        e = e->next;
+    }
+#ifdef HASHTABLE_THREADED
+    pthread_mutex_unlock(&h->mutex);
+#endif   
+    return NULL;
+}
+
+/*****************************************************************************/
+void * /* returns value associated with key */
+hashtable_remove(struct hashtable *h, void *k)
+{
+    /* TODO: consider compacting the table when the load factor drops enough,
+     *       or provide a 'compact' method. */
+#ifdef HASHTABLE_THREADED
+    pthread_mutex_lock(&h->mutex);
+#endif   
+    struct entry *e;
+    struct entry **pE;
+    void *v;
+    unsigned int hashvalue, index;
+
+    hashvalue = hash(h,k);
+    index = indexFor(h->tablelength,hash(h,k));
+    pE = &(h->table[index]);
+    e = *pE;
+    while (NULL != e)
+    {
+        /* Check hash value to short circuit heavier comparison */
+        if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
+        {
+            *pE = e->next;
+            h->entrycount--;
+            v = e->v;
+            freekey(e->k);
+            free(e);
+            return v;
+        }
+        pE = &(e->next);
+        e = e->next;
+    }
+#ifdef HASHTABLE_THREADED
+    pthread_mutex_unlock(&h->mutex);
+#endif   
+    return NULL;
+}
+
+/*****************************************************************************/
+/* destroy */
+void
+hashtable_destroy(struct hashtable *h, int free_values)
+{
+#ifdef HASHTABLE_THREADED
+    pthread_mutex_lock(&h->mutex);
+#endif   
+    unsigned int i;
+    struct entry *e, *f;
+    struct entry **table = h->table;
+    if (free_values)
+    {
+        for (i = 0; i < h->tablelength; i++)
+        {
+            e = table[i];
+            while (NULL != e)
+            { f = e; e = e->next; freekey(f->k); free(f->v); free(f); }
+        }
+    }
+    else
+    {
+        for (i = 0; i < h->tablelength; i++)
+        {
+            e = table[i];
+            while (NULL != e)
+            { f = e; e = e->next; freekey(f->k); free(f); }
+        }
+    }
+    free(h->table);
+#ifdef HASHTABLE_THREADED
+    pthread_mutex_destroy(&h->mutex);
+#endif   
+    free(h);
+}
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/util/hashtable.h
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/util/hashtable.h       Thu Sep  1 10:16:14 2005
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2005, Intel Corp
+ * Copyright (c) 2002, Christopher Clark <firstname.lastname@xxxxxxxxxxxx> 
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#ifndef __HASHTABLE_CWC22_H__
+#define __HASHTABLE_CWC22_H__
+
+struct hashtable;
+
+/* Example of use:
+ *
+ *      struct hashtable  *h;
+ *      struct some_key   *k;
+ *      struct some_value *v;
+ *
+ *      static unsigned int         hash_from_key_fn( void *k );
+ *      static int                  keys_equal_fn ( void *key1, void *key2 );
+ *
+ *      h = create_hashtable(16, hash_from_key_fn, keys_equal_fn);
+ *      k = (struct some_key *)     malloc(sizeof(struct some_key));
+ *      v = (struct some_value *)   malloc(sizeof(struct some_value));
+ *
+ *      (initialise k and v to suitable values)
+ * 
+ *      if (! hashtable_insert(h,k,v) )
+ *      {     exit(-1);               }
+ *
+ *      if (NULL == (found = hashtable_search(h,k) ))
+ *      {    printf("not found!");                  }
+ *
+ *      if (NULL == (found = hashtable_remove(h,k) ))
+ *      {    printf("Not found\n");                 }
+ *
+ */
+
+/* Macros may be used to define type-safe(r) hashtable access functions, with
+ * methods specialized to take known key and value types as parameters.
+ * 
+ * Example:
+ *
+ * Insert this at the start of your file:
+ *
+ * DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value);
+ * DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value);
+ * DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value);
+ *
+ * This defines the functions 'insert_some', 'search_some' and 'remove_some'.
+ * These operate just like hashtable_insert etc., with the same parameters,
+ * but their function signatures have 'struct some_key *' rather than
+ * 'void *', and hence can generate compile time errors if your program is
+ * supplying incorrect data as a key (and similarly for value).
+ *
+ * Note that the hash and key equality functions passed to create_hashtable
+ * still take 'void *' parameters instead of 'some key *'. This shouldn't be
+ * a difficult issue as they're only defined and passed once, and the other
+ * functions will ensure that only valid keys are supplied to them.
+ *
+ * The cost for this checking is increased code size and runtime overhead
+ * - if performance is important, it may be worth switching back to the
+ * unsafe methods once your program has been debugged with the safe methods.
+ * This just requires switching to some simple alternative defines - eg:
+ * #define insert_some hashtable_insert
+ *
+ */
+
+/*****************************************************************************
+ * create_hashtable
+   
+ * @name                    create_hashtable
+ * @param   minsize         minimum initial size of hashtable
+ * @param   hashfunction    function for hashing keys
+ * @param   key_eq_fn       function for determining key equality
+ * @return                  newly created hashtable or NULL on failure
+ */
+
+struct hashtable *
+create_hashtable(unsigned int minsize,
+                 unsigned int (*hashfunction) (void*),
+                 int (*key_eq_fn) (void*,void*));
+
+/*****************************************************************************
+ * hashtable_insert
+   
+ * @name        hashtable_insert
+ * @param   h   the hashtable to insert into
+ * @param   k   the key - hashtable claims ownership and will free on removal
+ * @param   v   the value - does not claim ownership
+ * @return      non-zero for successful insertion
+ *
+ * This function will cause the table to expand if the insertion would take
+ * the ratio of entries to table size over the maximum load factor.
+ *
+ * This function does not check for repeated insertions with a duplicate key.
+ * The value returned when using a duplicate key is undefined -- when
+ * the hashtable changes size, the order of retrieval of duplicate key
+ * entries is reversed.
+ * If in doubt, remove before insert.
+ */
+
+int 
+hashtable_insert(struct hashtable *h, void *k, void *v);
+
+#define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
+int fnname (struct hashtable *h, keytype *k, valuetype *v) \
+{ \
+    return hashtable_insert(h,k,v); \
+}
+
+/*****************************************************************************
+ * hashtable_search
+   
+ * @name        hashtable_search
+ * @param   h   the hashtable to search
+ * @param   k   the key to search for  - does not claim ownership
+ * @return      the value associated with the key, or NULL if none found
+ */
+
+void *
+hashtable_search(struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
+valuetype * fnname (struct hashtable *h, keytype *k) \
+{ \
+    return (valuetype *) (hashtable_search(h,k)); \
+}
+
+/*****************************************************************************
+ * hashtable_remove
+   
+ * @name        hashtable_remove
+ * @param   h   the hashtable to remove the item from
+ * @param   k   the key to search for  - does not claim ownership
+ * @return      the value associated with the key, or NULL if none found
+ */
+
+void * /* returns value */
+hashtable_remove(struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
+valuetype * fnname (struct hashtable *h, keytype *k) \
+{ \
+    return (valuetype *) (hashtable_remove(h,k)); \
+}
+
+
+/*****************************************************************************
+ * hashtable_count
+   
+ * @name        hashtable_count
+ * @param   h   the hashtable
+ * @return      the number of items stored in the hashtable
+ */
+unsigned int
+hashtable_count(struct hashtable *h);
+
+
+/*****************************************************************************
+ * hashtable_destroy
+   
+ * @name        hashtable_destroy
+ * @param   h   the hashtable
+ * @param       free_values     whether to call 'free' on the remaining values
+ */
+
+void
+hashtable_destroy(struct hashtable *h, int free_values);
+
+#endif /* __HASHTABLE_CWC22_H__ */
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/util/hashtable_itr.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/util/hashtable_itr.c   Thu Sep  1 10:16:14 2005
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2005, Intel Corp
+ * Copyright (c) 2002, Christopher Clark <firstname.lastname@xxxxxxxxxxxx> 
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "hashtable.h"
+#include "hashtable_private.h"
+#include "hashtable_itr.h"
+#include <stdlib.h> /* defines NULL */
+
+/*****************************************************************************/
+/* hashtable_iterator    - iterator constructor */
+
+struct hashtable_itr *
+hashtable_iterator(struct hashtable *h)
+{
+    unsigned int i, tablelength;
+    struct hashtable_itr *itr = (struct hashtable_itr *)
+        malloc(sizeof(struct hashtable_itr));
+    if (NULL == itr) return NULL;
+#ifdef HASHTABLE_THREADED
+    pthread_mutex_lock(&h->mutex);
+#endif   
+    itr->h = h;
+    itr->e = NULL;
+    itr->parent = NULL;
+    tablelength = h->tablelength;
+    itr->index = tablelength;
+    if (0 == h->entrycount) {
+#ifdef HASHTABLE_THREADED
+      pthread_mutex_unlock(&h->mutex);
+#endif   
+      return itr;
+    }
+
+    for (i = 0; i < tablelength; i++)
+    {
+        if (NULL != h->table[i])
+        {
+            itr->e = h->table[i];
+            itr->index = i;
+            break;
+        }
+    }
+#ifdef HASHTABLE_THREADED
+    pthread_mutex_unlock(&h->mutex);
+#endif   
+    return itr;
+}
+
+/*****************************************************************************/
+/* key      - return the key of the (key,value) pair at the current position */
+/* value    - return the value of the (key,value) pair at the current position 
*/
+
+void *
+hashtable_iterator_key(struct hashtable_itr *i)
+{ return i->e->k; }
+
+void *
+hashtable_iterator_value(struct hashtable_itr *i)
+{ return i->e->v; }
+
+/*****************************************************************************/
+/* advance - advance the iterator to the next element
+ *           returns zero if advanced to end of table */
+
+int
+hashtable_iterator_advance(struct hashtable_itr *itr)
+{
+#ifdef HASHTABLE_THREADED
+    pthread_mutex_lock(&itr->h->mutex);
+#endif   
+    unsigned int j,tablelength;
+    struct entry **table;
+    struct entry *next;
+    int ret;
+    if (NULL == itr->e) { /* stupidity check */
+      ret = 0; 
+      goto egress;
+    }
+
+    next = itr->e->next;
+    if (NULL != next)
+    {
+        itr->parent = itr->e;
+        itr->e = next;
+        ret = -1;
+        goto egress;
+    }
+
+    tablelength = itr->h->tablelength;
+    itr->parent = NULL;
+    if (tablelength <= (j = ++(itr->index)))
+    {
+        itr->e = NULL;
+        ret = 0;
+        goto egress;
+    }
+    table = itr->h->table;
+    while (NULL == (next = table[j]))
+    {
+        if (++j >= tablelength)
+        {
+            itr->index = tablelength;
+            itr->e = NULL;
+            ret = 0;
+            goto egress;
+        }
+    }
+    itr->index = j;
+    itr->e = next;
+    ret = -1;
+
+ egress:
+#ifdef HASHTABLE_THREADED
+    pthread_mutex_unlock(&itr->h->mutex);
+#endif   
+    return ret;
+}
+
+/*****************************************************************************/
+/* remove - remove the entry at the current iterator position
+ *          and advance the iterator, if there is a successive
+ *          element.
+ *          If you want the value, read it before you remove:
+ *          beware memory leaks if you don't.
+ *          Returns zero if end of iteration. */
+
+int
+hashtable_iterator_remove(struct hashtable_itr *itr)
+{
+#ifdef HASHTABLE_THREADED
+    pthread_mutex_lock(&itr->h->mutex);
+#endif 
+    struct entry *remember_e, *remember_parent;
+    int ret;
+
+    /* Do the removal */
+    if (NULL == (itr->parent))
+    {
+        /* element is head of a chain */
+        itr->h->table[itr->index] = itr->e->next;
+    } else {
+        /* element is mid-chain */
+        itr->parent->next = itr->e->next;
+    }
+    /* itr->e is now outside the hashtable */
+    remember_e = itr->e;
+    itr->h->entrycount--;
+    freekey(remember_e->k);
+
+    /* Advance the iterator, correcting the parent */
+    remember_parent = itr->parent;
+    ret = hashtable_iterator_advance(itr);
+    if (itr->parent == remember_e) { itr->parent = remember_parent; }
+    free(remember_e);
+#ifdef HASHTABLE_THREADED
+    pthread_mutex_unlock(&itr->h->mutex);
+#endif 
+    return ret;
+}
+
+/*****************************************************************************/
+int /* returns zero if not found */
+hashtable_iterator_search(struct hashtable_itr *itr,
+                          struct hashtable *h, void *k)
+{
+#ifdef HASHTABLE_THREADED
+    pthread_mutex_lock(&h->mutex);
+#endif 
+    struct entry *e, *parent;
+    unsigned int hashvalue, index;
+    int ret;
+    
+    hashvalue = hash(h,k);
+    index = indexFor(h->tablelength,hashvalue);
+
+    e = h->table[index];
+    parent = NULL;
+    while (NULL != e)
+    {
+        /* Check hash value to short circuit heavier comparison */
+        if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
+        {
+            itr->index = index;
+            itr->e = e;
+            itr->parent = parent;
+            itr->h = h;
+            ret= -1;
+            goto egress;
+        }
+        parent = e;
+        e = e->next;
+    }
+  ret = 0;
+    
+egress:
+#ifdef HASHTABLE_THREADED
+    pthread_mutex_lock(&h->mutex);
+#endif 
+    return ret;
+}
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/util/hashtable_itr.h
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/util/hashtable_itr.h   Thu Sep  1 10:16:14 2005
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2005, Intel Corp
+ * Copyright (c) 2002, Christopher Clark <firstname.lastname@xxxxxxxxxxxx> 
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#ifndef __HASHTABLE_ITR_CWC22__
+#define __HASHTABLE_ITR_CWC22__
+#include "hashtable.h"
+#include "hashtable_private.h" /* needed to enable inlining */
+
+/*****************************************************************************/
+/* This struct is only concrete here to allow the inlining of two of the
+ * accessor functions. */
+struct hashtable_itr
+{
+    struct hashtable *h;
+    struct entry *e;
+    struct entry *parent;
+    unsigned int index;
+};
+
+
+/*****************************************************************************/
+/* hashtable_iterator
+ */
+
+struct hashtable_itr *
+hashtable_iterator(struct hashtable *h);
+
+/*****************************************************************************/
+/* hashtable_iterator_key
+ * - return the value of the (key,value) pair at the current position */
+
+void *hashtable_iterator_key(struct hashtable_itr *i);
+
+/*****************************************************************************/
+/* value - return the value of the (key,value) pair at the current position */
+
+void *hashtable_iterator_value(struct hashtable_itr *i);
+
+/*****************************************************************************/
+/* advance - advance the iterator to the next element
+ *           returns zero if advanced to end of table */
+
+int
+hashtable_iterator_advance(struct hashtable_itr *itr);
+
+/*****************************************************************************/
+/* remove - remove current element and advance the iterator to the next element
+ *          NB: if you need the value to free it, read it before
+ *          removing. ie: beware memory leaks!
+ *          returns zero if advanced to end of table */
+
+int
+hashtable_iterator_remove(struct hashtable_itr *itr);
+
+/*****************************************************************************/
+/* search - overwrite the supplied iterator, to point to the entry
+ *          matching the supplied key.
+            h points to the hashtable to be searched.
+ *          returns zero if not found. */
+int
+hashtable_iterator_search(struct hashtable_itr *itr,
+                          struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_ITERATOR_SEARCH(fnname, keytype) \
+int fnname (struct hashtable_itr *i, struct hashtable *h, keytype *k) \
+{ \
+    return (hashtable_iterator_search(i,h,k)); \
+}
+
+
+
+#endif /* __HASHTABLE_ITR_CWC22__*/
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/util/hashtable_private.h
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/util/hashtable_private.h       Thu Sep  1 10:16:14 2005
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2005, Intel Corp
+ * Copyright (c) 2002, Christopher Clark <firstname.lastname@xxxxxxxxxxxx> 
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __HASHTABLE_PRIVATE_CWC22_H__
+#define __HASHTABLE_PRIVATE_CWC22_H__
+
+#include "hashtable.h"
+#ifdef HASHTABLE_THREADED
+#include <pthread.h>
+#endif
+
+/*****************************************************************************/
+struct entry
+{
+    void *k, *v;
+    unsigned int h;
+    struct entry *next;
+};
+
+struct hashtable {
+    unsigned int tablelength;
+    struct entry **table;
+    unsigned int entrycount;
+    unsigned int loadlimit;
+    unsigned int primeindex;
+    unsigned int (*hashfn) (void *k);
+    int (*eqfn) (void *k1, void *k2);
+#ifdef HASHTABLE_THREADED
+    pthread_mutex_t mutex;
+#endif
+};
+
+/*****************************************************************************/
+unsigned int
+hash(struct hashtable *h, void *k);
+
+/*****************************************************************************/
+/* indexFor */
+static inline unsigned int
+indexFor(unsigned int tablelength, unsigned int hashvalue) {
+    return (hashvalue % tablelength);
+};
+
+/* Only works if tablelength == 2^N */
+/*static inline unsigned int
+indexFor(unsigned int tablelength, unsigned int hashvalue)
+{
+    return (hashvalue & (tablelength - 1u));
+}
+*/
+
+/*****************************************************************************/
+#define freekey(X) free(X)
+/*define freekey(X) ; */
+
+
+/*****************************************************************************/
+
+#endif /* __HASHTABLE_PRIVATE_CWC22_H__*/
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/util/log.c
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/util/log.c     Thu Sep  1 10:16:14 2005
@@ -0,0 +1,142 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "buffer.h"
+#include "tcg.h"
+
+// Helper code for the consts, eg. to produce messages for error codes.
+
+typedef struct error_code_entry_t {
+  TPM_RESULT code;
+  char * code_name;
+  char * msg;
+} error_code_entry_t;
+
+static const error_code_entry_t error_msgs [] = {    
+  { TPM_SUCCESS, "TPM_SUCCESS", "Successful completion of the operation" },
+  { TPM_AUTHFAIL, "TPM_AUTHFAIL", "Authentication failed" },
+  { TPM_BADINDEX, "TPM_BADINDEX", "The index to a PCR, DIR or other register 
is incorrect" },
+  { TPM_BAD_PARAMETER, "TPM_BAD_PARAMETER", "One or more parameter is bad" },
+  { TPM_AUDITFAILURE, "TPM_AUDITFAILURE", "An operation completed successfully 
but the auditing of that operation failed." },
+  { TPM_CLEAR_DISABLED, "TPM_CLEAR_DISABLED", "The clear disable flag is set 
and all clear operations now require physical access" },
+  { TPM_DEACTIVATED, "TPM_DEACTIVATED", "The TPM is deactivated" },
+  { TPM_DISABLED, "TPM_DISABLED", "The TPM is disabled" },
+  { TPM_DISABLED_CMD, "TPM_DISABLED_CMD", "The target command has been 
disabled" },
+  { TPM_FAIL, "TPM_FAIL", "The operation failed" },
+  { TPM_BAD_ORDINAL, "TPM_BAD_ORDINAL", "The ordinal was unknown or 
inconsistent" },
+  { TPM_INSTALL_DISABLED, "TPM_INSTALL_DISABLED", "The ability to install an 
owner is disabled" },
+  { TPM_INVALID_KEYHANDLE, "TPM_INVALID_KEYHANDLE", "The key handle presented 
was invalid" },
+  { TPM_KEYNOTFOUND, "TPM_KEYNOTFOUND", "The target key was not found" },
+  { TPM_INAPPROPRIATE_ENC, "TPM_INAPPROPRIATE_ENC", "Unacceptable encryption 
scheme" },
+  { TPM_MIGRATEFAIL, "TPM_MIGRATEFAIL", "Migration authorization failed" },
+  { TPM_INVALID_PCR_INFO, "TPM_INVALID_PCR_INFO", "PCR information could not 
be interpreted" },
+  { TPM_NOSPACE, "TPM_NOSPACE", "No room to load key." },
+  { TPM_NOSRK, "TPM_NOSRK", "There is no SRK set" },
+  { TPM_NOTSEALED_BLOB, "TPM_NOTSEALED_BLOB", "An encrypted blob is invalid or 
was not created by this TPM" },
+  { TPM_OWNER_SET, "TPM_OWNER_SET", "There is already an Owner" },
+  { TPM_RESOURCES, "TPM_RESOURCES", "The TPM has insufficient internal 
resources to perform the requested action." },
+  { TPM_SHORTRANDOM, "TPM_SHORTRANDOM", "A random string was too short" },
+  { TPM_SIZE, "TPM_SIZE", "The TPM does not have the space to perform the 
operation." },
+  { TPM_WRONGPCRVAL, "TPM_WRONGPCRVAL", "The named PCR value does not match 
the current PCR value." },
+  { TPM_BAD_PARAM_SIZE, "TPM_BAD_PARAM_SIZE", "The paramSize argument to the 
command has the incorrect value" },
+  { TPM_SHA_THREAD, "TPM_SHA_THREAD", "There is no existing SHA-1 thread." },
+  { TPM_SHA_ERROR, "TPM_SHA_ERROR", "The calculation is unable to proceed 
because the existing SHA-1 thread has already encountered an error." },
+  { TPM_FAILEDSELFTEST, "TPM_FAILEDSELFTEST", "Self-test has failed and the 
TPM has shutdown." },
+  { TPM_AUTH2FAIL, "TPM_AUTH2FAIL", "The authorization for the second key in a 
2 key function failed authorization" },
+  { TPM_BADTAG, "TPM_BADTAG", "The tag value sent to for a command is invalid" 
},
+  { TPM_IOERROR, "TPM_IOERROR", "An IO error occurred transmitting information 
to the TPM" },
+  { TPM_ENCRYPT_ERROR, "TPM_ENCRYPT_ERROR", "The encryption process had a 
problem." },
+  { TPM_DECRYPT_ERROR, "TPM_DECRYPT_ERROR", "The decryption process did not 
complete." },
+  { TPM_INVALID_AUTHHANDLE, "TPM_INVALID_AUTHHANDLE", "An invalid handle was 
used." },
+  { TPM_NO_ENDORSEMENT, "TPM_NO_ENDORSEMENT", "The TPM does not a EK 
installed" },
+  { TPM_INVALID_KEYUSAGE, "TPM_INVALID_KEYUSAGE", "The usage of a key is not 
allowed" },
+  { TPM_WRONG_ENTITYTYPE, "TPM_WRONG_ENTITYTYPE", "The submitted entity type 
is not allowed" },
+  { TPM_INVALID_POSTINIT, "TPM_INVALID_POSTINIT", "The command was received in 
the wrong sequence relative to TPM_Init and a subsequent TPM_Startup" },
+  { TPM_INAPPROPRIATE_SIG, "TPM_INAPPROPRIATE_SIG", "Signed data cannot 
include additional DER information" },
+  { TPM_BAD_KEY_PROPERTY, "TPM_BAD_KEY_PROPERTY", "The key properties in 
TPM_KEY_PARMs are not supported by this TPM" },
+  
+  { TPM_BAD_MIGRATION, "TPM_BAD_MIGRATION", "The migration properties of this 
key are incorrect." },
+  { TPM_BAD_SCHEME, "TPM_BAD_SCHEME", "The signature or encryption scheme for 
this key is incorrect or not permitted in this situation." },
+  { TPM_BAD_DATASIZE, "TPM_BAD_DATASIZE", "The size of the data (or blob) 
parameter is bad or inconsistent with the referenced key" },
+  { TPM_BAD_MODE, "TPM_BAD_MODE", "A mode parameter is bad, such as capArea or 
subCapArea for TPM_GetCapability, phsicalPresence parameter for 
TPM_PhysicalPresence, or migrationType for TPM_CreateMigrationBlob." },
+  { TPM_BAD_PRESENCE, "TPM_BAD_PRESENCE", "Either the physicalPresence or 
physicalPresenceLock bits have the wrong value" },
+  { TPM_BAD_VERSION, "TPM_BAD_VERSION", "The TPM cannot perform this version 
of the capability" },
+  { TPM_NO_WRAP_TRANSPORT, "TPM_NO_WRAP_TRANSPORT", "The TPM does not allow 
for wrapped transport sessions" },
+  { TPM_AUDITFAIL_UNSUCCESSFUL, "TPM_AUDITFAIL_UNSUCCESSFUL", "TPM audit 
construction failed and the underlying command was returning a failure code 
also" },
+  { TPM_AUDITFAIL_SUCCESSFUL, "TPM_AUDITFAIL_SUCCESSFUL", "TPM audit 
construction failed and the underlying command was returning success" },
+  { TPM_NOTRESETABLE, "TPM_NOTRESETABLE", "Attempt to reset a PCR register 
that does not have the resettable attribute" },
+  { TPM_NOTLOCAL, "TPM_NOTLOCAL", "Attempt to reset a PCR register that 
requires locality and locality modifier not part of command transport" },
+  { TPM_BAD_TYPE, "TPM_BAD_TYPE", "Make identity blob not properly typed" },
+  { TPM_INVALID_RESOURCE, "TPM_INVALID_RESOURCE", "When saving context 
identified resource type does not match actual resource" },
+  { TPM_NOTFIPS, "TPM_NOTFIPS", "The TPM is attempting to execute a command 
only available when in FIPS mode" },
+  { TPM_INVALID_FAMILY, "TPM_INVALID_FAMILY", "The command is attempting to 
use an invalid family ID" },
+  { TPM_NO_NV_PERMISSION, "TPM_NO_NV_PERMISSION", "The permission to 
manipulate the NV storage is not available" },
+  { TPM_REQUIRES_SIGN, "TPM_REQUIRES_SIGN", "The operation requires a signed 
command" },
+  { TPM_KEY_NOTSUPPORTED, "TPM_KEY_NOTSUPPORTED", "Wrong operation to load an 
NV key" },
+  { TPM_AUTH_CONFLICT, "TPM_AUTH_CONFLICT", "NV_LoadKey blob requires both 
owner and blob authorization" },
+  { TPM_AREA_LOCKED, "TPM_AREA_LOCKED", "The NV area is locked and not 
writtable" },
+  { TPM_BAD_LOCALITY, "TPM_BAD_LOCALITY", "The locality is incorrect for the 
attempted operation" },
+  { TPM_READ_ONLY, "TPM_READ_ONLY", "The NV area is read only and can't be 
written to" },
+  { TPM_PER_NOWRITE, "TPM_PER_NOWRITE", "There is no protection on the write 
to the NV area" },
+  { TPM_FAMILYCOUNT, "TPM_FAMILYCOUNT", "The family count value does not 
match" },
+  { TPM_WRITE_LOCKED, "TPM_WRITE_LOCKED", "The NV area has already been 
written to" },
+  { TPM_BAD_ATTRIBUTES, "TPM_BAD_ATTRIBUTES", "The NV area attributes 
conflict" },
+  { TPM_INVALID_STRUCTURE, "TPM_INVALID_STRUCTURE", "The structure tag and 
version are invalid or inconsistent" },
+  { TPM_KEY_OWNER_CONTROL, "TPM_KEY_OWNER_CONTROL", "The key is under control 
of the TPM Owner and can only be evicted by the TPM Owner." },
+  { TPM_BAD_COUNTER, "TPM_BAD_COUNTER", "The counter handle is incorrect" },
+  { TPM_NOT_FULLWRITE, "TPM_NOT_FULLWRITE", "The write is not a complete write 
of the area" },
+  { TPM_CONTEXT_GAP, "TPM_CONTEXT_GAP", "The gap between saved context counts 
is too large" },
+  { TPM_MAXNVWRITES, "TPM_MAXNVWRITES", "The maximum number of NV writes 
without an owner has been exceeded" },
+  { TPM_NOOPERATOR, "TPM_NOOPERATOR", "No operator authorization value is set" 
},
+  { TPM_RESOURCEMISSING, "TPM_RESOURCEMISSING", "The resource pointed to by 
context is not loaded" },
+  { TPM_DELEGATE_LOCK, "TPM_DELEGATE_LOCK", "The delegate administration is 
locked" },
+  { TPM_DELEGATE_FAMILY, "TPM_DELEGATE_FAMILY", "Attempt to manage a family 
other then the delegated family" },
+  { TPM_DELEGATE_ADMIN, "TPM_DELEGATE_ADMIN", "Delegation table management not 
enabled" },
+  { TPM_TRANSPORT_EXCLUSIVE, "TPM_TRANSPORT_EXCLUSIVE", "There was a command 
executed outside of an exclusive transport session" },
+};
+
+
+// helper function for the error codes:
+const char* tpm_get_error_name (TPM_RESULT code) {
+  // just do a linear scan for now
+  unsigned i;
+  for (i = 0; i < sizeof(error_msgs)/sizeof(error_msgs[0]); i++) 
+    if (code == error_msgs[i].code) 
+      return error_msgs[i].code_name;
+  
+    return "Failed to find code name for given code";
+}
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/util/log.h
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/util/log.h     Thu Sep  1 10:16:14 2005
@@ -0,0 +1,92 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+
+#ifndef __VTPM_LOG_H__
+#define __VTPM_LOG_H__
+
+#include <stdint.h>             // for uint32_t
+#include <stddef.h>             // for pointer NULL
+
+// =========================== LOGGING ==============================
+
+// the logging module numbers
+#define VTPM_LOG_CRYPTO      1
+#define VTPM_LOG_BSG         2
+#define VTPM_LOG_TXDATA      3
+#define VTPM_LOG_TCS         4
+#define VTPM_LOG_TCS_DEEP    5
+#define VTPM_LOG_VTSP        6
+#define VTPM_LOG_VTPM        7
+#define VTPM_LOG_VTPM_DEEP   8
+
+static char *module_names[] = { "",
+                                "CRYPTO",
+                                "BSG",
+                                "TXDATA",
+                                "TCS",
+                                "TCS",
+                                "VTSP",
+                                "VTPM",
+                                "VTPM"
+                              };
+
+// Default to standard logging
+#ifndef LOGGING_MODULES
+#define LOGGING_MODULES (BITMASK(VTPM_LOG_VTPM))
+#endif
+
+// bit-access macros
+#define BITMASK(idx)      ( 1U << (idx) )
+#define GETBIT(num,idx)   ( ((num) & BITMASK(idx)) >> idx )
+#define SETBIT(num,idx)   (num) |= BITMASK(idx)
+#define CLEARBIT(num,idx) (num) &= ( ~ BITMASK(idx) )
+
+#define vtpmloginfo(module, fmt, args...) \
+  if (GETBIT (LOGGING_MODULES, module) == 1) {                         \
+    fprintf (stdout, "INFO[%s]: " fmt, module_names[module], ##args); \
+  }
+
+#define vtpmloginfomore(module, fmt, args...) \
+  if (GETBIT (LOGGING_MODULES, module) == 1) {                       \
+    fprintf (stdout, fmt,##args);                                    \
+  }
+                               
+#define vtpmlogerror(module, fmt, args...) \
+  fprintf (stderr, "ERROR[%s]: " fmt, module_names[module], ##args);
+                               
+//typedef UINT32 tpm_size_t;
+                        
+// helper function for the error codes:
+const char* tpm_get_error_name (TPM_RESULT code);
+
+#endif // _VTPM_LOG_H_
diff -r 84ab93e1ee05 -r dd668f7527cb tools/vtpm_manager/util/tcg.h
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/tools/vtpm_manager/util/tcg.h     Thu Sep  1 10:16:14 2005
@@ -0,0 +1,486 @@
+// ===================================================================
+// 
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without 
+// modification, are permitted provided that the following conditions 
+// are met:
+//
+//   * Redistributions of source code must retain the above copyright 
+//     notice, this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above 
+//     copyright notice, this list of conditions and the following 
+//     disclaimer in the documentation and/or other materials provided 
+//     with the distribution.
+//   * Neither the name of Intel Corporation nor the names of its 
+//     contributors may be used to endorse or promote products derived
+//     from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+// 
+// tcg.h
+// 
+//  This file contains all the structure and type definitions
+//
+// ==================================================================
+
+#ifndef __TCG_H__
+#define __TCG_H__
+
+// This pragma is used to disallow structure padding
+#pragma pack(push, 1)
+
+// *************************** TYPEDEFS *********************************
+typedef unsigned char BYTE;
+typedef unsigned char BOOL;
+typedef unsigned short UINT16;
+typedef unsigned int UINT32;
+typedef unsigned long long UINT64;
+
+typedef UINT32 TPM_RESULT;
+typedef UINT32 TPM_PCRINDEX;
+typedef UINT32 TPM_DIRINDEX;
+typedef UINT32 TPM_HANDLE;
+typedef TPM_HANDLE TPM_AUTHHANDLE;
+typedef TPM_HANDLE TCPA_HASHHANDLE;
+typedef TPM_HANDLE TCPA_HMACHANDLE;
+typedef TPM_HANDLE TCPA_ENCHANDLE;
+typedef TPM_HANDLE TPM_KEY_HANDLE;
+typedef TPM_HANDLE TCPA_ENTITYHANDLE;
+typedef UINT32 TPM_RESOURCE_TYPE;
+typedef UINT32 TPM_COMMAND_CODE;
+typedef UINT16 TPM_PROTOCOL_ID;
+typedef BYTE TPM_AUTH_DATA_USAGE;
+typedef UINT16 TPM_ENTITY_TYPE;
+typedef UINT32 TPM_ALGORITHM_ID;
+typedef UINT16 TPM_KEY_USAGE;
+typedef UINT16 TPM_STARTUP_TYPE;
+typedef UINT32 TPM_CAPABILITY_AREA;
+typedef UINT16 TPM_ENC_SCHEME;
+typedef UINT16 TPM_SIG_SCHEME;
+typedef UINT16 TPM_MIGRATE_SCHEME;
+typedef UINT16 TPM_PHYSICAL_PRESENCE;
+typedef UINT32 TPM_KEY_FLAGS;
+
+#define TPM_DIGEST_SIZE 20  // Don't change this
+typedef BYTE TPM_AUTHDATA[TPM_DIGEST_SIZE];
+typedef TPM_AUTHDATA TPM_SECRET;
+typedef TPM_AUTHDATA TPM_ENCAUTH;
+typedef BYTE TPM_PAYLOAD_TYPE;
+typedef UINT16 TPM_TAG;
+
+// Data Types of the TCS
+typedef UINT32 TCS_AUTHHANDLE;  // Handle addressing a authorization session
+typedef UINT32 TCS_CONTEXT_HANDLE; // Basic context handle
+typedef UINT32 TCS_KEY_HANDLE;  // Basic key handle
+
+// ************************* STRUCTURES **********************************
+
+typedef struct TPM_VERSION {
+  BYTE major;
+  BYTE minor;
+  BYTE revMajor;
+  BYTE revMinor;
+} TPM_VERSION;
+ 
+static const TPM_VERSION TPM_STRUCT_VER_1_1 = { 1,1,0,0 };
+
+typedef struct TPM_DIGEST {
+  BYTE digest[TPM_DIGEST_SIZE];
+} TPM_DIGEST;
+
+typedef TPM_DIGEST TPM_PCRVALUE;
+typedef TPM_DIGEST TPM_COMPOSITE_HASH;
+typedef TPM_DIGEST TPM_DIRVALUE;
+typedef TPM_DIGEST TPM_HMAC;
+typedef TPM_DIGEST TPM_CHOSENID_HASH;
+
+typedef struct TPM_NONCE {
+  BYTE nonce[TPM_DIGEST_SIZE];
+} TPM_NONCE;
+
+typedef struct TPM_KEY_PARMS {
+  TPM_ALGORITHM_ID algorithmID;
+  TPM_ENC_SCHEME encScheme;
+  TPM_SIG_SCHEME sigScheme;
+  UINT32 parmSize;
+  BYTE* parms;
+} TPM_KEY_PARMS;
+
+typedef struct TPM_RSA_KEY_PARMS {  
+  UINT32 keyLength; 
+  UINT32 numPrimes; 
+  UINT32 exponentSize;
+  BYTE* exponent;
+} TPM_RSA_KEY_PARMS;
+
+typedef struct TPM_STORE_PUBKEY {
+  UINT32 keyLength;
+  BYTE* key;
+} TPM_STORE_PUBKEY;
+
+typedef struct TPM_PUBKEY {
+  TPM_KEY_PARMS algorithmParms;
+  TPM_STORE_PUBKEY pubKey;
+} TPM_PUBKEY;
+
+typedef struct TPM_KEY {
+  TPM_VERSION         ver;
+  TPM_KEY_USAGE       keyUsage;
+  TPM_KEY_FLAGS       keyFlags;
+  TPM_AUTH_DATA_USAGE authDataUsage;
+  TPM_KEY_PARMS       algorithmParms; 
+  UINT32              PCRInfoSize;
+  BYTE*               PCRInfo; // this should be a TPM_PCR_INFO, or NULL
+  TPM_STORE_PUBKEY    pubKey;
+  UINT32              encDataSize;
+  BYTE*               encData;
+} TPM_KEY;
+
+typedef struct TPM_PCR_SELECTION { 
+  UINT16 sizeOfSelect;        /// in bytes
+  BYTE* pcrSelect;
+} TPM_PCR_SELECTION;
+
+typedef struct TPM_PCR_COMPOSITE { 
+  TPM_PCR_SELECTION select;
+  UINT32 valueSize;
+  TPM_PCRVALUE* pcrValue;
+} TPM_PCR_COMPOSITE;
+
+
+typedef struct TPM_PCR_INFO {
+  TPM_PCR_SELECTION pcrSelection;
+  TPM_COMPOSITE_HASH digestAtRelease;
+  TPM_COMPOSITE_HASH digestAtCreation;
+} TPM_PCR_INFO;
+
+
+typedef struct TPM_BOUND_DATA {
+  TPM_VERSION ver;
+  TPM_PAYLOAD_TYPE payload;
+  BYTE* payloadData;
+} TPM_BOUND_DATA;
+
+typedef struct TPM_STORED_DATA { 
+  TPM_VERSION ver;
+  UINT32 sealInfoSize;
+  BYTE* sealInfo;
+  UINT32 encDataSize;
+  BYTE* encData;
+} TPM_STORED_DATA;
+
+typedef struct TCS_AUTH {
+  TCS_AUTHHANDLE  AuthHandle;
+  TPM_NONCE   NonceOdd;   // system 
+  TPM_NONCE   NonceEven;   // TPM 
+  BOOL   fContinueAuthSession;
+  TPM_AUTHDATA  HMAC;
+} TCS_AUTH;
+
+// **************************** CONSTANTS *********************************
+
+// BOOL values
+#define TRUE 0x01
+#define FALSE 0x00
+
+#define TCPA_MAX_BUFFER_LENGTH 0x2000
+
+//
+// TPM_COMMAND_CODE values
+#define TPM_PROTECTED_ORDINAL 0x00000000UL
+#define TPM_UNPROTECTED_ORDINAL 0x80000000UL
+#define TPM_CONNECTION_ORDINAL 0x40000000UL
+#define TPM_VENDOR_ORDINAL 0x20000000UL
+
+#define TPM_ORD_OIAP                     (10UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_OSAP                     (11UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ChangeAuth               (12UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_TakeOwnership            (13UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ChangeAuthAsymStart      (14UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ChangeAuthAsymFinish     (15UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ChangeAuthOwner          (16UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Extend                   (20UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_PcrRead                  (21UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Quote                    (22UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Seal                     (23UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Unseal                   (24UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_DirWriteAuth             (25UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_DirRead                  (26UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_UnBind                   (30UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_CreateWrapKey            (31UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_LoadKey                  (32UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_GetPubKey                (33UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_EvictKey                 (34UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_CreateMigrationBlob      (40UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ReWrapKey                (41UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ConvertMigrationBlob     (42UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_AuthorizeMigrationKey    (43UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_CreateMaintenanceArchive (44UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_LoadMaintenanceArchive   (45UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_KillMaintenanceFeature   (46UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_LoadManuMaintPub         (47UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ReadManuMaintPub         (48UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_CertifyKey               (50UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Sign                     (60UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_GetRandom                (70UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_StirRandom               (71UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SelfTestFull             (80UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SelfTestStartup          (81UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_CertifySelfTest          (82UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ContinueSelfTest         (83UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_GetTestResult            (84UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Reset                    (90UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_OwnerClear               (91UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_DisableOwnerClear        (92UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ForceClear               (93UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_DisableForceClear        (94UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_GetCapabilitySigned      (100UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_GetCapability            (101UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_GetCapabilityOwner       (102UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_OwnerSetDisable          (110UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_PhysicalEnable           (111UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_PhysicalDisable          (112UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SetOwnerInstall          (113UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_PhysicalSetDeactivated   (114UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SetTempDeactivated       (115UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_CreateEndorsementKeyPair (120UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_MakeIdentity             (121UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ActivateIdentity         (122UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ReadPubek                (124UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_OwnerReadPubek           (125UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_DisablePubekRead         (126UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_GetAuditEvent            (130UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_GetAuditEventSigned      (131UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_GetOrdinalAuditStatus    (140UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SetOrdinalAuditStatus    (141UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Terminate_Handle         (150UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Init                     (151UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SaveState                (152UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Startup                  (153UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SetRedirection           (154UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SHA1Start                (160UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SHA1Update               (161UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SHA1Complete             (162UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SHA1CompleteExtend       (163UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_FieldUpgrade             (170UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SaveKeyContext           (180UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_LoadKeyContext           (181UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_SaveAuthContext          (182UL + TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_LoadAuthContext          (183UL + TPM_PROTECTED_ORDINAL)
+#define TSC_ORD_PhysicalPresence         (10UL + TPM_CONNECTION_ORDINAL)
+
+
+
+//
+// TPM_RESULT values
+//
+// just put in the whole table from spec 1.2
+              
+#define TPM_BASE   0x0 // The start of TPM return codes
+#define TPM_VENDOR_ERROR 0x00000400 // Mask to indicate that the error code is 
vendor specific for vendor specific commands
+#define TPM_NON_FATAL  0x00000800 // Mask to indicate that the error code is a 
non-fatal failure.
+
+#define TPM_SUCCESS   TPM_BASE // Successful completion of the operation
+#define TPM_AUTHFAIL      TPM_BASE + 1 // Authentication failed
+#define TPM_BADINDEX      TPM_BASE + 2 // The index to a PCR, DIR or other 
register is incorrect
+#define TPM_BAD_PARAMETER     TPM_BASE + 3 // One or more parameter is bad
+#define TPM_AUDITFAILURE     TPM_BASE + 4 // An operation completed 
successfully but the auditing of that operation failed.
+#define TPM_CLEAR_DISABLED     TPM_BASE + 5 // The clear disable flag is set 
and all clear operations now require physical access
+#define TPM_DEACTIVATED     TPM_BASE + 6 // The TPM is deactivated
+#define TPM_DISABLED      TPM_BASE + 7 // The TPM is disabled
+#define TPM_DISABLED_CMD     TPM_BASE + 8 // The target command has been 
disabled
+#define TPM_FAIL       TPM_BASE + 9 // The operation failed
+#define TPM_BAD_ORDINAL     TPM_BASE + 10 // The ordinal was unknown or 
inconsistent
+#define TPM_INSTALL_DISABLED   TPM_BASE + 11 // The ability to install an 
owner is disabled
+#define TPM_INVALID_KEYHANDLE  TPM_BASE + 12 // The key handle presented was 
invalid
+#define TPM_KEYNOTFOUND     TPM_BASE + 13 // The target key was not found
+#define TPM_INAPPROPRIATE_ENC  TPM_BASE + 14 // Unacceptable encryption scheme
+#define TPM_MIGRATEFAIL     TPM_BASE + 15 // Migration authorization failed
+#define TPM_INVALID_PCR_INFO   TPM_BASE + 16 // PCR information could not be 
interpreted
+#define TPM_NOSPACE      TPM_BASE + 17 // No room to load key.
+#define TPM_NOSRK       TPM_BASE + 18 // There is no SRK set
+#define TPM_NOTSEALED_BLOB     TPM_BASE + 19 // An encrypted blob is invalid 
or was not created by this TPM
+#define TPM_OWNER_SET      TPM_BASE + 20 // There is already an Owner
+#define TPM_RESOURCES      TPM_BASE + 21 // The TPM has insufficient internal 
resources to perform the requested action.
+#define TPM_SHORTRANDOM     TPM_BASE + 22 // A random string was too short
+#define TPM_SIZE       TPM_BASE + 23 // The TPM does not have the space to 
perform the operation.
+#define TPM_WRONGPCRVAL     TPM_BASE + 24 // The named PCR value does not 
match the current PCR value.
+#define TPM_BAD_PARAM_SIZE     TPM_BASE + 25 // The paramSize argument to the 
command has the incorrect value
+#define TPM_SHA_THREAD      TPM_BASE + 26 // There is no existing SHA-1 thread.
+#define TPM_SHA_ERROR      TPM_BASE + 27 // The calculation is unable to 
proceed because the existing SHA-1 thread has already encountered an error.
+#define TPM_FAILEDSELFTEST     TPM_BASE + 28 // Self-test has failed and the 
TPM has shutdown.
+#define TPM_AUTH2FAIL      TPM_BASE + 29 // The authorization for the second 
key in a 2 key function failed authorization
+#define TPM_BADTAG       TPM_BASE + 30 // The tag value sent to for a command 
is invalid
+#define TPM_IOERROR      TPM_BASE + 31 // An IO error occurred transmitting 
information to the TPM
+#define TPM_ENCRYPT_ERROR     TPM_BASE + 32 // The encryption process had a 
problem.
+#define TPM_DECRYPT_ERROR     TPM_BASE + 33 // The decryption process did not 
complete.
+#define TPM_INVALID_AUTHHANDLE TPM_BASE + 34 // An invalid handle was used.
+#define TPM_NO_ENDORSEMENT     TPM_BASE + 35 // The TPM does not a EK installed
+#define TPM_INVALID_KEYUSAGE   TPM_BASE + 36 // The usage of a key is not 
allowed
+#define TPM_WRONG_ENTITYTYPE   TPM_BASE + 37 // The submitted entity type is 
not allowed
+#define TPM_INVALID_POSTINIT   TPM_BASE + 38 // The command was received in 
the wrong sequence relative to TPM_Init and a subsequent TPM_Startup
+#define TPM_INAPPROPRIATE_SIG  TPM_BASE + 39 // Signed data cannot include 
additional DER information
+#define TPM_BAD_KEY_PROPERTY   TPM_BASE + 40 // The key properties in 
TPM_KEY_PARMs are not supported by this TPM
+
+#define TPM_BAD_MIGRATION      TPM_BASE + 41 // The migration properties of 
this key are incorrect.
+#define TPM_BAD_SCHEME       TPM_BASE + 42 // The signature or encryption 
scheme for this key is incorrect or not permitted in this situation.
+#define TPM_BAD_DATASIZE      TPM_BASE + 43 // The size of the data (or blob) 
parameter is bad or inconsistent with the referenced key
+#define TPM_BAD_MODE       TPM_BASE + 44 // A mode parameter is bad, such as 
capArea or subCapArea for TPM_GetCapability, phsicalPresence parameter for 
TPM_PhysicalPresence, or migrationType for TPM_CreateMigrationBlob.
+#define TPM_BAD_PRESENCE      TPM_BASE + 45 // Either the physicalPresence or 
physicalPresenceLock bits have the wrong value
+#define TPM_BAD_VERSION      TPM_BASE + 46 // The TPM cannot perform this 
version of the capability
+#define TPM_NO_WRAP_TRANSPORT     TPM_BASE + 47 // The TPM does not allow for 
wrapped transport sessions
+#define TPM_AUDITFAIL_UNSUCCESSFUL TPM_BASE + 48 // TPM audit construction 
failed and the underlying command was returning a failure code also
+#define TPM_AUDITFAIL_SUCCESSFUL   TPM_BASE + 49 // TPM audit construction 
failed and the underlying command was returning success
+#define TPM_NOTRESETABLE      TPM_BASE + 50 // Attempt to reset a PCR register 
that does not have the resettable attribute
+#define TPM_NOTLOCAL       TPM_BASE + 51 // Attempt to reset a PCR register 
that requires locality and locality modifier not part of command transport
+#define TPM_BAD_TYPE       TPM_BASE + 52 // Make identity blob not properly 
typed
+#define TPM_INVALID_RESOURCE     TPM_BASE + 53 // When saving context 
identified resource type does not match actual resource
+#define TPM_NOTFIPS       TPM_BASE + 54 // The TPM is attempting to execute a 
command only available when in FIPS mode
+#define TPM_INVALID_FAMILY      TPM_BASE + 55 // The command is attempting to 
use an invalid family ID
+#define TPM_NO_NV_PERMISSION     TPM_BASE + 56 // The permission to manipulate 
the NV storage is not available
+#define TPM_REQUIRES_SIGN      TPM_BASE + 57 // The operation requires a 
signed command
+#define TPM_KEY_NOTSUPPORTED     TPM_BASE + 58 // Wrong operation to load an 
NV key
+#define TPM_AUTH_CONFLICT      TPM_BASE + 59 // NV_LoadKey blob requires both 
owner and blob authorization
+#define TPM_AREA_LOCKED      TPM_BASE + 60 // The NV area is locked and not 
writtable
+#define TPM_BAD_LOCALITY      TPM_BASE + 61 // The locality is incorrect for 
the attempted operation
+#define TPM_READ_ONLY       TPM_BASE + 62 // The NV area is read only and 
can't be written to
+#define TPM_PER_NOWRITE      TPM_BASE + 63 // There is no protection on the 
write to the NV area
+#define TPM_FAMILYCOUNT      TPM_BASE + 64 // The family count value does not 
match
+#define TPM_WRITE_LOCKED      TPM_BASE + 65 // The NV area has already been 
written to
+#define TPM_BAD_ATTRIBUTES      TPM_BASE + 66 // The NV area attributes 
conflict
+#define TPM_INVALID_STRUCTURE     TPM_BASE + 67 // The structure tag and 
version are invalid or inconsistent
+#define TPM_KEY_OWNER_CONTROL     TPM_BASE + 68 // The key is under control of 
the TPM Owner and can only be evicted by the TPM Owner.
+#define TPM_BAD_COUNTER      TPM_BASE + 69 // The counter handle is incorrect
+#define TPM_NOT_FULLWRITE      TPM_BASE + 70 // The write is not a complete 
write of the area
+#define TPM_CONTEXT_GAP      TPM_BASE + 71 // The gap between saved context 
counts is too large
+#define TPM_MAXNVWRITES      TPM_BASE + 72 // The maximum number of NV writes 
without an owner has been exceeded
+#define TPM_NOOPERATOR       TPM_BASE + 73 // No operator authorization value 
is set
+#define TPM_RESOURCEMISSING     TPM_BASE + 74 // The resource pointed to by 
context is not loaded
+#define TPM_DELEGATE_LOCK      TPM_BASE + 75 // The delegate administration is 
locked
+#define TPM_DELEGATE_FAMILY     TPM_BASE + 76 // Attempt to manage a family 
other then the delegated family
+#define TPM_DELEGATE_ADMIN      TPM_BASE + 77 // Delegation table management 
not enabled
+#define TPM_TRANSPORT_EXCLUSIVE    TPM_BASE + 78 // There was a command 
executed outside of an exclusive transport session
+
+// TPM_TAG values
+#define TPM_TAG_RQU_COMMAND 0x00c1
+#define TPM_TAG_RQU_AUTH1_COMMAND 0x00c2
+#define TPM_TAG_RQU_AUTH2_COMMAND 0x00c3
+#define TPM_TAG_RSP_COMMAND 0x00c4
+#define TPM_TAG_RSP_AUTH1_COMMAND 0x00c5
+#define TPM_TAG_RSP_AUTH2_COMMAND 0x00c6
+
+// TPM_PAYLOAD_TYPE values
+#define TPM_PT_ASYM 0x01
+#define TPM_PT_BIND 0x02
+#define TPM_PT_MIGRATE 0x03
+#define TPM_PT_MAINT 0x04
+#define TPM_PT_SEAL 0x05
+
+// TPM_ENTITY_TYPE values
+#define TPM_ET_KEYHANDLE 0x0001
+#define TPM_ET_OWNER 0x0002
+#define TPM_ET_DATA 0x0003
+#define TPM_ET_SRK 0x0004
+#define TPM_ET_KEY 0x0005
+
+/// TPM_ResourceTypes
+#define TPM_RT_KEY      0x00000001
+#define TPM_RT_AUTH     0x00000002
+#define TPM_RT_TRANS    0x00000004
+#define TPM_RT_CONTEXT  0x00000005
+
+// TPM_PROTOCOL_ID values
+#define TPM_PID_OIAP 0x0001
+#define TPM_PID_OSAP 0x0002
+#define TPM_PID_ADIP 0x0003
+#define TPM_PID_ADCP 0x0004
+#define TPM_PID_OWNER 0x0005
+
+// TPM_ALGORITHM_ID values
+#define TPM_ALG_RSA 0x00000001
+#define TPM_ALG_DES 0x00000002
+#define TPM_ALG_3DES 0X00000003
+#define TPM_ALG_SHA 0x00000004
+#define TPM_ALG_HMAC 0x00000005
+#define TCPA_ALG_AES 0x00000006
+
+// TPM_ENC_SCHEME values
+#define TPM_ES_NONE 0x0001
+#define TPM_ES_RSAESPKCSv15 0x0002
+#define TPM_ES_RSAESOAEP_SHA1_MGF1 0x0003
+
+// TPM_SIG_SCHEME values
+#define TPM_SS_NONE 0x0001
+#define TPM_SS_RSASSAPKCS1v15_SHA1 0x0002
+#define TPM_SS_RSASSAPKCS1v15_DER 0x0003
+
+// TPM_KEY_USAGE values
+#define TPM_KEY_EK 0x0000 
+#define TPM_KEY_SIGNING 0x0010
+#define TPM_KEY_STORAGE 0x0011
+#define TPM_KEY_IDENTITY 0x0012
+#define TPM_KEY_AUTHCHANGE 0X0013
+#define TPM_KEY_BIND 0x0014
+#define TPM_KEY_LEGACY 0x0015
+
+// TPM_AUTH_DATA_USAGE values
+#define TPM_AUTH_NEVER 0x00
+#define TPM_AUTH_ALWAYS 0x01
+
+// Key Handle of owner and srk
+#define TPM_OWNER_KEYHANDLE 0x40000001
+#define TPM_SRK_KEYHANDLE 0x40000000
+
+// ---------------------- Functions for checking TPM_RESULTs -----------------
+
+// FIXME: Review use of these and delete unneeded ones.
+
+// these are really badly dependent on local structure:
+// DEPENDS: local var 'status' of type TPM_RESULT
+// DEPENDS: label 'abort_egress' which cleans up and returns the status
+#define ERRORDIE(s) do { status = s; \
+                         fprintf (stderr, "*** ERRORDIE in %s, line %i\n", 
__func__, __LINE__); \
+                         goto abort_egress; } \
+                    while (0)
+
+// ASSUME: the return value used after the abort_egress label has been set
+// already (eg. the 'status' local var)
+#define STATUSCHECK(s) if (s != TPM_SUCCESS) { \
+                            fprintf (stderr, "*** ERR in %s, line %i\n", 
__func__, __LINE__); \
+                            goto abort_egress; \
+                        }
+
+// DEPENDS: local var 'status' of type TPM_RESULT
+// DEPENDS: label 'abort_egress' which cleans up and returns the status
+// Try command c. If it fails, set status to s and goto shame.
+#define TPMTRY(s,c) if (c != TPM_SUCCESS) { \
+                       status = s; \
+                       goto abort_egress; \
+                    }
+
+// Try command c. If it fails, print error message, set status to actual 
return code. Goto shame
+#define TPMTRYRETURN(c) do { status = c; \
+                             if (status != TPM_SUCCESS) { \
+                               printf("ERROR in %s:%i code: %s.\n", __func__, 
__LINE__, tpm_get_error_name(status)); \
+                               goto abort_egress; \
+                             } \
+                        } while(0)    
+
+
+#pragma pack(pop)
+
+#endif //__TCPA_H__
diff -r 84ab93e1ee05 -r dd668f7527cb xen/include/public/io/tpmif.h
--- /dev/null   Thu Sep  1 10:08:53 2005
+++ b/xen/include/public/io/tpmif.h     Thu Sep  1 10:16:14 2005
@@ -0,0 +1,42 @@
+/******************************************************************************
+ * tpmif.h
+ *
+ * TPM I/O interface for Xen guest OSes.
+ *
+ * Copyright (c) 2005, IBM Corporation
+ *
+ * Author: Stefan Berger, stefanb@xxxxxxxxxx
+ * Grant table support: Mahadevan Gomathisankaran
+ *
+ * This code has been derived from tools/libxc/xen/io/netif.h
+ *
+ * Copyright (c) 2003-2004, Keir Fraser
+ */
+
+#ifndef __XEN_PUBLIC_IO_TPMIF_H__
+#define __XEN_PUBLIC_IO_TPMIF_H__
+
+typedef struct {
+    unsigned long addr;   /* Machine address of packet.   */
+    int      ref;         /* grant table access reference */
+    u16      id;          /* Echoed in response message.  */
+    u16      size:15;     /* Packet size in bytes.        */
+    u16      mapped:1;
+} tpmif_tx_request_t;
+
+/*
+ * The TPMIF_TX_RING_SIZE defines the number of pages the
+ * front-end and backend can exchange (= size of array).
+ */
+typedef u32 TPMIF_RING_IDX;
+
+#define TPMIF_TX_RING_SIZE 16
+
+/* This structure must fit in a memory page. */
+typedef struct {
+    union {
+        tpmif_tx_request_t  req;
+    } ring[TPMIF_TX_RING_SIZE];
+} tpmif_tx_interface_t;
+
+#endif
diff -r 84ab93e1ee05 -r dd668f7527cb tools/check/check_curl_devel
--- a/tools/check/check_curl_devel      Thu Sep  1 10:08:53 2005
+++ /dev/null   Thu Sep  1 10:16:14 2005
@@ -1,11 +0,0 @@
-#!/bin/bash
-# CHECK-BUILD
-
-function error {
-    echo 'Check for libcurl includes failed.'
-    exit 1
-}
-
-set -e
-[ -e /usr/include/curl ] || error
-[ -e /usr/include/curl/curl.h ] || error
\ No newline at end of file
diff -r 84ab93e1ee05 -r dd668f7527cb tools/check/check_curl_lib
--- a/tools/check/check_curl_lib        Thu Sep  1 10:08:53 2005
+++ /dev/null   Thu Sep  1 10:16:14 2005
@@ -1,10 +0,0 @@
-#!/bin/bash
-# CHECK-BUILD CHECK-INSTALL
-
-function error {
-        echo 'Check for CURL library failed.'
-        exit 1
-}
-
-set -e
-ldconfig -p | grep libcurl.so || error
\ No newline at end of file

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.