diff -r 6d377f296b01 tools/vtpm_manager/Makefile
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/Makefile	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/Rules.mk
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/Rules.mk	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/tcs/Makefile
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/tcs/Makefile	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/tcs/transmit.c
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/tcs/transmit.c	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/tcs/tcs.c
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/tcs/tcs.c	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/tcs/tcs.h
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/tcs/tcs.h	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/tcs/contextmgr.c
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/tcs/contextmgr.c	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/tcs/contextmgr.h
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/tcs/contextmgr.h	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/tcs/tpmddl.h
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/tcs/tpmddl.h	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/util/Makefile
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/util/Makefile	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/util/bsg.c
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/util/bsg.c	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/util/bsg.h
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/util/bsg.h	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/util/log.c
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/util/log.c	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/util/log.h
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/util/log.h	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/util/tcg.h
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/util/tcg.h	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/util/depend
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/util/depend	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/util/hashtable.c
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/util/hashtable.c	Wed Aug 17 10:59:37 2005
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 2005, Intel Corp
+ * Copyright (c) 2002, Christopher Clark <firstname.lastname@cl.cam.ac.uk> 
+ * 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 6d377f296b01 tools/vtpm_manager/util/hashtable.h
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/util/hashtable.h	Wed Aug 17 10:59:37 2005
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2005, Intel Corp
+ * Copyright (c) 2002, Christopher Clark <firstname.lastname@cl.cam.ac.uk> 
+ * 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 6d377f296b01 tools/vtpm_manager/util/buffer.c
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/util/buffer.c	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/util/buffer.h
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/util/buffer.h	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/util/hashtable_private.h
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/util/hashtable_private.h	Wed Aug 17 10:59:37 2005
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2005, Intel Corp
+ * Copyright (c) 2002, Christopher Clark <firstname.lastname@cl.cam.ac.uk> 
+ * 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 6d377f296b01 tools/vtpm_manager/util/hashtable_itr.c
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/util/hashtable_itr.c	Wed Aug 17 10:59:37 2005
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2005, Intel Corp
+ * Copyright (c) 2002, Christopher Clark <firstname.lastname@cl.cam.ac.uk> 
+ * 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 6d377f296b01 tools/vtpm_manager/util/hashtable_itr.h
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/util/hashtable_itr.h	Wed Aug 17 10:59:37 2005
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2005, Intel Corp
+ * Copyright (c) 2002, Christopher Clark <firstname.lastname@cl.cam.ac.uk> 
+ * 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 6d377f296b01 tools/vtpm_manager/manager/Makefile
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/manager/Makefile	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/manager/vtpm_manager.c
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/manager/vtpm_manager.c	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/manager/vtpm_manager.h
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/manager/vtpm_manager.h	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/manager/securestorage.c
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/manager/securestorage.c	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/manager/tpmpassthrough.c
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/manager/tpmpassthrough.c	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/manager/vtpmpriv.h
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/manager/vtpmpriv.h	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/manager/dmictl.c
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/manager/dmictl.c	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/manager/vtsp.c
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/manager/vtsp.c	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/manager/vtsp.h
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/manager/vtsp.h	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/manager/vtpmd.c
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/manager/vtpmd.c	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/crypto/Makefile
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/crypto/Makefile	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/crypto/crypto.c
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/crypto/crypto.c	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/crypto/crypto.h
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/crypto/crypto.h	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/crypto/rsa.c
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/crypto/rsa.c	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/crypto/hash.c
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/crypto/hash.c	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/crypto/sym_crypto.c
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/crypto/sym_crypto.c	Wed Aug 17 10:59:37 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 6d377f296b01 tools/vtpm_manager/crypto/sym_crypto.h
--- /dev/null	Wed Aug 17 17:48:56 2005
+++ b/tools/vtpm_manager/crypto/sym_crypto.h	Wed Aug 17 10:59:37 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 37ac3cf33506 tools/vtpm_manager/COPYING
--- /dev/null	Thu Aug 11 16:23:54 2005
+++ b/tools/vtpm_manager/COPYING	Wed Aug 17 12:00:26 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 37ac3cf33506 tools/vtpm_manager/README
--- /dev/null	Thu Aug 11 16:23:54 2005
+++ b/tools/vtpm_manager/README	Wed Aug 17 12:00:46 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.
