xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Matthew Fioravante <matthew.fioravante@jhuapl.edu>
To: "xen-devel@lists.xen.org" <xen-devel@lists.xen.org>,
	"Ian.Campbell@citrix.com" <Ian.Campbell@citrix.com>
Subject: Re: [PATCH VTPM v4 2/5] add stubdom/vtpmmgr code
Date: Tue, 20 Nov 2012 09:25:19 -0500	[thread overview]
Message-ID: <50AB92CF.8040306@jhuapl.edu> (raw)
In-Reply-To: <1353421272-24797-2-git-send-email-matthew.fioravante@jhuapl.edu>


[-- Attachment #1.1: Type: text/plain, Size: 186865 bytes --]

Please be sure to grab this updated version. I fixed an important 
comment about the disk image format that was out of date.

On 11/20/2012 09:21 AM, Matthew Fioravante wrote:
> Add the code base for vtpmmgrdom. Makefile changes
> next patch.
>
> Signed-off-by: Matthew Fioravante <matthew.fioravante@jhuapl.edu>
> Acked-by: Ian Campbell <ian.campbell@citrix.com>
> ---
>   stubdom/vtpmmgr/Makefile           |   32 ++
>   stubdom/vtpmmgr/init.c             |  553 +++++++++++++++++++++
>   stubdom/vtpmmgr/log.c              |  151 ++++++
>   stubdom/vtpmmgr/log.h              |   85 ++++
>   stubdom/vtpmmgr/marshal.h          |  528 ++++++++++++++++++++
>   stubdom/vtpmmgr/minios.cfg         |   14 +
>   stubdom/vtpmmgr/tcg.h              |  707 +++++++++++++++++++++++++++
>   stubdom/vtpmmgr/tpm.c              |  938 ++++++++++++++++++++++++++++++++++++
>   stubdom/vtpmmgr/tpm.h              |  218 +++++++++
>   stubdom/vtpmmgr/tpmrsa.c           |  175 +++++++
>   stubdom/vtpmmgr/tpmrsa.h           |   67 +++
>   stubdom/vtpmmgr/uuid.h             |   50 ++
>   stubdom/vtpmmgr/vtpm_cmd_handler.c |  152 ++++++
>   stubdom/vtpmmgr/vtpm_manager.h     |   64 +++
>   stubdom/vtpmmgr/vtpm_storage.c     |  794 ++++++++++++++++++++++++++++++
>   stubdom/vtpmmgr/vtpm_storage.h     |   68 +++
>   stubdom/vtpmmgr/vtpmmgr.c          |   93 ++++
>   stubdom/vtpmmgr/vtpmmgr.h          |   77 +++
>   18 files changed, 4766 insertions(+)
>   create mode 100644 stubdom/vtpmmgr/Makefile
>   create mode 100644 stubdom/vtpmmgr/init.c
>   create mode 100644 stubdom/vtpmmgr/log.c
>   create mode 100644 stubdom/vtpmmgr/log.h
>   create mode 100644 stubdom/vtpmmgr/marshal.h
>   create mode 100644 stubdom/vtpmmgr/minios.cfg
>   create mode 100644 stubdom/vtpmmgr/tcg.h
>   create mode 100644 stubdom/vtpmmgr/tpm.c
>   create mode 100644 stubdom/vtpmmgr/tpm.h
>   create mode 100644 stubdom/vtpmmgr/tpmrsa.c
>   create mode 100644 stubdom/vtpmmgr/tpmrsa.h
>   create mode 100644 stubdom/vtpmmgr/uuid.h
>   create mode 100644 stubdom/vtpmmgr/vtpm_cmd_handler.c
>   create mode 100644 stubdom/vtpmmgr/vtpm_manager.h
>   create mode 100644 stubdom/vtpmmgr/vtpm_storage.c
>   create mode 100644 stubdom/vtpmmgr/vtpm_storage.h
>   create mode 100644 stubdom/vtpmmgr/vtpmmgr.c
>   create mode 100644 stubdom/vtpmmgr/vtpmmgr.h
>
> diff --git a/stubdom/vtpmmgr/Makefile b/stubdom/vtpmmgr/Makefile
> new file mode 100644
> index 0000000..88c83c3
> --- /dev/null
> +++ b/stubdom/vtpmmgr/Makefile
> @@ -0,0 +1,32 @@
> +# Copyright (c) 2010-2012 United States Government, as represented by
> +# the Secretary of Defense.  All rights reserved.
> +#
> +# THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
> +# ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
> +# INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
> +# FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
> +# DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
> +# SOFTWARE.
> +#
> +
> +XEN_ROOT=../..
> +
> +PSSL_DIR=../polarssl-$(XEN_TARGET_ARCH)/library
> +PSSL_OBJS=aes.o sha1.o entropy.o ctr_drbg.o bignum.o sha4.o havege.o timing.o entropy_poll.o
> +
> +TARGET=vtpmmgr.a
> +OBJS=vtpmmgr.o vtpm_cmd_handler.o vtpm_storage.o init.o tpmrsa.o tpm.o log.o
> +
> +CFLAGS+=-Werror -Iutil -Icrypto -Itcs
> +CFLAGS+=-Wno-declaration-after-statement -Wno-unused-label
> +
> +build: $(TARGET)
> +$(TARGET): $(OBJS)
> +       ar -rcs $@ $^ $(foreach obj,$(PSSL_OBJS),$(PSSL_DIR)/$(obj))
> +
> +clean:
> +       rm -f $(TARGET) $(OBJS)
> +
> +distclean: clean
> +
> +.PHONY: clean distclean
> diff --git a/stubdom/vtpmmgr/init.c b/stubdom/vtpmmgr/init.c
> new file mode 100644
> index 0000000..a158020
> --- /dev/null
> +++ b/stubdom/vtpmmgr/init.c
> @@ -0,0 +1,553 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * based off of the original tools/vtpm_manager code base which is:
> + * 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 <stdint.h>
> +#include <stdlib.h>
> +
> +#include <xen/xen.h>
> +#include <mini-os/tpmback.h>
> +#include <mini-os/tpmfront.h>
> +#include <mini-os/tpm_tis.h>
> +#include <unistd.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <stdlib.h>
> +#include <polarssl/sha1.h>
> +
> +#include "log.h"
> +#include "vtpmmgr.h"
> +#include "vtpm_storage.h"
> +#include "tpm.h"
> +#include "marshal.h"
> +
> +struct Opts {
> +   enum {
> +      TPMDRV_TPM_TIS,
> +      TPMDRV_TPMFRONT,
> +   } tpmdriver;
> +   unsigned long tpmiomem;
> +   unsigned int tpmirq;
> +   unsigned int tpmlocality;
> +   int gen_owner_auth;
> +};
> +
> +// --------------------------- Well Known Auths --------------------------
> +const TPM_AUTHDATA WELLKNOWN_SRK_AUTH = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
> +
> +const TPM_AUTHDATA WELLKNOWN_OWNER_AUTH = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
> +
> +struct vtpm_globals vtpm_globals = {
> +   .tpm_fd = -1,
> +   .storage_key = TPM_KEY_INIT,
> +   .storage_key_handle = 0,
> +   .oiap = { .AuthHandle = 0 }
> +};
> +
> +static int tpm_entropy_source(void* dummy, unsigned char* data, size_t len, size_t* olen) {
> +   UINT32 sz = len;
> +   TPM_RESULT rc = TPM_GetRandom(&sz, data);
> +   *olen = sz;
> +   return rc == TPM_SUCCESS ? 0 : POLARSSL_ERR_ENTROPY_SOURCE_FAILED;
> +}
> +
> +static TPM_RESULT check_tpm_version(void) {
> +   TPM_RESULT status;
> +   UINT32 rsize;
> +   BYTE* res = NULL;
> +   TPM_CAP_VERSION_INFO vinfo;
> +
> +   TPMTRYRETURN(TPM_GetCapability(
> +            TPM_CAP_VERSION_VAL,
> +            0,
> +            NULL,
> +            &rsize,
> +            &res));
> +   if(rsize < 4) {
> +      vtpmlogerror(VTPM_LOG_VTPM, "Invalid size returned by GetCapability!\n");
> +      status = TPM_BAD_PARAMETER;
> +      goto abort_egress;
> +   }
> +
> +   unpack_TPM_CAP_VERSION_INFO(res, &vinfo, UNPACK_ALIAS);
> +
> +   vtpmloginfo(VTPM_LOG_VTPM, "Hardware TPM:\n");
> +   vtpmloginfo(VTPM_LOG_VTPM, " version: %hhd %hhd %hhd %hhd\n",
> +         vinfo.version.major, vinfo.version.minor, vinfo.version.revMajor, vinfo.version.revMinor);
> +   vtpmloginfo(VTPM_LOG_VTPM, " specLevel: %hd\n", vinfo.specLevel);
> +   vtpmloginfo(VTPM_LOG_VTPM, " errataRev: %hhd\n", vinfo.errataRev);
> +   vtpmloginfo(VTPM_LOG_VTPM, " vendorID: %c%c%c%c\n",
> +         vinfo.tpmVendorID[0], vinfo.tpmVendorID[1],
> +         vinfo.tpmVendorID[2], vinfo.tpmVendorID[3]);
> +   vtpmloginfo(VTPM_LOG_VTPM, " vendorSpecificSize: %hd\n", vinfo.vendorSpecificSize);
> +   vtpmloginfo(VTPM_LOG_VTPM, " vendorSpecific: ");
> +   for(int i = 0; i < vinfo.vendorSpecificSize; ++i) {
> +      vtpmloginfomore(VTPM_LOG_VTPM, "%02hhx", vinfo.vendorSpecific[i]);
> +   }
> +   vtpmloginfomore(VTPM_LOG_VTPM, "\n");
> +
> +abort_egress:
> +   free(res);
> +   return status;
> +}
> +
> +static TPM_RESULT flush_tpm(void) {
> +   TPM_RESULT status = TPM_SUCCESS;
> +   const TPM_RESOURCE_TYPE reslist[] = { TPM_RT_KEY, TPM_RT_AUTH, TPM_RT_TRANS, TPM_RT_COUNTER, TPM_RT_DAA_TPM, TPM_RT_CONTEXT };
> +   BYTE* keylist = NULL;
> +   UINT32 keylistSize;
> +   BYTE* ptr;
> +
> +   //Iterate through each resource type and flush all handles
> +   for(int i = 0; i < sizeof(reslist) / sizeof(TPM_RESOURCE_TYPE); ++i) {
> +      TPM_RESOURCE_TYPE beres = cpu_to_be32(reslist[i]);
> +      UINT16 size;
> +      TPMTRYRETURN(TPM_GetCapability(
> +               TPM_CAP_HANDLE,
> +               sizeof(TPM_RESOURCE_TYPE),
> +               (BYTE*)(&beres),
> +               &keylistSize,
> +               &keylist));
> +
> +      ptr = keylist;
> +      ptr = unpack_UINT16(ptr, &size);
> +
> +      //Flush each handle
> +      if(size) {
> +         vtpmloginfo(VTPM_LOG_VTPM, "Flushing %u handle(s) of type %lu\n", size, (unsigned long) reslist[i]);
> +         for(int j = 0; j < size; ++j) {
> +            TPM_HANDLE h;
> +            ptr = unpack_TPM_HANDLE(ptr, &h);
> +            TPMTRYRETURN(TPM_FlushSpecific(h, reslist[i]));
> +         }
> +      }
> +
> +      free(keylist);
> +      keylist = NULL;
> +   }
> +
> +   goto egress;
> +abort_egress:
> +   free(keylist);
> +egress:
> +   return status;
> +}
> +
> +
> +static TPM_RESULT try_take_ownership(void) {
> +   TPM_RESULT status = TPM_SUCCESS;
> +   TPM_PUBKEY pubEK = TPM_PUBKEY_INIT;
> +
> +   // If we can read PubEK then there is no owner and we should take it.
> +   status = TPM_ReadPubek(&pubEK);
> +
> +   switch(status) {
> +      case TPM_DISABLED_CMD:
> +         //Cannot read ek? TPM has owner
> +         vtpmloginfo(VTPM_LOG_VTPM, "Failed to readEK meaning TPM has an owner. Creating Keys off existing SRK.\n");
> +         status = TPM_SUCCESS;
> +         break;
> +      case TPM_NO_ENDORSEMENT:
> +         {
> +            //If theres no ek, we have to create one
> +            TPM_KEY_PARMS keyInfo = {
> +               .algorithmID = TPM_ALG_RSA,
> +               .encScheme = TPM_ES_RSAESOAEP_SHA1_MGF1,
> +               .sigScheme = TPM_SS_NONE,
> +               .parmSize = 12,
> +               .parms.rsa = {
> +                  .keyLength = RSA_KEY_SIZE,
> +                  .numPrimes = 2,
> +                  .exponentSize = 0,
> +                  .exponent = NULL,
> +               },
> +            };
> +            TPMTRYRETURN(TPM_CreateEndorsementKeyPair(&keyInfo, &pubEK));
> +         }
> +         //fall through to take ownership
> +      case TPM_SUCCESS:
> +         {
> +            //Construct the Srk
> +            TPM_KEY srk = {
> +               .ver = TPM_STRUCT_VER_1_1,
> +               .keyUsage = TPM_KEY_STORAGE,
> +               .keyFlags = 0x00,
> +               .authDataUsage = TPM_AUTH_ALWAYS,
> +               .algorithmParms = {
> +                  .algorithmID = TPM_ALG_RSA,
> +                  .encScheme = TPM_ES_RSAESOAEP_SHA1_MGF1,
> +                  .sigScheme =  TPM_SS_NONE,
> +                  .parmSize = 12,
> +                  .parms.rsa = {
> +                     .keyLength = RSA_KEY_SIZE,
> +                     .numPrimes = 2,
> +                     .exponentSize = 0,
> +                     .exponent = NULL,
> +                  },
> +               },
> +               .PCRInfoSize = 0,
> +               .pubKey = {
> +                  .keyLength = 0,
> +                  .key = NULL,
> +               },
> +               .encDataSize = 0,
> +            };
> +
> +            TPMTRYRETURN(TPM_TakeOwnership(
> +                     &pubEK,
> +                     (const TPM_AUTHDATA*)&vtpm_globals.owner_auth,
> +                     (const TPM_AUTHDATA*)&vtpm_globals.srk_auth,
> +                     &srk,
> +                     NULL,
> +                     &vtpm_globals.oiap));
> +
> +            TPMTRYRETURN(TPM_DisablePubekRead(
> +                     (const TPM_AUTHDATA*)&vtpm_globals.owner_auth,
> +                     &vtpm_globals.oiap));
> +         }
> +         break;
> +      default:
> +         break;
> +   }
> +abort_egress:
> +   free_TPM_PUBKEY(&pubEK);
> +   return status;
> +}
> +
> +static void init_storage_key(TPM_KEY* key) {
> +   key->ver.major = 1;
> +   key->ver.minor = 1;
> +   key->ver.revMajor = 0;
> +   key->ver.revMinor = 0;
> +
> +   key->keyUsage = TPM_KEY_BIND;
> +   key->keyFlags = 0;
> +   key->authDataUsage = TPM_AUTH_ALWAYS;
> +
> +   TPM_KEY_PARMS* p = &key->algorithmParms;
> +   p->algorithmID = TPM_ALG_RSA;
> +   p->encScheme = TPM_ES_RSAESOAEP_SHA1_MGF1;
> +   p->sigScheme = TPM_SS_NONE;
> +   p->parmSize = 12;
> +
> +   TPM_RSA_KEY_PARMS* r = &p->parms.rsa;
> +   r->keyLength = RSA_KEY_SIZE;
> +   r->numPrimes = 2;
> +   r->exponentSize = 0;
> +   r->exponent = NULL;
> +
> +   key->PCRInfoSize = 0;
> +   key->encDataSize = 0;
> +   key->encData = NULL;
> +}
> +
> +static int parse_auth_string(char* authstr, BYTE* target, const TPM_AUTHDATA wellknown, int allowrandom) {
> +   int rc;
> +   /* well known owner auth */
> +   if(!strcmp(authstr, "well-known")) {
> +      memcpy(target, wellknown, sizeof(TPM_AUTHDATA));
> +   }
> +   /* Create a randomly generated owner auth */
> +   else if(allowrandom && !strcmp(authstr, "random")) {
> +      return 1;
> +   }
> +   /* owner auth is a raw hash */
> +   else if(!strncmp(authstr, "hash:", 5)) {
> +      authstr += 5;
> +      if((rc = strlen(authstr)) != 40) {
> +         vtpmlogerror(VTPM_LOG_VTPM, "Supplied owner auth hex string `%s' must be exactly 40 characters (20 bytes) long, length=%d\n", authstr, rc);
> +         return -1;
> +      }
> +      for(int j = 0; j < 20; ++j) {
> +         if(sscanf(authstr, "%hhX", target + j) != 1) {
> +            vtpmlogerror(VTPM_LOG_VTPM, "Supplied owner auth string `%s' is not a valid hex string\n", authstr);
> +            return -1;
> +         }
> +         authstr += 2;
> +      }
> +   }
> +   /* owner auth is a string that will be hashed */
> +   else if(!strncmp(authstr, "text:", 5)) {
> +      authstr += 5;
> +      sha1((const unsigned char*)authstr, strlen(authstr), target);
> +   }
> +   else {
> +      vtpmlogerror(VTPM_LOG_VTPM, "Invalid auth string %s\n", authstr);
> +      return -1;
> +   }
> +
> +   return 0;
> +}
> +
> +int parse_cmdline_opts(int argc, char** argv, struct Opts* opts)
> +{
> +   int rc;
> +   int i;
> +
> +   //Set defaults
> +   memcpy(vtpm_globals.owner_auth, WELLKNOWN_OWNER_AUTH, sizeof(TPM_AUTHDATA));
> +   memcpy(vtpm_globals.srk_auth, WELLKNOWN_SRK_AUTH, sizeof(TPM_AUTHDATA));
> +
> +   for(i = 1; i < argc; ++i) {
> +      if(!strncmp(argv[i], "owner_auth:", 10)) {
> +         if((rc = parse_auth_string(argv[i] + 10, vtpm_globals.owner_auth, WELLKNOWN_OWNER_AUTH, 1)) < 0) {
> +            goto err_invalid;
> +         }
> +         if(rc == 1) {
> +            opts->gen_owner_auth = 1;
> +         }
> +      }
> +      else if(!strncmp(argv[i], "srk_auth:", 8)) {
> +         if((rc = parse_auth_string(argv[i] + 8, vtpm_globals.srk_auth, WELLKNOWN_SRK_AUTH, 0)) != 0) {
> +            goto err_invalid;
> +         }
> +      }
> +      else if(!strncmp(argv[i], "tpmdriver=", 10)) {
> +         if(!strcmp(argv[i] + 10, "tpm_tis")) {
> +            opts->tpmdriver = TPMDRV_TPM_TIS;
> +         } else if(!strcmp(argv[i] + 10, "tpmfront")) {
> +            opts->tpmdriver = TPMDRV_TPMFRONT;
> +         } else {
> +            goto err_invalid;
> +         }
> +      }
> +      else if(!strncmp(argv[i], "tpmiomem=",9)) {
> +         if(sscanf(argv[i] + 9, "0x%lX", &opts->tpmiomem) != 1) {
> +            goto err_invalid;
> +         }
> +      }
> +      else if(!strncmp(argv[i], "tpmirq=",7)) {
> +         if(!strcmp(argv[i] + 7, "probe")) {
> +            opts->tpmirq = TPM_PROBE_IRQ;
> +         } else if( sscanf(argv[i] + 7, "%u", &opts->tpmirq) != 1) {
> +            goto err_invalid;
> +         }
> +      }
> +      else if(!strncmp(argv[i], "tpmlocality=",12)) {
> +         if(sscanf(argv[i] + 12, "%u", &opts->tpmlocality) != 1 || opts->tpmlocality > 4) {
> +            goto err_invalid;
> +         }
> +      }
> +   }
> +
> +   switch(opts->tpmdriver) {
> +      case TPMDRV_TPM_TIS:
> +         vtpmloginfo(VTPM_LOG_VTPM, "Option: Using tpm_tis driver\n");
> +         break;
> +      case TPMDRV_TPMFRONT:
> +         vtpmloginfo(VTPM_LOG_VTPM, "Option: Using tpmfront driver\n");
> +         break;
> +   }
> +
> +   return 0;
> +err_invalid:
> +   vtpmlogerror(VTPM_LOG_VTPM, "Invalid Option %s\n", argv[i]);
> +   return -1;
> +}
> +
> +
> +
> +static TPM_RESULT vtpmmgr_create(void) {
> +   TPM_RESULT status = TPM_SUCCESS;
> +   TPM_AUTH_SESSION osap = TPM_AUTH_SESSION_INIT;
> +   TPM_AUTHDATA sharedsecret;
> +
> +   // Take ownership if TPM is unowned
> +   TPMTRYRETURN(try_take_ownership());
> +
> +   // Generate storage key's auth
> +   memset(&vtpm_globals.storage_key_usage_auth, 0, sizeof(TPM_AUTHDATA));
> +
> +   TPMTRYRETURN( TPM_OSAP(
> +            TPM_ET_KEYHANDLE,
> +            TPM_SRK_KEYHANDLE,
> +            (const TPM_AUTHDATA*)&vtpm_globals.srk_auth,
> +            &sharedsecret,
> +            &osap) );
> +
> +   init_storage_key(&vtpm_globals.storage_key);
> +
> +   //initialize the storage key
> +   TPMTRYRETURN( TPM_CreateWrapKey(
> +            TPM_SRK_KEYHANDLE,
> +            (const TPM_AUTHDATA*)&sharedsecret,
> +            (const TPM_AUTHDATA*)&vtpm_globals.storage_key_usage_auth,
> +            (const TPM_AUTHDATA*)&vtpm_globals.storage_key_usage_auth,
> +            &vtpm_globals.storage_key,
> +            &osap) );
> +
> +   //Load Storage Key
> +   TPMTRYRETURN( TPM_LoadKey(
> +            TPM_SRK_KEYHANDLE,
> +            &vtpm_globals.storage_key,
> +            &vtpm_globals.storage_key_handle,
> +            (const TPM_AUTHDATA*) &vtpm_globals.srk_auth,
> +            &vtpm_globals.oiap));
> +
> +   //Make sure TPM has commited changes
> +   TPMTRYRETURN( TPM_SaveState() );
> +
> +   //Create new disk image
> +   TPMTRYRETURN(vtpm_storage_new_header());
> +
> +   goto egress;
> +abort_egress:
> +egress:
> +   vtpmloginfo(VTPM_LOG_VTPM, "Finished initialized new VTPM manager\n");
> +
> +   //End the OSAP session
> +   if(osap.AuthHandle) {
> +      TPM_TerminateHandle(osap.AuthHandle);
> +   }
> +
> +   return status;
> +}
> +
> +TPM_RESULT vtpmmgr_init(int argc, char** argv) {
> +   TPM_RESULT status = TPM_SUCCESS;
> +
> +   /* Default commandline options */
> +   struct Opts opts = {
> +      .tpmdriver = TPMDRV_TPM_TIS,
> +      .tpmiomem = TPM_BASEADDR,
> +      .tpmirq = 0,
> +      .tpmlocality = 0,
> +      .gen_owner_auth = 0,
> +   };
> +
> +   if(parse_cmdline_opts(argc, argv, &opts) != 0) {
> +      vtpmlogerror(VTPM_LOG_VTPM, "Command line parsing failed! exiting..\n");
> +      status = TPM_BAD_PARAMETER;
> +      goto abort_egress;
> +   }
> +
> +   //Setup storage system
> +   if(vtpm_storage_init() != 0) {
> +      vtpmlogerror(VTPM_LOG_VTPM, "Unable to initialize storage subsystem!\n");
> +      status = TPM_IOERROR;
> +      goto abort_egress;
> +   }
> +
> +   //Setup tpmback device
> +   init_tpmback();
> +
> +   //Setup tpm access
> +   switch(opts.tpmdriver) {
> +      case TPMDRV_TPM_TIS:
> +         {
> +            struct tpm_chip* tpm;
> +            if((tpm = init_tpm_tis(opts.tpmiomem, TPM_TIS_LOCL_INT_TO_FLAG(opts.tpmlocality), opts.tpmirq)) == NULL) {
> +               vtpmlogerror(VTPM_LOG_VTPM, "Unable to initialize tpmfront device\n");
> +               status = TPM_IOERROR;
> +               goto abort_egress;
> +            }
> +            vtpm_globals.tpm_fd = tpm_tis_open(tpm);
> +            tpm_tis_request_locality(tpm, opts.tpmlocality);
> +         }
> +         break;
> +      case TPMDRV_TPMFRONT:
> +         {
> +            struct tpmfront_dev* tpmfront_dev;
> +            if((tpmfront_dev = init_tpmfront(NULL)) == NULL) {
> +               vtpmlogerror(VTPM_LOG_VTPM, "Unable to initialize tpmfront device\n");
> +               status = TPM_IOERROR;
> +               goto abort_egress;
> +            }
> +            vtpm_globals.tpm_fd = tpmfront_open(tpmfront_dev);
> +         }
> +         break;
> +   }
> +
> +   //Get the version of the tpm
> +   TPMTRYRETURN(check_tpm_version());
> +
> +   // Blow away all stale handles left in the tpm
> +   if(flush_tpm() != TPM_SUCCESS) {
> +      vtpmlogerror(VTPM_LOG_VTPM, "VTPM_FlushResources failed, continuing anyway..\n");
> +   }
> +
> +   /* Initialize the rng */
> +   entropy_init(&vtpm_globals.entropy);
> +   entropy_add_source(&vtpm_globals.entropy, tpm_entropy_source, NULL, 0);
> +   entropy_gather(&vtpm_globals.entropy);
> +   ctr_drbg_init(&vtpm_globals.ctr_drbg, entropy_func, &vtpm_globals.entropy, NULL, 0);
> +   ctr_drbg_set_prediction_resistance( &vtpm_globals.ctr_drbg, CTR_DRBG_PR_OFF );
> +
> +   // Generate Auth for Owner
> +   if(opts.gen_owner_auth) {
> +      vtpmmgr_rand(vtpm_globals.owner_auth, sizeof(TPM_AUTHDATA));
> +   }
> +
> +   // Create OIAP session for service's authorized commands
> +   TPMTRYRETURN( TPM_OIAP(&vtpm_globals.oiap) );
> +
> +   /* Load the Manager data, if it fails create a new manager */
> +   if (vtpm_storage_load_header() != TPM_SUCCESS) {
> +      /* If the OIAP session was closed by an error, create a new one */
> +      if(vtpm_globals.oiap.AuthHandle == 0) {
> +         TPMTRYRETURN( TPM_OIAP(&vtpm_globals.oiap) );
> +      }
> +      vtpmloginfo(VTPM_LOG_VTPM, "Failed to read manager file. Assuming first time initialization.\n");
> +      TPMTRYRETURN( vtpmmgr_create() );
> +   }
> +
> +   goto egress;
> +abort_egress:
> +   vtpmmgr_shutdown();
> +egress:
> +   return status;
> +}
> +
> +void vtpmmgr_shutdown(void)
> +{
> +   /* Cleanup resources */
> +   free_TPM_KEY(&vtpm_globals.storage_key);
> +
> +   /* Cleanup TPM resources */
> +   TPM_EvictKey(vtpm_globals.storage_key_handle);
> +   TPM_TerminateHandle(vtpm_globals.oiap.AuthHandle);
> +
> +   /* Close tpmback */
> +   shutdown_tpmback();
> +
> +   /* Close the storage system and blkfront */
> +   vtpm_storage_shutdown();
> +
> +   /* Close tpmfront/tpm_tis */
> +   close(vtpm_globals.tpm_fd);
> +
> +   vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager stopped.\n");
> +}
> diff --git a/stubdom/vtpmmgr/log.c b/stubdom/vtpmmgr/log.c
> new file mode 100644
> index 0000000..a82c913
> --- /dev/null
> +++ b/stubdom/vtpmmgr/log.c
> @@ -0,0 +1,151 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * based off of the original tools/vtpm_manager code base which is:
> + * 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 "tcg.h"
> +
> +char *module_names[] = { "",
> +                                "TPM",
> +                                "TPM",
> +                                "VTPM",
> +                                "VTPM",
> +                                "TXDATA",
> +                              };
> +// 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("Unknown Error Code");
> +}
> diff --git a/stubdom/vtpmmgr/log.h b/stubdom/vtpmmgr/log.h
> new file mode 100644
> index 0000000..5c7abf5
> --- /dev/null
> +++ b/stubdom/vtpmmgr/log.h
> @@ -0,0 +1,85 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * based off of the original tools/vtpm_manager code base which is:
> + * 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
> +#include <stdio.h>
> +#include "tcg.h"
> +
> +// =========================== LOGGING ==============================
> +
> +// the logging module numbers
> +#define VTPM_LOG_TPM         1
> +#define VTPM_LOG_TPM_DEEP    2
> +#define VTPM_LOG_VTPM        3
> +#define VTPM_LOG_VTPM_DEEP   4
> +#define VTPM_LOG_TXDATA      5
> +
> +extern char *module_names[];
> +
> +// Default to standard logging
> +#ifndef LOGGING_MODULES
> +#define LOGGING_MODULES (BITMASK(VTPM_LOG_VTPM)|BITMASK(VTPM_LOG_TPM))
> +#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 --git a/stubdom/vtpmmgr/marshal.h b/stubdom/vtpmmgr/marshal.h
> new file mode 100644
> index 0000000..77d32f0
> --- /dev/null
> +++ b/stubdom/vtpmmgr/marshal.h
> @@ -0,0 +1,528 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * based off of the original tools/vtpm_manager code base which is:
> + * 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 MARSHAL_H
> +#define MARSHAL_H
> +
> +#include <stdlib.h>
> +#include <mini-os/byteorder.h>
> +#include <mini-os/endian.h>
> +#include "tcg.h"
> +
> +typedef enum UnpackPtr {
> +   UNPACK_ALIAS,
> +   UNPACK_ALLOC
> +} UnpackPtr;
> +
> +inline BYTE* pack_BYTE(BYTE* ptr, BYTE t) {
> +   ptr[0] = t;
> +   return ++ptr;
> +}
> +
> +inline BYTE* unpack_BYTE(BYTE* ptr, BYTE* t) {
> +   t[0] = ptr[0];
> +   return ++ptr;
> +}
> +
> +#define pack_BOOL(p, t) pack_BYTE(p, t)
> +#define unpack_BOOL(p, t) unpack_BYTE(p, t)
> +
> +inline BYTE* pack_UINT16(BYTE* ptr, UINT16 t) {
> +   BYTE* b = (BYTE*)&t;
> +#if __BYTE_ORDER == __LITTLE_ENDIAN
> +   ptr[0] = b[1];
> +   ptr[1] = b[0];
> +#elif __BYTE_ORDER == __BIG_ENDIAN
> +   ptr[0] = b[0];
> +   ptr[1] = b[1];
> +#endif
> +   return ptr + sizeof(UINT16);
> +}
> +
> +inline BYTE* unpack_UINT16(BYTE* ptr, UINT16* t) {
> +   BYTE* b = (BYTE*)t;
> +#if __BYTE_ORDER == __LITTLE_ENDIAN
> +   b[0] = ptr[1];
> +   b[1] = ptr[0];
> +#elif __BYTE_ORDER == __BIG_ENDIAN
> +   b[0] = ptr[0];
> +   b[1] = ptr[1];
> +#endif
> +   return ptr + sizeof(UINT16);
> +}
> +
> +inline BYTE* pack_UINT32(BYTE* ptr, UINT32 t) {
> +   BYTE* b = (BYTE*)&t;
> +#if __BYTE_ORDER == __LITTLE_ENDIAN
> +   ptr[3] = b[0];
> +   ptr[2] = b[1];
> +   ptr[1] = b[2];
> +   ptr[0] = b[3];
> +#elif __BYTE_ORDER == __BIG_ENDIAN
> +   ptr[0] = b[0];
> +   ptr[1] = b[1];
> +   ptr[2] = b[2];
> +   ptr[3] = b[3];
> +#endif
> +   return ptr + sizeof(UINT32);
> +}
> +
> +inline BYTE* unpack_UINT32(BYTE* ptr, UINT32* t) {
> +   BYTE* b = (BYTE*)t;
> +#if __BYTE_ORDER == __LITTLE_ENDIAN
> +   b[0] = ptr[3];
> +   b[1] = ptr[2];
> +   b[2] = ptr[1];
> +   b[3] = ptr[0];
> +#elif __BYTE_ORDER == __BIG_ENDIAN
> +   b[0] = ptr[0];
> +   b[1] = ptr[1];
> +   b[2] = ptr[2];
> +   b[3] = ptr[3];
> +#endif
> +   return ptr + sizeof(UINT32);
> +}
> +
> +#define pack_TPM_RESULT(p, t) pack_UINT32(p, t)
> +#define pack_TPM_PCRINDEX(p, t) pack_UINT32(p, t)
> +#define pack_TPM_DIRINDEX(p, t) pack_UINT32(p, t)
> +#define pack_TPM_HANDLE(p, t) pack_UINT32(p, t)
> +#define pack_TPM_AUTHHANDLE(p, t) pack_TPM_HANDLE(p, t)
> +#define pack_TCPA_HASHHANDLE(p, t) pack_TPM_HANDLE(p, t)
> +#define pack_TCPA_HMACHANDLE(p, t) pack_TPM_HANDLE(p, t)
> +#define pack_TCPA_ENCHANDLE(p, t) pack_TPM_HANDLE(p, t)
> +#define pack_TPM_KEY_HANDLE(p, t) pack_TPM_HANDLE(p, t)
> +#define pack_TCPA_ENTITYHANDLE(p, t) pack_TPM_HANDLE(p, t)
> +#define pack_TPM_RESOURCE_TYPE(p, t) pack_UINT32(p, t)
> +#define pack_TPM_COMMAND_CODE(p, t) pack_UINT32(p, t)
> +#define pack_TPM_PROTOCOL_ID(p, t) pack_UINT16(p, t)
> +#define pack_TPM_AUTH_DATA_USAGE(p, t) pack_BYTE(p, t)
> +#define pack_TPM_ENTITY_TYPE(p, t) pack_UINT16(p, t)
> +#define pack_TPM_ALGORITHM_ID(p, t) pack_UINT32(p, t)
> +#define pack_TPM_KEY_USAGE(p, t) pack_UINT16(p, t)
> +#define pack_TPM_STARTUP_TYPE(p, t) pack_UINT16(p, t)
> +#define pack_TPM_CAPABILITY_AREA(p, t) pack_UINT32(p, t)
> +#define pack_TPM_ENC_SCHEME(p, t) pack_UINT16(p, t)
> +#define pack_TPM_SIG_SCHEME(p, t) pack_UINT16(p, t)
> +#define pack_TPM_MIGRATE_SCHEME(p, t) pack_UINT16(p, t)
> +#define pack_TPM_PHYSICAL_PRESENCE(p, t) pack_UINT16(p, t)
> +#define pack_TPM_KEY_FLAGS(p, t) pack_UINT32(p, t)
> +
> +#define unpack_TPM_RESULT(p, t) unpack_UINT32(p, t)
> +#define unpack_TPM_PCRINDEX(p, t) unpack_UINT32(p, t)
> +#define unpack_TPM_DIRINDEX(p, t) unpack_UINT32(p, t)
> +#define unpack_TPM_HANDLE(p, t) unpack_UINT32(p, t)
> +#define unpack_TPM_AUTHHANDLE(p, t) unpack_TPM_HANDLE(p, t)
> +#define unpack_TCPA_HASHHANDLE(p, t) unpack_TPM_HANDLE(p, t)
> +#define unpack_TCPA_HMACHANDLE(p, t) unpack_TPM_HANDLE(p, t)
> +#define unpack_TCPA_ENCHANDLE(p, t) unpack_TPM_HANDLE(p, t)
> +#define unpack_TPM_KEY_HANDLE(p, t) unpack_TPM_HANDLE(p, t)
> +#define unpack_TCPA_ENTITYHANDLE(p, t) unpack_TPM_HANDLE(p, t)
> +#define unpack_TPM_RESOURCE_TYPE(p, t) unpack_UINT32(p, t)
> +#define unpack_TPM_COMMAND_CODE(p, t) unpack_UINT32(p, t)
> +#define unpack_TPM_PROTOCOL_ID(p, t) unpack_UINT16(p, t)
> +#define unpack_TPM_AUTH_DATA_USAGE(p, t) unpack_BYTE(p, t)
> +#define unpack_TPM_ENTITY_TYPE(p, t) unpack_UINT16(p, t)
> +#define unpack_TPM_ALGORITHM_ID(p, t) unpack_UINT32(p, t)
> +#define unpack_TPM_KEY_USAGE(p, t) unpack_UINT16(p, t)
> +#define unpack_TPM_STARTUP_TYPE(p, t) unpack_UINT16(p, t)
> +#define unpack_TPM_CAPABILITY_AREA(p, t) unpack_UINT32(p, t)
> +#define unpack_TPM_ENC_SCHEME(p, t) unpack_UINT16(p, t)
> +#define unpack_TPM_SIG_SCHEME(p, t) unpack_UINT16(p, t)
> +#define unpack_TPM_MIGRATE_SCHEME(p, t) unpack_UINT16(p, t)
> +#define unpack_TPM_PHYSICAL_PRESENCE(p, t) unpack_UINT16(p, t)
> +#define unpack_TPM_KEY_FLAGS(p, t) unpack_UINT32(p, t)
> +
> +#define pack_TPM_AUTH_HANDLE(p, t) pack_UINT32(p, t);
> +#define pack_TCS_CONTEXT_HANDLE(p, t) pack_UINT32(p, t);
> +#define pack_TCS_KEY_HANDLE(p, t) pack_UINT32(p, t);
> +
> +#define unpack_TPM_AUTH_HANDLE(p, t) unpack_UINT32(p, t);
> +#define unpack_TCS_CONTEXT_HANDLE(p, t) unpack_UINT32(p, t);
> +#define unpack_TCS_KEY_HANDLE(p, t) unpack_UINT32(p, t);
> +
> +inline BYTE* pack_BUFFER(BYTE* ptr, const BYTE* buf, UINT32 size) {
> +   memcpy(ptr, buf, size);
> +   return ptr + size;
> +}
> +
> +inline BYTE* unpack_BUFFER(BYTE* ptr, BYTE* buf, UINT32 size) {
> +   memcpy(buf, ptr, size);
> +   return ptr + size;
> +}
> +
> +inline BYTE* unpack_ALIAS(BYTE* ptr, BYTE** buf, UINT32 size) {
> +   *buf = ptr;
> +   return ptr + size;
> +}
> +
> +inline BYTE* unpack_ALLOC(BYTE* ptr, BYTE** buf, UINT32 size) {
> +   if(size) {
> +      *buf = malloc(size);
> +      memcpy(*buf, ptr, size);
> +   } else {
> +      *buf = NULL;
> +   }
> +   return ptr + size;
> +}
> +
> +inline BYTE* unpack_PTR(BYTE* ptr, BYTE** buf, UINT32 size, UnpackPtr alloc) {
> +   if(alloc == UNPACK_ALLOC) {
> +      return unpack_ALLOC(ptr, buf, size);
> +   } else {
> +      return unpack_ALIAS(ptr, buf, size);
> +   }
> +}
> +
> +inline BYTE* pack_TPM_AUTHDATA(BYTE* ptr, const TPM_AUTHDATA* d) {
> +   return pack_BUFFER(ptr, *d, TPM_DIGEST_SIZE);
> +}
> +
> +inline BYTE* unpack_TPM_AUTHDATA(BYTE* ptr, TPM_AUTHDATA* d) {
> +   return unpack_BUFFER(ptr, *d, TPM_DIGEST_SIZE);
> +}
> +
> +#define pack_TPM_SECRET(p, t) pack_TPM_AUTHDATA(p, t)
> +#define pack_TPM_ENCAUTH(p, t) pack_TPM_AUTHDATA(p, t)
> +#define pack_TPM_PAYLOAD_TYPE(p, t) pack_BYTE(p, t)
> +#define pack_TPM_TAG(p, t) pack_UINT16(p, t)
> +#define pack_TPM_STRUCTURE_TAG(p, t) pack_UINT16(p, t)
> +
> +#define unpack_TPM_SECRET(p, t) unpack_TPM_AUTHDATA(p, t)
> +#define unpack_TPM_ENCAUTH(p, t) unpack_TPM_AUTHDATA(p, t)
> +#define unpack_TPM_PAYLOAD_TYPE(p, t) unpack_BYTE(p, t)
> +#define unpack_TPM_TAG(p, t) unpack_UINT16(p, t)
> +#define unpack_TPM_STRUCTURE_TAG(p, t) unpack_UINT16(p, t)
> +
> +inline BYTE* pack_TPM_VERSION(BYTE* ptr, const TPM_VERSION* t) {
> +   ptr[0] = t->major;
> +   ptr[1] = t->minor;
> +   ptr[2] = t->revMajor;
> +   ptr[3] = t->revMinor;
> +   return ptr + 4;
> +}
> +
> +inline BYTE* unpack_TPM_VERSION(BYTE* ptr, TPM_VERSION* t) {
> +   t->major = ptr[0];
> +   t->minor = ptr[1];
> +   t->revMajor = ptr[2];
> +   t->revMinor = ptr[3];
> +   return ptr + 4;
> +}
> +
> +inline BYTE* pack_TPM_CAP_VERSION_INFO(BYTE* ptr, const TPM_CAP_VERSION_INFO* v) {
> +   ptr = pack_TPM_STRUCTURE_TAG(ptr, v->tag);
> +   ptr = pack_TPM_VERSION(ptr, &v->version);
> +   ptr = pack_UINT16(ptr, v->specLevel);
> +   ptr = pack_BYTE(ptr, v->errataRev);
> +   ptr = pack_BUFFER(ptr, v->tpmVendorID, sizeof(v->tpmVendorID));
> +   ptr = pack_UINT16(ptr, v->vendorSpecificSize);
> +   ptr = pack_BUFFER(ptr, v->vendorSpecific, v->vendorSpecificSize);
> +   return ptr;
> +}
> +
> +inline BYTE* unpack_TPM_CAP_VERSION_INFO(BYTE* ptr, TPM_CAP_VERSION_INFO* v, UnpackPtr alloc) {
> +   ptr = unpack_TPM_STRUCTURE_TAG(ptr, &v->tag);
> +   ptr = unpack_TPM_VERSION(ptr, &v->version);
> +   ptr = unpack_UINT16(ptr, &v->specLevel);
> +   ptr = unpack_BYTE(ptr, &v->errataRev);
> +   ptr = unpack_BUFFER(ptr, v->tpmVendorID, sizeof(v->tpmVendorID));
> +   ptr = unpack_UINT16(ptr, &v->vendorSpecificSize);
> +   ptr = unpack_PTR(ptr, &v->vendorSpecific, v->vendorSpecificSize, alloc);
> +   return ptr;
> +}
> +
> +inline BYTE* pack_TPM_DIGEST(BYTE* ptr, const TPM_DIGEST* d) {
> +   return pack_BUFFER(ptr, d->digest, TPM_DIGEST_SIZE);
> +}
> +
> +inline BYTE* unpack_TPM_DIGEST(BYTE* ptr, TPM_DIGEST* d) {
> +   return unpack_BUFFER(ptr, d->digest, TPM_DIGEST_SIZE);
> +}
> +
> +#define pack_TPM_PCRVALUE(ptr, d) pack_TPM_DIGEST(ptr, d);
> +#define unpack_TPM_PCRVALUE(ptr, d) unpack_TPM_DIGEST(ptr, d);
> +
> +#define pack_TPM_COMPOSITE_HASH(ptr, d) pack_TPM_DIGEST(ptr, d);
> +#define unpack_TPM_COMPOSITE_HASH(ptr, d) unpack_TPM_DIGEST(ptr, d);
> +
> +#define pack_TPM_DIRVALUE(ptr, d) pack_TPM_DIGEST(ptr, d);
> +#define unpack_TPM_DIRVALUE(ptr, d) unpack_TPM_DIGEST(ptr, d);
> +
> +#define pack_TPM_HMAC(ptr, d) pack_TPM_DIGEST(ptr, d);
> +#define unpack_TPM_HMAC(ptr, d) unpack_TPM_DIGEST(ptr, d);
> +
> +#define pack_TPM_CHOSENID_HASH(ptr, d) pack_TPM_DIGEST(ptr, d);
> +#define unpack_TPM_CHOSENID_HASH(ptr, d) unpack_TPM_DIGEST(ptr, d);
> +
> +inline BYTE* pack_TPM_NONCE(BYTE* ptr, const TPM_NONCE* n) {
> +   return pack_BUFFER(ptr, n->nonce, TPM_DIGEST_SIZE);
> +}
> +
> +inline BYTE* unpack_TPM_NONCE(BYTE* ptr, TPM_NONCE* n) {
> +   return unpack_BUFFER(ptr, n->nonce, TPM_DIGEST_SIZE);
> +}
> +
> +inline BYTE* pack_TPM_SYMMETRIC_KEY_PARMS(BYTE* ptr, const TPM_SYMMETRIC_KEY_PARMS* k) {
> +   ptr = pack_UINT32(ptr, k->keyLength);
> +   ptr = pack_UINT32(ptr, k->blockSize);
> +   ptr = pack_UINT32(ptr, k->ivSize);
> +   return pack_BUFFER(ptr, k->IV, k->ivSize);
> +}
> +
> +inline BYTE* unpack_TPM_SYMMETRIC_KEY_PARMS(BYTE* ptr, TPM_SYMMETRIC_KEY_PARMS* k, UnpackPtr alloc) {
> +   ptr = unpack_UINT32(ptr, &k->keyLength);
> +   ptr = unpack_UINT32(ptr, &k->blockSize);
> +   ptr = unpack_UINT32(ptr, &k->ivSize);
> +   return unpack_PTR(ptr, &k->IV, k->ivSize, alloc);
> +}
> +
> +inline BYTE* pack_TPM_RSA_KEY_PARMS(BYTE* ptr, const TPM_RSA_KEY_PARMS* k) {
> +   ptr = pack_UINT32(ptr, k->keyLength);
> +   ptr = pack_UINT32(ptr, k->numPrimes);
> +   ptr = pack_UINT32(ptr, k->exponentSize);
> +   return pack_BUFFER(ptr, k->exponent, k->exponentSize);
> +}
> +
> +inline BYTE* unpack_TPM_RSA_KEY_PARMS(BYTE* ptr, TPM_RSA_KEY_PARMS* k, UnpackPtr alloc) {
> +   ptr = unpack_UINT32(ptr, &k->keyLength);
> +   ptr = unpack_UINT32(ptr, &k->numPrimes);
> +   ptr = unpack_UINT32(ptr, &k->exponentSize);
> +   return unpack_PTR(ptr, &k->exponent, k->exponentSize, alloc);
> +}
> +
> +inline BYTE* pack_TPM_KEY_PARMS(BYTE* ptr, const TPM_KEY_PARMS* k) {
> +   ptr = pack_TPM_ALGORITHM_ID(ptr, k->algorithmID);
> +   ptr = pack_TPM_ENC_SCHEME(ptr, k->encScheme);
> +   ptr = pack_TPM_SIG_SCHEME(ptr, k->sigScheme);
> +   ptr = pack_UINT32(ptr, k->parmSize);
> +
> +   if(k->parmSize) {
> +      switch(k->algorithmID) {
> +         case TPM_ALG_RSA:
> +            return pack_TPM_RSA_KEY_PARMS(ptr, &k->parms.rsa);
> +         case TPM_ALG_AES128:
> +         case TPM_ALG_AES192:
> +         case TPM_ALG_AES256:
> +            return pack_TPM_SYMMETRIC_KEY_PARMS(ptr, &k->parms.sym);
> +      }
> +   }
> +   return ptr;
> +}
> +
> +inline BYTE* unpack_TPM_KEY_PARMS(BYTE* ptr, TPM_KEY_PARMS* k, UnpackPtr alloc) {
> +   ptr = unpack_TPM_ALGORITHM_ID(ptr, &k->algorithmID);
> +   ptr = unpack_TPM_ENC_SCHEME(ptr, &k->encScheme);
> +   ptr = unpack_TPM_SIG_SCHEME(ptr, &k->sigScheme);
> +   ptr = unpack_UINT32(ptr, &k->parmSize);
> +
> +   if(k->parmSize) {
> +      switch(k->algorithmID) {
> +         case TPM_ALG_RSA:
> +            return unpack_TPM_RSA_KEY_PARMS(ptr, &k->parms.rsa, alloc);
> +         case TPM_ALG_AES128:
> +         case TPM_ALG_AES192:
> +         case TPM_ALG_AES256:
> +            return unpack_TPM_SYMMETRIC_KEY_PARMS(ptr, &k->parms.sym, alloc);
> +      }
> +   }
> +   return ptr;
> +}
> +
> +inline BYTE* pack_TPM_STORE_PUBKEY(BYTE* ptr, const TPM_STORE_PUBKEY* k) {
> +   ptr = pack_UINT32(ptr, k->keyLength);
> +   ptr = pack_BUFFER(ptr, k->key, k->keyLength);
> +   return ptr;
> +}
> +
> +inline BYTE* unpack_TPM_STORE_PUBKEY(BYTE* ptr, TPM_STORE_PUBKEY* k, UnpackPtr alloc) {
> +   ptr = unpack_UINT32(ptr, &k->keyLength);
> +   ptr = unpack_PTR(ptr, &k->key, k->keyLength, alloc);
> +   return ptr;
> +}
> +
> +inline BYTE* pack_TPM_PUBKEY(BYTE* ptr, const TPM_PUBKEY* k) {
> +   ptr = pack_TPM_KEY_PARMS(ptr, &k->algorithmParms);
> +   return pack_TPM_STORE_PUBKEY(ptr, &k->pubKey);
> +}
> +
> +inline BYTE* unpack_TPM_PUBKEY(BYTE* ptr, TPM_PUBKEY* k, UnpackPtr alloc) {
> +   ptr = unpack_TPM_KEY_PARMS(ptr, &k->algorithmParms, alloc);
> +   return unpack_TPM_STORE_PUBKEY(ptr, &k->pubKey, alloc);
> +}
> +
> +inline BYTE* pack_TPM_PCR_SELECTION(BYTE* ptr, const TPM_PCR_SELECTION* p) {
> +   ptr = pack_UINT16(ptr, p->sizeOfSelect);
> +   ptr = pack_BUFFER(ptr, p->pcrSelect, p->sizeOfSelect);
> +   return ptr;
> +}
> +
> +inline BYTE* unpack_TPM_PCR_SELECTION(BYTE* ptr, TPM_PCR_SELECTION* p, UnpackPtr alloc) {
> +   ptr = unpack_UINT16(ptr, &p->sizeOfSelect);
> +   ptr = unpack_PTR(ptr, &p->pcrSelect, p->sizeOfSelect, alloc);
> +   return ptr;
> +}
> +
> +inline BYTE* pack_TPM_PCR_INFO(BYTE* ptr, const TPM_PCR_INFO* p) {
> +   ptr = pack_TPM_PCR_SELECTION(ptr, &p->pcrSelection);
> +   ptr = pack_TPM_COMPOSITE_HASH(ptr, &p->digestAtRelease);
> +   ptr = pack_TPM_COMPOSITE_HASH(ptr, &p->digestAtCreation);
> +   return ptr;
> +}
> +
> +inline BYTE* unpack_TPM_PCR_INFO(BYTE* ptr, TPM_PCR_INFO* p, UnpackPtr alloc) {
> +   ptr = unpack_TPM_PCR_SELECTION(ptr, &p->pcrSelection, alloc);
> +   ptr = unpack_TPM_COMPOSITE_HASH(ptr, &p->digestAtRelease);
> +   ptr = unpack_TPM_COMPOSITE_HASH(ptr, &p->digestAtCreation);
> +   return ptr;
> +}
> +
> +inline BYTE* pack_TPM_PCR_COMPOSITE(BYTE* ptr, const TPM_PCR_COMPOSITE* p) {
> +   ptr = pack_TPM_PCR_SELECTION(ptr, &p->select);
> +   ptr = pack_UINT32(ptr, p->valueSize);
> +   ptr = pack_BUFFER(ptr, (const BYTE*)p->pcrValue, p->valueSize);
> +   return ptr;
> +}
> +
> +inline BYTE* unpack_TPM_PCR_COMPOSITE(BYTE* ptr, TPM_PCR_COMPOSITE* p, UnpackPtr alloc) {
> +   ptr = unpack_TPM_PCR_SELECTION(ptr, &p->select, alloc);
> +   ptr = unpack_UINT32(ptr, &p->valueSize);
> +   ptr = unpack_PTR(ptr, (BYTE**)&p->pcrValue, p->valueSize, alloc);
> +   return ptr;
> +}
> +
> +inline BYTE* pack_TPM_KEY(BYTE* ptr, const TPM_KEY* k) {
> +   ptr = pack_TPM_VERSION(ptr, &k->ver);
> +   ptr = pack_TPM_KEY_USAGE(ptr, k->keyUsage);
> +   ptr = pack_TPM_KEY_FLAGS(ptr, k->keyFlags);
> +   ptr = pack_TPM_AUTH_DATA_USAGE(ptr, k->authDataUsage);
> +   ptr = pack_TPM_KEY_PARMS(ptr, &k->algorithmParms);
> +   ptr = pack_UINT32(ptr, k->PCRInfoSize);
> +   if(k->PCRInfoSize) {
> +      ptr = pack_TPM_PCR_INFO(ptr, &k->PCRInfo);
> +   }
> +   ptr = pack_TPM_STORE_PUBKEY(ptr, &k->pubKey);
> +   ptr = pack_UINT32(ptr, k->encDataSize);
> +   return pack_BUFFER(ptr, k->encData, k->encDataSize);
> +}
> +
> +inline BYTE* unpack_TPM_KEY(BYTE* ptr, TPM_KEY* k, UnpackPtr alloc) {
> +   ptr = unpack_TPM_VERSION(ptr, &k->ver);
> +   ptr = unpack_TPM_KEY_USAGE(ptr, &k->keyUsage);
> +   ptr = unpack_TPM_KEY_FLAGS(ptr, &k->keyFlags);
> +   ptr = unpack_TPM_AUTH_DATA_USAGE(ptr, &k->authDataUsage);
> +   ptr = unpack_TPM_KEY_PARMS(ptr, &k->algorithmParms, alloc);
> +   ptr = unpack_UINT32(ptr, &k->PCRInfoSize);
> +   if(k->PCRInfoSize) {
> +      ptr = unpack_TPM_PCR_INFO(ptr, &k->PCRInfo, alloc);
> +   }
> +   ptr = unpack_TPM_STORE_PUBKEY(ptr, &k->pubKey, alloc);
> +   ptr = unpack_UINT32(ptr, &k->encDataSize);
> +   return unpack_PTR(ptr, &k->encData, k->encDataSize, alloc);
> +}
> +
> +inline BYTE* pack_TPM_BOUND_DATA(BYTE* ptr, const TPM_BOUND_DATA* b, UINT32 payloadSize) {
> +   ptr = pack_TPM_VERSION(ptr, &b->ver);
> +   ptr = pack_TPM_PAYLOAD_TYPE(ptr, b->payload);
> +   return pack_BUFFER(ptr, b->payloadData, payloadSize);
> +}
> +
> +inline BYTE* unpack_TPM_BOUND_DATA(BYTE* ptr, TPM_BOUND_DATA* b, UINT32 payloadSize, UnpackPtr alloc) {
> +   ptr = unpack_TPM_VERSION(ptr, &b->ver);
> +   ptr = unpack_TPM_PAYLOAD_TYPE(ptr, &b->payload);
> +   return unpack_PTR(ptr, &b->payloadData, payloadSize, alloc);
> +}
> +
> +inline BYTE* pack_TPM_STORED_DATA(BYTE* ptr, const TPM_STORED_DATA* d) {
> +   ptr = pack_TPM_VERSION(ptr, &d->ver);
> +   ptr = pack_UINT32(ptr, d->sealInfoSize);
> +   if(d->sealInfoSize) {
> +      ptr = pack_TPM_PCR_INFO(ptr, &d->sealInfo);
> +   }
> +   ptr = pack_UINT32(ptr, d->encDataSize);
> +   ptr = pack_BUFFER(ptr, d->encData, d->encDataSize);
> +   return ptr;
> +}
> +
> +inline BYTE* unpack_TPM_STORED_DATA(BYTE* ptr, TPM_STORED_DATA* d, UnpackPtr alloc) {
> +   ptr = unpack_TPM_VERSION(ptr, &d->ver);
> +   ptr = unpack_UINT32(ptr, &d->sealInfoSize);
> +   if(d->sealInfoSize) {
> +      ptr = unpack_TPM_PCR_INFO(ptr, &d->sealInfo, alloc);
> +   }
> +   ptr = unpack_UINT32(ptr, &d->encDataSize);
> +   ptr = unpack_PTR(ptr, &d->encData, d->encDataSize, alloc);
> +   return ptr;
> +}
> +
> +inline BYTE* pack_TPM_AUTH_SESSION(BYTE* ptr, const TPM_AUTH_SESSION* auth) {
> +   ptr = pack_TPM_AUTH_HANDLE(ptr, auth->AuthHandle);
> +   ptr = pack_TPM_NONCE(ptr, &auth->NonceOdd);
> +   ptr = pack_BOOL(ptr, auth->fContinueAuthSession);
> +   ptr = pack_TPM_AUTHDATA(ptr, &auth->HMAC);
> +   return ptr;
> +}
> +
> +inline BYTE* unpack_TPM_AUTH_SESSION(BYTE* ptr, TPM_AUTH_SESSION* auth) {
> +   ptr = unpack_TPM_NONCE(ptr, &auth->NonceEven);
> +   ptr = unpack_BOOL(ptr, &auth->fContinueAuthSession);
> +   ptr = unpack_TPM_AUTHDATA(ptr, &auth->HMAC);
> +   return ptr;
> +}
> +
> +inline BYTE* pack_TPM_RQU_HEADER(BYTE* ptr,
> +      TPM_TAG tag,
> +      UINT32 size,
> +      TPM_COMMAND_CODE ord) {
> +   ptr = pack_UINT16(ptr, tag);
> +   ptr = pack_UINT32(ptr, size);
> +   return pack_UINT32(ptr, ord);
> +}
> +
> +inline BYTE* unpack_TPM_RQU_HEADER(BYTE* ptr,
> +      TPM_TAG* tag,
> +      UINT32* size,
> +      TPM_COMMAND_CODE* ord) {
> +   ptr = unpack_UINT16(ptr, tag);
> +   ptr = unpack_UINT32(ptr, size);
> +   ptr = unpack_UINT32(ptr, ord);
> +   return ptr;
> +}
> +
> +#define pack_TPM_RSP_HEADER(p, t, s, r) pack_TPM_RQU_HEADER(p, t, s, r);
> +#define unpack_TPM_RSP_HEADER(p, t, s, r) unpack_TPM_RQU_HEADER(p, t, s, r);
> +
> +#endif
> diff --git a/stubdom/vtpmmgr/minios.cfg b/stubdom/vtpmmgr/minios.cfg
> new file mode 100644
> index 0000000..3fb383d
> --- /dev/null
> +++ b/stubdom/vtpmmgr/minios.cfg
> @@ -0,0 +1,14 @@
> +CONFIG_TPMFRONT=y
> +CONFIG_TPM_TIS=y
> +CONFIG_TPMBACK=y
> +CONFIG_START_NETWORK=n
> +CONFIG_TEST=n
> +CONFIG_PCIFRONT=n
> +CONFIG_BLKFRONT=y
> +CONFIG_NETFRONT=n
> +CONFIG_FBFRONT=n
> +CONFIG_KBDFRONT=n
> +CONFIG_CONSFRONT=n
> +CONFIG_XENBUS=y
> +CONFIG_LWIP=n
> +CONFIG_XC=n
> diff --git a/stubdom/vtpmmgr/tcg.h b/stubdom/vtpmmgr/tcg.h
> new file mode 100644
> index 0000000..7687eae
> --- /dev/null
> +++ b/stubdom/vtpmmgr/tcg.h
> @@ -0,0 +1,707 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * based off of the original tools/vtpm_manager code base which is:
> + * 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 __TCG_H__
> +#define __TCG_H__
> +
> +#include <stdlib.h>
> +#include <stdint.h>
> +
> +// **************************** 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 TPM_ORD_SaveContext                      (184UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_LoadContext                      (185UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_FlushSpecific                    (186UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_PCR_Reset                        (200UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_NV_DefineSpace                   (204UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_NV_WriteValue                    (205UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_NV_WriteValueAuth                (206UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_NV_ReadValue                     (207UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_NV_ReadValueAuth                 (208UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_Delegate_UpdateVerification      (209UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_Delegate_Manage                  (210UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_Delegate_CreateKeyDelegation     (212UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_Delegate_CreateOwnerDelegation   (213UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_Delegate_VerifyDelegation        (214UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_Delegate_LoadOwnerDelegation     (216UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_Delegate_ReadAuth                (217UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_Delegate_ReadTable               (219UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_CreateCounter                    (220UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_IncrementCounter                 (221UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_ReadCounter                      (222UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_ReleaseCounter                   (223UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_ReleaseCounterOwner              (224UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_EstablishTransport               (230UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_ExecuteTransport                 (231UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_ReleaseTransportSigned           (232UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_GetTicks                         (241UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_TickStampBlob                    (242UL + TPM_PROTECTED_ORDINAL)
> +#define TPM_ORD_MAX                              (256UL + 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_STARTUP_TYPE values
> +#define TPM_ST_CLEAR 0x0001
> +#define TPM_ST_STATE 0x0002
> +#define TPM_ST_DEACTIVATED 0x003
> +
> +// 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_HASH     0x00000003
> +#define TPM_RT_TRANS    0x00000004
> +#define TPM_RT_CONTEXT  0x00000005
> +#define TPM_RT_COUNTER  0x00000006
> +#define TPM_RT_DELEGATE 0x00000007
> +#define TPM_RT_DAA_TPM  0x00000008
> +#define TPM_RT_DAA_V0   0x00000009
> +#define TPM_RT_DAA_V1   0x0000000A
> +
> +
> +
> +// 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_SHA 0x00000004
> +#define TPM_ALG_HMAC 0x00000005
> +#define TPM_ALG_AES128 0x00000006
> +#define TPM_ALG_MFG1 0x00000007
> +#define TPM_ALG_AES192 0x00000008
> +#define TPM_ALG_AES256 0x00000009
> +#define TPM_ALG_XOR 0x0000000A
> +
> +// 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_CAPABILITY_AREA Values for TPM_GetCapability ([TPM_Part2], Section 21.1)
> + */
> +#define TPM_CAP_ORD                     0x00000001
> +#define TPM_CAP_ALG                     0x00000002
> +#define TPM_CAP_PID                     0x00000003
> +#define TPM_CAP_FLAG                    0x00000004
> +#define TPM_CAP_PROPERTY                0x00000005
> +#define TPM_CAP_VERSION                 0x00000006
> +#define TPM_CAP_KEY_HANDLE              0x00000007
> +#define TPM_CAP_CHECK_LOADED            0x00000008
> +#define TPM_CAP_SYM_MODE                0x00000009
> +#define TPM_CAP_KEY_STATUS              0x0000000C
> +#define TPM_CAP_NV_LIST                 0x0000000D
> +#define TPM_CAP_MFR                     0x00000010
> +#define TPM_CAP_NV_INDEX                0x00000011
> +#define TPM_CAP_TRANS_ALG               0x00000012
> +#define TPM_CAP_HANDLE                  0x00000014
> +#define TPM_CAP_TRANS_ES                0x00000015
> +#define TPM_CAP_AUTH_ENCRYPT            0x00000017
> +#define TPM_CAP_SELECT_SIZE             0x00000018
> +#define TPM_CAP_DA_LOGIC                0x00000019
> +#define TPM_CAP_VERSION_VAL             0x0000001A
> +
> +/* subCap definitions ([TPM_Part2], Section 21.2) */
> +#define TPM_CAP_PROP_PCR                0x00000101
> +#define TPM_CAP_PROP_DIR                0x00000102
> +#define TPM_CAP_PROP_MANUFACTURER       0x00000103
> +#define TPM_CAP_PROP_KEYS               0x00000104
> +#define TPM_CAP_PROP_MIN_COUNTER        0x00000107
> +#define TPM_CAP_FLAG_PERMANENT          0x00000108
> +#define TPM_CAP_FLAG_VOLATILE           0x00000109
> +#define TPM_CAP_PROP_AUTHSESS           0x0000010A
> +#define TPM_CAP_PROP_TRANSESS           0x0000010B
> +#define TPM_CAP_PROP_COUNTERS           0x0000010C
> +#define TPM_CAP_PROP_MAX_AUTHSESS       0x0000010D
> +#define TPM_CAP_PROP_MAX_TRANSESS       0x0000010E
> +#define TPM_CAP_PROP_MAX_COUNTERS       0x0000010F
> +#define TPM_CAP_PROP_MAX_KEYS           0x00000110
> +#define TPM_CAP_PROP_OWNER              0x00000111
> +#define TPM_CAP_PROP_CONTEXT            0x00000112
> +#define TPM_CAP_PROP_MAX_CONTEXT        0x00000113
> +#define TPM_CAP_PROP_FAMILYROWS         0x00000114
> +#define TPM_CAP_PROP_TIS_TIMEOUT        0x00000115
> +#define TPM_CAP_PROP_STARTUP_EFFECT     0x00000116
> +#define TPM_CAP_PROP_DELEGATE_ROW       0x00000117
> +#define TPM_CAP_PROP_MAX_DAASESS        0x00000119
> +#define TPM_CAP_PROP_DAASESS            0x0000011A
> +#define TPM_CAP_PROP_CONTEXT_DIST       0x0000011B
> +#define TPM_CAP_PROP_DAA_INTERRUPT      0x0000011C
> +#define TPM_CAP_PROP_SESSIONS           0x0000011D
> +#define TPM_CAP_PROP_MAX_SESSIONS       0x0000011E
> +#define TPM_CAP_PROP_CMK_RESTRICTION    0x0000011F
> +#define TPM_CAP_PROP_DURATION           0x00000120
> +#define TPM_CAP_PROP_ACTIVE_COUNTER     0x00000122
> +#define TPM_CAP_PROP_MAX_NV_AVAILABLE   0x00000123
> +#define TPM_CAP_PROP_INPUT_BUFFER       0x00000124
> +
> +// 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
> +
> +
> +
> +// *************************** TYPEDEFS *********************************
> +typedef unsigned char BYTE;
> +typedef unsigned char BOOL;
> +typedef uint16_t UINT16;
> +typedef uint32_t UINT32;
> +typedef uint64_t 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;
> +typedef UINT16 TPM_STRUCTURE_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_CAP_VERSION_INFO {
> +   TPM_STRUCTURE_TAG tag;
> +   TPM_VERSION version;
> +   UINT16 specLevel;
> +   BYTE errataRev;
> +   BYTE tpmVendorID[4];
> +   UINT16 vendorSpecificSize;
> +   BYTE* vendorSpecific;
> +} TPM_CAP_VERSION_INFO;
> +
> +inline void free_TPM_CAP_VERSION_INFO(TPM_CAP_VERSION_INFO* v) {
> +   free(v->vendorSpecific);
> +   v->vendorSpecific = NULL;
> +}
> +
> +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_SYMMETRIC_KEY_PARMS {
> +   UINT32 keyLength;
> +   UINT32 blockSize;
> +   UINT32 ivSize;
> +   BYTE* IV;
> +} TPM_SYMMETRIC_KEY_PARMS;
> +
> +inline void free_TPM_SYMMETRIC_KEY_PARMS(TPM_SYMMETRIC_KEY_PARMS* p) {
> +   free(p->IV);
> +   p->IV = NULL;
> +}
> +
> +#define TPM_SYMMETRIC_KEY_PARMS_INIT { 0, 0, 0, NULL }
> +
> +typedef struct TPM_RSA_KEY_PARMS {
> +  UINT32 keyLength;
> +  UINT32 numPrimes;
> +  UINT32 exponentSize;
> +  BYTE* exponent;
> +} TPM_RSA_KEY_PARMS;
> +
> +#define TPM_RSA_KEY_PARMS_INIT { 0, 0, 0, NULL }
> +
> +inline void free_TPM_RSA_KEY_PARMS(TPM_RSA_KEY_PARMS* p) {
> +   free(p->exponent);
> +   p->exponent = NULL;
> +}
> +
> +typedef struct TPM_KEY_PARMS {
> +  TPM_ALGORITHM_ID algorithmID;
> +  TPM_ENC_SCHEME encScheme;
> +  TPM_SIG_SCHEME sigScheme;
> +  UINT32 parmSize;
> +  union {
> +     TPM_SYMMETRIC_KEY_PARMS sym;
> +     TPM_RSA_KEY_PARMS rsa;
> +  } parms;
> +} TPM_KEY_PARMS;
> +
> +#define TPM_KEY_PARMS_INIT { 0, 0, 0, 0 }
> +
> +inline void free_TPM_KEY_PARMS(TPM_KEY_PARMS* p) {
> +   if(p->parmSize) {
> +      switch(p->algorithmID) {
> +         case TPM_ALG_RSA:
> +            free_TPM_RSA_KEY_PARMS(&p->parms.rsa);
> +            break;
> +         case TPM_ALG_AES128:
> +         case TPM_ALG_AES192:
> +         case TPM_ALG_AES256:
> +            free_TPM_SYMMETRIC_KEY_PARMS(&p->parms.sym);
> +            break;
> +      }
> +   }
> +}
> +
> +typedef struct TPM_STORE_PUBKEY {
> +  UINT32 keyLength;
> +  BYTE* key;
> +} TPM_STORE_PUBKEY;
> +
> +#define TPM_STORE_PUBKEY_INIT { 0, NULL }
> +
> +inline void free_TPM_STORE_PUBKEY(TPM_STORE_PUBKEY* p) {
> +   free(p->key);
> +   p->key = NULL;
> +}
> +
> +typedef struct TPM_PUBKEY {
> +  TPM_KEY_PARMS algorithmParms;
> +  TPM_STORE_PUBKEY pubKey;
> +} TPM_PUBKEY;
> +
> +#define TPM_PUBKEY_INIT { TPM_KEY_PARMS_INIT, TPM_STORE_PUBKEY_INIT }
> +
> +inline void free_TPM_PUBKEY(TPM_PUBKEY* k) {
> +   free_TPM_KEY_PARMS(&k->algorithmParms);
> +   free_TPM_STORE_PUBKEY(&k->pubKey);
> +}
> +
> +typedef struct TPM_PCR_SELECTION {
> +   UINT16 sizeOfSelect;
> +   BYTE* pcrSelect;
> +} TPM_PCR_SELECTION;
> +
> +#define TPM_PCR_SELECTION_INIT { 0, NULL }
> +
> +inline void free_TPM_PCR_SELECTION(TPM_PCR_SELECTION* p) {
> +   free(p->pcrSelect);
> +   p->pcrSelect = NULL;
> +}
> +
> +typedef struct TPM_PCR_INFO {
> +   TPM_PCR_SELECTION pcrSelection;
> +   TPM_COMPOSITE_HASH digestAtRelease;
> +   TPM_COMPOSITE_HASH digestAtCreation;
> +} TPM_PCR_INFO;
> +
> +#define TPM_PCR_INFO_INIT { TPM_PCR_SELECTION_INIT }
> +
> +inline void free_TPM_PCR_INFO(TPM_PCR_INFO* p) {
> +   free_TPM_PCR_SELECTION(&p->pcrSelection);
> +}
> +
> +typedef struct TPM_PCR_COMPOSITE {
> +  TPM_PCR_SELECTION select;
> +  UINT32 valueSize;
> +  TPM_PCRVALUE* pcrValue;
> +} TPM_PCR_COMPOSITE;
> +
> +#define TPM_PCR_COMPOSITE_INIT { TPM_PCR_SELECTION_INIT, 0, NULL }
> +
> +inline void free_TPM_PCR_COMPOSITE(TPM_PCR_COMPOSITE* p) {
> +   free_TPM_PCR_SELECTION(&p->select);
> +   free(p->pcrValue);
> +   p->pcrValue = NULL;
> +}
> +
> +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;
> +  TPM_PCR_INFO        PCRInfo;
> +  TPM_STORE_PUBKEY    pubKey;
> +  UINT32              encDataSize;
> +  BYTE*               encData;
> +} TPM_KEY;
> +
> +#define TPM_KEY_INIT { .algorithmParms = TPM_KEY_PARMS_INIT,\
> +   .PCRInfoSize = 0, .PCRInfo = TPM_PCR_INFO_INIT, \
> +   .pubKey = TPM_STORE_PUBKEY_INIT, \
> +   .encDataSize = 0, .encData = NULL }
> +
> +inline void free_TPM_KEY(TPM_KEY* k) {
> +   if(k->PCRInfoSize) {
> +      free_TPM_PCR_INFO(&k->PCRInfo);
> +   }
> +   free_TPM_STORE_PUBKEY(&k->pubKey);
> +   free(k->encData);
> +   k->encData = NULL;
> +}
> +
> +typedef struct TPM_BOUND_DATA {
> +  TPM_VERSION ver;
> +  TPM_PAYLOAD_TYPE payload;
> +  BYTE* payloadData;
> +} TPM_BOUND_DATA;
> +
> +#define TPM_BOUND_DATA_INIT { .payloadData = NULL }
> +
> +inline void free_TPM_BOUND_DATA(TPM_BOUND_DATA* d) {
> +   free(d->payloadData);
> +   d->payloadData = NULL;
> +}
> +
> +typedef struct TPM_STORED_DATA {
> +  TPM_VERSION ver;
> +  UINT32 sealInfoSize;
> +  TPM_PCR_INFO sealInfo;
> +  UINT32 encDataSize;
> +  BYTE* encData;
> +} TPM_STORED_DATA;
> +
> +#define TPM_STORED_DATA_INIT { .sealInfoSize = 0, sealInfo = TPM_PCR_INFO_INIT,\
> +   .encDataSize = 0, .encData = NULL }
> +
> +inline void free_TPM_STORED_DATA(TPM_STORED_DATA* d) {
> +   if(d->sealInfoSize) {
> +      free_TPM_PCR_INFO(&d->sealInfo);
> +   }
> +   free(d->encData);
> +   d->encData = NULL;
> +}
> +
> +typedef struct TPM_AUTH_SESSION {
> +  TPM_AUTHHANDLE  AuthHandle;
> +  TPM_NONCE   NonceOdd;   // system
> +  TPM_NONCE   NonceEven;   // TPM
> +  BOOL   fContinueAuthSession;
> +  TPM_AUTHDATA  HMAC;
> +} TPM_AUTH_SESSION;
> +
> +#define TPM_AUTH_SESSION_INIT { .AuthHandle = 0, .fContinueAuthSession = FALSE }
> +
> +// ---------------------- Functions for checking TPM_RESULTs -----------------
> +
> +#include <stdio.h>
> +
> +// 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 at %s: %i\n", __func__, __FILE__, __LINE__); \
> +                         goto abort_egress; } \
> +                    while (0)
> +
> +// 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 abort.
> +#define TPMTRY(s,c) if (c != TPM_SUCCESS) { \
> +                       status = s; \
> +                       printf("ERROR in %s at %s:%i code: %s.\n", __func__, __FILE__, __LINE__, tpm_get_error_name(status)); \
> +                       goto abort_egress; \
> +                    } else {\
> +                       status = c; \
> +                    }
> +
> +// Try command c. If it fails, print error message, set status to actual return code. Goto abort
> +#define TPMTRYRETURN(c) do { status = c; \
> +                             if (status != TPM_SUCCESS) { \
> +                               fprintf(stderr, "ERROR in %s at %s:%i code: %s.\n", __func__, __FILE__, __LINE__, tpm_get_error_name(status)); \
> +                               goto abort_egress; \
> +                             } \
> +                        } while(0)
> +
> +
> +#endif //__TCPA_H__
> diff --git a/stubdom/vtpmmgr/tpm.c b/stubdom/vtpmmgr/tpm.c
> new file mode 100644
> index 0000000..123a27c
> --- /dev/null
> +++ b/stubdom/vtpmmgr/tpm.c
> @@ -0,0 +1,938 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * based off of the original tools/vtpm_manager code base which is:
> + * 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 <stdio.h>
> +#include <string.h>
> +#include <malloc.h>
> +#include <unistd.h>
> +#include <errno.h>
> +
> +#include <polarssl/sha1.h>
> +
> +#include "tcg.h"
> +#include "tpm.h"
> +#include "log.h"
> +#include "marshal.h"
> +#include "tpmrsa.h"
> +#include "vtpmmgr.h"
> +
> +#define TCPA_MAX_BUFFER_LENGTH 0x2000
> +
> +#define TPM_BEGIN(TAG, ORD) \
> +   const TPM_TAG intag = TAG;\
> +TPM_TAG tag = intag;\
> +UINT32 paramSize;\
> +const TPM_COMMAND_CODE ordinal = ORD;\
> +TPM_RESULT status = TPM_SUCCESS;\
> +BYTE in_buf[TCPA_MAX_BUFFER_LENGTH];\
> +BYTE out_buf[TCPA_MAX_BUFFER_LENGTH];\
> +UINT32 out_len = sizeof(out_buf);\
> +BYTE* ptr = in_buf;\
> +/*Print a log message */\
> +vtpmloginfo(VTPM_LOG_TPM, "%s\n", __func__);\
> +/* Pack the header*/\
> +ptr = pack_TPM_TAG(ptr, tag);\
> +ptr += sizeof(UINT32);\
> +ptr = pack_TPM_COMMAND_CODE(ptr, ordinal)\
> +
> +#define TPM_AUTH_BEGIN() \
> +   sha1_context sha1_ctx;\
> +BYTE* authbase = ptr - sizeof(TPM_COMMAND_CODE);\
> +TPM_DIGEST paramDigest;\
> +sha1_starts(&sha1_ctx)
> +
> +#define TPM_AUTH1_GEN(HMACkey, auth) do {\
> +   sha1_finish(&sha1_ctx, paramDigest.digest);\
> +   generateAuth(&paramDigest, HMACkey, auth);\
> +   ptr = pack_TPM_AUTH_SESSION(ptr, auth);\
> +} while(0)
> +
> +#define TPM_AUTH2_GEN(HMACkey, auth) do {\
> +   generateAuth(&paramDigest, HMACkey, auth);\
> +   ptr = pack_TPM_AUTH_SESSION(ptr, auth);\
> +} while(0)
> +
> +#define TPM_TRANSMIT() do {\
> +   /* Pack the command size */\
> +   paramSize = ptr - in_buf;\
> +   pack_UINT32(in_buf + sizeof(TPM_TAG), paramSize);\
> +   if((status = TPM_TransmitData(in_buf, paramSize, out_buf, &out_len)) != TPM_SUCCESS) {\
> +      goto abort_egress;\
> +   }\
> +} while(0)
> +
> +#define TPM_AUTH_VERIFY_BEGIN() do {\
> +   UINT32 buf[2] = { cpu_to_be32(status), cpu_to_be32(ordinal) };\
> +   sha1_starts(&sha1_ctx);\
> +   sha1_update(&sha1_ctx, (unsigned char*)buf, sizeof(buf));\
> +   authbase = ptr;\
> +} while(0)
> +
> +#define TPM_AUTH1_VERIFY(HMACkey, auth) do {\
> +   sha1_finish(&sha1_ctx, paramDigest.digest);\
> +   ptr = unpack_TPM_AUTH_SESSION(ptr, auth);\
> +   if((status = verifyAuth(&paramDigest, HMACkey, auth)) != TPM_SUCCESS) {\
> +      goto abort_egress;\
> +   }\
> +} while(0)
> +
> +#define TPM_AUTH2_VERIFY(HMACkey, auth) do {\
> +   ptr = unpack_TPM_AUTH_SESSION(ptr, auth);\
> +   if((status = verifyAuth(&paramDigest, HMACkey, auth)) != TPM_SUCCESS) {\
> +      goto abort_egress;\
> +   }\
> +} while(0)
> +
> +
> +
> +#define TPM_UNPACK_VERIFY() do { \
> +   ptr = out_buf;\
> +   ptr = unpack_TPM_RSP_HEADER(ptr, \
> +         &(tag), &(paramSize), &(status));\
> +   if((status) != TPM_SUCCESS || (tag) != (intag +3)) { \
> +      vtpmlogerror(VTPM_LOG_TPM, "Failed with return code %s\n", tpm_get_error_name(status));\
> +      goto abort_egress;\
> +   }\
> +} while(0)
> +
> +#define TPM_AUTH_HASH() do {\
> +   sha1_update(&sha1_ctx, authbase, ptr - authbase);\
> +   authbase = ptr;\
> +} while(0)
> +
> +#define TPM_AUTH_SKIP() do {\
> +   authbase = ptr;\
> +} while(0)
> +
> +#define TPM_AUTH_ERR_CHECK(auth) do {\
> +   if(status != TPM_SUCCESS || auth->fContinueAuthSession == FALSE) {\
> +      vtpmloginfo(VTPM_LOG_TPM, "Auth Session: 0x%x closed by TPM\n", auth->AuthHandle);\
> +      auth->AuthHandle = 0;\
> +   }\
> +} while(0)
> +
> +static void xorEncrypt(const TPM_SECRET* sharedSecret,
> +      TPM_NONCE* nonce,
> +      const TPM_AUTHDATA* inAuth0,
> +      TPM_ENCAUTH outAuth0,
> +      const TPM_AUTHDATA* inAuth1,
> +      TPM_ENCAUTH outAuth1) {
> +   BYTE XORbuffer[sizeof(TPM_SECRET) + sizeof(TPM_NONCE)];
> +   BYTE XORkey[TPM_DIGEST_SIZE];
> +   BYTE* ptr = XORbuffer;
> +   ptr = pack_TPM_SECRET(ptr, sharedSecret);
> +   ptr = pack_TPM_NONCE(ptr, nonce);
> +
> +   sha1(XORbuffer, ptr - XORbuffer, XORkey);
> +
> +   if(inAuth0) {
> +      for(int i = 0; i < TPM_DIGEST_SIZE; ++i) {
> +         outAuth0[i] = XORkey[i] ^ (*inAuth0)[i];
> +      }
> +   }
> +   if(inAuth1) {
> +      for(int i = 0; i < TPM_DIGEST_SIZE; ++i) {
> +         outAuth1[i] = XORkey[i] ^ (*inAuth1)[i];
> +      }
> +   }
> +
> +}
> +
> +static void generateAuth(const TPM_DIGEST* paramDigest,
> +      const TPM_SECRET* HMACkey,
> +      TPM_AUTH_SESSION *auth)
> +{
> +   //Generate new OddNonce
> +   vtpmmgr_rand((BYTE*)auth->NonceOdd.nonce, sizeof(TPM_NONCE));
> +
> +   // Create HMAC text. (Concat inParamsDigest with inAuthSetupParams).
> +   BYTE hmacText[sizeof(TPM_DIGEST) + (2 * sizeof(TPM_NONCE)) + sizeof(BOOL)];
> +   BYTE* ptr = hmacText;
> +
> +   ptr = pack_TPM_DIGEST(ptr, paramDigest);
> +   ptr = pack_TPM_NONCE(ptr, &auth->NonceEven);
> +   ptr = pack_TPM_NONCE(ptr, &auth->NonceOdd);
> +   ptr = pack_BOOL(ptr, auth->fContinueAuthSession);
> +
> +   sha1_hmac((BYTE *) HMACkey, sizeof(TPM_DIGEST),
> +         (BYTE *) hmacText, sizeof(hmacText),
> +         auth->HMAC);
> +}
> +
> +static TPM_RESULT verifyAuth(const TPM_DIGEST* paramDigest,
> +      /*[IN]*/ const TPM_SECRET *HMACkey,
> +      /*[IN,OUT]*/ TPM_AUTH_SESSION *auth)
> +{
> +
> +   // Create HMAC text. (Concat inParamsDigest with inAuthSetupParams).
> +   TPM_AUTHDATA hm;
> +   BYTE hmacText[sizeof(TPM_DIGEST) + (2 * sizeof(TPM_NONCE)) + sizeof(BOOL)];
> +   BYTE* ptr = hmacText;
> +
> +   ptr = pack_TPM_DIGEST(ptr, paramDigest);
> +   ptr = pack_TPM_NONCE(ptr, &auth->NonceEven);
> +   ptr = pack_TPM_NONCE(ptr, &auth->NonceOdd);
> +   ptr = pack_BOOL(ptr, auth->fContinueAuthSession);
> +
> +   sha1_hmac( (BYTE *) HMACkey, sizeof(TPM_DIGEST),
> +         (BYTE *) hmacText, sizeof(hmacText),
> +         hm);
> +
> +   // Compare correct HMAC with provided one.
> +   if (memcmp(hm, auth->HMAC, sizeof(TPM_DIGEST)) == 0) { // 0 indicates equality
> +      return TPM_SUCCESS;
> +   } else {
> +      vtpmlogerror(VTPM_LOG_TPM, "Auth Session verification failed!\n");
> +      return TPM_AUTHFAIL;
> +   }
> +}
> +
> +
> +
> +// ------------------------------------------------------------------
> +// Authorization Commands
> +// ------------------------------------------------------------------
> +
> +TPM_RESULT TPM_OIAP(TPM_AUTH_SESSION*   auth)  // out
> +{
> +   TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_OIAP);
> +
> +   TPM_TRANSMIT();
> +   TPM_UNPACK_VERIFY();
> +
> +   memset(&auth->HMAC, 0, sizeof(TPM_DIGEST));
> +   auth->fContinueAuthSession = TRUE;
> +
> +   ptr = unpack_UINT32(ptr, &auth->AuthHandle);
> +   ptr = unpack_TPM_NONCE(ptr, &auth->NonceEven);
> +
> +   vtpmloginfo(VTPM_LOG_TPM, "Auth Session: 0x%x opened by TPM_OIAP.\n", auth->AuthHandle);
> +
> +abort_egress:
> +   return status;
> +}
> +
> +TPM_RESULT TPM_OSAP(TPM_ENTITY_TYPE  entityType,  // in
> +      UINT32    entityValue, // in
> +      const TPM_AUTHDATA* usageAuth, //in
> +      TPM_SECRET *sharedSecret, //out
> +      TPM_AUTH_SESSION *auth)
> +{
> +   BYTE* nonceOddOSAP;
> +   TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_OSAP);
> +
> +   ptr = pack_TPM_ENTITY_TYPE(ptr, entityType);
> +   ptr = pack_UINT32(ptr, entityValue);
> +
> +   //nonce Odd OSAP
> +   nonceOddOSAP = ptr;
> +   vtpmmgr_rand(ptr, TPM_DIGEST_SIZE);
> +   ptr += TPM_DIGEST_SIZE;
> +
> +   TPM_TRANSMIT();
> +   TPM_UNPACK_VERIFY();
> +
> +   ptr = unpack_UINT32(ptr, &auth->AuthHandle);
> +   ptr = unpack_TPM_NONCE(ptr, &auth->NonceEven);
> +
> +   //Calculate session secret
> +   sha1_context ctx;
> +   sha1_hmac_starts(&ctx, *usageAuth, TPM_DIGEST_SIZE);
> +   sha1_hmac_update(&ctx, ptr, TPM_DIGEST_SIZE); //ptr = nonceEvenOSAP
> +   sha1_hmac_update(&ctx, nonceOddOSAP, TPM_DIGEST_SIZE);
> +   sha1_hmac_finish(&ctx, *sharedSecret);
> +
> +   memset(&auth->HMAC, 0, sizeof(TPM_DIGEST));
> +   auth->fContinueAuthSession = FALSE;
> +
> +   vtpmloginfo(VTPM_LOG_TPM, "Auth Session: 0x%x opened by TPM_OSAP.\n", auth->AuthHandle);
> +
> +abort_egress:
> +   return status;
> +}
> +
> +TPM_RESULT TPM_TakeOwnership(
> +      const TPM_PUBKEY *pubEK, //in
> +      const TPM_AUTHDATA* ownerAuth, //in
> +      const TPM_AUTHDATA* srkAuth, //in
> +      const TPM_KEY* inSrk, //in
> +      TPM_KEY* outSrk, //out, optional
> +      TPM_AUTH_SESSION*   auth)   // in, out
> +{
> +   int keyAlloced = 0;
> +   tpmrsa_context ek_rsa = TPMRSA_CTX_INIT;
> +
> +   TPM_BEGIN(TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_TakeOwnership);
> +   TPM_AUTH_BEGIN();
> +
> +   tpmrsa_set_pubkey(&ek_rsa,
> +         pubEK->pubKey.key, pubEK->pubKey.keyLength,
> +         pubEK->algorithmParms.parms.rsa.exponent,
> +         pubEK->algorithmParms.parms.rsa.exponentSize);
> +
> +   /* Pack the protocol ID */
> +   ptr = pack_UINT16(ptr, TPM_PID_OWNER);
> +
> +   /* Pack the encrypted owner auth */
> +   ptr = pack_UINT32(ptr, pubEK->algorithmParms.parms.rsa.keyLength / 8);
> +   tpmrsa_pub_encrypt_oaep(&ek_rsa,
> +         ctr_drbg_random, &vtpm_globals.ctr_drbg,
> +         sizeof(TPM_SECRET),
> +         (BYTE*) ownerAuth,
> +         ptr);
> +   ptr += pubEK->algorithmParms.parms.rsa.keyLength / 8;
> +
> +   /* Pack the encrypted srk auth */
> +   ptr = pack_UINT32(ptr, pubEK->algorithmParms.parms.rsa.keyLength / 8);
> +   tpmrsa_pub_encrypt_oaep(&ek_rsa,
> +         ctr_drbg_random, &vtpm_globals.ctr_drbg,
> +         sizeof(TPM_SECRET),
> +         (BYTE*) srkAuth,
> +         ptr);
> +   ptr += pubEK->algorithmParms.parms.rsa.keyLength / 8;
> +
> +   /* Pack the Srk key */
> +   ptr = pack_TPM_KEY(ptr, inSrk);
> +
> +   /* Hash everything up to here */
> +   TPM_AUTH_HASH();
> +
> +   /* Generate the authorization */
> +   TPM_AUTH1_GEN(ownerAuth, auth);
> +
> +   /* Send the command to the tpm*/
> +   TPM_TRANSMIT();
> +   /* Unpack and validate the header */
> +   TPM_UNPACK_VERIFY();
> +   TPM_AUTH_VERIFY_BEGIN();
> +
> +   if(outSrk != NULL) {
> +      /* If the user wants a copy of the srk we give it to them */
> +      keyAlloced = 1;
> +      ptr = unpack_TPM_KEY(ptr, outSrk, UNPACK_ALLOC);
> +   } else {
> +      /*otherwise just parse past it */
> +      TPM_KEY temp;
> +      ptr = unpack_TPM_KEY(ptr, &temp, UNPACK_ALIAS);
> +   }
> +
> +   /* Hash the output key */
> +   TPM_AUTH_HASH();
> +
> +   /* Verify authorizaton */
> +   TPM_AUTH1_VERIFY(ownerAuth, auth);
> +
> +   goto egress;
> +abort_egress:
> +   if(keyAlloced) {
> +      free_TPM_KEY(outSrk);
> +   }
> +egress:
> +   tpmrsa_free(&ek_rsa);
> +   TPM_AUTH_ERR_CHECK(auth);
> +   return status;
> +}
> +
> +
> +TPM_RESULT TPM_DisablePubekRead (
> +      const TPM_AUTHDATA* ownerAuth,
> +      TPM_AUTH_SESSION*   auth)
> +{
> +   TPM_BEGIN(TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_DisablePubekRead);
> +   TPM_AUTH_BEGIN();
> +
> +   TPM_AUTH_HASH();
> +
> +   TPM_AUTH1_GEN(ownerAuth, auth);
> +   TPM_TRANSMIT();
> +   TPM_UNPACK_VERIFY();
> +   TPM_AUTH_VERIFY_BEGIN();
> +
> +   TPM_AUTH1_VERIFY(ownerAuth, auth);
> +
> +abort_egress:
> +   TPM_AUTH_ERR_CHECK(auth);
> +   return status;
> +}
> +
> +
> +TPM_RESULT TPM_TerminateHandle(TPM_AUTHHANDLE  handle)  // in
> +{
> +   if(handle == 0) {
> +      return TPM_SUCCESS;
> +   }
> +
> +   TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_Terminate_Handle);
> +
> +   ptr = pack_TPM_AUTHHANDLE(ptr, handle);
> +
> +   TPM_TRANSMIT();
> +   TPM_UNPACK_VERIFY();
> +
> +   vtpmloginfo(VTPM_LOG_TPM, "Auth Session: 0x%x closed by TPM_TerminateHandle\n", handle);
> +
> +abort_egress:
> +   return status;
> +}
> +
> +TPM_RESULT TPM_Extend( TPM_PCRINDEX  pcrNum,  // in
> +      TPM_DIGEST  inDigest, // in
> +      TPM_PCRVALUE*  outDigest) // out
> +{
> +   TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_Extend);
> +
> +   ptr = pack_TPM_PCRINDEX(ptr, pcrNum);
> +   ptr = pack_TPM_DIGEST(ptr, &inDigest);
> +
> +   TPM_TRANSMIT();
> +   TPM_UNPACK_VERIFY();
> +
> +   ptr = unpack_TPM_PCRVALUE(ptr, outDigest);
> +
> +abort_egress:
> +   return status;
> +}
> +
> +TPM_RESULT TPM_Seal(
> +      TPM_KEY_HANDLE  keyHandle,  // in
> +      UINT32    pcrInfoSize, // in
> +      TPM_PCR_INFO*    pcrInfo,  // in
> +      UINT32    inDataSize,  // in
> +      const BYTE*    inData,   // in
> +      TPM_STORED_DATA* sealedData, //out
> +      const TPM_SECRET* osapSharedSecret, //in
> +      const TPM_AUTHDATA* sealedDataAuth, //in
> +      TPM_AUTH_SESSION*   pubAuth  // in, out
> +      )
> +{
> +   int dataAlloced = 0;
> +   TPM_BEGIN(TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_Seal);
> +   TPM_AUTH_BEGIN();
> +
> +   TPM_AUTH_HASH();
> +
> +   ptr = pack_TPM_KEY_HANDLE(ptr, keyHandle);
> +
> +   TPM_AUTH_SKIP();
> +
> +   xorEncrypt(osapSharedSecret, &pubAuth->NonceEven,
> +         sealedDataAuth, ptr,
> +         NULL, NULL);
> +   ptr += sizeof(TPM_ENCAUTH);
> +
> +   ptr = pack_UINT32(ptr, pcrInfoSize);
> +   ptr = pack_TPM_PCR_INFO(ptr, pcrInfo);
> +
> +   ptr = pack_UINT32(ptr, inDataSize);
> +   ptr = pack_BUFFER(ptr, inData, inDataSize);
> +
> +   TPM_AUTH_HASH();
> +
> +   TPM_AUTH1_GEN(osapSharedSecret, pubAuth);
> +   TPM_TRANSMIT();
> +   TPM_UNPACK_VERIFY();
> +   TPM_AUTH_VERIFY_BEGIN();
> +
> +   ptr = unpack_TPM_STORED_DATA(ptr, sealedData, UNPACK_ALLOC);
> +   dataAlloced = 1;
> +
> +   TPM_AUTH_HASH();
> +
> +   TPM_AUTH1_VERIFY(osapSharedSecret, pubAuth);
> +
> +   goto egress;
> +abort_egress:
> +   if(dataAlloced) {
> +      free_TPM_STORED_DATA(sealedData);
> +   }
> +egress:
> +   TPM_AUTH_ERR_CHECK(pubAuth);
> +   return status;
> +}
> +
> +TPM_RESULT TPM_Unseal(
> +      TPM_KEY_HANDLE parentHandle, // in
> +      const TPM_STORED_DATA* sealedData,
> +      UINT32*   outSize,  // out
> +      BYTE**    out, //out
> +      const TPM_AUTHDATA* key_usage_auth, //in
> +      const TPM_AUTHDATA* data_usage_auth, //in
> +      TPM_AUTH_SESSION*   keyAuth,  // in, out
> +      TPM_AUTH_SESSION*   dataAuth  // in, out
> +      )
> +{
> +   TPM_BEGIN(TPM_TAG_RQU_AUTH2_COMMAND, TPM_ORD_Unseal);
> +   TPM_AUTH_BEGIN();
> +
> +   TPM_AUTH_HASH();
> +
> +   ptr = pack_TPM_KEY_HANDLE(ptr, parentHandle);
> +
> +   TPM_AUTH_SKIP();
> +
> +   ptr = pack_TPM_STORED_DATA(ptr, sealedData);
> +
> +   TPM_AUTH_HASH();
> +
> +   TPM_AUTH1_GEN(key_usage_auth, keyAuth);
> +   TPM_AUTH2_GEN(data_usage_auth, dataAuth);
> +   TPM_TRANSMIT();
> +   TPM_UNPACK_VERIFY();
> +   TPM_AUTH_VERIFY_BEGIN();
> +
> +   ptr = unpack_UINT32(ptr, outSize);
> +   ptr = unpack_ALLOC(ptr, out, *outSize);
> +
> +   TPM_AUTH_HASH();
> +
> +   TPM_AUTH1_VERIFY(key_usage_auth, keyAuth);
> +   TPM_AUTH2_VERIFY(data_usage_auth, dataAuth);
> +
> +abort_egress:
> +   TPM_AUTH_ERR_CHECK(keyAuth);
> +   TPM_AUTH_ERR_CHECK(dataAuth);
> +   return status;
> +}
> +
> +TPM_RESULT TPM_Bind(
> +      const TPM_KEY* key,
> +      const BYTE* in,
> +      UINT32 ilen,
> +      BYTE* out)
> +{
> +   TPM_RESULT status;
> +   tpmrsa_context rsa = TPMRSA_CTX_INIT;
> +   TPM_BOUND_DATA boundData;
> +   uint8_t plain[TCPA_MAX_BUFFER_LENGTH];
> +   BYTE* ptr = plain;
> +
> +   vtpmloginfo(VTPM_LOG_TPM, "%s\n", __func__);
> +
> +   tpmrsa_set_pubkey(&rsa,
> +         key->pubKey.key, key->pubKey.keyLength,
> +         key->algorithmParms.parms.rsa.exponent,
> +         key->algorithmParms.parms.rsa.exponentSize);
> +
> +   // Fill boundData's accessory information
> +   boundData.ver = TPM_STRUCT_VER_1_1;
> +   boundData.payload = TPM_PT_BIND;
> +   boundData.payloadData = (BYTE*)in;
> +
> +   //marshall the bound data object
> +   ptr = pack_TPM_BOUND_DATA(ptr, &boundData, ilen);
> +
> +   // Encrypt the data
> +   TPMTRYRETURN(tpmrsa_pub_encrypt_oaep(&rsa,
> +            ctr_drbg_random, &vtpm_globals.ctr_drbg,
> +            ptr - plain,
> +            plain,
> +            out));
> +
> +abort_egress:
> +   tpmrsa_free(&rsa);
> +   return status;
> +
> +}
> +
> +TPM_RESULT TPM_UnBind(
> +      TPM_KEY_HANDLE  keyHandle,  // in
> +      UINT32 ilen, //in
> +      const BYTE* in, //
> +      UINT32* olen, //
> +      BYTE*    out, //out
> +      const TPM_AUTHDATA* usage_auth,
> +      TPM_AUTH_SESSION* auth //in, out
> +      )
> +{
> +   TPM_BEGIN(TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_UnBind);
> +   TPM_AUTH_BEGIN();
> +
> +   TPM_AUTH_HASH();
> +
> +   ptr = pack_TPM_KEY_HANDLE(ptr, keyHandle);
> +
> +   TPM_AUTH_SKIP();
> +
> +   ptr = pack_UINT32(ptr, ilen);
> +   ptr = pack_BUFFER(ptr, in, ilen);
> +
> +   TPM_AUTH_HASH();
> +
> +   TPM_AUTH1_GEN(usage_auth, auth);
> +   TPM_TRANSMIT();
> +   TPM_UNPACK_VERIFY();
> +   TPM_AUTH_VERIFY_BEGIN();
> +
> +   ptr = unpack_UINT32(ptr, olen);
> +   if(*olen > ilen) {
> +      vtpmlogerror(VTPM_LOG_TPM, "Output length < input length!\n");
> +      status = TPM_IOERROR;
> +      goto abort_egress;
> +   }
> +   ptr = unpack_BUFFER(ptr, out, *olen);
> +
> +   TPM_AUTH_HASH();
> +
> +   TPM_AUTH1_VERIFY(usage_auth, auth);
> +
> +abort_egress:
> +egress:
> +   TPM_AUTH_ERR_CHECK(auth);
> +   return status;
> +}
> +
> +TPM_RESULT TPM_CreateWrapKey(
> +      TPM_KEY_HANDLE  hWrappingKey,  // in
> +      const TPM_AUTHDATA* osapSharedSecret,
> +      const TPM_AUTHDATA* dataUsageAuth, //in
> +      const TPM_AUTHDATA* dataMigrationAuth, //in
> +      TPM_KEY*     key, //in, out
> +      TPM_AUTH_SESSION*   pAuth)    // in, out
> +{
> +   int keyAlloced = 0;
> +   TPM_BEGIN(TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_CreateWrapKey);
> +   TPM_AUTH_BEGIN();
> +
> +   TPM_AUTH_HASH();
> +
> +   ptr = pack_TPM_KEY_HANDLE(ptr, hWrappingKey);
> +
> +   TPM_AUTH_SKIP();
> +
> +   //Encrypted auths
> +   xorEncrypt(osapSharedSecret, &pAuth->NonceEven,
> +         dataUsageAuth, ptr,
> +         dataMigrationAuth, ptr + sizeof(TPM_ENCAUTH));
> +   ptr += sizeof(TPM_ENCAUTH) * 2;
> +
> +   ptr = pack_TPM_KEY(ptr, key);
> +
> +   TPM_AUTH_HASH();
> +
> +   TPM_AUTH1_GEN(osapSharedSecret, pAuth);
> +   TPM_TRANSMIT();
> +   TPM_UNPACK_VERIFY();
> +   TPM_AUTH_VERIFY_BEGIN();
> +
> +   keyAlloced = 1;
> +   ptr = unpack_TPM_KEY(ptr, key, UNPACK_ALLOC);
> +
> +   TPM_AUTH_HASH();
> +
> +   TPM_AUTH1_VERIFY(osapSharedSecret, pAuth);
> +
> +   goto egress;
> +abort_egress:
> +   if(keyAlloced) {
> +      free_TPM_KEY(key);
> +   }
> +egress:
> +   TPM_AUTH_ERR_CHECK(pAuth);
> +   return status;
> +}
> +
> +TPM_RESULT TPM_LoadKey(
> +      TPM_KEY_HANDLE  parentHandle, //
> +      const TPM_KEY* key, //in
> +      TPM_HANDLE*  keyHandle,    // out
> +      const TPM_AUTHDATA* usage_auth,
> +      TPM_AUTH_SESSION* auth)
> +{
> +   TPM_BEGIN(TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_LoadKey);
> +   TPM_AUTH_BEGIN();
> +
> +   TPM_AUTH_HASH();
> +
> +   ptr = pack_TPM_KEY_HANDLE(ptr, parentHandle);
> +
> +   TPM_AUTH_SKIP();
> +
> +   ptr = pack_TPM_KEY(ptr, key);
> +
> +   TPM_AUTH_HASH();
> +
> +   TPM_AUTH1_GEN(usage_auth, auth);
> +   TPM_TRANSMIT();
> +   TPM_UNPACK_VERIFY();
> +   TPM_AUTH_VERIFY_BEGIN();
> +
> +   ptr = unpack_UINT32(ptr, keyHandle);
> +
> +   TPM_AUTH_HASH();
> +
> +   TPM_AUTH1_VERIFY(usage_auth, auth);
> +
> +   vtpmloginfo(VTPM_LOG_TPM, "Key Handle: 0x%x opened by TPM_LoadKey\n", *keyHandle);
> +
> +abort_egress:
> +   TPM_AUTH_ERR_CHECK(auth);
> +   return status;
> +}
> +
> +TPM_RESULT TPM_EvictKey( TPM_KEY_HANDLE  hKey)  // in
> +{
> +   if(hKey == 0) {
> +      return TPM_SUCCESS;
> +   }
> +
> +   TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_EvictKey);
> +
> +   ptr = pack_TPM_KEY_HANDLE(ptr, hKey);
> +
> +   TPM_TRANSMIT();
> +   TPM_UNPACK_VERIFY();
> +
> +   vtpmloginfo(VTPM_LOG_TPM, "Key handle: 0x%x closed by TPM_EvictKey\n", hKey);
> +
> +abort_egress:
> +   return status;
> +}
> +
> +TPM_RESULT TPM_FlushSpecific(TPM_HANDLE handle,
> +      TPM_RESOURCE_TYPE rt) {
> +   if(handle == 0) {
> +      return TPM_SUCCESS;
> +   }
> +
> +   TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_FlushSpecific);
> +
> +   ptr = pack_TPM_HANDLE(ptr, handle);
> +   ptr = pack_TPM_RESOURCE_TYPE(ptr, rt);
> +
> +   TPM_TRANSMIT();
> +   TPM_UNPACK_VERIFY();
> +
> +abort_egress:
> +   return status;
> +}
> +
> +TPM_RESULT TPM_GetRandom( UINT32*    bytesRequested, // in, out
> +      BYTE*    randomBytes) // out
> +{
> +   TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_GetRandom);
> +
> +   // check input params
> +   if (bytesRequested == NULL || randomBytes == NULL){
> +      return TPM_BAD_PARAMETER;
> +   }
> +
> +   ptr = pack_UINT32(ptr, *bytesRequested);
> +
> +   TPM_TRANSMIT();
> +   TPM_UNPACK_VERIFY();
> +
> +   ptr = unpack_UINT32(ptr, bytesRequested);
> +   ptr = unpack_BUFFER(ptr, randomBytes, *bytesRequested);
> +
> +abort_egress:
> +   return status;
> +}
> +
> +
> +TPM_RESULT TPM_ReadPubek(
> +      TPM_PUBKEY* pubEK //out
> +      )
> +{
> +   BYTE* antiReplay = NULL;
> +   BYTE* kptr = NULL;
> +   BYTE digest[TPM_DIGEST_SIZE];
> +   sha1_context ctx;
> +
> +   TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_ReadPubek);
> +
> +   //antiReplay nonce
> +   vtpmmgr_rand(ptr, TPM_DIGEST_SIZE);
> +   antiReplay = ptr;
> +   ptr += TPM_DIGEST_SIZE;
> +
> +   TPM_TRANSMIT();
> +   TPM_UNPACK_VERIFY();
> +
> +   //unpack and allocate the key
> +   kptr = ptr;
> +   ptr = unpack_TPM_PUBKEY(ptr, pubEK, UNPACK_ALLOC);
> +
> +   //Verify the checksum
> +   sha1_starts(&ctx);
> +   sha1_update(&ctx, kptr, ptr - kptr);
> +   sha1_update(&ctx, antiReplay, TPM_DIGEST_SIZE);
> +   sha1_finish(&ctx, digest);
> +
> +   //ptr points to the checksum computed by TPM
> +   if(memcmp(digest, ptr, TPM_DIGEST_SIZE)) {
> +      vtpmlogerror(VTPM_LOG_TPM, "TPM_ReadPubek: Checksum returned by TPM was invalid!\n");
> +      status = TPM_FAIL;
> +      goto abort_egress;
> +   }
> +
> +   goto egress;
> +abort_egress:
> +   if(kptr != NULL) { //If we unpacked the pubEK, we have to free it
> +      free_TPM_PUBKEY(pubEK);
> +   }
> +egress:
> +   return status;
> +}
> +
> +
> +TPM_RESULT TPM_SaveState(void)
> +{
> +   TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_SaveState);
> +
> +   TPM_TRANSMIT();
> +   TPM_UNPACK_VERIFY();
> +
> +abort_egress:
> +   return status;
> +}
> +
> +TPM_RESULT TPM_GetCapability(
> +      TPM_CAPABILITY_AREA capArea,
> +      UINT32 subCapSize,
> +      const BYTE* subCap,
> +      UINT32* respSize,
> +      BYTE** resp)
> +{
> +   TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_GetCapability);
> +
> +   ptr = pack_TPM_CAPABILITY_AREA(ptr, capArea);
> +   ptr = pack_UINT32(ptr, subCapSize);
> +   ptr = pack_BUFFER(ptr, subCap, subCapSize);
> +
> +   TPM_TRANSMIT();
> +   TPM_UNPACK_VERIFY();
> +
> +   ptr = unpack_UINT32(ptr, respSize);
> +   ptr = unpack_ALLOC(ptr, resp, *respSize);
> +
> +abort_egress:
> +   return status;
> +}
> +
> +TPM_RESULT TPM_CreateEndorsementKeyPair(
> +      const TPM_KEY_PARMS* keyInfo,
> +      TPM_PUBKEY* pubEK)
> +{
> +   BYTE* kptr = NULL;
> +   sha1_context ctx;
> +   TPM_DIGEST checksum;
> +   TPM_DIGEST hash;
> +   TPM_NONCE antiReplay;
> +   TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_CreateEndorsementKeyPair);
> +
> +   //Make anti replay nonce
> +   vtpmmgr_rand(antiReplay.nonce, sizeof(antiReplay.nonce));
> +
> +   ptr = pack_TPM_NONCE(ptr, &antiReplay);
> +   ptr = pack_TPM_KEY_PARMS(ptr, keyInfo);
> +
> +   TPM_TRANSMIT();
> +   TPM_UNPACK_VERIFY();
> +
> +   sha1_starts(&ctx);
> +
> +   kptr = ptr;
> +   ptr = unpack_TPM_PUBKEY(ptr, pubEK, UNPACK_ALLOC);
> +
> +   /* Hash the pub key blob */
> +   sha1_update(&ctx, kptr, ptr - kptr);
> +   ptr = unpack_TPM_DIGEST(ptr, &checksum);
> +
> +   sha1_update(&ctx, antiReplay.nonce, sizeof(antiReplay.nonce));
> +
> +   sha1_finish(&ctx, hash.digest);
> +   if(memcmp(checksum.digest, hash.digest, TPM_DIGEST_SIZE)) {
> +      vtpmloginfo(VTPM_LOG_VTPM, "TPM_CreateEndorsementKey: Checkum verification failed!\n");
> +      status = TPM_FAIL;
> +      goto abort_egress;
> +   }
> +
> +   goto egress;
> +abort_egress:
> +   if(kptr) {
> +      free_TPM_PUBKEY(pubEK);
> +   }
> +egress:
> +   return status;
> +}
> +
> +TPM_RESULT TPM_TransmitData(
> +      BYTE* in,
> +      UINT32 insize,
> +      BYTE* out,
> +      UINT32* outsize) {
> +   TPM_RESULT status = TPM_SUCCESS;
> +
> +   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;
> +
> +   // send the request
> +   size = write (vtpm_globals.tpm_fd, in, insize);
> +   if (size < 0) {
> +      vtpmlogerror(VTPM_LOG_TXDATA, "write() failed : %s\n", strerror(errno));
> +      ERRORDIE (TPM_IOERROR);
> +   }
> +   else if ((UINT32) size < insize) {
> +      vtpmlogerror(VTPM_LOG_TXDATA, "Wrote %d instead of %d bytes!\n", (int) size, insize);
> +      ERRORDIE (TPM_IOERROR);
> +   }
> +
> +   // read the response
> +   size = read (vtpm_globals.tpm_fd, out, *outsize);
> +   if (size < 0) {
> +      vtpmlogerror(VTPM_LOG_TXDATA, "read() failed : %s\n", strerror(errno));
> +      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;
> +   goto egress;
> +
> +abort_egress:
> +egress:
> +   return status;
> +}
> diff --git a/stubdom/vtpmmgr/tpm.h b/stubdom/vtpmmgr/tpm.h
> new file mode 100644
> index 0000000..304e145
> --- /dev/null
> +++ b/stubdom/vtpmmgr/tpm.h
> @@ -0,0 +1,218 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * based off of the original tools/vtpm_manager code base which is:
> + * Copyright (c) 2005/2006, 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 __TPM_H__
> +#define __TPM_H__
> +
> +#include "tcg.h"
> +
> +// ------------------------------------------------------------------
> +// Exposed API
> +// ------------------------------------------------------------------
> +
> +// TPM v1.1B Command Set
> +
> +// Authorzation
> +TPM_RESULT TPM_OIAP(
> +      TPM_AUTH_SESSION*   auth //out
> +      );
> +
> +TPM_RESULT TPM_OSAP (
> +      TPM_ENTITY_TYPE entityType,  // in
> +      UINT32    entityValue, // in
> +      const TPM_AUTHDATA* usageAuth, //in
> +      TPM_SECRET *sharedSecret, //out
> +      TPM_AUTH_SESSION *auth);
> +
> +TPM_RESULT TPM_TakeOwnership(
> +      const TPM_PUBKEY *pubEK, //in
> +      const TPM_AUTHDATA* ownerAuth, //in
> +      const TPM_AUTHDATA* srkAuth, //in
> +      const TPM_KEY* inSrk, //in
> +      TPM_KEY* outSrk, //out, optional
> +      TPM_AUTH_SESSION*   auth   // in, out
> +      );
> +
> +TPM_RESULT TPM_DisablePubekRead (
> +      const TPM_AUTHDATA* ownerAuth,
> +      TPM_AUTH_SESSION*   auth
> +      );
> +
> +TPM_RESULT TPM_TerminateHandle ( TPM_AUTHHANDLE  handle  // in
> +      );
> +
> +TPM_RESULT TPM_FlushSpecific ( TPM_HANDLE  handle,  // in
> +      TPM_RESOURCE_TYPE resourceType //in
> +      );
> +
> +// TPM Mandatory
> +TPM_RESULT TPM_Extend ( TPM_PCRINDEX  pcrNum,  // in
> +      TPM_DIGEST   inDigest, // in
> +      TPM_PCRVALUE*   outDigest // out
> +      );
> +
> +TPM_RESULT TPM_PcrRead ( TPM_PCRINDEX  pcrNum,  // in
> +      TPM_PCRVALUE*  outDigest // out
> +      );
> +
> +TPM_RESULT TPM_Quote ( TCS_KEY_HANDLE  keyHandle,  // in
> +      TPM_NONCE   antiReplay,  // in
> +      UINT32*    PcrDataSize, // in, out
> +      BYTE**    PcrData,  // in, out
> +      TPM_AUTH_SESSION*   privAuth,  // in, out
> +      UINT32*    sigSize,  // out
> +      BYTE**    sig    // out
> +      );
> +
> +TPM_RESULT TPM_Seal(
> +      TCS_KEY_HANDLE  keyHandle,  // in
> +      UINT32    pcrInfoSize, // in
> +      TPM_PCR_INFO*    pcrInfo,  // in
> +      UINT32    inDataSize,  // in
> +      const BYTE*    inData,   // in
> +      TPM_STORED_DATA* sealedData, //out
> +      const TPM_SECRET* osapSharedSecret, //in
> +      const TPM_AUTHDATA* sealDataAuth, //in
> +      TPM_AUTH_SESSION*   pubAuth  // in, out
> +      );
> +
> +TPM_RESULT TPM_Unseal (
> +      TPM_KEY_HANDLE parentHandle, // in
> +      const TPM_STORED_DATA* sealedData,
> +      UINT32*   outSize,  // out
> +      BYTE**    out, //out
> +      const TPM_AUTHDATA* key_usage_auth, //in
> +      const TPM_AUTHDATA* data_usage_auth, //in
> +      TPM_AUTH_SESSION*   keyAuth,  // in, out
> +      TPM_AUTH_SESSION*   dataAuth  // in, out
> +      );
> +
> +TPM_RESULT TPM_DirWriteAuth ( TPM_DIRINDEX  dirIndex,  // in
> +      TPM_DIRVALUE  newContents, // in
> +      TPM_AUTH_SESSION*   ownerAuth  // in, out
> +      );
> +
> +TPM_RESULT TPM_DirRead ( TPM_DIRINDEX  dirIndex, // in
> +      TPM_DIRVALUE*  dirValue // out
> +      );
> +
> +TPM_RESULT TPM_Bind(
> +      const TPM_KEY* key, //in
> +      const BYTE* in, //in
> +      UINT32 ilen, //in
> +      BYTE* out //out, must be at least cipher block size
> +      );
> +
> +TPM_RESULT TPM_UnBind (
> +      TCS_KEY_HANDLE  keyHandle,  // in
> +      UINT32 ilen, //in
> +      const BYTE* in, //
> +      UINT32*   outDataSize, // out
> +      BYTE*    outData, //out
> +      const TPM_AUTHDATA* usage_auth,
> +      TPM_AUTH_SESSION* auth //in, out
> +      );
> +
> +TPM_RESULT TPM_CreateWrapKey (
> +      TCS_KEY_HANDLE  hWrappingKey,  // in
> +      const TPM_AUTHDATA* osapSharedSecret,
> +      const TPM_AUTHDATA* dataUsageAuth, //in
> +      const TPM_AUTHDATA* dataMigrationAuth, //in
> +      TPM_KEY*     key, //in
> +      TPM_AUTH_SESSION*   pAuth    // in, out
> +      );
> +
> +TPM_RESULT TPM_LoadKey (
> +      TPM_KEY_HANDLE  parentHandle, //
> +      const TPM_KEY* key, //in
> +      TPM_HANDLE*  keyHandle,    // out
> +      const TPM_AUTHDATA* usage_auth,
> +      TPM_AUTH_SESSION* auth
> +      );
> +
> +TPM_RESULT TPM_GetPubKey (  TCS_KEY_HANDLE  hKey,   // in
> +      TPM_AUTH_SESSION*   pAuth,   // in, out
> +      UINT32*    pcPubKeySize, // out
> +      BYTE**    prgbPubKey  // out
> +      );
> +
> +TPM_RESULT TPM_EvictKey ( TCS_KEY_HANDLE  hKey  // in
> +      );
> +
> +TPM_RESULT TPM_FlushSpecific(TPM_HANDLE handle, //in
> +      TPM_RESOURCE_TYPE rt //in
> +      );
> +
> +TPM_RESULT TPM_Sign ( TCS_KEY_HANDLE  keyHandle,  // in
> +      UINT32    areaToSignSize, // in
> +      BYTE*    areaToSign,  // in
> +      TPM_AUTH_SESSION*   privAuth,  // in, out
> +      UINT32*    sigSize,  // out
> +      BYTE**    sig    // out
> +      );
> +
> +TPM_RESULT TPM_GetRandom (  UINT32*    bytesRequested, // in, out
> +      BYTE*    randomBytes  // out
> +      );
> +
> +TPM_RESULT TPM_StirRandom (  UINT32    inDataSize, // in
> +      BYTE*    inData  // in
> +      );
> +
> +TPM_RESULT TPM_ReadPubek (
> +      TPM_PUBKEY* pubEK //out
> +      );
> +
> +TPM_RESULT TPM_GetCapability(
> +      TPM_CAPABILITY_AREA capArea,
> +      UINT32 subCapSize,
> +      const BYTE* subCap,
> +      UINT32* respSize,
> +      BYTE** resp);
> +
> +TPM_RESULT TPM_SaveState(void);
> +
> +TPM_RESULT TPM_CreateEndorsementKeyPair(
> +      const TPM_KEY_PARMS* keyInfo,
> +      TPM_PUBKEY* pubEK);
> +
> +TPM_RESULT TPM_TransmitData(
> +      BYTE* in,
> +      UINT32 insize,
> +      BYTE* out,
> +      UINT32* outsize);
> +
> +#endif //TPM_H
> diff --git a/stubdom/vtpmmgr/tpmrsa.c b/stubdom/vtpmmgr/tpmrsa.c
> new file mode 100644
> index 0000000..56094e7
> --- /dev/null
> +++ b/stubdom/vtpmmgr/tpmrsa.c
> @@ -0,0 +1,175 @@
> +/*
> + *  The RSA public-key cryptosystem
> + *
> + *  Copyright (C) 2006-2011, Brainspark B.V.
> + *
> + *  This file is part of PolarSSL (http://www.polarssl.org)
> + *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
> + *
> + *  All rights reserved.
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License as published by
> + *  the Free Software Foundation; either version 2 of the License, or
> + *  (at your option) any later version.
> + *
> + *  This program is distributed in the hope that it will be useful,
> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *  GNU General Public License for more details.
> + *
> + *  You should have received a copy of the GNU General Public License along
> + *  with this program; if not, write to the Free Software Foundation, Inc.,
> + *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +/*
> + *  RSA was designed by Ron Rivest, Adi Shamir and Len Adleman.
> + *
> + *  http://theory.lcs.mit.edu/~rivest/rsapaper.pdf
> + *  http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf
> + */
> +
> +#include "tcg.h"
> +#include "polarssl/sha1.h"
> +
> +#include <stdlib.h>
> +#include <stdio.h>
> +
> +#include "tpmrsa.h"
> +
> +#define HASH_LEN 20
> +
> +void tpmrsa_set_pubkey(tpmrsa_context* ctx,
> +      const unsigned char* key,
> +      int keylen,
> +      const unsigned char* exponent,
> +      int explen) {
> +
> +   tpmrsa_free(ctx);
> +
> +   if(explen == 0) { //Default e= 2^16+1
> +      mpi_lset(&ctx->E, 65537);
> +   } else {
> +      mpi_read_binary(&ctx->E, exponent, explen);
> +   }
> +   mpi_read_binary(&ctx->N, key, keylen);
> +
> +   ctx->len = ( mpi_msb(&ctx->N) + 7) >> 3;
> +}
> +
> +static TPM_RESULT tpmrsa_public( tpmrsa_context *ctx,
> +      const unsigned char *input,
> +      unsigned char *output )
> +{
> +   int ret;
> +   size_t olen;
> +   mpi T;
> +
> +   mpi_init( &T );
> +
> +   MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
> +
> +   if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
> +   {
> +      mpi_free( &T );
> +      return TPM_ENCRYPT_ERROR;
> +   }
> +
> +   olen = ctx->len;
> +   MPI_CHK( mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
> +   MPI_CHK( mpi_write_binary( &T, output, olen ) );
> +
> +cleanup:
> +
> +   mpi_free( &T );
> +
> +   if( ret != 0 )
> +      return TPM_ENCRYPT_ERROR;
> +
> +   return TPM_SUCCESS;
> +}
> +
> +static void mgf_mask( unsigned char *dst, int dlen, unsigned char *src, int slen)
> +{
> +   unsigned char mask[HASH_LEN];
> +   unsigned char counter[4] = {0, 0, 0, 0};
> +   int i;
> +   sha1_context mctx;
> +
> +   //We always hash the src with the counter, so save the partial hash
> +   sha1_starts(&mctx);
> +   sha1_update(&mctx, src, slen);
> +
> +   // Generate and apply dbMask
> +   while(dlen > 0) {
> +      //Copy the sha1 context
> +      sha1_context ctx = mctx;
> +
> +      //compute hash for input || counter
> +      sha1_update(&ctx, counter, sizeof(counter));
> +      sha1_finish(&ctx, mask);
> +
> +      //Apply the mask
> +      for(i = 0; i < (dlen < HASH_LEN ? dlen : HASH_LEN); ++i) {
> +         *(dst++) ^= mask[i];
> +      }
> +
> +      //Increment counter
> +      ++counter[3];
> +
> +      dlen -= HASH_LEN;
> +   }
> +}
> +
> +/*
> + * Add the message padding, then do an RSA operation
> + */
> +TPM_RESULT tpmrsa_pub_encrypt_oaep( tpmrsa_context *ctx,
> +      int (*f_rng)(void *, unsigned char *, size_t),
> +      void *p_rng,
> +      size_t ilen,
> +      const unsigned char *input,
> +      unsigned char *output )
> +{
> +   int ret;
> +   int olen;
> +   unsigned char* seed = output + 1;
> +   unsigned char* db = output + HASH_LEN +1;
> +
> +   olen = ctx->len-1;
> +
> +   if( f_rng == NULL )
> +      return TPM_ENCRYPT_ERROR;
> +
> +   if( ilen > olen - 2 * HASH_LEN - 1)
> +      return TPM_ENCRYPT_ERROR;
> +
> +   output[0] = 0;
> +
> +   //Encoding parameter p
> +   sha1((unsigned char*)"TCPA", 4, db);
> +
> +   //PS
> +   memset(db + HASH_LEN, 0,
> +         olen - ilen - 2 * HASH_LEN - 1);
> +
> +   //constant 1 byte
> +   db[olen - ilen - HASH_LEN -1] = 0x01;
> +
> +   //input string
> +   memcpy(db + olen - ilen - HASH_LEN,
> +         input, ilen);
> +
> +   //Generate random seed
> +   if( ( ret = f_rng( p_rng, seed, HASH_LEN ) ) != 0 )
> +      return TPM_ENCRYPT_ERROR;
> +
> +   // maskedDB: Apply dbMask to DB
> +   mgf_mask( db, olen - HASH_LEN, seed, HASH_LEN);
> +
> +   // maskedSeed: Apply seedMask to seed
> +   mgf_mask( seed, HASH_LEN, db, olen - HASH_LEN);
> +
> +   // Do the crypto op
> +   return tpmrsa_public(ctx, output, output);
> +}
> diff --git a/stubdom/vtpmmgr/tpmrsa.h b/stubdom/vtpmmgr/tpmrsa.h
> new file mode 100644
> index 0000000..59579e7
> --- /dev/null
> +++ b/stubdom/vtpmmgr/tpmrsa.h
> @@ -0,0 +1,67 @@
> +/**
> + * \file rsa.h
> + *
> + * \brief The RSA public-key cryptosystem
> + *
> + *  Copyright (C) 2006-2010, Brainspark B.V.
> + *
> + *  This file is part of PolarSSL (http://www.polarssl.org)
> + *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
> + *
> + *  All rights reserved.
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License as published by
> + *  the Free Software Foundation; either version 2 of the License, or
> + *  (at your option) any later version.
> + *
> + *  This program is distributed in the hope that it will be useful,
> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *  GNU General Public License for more details.
> + *
> + *  You should have received a copy of the GNU General Public License along
> + *  with this program; if not, write to the Free Software Foundation, Inc.,
> + *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +#ifndef TPMRSA_H
> +#define TPMRSA_H
> +
> +#include "tcg.h"
> +#include <polarssl/bignum.h>
> +
> +/* tpm software key */
> +typedef struct
> +{
> +    size_t len;                 /*!<  size(N) in chars  */
> +
> +    mpi N;                      /*!<  public modulus    */
> +    mpi E;                      /*!<  public exponent   */
> +
> +    mpi RN;                     /*!<  cached R^2 mod N  */
> +}
> +tpmrsa_context;
> +
> +#define TPMRSA_CTX_INIT { 0, {0, 0, NULL}, {0, 0, NULL}, {0, 0, NULL}}
> +
> +/* Setup the rsa context using tpm public key data */
> +void tpmrsa_set_pubkey(tpmrsa_context* ctx,
> +      const unsigned char* key,
> +      int keylen,
> +      const unsigned char* exponent,
> +      int explen);
> +
> +/* Do rsa public crypto */
> +TPM_RESULT tpmrsa_pub_encrypt_oaep( tpmrsa_context *ctx,
> +      int (*f_rng)(void *, unsigned char *, size_t),
> +      void *p_rng,
> +      size_t ilen,
> +      const unsigned char *input,
> +      unsigned char *output );
> +
> +/* free tpmrsa key */
> +inline void tpmrsa_free( tpmrsa_context *ctx ) {
> +   mpi_free( &ctx->RN ); mpi_free( &ctx->E  ); mpi_free( &ctx->N  );
> +}
> +
> +#endif /* tpmrsa.h */
> diff --git a/stubdom/vtpmmgr/uuid.h b/stubdom/vtpmmgr/uuid.h
> new file mode 100644
> index 0000000..4737645
> --- /dev/null
> +++ b/stubdom/vtpmmgr/uuid.h
> @@ -0,0 +1,50 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * based off of the original tools/vtpm_manager code base which is:
> + * 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 VTPMMGR_UUID_H
> +#define VTPMMGR_UUID_H
> +
> +#define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
> +#define UUID_FMTLEN ((2*16)+4) /* 16 hex bytes plus 4 hypens */
> +#define UUID_BYTES(uuid) uuid[0], uuid[1], uuid[2], uuid[3], \
> +                                uuid[4], uuid[5], uuid[6], uuid[7], \
> +                                uuid[8], uuid[9], uuid[10], uuid[11], \
> +                                uuid[12], uuid[13], uuid[14], uuid[15]
> +
> +
> +typedef uint8_t uuid_t[16];
> +
> +#endif
> diff --git a/stubdom/vtpmmgr/vtpm_cmd_handler.c b/stubdom/vtpmmgr/vtpm_cmd_handler.c
> new file mode 100644
> index 0000000..f82a2a9
> --- /dev/null
> +++ b/stubdom/vtpmmgr/vtpm_cmd_handler.c
> @@ -0,0 +1,152 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * based off of the original tools/vtpm_manager code base which is:
> + * 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 <inttypes.h>
> +#include <string.h>
> +#include <stdlib.h>
> +
> +#include "marshal.h"
> +#include "log.h"
> +#include "vtpm_storage.h"
> +#include "vtpmmgr.h"
> +#include "tpm.h"
> +#include "tcg.h"
> +
> +static TPM_RESULT vtpmmgr_SaveHashKey(
> +      const uuid_t uuid,
> +      tpmcmd_t* tpmcmd)
> +{
> +   TPM_RESULT status = TPM_SUCCESS;
> +
> +   if(tpmcmd->req_len != VTPM_COMMAND_HEADER_SIZE + HASHKEYSZ) {
> +      vtpmlogerror(VTPM_LOG_VTPM, "VTPM_ORD_SAVEHASHKEY hashkey too short!\n");
> +      status = TPM_BAD_PARAMETER;
> +      goto abort_egress;
> +   }
> +
> +   /* Do the command */
> +   TPMTRYRETURN(vtpm_storage_save_hashkey(uuid, tpmcmd->req + VTPM_COMMAND_HEADER_SIZE));
> +
> +abort_egress:
> +   pack_TPM_RSP_HEADER(tpmcmd->resp,
> +         VTPM_TAG_RSP, VTPM_COMMAND_HEADER_SIZE, status);
> +   tpmcmd->resp_len = VTPM_COMMAND_HEADER_SIZE;
> +
> +   return status;
> +}
> +
> +static TPM_RESULT vtpmmgr_LoadHashKey(
> +      const uuid_t uuid,
> +      tpmcmd_t* tpmcmd) {
> +   TPM_RESULT status = TPM_SUCCESS;
> +
> +   tpmcmd->resp_len = VTPM_COMMAND_HEADER_SIZE;
> +
> +   TPMTRYRETURN(vtpm_storage_load_hashkey(uuid, tpmcmd->resp + VTPM_COMMAND_HEADER_SIZE));
> +
> +   tpmcmd->resp_len += HASHKEYSZ;
> +
> +abort_egress:
> +   pack_TPM_RSP_HEADER(tpmcmd->resp,
> +         VTPM_TAG_RSP, tpmcmd->resp_len, status);
> +
> +   return status;
> +}
> +
> +
> +TPM_RESULT vtpmmgr_handle_cmd(
> +      const uuid_t uuid,
> +      tpmcmd_t* tpmcmd)
> +{
> +   TPM_RESULT status = TPM_SUCCESS;
> +   TPM_TAG tag;
> +   UINT32 size;
> +   TPM_COMMAND_CODE ord;
> +
> +   unpack_TPM_RQU_HEADER(tpmcmd->req,
> +         &tag, &size, &ord);
> +
> +   /* Handle the command now */
> +   switch(tag) {
> +      case VTPM_TAG_REQ:
> +         //This is a vTPM command
> +         switch(ord) {
> +            case VTPM_ORD_SAVEHASHKEY:
> +               return vtpmmgr_SaveHashKey(uuid, tpmcmd);
> +            case VTPM_ORD_LOADHASHKEY:
> +               return vtpmmgr_LoadHashKey(uuid, tpmcmd);
> +            default:
> +               vtpmlogerror(VTPM_LOG_VTPM, "Invalid vTPM Ordinal %" PRIu32 "\n", ord);
> +               status = TPM_BAD_ORDINAL;
> +         }
> +         break;
> +      case TPM_TAG_RQU_COMMAND:
> +      case TPM_TAG_RQU_AUTH1_COMMAND:
> +      case TPM_TAG_RQU_AUTH2_COMMAND:
> +         //This is a TPM passthrough command
> +         switch(ord) {
> +            case TPM_ORD_GetRandom:
> +               vtpmloginfo(VTPM_LOG_VTPM, "Passthrough: TPM_GetRandom\n");
> +               break;
> +            case TPM_ORD_PcrRead:
> +               vtpmloginfo(VTPM_LOG_VTPM, "Passthrough: TPM_PcrRead\n");
> +               break;
> +            default:
> +               vtpmlogerror(VTPM_LOG_VTPM, "TPM Disallowed Passthrough ord=%" PRIu32 "\n", ord);
> +               status = TPM_DISABLED_CMD;
> +               goto abort_egress;
> +         }
> +
> +         size = TCPA_MAX_BUFFER_LENGTH;
> +         TPMTRYRETURN(TPM_TransmitData(tpmcmd->req, tpmcmd->req_len, tpmcmd->resp, &size));
> +         tpmcmd->resp_len = size;
> +
> +         unpack_TPM_RESULT(tpmcmd->resp + sizeof(TPM_TAG) + sizeof(UINT32), &status);
> +         return status;
> +
> +         break;
> +      default:
> +         vtpmlogerror(VTPM_LOG_VTPM, "Invalid tag=%" PRIu16 "\n", tag);
> +         status = TPM_BADTAG;
> +   }
> +
> +abort_egress:
> +   tpmcmd->resp_len = VTPM_COMMAND_HEADER_SIZE;
> +   pack_TPM_RSP_HEADER(tpmcmd->resp,
> +         tag + 3, tpmcmd->resp_len, status);
> +
> +   return status;
> +}
> diff --git a/stubdom/vtpmmgr/vtpm_manager.h b/stubdom/vtpmmgr/vtpm_manager.h
> new file mode 100644
> index 0000000..a2bbcca
> --- /dev/null
> +++ b/stubdom/vtpmmgr/vtpm_manager.h
> @@ -0,0 +1,64 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * based off of the original tools/vtpm_manager code base which is:
> + * 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_MANAGER_H
> +#define VTPM_MANAGER_H
> +
> +#define VTPM_TAG_REQ 0x01c1
> +#define VTPM_TAG_RSP 0x01c4
> +#define COMMAND_BUFFER_SIZE 4096
> +
> +// Header size
> +#define VTPM_COMMAND_HEADER_SIZE ( 2 + 4 + 4)
> +
> +//************************ Command Codes ****************************
> +#define VTPM_ORD_BASE       0x0000
> +#define VTPM_PRIV_MASK      0x01000000 // Priviledged VTPM Command
> +#define VTPM_PRIV_BASE      (VTPM_ORD_BASE | VTPM_PRIV_MASK)
> +
> +// Non-priviledged VTPM Commands (From DMI's)
> +#define VTPM_ORD_SAVEHASHKEY      (VTPM_ORD_BASE + 1) // DMI requests encryption key for persistent storage
> +#define VTPM_ORD_LOADHASHKEY      (VTPM_ORD_BASE + 2) // DMI requests symkey to be regenerated
> +
> +//************************ 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
> +
> +#endif
> diff --git a/stubdom/vtpmmgr/vtpm_storage.c b/stubdom/vtpmmgr/vtpm_storage.c
> new file mode 100644
> index 0000000..9ce0c32
> --- /dev/null
> +++ b/stubdom/vtpmmgr/vtpm_storage.c
> @@ -0,0 +1,794 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
> + * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
> + * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
> + * FOR A PARTICULAR  PURPOSE, AND NONINFRINGEMENT ARE HEREBY
> + * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
> + * SOFTWARE.
> + */
> +
> +/***************************************************************
> + * DISK IMAGE LAYOUT
> + * *************************************************************
> + * All data is stored in BIG ENDIAN format
> + * *************************************************************
> + * Section 1: Header
> + *
> + * 10 bytes     id                     ID String "VTPMMGRDOM"
> + * uint32_t     version                Disk Image version number (current == 1)
> + * uint32_t      storage_key_len       Length of the storage Key
> + * TPM_KEY       storage_key           Marshalled TPM_KEY structure (See TPM spec v2)
> + * RSA_BLOCK     aes_crypto             Encrypted aes key data (RSA_CIPHER_SIZE bytes), bound by the storage_key
> + *  BYTE[32] aes_key                    Aes key for encrypting the uuid table
> + *  uint32_t cipher_sz                  Encrypted size of the uuid table
> + *
> + * *************************************************************
> + * Section 2: Uuid Table
> + *
> + * This table is encrypted by the aes_key in the header. The cipher text size is just
> + * large enough to hold all of the entries plus required padding.
> + *
> + * Each entry is as follows
> + * BYTE[16] uuid                       Uuid of a vtpm that is stored on this disk
> + * uint32_t offset                     Disk offset where the vtpm data is stored
> + *
> + * *************************************************************
> + * Section 3: Vtpm Table
> + *
> + * The rest of the disk stores vtpms. Each vtpm is an RSA_BLOCK encrypted
> + * by the storage key. Each vtpm must exist on an RSA_BLOCK aligned boundary,
> + * starting at the first RSA_BLOCK aligned offset after the uuid table.
> + * As the uuid table grows, vtpms may be relocated.
> + *
> + * RSA_BLOCK     vtpm_crypto          Vtpm data encrypted by storage_key
> + *   BYTE[20]    hash                 Sha1 hash of vtpm encrypted data
> + *   BYTE[16]    vtpm_aes_key         Encryption key for vtpm data
> + *
> +  *************************************************************
> + */
> +#define DISKVERS 1
> +#define IDSTR "VTPMMGRDOM"
> +#define IDSTRLEN 10
> +#define AES_BLOCK_SIZE 16
> +#define AES_KEY_BITS 256
> +#define AES_KEY_SIZE (AES_KEY_BITS/8)
> +#define BUF_SIZE 4096
> +
> +#define UUID_TBL_ENT_SIZE (sizeof(uuid_t) + sizeof(uint32_t))
> +
> +#define HEADERSZ (10 + 4 + 4)
> +
> +#define TRY_READ(buf, size, msg) do {\
> +   int rc; \
> +   if((rc = read(blkfront_fd, buf, (size))) != (size)) { \
> +      vtpmlogerror(VTPM_LOG_VTPM, "read() failed! " msg " : rc=(%d/%d), error=(%s)\n", rc, (int)(size), strerror(errno)); \
> +      status = TPM_IOERROR;\
> +      goto abort_egress;\
> +   } \
> +} while(0)
> +
> +#define TRY_WRITE(buf, size, msg) do {\
> +   int rc; \
> +   if((rc = write(blkfront_fd, buf, (size))) != (size)) { \
> +      vtpmlogerror(VTPM_LOG_VTPM, "write() failed! " msg " : rc=(%d/%d), error=(%s)\n", rc, (int)(size), strerror(errno)); \
> +      status = TPM_IOERROR;\
> +      goto abort_egress;\
> +   } \
> +} while(0)
> +
> +#include <blkfront.h>
> +#include <unistd.h>
> +#include <errno.h>
> +#include <string.h>
> +#include <inttypes.h>
> +#include <stdlib.h>
> +#include <stdbool.h>
> +#include <mini-os/byteorder.h>
> +#include <polarssl/aes.h>
> +
> +#include "vtpm_manager.h"
> +#include "log.h"
> +#include "marshal.h"
> +#include "tpm.h"
> +#include "uuid.h"
> +
> +#include "vtpmmgr.h"
> +#include "vtpm_storage.h"
> +
> +#define MAX(a,b) ( ((a) > (b)) ? (a) : (b) )
> +#define MIN(a,b) ( ((a) < (b)) ? (a) : (b) )
> +
> +/* blkfront device objets */
> +static struct blkfront_dev* blkdev = NULL;
> +static int blkfront_fd = -1;
> +
> +struct Vtpm {
> +   uuid_t uuid;
> +   int offset;
> +};
> +struct Storage {
> +   int aes_offset;
> +   int uuid_offset;
> +   int end_offset;
> +
> +   int num_vtpms;
> +   int num_vtpms_alloced;
> +   struct Vtpm* vtpms;
> +};
> +
> +/* Global storage data */
> +static struct Storage g_store = {
> +   .vtpms = NULL,
> +};
> +
> +static int get_offset(void) {
> +   return lseek(blkfront_fd, 0, SEEK_CUR);
> +}
> +
> +static void reset_store(void) {
> +   g_store.aes_offset = 0;
> +   g_store.uuid_offset = 0;
> +   g_store.end_offset = 0;
> +
> +   g_store.num_vtpms = 0;
> +   g_store.num_vtpms_alloced = 0;
> +   free(g_store.vtpms);
> +   g_store.vtpms = NULL;
> +}
> +
> +static int vtpm_get_index(const uuid_t uuid) {
> +   int st = 0;
> +   int ed = g_store.num_vtpms-1;
> +   while(st <= ed) {
> +      int mid = ((unsigned int)st + (unsigned int)ed) >> 1; //avoid overflow
> +      int c = memcmp(uuid, &g_store.vtpms[mid].uuid, sizeof(uuid_t));
> +      if(c == 0) {
> +         return mid;
> +      } else if(c > 0) {
> +         st = mid + 1;
> +      } else {
> +         ed = mid - 1;
> +      }
> +   }
> +   return -(st + 1);
> +}
> +
> +static void vtpm_add(const uuid_t uuid, int offset, int index) {
> +   /* Realloc more space if needed */
> +   if(g_store.num_vtpms >= g_store.num_vtpms_alloced) {
> +      g_store.num_vtpms_alloced += 16;
> +      g_store.vtpms = realloc(
> +            g_store.vtpms,
> +            sizeof(struct Vtpm) * g_store.num_vtpms_alloced);
> +   }
> +
> +   /* Move everybody after the new guy */
> +   for(int i = g_store.num_vtpms; i > index; --i) {
> +      g_store.vtpms[i] = g_store.vtpms[i-1];
> +   }
> +
> +   vtpmloginfo(VTPM_LOG_VTPM, "Registered vtpm " UUID_FMT "\n", UUID_BYTES(uuid));
> +
> +   /* Finally add new one */
> +   memcpy(g_store.vtpms[index].uuid, uuid, sizeof(uuid_t));
> +   g_store.vtpms[index].offset = offset;
> +   ++g_store.num_vtpms;
> +}
> +
> +#if 0
> +static void vtpm_remove(int index) {
> +   for(i = index; i < g_store.num_vtpms; ++i) {
> +      g_store.vtpms[i] = g_store.vtpms[i+1];
> +   }
> +   --g_store.num_vtpms;
> +}
> +#endif
> +
> +static int pack_uuid_table(uint8_t* table, int size, int* nvtpms) {
> +   uint8_t* ptr = table;
> +   while(*nvtpms < g_store.num_vtpms && size >= 0)
> +   {
> +      /* Pack the uuid */
> +      memcpy(ptr, (uint8_t*)g_store.vtpms[*nvtpms].uuid, sizeof(uuid_t));
> +      ptr+= sizeof(uuid_t);
> +
> +
> +      /* Pack the offset */
> +      ptr = pack_UINT32(ptr, g_store.vtpms[*nvtpms].offset);
> +
> +      ++*nvtpms;
> +      size -= UUID_TBL_ENT_SIZE;
> +   }
> +   return ptr - table;
> +}
> +
> +/* Extract the uuids */
> +static int extract_uuid_table(uint8_t* table, int size) {
> +   uint8_t* ptr = table;
> +   for(;size >= UUID_TBL_ENT_SIZE; size -= UUID_TBL_ENT_SIZE) {
> +      int index;
> +      uint32_t v32;
> +
> +      /*uuid_t is just an array of bytes, so we can do a direct cast here */
> +      uint8_t* uuid = ptr;
> +      ptr += sizeof(uuid_t);
> +
> +      /* Get the offset of the key */
> +      ptr = unpack_UINT32(ptr, &v32);
> +
> +      /* Insert the new vtpm in sorted order */
> +      if((index = vtpm_get_index(uuid)) >= 0) {
> +         vtpmlogerror(VTPM_LOG_VTPM, "Vtpm (" UUID_FMT ") exists multiple times! ignoring...\n", UUID_BYTES(uuid));
> +         continue;
> +      }
> +      index = -index -1;
> +
> +      vtpm_add(uuid, v32, index);
> +
> +   }
> +   return ptr - table;
> +}
> +
> +static void vtpm_decrypt_block(aes_context* aes,
> +      uint8_t* iv,
> +      uint8_t* cipher,
> +      uint8_t* plain,
> +      int cipher_sz,
> +      int* overlap)
> +{
> +   int bytes_ext;
> +   /* Decrypt */
> +   aes_crypt_cbc(aes, AES_DECRYPT,
> +         cipher_sz,
> +         iv, cipher, plain + *overlap);
> +
> +   /* Extract */
> +   bytes_ext = extract_uuid_table(plain, cipher_sz + *overlap);
> +
> +   /* Copy left overs to the beginning */
> +   *overlap = cipher_sz + *overlap - bytes_ext;
> +   memcpy(plain, plain + bytes_ext, *overlap);
> +}
> +
> +static int vtpm_encrypt_block(aes_context* aes,
> +      uint8_t* iv,
> +      uint8_t* plain,
> +      uint8_t* cipher,
> +      int block_sz,
> +      int* overlap,
> +      int* num_vtpms)
> +{
> +   int bytes_to_crypt;
> +   int bytes_packed;
> +
> +   /* Pack the uuid table */
> +   bytes_packed = *overlap + pack_uuid_table(plain + *overlap, block_sz - *overlap, num_vtpms);
> +   bytes_to_crypt = MIN(bytes_packed, block_sz);
> +
> +   /* Add padding if we aren't on a multiple of the block size */
> +   if(bytes_to_crypt & (AES_BLOCK_SIZE-1)) {
> +      int oldsz = bytes_to_crypt;
> +      //add padding
> +      bytes_to_crypt += AES_BLOCK_SIZE - (bytes_to_crypt & (AES_BLOCK_SIZE-1));
> +      //fill padding with random bytes
> +      vtpmmgr_rand(plain + oldsz, bytes_to_crypt - oldsz);
> +      *overlap = 0;
> +   } else {
> +      *overlap = bytes_packed - bytes_to_crypt;
> +   }
> +
> +   /* Encrypt this chunk */
> +   aes_crypt_cbc(aes, AES_ENCRYPT,
> +            bytes_to_crypt,
> +            iv, plain, cipher);
> +
> +   /* Copy the left over partials to the beginning */
> +   memcpy(plain, plain + bytes_to_crypt, *overlap);
> +
> +   return bytes_to_crypt;
> +}
> +
> +static TPM_RESULT vtpm_storage_new_vtpm(const uuid_t uuid, int index) {
> +   TPM_RESULT status = TPM_SUCCESS;
> +   uint8_t plain[BUF_SIZE + AES_BLOCK_SIZE];
> +   uint8_t buf[BUF_SIZE];
> +   uint8_t* ptr;
> +   int cipher_sz;
> +   aes_context aes;
> +
> +   /* Add new vtpm to the table */
> +   vtpm_add(uuid, g_store.end_offset, index);
> +   g_store.end_offset += RSA_CIPHER_SIZE;
> +
> +   /* Compute the new end location of the encrypted uuid table */
> +   cipher_sz = AES_BLOCK_SIZE; //IV
> +   cipher_sz += g_store.num_vtpms * UUID_TBL_ENT_SIZE; //uuid table
> +   cipher_sz += (AES_BLOCK_SIZE - (cipher_sz & (AES_BLOCK_SIZE -1))) & (AES_BLOCK_SIZE-1); //aes padding
> +
> +   /* Does this overlap any key data? If so they need to be relocated */
> +   int uuid_end = (g_store.uuid_offset + cipher_sz + RSA_CIPHER_SIZE) & ~(RSA_CIPHER_SIZE -1);
> +   for(int i = 0; i < g_store.num_vtpms; ++i) {
> +      if(g_store.vtpms[i].offset < uuid_end) {
> +
> +         vtpmloginfo(VTPM_LOG_VTPM, "Relocating vtpm data\n");
> +
> +         //Read the hashkey cipher text
> +         lseek(blkfront_fd, g_store.vtpms[i].offset, SEEK_SET);
> +         TRY_READ(buf, RSA_CIPHER_SIZE, "vtpm hashkey relocate");
> +
> +         //Write the cipher text to new offset
> +         lseek(blkfront_fd, g_store.end_offset, SEEK_SET);
> +         TRY_WRITE(buf, RSA_CIPHER_SIZE, "vtpm hashkey relocate");
> +
> +         //Save new offset
> +         g_store.vtpms[i].offset = g_store.end_offset;
> +         g_store.end_offset += RSA_CIPHER_SIZE;
> +      }
> +   }
> +
> +   vtpmloginfo(VTPM_LOG_VTPM, "Generating a new symmetric key\n");
> +
> +   /* Generate an aes key */
> +   TPMTRYRETURN(vtpmmgr_rand(plain, AES_KEY_SIZE));
> +   aes_setkey_enc(&aes, plain, AES_KEY_BITS);
> +   ptr = plain + AES_KEY_SIZE;
> +
> +   /* Pack the crypted size */
> +   ptr = pack_UINT32(ptr, cipher_sz);
> +
> +   vtpmloginfo(VTPM_LOG_VTPM, "Binding encrypted key\n");
> +
> +   /* Seal the key and size */
> +   TPMTRYRETURN(TPM_Bind(&vtpm_globals.storage_key,
> +            plain,
> +            ptr - plain,
> +            buf));
> +
> +   /* Write the sealed key to disk */
> +   lseek(blkfront_fd, g_store.aes_offset, SEEK_SET);
> +   TRY_WRITE(buf, RSA_CIPHER_SIZE, "vtpm aes key");
> +
> +   /* ENCRYPT AND WRITE UUID TABLE */
> +
> +   vtpmloginfo(VTPM_LOG_VTPM, "Encrypting the uuid table\n");
> +
> +   int num_vtpms = 0;
> +   int overlap = 0;
> +   int bytes_crypted;
> +   uint8_t iv[AES_BLOCK_SIZE];
> +
> +   /* Generate the iv for the first block */
> +   TPMTRYRETURN(vtpmmgr_rand(iv, AES_BLOCK_SIZE));
> +
> +   /* Copy the iv to the cipher text buffer to be written to disk */
> +   memcpy(buf, iv, AES_BLOCK_SIZE);
> +   ptr = buf + AES_BLOCK_SIZE;
> +
> +   /* Encrypt the first block of the uuid table */
> +   bytes_crypted = vtpm_encrypt_block(&aes,
> +         iv, //iv
> +         plain, //plaintext
> +         ptr, //cipher text
> +         BUF_SIZE - AES_BLOCK_SIZE,
> +         &overlap,
> +         &num_vtpms);
> +
> +   /* Write the iv followed by the crypted table*/
> +   TRY_WRITE(buf, bytes_crypted + AES_BLOCK_SIZE, "vtpm uuid table");
> +
> +   /* Decrement the number of bytes encrypted */
> +   cipher_sz -= bytes_crypted + AES_BLOCK_SIZE;
> +
> +   /* If there are more vtpms, encrypt and write them block by block */
> +   while(cipher_sz > 0) {
> +      /* Encrypt the next block of the uuid table */
> +      bytes_crypted = vtpm_encrypt_block(&aes,
> +               iv,
> +               plain,
> +               buf,
> +               BUF_SIZE,
> +               &overlap,
> +               &num_vtpms);
> +
> +      /* Write the cipher text to disk */
> +      TRY_WRITE(buf, bytes_crypted, "vtpm uuid table");
> +
> +      cipher_sz -= bytes_crypted;
> +   }
> +
> +   goto egress;
> +abort_egress:
> +egress:
> +   return status;
> +}
> +
> +
> +/**************************************
> + * PUBLIC FUNCTIONS
> + * ***********************************/
> +
> +int vtpm_storage_init(void) {
> +   struct blkfront_info info;
> +   if((blkdev = init_blkfront(NULL, &info)) == NULL) {
> +      return -1;
> +   }
> +   if((blkfront_fd = blkfront_open(blkdev)) < 0) {
> +      return -1;
> +   }
> +   return 0;
> +}
> +
> +void vtpm_storage_shutdown(void) {
> +   reset_store();
> +   close(blkfront_fd);
> +}
> +
> +TPM_RESULT vtpm_storage_load_hashkey(const uuid_t uuid, uint8_t hashkey[HASHKEYSZ])
> +{
> +   TPM_RESULT status = TPM_SUCCESS;
> +   int index;
> +   uint8_t cipher[RSA_CIPHER_SIZE];
> +   uint8_t clear[RSA_CIPHER_SIZE];
> +   UINT32 clear_size;
> +
> +   /* Find the index of this uuid */
> +   if((index = vtpm_get_index(uuid)) < 0) {
> +      index = -index-1;
> +      vtpmlogerror(VTPM_LOG_VTPM, "LoadKey failure: Unrecognized uuid! " UUID_FMT "\n", UUID_BYTES(uuid));
> +      status = TPM_BAD_PARAMETER;
> +      goto abort_egress;
> +   }
> +
> +   /* Read the table entry */
> +   lseek(blkfront_fd, g_store.vtpms[index].offset, SEEK_SET);
> +   TRY_READ(cipher, RSA_CIPHER_SIZE, "vtpm hashkey data");
> +
> +   /* Decrypt the table entry */
> +   TPMTRYRETURN(TPM_UnBind(
> +            vtpm_globals.storage_key_handle,
> +            RSA_CIPHER_SIZE,
> +            cipher,
> +            &clear_size,
> +            clear,
> +            (const TPM_AUTHDATA*)&vtpm_globals.storage_key_usage_auth,
> +            &vtpm_globals.oiap));
> +
> +   if(clear_size < HASHKEYSZ) {
> +      vtpmloginfo(VTPM_LOG_VTPM, "Decrypted Hash key size (%" PRIu32 ") was too small!\n", clear_size);
> +      status = TPM_RESOURCES;
> +      goto abort_egress;
> +   }
> +
> +   memcpy(hashkey, clear, HASHKEYSZ);
> +
> +   vtpmloginfo(VTPM_LOG_VTPM, "Loaded hash and key for vtpm " UUID_FMT "\n", UUID_BYTES(uuid));
> +   goto egress;
> +abort_egress:
> +   vtpmlogerror(VTPM_LOG_VTPM, "Failed to load key\n");
> +egress:
> +   return status;
> +}
> +
> +TPM_RESULT vtpm_storage_save_hashkey(const uuid_t uuid, uint8_t hashkey[HASHKEYSZ])
> +{
> +   TPM_RESULT status = TPM_SUCCESS;
> +   int index;
> +   uint8_t buf[RSA_CIPHER_SIZE];
> +
> +   /* Find the index of this uuid */
> +   if((index = vtpm_get_index(uuid)) < 0) {
> +      index = -index-1;
> +      /* Create a new vtpm */
> +      TPMTRYRETURN( vtpm_storage_new_vtpm(uuid, index) );
> +   }
> +
> +   /* Encrypt the hash and key */
> +   TPMTRYRETURN( TPM_Bind(&vtpm_globals.storage_key,
> +            hashkey,
> +            HASHKEYSZ,
> +            buf));
> +
> +   /* Write to disk */
> +   lseek(blkfront_fd, g_store.vtpms[index].offset, SEEK_SET);
> +   TRY_WRITE(buf, RSA_CIPHER_SIZE, "vtpm hashkey data");
> +
> +   vtpmloginfo(VTPM_LOG_VTPM, "Saved hash and key for vtpm " UUID_FMT "\n", UUID_BYTES(uuid));
> +   goto egress;
> +abort_egress:
> +   vtpmlogerror(VTPM_LOG_VTPM, "Failed to save key\n");
> +egress:
> +   return status;
> +}
> +
> +TPM_RESULT vtpm_storage_new_header()
> +{
> +   TPM_RESULT status = TPM_SUCCESS;
> +   uint8_t buf[BUF_SIZE];
> +   uint8_t keybuf[AES_KEY_SIZE + sizeof(uint32_t)];
> +   uint8_t* ptr = buf;
> +   uint8_t* sptr;
> +
> +   /* Clear everything first */
> +   reset_store();
> +
> +   vtpmloginfo(VTPM_LOG_VTPM, "Creating new disk image header\n");
> +
> +   /*Copy the ID string */
> +   memcpy(ptr, IDSTR, IDSTRLEN);
> +   ptr += IDSTRLEN;
> +
> +   /*Copy the version */
> +   ptr = pack_UINT32(ptr, DISKVERS);
> +
> +   /*Save the location of the key size */
> +   sptr = ptr;
> +   ptr += sizeof(UINT32);
> +
> +   vtpmloginfo(VTPM_LOG_VTPM, "Saving root storage key..\n");
> +
> +   /* Copy the storage key */
> +   ptr = pack_TPM_KEY(ptr, &vtpm_globals.storage_key);
> +
> +   /* Now save the size */
> +   pack_UINT32(sptr, ptr - (sptr + 4));
> +
> +   /* Create a fake aes key and set cipher text size to 0 */
> +   memset(keybuf, 0, sizeof(keybuf));
> +
> +   vtpmloginfo(VTPM_LOG_VTPM, "Binding uuid table symmetric key..\n");
> +
> +   /* Save the location of the aes key */
> +   g_store.aes_offset = ptr - buf;
> +
> +   /* Store the fake aes key and vtpm count */
> +   TPMTRYRETURN(TPM_Bind(&vtpm_globals.storage_key,
> +         keybuf,
> +         sizeof(keybuf),
> +         ptr));
> +   ptr+= RSA_CIPHER_SIZE;
> +
> +   /* Write the header to disk */
> +   lseek(blkfront_fd, 0, SEEK_SET);
> +   TRY_WRITE(buf, ptr-buf, "vtpm header");
> +
> +   /* Save the location of the uuid table */
> +   g_store.uuid_offset = get_offset();
> +
> +   /* Save the end offset */
> +   g_store.end_offset = (g_store.uuid_offset + RSA_CIPHER_SIZE) & ~(RSA_CIPHER_SIZE -1);
> +
> +   vtpmloginfo(VTPM_LOG_VTPM, "Saved new manager disk header.\n");
> +
> +   goto egress;
> +abort_egress:
> +egress:
> +   return status;
> +}
> +
> +
> +TPM_RESULT vtpm_storage_load_header(void)
> +{
> +   TPM_RESULT status = TPM_SUCCESS;
> +   uint32_t v32;
> +   uint8_t buf[BUF_SIZE];
> +   uint8_t* ptr = buf;
> +   aes_context aes;
> +
> +   /* Clear everything first */
> +   reset_store();
> +
> +   /* Read the header from disk */
> +   lseek(blkfront_fd, 0, SEEK_SET);
> +   TRY_READ(buf, IDSTRLEN + sizeof(UINT32) + sizeof(UINT32), "vtpm header");
> +
> +   vtpmloginfo(VTPM_LOG_VTPM, "Loading disk image header\n");
> +
> +   /* Verify the ID string */
> +   if(memcmp(ptr, IDSTR, IDSTRLEN)) {
> +      vtpmlogerror(VTPM_LOG_VTPM, "Invalid ID string in disk image!\n");
> +      status = TPM_FAIL;
> +      goto abort_egress;
> +   }
> +   ptr+=IDSTRLEN;
> +
> +   /* Unpack the version */
> +   ptr = unpack_UINT32(ptr, &v32);
> +
> +   /* Verify the version */
> +   if(v32 != DISKVERS) {
> +      vtpmlogerror(VTPM_LOG_VTPM, "Unsupported disk image version number %" PRIu32 "\n", v32);
> +      status = TPM_FAIL;
> +      goto abort_egress;
> +   }
> +
> +   /* Size of the storage key */
> +   ptr = unpack_UINT32(ptr, &v32);
> +
> +   /* Sanity check */
> +   if(v32 > BUF_SIZE) {
> +      vtpmlogerror(VTPM_LOG_VTPM, "Size of storage key (%" PRIu32 ") is too large!\n", v32);
> +      status = TPM_IOERROR;
> +      goto abort_egress;
> +   }
> +
> +   /* read the storage key */
> +   TRY_READ(buf, v32, "storage pub key");
> +
> +   vtpmloginfo(VTPM_LOG_VTPM, "Unpacking storage key\n");
> +
> +   /* unpack the storage key */
> +   ptr = unpack_TPM_KEY(buf, &vtpm_globals.storage_key, UNPACK_ALLOC);
> +
> +   /* Load Storage Key into the TPM */
> +   TPMTRYRETURN( TPM_LoadKey(
> +            TPM_SRK_KEYHANDLE,
> +            &vtpm_globals.storage_key,
> +            &vtpm_globals.storage_key_handle,
> +            (const TPM_AUTHDATA*)&vtpm_globals.srk_auth,
> +            &vtpm_globals.oiap));
> +
> +   /* Initialize the storage key auth */
> +   memset(vtpm_globals.storage_key_usage_auth, 0, sizeof(TPM_AUTHDATA));
> +
> +   /* Store the offset of the aes key */
> +   g_store.aes_offset = get_offset();
> +
> +   /* Read the rsa cipher text for the aes key */
> +   TRY_READ(buf, RSA_CIPHER_SIZE, "aes key");
> +   ptr = buf + RSA_CIPHER_SIZE;
> +
> +   vtpmloginfo(VTPM_LOG_VTPM, "Unbinding uuid table symmetric key\n");
> +
> +   /* Decrypt the aes key protecting the uuid table */
> +   UINT32 datalen;
> +   TPMTRYRETURN(TPM_UnBind(
> +            vtpm_globals.storage_key_handle,
> +            RSA_CIPHER_SIZE,
> +            buf,
> +            &datalen,
> +            ptr,
> +            (const TPM_AUTHDATA*)&vtpm_globals.storage_key_usage_auth,
> +            &vtpm_globals.oiap));
> +
> +   /* Validate the length of the output buffer */
> +   if(datalen < AES_KEY_SIZE + sizeof(UINT32)) {
> +      vtpmlogerror(VTPM_LOG_VTPM, "Unbound AES key size (%d) was too small! expected (%ld)\n", datalen, AES_KEY_SIZE + sizeof(UINT32));
> +      status = TPM_IOERROR;
> +      goto abort_egress;
> +   }
> +
> +   /* Extract the aes key */
> +   aes_setkey_dec(&aes, ptr, AES_KEY_BITS);
> +   ptr+= AES_KEY_SIZE;
> +
> +   /* Extract the ciphertext size */
> +   ptr = unpack_UINT32(ptr, &v32);
> +   int cipher_size = v32;
> +
> +   /* Sanity check */
> +   if(cipher_size & (AES_BLOCK_SIZE-1)) {
> +      vtpmlogerror(VTPM_LOG_VTPM, "Cipher text size (%" PRIu32 ") is not a multiple of the aes block size! (%d)\n", v32, AES_BLOCK_SIZE);
> +      status = TPM_IOERROR;
> +      goto abort_egress;
> +   }
> +
> +   /* Save the location of the uuid table */
> +   g_store.uuid_offset = get_offset();
> +
> +   /* Only decrypt the table if there are vtpms to decrypt */
> +   if(cipher_size > 0) {
> +      int rbytes;
> +      int overlap = 0;
> +      uint8_t plain[BUF_SIZE + AES_BLOCK_SIZE];
> +      uint8_t iv[AES_BLOCK_SIZE];
> +
> +      vtpmloginfo(VTPM_LOG_VTPM, "Decrypting uuid table\n");
> +
> +      /* Pre allocate the vtpm array */
> +      g_store.num_vtpms_alloced = cipher_size / UUID_TBL_ENT_SIZE;
> +      g_store.vtpms = malloc(sizeof(struct Vtpm) * g_store.num_vtpms_alloced);
> +
> +      /* Read the iv and the first chunk of cipher text */
> +      rbytes = MIN(cipher_size, BUF_SIZE);
> +      TRY_READ(buf, rbytes, "vtpm uuid table\n");
> +      cipher_size -= rbytes;
> +
> +      /* Copy the iv */
> +      memcpy(iv, buf, AES_BLOCK_SIZE);
> +      ptr = buf + AES_BLOCK_SIZE;
> +
> +      /* Remove the iv from the number of bytes to decrypt */
> +      rbytes -= AES_BLOCK_SIZE;
> +
> +      /* Decrypt and extract vtpms */
> +      vtpm_decrypt_block(&aes,
> +            iv, ptr, plain,
> +            rbytes, &overlap);
> +
> +      /* Read the rest of the table if there is more */
> +      while(cipher_size > 0) {
> +         /* Read next chunk of cipher text */
> +         rbytes = MIN(cipher_size, BUF_SIZE);
> +         TRY_READ(buf, rbytes, "vtpm uuid table");
> +         cipher_size -= rbytes;
> +
> +         /* Decrypt a block of text */
> +         vtpm_decrypt_block(&aes,
> +               iv, buf, plain,
> +               rbytes, &overlap);
> +
> +      }
> +      vtpmloginfo(VTPM_LOG_VTPM, "Loaded %d vtpms!\n", g_store.num_vtpms);
> +   }
> +
> +   /* The end of the key table, new vtpms go here */
> +   int uuid_end = (get_offset() + RSA_CIPHER_SIZE) & ~(RSA_CIPHER_SIZE -1);
> +   g_store.end_offset = uuid_end;
> +
> +   /* Compute the end offset while validating vtpms*/
> +   for(int i = 0; i < g_store.num_vtpms; ++i) {
> +      /* offset must not collide with previous data */
> +      if(g_store.vtpms[i].offset < uuid_end) {
> +         vtpmlogerror(VTPM_LOG_VTPM, "vtpm: " UUID_FMT
> +               " offset (%d) is before end of uuid table (%d)!\n",
> +               UUID_BYTES(g_store.vtpms[i].uuid),
> +               g_store.vtpms[i].offset, uuid_end);
> +         status = TPM_IOERROR;
> +         goto abort_egress;
> +      }
> +      /* offset must be at a multiple of cipher size */
> +      if(g_store.vtpms[i].offset & (RSA_CIPHER_SIZE-1)) {
> +         vtpmlogerror(VTPM_LOG_VTPM, "vtpm: " UUID_FMT
> +               " offset(%d) is not at a multiple of the rsa cipher text size (%d)!\n",
> +               UUID_BYTES(g_store.vtpms[i].uuid),
> +               g_store.vtpms[i].offset, RSA_CIPHER_SIZE);
> +         status = TPM_IOERROR;
> +         goto abort_egress;
> +      }
> +      /* Save the last offset */
> +      if(g_store.vtpms[i].offset >= g_store.end_offset) {
> +         g_store.end_offset = g_store.vtpms[i].offset + RSA_CIPHER_SIZE;
> +      }
> +   }
> +
> +   goto egress;
> +abort_egress:
> +   //An error occured somewhere
> +   vtpmlogerror(VTPM_LOG_VTPM, "Failed to load manager data!\n");
> +
> +   //Clear the data store
> +   reset_store();
> +
> +   //Reset the storage key structure
> +   free_TPM_KEY(&vtpm_globals.storage_key);
> +   {
> +      TPM_KEY key = TPM_KEY_INIT;
> +      vtpm_globals.storage_key = key;
> +   }
> +
> +   //Reset the storage key handle
> +   TPM_EvictKey(vtpm_globals.storage_key_handle);
> +   vtpm_globals.storage_key_handle = 0;
> +egress:
> +   return status;
> +}
> +
> +#if 0
> +/* For testing disk IO */
> +void add_fake_vtpms(int num) {
> +   for(int i = 0; i < num; ++i) {
> +      uint32_t ind = cpu_to_be32(i);
> +
> +      uuid_t uuid;
> +      memset(uuid, 0, sizeof(uuid_t));
> +      memcpy(uuid, &ind, sizeof(ind));
> +      int index = vtpm_get_index(uuid);
> +      index = -index-1;
> +
> +      vtpm_storage_new_vtpm(uuid, index);
> +   }
> +}
> +#endif
> diff --git a/stubdom/vtpmmgr/vtpm_storage.h b/stubdom/vtpmmgr/vtpm_storage.h
> new file mode 100644
> index 0000000..a5a5fd7
> --- /dev/null
> +++ b/stubdom/vtpmmgr/vtpm_storage.h
> @@ -0,0 +1,68 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * based off of the original tools/vtpm_manager code base which is:
> + * 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_STORAGE_H
> +#define VTPM_STORAGE_h
> +
> +#include "uuid.h"
> +
> +#define VTPM_NVMKEY_SIZE 32
> +#define HASHKEYSZ (sizeof(TPM_DIGEST) + VTPM_NVMKEY_SIZE)
> +
> +/* Initialize the storage system and its virtual disk */
> +int vtpm_storage_init(void);
> +
> +/* Shutdown the storage system and its virtual disk */
> +void vtpm_storage_shutdown(void);
> +
> +/* Loads Sha1 hash and 256 bit AES key from disk and stores them
> + * packed together in outbuf. outbuf must be freed
> + * by the caller using buffer_free()
> + */
> +TPM_RESULT vtpm_storage_load_hashkey(const uuid_t uuid, uint8_t hashkey[HASHKEYSZ]);
> +
> +/* inbuf must contain a sha1 hash followed by a 256 bit AES key.
> + * Encrypts and stores the hash and key to disk */
> +TPM_RESULT vtpm_storage_save_hashkey(const uuid_t uuid, uint8_t hashkey[HASHKEYSZ]);
> +
> +/* Load the vtpm manager data - call this on startup */
> +TPM_RESULT vtpm_storage_load_header(void);
> +
> +/* Saves the vtpm manager data - call this on shutdown */
> +TPM_RESULT vtpm_storage_new_header(void);
> +
> +
> +#endif
> diff --git a/stubdom/vtpmmgr/vtpmmgr.c b/stubdom/vtpmmgr/vtpmmgr.c
> new file mode 100644
> index 0000000..563f4e8
> --- /dev/null
> +++ b/stubdom/vtpmmgr/vtpmmgr.c
> @@ -0,0 +1,93 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * based off of the original tools/vtpm_manager code base which is:
> + * 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 <stdint.h>
> +#include <mini-os/tpmback.h>
> +#include <unistd.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <stdlib.h>
> +#include "log.h"
> +
> +#include "vtpmmgr.h"
> +#include "tcg.h"
> +
> +
> +void main_loop(void) {
> +   tpmcmd_t* tpmcmd;
> +   uint8_t respbuf[TCPA_MAX_BUFFER_LENGTH];
> +
> +   while(1) {
> +      /* Wait for requests from a vtpm */
> +      vtpmloginfo(VTPM_LOG_VTPM, "Waiting for commands from vTPM's:\n");
> +      if((tpmcmd = tpmback_req_any()) == NULL) {
> +         vtpmlogerror(VTPM_LOG_VTPM, "NULL tpmcmd\n");
> +         continue;
> +      }
> +
> +      tpmcmd->resp = respbuf;
> +
> +      /* Process the command */
> +      vtpmmgr_handle_cmd(tpmcmd->uuid, tpmcmd);
> +
> +      /* Send response */
> +      tpmback_resp(tpmcmd);
> +   }
> +}
> +
> +int main(int argc, char** argv)
> +{
> +   int rc = 0;
> +   sleep(2);
> +   vtpmloginfo(VTPM_LOG_VTPM, "Starting vTPM manager domain\n");
> +
> +   /* Initialize the vtpm manager */
> +   if(vtpmmgr_init(argc, argv) != TPM_SUCCESS) {
> +      vtpmlogerror(VTPM_LOG_VTPM, "Unable to initialize vtpmmgr domain!\n");
> +      rc = -1;
> +      goto exit;
> +   }
> +
> +   main_loop();
> +
> +   vtpmloginfo(VTPM_LOG_VTPM, "vTPM Manager shutting down...\n");
> +
> +   vtpmmgr_shutdown();
> +
> +exit:
> +   return rc;
> +
> +}
> diff --git a/stubdom/vtpmmgr/vtpmmgr.h b/stubdom/vtpmmgr/vtpmmgr.h
> new file mode 100644
> index 0000000..50a1992
> --- /dev/null
> +++ b/stubdom/vtpmmgr/vtpmmgr.h
> @@ -0,0 +1,77 @@
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented by
> + * the Secretary of Defense.  All rights reserved.
> + *
> + * based off of the original tools/vtpm_manager code base which is:
> + * 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 VTPMMGR_H
> +#define VTPMMGR_H
> +
> +#include <mini-os/tpmback.h>
> +#include <polarssl/entropy.h>
> +#include <polarssl/ctr_drbg.h>
> +
> +#include "uuid.h"
> +#include "tcg.h"
> +#include "vtpm_manager.h"
> +
> +#define RSA_KEY_SIZE 0x0800
> +#define RSA_CIPHER_SIZE (RSA_KEY_SIZE / 8)
> +
> +struct vtpm_globals {
> +   int tpm_fd;
> +   TPM_KEY             storage_key;
> +   TPM_HANDLE          storage_key_handle;       // Key used by persistent store
> +   TPM_AUTH_SESSION    oiap;                // OIAP session for storageKey
> +   TPM_AUTHDATA        storage_key_usage_auth;
> +
> +   TPM_AUTHDATA        owner_auth;
> +   TPM_AUTHDATA        srk_auth;
> +
> +   entropy_context     entropy;
> +   ctr_drbg_context    ctr_drbg;
> +};
> +
> +// --------------------------- Global Values --------------------------
> +extern struct vtpm_globals vtpm_globals;   // Key info and DMI states
> +
> +TPM_RESULT vtpmmgr_init(int argc, char** argv);
> +void vtpmmgr_shutdown(void);
> +
> +TPM_RESULT vtpmmgr_handle_cmd(const uuid_t uuid, tpmcmd_t* tpmcmd);
> +
> +inline TPM_RESULT vtpmmgr_rand(unsigned char* bytes, size_t num_bytes) {
> +   return ctr_drbg_random(&vtpm_globals.ctr_drbg, bytes, num_bytes) == 0 ? 0 : TPM_FAIL;
> +}
> +
> +#endif
> --
> 1.7.10.4
>



