add stubdom/vtpmmgr code

Add the code base for vtpmmgrdom. Makefile changes
next patch.

Signed-off-by: Matthew Fioravante <matthew.fioravante@jhuapl.edu>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Committed-by: Ian Campbell <ian.campbell@citrix.com>
This commit is contained in:
Matthew Fioravante committed 2013-01-18 10:55:43 +00:00
1 parent d463e3c5a3
commit 095b0b7794
18 files changed
+4766

No files matched your search

+32
View File
@@ -0,0 +1,32 @@
# Copyright (c) 2010-2012 United States Government, as represented by
# the Secretary of Defense. All rights reserved.
#
# THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
# ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
# INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT ARE HEREBY
# DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
# SOFTWARE.
#
XEN_ROOT=../..
PSSL_DIR=../polarssl-$(XEN_TARGET_ARCH)/library
PSSL_OBJS=aes.o sha1.o entropy.o ctr_drbg.o bignum.o sha4.o havege.o timing.o entropy_poll.o
TARGET=vtpmmgr.a
OBJS=vtpmmgr.o vtpm_cmd_handler.o vtpm_storage.o init.o tpmrsa.o tpm.o log.o
CFLAGS+=-Werror -Iutil -Icrypto -Itcs
CFLAGS+=-Wno-declaration-after-statement -Wno-unused-label
build: $(TARGET)
$(TARGET): $(OBJS)
ar -rcs $@ $^ $(foreach obj,$(PSSL_OBJS),$(PSSL_DIR)/$(obj))
clean:
rm -f $(TARGET) $(OBJS)
distclean: clean
.PHONY: clean distclean
+553
View File
@@ -0,0 +1,553 @@
/*
* Copyright (c) 2010-2012 United States Government, as represented by
* the Secretary of Defense. All rights reserved.
*
* based off of the original tools/vtpm_manager code base which is:
* Copyright (c) 2005, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdint.h>
#include <stdlib.h>
#include <xen/xen.h>
#include <mini-os/tpmback.h>
#include <mini-os/tpmfront.h>
#include <mini-os/tpm_tis.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <polarssl/sha1.h>
#include "log.h"
#include "vtpmmgr.h"
#include "vtpm_storage.h"
#include "tpm.h"
#include "marshal.h"
struct Opts {
enum {
TPMDRV_TPM_TIS,
TPMDRV_TPMFRONT,
} tpmdriver;
unsigned long tpmiomem;
unsigned int tpmirq;
unsigned int tpmlocality;
int gen_owner_auth;
};
// --------------------------- Well Known Auths --------------------------
const TPM_AUTHDATA WELLKNOWN_SRK_AUTH = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const TPM_AUTHDATA WELLKNOWN_OWNER_AUTH = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
struct vtpm_globals vtpm_globals = {
.tpm_fd = -1,
.storage_key = TPM_KEY_INIT,
.storage_key_handle = 0,
.oiap = { .AuthHandle = 0 }
};
static int tpm_entropy_source(void* dummy, unsigned char* data, size_t len, size_t* olen) {
UINT32 sz = len;
TPM_RESULT rc = TPM_GetRandom(&sz, data);
*olen = sz;
return rc == TPM_SUCCESS ? 0 : POLARSSL_ERR_ENTROPY_SOURCE_FAILED;
}
static TPM_RESULT check_tpm_version(void) {
TPM_RESULT status;
UINT32 rsize;
BYTE* res = NULL;
TPM_CAP_VERSION_INFO vinfo;
TPMTRYRETURN(TPM_GetCapability(
TPM_CAP_VERSION_VAL,
0,
NULL,
&rsize,
&res));
if(rsize < 4) {
vtpmlogerror(VTPM_LOG_VTPM, "Invalid size returned by GetCapability!\n");
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
unpack_TPM_CAP_VERSION_INFO(res, &vinfo, UNPACK_ALIAS);
vtpmloginfo(VTPM_LOG_VTPM, "Hardware TPM:\n");
vtpmloginfo(VTPM_LOG_VTPM, " version: %hhd %hhd %hhd %hhd\n",
vinfo.version.major, vinfo.version.minor, vinfo.version.revMajor, vinfo.version.revMinor);
vtpmloginfo(VTPM_LOG_VTPM, " specLevel: %hd\n", vinfo.specLevel);
vtpmloginfo(VTPM_LOG_VTPM, " errataRev: %hhd\n", vinfo.errataRev);
vtpmloginfo(VTPM_LOG_VTPM, " vendorID: %c%c%c%c\n",
vinfo.tpmVendorID[0], vinfo.tpmVendorID[1],
vinfo.tpmVendorID[2], vinfo.tpmVendorID[3]);
vtpmloginfo(VTPM_LOG_VTPM, " vendorSpecificSize: %hd\n", vinfo.vendorSpecificSize);
vtpmloginfo(VTPM_LOG_VTPM, " vendorSpecific: ");
for(int i = 0; i < vinfo.vendorSpecificSize; ++i) {
vtpmloginfomore(VTPM_LOG_VTPM, "%02hhx", vinfo.vendorSpecific[i]);
}
vtpmloginfomore(VTPM_LOG_VTPM, "\n");
abort_egress:
free(res);
return status;
}
static TPM_RESULT flush_tpm(void) {
TPM_RESULT status = TPM_SUCCESS;
const TPM_RESOURCE_TYPE reslist[] = { TPM_RT_KEY, TPM_RT_AUTH, TPM_RT_TRANS, TPM_RT_COUNTER, TPM_RT_DAA_TPM, TPM_RT_CONTEXT };
BYTE* keylist = NULL;
UINT32 keylistSize;
BYTE* ptr;
//Iterate through each resource type and flush all handles
for(int i = 0; i < sizeof(reslist) / sizeof(TPM_RESOURCE_TYPE); ++i) {
TPM_RESOURCE_TYPE beres = cpu_to_be32(reslist[i]);
UINT16 size;
TPMTRYRETURN(TPM_GetCapability(
TPM_CAP_HANDLE,
sizeof(TPM_RESOURCE_TYPE),
(BYTE*)(&beres),
&keylistSize,
&keylist));
ptr = keylist;
ptr = unpack_UINT16(ptr, &size);
//Flush each handle
if(size) {
vtpmloginfo(VTPM_LOG_VTPM, "Flushing %u handle(s) of type %lu\n", size, (unsigned long) reslist[i]);
for(int j = 0; j < size; ++j) {
TPM_HANDLE h;
ptr = unpack_TPM_HANDLE(ptr, &h);
TPMTRYRETURN(TPM_FlushSpecific(h, reslist[i]));
}
}
free(keylist);
keylist = NULL;
}
goto egress;
abort_egress:
free(keylist);
egress:
return status;
}
static TPM_RESULT try_take_ownership(void) {
TPM_RESULT status = TPM_SUCCESS;
TPM_PUBKEY pubEK = TPM_PUBKEY_INIT;
// If we can read PubEK then there is no owner and we should take it.
status = TPM_ReadPubek(&pubEK);
switch(status) {
case TPM_DISABLED_CMD:
//Cannot read ek? TPM has owner
vtpmloginfo(VTPM_LOG_VTPM, "Failed to readEK meaning TPM has an owner. Creating Keys off existing SRK.\n");
status = TPM_SUCCESS;
break;
case TPM_NO_ENDORSEMENT:
{
//If theres no ek, we have to create one
TPM_KEY_PARMS keyInfo = {
.algorithmID = TPM_ALG_RSA,
.encScheme = TPM_ES_RSAESOAEP_SHA1_MGF1,
.sigScheme = TPM_SS_NONE,
.parmSize = 12,
.parms.rsa = {
.keyLength = RSA_KEY_SIZE,
.numPrimes = 2,
.exponentSize = 0,
.exponent = NULL,
},
};
TPMTRYRETURN(TPM_CreateEndorsementKeyPair(&keyInfo, &pubEK));
}
//fall through to take ownership
case TPM_SUCCESS:
{
//Construct the Srk
TPM_KEY srk = {
.ver = TPM_STRUCT_VER_1_1,
.keyUsage = TPM_KEY_STORAGE,
.keyFlags = 0x00,
.authDataUsage = TPM_AUTH_ALWAYS,
.algorithmParms = {
.algorithmID = TPM_ALG_RSA,
.encScheme = TPM_ES_RSAESOAEP_SHA1_MGF1,
.sigScheme = TPM_SS_NONE,
.parmSize = 12,
.parms.rsa = {
.keyLength = RSA_KEY_SIZE,
.numPrimes = 2,
.exponentSize = 0,
.exponent = NULL,
},
},
.PCRInfoSize = 0,
.pubKey = {
.keyLength = 0,
.key = NULL,
},
.encDataSize = 0,
};
TPMTRYRETURN(TPM_TakeOwnership(
&pubEK,
(const TPM_AUTHDATA*)&vtpm_globals.owner_auth,
(const TPM_AUTHDATA*)&vtpm_globals.srk_auth,
&srk,
NULL,
&vtpm_globals.oiap));
TPMTRYRETURN(TPM_DisablePubekRead(
(const TPM_AUTHDATA*)&vtpm_globals.owner_auth,
&vtpm_globals.oiap));
}
break;
default:
break;
}
abort_egress:
free_TPM_PUBKEY(&pubEK);
return status;
}
static void init_storage_key(TPM_KEY* key) {
key->ver.major = 1;
key->ver.minor = 1;
key->ver.revMajor = 0;
key->ver.revMinor = 0;
key->keyUsage = TPM_KEY_BIND;
key->keyFlags = 0;
key->authDataUsage = TPM_AUTH_ALWAYS;
TPM_KEY_PARMS* p = &key->algorithmParms;
p->algorithmID = TPM_ALG_RSA;
p->encScheme = TPM_ES_RSAESOAEP_SHA1_MGF1;
p->sigScheme = TPM_SS_NONE;
p->parmSize = 12;
TPM_RSA_KEY_PARMS* r = &p->parms.rsa;
r->keyLength = RSA_KEY_SIZE;
r->numPrimes = 2;
r->exponentSize = 0;
r->exponent = NULL;
key->PCRInfoSize = 0;
key->encDataSize = 0;
key->encData = NULL;
}
static int parse_auth_string(char* authstr, BYTE* target, const TPM_AUTHDATA wellknown, int allowrandom) {
int rc;
/* well known owner auth */
if(!strcmp(authstr, "well-known")) {
memcpy(target, wellknown, sizeof(TPM_AUTHDATA));
}
/* Create a randomly generated owner auth */
else if(allowrandom && !strcmp(authstr, "random")) {
return 1;
}
/* owner auth is a raw hash */
else if(!strncmp(authstr, "hash:", 5)) {
authstr += 5;
if((rc = strlen(authstr)) != 40) {
vtpmlogerror(VTPM_LOG_VTPM, "Supplied owner auth hex string `%s' must be exactly 40 characters (20 bytes) long, length=%d\n", authstr, rc);
return -1;
}
for(int j = 0; j < 20; ++j) {
if(sscanf(authstr, "%hhX", target + j) != 1) {
vtpmlogerror(VTPM_LOG_VTPM, "Supplied owner auth string `%s' is not a valid hex string\n", authstr);
return -1;
}
authstr += 2;
}
}
/* owner auth is a string that will be hashed */
else if(!strncmp(authstr, "text:", 5)) {
authstr += 5;
sha1((const unsigned char*)authstr, strlen(authstr), target);
}
else {
vtpmlogerror(VTPM_LOG_VTPM, "Invalid auth string %s\n", authstr);
return -1;
}
return 0;
}
int parse_cmdline_opts(int argc, char** argv, struct Opts* opts)
{
int rc;
int i;
//Set defaults
memcpy(vtpm_globals.owner_auth, WELLKNOWN_OWNER_AUTH, sizeof(TPM_AUTHDATA));
memcpy(vtpm_globals.srk_auth, WELLKNOWN_SRK_AUTH, sizeof(TPM_AUTHDATA));
for(i = 1; i < argc; ++i) {
if(!strncmp(argv[i], "owner_auth:", 10)) {
if((rc = parse_auth_string(argv[i] + 10, vtpm_globals.owner_auth, WELLKNOWN_OWNER_AUTH, 1)) < 0) {
goto err_invalid;
}
if(rc == 1) {
opts->gen_owner_auth = 1;
}
}
else if(!strncmp(argv[i], "srk_auth:", 8)) {
if((rc = parse_auth_string(argv[i] + 8, vtpm_globals.srk_auth, WELLKNOWN_SRK_AUTH, 0)) != 0) {
goto err_invalid;
}
}
else if(!strncmp(argv[i], "tpmdriver=", 10)) {
if(!strcmp(argv[i] + 10, "tpm_tis")) {
opts->tpmdriver = TPMDRV_TPM_TIS;
} else if(!strcmp(argv[i] + 10, "tpmfront")) {
opts->tpmdriver = TPMDRV_TPMFRONT;
} else {
goto err_invalid;
}
}
else if(!strncmp(argv[i], "tpmiomem=",9)) {
if(sscanf(argv[i] + 9, "0x%lX", &opts->tpmiomem) != 1) {
goto err_invalid;
}
}
else if(!strncmp(argv[i], "tpmirq=",7)) {
if(!strcmp(argv[i] + 7, "probe")) {
opts->tpmirq = TPM_PROBE_IRQ;
} else if( sscanf(argv[i] + 7, "%u", &opts->tpmirq) != 1) {
goto err_invalid;
}
}
else if(!strncmp(argv[i], "tpmlocality=",12)) {
if(sscanf(argv[i] + 12, "%u", &opts->tpmlocality) != 1 || opts->tpmlocality > 4) {
goto err_invalid;
}
}
}
switch(opts->tpmdriver) {
case TPMDRV_TPM_TIS:
vtpmloginfo(VTPM_LOG_VTPM, "Option: Using tpm_tis driver\n");
break;
case TPMDRV_TPMFRONT:
vtpmloginfo(VTPM_LOG_VTPM, "Option: Using tpmfront driver\n");
break;
}
return 0;
err_invalid:
vtpmlogerror(VTPM_LOG_VTPM, "Invalid Option %s\n", argv[i]);
return -1;
}
static TPM_RESULT vtpmmgr_create(void) {
TPM_RESULT status = TPM_SUCCESS;
TPM_AUTH_SESSION osap = TPM_AUTH_SESSION_INIT;
TPM_AUTHDATA sharedsecret;
// Take ownership if TPM is unowned
TPMTRYRETURN(try_take_ownership());
// Generate storage key's auth
memset(&vtpm_globals.storage_key_usage_auth, 0, sizeof(TPM_AUTHDATA));
TPMTRYRETURN( TPM_OSAP(
TPM_ET_KEYHANDLE,
TPM_SRK_KEYHANDLE,
(const TPM_AUTHDATA*)&vtpm_globals.srk_auth,
&sharedsecret,
&osap) );
init_storage_key(&vtpm_globals.storage_key);
//initialize the storage key
TPMTRYRETURN( TPM_CreateWrapKey(
TPM_SRK_KEYHANDLE,
(const TPM_AUTHDATA*)&sharedsecret,
(const TPM_AUTHDATA*)&vtpm_globals.storage_key_usage_auth,
(const TPM_AUTHDATA*)&vtpm_globals.storage_key_usage_auth,
&vtpm_globals.storage_key,
&osap) );
//Load Storage Key
TPMTRYRETURN( TPM_LoadKey(
TPM_SRK_KEYHANDLE,
&vtpm_globals.storage_key,
&vtpm_globals.storage_key_handle,
(const TPM_AUTHDATA*) &vtpm_globals.srk_auth,
&vtpm_globals.oiap));
//Make sure TPM has commited changes
TPMTRYRETURN( TPM_SaveState() );
//Create new disk image
TPMTRYRETURN(vtpm_storage_new_header());
goto egress;
abort_egress:
egress:
vtpmloginfo(VTPM_LOG_VTPM, "Finished initialized new VTPM manager\n");
//End the OSAP session
if(osap.AuthHandle) {
TPM_TerminateHandle(osap.AuthHandle);
}
return status;
}
TPM_RESULT vtpmmgr_init(int argc, char** argv) {
TPM_RESULT status = TPM_SUCCESS;
/* Default commandline options */
struct Opts opts = {
.tpmdriver = TPMDRV_TPM_TIS,
.tpmiomem = TPM_BASEADDR,
.tpmirq = 0,
.tpmlocality = 0,
.gen_owner_auth = 0,
};
if(parse_cmdline_opts(argc, argv, &opts) != 0) {
vtpmlogerror(VTPM_LOG_VTPM, "Command line parsing failed! exiting..\n");
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
//Setup storage system
if(vtpm_storage_init() != 0) {
vtpmlogerror(VTPM_LOG_VTPM, "Unable to initialize storage subsystem!\n");
status = TPM_IOERROR;
goto abort_egress;
}
//Setup tpmback device
init_tpmback();
//Setup tpm access
switch(opts.tpmdriver) {
case TPMDRV_TPM_TIS:
{
struct tpm_chip* tpm;
if((tpm = init_tpm_tis(opts.tpmiomem, TPM_TIS_LOCL_INT_TO_FLAG(opts.tpmlocality), opts.tpmirq)) == NULL) {
vtpmlogerror(VTPM_LOG_VTPM, "Unable to initialize tpmfront device\n");
status = TPM_IOERROR;
goto abort_egress;
}
vtpm_globals.tpm_fd = tpm_tis_open(tpm);
tpm_tis_request_locality(tpm, opts.tpmlocality);
}
break;
case TPMDRV_TPMFRONT:
{
struct tpmfront_dev* tpmfront_dev;
if((tpmfront_dev = init_tpmfront(NULL)) == NULL) {
vtpmlogerror(VTPM_LOG_VTPM, "Unable to initialize tpmfront device\n");
status = TPM_IOERROR;
goto abort_egress;
}
vtpm_globals.tpm_fd = tpmfront_open(tpmfront_dev);
}
break;
}
//Get the version of the tpm
TPMTRYRETURN(check_tpm_version());
// Blow away all stale handles left in the tpm
if(flush_tpm() != TPM_SUCCESS) {
vtpmlogerror(VTPM_LOG_VTPM, "VTPM_FlushResources failed, continuing anyway..\n");
}
/* Initialize the rng */
entropy_init(&vtpm_globals.entropy);
entropy_add_source(&vtpm_globals.entropy, tpm_entropy_source, NULL, 0);
entropy_gather(&vtpm_globals.entropy);
ctr_drbg_init(&vtpm_globals.ctr_drbg, entropy_func, &vtpm_globals.entropy, NULL, 0);
ctr_drbg_set_prediction_resistance( &vtpm_globals.ctr_drbg, CTR_DRBG_PR_OFF );
// Generate Auth for Owner
if(opts.gen_owner_auth) {
vtpmmgr_rand(vtpm_globals.owner_auth, sizeof(TPM_AUTHDATA));
}
// Create OIAP session for service's authorized commands
TPMTRYRETURN( TPM_OIAP(&vtpm_globals.oiap) );
/* Load the Manager data, if it fails create a new manager */
if (vtpm_storage_load_header() != TPM_SUCCESS) {
/* If the OIAP session was closed by an error, create a new one */
if(vtpm_globals.oiap.AuthHandle == 0) {
TPMTRYRETURN( TPM_OIAP(&vtpm_globals.oiap) );
}
vtpmloginfo(VTPM_LOG_VTPM, "Failed to read manager file. Assuming first time initialization.\n");
TPMTRYRETURN( vtpmmgr_create() );
}
goto egress;
abort_egress:
vtpmmgr_shutdown();
egress:
return status;
}
void vtpmmgr_shutdown(void)
{
/* Cleanup resources */
free_TPM_KEY(&vtpm_globals.storage_key);
/* Cleanup TPM resources */
TPM_EvictKey(vtpm_globals.storage_key_handle);
TPM_TerminateHandle(vtpm_globals.oiap.AuthHandle);
/* Close tpmback */
shutdown_tpmback();
/* Close the storage system and blkfront */
vtpm_storage_shutdown();
/* Close tpmfront/tpm_tis */
close(vtpm_globals.tpm_fd);
vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager stopped.\n");
}
+151
View File
@@ -0,0 +1,151 @@
/*
* Copyright (c) 2010-2012 United States Government, as represented by
* the Secretary of Defense. All rights reserved.
*
* based off of the original tools/vtpm_manager code base which is:
* Copyright (c) 2005, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "tcg.h"
char *module_names[] = { "",
"TPM",
"TPM",
"VTPM",
"VTPM",
"TXDATA",
};
// Helper code for the consts, eg. to produce messages for error codes.
typedef struct error_code_entry_t {
TPM_RESULT code;
char * code_name;
char * msg;
} error_code_entry_t;
static const error_code_entry_t error_msgs [] = {
{ TPM_SUCCESS, "TPM_SUCCESS", "Successful completion of the operation" },
{ TPM_AUTHFAIL, "TPM_AUTHFAIL", "Authentication failed" },
{ TPM_BADINDEX, "TPM_BADINDEX", "The index to a PCR, DIR or other register is incorrect" },
{ TPM_BAD_PARAMETER, "TPM_BAD_PARAMETER", "One or more parameter is bad" },
{ TPM_AUDITFAILURE, "TPM_AUDITFAILURE", "An operation completed successfully but the auditing of that operation failed." },
{ TPM_CLEAR_DISABLED, "TPM_CLEAR_DISABLED", "The clear disable flag is set and all clear operations now require physical access" },
{ TPM_DEACTIVATED, "TPM_DEACTIVATED", "The TPM is deactivated" },
{ TPM_DISABLED, "TPM_DISABLED", "The TPM is disabled" },
{ TPM_DISABLED_CMD, "TPM_DISABLED_CMD", "The target command has been disabled" },
{ TPM_FAIL, "TPM_FAIL", "The operation failed" },
{ TPM_BAD_ORDINAL, "TPM_BAD_ORDINAL", "The ordinal was unknown or inconsistent" },
{ TPM_INSTALL_DISABLED, "TPM_INSTALL_DISABLED", "The ability to install an owner is disabled" },
{ TPM_INVALID_KEYHANDLE, "TPM_INVALID_KEYHANDLE", "The key handle presented was invalid" },
{ TPM_KEYNOTFOUND, "TPM_KEYNOTFOUND", "The target key was not found" },
{ TPM_INAPPROPRIATE_ENC, "TPM_INAPPROPRIATE_ENC", "Unacceptable encryption scheme" },
{ TPM_MIGRATEFAIL, "TPM_MIGRATEFAIL", "Migration authorization failed" },
{ TPM_INVALID_PCR_INFO, "TPM_INVALID_PCR_INFO", "PCR information could not be interpreted" },
{ TPM_NOSPACE, "TPM_NOSPACE", "No room to load key." },
{ TPM_NOSRK, "TPM_NOSRK", "There is no SRK set" },
{ TPM_NOTSEALED_BLOB, "TPM_NOTSEALED_BLOB", "An encrypted blob is invalid or was not created by this TPM" },
{ TPM_OWNER_SET, "TPM_OWNER_SET", "There is already an Owner" },
{ TPM_RESOURCES, "TPM_RESOURCES", "The TPM has insufficient internal resources to perform the requested action." },
{ TPM_SHORTRANDOM, "TPM_SHORTRANDOM", "A random string was too short" },
{ TPM_SIZE, "TPM_SIZE", "The TPM does not have the space to perform the operation." },
{ TPM_WRONGPCRVAL, "TPM_WRONGPCRVAL", "The named PCR value does not match the current PCR value." },
{ TPM_BAD_PARAM_SIZE, "TPM_BAD_PARAM_SIZE", "The paramSize argument to the command has the incorrect value" },
{ TPM_SHA_THREAD, "TPM_SHA_THREAD", "There is no existing SHA-1 thread." },
{ TPM_SHA_ERROR, "TPM_SHA_ERROR", "The calculation is unable to proceed because the existing SHA-1 thread has already encountered an error." },
{ TPM_FAILEDSELFTEST, "TPM_FAILEDSELFTEST", "Self-test has failed and the TPM has shutdown." },
{ TPM_AUTH2FAIL, "TPM_AUTH2FAIL", "The authorization for the second key in a 2 key function failed authorization" },
{ TPM_BADTAG, "TPM_BADTAG", "The tag value sent to for a command is invalid" },
{ TPM_IOERROR, "TPM_IOERROR", "An IO error occurred transmitting information to the TPM" },
{ TPM_ENCRYPT_ERROR, "TPM_ENCRYPT_ERROR", "The encryption process had a problem." },
{ TPM_DECRYPT_ERROR, "TPM_DECRYPT_ERROR", "The decryption process did not complete." },
{ TPM_INVALID_AUTHHANDLE, "TPM_INVALID_AUTHHANDLE", "An invalid handle was used." },
{ TPM_NO_ENDORSEMENT, "TPM_NO_ENDORSEMENT", "The TPM does not a EK installed" },
{ TPM_INVALID_KEYUSAGE, "TPM_INVALID_KEYUSAGE", "The usage of a key is not allowed" },
{ TPM_WRONG_ENTITYTYPE, "TPM_WRONG_ENTITYTYPE", "The submitted entity type is not allowed" },
{ TPM_INVALID_POSTINIT, "TPM_INVALID_POSTINIT", "The command was received in the wrong sequence relative to TPM_Init and a subsequent TPM_Startup" },
{ TPM_INAPPROPRIATE_SIG, "TPM_INAPPROPRIATE_SIG", "Signed data cannot include additional DER information" },
{ TPM_BAD_KEY_PROPERTY, "TPM_BAD_KEY_PROPERTY", "The key properties in TPM_KEY_PARMs are not supported by this TPM" },
{ TPM_BAD_MIGRATION, "TPM_BAD_MIGRATION", "The migration properties of this key are incorrect." },
{ TPM_BAD_SCHEME, "TPM_BAD_SCHEME", "The signature or encryption scheme for this key is incorrect or not permitted in this situation." },
{ TPM_BAD_DATASIZE, "TPM_BAD_DATASIZE", "The size of the data (or blob) parameter is bad or inconsistent with the referenced key" },
{ TPM_BAD_MODE, "TPM_BAD_MODE", "A mode parameter is bad, such as capArea or subCapArea for TPM_GetCapability, phsicalPresence parameter for TPM_PhysicalPresence, or migrationType for TPM_CreateMigrationBlob." },
{ TPM_BAD_PRESENCE, "TPM_BAD_PRESENCE", "Either the physicalPresence or physicalPresenceLock bits have the wrong value" },
{ TPM_BAD_VERSION, "TPM_BAD_VERSION", "The TPM cannot perform this version of the capability" },
{ TPM_NO_WRAP_TRANSPORT, "TPM_NO_WRAP_TRANSPORT", "The TPM does not allow for wrapped transport sessions" },
{ TPM_AUDITFAIL_UNSUCCESSFUL, "TPM_AUDITFAIL_UNSUCCESSFUL", "TPM audit construction failed and the underlying command was returning a failure code also" },
{ TPM_AUDITFAIL_SUCCESSFUL, "TPM_AUDITFAIL_SUCCESSFUL", "TPM audit construction failed and the underlying command was returning success" },
{ TPM_NOTRESETABLE, "TPM_NOTRESETABLE", "Attempt to reset a PCR register that does not have the resettable attribute" },
{ TPM_NOTLOCAL, "TPM_NOTLOCAL", "Attempt to reset a PCR register that requires locality and locality modifier not part of command transport" },
{ TPM_BAD_TYPE, "TPM_BAD_TYPE", "Make identity blob not properly typed" },
{ TPM_INVALID_RESOURCE, "TPM_INVALID_RESOURCE", "When saving context identified resource type does not match actual resource" },
{ TPM_NOTFIPS, "TPM_NOTFIPS", "The TPM is attempting to execute a command only available when in FIPS mode" },
{ TPM_INVALID_FAMILY, "TPM_INVALID_FAMILY", "The command is attempting to use an invalid family ID" },
{ TPM_NO_NV_PERMISSION, "TPM_NO_NV_PERMISSION", "The permission to manipulate the NV storage is not available" },
{ TPM_REQUIRES_SIGN, "TPM_REQUIRES_SIGN", "The operation requires a signed command" },
{ TPM_KEY_NOTSUPPORTED, "TPM_KEY_NOTSUPPORTED", "Wrong operation to load an NV key" },
{ TPM_AUTH_CONFLICT, "TPM_AUTH_CONFLICT", "NV_LoadKey blob requires both owner and blob authorization" },
{ TPM_AREA_LOCKED, "TPM_AREA_LOCKED", "The NV area is locked and not writtable" },
{ TPM_BAD_LOCALITY, "TPM_BAD_LOCALITY", "The locality is incorrect for the attempted operation" },
{ TPM_READ_ONLY, "TPM_READ_ONLY", "The NV area is read only and can't be written to" },
{ TPM_PER_NOWRITE, "TPM_PER_NOWRITE", "There is no protection on the write to the NV area" },
{ TPM_FAMILYCOUNT, "TPM_FAMILYCOUNT", "The family count value does not match" },
{ TPM_WRITE_LOCKED, "TPM_WRITE_LOCKED", "The NV area has already been written to" },
{ TPM_BAD_ATTRIBUTES, "TPM_BAD_ATTRIBUTES", "The NV area attributes conflict" },
{ TPM_INVALID_STRUCTURE, "TPM_INVALID_STRUCTURE", "The structure tag and version are invalid or inconsistent" },
{ TPM_KEY_OWNER_CONTROL, "TPM_KEY_OWNER_CONTROL", "The key is under control of the TPM Owner and can only be evicted by the TPM Owner." },
{ TPM_BAD_COUNTER, "TPM_BAD_COUNTER", "The counter handle is incorrect" },
{ TPM_NOT_FULLWRITE, "TPM_NOT_FULLWRITE", "The write is not a complete write of the area" },
{ TPM_CONTEXT_GAP, "TPM_CONTEXT_GAP", "The gap between saved context counts is too large" },
{ TPM_MAXNVWRITES, "TPM_MAXNVWRITES", "The maximum number of NV writes without an owner has been exceeded" },
{ TPM_NOOPERATOR, "TPM_NOOPERATOR", "No operator authorization value is set" },
{ TPM_RESOURCEMISSING, "TPM_RESOURCEMISSING", "The resource pointed to by context is not loaded" },
{ TPM_DELEGATE_LOCK, "TPM_DELEGATE_LOCK", "The delegate administration is locked" },
{ TPM_DELEGATE_FAMILY, "TPM_DELEGATE_FAMILY", "Attempt to manage a family other then the delegated family" },
{ TPM_DELEGATE_ADMIN, "TPM_DELEGATE_ADMIN", "Delegation table management not enabled" },
{ TPM_TRANSPORT_EXCLUSIVE, "TPM_TRANSPORT_EXCLUSIVE", "There was a command executed outside of an exclusive transport session" },
};
// helper function for the error codes:
const char* tpm_get_error_name (TPM_RESULT code) {
// just do a linear scan for now
unsigned i;
for (i = 0; i < sizeof(error_msgs)/sizeof(error_msgs[0]); i++)
if (code == error_msgs[i].code)
return error_msgs[i].code_name;
return("Unknown Error Code");
}
+85
View File
@@ -0,0 +1,85 @@
/*
* Copyright (c) 2010-2012 United States Government, as represented by
* the Secretary of Defense. All rights reserved.
*
* based off of the original tools/vtpm_manager code base which is:
* Copyright (c) 2005, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __VTPM_LOG_H__
#define __VTPM_LOG_H__
#include <stdint.h> // for uint32_t
#include <stddef.h> // for pointer NULL
#include <stdio.h>
#include "tcg.h"
// =========================== LOGGING ==============================
// the logging module numbers
#define VTPM_LOG_TPM 1
#define VTPM_LOG_TPM_DEEP 2
#define VTPM_LOG_VTPM 3
#define VTPM_LOG_VTPM_DEEP 4
#define VTPM_LOG_TXDATA 5
extern char *module_names[];
// Default to standard logging
#ifndef LOGGING_MODULES
#define LOGGING_MODULES (BITMASK(VTPM_LOG_VTPM)|BITMASK(VTPM_LOG_TPM))
#endif
// bit-access macros
#define BITMASK(idx) ( 1U << (idx) )
#define GETBIT(num,idx) ( ((num) & BITMASK(idx)) >> idx )
#define SETBIT(num,idx) (num) |= BITMASK(idx)
#define CLEARBIT(num,idx) (num) &= ( ~ BITMASK(idx) )
#define vtpmloginfo(module, fmt, args...) \
if (GETBIT (LOGGING_MODULES, module) == 1) { \
fprintf (stdout, "INFO[%s]: " fmt, module_names[module], ##args); \
}
#define vtpmloginfomore(module, fmt, args...) \
if (GETBIT (LOGGING_MODULES, module) == 1) { \
fprintf (stdout, fmt,##args); \
}
#define vtpmlogerror(module, fmt, args...) \
fprintf (stderr, "ERROR[%s]: " fmt, module_names[module], ##args);
//typedef UINT32 tpm_size_t;
// helper function for the error codes:
const char* tpm_get_error_name (TPM_RESULT code);
#endif // _VTPM_LOG_H_
+528
View File
@@ -0,0 +1,528 @@
/*
* Copyright (c) 2010-2012 United States Government, as represented by
* the Secretary of Defense. All rights reserved.
*
* based off of the original tools/vtpm_manager code base which is:
* Copyright (c) 2005, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef MARSHAL_H
#define MARSHAL_H
#include <stdlib.h>
#include <mini-os/byteorder.h>
#include <mini-os/endian.h>
#include "tcg.h"
typedef enum UnpackPtr {
UNPACK_ALIAS,
UNPACK_ALLOC
} UnpackPtr;
inline BYTE* pack_BYTE(BYTE* ptr, BYTE t) {
ptr[0] = t;
return ++ptr;
}
inline BYTE* unpack_BYTE(BYTE* ptr, BYTE* t) {
t[0] = ptr[0];
return ++ptr;
}
#define pack_BOOL(p, t) pack_BYTE(p, t)
#define unpack_BOOL(p, t) unpack_BYTE(p, t)
inline BYTE* pack_UINT16(BYTE* ptr, UINT16 t) {
BYTE* b = (BYTE*)&t;
#if __BYTE_ORDER == __LITTLE_ENDIAN
ptr[0] = b[1];
ptr[1] = b[0];
#elif __BYTE_ORDER == __BIG_ENDIAN
ptr[0] = b[0];
ptr[1] = b[1];
#endif
return ptr + sizeof(UINT16);
}
inline BYTE* unpack_UINT16(BYTE* ptr, UINT16* t) {
BYTE* b = (BYTE*)t;
#if __BYTE_ORDER == __LITTLE_ENDIAN
b[0] = ptr[1];
b[1] = ptr[0];
#elif __BYTE_ORDER == __BIG_ENDIAN
b[0] = ptr[0];
b[1] = ptr[1];
#endif
return ptr + sizeof(UINT16);
}
inline BYTE* pack_UINT32(BYTE* ptr, UINT32 t) {
BYTE* b = (BYTE*)&t;
#if __BYTE_ORDER == __LITTLE_ENDIAN
ptr[3] = b[0];
ptr[2] = b[1];
ptr[1] = b[2];
ptr[0] = b[3];
#elif __BYTE_ORDER == __BIG_ENDIAN
ptr[0] = b[0];
ptr[1] = b[1];
ptr[2] = b[2];
ptr[3] = b[3];
#endif
return ptr + sizeof(UINT32);
}
inline BYTE* unpack_UINT32(BYTE* ptr, UINT32* t) {
BYTE* b = (BYTE*)t;
#if __BYTE_ORDER == __LITTLE_ENDIAN
b[0] = ptr[3];
b[1] = ptr[2];
b[2] = ptr[1];
b[3] = ptr[0];
#elif __BYTE_ORDER == __BIG_ENDIAN
b[0] = ptr[0];
b[1] = ptr[1];
b[2] = ptr[2];
b[3] = ptr[3];
#endif
return ptr + sizeof(UINT32);
}
#define pack_TPM_RESULT(p, t) pack_UINT32(p, t)
#define pack_TPM_PCRINDEX(p, t) pack_UINT32(p, t)
#define pack_TPM_DIRINDEX(p, t) pack_UINT32(p, t)
#define pack_TPM_HANDLE(p, t) pack_UINT32(p, t)
#define pack_TPM_AUTHHANDLE(p, t) pack_TPM_HANDLE(p, t)
#define pack_TCPA_HASHHANDLE(p, t) pack_TPM_HANDLE(p, t)
#define pack_TCPA_HMACHANDLE(p, t) pack_TPM_HANDLE(p, t)
#define pack_TCPA_ENCHANDLE(p, t) pack_TPM_HANDLE(p, t)
#define pack_TPM_KEY_HANDLE(p, t) pack_TPM_HANDLE(p, t)
#define pack_TCPA_ENTITYHANDLE(p, t) pack_TPM_HANDLE(p, t)
#define pack_TPM_RESOURCE_TYPE(p, t) pack_UINT32(p, t)
#define pack_TPM_COMMAND_CODE(p, t) pack_UINT32(p, t)
#define pack_TPM_PROTOCOL_ID(p, t) pack_UINT16(p, t)
#define pack_TPM_AUTH_DATA_USAGE(p, t) pack_BYTE(p, t)
#define pack_TPM_ENTITY_TYPE(p, t) pack_UINT16(p, t)
#define pack_TPM_ALGORITHM_ID(p, t) pack_UINT32(p, t)
#define pack_TPM_KEY_USAGE(p, t) pack_UINT16(p, t)
#define pack_TPM_STARTUP_TYPE(p, t) pack_UINT16(p, t)
#define pack_TPM_CAPABILITY_AREA(p, t) pack_UINT32(p, t)
#define pack_TPM_ENC_SCHEME(p, t) pack_UINT16(p, t)
#define pack_TPM_SIG_SCHEME(p, t) pack_UINT16(p, t)
#define pack_TPM_MIGRATE_SCHEME(p, t) pack_UINT16(p, t)
#define pack_TPM_PHYSICAL_PRESENCE(p, t) pack_UINT16(p, t)
#define pack_TPM_KEY_FLAGS(p, t) pack_UINT32(p, t)
#define unpack_TPM_RESULT(p, t) unpack_UINT32(p, t)
#define unpack_TPM_PCRINDEX(p, t) unpack_UINT32(p, t)
#define unpack_TPM_DIRINDEX(p, t) unpack_UINT32(p, t)
#define unpack_TPM_HANDLE(p, t) unpack_UINT32(p, t)
#define unpack_TPM_AUTHHANDLE(p, t) unpack_TPM_HANDLE(p, t)
#define unpack_TCPA_HASHHANDLE(p, t) unpack_TPM_HANDLE(p, t)
#define unpack_TCPA_HMACHANDLE(p, t) unpack_TPM_HANDLE(p, t)
#define unpack_TCPA_ENCHANDLE(p, t) unpack_TPM_HANDLE(p, t)
#define unpack_TPM_KEY_HANDLE(p, t) unpack_TPM_HANDLE(p, t)
#define unpack_TCPA_ENTITYHANDLE(p, t) unpack_TPM_HANDLE(p, t)
#define unpack_TPM_RESOURCE_TYPE(p, t) unpack_UINT32(p, t)
#define unpack_TPM_COMMAND_CODE(p, t) unpack_UINT32(p, t)
#define unpack_TPM_PROTOCOL_ID(p, t) unpack_UINT16(p, t)
#define unpack_TPM_AUTH_DATA_USAGE(p, t) unpack_BYTE(p, t)
#define unpack_TPM_ENTITY_TYPE(p, t) unpack_UINT16(p, t)
#define unpack_TPM_ALGORITHM_ID(p, t) unpack_UINT32(p, t)
#define unpack_TPM_KEY_USAGE(p, t) unpack_UINT16(p, t)
#define unpack_TPM_STARTUP_TYPE(p, t) unpack_UINT16(p, t)
#define unpack_TPM_CAPABILITY_AREA(p, t) unpack_UINT32(p, t)
#define unpack_TPM_ENC_SCHEME(p, t) unpack_UINT16(p, t)
#define unpack_TPM_SIG_SCHEME(p, t) unpack_UINT16(p, t)
#define unpack_TPM_MIGRATE_SCHEME(p, t) unpack_UINT16(p, t)
#define unpack_TPM_PHYSICAL_PRESENCE(p, t) unpack_UINT16(p, t)
#define unpack_TPM_KEY_FLAGS(p, t) unpack_UINT32(p, t)
#define pack_TPM_AUTH_HANDLE(p, t) pack_UINT32(p, t);
#define pack_TCS_CONTEXT_HANDLE(p, t) pack_UINT32(p, t);
#define pack_TCS_KEY_HANDLE(p, t) pack_UINT32(p, t);
#define unpack_TPM_AUTH_HANDLE(p, t) unpack_UINT32(p, t);
#define unpack_TCS_CONTEXT_HANDLE(p, t) unpack_UINT32(p, t);
#define unpack_TCS_KEY_HANDLE(p, t) unpack_UINT32(p, t);
inline BYTE* pack_BUFFER(BYTE* ptr, const BYTE* buf, UINT32 size) {
memcpy(ptr, buf, size);
return ptr + size;
}
inline BYTE* unpack_BUFFER(BYTE* ptr, BYTE* buf, UINT32 size) {
memcpy(buf, ptr, size);
return ptr + size;
}
inline BYTE* unpack_ALIAS(BYTE* ptr, BYTE** buf, UINT32 size) {
*buf = ptr;
return ptr + size;
}
inline BYTE* unpack_ALLOC(BYTE* ptr, BYTE** buf, UINT32 size) {
if(size) {
*buf = malloc(size);
memcpy(*buf, ptr, size);
} else {
*buf = NULL;
}
return ptr + size;
}
inline BYTE* unpack_PTR(BYTE* ptr, BYTE** buf, UINT32 size, UnpackPtr alloc) {
if(alloc == UNPACK_ALLOC) {
return unpack_ALLOC(ptr, buf, size);
} else {
return unpack_ALIAS(ptr, buf, size);
}
}
inline BYTE* pack_TPM_AUTHDATA(BYTE* ptr, const TPM_AUTHDATA* d) {
return pack_BUFFER(ptr, *d, TPM_DIGEST_SIZE);
}
inline BYTE* unpack_TPM_AUTHDATA(BYTE* ptr, TPM_AUTHDATA* d) {
return unpack_BUFFER(ptr, *d, TPM_DIGEST_SIZE);
}
#define pack_TPM_SECRET(p, t) pack_TPM_AUTHDATA(p, t)
#define pack_TPM_ENCAUTH(p, t) pack_TPM_AUTHDATA(p, t)
#define pack_TPM_PAYLOAD_TYPE(p, t) pack_BYTE(p, t)
#define pack_TPM_TAG(p, t) pack_UINT16(p, t)
#define pack_TPM_STRUCTURE_TAG(p, t) pack_UINT16(p, t)
#define unpack_TPM_SECRET(p, t) unpack_TPM_AUTHDATA(p, t)
#define unpack_TPM_ENCAUTH(p, t) unpack_TPM_AUTHDATA(p, t)
#define unpack_TPM_PAYLOAD_TYPE(p, t) unpack_BYTE(p, t)
#define unpack_TPM_TAG(p, t) unpack_UINT16(p, t)
#define unpack_TPM_STRUCTURE_TAG(p, t) unpack_UINT16(p, t)
inline BYTE* pack_TPM_VERSION(BYTE* ptr, const TPM_VERSION* t) {
ptr[0] = t->major;
ptr[1] = t->minor;
ptr[2] = t->revMajor;
ptr[3] = t->revMinor;
return ptr + 4;
}
inline BYTE* unpack_TPM_VERSION(BYTE* ptr, TPM_VERSION* t) {
t->major = ptr[0];
t->minor = ptr[1];
t->revMajor = ptr[2];
t->revMinor = ptr[3];
return ptr + 4;
}
inline BYTE* pack_TPM_CAP_VERSION_INFO(BYTE* ptr, const TPM_CAP_VERSION_INFO* v) {
ptr = pack_TPM_STRUCTURE_TAG(ptr, v->tag);
ptr = pack_TPM_VERSION(ptr, &v->version);
ptr = pack_UINT16(ptr, v->specLevel);
ptr = pack_BYTE(ptr, v->errataRev);
ptr = pack_BUFFER(ptr, v->tpmVendorID, sizeof(v->tpmVendorID));
ptr = pack_UINT16(ptr, v->vendorSpecificSize);
ptr = pack_BUFFER(ptr, v->vendorSpecific, v->vendorSpecificSize);
return ptr;
}
inline BYTE* unpack_TPM_CAP_VERSION_INFO(BYTE* ptr, TPM_CAP_VERSION_INFO* v, UnpackPtr alloc) {
ptr = unpack_TPM_STRUCTURE_TAG(ptr, &v->tag);
ptr = unpack_TPM_VERSION(ptr, &v->version);
ptr = unpack_UINT16(ptr, &v->specLevel);
ptr = unpack_BYTE(ptr, &v->errataRev);
ptr = unpack_BUFFER(ptr, v->tpmVendorID, sizeof(v->tpmVendorID));
ptr = unpack_UINT16(ptr, &v->vendorSpecificSize);
ptr = unpack_PTR(ptr, &v->vendorSpecific, v->vendorSpecificSize, alloc);
return ptr;
}
inline BYTE* pack_TPM_DIGEST(BYTE* ptr, const TPM_DIGEST* d) {
return pack_BUFFER(ptr, d->digest, TPM_DIGEST_SIZE);
}
inline BYTE* unpack_TPM_DIGEST(BYTE* ptr, TPM_DIGEST* d) {
return unpack_BUFFER(ptr, d->digest, TPM_DIGEST_SIZE);
}
#define pack_TPM_PCRVALUE(ptr, d) pack_TPM_DIGEST(ptr, d);
#define unpack_TPM_PCRVALUE(ptr, d) unpack_TPM_DIGEST(ptr, d);
#define pack_TPM_COMPOSITE_HASH(ptr, d) pack_TPM_DIGEST(ptr, d);
#define unpack_TPM_COMPOSITE_HASH(ptr, d) unpack_TPM_DIGEST(ptr, d);
#define pack_TPM_DIRVALUE(ptr, d) pack_TPM_DIGEST(ptr, d);
#define unpack_TPM_DIRVALUE(ptr, d) unpack_TPM_DIGEST(ptr, d);
#define pack_TPM_HMAC(ptr, d) pack_TPM_DIGEST(ptr, d);
#define unpack_TPM_HMAC(ptr, d) unpack_TPM_DIGEST(ptr, d);
#define pack_TPM_CHOSENID_HASH(ptr, d) pack_TPM_DIGEST(ptr, d);
#define unpack_TPM_CHOSENID_HASH(ptr, d) unpack_TPM_DIGEST(ptr, d);
inline BYTE* pack_TPM_NONCE(BYTE* ptr, const TPM_NONCE* n) {
return pack_BUFFER(ptr, n->nonce, TPM_DIGEST_SIZE);
}
inline BYTE* unpack_TPM_NONCE(BYTE* ptr, TPM_NONCE* n) {
return unpack_BUFFER(ptr, n->nonce, TPM_DIGEST_SIZE);
}
inline BYTE* pack_TPM_SYMMETRIC_KEY_PARMS(BYTE* ptr, const TPM_SYMMETRIC_KEY_PARMS* k) {
ptr = pack_UINT32(ptr, k->keyLength);
ptr = pack_UINT32(ptr, k->blockSize);
ptr = pack_UINT32(ptr, k->ivSize);
return pack_BUFFER(ptr, k->IV, k->ivSize);
}
inline BYTE* unpack_TPM_SYMMETRIC_KEY_PARMS(BYTE* ptr, TPM_SYMMETRIC_KEY_PARMS* k, UnpackPtr alloc) {
ptr = unpack_UINT32(ptr, &k->keyLength);
ptr = unpack_UINT32(ptr, &k->blockSize);
ptr = unpack_UINT32(ptr, &k->ivSize);
return unpack_PTR(ptr, &k->IV, k->ivSize, alloc);
}
inline BYTE* pack_TPM_RSA_KEY_PARMS(BYTE* ptr, const TPM_RSA_KEY_PARMS* k) {
ptr = pack_UINT32(ptr, k->keyLength);
ptr = pack_UINT32(ptr, k->numPrimes);
ptr = pack_UINT32(ptr, k->exponentSize);
return pack_BUFFER(ptr, k->exponent, k->exponentSize);
}
inline BYTE* unpack_TPM_RSA_KEY_PARMS(BYTE* ptr, TPM_RSA_KEY_PARMS* k, UnpackPtr alloc) {
ptr = unpack_UINT32(ptr, &k->keyLength);
ptr = unpack_UINT32(ptr, &k->numPrimes);
ptr = unpack_UINT32(ptr, &k->exponentSize);
return unpack_PTR(ptr, &k->exponent, k->exponentSize, alloc);
}
inline BYTE* pack_TPM_KEY_PARMS(BYTE* ptr, const TPM_KEY_PARMS* k) {
ptr = pack_TPM_ALGORITHM_ID(ptr, k->algorithmID);
ptr = pack_TPM_ENC_SCHEME(ptr, k->encScheme);
ptr = pack_TPM_SIG_SCHEME(ptr, k->sigScheme);
ptr = pack_UINT32(ptr, k->parmSize);
if(k->parmSize) {
switch(k->algorithmID) {
case TPM_ALG_RSA:
return pack_TPM_RSA_KEY_PARMS(ptr, &k->parms.rsa);
case TPM_ALG_AES128:
case TPM_ALG_AES192:
case TPM_ALG_AES256:
return pack_TPM_SYMMETRIC_KEY_PARMS(ptr, &k->parms.sym);
}
}
return ptr;
}
inline BYTE* unpack_TPM_KEY_PARMS(BYTE* ptr, TPM_KEY_PARMS* k, UnpackPtr alloc) {
ptr = unpack_TPM_ALGORITHM_ID(ptr, &k->algorithmID);
ptr = unpack_TPM_ENC_SCHEME(ptr, &k->encScheme);
ptr = unpack_TPM_SIG_SCHEME(ptr, &k->sigScheme);
ptr = unpack_UINT32(ptr, &k->parmSize);
if(k->parmSize) {
switch(k->algorithmID) {
case TPM_ALG_RSA:
return unpack_TPM_RSA_KEY_PARMS(ptr, &k->parms.rsa, alloc);
case TPM_ALG_AES128:
case TPM_ALG_AES192:
case TPM_ALG_AES256:
return unpack_TPM_SYMMETRIC_KEY_PARMS(ptr, &k->parms.sym, alloc);
}
}
return ptr;
}
inline BYTE* pack_TPM_STORE_PUBKEY(BYTE* ptr, const TPM_STORE_PUBKEY* k) {
ptr = pack_UINT32(ptr, k->keyLength);
ptr = pack_BUFFER(ptr, k->key, k->keyLength);
return ptr;
}
inline BYTE* unpack_TPM_STORE_PUBKEY(BYTE* ptr, TPM_STORE_PUBKEY* k, UnpackPtr alloc) {
ptr = unpack_UINT32(ptr, &k->keyLength);
ptr = unpack_PTR(ptr, &k->key, k->keyLength, alloc);
return ptr;
}
inline BYTE* pack_TPM_PUBKEY(BYTE* ptr, const TPM_PUBKEY* k) {
ptr = pack_TPM_KEY_PARMS(ptr, &k->algorithmParms);
return pack_TPM_STORE_PUBKEY(ptr, &k->pubKey);
}
inline BYTE* unpack_TPM_PUBKEY(BYTE* ptr, TPM_PUBKEY* k, UnpackPtr alloc) {
ptr = unpack_TPM_KEY_PARMS(ptr, &k->algorithmParms, alloc);
return unpack_TPM_STORE_PUBKEY(ptr, &k->pubKey, alloc);
}
inline BYTE* pack_TPM_PCR_SELECTION(BYTE* ptr, const TPM_PCR_SELECTION* p) {
ptr = pack_UINT16(ptr, p->sizeOfSelect);
ptr = pack_BUFFER(ptr, p->pcrSelect, p->sizeOfSelect);
return ptr;
}
inline BYTE* unpack_TPM_PCR_SELECTION(BYTE* ptr, TPM_PCR_SELECTION* p, UnpackPtr alloc) {
ptr = unpack_UINT16(ptr, &p->sizeOfSelect);
ptr = unpack_PTR(ptr, &p->pcrSelect, p->sizeOfSelect, alloc);
return ptr;
}
inline BYTE* pack_TPM_PCR_INFO(BYTE* ptr, const TPM_PCR_INFO* p) {
ptr = pack_TPM_PCR_SELECTION(ptr, &p->pcrSelection);
ptr = pack_TPM_COMPOSITE_HASH(ptr, &p->digestAtRelease);
ptr = pack_TPM_COMPOSITE_HASH(ptr, &p->digestAtCreation);
return ptr;
}
inline BYTE* unpack_TPM_PCR_INFO(BYTE* ptr, TPM_PCR_INFO* p, UnpackPtr alloc) {
ptr = unpack_TPM_PCR_SELECTION(ptr, &p->pcrSelection, alloc);
ptr = unpack_TPM_COMPOSITE_HASH(ptr, &p->digestAtRelease);
ptr = unpack_TPM_COMPOSITE_HASH(ptr, &p->digestAtCreation);
return ptr;
}
inline BYTE* pack_TPM_PCR_COMPOSITE(BYTE* ptr, const TPM_PCR_COMPOSITE* p) {
ptr = pack_TPM_PCR_SELECTION(ptr, &p->select);
ptr = pack_UINT32(ptr, p->valueSize);
ptr = pack_BUFFER(ptr, (const BYTE*)p->pcrValue, p->valueSize);
return ptr;
}
inline BYTE* unpack_TPM_PCR_COMPOSITE(BYTE* ptr, TPM_PCR_COMPOSITE* p, UnpackPtr alloc) {
ptr = unpack_TPM_PCR_SELECTION(ptr, &p->select, alloc);
ptr = unpack_UINT32(ptr, &p->valueSize);
ptr = unpack_PTR(ptr, (BYTE**)&p->pcrValue, p->valueSize, alloc);
return ptr;
}
inline BYTE* pack_TPM_KEY(BYTE* ptr, const TPM_KEY* k) {
ptr = pack_TPM_VERSION(ptr, &k->ver);
ptr = pack_TPM_KEY_USAGE(ptr, k->keyUsage);
ptr = pack_TPM_KEY_FLAGS(ptr, k->keyFlags);
ptr = pack_TPM_AUTH_DATA_USAGE(ptr, k->authDataUsage);
ptr = pack_TPM_KEY_PARMS(ptr, &k->algorithmParms);
ptr = pack_UINT32(ptr, k->PCRInfoSize);
if(k->PCRInfoSize) {
ptr = pack_TPM_PCR_INFO(ptr, &k->PCRInfo);
}
ptr = pack_TPM_STORE_PUBKEY(ptr, &k->pubKey);
ptr = pack_UINT32(ptr, k->encDataSize);
return pack_BUFFER(ptr, k->encData, k->encDataSize);
}
inline BYTE* unpack_TPM_KEY(BYTE* ptr, TPM_KEY* k, UnpackPtr alloc) {
ptr = unpack_TPM_VERSION(ptr, &k->ver);
ptr = unpack_TPM_KEY_USAGE(ptr, &k->keyUsage);
ptr = unpack_TPM_KEY_FLAGS(ptr, &k->keyFlags);
ptr = unpack_TPM_AUTH_DATA_USAGE(ptr, &k->authDataUsage);
ptr = unpack_TPM_KEY_PARMS(ptr, &k->algorithmParms, alloc);
ptr = unpack_UINT32(ptr, &k->PCRInfoSize);
if(k->PCRInfoSize) {
ptr = unpack_TPM_PCR_INFO(ptr, &k->PCRInfo, alloc);
}
ptr = unpack_TPM_STORE_PUBKEY(ptr, &k->pubKey, alloc);
ptr = unpack_UINT32(ptr, &k->encDataSize);
return unpack_PTR(ptr, &k->encData, k->encDataSize, alloc);
}
inline BYTE* pack_TPM_BOUND_DATA(BYTE* ptr, const TPM_BOUND_DATA* b, UINT32 payloadSize) {
ptr = pack_TPM_VERSION(ptr, &b->ver);
ptr = pack_TPM_PAYLOAD_TYPE(ptr, b->payload);
return pack_BUFFER(ptr, b->payloadData, payloadSize);
}
inline BYTE* unpack_TPM_BOUND_DATA(BYTE* ptr, TPM_BOUND_DATA* b, UINT32 payloadSize, UnpackPtr alloc) {
ptr = unpack_TPM_VERSION(ptr, &b->ver);
ptr = unpack_TPM_PAYLOAD_TYPE(ptr, &b->payload);
return unpack_PTR(ptr, &b->payloadData, payloadSize, alloc);
}
inline BYTE* pack_TPM_STORED_DATA(BYTE* ptr, const TPM_STORED_DATA* d) {
ptr = pack_TPM_VERSION(ptr, &d->ver);
ptr = pack_UINT32(ptr, d->sealInfoSize);
if(d->sealInfoSize) {
ptr = pack_TPM_PCR_INFO(ptr, &d->sealInfo);
}
ptr = pack_UINT32(ptr, d->encDataSize);
ptr = pack_BUFFER(ptr, d->encData, d->encDataSize);
return ptr;
}
inline BYTE* unpack_TPM_STORED_DATA(BYTE* ptr, TPM_STORED_DATA* d, UnpackPtr alloc) {
ptr = unpack_TPM_VERSION(ptr, &d->ver);
ptr = unpack_UINT32(ptr, &d->sealInfoSize);
if(d->sealInfoSize) {
ptr = unpack_TPM_PCR_INFO(ptr, &d->sealInfo, alloc);
}
ptr = unpack_UINT32(ptr, &d->encDataSize);
ptr = unpack_PTR(ptr, &d->encData, d->encDataSize, alloc);
return ptr;
}
inline BYTE* pack_TPM_AUTH_SESSION(BYTE* ptr, const TPM_AUTH_SESSION* auth) {
ptr = pack_TPM_AUTH_HANDLE(ptr, auth->AuthHandle);
ptr = pack_TPM_NONCE(ptr, &auth->NonceOdd);
ptr = pack_BOOL(ptr, auth->fContinueAuthSession);
ptr = pack_TPM_AUTHDATA(ptr, &auth->HMAC);
return ptr;
}
inline BYTE* unpack_TPM_AUTH_SESSION(BYTE* ptr, TPM_AUTH_SESSION* auth) {
ptr = unpack_TPM_NONCE(ptr, &auth->NonceEven);
ptr = unpack_BOOL(ptr, &auth->fContinueAuthSession);
ptr = unpack_TPM_AUTHDATA(ptr, &auth->HMAC);
return ptr;
}
inline BYTE* pack_TPM_RQU_HEADER(BYTE* ptr,
TPM_TAG tag,
UINT32 size,
TPM_COMMAND_CODE ord) {
ptr = pack_UINT16(ptr, tag);
ptr = pack_UINT32(ptr, size);
return pack_UINT32(ptr, ord);
}
inline BYTE* unpack_TPM_RQU_HEADER(BYTE* ptr,
TPM_TAG* tag,
UINT32* size,
TPM_COMMAND_CODE* ord) {
ptr = unpack_UINT16(ptr, tag);
ptr = unpack_UINT32(ptr, size);
ptr = unpack_UINT32(ptr, ord);
return ptr;
}
#define pack_TPM_RSP_HEADER(p, t, s, r) pack_TPM_RQU_HEADER(p, t, s, r);
#define unpack_TPM_RSP_HEADER(p, t, s, r) unpack_TPM_RQU_HEADER(p, t, s, r);
#endif
+14
View File
@@ -0,0 +1,14 @@
CONFIG_TPMFRONT=y
CONFIG_TPM_TIS=y
CONFIG_TPMBACK=y
CONFIG_START_NETWORK=n
CONFIG_TEST=n
CONFIG_PCIFRONT=n
CONFIG_BLKFRONT=y
CONFIG_NETFRONT=n
CONFIG_FBFRONT=n
CONFIG_KBDFRONT=n
CONFIG_CONSFRONT=n
CONFIG_XENBUS=y
CONFIG_LWIP=n
CONFIG_XC=n
+707
View File
@@ -0,0 +1,707 @@
/*
* Copyright (c) 2010-2012 United States Government, as represented by
* the Secretary of Defense. All rights reserved.
*
* based off of the original tools/vtpm_manager code base which is:
* Copyright (c) 2005 Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __TCG_H__
#define __TCG_H__
#include <stdlib.h>
#include <stdint.h>
// **************************** CONSTANTS *********************************
// BOOL values
#define TRUE 0x01
#define FALSE 0x00
#define TCPA_MAX_BUFFER_LENGTH 0x2000
//
// TPM_COMMAND_CODE values
#define TPM_PROTECTED_ORDINAL 0x00000000UL
#define TPM_UNPROTECTED_ORDINAL 0x80000000UL
#define TPM_CONNECTION_ORDINAL 0x40000000UL
#define TPM_VENDOR_ORDINAL 0x20000000UL
#define TPM_ORD_OIAP (10UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_OSAP (11UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ChangeAuth (12UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_TakeOwnership (13UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ChangeAuthAsymStart (14UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ChangeAuthAsymFinish (15UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ChangeAuthOwner (16UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Extend (20UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_PcrRead (21UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Quote (22UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Seal (23UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Unseal (24UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_DirWriteAuth (25UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_DirRead (26UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_UnBind (30UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_CreateWrapKey (31UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_LoadKey (32UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_GetPubKey (33UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_EvictKey (34UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_CreateMigrationBlob (40UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ReWrapKey (41UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ConvertMigrationBlob (42UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_AuthorizeMigrationKey (43UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_CreateMaintenanceArchive (44UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_LoadMaintenanceArchive (45UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_KillMaintenanceFeature (46UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_LoadManuMaintPub (47UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ReadManuMaintPub (48UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_CertifyKey (50UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Sign (60UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_GetRandom (70UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_StirRandom (71UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SelfTestFull (80UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SelfTestStartup (81UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_CertifySelfTest (82UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ContinueSelfTest (83UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_GetTestResult (84UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Reset (90UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_OwnerClear (91UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_DisableOwnerClear (92UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ForceClear (93UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_DisableForceClear (94UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_GetCapabilitySigned (100UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_GetCapability (101UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_GetCapabilityOwner (102UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_OwnerSetDisable (110UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_PhysicalEnable (111UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_PhysicalDisable (112UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SetOwnerInstall (113UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_PhysicalSetDeactivated (114UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SetTempDeactivated (115UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_CreateEndorsementKeyPair (120UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_MakeIdentity (121UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ActivateIdentity (122UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ReadPubek (124UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_OwnerReadPubek (125UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_DisablePubekRead (126UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_GetAuditEvent (130UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_GetAuditEventSigned (131UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_GetOrdinalAuditStatus (140UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SetOrdinalAuditStatus (141UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Terminate_Handle (150UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Init (151UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SaveState (152UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Startup (153UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SetRedirection (154UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SHA1Start (160UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SHA1Update (161UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SHA1Complete (162UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SHA1CompleteExtend (163UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_FieldUpgrade (170UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SaveKeyContext (180UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_LoadKeyContext (181UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SaveAuthContext (182UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_LoadAuthContext (183UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SaveContext (184UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_LoadContext (185UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_FlushSpecific (186UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_PCR_Reset (200UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_NV_DefineSpace (204UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_NV_WriteValue (205UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_NV_WriteValueAuth (206UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_NV_ReadValue (207UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_NV_ReadValueAuth (208UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Delegate_UpdateVerification (209UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Delegate_Manage (210UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Delegate_CreateKeyDelegation (212UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Delegate_CreateOwnerDelegation (213UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Delegate_VerifyDelegation (214UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Delegate_LoadOwnerDelegation (216UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Delegate_ReadAuth (217UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Delegate_ReadTable (219UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_CreateCounter (220UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_IncrementCounter (221UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ReadCounter (222UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ReleaseCounter (223UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ReleaseCounterOwner (224UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_EstablishTransport (230UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ExecuteTransport (231UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ReleaseTransportSigned (232UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_GetTicks (241UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_TickStampBlob (242UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_MAX (256UL + TPM_PROTECTED_ORDINAL)
#define TSC_ORD_PhysicalPresence (10UL + TPM_CONNECTION_ORDINAL)
//
// TPM_RESULT values
//
// just put in the whole table from spec 1.2
#define TPM_BASE 0x0 // The start of TPM return codes
#define TPM_VENDOR_ERROR 0x00000400 // Mask to indicate that the error code is vendor specific for vendor specific commands
#define TPM_NON_FATAL 0x00000800 // Mask to indicate that the error code is a non-fatal failure.
#define TPM_SUCCESS TPM_BASE // Successful completion of the operation
#define TPM_AUTHFAIL TPM_BASE + 1 // Authentication failed
#define TPM_BADINDEX TPM_BASE + 2 // The index to a PCR, DIR or other register is incorrect
#define TPM_BAD_PARAMETER TPM_BASE + 3 // One or more parameter is bad
#define TPM_AUDITFAILURE TPM_BASE + 4 // An operation completed successfully but the auditing of that operation failed.
#define TPM_CLEAR_DISABLED TPM_BASE + 5 // The clear disable flag is set and all clear operations now require physical access
#define TPM_DEACTIVATED TPM_BASE + 6 // The TPM is deactivated
#define TPM_DISABLED TPM_BASE + 7 // The TPM is disabled
#define TPM_DISABLED_CMD TPM_BASE + 8 // The target command has been disabled
#define TPM_FAIL TPM_BASE + 9 // The operation failed
#define TPM_BAD_ORDINAL TPM_BASE + 10 // The ordinal was unknown or inconsistent
#define TPM_INSTALL_DISABLED TPM_BASE + 11 // The ability to install an owner is disabled
#define TPM_INVALID_KEYHANDLE TPM_BASE + 12 // The key handle presented was invalid
#define TPM_KEYNOTFOUND TPM_BASE + 13 // The target key was not found
#define TPM_INAPPROPRIATE_ENC TPM_BASE + 14 // Unacceptable encryption scheme
#define TPM_MIGRATEFAIL TPM_BASE + 15 // Migration authorization failed
#define TPM_INVALID_PCR_INFO TPM_BASE + 16 // PCR information could not be interpreted
#define TPM_NOSPACE TPM_BASE + 17 // No room to load key.
#define TPM_NOSRK TPM_BASE + 18 // There is no SRK set
#define TPM_NOTSEALED_BLOB TPM_BASE + 19 // An encrypted blob is invalid or was not created by this TPM
#define TPM_OWNER_SET TPM_BASE + 20 // There is already an Owner
#define TPM_RESOURCES TPM_BASE + 21 // The TPM has insufficient internal resources to perform the requested action.
#define TPM_SHORTRANDOM TPM_BASE + 22 // A random string was too short
#define TPM_SIZE TPM_BASE + 23 // The TPM does not have the space to perform the operation.
#define TPM_WRONGPCRVAL TPM_BASE + 24 // The named PCR value does not match the current PCR value.
#define TPM_BAD_PARAM_SIZE TPM_BASE + 25 // The paramSize argument to the command has the incorrect value
#define TPM_SHA_THREAD TPM_BASE + 26 // There is no existing SHA-1 thread.
#define TPM_SHA_ERROR TPM_BASE + 27 // The calculation is unable to proceed because the existing SHA-1 thread has already encountered an error.
#define TPM_FAILEDSELFTEST TPM_BASE + 28 // Self-test has failed and the TPM has shutdown.
#define TPM_AUTH2FAIL TPM_BASE + 29 // The authorization for the second key in a 2 key function failed authorization
#define TPM_BADTAG TPM_BASE + 30 // The tag value sent to for a command is invalid
#define TPM_IOERROR TPM_BASE + 31 // An IO error occurred transmitting information to the TPM
#define TPM_ENCRYPT_ERROR TPM_BASE + 32 // The encryption process had a problem.
#define TPM_DECRYPT_ERROR TPM_BASE + 33 // The decryption process did not complete.
#define TPM_INVALID_AUTHHANDLE TPM_BASE + 34 // An invalid handle was used.
#define TPM_NO_ENDORSEMENT TPM_BASE + 35 // The TPM does not a EK installed
#define TPM_INVALID_KEYUSAGE TPM_BASE + 36 // The usage of a key is not allowed
#define TPM_WRONG_ENTITYTYPE TPM_BASE + 37 // The submitted entity type is not allowed
#define TPM_INVALID_POSTINIT TPM_BASE + 38 // The command was received in the wrong sequence relative to TPM_Init and a subsequent TPM_Startup
#define TPM_INAPPROPRIATE_SIG TPM_BASE + 39 // Signed data cannot include additional DER information
#define TPM_BAD_KEY_PROPERTY TPM_BASE + 40 // The key properties in TPM_KEY_PARMs are not supported by this TPM
#define TPM_BAD_MIGRATION TPM_BASE + 41 // The migration properties of this key are incorrect.
#define TPM_BAD_SCHEME TPM_BASE + 42 // The signature or encryption scheme for this key is incorrect or not permitted in this situation.
#define TPM_BAD_DATASIZE TPM_BASE + 43 // The size of the data (or blob) parameter is bad or inconsistent with the referenced key
#define TPM_BAD_MODE TPM_BASE + 44 // A mode parameter is bad, such as capArea or subCapArea for TPM_GetCapability, phsicalPresence parameter for TPM_PhysicalPresence, or migrationType for TPM_CreateMigrationBlob.
#define TPM_BAD_PRESENCE TPM_BASE + 45 // Either the physicalPresence or physicalPresenceLock bits have the wrong value
#define TPM_BAD_VERSION TPM_BASE + 46 // The TPM cannot perform this version of the capability
#define TPM_NO_WRAP_TRANSPORT TPM_BASE + 47 // The TPM does not allow for wrapped transport sessions
#define TPM_AUDITFAIL_UNSUCCESSFUL TPM_BASE + 48 // TPM audit construction failed and the underlying command was returning a failure code also
#define TPM_AUDITFAIL_SUCCESSFUL TPM_BASE + 49 // TPM audit construction failed and the underlying command was returning success
#define TPM_NOTRESETABLE TPM_BASE + 50 // Attempt to reset a PCR register that does not have the resettable attribute
#define TPM_NOTLOCAL TPM_BASE + 51 // Attempt to reset a PCR register that requires locality and locality modifier not part of command transport
#define TPM_BAD_TYPE TPM_BASE + 52 // Make identity blob not properly typed
#define TPM_INVALID_RESOURCE TPM_BASE + 53 // When saving context identified resource type does not match actual resource
#define TPM_NOTFIPS TPM_BASE + 54 // The TPM is attempting to execute a command only available when in FIPS mode
#define TPM_INVALID_FAMILY TPM_BASE + 55 // The command is attempting to use an invalid family ID
#define TPM_NO_NV_PERMISSION TPM_BASE + 56 // The permission to manipulate the NV storage is not available
#define TPM_REQUIRES_SIGN TPM_BASE + 57 // The operation requires a signed command
#define TPM_KEY_NOTSUPPORTED TPM_BASE + 58 // Wrong operation to load an NV key
#define TPM_AUTH_CONFLICT TPM_BASE + 59 // NV_LoadKey blob requires both owner and blob authorization
#define TPM_AREA_LOCKED TPM_BASE + 60 // The NV area is locked and not writtable
#define TPM_BAD_LOCALITY TPM_BASE + 61 // The locality is incorrect for the attempted operation
#define TPM_READ_ONLY TPM_BASE + 62 // The NV area is read only and can't be written to
#define TPM_PER_NOWRITE TPM_BASE + 63 // There is no protection on the write to the NV area
#define TPM_FAMILYCOUNT TPM_BASE + 64 // The family count value does not match
#define TPM_WRITE_LOCKED TPM_BASE + 65 // The NV area has already been written to
#define TPM_BAD_ATTRIBUTES TPM_BASE + 66 // The NV area attributes conflict
#define TPM_INVALID_STRUCTURE TPM_BASE + 67 // The structure tag and version are invalid or inconsistent
#define TPM_KEY_OWNER_CONTROL TPM_BASE + 68 // The key is under control of the TPM Owner and can only be evicted by the TPM Owner.
#define TPM_BAD_COUNTER TPM_BASE + 69 // The counter handle is incorrect
#define TPM_NOT_FULLWRITE TPM_BASE + 70 // The write is not a complete write of the area
#define TPM_CONTEXT_GAP TPM_BASE + 71 // The gap between saved context counts is too large
#define TPM_MAXNVWRITES TPM_BASE + 72 // The maximum number of NV writes without an owner has been exceeded
#define TPM_NOOPERATOR TPM_BASE + 73 // No operator authorization value is set
#define TPM_RESOURCEMISSING TPM_BASE + 74 // The resource pointed to by context is not loaded
#define TPM_DELEGATE_LOCK TPM_BASE + 75 // The delegate administration is locked
#define TPM_DELEGATE_FAMILY TPM_BASE + 76 // Attempt to manage a family other then the delegated family
#define TPM_DELEGATE_ADMIN TPM_BASE + 77 // Delegation table management not enabled
#define TPM_TRANSPORT_EXCLUSIVE TPM_BASE + 78 // There was a command executed outside of an exclusive transport session
// TPM_STARTUP_TYPE values
#define TPM_ST_CLEAR 0x0001
#define TPM_ST_STATE 0x0002
#define TPM_ST_DEACTIVATED 0x003
// TPM_TAG values
#define TPM_TAG_RQU_COMMAND 0x00c1
#define TPM_TAG_RQU_AUTH1_COMMAND 0x00c2
#define TPM_TAG_RQU_AUTH2_COMMAND 0x00c3
#define TPM_TAG_RSP_COMMAND 0x00c4
#define TPM_TAG_RSP_AUTH1_COMMAND 0x00c5
#define TPM_TAG_RSP_AUTH2_COMMAND 0x00c6
// TPM_PAYLOAD_TYPE values
#define TPM_PT_ASYM 0x01
#define TPM_PT_BIND 0x02
#define TPM_PT_MIGRATE 0x03
#define TPM_PT_MAINT 0x04
#define TPM_PT_SEAL 0x05
// TPM_ENTITY_TYPE values
#define TPM_ET_KEYHANDLE 0x0001
#define TPM_ET_OWNER 0x0002
#define TPM_ET_DATA 0x0003
#define TPM_ET_SRK 0x0004
#define TPM_ET_KEY 0x0005
/// TPM_ResourceTypes
#define TPM_RT_KEY 0x00000001
#define TPM_RT_AUTH 0x00000002
#define TPM_RT_HASH 0x00000003
#define TPM_RT_TRANS 0x00000004
#define TPM_RT_CONTEXT 0x00000005
#define TPM_RT_COUNTER 0x00000006
#define TPM_RT_DELEGATE 0x00000007
#define TPM_RT_DAA_TPM 0x00000008
#define TPM_RT_DAA_V0 0x00000009
#define TPM_RT_DAA_V1 0x0000000A
// TPM_PROTOCOL_ID values
#define TPM_PID_OIAP 0x0001
#define TPM_PID_OSAP 0x0002
#define TPM_PID_ADIP 0x0003
#define TPM_PID_ADCP 0x0004
#define TPM_PID_OWNER 0x0005
// TPM_ALGORITHM_ID values
#define TPM_ALG_RSA 0x00000001
#define TPM_ALG_SHA 0x00000004
#define TPM_ALG_HMAC 0x00000005
#define TPM_ALG_AES128 0x00000006
#define TPM_ALG_MFG1 0x00000007
#define TPM_ALG_AES192 0x00000008
#define TPM_ALG_AES256 0x00000009
#define TPM_ALG_XOR 0x0000000A
// TPM_ENC_SCHEME values
#define TPM_ES_NONE 0x0001
#define TPM_ES_RSAESPKCSv15 0x0002
#define TPM_ES_RSAESOAEP_SHA1_MGF1 0x0003
// TPM_SIG_SCHEME values
#define TPM_SS_NONE 0x0001
#define TPM_SS_RSASSAPKCS1v15_SHA1 0x0002
#define TPM_SS_RSASSAPKCS1v15_DER 0x0003
/*
* TPM_CAPABILITY_AREA Values for TPM_GetCapability ([TPM_Part2], Section 21.1)
*/
#define TPM_CAP_ORD 0x00000001
#define TPM_CAP_ALG 0x00000002
#define TPM_CAP_PID 0x00000003
#define TPM_CAP_FLAG 0x00000004
#define TPM_CAP_PROPERTY 0x00000005
#define TPM_CAP_VERSION 0x00000006
#define TPM_CAP_KEY_HANDLE 0x00000007
#define TPM_CAP_CHECK_LOADED 0x00000008
#define TPM_CAP_SYM_MODE 0x00000009
#define TPM_CAP_KEY_STATUS 0x0000000C
#define TPM_CAP_NV_LIST 0x0000000D
#define TPM_CAP_MFR 0x00000010
#define TPM_CAP_NV_INDEX 0x00000011
#define TPM_CAP_TRANS_ALG 0x00000012
#define TPM_CAP_HANDLE 0x00000014
#define TPM_CAP_TRANS_ES 0x00000015
#define TPM_CAP_AUTH_ENCRYPT 0x00000017
#define TPM_CAP_SELECT_SIZE 0x00000018
#define TPM_CAP_DA_LOGIC 0x00000019
#define TPM_CAP_VERSION_VAL 0x0000001A
/* subCap definitions ([TPM_Part2], Section 21.2) */
#define TPM_CAP_PROP_PCR 0x00000101
#define TPM_CAP_PROP_DIR 0x00000102
#define TPM_CAP_PROP_MANUFACTURER 0x00000103
#define TPM_CAP_PROP_KEYS 0x00000104
#define TPM_CAP_PROP_MIN_COUNTER 0x00000107
#define TPM_CAP_FLAG_PERMANENT 0x00000108
#define TPM_CAP_FLAG_VOLATILE 0x00000109
#define TPM_CAP_PROP_AUTHSESS 0x0000010A
#define TPM_CAP_PROP_TRANSESS 0x0000010B
#define TPM_CAP_PROP_COUNTERS 0x0000010C
#define TPM_CAP_PROP_MAX_AUTHSESS 0x0000010D
#define TPM_CAP_PROP_MAX_TRANSESS 0x0000010E
#define TPM_CAP_PROP_MAX_COUNTERS 0x0000010F
#define TPM_CAP_PROP_MAX_KEYS 0x00000110
#define TPM_CAP_PROP_OWNER 0x00000111
#define TPM_CAP_PROP_CONTEXT 0x00000112
#define TPM_CAP_PROP_MAX_CONTEXT 0x00000113
#define TPM_CAP_PROP_FAMILYROWS 0x00000114
#define TPM_CAP_PROP_TIS_TIMEOUT 0x00000115
#define TPM_CAP_PROP_STARTUP_EFFECT 0x00000116
#define TPM_CAP_PROP_DELEGATE_ROW 0x00000117
#define TPM_CAP_PROP_MAX_DAASESS 0x00000119
#define TPM_CAP_PROP_DAASESS 0x0000011A
#define TPM_CAP_PROP_CONTEXT_DIST 0x0000011B
#define TPM_CAP_PROP_DAA_INTERRUPT 0x0000011C
#define TPM_CAP_PROP_SESSIONS 0x0000011D
#define TPM_CAP_PROP_MAX_SESSIONS 0x0000011E
#define TPM_CAP_PROP_CMK_RESTRICTION 0x0000011F
#define TPM_CAP_PROP_DURATION 0x00000120
#define TPM_CAP_PROP_ACTIVE_COUNTER 0x00000122
#define TPM_CAP_PROP_MAX_NV_AVAILABLE 0x00000123
#define TPM_CAP_PROP_INPUT_BUFFER 0x00000124
// TPM_KEY_USAGE values
#define TPM_KEY_EK 0x0000
#define TPM_KEY_SIGNING 0x0010
#define TPM_KEY_STORAGE 0x0011
#define TPM_KEY_IDENTITY 0x0012
#define TPM_KEY_AUTHCHANGE 0X0013
#define TPM_KEY_BIND 0x0014
#define TPM_KEY_LEGACY 0x0015
// TPM_AUTH_DATA_USAGE values
#define TPM_AUTH_NEVER 0x00
#define TPM_AUTH_ALWAYS 0x01
// Key Handle of owner and srk
#define TPM_OWNER_KEYHANDLE 0x40000001
#define TPM_SRK_KEYHANDLE 0x40000000
// *************************** TYPEDEFS *********************************
typedef unsigned char BYTE;
typedef unsigned char BOOL;
typedef uint16_t UINT16;
typedef uint32_t UINT32;
typedef uint64_t UINT64;
typedef UINT32 TPM_RESULT;
typedef UINT32 TPM_PCRINDEX;
typedef UINT32 TPM_DIRINDEX;
typedef UINT32 TPM_HANDLE;
typedef TPM_HANDLE TPM_AUTHHANDLE;
typedef TPM_HANDLE TCPA_HASHHANDLE;
typedef TPM_HANDLE TCPA_HMACHANDLE;
typedef TPM_HANDLE TCPA_ENCHANDLE;
typedef TPM_HANDLE TPM_KEY_HANDLE;
typedef TPM_HANDLE TCPA_ENTITYHANDLE;
typedef UINT32 TPM_RESOURCE_TYPE;
typedef UINT32 TPM_COMMAND_CODE;
typedef UINT16 TPM_PROTOCOL_ID;
typedef BYTE TPM_AUTH_DATA_USAGE;
typedef UINT16 TPM_ENTITY_TYPE;
typedef UINT32 TPM_ALGORITHM_ID;
typedef UINT16 TPM_KEY_USAGE;
typedef UINT16 TPM_STARTUP_TYPE;
typedef UINT32 TPM_CAPABILITY_AREA;
typedef UINT16 TPM_ENC_SCHEME;
typedef UINT16 TPM_SIG_SCHEME;
typedef UINT16 TPM_MIGRATE_SCHEME;
typedef UINT16 TPM_PHYSICAL_PRESENCE;
typedef UINT32 TPM_KEY_FLAGS;
#define TPM_DIGEST_SIZE 20 // Don't change this
typedef BYTE TPM_AUTHDATA[TPM_DIGEST_SIZE];
typedef TPM_AUTHDATA TPM_SECRET;
typedef TPM_AUTHDATA TPM_ENCAUTH;
typedef BYTE TPM_PAYLOAD_TYPE;
typedef UINT16 TPM_TAG;
typedef UINT16 TPM_STRUCTURE_TAG;
// Data Types of the TCS
typedef UINT32 TCS_AUTHHANDLE; // Handle addressing a authorization session
typedef UINT32 TCS_CONTEXT_HANDLE; // Basic context handle
typedef UINT32 TCS_KEY_HANDLE; // Basic key handle
// ************************* STRUCTURES **********************************
typedef struct TPM_VERSION {
BYTE major;
BYTE minor;
BYTE revMajor;
BYTE revMinor;
} TPM_VERSION;
static const TPM_VERSION TPM_STRUCT_VER_1_1 = { 1,1,0,0 };
typedef struct TPM_CAP_VERSION_INFO {
TPM_STRUCTURE_TAG tag;
TPM_VERSION version;
UINT16 specLevel;
BYTE errataRev;
BYTE tpmVendorID[4];
UINT16 vendorSpecificSize;
BYTE* vendorSpecific;
} TPM_CAP_VERSION_INFO;
inline void free_TPM_CAP_VERSION_INFO(TPM_CAP_VERSION_INFO* v) {
free(v->vendorSpecific);
v->vendorSpecific = NULL;
}
typedef struct TPM_DIGEST {
BYTE digest[TPM_DIGEST_SIZE];
} TPM_DIGEST;
typedef TPM_DIGEST TPM_PCRVALUE;
typedef TPM_DIGEST TPM_COMPOSITE_HASH;
typedef TPM_DIGEST TPM_DIRVALUE;
typedef TPM_DIGEST TPM_HMAC;
typedef TPM_DIGEST TPM_CHOSENID_HASH;
typedef struct TPM_NONCE {
BYTE nonce[TPM_DIGEST_SIZE];
} TPM_NONCE;
typedef struct TPM_SYMMETRIC_KEY_PARMS {
UINT32 keyLength;
UINT32 blockSize;
UINT32 ivSize;
BYTE* IV;
} TPM_SYMMETRIC_KEY_PARMS;
inline void free_TPM_SYMMETRIC_KEY_PARMS(TPM_SYMMETRIC_KEY_PARMS* p) {
free(p->IV);
p->IV = NULL;
}
#define TPM_SYMMETRIC_KEY_PARMS_INIT { 0, 0, 0, NULL }
typedef struct TPM_RSA_KEY_PARMS {
UINT32 keyLength;
UINT32 numPrimes;
UINT32 exponentSize;
BYTE* exponent;
} TPM_RSA_KEY_PARMS;
#define TPM_RSA_KEY_PARMS_INIT { 0, 0, 0, NULL }
inline void free_TPM_RSA_KEY_PARMS(TPM_RSA_KEY_PARMS* p) {
free(p->exponent);
p->exponent = NULL;
}
typedef struct TPM_KEY_PARMS {
TPM_ALGORITHM_ID algorithmID;
TPM_ENC_SCHEME encScheme;
TPM_SIG_SCHEME sigScheme;
UINT32 parmSize;
union {
TPM_SYMMETRIC_KEY_PARMS sym;
TPM_RSA_KEY_PARMS rsa;
} parms;
} TPM_KEY_PARMS;
#define TPM_KEY_PARMS_INIT { 0, 0, 0, 0 }
inline void free_TPM_KEY_PARMS(TPM_KEY_PARMS* p) {
if(p->parmSize) {
switch(p->algorithmID) {
case TPM_ALG_RSA:
free_TPM_RSA_KEY_PARMS(&p->parms.rsa);
break;
case TPM_ALG_AES128:
case TPM_ALG_AES192:
case TPM_ALG_AES256:
free_TPM_SYMMETRIC_KEY_PARMS(&p->parms.sym);
break;
}
}
}
typedef struct TPM_STORE_PUBKEY {
UINT32 keyLength;
BYTE* key;
} TPM_STORE_PUBKEY;
#define TPM_STORE_PUBKEY_INIT { 0, NULL }
inline void free_TPM_STORE_PUBKEY(TPM_STORE_PUBKEY* p) {
free(p->key);
p->key = NULL;
}
typedef struct TPM_PUBKEY {
TPM_KEY_PARMS algorithmParms;
TPM_STORE_PUBKEY pubKey;
} TPM_PUBKEY;
#define TPM_PUBKEY_INIT { TPM_KEY_PARMS_INIT, TPM_STORE_PUBKEY_INIT }
inline void free_TPM_PUBKEY(TPM_PUBKEY* k) {
free_TPM_KEY_PARMS(&k->algorithmParms);
free_TPM_STORE_PUBKEY(&k->pubKey);
}
typedef struct TPM_PCR_SELECTION {
UINT16 sizeOfSelect;
BYTE* pcrSelect;
} TPM_PCR_SELECTION;
#define TPM_PCR_SELECTION_INIT { 0, NULL }
inline void free_TPM_PCR_SELECTION(TPM_PCR_SELECTION* p) {
free(p->pcrSelect);
p->pcrSelect = NULL;
}
typedef struct TPM_PCR_INFO {
TPM_PCR_SELECTION pcrSelection;
TPM_COMPOSITE_HASH digestAtRelease;
TPM_COMPOSITE_HASH digestAtCreation;
} TPM_PCR_INFO;
#define TPM_PCR_INFO_INIT { TPM_PCR_SELECTION_INIT }
inline void free_TPM_PCR_INFO(TPM_PCR_INFO* p) {
free_TPM_PCR_SELECTION(&p->pcrSelection);
}
typedef struct TPM_PCR_COMPOSITE {
TPM_PCR_SELECTION select;
UINT32 valueSize;
TPM_PCRVALUE* pcrValue;
} TPM_PCR_COMPOSITE;
#define TPM_PCR_COMPOSITE_INIT { TPM_PCR_SELECTION_INIT, 0, NULL }
inline void free_TPM_PCR_COMPOSITE(TPM_PCR_COMPOSITE* p) {
free_TPM_PCR_SELECTION(&p->select);
free(p->pcrValue);
p->pcrValue = NULL;
}
typedef struct TPM_KEY {
TPM_VERSION ver;
TPM_KEY_USAGE keyUsage;
TPM_KEY_FLAGS keyFlags;
TPM_AUTH_DATA_USAGE authDataUsage;
TPM_KEY_PARMS algorithmParms;
UINT32 PCRInfoSize;
TPM_PCR_INFO PCRInfo;
TPM_STORE_PUBKEY pubKey;
UINT32 encDataSize;
BYTE* encData;
} TPM_KEY;
#define TPM_KEY_INIT { .algorithmParms = TPM_KEY_PARMS_INIT,\
.PCRInfoSize = 0, .PCRInfo = TPM_PCR_INFO_INIT, \
.pubKey = TPM_STORE_PUBKEY_INIT, \
.encDataSize = 0, .encData = NULL }
inline void free_TPM_KEY(TPM_KEY* k) {
if(k->PCRInfoSize) {
free_TPM_PCR_INFO(&k->PCRInfo);
}
free_TPM_STORE_PUBKEY(&k->pubKey);
free(k->encData);
k->encData = NULL;
}
typedef struct TPM_BOUND_DATA {
TPM_VERSION ver;
TPM_PAYLOAD_TYPE payload;
BYTE* payloadData;
} TPM_BOUND_DATA;
#define TPM_BOUND_DATA_INIT { .payloadData = NULL }
inline void free_TPM_BOUND_DATA(TPM_BOUND_DATA* d) {
free(d->payloadData);
d->payloadData = NULL;
}
typedef struct TPM_STORED_DATA {
TPM_VERSION ver;
UINT32 sealInfoSize;
TPM_PCR_INFO sealInfo;
UINT32 encDataSize;
BYTE* encData;
} TPM_STORED_DATA;
#define TPM_STORED_DATA_INIT { .sealInfoSize = 0, sealInfo = TPM_PCR_INFO_INIT,\
.encDataSize = 0, .encData = NULL }
inline void free_TPM_STORED_DATA(TPM_STORED_DATA* d) {
if(d->sealInfoSize) {
free_TPM_PCR_INFO(&d->sealInfo);
}
free(d->encData);
d->encData = NULL;
}
typedef struct TPM_AUTH_SESSION {
TPM_AUTHHANDLE AuthHandle;
TPM_NONCE NonceOdd; // system
TPM_NONCE NonceEven; // TPM
BOOL fContinueAuthSession;
TPM_AUTHDATA HMAC;
} TPM_AUTH_SESSION;
#define TPM_AUTH_SESSION_INIT { .AuthHandle = 0, .fContinueAuthSession = FALSE }
// ---------------------- Functions for checking TPM_RESULTs -----------------
#include <stdio.h>
// FIXME: Review use of these and delete unneeded ones.
// these are really badly dependent on local structure:
// DEPENDS: local var 'status' of type TPM_RESULT
// DEPENDS: label 'abort_egress' which cleans up and returns the status
#define ERRORDIE(s) do { status = s; \
fprintf (stderr, "*** ERRORDIE in %s at %s: %i\n", __func__, __FILE__, __LINE__); \
goto abort_egress; } \
while (0)
// DEPENDS: local var 'status' of type TPM_RESULT
// DEPENDS: label 'abort_egress' which cleans up and returns the status
// Try command c. If it fails, set status to s and goto abort.
#define TPMTRY(s,c) if (c != TPM_SUCCESS) { \
status = s; \
printf("ERROR in %s at %s:%i code: %s.\n", __func__, __FILE__, __LINE__, tpm_get_error_name(status)); \
goto abort_egress; \
} else {\
status = c; \
}
// Try command c. If it fails, print error message, set status to actual return code. Goto abort
#define TPMTRYRETURN(c) do { status = c; \
if (status != TPM_SUCCESS) { \
fprintf(stderr, "ERROR in %s at %s:%i code: %s.\n", __func__, __FILE__, __LINE__, tpm_get_error_name(status)); \
goto abort_egress; \
} \
} while(0)
#endif //__TCPA_H__
+938
View File
@@ -0,0 +1,938 @@
/*
* Copyright (c) 2010-2012 United States Government, as represented by
* the Secretary of Defense. All rights reserved.
*
* based off of the original tools/vtpm_manager code base which is:
* Copyright (c) 2005, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <unistd.h>
#include <errno.h>
#include <polarssl/sha1.h>
#include "tcg.h"
#include "tpm.h"
#include "log.h"
#include "marshal.h"
#include "tpmrsa.h"
#include "vtpmmgr.h"
#define TCPA_MAX_BUFFER_LENGTH 0x2000
#define TPM_BEGIN(TAG, ORD) \
const TPM_TAG intag = TAG;\
TPM_TAG tag = intag;\
UINT32 paramSize;\
const TPM_COMMAND_CODE ordinal = ORD;\
TPM_RESULT status = TPM_SUCCESS;\
BYTE in_buf[TCPA_MAX_BUFFER_LENGTH];\
BYTE out_buf[TCPA_MAX_BUFFER_LENGTH];\
UINT32 out_len = sizeof(out_buf);\
BYTE* ptr = in_buf;\
/*Print a log message */\
vtpmloginfo(VTPM_LOG_TPM, "%s\n", __func__);\
/* Pack the header*/\
ptr = pack_TPM_TAG(ptr, tag);\
ptr += sizeof(UINT32);\
ptr = pack_TPM_COMMAND_CODE(ptr, ordinal)\
#define TPM_AUTH_BEGIN() \
sha1_context sha1_ctx;\
BYTE* authbase = ptr - sizeof(TPM_COMMAND_CODE);\
TPM_DIGEST paramDigest;\
sha1_starts(&sha1_ctx)
#define TPM_AUTH1_GEN(HMACkey, auth) do {\
sha1_finish(&sha1_ctx, paramDigest.digest);\
generateAuth(&paramDigest, HMACkey, auth);\
ptr = pack_TPM_AUTH_SESSION(ptr, auth);\
} while(0)
#define TPM_AUTH2_GEN(HMACkey, auth) do {\
generateAuth(&paramDigest, HMACkey, auth);\
ptr = pack_TPM_AUTH_SESSION(ptr, auth);\
} while(0)
#define TPM_TRANSMIT() do {\
/* Pack the command size */\
paramSize = ptr - in_buf;\
pack_UINT32(in_buf + sizeof(TPM_TAG), paramSize);\
if((status = TPM_TransmitData(in_buf, paramSize, out_buf, &out_len)) != TPM_SUCCESS) {\
goto abort_egress;\
}\
} while(0)
#define TPM_AUTH_VERIFY_BEGIN() do {\
UINT32 buf[2] = { cpu_to_be32(status), cpu_to_be32(ordinal) };\
sha1_starts(&sha1_ctx);\
sha1_update(&sha1_ctx, (unsigned char*)buf, sizeof(buf));\
authbase = ptr;\
} while(0)
#define TPM_AUTH1_VERIFY(HMACkey, auth) do {\
sha1_finish(&sha1_ctx, paramDigest.digest);\
ptr = unpack_TPM_AUTH_SESSION(ptr, auth);\
if((status = verifyAuth(&paramDigest, HMACkey, auth)) != TPM_SUCCESS) {\
goto abort_egress;\
}\
} while(0)
#define TPM_AUTH2_VERIFY(HMACkey, auth) do {\
ptr = unpack_TPM_AUTH_SESSION(ptr, auth);\
if((status = verifyAuth(&paramDigest, HMACkey, auth)) != TPM_SUCCESS) {\
goto abort_egress;\
}\
} while(0)
#define TPM_UNPACK_VERIFY() do { \
ptr = out_buf;\
ptr = unpack_TPM_RSP_HEADER(ptr, \
&(tag), &(paramSize), &(status));\
if((status) != TPM_SUCCESS || (tag) != (intag +3)) { \
vtpmlogerror(VTPM_LOG_TPM, "Failed with return code %s\n", tpm_get_error_name(status));\
goto abort_egress;\
}\
} while(0)
#define TPM_AUTH_HASH() do {\
sha1_update(&sha1_ctx, authbase, ptr - authbase);\
authbase = ptr;\
} while(0)
#define TPM_AUTH_SKIP() do {\
authbase = ptr;\
} while(0)
#define TPM_AUTH_ERR_CHECK(auth) do {\
if(status != TPM_SUCCESS || auth->fContinueAuthSession == FALSE) {\
vtpmloginfo(VTPM_LOG_TPM, "Auth Session: 0x%x closed by TPM\n", auth->AuthHandle);\
auth->AuthHandle = 0;\
}\
} while(0)
static void xorEncrypt(const TPM_SECRET* sharedSecret,
TPM_NONCE* nonce,
const TPM_AUTHDATA* inAuth0,
TPM_ENCAUTH outAuth0,
const TPM_AUTHDATA* inAuth1,
TPM_ENCAUTH outAuth1) {
BYTE XORbuffer[sizeof(TPM_SECRET) + sizeof(TPM_NONCE)];
BYTE XORkey[TPM_DIGEST_SIZE];
BYTE* ptr = XORbuffer;
ptr = pack_TPM_SECRET(ptr, sharedSecret);
ptr = pack_TPM_NONCE(ptr, nonce);
sha1(XORbuffer, ptr - XORbuffer, XORkey);
if(inAuth0) {
for(int i = 0; i < TPM_DIGEST_SIZE; ++i) {
outAuth0[i] = XORkey[i] ^ (*inAuth0)[i];
}
}
if(inAuth1) {
for(int i = 0; i < TPM_DIGEST_SIZE; ++i) {
outAuth1[i] = XORkey[i] ^ (*inAuth1)[i];
}
}
}
static void generateAuth(const TPM_DIGEST* paramDigest,
const TPM_SECRET* HMACkey,
TPM_AUTH_SESSION *auth)
{
//Generate new OddNonce
vtpmmgr_rand((BYTE*)auth->NonceOdd.nonce, sizeof(TPM_NONCE));
// Create HMAC text. (Concat inParamsDigest with inAuthSetupParams).
BYTE hmacText[sizeof(TPM_DIGEST) + (2 * sizeof(TPM_NONCE)) + sizeof(BOOL)];
BYTE* ptr = hmacText;
ptr = pack_TPM_DIGEST(ptr, paramDigest);
ptr = pack_TPM_NONCE(ptr, &auth->NonceEven);
ptr = pack_TPM_NONCE(ptr, &auth->NonceOdd);
ptr = pack_BOOL(ptr, auth->fContinueAuthSession);
sha1_hmac((BYTE *) HMACkey, sizeof(TPM_DIGEST),
(BYTE *) hmacText, sizeof(hmacText),
auth->HMAC);
}
static TPM_RESULT verifyAuth(const TPM_DIGEST* paramDigest,
/*[IN]*/ const TPM_SECRET *HMACkey,
/*[IN,OUT]*/ TPM_AUTH_SESSION *auth)
{
// Create HMAC text. (Concat inParamsDigest with inAuthSetupParams).
TPM_AUTHDATA hm;
BYTE hmacText[sizeof(TPM_DIGEST) + (2 * sizeof(TPM_NONCE)) + sizeof(BOOL)];
BYTE* ptr = hmacText;
ptr = pack_TPM_DIGEST(ptr, paramDigest);
ptr = pack_TPM_NONCE(ptr, &auth->NonceEven);
ptr = pack_TPM_NONCE(ptr, &auth->NonceOdd);
ptr = pack_BOOL(ptr, auth->fContinueAuthSession);
sha1_hmac( (BYTE *) HMACkey, sizeof(TPM_DIGEST),
(BYTE *) hmacText, sizeof(hmacText),
hm);
// Compare correct HMAC with provided one.
if (memcmp(hm, auth->HMAC, sizeof(TPM_DIGEST)) == 0) { // 0 indicates equality
return TPM_SUCCESS;
} else {
vtpmlogerror(VTPM_LOG_TPM, "Auth Session verification failed!\n");
return TPM_AUTHFAIL;
}
}
// ------------------------------------------------------------------
// Authorization Commands
// ------------------------------------------------------------------
TPM_RESULT TPM_OIAP(TPM_AUTH_SESSION* auth) // out
{
TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_OIAP);
TPM_TRANSMIT();
TPM_UNPACK_VERIFY();
memset(&auth->HMAC, 0, sizeof(TPM_DIGEST));
auth->fContinueAuthSession = TRUE;
ptr = unpack_UINT32(ptr, &auth->AuthHandle);
ptr = unpack_TPM_NONCE(ptr, &auth->NonceEven);
vtpmloginfo(VTPM_LOG_TPM, "Auth Session: 0x%x opened by TPM_OIAP.\n", auth->AuthHandle);
abort_egress:
return status;
}
TPM_RESULT TPM_OSAP(TPM_ENTITY_TYPE entityType, // in
UINT32 entityValue, // in
const TPM_AUTHDATA* usageAuth, //in
TPM_SECRET *sharedSecret, //out
TPM_AUTH_SESSION *auth)
{
BYTE* nonceOddOSAP;
TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_OSAP);
ptr = pack_TPM_ENTITY_TYPE(ptr, entityType);
ptr = pack_UINT32(ptr, entityValue);
//nonce Odd OSAP
nonceOddOSAP = ptr;
vtpmmgr_rand(ptr, TPM_DIGEST_SIZE);
ptr += TPM_DIGEST_SIZE;
TPM_TRANSMIT();
TPM_UNPACK_VERIFY();
ptr = unpack_UINT32(ptr, &auth->AuthHandle);
ptr = unpack_TPM_NONCE(ptr, &auth->NonceEven);
//Calculate session secret
sha1_context ctx;
sha1_hmac_starts(&ctx, *usageAuth, TPM_DIGEST_SIZE);
sha1_hmac_update(&ctx, ptr, TPM_DIGEST_SIZE); //ptr = nonceEvenOSAP
sha1_hmac_update(&ctx, nonceOddOSAP, TPM_DIGEST_SIZE);
sha1_hmac_finish(&ctx, *sharedSecret);
memset(&auth->HMAC, 0, sizeof(TPM_DIGEST));
auth->fContinueAuthSession = FALSE;
vtpmloginfo(VTPM_LOG_TPM, "Auth Session: 0x%x opened by TPM_OSAP.\n", auth->AuthHandle);
abort_egress:
return status;
}
TPM_RESULT TPM_TakeOwnership(
const TPM_PUBKEY *pubEK, //in
const TPM_AUTHDATA* ownerAuth, //in
const TPM_AUTHDATA* srkAuth, //in
const TPM_KEY* inSrk, //in
TPM_KEY* outSrk, //out, optional
TPM_AUTH_SESSION* auth) // in, out
{
int keyAlloced = 0;
tpmrsa_context ek_rsa = TPMRSA_CTX_INIT;
TPM_BEGIN(TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_TakeOwnership);
TPM_AUTH_BEGIN();
tpmrsa_set_pubkey(&ek_rsa,
pubEK->pubKey.key, pubEK->pubKey.keyLength,
pubEK->algorithmParms.parms.rsa.exponent,
pubEK->algorithmParms.parms.rsa.exponentSize);
/* Pack the protocol ID */
ptr = pack_UINT16(ptr, TPM_PID_OWNER);
/* Pack the encrypted owner auth */
ptr = pack_UINT32(ptr, pubEK->algorithmParms.parms.rsa.keyLength / 8);
tpmrsa_pub_encrypt_oaep(&ek_rsa,
ctr_drbg_random, &vtpm_globals.ctr_drbg,
sizeof(TPM_SECRET),
(BYTE*) ownerAuth,
ptr);
ptr += pubEK->algorithmParms.parms.rsa.keyLength / 8;
/* Pack the encrypted srk auth */
ptr = pack_UINT32(ptr, pubEK->algorithmParms.parms.rsa.keyLength / 8);
tpmrsa_pub_encrypt_oaep(&ek_rsa,
ctr_drbg_random, &vtpm_globals.ctr_drbg,
sizeof(TPM_SECRET),
(BYTE*) srkAuth,
ptr);
ptr += pubEK->algorithmParms.parms.rsa.keyLength / 8;
/* Pack the Srk key */
ptr = pack_TPM_KEY(ptr, inSrk);
/* Hash everything up to here */
TPM_AUTH_HASH();
/* Generate the authorization */
TPM_AUTH1_GEN(ownerAuth, auth);
/* Send the command to the tpm*/
TPM_TRANSMIT();
/* Unpack and validate the header */
TPM_UNPACK_VERIFY();
TPM_AUTH_VERIFY_BEGIN();
if(outSrk != NULL) {
/* If the user wants a copy of the srk we give it to them */
keyAlloced = 1;
ptr = unpack_TPM_KEY(ptr, outSrk, UNPACK_ALLOC);
} else {
/*otherwise just parse past it */
TPM_KEY temp;
ptr = unpack_TPM_KEY(ptr, &temp, UNPACK_ALIAS);
}
/* Hash the output key */
TPM_AUTH_HASH();
/* Verify authorizaton */
TPM_AUTH1_VERIFY(ownerAuth, auth);
goto egress;
abort_egress:
if(keyAlloced) {
free_TPM_KEY(outSrk);
}
egress:
tpmrsa_free(&ek_rsa);
TPM_AUTH_ERR_CHECK(auth);
return status;
}
TPM_RESULT TPM_DisablePubekRead (
const TPM_AUTHDATA* ownerAuth,
TPM_AUTH_SESSION* auth)
{
TPM_BEGIN(TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_DisablePubekRead);
TPM_AUTH_BEGIN();
TPM_AUTH_HASH();
TPM_AUTH1_GEN(ownerAuth, auth);
TPM_TRANSMIT();
TPM_UNPACK_VERIFY();
TPM_AUTH_VERIFY_BEGIN();
TPM_AUTH1_VERIFY(ownerAuth, auth);
abort_egress:
TPM_AUTH_ERR_CHECK(auth);
return status;
}
TPM_RESULT TPM_TerminateHandle(TPM_AUTHHANDLE handle) // in
{
if(handle == 0) {
return TPM_SUCCESS;
}
TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_Terminate_Handle);
ptr = pack_TPM_AUTHHANDLE(ptr, handle);
TPM_TRANSMIT();
TPM_UNPACK_VERIFY();
vtpmloginfo(VTPM_LOG_TPM, "Auth Session: 0x%x closed by TPM_TerminateHandle\n", handle);
abort_egress:
return status;
}
TPM_RESULT TPM_Extend( TPM_PCRINDEX pcrNum, // in
TPM_DIGEST inDigest, // in
TPM_PCRVALUE* outDigest) // out
{
TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_Extend);
ptr = pack_TPM_PCRINDEX(ptr, pcrNum);
ptr = pack_TPM_DIGEST(ptr, &inDigest);
TPM_TRANSMIT();
TPM_UNPACK_VERIFY();
ptr = unpack_TPM_PCRVALUE(ptr, outDigest);
abort_egress:
return status;
}
TPM_RESULT TPM_Seal(
TPM_KEY_HANDLE keyHandle, // in
UINT32 pcrInfoSize, // in
TPM_PCR_INFO* pcrInfo, // in
UINT32 inDataSize, // in
const BYTE* inData, // in
TPM_STORED_DATA* sealedData, //out
const TPM_SECRET* osapSharedSecret, //in
const TPM_AUTHDATA* sealedDataAuth, //in
TPM_AUTH_SESSION* pubAuth // in, out
)
{
int dataAlloced = 0;
TPM_BEGIN(TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_Seal);
TPM_AUTH_BEGIN();
TPM_AUTH_HASH();
ptr = pack_TPM_KEY_HANDLE(ptr, keyHandle);
TPM_AUTH_SKIP();
xorEncrypt(osapSharedSecret, &pubAuth->NonceEven,
sealedDataAuth, ptr,
NULL, NULL);
ptr += sizeof(TPM_ENCAUTH);
ptr = pack_UINT32(ptr, pcrInfoSize);
ptr = pack_TPM_PCR_INFO(ptr, pcrInfo);
ptr = pack_UINT32(ptr, inDataSize);
ptr = pack_BUFFER(ptr, inData, inDataSize);
TPM_AUTH_HASH();
TPM_AUTH1_GEN(osapSharedSecret, pubAuth);
TPM_TRANSMIT();
TPM_UNPACK_VERIFY();
TPM_AUTH_VERIFY_BEGIN();
ptr = unpack_TPM_STORED_DATA(ptr, sealedData, UNPACK_ALLOC);
dataAlloced = 1;
TPM_AUTH_HASH();
TPM_AUTH1_VERIFY(osapSharedSecret, pubAuth);
goto egress;
abort_egress:
if(dataAlloced) {
free_TPM_STORED_DATA(sealedData);
}
egress:
TPM_AUTH_ERR_CHECK(pubAuth);
return status;
}
TPM_RESULT TPM_Unseal(
TPM_KEY_HANDLE parentHandle, // in
const TPM_STORED_DATA* sealedData,
UINT32* outSize, // out
BYTE** out, //out
const TPM_AUTHDATA* key_usage_auth, //in
const TPM_AUTHDATA* data_usage_auth, //in
TPM_AUTH_SESSION* keyAuth, // in, out
TPM_AUTH_SESSION* dataAuth // in, out
)
{
TPM_BEGIN(TPM_TAG_RQU_AUTH2_COMMAND, TPM_ORD_Unseal);
TPM_AUTH_BEGIN();
TPM_AUTH_HASH();
ptr = pack_TPM_KEY_HANDLE(ptr, parentHandle);
TPM_AUTH_SKIP();
ptr = pack_TPM_STORED_DATA(ptr, sealedData);
TPM_AUTH_HASH();
TPM_AUTH1_GEN(key_usage_auth, keyAuth);
TPM_AUTH2_GEN(data_usage_auth, dataAuth);
TPM_TRANSMIT();
TPM_UNPACK_VERIFY();
TPM_AUTH_VERIFY_BEGIN();
ptr = unpack_UINT32(ptr, outSize);
ptr = unpack_ALLOC(ptr, out, *outSize);
TPM_AUTH_HASH();
TPM_AUTH1_VERIFY(key_usage_auth, keyAuth);
TPM_AUTH2_VERIFY(data_usage_auth, dataAuth);
abort_egress:
TPM_AUTH_ERR_CHECK(keyAuth);
TPM_AUTH_ERR_CHECK(dataAuth);
return status;
}
TPM_RESULT TPM_Bind(
const TPM_KEY* key,
const BYTE* in,
UINT32 ilen,
BYTE* out)
{
TPM_RESULT status;
tpmrsa_context rsa = TPMRSA_CTX_INIT;
TPM_BOUND_DATA boundData;
uint8_t plain[TCPA_MAX_BUFFER_LENGTH];
BYTE* ptr = plain;
vtpmloginfo(VTPM_LOG_TPM, "%s\n", __func__);
tpmrsa_set_pubkey(&rsa,
key->pubKey.key, key->pubKey.keyLength,
key->algorithmParms.parms.rsa.exponent,
key->algorithmParms.parms.rsa.exponentSize);
// Fill boundData's accessory information
boundData.ver = TPM_STRUCT_VER_1_1;
boundData.payload = TPM_PT_BIND;
boundData.payloadData = (BYTE*)in;
//marshall the bound data object
ptr = pack_TPM_BOUND_DATA(ptr, &boundData, ilen);
// Encrypt the data
TPMTRYRETURN(tpmrsa_pub_encrypt_oaep(&rsa,
ctr_drbg_random, &vtpm_globals.ctr_drbg,
ptr - plain,
plain,
out));
abort_egress:
tpmrsa_free(&rsa);
return status;
}
TPM_RESULT TPM_UnBind(
TPM_KEY_HANDLE keyHandle, // in
UINT32 ilen, //in
const BYTE* in, //
UINT32* olen, //
BYTE* out, //out
const TPM_AUTHDATA* usage_auth,
TPM_AUTH_SESSION* auth //in, out
)
{
TPM_BEGIN(TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_UnBind);
TPM_AUTH_BEGIN();
TPM_AUTH_HASH();
ptr = pack_TPM_KEY_HANDLE(ptr, keyHandle);
TPM_AUTH_SKIP();
ptr = pack_UINT32(ptr, ilen);
ptr = pack_BUFFER(ptr, in, ilen);
TPM_AUTH_HASH();
TPM_AUTH1_GEN(usage_auth, auth);
TPM_TRANSMIT();
TPM_UNPACK_VERIFY();
TPM_AUTH_VERIFY_BEGIN();
ptr = unpack_UINT32(ptr, olen);
if(*olen > ilen) {
vtpmlogerror(VTPM_LOG_TPM, "Output length < input length!\n");
status = TPM_IOERROR;
goto abort_egress;
}
ptr = unpack_BUFFER(ptr, out, *olen);
TPM_AUTH_HASH();
TPM_AUTH1_VERIFY(usage_auth, auth);
abort_egress:
egress:
TPM_AUTH_ERR_CHECK(auth);
return status;
}
TPM_RESULT TPM_CreateWrapKey(
TPM_KEY_HANDLE hWrappingKey, // in
const TPM_AUTHDATA* osapSharedSecret,
const TPM_AUTHDATA* dataUsageAuth, //in
const TPM_AUTHDATA* dataMigrationAuth, //in
TPM_KEY* key, //in, out
TPM_AUTH_SESSION* pAuth) // in, out
{
int keyAlloced = 0;
TPM_BEGIN(TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_CreateWrapKey);
TPM_AUTH_BEGIN();
TPM_AUTH_HASH();
ptr = pack_TPM_KEY_HANDLE(ptr, hWrappingKey);
TPM_AUTH_SKIP();
//Encrypted auths
xorEncrypt(osapSharedSecret, &pAuth->NonceEven,
dataUsageAuth, ptr,
dataMigrationAuth, ptr + sizeof(TPM_ENCAUTH));
ptr += sizeof(TPM_ENCAUTH) * 2;
ptr = pack_TPM_KEY(ptr, key);
TPM_AUTH_HASH();
TPM_AUTH1_GEN(osapSharedSecret, pAuth);
TPM_TRANSMIT();
TPM_UNPACK_VERIFY();
TPM_AUTH_VERIFY_BEGIN();
keyAlloced = 1;
ptr = unpack_TPM_KEY(ptr, key, UNPACK_ALLOC);
TPM_AUTH_HASH();
TPM_AUTH1_VERIFY(osapSharedSecret, pAuth);
goto egress;
abort_egress:
if(keyAlloced) {
free_TPM_KEY(key);
}
egress:
TPM_AUTH_ERR_CHECK(pAuth);
return status;
}
TPM_RESULT TPM_LoadKey(
TPM_KEY_HANDLE parentHandle, //
const TPM_KEY* key, //in
TPM_HANDLE* keyHandle, // out
const TPM_AUTHDATA* usage_auth,
TPM_AUTH_SESSION* auth)
{
TPM_BEGIN(TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_LoadKey);
TPM_AUTH_BEGIN();
TPM_AUTH_HASH();
ptr = pack_TPM_KEY_HANDLE(ptr, parentHandle);
TPM_AUTH_SKIP();
ptr = pack_TPM_KEY(ptr, key);
TPM_AUTH_HASH();
TPM_AUTH1_GEN(usage_auth, auth);
TPM_TRANSMIT();
TPM_UNPACK_VERIFY();
TPM_AUTH_VERIFY_BEGIN();
ptr = unpack_UINT32(ptr, keyHandle);
TPM_AUTH_HASH();
TPM_AUTH1_VERIFY(usage_auth, auth);
vtpmloginfo(VTPM_LOG_TPM, "Key Handle: 0x%x opened by TPM_LoadKey\n", *keyHandle);
abort_egress:
TPM_AUTH_ERR_CHECK(auth);
return status;
}
TPM_RESULT TPM_EvictKey( TPM_KEY_HANDLE hKey) // in
{
if(hKey == 0) {
return TPM_SUCCESS;
}
TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_EvictKey);
ptr = pack_TPM_KEY_HANDLE(ptr, hKey);
TPM_TRANSMIT();
TPM_UNPACK_VERIFY();
vtpmloginfo(VTPM_LOG_TPM, "Key handle: 0x%x closed by TPM_EvictKey\n", hKey);
abort_egress:
return status;
}
TPM_RESULT TPM_FlushSpecific(TPM_HANDLE handle,
TPM_RESOURCE_TYPE rt) {
if(handle == 0) {
return TPM_SUCCESS;
}
TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_FlushSpecific);
ptr = pack_TPM_HANDLE(ptr, handle);
ptr = pack_TPM_RESOURCE_TYPE(ptr, rt);
TPM_TRANSMIT();
TPM_UNPACK_VERIFY();
abort_egress:
return status;
}
TPM_RESULT TPM_GetRandom( UINT32* bytesRequested, // in, out
BYTE* randomBytes) // out
{
TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_GetRandom);
// check input params
if (bytesRequested == NULL || randomBytes == NULL){
return TPM_BAD_PARAMETER;
}
ptr = pack_UINT32(ptr, *bytesRequested);
TPM_TRANSMIT();
TPM_UNPACK_VERIFY();
ptr = unpack_UINT32(ptr, bytesRequested);
ptr = unpack_BUFFER(ptr, randomBytes, *bytesRequested);
abort_egress:
return status;
}
TPM_RESULT TPM_ReadPubek(
TPM_PUBKEY* pubEK //out
)
{
BYTE* antiReplay = NULL;
BYTE* kptr = NULL;
BYTE digest[TPM_DIGEST_SIZE];
sha1_context ctx;
TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_ReadPubek);
//antiReplay nonce
vtpmmgr_rand(ptr, TPM_DIGEST_SIZE);
antiReplay = ptr;
ptr += TPM_DIGEST_SIZE;
TPM_TRANSMIT();
TPM_UNPACK_VERIFY();
//unpack and allocate the key
kptr = ptr;
ptr = unpack_TPM_PUBKEY(ptr, pubEK, UNPACK_ALLOC);
//Verify the checksum
sha1_starts(&ctx);
sha1_update(&ctx, kptr, ptr - kptr);
sha1_update(&ctx, antiReplay, TPM_DIGEST_SIZE);
sha1_finish(&ctx, digest);
//ptr points to the checksum computed by TPM
if(memcmp(digest, ptr, TPM_DIGEST_SIZE)) {
vtpmlogerror(VTPM_LOG_TPM, "TPM_ReadPubek: Checksum returned by TPM was invalid!\n");
status = TPM_FAIL;
goto abort_egress;
}
goto egress;
abort_egress:
if(kptr != NULL) { //If we unpacked the pubEK, we have to free it
free_TPM_PUBKEY(pubEK);
}
egress:
return status;
}
TPM_RESULT TPM_SaveState(void)
{
TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_SaveState);
TPM_TRANSMIT();
TPM_UNPACK_VERIFY();
abort_egress:
return status;
}
TPM_RESULT TPM_GetCapability(
TPM_CAPABILITY_AREA capArea,
UINT32 subCapSize,
const BYTE* subCap,
UINT32* respSize,
BYTE** resp)
{
TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_GetCapability);
ptr = pack_TPM_CAPABILITY_AREA(ptr, capArea);
ptr = pack_UINT32(ptr, subCapSize);
ptr = pack_BUFFER(ptr, subCap, subCapSize);
TPM_TRANSMIT();
TPM_UNPACK_VERIFY();
ptr = unpack_UINT32(ptr, respSize);
ptr = unpack_ALLOC(ptr, resp, *respSize);
abort_egress:
return status;
}
TPM_RESULT TPM_CreateEndorsementKeyPair(
const TPM_KEY_PARMS* keyInfo,
TPM_PUBKEY* pubEK)
{
BYTE* kptr = NULL;
sha1_context ctx;
TPM_DIGEST checksum;
TPM_DIGEST hash;
TPM_NONCE antiReplay;
TPM_BEGIN(TPM_TAG_RQU_COMMAND, TPM_ORD_CreateEndorsementKeyPair);
//Make anti replay nonce
vtpmmgr_rand(antiReplay.nonce, sizeof(antiReplay.nonce));
ptr = pack_TPM_NONCE(ptr, &antiReplay);
ptr = pack_TPM_KEY_PARMS(ptr, keyInfo);
TPM_TRANSMIT();
TPM_UNPACK_VERIFY();
sha1_starts(&ctx);
kptr = ptr;
ptr = unpack_TPM_PUBKEY(ptr, pubEK, UNPACK_ALLOC);
/* Hash the pub key blob */
sha1_update(&ctx, kptr, ptr - kptr);
ptr = unpack_TPM_DIGEST(ptr, &checksum);
sha1_update(&ctx, antiReplay.nonce, sizeof(antiReplay.nonce));
sha1_finish(&ctx, hash.digest);
if(memcmp(checksum.digest, hash.digest, TPM_DIGEST_SIZE)) {
vtpmloginfo(VTPM_LOG_VTPM, "TPM_CreateEndorsementKey: Checkum verification failed!\n");
status = TPM_FAIL;
goto abort_egress;
}
goto egress;
abort_egress:
if(kptr) {
free_TPM_PUBKEY(pubEK);
}
egress:
return status;
}
TPM_RESULT TPM_TransmitData(
BYTE* in,
UINT32 insize,
BYTE* out,
UINT32* outsize) {
TPM_RESULT status = TPM_SUCCESS;
UINT32 i;
vtpmloginfo(VTPM_LOG_TXDATA, "Sending buffer = 0x");
for(i = 0 ; i < insize ; i++)
vtpmloginfomore(VTPM_LOG_TXDATA, "%2.2x ", in[i]);
vtpmloginfomore(VTPM_LOG_TXDATA, "\n");
ssize_t size = 0;
// send the request
size = write (vtpm_globals.tpm_fd, in, insize);
if (size < 0) {
vtpmlogerror(VTPM_LOG_TXDATA, "write() failed : %s\n", strerror(errno));
ERRORDIE (TPM_IOERROR);
}
else if ((UINT32) size < insize) {
vtpmlogerror(VTPM_LOG_TXDATA, "Wrote %d instead of %d bytes!\n", (int) size, insize);
ERRORDIE (TPM_IOERROR);
}
// read the response
size = read (vtpm_globals.tpm_fd, out, *outsize);
if (size < 0) {
vtpmlogerror(VTPM_LOG_TXDATA, "read() failed : %s\n", strerror(errno));
ERRORDIE (TPM_IOERROR);
}
vtpmloginfo(VTPM_LOG_TXDATA, "Receiving buffer = 0x");
for(i = 0 ; i < size ; i++)
vtpmloginfomore(VTPM_LOG_TXDATA, "%2.2x ", out[i]);
vtpmloginfomore(VTPM_LOG_TXDATA, "\n");
*outsize = size;
goto egress;
abort_egress:
egress:
return status;
}
+218
View File
@@ -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
+175
View File
@@ -0,0 +1,175 @@
/*
* The RSA public-key cryptosystem
*
* Copyright (C) 2006-2011, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* RSA was designed by Ron Rivest, Adi Shamir and Len Adleman.
*
* http://theory.lcs.mit.edu/~rivest/rsapaper.pdf
* http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf
*/
#include "tcg.h"
#include "polarssl/sha1.h"
#include <stdlib.h>
#include <stdio.h>
#include "tpmrsa.h"
#define HASH_LEN 20
void tpmrsa_set_pubkey(tpmrsa_context* ctx,
const unsigned char* key,
int keylen,
const unsigned char* exponent,
int explen) {
tpmrsa_free(ctx);
if(explen == 0) { //Default e= 2^16+1
mpi_lset(&ctx->E, 65537);
} else {
mpi_read_binary(&ctx->E, exponent, explen);
}
mpi_read_binary(&ctx->N, key, keylen);
ctx->len = ( mpi_msb(&ctx->N) + 7) >> 3;
}
static TPM_RESULT tpmrsa_public( tpmrsa_context *ctx,
const unsigned char *input,
unsigned char *output )
{
int ret;
size_t olen;
mpi T;
mpi_init( &T );
MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
{
mpi_free( &T );
return TPM_ENCRYPT_ERROR;
}
olen = ctx->len;
MPI_CHK( mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
MPI_CHK( mpi_write_binary( &T, output, olen ) );
cleanup:
mpi_free( &T );
if( ret != 0 )
return TPM_ENCRYPT_ERROR;
return TPM_SUCCESS;
}
static void mgf_mask( unsigned char *dst, int dlen, unsigned char *src, int slen)
{
unsigned char mask[HASH_LEN];
unsigned char counter[4] = {0, 0, 0, 0};
int i;
sha1_context mctx;
//We always hash the src with the counter, so save the partial hash
sha1_starts(&mctx);
sha1_update(&mctx, src, slen);
// Generate and apply dbMask
while(dlen > 0) {
//Copy the sha1 context
sha1_context ctx = mctx;
//compute hash for input || counter
sha1_update(&ctx, counter, sizeof(counter));
sha1_finish(&ctx, mask);
//Apply the mask
for(i = 0; i < (dlen < HASH_LEN ? dlen : HASH_LEN); ++i) {
*(dst++) ^= mask[i];
}
//Increment counter
++counter[3];
dlen -= HASH_LEN;
}
}
/*
* Add the message padding, then do an RSA operation
*/
TPM_RESULT tpmrsa_pub_encrypt_oaep( tpmrsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
size_t ilen,
const unsigned char *input,
unsigned char *output )
{
int ret;
int olen;
unsigned char* seed = output + 1;
unsigned char* db = output + HASH_LEN +1;
olen = ctx->len-1;
if( f_rng == NULL )
return TPM_ENCRYPT_ERROR;
if( ilen > olen - 2 * HASH_LEN - 1)
return TPM_ENCRYPT_ERROR;
output[0] = 0;
//Encoding parameter p
sha1((unsigned char*)"TCPA", 4, db);
//PS
memset(db + HASH_LEN, 0,
olen - ilen - 2 * HASH_LEN - 1);
//constant 1 byte
db[olen - ilen - HASH_LEN -1] = 0x01;
//input string
memcpy(db + olen - ilen - HASH_LEN,
input, ilen);
//Generate random seed
if( ( ret = f_rng( p_rng, seed, HASH_LEN ) ) != 0 )
return TPM_ENCRYPT_ERROR;
// maskedDB: Apply dbMask to DB
mgf_mask( db, olen - HASH_LEN, seed, HASH_LEN);
// maskedSeed: Apply seedMask to seed
mgf_mask( seed, HASH_LEN, db, olen - HASH_LEN);
// Do the crypto op
return tpmrsa_public(ctx, output, output);
}
+67
View File
@@ -0,0 +1,67 @@
/**
* \file rsa.h
*
* \brief The RSA public-key cryptosystem
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef TPMRSA_H
#define TPMRSA_H
#include "tcg.h"
#include <polarssl/bignum.h>
/* tpm software key */
typedef struct
{
size_t len; /*!< size(N) in chars */
mpi N; /*!< public modulus */
mpi E; /*!< public exponent */
mpi RN; /*!< cached R^2 mod N */
}
tpmrsa_context;
#define TPMRSA_CTX_INIT { 0, {0, 0, NULL}, {0, 0, NULL}, {0, 0, NULL}}
/* Setup the rsa context using tpm public key data */
void tpmrsa_set_pubkey(tpmrsa_context* ctx,
const unsigned char* key,
int keylen,
const unsigned char* exponent,
int explen);
/* Do rsa public crypto */
TPM_RESULT tpmrsa_pub_encrypt_oaep( tpmrsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
size_t ilen,
const unsigned char *input,
unsigned char *output );
/* free tpmrsa key */
inline void tpmrsa_free( tpmrsa_context *ctx ) {
mpi_free( &ctx->RN ); mpi_free( &ctx->E ); mpi_free( &ctx->N );
}
#endif /* tpmrsa.h */
+50
View File
@@ -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
+152
View File
@@ -0,0 +1,152 @@
/*
* Copyright (c) 2010-2012 United States Government, as represented by
* the Secretary of Defense. All rights reserved.
*
* based off of the original tools/vtpm_manager code base which is:
* Copyright (c) 2005, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <inttypes.h>
#include <string.h>
#include <stdlib.h>
#include "marshal.h"
#include "log.h"
#include "vtpm_storage.h"
#include "vtpmmgr.h"
#include "tpm.h"
#include "tcg.h"
static TPM_RESULT vtpmmgr_SaveHashKey(
const uuid_t uuid,
tpmcmd_t* tpmcmd)
{
TPM_RESULT status = TPM_SUCCESS;
if(tpmcmd->req_len != VTPM_COMMAND_HEADER_SIZE + HASHKEYSZ) {
vtpmlogerror(VTPM_LOG_VTPM, "VTPM_ORD_SAVEHASHKEY hashkey too short!\n");
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
/* Do the command */
TPMTRYRETURN(vtpm_storage_save_hashkey(uuid, tpmcmd->req + VTPM_COMMAND_HEADER_SIZE));
abort_egress:
pack_TPM_RSP_HEADER(tpmcmd->resp,
VTPM_TAG_RSP, VTPM_COMMAND_HEADER_SIZE, status);
tpmcmd->resp_len = VTPM_COMMAND_HEADER_SIZE;
return status;
}
static TPM_RESULT vtpmmgr_LoadHashKey(
const uuid_t uuid,
tpmcmd_t* tpmcmd) {
TPM_RESULT status = TPM_SUCCESS;
tpmcmd->resp_len = VTPM_COMMAND_HEADER_SIZE;
TPMTRYRETURN(vtpm_storage_load_hashkey(uuid, tpmcmd->resp + VTPM_COMMAND_HEADER_SIZE));
tpmcmd->resp_len += HASHKEYSZ;
abort_egress:
pack_TPM_RSP_HEADER(tpmcmd->resp,
VTPM_TAG_RSP, tpmcmd->resp_len, status);
return status;
}
TPM_RESULT vtpmmgr_handle_cmd(
const uuid_t uuid,
tpmcmd_t* tpmcmd)
{
TPM_RESULT status = TPM_SUCCESS;
TPM_TAG tag;
UINT32 size;
TPM_COMMAND_CODE ord;
unpack_TPM_RQU_HEADER(tpmcmd->req,
&tag, &size, &ord);
/* Handle the command now */
switch(tag) {
case VTPM_TAG_REQ:
//This is a vTPM command
switch(ord) {
case VTPM_ORD_SAVEHASHKEY:
return vtpmmgr_SaveHashKey(uuid, tpmcmd);
case VTPM_ORD_LOADHASHKEY:
return vtpmmgr_LoadHashKey(uuid, tpmcmd);
default:
vtpmlogerror(VTPM_LOG_VTPM, "Invalid vTPM Ordinal %" PRIu32 "\n", ord);
status = TPM_BAD_ORDINAL;
}
break;
case TPM_TAG_RQU_COMMAND:
case TPM_TAG_RQU_AUTH1_COMMAND:
case TPM_TAG_RQU_AUTH2_COMMAND:
//This is a TPM passthrough command
switch(ord) {
case TPM_ORD_GetRandom:
vtpmloginfo(VTPM_LOG_VTPM, "Passthrough: TPM_GetRandom\n");
break;
case TPM_ORD_PcrRead:
vtpmloginfo(VTPM_LOG_VTPM, "Passthrough: TPM_PcrRead\n");
break;
default:
vtpmlogerror(VTPM_LOG_VTPM, "TPM Disallowed Passthrough ord=%" PRIu32 "\n", ord);
status = TPM_DISABLED_CMD;
goto abort_egress;
}
size = TCPA_MAX_BUFFER_LENGTH;
TPMTRYRETURN(TPM_TransmitData(tpmcmd->req, tpmcmd->req_len, tpmcmd->resp, &size));
tpmcmd->resp_len = size;
unpack_TPM_RESULT(tpmcmd->resp + sizeof(TPM_TAG) + sizeof(UINT32), &status);
return status;
break;
default:
vtpmlogerror(VTPM_LOG_VTPM, "Invalid tag=%" PRIu16 "\n", tag);
status = TPM_BADTAG;
}
abort_egress:
tpmcmd->resp_len = VTPM_COMMAND_HEADER_SIZE;
pack_TPM_RSP_HEADER(tpmcmd->resp,
tag + 3, tpmcmd->resp_len, status);
return status;
}
+64
View File
@@ -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
+794
View File
@@ -0,0 +1,794 @@
/*
* Copyright (c) 2010-2012 United States Government, as represented by
* the Secretary of Defense. All rights reserved.
*
* THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
* ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
* INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT ARE HEREBY
* DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
* SOFTWARE.
*/
/***************************************************************
* DISK IMAGE LAYOUT
* *************************************************************
* All data is stored in BIG ENDIAN format
* *************************************************************
* Section 1: Header
*
* 10 bytes id ID String "VTPMMGRDOM"
* uint32_t version Disk Image version number (current == 1)
* uint32_t storage_key_len Length of the storage Key
* TPM_KEY storage_key Marshalled TPM_KEY structure (See TPM spec v2)
* RSA_BLOCK aes_crypto Encrypted aes key data (RSA_CIPHER_SIZE bytes), bound by the storage_key
* BYTE[32] aes_key Aes key for encrypting the uuid table
* uint32_t cipher_sz Encrypted size of the uuid table
*
* *************************************************************
* Section 2: Uuid Table
*
* This table is encrypted by the aes_key in the header. The cipher text size is just
* large enough to hold all of the entries plus required padding.
*
* Each entry is as follows
* BYTE[16] uuid Uuid of a vtpm that is stored on this disk
* uint32_t offset Disk offset where the vtpm data is stored
*
* *************************************************************
* Section 3: Vtpm Table
*
* The rest of the disk stores vtpms. Each vtpm is an RSA_BLOCK encrypted
* by the storage key. Each vtpm must exist on an RSA_BLOCK aligned boundary,
* starting at the first RSA_BLOCK aligned offset after the uuid table.
* As the uuid table grows, vtpms may be relocated.
*
* RSA_BLOCK vtpm_crypto Vtpm data encrypted by storage_key
* BYTE[20] hash Sha1 hash of vtpm encrypted data
* BYTE[16] vtpm_aes_key Encryption key for vtpm data
*
*************************************************************
*/
#define DISKVERS 1
#define IDSTR "VTPMMGRDOM"
#define IDSTRLEN 10
#define AES_BLOCK_SIZE 16
#define AES_KEY_BITS 256
#define AES_KEY_SIZE (AES_KEY_BITS/8)
#define BUF_SIZE 4096
#define UUID_TBL_ENT_SIZE (sizeof(uuid_t) + sizeof(uint32_t))
#define HEADERSZ (10 + 4 + 4)
#define TRY_READ(buf, size, msg) do {\
int rc; \
if((rc = read(blkfront_fd, buf, (size))) != (size)) { \
vtpmlogerror(VTPM_LOG_VTPM, "read() failed! " msg " : rc=(%d/%d), error=(%s)\n", rc, (int)(size), strerror(errno)); \
status = TPM_IOERROR;\
goto abort_egress;\
} \
} while(0)
#define TRY_WRITE(buf, size, msg) do {\
int rc; \
if((rc = write(blkfront_fd, buf, (size))) != (size)) { \
vtpmlogerror(VTPM_LOG_VTPM, "write() failed! " msg " : rc=(%d/%d), error=(%s)\n", rc, (int)(size), strerror(errno)); \
status = TPM_IOERROR;\
goto abort_egress;\
} \
} while(0)
#include <blkfront.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <inttypes.h>
#include <stdlib.h>
#include <stdbool.h>
#include <mini-os/byteorder.h>
#include <polarssl/aes.h>
#include "vtpm_manager.h"
#include "log.h"
#include "marshal.h"
#include "tpm.h"
#include "uuid.h"
#include "vtpmmgr.h"
#include "vtpm_storage.h"
#define MAX(a,b) ( ((a) > (b)) ? (a) : (b) )
#define MIN(a,b) ( ((a) < (b)) ? (a) : (b) )
/* blkfront device objets */
static struct blkfront_dev* blkdev = NULL;
static int blkfront_fd = -1;
struct Vtpm {
uuid_t uuid;
int offset;
};
struct Storage {
int aes_offset;
int uuid_offset;
int end_offset;
int num_vtpms;
int num_vtpms_alloced;
struct Vtpm* vtpms;
};
/* Global storage data */
static struct Storage g_store = {
.vtpms = NULL,
};
static int get_offset(void) {
return lseek(blkfront_fd, 0, SEEK_CUR);
}
static void reset_store(void) {
g_store.aes_offset = 0;
g_store.uuid_offset = 0;
g_store.end_offset = 0;
g_store.num_vtpms = 0;
g_store.num_vtpms_alloced = 0;
free(g_store.vtpms);
g_store.vtpms = NULL;
}
static int vtpm_get_index(const uuid_t uuid) {
int st = 0;
int ed = g_store.num_vtpms-1;
while(st <= ed) {
int mid = ((unsigned int)st + (unsigned int)ed) >> 1; //avoid overflow
int c = memcmp(uuid, &g_store.vtpms[mid].uuid, sizeof(uuid_t));
if(c == 0) {
return mid;
} else if(c > 0) {
st = mid + 1;
} else {
ed = mid - 1;
}
}
return -(st + 1);
}
static void vtpm_add(const uuid_t uuid, int offset, int index) {
/* Realloc more space if needed */
if(g_store.num_vtpms >= g_store.num_vtpms_alloced) {
g_store.num_vtpms_alloced += 16;
g_store.vtpms = realloc(
g_store.vtpms,
sizeof(struct Vtpm) * g_store.num_vtpms_alloced);
}
/* Move everybody after the new guy */
for(int i = g_store.num_vtpms; i > index; --i) {
g_store.vtpms[i] = g_store.vtpms[i-1];
}
vtpmloginfo(VTPM_LOG_VTPM, "Registered vtpm " UUID_FMT "\n", UUID_BYTES(uuid));
/* Finally add new one */
memcpy(g_store.vtpms[index].uuid, uuid, sizeof(uuid_t));
g_store.vtpms[index].offset = offset;
++g_store.num_vtpms;
}
#if 0
static void vtpm_remove(int index) {
for(i = index; i < g_store.num_vtpms; ++i) {
g_store.vtpms[i] = g_store.vtpms[i+1];
}
--g_store.num_vtpms;
}
#endif
static int pack_uuid_table(uint8_t* table, int size, int* nvtpms) {
uint8_t* ptr = table;
while(*nvtpms < g_store.num_vtpms && size >= 0)
{
/* Pack the uuid */
memcpy(ptr, (uint8_t*)g_store.vtpms[*nvtpms].uuid, sizeof(uuid_t));
ptr+= sizeof(uuid_t);
/* Pack the offset */
ptr = pack_UINT32(ptr, g_store.vtpms[*nvtpms].offset);
++*nvtpms;
size -= UUID_TBL_ENT_SIZE;
}
return ptr - table;
}
/* Extract the uuids */
static int extract_uuid_table(uint8_t* table, int size) {
uint8_t* ptr = table;
for(;size >= UUID_TBL_ENT_SIZE; size -= UUID_TBL_ENT_SIZE) {
int index;
uint32_t v32;
/*uuid_t is just an array of bytes, so we can do a direct cast here */
uint8_t* uuid = ptr;
ptr += sizeof(uuid_t);
/* Get the offset of the key */
ptr = unpack_UINT32(ptr, &v32);
/* Insert the new vtpm in sorted order */
if((index = vtpm_get_index(uuid)) >= 0) {
vtpmlogerror(VTPM_LOG_VTPM, "Vtpm (" UUID_FMT ") exists multiple times! ignoring...\n", UUID_BYTES(uuid));
continue;
}
index = -index -1;
vtpm_add(uuid, v32, index);
}
return ptr - table;
}
static void vtpm_decrypt_block(aes_context* aes,
uint8_t* iv,
uint8_t* cipher,
uint8_t* plain,
int cipher_sz,
int* overlap)
{
int bytes_ext;
/* Decrypt */
aes_crypt_cbc(aes, AES_DECRYPT,
cipher_sz,
iv, cipher, plain + *overlap);
/* Extract */
bytes_ext = extract_uuid_table(plain, cipher_sz + *overlap);
/* Copy left overs to the beginning */
*overlap = cipher_sz + *overlap - bytes_ext;
memcpy(plain, plain + bytes_ext, *overlap);
}
static int vtpm_encrypt_block(aes_context* aes,
uint8_t* iv,
uint8_t* plain,
uint8_t* cipher,
int block_sz,
int* overlap,
int* num_vtpms)
{
int bytes_to_crypt;
int bytes_packed;
/* Pack the uuid table */
bytes_packed = *overlap + pack_uuid_table(plain + *overlap, block_sz - *overlap, num_vtpms);
bytes_to_crypt = MIN(bytes_packed, block_sz);
/* Add padding if we aren't on a multiple of the block size */
if(bytes_to_crypt & (AES_BLOCK_SIZE-1)) {
int oldsz = bytes_to_crypt;
//add padding
bytes_to_crypt += AES_BLOCK_SIZE - (bytes_to_crypt & (AES_BLOCK_SIZE-1));
//fill padding with random bytes
vtpmmgr_rand(plain + oldsz, bytes_to_crypt - oldsz);
*overlap = 0;
} else {
*overlap = bytes_packed - bytes_to_crypt;
}
/* Encrypt this chunk */
aes_crypt_cbc(aes, AES_ENCRYPT,
bytes_to_crypt,
iv, plain, cipher);
/* Copy the left over partials to the beginning */
memcpy(plain, plain + bytes_to_crypt, *overlap);
return bytes_to_crypt;
}
static TPM_RESULT vtpm_storage_new_vtpm(const uuid_t uuid, int index) {
TPM_RESULT status = TPM_SUCCESS;
uint8_t plain[BUF_SIZE + AES_BLOCK_SIZE];
uint8_t buf[BUF_SIZE];
uint8_t* ptr;
int cipher_sz;
aes_context aes;
/* Add new vtpm to the table */
vtpm_add(uuid, g_store.end_offset, index);
g_store.end_offset += RSA_CIPHER_SIZE;
/* Compute the new end location of the encrypted uuid table */
cipher_sz = AES_BLOCK_SIZE; //IV
cipher_sz += g_store.num_vtpms * UUID_TBL_ENT_SIZE; //uuid table
cipher_sz += (AES_BLOCK_SIZE - (cipher_sz & (AES_BLOCK_SIZE -1))) & (AES_BLOCK_SIZE-1); //aes padding
/* Does this overlap any key data? If so they need to be relocated */
int uuid_end = (g_store.uuid_offset + cipher_sz + RSA_CIPHER_SIZE) & ~(RSA_CIPHER_SIZE -1);
for(int i = 0; i < g_store.num_vtpms; ++i) {
if(g_store.vtpms[i].offset < uuid_end) {
vtpmloginfo(VTPM_LOG_VTPM, "Relocating vtpm data\n");
//Read the hashkey cipher text
lseek(blkfront_fd, g_store.vtpms[i].offset, SEEK_SET);
TRY_READ(buf, RSA_CIPHER_SIZE, "vtpm hashkey relocate");
//Write the cipher text to new offset
lseek(blkfront_fd, g_store.end_offset, SEEK_SET);
TRY_WRITE(buf, RSA_CIPHER_SIZE, "vtpm hashkey relocate");
//Save new offset
g_store.vtpms[i].offset = g_store.end_offset;
g_store.end_offset += RSA_CIPHER_SIZE;
}
}
vtpmloginfo(VTPM_LOG_VTPM, "Generating a new symmetric key\n");
/* Generate an aes key */
TPMTRYRETURN(vtpmmgr_rand(plain, AES_KEY_SIZE));
aes_setkey_enc(&aes, plain, AES_KEY_BITS);
ptr = plain + AES_KEY_SIZE;
/* Pack the crypted size */
ptr = pack_UINT32(ptr, cipher_sz);
vtpmloginfo(VTPM_LOG_VTPM, "Binding encrypted key\n");
/* Seal the key and size */
TPMTRYRETURN(TPM_Bind(&vtpm_globals.storage_key,
plain,
ptr - plain,
buf));
/* Write the sealed key to disk */
lseek(blkfront_fd, g_store.aes_offset, SEEK_SET);
TRY_WRITE(buf, RSA_CIPHER_SIZE, "vtpm aes key");
/* ENCRYPT AND WRITE UUID TABLE */
vtpmloginfo(VTPM_LOG_VTPM, "Encrypting the uuid table\n");
int num_vtpms = 0;
int overlap = 0;
int bytes_crypted;
uint8_t iv[AES_BLOCK_SIZE];
/* Generate the iv for the first block */
TPMTRYRETURN(vtpmmgr_rand(iv, AES_BLOCK_SIZE));
/* Copy the iv to the cipher text buffer to be written to disk */
memcpy(buf, iv, AES_BLOCK_SIZE);
ptr = buf + AES_BLOCK_SIZE;
/* Encrypt the first block of the uuid table */
bytes_crypted = vtpm_encrypt_block(&aes,
iv, //iv
plain, //plaintext
ptr, //cipher text
BUF_SIZE - AES_BLOCK_SIZE,
&overlap,
&num_vtpms);
/* Write the iv followed by the crypted table*/
TRY_WRITE(buf, bytes_crypted + AES_BLOCK_SIZE, "vtpm uuid table");
/* Decrement the number of bytes encrypted */
cipher_sz -= bytes_crypted + AES_BLOCK_SIZE;
/* If there are more vtpms, encrypt and write them block by block */
while(cipher_sz > 0) {
/* Encrypt the next block of the uuid table */
bytes_crypted = vtpm_encrypt_block(&aes,
iv,
plain,
buf,
BUF_SIZE,
&overlap,
&num_vtpms);
/* Write the cipher text to disk */
TRY_WRITE(buf, bytes_crypted, "vtpm uuid table");
cipher_sz -= bytes_crypted;
}
goto egress;
abort_egress:
egress:
return status;
}
/**************************************
* PUBLIC FUNCTIONS
* ***********************************/
int vtpm_storage_init(void) {
struct blkfront_info info;
if((blkdev = init_blkfront(NULL, &info)) == NULL) {
return -1;
}
if((blkfront_fd = blkfront_open(blkdev)) < 0) {
return -1;
}
return 0;
}
void vtpm_storage_shutdown(void) {
reset_store();
close(blkfront_fd);
}
TPM_RESULT vtpm_storage_load_hashkey(const uuid_t uuid, uint8_t hashkey[HASHKEYSZ])
{
TPM_RESULT status = TPM_SUCCESS;
int index;
uint8_t cipher[RSA_CIPHER_SIZE];
uint8_t clear[RSA_CIPHER_SIZE];
UINT32 clear_size;
/* Find the index of this uuid */
if((index = vtpm_get_index(uuid)) < 0) {
index = -index-1;
vtpmlogerror(VTPM_LOG_VTPM, "LoadKey failure: Unrecognized uuid! " UUID_FMT "\n", UUID_BYTES(uuid));
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
/* Read the table entry */
lseek(blkfront_fd, g_store.vtpms[index].offset, SEEK_SET);
TRY_READ(cipher, RSA_CIPHER_SIZE, "vtpm hashkey data");
/* Decrypt the table entry */
TPMTRYRETURN(TPM_UnBind(
vtpm_globals.storage_key_handle,
RSA_CIPHER_SIZE,
cipher,
&clear_size,
clear,
(const TPM_AUTHDATA*)&vtpm_globals.storage_key_usage_auth,
&vtpm_globals.oiap));
if(clear_size < HASHKEYSZ) {
vtpmloginfo(VTPM_LOG_VTPM, "Decrypted Hash key size (%" PRIu32 ") was too small!\n", clear_size);
status = TPM_RESOURCES;
goto abort_egress;
}
memcpy(hashkey, clear, HASHKEYSZ);
vtpmloginfo(VTPM_LOG_VTPM, "Loaded hash and key for vtpm " UUID_FMT "\n", UUID_BYTES(uuid));
goto egress;
abort_egress:
vtpmlogerror(VTPM_LOG_VTPM, "Failed to load key\n");
egress:
return status;
}
TPM_RESULT vtpm_storage_save_hashkey(const uuid_t uuid, uint8_t hashkey[HASHKEYSZ])
{
TPM_RESULT status = TPM_SUCCESS;
int index;
uint8_t buf[RSA_CIPHER_SIZE];
/* Find the index of this uuid */
if((index = vtpm_get_index(uuid)) < 0) {
index = -index-1;
/* Create a new vtpm */
TPMTRYRETURN( vtpm_storage_new_vtpm(uuid, index) );
}
/* Encrypt the hash and key */
TPMTRYRETURN( TPM_Bind(&vtpm_globals.storage_key,
hashkey,
HASHKEYSZ,
buf));
/* Write to disk */
lseek(blkfront_fd, g_store.vtpms[index].offset, SEEK_SET);
TRY_WRITE(buf, RSA_CIPHER_SIZE, "vtpm hashkey data");
vtpmloginfo(VTPM_LOG_VTPM, "Saved hash and key for vtpm " UUID_FMT "\n", UUID_BYTES(uuid));
goto egress;
abort_egress:
vtpmlogerror(VTPM_LOG_VTPM, "Failed to save key\n");
egress:
return status;
}
TPM_RESULT vtpm_storage_new_header()
{
TPM_RESULT status = TPM_SUCCESS;
uint8_t buf[BUF_SIZE];
uint8_t keybuf[AES_KEY_SIZE + sizeof(uint32_t)];
uint8_t* ptr = buf;
uint8_t* sptr;
/* Clear everything first */
reset_store();
vtpmloginfo(VTPM_LOG_VTPM, "Creating new disk image header\n");
/*Copy the ID string */
memcpy(ptr, IDSTR, IDSTRLEN);
ptr += IDSTRLEN;
/*Copy the version */
ptr = pack_UINT32(ptr, DISKVERS);
/*Save the location of the key size */
sptr = ptr;
ptr += sizeof(UINT32);
vtpmloginfo(VTPM_LOG_VTPM, "Saving root storage key..\n");
/* Copy the storage key */
ptr = pack_TPM_KEY(ptr, &vtpm_globals.storage_key);
/* Now save the size */
pack_UINT32(sptr, ptr - (sptr + 4));
/* Create a fake aes key and set cipher text size to 0 */
memset(keybuf, 0, sizeof(keybuf));
vtpmloginfo(VTPM_LOG_VTPM, "Binding uuid table symmetric key..\n");
/* Save the location of the aes key */
g_store.aes_offset = ptr - buf;
/* Store the fake aes key and vtpm count */
TPMTRYRETURN(TPM_Bind(&vtpm_globals.storage_key,
keybuf,
sizeof(keybuf),
ptr));
ptr+= RSA_CIPHER_SIZE;
/* Write the header to disk */
lseek(blkfront_fd, 0, SEEK_SET);
TRY_WRITE(buf, ptr-buf, "vtpm header");
/* Save the location of the uuid table */
g_store.uuid_offset = get_offset();
/* Save the end offset */
g_store.end_offset = (g_store.uuid_offset + RSA_CIPHER_SIZE) & ~(RSA_CIPHER_SIZE -1);
vtpmloginfo(VTPM_LOG_VTPM, "Saved new manager disk header.\n");
goto egress;
abort_egress:
egress:
return status;
}
TPM_RESULT vtpm_storage_load_header(void)
{
TPM_RESULT status = TPM_SUCCESS;
uint32_t v32;
uint8_t buf[BUF_SIZE];
uint8_t* ptr = buf;
aes_context aes;
/* Clear everything first */
reset_store();
/* Read the header from disk */
lseek(blkfront_fd, 0, SEEK_SET);
TRY_READ(buf, IDSTRLEN + sizeof(UINT32) + sizeof(UINT32), "vtpm header");
vtpmloginfo(VTPM_LOG_VTPM, "Loading disk image header\n");
/* Verify the ID string */
if(memcmp(ptr, IDSTR, IDSTRLEN)) {
vtpmlogerror(VTPM_LOG_VTPM, "Invalid ID string in disk image!\n");
status = TPM_FAIL;
goto abort_egress;
}
ptr+=IDSTRLEN;
/* Unpack the version */
ptr = unpack_UINT32(ptr, &v32);
/* Verify the version */
if(v32 != DISKVERS) {
vtpmlogerror(VTPM_LOG_VTPM, "Unsupported disk image version number %" PRIu32 "\n", v32);
status = TPM_FAIL;
goto abort_egress;
}
/* Size of the storage key */
ptr = unpack_UINT32(ptr, &v32);
/* Sanity check */
if(v32 > BUF_SIZE) {
vtpmlogerror(VTPM_LOG_VTPM, "Size of storage key (%" PRIu32 ") is too large!\n", v32);
status = TPM_IOERROR;
goto abort_egress;
}
/* read the storage key */
TRY_READ(buf, v32, "storage pub key");
vtpmloginfo(VTPM_LOG_VTPM, "Unpacking storage key\n");
/* unpack the storage key */
ptr = unpack_TPM_KEY(buf, &vtpm_globals.storage_key, UNPACK_ALLOC);
/* Load Storage Key into the TPM */
TPMTRYRETURN( TPM_LoadKey(
TPM_SRK_KEYHANDLE,
&vtpm_globals.storage_key,
&vtpm_globals.storage_key_handle,
(const TPM_AUTHDATA*)&vtpm_globals.srk_auth,
&vtpm_globals.oiap));
/* Initialize the storage key auth */
memset(vtpm_globals.storage_key_usage_auth, 0, sizeof(TPM_AUTHDATA));
/* Store the offset of the aes key */
g_store.aes_offset = get_offset();
/* Read the rsa cipher text for the aes key */
TRY_READ(buf, RSA_CIPHER_SIZE, "aes key");
ptr = buf + RSA_CIPHER_SIZE;
vtpmloginfo(VTPM_LOG_VTPM, "Unbinding uuid table symmetric key\n");
/* Decrypt the aes key protecting the uuid table */
UINT32 datalen;
TPMTRYRETURN(TPM_UnBind(
vtpm_globals.storage_key_handle,
RSA_CIPHER_SIZE,
buf,
&datalen,
ptr,
(const TPM_AUTHDATA*)&vtpm_globals.storage_key_usage_auth,
&vtpm_globals.oiap));
/* Validate the length of the output buffer */
if(datalen < AES_KEY_SIZE + sizeof(UINT32)) {
vtpmlogerror(VTPM_LOG_VTPM, "Unbound AES key size (%d) was too small! expected (%ld)\n", datalen, AES_KEY_SIZE + sizeof(UINT32));
status = TPM_IOERROR;
goto abort_egress;
}
/* Extract the aes key */
aes_setkey_dec(&aes, ptr, AES_KEY_BITS);
ptr+= AES_KEY_SIZE;
/* Extract the ciphertext size */
ptr = unpack_UINT32(ptr, &v32);
int cipher_size = v32;
/* Sanity check */
if(cipher_size & (AES_BLOCK_SIZE-1)) {
vtpmlogerror(VTPM_LOG_VTPM, "Cipher text size (%" PRIu32 ") is not a multiple of the aes block size! (%d)\n", v32, AES_BLOCK_SIZE);
status = TPM_IOERROR;
goto abort_egress;
}
/* Save the location of the uuid table */
g_store.uuid_offset = get_offset();
/* Only decrypt the table if there are vtpms to decrypt */
if(cipher_size > 0) {
int rbytes;
int overlap = 0;
uint8_t plain[BUF_SIZE + AES_BLOCK_SIZE];
uint8_t iv[AES_BLOCK_SIZE];
vtpmloginfo(VTPM_LOG_VTPM, "Decrypting uuid table\n");
/* Pre allocate the vtpm array */
g_store.num_vtpms_alloced = cipher_size / UUID_TBL_ENT_SIZE;
g_store.vtpms = malloc(sizeof(struct Vtpm) * g_store.num_vtpms_alloced);
/* Read the iv and the first chunk of cipher text */
rbytes = MIN(cipher_size, BUF_SIZE);
TRY_READ(buf, rbytes, "vtpm uuid table\n");
cipher_size -= rbytes;
/* Copy the iv */
memcpy(iv, buf, AES_BLOCK_SIZE);
ptr = buf + AES_BLOCK_SIZE;
/* Remove the iv from the number of bytes to decrypt */
rbytes -= AES_BLOCK_SIZE;
/* Decrypt and extract vtpms */
vtpm_decrypt_block(&aes,
iv, ptr, plain,
rbytes, &overlap);
/* Read the rest of the table if there is more */
while(cipher_size > 0) {
/* Read next chunk of cipher text */
rbytes = MIN(cipher_size, BUF_SIZE);
TRY_READ(buf, rbytes, "vtpm uuid table");
cipher_size -= rbytes;
/* Decrypt a block of text */
vtpm_decrypt_block(&aes,
iv, buf, plain,
rbytes, &overlap);
}
vtpmloginfo(VTPM_LOG_VTPM, "Loaded %d vtpms!\n", g_store.num_vtpms);
}
/* The end of the key table, new vtpms go here */
int uuid_end = (get_offset() + RSA_CIPHER_SIZE) & ~(RSA_CIPHER_SIZE -1);
g_store.end_offset = uuid_end;
/* Compute the end offset while validating vtpms*/
for(int i = 0; i < g_store.num_vtpms; ++i) {
/* offset must not collide with previous data */
if(g_store.vtpms[i].offset < uuid_end) {
vtpmlogerror(VTPM_LOG_VTPM, "vtpm: " UUID_FMT
" offset (%d) is before end of uuid table (%d)!\n",
UUID_BYTES(g_store.vtpms[i].uuid),
g_store.vtpms[i].offset, uuid_end);
status = TPM_IOERROR;
goto abort_egress;
}
/* offset must be at a multiple of cipher size */
if(g_store.vtpms[i].offset & (RSA_CIPHER_SIZE-1)) {
vtpmlogerror(VTPM_LOG_VTPM, "vtpm: " UUID_FMT
" offset(%d) is not at a multiple of the rsa cipher text size (%d)!\n",
UUID_BYTES(g_store.vtpms[i].uuid),
g_store.vtpms[i].offset, RSA_CIPHER_SIZE);
status = TPM_IOERROR;
goto abort_egress;
}
/* Save the last offset */
if(g_store.vtpms[i].offset >= g_store.end_offset) {
g_store.end_offset = g_store.vtpms[i].offset + RSA_CIPHER_SIZE;
}
}
goto egress;
abort_egress:
//An error occured somewhere
vtpmlogerror(VTPM_LOG_VTPM, "Failed to load manager data!\n");
//Clear the data store
reset_store();
//Reset the storage key structure
free_TPM_KEY(&vtpm_globals.storage_key);
{
TPM_KEY key = TPM_KEY_INIT;
vtpm_globals.storage_key = key;
}
//Reset the storage key handle
TPM_EvictKey(vtpm_globals.storage_key_handle);
vtpm_globals.storage_key_handle = 0;
egress:
return status;
}
#if 0
/* For testing disk IO */
void add_fake_vtpms(int num) {
for(int i = 0; i < num; ++i) {
uint32_t ind = cpu_to_be32(i);
uuid_t uuid;
memset(uuid, 0, sizeof(uuid_t));
memcpy(uuid, &ind, sizeof(ind));
int index = vtpm_get_index(uuid);
index = -index-1;
vtpm_storage_new_vtpm(uuid, index);
}
}
#endif
+68
View File
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2010-2012 United States Government, as represented by
* the Secretary of Defense. All rights reserved.
*
* based off of the original tools/vtpm_manager code base which is:
* Copyright (c) 2005, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef VTPM_STORAGE_H
#define VTPM_STORAGE_h
#include "uuid.h"
#define VTPM_NVMKEY_SIZE 32
#define HASHKEYSZ (sizeof(TPM_DIGEST) + VTPM_NVMKEY_SIZE)
/* Initialize the storage system and its virtual disk */
int vtpm_storage_init(void);
/* Shutdown the storage system and its virtual disk */
void vtpm_storage_shutdown(void);
/* Loads Sha1 hash and 256 bit AES key from disk and stores them
* packed together in outbuf. outbuf must be freed
* by the caller using buffer_free()
*/
TPM_RESULT vtpm_storage_load_hashkey(const uuid_t uuid, uint8_t hashkey[HASHKEYSZ]);
/* inbuf must contain a sha1 hash followed by a 256 bit AES key.
* Encrypts and stores the hash and key to disk */
TPM_RESULT vtpm_storage_save_hashkey(const uuid_t uuid, uint8_t hashkey[HASHKEYSZ]);
/* Load the vtpm manager data - call this on startup */
TPM_RESULT vtpm_storage_load_header(void);
/* Saves the vtpm manager data - call this on shutdown */
TPM_RESULT vtpm_storage_new_header(void);
#endif
+93
View File
@@ -0,0 +1,93 @@
/*
* Copyright (c) 2010-2012 United States Government, as represented by
* the Secretary of Defense. All rights reserved.
*
* based off of the original tools/vtpm_manager code base which is:
* Copyright (c) 2005, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdint.h>
#include <mini-os/tpmback.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "log.h"
#include "vtpmmgr.h"
#include "tcg.h"
void main_loop(void) {
tpmcmd_t* tpmcmd;
uint8_t respbuf[TCPA_MAX_BUFFER_LENGTH];
while(1) {
/* Wait for requests from a vtpm */
vtpmloginfo(VTPM_LOG_VTPM, "Waiting for commands from vTPM's:\n");
if((tpmcmd = tpmback_req_any()) == NULL) {
vtpmlogerror(VTPM_LOG_VTPM, "NULL tpmcmd\n");
continue;
}
tpmcmd->resp = respbuf;
/* Process the command */
vtpmmgr_handle_cmd(tpmcmd->uuid, tpmcmd);
/* Send response */
tpmback_resp(tpmcmd);
}
}
int main(int argc, char** argv)
{
int rc = 0;
sleep(2);
vtpmloginfo(VTPM_LOG_VTPM, "Starting vTPM manager domain\n");
/* Initialize the vtpm manager */
if(vtpmmgr_init(argc, argv) != TPM_SUCCESS) {
vtpmlogerror(VTPM_LOG_VTPM, "Unable to initialize vtpmmgr domain!\n");
rc = -1;
goto exit;
}
main_loop();
vtpmloginfo(VTPM_LOG_VTPM, "vTPM Manager shutting down...\n");
vtpmmgr_shutdown();
exit:
return rc;
}
+77
View File
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2010-2012 United States Government, as represented by
* the Secretary of Defense. All rights reserved.
*
* based off of the original tools/vtpm_manager code base which is:
* Copyright (c) 2005, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef VTPMMGR_H
#define VTPMMGR_H
#include <mini-os/tpmback.h>
#include <polarssl/entropy.h>
#include <polarssl/ctr_drbg.h>
#include "uuid.h"
#include "tcg.h"
#include "vtpm_manager.h"
#define RSA_KEY_SIZE 0x0800
#define RSA_CIPHER_SIZE (RSA_KEY_SIZE / 8)
struct vtpm_globals {
int tpm_fd;
TPM_KEY storage_key;
TPM_HANDLE storage_key_handle; // Key used by persistent store
TPM_AUTH_SESSION oiap; // OIAP session for storageKey
TPM_AUTHDATA storage_key_usage_auth;
TPM_AUTHDATA owner_auth;
TPM_AUTHDATA srk_auth;
entropy_context entropy;
ctr_drbg_context ctr_drbg;
};
// --------------------------- Global Values --------------------------
extern struct vtpm_globals vtpm_globals; // Key info and DMI states
TPM_RESULT vtpmmgr_init(int argc, char** argv);
void vtpmmgr_shutdown(void);
TPM_RESULT vtpmmgr_handle_cmd(const uuid_t uuid, tpmcmd_t* tpmcmd);
inline TPM_RESULT vtpmmgr_rand(unsigned char* bytes, size_t num_bytes) {
return ctr_drbg_random(&vtpm_globals.ctr_drbg, bytes, num_bytes) == 0 ? 0 : TPM_FAIL;
}
#endif
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.