[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] vTPM manager - Intel/IBM joint TPM Virtualization implementation for Xen.
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |