From mboxrd@z Thu Jan 1 00:00:00 1970 From: Matthew Fioravante Subject: Re: [PATCH VTPM v4 2/5] add stubdom/vtpmmgr code Date: Tue, 20 Nov 2012 09:25:19 -0500 Message-ID: <50AB92CF.8040306@jhuapl.edu> References: <1353421272-24797-1-git-send-email-matthew.fioravante@jhuapl.edu> <1353421272-24797-2-git-send-email-matthew.fioravante@jhuapl.edu> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0475244974786596101==" Return-path: In-Reply-To: <1353421272-24797-2-git-send-email-matthew.fioravante@jhuapl.edu> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: "xen-devel@lists.xen.org" , "Ian.Campbell@citrix.com" List-Id: xen-devel@lists.xenproject.org This is a cryptographically signed message in MIME format. --===============0475244974786596101== Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha1; boundary="------------ms080704030001010001060100" This is a cryptographically signed message in MIME format. --------------ms080704030001010001060100 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: quoted-printable Please be sure to grab this updated version. I fixed an important=20 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 > Acked-by: Ian Campbell > --- > 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=3D../.. > + > +PSSL_DIR=3D../polarssl-$(XEN_TARGET_ARCH)/library > +PSSL_OBJS=3Daes.o sha1.o entropy.o ctr_drbg.o bignum.o sha4.o havege.o= timing.o entropy_poll.o > + > +TARGET=3Dvtpmmgr.a > +OBJS=3Dvtpmmgr.o vtpm_cmd_handler.o vtpm_storage.o init.o tpmrsa.o tpm= =2Eo log.o > + > +CFLAGS+=3D-Werror -Iutil -Icrypto -Itcs > +CFLAGS+=3D-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 > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#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 =3D {0x00, 0x00, 0x00, 0x00, 0x0= 0, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; > + > +const TPM_AUTHDATA WELLKNOWN_OWNER_AUTH =3D {0xff, 0xff, 0xff, 0xff, 0= xff, 0xff, 0xff, 0xff, 0xff, 0xff, > + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; > + > +struct vtpm_globals vtpm_globals =3D { > + .tpm_fd =3D -1, > + .storage_key =3D TPM_KEY_INIT, > + .storage_key_handle =3D 0, > + .oiap =3D { .AuthHandle =3D 0 } > +}; > + > +static int tpm_entropy_source(void* dummy, unsigned char* data, size_t= len, size_t* olen) { > + UINT32 sz =3D len; > + TPM_RESULT rc =3D TPM_GetRandom(&sz, data); > + *olen =3D sz; > + return rc =3D=3D TPM_SUCCESS ? 0 : POLARSSL_ERR_ENTROPY_SOURCE_FAIL= ED; > +} > + > +static TPM_RESULT check_tpm_version(void) { > + TPM_RESULT status; > + UINT32 rsize; > + BYTE* res =3D 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 GetCapabil= ity!\n"); > + status =3D 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.revMa= jor, 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.vend= orSpecificSize); > + vtpmloginfo(VTPM_LOG_VTPM, " vendorSpecific: "); > + for(int i =3D 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 =3D TPM_SUCCESS; > + const TPM_RESOURCE_TYPE reslist[] =3D { TPM_RT_KEY, TPM_RT_AUTH, TP= M_RT_TRANS, TPM_RT_COUNTER, TPM_RT_DAA_TPM, TPM_RT_CONTEXT }; > + BYTE* keylist =3D NULL; > + UINT32 keylistSize; > + BYTE* ptr; > + > + //Iterate through each resource type and flush all handles > + for(int i =3D 0; i < sizeof(reslist) / sizeof(TPM_RESOURCE_TYPE); += +i) { > + TPM_RESOURCE_TYPE beres =3D cpu_to_be32(reslist[i]); > + UINT16 size; > + TPMTRYRETURN(TPM_GetCapability( > + TPM_CAP_HANDLE, > + sizeof(TPM_RESOURCE_TYPE), > + (BYTE*)(&beres), > + &keylistSize, > + &keylist)); > + > + ptr =3D keylist; > + ptr =3D 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 =3D 0; j < size; ++j) { > + TPM_HANDLE h; > + ptr =3D unpack_TPM_HANDLE(ptr, &h); > + TPMTRYRETURN(TPM_FlushSpecific(h, reslist[i])); > + } > + } > + > + free(keylist); > + keylist =3D NULL; > + } > + > + goto egress; > +abort_egress: > + free(keylist); > +egress: > + return status; > +} > + > + > +static TPM_RESULT try_take_ownership(void) { > + TPM_RESULT status =3D TPM_SUCCESS; > + TPM_PUBKEY pubEK =3D TPM_PUBKEY_INIT; > + > + // If we can read PubEK then there is no owner and we should take i= t. > + status =3D 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 =3D TPM_SUCCESS; > + break; > + case TPM_NO_ENDORSEMENT: > + { > + //If theres no ek, we have to create one > + TPM_KEY_PARMS keyInfo =3D { > + .algorithmID =3D TPM_ALG_RSA, > + .encScheme =3D TPM_ES_RSAESOAEP_SHA1_MGF1, > + .sigScheme =3D TPM_SS_NONE, > + .parmSize =3D 12, > + .parms.rsa =3D { > + .keyLength =3D RSA_KEY_SIZE, > + .numPrimes =3D 2, > + .exponentSize =3D 0, > + .exponent =3D NULL, > + }, > + }; > + TPMTRYRETURN(TPM_CreateEndorsementKeyPair(&keyInfo, &pubEK= )); > + } > + //fall through to take ownership > + case TPM_SUCCESS: > + { > + //Construct the Srk > + TPM_KEY srk =3D { > + .ver =3D TPM_STRUCT_VER_1_1, > + .keyUsage =3D TPM_KEY_STORAGE, > + .keyFlags =3D 0x00, > + .authDataUsage =3D TPM_AUTH_ALWAYS, > + .algorithmParms =3D { > + .algorithmID =3D TPM_ALG_RSA, > + .encScheme =3D TPM_ES_RSAESOAEP_SHA1_MGF1, > + .sigScheme =3D TPM_SS_NONE, > + .parmSize =3D 12, > + .parms.rsa =3D { > + .keyLength =3D RSA_KEY_SIZE, > + .numPrimes =3D 2, > + .exponentSize =3D 0, > + .exponent =3D NULL, > + }, > + }, > + .PCRInfoSize =3D 0, > + .pubKey =3D { > + .keyLength =3D 0, > + .key =3D NULL, > + }, > + .encDataSize =3D 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 =3D 1; > + key->ver.minor =3D 1; > + key->ver.revMajor =3D 0; > + key->ver.revMinor =3D 0; > + > + key->keyUsage =3D TPM_KEY_BIND; > + key->keyFlags =3D 0; > + key->authDataUsage =3D TPM_AUTH_ALWAYS; > + > + TPM_KEY_PARMS* p =3D &key->algorithmParms; > + p->algorithmID =3D TPM_ALG_RSA; > + p->encScheme =3D TPM_ES_RSAESOAEP_SHA1_MGF1; > + p->sigScheme =3D TPM_SS_NONE; > + p->parmSize =3D 12; > + > + TPM_RSA_KEY_PARMS* r =3D &p->parms.rsa; > + r->keyLength =3D RSA_KEY_SIZE; > + r->numPrimes =3D 2; > + r->exponentSize =3D 0; > + r->exponent =3D NULL; > + > + key->PCRInfoSize =3D 0; > + key->encDataSize =3D 0; > + key->encData =3D NULL; > +} > + > +static int parse_auth_string(char* authstr, BYTE* target, const TPM_AU= THDATA 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 +=3D 5; > + if((rc =3D strlen(authstr)) !=3D 40) { > + vtpmlogerror(VTPM_LOG_VTPM, "Supplied owner auth hex string `= %s' must be exactly 40 characters (20 bytes) long, length=3D%d\n", authst= r, rc); > + return -1; > + } > + for(int j =3D 0; j < 20; ++j) { > + if(sscanf(authstr, "%hhX", target + j) !=3D 1) { > + vtpmlogerror(VTPM_LOG_VTPM, "Supplied owner auth string `%= s' is not a valid hex string\n", authstr); > + return -1; > + } > + authstr +=3D 2; > + } > + } > + /* owner auth is a string that will be hashed */ > + else if(!strncmp(authstr, "text:", 5)) { > + authstr +=3D 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_AU= THDATA)); > + memcpy(vtpm_globals.srk_auth, WELLKNOWN_SRK_AUTH, sizeof(TPM_AUTHDA= TA)); > + > + for(i =3D 1; i < argc; ++i) { > + if(!strncmp(argv[i], "owner_auth:", 10)) { > + if((rc =3D parse_auth_string(argv[i] + 10, vtpm_globals.owner= _auth, WELLKNOWN_OWNER_AUTH, 1)) < 0) { > + goto err_invalid; > + } > + if(rc =3D=3D 1) { > + opts->gen_owner_auth =3D 1; > + } > + } > + else if(!strncmp(argv[i], "srk_auth:", 8)) { > + if((rc =3D parse_auth_string(argv[i] + 8, vtpm_globals.srk_au= th, WELLKNOWN_SRK_AUTH, 0)) !=3D 0) { > + goto err_invalid; > + } > + } > + else if(!strncmp(argv[i], "tpmdriver=3D", 10)) { > + if(!strcmp(argv[i] + 10, "tpm_tis")) { > + opts->tpmdriver =3D TPMDRV_TPM_TIS; > + } else if(!strcmp(argv[i] + 10, "tpmfront")) { > + opts->tpmdriver =3D TPMDRV_TPMFRONT; > + } else { > + goto err_invalid; > + } > + } > + else if(!strncmp(argv[i], "tpmiomem=3D",9)) { > + if(sscanf(argv[i] + 9, "0x%lX", &opts->tpmiomem) !=3D 1) { > + goto err_invalid; > + } > + } > + else if(!strncmp(argv[i], "tpmirq=3D",7)) { > + if(!strcmp(argv[i] + 7, "probe")) { > + opts->tpmirq =3D TPM_PROBE_IRQ; > + } else if( sscanf(argv[i] + 7, "%u", &opts->tpmirq) !=3D 1) {= > + goto err_invalid; > + } > + } > + else if(!strncmp(argv[i], "tpmlocality=3D",12)) { > + if(sscanf(argv[i] + 12, "%u", &opts->tpmlocality) !=3D 1 || o= pts->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 =3D TPM_SUCCESS; > + TPM_AUTH_SESSION osap =3D 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 =3D TPM_SUCCESS; > + > + /* Default commandline options */ > + struct Opts opts =3D { > + .tpmdriver =3D TPMDRV_TPM_TIS, > + .tpmiomem =3D TPM_BASEADDR, > + .tpmirq =3D 0, > + .tpmlocality =3D 0, > + .gen_owner_auth =3D 0, > + }; > + > + if(parse_cmdline_opts(argc, argv, &opts) !=3D 0) { > + vtpmlogerror(VTPM_LOG_VTPM, "Command line parsing failed! exitin= g..\n"); > + status =3D TPM_BAD_PARAMETER; > + goto abort_egress; > + } > + > + //Setup storage system > + if(vtpm_storage_init() !=3D 0) { > + vtpmlogerror(VTPM_LOG_VTPM, "Unable to initialize storage subsys= tem!\n"); > + status =3D 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 =3D init_tpm_tis(opts.tpmiomem, TPM_TIS_LOCL_INT_T= O_FLAG(opts.tpmlocality), opts.tpmirq)) =3D=3D NULL) { > + vtpmlogerror(VTPM_LOG_VTPM, "Unable to initialize tpmfr= ont device\n"); > + status =3D TPM_IOERROR; > + goto abort_egress; > + } > + vtpm_globals.tpm_fd =3D tpm_tis_open(tpm); > + tpm_tis_request_locality(tpm, opts.tpmlocality); > + } > + break; > + case TPMDRV_TPMFRONT: > + { > + struct tpmfront_dev* tpmfront_dev; > + if((tpmfront_dev =3D init_tpmfront(NULL)) =3D=3D NULL) { > + vtpmlogerror(VTPM_LOG_VTPM, "Unable to initialize tpmfr= ont device\n"); > + status =3D TPM_IOERROR; > + goto abort_egress; > + } > + vtpm_globals.tpm_fd =3D 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() !=3D TPM_SUCCESS) { > + vtpmlogerror(VTPM_LOG_VTPM, "VTPM_FlushResources failed, continu= ing 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.e= ntropy, NULL, 0); > + ctr_drbg_set_prediction_resistance( &vtpm_globals.ctr_drbg, CTR_DRB= G_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() !=3D TPM_SUCCESS) { > + /* If the OIAP session was closed by an error, create a new one = */ > + if(vtpm_globals.oiap.AuthHandle =3D=3D 0) { > + TPMTRYRETURN( TPM_OIAP(&vtpm_globals.oiap) ); > + } > + vtpmloginfo(VTPM_LOG_VTPM, "Failed to read manager file. Assumin= g 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 > +#include > +#include > + > +#include "tcg.h" > + > +char *module_names[] =3D { "", > + "TPM", > + "TPM", > + "VTPM", > + "VTPM", > + "TXDATA", > + }; > +// Helper code for the consts, eg. to produce messages for error codes= =2E > + > +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 [] =3D { > + { TPM_SUCCESS, "TPM_SUCCESS", "Successful completion of the operatio= n" }, > + { TPM_AUTHFAIL, "TPM_AUTHFAIL", "Authentication failed" }, > + { TPM_BADINDEX, "TPM_BADINDEX", "The index to a PCR, DIR or other re= gister is incorrect" }, > + { TPM_BAD_PARAMETER, "TPM_BAD_PARAMETER", "One or more parameter is = bad" }, > + { TPM_AUDITFAILURE, "TPM_AUDITFAILURE", "An operation completed succ= essfully 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 in= consistent" }, > + { TPM_INSTALL_DISABLED, "TPM_INSTALL_DISABLED", "The ability to inst= all an owner is disabled" }, > + { TPM_INVALID_KEYHANDLE, "TPM_INVALID_KEYHANDLE", "The key handle pr= esented was invalid" }, > + { TPM_KEYNOTFOUND, "TPM_KEYNOTFOUND", "The target key was not found"= }, > + { TPM_INAPPROPRIATE_ENC, "TPM_INAPPROPRIATE_ENC", "Unacceptable encr= yption scheme" }, > + { TPM_MIGRATEFAIL, "TPM_MIGRATEFAIL", "Migration authorization faile= d" }, > + { TPM_INVALID_PCR_INFO, "TPM_INVALID_PCR_INFO", "PCR information cou= ld 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 in= valid 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 thre= ad." }, > + { TPM_SHA_ERROR, "TPM_SHA_ERROR", "The calculation is unable to proc= eed because the existing SHA-1 thread has already encountered an error." = }, > + { TPM_FAILEDSELFTEST, "TPM_FAILEDSELFTEST", "Self-test has failed an= d 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 inf= ormation to the TPM" }, > + { TPM_ENCRYPT_ERROR, "TPM_ENCRYPT_ERROR", "The encryption process ha= d a problem." }, > + { TPM_DECRYPT_ERROR, "TPM_DECRYPT_ERROR", "The decryption process di= d not complete." }, > + { TPM_INVALID_AUTHHANDLE, "TPM_INVALID_AUTHHANDLE", "An invalid hand= le was used." }, > + { TPM_NO_ENDORSEMENT, "TPM_NO_ENDORSEMENT", "The TPM does not a EK i= nstalled" }, > + { TPM_INVALID_KEYUSAGE, "TPM_INVALID_KEYUSAGE", "The usage of a key = is not allowed" }, > + { TPM_WRONG_ENTITYTYPE, "TPM_WRONG_ENTITYTYPE", "The submitted entit= y type is not allowed" }, > + { TPM_INVALID_POSTINIT, "TPM_INVALID_POSTINIT", "The command was rec= eived in the wrong sequence relative to TPM_Init and a subsequent TPM_Sta= rtup" }, > + { TPM_INAPPROPRIATE_SIG, "TPM_INAPPROPRIATE_SIG", "Signed data canno= t 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 sch= eme for this key is incorrect or not permitted in this situation." }, > + { TPM_BAD_DATASIZE, "TPM_BAD_DATASIZE", "The size of the data (or bl= ob) parameter is bad or inconsistent with the referenced key" }, > + { TPM_BAD_MODE, "TPM_BAD_MODE", "A mode parameter is bad, such as ca= pArea 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 v= ersion 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 aud= it construction failed and the underlying command was returning a failure= code also" }, > + { TPM_AUDITFAIL_SUCCESSFUL, "TPM_AUDITFAIL_SUCCESSFUL", "TPM audit c= onstruction failed and the underlying command was returning success" }, > + { TPM_NOTRESETABLE, "TPM_NOTRESETABLE", "Attempt to reset a PCR regi= ster that does not have the resettable attribute" }, > + { TPM_NOTLOCAL, "TPM_NOTLOCAL", "Attempt to reset a PCR register tha= t requires locality and locality modifier not part of command transport" = }, > + { TPM_BAD_TYPE, "TPM_BAD_TYPE", "Make identity blob not properly typ= ed" }, > + { 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 co= mmand only available when in FIPS mode" }, > + { TPM_INVALID_FAMILY, "TPM_INVALID_FAMILY", "The command is attempti= ng to use an invalid family ID" }, > + { TPM_NO_NV_PERMISSION, "TPM_NO_NV_PERMISSION", "The permission to m= anipulate 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 f= or 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 n= ot match" }, > + { TPM_WRITE_LOCKED, "TPM_WRITE_LOCKED", "The NV area has already bee= n 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 incorre= ct" }, > + { TPM_NOT_FULLWRITE, "TPM_NOT_FULLWRITE", "The write is not a comple= te 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 writ= es 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 administrati= on is locked" }, > + { TPM_DELEGATE_FAMILY, "TPM_DELEGATE_FAMILY", "Attempt to manage a f= amily other then the delegated family" }, > + { TPM_DELEGATE_ADMIN, "TPM_DELEGATE_ADMIN", "Delegation table manage= ment not enabled" }, > + { TPM_TRANSPORT_EXCLUSIVE, "TPM_TRANSPORT_EXCLUSIVE", "There was a c= ommand 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 =3D 0; i < sizeof(error_msgs)/sizeof(error_msgs[0]); i++) > + if (code =3D=3D 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 // for uint32_t > +#include // for pointer NULL > +#include > +#include "tcg.h" > + > +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D LOGGING =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > + > +// 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) |=3D BITMASK(idx) > +#define CLEARBIT(num,idx) (num) &=3D ( ~ BITMASK(idx) ) > + > +#define vtpmloginfo(module, fmt, args...) \ > + if (GETBIT (LOGGING_MODULES, module) =3D=3D 1) { = \ > + fprintf (stdout, "INFO[%s]: " fmt, module_names[module], ##args); = \ > + } > + > +#define vtpmloginfomore(module, fmt, args...) \ > + if (GETBIT (LOGGING_MODULES, module) =3D=3D 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 > +#include > +#include > +#include "tcg.h" > + > +typedef enum UnpackPtr { > + UNPACK_ALIAS, > + UNPACK_ALLOC > +} UnpackPtr; > + > +inline BYTE* pack_BYTE(BYTE* ptr, BYTE t) { > + ptr[0] =3D t; > + return ++ptr; > +} > + > +inline BYTE* unpack_BYTE(BYTE* ptr, BYTE* t) { > + t[0] =3D 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 =3D (BYTE*)&t; > +#if __BYTE_ORDER =3D=3D __LITTLE_ENDIAN > + ptr[0] =3D b[1]; > + ptr[1] =3D b[0]; > +#elif __BYTE_ORDER =3D=3D __BIG_ENDIAN > + ptr[0] =3D b[0]; > + ptr[1] =3D b[1]; > +#endif > + return ptr + sizeof(UINT16); > +} > + > +inline BYTE* unpack_UINT16(BYTE* ptr, UINT16* t) { > + BYTE* b =3D (BYTE*)t; > +#if __BYTE_ORDER =3D=3D __LITTLE_ENDIAN > + b[0] =3D ptr[1]; > + b[1] =3D ptr[0]; > +#elif __BYTE_ORDER =3D=3D __BIG_ENDIAN > + b[0] =3D ptr[0]; > + b[1] =3D ptr[1]; > +#endif > + return ptr + sizeof(UINT16); > +} > + > +inline BYTE* pack_UINT32(BYTE* ptr, UINT32 t) { > + BYTE* b =3D (BYTE*)&t; > +#if __BYTE_ORDER =3D=3D __LITTLE_ENDIAN > + ptr[3] =3D b[0]; > + ptr[2] =3D b[1]; > + ptr[1] =3D b[2]; > + ptr[0] =3D b[3]; > +#elif __BYTE_ORDER =3D=3D __BIG_ENDIAN > + ptr[0] =3D b[0]; > + ptr[1] =3D b[1]; > + ptr[2] =3D b[2]; > + ptr[3] =3D b[3]; > +#endif > + return ptr + sizeof(UINT32); > +} > + > +inline BYTE* unpack_UINT32(BYTE* ptr, UINT32* t) { > + BYTE* b =3D (BYTE*)t; > +#if __BYTE_ORDER =3D=3D __LITTLE_ENDIAN > + b[0] =3D ptr[3]; > + b[1] =3D ptr[2]; > + b[2] =3D ptr[1]; > + b[3] =3D ptr[0]; > +#elif __BYTE_ORDER =3D=3D __BIG_ENDIAN > + b[0] =3D ptr[0]; > + b[1] =3D ptr[1]; > + b[2] =3D ptr[2]; > + b[3] =3D 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 =3D ptr; > + return ptr + size; > +} > + > +inline BYTE* unpack_ALLOC(BYTE* ptr, BYTE** buf, UINT32 size) { > + if(size) { > + *buf =3D malloc(size); > + memcpy(*buf, ptr, size); > + } else { > + *buf =3D NULL; > + } > + return ptr + size; > +} > + > +inline BYTE* unpack_PTR(BYTE* ptr, BYTE** buf, UINT32 size, UnpackPtr = alloc) { > + if(alloc =3D=3D 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] =3D t->major; > + ptr[1] =3D t->minor; > + ptr[2] =3D t->revMajor; > + ptr[3] =3D t->revMinor; > + return ptr + 4; > +} > + > +inline BYTE* unpack_TPM_VERSION(BYTE* ptr, TPM_VERSION* t) { > + t->major =3D ptr[0]; > + t->minor =3D ptr[1]; > + t->revMajor =3D ptr[2]; > + t->revMinor =3D ptr[3]; > + return ptr + 4; > +} > + > +inline BYTE* pack_TPM_CAP_VERSION_INFO(BYTE* ptr, const TPM_CAP_VERSIO= N_INFO* v) { > + ptr =3D pack_TPM_STRUCTURE_TAG(ptr, v->tag); > + ptr =3D pack_TPM_VERSION(ptr, &v->version); > + ptr =3D pack_UINT16(ptr, v->specLevel); > + ptr =3D pack_BYTE(ptr, v->errataRev); > + ptr =3D pack_BUFFER(ptr, v->tpmVendorID, sizeof(v->tpmVendorID)); > + ptr =3D pack_UINT16(ptr, v->vendorSpecificSize); > + ptr =3D pack_BUFFER(ptr, v->vendorSpecific, v->vendorSpecificSize);= > + return ptr; > +} > + > +inline BYTE* unpack_TPM_CAP_VERSION_INFO(BYTE* ptr, TPM_CAP_VERSION_IN= FO* v, UnpackPtr alloc) { > + ptr =3D unpack_TPM_STRUCTURE_TAG(ptr, &v->tag); > + ptr =3D unpack_TPM_VERSION(ptr, &v->version); > + ptr =3D unpack_UINT16(ptr, &v->specLevel); > + ptr =3D unpack_BYTE(ptr, &v->errataRev); > + ptr =3D unpack_BUFFER(ptr, v->tpmVendorID, sizeof(v->tpmVendorID));= > + ptr =3D unpack_UINT16(ptr, &v->vendorSpecificSize); > + ptr =3D 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_SYMMETR= IC_KEY_PARMS* k) { > + ptr =3D pack_UINT32(ptr, k->keyLength); > + ptr =3D pack_UINT32(ptr, k->blockSize); > + ptr =3D pack_UINT32(ptr, k->ivSize); > + return pack_BUFFER(ptr, k->IV, k->ivSize); > +} > + > +inline BYTE* unpack_TPM_SYMMETRIC_KEY_PARMS(BYTE* ptr, TPM_SYMMETRIC_K= EY_PARMS* k, UnpackPtr alloc) { > + ptr =3D unpack_UINT32(ptr, &k->keyLength); > + ptr =3D unpack_UINT32(ptr, &k->blockSize); > + ptr =3D 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 =3D pack_UINT32(ptr, k->keyLength); > + ptr =3D pack_UINT32(ptr, k->numPrimes); > + ptr =3D 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 =3D unpack_UINT32(ptr, &k->keyLength); > + ptr =3D unpack_UINT32(ptr, &k->numPrimes); > + ptr =3D 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 =3D pack_TPM_ALGORITHM_ID(ptr, k->algorithmID); > + ptr =3D pack_TPM_ENC_SCHEME(ptr, k->encScheme); > + ptr =3D pack_TPM_SIG_SCHEME(ptr, k->sigScheme); > + ptr =3D 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, UnpackP= tr alloc) { > + ptr =3D unpack_TPM_ALGORITHM_ID(ptr, &k->algorithmID); > + ptr =3D unpack_TPM_ENC_SCHEME(ptr, &k->encScheme); > + ptr =3D unpack_TPM_SIG_SCHEME(ptr, &k->sigScheme); > + ptr =3D 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 =3D pack_UINT32(ptr, k->keyLength); > + ptr =3D pack_BUFFER(ptr, k->key, k->keyLength); > + return ptr; > +} > + > +inline BYTE* unpack_TPM_STORE_PUBKEY(BYTE* ptr, TPM_STORE_PUBKEY* k, U= npackPtr alloc) { > + ptr =3D unpack_UINT32(ptr, &k->keyLength); > + ptr =3D unpack_PTR(ptr, &k->key, k->keyLength, alloc); > + return ptr; > +} > + > +inline BYTE* pack_TPM_PUBKEY(BYTE* ptr, const TPM_PUBKEY* k) { > + ptr =3D 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 all= oc) { > + ptr =3D 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 =3D pack_UINT16(ptr, p->sizeOfSelect); > + ptr =3D pack_BUFFER(ptr, p->pcrSelect, p->sizeOfSelect); > + return ptr; > +} > + > +inline BYTE* unpack_TPM_PCR_SELECTION(BYTE* ptr, TPM_PCR_SELECTION* p,= UnpackPtr alloc) { > + ptr =3D unpack_UINT16(ptr, &p->sizeOfSelect); > + ptr =3D unpack_PTR(ptr, &p->pcrSelect, p->sizeOfSelect, alloc); > + return ptr; > +} > + > +inline BYTE* pack_TPM_PCR_INFO(BYTE* ptr, const TPM_PCR_INFO* p) { > + ptr =3D pack_TPM_PCR_SELECTION(ptr, &p->pcrSelection); > + ptr =3D pack_TPM_COMPOSITE_HASH(ptr, &p->digestAtRelease); > + ptr =3D pack_TPM_COMPOSITE_HASH(ptr, &p->digestAtCreation); > + return ptr; > +} > + > +inline BYTE* unpack_TPM_PCR_INFO(BYTE* ptr, TPM_PCR_INFO* p, UnpackPtr= alloc) { > + ptr =3D unpack_TPM_PCR_SELECTION(ptr, &p->pcrSelection, alloc); > + ptr =3D unpack_TPM_COMPOSITE_HASH(ptr, &p->digestAtRelease); > + ptr =3D unpack_TPM_COMPOSITE_HASH(ptr, &p->digestAtCreation); > + return ptr; > +} > + > +inline BYTE* pack_TPM_PCR_COMPOSITE(BYTE* ptr, const TPM_PCR_COMPOSITE= * p) { > + ptr =3D pack_TPM_PCR_SELECTION(ptr, &p->select); > + ptr =3D pack_UINT32(ptr, p->valueSize); > + ptr =3D 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 =3D unpack_TPM_PCR_SELECTION(ptr, &p->select, alloc); > + ptr =3D unpack_UINT32(ptr, &p->valueSize); > + ptr =3D unpack_PTR(ptr, (BYTE**)&p->pcrValue, p->valueSize, alloc);= > + return ptr; > +} > + > +inline BYTE* pack_TPM_KEY(BYTE* ptr, const TPM_KEY* k) { > + ptr =3D pack_TPM_VERSION(ptr, &k->ver); > + ptr =3D pack_TPM_KEY_USAGE(ptr, k->keyUsage); > + ptr =3D pack_TPM_KEY_FLAGS(ptr, k->keyFlags); > + ptr =3D pack_TPM_AUTH_DATA_USAGE(ptr, k->authDataUsage); > + ptr =3D pack_TPM_KEY_PARMS(ptr, &k->algorithmParms); > + ptr =3D pack_UINT32(ptr, k->PCRInfoSize); > + if(k->PCRInfoSize) { > + ptr =3D pack_TPM_PCR_INFO(ptr, &k->PCRInfo); > + } > + ptr =3D pack_TPM_STORE_PUBKEY(ptr, &k->pubKey); > + ptr =3D 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 =3D unpack_TPM_VERSION(ptr, &k->ver); > + ptr =3D unpack_TPM_KEY_USAGE(ptr, &k->keyUsage); > + ptr =3D unpack_TPM_KEY_FLAGS(ptr, &k->keyFlags); > + ptr =3D unpack_TPM_AUTH_DATA_USAGE(ptr, &k->authDataUsage); > + ptr =3D unpack_TPM_KEY_PARMS(ptr, &k->algorithmParms, alloc); > + ptr =3D unpack_UINT32(ptr, &k->PCRInfoSize); > + if(k->PCRInfoSize) { > + ptr =3D unpack_TPM_PCR_INFO(ptr, &k->PCRInfo, alloc); > + } > + ptr =3D unpack_TPM_STORE_PUBKEY(ptr, &k->pubKey, alloc); > + ptr =3D 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, U= INT32 payloadSize) { > + ptr =3D pack_TPM_VERSION(ptr, &b->ver); > + ptr =3D 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, UINT3= 2 payloadSize, UnpackPtr alloc) { > + ptr =3D unpack_TPM_VERSION(ptr, &b->ver); > + ptr =3D 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 =3D pack_TPM_VERSION(ptr, &d->ver); > + ptr =3D pack_UINT32(ptr, d->sealInfoSize); > + if(d->sealInfoSize) { > + ptr =3D pack_TPM_PCR_INFO(ptr, &d->sealInfo); > + } > + ptr =3D pack_UINT32(ptr, d->encDataSize); > + ptr =3D pack_BUFFER(ptr, d->encData, d->encDataSize); > + return ptr; > +} > + > +inline BYTE* unpack_TPM_STORED_DATA(BYTE* ptr, TPM_STORED_DATA* d, Unp= ackPtr alloc) { > + ptr =3D unpack_TPM_VERSION(ptr, &d->ver); > + ptr =3D unpack_UINT32(ptr, &d->sealInfoSize); > + if(d->sealInfoSize) { > + ptr =3D unpack_TPM_PCR_INFO(ptr, &d->sealInfo, alloc); > + } > + ptr =3D unpack_UINT32(ptr, &d->encDataSize); > + ptr =3D unpack_PTR(ptr, &d->encData, d->encDataSize, alloc); > + return ptr; > +} > + > +inline BYTE* pack_TPM_AUTH_SESSION(BYTE* ptr, const TPM_AUTH_SESSION* = auth) { > + ptr =3D pack_TPM_AUTH_HANDLE(ptr, auth->AuthHandle); > + ptr =3D pack_TPM_NONCE(ptr, &auth->NonceOdd); > + ptr =3D pack_BOOL(ptr, auth->fContinueAuthSession); > + ptr =3D pack_TPM_AUTHDATA(ptr, &auth->HMAC); > + return ptr; > +} > + > +inline BYTE* unpack_TPM_AUTH_SESSION(BYTE* ptr, TPM_AUTH_SESSION* auth= ) { > + ptr =3D unpack_TPM_NONCE(ptr, &auth->NonceEven); > + ptr =3D unpack_BOOL(ptr, &auth->fContinueAuthSession); > + ptr =3D 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 =3D pack_UINT16(ptr, tag); > + ptr =3D 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 =3D unpack_UINT16(ptr, tag); > + ptr =3D unpack_UINT32(ptr, size); > + ptr =3D 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=3Dy > +CONFIG_TPM_TIS=3Dy > +CONFIG_TPMBACK=3Dy > +CONFIG_START_NETWORK=3Dn > +CONFIG_TEST=3Dn > +CONFIG_PCIFRONT=3Dn > +CONFIG_BLKFRONT=3Dy > +CONFIG_NETFRONT=3Dn > +CONFIG_FBFRONT=3Dn > +CONFIG_KBDFRONT=3Dn > +CONFIG_CONSFRONT=3Dn > +CONFIG_XENBUS=3Dy > +CONFIG_LWIP=3Dn > +CONFIG_XC=3Dn > 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 > +#include > + > +// **************************** 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_ORDINA= L) > +#define TPM_ORD_GetCapability (101UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_GetCapabilityOwner (102UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_OwnerSetDisable (110UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_PhysicalEnable (111UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_PhysicalDisable (112UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_SetOwnerInstall (113UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_PhysicalSetDeactivated (114UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_SetTempDeactivated (115UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_CreateEndorsementKeyPair (120UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_MakeIdentity (121UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_ActivateIdentity (122UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_ReadPubek (124UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_OwnerReadPubek (125UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_DisablePubekRead (126UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_GetAuditEvent (130UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_GetAuditEventSigned (131UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_GetOrdinalAuditStatus (140UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_SetOrdinalAuditStatus (141UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_Terminate_Handle (150UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_Init (151UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_SaveState (152UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_Startup (153UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_SetRedirection (154UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_SHA1Start (160UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_SHA1Update (161UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_SHA1Complete (162UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_SHA1CompleteExtend (163UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_FieldUpgrade (170UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_SaveKeyContext (180UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_LoadKeyContext (181UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_SaveAuthContext (182UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_LoadAuthContext (183UL + TPM_PROTECTED_ORDINA= L) > +#define TPM_ORD_SaveContext (184UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_LoadContext (185UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_FlushSpecific (186UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_PCR_Reset (200UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_NV_DefineSpace (204UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_NV_WriteValue (205UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_NV_WriteValueAuth (206UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_NV_ReadValue (207UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_NV_ReadValueAuth (208UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_Delegate_UpdateVerification (209UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_Delegate_Manage (210UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_Delegate_CreateKeyDelegation (212UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_Delegate_CreateOwnerDelegation (213UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_Delegate_VerifyDelegation (214UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_Delegate_LoadOwnerDelegation (216UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_Delegate_ReadAuth (217UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_Delegate_ReadTable (219UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_CreateCounter (220UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_IncrementCounter (221UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_ReadCounter (222UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_ReleaseCounter (223UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_ReleaseCounterOwner (224UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_EstablishTransport (230UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_ExecuteTransport (231UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_ReleaseTransportSigned (232UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_GetTicks (241UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_TickStampBlob (242UL + TPM_PROTECTE= D_ORDINAL) > +#define TPM_ORD_MAX (256UL + TPM_PROTECTE= D_ORDINAL) > + > +#define TSC_ORD_PhysicalPresence (10UL + TPM_CONNECTION_ORDINA= L) > + > + > + > +// > +// 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 c= ode is a non-fatal failure. > + > +#define TPM_SUCCESS TPM_BASE // Successful completion of the operati= on > +#define TPM_AUTHFAIL TPM_BASE + 1 // Authentication failed > +#define TPM_BADINDEX TPM_BASE + 2 // The index to a PCR, DIR or o= ther 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 su= ccessfully 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 be= en disabled > +#define TPM_FAIL TPM_BASE + 9 // The operation failed > +#define TPM_BAD_ORDINAL TPM_BASE + 10 // The ordinal was unknown o= r 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 present= ed was invalid > +#define TPM_KEYNOTFOUND TPM_BASE + 13 // The target key was not fo= und > +#define TPM_INAPPROPRIATE_ENC TPM_BASE + 14 // Unacceptable encryptio= n scheme > +#define TPM_MIGRATEFAIL TPM_BASE + 15 // Migration authorization f= ailed > +#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 i= nvalid 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 i= nternal resources to perform the requested action. > +#define TPM_SHORTRANDOM TPM_BASE + 22 // A random string was too s= hort > +#define TPM_SIZE TPM_BASE + 23 // The TPM does not have the spac= e 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 e= rror. > +#define TPM_FAILEDSELFTEST TPM_BASE + 28 // Self-test has failed a= nd 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 transmi= tting 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 t= ype is not allowed > +#define TPM_INVALID_POSTINIT TPM_BASE + 38 // The command was receiv= ed in the wrong sequence relative to TPM_Init and a subsequent TPM_Startu= p > +#define TPM_INAPPROPRIATE_SIG TPM_BASE + 39 // Signed data cannot inc= lude 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 properti= es of this key are incorrect. > +#define TPM_BAD_SCHEME TPM_BASE + 42 // The signature or encrypt= ion scheme for this key is incorrect or not permitted in this situation. > +#define TPM_BAD_DATASIZE TPM_BASE + 43 // The size of the data (o= r blob) parameter is bad or inconsistent with the referenced key > +#define TPM_BAD_MODE TPM_BASE + 44 // A mode parameter is bad, s= uch as capArea or subCapArea for TPM_GetCapability, phsicalPresence param= eter for TPM_PhysicalPresence, or migrationType for TPM_CreateMigrationBl= ob. > +#define TPM_BAD_PRESENCE TPM_BASE + 45 // Either the physicalPres= ence or physicalPresenceLock bits have the wrong value > +#define TPM_BAD_VERSION TPM_BASE + 46 // The TPM cannot perform t= his version of the capability > +#define TPM_NO_WRAP_TRANSPORT TPM_BASE + 47 // The TPM does not al= low for wrapped transport sessions > +#define TPM_AUDITFAIL_UNSUCCESSFUL TPM_BASE + 48 // TPM audit construc= tion failed and the underlying command was returning a failure code also > +#define TPM_AUDITFAIL_SUCCESSFUL TPM_BASE + 49 // TPM audit construc= tion 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 reg= ister that requires locality and locality modifier not part of command tr= ansport > +#define TPM_BAD_TYPE TPM_BASE + 52 // Make identity blob not pro= perly 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 ex= ecute a command only available when in FIPS mode > +#define TPM_INVALID_FAMILY TPM_BASE + 55 // The command is attemp= ting to use an invalid family ID > +#define TPM_NO_NV_PERMISSION TPM_BASE + 56 // The permission to ma= nipulate 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 l= oad an NV key > +#define TPM_AUTH_CONFLICT TPM_BASE + 59 // NV_LoadKey blob requir= es both owner and blob authorization > +#define TPM_AREA_LOCKED TPM_BASE + 60 // The NV area is locked an= d not writtable > +#define TPM_BAD_LOCALITY TPM_BASE + 61 // The locality is incorre= ct 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 o= n the write to the NV area > +#define TPM_FAMILYCOUNT TPM_BASE + 64 // The family count value d= oes 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 attribute= s conflict > +#define TPM_INVALID_STRUCTURE TPM_BASE + 67 // The structure tag a= nd version are invalid or inconsistent > +#define TPM_KEY_OWNER_CONTROL TPM_BASE + 68 // The key is under co= ntrol of the TPM Owner and can only be evicted by the TPM Owner. > +#define TPM_BAD_COUNTER TPM_BASE + 69 // The counter handle is in= correct > +#define TPM_NOT_FULLWRITE TPM_BASE + 70 // The write is not a com= plete write of the area > +#define TPM_CONTEXT_GAP TPM_BASE + 71 // The gap between saved co= ntext 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 authorizatio= n 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 administr= ation is locked > +#define TPM_DELEGATE_FAMILY TPM_BASE + 76 // Attempt to manage a f= amily other then the delegated family > +#define TPM_DELEGATE_ADMIN TPM_BASE + 77 // Delegation table mana= gement not enabled > +#define TPM_TRANSPORT_EXCLUSIVE TPM_BASE + 78 // There was a comman= d 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], Sect= ion 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 s= ession > +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 =3D { 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 =3D 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 =3D 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 =3D 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 =3D 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 =3D 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 =3D 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 =3D TPM_KEY_PARMS_INIT,\ > + .PCRInfoSize =3D 0, .PCRInfo =3D TPM_PCR_INFO_INIT, \ > + .pubKey =3D TPM_STORE_PUBKEY_INIT, \ > + .encDataSize =3D 0, .encData =3D 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 =3D NULL; > +} > + > +typedef struct TPM_BOUND_DATA { > + TPM_VERSION ver; > + TPM_PAYLOAD_TYPE payload; > + BYTE* payloadData; > +} TPM_BOUND_DATA; > + > +#define TPM_BOUND_DATA_INIT { .payloadData =3D NULL } > + > +inline void free_TPM_BOUND_DATA(TPM_BOUND_DATA* d) { > + free(d->payloadData); > + d->payloadData =3D 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 =3D 0, sealInfo =3D TPM_P= CR_INFO_INIT,\ > + .encDataSize =3D 0, .encData =3D 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 =3D 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 =3D 0, .fContinueAuthSessi= on =3D FALSE } > + > +// ---------------------- Functions for checking TPM_RESULTs ---------= -------- > + > +#include > + > +// 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 statu= s > +#define ERRORDIE(s) do { status =3D 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 statu= s > +// Try command c. If it fails, set status to s and goto abort. > +#define TPMTRY(s,c) if (c !=3D TPM_SUCCESS) { \ > + status =3D s; \ > + printf("ERROR in %s at %s:%i code: %s.\n", __fu= nc__, __FILE__, __LINE__, tpm_get_error_name(status)); \ > + goto abort_egress; \ > + } else {\ > + status =3D c; \ > + } > + > +// Try command c. If it fails, print error message, set status to actu= al return code. Goto abort > +#define TPMTRYRETURN(c) do { status =3D c; \ > + if (status !=3D TPM_SUCCESS) { \ > + fprintf(stderr, "ERROR in %s at %s:%i c= ode: %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 > +#include > +#include > +#include > +#include > + > +#include > + > +#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 =3D TAG;\ > +TPM_TAG tag =3D intag;\ > +UINT32 paramSize;\ > +const TPM_COMMAND_CODE ordinal =3D ORD;\ > +TPM_RESULT status =3D TPM_SUCCESS;\ > +BYTE in_buf[TCPA_MAX_BUFFER_LENGTH];\ > +BYTE out_buf[TCPA_MAX_BUFFER_LENGTH];\ > +UINT32 out_len =3D sizeof(out_buf);\ > +BYTE* ptr =3D in_buf;\ > +/*Print a log message */\ > +vtpmloginfo(VTPM_LOG_TPM, "%s\n", __func__);\ > +/* Pack the header*/\ > +ptr =3D pack_TPM_TAG(ptr, tag);\ > +ptr +=3D sizeof(UINT32);\ > +ptr =3D pack_TPM_COMMAND_CODE(ptr, ordinal)\ > + > +#define TPM_AUTH_BEGIN() \ > + sha1_context sha1_ctx;\ > +BYTE* authbase =3D 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(¶mDigest, HMACkey, auth);\ > + ptr =3D pack_TPM_AUTH_SESSION(ptr, auth);\ > +} while(0) > + > +#define TPM_AUTH2_GEN(HMACkey, auth) do {\ > + generateAuth(¶mDigest, HMACkey, auth);\ > + ptr =3D pack_TPM_AUTH_SESSION(ptr, auth);\ > +} while(0) > + > +#define TPM_TRANSMIT() do {\ > + /* Pack the command size */\ > + paramSize =3D ptr - in_buf;\ > + pack_UINT32(in_buf + sizeof(TPM_TAG), paramSize);\ > + if((status =3D TPM_TransmitData(in_buf, paramSize, out_buf, &out_le= n)) !=3D TPM_SUCCESS) {\ > + goto abort_egress;\ > + }\ > +} while(0) > + > +#define TPM_AUTH_VERIFY_BEGIN() do {\ > + UINT32 buf[2] =3D { cpu_to_be32(status), cpu_to_be32(ordinal) };\ > + sha1_starts(&sha1_ctx);\ > + sha1_update(&sha1_ctx, (unsigned char*)buf, sizeof(buf));\ > + authbase =3D ptr;\ > +} while(0) > + > +#define TPM_AUTH1_VERIFY(HMACkey, auth) do {\ > + sha1_finish(&sha1_ctx, paramDigest.digest);\ > + ptr =3D unpack_TPM_AUTH_SESSION(ptr, auth);\ > + if((status =3D verifyAuth(¶mDigest, HMACkey, auth)) !=3D TPM_SU= CCESS) {\ > + goto abort_egress;\ > + }\ > +} while(0) > + > +#define TPM_AUTH2_VERIFY(HMACkey, auth) do {\ > + ptr =3D unpack_TPM_AUTH_SESSION(ptr, auth);\ > + if((status =3D verifyAuth(¶mDigest, HMACkey, auth)) !=3D TPM_SU= CCESS) {\ > + goto abort_egress;\ > + }\ > +} while(0) > + > + > + > +#define TPM_UNPACK_VERIFY() do { \ > + ptr =3D out_buf;\ > + ptr =3D unpack_TPM_RSP_HEADER(ptr, \ > + &(tag), &(paramSize), &(status));\ > + if((status) !=3D TPM_SUCCESS || (tag) !=3D (intag +3)) { \ > + vtpmlogerror(VTPM_LOG_TPM, "Failed with return code %s\n", tpm_g= et_error_name(status));\ > + goto abort_egress;\ > + }\ > +} while(0) > + > +#define TPM_AUTH_HASH() do {\ > + sha1_update(&sha1_ctx, authbase, ptr - authbase);\ > + authbase =3D ptr;\ > +} while(0) > + > +#define TPM_AUTH_SKIP() do {\ > + authbase =3D ptr;\ > +} while(0) > + > +#define TPM_AUTH_ERR_CHECK(auth) do {\ > + if(status !=3D TPM_SUCCESS || auth->fContinueAuthSession =3D=3D FAL= SE) {\ > + vtpmloginfo(VTPM_LOG_TPM, "Auth Session: 0x%x closed by TPM\n", = auth->AuthHandle);\ > + auth->AuthHandle =3D 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 =3D XORbuffer; > + ptr =3D pack_TPM_SECRET(ptr, sharedSecret); > + ptr =3D pack_TPM_NONCE(ptr, nonce); > + > + sha1(XORbuffer, ptr - XORbuffer, XORkey); > + > + if(inAuth0) { > + for(int i =3D 0; i < TPM_DIGEST_SIZE; ++i) { > + outAuth0[i] =3D XORkey[i] ^ (*inAuth0)[i]; > + } > + } > + if(inAuth1) { > + for(int i =3D 0; i < TPM_DIGEST_SIZE; ++i) { > + outAuth1[i] =3D 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)= =2E > + BYTE hmacText[sizeof(TPM_DIGEST) + (2 * sizeof(TPM_NONCE)) + sizeof= (BOOL)]; > + BYTE* ptr =3D hmacText; > + > + ptr =3D pack_TPM_DIGEST(ptr, paramDigest); > + ptr =3D pack_TPM_NONCE(ptr, &auth->NonceEven); > + ptr =3D pack_TPM_NONCE(ptr, &auth->NonceOdd); > + ptr =3D 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)= =2E > + TPM_AUTHDATA hm; > + BYTE hmacText[sizeof(TPM_DIGEST) + (2 * sizeof(TPM_NONCE)) + sizeof= (BOOL)]; > + BYTE* ptr =3D hmacText; > + > + ptr =3D pack_TPM_DIGEST(ptr, paramDigest); > + ptr =3D pack_TPM_NONCE(ptr, &auth->NonceEven); > + ptr =3D pack_TPM_NONCE(ptr, &auth->NonceOdd); > + ptr =3D 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)) =3D=3D 0) { // 0 ind= icates 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 =3D TRUE; > + > + ptr =3D unpack_UINT32(ptr, &auth->AuthHandle); > + ptr =3D 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 =3D pack_TPM_ENTITY_TYPE(ptr, entityType); > + ptr =3D pack_UINT32(ptr, entityValue); > + > + //nonce Odd OSAP > + nonceOddOSAP =3D ptr; > + vtpmmgr_rand(ptr, TPM_DIGEST_SIZE); > + ptr +=3D TPM_DIGEST_SIZE; > + > + TPM_TRANSMIT(); > + TPM_UNPACK_VERIFY(); > + > + ptr =3D unpack_UINT32(ptr, &auth->AuthHandle); > + ptr =3D 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 =3D nonceEvenOS= AP > + sha1_hmac_update(&ctx, nonceOddOSAP, TPM_DIGEST_SIZE); > + sha1_hmac_finish(&ctx, *sharedSecret); > + > + memset(&auth->HMAC, 0, sizeof(TPM_DIGEST)); > + auth->fContinueAuthSession =3D 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 =3D 0; > + tpmrsa_context ek_rsa =3D 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 =3D pack_UINT16(ptr, TPM_PID_OWNER); > + > + /* Pack the encrypted owner auth */ > + ptr =3D 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 +=3D pubEK->algorithmParms.parms.rsa.keyLength / 8; > + > + /* Pack the encrypted srk auth */ > + ptr =3D 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 +=3D pubEK->algorithmParms.parms.rsa.keyLength / 8; > + > + /* Pack the Srk key */ > + ptr =3D 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 !=3D NULL) { > + /* If the user wants a copy of the srk we give it to them */ > + keyAlloced =3D 1; > + ptr =3D unpack_TPM_KEY(ptr, outSrk, UNPACK_ALLOC); > + } else { > + /*otherwise just parse past it */ > + TPM_KEY temp; > + ptr =3D 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 =3D=3D 0) { > + return TPM_SUCCESS; > + } > + > + TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_Terminate_Handle); > + > + ptr =3D pack_TPM_AUTHHANDLE(ptr, handle); > + > + TPM_TRANSMIT(); > + TPM_UNPACK_VERIFY(); > + > + vtpmloginfo(VTPM_LOG_TPM, "Auth Session: 0x%x closed by TPM_Termina= teHandle\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 =3D pack_TPM_PCRINDEX(ptr, pcrNum); > + ptr =3D pack_TPM_DIGEST(ptr, &inDigest); > + > + TPM_TRANSMIT(); > + TPM_UNPACK_VERIFY(); > + > + ptr =3D 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 =3D 0; > + TPM_BEGIN(TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_Seal); > + TPM_AUTH_BEGIN(); > + > + TPM_AUTH_HASH(); > + > + ptr =3D pack_TPM_KEY_HANDLE(ptr, keyHandle); > + > + TPM_AUTH_SKIP(); > + > + xorEncrypt(osapSharedSecret, &pubAuth->NonceEven, > + sealedDataAuth, ptr, > + NULL, NULL); > + ptr +=3D sizeof(TPM_ENCAUTH); > + > + ptr =3D pack_UINT32(ptr, pcrInfoSize); > + ptr =3D pack_TPM_PCR_INFO(ptr, pcrInfo); > + > + ptr =3D pack_UINT32(ptr, inDataSize); > + ptr =3D pack_BUFFER(ptr, inData, inDataSize); > + > + TPM_AUTH_HASH(); > + > + TPM_AUTH1_GEN(osapSharedSecret, pubAuth); > + TPM_TRANSMIT(); > + TPM_UNPACK_VERIFY(); > + TPM_AUTH_VERIFY_BEGIN(); > + > + ptr =3D unpack_TPM_STORED_DATA(ptr, sealedData, UNPACK_ALLOC); > + dataAlloced =3D 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 =3D pack_TPM_KEY_HANDLE(ptr, parentHandle); > + > + TPM_AUTH_SKIP(); > + > + ptr =3D 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 =3D unpack_UINT32(ptr, outSize); > + ptr =3D 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 =3D TPMRSA_CTX_INIT; > + TPM_BOUND_DATA boundData; > + uint8_t plain[TCPA_MAX_BUFFER_LENGTH]; > + BYTE* ptr =3D 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 =3D TPM_STRUCT_VER_1_1; > + boundData.payload =3D TPM_PT_BIND; > + boundData.payloadData =3D (BYTE*)in; > + > + //marshall the bound data object > + ptr =3D 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 =3D pack_TPM_KEY_HANDLE(ptr, keyHandle); > + > + TPM_AUTH_SKIP(); > + > + ptr =3D pack_UINT32(ptr, ilen); > + ptr =3D pack_BUFFER(ptr, in, ilen); > + > + TPM_AUTH_HASH(); > + > + TPM_AUTH1_GEN(usage_auth, auth); > + TPM_TRANSMIT(); > + TPM_UNPACK_VERIFY(); > + TPM_AUTH_VERIFY_BEGIN(); > + > + ptr =3D unpack_UINT32(ptr, olen); > + if(*olen > ilen) { > + vtpmlogerror(VTPM_LOG_TPM, "Output length < input length!\n"); > + status =3D TPM_IOERROR; > + goto abort_egress; > + } > + ptr =3D 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 =3D 0; > + TPM_BEGIN(TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_CreateWrapKey); > + TPM_AUTH_BEGIN(); > + > + TPM_AUTH_HASH(); > + > + ptr =3D pack_TPM_KEY_HANDLE(ptr, hWrappingKey); > + > + TPM_AUTH_SKIP(); > + > + //Encrypted auths > + xorEncrypt(osapSharedSecret, &pAuth->NonceEven, > + dataUsageAuth, ptr, > + dataMigrationAuth, ptr + sizeof(TPM_ENCAUTH)); > + ptr +=3D sizeof(TPM_ENCAUTH) * 2; > + > + ptr =3D pack_TPM_KEY(ptr, key); > + > + TPM_AUTH_HASH(); > + > + TPM_AUTH1_GEN(osapSharedSecret, pAuth); > + TPM_TRANSMIT(); > + TPM_UNPACK_VERIFY(); > + TPM_AUTH_VERIFY_BEGIN(); > + > + keyAlloced =3D 1; > + ptr =3D 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 =3D pack_TPM_KEY_HANDLE(ptr, parentHandle); > + > + TPM_AUTH_SKIP(); > + > + ptr =3D pack_TPM_KEY(ptr, key); > + > + TPM_AUTH_HASH(); > + > + TPM_AUTH1_GEN(usage_auth, auth); > + TPM_TRANSMIT(); > + TPM_UNPACK_VERIFY(); > + TPM_AUTH_VERIFY_BEGIN(); > + > + ptr =3D 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 =3D=3D 0) { > + return TPM_SUCCESS; > + } > + > + TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_EvictKey); > + > + ptr =3D 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 =3D=3D 0) { > + return TPM_SUCCESS; > + } > + > + TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_FlushSpecific); > + > + ptr =3D pack_TPM_HANDLE(ptr, handle); > + ptr =3D 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 =3D=3D NULL || randomBytes =3D=3D NULL){ > + return TPM_BAD_PARAMETER; > + } > + > + ptr =3D pack_UINT32(ptr, *bytesRequested); > + > + TPM_TRANSMIT(); > + TPM_UNPACK_VERIFY(); > + > + ptr =3D unpack_UINT32(ptr, bytesRequested); > + ptr =3D unpack_BUFFER(ptr, randomBytes, *bytesRequested); > + > +abort_egress: > + return status; > +} > + > + > +TPM_RESULT TPM_ReadPubek( > + TPM_PUBKEY* pubEK //out > + ) > +{ > + BYTE* antiReplay =3D NULL; > + BYTE* kptr =3D 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 =3D ptr; > + ptr +=3D TPM_DIGEST_SIZE; > + > + TPM_TRANSMIT(); > + TPM_UNPACK_VERIFY(); > + > + //unpack and allocate the key > + kptr =3D ptr; > + ptr =3D 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 =3D TPM_FAIL; > + goto abort_egress; > + } > + > + goto egress; > +abort_egress: > + if(kptr !=3D 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 =3D pack_TPM_CAPABILITY_AREA(ptr, capArea); > + ptr =3D pack_UINT32(ptr, subCapSize); > + ptr =3D pack_BUFFER(ptr, subCap, subCapSize); > + > + TPM_TRANSMIT(); > + TPM_UNPACK_VERIFY(); > + > + ptr =3D unpack_UINT32(ptr, respSize); > + ptr =3D unpack_ALLOC(ptr, resp, *respSize); > + > +abort_egress: > + return status; > +} > + > +TPM_RESULT TPM_CreateEndorsementKeyPair( > + const TPM_KEY_PARMS* keyInfo, > + TPM_PUBKEY* pubEK) > +{ > + BYTE* kptr =3D 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 =3D pack_TPM_NONCE(ptr, &antiReplay); > + ptr =3D pack_TPM_KEY_PARMS(ptr, keyInfo); > + > + TPM_TRANSMIT(); > + TPM_UNPACK_VERIFY(); > + > + sha1_starts(&ctx); > + > + kptr =3D ptr; > + ptr =3D unpack_TPM_PUBKEY(ptr, pubEK, UNPACK_ALLOC); > + > + /* Hash the pub key blob */ > + sha1_update(&ctx, kptr, ptr - kptr); > + ptr =3D 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 ve= rification failed!\n"); > + status =3D 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 =3D TPM_SUCCESS; > + > + UINT32 i; > + vtpmloginfo(VTPM_LOG_TXDATA, "Sending buffer =3D 0x"); > + for(i =3D 0 ; i < insize ; i++) > + vtpmloginfomore(VTPM_LOG_TXDATA, "%2.2x ", in[i]); > + > + vtpmloginfomore(VTPM_LOG_TXDATA, "\n"); > + > + ssize_t size =3D 0; > + > + // send the request > + size =3D 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 =3D read (vtpm_globals.tpm_fd, out, *outsize); > + if (size < 0) { > + vtpmlogerror(VTPM_LOG_TXDATA, "read() failed : %s\n", strerror(e= rrno)); > + ERRORDIE (TPM_IOERROR); > + } > + > + vtpmloginfo(VTPM_LOG_TXDATA, "Receiving buffer =3D 0x"); > + for(i =3D 0 ; i < size ; i++) > + vtpmloginfomore(VTPM_LOG_TXDATA, "%2.2x ", out[i]); > + > + vtpmloginfomore(VTPM_LOG_TXDATA, "\n"); > + > + *outsize =3D 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 = > + * > + * All rights reserved. > + * > + * This program is free software; you can redistribute it and/or modi= fy > + * 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 > +#include > + > +#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 =3D=3D 0) { //Default e=3D 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 =3D ( 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 ) >=3D 0 ) > + { > + mpi_free( &T ); > + return TPM_ENCRYPT_ERROR; > + } > + > + olen =3D 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 !=3D 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] =3D {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 =3D mctx; > + > + //compute hash for input || counter > + sha1_update(&ctx, counter, sizeof(counter)); > + sha1_finish(&ctx, mask); > + > + //Apply the mask > + for(i =3D 0; i < (dlen < HASH_LEN ? dlen : HASH_LEN); ++i) { > + *(dst++) ^=3D mask[i]; > + } > + > + //Increment counter > + ++counter[3]; > + > + dlen -=3D 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 =3D output + 1; > + unsigned char* db =3D output + HASH_LEN +1; > + > + olen =3D ctx->len-1; > + > + if( f_rng =3D=3D NULL ) > + return TPM_ENCRYPT_ERROR; > + > + if( ilen > olen - 2 * HASH_LEN - 1) > + return TPM_ENCRYPT_ERROR; > + > + output[0] =3D 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] =3D 0x01; > + > + //input string > + memcpy(db + olen - ilen - HASH_LEN, > + input, ilen); > + > + //Generate random seed > + if( ( ret =3D f_rng( p_rng, seed, HASH_LEN ) ) !=3D 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 = > + * > + * All rights reserved. > + * > + * This program is free software; you can redistribute it and/or modi= fy > + * 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 > + > +/* 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 > +#include > +#include > + > +#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 =3D TPM_SUCCESS; > + > + if(tpmcmd->req_len !=3D VTPM_COMMAND_HEADER_SIZE + HASHKEYSZ) { > + vtpmlogerror(VTPM_LOG_VTPM, "VTPM_ORD_SAVEHASHKEY hashkey too sh= ort!\n"); > + status =3D TPM_BAD_PARAMETER; > + goto abort_egress; > + } > + > + /* Do the command */ > + TPMTRYRETURN(vtpm_storage_save_hashkey(uuid, tpmcmd->req + VTPM_COM= MAND_HEADER_SIZE)); > + > +abort_egress: > + pack_TPM_RSP_HEADER(tpmcmd->resp, > + VTPM_TAG_RSP, VTPM_COMMAND_HEADER_SIZE, status); > + tpmcmd->resp_len =3D VTPM_COMMAND_HEADER_SIZE; > + > + return status; > +} > + > +static TPM_RESULT vtpmmgr_LoadHashKey( > + const uuid_t uuid, > + tpmcmd_t* tpmcmd) { > + TPM_RESULT status =3D TPM_SUCCESS; > + > + tpmcmd->resp_len =3D VTPM_COMMAND_HEADER_SIZE; > + > + TPMTRYRETURN(vtpm_storage_load_hashkey(uuid, tpmcmd->resp + VTPM_CO= MMAND_HEADER_SIZE)); > + > + tpmcmd->resp_len +=3D 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 =3D 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 %" PR= Iu32 "\n", ord); > + status =3D 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=3D%" PRIu32 "\n", ord); > + status =3D TPM_DISABLED_CMD; > + goto abort_egress; > + } > + > + size =3D TCPA_MAX_BUFFER_LENGTH; > + TPMTRYRETURN(TPM_TransmitData(tpmcmd->req, tpmcmd->req_len, t= pmcmd->resp, &size)); > + tpmcmd->resp_len =3D size; > + > + unpack_TPM_RESULT(tpmcmd->resp + sizeof(TPM_TAG) + sizeof(UIN= T32), &status); > + return status; > + > + break; > + default: > + vtpmlogerror(VTPM_LOG_VTPM, "Invalid tag=3D%" PRIu16 "\n", ta= g); > + status =3D TPM_BADTAG; > + } > + > +abort_egress: > + tpmcmd->resp_len =3D 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_mana= ger.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_stor= age.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, FITNES= S > + * 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 (curr= ent =3D=3D 1) > + * uint32_t storage_key_len Length of the storage Key > + * TPM_KEY storage_key Marshalled TPM_KEY structure (S= ee TPM spec v2) > + * RSA_BLOCK aes_crypto Encrypted aes key data (RSA_CI= PHER_SIZE bytes), bound by the storage_key > + * BYTE[32] aes_key Aes key for encrypting the uui= d table > + * uint32_t cipher_sz Encrypted size of the uuid tab= le > + * > + * ************************************************************* > + * Section 2: Uuid Table > + * > + * This table is encrypted by the aes_key in the header. The cipher te= xt 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 o= n 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 encryp= ted > + * by the storage key. Each vtpm must exist on an RSA_BLOCK aligned bo= undary, > + * starting at the first RSA_BLOCK aligned offset after the uuid table= =2E > + * As the uuid table grows, vtpms may be relocated. > + * > + * RSA_BLOCK vtpm_crypto Vtpm data encrypted by storage_k= ey > + * 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 =3D read(blkfront_fd, buf, (size))) !=3D (size)) { \ > + vtpmlogerror(VTPM_LOG_VTPM, "read() failed! " msg " : rc=3D(%d/%= d), error=3D(%s)\n", rc, (int)(size), strerror(errno)); \ > + status =3D TPM_IOERROR;\ > + goto abort_egress;\ > + } \ > +} while(0) > + > +#define TRY_WRITE(buf, size, msg) do {\ > + int rc; \ > + if((rc =3D write(blkfront_fd, buf, (size))) !=3D (size)) { \ > + vtpmlogerror(VTPM_LOG_VTPM, "write() failed! " msg " : rc=3D(%d/= %d), error=3D(%s)\n", rc, (int)(size), strerror(errno)); \ > + status =3D TPM_IOERROR;\ > + goto abort_egress;\ > + } \ > +} while(0) > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#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 =3D NULL; > +static int blkfront_fd =3D -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 =3D { > + .vtpms =3D NULL, > +}; > + > +static int get_offset(void) { > + return lseek(blkfront_fd, 0, SEEK_CUR); > +} > + > +static void reset_store(void) { > + g_store.aes_offset =3D 0; > + g_store.uuid_offset =3D 0; > + g_store.end_offset =3D 0; > + > + g_store.num_vtpms =3D 0; > + g_store.num_vtpms_alloced =3D 0; > + free(g_store.vtpms); > + g_store.vtpms =3D NULL; > +} > + > +static int vtpm_get_index(const uuid_t uuid) { > + int st =3D 0; > + int ed =3D g_store.num_vtpms-1; > + while(st <=3D ed) { > + int mid =3D ((unsigned int)st + (unsigned int)ed) >> 1; //avoid = overflow > + int c =3D memcmp(uuid, &g_store.vtpms[mid].uuid, sizeof(uuid_t))= ; > + if(c =3D=3D 0) { > + return mid; > + } else if(c > 0) { > + st =3D mid + 1; > + } else { > + ed =3D 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 >=3D g_store.num_vtpms_alloced) { > + g_store.num_vtpms_alloced +=3D 16; > + g_store.vtpms =3D realloc( > + g_store.vtpms, > + sizeof(struct Vtpm) * g_store.num_vtpms_alloced); > + } > + > + /* Move everybody after the new guy */ > + for(int i =3D g_store.num_vtpms; i > index; --i) { > + g_store.vtpms[i] =3D g_store.vtpms[i-1]; > + } > + > + vtpmloginfo(VTPM_LOG_VTPM, "Registered vtpm " UUID_FMT "\n", UUID_B= YTES(uuid)); > + > + /* Finally add new one */ > + memcpy(g_store.vtpms[index].uuid, uuid, sizeof(uuid_t)); > + g_store.vtpms[index].offset =3D offset; > + ++g_store.num_vtpms; > +} > + > +#if 0 > +static void vtpm_remove(int index) { > + for(i =3D index; i < g_store.num_vtpms; ++i) { > + g_store.vtpms[i] =3D 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 =3D table; > + while(*nvtpms < g_store.num_vtpms && size >=3D 0) > + { > + /* Pack the uuid */ > + memcpy(ptr, (uint8_t*)g_store.vtpms[*nvtpms].uuid, sizeof(uuid_t= )); > + ptr+=3D sizeof(uuid_t); > + > + > + /* Pack the offset */ > + ptr =3D pack_UINT32(ptr, g_store.vtpms[*nvtpms].offset); > + > + ++*nvtpms; > + size -=3D UUID_TBL_ENT_SIZE; > + } > + return ptr - table; > +} > + > +/* Extract the uuids */ > +static int extract_uuid_table(uint8_t* table, int size) { > + uint8_t* ptr =3D table; > + for(;size >=3D UUID_TBL_ENT_SIZE; size -=3D UUID_TBL_ENT_SIZE) { > + int index; > + uint32_t v32; > + > + /*uuid_t is just an array of bytes, so we can do a direct cast h= ere */ > + uint8_t* uuid =3D ptr; > + ptr +=3D sizeof(uuid_t); > + > + /* Get the offset of the key */ > + ptr =3D unpack_UINT32(ptr, &v32); > + > + /* Insert the new vtpm in sorted order */ > + if((index =3D vtpm_get_index(uuid)) >=3D 0) { > + vtpmlogerror(VTPM_LOG_VTPM, "Vtpm (" UUID_FMT ") exists multi= ple times! ignoring...\n", UUID_BYTES(uuid)); > + continue; > + } > + index =3D -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 =3D extract_uuid_table(plain, cipher_sz + *overlap); > + > + /* Copy left overs to the beginning */ > + *overlap =3D 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 =3D *overlap + pack_uuid_table(plain + *overlap, block= _sz - *overlap, num_vtpms); > + bytes_to_crypt =3D 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 =3D bytes_to_crypt; > + //add padding > + bytes_to_crypt +=3D AES_BLOCK_SIZE - (bytes_to_crypt & (AES_BLOC= K_SIZE-1)); > + //fill padding with random bytes > + vtpmmgr_rand(plain + oldsz, bytes_to_crypt - oldsz); > + *overlap =3D 0; > + } else { > + *overlap =3D 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 =3D 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 +=3D RSA_CIPHER_SIZE; > + > + /* Compute the new end location of the encrypted uuid table */ > + cipher_sz =3D AES_BLOCK_SIZE; //IV > + cipher_sz +=3D g_store.num_vtpms * UUID_TBL_ENT_SIZE; //uuid table > + cipher_sz +=3D (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 =3D (g_store.uuid_offset + cipher_sz + RSA_CIPHER_SIZE= ) & ~(RSA_CIPHER_SIZE -1); > + for(int i =3D 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 =3D g_store.end_offset; > + g_store.end_offset +=3D 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 =3D plain + AES_KEY_SIZE; > + > + /* Pack the crypted size */ > + ptr =3D 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 =3D 0; > + int overlap =3D 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 =3D buf + AES_BLOCK_SIZE; > + > + /* Encrypt the first block of the uuid table */ > + bytes_crypted =3D 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 -=3D 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 =3D 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 -=3D bytes_crypted; > + } > + > + goto egress; > +abort_egress: > +egress: > + return status; > +} > + > + > +/************************************** > + * PUBLIC FUNCTIONS > + * ***********************************/ > + > +int vtpm_storage_init(void) { > + struct blkfront_info info; > + if((blkdev =3D init_blkfront(NULL, &info)) =3D=3D NULL) { > + return -1; > + } > + if((blkfront_fd =3D 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 hashke= y[HASHKEYSZ]) > +{ > + TPM_RESULT status =3D 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 =3D vtpm_get_index(uuid)) < 0) { > + index =3D -index-1; > + vtpmlogerror(VTPM_LOG_VTPM, "LoadKey failure: Unrecognized uuid!= " UUID_FMT "\n", UUID_BYTES(uuid)); > + status =3D 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 =3D 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 hashke= y[HASHKEYSZ]) > +{ > + TPM_RESULT status =3D TPM_SUCCESS; > + int index; > + uint8_t buf[RSA_CIPHER_SIZE]; > + > + /* Find the index of this uuid */ > + if((index =3D vtpm_get_index(uuid)) < 0) { > + index =3D -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 =3D TPM_SUCCESS; > + uint8_t buf[BUF_SIZE]; > + uint8_t keybuf[AES_KEY_SIZE + sizeof(uint32_t)]; > + uint8_t* ptr =3D 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 +=3D IDSTRLEN; > + > + /*Copy the version */ > + ptr =3D pack_UINT32(ptr, DISKVERS); > + > + /*Save the location of the key size */ > + sptr =3D ptr; > + ptr +=3D sizeof(UINT32); > + > + vtpmloginfo(VTPM_LOG_VTPM, "Saving root storage key..\n"); > + > + /* Copy the storage key */ > + ptr =3D 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 =3D ptr - buf; > + > + /* Store the fake aes key and vtpm count */ > + TPMTRYRETURN(TPM_Bind(&vtpm_globals.storage_key, > + keybuf, > + sizeof(keybuf), > + ptr)); > + ptr+=3D 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 =3D get_offset(); > + > + /* Save the end offset */ > + g_store.end_offset =3D (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 =3D TPM_SUCCESS; > + uint32_t v32; > + uint8_t buf[BUF_SIZE]; > + uint8_t* ptr =3D 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 hea= der"); > + > + 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 =3D TPM_FAIL; > + goto abort_egress; > + } > + ptr+=3DIDSTRLEN; > + > + /* Unpack the version */ > + ptr =3D unpack_UINT32(ptr, &v32); > + > + /* Verify the version */ > + if(v32 !=3D DISKVERS) { > + vtpmlogerror(VTPM_LOG_VTPM, "Unsupported disk image version numb= er %" PRIu32 "\n", v32); > + status =3D TPM_FAIL; > + goto abort_egress; > + } > + > + /* Size of the storage key */ > + ptr =3D unpack_UINT32(ptr, &v32); > + > + /* Sanity check */ > + if(v32 > BUF_SIZE) { > + vtpmlogerror(VTPM_LOG_VTPM, "Size of storage key (%" PRIu32 ") i= s too large!\n", v32); > + status =3D 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 =3D 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 =3D get_offset(); > + > + /* Read the rsa cipher text for the aes key */ > + TRY_READ(buf, RSA_CIPHER_SIZE, "aes key"); > + ptr =3D 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 s= mall! expected (%ld)\n", datalen, AES_KEY_SIZE + sizeof(UINT32)); > + status =3D TPM_IOERROR; > + goto abort_egress; > + } > + > + /* Extract the aes key */ > + aes_setkey_dec(&aes, ptr, AES_KEY_BITS); > + ptr+=3D AES_KEY_SIZE; > + > + /* Extract the ciphertext size */ > + ptr =3D unpack_UINT32(ptr, &v32); > + int cipher_size =3D v32; > + > + /* Sanity check */ > + if(cipher_size & (AES_BLOCK_SIZE-1)) { > + vtpmlogerror(VTPM_LOG_VTPM, "Cipher text size (%" PRIu32 ") is n= ot a multiple of the aes block size! (%d)\n", v32, AES_BLOCK_SIZE); > + status =3D TPM_IOERROR; > + goto abort_egress; > + } > + > + /* Save the location of the uuid table */ > + g_store.uuid_offset =3D get_offset(); > + > + /* Only decrypt the table if there are vtpms to decrypt */ > + if(cipher_size > 0) { > + int rbytes; > + int overlap =3D 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 =3D cipher_size / UUID_TBL_ENT_SIZE; > + g_store.vtpms =3D malloc(sizeof(struct Vtpm) * g_store.num_vtpms= _alloced); > + > + /* Read the iv and the first chunk of cipher text */ > + rbytes =3D MIN(cipher_size, BUF_SIZE); > + TRY_READ(buf, rbytes, "vtpm uuid table\n"); > + cipher_size -=3D rbytes; > + > + /* Copy the iv */ > + memcpy(iv, buf, AES_BLOCK_SIZE); > + ptr =3D buf + AES_BLOCK_SIZE; > + > + /* Remove the iv from the number of bytes to decrypt */ > + rbytes -=3D 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 =3D MIN(cipher_size, BUF_SIZE); > + TRY_READ(buf, rbytes, "vtpm uuid table"); > + cipher_size -=3D 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_vtp= ms); > + } > + > + /* The end of the key table, new vtpms go here */ > + int uuid_end =3D (get_offset() + RSA_CIPHER_SIZE) & ~(RSA_CIPHER_SI= ZE -1); > + g_store.end_offset =3D uuid_end; > + > + /* Compute the end offset while validating vtpms*/ > + for(int i =3D 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 =3D 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 tex= t size (%d)!\n", > + UUID_BYTES(g_store.vtpms[i].uuid), > + g_store.vtpms[i].offset, RSA_CIPHER_SIZE); > + status =3D TPM_IOERROR; > + goto abort_egress; > + } > + /* Save the last offset */ > + if(g_store.vtpms[i].offset >=3D g_store.end_offset) { > + g_store.end_offset =3D g_store.vtpms[i].offset + RSA_CIPHER_S= IZE; > + } > + } > + > + 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 =3D TPM_KEY_INIT; > + vtpm_globals.storage_key =3D key; > + } > + > + //Reset the storage key handle > + TPM_EvictKey(vtpm_globals.storage_key_handle); > + vtpm_globals.storage_key_handle =3D 0; > +egress: > + return status; > +} > + > +#if 0 > +/* For testing disk IO */ > +void add_fake_vtpms(int num) { > + for(int i =3D 0; i < num; ++i) { > + uint32_t ind =3D cpu_to_be32(i); > + > + uuid_t uuid; > + memset(uuid, 0, sizeof(uuid_t)); > + memcpy(uuid, &ind, sizeof(ind)); > + int index =3D vtpm_get_index(uuid); > + index =3D -index-1; > + > + vtpm_storage_new_vtpm(uuid, index); > + } > +} > +#endif > diff --git a/stubdom/vtpmmgr/vtpm_storage.h b/stubdom/vtpmmgr/vtpm_stor= age.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 hashke= y[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 hashke= y[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 > +#include > +#include > +#include > +#include > +#include > +#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 =3D tpmback_req_any()) =3D=3D NULL) { > + vtpmlogerror(VTPM_LOG_VTPM, "NULL tpmcmd\n"); > + continue; > + } > + > + tpmcmd->resp =3D respbuf; > + > + /* Process the command */ > + vtpmmgr_handle_cmd(tpmcmd->uuid, tpmcmd); > + > + /* Send response */ > + tpmback_resp(tpmcmd); > + } > +} > + > +int main(int argc, char** argv) > +{ > + int rc =3D 0; > + sleep(2); > + vtpmloginfo(VTPM_LOG_VTPM, "Starting vTPM manager domain\n"); > + > + /* Initialize the vtpm manager */ > + if(vtpmmgr_init(argc, argv) !=3D TPM_SUCCESS) { > + vtpmlogerror(VTPM_LOG_VTPM, "Unable to initialize vtpmmgr domain= !\n"); > + rc =3D -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 > +#include > +#include > + > +#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 persis= tent store > + TPM_AUTH_SESSION oiap; // OIAP session for storag= eKey > + 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) =3D= =3D 0 ? 0 : TPM_FAIL; > +} > + > +#endif > -- > 1.7.10.4 > --------------ms080704030001010001060100 Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIDyjCC A8YwggMvoAMCAQICBD/xyf0wDQYJKoZIhvcNAQEFBQAwLzELMAkGA1UEBhMCVVMxDzANBgNV BAoTBkpIVUFQTDEPMA0GA1UECxMGQklTRENBMB4XDTEwMDYxMTE4MjIwNloXDTEzMDYxMTE4 NTIwNlowZjELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkpIVUFQTDEPMA0GA1UECxMGUGVvcGxl MTUwFgYDVQQLEw9WUE5Hcm91cC1CSVNEQ0EwGwYDVQQDExRNYXR0aGV3IEUgRmlvcmF2YW50 ZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAnpbwVSP6o1Nb5lcW7dd3yTo9iBJdi7qz 4nANOMFPK7JOy5npKN1iiousl28U/scUJES55gPwAWYJK3uVyQAsA4adgDKi5DoD1UHDQEwp bY7iHLJeq0NPr4BqYNqnCFPbE6HC8zSJrr4qKn+gVUQT39SIFqdiIPJwZL8FYTRQ/zsCAwEA AaOCAbYwggGyMAsGA1UdDwQEAwIHgDArBgNVHRAEJDAigA8yMDEwMDYxMTE4MjIwNlqBDzIw MTIwNzE3MjI1MjA2WjAbBg0rBgEEAbMlCwMBAQEBBAoWCGZpb3JhbWUxMBsGDSsGAQQBsyUL AwEBAQIEChIIMDAxMDQyNjEwWAYJYIZIAYb6ax4BBEsMSVRoZSBwcml2YXRlIGtleSBjb3Jy ZXNwb25kaW5nIHRvIHRoaXMgY2VydGlmaWNhdGUgbWF5IGhhdmUgYmVlbiBleHBvcnRlZC4w KAYDVR0RBCEwH4EdTWF0dGhldy5GaW9yYXZhbnRlQGpodWFwbC5lZHUwUgYDVR0fBEswSTBH oEWgQ6RBMD8xCzAJBgNVBAYTAlVTMQ8wDQYDVQQKEwZKSFVBUEwxDzANBgNVBAsTBkJJU0RD QTEOMAwGA1UEAxMFQ1JMNTYwHwYDVR0jBBgwFoAUCDUpmxH52EU2CyWmF2EJMB1yqeswHQYD VR0OBBYEFO6LYxg6r9wHZ+zdQtBHn1dZ/YTNMAkGA1UdEwQCMAAwGQYJKoZIhvZ9B0EABAww ChsEVjcuMQMCBLAwDQYJKoZIhvcNAQEFBQADgYEAJO9HQh4YNChVLzuZqK5ARJARD8JoujGZ fdo75quvg2jXFQe2sEjvLnxJZgm/pv8fdZakq48CWwjYHKuvIp7sDjTEsQfo+y7SpN/N2NvJ WU5SqfK1VgYtNLRRoGJUB5Q1aZ+Dg95g3kqpyfpUMISJL8IKVLtJVfN4fggFVUYZ9wwxggGr MIIBpwIBATA3MC8xCzAJBgNVBAYTAlVTMQ8wDQYDVQQKEwZKSFVBUEwxDzANBgNVBAsTBkJJ U0RDQQIEP/HJ/TAJBgUrDgMCGgUAoIHLMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJ KoZIhvcNAQkFMQ8XDTEyMTEyMDE0MjUxOVowIwYJKoZIhvcNAQkEMRYEFAONLixQwzoLhKP3 k2L24VD9JBdYMGwGCSqGSIb3DQEJDzFfMF0wCwYJYIZIAWUDBAEqMAsGCWCGSAFlAwQBAjAK BggqhkiG9w0DBzAOBggqhkiG9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYI KoZIhvcNAwICASgwDQYJKoZIhvcNAQEBBQAEgYARV3Wmi+mb394qFYY5i7D2erEwQhzvEn1G VUDRsCdpu9v+ntpU2j2Xe0gGBTl9IAJp6WVyP+eQ2BNzx+ufNWsMMauOg+lOl400p0W9u5cq H2AE6aE1OzVsO/66lHkNjIsHIlISebgIFygQFIcTvN6edvvzASWO4rndvJUnJt7b7wAAAAAA AA== --------------ms080704030001010001060100-- --===============0475244974786596101== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel --===============0475244974786596101==--