# HG changeset patch
# User shand@xxxxxxxxxxxxxxxxxxxxxxxxxxx
# Node ID 9ba52ccadc06dd96dad2981eae4f212d1f6efe75
# Parent edbdd7123d24d2c418dc4abd63e84ba2d87f5576
vTPM manager - Intel/IBM joint TPM Virtualization implementation for Xen.
This is a software implementation for people without h/w vTPM support.
Signed-off-by: Vinnie Scarlata <vincent.r.scarlata@xxxxxxxxx>
Signed-off-by: Joseph Cihula <joseph.cihula@xxxxxxxxx>
Signed-off-by: Steven Hand <steven@xxxxxxxxxxxxx>
diff -r edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/COPYING
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/COPYING Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/Makefile
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/Makefile Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/README
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/README Tue Aug 30 19:39:25 2005
@@ -0,0 +1,89 @@
+// ===================================================================
+//
+// Copyright (c) 2005, Intel Corp.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Intel Corporation nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+// ===================================================================
+
+Directory Structure
+===================
+tools/vtpm_manager/crypto -> crypto files
+tools/vtpm_manager/TCS -> TCS implementation
+tools/vtpm_manager/util -> Utility Library. Include disk-io and buffers.
+tools/vtpm_manager/manager -> VTPM Manager
+
+Compile Flags
+===================
+LOGGING_MODULES -> How extensive logging happens
+ see util/log.h for more info
+
+VTPM_MULTI_VM -> Defined: VTPMs run in their own VMs
+ Not Defined (default): VTPMs are processes
+
+# Debugging flags that may disappear without notice in the future
+
+DUMMY_BACKEND -> vtpm_manager listens on /tmp/in.fifo and
+ /tmp/out.fifo rather than backend
+
+MANUAL_DM_LAUNCH -> User must manually launch & kill VTPMs
+
+USE_FIXED_SRK_AUTH -> Do not randomly generate a random SRK & Owner
auth
+
+Requirements
+============
+- xen-unstable
+- IBM frontend/backend vtpm driver patch
+
+Single-VM Flow
+============================
+- Launch the VTPM manager (vtpm_managerd) which which begins listening to the
BE with one thread
+ and listens to a named fifo that is shared by the vtpms to commuincate with
the manager.
+- VTPM Manager listens to TPM BE.
+- When xend launches a tpm frontend equipped VM it contacts the manager over
the vtpm backend.
+- When the manager receives the open message from the BE, it launches a vtpm
+- Xend allows the VM to continue booting.
+- When a TPM request is issued to the front end, the front end transmits the
TPM request to the backend.
+- The manager receives the TPM requests and uses a named fifo to forward the
request to the vtpm.
+- The fifo listener begins listening for the reply from vtpm for the request.
+- Vtpm processes request and replies to manager over shared named fifo.
+- If needed, the vtpm may send a request to the vtpm_manager at any time to
save it's secrets to disk.
+- Manager receives response from vtpm and passes it back to backend for
forwarding to guest.
+
+NOTES:
+* SaveService SHOULD seal it's table before saving it to disk. However,
+ the current Xen infrastructure does not provide a mechanism for this to be
+ unsealed later. Specifically, the auth and wrapped key must be available ONLY
+ to the service, or it's not even worth encrypting
+
+ In the future the vtpm manager will be protected by an early boot mechanism
+ that will allow for better protection of it's data.
+
+TODO:
+- Timeout on crashed vtpms
+- create lock for shared fifo for talking to vtpms.
diff -r edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/Rules.mk
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/Rules.mk Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/crypto/Makefile
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/crypto/Makefile Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/crypto/crypto.c
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/crypto/crypto.c Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/crypto/crypto.h
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/crypto/crypto.h Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/crypto/hash.c
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/crypto/hash.c Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/crypto/rsa.c
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/crypto/rsa.c Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/crypto/sym_crypto.c
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/crypto/sym_crypto.c Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/crypto/sym_crypto.h
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/crypto/sym_crypto.h Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/manager/Makefile
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/manager/Makefile Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/manager/dmictl.c
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/manager/dmictl.c Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/manager/securestorage.c
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/manager/securestorage.c Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/manager/tpmpassthrough.c
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/manager/tpmpassthrough.c Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/manager/vtpm_manager.c
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/manager/vtpm_manager.c Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/manager/vtpm_manager.h
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/manager/vtpm_manager.h Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/manager/vtpmd.c
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/manager/vtpmd.c Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/manager/vtpmpriv.h
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/manager/vtpmpriv.h Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/manager/vtsp.c
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/manager/vtsp.c Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/manager/vtsp.h
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/manager/vtsp.h Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/tcs/Makefile
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/tcs/Makefile Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/tcs/contextmgr.c
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/tcs/contextmgr.c Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/tcs/contextmgr.h
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/tcs/contextmgr.h Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/tcs/tcs.c
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/tcs/tcs.c Tue Aug 30 19:39:25 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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, ¶mSize,
+ 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/tcs/tcs.h
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/tcs/tcs.h Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/tcs/tpmddl.h
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/tcs/tpmddl.h Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/tcs/transmit.c
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/tcs/transmit.c Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/util/Makefile
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/util/Makefile Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/util/bsg.c
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/util/bsg.c Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/util/bsg.h
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/util/bsg.h Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/util/buffer.c
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/util/buffer.c Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/util/buffer.h
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/util/buffer.h Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/util/depend
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/util/depend Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/util/hashtable.c
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/util/hashtable.c Tue Aug 30 19:39:25 2005
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 2005, Intel Corp
+ * Copyright (c) 2002, Christopher Clark <firstname.lastname@xxxxxxxxxxxx>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "hashtable.h"
+#include "hashtable_private.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+/*
+Credit for primes table: Aaron Krowne
+ http://br.endernet.org/~akrowne/
+ http://planetmath.org/encyclopedia/GoodHashTablePrimes.html
+*/
+static const unsigned int primes[] = {
+53, 97, 193, 389,
+769, 1543, 3079, 6151,
+12289, 24593, 49157, 98317,
+196613, 393241, 786433, 1572869,
+3145739, 6291469, 12582917, 25165843,
+50331653, 100663319, 201326611, 402653189,
+805306457, 1610612741
+};
+const unsigned int prime_table_length = sizeof(primes)/sizeof(primes[0]);
+const float max_load_factor = 0.65;
+
+/*****************************************************************************/
+struct hashtable *
+create_hashtable(unsigned int minsize,
+ unsigned int (*hashf) (void*),
+ int (*eqf) (void*,void*))
+{
+ struct hashtable *h;
+ unsigned int pindex, size = primes[0];
+ /* Check requested hashtable isn't too large */
+ if (minsize > (1u << 30)) return NULL;
+ /* Enforce size as prime */
+ for (pindex=0; pindex < prime_table_length; pindex++) {
+ if (primes[pindex] > minsize) { size = primes[pindex]; break; }
+ }
+ h = (struct hashtable *)malloc(sizeof(struct hashtable));
+ if (NULL == h) return NULL; /*oom*/
+ h->table = (struct entry **)malloc(sizeof(struct entry*) * size);
+ if (NULL == h->table) { free(h); return NULL; } /*oom*/
+ memset(h->table, 0, size * sizeof(struct entry *));
+ h->tablelength = size;
+ h->primeindex = pindex;
+ h->entrycount = 0;
+ h->hashfn = hashf;
+ h->eqfn = eqf;
+ h->loadlimit = (unsigned int) ceil(size * max_load_factor);
+#ifdef HASHTABLE_THREADED
+ pthread_mutex_init(&h->mutex, NULL);
+#endif
+ return h;
+}
+
+/*****************************************************************************/
+unsigned int
+hash(struct hashtable *h, void *k)
+{
+ unsigned int i = h->hashfn(k);
+ i += ~(i << 9);
+ i ^= ((i >> 14) | (i << 18)); /* >>> */
+ i += (i << 4);
+ i ^= ((i >> 10) | (i << 22)); /* >>> */
+ return i;
+}
+
+/*****************************************************************************/
+static int
+hashtable_expand(struct hashtable *h)
+{
+ /* Double the size of the table to accomodate more entries */
+ struct entry **newtable;
+ struct entry *e;
+ struct entry **pE;
+ unsigned int newsize, i, index;
+ /* Check we're not hitting max capacity */
+ if (h->primeindex == (prime_table_length - 1)) return 0;
+ newsize = primes[++(h->primeindex)];
+
+ newtable = (struct entry **)malloc(sizeof(struct entry*) * newsize);
+ if (NULL != newtable)
+ {
+ memset(newtable, 0, newsize * sizeof(struct entry *));
+ /* This algorithm is not 'stable'. ie. it reverses the list
+ * when it transfers entries between the tables */
+ for (i = 0; i < h->tablelength; i++) {
+ while (NULL != (e = h->table[i])) {
+ h->table[i] = e->next;
+ index = indexFor(newsize,e->h);
+ e->next = newtable[index];
+ newtable[index] = e;
+ }
+ }
+ free(h->table);
+ h->table = newtable;
+ }
+ /* Plan B: realloc instead */
+ else
+ {
+ newtable = (struct entry **)
+ realloc(h->table, newsize * sizeof(struct entry *));
+ if (NULL == newtable) { (h->primeindex)--; return 0; }
+ h->table = newtable;
+ memset(newtable[h->tablelength], 0, newsize - h->tablelength);
+ for (i = 0; i < h->tablelength; i++) {
+ for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {
+ index = indexFor(newsize,e->h);
+ if (index == i)
+ {
+ pE = &(e->next);
+ }
+ else
+ {
+ *pE = e->next;
+ e->next = newtable[index];
+ newtable[index] = e;
+ }
+ }
+ }
+ }
+ h->tablelength = newsize;
+ h->loadlimit = (unsigned int) ceil(newsize * max_load_factor);
+ return -1;
+}
+
+/*****************************************************************************/
+unsigned int
+hashtable_count(struct hashtable *h)
+{
+ unsigned int count;
+#ifdef HASHTABLE_THREADED
+ pthread_mutex_lock(&h->mutex);
+#endif
+ count = h->entrycount;
+#ifdef HASHTABLE_THREADED
+ pthread_mutex_unlock(&h->mutex);
+#endif
+ return count;
+}
+
+/*****************************************************************************/
+int
+hashtable_insert(struct hashtable *h, void *k, void *v)
+{
+ /* This method allows duplicate keys - but they shouldn't be used */
+ unsigned int index;
+ struct entry *e;
+#ifdef HASHTABLE_THREADED
+ pthread_mutex_lock(&h->mutex);
+#endif
+ if (++(h->entrycount) > h->loadlimit)
+ {
+ /* Ignore the return value. If expand fails, we should
+ * still try cramming just this value into the existing table
+ * -- we may not have memory for a larger table, but one more
+ * element may be ok. Next time we insert, we'll try expanding again.*/
+ hashtable_expand(h);
+ }
+ e = (struct entry *)malloc(sizeof(struct entry));
+ if (NULL == e) { --(h->entrycount); return 0; } /*oom*/
+ e->h = hash(h,k);
+ index = indexFor(h->tablelength,e->h);
+ e->k = k;
+ e->v = v;
+ e->next = h->table[index];
+ h->table[index] = e;
+#ifdef HASHTABLE_THREADED
+ pthread_mutex_unlock(&h->mutex);
+#endif
+ return -1;
+}
+
+/*****************************************************************************/
+void * /* returns value associated with key */
+hashtable_search(struct hashtable *h, void *k)
+{
+#ifdef HASHTABLE_THREADED
+ pthread_mutex_lock(&h->mutex);
+#endif
+ struct entry *e;
+ unsigned int hashvalue, index;
+ hashvalue = hash(h,k);
+ index = indexFor(h->tablelength,hashvalue);
+ e = h->table[index];
+ while (NULL != e)
+ {
+ /* Check hash value to short circuit heavier comparison */
+ if ((hashvalue == e->h) && (h->eqfn(k, e->k))) {
+#ifdef HASHTABLE_THREADED
+ pthread_mutex_unlock(&h->mutex);
+#endif
+ return e->v;
+ }
+ e = e->next;
+ }
+#ifdef HASHTABLE_THREADED
+ pthread_mutex_unlock(&h->mutex);
+#endif
+ return NULL;
+}
+
+/*****************************************************************************/
+void * /* returns value associated with key */
+hashtable_remove(struct hashtable *h, void *k)
+{
+ /* TODO: consider compacting the table when the load factor drops enough,
+ * or provide a 'compact' method. */
+#ifdef HASHTABLE_THREADED
+ pthread_mutex_lock(&h->mutex);
+#endif
+ struct entry *e;
+ struct entry **pE;
+ void *v;
+ unsigned int hashvalue, index;
+
+ hashvalue = hash(h,k);
+ index = indexFor(h->tablelength,hash(h,k));
+ pE = &(h->table[index]);
+ e = *pE;
+ while (NULL != e)
+ {
+ /* Check hash value to short circuit heavier comparison */
+ if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
+ {
+ *pE = e->next;
+ h->entrycount--;
+ v = e->v;
+ freekey(e->k);
+ free(e);
+ return v;
+ }
+ pE = &(e->next);
+ e = e->next;
+ }
+#ifdef HASHTABLE_THREADED
+ pthread_mutex_unlock(&h->mutex);
+#endif
+ return NULL;
+}
+
+/*****************************************************************************/
+/* destroy */
+void
+hashtable_destroy(struct hashtable *h, int free_values)
+{
+#ifdef HASHTABLE_THREADED
+ pthread_mutex_lock(&h->mutex);
+#endif
+ unsigned int i;
+ struct entry *e, *f;
+ struct entry **table = h->table;
+ if (free_values)
+ {
+ for (i = 0; i < h->tablelength; i++)
+ {
+ e = table[i];
+ while (NULL != e)
+ { f = e; e = e->next; freekey(f->k); free(f->v); free(f); }
+ }
+ }
+ else
+ {
+ for (i = 0; i < h->tablelength; i++)
+ {
+ e = table[i];
+ while (NULL != e)
+ { f = e; e = e->next; freekey(f->k); free(f); }
+ }
+ }
+ free(h->table);
+#ifdef HASHTABLE_THREADED
+ pthread_mutex_destroy(&h->mutex);
+#endif
+ free(h);
+}
diff -r edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/util/hashtable.h
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/util/hashtable.h Tue Aug 30 19:39:25 2005
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2005, Intel Corp
+ * Copyright (c) 2002, Christopher Clark <firstname.lastname@xxxxxxxxxxxx>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#ifndef __HASHTABLE_CWC22_H__
+#define __HASHTABLE_CWC22_H__
+
+struct hashtable;
+
+/* Example of use:
+ *
+ * struct hashtable *h;
+ * struct some_key *k;
+ * struct some_value *v;
+ *
+ * static unsigned int hash_from_key_fn( void *k );
+ * static int keys_equal_fn ( void *key1, void *key2 );
+ *
+ * h = create_hashtable(16, hash_from_key_fn, keys_equal_fn);
+ * k = (struct some_key *) malloc(sizeof(struct some_key));
+ * v = (struct some_value *) malloc(sizeof(struct some_value));
+ *
+ * (initialise k and v to suitable values)
+ *
+ * if (! hashtable_insert(h,k,v) )
+ * { exit(-1); }
+ *
+ * if (NULL == (found = hashtable_search(h,k) ))
+ * { printf("not found!"); }
+ *
+ * if (NULL == (found = hashtable_remove(h,k) ))
+ * { printf("Not found\n"); }
+ *
+ */
+
+/* Macros may be used to define type-safe(r) hashtable access functions, with
+ * methods specialized to take known key and value types as parameters.
+ *
+ * Example:
+ *
+ * Insert this at the start of your file:
+ *
+ * DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value);
+ * DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value);
+ * DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value);
+ *
+ * This defines the functions 'insert_some', 'search_some' and 'remove_some'.
+ * These operate just like hashtable_insert etc., with the same parameters,
+ * but their function signatures have 'struct some_key *' rather than
+ * 'void *', and hence can generate compile time errors if your program is
+ * supplying incorrect data as a key (and similarly for value).
+ *
+ * Note that the hash and key equality functions passed to create_hashtable
+ * still take 'void *' parameters instead of 'some key *'. This shouldn't be
+ * a difficult issue as they're only defined and passed once, and the other
+ * functions will ensure that only valid keys are supplied to them.
+ *
+ * The cost for this checking is increased code size and runtime overhead
+ * - if performance is important, it may be worth switching back to the
+ * unsafe methods once your program has been debugged with the safe methods.
+ * This just requires switching to some simple alternative defines - eg:
+ * #define insert_some hashtable_insert
+ *
+ */
+
+/*****************************************************************************
+ * create_hashtable
+
+ * @name create_hashtable
+ * @param minsize minimum initial size of hashtable
+ * @param hashfunction function for hashing keys
+ * @param key_eq_fn function for determining key equality
+ * @return newly created hashtable or NULL on failure
+ */
+
+struct hashtable *
+create_hashtable(unsigned int minsize,
+ unsigned int (*hashfunction) (void*),
+ int (*key_eq_fn) (void*,void*));
+
+/*****************************************************************************
+ * hashtable_insert
+
+ * @name hashtable_insert
+ * @param h the hashtable to insert into
+ * @param k the key - hashtable claims ownership and will free on removal
+ * @param v the value - does not claim ownership
+ * @return non-zero for successful insertion
+ *
+ * This function will cause the table to expand if the insertion would take
+ * the ratio of entries to table size over the maximum load factor.
+ *
+ * This function does not check for repeated insertions with a duplicate key.
+ * The value returned when using a duplicate key is undefined -- when
+ * the hashtable changes size, the order of retrieval of duplicate key
+ * entries is reversed.
+ * If in doubt, remove before insert.
+ */
+
+int
+hashtable_insert(struct hashtable *h, void *k, void *v);
+
+#define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
+int fnname (struct hashtable *h, keytype *k, valuetype *v) \
+{ \
+ return hashtable_insert(h,k,v); \
+}
+
+/*****************************************************************************
+ * hashtable_search
+
+ * @name hashtable_search
+ * @param h the hashtable to search
+ * @param k the key to search for - does not claim ownership
+ * @return the value associated with the key, or NULL if none found
+ */
+
+void *
+hashtable_search(struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
+valuetype * fnname (struct hashtable *h, keytype *k) \
+{ \
+ return (valuetype *) (hashtable_search(h,k)); \
+}
+
+/*****************************************************************************
+ * hashtable_remove
+
+ * @name hashtable_remove
+ * @param h the hashtable to remove the item from
+ * @param k the key to search for - does not claim ownership
+ * @return the value associated with the key, or NULL if none found
+ */
+
+void * /* returns value */
+hashtable_remove(struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
+valuetype * fnname (struct hashtable *h, keytype *k) \
+{ \
+ return (valuetype *) (hashtable_remove(h,k)); \
+}
+
+
+/*****************************************************************************
+ * hashtable_count
+
+ * @name hashtable_count
+ * @param h the hashtable
+ * @return the number of items stored in the hashtable
+ */
+unsigned int
+hashtable_count(struct hashtable *h);
+
+
+/*****************************************************************************
+ * hashtable_destroy
+
+ * @name hashtable_destroy
+ * @param h the hashtable
+ * @param free_values whether to call 'free' on the remaining values
+ */
+
+void
+hashtable_destroy(struct hashtable *h, int free_values);
+
+#endif /* __HASHTABLE_CWC22_H__ */
diff -r edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/util/hashtable_itr.c
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/util/hashtable_itr.c Tue Aug 30 19:39:25 2005
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2005, Intel Corp
+ * Copyright (c) 2002, Christopher Clark <firstname.lastname@xxxxxxxxxxxx>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "hashtable.h"
+#include "hashtable_private.h"
+#include "hashtable_itr.h"
+#include <stdlib.h> /* defines NULL */
+
+/*****************************************************************************/
+/* hashtable_iterator - iterator constructor */
+
+struct hashtable_itr *
+hashtable_iterator(struct hashtable *h)
+{
+ unsigned int i, tablelength;
+ struct hashtable_itr *itr = (struct hashtable_itr *)
+ malloc(sizeof(struct hashtable_itr));
+ if (NULL == itr) return NULL;
+#ifdef HASHTABLE_THREADED
+ pthread_mutex_lock(&h->mutex);
+#endif
+ itr->h = h;
+ itr->e = NULL;
+ itr->parent = NULL;
+ tablelength = h->tablelength;
+ itr->index = tablelength;
+ if (0 == h->entrycount) {
+#ifdef HASHTABLE_THREADED
+ pthread_mutex_unlock(&h->mutex);
+#endif
+ return itr;
+ }
+
+ for (i = 0; i < tablelength; i++)
+ {
+ if (NULL != h->table[i])
+ {
+ itr->e = h->table[i];
+ itr->index = i;
+ break;
+ }
+ }
+#ifdef HASHTABLE_THREADED
+ pthread_mutex_unlock(&h->mutex);
+#endif
+ return itr;
+}
+
+/*****************************************************************************/
+/* key - return the key of the (key,value) pair at the current position */
+/* value - return the value of the (key,value) pair at the current position
*/
+
+void *
+hashtable_iterator_key(struct hashtable_itr *i)
+{ return i->e->k; }
+
+void *
+hashtable_iterator_value(struct hashtable_itr *i)
+{ return i->e->v; }
+
+/*****************************************************************************/
+/* advance - advance the iterator to the next element
+ * returns zero if advanced to end of table */
+
+int
+hashtable_iterator_advance(struct hashtable_itr *itr)
+{
+#ifdef HASHTABLE_THREADED
+ pthread_mutex_lock(&itr->h->mutex);
+#endif
+ unsigned int j,tablelength;
+ struct entry **table;
+ struct entry *next;
+ int ret;
+ if (NULL == itr->e) { /* stupidity check */
+ ret = 0;
+ goto egress;
+ }
+
+ next = itr->e->next;
+ if (NULL != next)
+ {
+ itr->parent = itr->e;
+ itr->e = next;
+ ret = -1;
+ goto egress;
+ }
+
+ tablelength = itr->h->tablelength;
+ itr->parent = NULL;
+ if (tablelength <= (j = ++(itr->index)))
+ {
+ itr->e = NULL;
+ ret = 0;
+ goto egress;
+ }
+ table = itr->h->table;
+ while (NULL == (next = table[j]))
+ {
+ if (++j >= tablelength)
+ {
+ itr->index = tablelength;
+ itr->e = NULL;
+ ret = 0;
+ goto egress;
+ }
+ }
+ itr->index = j;
+ itr->e = next;
+ ret = -1;
+
+ egress:
+#ifdef HASHTABLE_THREADED
+ pthread_mutex_unlock(&itr->h->mutex);
+#endif
+ return ret;
+}
+
+/*****************************************************************************/
+/* remove - remove the entry at the current iterator position
+ * and advance the iterator, if there is a successive
+ * element.
+ * If you want the value, read it before you remove:
+ * beware memory leaks if you don't.
+ * Returns zero if end of iteration. */
+
+int
+hashtable_iterator_remove(struct hashtable_itr *itr)
+{
+#ifdef HASHTABLE_THREADED
+ pthread_mutex_lock(&itr->h->mutex);
+#endif
+ struct entry *remember_e, *remember_parent;
+ int ret;
+
+ /* Do the removal */
+ if (NULL == (itr->parent))
+ {
+ /* element is head of a chain */
+ itr->h->table[itr->index] = itr->e->next;
+ } else {
+ /* element is mid-chain */
+ itr->parent->next = itr->e->next;
+ }
+ /* itr->e is now outside the hashtable */
+ remember_e = itr->e;
+ itr->h->entrycount--;
+ freekey(remember_e->k);
+
+ /* Advance the iterator, correcting the parent */
+ remember_parent = itr->parent;
+ ret = hashtable_iterator_advance(itr);
+ if (itr->parent == remember_e) { itr->parent = remember_parent; }
+ free(remember_e);
+#ifdef HASHTABLE_THREADED
+ pthread_mutex_unlock(&itr->h->mutex);
+#endif
+ return ret;
+}
+
+/*****************************************************************************/
+int /* returns zero if not found */
+hashtable_iterator_search(struct hashtable_itr *itr,
+ struct hashtable *h, void *k)
+{
+#ifdef HASHTABLE_THREADED
+ pthread_mutex_lock(&h->mutex);
+#endif
+ struct entry *e, *parent;
+ unsigned int hashvalue, index;
+ int ret;
+
+ hashvalue = hash(h,k);
+ index = indexFor(h->tablelength,hashvalue);
+
+ e = h->table[index];
+ parent = NULL;
+ while (NULL != e)
+ {
+ /* Check hash value to short circuit heavier comparison */
+ if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
+ {
+ itr->index = index;
+ itr->e = e;
+ itr->parent = parent;
+ itr->h = h;
+ ret= -1;
+ goto egress;
+ }
+ parent = e;
+ e = e->next;
+ }
+ ret = 0;
+
+egress:
+#ifdef HASHTABLE_THREADED
+ pthread_mutex_lock(&h->mutex);
+#endif
+ return ret;
+}
diff -r edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/util/hashtable_itr.h
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/util/hashtable_itr.h Tue Aug 30 19:39:25 2005
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2005, Intel Corp
+ * Copyright (c) 2002, Christopher Clark <firstname.lastname@xxxxxxxxxxxx>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#ifndef __HASHTABLE_ITR_CWC22__
+#define __HASHTABLE_ITR_CWC22__
+#include "hashtable.h"
+#include "hashtable_private.h" /* needed to enable inlining */
+
+/*****************************************************************************/
+/* This struct is only concrete here to allow the inlining of two of the
+ * accessor functions. */
+struct hashtable_itr
+{
+ struct hashtable *h;
+ struct entry *e;
+ struct entry *parent;
+ unsigned int index;
+};
+
+
+/*****************************************************************************/
+/* hashtable_iterator
+ */
+
+struct hashtable_itr *
+hashtable_iterator(struct hashtable *h);
+
+/*****************************************************************************/
+/* hashtable_iterator_key
+ * - return the value of the (key,value) pair at the current position */
+
+void *hashtable_iterator_key(struct hashtable_itr *i);
+
+/*****************************************************************************/
+/* value - return the value of the (key,value) pair at the current position */
+
+void *hashtable_iterator_value(struct hashtable_itr *i);
+
+/*****************************************************************************/
+/* advance - advance the iterator to the next element
+ * returns zero if advanced to end of table */
+
+int
+hashtable_iterator_advance(struct hashtable_itr *itr);
+
+/*****************************************************************************/
+/* remove - remove current element and advance the iterator to the next element
+ * NB: if you need the value to free it, read it before
+ * removing. ie: beware memory leaks!
+ * returns zero if advanced to end of table */
+
+int
+hashtable_iterator_remove(struct hashtable_itr *itr);
+
+/*****************************************************************************/
+/* search - overwrite the supplied iterator, to point to the entry
+ * matching the supplied key.
+ h points to the hashtable to be searched.
+ * returns zero if not found. */
+int
+hashtable_iterator_search(struct hashtable_itr *itr,
+ struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_ITERATOR_SEARCH(fnname, keytype) \
+int fnname (struct hashtable_itr *i, struct hashtable *h, keytype *k) \
+{ \
+ return (hashtable_iterator_search(i,h,k)); \
+}
+
+
+
+#endif /* __HASHTABLE_ITR_CWC22__*/
diff -r edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/util/hashtable_private.h
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/util/hashtable_private.h Tue Aug 30 19:39:25 2005
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2005, Intel Corp
+ * Copyright (c) 2002, Christopher Clark <firstname.lastname@xxxxxxxxxxxx>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __HASHTABLE_PRIVATE_CWC22_H__
+#define __HASHTABLE_PRIVATE_CWC22_H__
+
+#include "hashtable.h"
+#ifdef HASHTABLE_THREADED
+#include <pthread.h>
+#endif
+
+/*****************************************************************************/
+struct entry
+{
+ void *k, *v;
+ unsigned int h;
+ struct entry *next;
+};
+
+struct hashtable {
+ unsigned int tablelength;
+ struct entry **table;
+ unsigned int entrycount;
+ unsigned int loadlimit;
+ unsigned int primeindex;
+ unsigned int (*hashfn) (void *k);
+ int (*eqfn) (void *k1, void *k2);
+#ifdef HASHTABLE_THREADED
+ pthread_mutex_t mutex;
+#endif
+};
+
+/*****************************************************************************/
+unsigned int
+hash(struct hashtable *h, void *k);
+
+/*****************************************************************************/
+/* indexFor */
+static inline unsigned int
+indexFor(unsigned int tablelength, unsigned int hashvalue) {
+ return (hashvalue % tablelength);
+};
+
+/* Only works if tablelength == 2^N */
+/*static inline unsigned int
+indexFor(unsigned int tablelength, unsigned int hashvalue)
+{
+ return (hashvalue & (tablelength - 1u));
+}
+*/
+
+/*****************************************************************************/
+#define freekey(X) free(X)
+/*define freekey(X) ; */
+
+
+/*****************************************************************************/
+
+#endif /* __HASHTABLE_PRIVATE_CWC22_H__*/
diff -r edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/util/log.c
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/util/log.c Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/util/log.h
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/util/log.h Tue Aug 30 19:39:25 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 edbdd7123d24 -r 9ba52ccadc06 tools/vtpm_manager/util/tcg.h
--- /dev/null Tue Aug 30 19:28:26 2005
+++ b/tools/vtpm_manager/util/tcg.h Tue Aug 30 19:39:25 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__
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|