[-- Attachment #1.2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 1459 bytes --]

[-- Attachment #2: Type: text/plain, Size: 126 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

  reply	other threads:[~2012-11-20 14:25 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-11-20 14:21 [PATCH VTPM v4 1/5] add vtpm-stubdom code Matthew Fioravante
2012-11-20 14:21 ` [PATCH VTPM v4 2/5] add stubdom/vtpmmgr code Matthew Fioravante
2012-11-20 14:25   ` Matthew Fioravante [this message]
2012-11-20 14:21 ` [PATCH VTPM v4 3/5] vtpm/vtpmmgr and required libs to stubdom/Makefile Matthew Fioravante
2012-11-20 15:45   ` Samuel Thibault
2012-11-23  9:59   ` Ian Campbell
2012-11-29 11:39     ` Ian Jackson
2012-11-29 11:41       ` Ian Jackson
2012-11-29 13:54         ` Matthew Fioravante
2012-11-29 16:03           ` Ian Campbell
2012-11-29 17:54           ` Ian Jackson
2012-11-29 18:30             ` Matthew Fioravante
2012-11-20 14:21 ` [PATCH VTPM v4 4/5] Add vtpm documentation Matthew Fioravante
2012-11-20 14:21 ` [PATCH VTPM v4 5/5] Add cmake dependency to README Matthew Fioravante

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=50AB92CF.8040306@jhuapl.edu \
    --to=matthew.fioravante@jhuapl.edu \
    --cc=Ian.Campbell@citrix.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).