<|start_filename|>src/include/tss/tss_typedef.h<|end_filename|>
/*++

Global typedefs for TSS
 
*/

#ifndef __TSS_TYPEDEF_H__
#define __TSS_TYPEDEF_H__

#include <tss/platform.h>

//--------------------------------------------------------------------
// definitions for TSS Service Provider (TSP)
//
typedef  UINT32  TSS_HANDLE;

typedef  UINT32  TSS_FLAG;  // object attributes
typedef  UINT32  TSS_RESULT;  // the return code from a TSS function

typedef  UINT32          TSS_HOBJECT;     // basic object handle
typedef  TSS_HOBJECT     TSS_HCONTEXT;    // context object handle
typedef  TSS_HOBJECT     TSS_HPOLICY;     // policy object handle
typedef  TSS_HOBJECT     TSS_HTPM;        // TPM object handle
typedef  TSS_HOBJECT     TSS_HKEY;        // key object handle
typedef  TSS_HOBJECT     TSS_HENCDATA;    // encrypted data object handle
typedef  TSS_HOBJECT     TSS_HPCRS;       // PCR composite object handle
typedef  TSS_HOBJECT     TSS_HHASH;       // hash object handle
typedef  TSS_HOBJECT     TSS_HNVSTORE;    // NV storage object handle
typedef  TSS_HOBJECT     TSS_HMIGDATA;    // migration data utility obj handle
typedef  TSS_HOBJECT     TSS_HDELFAMILY;  // delegation family object handle
typedef  TSS_HOBJECT     TSS_HDAA_CREDENTIAL; // daa credential
typedef  TSS_HOBJECT     TSS_HDAA_ISSUER_KEY; // daa credential issuer keypair
typedef  TSS_HOBJECT     TSS_HDAA_ARA_KEY;    // daa anonymity revocation
                                              // authority keypair

typedef UINT32  TSS_EVENTTYPE;
typedef UINT16  TSS_MIGRATE_SCHEME;
typedef UINT32  TSS_ALGORITHM_ID;
typedef UINT32  TSS_KEY_USAGE_ID;
typedef UINT16  TSS_KEY_ENC_SCHEME;
typedef UINT16  TSS_KEY_SIG_SCHEME;
typedef BYTE    TSS_KEY_AUTH_DATA_USAGE;
typedef UINT32  TSS_CMK_DELEGATE;
typedef UINT32  TSS_NV_INDEX;
typedef UINT32  TSS_COUNTER_ID;

#endif // __TSS_TYPEDEF_H__



<|start_filename|>src/tddl/tddl.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004, 2005
 *
 */


#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "linux/tpm.h"
#include "tcslog.h"
#include "tddl.h"

struct tpm_device_node tpm_device_nodes[] = {
	{"/dev/tpm0", TDDL_UNDEF, TDDL_UNDEF},
	{"/udev/tpm0", TDDL_UNDEF, TDDL_UNDEF},
	{"/dev/tpm", TDDL_UNDEF, TDDL_UNDEF},
	{NULL, 0, 0}
};

struct tpm_device_node *opened_device = NULL;

BYTE txBuffer[TDDL_TXBUF_SIZE];
TSS_BOOL use_in_socket = FALSE;
struct tcsd_config *_tcsd_options = NULL;

#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <netdb.h>
#include <fcntl.h>


int
open_device()
{
	int i = 0, fd = -1, tcp_device_port;
	char *tcp_device_hostname = NULL;
	char *un_socket_device_path = NULL;
	char *tcp_device_port_string = NULL;
	
	if (getenv("TCSD_USE_TCP_DEVICE")) {
		if ((tcp_device_hostname = getenv("TCSD_TCP_DEVICE_HOSTNAME")) == NULL)
			tcp_device_hostname = "localhost";
		if ((un_socket_device_path = getenv("TCSD_UN_SOCKET_DEVICE_PATH")) == NULL)
			un_socket_device_path = "/var/run/tpm/tpmd_socket:0";
		if ((tcp_device_port_string = getenv("TCSD_TCP_DEVICE_PORT")) != NULL)
			tcp_device_port = atoi(tcp_device_port_string);
		else
			tcp_device_port = 6545;
	 
		
		fd = socket(AF_INET, SOCK_STREAM, 0);
		if (fd > 0) {
			struct hostent *host = gethostbyname(tcp_device_hostname);
			if (host != NULL) {   
				struct sockaddr_in addr;
				memset(&addr, 0x0, sizeof(addr));
				addr.sin_family = host->h_addrtype;
				addr.sin_port   = htons(tcp_device_port);
				memcpy(&addr.sin_addr,
						host->h_addr,
						host->h_length);
				if (connect(fd,	(struct sockaddr *)&addr,
					    sizeof(addr)) < 0) {
					close(fd);
					fd = -1;
				} else
					use_in_socket = TRUE;
			} else {
				close (fd);
				fd = -1;
			}
		}
	       
		if (fd < 0) {
			struct sockaddr_un addr;

			fd = socket(AF_UNIX, SOCK_STREAM, 0);
			if (fd >= 0) {
				addr.sun_family = AF_UNIX;
				strncpy(addr.sun_path, un_socket_device_path,
						sizeof(addr.sun_path));
				if (connect(fd, (void *)&addr, sizeof(addr)) < 0) {
					close(fd);
					fd = -1;
				}
			}
		}
	} 
	
	if (fd < 0) {
		/* tpm_device_paths is filled out in tddl.h */
		for (i = 0; tpm_device_nodes[i].path != NULL; i++) {
			errno = 0;
			if ((fd = open(tpm_device_nodes[i].path, O_RDWR)) >= 0)
				break;
		}
	}
	
	if (fd > 0) {
		opened_device = &(tpm_device_nodes[i]);
		tpm_device_nodes[i].fd = fd;
	}
	return fd;
}

TSS_RESULT
Tddli_Open()
{
	int rc;

	if (opened_device != NULL) {
		LogDebug("attempted to re-open the TPM driver!");
		return TDDLERR(TDDL_E_ALREADY_OPENED);
	}

	rc = open_device();
	if (rc < 0) {
		LogError("Could not find a device to open!");
		if (errno == ENOENT) {
			/* File DNE */
			return TDDLERR(TDDL_E_COMPONENT_NOT_FOUND);
		}

		return TDDLERR(TDDL_E_FAIL);
	}

	return TSS_SUCCESS;
}

TSS_RESULT
Tddli_Close()
{
	if (opened_device == NULL) {
		LogDebug("attempted to re-close the TPM driver!");
		return TDDLERR(TDDL_E_ALREADY_CLOSED);
	}

	close(opened_device->fd);
	opened_device->fd = TDDL_UNDEF;
	opened_device = NULL;

	return TSS_SUCCESS;
}

TSS_RESULT
Tddli_TransmitData(BYTE * pTransmitBuf, UINT32 TransmitBufLen, BYTE * pReceiveBuf,
		   UINT32 * pReceiveBufLen)
{
	int sizeResult;

	if (TransmitBufLen > TDDL_TXBUF_SIZE) {
		LogError("buffer size handed to TDDL is too large! (%u bytes)", TransmitBufLen);
		return TDDLERR(TDDL_E_FAIL);
	}

	memcpy(txBuffer, pTransmitBuf, TransmitBufLen);
	LogDebug("Calling write to driver");

	if (use_in_socket) {
		Tddli_Close();
		if (Tddli_Open())
			return TDDLERR(TDDL_E_IOERROR);
	}

	switch (opened_device->transmit) {
		case TDDL_UNDEF:
			/* fall through */
		case TDDL_TRANSMIT_IOCTL:
			errno = 0;
			if ((sizeResult = ioctl(opened_device->fd, TPMIOC_TRANSMIT, txBuffer)) != -1) {
				opened_device->transmit = TDDL_TRANSMIT_IOCTL;
				break;
			}
			LogWarn("ioctl: (%d) %s", errno, strerror(errno));
			LogInfo("Falling back to Read/Write device support.");
			/* fall through */
		case TDDL_TRANSMIT_RW:
			if ((sizeResult = write(opened_device->fd,
						txBuffer,
						TransmitBufLen)) == (int)TransmitBufLen) {
				opened_device->transmit = TDDL_TRANSMIT_RW;
				sizeResult = read(opened_device->fd, txBuffer,
						  TDDL_TXBUF_SIZE);
				break;
			} else {
				if (sizeResult == -1) {
					LogError("write to device %s failed: %s",
						 opened_device->path,
						 strerror(errno));
				} else {
					LogError("wrote %d bytes to %s (tried "
						 "to write %d)", sizeResult,
						 opened_device->path,
						 TransmitBufLen);
				}
			}
			/* fall through */
		default:
			return TDDLERR(TDDL_E_IOERROR);
	}

	if (sizeResult < 0) {
		LogError("read from device %s failed: %s", opened_device->path, strerror(errno));
		return TDDLERR(TDDL_E_IOERROR);
	} else if (sizeResult == 0) {
		LogError("Zero bytes read from device %s", opened_device->path);
		return TDDLERR(TDDL_E_IOERROR);
	}

	if ((unsigned)sizeResult > *pReceiveBufLen) {
		LogError("read %d bytes from device %s, (only room for %d)", sizeResult,
				opened_device->path, *pReceiveBufLen);
		return TDDLERR(TDDL_E_INSUFFICIENT_BUFFER);
	}

	*pReceiveBufLen = sizeResult;

	memcpy(pReceiveBuf, txBuffer, *pReceiveBufLen);
	return TSS_SUCCESS;
}

TSS_RESULT
Tddli_GetStatus(UINT32 ReqStatusType, UINT32 *pStatus)
{
	return TDDLERR(TSS_E_NOTIMPL);
}

TSS_RESULT
Tddli_SetCapability(UINT32 CapArea, UINT32 SubCap,
		    BYTE *pSetCapBuf, UINT32 SetCapBufLen)
{
	return TDDLERR(TSS_E_NOTIMPL);
}

TSS_RESULT
Tddli_GetCapability(UINT32 CapArea, UINT32 SubCap,
		    BYTE *pCapBuf, UINT32 *pCapBufLen)
{
	return TDDLERR(TSS_E_NOTIMPL);
}

TSS_RESULT Tddli_Cancel(void)
{
	int rc;

	if (opened_device->transmit == TDDL_TRANSMIT_IOCTL) {
		if ((rc = ioctl(opened_device->fd, TPMIOC_CANCEL, NULL)) == -1) {
			LogError("ioctl: (%d) %s", errno, strerror(errno));
			return TDDLERR(TDDL_E_FAIL);
		} else if (rc == -EIO) {
			/* The driver timed out while trying to tell the chip to cancel */
			return TDDLERR(TDDL_E_COMMAND_COMPLETED);
		}

		return TSS_SUCCESS;
	} else {
		return TDDLERR(TSS_E_NOTIMPL);
	}
}


<|start_filename|>src/include/tcs_context.h<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */

#ifndef _TCS_CONTEXT_H_
#define _TCS_CONTEXT_H_

#include "threads.h"

struct keys_loaded
{
	TCS_KEY_HANDLE key_handle;
	struct keys_loaded *next;
};

#define TSS_CONTEXT_FLAG_TRANSPORT_EXCLUSIVE	0x1
#define TSS_CONTEXT_FLAG_TRANSPORT_ENCRYPTED	0x2
#define TSS_CONTEXT_FLAG_TRANSPORT_ENABLED	0x4

struct tcs_context {
	TSS_FLAG flags;
	TPM_TRANSHANDLE transHandle;
	TCS_CONTEXT_HANDLE handle;
	COND_VAR cond; /* used in waiting for an auth ctx to become available */
	struct keys_loaded *keys;
	struct tcs_context *next;
};

#endif



<|start_filename|>src/tspi/daa/daa_verifier/verifier.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2006
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "bi.h"
#include "daa_parameter.h"
#include "trousers/tss.h"
#include "spi_internal_types.h"
#include "spi_utils.h"
#include <trousers/trousers.h>
#include <obj.h>
#include "tsplog.h"
#include "tss/tcs.h"
#include "platform.h"

#include "verifier.h"

TSPICALL Tspi_DAA_VerifyInit_internal
(
	TSS_HDAA	hDAA,	// in
	UINT32*	nonceVerifierLength,	// out
	BYTE**	nonceVerifier,	// out
	UINT32	baseNameLength,	// out
	BYTE **	baseName	// out
) {
	TSS_RESULT result = TSS_SUCCESS;
	TCS_CONTEXT_HANDLE tcsContext;
	bi_ptr nounce = NULL;

	//TODO how to setup the baseName & baseNameLength
	if( (result = obj_daa_get_tsp_context( hDAA, &tcsContext)) != TSS_SUCCESS)
		goto close;
	*nonceVerifierLength = DAA_PARAM_LENGTH_MESSAGE_DIGEST;
	*nonceVerifier = calloc_tspi( tcsContext, DAA_PARAM_LENGTH_MESSAGE_DIGEST);
	if (*nonceVerifier == NULL) {
		LogError("malloc of %d bytes failed", DAA_PARAM_LENGTH_MESSAGE_DIGEST);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	nounce = bi_new_ptr();
	bi_urandom( nounce, DAA_PARAM_LENGTH_MESSAGE_DIGEST * 8);
	bi_2_byte_array( *nonceVerifier, DAA_PARAM_LENGTH_MESSAGE_DIGEST, nounce);
close:
	FREE_BI( nounce);
	return result;
}


<|start_filename|>src/tspi/daa/big_integer/bi_gmp.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2006
 *
 */

#ifdef BI_GMP

#include <time.h>
#include <stdio.h>
#include <stdlib.h>

#include <bi.h>

#undef INLINE_DECL
#define INLINE_DECL

gmp_randstate_t state;

/*
 reps controls how many  tests should be done in mpz_probable_prime_p:
 5 to 10 are reasonable number
*/
static int reps = 20;

static int initialized = 0;
void * (*bi_alloc)(size_t size);

/***********************************************************************************
	BITS OPERATION
*************************************************************************************/

// for conversion from and to byte[] see mpz_export and mpz_import

/* return the size of a network byte order representation of <i>  */
long bi_nbin_size(const bi_ptr i) {
	int word_size = 1; // 1 byte per word
	int numb = 8 * word_size - 0;
	int count = (mpz_sizeinbase ( i, 2) + numb-1) / numb;

	return count * word_size;
}

/* return a BYTE * - in network byte order -  and update the length <length> */
unsigned char *bi_2_nbin( int *length, const bi_ptr i) {
	unsigned char *buffer = (unsigned char *)bi_alloc( bi_nbin_size( i));

	if( buffer == NULL) return NULL;
	mpz_export(buffer, length, 1, 1, 1, 0, i);
	return buffer;
}

/* return a BYTE * - in network byte order -  and update the length <length>  */
/* different from bi_2_nbin: you should reserve enough memory for the storage */
void bi_2_nbin1( int *length, unsigned char *buffer, const bi_ptr i) {
	mpz_export(buffer, length, 1, 1, 1, 0, i);
}

/* return a bi_ptr that correspond to the big endian encoded BYTE array of length <n_length> */
INLINE_DECL bi_ptr bi_set_as_nbin( const unsigned long length, const unsigned char *buffer) {
	bi_ptr ret = bi_new_ptr();

	if( ret == NULL) return NULL;
	mpz_import( ret, length, 1, 1, 1, 0, buffer);
	return ret;
}


/***********************************************************************************
	BASIC MATH OPERATION
*************************************************************************************/

/* multiple-exponentiation */
/* <result> := mod( Multi( <g>i, <e>i), number of byte <m>) with  0 <= i <= <n> */
bi_ptr bi_multi_mod_exp( bi_ptr result,
			const int n,
			const bi_t g[],
			const long e[],
			const int m) {
	mpz_t temp, bi_m;
	int i;

	mpz_init( temp);
	mpz_init( bi_m);
	mpz_set_si( bi_m, m);
	// result := (g[0] ^ e[0]) mod m
	mpz_powm_ui( result, g[0], e[0], bi_m);
	for( i=1; i<n; i++) {
		//  temp := (g[i] ^ e[i]) mod bi_m
		mpz_powm_ui( temp, g[i], e[i], bi_m);
		//  result := result * temp
		mpz_mul( result, result, temp);
	}
	mpz_mod_ui( result, result, m);
	mpz_clear( bi_m);
	mpz_clear( temp);
	return result;
}

/***********************************************************************************
	NUMBER THEORIE OPERATION
*************************************************************************************/
/* generate prime number of <length> bits  */
INLINE_DECL bi_ptr bi_generate_prime( bi_ptr result, const long length) {
	do {
		mpz_urandomb( result, state, length);	// i := random( length)
		bi_setbit( result, 0);
		bi_setbit( result, length - 1);
		bi_setbit( result, length - 2);
		mpz_nextprime( result, result);	// i := nextPrime( i)
	} while( mpz_sizeinbase( result, 2) != (unsigned long)length &&
			bi_is_probable_prime( result) );
	return result;
}

/* generate a safe prime number of <length> bits  */
/* by safe we mean a prime p so that (p-1)/2 is also prime */
INLINE_DECL bi_ptr bi_generate_safe_prime( bi_ptr result, long length) {
	mpz_t temp;

	mpz_init(temp);
	do {
		bi_generate_prime( result, length);
		mpz_sub_ui( temp, result, 1); // temp := result - 1
		mpz_div_2exp( temp, temp, 1); // temp := temp / 2
	} while( mpz_probab_prime_p( temp, 10) == 0);
#ifdef BI_DEBUG
	printf("GENERATE SAFE PRIME DONE");fflush(stdout);
#endif
	mpz_clear( temp);
	return result;
}

/* return true if <i> is a probably prime  */
INLINE_DECL int bi_is_probable_prime( bi_ptr i) {
	/*
	This function does some trial divisions and after some Miller-Rabin probabilistic
	primality tests. The second parameter controls how many  tests should be done,
	5 to 10 are reasonable number
	*/
	return mpz_probab_prime_p( i, reps)>=1 ? 1 : 0;
}

/* return in <result> the greatest common divisor of <a> and <b> */
/* <result> := gcd( <a>, <b>) */
INLINE_DECL bi_ptr bi_gcd( bi_ptr result, bi_ptr a, bi_ptr b) {
	// result := gcd( a, b)
	mpz_gcd( result, a, b);
	return result;
}


/***********************************************************************************
	INIT/RELEASE LIBRARY
*************************************************************************************/

/* bi_alloc_p allocation function used only for exporting a bi struct, so for bi_2_nbin
if define as NULL, a stdlib malloc() will be used */
void bi_init( void * (*bi_alloc_p)(size_t size)) {
	time_t start;
	unsigned long seed;
	FILE *f;
#ifdef INTERACTIVE
	int c, i;
#endif

	if( initialized == 1) return;
	if( bi_alloc_p == NULL) bi_alloc = &malloc;
	else bi_alloc = bi_alloc_p;
	mpz_init( bi_0);
	mpz_set_ui( bi_0, 0);
	mpz_init( bi_1);
	mpz_set_ui( bi_1, 1);
	mpz_init( bi_2);
	mpz_set_ui( bi_2, 2);
	allocs = list_new();
	if( allocs == NULL) {
		LogError("malloc of list failed");
		return;
	}
#ifdef BI_DEBUG
	printf("bi_init() -> gmp lib\n");
#endif
	time( &start);
	// first try /dev/random, the most secure random generator
	f = fopen("/dev/random", "r");
	// in case of failure, but les secure :(
	if( f== NULL) f = fopen("/dev/urandom", "r");
	if( f != NULL) {
		fread( &seed, sizeof(unsigned long int), 1, f);
		fclose(f);
	}
#ifdef INTERACTIVE
	else {
		printf("! devices /dev/random and /dev/urandom not found\n");
		printf("type some characters to generate a random seed (follow by enter)\n");
		fflush(stdout);
		i=0;
		while( (c = fgetc(stdin)) != 10) {
			time_t temps;
			time( &temps);
			seed += temps +( c << i);
			i++;
		}
		time_t temps;
		time( &temps);
		seed += temps;
#ifdef BI_DEBUG
		printf("temps=%lx\n", temps - start);
#endif // BI_DEBUG
		seed = (long)( temps * start);
	}
#endif // INTERACTIVE
#ifdef BI_DEBUG
	printf("seed=%lx\n", seed);
#endif
	gmp_randinit_default( state);
	gmp_randseed_ui( state, seed);
	initialized = 1;
}

void bi_release(void) {
	if( initialized) {
		bi_flush_memory();
		bi_free( bi_0);
		bi_free( bi_1);
		bi_free( bi_2);
		initialized = 0;
	}
}
void bi_flush_memory(void) {
	node_t *current;
	list_ptr list = allocs;

	if( list->head == NULL) return; // list is empty
	else {
		current = list->head; // go to first node
		do {
			LogDebug("[flush memory] free %lx\n", current->obj);
			free( current->obj);
			current = current->next; // traverse through the list
		} while(current != NULL); // until current node is NULL
	}
	list_freeall( allocs);
	allocs = list_new();
	if( allocs == NULL) {
		LogError("malloc of list failed");
		return;
	}
}


int bi_is_initialized(void) {
	return initialized;
}

#endif


<|start_filename|>src/tspi/daa/daa_platform/platform.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2006
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

// for message digest
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/err.h>
#include <openssl/rsa.h>
#include <openssl/sha.h>

#include <stdlib.h>

#include "daa_structs.h"
#include "daa_parameter.h"
#include "trousers/tss.h"
#include "spi_internal_types.h"
#include "spi_utils.h"
#include <trousers/trousers.h>
#include <spi_utils.h>
#include <obj.h>
#include "tsplog.h"
#include "tss/tcs.h"
#include "platform.h"
#include "issuer.h"
#include "verifier.h"

#define EVP_SUCCESS 1

TSS_RESULT
Tcsip_TPM_DAA_Join(TCS_CONTEXT_HANDLE tcsContext, // in
			TSS_HDAA hDAA, // in
			BYTE stage, // in
			UINT32 inputSize0, // in
			BYTE* inputData0, // in
			UINT32 inputSize1, // in
			BYTE* inputData1, // in
			TPM_AUTH* ownerAuth, // in/out
			UINT32* outputSize, // out
			BYTE** outputData // out
) {
	TSS_RESULT result;
	TSS_HPOLICY hPolicy;
	TCPA_DIGEST digest;
	UINT16 offset = 0;
	BYTE hashblob[10000];
	TPM_HANDLE hTPM;
	TPM_HANDLE join_session;
	// TPM_HANDLE hTPM;

	if( (result = obj_daa_get_handle_tpm( hDAA, &hTPM)) != TSS_SUCCESS)
		return result;
	if( (result = obj_daa_get_session_handle( hDAA, &join_session)) != TSS_SUCCESS)
		return result;
	LogDebug("Tcsip_TPM_DAA_Join(tcsContext=%x,hDAA=%x,join_session=%x, hTPM=%x stage=%d)",
		tcsContext,
		hDAA,
		join_session,
		hTPM,
		stage);

	LogDebug("obj_tpm_get_policy(hTPM=%X)", hTPM);
	if( (result = obj_tpm_get_policy( hTPM, &hPolicy)) != TSS_SUCCESS)
		return result;
	LogDebug("Trspi_LoadBlob_UINT32(&offset, TPM_ORD_DAA_Join, hashblob)");
	// hash TPM_COMMAND_CODE
	Trspi_LoadBlob_UINT32(&offset, TPM_ORD_DAA_Join, hashblob);
	LogDebug("Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest)");
	// hash stage
	Trspi_LoadBlob_BYTE(&offset, stage, hashblob);
	LogDebug("Trspi_LoadBlob_UINT32(&offset, 0, hashblob)");
	// hash inputSize0
	Trspi_LoadBlob_UINT32(&offset, inputSize0, hashblob);
	LogDebug("Trspi_LoadBlob_UINT32(&offset, inputSize0:%d", inputSize0);
	// hash inputData0
	Trspi_LoadBlob( &offset, inputSize0, hashblob, inputData0);
	// hash inputSize1
	Trspi_LoadBlob_UINT32(&offset, inputSize1, hashblob);
	LogDebug("Trspi_LoadBlob_UINT32(&offset, inputSize1:%d", inputSize1);
	// hash inputData1
	Trspi_LoadBlob( &offset, inputSize1, hashblob, inputData1);
	Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest);

	if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_DAA_Join,
	     hPolicy, &digest,
	     ownerAuth)) != TSS_SUCCESS) return result;
	LogDebug("secret_PerformAuth_OIAP(hTPM, TPM_ORD_DAA_Join ret=%d", result);
	LogDebug("TCSP_DAAJoin(%x,%x,stage=%x,%x,%x,%x,%x,%x)\n",
		tcsContext,
		hTPM,
		stage,
		inputSize0,
		(int)inputData0,
		inputSize1,
		(int)inputData1,
		(int)&ownerAuth);
	/* step of the following call:
	TCSP_DAAJoin 		tcsd_api/calltcsapi.c (define in spi_utils.h)
	TCSP_DAAJoin_TP 	tcsd_api/tcstp.c (define in	trctp.h)
	*/
	result =  TCSP_DaaJoin( tcsContext,
				join_session,
				stage,
				inputSize0, inputData0,
				inputSize1, inputData1,
				ownerAuth,
				outputSize, outputData);
	if( result != TSS_SUCCESS) return result;

	offset = 0;
	Trspi_LoadBlob_UINT32(&offset, result, hashblob);
	Trspi_LoadBlob_UINT32(&offset, TPM_ORD_DAA_Join, hashblob);
	Trspi_LoadBlob_UINT32(&offset, *outputSize, hashblob);
	Trspi_LoadBlob(&offset, *outputSize, hashblob, *outputData);
	LogDebug("TCSP_DAAJoin stage=%d outputSize=%d outputData=%x RESULT=%d",
		(int)stage, (int)*outputSize, (int)outputData, (int)result);
	Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest);
	if( (result = obj_policy_validate_auth_oiap( hPolicy, &digest, ownerAuth))) {
		LogError("obj_policy_validate_auth=%d", result);
	}
	return result;
}

TSS_RESULT Tcsip_TPM_DAA_Sign( TCS_CONTEXT_HANDLE hContext,	// in
				TPM_HANDLE handle,	// in
				BYTE stage,	// in
				UINT32 inputSize0,	// in
				BYTE* inputData0,	// in
				UINT32 inputSize1,	// in
				BYTE* inputData1,	// in
				TPM_AUTH* ownerAuth,	// in, out
				UINT32* outputSize,	// out
				BYTE** outputData	// out
) {
	TSS_RESULT result;
	TSS_HPOLICY hPolicy;
	TCPA_DIGEST digest;
	UINT16 offset = 0;
	BYTE hashblob[1000];
	TPM_HANDLE hTPM;
	TPM_HANDLE session_handle;
	TSS_HDAA hDAA = (TSS_HDAA)handle;
	// TPM_HANDLE hTPM;

	if( (result = obj_daa_get_handle_tpm( hDAA, &hTPM)) != TSS_SUCCESS)
		return result;
	if( (result = obj_daa_get_session_handle( hDAA, &session_handle)) != TSS_SUCCESS)
		return result;
	LogDebug("Tcsip_TPM_DAA_Sign(tcsContext=%x,hDAA=%x,sign_session=%x, hTPM=%x stage=%d)",
		hContext,
		hDAA,
		session_handle,
		hTPM,
		stage);

	LogDebug("obj_tpm_get_policy(hTPM=%X)", hTPM);
	if( (result = obj_tpm_get_policy( hTPM, &hPolicy)) != TSS_SUCCESS)
		return result;
	LogDebug("Trspi_LoadBlob_UINT32(&offset, TPM_ORD_DAA_Sign, hashblob)");
	// hash TPM_COMMAND_CODE
	Trspi_LoadBlob_UINT32(&offset, TPM_ORD_DAA_Sign, hashblob);
	LogDebug("Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest)");
	// hash stage
	Trspi_LoadBlob_BYTE(&offset, stage, hashblob);
	LogDebug("Trspi_LoadBlob_UINT32(&offset, 0, hashblob)");
	// hash inputSize0
	Trspi_LoadBlob_UINT32(&offset, inputSize0, hashblob);
	LogDebug("Trspi_LoadBlob_UINT32(&offset, inputSize0:%d", inputSize0);
	// hash inputData0
	Trspi_LoadBlob( &offset, inputSize0, hashblob, inputData0);
	// hash inputSize1
	Trspi_LoadBlob_UINT32(&offset, inputSize1, hashblob);
	LogDebug("Trspi_LoadBlob_UINT32(&offset, inputSize1:%d", inputSize1);
	// hash inputData1
	Trspi_LoadBlob( &offset, inputSize1, hashblob, inputData1);
	Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest);

	if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_DAA_Join,
	     hPolicy, &digest,
	     ownerAuth)) != TSS_SUCCESS) return result;
	LogDebug("secret_PerformAuth_OIAP(hTPM, TPM_ORD_DAA_Join ret=%d", result);
	LogDebug("TCSP_DAASign(%x,%x,stage=%x,%x,%x,%x,%x,%x)",
		hContext,
		hTPM,
		stage,
		inputSize0,(int)inputData0,
		inputSize1,(int)inputData1,
		(int)&ownerAuth);
	/* step of the following call:
	TCSP_DAASign 		tcsd_api/calltcsapi.c (define in spi_utils.h)
	TCSP_DAASign_TP 	tcsd_api/tcstp.c (define in	trctp.h)
	*/
	result =  TCSP_DaaSign( hContext,
				session_handle,
				stage,
				inputSize0, inputData0,
				inputSize1, inputData1,
				ownerAuth,
				outputSize, outputData);
	if( result != TSS_SUCCESS) return result;

	offset = 0;
	Trspi_LoadBlob_UINT32(&offset, result, hashblob);
	Trspi_LoadBlob_UINT32(&offset, TPM_ORD_DAA_Sign, hashblob);
	Trspi_LoadBlob_UINT32(&offset, *outputSize, hashblob);
	Trspi_LoadBlob(&offset, *outputSize, hashblob, *outputData);
	LogDebug("TCSP_DAASign stage=%d outputSize=%d outputData=%x RESULT=%d",
		(int)stage, (int)*outputSize, (int)outputData, (int)result);
	Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest);
	if( (result = obj_policy_validate_auth_oiap( hPolicy, &digest, ownerAuth)))
	{
		LogError("obj_policy_validate_auth=%d", result);
	}
	return result;
}

/**
	Only used for the logging
*/
static TSS_RESULT
Tcsip_TPM_DAA_Join_encapsulate(TCS_CONTEXT_HANDLE tcsContext, // in
				TSS_HDAA	hDAA,				// in
				BYTE stage, // in
				UINT32 inputSize0, // in
				BYTE* inputData0, // in
				UINT32 inputSize1, // in
				BYTE* inputData1, // in
				TPM_AUTH* ownerAuth, // in/out
				UINT32* outputSize, // out
				BYTE** outputData // out
) {
	TSS_RESULT result;

	LogDebug("Tcsip_DAA_Join(TCS_CONTEXT=%X,TSS_HDAA=%X,stage=%d,\
				inputSize0=%u,inputData0=%s\ninputSize1=%u,inputData1=%s,ownerAuth=%X)",
		tcsContext, hDAA, stage,
		inputSize0, dump_byte_array(inputSize0, inputData0),
		inputSize1,dump_byte_array(inputSize1, inputData1),
		(int)ownerAuth);
	result = Tcsip_TPM_DAA_Join(
		tcsContext, // in
		hDAA,	// in
		stage, // in
		inputSize0, // in
		inputData0, // in
		inputSize1, // in
		inputData1, // in
		ownerAuth, // in/out
		outputSize, // out
		outputData // out
	);
	LogDebug("Tcsip_DAA_Join(stage=%d,outputSize=%u outputData=%s ownerAuth=%X) result=%d",
		 (int)stage, *outputSize, dump_byte_array( *outputSize, *outputData), (int)ownerAuth, result);
	return result;
}

#if 0
/* from TSS.java */
/* openssl RSA (struct rsa_st) could manage RSA Key */
TSS_RESULT
Tspi_TPM_DAA_JoinInit_internal(	TSS_HDAA hDAA,
				TSS_HTPM hTPM,
				int daa_counter,
				TSS_DAA_PK *issuer_pk,
				int issuer_authentication_PKLengh,
				RSA **issuer_authentication_PK,
				int issuer_authentication_PK_signaturesLength,
				BYTE **issuer_authentication_PK_signatures,
				int *capital_UprimeLength,
				BYTE **capital_Uprime,
				TSS_DAA_IDENTITY_PROOF *identity_proof,
				TSS_DAA_JOIN_SESSION *join_session)
{
	// Optional: verification of the PKDAA and issuer settings (authen. by the RSA Public Key chain)
	TSS_RESULT result;
	TCS_CONTEXT_HANDLE tcsContext;
	TPM_AUTH ownerAuth;
	int i, modulus_length, outputSize, length, length1;
	UINT32 return_join_session;
	BYTE *outputData, *issuer_settings_bytes;
	BYTE *buffer_modulus;
	TPM_DAA_ISSUER *issuer_settings;
	char buffer[1000], buffer1[1000];
	TSS_DAA_PK_internal *pk_internal = e_2_i_TSS_DAA_PK( issuer_pk);
	bi_ptr issuer_authentication_PK_i = NULL;

	if( (result = obj_tpm_is_connected(  hTPM, &tcsContext)) != TSS_SUCCESS)
		return result;
	obj_daa_set_handle_tpm( hDAA, hTPM);

	// stages 0-2 explained in the diagram "Keys of DAA Issuer"
	// issuer_authentication_PKLengh should be converted to Network Based integer
	i = htonl(issuer_authentication_PKLengh);
	result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
			0,
			sizeof(int), (BYTE *)(&i),
			0, NULL,
			&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) { goto close;}
	// set the sessionHandle to the returned value
	return_join_session = ntohl( *((UINT32 *)outputData));
	free( outputData);
	obj_daa_set_session_handle( hDAA, return_join_session);

	LogDebug("done join 0 settings join_session:%x\n", return_join_session);
	modulus_length = DAA_PARAM_SIZE_RSA_MODULUS / 8;
	buffer_modulus = malloc(modulus_length);
	if (buffer_modulus == NULL) {
		LogError("malloc of %d bytes failed", modulus_length);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	issuer_authentication_PK_i = bi_new_ptr();
	for(i =0; i< issuer_authentication_PKLengh; i++) {
		bi_set_as_BIGNUM( issuer_authentication_PK_i, issuer_authentication_PK[i]->n);
		bi_2_byte_array( buffer_modulus,
				modulus_length,
				issuer_authentication_PK_i);
		if ( i==0) {
			result = Tcsip_TPM_DAA_Join_encapsulate(
				tcsContext, hDAA,
				1,
				modulus_length, buffer_modulus,
				0, NULL,
				&ownerAuth, &outputSize, &outputData);
			if( result != TSS_SUCCESS) {
				free( buffer_modulus);
				goto close;
			}
		} else {
			result = Tcsip_TPM_DAA_Join_encapsulate(
				tcsContext,  hDAA,
				1,
				modulus_length, buffer_modulus,
				DAA_PARAM_KEY_SIZE / 8, issuer_authentication_PK_signatures[i -1],
				&ownerAuth, &outputSize, &outputData);
			if( result != TSS_SUCCESS) {
				free( buffer_modulus);
				goto close;
			}
		}
	}
	free( buffer_modulus);
	LogDebug("done join 1-%d\n", issuer_authentication_PKLengh);
	// define issuer_settings
	issuer_settings = convert2issuer_settings( pk_internal);
	issuer_settings_bytes = issuer_2_byte_array( issuer_settings, &length);
	result = Tcsip_TPM_DAA_Join_encapsulate(
		tcsContext, hDAA,
		2,
		length, issuer_settings_bytes,
		modulus_length,
		issuer_authentication_PK_signatures[issuer_authentication_PKLengh-1],
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) { goto close;}
	LogDebug("done join 2\n");
	i = htonl( daa_counter);
	result = Tcsip_TPM_DAA_Join_encapsulate(
		tcsContext, hDAA,
		3,
		sizeof(UINT32), (BYTE *)(&i),
		0, NULL,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) { goto close;}
	LogDebug("done join 3\n");
	// reserved another buffer for storing Big Integer
	bi_2_nbin1( &length, buffer, pk_internal->capitalR0);
	bi_2_nbin1( &length1, buffer1, pk_internal->modulus);
	result = Tcsip_TPM_DAA_Join_encapsulate(
		tcsContext, hDAA,
		4,
		length, buffer,
		length1, buffer1,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) { goto close;}
	LogDebug("done join 4\n");
	bi_2_nbin1( &length, buffer, pk_internal->capitalR1);
	result = Tcsip_TPM_DAA_Join_encapsulate(
		tcsContext, hDAA,
		5,
		length, buffer,
		length1, buffer1,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) { goto close;}
	LogDebug("done join 5\n");
	bi_2_nbin1( &length, buffer, pk_internal->capitalS);
	result = Tcsip_TPM_DAA_Join_encapsulate(
		tcsContext, hDAA,
		6,
		length, buffer,
		length1, buffer1,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) { goto close;}
	LogDebug("done join 6\n");
	bi_2_nbin1( &length, buffer, pk_internal->capitalSprime);
	// define Uprime
	result = Tcsip_TPM_DAA_Join_encapsulate(
		tcsContext, hDAA,
		7,
		length, buffer,
		length1, buffer1,
		&ownerAuth, &outputSize, &outputData);
	// 5 : save PKDAA, U, daaCount and sessionHandle in joinSession
	join_session->issuerPk = (TSS_HKEY)issuer_pk;
	if( result == TSS_SUCCESS) {
		*capital_UprimeLength = outputSize;
		*capital_Uprime = convert_alloc( tcsContext, outputSize, outputData);
		if (*capital_Uprime == NULL) {
			LogError("malloc of %d bytes failed", outputSize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto close;
		}
		join_session->capitalUPrime = copy_alloc( tcsContext,
							*capital_UprimeLength,
							*capital_Uprime);
		if (join_session->capitalUPrime == NULL) {
			LogError("malloc of %d bytes failed", *capital_UprimeLength);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto close;
		}
		join_session->capitalUPrimeLength = *capital_UprimeLength;
	}
	join_session->sessionHandle = return_join_session;
	// get the endorsement Key (public part)
	result = get_public_EK(
		hTPM,	// in
		&( identity_proof->endorsementLength),
		&( identity_proof->endorsementCredential)
	);

close:
	FREE_BI( issuer_authentication_PK_i);
	LogDebug("result = %d", result);
	LogDebug("outputSize=%d", outputSize);
	LogDebug("outputData=%s", dump_byte_array( outputSize, outputData));
  	return result;
}
#else
TSS_RESULT
Tspi_TPM_DAA_JoinInit_internal(TSS_HTPM			hTPM,
			       TSS_HDAA_ISSUER_KEY	hIssuerKey
			       UINT32			daa_counter,
			       UINT32			issuerAuthPKsLength,
			       TSS_HKEY*		issuerAuthPKs,
			       UINT32			issuerAuthPKSignaturesLength,
			       UINT32			issuerAuthPKSignaturesLength2,
			       BYTE**			issuerAuthPKSignatures,
			       UINT32*			capitalUprimeLength,
			       BYTE**			capitalUprime,
			       TSS_DAA_IDENTITY_PROOF** identity_proof,
			       UINT32*			joinSessionLength,
			       BYTE**			joinSession)
{
	// Optional: verification of the PKDAA and issuer settings (authen. by the RSA Public Key chain)
	TSS_RESULT result;
	TSS_HCONTEXT tspContext;
	TPM_AUTH ownerAuth;
	int length, length1;
	UINT32 i, modulus_length, outputSize, buf_len;
	BYTE *outputData, *issuer_settings_bytes;
	BYTE *modulus, stage, *buf;
	//TPM_DAA_ISSUER *issuer_settings;
	//char buffer[1000], buffer1[1000];
	//TSS_DAA_PK_internal *pk_internal = e_2_i_TSS_DAA_PK(issuer_pk);
	bi_ptr issuerAuthPK = NULL;
	TPM_HANDLE daaHandle;
	Trspi_HashCtx hashCtx;
	TPM_DIGEST digest;
	TSS_DAA_IDENTITY_PROOF daaIdentityProof;

	if ((result = obj_tpm_is_connected(hTPM, &tspContext)))
		return result;

	if ((result = obj_daaissuerkey_get_daa_handle(hIssuerKey, &daaHandle)))
		return result;

	stage = 0;
	inputSize0 = (UINT32)sizeof(UINT32);
	inputData0 = issuerAuthPKsLength;
	inputSize1 = 0;
	inputData1 = NULL;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_DAA_Join);
	result |= Trspi_Hash_BYTE(&hashCtx, stage);
	result |= Trspi_Hash_UINT32(&hashCtx, inputSize0);
	result |= Trspi_HashUpdate(&hashCtx, inputSize0, inputData0);
	result |= Trspi_Hash_UINT32(&hashCtx, inputSize1);
	result |= Trspi_HashUpdate(&hashCtx, inputSize1, inputData1);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
		return result;

	// stages 0-2 explained in the diagram "Keys of DAA Issuer"
	if ((result = TCS_API(tspContext)->DaaJoin(tspContext, daaHandle, stage, inputSize1,
						   inputData0, inputSize1, inputData1, &ownerAuth,
						   &outputSize, &outputData)))
		goto close;

	if (outputSize != sizeof(UINT32)) {
		result = TSPERR(TSS_E_INTERNAL_ERROR);
		goto close;
	}

	// set the sessionHandle to the returned value
	Trspi_UnloadBlob_UINT32(&offset, &daaHandle, outputData);
	free(outputData);
	if ((result = obj_daaissuerkey_set_daa_handle(hIssuerKey, daaHandle)))
		goto close;

	LogDebug("done join 0 settings join_session:%x", daaHandle);

	modulus_length = DAA_PARAM_SIZE_RSA_MODULUS / 8;
	if ((buffer_modulus = malloc(modulus_length)) == NULL) {
		LogError("malloc of %d bytes failed", modulus_length);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}

	stage = 1;
	for (i = 0; i < issuerAuthPKsLength; i++) {
		if ((result = obj_rsakey_get_modulus(issuerAuthPKs[i], &modulus_length, &modulus)))
			goto close;

		outputData = NULL;
		if (i==0) {
			result = Tcsip_TPM_DAA_Join_encapsulate(tspContext, daaHandle, stage,
								modulus_length, modulus, 0, NULL,
								&ownerAuth, &outputSize,
								&outputData);
		} else {
			result = Tcsip_TPM_DAA_Join_encapsulate(tspContext, daaHandle, stage,
								modulus_length, modulus,
								issuerAuthPKSignaturesLength2,
								issuerAuthPKSignatures[i - 1],
								&ownerAuth, &outputSize,
								&outputData);
		}

		free(outputData);
		free_tspi(tspContext, modulus);
		if (result != TSS_SUCCESS) {
			LogDebugFn("Stage 1 iteration %u failed", i);
			goto close;
		}
	}

	LogDebug("done join 1-%d\n", issuer_authentication_PKLengh);

	stage = 2;
	// define issuer_settings
#if 0
	issuer_settings = convert2issuer_settings(pk_internal);
	issuer_settings_bytes = issuer_2_byte_array(issuer_settings, &length);
#else
	if ((result = obj_daaissuerkey_get_daa_issuer(hIssuerKey, &issuer_length, &issuer)))
		goto close;

	if ((result = obj_daaissuerkey_get_modulus(hIssuerKey, &modulus_length, &modulus))) {
		free_tspi(tspContext, issuer);
		goto close;
	}
#endif
	if ((result = Tcsip_TPM_DAA_Join_encapsulate(tspContext, daaHandle, stage, issuer_length,
						     issuer, issuerAuthPKSignaturesLength2,
						     issuerAuthPKSignatures[i - 1], &ownerAuth,
						     &outputSize, &outputData))) {
		free_tspi(tspContext, issuer);
		free_tspi(tspContext, modulus);
		goto close;
	}
	free_tspi(tspContext, issuer);

	LogDebug("done join 2\n");

	stage = 3;
	if ((result = Tcsip_TPM_DAA_Join_encapsulate(tspContext, daaHandle, stage, sizeof(UINT32),
						     (BYTE *)(&daa_counter), 0, NULL, &ownerAuth,
						     &outputSize, &outputData)))
		goto close;

	LogDebug("done join 3\n");

	stage = 4;
#if 0
	// reserved another buffer for storing Big Integer
	bi_2_nbin1( &length, buffer, pk_internal->capitalR0);
	bi_2_nbin1( &length1, buffer1, pk_internal->modulus);
#else
	if ((result = obj_daaissuerkey_get_capitalR0(hIssuerKey, &buf_len, &buf)))
		return result;
#endif
	if ((result = Tcsip_TPM_DAA_Join_encapsulate(tspContext, daaHandle, stage, buf_len, buf,
						     modulus_length, modulus, &ownerAuth,
						     &outputSize, &outputData))) {
		free_tspi(tspContext, buf);
		free_tspi(tspContext, modulus);
		goto close;
	}
	free_tspi(tspContext, buf);

	LogDebug("done join 4\n");

	stage = 5;
#if 0
	bi_2_nbin1( &length, buffer, pk_internal->capitalR1);
#else
	if ((result = obj_daaissuerkey_get_capitalR1(hIssuerKey, &buf_len, &buf)))
		return result;
#endif
	if ((result = Tcsip_TPM_DAA_Join_encapsulate(tspContext, daaHandle, stage, buf_len,
						     buf, modulus_length, modulus, &ownerAuth,
						     &outputSize, &outputData))) {
		free_tspi(tspContext, buf);
		free_tspi(tspContext, modulus);
		goto close;
	}
	free_tspi(tspContext, buf);

	LogDebug("done join 5\n");

	stage = 6;
#if 0
	bi_2_nbin1( &length, buffer, pk_internal->capitalS);
#else
	if ((result = obj_daaissuerkey_get_capitalS(hIssuerKey, &buf_len, &buf)))
		return result;
#endif
	if ((result = Tcsip_TPM_DAA_Join_encapsulate(tspContext, daaHandle, stage, buf_len, buf,
						     modulus_length, modulus, &ownerAuth,
						     &outputSize, &outputData))) {
		free_tspi(tspContext, buf);
		free_tspi(tspContext, modulus);
		goto close;
	}
	free_tspi(tspContext, buf);

	LogDebug("done join 6\n");

	stage = 7;
#if 0
	bi_2_nbin1( &length, buffer, pk_internal->capitalSprime);
#else
	if ((result = obj_daaissuerkey_get_capitalSprime(hIssuerKey, &buf_len, &buf)))
		return result;
#endif
	// define Uprime
	if ((result = Tcsip_TPM_DAA_Join_encapsulate(tspContext, daaHandle, stage, buf_len, buf,
						     modulus_length, modulus, &ownerAuth,
						     &outputSize, &outputData))) {
		free_tspi(tspContext, buf);
		free_tspi(tspContext, modulus);
		goto close;
	}
	free_tspi(tspContext, buf);

#if 0
	// 5 : save PKDAA, U, daaCount and sessionHandle in joinSession
	join_session->issuerPk = (TSS_HKEY)issuer_pk;
	if( result == TSS_SUCCESS) {
		*capital_UprimeLength = outputSize;
		*capital_Uprime = convert_alloc( tspContext, outputSize, outputData);
		if (*capital_Uprime == NULL) {
			LogError("malloc of %d bytes failed", outputSize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto close;
		}
		join_session->capitalUPrime = copy_alloc( tspContext,
							*capital_UprimeLength,
							*capital_Uprime);
		if (join_session->capitalUPrime == NULL) {
			LogError("malloc of %d bytes failed", *capital_UprimeLength);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto close;
		}
		join_session->capitalUPrimeLength = *capital_UprimeLength;
	}
	join_session->sessionHandle = return_join_session;
	// get the endorsement Key (public part)
	result = get_public_EK(
		hTPM,	// in
		&( identity_proof->endorsementLength),
		&( identity_proof->endorsementCredential)
	);
#else
	/* fill out the identity proof struct */
	if ((result = TCS_API(obj->tspContext)->GetTPMCapability(obj->tspContext, TPM_CAP_VERSION,
								 0, NULL, &buf_len, &buf)))
		goto close;

	offset = 0;
	Trspi_UnloadBlob_VERSION(&offset, buf, &daaIdentityProof.versionInfo);
	free_tspi(tspContext, buf);

#error set all 3 credentials in the daaIdentityProof struct here

	/* set the U data */
	if ((result = __tspi_add_mem_entry(tspContext, outputData)))
		goto close;
	*capitalUPrime = outputData;
	*capitalUPrimeLength = outputSize;

	/* return the TSS specific stuff */
#endif

close:
	FREE_BI( issuer_authentication_PK_i);
	LogDebug("result = %d", result);
	LogDebug("outputSize=%d", outputSize);
	LogDebug("outputData=%s", dump_byte_array( outputSize, outputData));
  	return result;
}
#endif


/* allocation:
	endorsementKey as BYTE *
*/
TSS_RESULT
get_public_EK(TSS_HTPM hTPM,
		UINT32 *endorsementKeyLength,
		BYTE **endorsementKey

) {
	TSS_RESULT result;
	TSS_HKEY hEk;
	TSS_HPOLICY hTpmPolicy;
	UINT32 uiAttrSize;
	BYTE *pAttr;

	if( (result = obj_tpm_get_policy( hTPM, &hTpmPolicy)) != TSS_SUCCESS) {
		LogError("can not retrieve policy from the TPM handler");
		goto out_close;
	}

	if( (result = Tspi_TPM_GetPubEndorsementKey(hTPM, TRUE, NULL, &hEk)) != TSS_SUCCESS) {
		LogError("can not retrieve the Public endorsed Key");
		goto out_close;
	}

	result = Tspi_GetAttribData(
		hEk,
		TSS_TSPATTRIB_KEY_INFO,
		TSS_TSPATTRIB_KEYINFO_VERSION,
		&uiAttrSize,
		&pAttr);

	if (result != TSS_SUCCESS) goto out_close;
	LogDebug("keyinfo:%s", dump_byte_array( uiAttrSize, pAttr));

	result = Tspi_GetAttribData(
		hEk,
		TSS_TSPATTRIB_KEY_BLOB,
		TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY,
		endorsementKeyLength,
		endorsementKey);

	LogDebug("Public Endorsement Key:%s",
		dump_byte_array( *endorsementKeyLength, *endorsementKey));
out_close:
      return result;
}

// from TSS.java (479)
TSS_RESULT
compute_join_challenge_host(TSS_HDAA hDAA,
						TSS_DAA_PK_internal *pk_internal,
						bi_ptr capitalU,
						bi_ptr capital_Uprime,
						bi_ptr capital_utilde,
						bi_ptr capital_utilde_prime,
						bi_ptr capital_ni,
						bi_ptr capital_ni_tilde,
						UINT32 commitments_proofLength,
						TSS_DAA_ATTRIB_COMMIT_internal *
						commitments_proof,
						UINT32 nonceIssuerLength,
						BYTE* nonceIssuer,
						UINT32 *resultLength,
						BYTE **result) {
	EVP_MD_CTX mdctx;
	BYTE *encoded_pk = NULL, *buffer;
	UINT32 encoded_pkLength;
	int rv, length;

	buffer = (BYTE *)malloc( 10000); // to be sure, and it will be free quickly
	if (buffer == NULL) {
		LogError("malloc of %d bytes failed", 10000);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}
	// EVP_MD_CTX_init(&mdctx);
	rv = EVP_DigestInit(&mdctx, DAA_PARAM_get_message_digest());
	if (rv != EVP_SUCCESS) goto err;
	// allocation
	encoded_pk = encoded_DAA_PK_internal( &encoded_pkLength, pk_internal);
	LogDebug("encoded issuerPk[%d]: %s",
		encoded_pkLength,
		dump_byte_array( encoded_pkLength, encoded_pk));
	rv = EVP_DigestUpdate(&mdctx,  encoded_pk, encoded_pkLength);
	if (rv != EVP_SUCCESS) goto err;
	// capitalU
	length = DAA_PARAM_SIZE_RSA_MODULUS / 8;
	bi_2_byte_array( buffer, length, capitalU);
	LogDebug("capitalU[%ld]: %s",
		bi_nbin_size(capitalU) ,
		dump_byte_array( length, buffer));
	rv = EVP_DigestUpdate(&mdctx,  buffer, length);
	if (rv != EVP_SUCCESS) goto err;
	// capital UPrime
	bi_2_byte_array( buffer, length, capital_Uprime);
	LogDebug("capitalUPrime[%d]: %s",
		length,
		dump_byte_array( length, buffer));
	rv = EVP_DigestUpdate(&mdctx,  buffer, length);
	if (rv != EVP_SUCCESS) goto err;
	// capital Utilde
	bi_2_byte_array( buffer, length, capital_utilde);
	LogDebug("capitalUTilde[%d]: %s",
		length,
		dump_byte_array( length, buffer));
	rv = EVP_DigestUpdate(&mdctx,  buffer, length);
	if (rv != EVP_SUCCESS) goto err;
	// capital UtildePrime
	bi_2_byte_array( buffer, length, capital_utilde_prime);
	LogDebug("capital_utilde_prime[%d]: %s",
		length,
		dump_byte_array( length, buffer));
	rv = EVP_DigestUpdate(&mdctx,  buffer, length);
	if (rv != EVP_SUCCESS) goto err;
	//capital_ni
	length = DAA_PARAM_SIZE_MODULUS_GAMMA / 8;
	bi_2_byte_array( buffer, length, capital_ni);
	LogDebug("capital_ni[%d]: %s",
		length,
		dump_byte_array( length, buffer));
	rv = EVP_DigestUpdate(&mdctx,  buffer, length);
	if (rv != EVP_SUCCESS) goto err;
	//capital_ni_tilde
	bi_2_byte_array( buffer, length, capital_ni_tilde);
	LogDebug("capital_ni_tilde[%d]: %s",
		length,
		dump_byte_array( length, buffer));
	rv = EVP_DigestUpdate(&mdctx,  buffer, length);
	if (rv != EVP_SUCCESS) goto err;
	// TODO: commitments
	LogDebug("nonceIssuer[%d]: %s",
		nonceIssuerLength,
		dump_byte_array( nonceIssuerLength, nonceIssuer));
	rv = EVP_DigestUpdate(&mdctx,  nonceIssuer, nonceIssuerLength);
	if (rv != EVP_SUCCESS) goto err;
	*resultLength = EVP_MD_CTX_size(&mdctx);
	*result = (BYTE *)malloc( *resultLength);
	if (*result == NULL) {
		LogError("malloc of %d bytes failed", *resultLength);
		free( buffer);
		free( encoded_pk);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}
	rv = EVP_DigestFinal(&mdctx, *result, NULL);
	if (rv != EVP_SUCCESS) goto err;
	free( buffer);
	free( encoded_pk);
	return TSS_SUCCESS;
err:
	free( buffer);
	free( encoded_pk);
	DEBUG_print_openssl_errors();
	return TSPERR(TSS_E_INTERNAL_ERROR);
}

/*
This is the second out of 3 functions to execute in order to receive a DAA Credential. It
computes the credential request for the DAA Issuer, which also includes the Platforms & DAA
public key and the attributes that were chosen by the Platform, and which are not visible to \
the DAA Issuer. The Platform can commit to the attribute values it has chosen.
Code influenced by TSS.java (TssDaaCredentialRequest)
*/
TSPICALL
Tspi_TPM_DAA_JoinCreateDaaPubKey_internal(
	TSS_HDAA hDAA,	// in
	TSS_HTPM hTPM,	// in
	UINT32 authenticationChallengeLength,	// in
	BYTE* authenticationChallenge,	// in
	UINT32 nonceIssuerLength,	// in
	BYTE* nonceIssuer,	// in
	UINT32 attributesPlatformLength,	// in
	BYTE** attributesPlatform,	// in
	TSS_DAA_JOIN_SESSION* joinSession,	// in, out
	TSS_DAA_CREDENTIAL_REQUEST* credentialRequest	// out
) {
	TSS_RESULT result;
	TCS_CONTEXT_HANDLE tcsContext;
	TPM_AUTH ownerAuth;
	bi_ptr tmp1 = bi_new_ptr();
	bi_ptr tmp2 = bi_new_ptr();
	bi_ptr capital_utilde = bi_new_ptr();
	bi_ptr v_tilde_prime = bi_new_ptr();
	bi_ptr rv_tilde_prime = bi_new_ptr();
	bi_ptr capitalU = bi_new_ptr();
	bi_ptr product_attributes = bi_new_ptr();
	bi_ptr capital_ni = NULL;
	bi_ptr capital_utilde_prime = NULL;
	bi_ptr capital_ni_tilde = NULL;
	bi_ptr n = NULL;
	bi_ptr attributePlatform = NULL;
	bi_ptr c = NULL;
	bi_ptr zeta = NULL;
	bi_ptr capital_Uprime = NULL;
	bi_ptr sv_tilde_prime = NULL;
	bi_ptr s_f0 = NULL;
	bi_ptr s_f1 = NULL;
	bi_ptr sv_prime = NULL;
	bi_ptr sv_prime1 = NULL;
	bi_ptr sv_prime2 = NULL;
	bi_array_ptr ra = NULL;
	bi_array_ptr sa = NULL;
	TSS_DAA_PK* pk_extern = (TSS_DAA_PK *)joinSession->issuerPk;
	TSS_DAA_PK_internal* pk_internal = e_2_i_TSS_DAA_PK( pk_extern);
	UINT32 i, outputSize, authentication_proofLength, nonce_tpmLength;
	UINT32 capitalSprime_byte_arrayLength, size_bits, length, chLength, c_byteLength;
	UINT32 internal_cbyteLength, noncePlatformLength;
	BYTE *outputData, *authentication_proof, *capitalSprime_byte_array = NULL, *buffer;
	BYTE *ch = NULL;
	BYTE *c_byte, *noncePlatform, *nonce_tpm;
	BYTE *internal_cbyte = NULL;
	EVP_MD_CTX mdctx;

	if( tmp1 == NULL || tmp2 == NULL || capital_utilde == NULL ||
		v_tilde_prime == NULL || rv_tilde_prime == NULL ||
		capitalU == NULL || product_attributes == NULL) {
		LogError("malloc of bi(s) failed");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	if( pk_internal == NULL) {
		LogError("malloc of pk_internal failed");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	if( (result = obj_tpm_is_connected(  hTPM, &tcsContext)) != TSS_SUCCESS) {
		 goto close;
	}
	obj_daa_set_handle_tpm( hDAA, hTPM);
	// allocation
	n = bi_set_as_nbin( pk_extern->modulusLength, pk_extern->modulus);
	if( n == NULL) {
		LogError("malloc of %d bytes failed", pk_extern->modulusLength);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	// allocation
	capitalSprime_byte_array = bi_2_nbin( &capitalSprime_byte_arrayLength,
								pk_internal->capitalSprime);
	if( capitalSprime_byte_array == NULL) {
		LogError("malloc of %d bytes failed", capitalSprime_byte_arrayLength);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	// compute second part of the credential request
	// encode plateform attributes (the one visible only by the receiver)
	bi_set( product_attributes, bi_1);
	for( i=0; i<attributesPlatformLength; i++) {
		attributePlatform = bi_set_as_nbin( DAA_PARAM_SIZE_F_I / 8,
									attributesPlatform[i]); // allocation
		if( attributePlatform == NULL) {
			LogError("malloc of bi <%s> failed", "attributePlatform");
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto close;
		}
		// bi_tmp1 = ( capitalRReceiver[i] ^ attributesPlatform ) % n
		bi_mod_exp( tmp1, pk_internal->capitalRReceiver->array[i], attributePlatform, n);
		// bi_tmp1 = bi_tmp1 * product_attributes
		bi_mul( tmp1, tmp1, product_attributes);
		// product_attributes = bi_tmp1 % n
		bi_mod( product_attributes, tmp1, n);
		bi_free_ptr( attributePlatform);
	}
	bi_urandom( v_tilde_prime, DAA_PARAM_SIZE_RSA_MODULUS +
							DAA_PARAM_SAFETY_MARGIN);
	// tmp1 = capitalUPrime * capitalS
	bi_free_ptr( tmp1);
	tmp1 = bi_set_as_nbin( joinSession->capitalUPrimeLength,
						joinSession->capitalUPrime); // allocation
	if( tmp1 == NULL) {
		LogError("malloc of %d bytes failed", joinSession->capitalUPrimeLength);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	// U = ( U' * ( ( pk->S ^ v~' ) % n) ) % n
	// tmp2 = ( pk->S ^ v~') % n
	bi_mod_exp( tmp2, pk_internal->capitalS, v_tilde_prime, n);
	// U = tmp1( U') * tmp2
	bi_mul( capitalU, tmp1, tmp2);
	bi_mod( capitalU, capitalU, n);
	// U = ( U * product_attributes ) % n
	bi_mul( capitalU, capitalU, product_attributes);
	bi_mod( capitalU, capitalU, n);
	// 2  : call the TPM to compute authentication proof with U'
	result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
		8,
		authenticationChallengeLength, authenticationChallenge,
		0, NULL,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) goto close;
	LogDebug("Done Join 8");
	authentication_proof = calloc_tspi( tcsContext, outputSize);
	if( authentication_proof == NULL) {
		LogError("malloc of %d bytes failed", outputSize);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	memcpy( authentication_proof, outputData, outputSize);
	free( outputData);
	authentication_proofLength = outputSize;

	// 3 : call the TPM to compute U' (first part of correctness proof of the credential
	// request
	result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
		9,
		pk_extern->capitalR0Length, pk_extern->capitalR0,
		pk_extern->modulusLength, pk_extern->modulus,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) goto close;
	LogDebug("Done Join 9: capitalR0");
	free( outputData);

	result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
		10,
		pk_extern->capitalR1Length, pk_extern->capitalR1,
		pk_extern->modulusLength, pk_extern->modulus,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) goto close;
	LogDebug("Done Join 10: capitalR1");
	free( outputData);

	result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
		11,
		pk_extern->capitalSLength, pk_extern->capitalS,
		pk_extern->modulusLength, pk_extern->modulus,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) goto close;
	LogDebug("Done Join 11: capitalS");
	free( outputData);

	result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
		12,
		capitalSprime_byte_arrayLength, capitalSprime_byte_array,
		pk_extern->modulusLength, pk_extern->modulus,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) goto close;
	LogDebug("Done Join 12: capitalUTildePrime");
	capital_utilde_prime = bi_set_as_nbin( outputSize, outputData); // allocation
	if( capital_utilde_prime == NULL) {
		LogError("malloc of %d bytes failed", outputSize);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	free( outputData);
	// 4 compute pseudonym with respect to the DAA Issuer
	// allocation
	zeta = compute_zeta( pk_internal->issuerBaseNameLength,
					pk_internal->issuerBaseName,
					pk_internal);
	if( zeta == NULL) {
		LogError("malloc of bi <%s> failed", "zeta");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	buffer = (BYTE *)malloc( TPM_DAA_SIZE_w);
	if( buffer == NULL) {
		LogError("malloc of %d bytes failed", TPM_DAA_SIZE_w);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	LogDebug("zeta[%ld] = %s", bi_nbin_size( zeta), bi_2_hex_char( zeta));
	bi_2_byte_array( buffer, TPM_DAA_SIZE_w, zeta);
	LogDebug("zeta[%d] = %s", TPM_DAA_SIZE_w, dump_byte_array( TPM_DAA_SIZE_w, buffer));

	result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
		13,
		pk_extern->capitalGammaLength, pk_extern->capitalGamma,
		TPM_DAA_SIZE_w, buffer, // zeta
		&ownerAuth, &outputSize, &outputData);
	free( buffer);
	if( result != TSS_SUCCESS) goto close;
	LogDebug("Done Join 13: capitalGamma / zeta");
	free( outputData);

	result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
		14,
		pk_extern->capitalGammaLength, pk_extern->capitalGamma,
		0, NULL,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) goto close;
	LogDebug("Done Join 14: capitalGamma");
	capital_ni = bi_set_as_nbin( outputSize, outputData); // allocation
	if( capital_ni == NULL) {
		LogError("malloc of bi <%s> failed", "capital_ni");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	free( outputData);

	result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
		15,
		pk_extern->capitalGammaLength, pk_extern->capitalGamma,
		0, NULL,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) goto close;
	LogDebug("Done Join 15: capitalGamma");
	capital_ni_tilde = bi_set_as_nbin( outputSize, outputData); // allocation
	if( capital_ni_tilde == NULL) {
		LogError("malloc of bi <%s> failed", "capital_ni_tilde");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	free( outputData);

	// 5 : compute the second part of the correctness proof of the credential request
	// (with attributes not visible to issuer)
	// randomize/blind attributesReceiver
	size_bits = DAA_PARAM_SIZE_RANDOMIZED_ATTRIBUTES;
	bi_set( product_attributes, bi_1);
	ra = (bi_array_ptr)malloc( sizeof( struct _bi_array));
	if( ra == NULL) {
		LogError("malloc of %d bytes failed", sizeof( struct _bi_array));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_new_array( ra, attributesPlatformLength);
	if( ra->array == NULL) {
		LogError("malloc of bi_array <%s> failed", "ra");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	for( i=0; i < attributesPlatformLength; i++) {
		bi_urandom( ra->array[i], size_bits);
		LogDebug("ra[i]=%s size=%d", bi_2_hex_char( ra->array[i]), size_bits);
		// product_attributes=(((capitalYplatform ^ ra[i]) % n)*<product_attributes-1>)%n
		bi_mod_exp( tmp1, pk_internal->capitalRReceiver->array[i], ra->array[i], n);
		bi_mul( tmp1, tmp1, product_attributes);
		bi_mod( product_attributes, tmp1, n);
	}
	size_bits = DAA_PARAM_SIZE_F_I+2*DAA_PARAM_SAFETY_MARGIN+DAA_PARAM_SIZE_MESSAGE_DIGEST;
	bi_urandom( rv_tilde_prime, size_bits);
	// capital_utilde = ( capitalS ^ rv_tilde_prime) % n
	bi_mod_exp( capital_utilde, pk_internal->capitalS, rv_tilde_prime, n);
	// capital_utilde = capital_utilde * product_attributes
	bi_mul( capital_utilde, capital_utilde, product_attributes);
	// capital_utilde = capital_utilde % n
	bi_mod( capital_utilde, capital_utilde, n);
	// 5e
	capital_Uprime = bi_set_as_nbin( joinSession->capitalUPrimeLength,
					joinSession->capitalUPrime); // allocation
	if( capital_Uprime == NULL) {
		LogError("malloc of bi <%s> failed", "capital_Uprime");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	LogDebug("calculation UTilde:                capitalS:%s\n", bi_2_hex_char( pk_internal->capitalS));
	LogDebug("calculation UTilde:       rv_tilde_prime:%s\n", bi_2_hex_char( rv_tilde_prime));
	LogDebug("calculation UTilde:                          n:%s\n", bi_2_hex_char( n));
	LogDebug("calculation UTilde: product_attributes:%s\n", bi_2_hex_char( product_attributes));
	LogDebug("calculation NItilde:                     ntilde:%s\n", bi_2_hex_char( capital_ni_tilde));

	result = compute_join_challenge_host(
		hDAA,
		pk_internal,
		capitalU,
		capital_Uprime,
		capital_utilde,
		capital_utilde_prime,
		capital_ni,
		capital_ni_tilde,
		0,		// TODO commitmentProofLength
		NULL,	// TODO commitment
		nonceIssuerLength,
		nonceIssuer,
		&chLength, // out
		&ch // out allocation
	);
	if( result != TSS_SUCCESS) goto close;

	result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
		16,
		chLength, ch,
		0, NULL,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) goto close;
	nonce_tpm = outputData;
	nonce_tpmLength = outputSize;
	LogDebug("Done Join 16: compute_join_challenge_host return nonce_tpm:%s",
		dump_byte_array(nonce_tpmLength, nonce_tpm));

	result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
		17,
		0, NULL,
		0, NULL,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) goto close;
	s_f0 = bi_set_as_nbin( outputSize, outputData); // allocation
	if( s_f0 == NULL) {
		LogError("malloc of <bi> %s failed", "s_f0");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	LogDebug("Done Join 17: return sF0:%s", dump_byte_array(outputSize, outputData) );
	free( outputData);

	result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
		18,
		0, NULL,
		0, NULL,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) goto close;
	s_f1 = bi_set_as_nbin( outputSize, outputData); // allocation
	if( s_f1 == NULL) {
		LogError("malloc of <bi> %s failed", "s_f1");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	LogDebug("Done Join 18: return sF1:%s", dump_byte_array(outputSize, outputData) );
	free( outputData);

	result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
		19,
		0, NULL,
		0, NULL,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) goto close;
	LogDebug("Done Join 19: return sv_prime1");
	sv_prime1 = bi_set_as_nbin( outputSize, outputData); // allocation
	if( sv_prime1 == NULL) {
		LogError("malloc of <bi> %s failed", "sv_prime1");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	free( outputData);

	result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
		20,
		0, NULL,
		0, NULL,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) goto close;
	LogDebug("Done Join 20: return cByte");
	c_byte = (BYTE *)calloc_tspi( tcsContext, outputSize);
	if( c_byte == NULL) {
		LogError("malloc of %d bytes failed", outputSize);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	memcpy( c_byte, outputData, outputSize);
	free( outputData);
	c_byteLength = outputSize;
	c = bi_set_as_nbin( c_byteLength, c_byte); // allocation
	if( c == NULL) {
		LogError("malloc of <bi> %s failed", "c");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}

	// verify computation of c by TPM
	EVP_DigestInit(&mdctx, DAA_PARAM_get_message_digest());
	EVP_DigestUpdate(&mdctx,  ch, chLength);
	EVP_DigestUpdate(&mdctx,  nonce_tpm, nonce_tpmLength);
	nonce_tpm = convert_alloc( tcsContext, nonce_tpmLength, nonce_tpm); // allocation
	if( nonce_tpm == NULL) {
		LogError("malloc of %d bytes failed", nonce_tpmLength);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	internal_cbyteLength = EVP_MD_CTX_size(&mdctx);
	internal_cbyte = (BYTE *)malloc( internal_cbyteLength);
	if( internal_cbyte == NULL) {
		LogError("malloc of %d bytes failed", internal_cbyteLength);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	EVP_DigestFinal(&mdctx, internal_cbyte, NULL);
	if( c_byteLength != internal_cbyteLength ||
		memcmp( c_byte, internal_cbyte, c_byteLength) != 0) {
		LogError( "Computation of c in TPM DAA Join command is incorrect. Affected stages: 16,20\n");
		LogError( "\t            c_byte[%d] %s",
				c_byteLength,
				dump_byte_array( c_byteLength, c_byte));
		LogError( "\tc_internal_byte[%d] %s",
				internal_cbyteLength,
				dump_byte_array( internal_cbyteLength, internal_cbyte));
		result = TSS_E_INTERNAL_ERROR;
		goto close;
	}

	// 5m) blind attributesReceiver
	sa = (bi_array_ptr)malloc( sizeof( struct _bi_array));
	if( sa == NULL) {
		LogError("malloc of %d bytes failed", sizeof( struct _bi_array));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_new_array( sa, attributesPlatformLength);
	for( i=0; i < attributesPlatformLength; i++) {
		attributePlatform = bi_set_as_nbin( DAA_PARAM_SIZE_F_I / 8,
								attributesPlatform[i]); // allocation
		if( attributePlatform == NULL) {
			LogError("malloc of <bi> %s failed", "attributePlatform");
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto close;
		}
		LogDebug("calculating sa[%d]: raLength=%ld cLength=%ld attributesPlatformLength=%ld\n",
				i, bi_nbin_size( ra->array[i]), bi_nbin_size( c), bi_nbin_size( attributePlatform));
		bi_add( sa->array[i], ra->array[i], bi_mul( tmp1, c, attributePlatform));
		bi_free_ptr( attributePlatform);
	}
	attributePlatform = NULL;
	// 5o) Commitments
	// TODO

	result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
		21,
		0, NULL,
		0, NULL,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) goto close;
	LogDebug("Done Join 21: return sv_prime2");
	sv_prime2 = bi_set_as_nbin( outputSize, outputData); // allocation
	if( sv_prime2 == NULL) {
		LogError("malloc of <bi> %s failed", "sv_prime2");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	free( outputData);
	sv_prime = bi_new_ptr();
	if( sv_prime == NULL) {
		LogError("malloc of <bi> %s failed", "sv_prime");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	// sv_prime = sv_prime2 << DAA_PARAM_SIZE_SPLIT_EXPONENT
	bi_shift_left( sv_prime, sv_prime2, DAA_PARAM_SIZE_SPLIT_EXPONENT);
	// sv_prime = sv_prime + sv_prime1
	bi_add( sv_prime, sv_prime, sv_prime1);

	sv_tilde_prime = bi_new_ptr();
	// tmp1 = c * v_tilde_prime
	bi_mul( tmp1, c, v_tilde_prime);
	// sv_tilde_prime = rv_tilde_prime + tmp1
	bi_add( sv_tilde_prime, rv_tilde_prime, tmp1);

	// step 6) - choose nonce
	bi_urandom( tmp1, DAA_PARAM_SAFETY_MARGIN * 8);
	noncePlatform = (BYTE *)calloc_tspi( tcsContext, DAA_PARAM_SAFETY_MARGIN);
	if( noncePlatform == NULL) {
		LogError("malloc of <bi> %s failed", "noncePlatform");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_2_nbin1( &noncePlatformLength, noncePlatform, tmp1);

	LogDebug("challenge:%s", dump_byte_array( c_byteLength, c_byte));
	LogDebug("sF0 [%ld]:%s", bi_length( s_f0), bi_2_hex_char( s_f0));
	LogDebug("sF1 [%ld]:%s", bi_length( s_f1), bi_2_hex_char( s_f1));
	LogDebug("sv_prime [%ld]:%s", bi_length( sv_prime), bi_2_hex_char( sv_prime));
	LogDebug("sv_tilde_prime [%ld]:%s", bi_length( sv_tilde_prime), bi_2_hex_char( sv_tilde_prime));
	// update joinSession
	joinSession->capitalU = calloc_tspi( tcsContext, bi_nbin_size( capitalU));
	if( joinSession->capitalU == NULL) {
		LogError("malloc of %ld bytes failed", bi_nbin_size( capitalU));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_2_nbin1( &(joinSession->capitalULength),
			joinSession->capitalU,
			capitalU);
	joinSession->attributesPlatformLength = attributesPlatformLength;
	joinSession->attributesPlatform = calloc_tspi( tcsContext, sizeof(BYTE *));
	for( i=0; i<joinSession->attributesPlatformLength; i++) {
		joinSession->attributesPlatform[i] =
				calloc_tspi( tcsContext,DAA_PARAM_SIZE_F_I / 8);
		memcpy( joinSession->attributesPlatform[i],
				attributesPlatform[i],
				DAA_PARAM_SIZE_F_I / 8);
	}
	joinSession->noncePlatform = noncePlatform;
	joinSession->noncePlatformLength = noncePlatformLength;
	joinSession->vTildePrime = calloc_tspi( tcsContext, bi_nbin_size( v_tilde_prime));
	if( joinSession->vTildePrime == NULL) {
		LogError("malloc of %ld bytes failed", bi_nbin_size( v_tilde_prime));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_2_nbin1( &(joinSession->vTildePrimeLength),
			joinSession->vTildePrime,
			v_tilde_prime);
	// update credentialRequest
	credentialRequest->capitalU = calloc_tspi( tcsContext, bi_nbin_size( capitalU));
	if( credentialRequest->capitalU == NULL) {
		LogError("malloc of %ld bytes failed", bi_nbin_size( capitalU));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_2_nbin1( &(credentialRequest->capitalULength),
			credentialRequest->capitalU,
			capitalU);
	credentialRequest->capitalNi = calloc_tspi( tcsContext, bi_nbin_size( capital_ni));
	if( credentialRequest->capitalNi == NULL) {
		LogError("malloc of %ld bytes failed", bi_nbin_size( capital_ni));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_2_nbin1( &(credentialRequest->capitalNiLength),
			credentialRequest->capitalNi,
			capital_ni);
	credentialRequest->authenticationProofLength = authentication_proofLength;
	credentialRequest->authenticationProof = authentication_proof;
	credentialRequest->challenge = c_byte;
	credentialRequest->challengeLength = c_byteLength;
	credentialRequest->nonceTpm = nonce_tpm;
	credentialRequest->nonceTpmLength = nonce_tpmLength;
	credentialRequest->noncePlatform = noncePlatform;
	credentialRequest->noncePlatformLength = DAA_PARAM_SAFETY_MARGIN;
	credentialRequest->sF0 = calloc_tspi( tcsContext, bi_nbin_size( s_f0));
	if( credentialRequest->sF0 == NULL) {
		LogError("malloc of %ld bytes failed", bi_nbin_size( s_f0));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_2_nbin1( &(credentialRequest->sF0Length), credentialRequest->sF0, s_f0);
	credentialRequest->sF1 = calloc_tspi( tcsContext, bi_nbin_size( s_f1));
	if( credentialRequest->sF1 == NULL) {
		LogError("malloc of %ld bytes failed", bi_nbin_size( s_f1));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_2_nbin1( &(credentialRequest->sF1Length), credentialRequest->sF1, s_f1);
	credentialRequest->sVprime = calloc_tspi( tcsContext, bi_nbin_size( sv_prime));
	if( credentialRequest->sVprime == NULL) {
		LogError("malloc of %ld bytes failed", bi_nbin_size( sv_prime));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_2_nbin1( &(credentialRequest->sVprimeLength),
			credentialRequest->sVprime,
			sv_prime);
	credentialRequest->sVtildePrime = calloc_tspi( tcsContext, bi_nbin_size( sv_tilde_prime));
	if( credentialRequest->sVtildePrime == NULL) {
		LogError("malloc of %ld bytes failed", bi_nbin_size( sv_tilde_prime));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_2_nbin1( &(credentialRequest->sVtildePrimeLength),
			credentialRequest->sVtildePrime,
			sv_tilde_prime);
	length = (DAA_PARAM_SIZE_RANDOMIZED_ATTRIBUTES + 7) / 8;
	LogDebug("SA length=%d", sa->length);
	credentialRequest->sA = calloc_tspi( tcsContext, sizeof( BYTE *) * sa->length);
	if( credentialRequest->sA == NULL) {
		LogError("malloc of %d bytes failed", sizeof( BYTE *) * sa->length);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}

	for( i=0; i<(UINT32)sa->length; i++) {
		LogDebug("sa[%d].size=%d", i, (int)bi_nbin_size( sa->array[i]));
		credentialRequest->sA[i] = calloc_tspi( tcsContext, length);
		if( credentialRequest->sA[i] == NULL) {
			LogError("malloc of %d bytes failed", length);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto close;
		}
		// size used only as repository
		bi_2_byte_array( credentialRequest->sA[i], length, sa->array[i]);
	}
	credentialRequest->sALength = sa->length;
close:
	if( capitalSprime_byte_array!=NULL) free( capitalSprime_byte_array);
	if( ch!=NULL) free( ch);
	if( internal_cbyte != NULL) free( internal_cbyte);
	bi_free_ptr( rv_tilde_prime);
	bi_free_ptr( v_tilde_prime);
	bi_free_ptr( capital_utilde);
	bi_free_ptr( tmp1);
	bi_free_ptr( tmp2);
	bi_free_ptr( capitalU);
	if( ra != NULL) {
		bi_free_array( ra);
		free( ra);
	}
	if( sa != NULL) {
		bi_free_array( sa);
		free( sa);
	}
	FREE_BI( capital_ni);
	FREE_BI( capital_utilde_prime);
	FREE_BI( capital_ni_tilde);
	FREE_BI( n);
	FREE_BI( attributePlatform);
	FREE_BI( c);
	FREE_BI( zeta);
	FREE_BI( capital_Uprime);
	FREE_BI( sv_tilde_prime);
	FREE_BI( s_f0);
	FREE_BI( s_f1);
	FREE_BI( sv_prime);
	FREE_BI( sv_prime1);
	FREE_BI( sv_prime2);
	FREE_BI( product_attributes);
	free_TSS_DAA_PK_internal( pk_internal);
	return result;
}

/*
Code influenced by TSS.java (joinStoreCredential)
*/
TSPICALL Tspi_TPM_DAA_JoinStoreCredential_internal
(
	TSS_HDAA	hDAA,	// in
	TSS_HTPM	hTPM,	// in
	TSS_DAA_CRED_ISSUER	credIssuer,	// in
	TSS_DAA_JOIN_SESSION	joinSession,	// in
	TSS_HKEY*	hDaaCredential	// out
) {
	TCS_CONTEXT_HANDLE tcsContext;
	TPM_AUTH ownerAuth;
	bi_ptr tmp1 = bi_new_ptr();
	bi_ptr tmp2 = bi_new_ptr();
	bi_ptr n = NULL;
	bi_ptr e = NULL;
	bi_ptr fraction_A = NULL;
	bi_ptr v_prime_prime = NULL;
	bi_ptr capital_U = NULL;
	bi_ptr product_attributes = NULL;
	bi_ptr capital_Atilde = NULL;
	bi_ptr s_e = NULL;
	bi_ptr c_prime = NULL;
	bi_ptr capital_A = NULL;
	bi_ptr product = NULL;
	bi_ptr v_tilde_prime = NULL;
	bi_ptr v_prime_prime0 = NULL;
	bi_ptr v_prime_prime1 = NULL;
	TSS_DAA_PK *daa_pk_extern;
	TSS_DAA_PK_internal *pk_intern = NULL;
	TSS_DAA_CREDENTIAL *daaCredential;
	bi_array_ptr attributes_issuer;
	TSS_RESULT result = TSS_SUCCESS;
	UINT32 i;
	UINT32  c_byteLength, v0Length, v1Length, tpm_specificLength;
 	BYTE *c_byte = NULL;
	BYTE *v0 = NULL;
	BYTE *v1 = NULL;
	BYTE *tpm_specific = NULL;

	if( tmp1 == NULL || tmp2 == NULL) {
		LogError("malloc of bi(s) failed");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	if( (result = obj_tpm_is_connected(  hTPM, &tcsContext)) != TSS_SUCCESS) return result;
	obj_daa_set_handle_tpm( hDAA, hTPM);

	LogDebug("Converting issuer public");
	daa_pk_extern = (TSS_DAA_PK *)joinSession.issuerPk;
	pk_intern = e_2_i_TSS_DAA_PK( daa_pk_extern);
	if( pk_intern == NULL) {
		LogError("malloc of pk_intern failed");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	n = bi_new_ptr();
	if( n == NULL) {
		LogError("malloc of bi <%s> failed", "n");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_set( n, pk_intern->modulus);
	attributes_issuer = (bi_array_ptr)malloc( sizeof( struct _bi_array));
	if( attributes_issuer == NULL) {
		LogError("malloc of %d bytes failed", sizeof( struct _bi_array));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_new_array( attributes_issuer, credIssuer.attributesIssuerLength);
	if( attributes_issuer->array == NULL) {
		LogError("malloc of bi_array <%s> failed", "attributes_issuer->array");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	for( i=0; i < credIssuer.attributesIssuerLength; i++) {
		// allocation
		attributes_issuer->array[i] = bi_set_as_nbin( DAA_PARAM_SIZE_F_I / 8,
								credIssuer.attributesIssuer[i]);
		if( attributes_issuer->array[i] == NULL) {
			LogError("malloc of bi <attributes_issuer->array[%d]> failed", i);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto close;
		}
	}
	LogDebug("verify credential of issuer ( part 1)");
	e = bi_set_as_nbin( credIssuer.eLength, credIssuer.e); // allocation
	if( e == NULL) {
		LogError("malloc of bi <%s> failed", "e");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_set( tmp1, bi_0);
	bi_setbit( tmp1, DAA_PARAM_SIZE_EXPONENT_CERTIFICATE - 1);
	bi_set( tmp2, bi_0);
	bi_setbit( tmp1, DAA_PARAM_SIZE_INTERVAL_EXPONENT_CERTIFICATE - 1);
	bi_add( tmp1, tmp1, tmp2);
	if( bi_is_probable_prime( e) == 0 ||
		bi_length(e) < DAA_PARAM_SIZE_EXPONENT_CERTIFICATE ||
		bi_cmp( e, tmp1) > 0) {
			LogError("Verification e failed - Step 1.a");
			LogError("\tPrime(e):%d", bi_is_probable_prime( e));
			LogError("\tbit_length(e):%ld", bi_length(e));
			LogError("\te > (2^(l_e) + 2^(l_prime_e)):%d", bi_cmp( e, tmp1));
			result = TSS_E_DAA_CREDENTIAL_PROOF_ERROR;
			goto close;
	}
	LogDebug("verify credential of issuer (part 2) with proof");
	fraction_A = bi_new_ptr();
	if( fraction_A == NULL) {
		LogError("malloc of bi <%s> failed", "fraction_A");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	v_prime_prime = bi_set_as_nbin( credIssuer.vPrimePrimeLength,
						credIssuer.vPrimePrime); // allocation
	if( v_prime_prime == NULL) {
		LogError("malloc of bi <%s> failed", "v_prime_prime");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	capital_U = bi_set_as_nbin( joinSession.capitalULength,
						joinSession.capitalU); // allocation
	if( capital_U == NULL) {
		LogError("malloc of bi <%s> failed", "capital_U");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_mod_exp( fraction_A, pk_intern->capitalS, v_prime_prime, n);
	bi_mul( fraction_A, fraction_A, capital_U);
	bi_mod( fraction_A, fraction_A, n);
	LogDebug("encode attributes");
	product_attributes = bi_new_ptr();
	bi_set( product_attributes, bi_1);
	for( i=0; i<(UINT32)attributes_issuer->length; i++) {
		bi_mod_exp( tmp1, pk_intern->capitalRIssuer->array[i],
					attributes_issuer->array[i], n);
		bi_mul( product_attributes, tmp1, product_attributes);
		bi_mod( product_attributes, product_attributes, n);
	}
	bi_mul( fraction_A, fraction_A, product_attributes);
	bi_mod( fraction_A, fraction_A, n);
	capital_Atilde = bi_new_ptr();
	if( capital_Atilde == NULL) {
		LogError("malloc of bi <%s> failed", "capital_Atilde");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_invert_mod( capital_Atilde, fraction_A, n);
	bi_mul( capital_Atilde, capital_Atilde, pk_intern->capitalZ);
	bi_mod( capital_Atilde, capital_Atilde, n);
	s_e = bi_set_as_nbin( credIssuer.sELength, credIssuer.sE); // allocation
	if( s_e == NULL) {
		LogError("malloc of bi <%s> failed", "s_e");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_mod_exp( capital_Atilde, capital_Atilde, s_e, n);
	c_prime = bi_set_as_nbin( credIssuer.cPrimeLength, credIssuer.cPrime); // allocation
	if( c_prime == NULL) {
		LogError("malloc of bi <%s> failed", "c_prime");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	capital_A = bi_set_as_nbin( credIssuer.capitalALength, credIssuer.capitalA); // allocation
	if( capital_A == NULL) {
		LogError("malloc of bi <%s> failed", "capital_A");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_mod_exp( tmp1, capital_A, c_prime, n);
	bi_mul( capital_Atilde, capital_Atilde, tmp1);
	bi_mod( capital_Atilde, capital_Atilde, n);

	result = compute_join_challenge_issuer( pk_intern,
						v_prime_prime,
						capital_A,
						capital_Atilde,
						joinSession.noncePlatformLength,
						joinSession.noncePlatform,
						&c_byteLength,
						&c_byte); // out allocation
	if( result != TSS_SUCCESS) goto close;
	if( credIssuer.cPrimeLength != c_byteLength ||
		memcmp( credIssuer.cPrime, c_byte, c_byteLength)!=0) {
		LogError("Verification of c failed - Step 1.c.i");
		LogError("credentialRequest.cPrime[%d]=%s",
			credIssuer.cPrimeLength,
			dump_byte_array( credIssuer.cPrimeLength, credIssuer.cPrime) );
		LogError("challenge[%d]=%s",
			c_byteLength,
			dump_byte_array( c_byteLength, c_byte) );
		result = TSS_E_DAA_CREDENTIAL_PROOF_ERROR;
		goto close;
	}
	product = bi_new_ptr();
	if( product == NULL) {
		LogError("malloc of bi <%s> failed", "product");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_mod_exp( product, capital_A, e, n);
	bi_mul( product, product, fraction_A);
	bi_mod( product, product, n);
	if( bi_equals( pk_intern->capitalZ, product) == 0) {
		LogError("Verification of A failed - Step 1.c.ii");
		LogError("\tcapitalZ=%s", bi_2_hex_char( pk_intern->capitalZ));
		LogError("\tproduct=%s", bi_2_hex_char( product));
		result = TSS_E_DAA_CREDENTIAL_PROOF_ERROR;
		goto close;
	}
	v_tilde_prime = bi_set_as_nbin( joinSession.vTildePrimeLength,
					joinSession.vTildePrime); // allocation
	bi_add( v_prime_prime, v_prime_prime, v_tilde_prime);
	bi_shift_left( tmp1, bi_1, DAA_PARAM_SIZE_SPLIT_EXPONENT);
	v_prime_prime0 = bi_new_ptr();
	if( v_prime_prime0 == NULL) {
		LogError("malloc of bi <%s> failed", "v_prime_prime0");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_mod( v_prime_prime0, v_prime_prime, tmp1);
	v_prime_prime1 = bi_new_ptr();
	if( v_prime_prime1 == NULL) {
		LogError("malloc of bi <%s> failed", "v_prime_prime1");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_shift_right( v_prime_prime1, v_prime_prime, DAA_PARAM_SIZE_SPLIT_EXPONENT);
	free( c_byte);
	c_byte = (BYTE *)malloc( TPM_DAA_SIZE_v0);
	if( c_byte == NULL) {
		LogError("malloc of %d bytes failed", TPM_DAA_SIZE_v0);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_2_byte_array( c_byte, TPM_DAA_SIZE_v0, v_prime_prime0);
	result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
		22,
		TPM_DAA_SIZE_v0, c_byte,
		0, NULL,
		&ownerAuth, &v0Length, &v0);
	if( result != TSS_SUCCESS) goto close;
	LogDebug("Done Join 22: return v0");
	free( c_byte);
	c_byte = (BYTE *)malloc( TPM_DAA_SIZE_v1);
	if( c_byte == NULL) {
		LogError("malloc of %d bytes failed", TPM_DAA_SIZE_v1);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_2_byte_array( c_byte, TPM_DAA_SIZE_v1, v_prime_prime1);
	result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
		23,
		TPM_DAA_SIZE_v1, c_byte,
		0, NULL,
		&ownerAuth, &v1Length, &v1);
	if( result != TSS_SUCCESS) goto close;
	LogDebug("Done Join 23: return v1");
	result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA,
		24,
		0, NULL,
		0, NULL,
		&ownerAuth, &tpm_specificLength, &tpm_specific);
	if( result != TSS_SUCCESS) goto close;

	daaCredential = (TSS_DAA_CREDENTIAL *)hDaaCredential;
	daaCredential->capitalA = calloc_tspi( tcsContext, bi_nbin_size( capital_A));
	if( daaCredential->capitalA == NULL) {
		LogError("malloc of %ld bytes failed", bi_nbin_size( capital_A));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_2_nbin1( &(daaCredential->capitalALength), daaCredential->capitalA, capital_A);
	daaCredential->exponent = calloc_tspi( tcsContext, bi_nbin_size( e));
	if( daaCredential->exponent == NULL) {
		LogError("malloc of %ld bytes failed", bi_nbin_size( e));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_2_nbin1( &(daaCredential->exponentLength), daaCredential->exponent, e);
	daaCredential->vBar0 = calloc_tspi( tcsContext, v0Length);
	if( daaCredential->vBar0 == NULL) {
		LogError("malloc of %d bytes failed", v0Length);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	daaCredential->vBar0Length = v0Length;
	memcpy( daaCredential->vBar0, v0, v0Length);
	LogDebug("vBar0[%d]=%s",
			daaCredential->vBar0Length,
			dump_byte_array( daaCredential->vBar0Length, daaCredential->vBar0));
	daaCredential->vBar1 = calloc_tspi( tcsContext, v1Length);
	if( daaCredential->vBar1 == NULL) {
		LogError("malloc of %d bytes failed", v1Length);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	daaCredential->vBar1Length = v1Length;
	memcpy( daaCredential->vBar1, v1, v1Length);
	LogDebug("vBar1[%d]=%s",
		daaCredential->vBar1Length,
		dump_byte_array( daaCredential->vBar1Length, daaCredential->vBar1));
	//TODO remove
	LogDebug("[BUSS] joinSession.attributesPlatformLength=%d",
			joinSession.attributesPlatformLength);
	LogDebug("[BUSS]       credIssuer.attributesIssuerLength=%d",
			credIssuer.attributesIssuerLength);
	daaCredential->attributesLength = joinSession.attributesPlatformLength +
		credIssuer.attributesIssuerLength;
	daaCredential->attributes = (BYTE **)calloc_tspi( tcsContext,
						sizeof(BYTE *) * daaCredential->attributesLength);
	if( daaCredential->attributes == NULL) {
		LogError("malloc of %d bytes failed",
			sizeof(BYTE *) * daaCredential->attributesLength);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	for( i=0; i < joinSession.attributesPlatformLength; i++) {
		daaCredential->attributes[i] = calloc_tspi( tcsContext, DAA_PARAM_SIZE_F_I / 8);
		if( daaCredential->attributes[i] == NULL) {
			LogError("malloc of %d bytes failed", DAA_PARAM_SIZE_F_I / 8);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto close;
		}
		LogDebug("allocation attributes[%d]=%lx", i, (long)daaCredential->attributes[i]);
		memcpy( daaCredential->attributes[i],
				joinSession.attributesPlatform[i],
				DAA_PARAM_SIZE_F_I / 8);
	}
	for( i=0; i < credIssuer.attributesIssuerLength; i++) {
		daaCredential->attributes[i+joinSession.attributesPlatformLength] =
			calloc_tspi( tcsContext, DAA_PARAM_SIZE_F_I / 8);
		if( daaCredential->attributes[i+joinSession.attributesPlatformLength] == NULL) {
			LogError("malloc of %d bytes failed", DAA_PARAM_SIZE_F_I / 8);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto close;
		}
		memcpy( daaCredential->attributes[i+joinSession.attributesPlatformLength],
			credIssuer.attributesIssuer[i], DAA_PARAM_SIZE_F_I / 8);
	}
	memcpy( &(daaCredential->issuerPK), daa_pk_extern, sizeof( TSS_DAA_PK));
	daaCredential->tpmSpecificEnc = calloc_tspi( tcsContext, tpm_specificLength);
	if( daaCredential->tpmSpecificEnc == NULL) {
		LogError("malloc of %d bytes failed", tpm_specificLength);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	daaCredential->tpmSpecificEncLength = tpm_specificLength;
	memcpy( daaCredential->tpmSpecificEnc, tpm_specific, tpm_specificLength);
	// TODO store in TSS this TSS_DAA_CREDENTIAL_REQUEST
	*hDaaCredential = (TSS_HKEY)daaCredential;
close:
	if( v0 != NULL) free( v0);
	if( v1 != NULL) free( v1);
	if( tpm_specific != NULL) free( tpm_specific);
	if( c_byte != NULL) free( c_byte);
	bi_free_ptr( tmp2);
	bi_free_ptr( tmp1);
	if( attributes_issuer != NULL) {
		bi_free_array( attributes_issuer);
		free( attributes_issuer);
	}
	FREE_BI( v_prime_prime1);
	FREE_BI( v_prime_prime0);
	FREE_BI( v_tilde_prime);
	FREE_BI( product);
	FREE_BI( capital_A);
	FREE_BI( c_prime);
	FREE_BI( s_e);
	FREE_BI( capital_Atilde);
	FREE_BI( product_attributes);
	FREE_BI( capital_U);
	FREE_BI( v_prime_prime);
	FREE_BI( fraction_A);
	FREE_BI( e);
	FREE_BI( n);
	if( pk_intern!=NULL) free_TSS_DAA_PK_internal( pk_intern);
	return result;
}

static void add_splitet( bi_ptr result, bi_ptr a, bi_ptr b) {
	bi_shift_left( result, bi_1, DAA_PARAM_SIZE_SPLIT_EXPONENT);
	bi_mul( result, result, b);
	bi_add( result, result, a);
}

/* code influenced by TSS.java (signStep) */
TSS_RESULT Tspi_TPM_DAA_Sign_internal
(
	TSS_HDAA	hDAA,	// in
	TSS_HTPM	hTPM,	// in
	TSS_HKEY	hDaaCredential,	// in
	TSS_DAA_SELECTED_ATTRIB	revealAttributes,	// in
	UINT32	verifierBaseNameLength,	// in
	BYTE*	verifierBaseName,	// in
	UINT32	verifierNonceLength,	// in
	BYTE*	verifierNonce,	// in
	TSS_DAA_SIGN_DATA	signData,	// in
	TSS_DAA_SIGNATURE*	daaSignature	// out
)
{
	TCS_CONTEXT_HANDLE tcsContext;
	TSS_DAA_CREDENTIAL *daaCredential;
	TPM_DAA_ISSUER *tpm_daa_issuer;
	TPM_AUTH ownerAuth;
	TSS_RESULT result = TSS_SUCCESS;
	TSS_DAA_PK *pk;
	TSS_DAA_PK_internal *pk_intern;
	int i;
	bi_ptr tmp1 = bi_new_ptr(), tmp2;
	bi_ptr n = NULL;
	bi_ptr capital_gamma = NULL;
	bi_ptr gamma = NULL;
	bi_ptr zeta = NULL;
	bi_ptr r = NULL;
	bi_ptr t_tilde_T = NULL;
	bi_ptr capital_Nv = NULL;
	bi_ptr capital_N_tilde_v = NULL;
	bi_ptr w = NULL;
	bi_ptr capital_T = NULL;
	bi_ptr r_E = NULL;
	bi_ptr r_V = NULL;
	bi_ptr capital_T_tilde = NULL;
	bi_ptr capital_A = NULL;
	bi_array_ptr capital_R;
	bi_ptr product_R = NULL;
	bi_array_ptr r_A = NULL;
	bi_array_ptr s_A = NULL;
	bi_ptr c = NULL;
	bi_ptr sF0 = NULL;
	bi_ptr sF1 = NULL;
	bi_ptr sV1 = NULL;
	bi_ptr sV2 = NULL;
	bi_ptr e = NULL;
	bi_ptr s_E = NULL;
	bi_ptr s_V = NULL;
	CS_ENCRYPTION_RESULT_RANDOMNESS *encryption_result_rand = NULL;
	BYTE *issuer_settings = NULL, *outputData, byte;
	BYTE *buffer = NULL, *ch = NULL, *nonce_tpm = NULL, *c_bytes = NULL;
	UINT32 issuer_settingsLength, outputSize, length, size_bits, chLength;
	UINT32 nonce_tpmLength;
	UINT32 c_bytesLength, return_sign_session;
	// for anonymity revocation
	CS_ENCRYPTION_RESULT *encryption_result = NULL;
	CS_ENCRYPTION_RESULT *encryption_result_tilde = NULL;
	TSS_DAA_PSEUDONYM *signature_pseudonym;
	TSS_DAA_PSEUDONYM_PLAIN *pseudonym_plain = NULL;
	TSS_DAA_PSEUDONYM_PLAIN *pseudonym_plain_tilde = NULL;
	TSS_DAA_ATTRIB_COMMIT *signed_commitments;

	if( (result = obj_tpm_is_connected(  hTPM, &tcsContext)) != TSS_SUCCESS)
		return result;
	if( tmp1 == NULL) {
		LogError("malloc of bi <%s> failed", "tmp1");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	obj_daa_set_handle_tpm( hDAA, hTPM);
	// TODO retrieve the daaCredential from the persistence storage
	daaCredential = (TSS_DAA_CREDENTIAL *)hDaaCredential;
	pk = (TSS_DAA_PK *)&(daaCredential->issuerPK);
	pk_intern = e_2_i_TSS_DAA_PK( pk);
	if( pk_intern == NULL) {
		LogError("malloc of <%s> failed", "pk_intern");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	tpm_daa_issuer = convert2issuer_settings( pk_intern);
	if( daaCredential->attributesLength == 0 ||
		daaCredential->attributesLength != revealAttributes.indicesListLength) {
		LogDebug("Problem with the reveal attribs: attributes length:%d reveal length:%d",
			daaCredential->attributesLength, revealAttributes.indicesListLength);
		result = TSS_E_BAD_PARAMETER;
		goto close;
	}
	if( verifierNonce == NULL ||
		verifierNonceLength != DAA_PARAM_LENGTH_MESSAGE_DIGEST) {
		LogDebug("Problem with the nonce verifier: nonce verifier length:%d",
			verifierNonceLength);
		result = TSS_E_BAD_PARAMETER;
		goto close;
	}
	n = bi_new_ptr();
	if( n == NULL) {
		LogError("malloc of bi <%s> failed", "n");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_set( n, pk_intern->modulus);
	capital_gamma = bi_new_ptr();
	if( capital_gamma == NULL) {
		LogError("malloc of bi <%s> failed", "capital_gamma");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_set( capital_gamma, pk_intern->capitalGamma);
	gamma = bi_new_ptr();
	if( gamma == NULL) {
		LogError("malloc of bi <%s> failed", "gamma");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_set( gamma, pk_intern->gamma);
	if( verifierBaseNameLength == 0 || verifierBaseName == NULL) {
		r = bi_new_ptr();
		compute_random_number( r, capital_gamma);
		zeta = project_into_group_gamma( r, pk_intern); // allocation
		if( zeta == NULL) {
			LogError("malloc of bi <%s> failed", "zeta");
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto close;
		}
	} else {
		zeta = compute_zeta( verifierBaseNameLength, verifierBaseName, pk_intern);
		if( zeta == NULL) {
			LogError("malloc of bi <%s> failed", "zeta");
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto close;
		}
	}
	issuer_settings = issuer_2_byte_array( tpm_daa_issuer,
						&issuer_settingsLength); // allocation
	if( issuer_settings == NULL) {
		LogError("malloc of %d bytes failed", issuer_settingsLength);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	LogDebug( "Issuer Settings:[%s]",
		dump_byte_array(issuer_settingsLength, issuer_settings) );
	result = Tcsip_TPM_DAA_Sign(
		tcsContext, hDAA,
		0,
		issuer_settingsLength, issuer_settings,
		0, NULL,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) goto close;
	// set the sessionHandle to the returned value
	return_sign_session = ntohl( *((UINT32 *)outputData));
	obj_daa_set_session_handle( hDAA, return_sign_session);
	free( outputData);
	result = Tcsip_TPM_DAA_Sign(
		tcsContext, hDAA,
		1,
		daaCredential->tpmSpecificEncLength, daaCredential->tpmSpecificEnc,
		0, NULL,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) goto close;
	free( outputData);
	LogDebug( "done Sign 1 - TPM specific");
	result = Tcsip_TPM_DAA_Sign(
		tcsContext, hDAA,
		2,
		pk->capitalR0Length, pk->capitalR0,
		pk->modulusLength, pk->modulus,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) goto close;
	free( outputData);
	LogDebug( "done Sign 2 - capitalR0");
	result = Tcsip_TPM_DAA_Sign(
		tcsContext, hDAA,
		3,
		pk->capitalR1Length, pk->capitalR1,
		pk->modulusLength, pk->modulus,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) goto close;
	free( outputData);
	LogDebug( "done Sign 3 - capitalR1");
	result = Tcsip_TPM_DAA_Sign(
		tcsContext, hDAA,
		4,
		pk->capitalSLength, pk->capitalS,
		pk->modulusLength, pk->modulus,
		&ownerAuth, &outputSize, &outputData);
	if( outputSize > 0 && outputData != NULL) free( outputData);
	if( result != TSS_SUCCESS) goto close;
	LogDebug( "done Sign 4 - capitalS");
	buffer = bi_2_nbin( &length, pk_intern->capitalSprime); // allocation
	if( buffer == NULL) {
		LogError("malloc of %d bytes failed", length);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	result = Tcsip_TPM_DAA_Sign(
		tcsContext, hDAA,
		5,
		length, buffer,
		pk->modulusLength, pk->modulus,
		&ownerAuth, &outputSize, &outputData);
	free( buffer);
	if( result != TSS_SUCCESS) goto close;
	LogDebug( "done Sign 5 - capitalSPrime. Return t_tilde_T");
	t_tilde_T = bi_set_as_nbin( outputSize, outputData); // allocation
	if( t_tilde_T == NULL) {
		LogError("malloc of bi <%s> failed", "t_tilde_T");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	free( outputData);
	// first precomputation until here possible (verifier independent)
	length = TPM_DAA_SIZE_w;
	buffer = (BYTE *)malloc( length);
	if( buffer == NULL) {
		LogError("malloc of %d bytes failed", length);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_2_byte_array( buffer, length, zeta);
	result = Tcsip_TPM_DAA_Sign(
		tcsContext, hDAA,
		6,
		pk->capitalGammaLength, pk->capitalGamma,
		length, buffer,
		&ownerAuth, &outputSize, &outputData);
	free( buffer);
	if( result != TSS_SUCCESS) goto close;
	LogDebug( "done Sign 6 - capitalGamma & zeta");
	result = Tcsip_TPM_DAA_Sign(
		tcsContext, hDAA,
		7,
		pk->capitalGammaLength, pk->capitalGamma,
		0, NULL,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) goto close;
	LogDebug( "done Sign 7 - capitalGamma. Return capital_Nv");
	capital_Nv = bi_set_as_nbin( outputSize, outputData); // allocation
	if( capital_Nv == NULL) {
		LogError("malloc of bi <%s> failed", "capital_Nv");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	free( outputData);
	// TODO Step 6 a.b - anonymity revocation

	result = Tcsip_TPM_DAA_Sign(
		tcsContext, hDAA,
		8,
		pk->capitalGammaLength, pk->capitalGamma,
		0, NULL,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) goto close;
	LogDebug( "done Sign 8 - capitalGamma. Return capital_N_tilde_v");
	capital_N_tilde_v = bi_set_as_nbin( outputSize, outputData); // allocation
	if( capital_N_tilde_v == NULL) {
		LogError("malloc of bi <%s> failed", "capital_N_tilde_v");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	free( outputData);
	// TODO  Step 6 c,d - anonymity revocation

	// Second precomputation until here possible (verifier dependent)
	size_bits = DAA_PARAM_SIZE_RSA_MODULUS + DAA_PARAM_SAFETY_MARGIN;
	w = bi_new_ptr();
	if( w == NULL) {
		LogError("malloc of bi <%s> failed", "w");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_urandom( w, size_bits);
	capital_A = bi_set_as_nbin( daaCredential->capitalALength,
					daaCredential->capitalA); // allocation
	if( capital_A == NULL) {
		LogError("malloc of bi <%s> failed", "capital_A");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	capital_T = bi_new_ptr();
	if( capital_T == NULL) {
		LogError("malloc of bi <%s> failed", "capital_T");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_mod_exp( tmp1, pk_intern->capitalS, w, n);
	bi_mul( capital_T, capital_A, tmp1);
	bi_mod( capital_T, capital_T, n);
	size_bits = DAA_PARAM_SIZE_INTERVAL_EXPONENT_CERTIFICATE +
		DAA_PARAM_SAFETY_MARGIN + DAA_PARAM_SIZE_MESSAGE_DIGEST;
	r_E = bi_new_ptr();
	if( r_E == NULL) {
		LogError("malloc of bi <%s> failed", "r_E");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_urandom( r_E, size_bits);
	size_bits = DAA_PARAM_SIZE_EXPONENT_CERTIFICATE + DAA_PARAM_SIZE_RSA_MODULUS +
		2 * DAA_PARAM_SAFETY_MARGIN + DAA_PARAM_SIZE_MESSAGE_DIGEST + 1;
	r_V = bi_new_ptr();
	if( r_V == NULL) {
		LogError("malloc of bi <%s> failed", "r_V");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_urandom( r_V, size_bits);
	capital_T_tilde = bi_new_ptr();
	if( capital_T_tilde == NULL) {
		LogError("malloc of bi <%s> failed", "capital_T_tilde");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_mod_exp( tmp1, capital_T, r_E, n);
	bi_mul( capital_T_tilde, t_tilde_T, tmp1);
	bi_mod( capital_T_tilde, capital_T_tilde, n);

	bi_mod_exp( tmp1, pk_intern->capitalS, r_V, n);
	bi_mul( capital_T_tilde, capital_T_tilde, tmp1);
	bi_mod( capital_T_tilde, capital_T_tilde, n);

	// attributes extension
	size_bits = DAA_PARAM_SIZE_F_I +
			DAA_PARAM_SAFETY_MARGIN +
			DAA_PARAM_SIZE_MESSAGE_DIGEST;
	capital_R = pk_intern->capitalY;
	r_A = (bi_array_ptr)malloc( sizeof( struct _bi_array));
	if( r_A == NULL) {
		LogError("malloc of %d bytes failed", sizeof( struct _bi_array));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_new_array2( r_A, revealAttributes.indicesListLength);
	product_R = bi_new_ptr();
	if( product_R == NULL) {
		LogError("malloc of bi <%s> failed", "product_R");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_set( product_R, bi_1);
	for( i=0; i<(int)revealAttributes.indicesListLength; i++) {
		if( revealAttributes.indicesList[i] == 0) {
			// only non selected
			r_A->array[i] = bi_new_ptr();
			if( r_A->array[i] == NULL) {
				LogError("malloc of bi <%s> failed", "r_A->array[i]");
				result = TSPERR(TSS_E_OUTOFMEMORY);
				goto close;
			}
			bi_urandom( r_A->array[i] , size_bits);
			bi_mod_exp( tmp1, capital_R->array[i], r_A->array[i], n);
			bi_mul( product_R, product_R, tmp1);
			bi_mod( product_R, product_R, n);
		} else r_A->array[i] = NULL;
	}
	bi_mul( capital_T_tilde, capital_T_tilde, product_R);
	bi_mod( capital_T_tilde, capital_T_tilde, n);
	//TODO Step 8 - Commitments
	// compute commitment to attributes not revealed to the verifier

	//TODO Step 9 - callback functions

	// only when revocation not enabled
	pseudonym_plain = (TSS_DAA_PSEUDONYM_PLAIN *)calloc_tspi( tcsContext,
								sizeof(TSS_DAA_PSEUDONYM_PLAIN));
	if( pseudonym_plain == NULL) {
		LogError("malloc of %d bytes failed", sizeof(TSS_DAA_PSEUDONYM_PLAIN));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	init_tss_version( pseudonym_plain);
	pseudonym_plain->capitalNv = calloc_tspi( tcsContext,
						bi_nbin_size( capital_Nv));
	if( pseudonym_plain->capitalNv == NULL) {
		LogError("malloc of bi <%s> failed", "pseudonym_plain->capitalNv");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_2_nbin1( &(pseudonym_plain->capitalNvLength),
				pseudonym_plain->capitalNv,
				capital_Nv);
	pseudonym_plain_tilde = (TSS_DAA_PSEUDONYM_PLAIN *)
		calloc_tspi( tcsContext,sizeof(TSS_DAA_PSEUDONYM_PLAIN));
	if( pseudonym_plain_tilde == NULL) {
		LogError("malloc of %d bytes failed", sizeof(TSS_DAA_PSEUDONYM_PLAIN));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	init_tss_version( pseudonym_plain_tilde);
	pseudonym_plain_tilde->capitalNv = calloc_tspi( tcsContext,
							bi_nbin_size( capital_N_tilde_v));
	if( pseudonym_plain_tilde->capitalNv == NULL) {
		LogError("malloc of bi <%s> failed", "pseudonym_plain_tilde->capitalNv");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_2_nbin1( &(pseudonym_plain_tilde->capitalNvLength),
				pseudonym_plain_tilde->capitalNv,
				capital_N_tilde_v);

	// Step 10 - compute challenge
	ch = compute_sign_challenge_host(
		&chLength,
		DAA_PARAM_get_message_digest(),
		pk_intern,
		verifierNonceLength,
		verifierNonce,
		0,	// int selected_attributes2commitLength,
		NULL,	// TSS_DAA_SELECTED_ATTRIB **selected_attributes2commit,
		0,	// 	int is_anonymity_revocation_enabled,
		zeta,
		capital_T,
		capital_T_tilde,
		0, //	int attribute_commitmentsLength,
		NULL, //	TSS_DAA_ATTRIB_COMMIT_internal **attribute_commitments,
		NULL, //	TSS_DAA_ATTRIB_COMMIT_internal **attribute_commitment_proofs,
		capital_Nv,
		capital_N_tilde_v,
		NULL, // CS_PUBLIC_KEY *anonymity_revocator_pk,
		NULL, // CS_ENCRYPTION_RESULT *encryption_result_rand,
		NULL //CS_ENCRYPTION_RESULT *encryption_result_proof)
	);
	if( ch == NULL) {
		LogError("malloc in compute_sign_challenge_host failed");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	result = Tcsip_TPM_DAA_Sign( tcsContext, hDAA,
			9,
			chLength, ch,
			0, NULL,
			&ownerAuth, &nonce_tpmLength, &nonce_tpm);
	if( result != TSS_SUCCESS) goto close;
	LogDebug( "done Sign 9 - compute sign challenge host. Return nonce_tpm");
	byte = (BYTE)signData.payloadFlag; // 0 -> payload contains a handle to an AIK
					// 1 -> payload contains a hashed message
	result = Tcsip_TPM_DAA_Sign( tcsContext, hDAA,
			10,
			sizeof(BYTE), &byte,
			signData.payloadLength, signData.payload,
			&ownerAuth, &c_bytesLength, &c_bytes);
	LogDebug("calculation of c: ch[%d]%s", chLength, dump_byte_array( chLength, ch));
	LogDebug("calculation of c: nonce_tpm[%d]%s",
			nonce_tpmLength,
			dump_byte_array( nonce_tpmLength, nonce_tpm));
	LogDebug("calculation of c: sign_data.payloadFlag[%d]%x",
		1,
		(int)signData.payloadFlag);
	LogDebug("calculation of c: signdata.payload[%d]%s",
			signData.payloadLength,
			dump_byte_array( signData.payloadLength, signData.payload));

	if( result != TSS_SUCCESS) goto close;
	LogDebug( "done Sign 10 - compute signData.payload.");
	LogDebug(" Return c_bytes[%d]%s",
		c_bytesLength,
		dump_byte_array( c_bytesLength, c_bytes));
	c = bi_set_as_nbin( c_bytesLength, c_bytes); // allocation
	if( c == NULL) {
		LogError("malloc of bi <%s> failed", "c");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	result = Tcsip_TPM_DAA_Sign(
		tcsContext, hDAA,
		11,
		0, NULL,
		0, NULL,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS)goto close;
	LogDebug( "done Sign 11. Return sF0");
	sF0 = bi_set_as_nbin( outputSize, outputData); // allocation
	if( sF0 == NULL) {
		LogError("malloc of bi <%s> failed", "sF0");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	free( outputData);
	result = Tcsip_TPM_DAA_Sign(
		tcsContext, hDAA,
		12,
		0, NULL,
		0, NULL,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) goto close;
	LogDebug( "done Sign 12. Return sF1");
	sF1 = bi_set_as_nbin( outputSize, outputData); // allocation
	if( sF1 == NULL) {
		LogError("malloc of bi <%s> failed", "sF1");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	free( outputData);
	result = Tcsip_TPM_DAA_Sign(
		tcsContext, hDAA,
		13,
		daaCredential->vBar0Length,  daaCredential->vBar0,
		0, NULL,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) goto close;
	LogDebug( "done Sign 13. Return sV1");
	sV1 = bi_set_as_nbin( outputSize, outputData); // allocation
	if( sV1 == NULL) {
		LogError("malloc of bi <%s> failed", "sV1");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	free( outputData);
	result = Tcsip_TPM_DAA_Sign(
		tcsContext, hDAA,
		14,
		daaCredential->vBar0Length,  daaCredential->vBar0,
		0, NULL,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) goto close;
	free( outputData);
	LogDebug( "done Sign 14.");
	result = Tcsip_TPM_DAA_Sign(
		tcsContext, hDAA,
		15,
		daaCredential->vBar1Length,  daaCredential->vBar1,
		0, NULL,
		&ownerAuth, &outputSize, &outputData);
	if( result != TSS_SUCCESS) goto close;
	LogDebug( "done Sign 15. Return sV2");
	sV2 = bi_set_as_nbin( outputSize, outputData); // allocation
	if( sV2 == NULL) {
		LogError("malloc of bi <%s> failed", "sV2");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	free( outputData);
	// allocation
	e = bi_set_as_nbin( daaCredential->exponentLength, daaCredential->exponent);
	if( e == NULL) {
		LogError("malloc of bi <%s> failed", "e");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	// s_e = r_E + ( c * ( e - ( 1 << (sizeExponentCertificate -1))))
	s_E = bi_new_ptr();
	if( s_E == NULL) {
		LogError("malloc of bi <%s> failed", "s_E");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_shift_left( tmp1, bi_1, DAA_PARAM_SIZE_EXPONENT_CERTIFICATE - 1);
	bi_sub( tmp1, e, tmp1);
	bi_mul( tmp1, c, tmp1);
	bi_add( s_E, r_E, tmp1);
	s_V = bi_new_ptr();
	if( s_V == NULL) {
		LogError("malloc of bi <%s> failed", "s_V");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	add_splitet( s_V, sV1, sV2);
	bi_add( s_V, s_V, r_V);
	bi_mul( tmp1, c, w);
	bi_mul( tmp1, tmp1, e);
	bi_sub( s_V, s_V, tmp1);
	// attributes extension
	// TODO verify the size of each selected attributes
	s_A = (bi_array_ptr)malloc( sizeof( struct _bi_array));
	if( s_A == NULL) {
		LogError("malloc of bi_array <%s> failed", "s_A");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_new_array2( s_A, revealAttributes.indicesListLength);
	if( s_A->array == NULL) {
		LogError("malloc of bi_array <%s> failed", "s_A");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	for( i=0; i<(int)revealAttributes.indicesListLength; i++) {
		if( revealAttributes.indicesList[i] == 0) {
			s_A->array[i] = bi_new_ptr();
			if( s_A->array[i] == NULL) {
				LogError("malloc of bi <%s> failed", "s_A->array[i]");
				result = TSPERR(TSS_E_OUTOFMEMORY);
				goto close;
			}
			tmp2 = bi_set_as_nbin( DAA_PARAM_SIZE_F_I / 8,
						daaCredential->attributes[i]); // allocation
			if( tmp2 == NULL) {
				LogError("malloc of %d bytes failed", DAA_PARAM_SIZE_F_I / 8);
				result = TSPERR(TSS_E_OUTOFMEMORY);
				goto close;
			}
			bi_mul( tmp1, c, tmp2);
			// TODEL
			LogDebug("daaCredential->attributes[i]=%ld", bi_nbin_size( tmp2));
			LogDebug("r_A:%ld", bi_nbin_size( r_A->array[i]));
			LogDebug("c:%ld", bi_nbin_size( c));
			LogDebug("c*daaCredential->attributes[i]=%ld", bi_nbin_size( tmp1));
			// END TODEL
			bi_add( s_A->array[i], r_A->array[i], tmp1);
			bi_free_ptr( tmp2);
		} else s_A->array[i] = NULL;
	}

	// Compose result structure

	// DAASignaturePseudonym TODO: implement anonymity revocation
	// if ( !revocation_enabled)
	signature_pseudonym = pseudonym_plain;

	// populate the signature (TSS_DAA_SIGNATURE)
	daaSignature->zeta = (BYTE *)calloc_tspi( tcsContext, bi_nbin_size( zeta));
	if (daaSignature->zeta == NULL) {
		LogError("malloc of %ld bytes failed", bi_nbin_size( zeta));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_2_nbin1( &(daaSignature->zetaLength), daaSignature->zeta, zeta);
	daaSignature->capitalT = (BYTE *)calloc_tspi( tcsContext, bi_nbin_size( capital_T));
	if (daaSignature->capitalT == NULL) {
		LogError("malloc of %ld bytes failed", bi_nbin_size( capital_T));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_2_nbin1( &(daaSignature->capitalTLength), daaSignature->capitalT, capital_T);
	daaSignature->challenge = (BYTE *)calloc_tspi( tcsContext, c_bytesLength);
	if (daaSignature->challenge == NULL) {
		LogError("malloc of %d bytes failed", c_bytesLength);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	daaSignature->challengeLength = c_bytesLength;
	memcpy( daaSignature->challenge, c_bytes, c_bytesLength);
	daaSignature->nonceTpm = (BYTE *)calloc_tspi( tcsContext, nonce_tpmLength);
	if (daaSignature->nonceTpm == NULL) {
		LogError("malloc of %d bytes failed", nonce_tpmLength);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	daaSignature->nonceTpmLength = nonce_tpmLength;
	memcpy( daaSignature->nonceTpm, nonce_tpm, nonce_tpmLength);
	daaSignature->sV = (BYTE *)calloc_tspi( tcsContext, bi_nbin_size( s_V));
	if (daaSignature->sV == NULL) {
		LogError("malloc of %ld bytes failed", bi_nbin_size( s_V));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_2_nbin1( &(daaSignature->sVLength), daaSignature->sV, s_V);
	daaSignature->sF0 = (BYTE *)calloc_tspi( tcsContext, bi_nbin_size( sF0));
	if (daaSignature->sF0 == NULL) {
		LogError("malloc of %ld bytes failed", bi_nbin_size( sF0));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_2_nbin1( &(daaSignature->sF0Length), daaSignature->sF0, sF0);
	daaSignature->sF1 = (BYTE *)calloc_tspi( tcsContext, bi_nbin_size( sF1));
	if (daaSignature->sF1 == NULL) {
		LogError("malloc of %ld bytes failed", bi_nbin_size( sF1));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_2_nbin1( &(daaSignature->sF1Length), daaSignature->sF1, sF1);
	daaSignature->sE = (BYTE *)calloc_tspi( tcsContext, bi_nbin_size( s_E));
	if (daaSignature->sE == NULL) {
		LogError("malloc of %ld bytes failed", bi_nbin_size( s_E));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	bi_2_nbin1( &(daaSignature->sELength), daaSignature->sE, s_E);
	daaSignature->sALength = revealAttributes.indicesListLength;
	daaSignature->sA = (BYTE **)calloc_tspi(
		tcsContext,
		sizeof(BYTE *)*revealAttributes.indicesListLength);
	if (daaSignature->sA == NULL) {
		LogError("malloc of %d bytes failed",
			sizeof(BYTE *)*revealAttributes.indicesListLength);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	length = (DAA_PARAM_SIZE_RANDOMIZED_ATTRIBUTES + 7) / 8;
	for( i=0; i<(int)revealAttributes.indicesListLength; i++) {
		daaSignature->sA[i] = calloc_tspi( tcsContext, length);
		if (daaSignature->sA[i] == NULL) {
			LogError("malloc of %d bytes failed", length);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto close;
		}
		if( s_A->array[i] == NULL)
			bi_2_byte_array( daaSignature->sA[i], length, bi_0);
		else {
			bi_2_byte_array( daaSignature->sA[i], length, s_A->array[i]);
			LogDebug("size big_integer s_A[i] = %ld   size daaSignature->sA[i]=%d",
				bi_nbin_size( s_A->array[i]), length);
		}
	}
	daaSignature->attributeCommitmentsLength = 0;
	daaSignature->signedPseudonym = signature_pseudonym;
close:
	bi_free_ptr( tmp1);
	if( c_bytes != NULL) free( c_bytes);
	if( ch != NULL) free( ch);
	if( nonce_tpm != NULL) free( nonce_tpm);
	if( encryption_result !=NULL) free( encryption_result);
	if( encryption_result_tilde !=NULL) free( encryption_result_tilde);
	if( issuer_settings != NULL) free( issuer_settings);
	if( r_A != NULL) {
		for( i=0; i<(int)revealAttributes.indicesListLength; i++)
			if( r_A->array[i] != NULL) bi_free_ptr( r_A->array[i]);
		free( r_A);
	}
	FREE_BI( s_V);
	FREE_BI( s_E);
	FREE_BI( e);
	FREE_BI( sV2);
	FREE_BI( sV1);
        FREE_BI( sF1);
	FREE_BI( sF0);
	FREE_BI( c);
	FREE_BI( product_R);
	FREE_BI( capital_A);
	FREE_BI( capital_T_tilde);
	FREE_BI( r_V);
	FREE_BI( r_E);
	FREE_BI( capital_T);
	FREE_BI( w);
	FREE_BI( capital_N_tilde_v);
	FREE_BI( capital_Nv);
	FREE_BI( t_tilde_T);
	FREE_BI( n);
	FREE_BI( capital_gamma);
	FREE_BI( gamma);
	FREE_BI( zeta);
	FREE_BI( r);
	free_TSS_DAA_PK_internal( pk_intern);
	free_TPM_DAA_ISSUER( tpm_daa_issuer);
	return result;
}


<|start_filename|>src/include/tcs_key_ps.h<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

#ifndef _TCS_KEY_PS_H_
#define _TCS_KEY_PS_H_

TSS_RESULT ps_init_disk_cache();
void       ps_close_disk_cache();
TSS_BOOL   ps_is_key_registered(TCPA_STORE_PUBKEY *);
TSS_RESULT getParentUUIDByUUID(TSS_UUID *, TSS_UUID *);
TSS_RESULT isUUIDRegistered(TSS_UUID *, TSS_BOOL *);
void       disk_cache_shift(struct key_disk_cache *);
TSS_RESULT ps_remove_key(TSS_UUID *);
TSS_RESULT clean_disk_cache(int);
TSS_RESULT ps_get_key_by_uuid(TSS_UUID *, BYTE *, UINT16 *);
TSS_RESULT ps_get_key_by_cache_entry(struct key_disk_cache *, BYTE *, UINT16 *);
TSS_RESULT ps_is_pub_registered(TCPA_STORE_PUBKEY *);
TSS_RESULT ps_get_uuid_by_pub(TCPA_STORE_PUBKEY *, TSS_UUID **);
TSS_RESULT ps_get_key_by_pub(TCPA_STORE_PUBKEY *, UINT32 *, BYTE **);
TSS_RESULT ps_write_key(TSS_UUID *, TSS_UUID *, BYTE *, UINT32, BYTE *, UINT32);

#endif


<|start_filename|>src/include/tcsem.h<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

#ifndef _TCSEM_H_
#define _TCSEM_H_

struct ext_log_source {
        int (*open)(void *, FILE **);
        TSS_RESULT (*get_entries_by_pcr)(FILE *, UINT32, UINT32, UINT32 *, TSS_PCR_EVENT **);
        TSS_RESULT (*get_entry)(FILE *, UINT32, UINT32 *, TSS_PCR_EVENT **);
        int (*close)(FILE *);
};

struct event_wrapper {
	TSS_PCR_EVENT event;
	struct event_wrapper *next;
};

struct event_log {
	MUTEX_DECLARE(lock);
	struct ext_log_source *firmware_source;
	struct ext_log_source *kernel_source;
	struct event_wrapper **lists;
};

/* include the compiled-in log sources and struct references here */
#include "imaem.h"
#include "biosem.h"

#ifdef EVLOG_SOURCE_IMA
#define EVLOG_IMA_SOURCE	&ima_source
#else
#define EVLOG_IMA_SOURCE	NULL
#endif

#ifdef EVLOG_SOURCE_BIOS
#define EVLOG_BIOS_SOURCE	&bios_source
#else
#define EVLOG_BIOS_SOURCE	NULL
#endif


TSS_RESULT event_log_init();
TSS_RESULT event_log_final();
TSS_RESULT copy_pcr_event(TSS_PCR_EVENT *, TSS_PCR_EVENT *);
TSS_RESULT event_log_add(TSS_PCR_EVENT *, UINT32 *);
TSS_PCR_EVENT *get_pcr_event(UINT32, UINT32);
UINT32 get_num_events(UINT32);
TSS_PCR_EVENT *concat_pcr_events(TSS_PCR_EVENT **, UINT32, TSS_PCR_EVENT *, UINT32);
UINT32 get_pcr_event_size(TSS_PCR_EVENT *);
void free_external_events(UINT32, TSS_PCR_EVENT *);

extern struct event_log *tcs_event_log;

#endif


<|start_filename|>src/tcs/tcsi_aik.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "tcsps.h"
#include "req_mgr.h"
#include "tcs_aik.h"


TSS_RESULT
TCSP_MakeIdentity_Internal(TCS_CONTEXT_HANDLE hContext,			/* in  */
			   TCPA_ENCAUTH identityAuth,			/* in */
			   TCPA_CHOSENID_HASH IDLabel_PrivCAHash,	/* in */
			   UINT32 idKeyInfoSize,			/* in */
			   BYTE * idKeyInfo,				/* in */
			   TPM_AUTH * pSrkAuth,				/* in, out */
			   TPM_AUTH * pOwnerAuth,			/* in, out */
			   UINT32 * idKeySize,				/* out */
			   BYTE ** idKey,				/* out */
			   UINT32 * pcIdentityBindingSize,		/* out */
			   BYTE ** prgbIdentityBinding,			/* out */
			   UINT32 * pcEndorsementCredentialSize,	/* out */
			   BYTE ** prgbEndorsementCredential,		/* out */
			   UINT32 * pcPlatformCredentialSize,		/* out */
			   BYTE ** prgbPlatformCredential,		/* out */
			   UINT32 * pcConformanceCredentialSize,	/* out */
			   BYTE ** prgbConformanceCredential)		/* out */
{
	UINT64 offset;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	if ((result = ctx_verify_context(hContext)))
		goto done;

	if (pSrkAuth != NULL) {
		LogDebug("SRK Auth Used");
		if ((result = auth_mgr_check(hContext, &pSrkAuth->AuthHandle)))
			goto done;
	} else {
		LogDebug("No SRK Auth");
	}

	if ((result = auth_mgr_check(hContext, &pOwnerAuth->AuthHandle)))
		goto done;

	offset = 0;
	if ((result = tpm_rqu_build(TPM_ORD_MakeIdentity, &offset, txBlob, identityAuth.authdata,
				    IDLabel_PrivCAHash.digest, idKeyInfoSize, idKeyInfo, pSrkAuth,
				    pOwnerAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		if ((result = tpm_rsp_parse(TPM_ORD_MakeIdentity, txBlob, paramSize, idKeySize,
					    idKey, pcIdentityBindingSize, prgbIdentityBinding,
					    pSrkAuth, pOwnerAuth)))
			goto done;

		/* If an error occurs, these will return NULL */
		get_credential(TSS_TCS_CREDENTIAL_PLATFORMCERT, pcPlatformCredentialSize,
			       prgbPlatformCredential);
		get_credential(TSS_TCS_CREDENTIAL_TPM_CC, pcConformanceCredentialSize,
			       prgbConformanceCredential);
		get_credential(TSS_TCS_CREDENTIAL_EKCERT, pcEndorsementCredentialSize,
			       prgbEndorsementCredential);
	}
	LogResult("Make Identity", result);
done:
	auth_mgr_release_auth(pSrkAuth, pOwnerAuth, hContext);
	return result;
}

TSS_RESULT
TCSP_ActivateTPMIdentity_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
				  TCS_KEY_HANDLE idKey,	/* in */
				  UINT32 blobSize,	/* in */
				  BYTE * blob,	/* in */
				  TPM_AUTH * idKeyAuth,	/* in, out */
				  TPM_AUTH * ownerAuth,	/* in, out */
				  UINT32 * SymmetricKeySize,	/* out */
				  BYTE ** SymmetricKey)	/* out */
{
	UINT64 offset;
	TSS_RESULT result;
	UINT32 paramSize;
	UINT32 keySlot;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("TCSP_ActivateTPMIdentity");

	if ((result = ctx_verify_context(hContext)))
		goto done;

	if (idKeyAuth != NULL) {
		if ((result = auth_mgr_check(hContext, &idKeyAuth->AuthHandle)))
			goto done;
	}
	if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
		goto done;

	if ((result = ensureKeyIsLoaded(hContext, idKey, &keySlot)))
		goto done;

	offset = 0;
	if ((result = tpm_rqu_build(TPM_ORD_ActivateIdentity, &offset, txBlob, keySlot, blobSize,
				    blob, idKeyAuth, ownerAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		if ((result = tpm_rsp_parse(TPM_ORD_ActivateIdentity, txBlob, paramSize,
					    SymmetricKeySize, SymmetricKey, idKeyAuth, ownerAuth)))
			goto done;
	}

done:
	auth_mgr_release_auth(idKeyAuth, ownerAuth, hContext);
	return result;
}

TSS_RESULT
TCS_GetCredential_Internal(TCS_CONTEXT_HANDLE hContext,		/* in  */
			   UINT32 ulCredentialType,		/* in */
			   UINT32 ulCredentialAccessMode,	/* in */
			   UINT32 * pulCredentialSize,		/* out */
			   BYTE ** prgbCredentialData)		/* out */
{
	TSS_RESULT result;

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((ulCredentialType != TSS_TCS_CREDENTIAL_EKCERT) &&
	    (ulCredentialType != TSS_TCS_CREDENTIAL_TPM_CC) &&
	    (ulCredentialType != TSS_TCS_CREDENTIAL_PLATFORMCERT)) {
		LogError("GetCredential - Unsupported Credential Type");
		return TCSERR(TSS_E_BAD_PARAMETER);
	}

	if (ulCredentialAccessMode == TSS_TCS_CERT_ACCESS_AUTO) {
		get_credential(ulCredentialType, pulCredentialSize, prgbCredentialData);
	} else {
		LogError("GetCredential - Unsupported Credential Access Mode");
		return TCSERR(TSS_E_FAIL);
	}

	return TSS_SUCCESS;
}

TSS_RESULT
TCSP_MakeIdentity2_Internal(TCS_CONTEXT_HANDLE hContext,		/* in  */
			    TCPA_ENCAUTH identityAuth,			/* in */
			    TCPA_CHOSENID_HASH IDLabel_PrivCAHash,	/* in */
			    UINT32 idKeyInfoSize,			/* in */
			    BYTE * idKeyInfo,				/* in */
			    TPM_AUTH * pSrkAuth,			/* in, out */
			    TPM_AUTH * pOwnerAuth,			/* in, out */
			    UINT32 * idKeySize,				/* out */
			    BYTE ** idKey,				/* out */
			    UINT32 * pcIdentityBindingSize,		/* out */
			    BYTE ** prgbIdentityBinding)		/* out */
{
	UINT64 offset;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	if ((result = ctx_verify_context(hContext)))
		goto done;

	if (pSrkAuth) {
		if ((result = auth_mgr_check(hContext, &pSrkAuth->AuthHandle)))
			goto done;
	}

	if ((result = auth_mgr_check(hContext, &pOwnerAuth->AuthHandle)))
		goto done;

	offset = 0;
	if ((result = tpm_rqu_build(TPM_ORD_MakeIdentity, &offset, txBlob, identityAuth.authdata,
				    IDLabel_PrivCAHash.digest, idKeyInfoSize, idKeyInfo, pSrkAuth,
				    pOwnerAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		if ((result = tpm_rsp_parse(TPM_ORD_MakeIdentity, txBlob, paramSize, idKeySize,
					    idKey, pcIdentityBindingSize, prgbIdentityBinding,
					    pSrkAuth, pOwnerAuth)))
			goto done;
	}
	LogResult("Make Identity", result);
done:
	auth_mgr_release_auth(pSrkAuth, pOwnerAuth, hContext);
	return result;
}



<|start_filename|>src/tcs/tcsi_admin.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004, 2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcsps.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "req_mgr.h"
#include "tcsd_wrap.h"
#include "tcsd.h"

TSS_RESULT
TCSP_SetOwnerInstall_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			      TSS_BOOL state)	/* in  */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering SetOwnerInstall");
	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_SetOwnerInstall, &offset, txBlob, state, NULL)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);
	LogResult("SetOwnerInstall", result);
	return result;
}

TSS_RESULT
TCSP_OwnerSetDisable_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			      TSS_BOOL disableState,	/* in */
			      TPM_AUTH * ownerAuth)	/* in, out */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	if ((result = ctx_verify_context(hContext)))
		goto done;

	if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
		goto done;

	if ((result = tpm_rqu_build(TPM_ORD_OwnerSetDisable, &offset, txBlob, disableState,
				    ownerAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_OwnerSetDisable, txBlob, paramSize, ownerAuth);
	}
done:
	auth_mgr_release_auth(ownerAuth, NULL, hContext);
	return result;
}

TSS_RESULT
TCSP_DisableOwnerClear_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
				TPM_AUTH * ownerAuth)	/* in, out */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering DisableownerClear");

	if ((result = ctx_verify_context(hContext)))
		goto done;

	if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
		goto done;

	if ((result = tpm_rqu_build(TPM_ORD_DisableOwnerClear, &offset, txBlob, ownerAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_DisableOwnerClear, txBlob, paramSize, ownerAuth);
	}
	LogResult("DisableOwnerClear", result);
done:
	auth_mgr_release_auth(ownerAuth, NULL, hContext);
	return result;
}

TSS_RESULT
TCSP_ForceClear_Internal(TCS_CONTEXT_HANDLE hContext)	/* in */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering Force Clear");
	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_ForceClear, &offset, txBlob, NULL)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);
	LogResult("Force Clear", result);
	return result;
}

TSS_RESULT
TCSP_DisableForceClear_Internal(TCS_CONTEXT_HANDLE hContext)	/* in */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering Disable Force Clear");
	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_DisableForceClear, &offset, txBlob, NULL)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);
	LogResult("Disable Force Clear", result);
	return result;
}

TSS_RESULT
TCSP_PhysicalPresence_Internal(TCS_CONTEXT_HANDLE hContext, /* in */
			TCPA_PHYSICAL_PRESENCE fPhysicalPresence) /* in */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result = TCSERR(TSS_E_NOTIMPL);
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];
	char runlevel;

	runlevel = platform_get_runlevel();

	if (runlevel != 's' && runlevel != 'S' && runlevel != '1') {
		LogInfo("Physical Presence command denied: Must be in single"
				" user mode.");
		return TCSERR(TSS_E_NOTIMPL);
	}

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = tpm_rqu_build(TSC_ORD_PhysicalPresence, &offset, txBlob, fPhysicalPresence)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	return UnloadBlob_Header(txBlob, &paramSize);
}

TSS_RESULT
TCSP_PhysicalDisable_Internal(TCS_CONTEXT_HANDLE hContext)	/* in */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering Physical Disable");
	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_PhysicalDisable, &offset, txBlob, NULL)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);
	LogResult("Physical Disable", result);

	return result;
}

TSS_RESULT
TCSP_PhysicalEnable_Internal(TCS_CONTEXT_HANDLE hContext)	/* in */
{
	UINT64 offset = 0;
	TSS_RESULT result;
	UINT32 paramSize;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering Physical Enable");
	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_PhysicalEnable, &offset, txBlob, NULL)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);
	LogResult("Physical Enable", result);

	return result;
}

TSS_RESULT
TCSP_PhysicalSetDeactivated_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
				     TSS_BOOL state)	/* in */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering Physical Set Deactivated");
	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_PhysicalSetDeactivated, &offset, txBlob, state, NULL)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);
	LogResult("PhysicalSetDeactivated", result);
	return result;
}

TSS_RESULT
TCSP_SetTempDeactivated_Internal(TCS_CONTEXT_HANDLE hContext)	/* in */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering Set Temp Deactivated");
	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_SetTempDeactivated, &offset, txBlob, NULL)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);
	LogResult("SetTempDeactivated", result);

	return result;
}

#ifdef TSS_BUILD_TSS12
TSS_RESULT
TCSP_SetTempDeactivated2_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
				  TPM_AUTH * operatorAuth)	/* in, out */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering Set Temp Deactivated2");
	if ((result = ctx_verify_context(hContext)))
		return result;

	if (operatorAuth) {
		if ((result = auth_mgr_check(hContext, &operatorAuth->AuthHandle)))
			return result;
	}

	if ((result = tpm_rqu_build(TPM_ORD_SetTempDeactivated, &offset, txBlob, operatorAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);

	if (!result) {
			result = tpm_rsp_parse(TPM_ORD_SetTempDeactivated, txBlob, paramSize,
					       operatorAuth);
	}

	LogResult("SetTempDeactivated2", result);

done:
	auth_mgr_release_auth(operatorAuth, NULL, hContext);

	return result;
}
#endif

TSS_RESULT
TCSP_FieldUpgrade_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			   UINT32 dataInSize,	/* in */
			   BYTE * dataIn,	/* in */
			   UINT32 * dataOutSize,	/* out */
			   BYTE ** dataOut,	/* out */
			   TPM_AUTH * ownerAuth)	/* in, out */
{
	TSS_RESULT result;
	UINT32 paramSize;
	UINT64 offset = 0;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Field Upgrade");

	if ((result = ctx_verify_context(hContext)))
		goto done;

	if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
		goto done;

	if ((result = tpm_rqu_build(TPM_ORD_FieldUpgrade, &offset, txBlob, dataInSize, dataInSize,
				    dataIn, ownerAuth, NULL)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);

	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_FieldUpgrade, txBlob, paramSize, dataOutSize,
				       dataOut, ownerAuth);
	}
	LogResult("Field Upgrade", result);
done:
	auth_mgr_release_auth(ownerAuth, NULL, hContext);
	return result;
}

TSS_RESULT
TCSP_SetRedirection_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			     TCS_KEY_HANDLE keyHandle,	/* in */
			     UINT32 c1,	/* in */
			     UINT32 c2,	/* in */
			     TPM_AUTH * privAuth)	/* in, out */
{
	TSS_RESULT result;
	UINT32 paramSize;
	UINT64 offset = 0;
	TCPA_KEY_HANDLE keySlot;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Set Redirection");

	if ((result = ctx_verify_context(hContext)))
		goto done;

	if (privAuth != NULL) {
		if ((result = auth_mgr_check(hContext, &privAuth->AuthHandle)))
			goto done;
	}

	if ((result = ensureKeyIsLoaded(hContext, keyHandle, &keySlot))) {
		result = TCSERR(TSS_E_FAIL);
		goto done;
	}

	if ((result = tpm_rqu_build(TPM_ORD_SetRedirection, &offset, txBlob, keySlot, c1, c2,
				    privAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);

	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_SetRedirection, txBlob, paramSize, privAuth);
	}
	LogResult("Set Redirection", result);
done:
	auth_mgr_release_auth(privAuth, NULL, hContext);
	return result;
}

#ifdef TSS_BUILD_TSS12
TSS_RESULT
TCSP_ResetLockValue_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			     TPM_AUTH * ownerAuth)	/* in, out */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	if ((result = ctx_verify_context(hContext)))
		goto done;

	if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
		goto done;

	if ((result = tpm_rqu_build(TPM_ORD_ResetLockValue, &offset, txBlob, ownerAuth)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_ResetLockValue, txBlob, paramSize, ownerAuth);
	}

done:
	auth_mgr_release_auth(ownerAuth, NULL, hContext);
	return result;
}

TSS_RESULT
TCSP_FlushSpecific_Common(UINT32 tpmResHandle, TPM_RESOURCE_TYPE resourceType)
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	if ((result = tpm_rqu_build(TPM_ORD_FlushSpecific, &offset, txBlob, tpmResHandle,
				    resourceType)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_FlushSpecific, txBlob, paramSize, NULL);
	}

	return result;
}

TSS_RESULT
TCSP_FlushSpecific_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			    TCS_HANDLE hResHandle,	/* in */
			    TPM_RESOURCE_TYPE resourceType) /* in */
{
	UINT32 tpmResHandle;
	TSS_RESULT result;

	if ((result = ctx_verify_context(hContext)))
		return result;

	switch (resourceType) {
		case TPM_RT_KEY:
			if ((result = get_slot_lite(hContext, hResHandle, &tpmResHandle)))
				return result;

			if ((result = ctx_remove_key_loaded(hContext, hResHandle)))
				return result;

			if ((result = key_mgr_dec_ref_count(hResHandle)))
				return result;
			break;
		case TPM_RT_AUTH:
			if ((result = auth_mgr_check(hContext, &hResHandle)))
				return result;

			auth_mgr_release_auth_handle(hResHandle, hContext, FALSE);
			/* fall through */
		case TPM_RT_TRANS:
		case TPM_RT_DAA_TPM:
			tpmResHandle = hResHandle;
			break;
		case TPM_RT_CONTEXT:
			result = TCSERR(TSS_E_NOTIMPL);
			goto done;
		default:
			LogDebugFn("Unknown resource type: 0x%x", resourceType);
			goto done;
	}

	result = TCSP_FlushSpecific_Common(tpmResHandle, resourceType);

done:
	return result;
}
#endif



<|start_filename|>src/include/tss/tcpa_error.h<|end_filename|>

#ifndef __TCPA_ERROR_H__
#define __TCPA_ERROR_H__

#warning including deprecated header file tcpa_error.h

#endif


<|start_filename|>src/tspi/tspi_transport.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


TSS_RESULT
Tspi_Context_SetTransEncryptionKey(TSS_HCONTEXT hContext,	/* in */
				   TSS_HKEY     hIdentKey)	/* in */
{
	if (!obj_is_rsakey(hIdentKey))
		return TSPERR(TSS_E_INVALID_HANDLE);

	return obj_context_set_transport_key(hContext, hIdentKey);
}

TSS_RESULT
Tspi_Context_CloseSignTransport(TSS_HCONTEXT    hContext,		/* in */
				TSS_HKEY        hSigningKey,		/* in */
				TSS_VALIDATION* pValidationData)	/* in, out */
{
	TSS_RESULT result;
	TSS_HPOLICY hPolicy;
	TSS_BOOL usesAuth;
	UINT32 sigLen;
	BYTE *sig;
	UINT64 offset;
	Trspi_HashCtx hashCtx;
	TPM_DIGEST digest;
	TPM_SIGN_INFO signInfo;

	if (!obj_is_context(hContext))
		return TSPERR(TSS_E_INVALID_HANDLE);

	if ((result = obj_rsakey_get_policy(hSigningKey, TSS_POLICY_USAGE, &hPolicy, &usesAuth)))
		return result;

	if (pValidationData) {
		if (pValidationData->ulExternalDataLength != sizeof(TPM_NONCE))
			return TSPERR(TSS_E_BAD_PARAMETER);

		memcpy(signInfo.replay.nonce, pValidationData->rgbExternalData, sizeof(TPM_NONCE));
	} else {
		if ((result = get_local_random(hContext, FALSE, sizeof(TPM_NONCE),
					       (BYTE **)&signInfo.replay.nonce)))
			return result;
	}

	/* the transport sessions properties are kept in the context object itself, so just pass
	 * in what this function provides and let it call ReleaseTransportSigned */
	if ((result = obj_context_transport_close(hContext, hSigningKey, hPolicy, usesAuth,
						  &signInfo, &sigLen, &sig)))
		return result;

	/* inside obj_context_transport_close we set up all the fields of the sign info structure
	 * other than the tag and 'fixed' */
	signInfo.tag = TPM_TAG_SIGNINFO;
	signInfo.fixed[0] = 'T';
	signInfo.fixed[1] = 'R';
	signInfo.fixed[2] = 'A';
	signInfo.fixed[3] = 'N';

	/* hash the sign info struct for use in verifying the TPM's signature */
	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_SIGN_INFO(&hashCtx, &signInfo);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
		free(sig);
		return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	offset = 0;
	if (pValidationData) {
		/* tag the returned allocated memory as alloc'd by the TSP */
		if ((result = __tspi_add_mem_entry(hContext, sig))) {
			free(sig);
			return TSPERR(TSS_E_INTERNAL_ERROR);
		}
		pValidationData->rgbValidationData = sig;
		pValidationData->ulValidationDataLength = sigLen;

		/* passing a NULL blob here puts the exact size of TPM_SIGN_INFO into offset */
		Trspi_LoadBlob_SIGN_INFO(&offset, NULL, &signInfo);
		pValidationData->rgbData = calloc_tspi(hContext, offset);
		if (pValidationData->rgbData == NULL) {
			LogError("malloc of %" PRIu64 " bytes failed.", offset);
			free_tspi(hContext, pValidationData->rgbValidationData);
			pValidationData->rgbValidationData = NULL;
			pValidationData->ulValidationDataLength = 0;
			return TSPERR(TSS_E_OUTOFMEMORY);
		}
		pValidationData->ulDataLength = (UINT32)offset;

		offset = 0;
		Trspi_LoadBlob_SIGN_INFO(&offset, pValidationData->rgbData, &signInfo);
	} else
		result = __tspi_rsa_verify(hSigningKey, TSS_HASH_SHA1, sizeof(TPM_DIGEST), digest.digest,
				    sigLen, sig);

	return result;
}


<|start_filename|>src/tspi/tspi_caps_tpm.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


TSS_RESULT
Tspi_TPM_GetCapability(TSS_HTPM hTPM,			/* in */
		       TSS_FLAG capArea,		/* in */
		       UINT32 ulSubCapLength,		/* in */
		       BYTE * rgbSubCap,		/* in */
		       UINT32 * pulRespDataLength,	/* out */
		       BYTE ** prgbRespData)		/* out */
{
	TSS_HCONTEXT tspContext;
	TPM_CAPABILITY_AREA tcsCapArea;
	UINT32 tcsSubCap = 0;
	UINT32 tcsSubCapContainer;
	TSS_RESULT result;
	UINT32 nonVolFlags, volFlags, respLen;
	BYTE *respData;
	UINT64 offset;
	TSS_BOOL fOwnerAuth = FALSE, endianFlag = TRUE;

	if (pulRespDataLength == NULL || prgbRespData == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
		return result;

	/* Verify the caps and subcaps */
	switch (capArea) {
	case TSS_TPMCAP_ORD:
		if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap)
			return TSPERR(TSS_E_BAD_PARAMETER);

		tcsCapArea = TCPA_CAP_ORD;
		tcsSubCap = *(UINT32 *)rgbSubCap;
		break;
	case TSS_TPMCAP_FLAG:
		fOwnerAuth = TRUE;
		break;
	case TSS_TPMCAP_AUTH_ENCRYPT:
	case TSS_TPMCAP_ALG:
		if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap)
			return TSPERR(TSS_E_BAD_PARAMETER);

		/* Test capArea again here in order to keep from having to duplicate the switch
		 * statement below */
		tcsCapArea = (capArea == TSS_TPMCAP_ALG ? TPM_CAP_ALG : TPM_CAP_AUTH_ENCRYPT);

		switch (*(UINT32 *)rgbSubCap) {
		case TSS_ALG_RSA:
			tcsSubCap = TPM_ALG_RSA;
			break;
		case TSS_ALG_AES128:
			tcsSubCap = TPM_ALG_AES128;
			break;
		case TSS_ALG_AES192:
			tcsSubCap = TPM_ALG_AES192;
			break;
		case TSS_ALG_AES256:
			tcsSubCap = TPM_ALG_AES256;
			break;
		case TSS_ALG_3DES:
			tcsSubCap = TPM_ALG_3DES;
			break;
		case TSS_ALG_DES:
			tcsSubCap = TPM_ALG_DES;
			break;
		case TSS_ALG_SHA:
			tcsSubCap = TPM_ALG_SHA;
			break;
		case TSS_ALG_HMAC:
			tcsSubCap = TPM_ALG_HMAC;
			break;
		case TSS_ALG_MGF1:
			tcsSubCap = TPM_ALG_MGF1;
			break;
		case TSS_ALG_XOR:
			tcsSubCap = TPM_ALG_XOR;
			break;
		default:
			tcsSubCap = *(UINT32 *)rgbSubCap;
			break;
		}
		break;
#ifdef TSS_BUILD_NV
	case TSS_TPMCAP_NV_LIST:
		tcsCapArea = TPM_CAP_NV_LIST;
		endianFlag = FALSE;
		break;
	case TSS_TPMCAP_NV_INDEX:
		if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap)
			return TSPERR(TSS_E_BAD_PARAMETER);

		tcsCapArea = TPM_CAP_NV_INDEX;
		tcsSubCap = *(UINT32 *)rgbSubCap;
		break;
#endif
	case TSS_TPMCAP_PROPERTY:	/* Determines a physical property of the TPM. */
		if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap)
			return TSPERR(TSS_E_BAD_PARAMETER);

		tcsCapArea = TCPA_CAP_PROPERTY;
		tcsSubCapContainer = *(UINT32 *)rgbSubCap;

		switch (tcsSubCapContainer) {
		case TSS_TPMCAP_PROP_PCR:
			tcsSubCap = TPM_CAP_PROP_PCR;
			break;
		case TSS_TPMCAP_PROP_DIR:
			tcsSubCap = TPM_CAP_PROP_DIR;
			break;
		/* case TSS_TPMCAP_PROP_SLOTS: */
		case TSS_TPMCAP_PROP_KEYS:
			tcsSubCap = TPM_CAP_PROP_SLOTS;
			break;
		case TSS_TPMCAP_PROP_MANUFACTURER:
			tcsSubCap = TPM_CAP_PROP_MANUFACTURER;
			endianFlag = FALSE;
			break;
		case TSS_TPMCAP_PROP_COUNTERS:
			tcsSubCap = TPM_CAP_PROP_COUNTERS;
			break;
		case TSS_TPMCAP_PROP_MAXCOUNTERS:
			tcsSubCap = TPM_CAP_PROP_MAX_COUNTERS;
			break;
		/*case TSS_TPMCAP_PROP_MINCOUNTERINCTIME: */
		case TSS_TPMCAP_PROP_MIN_COUNTER:
			tcsSubCap = TPM_CAP_PROP_MIN_COUNTER;
			break;
		case TSS_TPMCAP_PROP_ACTIVECOUNTER:
			tcsSubCap = TPM_CAP_PROP_ACTIVE_COUNTER;
			break;
		case TSS_TPMCAP_PROP_TRANSESSIONS:
			tcsSubCap = TPM_CAP_PROP_TRANSSESS;
			break;
		case TSS_TPMCAP_PROP_MAXTRANSESSIONS:
			tcsSubCap = TPM_CAP_PROP_MAX_TRANSSESS;
			break;
		case TSS_TPMCAP_PROP_SESSIONS:
			tcsSubCap = TPM_CAP_PROP_SESSIONS;
			break;
		case TSS_TPMCAP_PROP_MAXSESSIONS:
			tcsSubCap = TPM_CAP_PROP_MAX_SESSIONS;
			break;
		case TSS_TPMCAP_PROP_FAMILYROWS:
			tcsSubCap = TPM_CAP_PROP_FAMILYROWS;
			break;
		case TSS_TPMCAP_PROP_DELEGATEROWS:
			tcsSubCap = TPM_CAP_PROP_DELEGATE_ROW;
			break;
		case TSS_TPMCAP_PROP_OWNER:
			tcsSubCap = TPM_CAP_PROP_OWNER;
			break;
		case TSS_TPMCAP_PROP_MAXKEYS:
			tcsSubCap = TPM_CAP_PROP_MAX_KEYS;
			break;
		case TSS_TPMCAP_PROP_AUTHSESSIONS:
			tcsSubCap = TPM_CAP_PROP_AUTHSESS;
			break;
		case TSS_TPMCAP_PROP_MAXAUTHSESSIONS:
			tcsSubCap = TPM_CAP_PROP_MAX_AUTHSESS;
			break;
		case TSS_TPMCAP_PROP_CONTEXTS:
			tcsSubCap = TPM_CAP_PROP_CONTEXT;
			break;
		case TSS_TPMCAP_PROP_MAXCONTEXTS:
			tcsSubCap = TPM_CAP_PROP_MAX_CONTEXT;
			break;
		case TSS_TPMCAP_PROP_DAASESSIONS:
			tcsSubCap = TPM_CAP_PROP_SESSION_DAA;
			break;
		case TSS_TPMCAP_PROP_MAXDAASESSIONS:
			tcsSubCap = TPM_CAP_PROP_DAA_MAX;
			break;
		case TSS_TPMCAP_PROP_TISTIMEOUTS:
			tcsSubCap = TPM_CAP_PROP_TIS_TIMEOUT;
			break;
		case TSS_TPMCAP_PROP_STARTUPEFFECTS:
			tcsSubCap = TPM_CAP_PROP_STARTUP_EFFECT;
			endianFlag = FALSE;
			break;
		case TSS_TPMCAP_PROP_MAXCONTEXTCOUNTDIST:
			tcsSubCap = TPM_CAP_PROP_CONTEXT_DIST;
			break;
		case TSS_TPMCAP_PROP_CMKRESTRICTION:
			tcsSubCap = TPM_CAP_PROP_CMK_RESTRICTION;
			break;
		case TSS_TPMCAP_PROP_DURATION:
			tcsSubCap = TPM_CAP_PROP_DURATION;
			break;
		case TSS_TPMCAP_PROP_MAXNVAVAILABLE:
			tcsSubCap = TPM_CAP_PROP_NV_AVAILABLE;
			break;
		case TSS_TPMCAP_PROP_INPUTBUFFERSIZE:
			tcsSubCap = TPM_CAP_PROP_INPUT_BUFFER;
			break;
#if 0
		/* There isn't a way to query the TPM for these, the TPMWG is considering how to
		 * address some of them in the next version of the TPM - KEY Oct 15, 2007*/
		case TSS_TPMCAP_PROP_MAXNVWRITE:
			break;
		case TSS_TPMCAP_PROP_REVISION:
			break;
		case TSS_TPMCAP_PROP_LOCALITIES_AVAIL:
			break;
		case TSS_TPMCAP_PROP_PCRMAP:
			break;
#endif
		default:
			return TSPERR(TSS_E_BAD_PARAMETER);
		}
		break;
	case TSS_TPMCAP_VERSION:	/* Queries the current TPM version. */
		tcsCapArea = TCPA_CAP_VERSION;
		endianFlag = FALSE;
		break;
	case TSS_TPMCAP_VERSION_VAL:	/* Queries the current TPM version for 1.2 TPM device. */
		tcsCapArea = TPM_CAP_VERSION_VAL;
		endianFlag = FALSE;
		break;
	case TSS_TPMCAP_MFR:
		tcsCapArea = TPM_CAP_MFR;
		endianFlag = FALSE;
		break;
	case TSS_TPMCAP_SYM_MODE:
		if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap)
			return TSPERR(TSS_E_BAD_PARAMETER);

		tcsCapArea = TPM_CAP_SYM_MODE;
		tcsSubCap = *(UINT32 *)rgbSubCap;
		break;
	case TSS_TPMCAP_HANDLE:
		if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap)
			return TSPERR(TSS_E_BAD_PARAMETER);

		tcsCapArea = TPM_CAP_HANDLE;
		tcsSubCap = *(UINT32 *)rgbSubCap;
		break;
	case TSS_TPMCAP_TRANS_ES:
		if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap)
			return TSPERR(TSS_E_BAD_PARAMETER);

		tcsCapArea = TPM_CAP_TRANS_ES;
		switch (*(UINT32 *)rgbSubCap) {
		case TSS_ES_NONE:
			tcsSubCap = TPM_ES_NONE;
			break;
		case TSS_ES_RSAESPKCSV15:
			tcsSubCap = TPM_ES_RSAESPKCSv15;
			break;
		case TSS_ES_RSAESOAEP_SHA1_MGF1:
			tcsSubCap = TPM_ES_RSAESOAEP_SHA1_MGF1;
			break;
		case TSS_ES_SYM_CNT:
			tcsSubCap = TPM_ES_SYM_CNT;
			break;
		case TSS_ES_SYM_OFB:
			tcsSubCap = TPM_ES_SYM_OFB;
			break;
		case TSS_ES_SYM_CBC_PKCS5PAD:
			tcsSubCap = TPM_ES_SYM_CBC_PKCS5PAD;
			break;
		default:
			tcsSubCap = *(UINT32 *)rgbSubCap;
			break;
		}
		break;
	default:
		return TSPERR(TSS_E_BAD_PARAMETER);
		break;
	}

	if (fOwnerAuth) {
		/* do an owner authorized get capability call */
		if ((result = get_tpm_flags(tspContext, hTPM, &volFlags, &nonVolFlags)))
			return result;

		respLen = 2 * sizeof(UINT32);
		respData = calloc_tspi(tspContext, respLen);
		if (respData == NULL) {
			LogError("malloc of %u bytes failed.", respLen);
			return TSPERR(TSS_E_OUTOFMEMORY);
		}

		offset = 0;
		Trspi_LoadBlob_UINT32(&offset, nonVolFlags, respData);
		Trspi_LoadBlob_UINT32(&offset, volFlags, respData);

		*pulRespDataLength = respLen;
		*prgbRespData = respData;

		return TSS_SUCCESS;
	}

	tcsSubCap = endian32(tcsSubCap);

	if ((result = TCS_API(tspContext)->GetTPMCapability(tspContext, tcsCapArea, ulSubCapLength,
							    (BYTE *)&tcsSubCap, pulRespDataLength,
							    prgbRespData)))
		return result;

	if (endianFlag) {
		if (*pulRespDataLength == sizeof(UINT32))
			*(UINT32 *)(*prgbRespData) = endian32(*(UINT32 *)(*prgbRespData));
		else if (*pulRespDataLength == sizeof(UINT16))
			*(UINT32 *)(*prgbRespData) = endian16(*(UINT32 *)(*prgbRespData));
	}

	if ((result = __tspi_add_mem_entry(tspContext, *prgbRespData))) {
		free(*prgbRespData);
		*prgbRespData = NULL;
		*pulRespDataLength = 0;
		return result;
	}

	return TSS_SUCCESS;
}

TSS_RESULT
Tspi_TPM_GetCapabilitySigned(TSS_HTPM hTPM,			/* in */
			     TSS_HTPM hKey,			/* in */
			     TSS_FLAG capArea,			/* in */
			     UINT32 ulSubCapLength,		/* in */
			     BYTE * rgbSubCap,			/* in */
			     TSS_VALIDATION * pValidationData,	/* in, out */
			     UINT32 * pulRespDataLength,	/* out */
			     BYTE ** prgbRespData)		/* out */
{
	/*
	 * Function was found to have a vulnerability, so implementation is not
	 * required by the TSS 1.1b spec.
	 */
	return TSPERR(TSS_E_NOTIMPL);
}



<|start_filename|>src/tspi/tspi_caps.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "tcs_tsp.h"
#include "tspps.h"
#include "tcsd_wrap.h"
#include "tcsd.h"
#include "obj.h"


TSS_RESULT
Tspi_Context_GetCapability(TSS_HCONTEXT tspContext,	/* in */
			   TSS_FLAG capArea,		/* in */
			   UINT32 ulSubCapLength,	/* in */
			   BYTE * rgbSubCap,		/* in */
			   UINT32 * pulRespDataLength,	/* out */
			   BYTE ** prgbRespData)	/* out */
{
	TSS_RESULT result;

	if (prgbRespData == NULL || pulRespDataLength == NULL )
		return TSPERR(TSS_E_BAD_PARAMETER);

	if (rgbSubCap == NULL && ulSubCapLength != 0)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if (ulSubCapLength > sizeof(UINT32))
		return TSPERR(TSS_E_BAD_PARAMETER);

	if (!obj_is_context(tspContext))
		return TSPERR(TSS_E_INVALID_HANDLE);

	switch (capArea) {
		case TSS_TSPCAP_ALG:
		case TSS_TSPCAP_RETURNVALUE_INFO:
		case TSS_TSPCAP_PLATFORM_INFO:
		case TSS_TSPCAP_MANUFACTURER:
			if (ulSubCapLength != sizeof(UINT32) || !rgbSubCap)
				return TSPERR(TSS_E_BAD_PARAMETER);
			/* fall through */
		case TSS_TSPCAP_VERSION:
		case TSS_TSPCAP_PERSSTORAGE:
			result = internal_GetCap(tspContext, capArea,
						 rgbSubCap ? *(UINT32 *)rgbSubCap : 0,
						 pulRespDataLength,
						 prgbRespData);
			break;
		case TSS_TCSCAP_ALG:
			if (ulSubCapLength != sizeof(UINT32) || !rgbSubCap)
				return TSPERR(TSS_E_BAD_PARAMETER);
			/* fall through */
		case TSS_TCSCAP_VERSION:
		case TSS_TCSCAP_CACHING:
		case TSS_TCSCAP_PERSSTORAGE:
		case TSS_TCSCAP_MANUFACTURER:
		case TSS_TCSCAP_TRANSPORT:
		case TSS_TCSCAP_PLATFORM_CLASS:
			result = RPC_GetCapability(tspContext, capArea, ulSubCapLength, rgbSubCap,
						   pulRespDataLength, prgbRespData);
			break;
		default:
			LogDebug("Invalid capArea: 0x%x", capArea);
			result = TSPERR(TSS_E_BAD_PARAMETER);
			break;
	}

	return result;
}


<|start_filename|>src/tspi/tspi_asn1.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <openssl/asn1.h>
#include <openssl/asn1t.h>

#ifndef TSS_BUILD_ASN1_OPENSSL
#include <arpa/inet.h>
#endif

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "tsplog.h"

#define TSS_OPENSSL_ASN1_ERROR	(0xffffffff)

#if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
#define OPENSSL_COMPAT_CONST const
#else
#define OPENSSL_COMPAT_CONST
#endif

#define OPENSSL_COMPAT_ASN1_SEQUENCE(tname) \
	static const ASN1_TEMPLATE tname##_seq_tt[] 

typedef struct tdTSS_BLOB {
	ASN1_INTEGER *		structVersion;
	ASN1_INTEGER *		blobType;
	ASN1_INTEGER *		blobLength;
	ASN1_OCTET_STRING *	blob;
} TSS_BLOB;

OPENSSL_COMPAT_ASN1_SEQUENCE(TSS_BLOB) = {
	ASN1_SIMPLE(TSS_BLOB, structVersion, ASN1_INTEGER),
	ASN1_SIMPLE(TSS_BLOB, blobType, ASN1_INTEGER),
	ASN1_SIMPLE(TSS_BLOB, blobLength, ASN1_INTEGER),
	ASN1_SIMPLE(TSS_BLOB, blob, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(TSS_BLOB)
IMPLEMENT_ASN1_FUNCTIONS(TSS_BLOB)


TSS_RESULT
Tspi_EncodeDER_TssBlob(UINT32 rawBlobSize,		/* in */
			BYTE *rawBlob,			/* in */
			UINT32 blobType,		/* in */
			UINT32 *derBlobSize,		/* in/out */
			BYTE *derBlob)			/* out */
{
#ifdef TSS_BUILD_ASN1_OPENSSL
	TSS_BLOB *tssBlob = NULL;
#endif
	BYTE *encBlob = NULL;
	UINT32 encBlobLen;

	if ((rawBlobSize == 0) || (rawBlob == NULL))
		return TSPERR(TSS_E_BAD_PARAMETER);

	if ((blobType < TSS_BLOB_TYPE_KEY) || (blobType > TSS_BLOB_TYPE_CMK_BYTE_STREAM))
		return TSPERR(TSS_E_BAD_PARAMETER);

	if ((*derBlobSize != 0) && (derBlob == NULL))
		return TSPERR(TSS_E_BAD_PARAMETER);

	/* The TSS working group has stated that the ASN1 encoding will be done in a
	 * specific way that generates an ASN1 encoding that is exactly 20 bytes
	 * larger than the blob being encoded.
	 *
	 * OpenSSL uses the smallest number of bytes possible to encode and object
	 * and as a result cannot be used to perform the encoding.  The encoding
	 * must be done manually.
	 *
	 * The 20 byte fixed header will result in issues for objects greater than
	 * 2^16 in size since some fields are now limited to 16-bit lengths.
	 */

#ifdef TSS_BUILD_ASN1_OPENSSL
	tssBlob = TSS_BLOB_new();
	if (!tssBlob)
		return TSPERR(TSS_E_OUTOFMEMORY);

	if (ASN1_INTEGER_set(tssBlob->structVersion, TSS_BLOB_STRUCT_VERSION) == 0) {
		TSS_BLOB_free(tssBlob);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	if (ASN1_INTEGER_set(tssBlob->blobType, blobType) == 0) {
		TSS_BLOB_free(tssBlob);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	if (ASN1_INTEGER_set(tssBlob->blobLength, rawBlobSize) == 0) {
		TSS_BLOB_free(tssBlob);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	if (ASN1_OCTET_STRING_set(tssBlob->blob, rawBlob, rawBlobSize) == 0) {
		TSS_BLOB_free(tssBlob);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	encBlobLen = i2d_TSS_BLOB(tssBlob, &encBlob);
	if (encBlobLen <= 0) {
		TSS_BLOB_free(tssBlob);
		return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	if (*derBlobSize != 0) {
		if (encBlobLen <= *derBlobSize) {
			memcpy(derBlob, encBlob, encBlobLen);
		}
		else {
			OPENSSL_free(encBlob);
			TSS_BLOB_free(tssBlob);
			return TSPERR(TSS_E_BAD_PARAMETER);
		}
	}

	*derBlobSize = encBlobLen;

	OPENSSL_free(encBlob);
	TSS_BLOB_free(tssBlob);
#else
	if ((rawBlobSize + 16) > UINT16_MAX)
		return TSPERR(TSS_E_INTERNAL_ERROR);

	encBlobLen = rawBlobSize + 20;

	if (*derBlobSize != 0) {
		if (encBlobLen <= *derBlobSize) {
			UINT16 *pShort;
			UINT32 *pLong;

			encBlob = derBlob;
			encBlob[0] = 0x30;	/* Sequence tag */
			encBlob[1] = 0x82;	/* Length in the two octets that follow */
			encBlob += 2;
			pShort = (UINT16 *)encBlob;
			*pShort = htons(rawBlobSize + 16);
			encBlob += sizeof(UINT16);

			encBlob[0] = 0x02;	/* Integer tag */
			encBlob[1] = 0x01;	/* Length is one */
			encBlob[2] = (BYTE)TSS_BLOB_STRUCT_VERSION;
			encBlob += 3;

			encBlob[0] = 0x02;	/* Integer tag */
			encBlob[1] = 0x01;	/* Length is one */
			encBlob[2] = (BYTE)blobType;
			encBlob += 3;

			encBlob[0] = 0x02;	/* Integer tag */
			encBlob[1] = 0x04;	/* Length is four */
			encBlob += 2;
			pLong = (UINT32 *)encBlob;
			*pLong = htonl(rawBlobSize);
			encBlob += sizeof(UINT32);

			encBlob[0] = 0x04;	/* Octet string tag */
			encBlob[1] = 0x82;	/* Length in the two octets that follow */
			encBlob += 2;
			pShort = (UINT16 *)encBlob;
			*pShort = htons(rawBlobSize);
			encBlob += sizeof(UINT16);
			memcpy(encBlob, rawBlob, rawBlobSize);
		}
		else
			return TSPERR(TSS_E_BAD_PARAMETER);
	}

	*derBlobSize = encBlobLen;
#endif

	return TSS_SUCCESS;
}

TSS_RESULT
Tspi_DecodeBER_TssBlob(UINT32 berBlobSize,		/* in */
			BYTE *berBlob,			/* in */
			UINT32 *blobType,		/* out */
			UINT32 *rawBlobSize,		/* in/out */
			BYTE *rawBlob)			/* out */
{
	TSS_BLOB *tssBlob = NULL;
	OPENSSL_COMPAT_CONST BYTE *encBlob = berBlob;

	UINT32 encBlobLen = berBlobSize;
	UINT32 decStructVersion, decBlobType, decBlobSize;

	if ((berBlobSize == 0) || (berBlob == NULL))
		return TSPERR(TSS_E_BAD_PARAMETER);

	if ((*rawBlobSize != 0) && (rawBlob == NULL))
		return TSPERR(TSS_E_BAD_PARAMETER);

	tssBlob = d2i_TSS_BLOB(NULL, &encBlob, encBlobLen);
	if (!tssBlob)
		return TSPERR(TSS_E_INTERNAL_ERROR);

	decStructVersion = ASN1_INTEGER_get(tssBlob->structVersion);
	if (decStructVersion == TSS_OPENSSL_ASN1_ERROR) {
		TSS_BLOB_free(tssBlob);
		return TSPERR(TSS_E_INTERNAL_ERROR);
	}
	if (decStructVersion > TSS_BLOB_STRUCT_VERSION) {
		TSS_BLOB_free(tssBlob);
		return TSPERR(TSS_E_BAD_PARAMETER);
	}

	decBlobType = ASN1_INTEGER_get(tssBlob->blobType);
	if (decBlobType == TSS_OPENSSL_ASN1_ERROR) {
		TSS_BLOB_free(tssBlob);
		return TSPERR(TSS_E_INTERNAL_ERROR);
	}
	if ((decBlobType < TSS_BLOB_TYPE_KEY) || (decBlobType > TSS_BLOB_TYPE_CMK_BYTE_STREAM)) {
		TSS_BLOB_free(tssBlob);
		return TSPERR(TSS_E_BAD_PARAMETER);
	}

	decBlobSize = ASN1_INTEGER_get(tssBlob->blobLength);
	if (decBlobSize == TSS_OPENSSL_ASN1_ERROR) {
		TSS_BLOB_free(tssBlob);
		return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	if (*rawBlobSize != 0) {
		if (decBlobSize <= *rawBlobSize) {
			memcpy(rawBlob, tssBlob->blob->data, decBlobSize);
		}
		else {
			TSS_BLOB_free(tssBlob);
			return TSPERR(TSS_E_BAD_PARAMETER);
		}
	}

	*rawBlobSize = decBlobSize;
	*blobType = decBlobType;

	TSS_BLOB_free(tssBlob);

	return TSS_SUCCESS;
}



<|start_filename|>src/tcs/tcsi_counter.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "tcsps.h"
#include "req_mgr.h"


TSS_RESULT
TCSP_ReadCounter_Internal(TCS_CONTEXT_HANDLE hContext,
			  TSS_COUNTER_ID     idCounter,
			  TPM_COUNTER_VALUE* counterValue)
{
	TSS_RESULT result;
	UINT32 paramSize;
	UINT64 offset = 0;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_ReadCounter, &offset, txBlob, idCounter, NULL)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		goto out;

	if ((result = UnloadBlob_Header(txBlob, &paramSize))) {
		LogDebugFn("TPM_ReadCounter failed: rc=0x%x", result);
		goto out;
	}

	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_ReadCounter, txBlob, paramSize, NULL, counterValue,
				       NULL);
	}

out:
	return result;
}

TSS_RESULT
TCSP_CreateCounter_Internal(TCS_CONTEXT_HANDLE hContext,
			    UINT32             LabelSize,
			    BYTE*              pLabel,
			    TPM_ENCAUTH        CounterAuth,
			    TPM_AUTH*          pOwnerAuth,
			    TSS_COUNTER_ID*    idCounter,
			    TPM_COUNTER_VALUE* counterValue)
{
	TSS_RESULT result;
	UINT32 paramSize;
	UINT64 offset = 0;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	if (LabelSize != 4) {
		LogDebugFn("BAD_PARAMETER: LabelSize != 4");
		return TCSERR(TSS_E_BAD_PARAMETER);
	}

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = auth_mgr_check(hContext, &pOwnerAuth->AuthHandle)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_CreateCounter, &offset, txBlob, CounterAuth.authdata,
				    LabelSize, pLabel, pOwnerAuth)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		goto out;

	if ((result = UnloadBlob_Header(txBlob, &paramSize))) {
		LogDebugFn("TPM_CreateCounter failed: rc=0x%x", result);
		goto out;
	}

	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_CreateCounter, txBlob, paramSize, idCounter,
				       counterValue, pOwnerAuth);
	}

out:
	return result;
}

TSS_RESULT
TCSP_IncrementCounter_Internal(TCS_CONTEXT_HANDLE hContext,
			       TSS_COUNTER_ID     idCounter,
			       TPM_AUTH*          pCounterAuth,
			       TPM_COUNTER_VALUE* counterValue)
{
	TSS_RESULT result;
	UINT32 paramSize;
	UINT64 offset = 0;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = auth_mgr_check(hContext, &pCounterAuth->AuthHandle)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_IncrementCounter, &offset, txBlob, idCounter,
				    pCounterAuth)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		goto out;

	if ((result = UnloadBlob_Header(txBlob, &paramSize))) {
		LogDebugFn("UnloadBlob_Header failed: rc=0x%x", result);
		goto out;
	}

	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_IncrementCounter, txBlob, paramSize, NULL,
				       counterValue, pCounterAuth);
	}
out:
	return result;
}

TSS_RESULT
TCSP_ReleaseCounter_Internal(TCS_CONTEXT_HANDLE hContext,
			     TSS_COUNTER_ID     idCounter,
			     TPM_AUTH*          pCounterAuth)
{
	TSS_RESULT result;
	UINT32 paramSize;
	UINT64 offset = 0;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = auth_mgr_check(hContext, &pCounterAuth->AuthHandle)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_ReleaseCounter, &offset, txBlob, idCounter,
				    pCounterAuth)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		goto out;

	if ((result = UnloadBlob_Header(txBlob, &paramSize))) {
		LogDebugFn("UnloadBlob_Header failed: rc=0x%x", result);
		goto out;
	}

	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_ReleaseCounter, txBlob, paramSize, pCounterAuth);
	}
out:
	return result;
}

TSS_RESULT
TCSP_ReleaseCounterOwner_Internal(TCS_CONTEXT_HANDLE hContext,
				  TSS_COUNTER_ID     idCounter,
				  TPM_AUTH*          pOwnerAuth)
{
	TSS_RESULT result;
	UINT32 paramSize;
	UINT64 offset = 0;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = auth_mgr_check(hContext, &pOwnerAuth->AuthHandle)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_ReleaseCounterOwner, &offset, txBlob, idCounter,
				    pOwnerAuth)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		goto out;

	if ((result = UnloadBlob_Header(txBlob, &paramSize))) {
		LogDebugFn("UnloadBlob_Header failed: rc=0x%x", result);
		goto out;
	}

	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_ReleaseCounterOwner, txBlob, paramSize, pOwnerAuth);
	}
out:
	return result;
}



<|start_filename|>src/tcs/tcsi_migration.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcsps.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "req_mgr.h"
#include "tcsd_wrap.h"
#include "tcsd.h"

TSS_RESULT
TCSP_CreateMigrationBlob_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
				  TCS_KEY_HANDLE parentHandle,	/* in */
				  TSS_MIGRATE_SCHEME migrationType,	/* in */
				  UINT32 MigrationKeyAuthSize,	/* in */
				  BYTE * MigrationKeyAuth,	/* in */
				  UINT32 encDataSize,	/* in */
				  BYTE * encData,	/* in */
				  TPM_AUTH * parentAuth,	/* in, out */
				  TPM_AUTH * entityAuth,	/* in, out */
				  UINT32 * randomSize,	/* out */
				  BYTE ** random,	/* out */
				  UINT32 * outDataSize,	/* out */
				  BYTE ** outData)	/* out */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	TCPA_KEY_HANDLE keyHandle;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering TPM_CreateMigrationBlob");

	if ((result = ctx_verify_context(hContext)))
		goto done;

	if (parentAuth != NULL) {
		if ((result = auth_mgr_check(hContext, &parentAuth->AuthHandle)))
			goto done;
	}

	if ((result = auth_mgr_check(hContext, &entityAuth->AuthHandle)))
		goto done;

	if ((result = ensureKeyIsLoaded(hContext, parentHandle, &keyHandle)))
		goto done;

	switch (migrationType) {
		case TSS_MS_MIGRATE:
			migrationType = TCPA_MS_MIGRATE;
			break;
		case TSS_MS_REWRAP:
			migrationType = TCPA_MS_REWRAP;
			break;
		case TSS_MS_MAINT:
			migrationType = TCPA_MS_MAINT;
			break;
		default:
			/* Let the TPM return an error */
			break;
	}

	if ((result = tpm_rqu_build(TPM_ORD_CreateMigrationBlob, &offset, txBlob, keyHandle,
				    migrationType, MigrationKeyAuthSize, MigrationKeyAuth,
				    encDataSize, encData, parentAuth, entityAuth)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (result == TSS_SUCCESS) {
		result = tpm_rsp_parse(TPM_ORD_CreateMigrationBlob, txBlob, paramSize, randomSize,
				       random, outDataSize, outData, parentAuth, entityAuth);
	}
	LogResult("TPM_CreateMigrationBlob", result);

done:
	auth_mgr_release_auth(entityAuth, parentAuth, hContext);
	return result;
}

TSS_RESULT
TCSP_ConvertMigrationBlob_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
				   TCS_KEY_HANDLE parentHandle,	/* in */
				   UINT32 inDataSize,	/* in */
				   BYTE * inData,	/* in */
				   UINT32 randomSize,	/* in */
				   BYTE * random,	/* in */
				   TPM_AUTH * parentAuth,	/* in, out */
				   UINT32 * outDataSize,	/* out */
				   BYTE ** outData)	/* out */
{
	TSS_RESULT result;
	UINT32 paramSize;
	UINT64 offset = 0;
	TCPA_KEY_HANDLE keySlot;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("ConvertMigBlob");
	if ((result = ctx_verify_context(hContext)))
		goto done;

	if (parentAuth != NULL) {
		LogDebug("Auth Used");
		if ((result = auth_mgr_check(hContext, &parentAuth->AuthHandle)))
			goto done;
	} else {
		LogDebug("No Auth");
	}
	if ((result = ensureKeyIsLoaded(hContext, parentHandle, &keySlot)))
		goto done;

	if ((result = tpm_rqu_build(TPM_ORD_ConvertMigrationBlob, &offset, txBlob, keySlot,
				    inDataSize, inData, randomSize, random, parentAuth)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	offset = 10;
	result = UnloadBlob_Header(txBlob, &paramSize);

	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_ConvertMigrationBlob, txBlob, paramSize, outDataSize,
				       outData, parentAuth, NULL);
	}
	LogResult("***Leaving ConvertMigrationBlob with result ", result);
done:
	auth_mgr_release_auth(parentAuth, NULL, hContext);
	return result;
}

TSS_RESULT
TCSP_AuthorizeMigrationKey_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
				    TSS_MIGRATE_SCHEME migrateScheme,	/* in */
				    UINT32 MigrationKeySize,	/* in */
				    BYTE * MigrationKey,	/* in */
				    TPM_AUTH * ownerAuth,	/* in, out */
				    UINT32 * MigrationKeyAuthSize,	/* out */
				    BYTE ** MigrationKeyAuth)	/* out */
{

	TSS_RESULT result;
	UINT32 paramSize;
	UINT64 offset = 0;
	//TCPA_MIGRATIONKEYAUTH container;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("TCSP_AuthorizeMigrationKey");
	if ((result = ctx_verify_context(hContext)))
		goto done;

	if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
		goto done;

	switch (migrateScheme) {
		case TSS_MS_MIGRATE:
			migrateScheme = TCPA_MS_MIGRATE;
			break;
		case TSS_MS_REWRAP:
			migrateScheme = TCPA_MS_REWRAP;
			break;
		case TSS_MS_MAINT:
			migrateScheme = TCPA_MS_MAINT;
			break;
#ifdef TSS_BUILD_CMK
		case TSS_MS_RESTRICT_MIGRATE:
			migrateScheme = TPM_MS_RESTRICT_MIGRATE;
			break;

		case TSS_MS_RESTRICT_APPROVE_DOUBLE:
			migrateScheme = TPM_MS_RESTRICT_APPROVE_DOUBLE;
			break;
#endif
		default:
			/* Let the TPM return an error */
			break;
	}

	if ((result = tpm_rqu_build(TPM_ORD_AuthorizeMigrationKey, &offset, txBlob, migrateScheme,
				    MigrationKeySize, MigrationKey, ownerAuth)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_AuthorizeMigrationKey, txBlob, paramSize,
				       MigrationKeyAuthSize, MigrationKeyAuth, ownerAuth);
	}
	LogDebugFn("TPM_AuthorizeMigrationKey result: 0x%x", result);
done:
	auth_mgr_release_auth(ownerAuth, NULL, hContext);
	return result;

}



<|start_filename|>src/include/tss/tcpa_typedef.h<|end_filename|>

#ifndef __TCPA_TYPEDEF_H__
#define __TCPA_TYPEDEF_H__

#warning including deprecated header file tcpa_typedef.h

#endif


<|start_filename|>src/tcs/tcs_key.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */


#include <string.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "req_mgr.h"
#include "tcs_tsp.h"
#include "tcslog.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"

struct key_mem_cache *key_mem_cache_head = NULL;

TSS_UUID NULL_UUID = { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0 } };


TSS_RESULT
add_cache_entry(TCS_CONTEXT_HANDLE hContext,
		BYTE*              blob,
		TCS_KEY_HANDLE     hParent,
		TPM_KEY_HANDLE     hSlot,
		TCS_KEY_HANDLE*    new)
{
	UINT64 offset;
	TSS_RESULT result;
	TCS_KEY_HANDLE tcsHandle;
	TSS_KEY key, *pKey;

	if (!blob) {
		pKey = NULL;
	} else {
		offset = 0;
		if ((result = UnloadBlob_TSS_KEY(&offset, blob, &key)))
			return result;

		if ((tcsHandle = mc_get_handle_by_pub(&key.pubKey, hParent)) == NULL_TCS_HANDLE) {
			pKey = &key;
		} else {
			mc_set_slot_by_handle(tcsHandle, hSlot);
			*new = tcsHandle;
			goto done;
		}
	}

	LogDebugFn("No existing key handle for this key, creating new one...");
	/* Get a new TCS Key Handle */
	tcsHandle = getNextTcsKeyHandle();
	LogDebugFn("calling mc_add_entry, TCS handle: 0x%x, TPM handle 0x%x", tcsHandle, hSlot);

	if ((result = mc_add_entry(tcsHandle, hSlot, pKey)))
		goto done;

	LogDebugFn("ctx_mark_key_loaded");
	if (ctx_mark_key_loaded(hContext, tcsHandle)) {
		LogError("Error marking key as loaded");
		result = TCSERR(TSS_E_INTERNAL_ERROR);
		goto done;
	}

	if ((result = mc_set_parent_by_handle(tcsHandle, hParent))) {
		LogError("mc_set_parent_by_handle failed.");
		goto done;
	}

	*new = tcsHandle;
done:
	if (blob)
		destroy_key_refs(&key);
	return result;
}

/* Check that the context has this key loaded and return the associated slot. Do not search PS if
 * the key is not found */
TSS_RESULT
get_slot_lite(TCS_CONTEXT_HANDLE hContext, TCS_KEY_HANDLE hKey, TPM_KEY_HANDLE *out)
{
	if (ctx_has_key_loaded(hContext, hKey)) {
		if ((*out = mc_get_slot_by_handle(hKey)) == NULL_TPM_HANDLE)
			return TCSERR(TCS_E_INVALID_KEY);

		return TSS_SUCCESS;
	}

	return TCSERR(TCS_E_INVALID_KEY);
}

/* XXX Can get_slot be merged with ensureKeyIsLoaded? */

/* Given a handle, get_slot searches the mem cache for a mapping to a TPM handle. If there is no
 * mapping, it looks up the pub key of the handle and attempts to load it by finding its pub key
 * in the persistent store. If that's not found, return error. */
TSS_RESULT
get_slot(TCS_CONTEXT_HANDLE hContext, TCS_KEY_HANDLE hKey, TPM_KEY_HANDLE *out)
{
	TSS_RESULT result = TSS_SUCCESS;
	TPM_STORE_PUBKEY *pub = NULL;
	TPM_KEY_HANDLE slot;

        LogDebugFn("calling mc_get_slot_by_handle");
        if ((slot = mc_get_slot_by_handle(hKey)) == NULL_TPM_HANDLE) {
                LogDebugFn("calling mc_get_pub_by_slot");
                if ((pub = mc_get_pub_by_slot(hKey)) == NULL)
                        return TCSERR(TCS_E_KM_LOADFAILED);

                LogDebugFn("calling LoadKeyShim");
                /* Otherwise, try to load it using the shim */
                result = LoadKeyShim(hContext, pub, NULL, &slot);
        }

	if (!result)
		*out = slot;

	return result;
}

/* load_key_init is the common entry point for all load key requests to the TCSD. These can come in
 * as straight load or load2 requests, or through a transport session.
 *
 * We'll always attempt to load the key if
 * A) It requires auth (load should fail if auth is bad, even when its already been loaded by
 *    another thread)
 * B) Its in a transport session (the key blob is encrypted)
 *
 * Otherwise if the key is already loaded by another thread and it doesn't require auth, then we
 * will just set *load_key to FALSE, telling the caller that there's no need to send anything to
 * the TPM.
 */
TSS_RESULT
load_key_init(TPM_COMMAND_CODE   ord,
	      TCS_CONTEXT_HANDLE hContext,
	      TCS_KEY_HANDLE     parent_handle,
	      UINT32             blob_size,
	      BYTE*              blob,
	      TSS_BOOL           encrypted,
	      TPM_AUTH*          auth,
	      TSS_BOOL*          load_key,
	      UINT64*            out_len,
	      BYTE*              out,
	      TCS_KEY_HANDLE*    handle,
	      TPM_KEY_HANDLE*    slot)
{
	TSS_RESULT result = TSS_SUCCESS;
	TSS_KEY key;
	UINT64 offset;
	TPM_KEY_HANDLE tpm_slot;
	TCS_KEY_HANDLE tcs_handle;
	TSS_BOOL canLoad;


	if (!encrypted) {
		offset = 0;
		memset(&key, 0, sizeof(TSS_KEY));
		if ((result = UnloadBlob_TSS_KEY(&offset, blob, &key)))
			return result;
	}

	if (!auth && !encrypted) {
		LogDebugFn("Checking if LoadKeyByBlob can be avoided by using existing key");

		if ((tcs_handle = mc_get_handle_by_pub(&key.pubKey, parent_handle))) {
			LogDebugFn("tcs key handle exists");

			tpm_slot = mc_get_slot_by_handle(tcs_handle);
			if (tpm_slot && (isKeyLoaded(tpm_slot) == TRUE)) {
				LogDebugFn("Don't need to reload this key.");
				*handle = tcs_handle;
				*slot = tpm_slot;
				*load_key = FALSE;
				goto done;
			}
		}
	}
	*load_key = TRUE;

	LogDebugFn("calling canILoadThisKey");
	if (!encrypted) {
		if ((result = canILoadThisKey(&(key.algorithmParms), &canLoad)))
			goto error;

		if (canLoad == FALSE) {
			LogDebugFn("calling evictFirstKey");
			/* Evict a key that isn't the parent */
			if ((result = evictFirstKey(parent_handle)))
				goto error;
		}
	}

error:
	if (!encrypted)
		destroy_key_refs(&key);
done:
	return result;
}

TSS_RESULT
load_key_final(TCS_CONTEXT_HANDLE hContext,
	       TCS_KEY_HANDLE     parent_handle,
	       TCS_KEY_HANDLE*    tcs_handle,
	       BYTE*              blob,
	       TPM_KEY_HANDLE     slot)
{
	if (*tcs_handle == NULL_TCS_HANDLE)
		return add_cache_entry(hContext, blob, parent_handle, slot, tcs_handle);
	else
		return mc_set_slot_by_handle(*tcs_handle, slot);
}

TSS_RESULT
canILoadThisKey(TCPA_KEY_PARMS *parms, TSS_BOOL *b)
{
	UINT16 subCapLength;
	UINT64 offset;
	BYTE subCap[100];
	TCPA_RESULT result;
	UINT32 respDataLength;
	BYTE *respData;

	offset = 0;
	LoadBlob_KEY_PARMS(&offset, subCap, parms);
	subCapLength = offset;

	if ((result = TCSP_GetCapability_Internal(InternalContext, TCPA_CAP_CHECK_LOADED,
						  subCapLength, subCap, &respDataLength,
						  &respData))) {
		*b = FALSE;
		LogDebugFn("NO");
		return result;
	}

	*b = respData[0];
	free(respData);
	LogDebugFn("%s", *b ? "YES" : "NO");

	return TSS_SUCCESS;
}

TCPA_RESULT
internal_EvictByKeySlot(TCPA_KEY_HANDLE slot)
{
	TCPA_RESULT result;
	UINT32 paramSize;
	UINT64 offset;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering Evict Key");

#ifdef TSS_BUILD_TSS12
	if (TPM_VERSION_IS(1,2)) {
		LogDebugFn("Evicting key using FlushSpecific for TPM 1.2");

		return TCSP_FlushSpecific_Common(slot, TPM_RT_KEY);
	}
#endif

	offset = 10;
	LoadBlob_UINT32(&offset, slot, txBlob);
	LoadBlob_Header(TPM_TAG_RQU_COMMAND, offset, TPM_ORD_EvictKey, txBlob);

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);

	LogResult("Evict Key", result);
	return result;
}

TSS_RESULT
clearUnknownKeys(TCS_CONTEXT_HANDLE hContext, UINT32 *cleared)
{
	TSS_RESULT result = TSS_SUCCESS;
	TCPA_KEY_HANDLE_LIST keyList = { 0, NULL };
	int i;
	BYTE *respData = NULL;
	UINT32 respDataSize = 0, count = 0;
	TCPA_CAPABILITY_AREA capArea = -1;
	UINT64 offset = 0;
	TSS_BOOL found = FALSE;
	struct key_mem_cache *tmp;

	capArea = TCPA_CAP_KEY_HANDLE;

	if ((result = TCSP_GetCapability_Internal(hContext, capArea, 0, NULL, &respDataSize,
						  &respData)))
		return result;

	if ((result = UnloadBlob_KEY_HANDLE_LIST(&offset, respData, &keyList)))
		goto done;

#ifdef TSS_DEBUG
	LogDebug("Loaded TPM key handles:");
	for (i = 0; i < keyList.loaded; i++) {
		LogDebugFn("%d: %x", i, keyList.handle[i]);
	}

	LogDebug("Loaded TCSD key handles:");
	i=0;
	for (tmp = key_mem_cache_head; tmp; tmp = tmp->next) {
		LogDebugFn("%d: 0x%x -> 0x%x", i++, tmp->tpm_handle,
			    tmp->tcs_handle);
	}
#endif

	for (i = 0; i < keyList.loaded; i++) {
		/* as long as we're only called from evictFirstKey(), we don't
		 * need to lock here */
		for (tmp = key_mem_cache_head; tmp; tmp = tmp->next) {
			if (tmp->tpm_handle == keyList.handle[i]) {
				found = TRUE;
				break;
			}
		}
		if (found)
			found = FALSE;
		else {
			if ((result = internal_EvictByKeySlot(keyList.handle[i])))
				goto done;
			else
				count++;
		}
	}

	*cleared = count;
done:
	free(keyList.handle);
	free(respData);

	return TSS_SUCCESS;
}

#if 0
TCPA_RESULT
clearKeysFromChip(TCS_CONTEXT_HANDLE hContext)
{
	TCPA_RESULT result;
	TCPA_KEY_HANDLE_LIST keyList;
	UINT32 i;
	BYTE *respData = 0;
	UINT32 respDataSize = 0;
	TCPA_CAPABILITY_AREA capArea = -1;
	UINT64 offset = 0;

	capArea = TCPA_CAP_KEY_HANDLE;

	if ((result = TCSP_GetCapability_Internal(hContext, capArea, 0, NULL,
					&respDataSize, &respData)))
		return result;

	if ((result = UnloadBlob_KEY_HANDLE_LIST(&offset, respData, &keyList)))
		return result;
	for (i = 0; i < keyList.loaded; i++) {
		if (keyList.handle[i] == SRK_TPM_HANDLE ||	/*can't evict SRK */
		    keyList.handle[i] == EK_TPM_HANDLE)	/*can't evict EK */
			continue;
		if ((result = internal_EvictByKeySlot(keyList.handle[i])))
			return result;
	}
	return TSS_SUCCESS;
}
#endif

void
LoadBlob_KEY_PARMS(UINT64 *offset, BYTE *blob, TCPA_KEY_PARMS *keyInfo)
{
	LoadBlob_UINT32(offset, keyInfo->algorithmID, blob);
	LoadBlob_UINT16(offset, keyInfo->encScheme, blob);
	LoadBlob_UINT16(offset, keyInfo->sigScheme, blob);
	LoadBlob_UINT32(offset, keyInfo->parmSize, blob);
	LoadBlob(offset, keyInfo->parmSize, blob, keyInfo->parms);
}

TSS_RESULT
UnloadBlob_STORE_PUBKEY(UINT64 *offset, BYTE *blob, TCPA_STORE_PUBKEY *store)
{
	if (!store) {
		UINT32 keyLength;

		UnloadBlob_UINT32(offset, &keyLength, blob);

		if (keyLength > 0)
			UnloadBlob(offset, keyLength, blob, NULL);

		return TSS_SUCCESS;
	}

	UnloadBlob_UINT32(offset, &store->keyLength, blob);

	if (store->keyLength == 0) {
		store->key = NULL;
		LogWarn("Unloading a public key of size 0!");
	} else {
		store->key = (BYTE *)malloc(store->keyLength);
		if (store->key == NULL) {
			LogError("malloc of %u bytes failed.", store->keyLength);
			store->keyLength = 0;
			return TCSERR(TSS_E_OUTOFMEMORY);
		}

		UnloadBlob(offset, store->keyLength, blob, store->key);
	}

	return TSS_SUCCESS;
}

void
LoadBlob_STORE_PUBKEY(UINT64 *offset, BYTE * blob, TCPA_STORE_PUBKEY * store)
{
	LoadBlob_UINT32(offset, store->keyLength, blob);
	LoadBlob(offset, store->keyLength, blob, store->key);
}

TSS_RESULT
UnloadBlob_TSS_KEY(UINT64 *offset, BYTE *blob, TSS_KEY *key)
{
	TSS_RESULT rc;

	if (!key) {
		UINT32 size;

		/* TPM_KEY's ver and TPM_KEY12's tag/file are
		   the same size, so... */
		UnloadBlob_VERSION(offset, blob, NULL);
		UnloadBlob_UINT16(offset, NULL, blob);
		UnloadBlob_KEY_FLAGS(offset, blob, NULL);
		UnloadBlob_BOOL(offset, NULL, blob);
		if ((rc = UnloadBlob_KEY_PARMS(offset, blob, NULL)))
			return rc;
		UnloadBlob_UINT32(offset, &size, blob);

		if (size > 0)
			UnloadBlob(offset, size, blob, NULL);

		if ((rc = UnloadBlob_STORE_PUBKEY(offset, blob, NULL)))
			return rc;

		UnloadBlob_UINT32(offset, &size, blob);

		if (size > 0)
			UnloadBlob(offset, size, blob, NULL);

		return TSS_SUCCESS;
	}

	if (key->hdr.key12.tag == TPM_TAG_KEY12) {
		UnloadBlob_UINT16(offset, &key->hdr.key12.tag, blob);
		UnloadBlob_UINT16(offset, &key->hdr.key12.fill, blob);
	} else
		UnloadBlob_TCPA_VERSION(offset, blob, &key->hdr.key11.ver);
	UnloadBlob_UINT16(offset, &key->keyUsage, blob);
	UnloadBlob_KEY_FLAGS(offset, blob, &key->keyFlags);
	UnloadBlob_BOOL(offset, (TSS_BOOL *)&key->authDataUsage, blob);
	if ((rc = UnloadBlob_KEY_PARMS(offset, blob, &key->algorithmParms)))
		return rc;
	UnloadBlob_UINT32(offset, &key->PCRInfoSize, blob);

	if (key->PCRInfoSize == 0)
		key->PCRInfo = NULL;
	else {
		key->PCRInfo = malloc(key->PCRInfoSize);
		if (key->PCRInfo == NULL) {
			LogError("malloc of %u bytes failed.", key->PCRInfoSize);
			key->PCRInfoSize = 0;
			free(key->algorithmParms.parms);
			key->algorithmParms.parms = NULL;
			key->algorithmParms.parmSize = 0;
			return TCSERR(TSS_E_OUTOFMEMORY);
		}
		UnloadBlob(offset, key->PCRInfoSize, blob, key->PCRInfo);
	}

	if ((rc = UnloadBlob_STORE_PUBKEY(offset, blob, &key->pubKey))) {
		free(key->PCRInfo);
		key->PCRInfo = NULL;
		key->PCRInfoSize = 0;
		free(key->algorithmParms.parms);
		key->algorithmParms.parms = NULL;
		key->algorithmParms.parmSize = 0;
		return rc;
	}
	UnloadBlob_UINT32(offset, &key->encSize, blob);

	if (key->encSize == 0)
		key->encData = NULL;
	else {
		key->encData = (BYTE *)malloc(key->encSize);
		if (key->encData == NULL) {
			LogError("malloc of %d bytes failed.", key->encSize);
			key->encSize = 0;
			free(key->algorithmParms.parms);
			key->algorithmParms.parms = NULL;
			key->algorithmParms.parmSize = 0;
			free(key->PCRInfo);
			key->PCRInfo = NULL;
			key->PCRInfoSize = 0;
			free(key->pubKey.key);
			key->pubKey.key = NULL;
			key->pubKey.keyLength = 0;
			return TCSERR(TSS_E_OUTOFMEMORY);
		}
		UnloadBlob(offset, key->encSize, blob, key->encData);
	}

	return TSS_SUCCESS;
}

void
LoadBlob_TSS_KEY(UINT64 *offset, BYTE * blob, TSS_KEY * key)
{
	if (key->hdr.key12.tag == TPM_TAG_KEY12) {
		LoadBlob_UINT16(offset, key->hdr.key12.tag, blob);
		LoadBlob_UINT16(offset, key->hdr.key12.fill, blob);
	} else
		LoadBlob_TCPA_VERSION(offset, blob, &key->hdr.key11.ver);
	LoadBlob_UINT16(offset, key->keyUsage, blob);
	LoadBlob_KEY_FLAGS(offset, blob, &key->keyFlags);
	LoadBlob_BOOL(offset, key->authDataUsage, blob);
	LoadBlob_KEY_PARMS(offset, blob, &key->algorithmParms);
	LoadBlob_UINT32(offset, key->PCRInfoSize, blob);
	LoadBlob(offset, key->PCRInfoSize, blob, key->PCRInfo);
	LoadBlob_STORE_PUBKEY(offset, blob, &key->pubKey);
	LoadBlob_UINT32(offset, key->encSize, blob);
	LoadBlob(offset, key->encSize, blob, key->encData);
}

void
LoadBlob_PUBKEY(UINT64 *offset, BYTE * blob, TCPA_PUBKEY * key)
{
	LoadBlob_KEY_PARMS(offset, blob, &(key->algorithmParms));
	LoadBlob_STORE_PUBKEY(offset, blob, &(key->pubKey));
}

TSS_RESULT
UnloadBlob_PUBKEY(UINT64 *offset, BYTE *blob, TCPA_PUBKEY *key)
{
	TSS_RESULT rc;

	if (!key) {
		if ((rc = UnloadBlob_KEY_PARMS(offset, blob, NULL)))
			return rc;
		return UnloadBlob_STORE_PUBKEY(offset, blob, NULL);
	}

	if ((rc = UnloadBlob_KEY_PARMS(offset, blob, &key->algorithmParms)))
		return rc;
	if ((rc = UnloadBlob_STORE_PUBKEY(offset, blob, &key->pubKey))) {
		free(key->algorithmParms.parms);
		key->algorithmParms.parms = NULL;
		key->algorithmParms.parmSize = 0;
	}

	return rc;
}

void
LoadBlob_KEY_FLAGS(UINT64 *offset, BYTE * blob, TCPA_KEY_FLAGS * flags)
{
	LoadBlob_UINT32(offset, *flags, blob);
}

void
destroy_key_refs(TSS_KEY *key)
{
	free(key->algorithmParms.parms);
	key->algorithmParms.parms = NULL;
	key->algorithmParms.parmSize = 0;

	free(key->pubKey.key);
	key->pubKey.key = NULL;
	key->pubKey.keyLength = 0;

	free(key->encData);
	key->encData = NULL;
	key->encSize = 0;

	free(key->PCRInfo);
	key->PCRInfo = NULL;
	key->PCRInfoSize = 0;
}


<|start_filename|>src/tspi/tspi_pcr_extend.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 * (C) <NAME> 2007
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


TSS_RESULT
Tspi_TPM_PcrExtend(TSS_HTPM hTPM,		/* in */
		   UINT32 ulPcrIndex,		/* in */
		   UINT32 ulPcrDataLength,	/* in */
		   BYTE *pbPcrData,		/* in */
		   TSS_PCR_EVENT *pPcrEvent,	/* in */
		   UINT32 * pulPcrValueLength,	/* out */
		   BYTE ** prgbPcrValue)	/* out */
{
	TCPA_PCRVALUE outDigest;
	TSS_RESULT result;
	BYTE *extendData;
	TPM_DIGEST digest;
	UINT32 number;
	TSS_HCONTEXT tspContext;
	Trspi_HashCtx hashCtx;

	if (pulPcrValueLength == NULL || prgbPcrValue == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if (ulPcrDataLength > 0 && pbPcrData == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
		return result;

	if (pPcrEvent) {
		/* Create data to extend according to the TSS 1.2 spec section 2.6.2
		 * 'TSS_PCR_EVENT', in the 'rgbPcrValue' parameter description. */
		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
		result |= Trspi_Hash_UINT32(&hashCtx, ulPcrIndex);
		result |= Trspi_HashUpdate(&hashCtx, ulPcrDataLength, pbPcrData);
		result |= Trspi_Hash_UINT32(&hashCtx, pPcrEvent->eventType);
		result |= Trspi_HashUpdate(&hashCtx, pPcrEvent->ulEventLength, pPcrEvent->rgbEvent);
		if ((result |= Trspi_HashFinal(&hashCtx, (BYTE *)&digest.digest)))
			return result;

		extendData = (BYTE *)&digest.digest;
	} else {
		if (ulPcrDataLength != TPM_SHA1_160_HASH_LEN)
			return TSPERR(TSS_E_BAD_PARAMETER);

		extendData = pbPcrData;
	}

	if ((result = TCS_API(tspContext)->Extend(tspContext, ulPcrIndex, *(TPM_DIGEST *)extendData,
						  &outDigest)))
		return result;

	/* log the event structure if its passed in */
	if (pPcrEvent) {
		/* Set the PCR index in the event struct */
		pPcrEvent->ulPcrIndex = ulPcrIndex;

		if ((pPcrEvent->rgbPcrValue = calloc_tspi(tspContext,
							  TPM_SHA1_160_HASH_LEN)) == NULL) {
			LogError("malloc of %d bytes failed.", TPM_SHA1_160_HASH_LEN);
			return TSPERR(TSS_E_OUTOFMEMORY);
		}

		memcpy(pPcrEvent->rgbPcrValue, (BYTE *)&digest.digest, TPM_SHA1_160_HASH_LEN);
		pPcrEvent->ulPcrValueLength = TPM_SHA1_160_HASH_LEN;

		/* Set the version info in the event struct */
		memcpy(&pPcrEvent->versionInfo, &VERSION_1_1, sizeof(TCPA_VERSION));

		if ((result = RPC_LogPcrEvent(tspContext, *pPcrEvent, &number)))
			return result;
	}

	*prgbPcrValue = calloc_tspi(tspContext, sizeof(TPM_PCRVALUE));
	if (*prgbPcrValue == NULL) {
		LogError("malloc of %zd bytes failed.", sizeof(TPM_PCRVALUE));
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	memcpy(*prgbPcrValue, &outDigest, sizeof(TPM_PCRVALUE));
	*pulPcrValueLength = sizeof(TPM_PCRVALUE);

	return result;
}

TSS_RESULT
Tspi_TPM_PcrRead(TSS_HTPM hTPM,			/* in */
		 UINT32 ulPcrIndex,		/* in */
		 UINT32 *pulPcrValueLength,	/* out */
		 BYTE **prgbPcrValue)		/* out */
{
	TCPA_PCRVALUE outDigest;
	TSS_RESULT result;
	TSS_HCONTEXT tspContext;

	if (pulPcrValueLength == NULL || prgbPcrValue == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
		return result;

	if ((result = TCS_API(tspContext)->PcrRead(tspContext, ulPcrIndex, &outDigest)))
		return result;

	*prgbPcrValue = calloc_tspi(tspContext, sizeof(TCPA_PCRVALUE));
	if (*prgbPcrValue == NULL) {
		LogError("malloc of %zd bytes failed.", sizeof(TCPA_PCRVALUE));
		return TSPERR(TSS_E_OUTOFMEMORY);
	}
	memcpy(*prgbPcrValue, outDigest.digest, sizeof(TCPA_PCRVALUE));
	*pulPcrValueLength = sizeof(TCPA_PCRVALUE);

	return TSS_SUCCESS;
}

TSS_RESULT
Tspi_TPM_PcrReset(TSS_HTPM hTPM,                 /* in */
		  TSS_HPCRS hPcrComposite)       /* in */
{
	TSS_RESULT result;
	TSS_HCONTEXT tspContext;
	UINT32 pcrDataSize;
	BYTE pcrData[16];

	if (!hPcrComposite)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
		return result;

	if ((result = obj_pcrs_get_selection(hPcrComposite, &pcrDataSize, pcrData)))
		return result;

	return TCS_API(tspContext)->PcrReset(tspContext, pcrDataSize, pcrData);
}



<|start_filename|>src/tspi/tspi_seal.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"
#include "authsess.h"


TSS_RESULT
Tspi_Data_Seal(TSS_HENCDATA hEncData,	/* in */
	       TSS_HKEY hEncKey,	/* in */
	       UINT32 ulDataLength,	/* in */
	       BYTE * rgbDataToSeal,	/* in */
	       TSS_HPCRS hPcrComposite)	/* in */
{
	TPM_DIGEST digest;
	TSS_RESULT result;
	TSS_HPOLICY hPolicy, hEncPolicy;
	BYTE *encData = NULL;
	BYTE *pcrData = NULL;
	UINT32 encDataSize;
	UINT32 pcrDataSize;
	UINT32 pcrInfoType = TSS_PCRS_STRUCT_DEFAULT;
	UINT32 sealOrdinal = TPM_ORD_Seal;
	TCS_KEY_HANDLE tcsKeyHandle;
	TSS_HCONTEXT tspContext;
	Trspi_HashCtx hashCtx;
	BYTE *sealData = NULL;
	struct authsess *xsap = NULL;
#ifdef TSS_BUILD_SEALX
	UINT32 protectMode;
#endif

	if (rgbDataToSeal == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if ((result = obj_encdata_get_tsp_context(hEncData, &tspContext)))
		return result;

	if ((result = obj_rsakey_get_policy(hEncKey, TSS_POLICY_USAGE,
					    &hPolicy, NULL)))
		return result;

	if ((result = obj_encdata_get_policy(hEncData, TSS_POLICY_USAGE,
					     &hEncPolicy)))
		return result;

	if ((result = obj_rsakey_get_tcs_handle(hEncKey, &tcsKeyHandle)))
		return result;

#ifdef TSS_BUILD_SEALX
	/* Get the TSS_TSPATTRIB_ENCDATASEAL_PROTECT_MODE attribute
	   to determine the seal function to invoke */
	if ((result = obj_encdata_get_seal_protect_mode(hEncData, &protectMode)))
		return result;

	if (protectMode == TSS_TSPATTRIB_ENCDATASEAL_NO_PROTECT) {
		sealOrdinal = TPM_ORD_Seal;
		pcrInfoType = 0;
	} else if (protectMode == TSS_TSPATTRIB_ENCDATASEAL_PROTECT) {
		sealOrdinal = TPM_ORD_Sealx;
		pcrInfoType = TSS_PCRS_STRUCT_INFO_LONG;
	} else
		return TSPERR(TSS_E_INTERNAL_ERROR);
#endif

	/* If PCR's are of interest */
	pcrDataSize = 0;
	if (hPcrComposite) {
		if ((result = obj_pcrs_create_info_type(hPcrComposite, &pcrInfoType, &pcrDataSize,
							&pcrData)))
			return result;
	}

	if ((result = authsess_xsap_init(tspContext, hEncKey, hEncData, TSS_AUTH_POLICY_REQUIRED,
					 sealOrdinal, TPM_ET_KEYHANDLE, &xsap)))
		goto error;

#ifdef TSS_BUILD_SEALX
	if (sealOrdinal == TPM_ORD_Seal)
		sealData = rgbDataToSeal;
	else {
		if ((sealData = (BYTE *)calloc(1, ulDataLength)) == NULL) {
			LogError("malloc of %u bytes failed", ulDataLength);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto error;
		}

		if ((result =
		     ((TSS_RESULT (*)(PVOID, TSS_HKEY, TSS_HENCDATA, TSS_ALGORITHM_ID,
		     UINT32, BYTE *, BYTE *, BYTE *, BYTE *, UINT32, BYTE *,
		     BYTE *))xsap->cb_sealx.callback)(xsap->cb_sealx.appData, hEncKey, hEncData,
						      xsap->cb_sealx.alg, sizeof(TPM_NONCE),
						      xsap->auth.NonceEven.nonce,
						      xsap->auth.NonceOdd.nonce,
						      xsap->nonceEvenxSAP.nonce,
						      xsap->nonceOddxSAP.nonce, ulDataLength,
						      rgbDataToSeal, sealData)))
			goto error;
	}
#else
	sealData = rgbDataToSeal;
#endif

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, sealOrdinal);
	result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata);
	result |= Trspi_Hash_UINT32(&hashCtx, pcrDataSize);
	result |= Trspi_HashUpdate(&hashCtx, pcrDataSize, pcrData);
	result |= Trspi_Hash_UINT32(&hashCtx, ulDataLength);
	result |= Trspi_HashUpdate(&hashCtx, ulDataLength, sealData);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
		goto error;
	}

	if ((result = authsess_xsap_hmac(xsap, &digest)))
		goto error;

#ifdef TSS_BUILD_SEALX
	if (sealOrdinal == TPM_ORD_Seal) {
		if ((result = TCS_API(tspContext)->Seal(tspContext, tcsKeyHandle, &xsap->encAuthUse,
							pcrDataSize, pcrData, ulDataLength,
							sealData, xsap->pAuth, &encDataSize,
							&encData))) {
			goto error;
		}
	} else if (sealOrdinal == TPM_ORD_Sealx) {
		if ((result = TCS_API(tspContext)->Sealx(tspContext, tcsKeyHandle, &xsap->encAuthUse,
						    pcrDataSize, pcrData, ulDataLength, sealData,
						    xsap->pAuth, &encDataSize, &encData))) {
			goto error;
		}
	} else {
		result = TSPERR(TSS_E_INTERNAL_ERROR);
		goto error;
	}
#else
	if ((result = TCS_API(tspContext)->Seal(tspContext, tcsKeyHandle, &xsap->encAuthUse,
						pcrDataSize, pcrData, ulDataLength, sealData,
						xsap->pAuth, &encDataSize, &encData)))
		goto error;
#endif

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, result);
	result |= Trspi_Hash_UINT32(&hashCtx, sealOrdinal);
	result |= Trspi_HashUpdate(&hashCtx, encDataSize, encData);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
		goto error;

	if ((result = authsess_xsap_verify(xsap, &digest)))
		goto error;

	/* Need to set the object with the blob and the pcr's */
	if ((result = obj_encdata_set_data(hEncData, encDataSize, encData)))
		goto error;

	if (pcrDataSize)
		result = obj_encdata_set_pcr_info(hEncData, pcrInfoType, pcrData);

error:
	authsess_free(xsap);
	free(encData);
	free(pcrData);
	if (sealData != rgbDataToSeal)
		free(sealData);
	return result;
}

TSS_RESULT
Tspi_Data_Unseal(TSS_HENCDATA hEncData,		/* in */
		 TSS_HKEY hKey,			/* in */
		 UINT32 * pulUnsealedDataLength,/* out */
		 BYTE ** prgbUnsealedData)	/* out */
{
	UINT64 offset;
	TPM_AUTH privAuth2;
	TPM_DIGEST digest;
	TPM_NONCE authLastNonceEven;
	TSS_RESULT result;
	TSS_HPOLICY hPolicy, hEncPolicy;
	TCS_KEY_HANDLE tcsKeyHandle;
        TSS_HCONTEXT tspContext;
	UINT32 ulDataLen, unSealedDataLen;
	BYTE *data = NULL, *unSealedData = NULL, *maskedData;
	UINT16 mask;
	Trspi_HashCtx hashCtx;
	struct authsess *xsap = NULL;

	if (pulUnsealedDataLength == NULL || prgbUnsealedData == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if ((result = obj_encdata_get_tsp_context(hEncData, &tspContext)))
		return result;

	if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, &hPolicy, NULL)))
		return result;

	if ((result = obj_encdata_get_policy(hEncData, TSS_POLICY_USAGE, &hEncPolicy)))
		return result;

	if ((result = obj_encdata_get_data(hEncData, &ulDataLen, &data)))
		return result == (TSS_E_INVALID_OBJ_ACCESS | TSS_LAYER_TSP) ?
		       TSPERR(TSS_E_ENC_NO_DATA) :
		       result;

	offset = 0;
	Trspi_UnloadBlob_UINT16(&offset, &mask, data);
	if (mask == TPM_TAG_STORED_DATA12) {
		/* The second UINT16 in a TPM_STORED_DATA12 is the entity type. If its non-zero
		 * then we must unmask the unsealed data after it returns from the TCS */
		Trspi_UnloadBlob_UINT16(&offset, &mask, data);
	} else
		mask = 0;

	if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKeyHandle)))
		goto error;

	if ((result = authsess_xsap_init(tspContext, hKey, hEncData, TSS_AUTH_POLICY_REQUIRED,
					 TPM_ORD_Unseal, TPM_ET_KEYHANDLE, &xsap)))
		goto error;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Unseal);
	result |= Trspi_HashUpdate(&hashCtx, ulDataLen, data);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
		goto error;

	if ((result = authsess_xsap_hmac(xsap, &digest)))
		goto error;

	if ((result = secret_PerformAuth_OIAP(hEncData, TPM_ORD_Unseal, hEncPolicy, FALSE, &digest,
					      &privAuth2)))
		goto error;

	if (mask) {
		/* save off last nonce even to pass to sealx callback */
		   memcpy(authLastNonceEven.nonce, xsap->auth.NonceEven.nonce, sizeof(TPM_NONCE));
	}

	if ((result = TCS_API(tspContext)->Unseal(tspContext, tcsKeyHandle, ulDataLen, data,
						  xsap->pAuth, &privAuth2, &unSealedDataLen,
						  &unSealedData)))
		goto error;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, TSS_SUCCESS);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Unseal);
	result |= Trspi_Hash_UINT32(&hashCtx, unSealedDataLen);
	result |= Trspi_HashUpdate(&hashCtx, unSealedDataLen, unSealedData);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
		free(unSealedData);
		goto error;
	}

	if ((result = authsess_xsap_verify(xsap, &digest))) {
		free(unSealedData);
		goto error;
	}

	if ((result = obj_policy_validate_auth_oiap(hEncPolicy, &digest, &privAuth2))) {
		free(unSealedData);
		goto error;
	}

	/* If the data is masked, use the callback set up in authsess_xsap_init */
	if (mask) {
		maskedData = unSealedData;

		if ((unSealedData = calloc_tspi(tspContext, unSealedDataLen)) == NULL) {
			free(maskedData);
			LogError("malloc of %u bytes failed", unSealedDataLen);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto error;
		}

		/* XXX pass in out saved-off authLastNonceEven. This conflicts with the
		 * description of the rgbNonceEven parameter in the spec, but without it, its not
		 * possible to compute the MGF1 key */
		if ((result =
		     ((TSS_RESULT (*)(PVOID, TSS_HKEY, TSS_HENCDATA, TSS_ALGORITHM_ID,
		       UINT32, BYTE *, BYTE *, BYTE *, BYTE *, UINT32, BYTE *,
		       BYTE *))xsap->cb_sealx.callback)(xsap->cb_sealx.appData, hKey, hEncData,
							 xsap->cb_sealx.alg, sizeof(TPM_NONCE),
							 authLastNonceEven.nonce,
							 xsap->auth.NonceOdd.nonce,
							 xsap->nonceEvenxSAP.nonce,
							 xsap->nonceOddxSAP.nonce,
							 unSealedDataLen, maskedData,
							 unSealedData))) {
			free(maskedData);
			goto error;
		}

		free(maskedData);
	} else {
		if ((result = __tspi_add_mem_entry(tspContext, unSealedData)))
			goto error;
	}

	*pulUnsealedDataLength = unSealedDataLen;
	*prgbUnsealedData = unSealedData;

error:
	authsess_free(xsap);
	if (data)
		free_tspi(tspContext, data);

	return result;
}


<|start_filename|>src/tspi/rpc/tcstp/rpc_caps.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "hosttable.h"
#include "tcsd_wrap.h"
#include "obj.h"
#include "rpc_tcstp_tsp.h"


TSS_RESULT
RPC_GetCapability_TP(struct host_table_entry *hte,
				 TCPA_CAPABILITY_AREA capArea,	/* in */
				 UINT32 subCapSize,	/* in */
				 BYTE * subCap,	/* in */
				 UINT32 * respSize,	/* out */
				 BYTE ** resp)	/* out */
{
	TSS_RESULT result;

	initData(&hte->comm, 4);
	hte->comm.hdr.u.ordinal = TCSD_ORD_TCSGETCAPABILITY;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &capArea, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 2, &subCapSize, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 3, subCap, subCapSize, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_UINT32, 0, respSize, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		*resp = (BYTE *) calloc_tspi(hte->tspContext, *respSize);
		if (*resp == NULL) {
			LogError("malloc of %u bytes failed.", *respSize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, 1, *resp, *respSize, &hte->comm)) {
			free_tspi(hte->tspContext, *resp);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		}
	}

done:
	return result;
}


<|start_filename|>src/tspi/tspi_own.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


TSS_RESULT
Tspi_TPM_TakeOwnership(TSS_HTPM hTPM,			/* in */
		       TSS_HKEY hKeySRK,		/* in */
		       TSS_HKEY hEndorsementPubKey)	/* in */
{
	TPM_AUTH privAuth;
	BYTE encOwnerAuth[256];
	UINT32 encOwnerAuthLength;
	BYTE encSRKAuth[256];
	UINT32 encSRKAuthLength;
	TCPA_DIGEST digest;
	TSS_RESULT result;
	TSS_HCONTEXT tspContext;
	UINT32 srkKeyBlobLength;
	BYTE *srkKeyBlob;
	TSS_HPOLICY hOwnerPolicy;
	UINT32 newSrkBlobSize;
	BYTE *newSrkBlob = NULL;
	BYTE oldAuthDataUsage;
	TSS_HKEY hPubEK;
	Trspi_HashCtx hashCtx;


	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
		return result;

	if (hEndorsementPubKey == NULL_HKEY) {
		if ((result = Tspi_TPM_GetPubEndorsementKey(hTPM, FALSE, NULL, &hPubEK))) {
			return result;
		}
	} else {
		hPubEK = hEndorsementPubKey;
	}

	/* Get the srkKeyData */
	if ((result = obj_rsakey_get_blob(hKeySRK, &srkKeyBlobLength, &srkKeyBlob)))
		return result;

	/* Need to check for Atmel bug where authDataUsage is changed */
	oldAuthDataUsage = srkKeyBlob[10];
	LogDebug("oldAuthDataUsage is %.2X.  Wait to see if it changes", oldAuthDataUsage);

	/* Now call the module that will encrypt the secrets.  This
	 * will either get the secrets from the policy objects or
	 * use the callback function to encrypt the secrets */

	if ((result = secret_TakeOwnership(hPubEK, hTPM, hKeySRK, &privAuth, &encOwnerAuthLength,
					   encOwnerAuth, &encSRKAuthLength, encSRKAuth)))
		return result;

	/* Now, take ownership is ready to call.  The auth structure should be complete
	 * and the encrypted data structures should be ready */
	if ((result = RPC_TakeOwnership(tspContext, TPM_PID_OWNER, encOwnerAuthLength, encOwnerAuth,
					encSRKAuthLength, encSRKAuth, srkKeyBlobLength, srkKeyBlob,
					&privAuth, &newSrkBlobSize, &newSrkBlob)))
		return result;

	/* The final step is to validate the return Auth */
	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, result);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_TakeOwnership);
	result |= Trspi_HashUpdate(&hashCtx, newSrkBlobSize, newSrkBlob);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
		return result;

	if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hOwnerPolicy))) {
		free(newSrkBlob);
		return result;
	}
	if ((result = obj_policy_validate_auth_oiap(hOwnerPolicy, &digest, &privAuth))) {
		free(newSrkBlob);
		return result;
	}

	/* Now that it's all happy, stuff the keyBlob into the object
	 * If atmel, need to adjust the authDataUsage if it changed */
	if (oldAuthDataUsage != newSrkBlob[10]) {	/* hardcoded blob stuff */
		LogDebug("auth data usage changed. Atmel bug. Fixing in key object");
		newSrkBlob[10] = oldAuthDataUsage;	/* this will fix it  */
	}

	result = obj_rsakey_set_tcpakey(hKeySRK, newSrkBlobSize, newSrkBlob);
	free(newSrkBlob);

	if (result)
		return result;

	/* The SRK is loaded at this point, so insert it into the key handle list */
	return obj_rsakey_set_tcs_handle(hKeySRK, TPM_KEYHND_SRK);
}

TSS_RESULT
Tspi_TPM_ClearOwner(TSS_HTPM hTPM,		/* in */
		    TSS_BOOL fForcedClear)	/* in */
{
	TCPA_RESULT result;
	TPM_AUTH auth;
	TSS_HCONTEXT tspContext;
	TCPA_DIGEST hashDigest;
	TSS_HPOLICY hPolicy;
	Trspi_HashCtx hashCtx;

	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
		return result;

	if (!fForcedClear) {	/*  TPM_OwnerClear */
		if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hPolicy)))
			return result;

		/* Now do some Hash'ing */
		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerClear);
		if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest)))
			return result;

		/* hashDigest now has the hash result */
		if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_OwnerClear, hPolicy, FALSE,
						      &hashDigest, &auth)))
			return result;

		if ((result = TCS_API(tspContext)->OwnerClear(tspContext, &auth)))
			return result;

		/* validate auth */
		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
		result |= Trspi_Hash_UINT32(&hashCtx, result);
		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerClear);
		if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest)))
			return result;

		if ((result = obj_policy_validate_auth_oiap(hPolicy, &hashDigest, &auth)))
			return result;
	} else {
		if ((result = TCS_API(tspContext)->ForceClear(tspContext)))
			return result;
	}

	return TSS_SUCCESS;
}


<|start_filename|>src/tspi/rpc/tcstp/rpc_ps.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "hosttable.h"
#include "tcsd_wrap.h"
#include "obj.h"
#include "rpc_tcstp_tsp.h"


TSS_RESULT
RPC_GetRegisteredKeyByPublicInfo_TP(struct host_table_entry *hte,
				     TCPA_ALGORITHM_ID algID,	/* in */
				     UINT32 ulPublicInfoLength,	/* in */
				     BYTE * rgbPublicInfo,	/* in */
				     UINT32 * keySize,		/* out */
				     BYTE ** keyBlob)		/* out */
{
	TSS_RESULT result;

	initData(&hte->comm, 4);
	hte->comm.hdr.u.ordinal = TCSD_ORD_GETREGISTEREDKEYBYPUBLICINFO;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &algID, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 2, &ulPublicInfoLength, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 3, rgbPublicInfo, ulPublicInfoLength, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_UINT32, 0, keySize, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		*keyBlob = (BYTE *) malloc(*keySize);
		if (*keyBlob == NULL) {
			LogError("malloc of %u bytes failed.", *keySize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, 1, *keyBlob, *keySize, &hte->comm)) {
			free(*keyBlob);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
	}

done:
	return result;
}

TSS_RESULT
RPC_RegisterKey_TP(struct host_table_entry *hte,
			       TSS_UUID WrappingKeyUUID,	/* in */
			       TSS_UUID KeyUUID,	/* in */
			       UINT32 cKeySize,	/* in */
			       BYTE * rgbKey,	/* in */
			       UINT32 cVendorData,	/* in */
			       BYTE * gbVendorData	/* in */
    ) {
	TSS_RESULT result;

	initData(&hte->comm, 7);
	hte->comm.hdr.u.ordinal = TCSD_ORD_REGISTERKEY;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UUID, 1, &WrappingKeyUUID, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UUID, 2, &KeyUUID, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 3, &cKeySize, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 4, rgbKey, cKeySize, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 5, &cVendorData, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 6, gbVendorData, cVendorData, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	return result;
}

TSS_RESULT
RPC_UnregisterKey_TP(struct host_table_entry *hte,
				  TSS_UUID KeyUUID	/* in */
    ) {
	TSS_RESULT result;

	initData(&hte->comm, 2);
	hte->comm.hdr.u.ordinal = TCSD_ORD_UNREGISTERKEY;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UUID, 1, &KeyUUID, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	return result;
}

TSS_RESULT
RPC_EnumRegisteredKeys_TP(struct host_table_entry *hte,
				      TSS_UUID * pKeyUUID,	/* in */
				      UINT32 * pcKeyHierarchySize,	/* out */
				      TSS_KM_KEYINFO ** ppKeyHierarchy	/* out */
    ) {
	TSS_RESULT result;
	int i, j;

	initData(&hte->comm, 2);
	hte->comm.hdr.u.ordinal = TCSD_ORD_ENUMREGISTEREDKEYS;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	if (pKeyUUID != NULL) {
		if (setData(TCSD_PACKET_TYPE_UUID, 1, pKeyUUID, 0, &hte->comm))
			return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		i = 0;
		if (getData(TCSD_PACKET_TYPE_UINT32, i++, pcKeyHierarchySize, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		if (*pcKeyHierarchySize > 0) {
			*ppKeyHierarchy = malloc((*pcKeyHierarchySize) * sizeof(TSS_KM_KEYINFO));
			if (*ppKeyHierarchy == NULL) {
				LogError("malloc of %zu bytes failed.", (*pcKeyHierarchySize) *
					 sizeof(TSS_KM_KEYINFO));
				result = TSPERR(TSS_E_OUTOFMEMORY);
				goto done;
			}
			for (j = 0; (UINT32)j < *pcKeyHierarchySize; j++) {
				if (getData(TCSD_PACKET_TYPE_KM_KEYINFO, i++,
					    &((*ppKeyHierarchy)[j]), 0, &hte->comm)) {
					free(*ppKeyHierarchy);
					result = TSPERR(TSS_E_INTERNAL_ERROR);
					goto done;
				}
			}
		} else {
			*ppKeyHierarchy = NULL;
		}
	}

done:
	return result;
}

TSS_RESULT
RPC_EnumRegisteredKeys2_TP(struct host_table_entry *hte,
				      TSS_UUID * pKeyUUID,	/* in */
				      UINT32 * pcKeyHierarchySize,	/* out */
				      TSS_KM_KEYINFO2 ** ppKeyHierarchy	/* out */
					  )
{
	TSS_RESULT result;
	int i, j;

	initData(&hte->comm, 2);
	hte->comm.hdr.u.ordinal = TCSD_ORD_ENUMREGISTEREDKEYS2;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	if (pKeyUUID != NULL) {
		if (setData(TCSD_PACKET_TYPE_UUID, 1, pKeyUUID, 0, &hte->comm))
			return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		i = 0;
		if (getData(TCSD_PACKET_TYPE_UINT32, i++, pcKeyHierarchySize, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		if (*pcKeyHierarchySize > 0) {
			*ppKeyHierarchy = malloc((*pcKeyHierarchySize) * sizeof(TSS_KM_KEYINFO2));
			if (*ppKeyHierarchy == NULL) {
				LogError("malloc of %zu bytes failed.", (*pcKeyHierarchySize) *
					 sizeof(TSS_KM_KEYINFO2));
				result = TSPERR(TSS_E_OUTOFMEMORY);
				goto done;
			}
			for (j = 0; (UINT32)j < *pcKeyHierarchySize; j++) {
				if (getData(TCSD_PACKET_TYPE_KM_KEYINFO2, i++,
					    &((*ppKeyHierarchy)[j]), 0, &hte->comm)) {
					free(*ppKeyHierarchy);
					result = TSPERR(TSS_E_INTERNAL_ERROR);
					goto done;
				}
			}
		} else {
			*ppKeyHierarchy = NULL;
		}
	}

done:
	return result;
}

TSS_RESULT
RPC_GetRegisteredKey_TP(struct host_table_entry *hte,
				    TSS_UUID KeyUUID,	/* in */
				    TSS_KM_KEYINFO ** ppKeyInfo	/* out */
    ) {
	return TSPERR(TSS_E_NOTIMPL);
}

TSS_RESULT
RPC_GetRegisteredKeyBlob_TP(struct host_table_entry *hte,
					TSS_UUID KeyUUID,	/* in */
					UINT32 * pcKeySize,	/* out */
					BYTE ** prgbKey	/* out */
    ) {
	TSS_RESULT result;

	initData(&hte->comm, 2);
	hte->comm.hdr.u.ordinal = TCSD_ORD_GETREGISTEREDKEYBLOB;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UUID, 1, &KeyUUID, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_UINT32, 0, pcKeySize, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		*prgbKey = malloc(*pcKeySize);
		if (*prgbKey == NULL) {
			LogError("malloc of %u bytes failed.", *pcKeySize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, 1, *prgbKey, *pcKeySize, &hte->comm)) {
			free(*prgbKey);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		}
	}

done:
	return result;

}

TSS_RESULT
RPC_LoadKeyByUUID_TP(struct host_table_entry *hte,
				  TSS_UUID KeyUUID,	/* in */
				  TCS_LOADKEY_INFO * pLoadKeyInfo,	/* in, out */
				  TCS_KEY_HANDLE * phKeyTCSI	/* out */
    ) {
	TSS_RESULT result;

	initData(&hte->comm, 3);
	hte->comm.hdr.u.ordinal = TCSD_ORD_LOADKEYBYUUID;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UUID, 1, &KeyUUID, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	if (pLoadKeyInfo != NULL) {
		if (setData(TCSD_PACKET_TYPE_LOADKEY_INFO, 2, pLoadKeyInfo, 0, &hte->comm))
			return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_UINT32, 0, phKeyTCSI, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);

		LogDebugFn("TCS key handle: 0x%x", *phKeyTCSI);
	} else if (pLoadKeyInfo && (result == (TCS_E_KM_LOADFAILED | TSS_LAYER_TCS))) {
		if (getData(TCSD_PACKET_TYPE_LOADKEY_INFO, 0, pLoadKeyInfo, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
	}

	return result;
}

void
LoadBlob_LOADKEY_INFO(UINT64 *offset, BYTE *blob, TCS_LOADKEY_INFO *info)
{
	Trspi_LoadBlob_UUID(offset, blob, info->keyUUID);
	Trspi_LoadBlob_UUID(offset, blob, info->parentKeyUUID);
	Trspi_LoadBlob(offset, TCPA_DIGEST_SIZE, blob, info->paramDigest.digest);
	Trspi_LoadBlob_UINT32(offset, info->authData.AuthHandle, blob);
	Trspi_LoadBlob(offset, TCPA_NONCE_SIZE, blob, (BYTE *)&info->authData.NonceOdd.nonce);
	Trspi_LoadBlob(offset, TCPA_NONCE_SIZE, blob, (BYTE *)&info->authData.NonceEven.nonce);
	Trspi_LoadBlob_BOOL(offset, info->authData.fContinueAuthSession, blob);
	Trspi_LoadBlob(offset, TCPA_DIGEST_SIZE, blob, (BYTE *)&info->authData.HMAC);
}

void
UnloadBlob_LOADKEY_INFO(UINT64 *offset, BYTE *blob, TCS_LOADKEY_INFO *info)
{
	Trspi_UnloadBlob_UUID(offset, blob, &info->keyUUID);
	Trspi_UnloadBlob_UUID(offset, blob, &info->parentKeyUUID);
	Trspi_UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, (BYTE *)&info->paramDigest.digest);
	Trspi_UnloadBlob_UINT32(offset, &info->authData.AuthHandle, blob);
	Trspi_UnloadBlob(offset, TCPA_NONCE_SIZE, blob, (BYTE *)&info->authData.NonceOdd.nonce);
	Trspi_UnloadBlob(offset, TCPA_NONCE_SIZE, blob, (BYTE *)&info->authData.NonceEven.nonce);
	Trspi_UnloadBlob_BOOL(offset, &info->authData.fContinueAuthSession, blob);
	Trspi_UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, (BYTE *)&info->authData.HMAC);
}



<|start_filename|>src/include/tss/tddlapi_error.h<|end_filename|>
/*++

TDDL error return codes for the TPM Device Driver Library Interface (TDDLI)
 
--*/

#ifndef __TDDLAPI_ERROR_H__
#define __TDDLAPI_ERROR_H__


//
// error coding scheme for a Microsoft Windows platform -
// refer to the TSS Specification Parts
//
//  Values are 32 bit values layed out as follows:
//
//   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
//   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
//  +---+-+-+-----------------------+-------+-----------------------+
//  |Lev|C|R|     Facility          | Layer |         Code          |
//  +---+-+-+-----------------------+-------+-----------------------+
//  | Platform specific coding      | TSS error coding system       |
//  +---+-+-+-----------------------+-------+-----------------------+
//
//      Lev - is the Level code
//
//          00 - Success
//          01 - Informational
//          10 - Warning
//          11 - Error
//
//      C - is the Customer code flag  (must actually be set)
//
//      R - is a reserved bit    (unused)
//
//      Facility - is the facility code: TCPA: proposal 0x028
//
//      Code - is the facility's status code
//


// no macros are used below intentionally 
// for a better error code recognition by the reader

// note that the values of TPM_E_BASE and TSS_E_BASE, TSS_W_BASE and TSS_I_BASE
// have to be adjusted for a platform other than Windows

//
// TPM specific error codes (layer nibble set to TPM layer TSS_LAYER_TPM)
//


#endif // __TDDLAPI_ERROR_H__



<|start_filename|>src/tcs/log.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */


#include <stdio.h>
#include <string.h>
#include <syslog.h>

#include "trousers/tss.h"
#include "tcslog.h"

#ifdef TSS_DEBUG

/*
 * LogBlobData()
 *
 *   Log a blob's data to the debugging stream
 *
 * szDescriptor - The APPID tag found in the caller's environment at build time
 * sizeOfBlob - The size of the data to log
 * blob - the data to log
 *
 */

void
LogBlobData(char *szDescriptor, unsigned long sizeOfBlob, unsigned char *blob)
{
	char temp[64];
	unsigned int i;


	if (getenv("TCSD_FOREGROUND") == NULL)
		openlog(szDescriptor, LOG_NDELAY|LOG_PID, TSS_SYSLOG_LVL);
	memset(temp, 0, sizeof(temp));

	for (i = 0; (unsigned long)i < sizeOfBlob; i++) {
		if ((i > 0) && ((i % 16) == 0)) {
			if (getenv("TCSD_FOREGROUND") != NULL)
				fprintf(stdout, "%s %s\n", szDescriptor, temp);
			else
				syslog(LOG_DEBUG, "%s", temp);
			memset(temp, 0, sizeof(temp));
		}
		snprintf(&temp[(i%16)*3], 4, "%.2X ", blob[i]);
	}

	if (i == sizeOfBlob) {
		if (getenv("TCSD_FOREGROUND") != NULL)
			fprintf(stdout, "%s %s\n", szDescriptor, temp);
		else
			syslog(LOG_DEBUG, "%s", temp);
	}
}

void
LogTPMERR(TSS_RESULT result, char *file, int line)
{
	if (getenv("TSS_DEBUG_OFF") == NULL)
		fprintf(stderr, "%s %s %s:%d: 0x%x\n", "LOG_RETERR", "TPM", file, line, result);
}

TSS_RESULT
LogTDDLERR(TSS_RESULT result, char *file, int line)
{
	if (getenv("TSS_DEBUG_OFF") == NULL)
		fprintf(stderr, "%s %s %s:%d: 0x%x\n", "LOG_RETERR", APPID, file, line, result);

	return (result | TSS_LAYER_TDDL);
}

TSS_RESULT
LogTCSERR(TSS_RESULT result, char *file, int line)
{
	if (getenv("TSS_DEBUG_OFF") == NULL)
		fprintf(stderr, "%s %s %s:%d: 0x%x\n", "LOG_RETERR", APPID, file, line, result);

	return (result | TSS_LAYER_TCS);
}

#endif


<|start_filename|>src/include/tsp_delegate.h<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2007
 *
 */

#ifndef _TSP_DELEGATE_H_
#define _TSP_DELEGATE_H_

TSS_RESULT      do_delegate_manage(TSS_HTPM hTpm, UINT32 familyID, UINT32 opFlag,
				   UINT32 opDataSize, BYTE *opData, UINT32 *outDataSize, BYTE **outData);
TSS_RESULT	create_key_delegation(TSS_HKEY, BYTE, UINT32, TSS_HPCRS, TSS_HDELFAMILY, TSS_HPOLICY);
TSS_RESULT	create_owner_delegation(TSS_HTPM, BYTE, UINT32, TSS_HPCRS, TSS_HDELFAMILY, TSS_HPOLICY);

TSS_RESULT	update_delfamily_object(TSS_HTPM, UINT32);
TSS_RESULT	get_delegate_index(TSS_HCONTEXT, UINT32, TPM_DELEGATE_PUBLIC *);
TSS_RESULT	__tspi_build_delegate_public_info(BYTE, TSS_HPCRS, TSS_HDELFAMILY, TSS_HPOLICY, UINT32 *, BYTE **);

#endif


<|start_filename|>src/tspi/daa/daa_issuer/issuer_init.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2006
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

// for message digest
#include <openssl/evp.h>

#include <stdlib.h>
#include "daa_structs.h"
#include "daa_parameter.h"
#include "trousers/tss.h"
#include "spi_internal_types.h"
#include "spi_utils.h"
#include <trousers/trousers.h>
#include <spi_utils.h>
#include <obj.h>
#include "tsplog.h"
#include "tss/tcs.h"

/*
Verifies if the key is a valid endorsement key of a TPM. (TPM is good)
return 0 if correct
 */
int verify_ek_and_daaCounter(
	UINT32 endorsementLength,
	BYTE *endorsementCredential,
	UINT32 daaCounter
) {
	// TODO
	return 0;
}


TSS_RESULT Tspi_DAA_IssueInit_internal(
	TSS_HDAA	hDAA,	// in
	TSS_HKEY	issuerAuthPK,	// in
	TSS_HKEY	issuerKeyPair,	// in (TSS_DAA_KEY_PAIR *)
	TSS_DAA_IDENTITY_PROOF	identityProof,	// in
	UINT32	capitalUprimeLength,	// in
	BYTE*	capitalUprime,	// in
	UINT32	daaCounter,	// in
	UINT32*	nonceIssuerLength,	// out
	BYTE**	nonceIssuer,	// out
	UINT32*	authenticationChallengeLength,	// out
	BYTE**	authenticationChallenge,	// out
	TSS_DAA_JOIN_ISSUER_SESSION*	joinSession	// out
) {
	TCS_CONTEXT_HANDLE tcsContext;
	TSS_RESULT result;
	BYTE *ne, *buffer;
	bi_t random;
	int length_ne;

	if( (result = obj_daa_get_tsp_context( hDAA, &tcsContext)) != TSS_SUCCESS)
		return result;
	// 1 & 2 : verify EK (and associated credentials) of the platform
	if( verify_ek_and_daaCounter( identityProof.endorsementLength,
				identityProof.endorsementCredential, daaCounter) != 0) {
		LogError("EK verification failed");
		return TSS_E_INTERNAL_ERROR;
	}

	// 3 : choose a random nonce for the platform (ni)
	bi_new( random);
	bi_urandom( random, DAA_PARAM_LENGTH_MESSAGE_DIGEST * 8);
	buffer = bi_2_nbin( nonceIssuerLength, random);
	if( buffer == NULL) {
		LogError("malloc of %d bytes failed", *nonceIssuerLength);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}
	*nonceIssuer =  convert_alloc( tcsContext, *nonceIssuerLength, buffer);
	if (*nonceIssuer == NULL) {
		LogError("malloc of %d bytes failed", *nonceIssuerLength);
		free( buffer);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	LogDebug("nonce Issuer[%d:%d]:%s", DAA_PARAM_LENGTH_MESSAGE_DIGEST,
		*nonceIssuerLength,
		dump_byte_array( *nonceIssuerLength , *nonceIssuer));

	// 4 : choose a random nonce ne and encrypt it under EK
	bi_urandom( random, DAA_PARAM_LENGTH_MESSAGE_DIGEST * 8);
	ne = convert_alloc( tcsContext, length_ne, bi_2_nbin( &length_ne, random));
	if (ne == NULL) {
		LogError("malloc of %d bytes failed", length_ne);
		free( buffer);
		free( nonceIssuer);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	bi_free( random);
	*authenticationChallenge = (BYTE *)calloc_tspi( tcsContext, 256); // 256: RSA size
	if (*authenticationChallenge == NULL) {
		LogError("malloc of %d bytes failed", 256);
		free( buffer);
		free( nonceIssuer);
		free( ne);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}
	result = Trspi_RSA_Encrypt(
		ne,	// message to encrypt
		length_ne,	// length message to encrypt
		*authenticationChallenge,	// destination
		authenticationChallengeLength, // length destination
		identityProof.endorsementCredential, // public key
		identityProof.endorsementLength); // public key size
	if( result != TSS_SUCCESS) {
		LogError("Can not encrypt the Authentication Challenge");
		free( buffer);
		free( nonceIssuer);
		free( ne);
		return TSS_E_INTERNAL_ERROR;
	}
	LogDebug("authenticationChallenge[%d:%d]:%s", DAA_PARAM_LENGTH_MESSAGE_DIGEST,
		*authenticationChallengeLength,
		dump_byte_array( *authenticationChallengeLength , *authenticationChallenge));

	// 5 : save PK, PKDAA, (p', q'), U', daaCounter, ni, ne in joinSession
	// EK is not a member of joinSession but is already saved in identityProof
	joinSession->issuerAuthPK = issuerAuthPK;
	joinSession->issuerKeyPair = issuerKeyPair;
	memcpy( &(joinSession->identityProof), &identityProof, sizeof(TSS_DAA_IDENTITY_PROOF));
	joinSession->capitalUprimeLength = capitalUprimeLength;
	joinSession->capitalUprime = capitalUprime;
	joinSession->daaCounter = daaCounter;
	joinSession->nonceIssuerLength = *nonceIssuerLength;
	joinSession->nonceIssuer = *nonceIssuer;
	joinSession->nonceEncryptedLength = length_ne;
	joinSession->nonceEncrypted = ne;
	return result;
}


<|start_filename|>src/tspi/tsp_ek.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


TSS_RESULT
owner_get_pubek(TSS_HCONTEXT tspContext, TSS_HTPM hTPM, TSS_HKEY *hPubEk)
{
	TSS_RESULT result;
	UINT32 tpmVersion, pubEKSize;
	TSS_HPOLICY hPolicy;
	Trspi_HashCtx hashCtx;
	BYTE *pubEK = NULL;
	TSS_HKEY hRetKey;
	TPM_AUTH ownerAuth;
	TPM_DIGEST digest;


	if ((result = obj_context_get_tpm_version(tspContext, &tpmVersion)))
		return result;

	if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hPolicy)))
		return result;

	switch (tpmVersion) {
	case 2:
		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerReadInternalPub);
		result |= Trspi_Hash_UINT32(&hashCtx, TPM_KH_EK);
		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
			goto done;

		if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_OwnerReadInternalPub,
						      hPolicy, FALSE, &digest, &ownerAuth)))
			goto done;

		if ((result = TCS_API(tspContext)->OwnerReadInternalPub(tspContext, TPM_KH_EK,
									&ownerAuth, &pubEKSize,
									&pubEK)))
			goto done;

		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
		result |= Trspi_Hash_UINT32(&hashCtx, TPM_SUCCESS);
		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerReadInternalPub);
		result |= Trspi_HashUpdate(&hashCtx, pubEKSize, pubEK);
		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
			goto done;

		if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &ownerAuth)))
			goto done;
		break;
	default:
		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerReadPubek);
		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
			goto done;

		if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_OwnerReadPubek, hPolicy, FALSE,
						      &digest, &ownerAuth)))
			goto done;

		if ((result = TCS_API(tspContext)->OwnerReadPubek(tspContext, &ownerAuth,
								  &pubEKSize, &pubEK)))
			goto done;

		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
		result |= Trspi_Hash_UINT32(&hashCtx, TPM_SUCCESS);
		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerReadPubek);
		result |= Trspi_HashUpdate(&hashCtx, pubEKSize, pubEK);
		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
			goto done;

		if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &ownerAuth)))
			goto done;

		break;
	}

	if ((result = obj_rsakey_add(tspContext, TSS_KEY_SIZE_2048|TSS_KEY_TYPE_LEGACY, &hRetKey)))
		goto done;

	if ((result = obj_rsakey_set_pubkey(hRetKey, TRUE, pubEK)))
		goto done;

	*hPubEk = hRetKey;
done:
	free(pubEK);
	return result;
}


<|start_filename|>src/tcs/tcsi_dir.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcsps.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "req_mgr.h"
#include "tcsd_wrap.h"
#include "tcsd.h"

TSS_RESULT
TCSP_DirWriteAuth_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			   TCPA_DIRINDEX dirIndex,	/* in */
			   TCPA_DIRVALUE newContents,	/* in */
			   TPM_AUTH * ownerAuth)	/* in, out */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering dirwriteauth");
	if ((result = ctx_verify_context(hContext)))
		goto done;

	if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
		goto done;

	if (dirIndex > tpm_metrics.num_dirs) {
		result = TCSERR(TSS_E_BAD_PARAMETER);
		goto done;
	}

	if ((result = tpm_rqu_build(TPM_ORD_DirWriteAuth, &offset, txBlob, dirIndex,
				    TPM_DIGEST_SIZE, newContents.digest, ownerAuth, NULL)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);

	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_DirWriteAuth, txBlob, paramSize, ownerAuth);
	}
	LogResult("DirWriteAuth", result);
done:
	auth_mgr_release_auth(ownerAuth, NULL, hContext);
	return result;
}

TSS_RESULT
TCSP_DirRead_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
		      TCPA_DIRINDEX dirIndex,	/* in */
		      TCPA_DIRVALUE * dirValue)	/* out */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering DirRead");
	if ((result = ctx_verify_context(hContext)))
		return result;

	if (dirValue == NULL)
		return TCSERR(TSS_E_BAD_PARAMETER);

	if (dirIndex > tpm_metrics.num_dirs)
		return TCSERR(TSS_E_BAD_PARAMETER);

	if ((result = tpm_rqu_build(TPM_ORD_DirRead, &offset, txBlob, dirIndex, NULL)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_DirRead, txBlob, paramSize, NULL, dirValue->digest);
	}
	LogResult("DirRead", result);
	return result;
}



<|start_filename|>src/tspi/rpc/tcstp/rpc_auth.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "hosttable.h"
#include "tcsd_wrap.h"
#include "obj.h"
#include "rpc_tcstp_tsp.h"


TSS_RESULT
RPC_OIAP_TP(struct host_table_entry *hte,
			 TCS_AUTHHANDLE * authHandle,	/* out */
			 TCPA_NONCE * nonce0	/* out */
    ) {
	TSS_RESULT result;

	initData(&hte->comm, 1);
	hte->comm.hdr.u.ordinal = TCSD_ORD_OIAP;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_UINT32, 0, authHandle, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		if (getData(TCSD_PACKET_TYPE_NONCE, 1, nonce0, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
	}

	return result;
}

TSS_RESULT
RPC_OSAP_TP(struct host_table_entry *hte,
			 TCPA_ENTITY_TYPE entityType,	/* in */
			 UINT32 entityValue,	/* in */
			 TCPA_NONCE * nonceOddOSAP,	/* in */
			 TCS_AUTHHANDLE * authHandle,	/* out */
			 TCPA_NONCE * nonceEven,	/* out */
			 TCPA_NONCE * nonceEvenOSAP	/* out */
    ) {
	TSS_RESULT result;

	initData(&hte->comm, 4);
	hte->comm.hdr.u.ordinal = TCSD_ORD_OSAP;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT16, 1, &entityType, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 2, &entityValue, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_NONCE, 3, nonceOddOSAP, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_UINT32, 0, authHandle, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		if (getData(TCSD_PACKET_TYPE_NONCE, 1, nonceEven, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		if (getData(TCSD_PACKET_TYPE_NONCE, 2, nonceEvenOSAP, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
	}

	return result;
}


<|start_filename|>src/tspi/tsp_oper.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <errno.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


#ifdef TSS_BUILD_TRANSPORT
TSS_RESULT
Transport_SetOperatorAuth(TSS_HCONTEXT tspContext,	/* in */
			  TCPA_SECRET *operatorAuth)		/* in */
{
	TSS_RESULT result;
	UINT64 offset;
	TCS_HANDLE handlesLen = 0;
	BYTE data[sizeof(TCPA_SECRET)];

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	offset = 0;
	Trspi_LoadBlob(&offset, TPM_SHA1_160_HASH_LEN, data, operatorAuth->authdata);

	return obj_context_transport_execute(tspContext, TPM_ORD_SetOperatorAuth, sizeof(data),
					     data, NULL, &handlesLen, NULL, NULL, NULL, NULL, NULL);
}
#endif


<|start_filename|>src/tcs/tcsi_quote.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2006
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcsps.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "req_mgr.h"
#include "tcsd_wrap.h"
#include "tcsd.h"


TSS_RESULT
TCSP_Quote_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
		    TCS_KEY_HANDLE keyHandle,	/* in */
		    TCPA_NONCE antiReplay,	/* in */
		    UINT32 pcrDataSizeIn,	/* in */
		    BYTE * pcrDataIn,	/* in */
		    TPM_AUTH * privAuth,	/* in, out */
		    UINT32 * pcrDataSizeOut,	/* out */
		    BYTE ** pcrDataOut,	/* out */
		    UINT32 * sigSize,	/* out */
		    BYTE ** sig)	/* out */
{

	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	UINT32 keySlot;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering quote");

	if ((result = ctx_verify_context(hContext)))
		goto done;

	if (privAuth != NULL) {
		LogDebug("Auth Used");
		if ((result = auth_mgr_check(hContext, &privAuth->AuthHandle)))
			goto done;
	} else {
		LogDebug("No Auth");
	}
	if ((result = ensureKeyIsLoaded(hContext, keyHandle, &keySlot)))
		goto done;

	if ((result = tpm_rqu_build(TPM_ORD_Quote, &offset, txBlob, keySlot, antiReplay.nonce,
				    pcrDataSizeIn, pcrDataIn, privAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_Quote, txBlob, paramSize, pcrDataSizeOut, pcrDataOut,
				       sigSize, sig, privAuth);
	}
	LogResult("Quote", result);
done:
	auth_mgr_release_auth(privAuth, NULL, hContext);
	return result;
}



<|start_filename|>src/tcs/tcs_evlog.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcsd_wrap.h"
#include "tcsd.h"
#include "tcslog.h"
#include "tcsem.h"


struct event_log *tcs_event_log = NULL;

TSS_RESULT
event_log_init()
{
	if (tcs_event_log != NULL)
		return TSS_SUCCESS;

	tcs_event_log = calloc(1, sizeof(struct event_log));
	if (tcs_event_log == NULL) {
		LogError("malloc of %zd bytes failed.", sizeof(struct event_log));
		return TCSERR(TSS_E_OUTOFMEMORY);
	}

	MUTEX_INIT(tcs_event_log->lock);

	/* allocate as many event lists as there are PCR's */
	tcs_event_log->lists = calloc(tpm_metrics.num_pcrs, sizeof(struct event_wrapper *));
	if (tcs_event_log->lists == NULL) {
		LogError("malloc of %zd bytes failed.",
				tpm_metrics.num_pcrs * sizeof(struct event_wrapper *));
		free(tcs_event_log);
		return TCSERR(TSS_E_OUTOFMEMORY);
	}

	/* assign external event log sources here */
	//tcs_event_log->firmware_source = EVLOG_IMA_SOURCE;
	tcs_event_log->firmware_source = EVLOG_BIOS_SOURCE;
	tcs_event_log->kernel_source = EVLOG_IMA_SOURCE;

	return TSS_SUCCESS;
}

TSS_RESULT
event_log_final()
{
	struct event_wrapper *cur, *next;
	UINT32 i;

	MUTEX_LOCK(tcs_event_log->lock);

	for (i = 0; i < tpm_metrics.num_pcrs; i++) {
		cur = tcs_event_log->lists[i];
		while (cur != NULL) {
			next = cur->next;
			free(cur->event.rgbPcrValue);
			free(cur->event.rgbEvent);
			free(cur);
			cur = next;
		}
	}

	MUTEX_UNLOCK(tcs_event_log->lock);

	free(tcs_event_log->lists);
	free(tcs_event_log);

	return TSS_SUCCESS;
}

TSS_RESULT
copy_pcr_event(TSS_PCR_EVENT *dest, TSS_PCR_EVENT *source)
{
	memcpy(dest, source, sizeof(TSS_PCR_EVENT));
	return TSS_SUCCESS;
}

TSS_RESULT
event_log_add(TSS_PCR_EVENT *event, UINT32 *pNumber)
{
	struct event_wrapper *new, *tmp;
	TSS_RESULT result;
	UINT32 i;

	MUTEX_LOCK(tcs_event_log->lock);

	new = calloc(1, sizeof(struct event_wrapper));
	if (new == NULL) {
		LogError("malloc of %zd bytes failed.", sizeof(struct event_wrapper));
		MUTEX_UNLOCK(tcs_event_log->lock);
		return TCSERR(TSS_E_OUTOFMEMORY);
	}

	if ((result = copy_pcr_event(&(new->event), event))) {
		free(new);
		MUTEX_UNLOCK(tcs_event_log->lock);
		return result;
	}

	/* go to the end of the list to add the element, so that they're in order */
	i = 0;
	if (tcs_event_log->lists[event->ulPcrIndex] == NULL) {
		tcs_event_log->lists[event->ulPcrIndex] = new;
	} else {
		i++;
		tmp = tcs_event_log->lists[event->ulPcrIndex];
		while (tmp->next != NULL) {
			i++;
			tmp = tmp->next;
		}
		tmp->next = new;
	}

	*pNumber = ++i;

	MUTEX_UNLOCK(tcs_event_log->lock);

	return TSS_SUCCESS;
}

TSS_PCR_EVENT *
get_pcr_event(UINT32 pcrIndex, UINT32 eventNumber)
{
	struct event_wrapper *tmp;
	UINT32 counter = 0;

	MUTEX_LOCK(tcs_event_log->lock);

	tmp = tcs_event_log->lists[pcrIndex];
	for (; tmp; tmp = tmp->next) {
		if (counter == eventNumber) {
			break;
		}
		counter++;
	}

	MUTEX_UNLOCK(tcs_event_log->lock);

	return (tmp ? &(tmp->event) : NULL);
}

/* the lock should be held before calling this function */
UINT32
get_num_events(UINT32 pcrIndex)
{
	struct event_wrapper *tmp;
	UINT32 counter = 0;

	tmp = tcs_event_log->lists[pcrIndex];
	for (; tmp; tmp = tmp->next) {
		counter++;
	}

	return counter;
}

TSS_PCR_EVENT *
concat_pcr_events(TSS_PCR_EVENT **list_so_far, UINT32 list_size, TSS_PCR_EVENT *addition,
		  UINT32 addition_size)
{
	TSS_PCR_EVENT *ret;

	ret = realloc(*list_so_far, (list_size + addition_size) * sizeof(TSS_PCR_EVENT));
	if (ret == NULL) {
		LogError("malloc of %zd bytes failed",
			 (list_size + addition_size) * sizeof(TSS_PCR_EVENT));
		return ret;
	}

	memcpy(&ret[list_size], addition, addition_size * sizeof(TSS_PCR_EVENT));
	return ret;
}

/* XXX make this a macro */
UINT32
get_pcr_event_size(TSS_PCR_EVENT *e)
{
	return (sizeof(TSS_PCR_EVENT) + e->ulEventLength + e->ulPcrValueLength);
}

void
free_external_events(UINT32 eventCount, TSS_PCR_EVENT *ppEvents)
{
	UINT32 j;

	if (!ppEvents)
		return;

	for (j = 0; j < eventCount; j++) {
		/* This is a fairly heinous hack, but PCR event logs can get really large
		 * and without it, there is a real potential to exhaust memory by leaks.
		 * The PCR event logs that we pull out of securityfs have had their
		 * rgbPcrValue and rgbEvent pointers malloc'd dynamically as the
		 * securityfs log was parsed. The other event log lists that are
		 * maintained by the TCSD don't need to have this data free'd, since that
		 * will happen at shutdown time only. So, for each PCR index that's
		 * read from securityfs, we need to free its pointers after that data has
		 * been set in the packet to send back to the TSP. */
		if ((tcsd_options.kernel_pcrs & (1 << ppEvents[j].ulPcrIndex)) ||
		    (tcsd_options.firmware_pcrs & (1 << ppEvents[j].ulPcrIndex))) {
			free(ppEvents[j].rgbPcrValue);
			free(ppEvents[j].rgbEvent);
		}
	}
}


<|start_filename|>src/tspi/rpc/tcstp/rpc_key.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "hosttable.h"
#include "tcsd_wrap.h"
#include "obj.h"
#include "rpc_tcstp_tsp.h"


TSS_RESULT
RPC_LoadKeyByBlob_TP(struct host_table_entry *hte,
		      TCS_KEY_HANDLE hUnwrappingKey,	/* in */
		      UINT32 cWrappedKeyBlobSize,	/* in */
		      BYTE * rgbWrappedKeyBlob,	/* in */
		      TPM_AUTH * pAuth,	/* in, out */
		      TCS_KEY_HANDLE * phKeyTCSI,	/* out */
		      TCS_KEY_HANDLE * phKeyHMAC)	/* out */
{
	TSS_RESULT result;
	int i;

	initData(&hte->comm, 5);
	hte->comm.hdr.u.ordinal = TCSD_ORD_LOADKEYBYBLOB;
	LogDebugFn("IN: TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &hUnwrappingKey, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 2, &cWrappedKeyBlobSize, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 3, rgbWrappedKeyBlob, cWrappedKeyBlobSize, &hte->comm))
			return TSPERR(TSS_E_INTERNAL_ERROR);

	if (pAuth != NULL) {
		if (setData(TCSD_PACKET_TYPE_AUTH, 4, pAuth, 0, &hte->comm))
			return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		i = 0;
		if (pAuth != NULL) {
			if (getData(TCSD_PACKET_TYPE_AUTH, i++, pAuth, 0, &hte->comm))
				result = TSPERR(TSS_E_INTERNAL_ERROR);
		}
		if (getData(TCSD_PACKET_TYPE_UINT32, i++, phKeyTCSI, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		if (getData(TCSD_PACKET_TYPE_UINT32, i++, phKeyHMAC, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);

		LogDebugFn("OUT: TCS key handle: 0x%x, TPM key slot: 0x%x", *phKeyTCSI,
			   *phKeyHMAC);
	}

	return result;
}

TSS_RESULT
RPC_EvictKey_TP(struct host_table_entry *hte,
		 TCS_KEY_HANDLE hKey)	/* in */
{
	TSS_RESULT result;

	initData(&hte->comm, 2);
	hte->comm.hdr.u.ordinal = TCSD_ORD_EVICTKEY;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &hKey, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	return result;
}

TSS_RESULT
RPC_CreateWrapKey_TP(struct host_table_entry *hte,
		      TCS_KEY_HANDLE hWrappingKey,	/* in */
		      TCPA_ENCAUTH *KeyUsageAuth,	/* in */
		      TCPA_ENCAUTH *KeyMigrationAuth,	/* in */
		      UINT32 keyInfoSize,	/* in */
		      BYTE * keyInfo,	/* in */
		      UINT32 * keyDataSize,	/* out */
		      BYTE ** keyData,	/* out */
		      TPM_AUTH * pAuth)	/* in, out */
{
	TSS_RESULT result;

	initData(&hte->comm, 7);
	hte->comm.hdr.u.ordinal = TCSD_ORD_CREATEWRAPKEY;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &hWrappingKey, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_ENCAUTH, 2, KeyUsageAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_ENCAUTH, 3, KeyMigrationAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 4, &keyInfoSize, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 5, keyInfo, keyInfoSize, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (pAuth) {
		if (setData(TCSD_PACKET_TYPE_AUTH, 6, pAuth, 0, &hte->comm))
			return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_UINT32, 0, keyDataSize, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		*keyData = (BYTE *) malloc(*keyDataSize);
		if (*keyData == NULL) {
			LogError("malloc of %u bytes failed.", *keyDataSize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, 1, *keyData, *keyDataSize, &hte->comm)) {
			free(*keyData);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (pAuth) {
			if (getData(TCSD_PACKET_TYPE_AUTH, 2, pAuth, 0, &hte->comm)) {
				free(*keyData);
				result = TSPERR(TSS_E_INTERNAL_ERROR);
				goto done;
			}
		}
	}

done:
	return result;
}

TSS_RESULT
RPC_GetPubKey_TP(struct host_table_entry *hte,
		  TCS_KEY_HANDLE hKey,	/* in */
		  TPM_AUTH * pAuth,	/* in, out */
		  UINT32 * pcPubKeySize,	/* out */
		  BYTE ** prgbPubKey)	/* out */
{
	TSS_RESULT result;
	int i;

	initData(&hte->comm, 3);
	hte->comm.hdr.u.ordinal = TCSD_ORD_GETPUBKEY;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &hKey, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (pAuth != NULL) {
		if (setData(TCSD_PACKET_TYPE_AUTH, 2, pAuth, 0, &hte->comm))
			return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	i = 0;
	if (result == TSS_SUCCESS) {
		if (pAuth != NULL) {
			if (getData(TCSD_PACKET_TYPE_AUTH, i++, pAuth, 0, &hte->comm)) {
				result = TSPERR(TSS_E_INTERNAL_ERROR);
				goto done;
			}
		}
		if (getData(TCSD_PACKET_TYPE_UINT32, i++, pcPubKeySize, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		*prgbPubKey = (BYTE *) malloc(*pcPubKeySize);
		if (*prgbPubKey == NULL) {
			LogError("malloc of %u bytes failed.", *pcPubKeySize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *prgbPubKey, *pcPubKeySize, &hte->comm)) {
			free(*prgbPubKey);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		}
	}

done:
	return result;
}

TSS_RESULT
RPC_TerminateHandle_TP(struct host_table_entry *hte,
			TCS_AUTHHANDLE handle)	/* in */
{
	TSS_RESULT result;

	initData(&hte->comm, 2);
	hte->comm.hdr.u.ordinal = TCSD_ORD_TERMINATEHANDLE;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &handle, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	return result;
}

TSS_RESULT
RPC_OwnerReadInternalPub_TP(struct host_table_entry *hte,
			     TCS_KEY_HANDLE hKey,	/* in */
			     TPM_AUTH * pOwnerAuth,	/* in, out */
			     UINT32 * punPubKeySize,	/* out */
			     BYTE ** ppbPubKeyData)	/* out */
{
	TSS_RESULT result;

	initData(&hte->comm, 3);
	hte->comm.hdr.u.ordinal = TCSD_ORD_OWNERREADINTERNALPUB;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &hKey, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (pOwnerAuth != NULL) {
		if (setData(TCSD_PACKET_TYPE_AUTH, 2, pOwnerAuth, 0, &hte->comm))
			return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_AUTH, 0, pOwnerAuth, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		if (getData(TCSD_PACKET_TYPE_UINT32, 1, punPubKeySize, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);

		*ppbPubKeyData = (BYTE *) malloc(*punPubKeySize);
		if (*ppbPubKeyData == NULL) {
			LogError("malloc of %u bytes failed.", *punPubKeySize);
			return TSPERR(TSS_E_OUTOFMEMORY);
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, 2, *ppbPubKeyData, *punPubKeySize, 
			    &hte->comm)) {
			free(*ppbPubKeyData);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		}
	}

	return result;
}

/* TSS 1.2-only interfaces */
#ifdef TSS_BUILD_TSS12
TSS_RESULT
RPC_KeyControlOwner_TP(struct host_table_entry *hte,		// in
			TCS_KEY_HANDLE     hKey,		// in
			UINT32             ulPublicInfoLength,	// in
			BYTE*              rgbPublicInfo,	// in
			UINT32             attribName,		// in
			TSS_BOOL           attribValue,		// in
			TPM_AUTH*          pOwnerAuth,		// in, out
			TSS_UUID*          pUuidData)		// out

{
	TSS_RESULT result;

	initData(&hte->comm, 7);
	hte->comm.hdr.u.ordinal = TCSD_ORD_KEYCONTROLOWNER;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &hKey, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 2, &ulPublicInfoLength, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 3, rgbPublicInfo, ulPublicInfoLength, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 4, &attribName, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_BOOL, 5, &attribValue, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (pOwnerAuth != NULL) {
		if (setData(TCSD_PACKET_TYPE_AUTH, 6, pOwnerAuth, 0, &hte->comm))
			return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_AUTH, 0, pOwnerAuth, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		if (getData(TCSD_PACKET_TYPE_UUID, 1, pUuidData, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
	}

	return result;
}
#endif


<|start_filename|>src/include/imaem.h<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */

#ifndef _IMAEM_H_
#define _IMAEM_H_

int ima_open(void *, FILE **);
TSS_RESULT ima_get_entries_by_pcr(FILE *, UINT32, UINT32, UINT32 *, TSS_PCR_EVENT **);
TSS_RESULT ima_get_entry(FILE *, UINT32, UINT32 *, TSS_PCR_EVENT **);
int ima_close(FILE *);

extern struct ext_log_source ima_source;

/*  4  bytes binary         [PCR  value]
 * 20  bytes binary         [SHA1 value]
 *  4  bytes binary         [event type]
 * 255 bytes of ascii (MAX) [event name]
 * 1   byte -> '\0'         [separator ]
 */
#define IMA_MIN_EVENT_SIZE 29
#define IMA_MAX_EVENT_SIZE 284

/* this should be large if we're reading out of /proc */
#define IMA_READ_SIZE	(4096 + IMA_MAX_EVENT_SIZE)

#define EVLOG_SOURCE_IMA	1

#endif


<|start_filename|>src/include/tss/tcs_defines.h<|end_filename|>
/*++

TSS Core Service structures

*/

#ifndef __TCS_DEFINES_H__
#define __TCS_DEFINES_H__

#define TSS_TCSATTRIB_TRANSPORT_DEFAULT           ((UINT32)(0x00000000))
#define TSS_TCSATTRIB_TRANSPORT_EXCLUSIVE         ((UINT32)(0x00000001))


// Values for the ulCredentialType parameter to Tcsi_GetCredential
#define TSS_TCS_CREDENTIAL_EKCERT                 ((UINT32)0x00000001)
#define TSS_TCS_CREDENTIAL_TPM_CC                 ((UINT32)0x00000002)
#define TSS_TCS_CREDENTIAL_PLATFORMCERT           ((UINT32)0x00000003)


// Values for the ulCredentialAccessMode parameter to Tcsi_GetCredential
//  TSS_TCS_CERT_ACCESS_AUTO triggers the default behavior.
//  Values with TSS_TCS_CERT_VENDOR_SPECIFIC_BIT set trigger
//    vendor specific behavior.
#define TSS_TCS_CERT_ACCESS_AUTO                  ((UINT32)0x00000001)

#define TSS_TCS_CERT_VENDOR_SPECIFIC_BIT          ((UINT32)0x80000000)

#endif // __TCS_DEFINES_H__


<|start_filename|>src/tspi/tspi_getset.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <errno.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"
#include "tsp_audit.h"


TSS_RESULT
Tspi_SetAttribUint32(TSS_HOBJECT hObject,	/* in */
		     TSS_FLAG attribFlag,	/* in */
		     TSS_FLAG subFlag,		/* in */
		     UINT32 ulAttrib)		/* in */
{
	TSS_RESULT result;

	if (obj_is_rsakey(hObject)) {
#ifdef TSS_BUILD_RSAKEY_LIST
		if (attribFlag == TSS_TSPATTRIB_KEY_REGISTER) {
			if (subFlag)
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);

			if (ulAttrib == TSS_TSPATTRIB_KEYREGISTER_USER)
				result = obj_rsakey_set_pstype(hObject, TSS_PS_TYPE_USER);
			else if (ulAttrib == TSS_TSPATTRIB_KEYREGISTER_SYSTEM)
				result = obj_rsakey_set_pstype(hObject, TSS_PS_TYPE_SYSTEM);
			else if (ulAttrib == TSS_TSPATTRIB_KEYREGISTER_NO)
				result = obj_rsakey_set_pstype(hObject, TSS_PS_TYPE_NO);
			else
				return TSPERR(TSS_E_INVALID_ATTRIB_DATA);
		} else if (attribFlag == TSS_TSPATTRIB_KEY_INFO) {
			switch (subFlag) {
				case TSS_TSPATTRIB_KEYINFO_USAGE:
					result = obj_rsakey_set_usage(hObject, ulAttrib);
					break;
				case TSS_TSPATTRIB_KEYINFO_MIGRATABLE:
					if (ulAttrib != TRUE && ulAttrib != FALSE)
						return TSPERR(TSS_E_INVALID_ATTRIB_DATA);

					result = obj_rsakey_set_migratable(hObject, ulAttrib);
					break;
				case TSS_TSPATTRIB_KEYINFO_REDIRECTED:
					if (ulAttrib != TRUE && ulAttrib != FALSE)
						return TSPERR(TSS_E_INVALID_ATTRIB_DATA);

					result = obj_rsakey_set_redirected(hObject, ulAttrib);
					break;
				case TSS_TSPATTRIB_KEYINFO_VOLATILE:
					if (ulAttrib != TRUE && ulAttrib != FALSE)
						return TSPERR(TSS_E_INVALID_ATTRIB_DATA);

					result = obj_rsakey_set_volatile(hObject, ulAttrib);
					break;
				case TSS_TSPATTRIB_KEYINFO_AUTHUSAGE:
					/* fall through */
				case TSS_TSPATTRIB_KEYINFO_AUTHDATAUSAGE:
					if (ulAttrib != TRUE && ulAttrib != FALSE)
						return TSPERR(TSS_E_INVALID_ATTRIB_DATA);

					result = obj_rsakey_set_authdata_usage(hObject, ulAttrib);
					break;
				case TSS_TSPATTRIB_KEYINFO_ALGORITHM:
					result = obj_rsakey_set_alg(hObject, ulAttrib);
					break;
				case TSS_TSPATTRIB_KEYINFO_ENCSCHEME:
					if (ulAttrib != TSS_ES_NONE &&
					    ulAttrib != TSS_ES_RSAESPKCSV15 &&
					    ulAttrib != TSS_ES_RSAESOAEP_SHA1_MGF1)
						return TSPERR(TSS_E_INVALID_ATTRIB_DATA);

					result = obj_rsakey_set_es(hObject, ulAttrib);
					break;
				case TSS_TSPATTRIB_KEYINFO_SIGSCHEME:
					if (ulAttrib != TSS_SS_NONE &&
					    ulAttrib != TSS_SS_RSASSAPKCS1V15_SHA1 &&
					    ulAttrib != TSS_SS_RSASSAPKCS1V15_DER  &&
					    ulAttrib !=	TSS_SS_RSASSAPKCS1V15_INFO)
						return TSPERR(TSS_E_INVALID_ATTRIB_DATA);

					result = obj_rsakey_set_ss(hObject, ulAttrib);
					break;
				case TSS_TSPATTRIB_KEYINFO_KEYFLAGS:
					result = obj_rsakey_set_flags(hObject, ulAttrib);
					break;
				case TSS_TSPATTRIB_KEYINFO_SIZE:
					result = obj_rsakey_set_size(hObject, ulAttrib);
					break;
				default:
					return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
			}
		} else if (attribFlag == TSS_TSPATTRIB_RSAKEY_INFO) {
			if (subFlag == TSS_TSPATTRIB_KEYINFO_RSA_PRIMES) {
				result = obj_rsakey_set_num_primes(hObject, ulAttrib);
			} else
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
		} else
			return TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
#endif
#ifdef TSS_BUILD_NV
	} else if (obj_is_nvstore(hObject)) {
		switch (attribFlag) {
			case TSS_TSPATTRIB_NV_INDEX:
				if ((result = obj_nvstore_set_index(hObject, ulAttrib)))
					return result;
				break;
			case TSS_TSPATTRIB_NV_DATASIZE:
				if ((result = obj_nvstore_set_datasize(hObject, ulAttrib)))
					return result;
				break;
			case TSS_TSPATTRIB_NV_PERMISSIONS:
				if ((result = obj_nvstore_set_permission(hObject, ulAttrib)))
					return result;
				break;
			default:
				return TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
				break;
		}
#endif
	} else if (obj_is_policy(hObject)) {
		switch (attribFlag) {
			case TSS_TSPATTRIB_POLICY_CALLBACK_HMAC:
			case TSS_TSPATTRIB_POLICY_CALLBACK_XOR_ENC:
			case TSS_TSPATTRIB_POLICY_CALLBACK_TAKEOWNERSHIP:
			case TSS_TSPATTRIB_POLICY_CALLBACK_CHANGEAUTHASYM:
				result = obj_policy_set_cb11(hObject, attribFlag,
							     subFlag, ulAttrib);
				break;
			case TSS_TSPATTRIB_POLICY_SECRET_LIFETIME:
				if (subFlag == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_ALWAYS ||
				    subFlag == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER ||
				    subFlag == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_TIMER) {
					result = obj_policy_set_lifetime(hObject, subFlag,
									 ulAttrib);
				} else {
					result = TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
				}
				break;
			case TSS_TSPATTRIB_SECRET_HASH_MODE:
				result = obj_policy_set_hash_mode(hObject, ulAttrib);
				break;
#ifdef TSS_BUILD_DELEGATION
			case TSS_TSPATTRIB_POLICY_DELEGATION_INFO:
				switch (subFlag) {
				case TSS_TSPATTRIB_POLDEL_TYPE:
					switch (ulAttrib) {
					case TSS_DELEGATIONTYPE_NONE:
					case TSS_DELEGATIONTYPE_OWNER:
					case TSS_DELEGATIONTYPE_KEY:
						result = obj_policy_set_delegation_type(hObject,
											ulAttrib);
						break;
					default:
						result = TSPERR(TSS_E_INVALID_ATTRIB_DATA);
					}
					break;
				case TSS_TSPATTRIB_POLDEL_INDEX:
					result = obj_policy_set_delegation_index(hObject, ulAttrib);
					break;
				case TSS_TSPATTRIB_POLDEL_PER1:
					result = obj_policy_set_delegation_per1(hObject, ulAttrib);
					break;
				case TSS_TSPATTRIB_POLDEL_PER2:
					result = obj_policy_set_delegation_per2(hObject, ulAttrib);
					break;
				default:
					result = TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
				}
				break;
#endif
			default:
				return TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
				break;
		}
	} else if (obj_is_context(hObject)) {
		switch (attribFlag) {
			case TSS_TSPATTRIB_CONTEXT_SILENT_MODE:
				if (ulAttrib == TSS_TSPATTRIB_CONTEXT_NOT_SILENT)
					result = obj_context_set_mode(hObject, ulAttrib);
				else if (ulAttrib == TSS_TSPATTRIB_CONTEXT_SILENT) {
					if (obj_context_has_popups(hObject))
						return TSPERR(TSS_E_SILENT_CONTEXT);
					result = obj_context_set_mode(hObject, ulAttrib);
				} else
					return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
				break;
#ifdef TSS_BUILD_TRANSPORT
			case TSS_TSPATTRIB_CONTEXT_TRANSPORT:
				if (subFlag == TSS_TSPATTRIB_CONTEXTTRANS_CONTROL) {
					if (ulAttrib != TSS_TSPATTRIB_DISABLE_TRANSPORT &&
					    ulAttrib != TSS_TSPATTRIB_ENABLE_TRANSPORT)
						return TSPERR(TSS_E_INVALID_ATTRIB_DATA);

					result = obj_context_transport_set_control(hObject,
										   ulAttrib);
				} else if (subFlag == TSS_TSPATTRIB_CONTEXTTRANS_MODE) {
					switch (ulAttrib) {
						case TSS_TSPATTRIB_TRANSPORT_NO_DEFAULT_ENCRYPTION:
						case TSS_TSPATTRIB_TRANSPORT_DEFAULT_ENCRYPTION:
						case TSS_TSPATTRIB_TRANSPORT_AUTHENTIC_CHANNEL:
						case TSS_TSPATTRIB_TRANSPORT_EXCLUSIVE:
						case TSS_TSPATTRIB_TRANSPORT_STATIC_AUTH:
							break;
						default:
							return TSPERR(TSS_E_INVALID_ATTRIB_DATA);
					}

					result = obj_context_transport_set_mode(hObject, ulAttrib);
				} else
					return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);

				break;
#endif
			case TSS_TSPATTRIB_SECRET_HASH_MODE:
				result = obj_context_set_hash_mode(hObject, ulAttrib);
				break;
			default:
				return TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
				break;
		}
	} else if (obj_is_tpm(hObject)) {
		switch (attribFlag) {
			case TSS_TSPATTRIB_TPM_CALLBACK_COLLATEIDENTITY:
			case TSS_TSPATTRIB_TPM_CALLBACK_ACTIVATEIDENTITY:
				if ((result = obj_tpm_set_cb11(hObject, attribFlag, subFlag,
							       ulAttrib)))
					return result;
				break;
#ifdef TSS_BUILD_AUDIT
			case TSS_TSPATTRIB_TPM_ORDINAL_AUDIT_STATUS:
				result = __tspi_audit_set_ordinal_audit_status(hObject, attribFlag,
									subFlag, ulAttrib);
				break;
#endif
			default:
				result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
				break;
		}
#ifdef TSS_BUILD_SEALX
	} else if (obj_is_encdata(hObject)) {
		if (attribFlag != TSS_TSPATTRIB_ENCDATA_SEAL)
			return TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
		if (subFlag == TSS_TSPATTRIB_ENCDATASEAL_PROTECT_MODE) {
			if (ulAttrib != TSS_TSPATTRIB_ENCDATASEAL_NO_PROTECT &&
			    ulAttrib != TSS_TSPATTRIB_ENCDATASEAL_PROTECT)
				return TSPERR(TSS_E_INVALID_ATTRIB_DATA);

			result = obj_encdata_set_seal_protect_mode(hObject, ulAttrib);
		} else
			return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
#endif
#ifdef TSS_BUILD_DELEGATION
	} else if (obj_is_delfamily(hObject)) {
		switch (attribFlag) {
		case TSS_TSPATTRIB_DELFAMILY_STATE:
			switch (subFlag) {
			case TSS_TSPATTRIB_DELFAMILYSTATE_LOCKED:
				result = obj_delfamily_set_locked(hObject, (TSS_BOOL)ulAttrib, TRUE);
				break;
			case TSS_TSPATTRIB_DELFAMILYSTATE_ENABLED:
				result = obj_delfamily_set_enabled(hObject, (TSS_BOOL)ulAttrib, TRUE);
				break;
			default:
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
			}
			break;
		default:
			return TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
		}
#endif
	} else {
		if (obj_is_hash(hObject) || obj_is_pcrs(hObject))
			result = TSPERR(TSS_E_BAD_PARAMETER);
		else
			result = TSPERR(TSS_E_INVALID_HANDLE);
	}

	return result;
}

TSS_RESULT
Tspi_GetAttribUint32(TSS_HOBJECT hObject,	/* in */
		     TSS_FLAG attribFlag,	/* in */
		     TSS_FLAG subFlag,		/* in */
		     UINT32 * pulAttrib)	/* out */
{
	UINT32 attrib;
	TSS_RESULT result = TSS_SUCCESS;

	if (pulAttrib == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if (obj_is_rsakey(hObject)) {
#ifdef TSS_BUILD_RSAKEY_LIST
		if (attribFlag == TSS_TSPATTRIB_KEY_REGISTER) {
			if (subFlag != 0)
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);

			if ((result = obj_rsakey_get_pstype(hObject, &attrib)))
				return result;

			if (attrib == TSS_PS_TYPE_USER)
				*pulAttrib = TSS_TSPATTRIB_KEYREGISTER_USER;
			else if (attrib == TSS_PS_TYPE_SYSTEM)
				*pulAttrib = TSS_TSPATTRIB_KEYREGISTER_SYSTEM;
			else
				*pulAttrib = TSS_TSPATTRIB_KEYREGISTER_NO;
		} else if (attribFlag == TSS_TSPATTRIB_KEY_INFO) {
			switch (subFlag) {
			case TSS_TSPATTRIB_KEYINFO_USAGE:
				if ((result = obj_rsakey_get_usage(hObject, pulAttrib)))
					return result;
				break;
			case TSS_TSPATTRIB_KEYINFO_MIGRATABLE:
				*pulAttrib = obj_rsakey_is_migratable(hObject);
				break;
			case TSS_TSPATTRIB_KEYINFO_REDIRECTED:
				*pulAttrib = obj_rsakey_is_redirected(hObject);
				break;
			case TSS_TSPATTRIB_KEYINFO_VOLATILE:
				*pulAttrib = obj_rsakey_is_volatile(hObject);
				break;
			case TSS_TSPATTRIB_KEYINFO_AUTHUSAGE:
				/* fall through */
			case TSS_TSPATTRIB_KEYINFO_AUTHDATAUSAGE:
				if ((result = obj_rsakey_get_authdata_usage(hObject, pulAttrib)))
					return result;
				break;
			case TSS_TSPATTRIB_KEYINFO_ALGORITHM:
				if ((result = obj_rsakey_get_alg(hObject, pulAttrib)))
					return result;
				break;
			case TSS_TSPATTRIB_KEYINFO_ENCSCHEME:
				if ((result = obj_rsakey_get_es(hObject, pulAttrib)))
					return result;
				break;
			case TSS_TSPATTRIB_KEYINFO_SIGSCHEME:
				if ((result = obj_rsakey_get_ss(hObject, pulAttrib)))
					return result;
				break;
			case TSS_TSPATTRIB_KEYINFO_KEYFLAGS:
				if ((result = obj_rsakey_get_flags(hObject, pulAttrib)))
					return result;
				break;
			case TSS_TSPATTRIB_KEYINFO_SIZE:
				if ((result = obj_rsakey_get_size(hObject, pulAttrib)))
					return result;
				break;
#ifdef TSS_BUILD_CMK
			case TSS_TSPATTRIB_KEYINFO_CMK:
				*pulAttrib = obj_rsakey_is_cmk(hObject);
				break;
#endif
			default:
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
			}
		} else if (attribFlag == TSS_TSPATTRIB_RSAKEY_INFO) {
			if (subFlag == TSS_TSPATTRIB_KEYINFO_RSA_KEYSIZE) {
				if ((result = obj_rsakey_get_size(hObject, pulAttrib)))
					return result;
			} else if (subFlag == TSS_TSPATTRIB_KEYINFO_RSA_PRIMES) {
				if ((result = obj_rsakey_get_num_primes(hObject, pulAttrib)))
					return result;
			} else {
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
			}
		} else if (attribFlag == TSS_TSPATTRIB_KEY_PCR_LONG) {
			if (subFlag == TSS_TSPATTRIB_KEYPCRLONG_LOCALITY_ATCREATION ||
			    subFlag == TSS_TSPATTRIB_KEYPCRLONG_LOCALITY_ATRELEASE) {
				result = obj_rsakey_get_pcr_locality(hObject, subFlag, pulAttrib);
			} else
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
		} else
			return TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
#endif
#ifdef TSS_BUILD_NV
	} else if (obj_is_nvstore(hObject)) {
		switch (attribFlag) {
			case TSS_TSPATTRIB_NV_INDEX:
				if ((result = obj_nvstore_get_index(hObject, pulAttrib)))
					return result;
				break;
			case TSS_TSPATTRIB_NV_DATASIZE:
				if ((result = obj_nvstore_get_datasize(hObject, pulAttrib)))
					return result;
				break;
			case TSS_TSPATTRIB_NV_PERMISSIONS:
				if ((result = obj_nvstore_get_permission(hObject, pulAttrib)))
					return result;
				break;
			case TSS_TSPATTRIB_NV_STATE:
				switch (subFlag) {
					case TSS_TSPATTRIB_NVSTATE_READSTCLEAR:
						if ((result =
						     obj_nvstore_get_state_readstclear(hObject,
										       pulAttrib)))
							return result;
						break;
					case TSS_TSPATTRIB_NVSTATE_WRITEDEFINE:
						if ((result =
						     obj_nvstore_get_state_writedefine(hObject,
										       pulAttrib)))
							return result;
						break;
					case TSS_TSPATTRIB_NVSTATE_WRITESTCLEAR:
						if ((result =
						     obj_nvstore_get_state_writestclear(hObject,
											pulAttrib)))
							return result;
						break;
					default:
						return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
					}
				break;
			case TSS_TSPATTRIB_NV_PCR:
				switch (subFlag) {
					case TSS_TSPATTRIB_NVPCR_READLOCALITYATRELEASE:
						if ((result =
						     obj_nvstore_get_readlocalityatrelease(hObject,
										   pulAttrib)))
							return result;
						break;
					case TSS_TSPATTRIB_NVPCR_WRITELOCALITYATRELEASE:
						if ((result =
						     obj_nvstore_get_writelocalityatrelease(hObject,
										    pulAttrib)))
							return result;
						break;
					default:
						return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
					}
				break;
			case TSS_TSPATTRIB_KEYCONTROL_OWNEREVICT:
				if ((result = obj_rsakey_get_ownerevict(hObject, pulAttrib)))
					return result;
				break;
			default:
				return TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
		}
#endif
	} else if (obj_is_policy(hObject)) {
		switch (attribFlag) {
			case TSS_TSPATTRIB_POLICY_CALLBACK_HMAC:
			case TSS_TSPATTRIB_POLICY_CALLBACK_XOR_ENC:
			case TSS_TSPATTRIB_POLICY_CALLBACK_TAKEOWNERSHIP:
			case TSS_TSPATTRIB_POLICY_CALLBACK_CHANGEAUTHASYM:
				if ((result = obj_policy_get_cb11(hObject, attribFlag, pulAttrib)))
					return result;
				break;
			case TSS_TSPATTRIB_POLICY_SECRET_LIFETIME:
				if ((result = obj_policy_get_lifetime(hObject, &attrib)))
					return result;

				if (subFlag == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_ALWAYS) {
					if (attrib == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_ALWAYS)
						*pulAttrib = TRUE;
					else
						*pulAttrib = FALSE;
				} else if (subFlag == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER) {
					if (attrib != TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER)
						return TSPERR(TSS_E_BAD_PARAMETER);
					if ((result = obj_policy_get_counter(hObject, pulAttrib)))
						return result;
				} else if (subFlag == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_TIMER) {
					if ((result =
					    obj_policy_get_secs_until_expired(hObject, pulAttrib)))
						return result;
				} else
					return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
				break;
			case TSS_TSPATTRIB_SECRET_HASH_MODE:
				if (subFlag == TSS_TSPATTRIB_SECRET_HASH_MODE_POPUP)
					result = obj_policy_get_hash_mode(hObject, pulAttrib);
				else
					return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
				break;
#ifdef TSS_BUILD_DELEGATION
			case TSS_TSPATTRIB_POLICY_DELEGATION_INFO:
				switch (subFlag) {
				case TSS_TSPATTRIB_POLDEL_TYPE:
					result = obj_policy_get_delegation_type(hObject,
							pulAttrib);
					break;
				case TSS_TSPATTRIB_POLDEL_INDEX:
					result = obj_policy_get_delegation_index(hObject,
							pulAttrib);
					break;
				case TSS_TSPATTRIB_POLDEL_PER1:
					result = obj_policy_get_delegation_per1(hObject,
							pulAttrib);
					break;
				case TSS_TSPATTRIB_POLDEL_PER2:
					result = obj_policy_get_delegation_per2(hObject,
							pulAttrib);
					break;
				case TSS_TSPATTRIB_POLDEL_LABEL:
					result = obj_policy_get_delegation_label(hObject,
							(BYTE *)pulAttrib);
					break;
				case TSS_TSPATTRIB_POLDEL_FAMILYID:
					result = obj_policy_get_delegation_familyid(hObject,
							pulAttrib);
					break;
				case TSS_TSPATTRIB_POLDEL_VERCOUNT:
					result = obj_policy_get_delegation_vercount(hObject,
							pulAttrib);
					break;
				default:
					result = TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
				}
				break;
			case TSS_TSPATTRIB_POLICY_DELEGATION_PCR:
				switch (subFlag) {
				case TSS_TSPATTRIB_POLDELPCR_LOCALITY:
					result = obj_policy_get_delegation_pcr_locality(hObject,
							pulAttrib);
					break;
				default:
					result = TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
				}
				break;
#endif
			default:
				return TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
				break;
		}
	} else if (obj_is_context(hObject)) {
		switch (attribFlag) {
			case TSS_TSPATTRIB_CONTEXT_SILENT_MODE:
				if ((result = obj_context_get_mode(hObject, pulAttrib)))
					return result;
				break;
			case TSS_TSPATTRIB_SECRET_HASH_MODE:
				if (subFlag == TSS_TSPATTRIB_SECRET_HASH_MODE_POPUP)
					result = obj_context_get_hash_mode(hObject, pulAttrib);
				else
					return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
				break;
#ifdef TSS_BUILD_TRANSPORT
			case TSS_TSPATTRIB_CONTEXT_TRANSPORT:
				if (subFlag == TSS_TSPATTRIB_DISABLE_TRANSPORT ||
				    subFlag == TSS_TSPATTRIB_ENABLE_TRANSPORT) {
					result = obj_context_transport_get_control(hObject, subFlag,
										   pulAttrib);
				} else if (
					subFlag == TSS_TSPATTRIB_TRANSPORT_NO_DEFAULT_ENCRYPTION ||
					subFlag == TSS_TSPATTRIB_TRANSPORT_DEFAULT_ENCRYPTION ||
					subFlag == TSS_TSPATTRIB_TRANSPORT_AUTHENTIC_CHANNEL ||
					subFlag == TSS_TSPATTRIB_TRANSPORT_EXCLUSIVE ||
					subFlag == TSS_TSPATTRIB_TRANSPORT_STATIC_AUTH) {
					result = obj_context_transport_get_mode(hObject, subFlag,
										pulAttrib);
				} else
					return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
				break;
#endif
			default:
				return TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
				break;
		}
	} else if (obj_is_tpm(hObject)) {
		switch (attribFlag) {
			case TSS_TSPATTRIB_TPM_CALLBACK_COLLATEIDENTITY:
			case TSS_TSPATTRIB_TPM_CALLBACK_ACTIVATEIDENTITY:
				if ((result = obj_tpm_get_cb11(hObject, attribFlag, pulAttrib)))
					return result;
				break;
			default:
				result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
				break;
		}
	} else if (obj_is_encdata(hObject)) {
#ifdef TSS_BUILD_SEALX
		if (attribFlag == TSS_TSPATTRIB_ENCDATA_SEAL) {
			if (subFlag == TSS_TSPATTRIB_ENCDATASEAL_PROTECT_MODE)
				result = obj_encdata_get_seal_protect_mode(hObject, pulAttrib);
			else
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
		} else if (attribFlag == TSS_TSPATTRIB_ENCDATA_PCR_LONG) {
			if (subFlag == TSS_TSPATTRIB_ENCDATAPCRLONG_LOCALITY_ATCREATION ||
			    subFlag == TSS_TSPATTRIB_ENCDATAPCRLONG_LOCALITY_ATRELEASE) {
				result = obj_encdata_get_pcr_locality(hObject, subFlag, pulAttrib);
			} else
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
		} else
			return TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
#endif
#ifdef TSS_BUILD_DELEGATION
	} else if (obj_is_delfamily(hObject)) {
		switch (attribFlag) {
		case TSS_TSPATTRIB_DELFAMILY_STATE:
			switch (subFlag) {
			case TSS_TSPATTRIB_DELFAMILYSTATE_LOCKED:
				result = obj_delfamily_get_locked(hObject, (TSS_BOOL *)pulAttrib);
				break;
			case TSS_TSPATTRIB_DELFAMILYSTATE_ENABLED:
				result = obj_delfamily_get_enabled(hObject, (TSS_BOOL *)pulAttrib);
				break;
			default:
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
			}
			break;
		case TSS_TSPATTRIB_DELFAMILY_INFO:
			switch (subFlag) {
			case TSS_TSPATTRIB_DELFAMILYINFO_LABEL:
				result = obj_delfamily_get_label(hObject, (BYTE *)pulAttrib);
				break;
			case TSS_TSPATTRIB_DELFAMILYINFO_VERCOUNT:
				result = obj_delfamily_get_vercount(hObject, pulAttrib);
				break;
			case TSS_TSPATTRIB_DELFAMILYINFO_FAMILYID:
				result = obj_delfamily_get_familyid(hObject, pulAttrib);
				break;
			default:
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
			}
			break;
		default:
			return TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
		}
#endif
	} else {
		if (obj_is_hash(hObject) || obj_is_pcrs(hObject))
			result = TSPERR(TSS_E_BAD_PARAMETER);
		else
			result = TSPERR(TSS_E_INVALID_HANDLE);
	}

	return result;
}

TSS_RESULT
Tspi_SetAttribData(TSS_HOBJECT hObject,		/* in */
		   TSS_FLAG attribFlag,		/* in */
		   TSS_FLAG subFlag,		/* in */
		   UINT32 ulAttribDataSize,	/* in */
		   BYTE * rgbAttribData)	/* in */
{
	TSS_RESULT result;
	BYTE *string = NULL;

	if (obj_is_rsakey(hObject)) {
#ifdef TSS_BUILD_RSAKEY_LIST
		if (attribFlag == TSS_TSPATTRIB_KEY_BLOB) {
			if (subFlag == TSS_TSPATTRIB_KEYBLOB_BLOB) {
				/* A TPM_KEY(12) structure, in blob form */
				result = obj_rsakey_set_tcpakey(hObject, ulAttribDataSize,
								rgbAttribData);
				if (result == TSS_SUCCESS)
					result = obj_rsakey_set_tcs_handle(hObject, 0);
			} else if (subFlag == TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY) {
				/* A TCPA_PUBKEY structure, in blob form */
				result = obj_rsakey_set_pubkey(hObject, FALSE, rgbAttribData);
			} else if (subFlag == TSS_TSPATTRIB_KEYBLOB_PRIVATE_KEY) {
				/* A blob, either encrypted or unencrypted */
				result = obj_rsakey_set_privkey(hObject, FALSE, ulAttribDataSize,
								rgbAttribData);
			} else {
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
			}
		} else if (attribFlag == TSS_TSPATTRIB_RSAKEY_INFO) {
			if (subFlag == TSS_TSPATTRIB_KEYINFO_RSA_EXPONENT) {
				result = obj_rsakey_set_exponent(hObject, ulAttribDataSize,
								 rgbAttribData);
			} else if (subFlag == TSS_TSPATTRIB_KEYINFO_RSA_MODULUS) {
				result = obj_rsakey_set_modulus(hObject, ulAttribDataSize,
								rgbAttribData);
			} else {
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
			}
#ifdef TSS_BUILD_CMK
		} else if (attribFlag == TSS_TSPATTRIB_KEY_CMKINFO) {
			if (subFlag == TSS_TSPATTRIB_KEYINFO_CMK_MA_APPROVAL) {
				result = obj_rsakey_set_msa_approval(hObject, ulAttribDataSize,
						rgbAttribData);
			} else if (subFlag == TSS_TSPATTRIB_KEYINFO_CMK_MA_DIGEST) {
				result = obj_rsakey_set_msa_digest(hObject, ulAttribDataSize,
						rgbAttribData);
			} else {
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
			}
#endif
		} else {
			return TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
		}
#endif
	} else if (obj_is_encdata(hObject)) {
#ifdef TSS_BUILD_ENCDATA_LIST
		if (attribFlag != TSS_TSPATTRIB_ENCDATA_BLOB)
			return TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
		if (subFlag != TSS_TSPATTRIB_ENCDATABLOB_BLOB)
			return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);

		result = obj_encdata_set_data(hObject, ulAttribDataSize, rgbAttribData);
#endif
	} else if (obj_is_policy(hObject)) {
		switch (attribFlag) {
			case TSS_TSPATTRIB_POLICY_POPUPSTRING:
				if ((string = Trspi_UNICODE_To_Native(rgbAttribData,
								      NULL)) == NULL)
					return TSPERR(TSS_E_INTERNAL_ERROR);

				result = obj_policy_set_string(hObject,
							       ulAttribDataSize,
							       string);
				break;
			case TSS_TSPATTRIB_POLICY_CALLBACK_HMAC:
			case TSS_TSPATTRIB_POLICY_CALLBACK_XOR_ENC:
			case TSS_TSPATTRIB_POLICY_CALLBACK_TAKEOWNERSHIP:
			case TSS_TSPATTRIB_POLICY_CALLBACK_CHANGEAUTHASYM:
#ifdef TSS_BUILD_SEALX
			case TSS_TSPATTRIB_POLICY_CALLBACK_SEALX_MASK:
#endif
				result = obj_policy_set_cb12(hObject, attribFlag,
							     rgbAttribData);
				break;
#ifdef TSS_BUILD_DELEGATION
			case TSS_TSPATTRIB_POLICY_DELEGATION_INFO:
				switch (subFlag) {
				case TSS_TSPATTRIB_POLDEL_OWNERBLOB:
					result = obj_policy_set_delegation_blob(hObject,
							TSS_DELEGATIONTYPE_OWNER,
							ulAttribDataSize, rgbAttribData);
					break;
				case TSS_TSPATTRIB_POLDEL_KEYBLOB:
					result = obj_policy_set_delegation_blob(hObject,
							TSS_DELEGATIONTYPE_KEY,
							ulAttribDataSize, rgbAttribData);
					break;
				default:
					result = TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
				}
				break;
#endif
			default:
				return TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
				break;
		}
	} else if (obj_is_hash(hObject)) {
#ifdef TSS_BUILD_HASH_LIST
		if (attribFlag != TSS_TSPATTRIB_HASH_IDENTIFIER)
			return TSPERR(TSS_E_INVALID_ATTRIB_FLAG);

		if (subFlag != 0)
			return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);

		result = obj_hash_set_value(hObject, ulAttribDataSize, rgbAttribData);
#endif
	} else if (obj_is_tpm(hObject)) {
		switch (attribFlag) {
			case TSS_TSPATTRIB_TPM_CALLBACK_COLLATEIDENTITY:
			case TSS_TSPATTRIB_TPM_CALLBACK_ACTIVATEIDENTITY:
				result = obj_tpm_set_cb12(hObject, attribFlag,
							  rgbAttribData);
				break;
			case TSS_TSPATTRIB_TPM_CREDENTIAL:
				if (subFlag == TSS_TPMATTRIB_EKCERT ||
				    subFlag == TSS_TPMATTRIB_TPM_CC ||
				    subFlag == TSS_TPMATTRIB_PLATFORMCERT ||
				    subFlag == TSS_TPMATTRIB_PLATFORM_CC) {
					result = obj_tpm_set_cred(hObject, subFlag,
								  ulAttribDataSize, rgbAttribData);
				} else {
					return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
				}
				break;
			default:
				return TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
				break;
		}
	} else if (obj_is_migdata(hObject)) {
#ifdef TSS_BUILD_CMK
		switch (attribFlag) {
		case TSS_MIGATTRIB_MIGRATIONBLOB:
			switch (subFlag) {
			case TSS_MIGATTRIB_MIG_MSALIST_PUBKEY_BLOB:
			case TSS_MIGATTRIB_MIG_AUTHORITY_PUBKEY_BLOB:
			case TSS_MIGATTRIB_MIG_DESTINATION_PUBKEY_BLOB:
			case TSS_MIGATTRIB_MIG_SOURCE_PUBKEY_BLOB:
				result = obj_migdata_set_migrationblob(hObject, subFlag,
						ulAttribDataSize, rgbAttribData);
				break;
			default:
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
			}
			break;
		case TSS_MIGATTRIB_MIGRATIONTICKET:
			if (subFlag != 0)
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
			result = obj_migdata_set_ticket_blob(hObject, ulAttribDataSize, rgbAttribData);
			break;
		case TSS_MIGATTRIB_AUTHORITY_DATA:
			switch (subFlag) {
			case TSS_MIGATTRIB_AUTHORITY_DIGEST:
			case TSS_MIGATTRIB_AUTHORITY_APPROVAL_HMAC:
			case TSS_MIGATTRIB_AUTHORITY_MSALIST:
				result = obj_migdata_set_authoritydata(hObject, subFlag,
						ulAttribDataSize, rgbAttribData);
				break;
			default:
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
			}
			break;
		case TSS_MIGATTRIB_MIG_AUTH_DATA:
			switch (subFlag) {
			case TSS_MIGATTRIB_MIG_AUTH_AUTHORITY_DIGEST:
			case TSS_MIGATTRIB_MIG_AUTH_DESTINATION_DIGEST:
			case TSS_MIGATTRIB_MIG_AUTH_SOURCE_DIGEST:
				result = obj_migdata_set_migauthdata(hObject, subFlag,
						ulAttribDataSize, rgbAttribData);
				break;
			default:
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
			}
			break;
		case TSS_MIGATTRIB_TICKET_DATA:
			switch (subFlag) {
			case TSS_MIGATTRIB_TICKET_SIG_DIGEST:
			case TSS_MIGATTRIB_TICKET_SIG_VALUE:
			case TSS_MIGATTRIB_TICKET_SIG_TICKET:
			case TSS_MIGATTRIB_TICKET_RESTRICT_TICKET:
				result = obj_migdata_set_ticketdata(hObject, subFlag,
						ulAttribDataSize, rgbAttribData);
				break;
			default:
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
			}
			break;
		default:
			return TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
			break;
		}
#endif
	} else {
		if (obj_is_pcrs(hObject) || obj_is_context(hObject))
			result = TSPERR(TSS_E_BAD_PARAMETER);
#ifdef TSS_BUILD_NV
		else if (obj_is_nvstore(hObject))
			result = TSPERR(TSS_E_BAD_PARAMETER);
#endif
		else
			result = TSPERR(TSS_E_INVALID_HANDLE);
	}

	return result;
}

TSS_RESULT
Tspi_GetAttribData(TSS_HOBJECT hObject,		/* in */
		   TSS_FLAG attribFlag,		/* in */
		   TSS_FLAG subFlag,		/* in */
		   UINT32 * pulAttribDataSize,	/* out */
		   BYTE ** prgbAttribData)	/* out */
{
	TSS_RESULT result;

	if (pulAttribDataSize == NULL || prgbAttribData == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if (obj_is_rsakey(hObject)) {
#ifdef TSS_BUILD_RSAKEY_LIST
		if (attribFlag == TSS_TSPATTRIB_KEY_BLOB) {
			if (subFlag == TSS_TSPATTRIB_KEYBLOB_BLOB) {
				/* A TPM_KEY(12) structure, in blob form */
				result = obj_rsakey_get_blob(hObject, pulAttribDataSize,
							     prgbAttribData);
			} else if (subFlag == TSS_TSPATTRIB_KEYBLOB_PRIVATE_KEY) {
				/* A blob, either encrypted or unencrypted */
				result = obj_rsakey_get_priv_blob(hObject, pulAttribDataSize,
								  prgbAttribData);
			} else if (subFlag == TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY) {
				/* A TCPA_PUBKEY structure, in blob form */
				result = obj_rsakey_get_pub_blob(hObject, pulAttribDataSize,
								 prgbAttribData);
			} else {
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
			}
		} else if (attribFlag == TSS_TSPATTRIB_KEY_INFO) {
			if (subFlag != TSS_TSPATTRIB_KEYINFO_VERSION)
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);

			result = obj_rsakey_get_version(hObject, pulAttribDataSize,
							prgbAttribData);
		} else if (attribFlag == TSS_TSPATTRIB_RSAKEY_INFO) {
			if (subFlag == TSS_TSPATTRIB_KEYINFO_RSA_EXPONENT) {
				result = obj_rsakey_get_exponent(hObject, pulAttribDataSize,
								 prgbAttribData);
			} else if (subFlag == TSS_TSPATTRIB_KEYINFO_RSA_MODULUS) {
				result = obj_rsakey_get_modulus(hObject, pulAttribDataSize,
								prgbAttribData);
			} else
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
		} else if (attribFlag == TSS_TSPATTRIB_KEY_UUID) {
			if (subFlag)
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);

			result = obj_rsakey_get_uuid(hObject, pulAttribDataSize, prgbAttribData);
		} else if (attribFlag == TSS_TSPATTRIB_KEY_PCR) {
			if (subFlag == TSS_TSPATTRIB_KEYPCR_DIGEST_ATCREATION ||
			    subFlag == TSS_TSPATTRIB_KEYPCR_DIGEST_ATRELEASE) {
				result = obj_rsakey_get_pcr_digest(hObject, TSS_PCRS_STRUCT_INFO,
								   subFlag, pulAttribDataSize,
								   prgbAttribData);
			} else if (subFlag == TSS_TSPATTRIB_KEYPCR_SELECTION) {
				result = obj_rsakey_get_pcr_selection(hObject, TSS_PCRS_STRUCT_INFO,
								      subFlag, pulAttribDataSize,
								      prgbAttribData);
			} else
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
		} else if (attribFlag == TSS_TSPATTRIB_KEY_PCR_LONG) {
			if (subFlag == TSS_TSPATTRIB_KEYPCRLONG_DIGEST_ATCREATION ||
			    subFlag == TSS_TSPATTRIB_KEYPCRLONG_DIGEST_ATRELEASE) {
				result = obj_rsakey_get_pcr_digest(hObject,
								   TSS_PCRS_STRUCT_INFO_LONG,
								   subFlag, pulAttribDataSize,
								   prgbAttribData);
			} else if (subFlag == TSS_TSPATTRIB_KEYPCRLONG_CREATION_SELECTION ||
			           subFlag == TSS_TSPATTRIB_KEYPCRLONG_RELEASE_SELECTION) {
				result = obj_rsakey_get_pcr_selection(hObject,
								      TSS_PCRS_STRUCT_INFO_LONG,
								      subFlag, pulAttribDataSize,
								      prgbAttribData);
			} else
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
#ifdef TSS_BUILD_CMK
		} else if (attribFlag == TSS_TSPATTRIB_KEY_CMKINFO) {
			if (subFlag == TSS_TSPATTRIB_KEYINFO_CMK_MA_APPROVAL) {
				result = obj_rsakey_get_msa_approval(hObject, pulAttribDataSize,
						prgbAttribData);
			} else if (subFlag == TSS_TSPATTRIB_KEYINFO_CMK_MA_DIGEST) {
				result = obj_rsakey_get_msa_digest(hObject, pulAttribDataSize,
						prgbAttribData);
			} else {
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
			}
#endif
		} else
			return TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
#endif
#ifdef TSS_BUILD_NV
	} else if (obj_is_nvstore(hObject)) {
		if (attribFlag == TSS_TSPATTRIB_NV_PCR) {
			switch (subFlag) {
				case TSS_TSPATTRIB_NVPCR_READDIGESTATRELEASE:
					if ((result = obj_nvstore_get_readdigestatrelease(hObject,
									pulAttribDataSize,
									prgbAttribData)))
							return result;
					break;
				case TSS_TSPATTRIB_NVPCR_READPCRSELECTION:
					if ((result = obj_nvstore_get_readpcrselection(
									hObject,
									pulAttribDataSize,
									prgbAttribData)))
						return result;
					break;
				case TSS_TSPATTRIB_NVPCR_WRITEDIGESTATRELEASE:
					if ((result = obj_nvstore_get_writedigestatrelease(hObject,
									pulAttribDataSize,
									prgbAttribData)))
						return result;
					break;
				case TSS_TSPATTRIB_NVPCR_WRITEPCRSELECTION:
					if ((result = obj_nvstore_get_writepcrselection(hObject,
									pulAttribDataSize,
									prgbAttribData)))
						return result;
					break;
				default:
					return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
			}
		} else
			return TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
#endif
	} else if (obj_is_encdata(hObject)) {
#ifdef TSS_BUILD_ENCDATA_LIST
		if (attribFlag == TSS_TSPATTRIB_ENCDATA_BLOB) {
			if (subFlag != TSS_TSPATTRIB_ENCDATABLOB_BLOB)
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);

			result = obj_encdata_get_data(hObject, pulAttribDataSize, prgbAttribData);
		} else if (attribFlag == TSS_TSPATTRIB_ENCDATA_PCR) {
			if (subFlag == TSS_TSPATTRIB_ENCDATAPCR_DIGEST_ATCREATION ||
			    subFlag == TSS_TSPATTRIB_ENCDATAPCR_DIGEST_RELEASE) {
				result = obj_encdata_get_pcr_digest(hObject, TSS_PCRS_STRUCT_INFO,
								    subFlag, pulAttribDataSize,
								    prgbAttribData);
			} else if (subFlag == TSS_TSPATTRIB_ENCDATAPCR_SELECTION) {
				result = obj_encdata_get_pcr_selection(hObject,
								       TSS_PCRS_STRUCT_INFO,
								       subFlag, pulAttribDataSize,
								       prgbAttribData);
			} else {
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
			}
		} else if (attribFlag == TSS_TSPATTRIB_ENCDATA_PCR_LONG) {
			if (subFlag == TSS_TSPATTRIB_ENCDATAPCRLONG_CREATION_SELECTION ||
			    subFlag == TSS_TSPATTRIB_ENCDATAPCRLONG_RELEASE_SELECTION) {
				result = obj_encdata_get_pcr_selection(hObject,
								       TSS_PCRS_STRUCT_INFO_LONG,
								       subFlag, pulAttribDataSize,
								       prgbAttribData);
			} else if (subFlag == TSS_TSPATTRIB_ENCDATAPCRLONG_DIGEST_ATCREATION ||
				   subFlag == TSS_TSPATTRIB_ENCDATAPCRLONG_DIGEST_ATRELEASE) {
				result = obj_encdata_get_pcr_digest(hObject,
								    TSS_PCRS_STRUCT_INFO_LONG,
								    subFlag, pulAttribDataSize,
								    prgbAttribData);
			} else {
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
			}
		} else {
			return TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
		}
#endif
	} else if (obj_is_context(hObject)) {
		if (attribFlag != TSS_TSPATTRIB_CONTEXT_MACHINE_NAME)
			return TSPERR(TSS_E_INVALID_ATTRIB_FLAG);

		if ((result = obj_context_get_machine_name_attrib(hObject,
								  pulAttribDataSize,
								  prgbAttribData)))
			return result;
	} else if (obj_is_policy(hObject)) {
		switch (attribFlag) {
			case TSS_TSPATTRIB_POLICY_CALLBACK_HMAC:
			case TSS_TSPATTRIB_POLICY_CALLBACK_XOR_ENC:
			case TSS_TSPATTRIB_POLICY_CALLBACK_TAKEOWNERSHIP:
			case TSS_TSPATTRIB_POLICY_CALLBACK_CHANGEAUTHASYM:
#ifdef TSS_BUILD_SEALX
			case TSS_TSPATTRIB_POLICY_CALLBACK_SEALX_MASK:
#endif
				result = obj_policy_get_cb12(hObject, attribFlag,
							     pulAttribDataSize, prgbAttribData);
				break;
			case TSS_TSPATTRIB_POLICY_POPUPSTRING:
				if ((result = obj_policy_get_string(hObject, pulAttribDataSize,
								    prgbAttribData)))
					return result;
				break;
#ifdef TSS_BUILD_DELEGATION
			case TSS_TSPATTRIB_POLICY_DELEGATION_INFO:
				switch (subFlag) {
				case TSS_TSPATTRIB_POLDEL_OWNERBLOB:
					result = obj_policy_get_delegation_blob(hObject,
							TSS_DELEGATIONTYPE_OWNER,
							pulAttribDataSize, prgbAttribData);
					break;
				case TSS_TSPATTRIB_POLDEL_KEYBLOB:
					result = obj_policy_get_delegation_blob(hObject,
							TSS_DELEGATIONTYPE_KEY,
							pulAttribDataSize, prgbAttribData);
					break;
				default:
					return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
				}
				break;
			case TSS_TSPATTRIB_POLICY_DELEGATION_PCR:
				switch (subFlag) {
				case TSS_TSPATTRIB_POLDELPCR_DIGESTATRELEASE:
					result = obj_policy_get_delegation_pcr_digest(hObject,
							pulAttribDataSize, prgbAttribData);
					break;
				case TSS_TSPATTRIB_POLDELPCR_SELECTION:
					result = obj_policy_get_delegation_pcr_selection(hObject,
							pulAttribDataSize, prgbAttribData);
					break;
				default:
					return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
				}
				break;
#endif
			default:
				result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
				break;
		}
	} else if (obj_is_tpm(hObject)) {
		switch (attribFlag) {
			case TSS_TSPATTRIB_TPM_CALLBACK_COLLATEIDENTITY:
			case TSS_TSPATTRIB_TPM_CALLBACK_ACTIVATEIDENTITY:
				result = obj_tpm_get_cb12(hObject, attribFlag,
							  pulAttribDataSize, prgbAttribData);
				break;
			default:
				return TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
				break;
		}
	} else if (obj_is_migdata(hObject)) {
#ifdef TSS_BUILD_CMK
		switch (attribFlag) {
		case TSS_MIGATTRIB_MIGRATIONBLOB:
			switch (subFlag) {
			case TSS_MIGATTRIB_MIG_XOR_BLOB:
				result = obj_migdata_get_migrationblob(hObject, subFlag,
						pulAttribDataSize, prgbAttribData);
				break;
			default:
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
			}
			break;
		case TSS_MIGATTRIB_AUTHORITY_DATA:
			switch (subFlag) {
			case TSS_MIGATTRIB_AUTHORITY_DIGEST:
			case TSS_MIGATTRIB_AUTHORITY_APPROVAL_HMAC:
			case TSS_MIGATTRIB_AUTHORITY_MSALIST:
				result = obj_migdata_get_authoritydata(hObject, subFlag,
						pulAttribDataSize, prgbAttribData);
				break;
			default:
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
			}
			break;
		case TSS_MIGATTRIB_MIG_AUTH_DATA:
			switch (subFlag) {
			case TSS_MIGATTRIB_MIG_AUTH_AUTHORITY_DIGEST:
			case TSS_MIGATTRIB_MIG_AUTH_DESTINATION_DIGEST:
			case TSS_MIGATTRIB_MIG_AUTH_SOURCE_DIGEST:
				result = obj_migdata_get_migauthdata(hObject, subFlag,
						pulAttribDataSize, prgbAttribData);
				break;
			default:
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
			}
			break;
		case TSS_MIGATTRIB_TICKET_DATA:
			switch (subFlag) {
			case TSS_MIGATTRIB_TICKET_SIG_TICKET:
				result = obj_migdata_get_ticketdata(hObject, subFlag,
						pulAttribDataSize, prgbAttribData);
				break;
			default:
				return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
			}
			break;
		default:
			return TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
			break;
		}
#endif
	} else {
		if (obj_is_hash(hObject) || obj_is_pcrs(hObject))
			result = TSPERR(TSS_E_BAD_PARAMETER);
		else
			result = TSPERR(TSS_E_INVALID_HANDLE);
	}

	return result;
}



<|start_filename|>src/tcs/tcsi_certify.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcsps.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "req_mgr.h"
#include "tcsd_wrap.h"
#include "tcsd.h"


TSS_RESULT
TCSP_CertifyKey_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			 TCS_KEY_HANDLE certHandle,	/* in */
			 TCS_KEY_HANDLE keyHandle,	/* in */
			 TCPA_NONCE antiReplay,	/* in */
			 TPM_AUTH * certAuth,	/* in, out */
			 TPM_AUTH * keyAuth,	/* in, out */
			 UINT32 * CertifyInfoSize,	/* out */
			 BYTE ** CertifyInfo,	/* out */
			 UINT32 * outDataSize,	/* out */
			 BYTE ** outData)	/* out */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	TCPA_KEY_HANDLE certKeySlot, keySlot;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering Certify Key");
	if ((result = ctx_verify_context(hContext)))
		goto done;

	if (certAuth != NULL) {
		LogDebug("Auth Used for Cert signing key");
		if ((result = auth_mgr_check(hContext, &certAuth->AuthHandle)))
			goto done;
	} else {
		LogDebug("No Auth used for Cert signing key");
	}

	if (keyAuth != NULL) {
		LogDebug("Auth Used for Key being signed");
		if ((result = auth_mgr_check(hContext, &keyAuth->AuthHandle)))
			goto done;
	} else {
		LogDebug("No Auth used for Key being signed");
	}

	if ((result = ensureKeyIsLoaded(hContext, certHandle, &certKeySlot)))
		goto done;

	if ((result = ensureKeyIsLoaded(hContext, keyHandle, &keySlot)))
		goto done;

	if ((result = tpm_rqu_build(TPM_ORD_CertifyKey, &offset, txBlob, certKeySlot, keySlot,
				    antiReplay.nonce, certAuth, keyAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_CertifyKey, txBlob, paramSize, CertifyInfoSize,
				       CertifyInfo, outDataSize, outData, certAuth, keyAuth);
	}
	LogResult("Certify Key", result);
done:
	auth_mgr_release_auth(certAuth, keyAuth, hContext);
	return result;
}


<|start_filename|>src/tcs/tcs_key_ps.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "tcsps.h"
#include "req_mgr.h"


TSS_RESULT
ps_init_disk_cache(void)
{
	int fd;
	TSS_RESULT rc;

	MUTEX_INIT(disk_cache_lock);

	if ((fd = get_file()) < 0)
		return TCSERR(TSS_E_INTERNAL_ERROR);

	if ((rc = init_disk_cache(fd)))
		return rc;

	/* this is temporary, to clear out a PS file from trousers
	 * versions before 0.2.1 */
	if ((rc = clean_disk_cache(fd)))
		return rc;

	put_file(fd);
	return TSS_SUCCESS;
}

void
ps_close_disk_cache(void)
{
	int fd;

	if ((fd = get_file()) < 0) {
		LogError("get_file() failed while trying to close disk cache.");
		return;
	}

	close_disk_cache(fd);

	put_file(fd);
}

TSS_BOOL
ps_is_key_registered(TCPA_STORE_PUBKEY *pub)
{
	TSS_UUID *uuid;
	int fd;
	TSS_RESULT rc;
	TSS_BOOL is_reg = FALSE;

	if ((fd = get_file()) < 0)
		return FALSE;

	if ((rc = psfile_get_uuid_by_pub(fd, pub, &uuid))) {
		put_file(fd);
		return FALSE;
	}

	put_file(fd);

	if ((isUUIDRegistered(uuid, &is_reg)))
		is_reg = FALSE;

	free(uuid);
	return is_reg;
}

TSS_RESULT
getParentUUIDByUUID(TSS_UUID *uuid, TSS_UUID *ret_uuid)
{
	struct key_disk_cache *disk_tmp;

	/* check the registered key disk cache */
	MUTEX_LOCK(disk_cache_lock);

	for (disk_tmp = key_disk_cache_head; disk_tmp; disk_tmp = disk_tmp->next) {
		if ((disk_tmp->flags & CACHE_FLAG_VALID) &&
		    !memcmp(&disk_tmp->uuid, uuid, sizeof(TSS_UUID))) {
			memcpy(ret_uuid, &disk_tmp->parent_uuid, sizeof(TSS_UUID));
			MUTEX_UNLOCK(disk_cache_lock);
			return TSS_SUCCESS;
		}
	}
	MUTEX_UNLOCK(disk_cache_lock);

	return TCSERR(TSS_E_FAIL);
}

TSS_RESULT
isUUIDRegistered(TSS_UUID *uuid, TSS_BOOL *is_reg)
{
	struct key_disk_cache *disk_tmp;

	/* check the registered key disk cache */
	MUTEX_LOCK(disk_cache_lock);

	for (disk_tmp = key_disk_cache_head; disk_tmp; disk_tmp = disk_tmp->next) {
		if ((disk_tmp->flags & CACHE_FLAG_VALID) &&
		    !memcmp(&disk_tmp->uuid, uuid, sizeof(TSS_UUID))) {
			*is_reg = TRUE;
			MUTEX_UNLOCK(disk_cache_lock);
			return TSS_SUCCESS;
		}
	}
	MUTEX_UNLOCK(disk_cache_lock);
	*is_reg = FALSE;

	return TSS_SUCCESS;
}

void
disk_cache_shift(struct key_disk_cache *c)
{
	UINT32 key_size, offset;
	struct key_disk_cache *tmp = key_disk_cache_head;

	/* offset is the end of the key location in the file */
	offset = TSSPS_VENDOR_DATA_OFFSET(c) + c->vendor_data_size;
	/* key_size is the size of the key entry on disk */
	key_size = offset - TSSPS_UUID_OFFSET(c);

	/* for each disk cache entry, if the data for that entry is at an
	 * offset greater than the key beign removed, then the entry needs to
	 * be decremented by the size of key's disk footprint (the key_size
	 * variable) */
	while (tmp) {
		if (tmp->offset >= offset) {
			tmp->offset -= key_size;
		}

		tmp = tmp->next;
	}
}

TSS_RESULT
ps_remove_key(TSS_UUID *uuid)
{
	struct key_disk_cache *tmp, *prev = NULL;
	TSS_RESULT rc;
        int fd = -1;

	MUTEX_LOCK(disk_cache_lock);
	tmp = key_disk_cache_head;

	for (; tmp; prev = tmp, tmp = tmp->next) {
		if ((tmp->flags & CACHE_FLAG_VALID) &&
		    !memcmp(uuid, &tmp->uuid, sizeof(TSS_UUID))) {
			if ((fd = get_file()) < 0) {
				rc = TCSERR(TSS_E_INTERNAL_ERROR);
				break;
			}

			rc = psfile_remove_key(fd, tmp);

			put_file(fd);

			/* if moving the file contents around succeeded, then
			 * change the offsets of the keys in the cache in
			 * mem_cache_shift() and remove the key from the
			 * cache. */
			if (!rc) {
				disk_cache_shift(tmp);
				if (prev) {
					prev->next = tmp->next;
				} else {
					key_disk_cache_head = tmp->next;
				}
				free(tmp);
			} else {
				LogError("Error removing registered key.");
			}

			MUTEX_UNLOCK(disk_cache_lock);
			return rc;
		}
	}

	MUTEX_UNLOCK(disk_cache_lock);

	return TCSERR(TCSERR(TSS_E_PS_KEY_NOTFOUND));
}

/*
 * temporary function to clean out blanked keys from a PS file from
 * trousers 0.2.0 and before
 */
TSS_RESULT
clean_disk_cache(int fd)
{
	struct key_disk_cache *tmp, *prev = NULL;
	TSS_RESULT rc;

	MUTEX_LOCK(disk_cache_lock);
	tmp = key_disk_cache_head;

	for (; tmp; prev = tmp, tmp = tmp->next) {
		if (!(tmp->flags & CACHE_FLAG_VALID)) {
			rc = psfile_remove_key(fd, tmp);

			/* if moving the file contents around succeeded, then
			 * change the offsets of the keys in the cache in
			 * mem_cache_shift() and remove the key from the
			 * cache. */
			if (!rc) {
				disk_cache_shift(tmp);
				if (prev) {
					prev->next = tmp->next;
				}
				free(tmp);
			} else {
				LogError("Error removing blank key.");
			}

			MUTEX_UNLOCK(disk_cache_lock);
			return rc;
		}
	}

	MUTEX_UNLOCK(disk_cache_lock);
	return TSS_SUCCESS;
}

TSS_RESULT
ps_get_key_by_uuid(TSS_UUID *uuid, BYTE *blob, UINT16 *blob_size)
{
        int fd = -1;
        TSS_RESULT rc = TSS_SUCCESS;

        if ((fd = get_file()) < 0)
                return TCSERR(TSS_E_INTERNAL_ERROR);

        rc = psfile_get_key_by_uuid(fd, uuid, blob, blob_size);

        put_file(fd);
        return rc;
}

TSS_RESULT
ps_get_key_by_cache_entry(struct key_disk_cache *c, BYTE *blob, UINT16 *blob_size)
{
        int fd = -1;
        TSS_RESULT rc = TSS_SUCCESS;

        if ((fd = get_file()) < 0)
                return TCSERR(TSS_E_INTERNAL_ERROR);

        rc = psfile_get_key_by_cache_entry(fd, c, blob, blob_size);

        put_file(fd);
        return rc;
}

TSS_RESULT
ps_get_vendor_data(struct key_disk_cache *c, UINT32 *size, BYTE **data)
{
        int fd = -1;
        TSS_RESULT rc;

        if ((fd = get_file()) < 0)
                return TCSERR(TSS_E_INTERNAL_ERROR);

        rc = psfile_get_vendor_data(fd, c, size, data);

        put_file(fd);
        return rc;
}

TSS_RESULT
ps_is_pub_registered(TCPA_STORE_PUBKEY *key)
{
        int fd = -1;
        TSS_BOOL answer;

        if ((fd = get_file()) < 0)
                return FALSE;

        if (psfile_is_pub_registered(fd, key, &answer)) {
                put_file(fd);
                return FALSE;
        }

        put_file(fd);
        return answer;
}

TSS_RESULT
ps_get_uuid_by_pub(TCPA_STORE_PUBKEY *pub, TSS_UUID **uuid)
{
        int fd = -1;
	TSS_RESULT ret;

        if ((fd = get_file()) < 0)
                return TCSERR(TSS_E_INTERNAL_ERROR);

        ret = psfile_get_uuid_by_pub(fd, pub, uuid);

        put_file(fd);
        return ret;
}

TSS_RESULT
ps_get_key_by_pub(TCPA_STORE_PUBKEY *pub, UINT32 *size, BYTE **key)
{
        int fd = -1;
	TSS_RESULT ret;

        if ((fd = get_file()) < 0)
                return TCSERR(TSS_E_INTERNAL_ERROR);

        ret = psfile_get_key_by_pub(fd, pub, size, key);

        put_file(fd);
        return ret;
}

TSS_RESULT
ps_write_key(TSS_UUID *uuid, TSS_UUID *parent_uuid, BYTE *vendor_data,
	     UINT32 vendor_size, BYTE *blob, UINT32 blob_size)
{
        int fd = -1;
        TSS_RESULT rc;
	UINT32 parent_ps;
	UINT16 short_blob_size = (UINT16)blob_size;

        if ((fd = get_file()) < 0)
                return TCSERR(TSS_E_INTERNAL_ERROR);

	/* this case needed for PS file init. if the key file doesn't yet exist, the
	 * psfile_get_parent_ps_type_by_uuid() call would fail. */
	if (!memcmp(parent_uuid, &NULL_UUID, sizeof(TSS_UUID))) {
		parent_ps = TSS_PS_TYPE_SYSTEM;
	} else {
		if ((rc = psfile_get_ps_type_by_uuid(fd, parent_uuid, &parent_ps)))
			return rc;
	}

        rc = psfile_write_key(fd, uuid, parent_uuid, &parent_ps, vendor_data,
			      vendor_size, blob, short_blob_size);

        put_file(fd);
        return TSS_SUCCESS;
}


<|start_filename|>src/tspi/tsp_aik.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2007
 *
 */


#include <stdlib.h>
#include <string.h>
#include <limits.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


#ifdef TSS_BUILD_TRANSPORT
TSS_RESULT
Transport_ActivateTPMIdentity(TSS_HCONTEXT tspContext,
			      TCS_KEY_HANDLE idKey,        /* in */
			      UINT32 blobSize,     /* in */
			      BYTE * blob, /* in */
			      TPM_AUTH * idKeyAuth,        /* in, out */
			      TPM_AUTH * ownerAuth,        /* in, out */
			      UINT32 * SymmetricKeySize,   /* out */
			      BYTE ** SymmetricKey)        /* out */
{
	TSS_RESULT result;
	UINT32 handlesLen, decLen;
	TCS_HANDLE *handles, handle;
	TPM_DIGEST pubKeyHash;
	Trspi_HashCtx hashCtx;
	BYTE *dec;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	if ((result = obj_tcskey_get_pubkeyhash(idKey, pubKeyHash.digest)))
		return result;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
		return result;

	handlesLen = 1;
	handle = idKey;
	handles = &handle;

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_ActivateIdentity, blobSize,
						    blob, &pubKeyHash, &handlesLen, &handles,
						    idKeyAuth, ownerAuth, &decLen, &dec)))
		return result;

	*SymmetricKeySize = decLen;
	*SymmetricKey = dec;

	return result;
}

TSS_RESULT
Transport_MakeIdentity2(TSS_HCONTEXT tspContext,
			TCPA_ENCAUTH identityAuth, /* in */
			TCPA_CHOSENID_HASH IDLabel_PrivCAHash,     /* in */
			UINT32 idKeyInfoSize,      /* in */
			BYTE * idKeyInfo,  /* in */
			TPM_AUTH * pSrkAuth,       /* in, out */
			TPM_AUTH * pOwnerAuth,     /* in, out */
			UINT32 * idKeySize,        /* out */
			BYTE ** idKey,     /* out */
			UINT32 * pcIdentityBindingSize,    /* out */
			BYTE ** prgbIdentityBinding)       /* out */
{
	UINT64 offset;
	TSS_RESULT result;
	UINT32 handlesLen = 0, decLen, dataLen;
	BYTE *dec, *data;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	dataLen = sizeof(TCPA_ENCAUTH) + sizeof(TCPA_CHOSENID_HASH) + idKeyInfoSize;
	if ((data = malloc(dataLen)) == NULL) {
		LogError("malloc of %u bytes failed", dataLen);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	offset = 0;
	Trspi_LoadBlob(&offset, sizeof(TCPA_ENCAUTH), data, identityAuth.authdata);
	Trspi_LoadBlob(&offset, sizeof(TCPA_CHOSENID_HASH), data, IDLabel_PrivCAHash.digest);
	Trspi_LoadBlob(&offset, idKeyInfoSize, data, idKeyInfo);

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_MakeIdentity, dataLen,
						    data, NULL, &handlesLen, NULL, pSrkAuth,
						    pOwnerAuth, &decLen, &dec))) {
		free(data);
		return result;
	}
	free(data);

	offset = 0;
	UnloadBlob_TSS_KEY(&offset, dec, NULL);
	*idKeySize = offset;

	if ((*idKey = malloc(*idKeySize)) == NULL) {
		free(dec);
		LogError("malloc of %u bytes failed", *idKeySize);
		*idKeySize = 0;
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	offset = 0;
	Trspi_UnloadBlob(&offset, *idKeySize, dec, *idKey);

	Trspi_UnloadBlob_UINT32(&offset, pcIdentityBindingSize, dec);
	if ((*prgbIdentityBinding = malloc(*pcIdentityBindingSize)) == NULL) {
		free(dec);
		free(*idKey);
		*idKey = NULL;
		*idKeySize = 0;
		LogError("malloc of %u bytes failed", *pcIdentityBindingSize);
		*pcIdentityBindingSize = 0;
		return TSPERR(TSS_E_OUTOFMEMORY);
	}
	Trspi_UnloadBlob(&offset, *pcIdentityBindingSize, dec, *prgbIdentityBinding);
	free(dec);

	return result;
}
#endif



<|start_filename|>src/tspi/rpc/tcstp/rpc_seal.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "hosttable.h"
#include "tcsd_wrap.h"
#include "obj.h"
#include "rpc_tcstp_tsp.h"


TSS_RESULT
common_Seal_TP(UINT32 sealOrdinal,
			 struct host_table_entry *hte,
			 TCS_KEY_HANDLE keyHandle,	/* in */
			 TCPA_ENCAUTH *encAuth,	/* in */
			 UINT32 pcrInfoSize,	/* in */
			 BYTE * PcrInfo,	/* in */
			 UINT32 inDataSize,	/* in */
			 BYTE * inData,	/* in */
			 TPM_AUTH * pubAuth,	/* in, out */
			 UINT32 * SealedDataSize,	/* out */
			 BYTE ** SealedData	/* out */
    ) {
	TSS_RESULT result;
	int i = 0;

	initData(&hte->comm, 8);
	hte->comm.hdr.u.ordinal = sealOrdinal;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, i++, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, i++, &keyHandle, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_ENCAUTH, i++, encAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, i++, &pcrInfoSize, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (pcrInfoSize > 0) {
		if (setData(TCSD_PACKET_TYPE_PBYTE, i++, PcrInfo, pcrInfoSize, &hte->comm))
			return TSPERR(TSS_E_INTERNAL_ERROR);
	}
	if (setData(TCSD_PACKET_TYPE_UINT32, i++, &inDataSize, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (inDataSize > 0) {
		if (setData(TCSD_PACKET_TYPE_PBYTE, i++, inData, inDataSize, &hte->comm))
			return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	if (setData(TCSD_PACKET_TYPE_AUTH, i, pubAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (hte->comm.hdr.u.result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_AUTH, 0, pubAuth, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		if (getData(TCSD_PACKET_TYPE_UINT32, 1, SealedDataSize, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		*SealedData = (BYTE *) malloc(*SealedDataSize);
		if (*SealedData == NULL) {
			LogError("malloc of %u bytes failed.", *SealedDataSize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, 2, *SealedData, *SealedDataSize, &hte->comm)) {
			free(*SealedData);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		}
	}

done:
	return result;
}

TSS_RESULT
RPC_Seal_TP(struct host_table_entry *hte,
			 TCS_KEY_HANDLE keyHandle,	/* in */
			 TCPA_ENCAUTH *encAuth,	/* in */
			 UINT32 pcrInfoSize,	/* in */
			 BYTE * PcrInfo,	/* in */
			 UINT32 inDataSize,	/* in */
			 BYTE * inData,	/* in */
			 TPM_AUTH * pubAuth,	/* in, out */
			 UINT32 * SealedDataSize,	/* out */
			 BYTE ** SealedData	/* out */
    ) {
	return common_Seal_TP(TCSD_ORD_SEAL, hte, keyHandle, encAuth, pcrInfoSize, PcrInfo,
			      inDataSize, inData, pubAuth, SealedDataSize, SealedData);
}

#ifdef TSS_BUILD_SEALX
TSS_RESULT
RPC_Sealx_TP(struct host_table_entry *hte,
			 TCS_KEY_HANDLE keyHandle,	/* in */
			 TCPA_ENCAUTH *encAuth,	/* in */
			 UINT32 pcrInfoSize,	/* in */
			 BYTE * PcrInfo,	/* in */
			 UINT32 inDataSize,	/* in */
			 BYTE * inData,	/* in */
			 TPM_AUTH * pubAuth,	/* in, out */
			 UINT32 * SealedDataSize,	/* out */
			 BYTE ** SealedData	/* out */
    ) {
	return common_Seal_TP(TCSD_ORD_SEALX, hte, keyHandle, encAuth, pcrInfoSize, PcrInfo,
			      inDataSize, inData, pubAuth, SealedDataSize, SealedData);
}
#endif

TSS_RESULT
RPC_Unseal_TP(struct host_table_entry *hte,
			   TCS_KEY_HANDLE parentHandle,	/* in */
			   UINT32 SealedDataSize,	/* in */
			   BYTE * SealedData,	/* in */
			   TPM_AUTH * parentAuth,	/* in, out */
			   TPM_AUTH * dataAuth,	/* in, out */
			   UINT32 * DataSize,	/* out */
			   BYTE ** Data	/* out */
    ) {
	TSS_RESULT result;

	initData(&hte->comm, 6);
	hte->comm.hdr.u.ordinal = TCSD_ORD_UNSEAL;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &parentHandle, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 2, &SealedDataSize, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 3, SealedData, SealedDataSize, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	if (parentAuth != NULL) {
		if (setData(TCSD_PACKET_TYPE_AUTH, 4, parentAuth, 0, &hte->comm))
			return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	if (setData(TCSD_PACKET_TYPE_AUTH, 5, dataAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (parentAuth != NULL) {
			if (getData(TCSD_PACKET_TYPE_AUTH, 0, parentAuth, 0, &hte->comm)) {
				result = TSPERR(TSS_E_INTERNAL_ERROR);
				goto done;
			}
		}

		if (getData(TCSD_PACKET_TYPE_AUTH, 1, dataAuth, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		if (getData(TCSD_PACKET_TYPE_UINT32, 2, DataSize, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		*Data = (BYTE *) malloc(*DataSize);
		if (*Data == NULL) {
			LogError("malloc of %u bytes failed.", *DataSize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, 3, *Data, *DataSize, &hte->comm)) {
			free(*Data);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		}
	}

done:
	return result;
}


<|start_filename|>src/tcs/tcs_caps.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcsps.h"
#include "tcslog.h"
#include "tddl.h"
#include "req_mgr.h"


TSS_RESULT
get_current_version(TPM_VERSION *version)
{
	TCPA_CAPABILITY_AREA capArea = TPM_CAP_VERSION_VAL;
	UINT32 respSize;
	BYTE *resp;
	TSS_RESULT result;
	UINT64 offset;

	/* try the 1.2 way first */
	result = TCSP_GetCapability_Internal(InternalContext, capArea, 0, NULL, &respSize, &resp);
	if (result == TSS_SUCCESS) {
		offset = sizeof(UINT16); // XXX hack
		UnloadBlob_VERSION(&offset, resp, version);
		free(resp);
	} else if (result == TCPA_E_BAD_MODE) {
		/* if the TPM doesn't understand VERSION_VAL, try the 1.1 way */
		capArea = TCPA_CAP_VERSION;
		result = TCSP_GetCapability_Internal(InternalContext, capArea, 0, NULL, &respSize,
						     &resp);
		if (result == TSS_SUCCESS) {
			offset = 0;
			UnloadBlob_VERSION(&offset, resp, version);
			free(resp);
		}
	}

	return result;
}

TSS_RESULT
get_cap_uint32(TCPA_CAPABILITY_AREA capArea, BYTE *subCap, UINT32 subCapSize, UINT32 *v)
{
	UINT32 respSize;
	BYTE *resp;
	TSS_RESULT result;
	UINT64 offset;

	result = TCSP_GetCapability_Internal(InternalContext, capArea, subCapSize, subCap,
					     &respSize, &resp);
	if (!result) {
		offset = 0;
		switch (respSize) {
			case 1:
				UnloadBlob_BYTE(&offset, (BYTE *)v, resp);
				break;
			case sizeof(UINT16):
				UnloadBlob_UINT16(&offset, (UINT16 *)v, resp);
				break;
			case sizeof(UINT32):
				UnloadBlob_UINT32(&offset, v, resp);
				break;
			default:
				LogDebug("TCSP_GetCapability_Internal returned"
					  " %u bytes", respSize);
				result = TCSERR(TSS_E_FAIL);
				break;
		}
		free(resp);
	}

	return result;
}


TSS_RESULT
get_max_auths(UINT32 *auths)
{
	TCS_AUTHHANDLE handles[TSS_MAX_AUTHS_CAP];
	TCPA_NONCE nonce;
	UINT32 subCap;
	TSS_RESULT result;
	int i;

	if (TPM_VERSION_IS(1,2)) {
		UINT32ToArray(TPM_CAP_PROP_MAX_AUTHSESS, (BYTE *)(&subCap));
		result = get_cap_uint32(TPM_CAP_PROPERTY, (BYTE *)&subCap, sizeof(subCap), auths);
	} else if (TPM_VERSION_IS(1,1)) {
		/* open auth sessions until we get a failure */
		for (i = 0; i < TSS_MAX_AUTHS_CAP; i++) {
			result = TCSP_OIAP_Internal(InternalContext, &(handles[i]), &nonce);
			if (result != TSS_SUCCESS) {
				/* this is not off by one since we're 0 indexed */
				*auths = i;
				break;
			}
		}

		if (i == TSS_MAX_AUTHS_CAP)
			*auths = TSS_MAX_AUTHS_CAP;

		/* close the auth sessions */
		for (i = 0; (UINT32)i < *auths; i++) {
			internal_TerminateHandle(handles[i]);
		}
	} else {
		result = TCSERR(TSS_E_INTERNAL_ERROR);
		*auths = 0;
	}

	if (*auths < 2) {
		LogError("%s reported only %u auth available!", __FUNCTION__, *auths);
		LogError("Your TPM must be reset before the TCSD can be started.");
	} else {
		LogDebug("get_max_auths reports %u auth contexts found", *auths);
		result = TSS_SUCCESS;
	}

	return result;
}

/* This is only called from init paths, so printing an error message is
 * appropriate if something goes wrong */
TSS_RESULT
get_tpm_metrics(struct tpm_properties *p)
{
	TSS_RESULT result;
	UINT32 subCap, rv = 0;

	if ((result = get_current_version(&p->version)))
		goto err;

	UINT32ToArray(TPM_ORD_SaveKeyContext, (BYTE *)&subCap);
	if ((result = get_cap_uint32(TCPA_CAP_ORD, (BYTE *)&subCap, sizeof(UINT32), &rv)))
		goto err;
	p->keyctx_swap = rv ? TRUE : FALSE;

	rv = 0;
	UINT32ToArray(TPM_ORD_SaveAuthContext, (BYTE *)&subCap);
	if ((result = get_cap_uint32(TCPA_CAP_ORD, (BYTE *)&subCap, sizeof(UINT32), &rv)))
		goto err;
	p->authctx_swap = rv ? TRUE : FALSE;

	UINT32ToArray(TPM_CAP_PROP_PCR, (BYTE *)&subCap);
	if ((result = get_cap_uint32(TCPA_CAP_PROPERTY, (BYTE *)&subCap, sizeof(UINT32),
					&p->num_pcrs)))
		goto err;

	UINT32ToArray(TPM_CAP_PROP_DIR, (BYTE *)&subCap);
	if ((result = get_cap_uint32(TCPA_CAP_PROPERTY, (BYTE *)&subCap, sizeof(UINT32),
					&p->num_dirs)))
		goto err;

	UINT32ToArray(TPM_CAP_PROP_SLOTS, (BYTE *)&subCap);
	if ((result = get_cap_uint32(TCPA_CAP_PROPERTY, (BYTE *)&subCap, sizeof(UINT32),
					&p->num_keys)))
		goto err;

	UINT32ToArray(TPM_CAP_PROP_MANUFACTURER, (BYTE *)&subCap);
	if ((result = get_cap_uint32(TCPA_CAP_PROPERTY, (BYTE *)&subCap, sizeof(UINT32),
					(UINT32 *)&p->manufacturer)))
		goto err;

	result = get_max_auths(&(p->num_auths));

err:
	if (result)
		LogError("TCS GetCapability failed with result = 0x%x", result);

	return result;
}



<|start_filename|>src/include/tsp_audit.h<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2007
 *
 */

#ifndef _TSP_AUDIT_H_
#define _TSP_AUDIT_H_

TSS_RESULT	   __tspi_audit_set_ordinal_audit_status(TSS_HTPM, TSS_FLAG, TSS_FLAG, UINT32);

#endif


<|start_filename|>src/tspi/rpc/tcstp/rpc_own.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "hosttable.h"
#include "tcsd_wrap.h"
#include "obj.h"
#include "rpc_tcstp_tsp.h"


TSS_RESULT
RPC_TakeOwnership_TP(struct host_table_entry *hte,
		      UINT16 protocolID,	/* in */
		      UINT32 encOwnerAuthSize,	/* in */
		      BYTE * encOwnerAuth,	/* in */
		      UINT32 encSrkAuthSize,	/* in */
		      BYTE * encSrkAuth,	/* in */
		      UINT32 srkInfoSize,	/* in */
		      BYTE * srkInfo,	/* in */
		      TPM_AUTH * ownerAuth,	/* in, out */
		      UINT32 * srkKeySize,
		      BYTE ** srkKey)
{
	TSS_RESULT result;

	initData(&hte->comm, 9);
	hte->comm.hdr.u.ordinal = TCSD_ORD_TAKEOWNERSHIP;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT16, 1, &protocolID, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 2, &encOwnerAuthSize, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 3, encOwnerAuth, encOwnerAuthSize, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 4, &encSrkAuthSize, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 5, encSrkAuth, encSrkAuthSize, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 6, &srkInfoSize, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 7, srkInfo, srkInfoSize, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_AUTH, 8, ownerAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_UINT32, 1, srkKeySize, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		*srkKey = (BYTE *) malloc(*srkKeySize);
		if (*srkKey == NULL) {
			LogError("malloc of %u bytes failed.", *srkKeySize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, 2, *srkKey, *srkKeySize, &hte->comm)) {
			free(*srkKey);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		}
	}

done:
	return result;
}


TSS_RESULT
RPC_OwnerClear_TP(struct host_table_entry *hte,
		   TPM_AUTH * ownerAuth)	/* in, out */
{
        TSS_RESULT result;

	initData(&hte->comm, 2);
        hte->comm.hdr.u.ordinal = TCSD_ORD_OWNERCLEAR;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

        if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
                return TSPERR(TSS_E_INTERNAL_ERROR);

        if (setData(TCSD_PACKET_TYPE_AUTH, 1, ownerAuth, 0, &hte->comm))
                return TSPERR(TSS_E_INTERNAL_ERROR);

        result = sendTCSDPacket(hte);

        if (result == TSS_SUCCESS)
                result = hte->comm.hdr.u.result;

        if (result == TSS_SUCCESS ){
                if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm))
                        result = TSPERR(TSS_E_INTERNAL_ERROR);
        }

        return result;
}


<|start_filename|>src/tspi/tspi_random.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


TSS_RESULT
Tspi_TPM_GetRandom(TSS_HTPM hTPM,		/* in */
		   UINT32 ulRandomDataLength,	/* in */
		   BYTE ** prgbRandomData)	/* out */
{
	TSS_HCONTEXT tspContext;
	TSS_RESULT result;

	if (prgbRandomData == NULL || ulRandomDataLength > 4096)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
		return result;

	if (ulRandomDataLength == 0)
		return TSS_SUCCESS;

	if ((result = TCS_API(tspContext)->GetRandom(tspContext, ulRandomDataLength,
						     prgbRandomData)))
		return result;

	if ((result = __tspi_add_mem_entry(tspContext, *prgbRandomData))) {
		free(*prgbRandomData);
		*prgbRandomData = NULL;
		return result;
	}

	return TSS_SUCCESS;
}

TSS_RESULT
Tspi_TPM_StirRandom(TSS_HTPM hTPM,		/* in */
		    UINT32 ulEntropyDataLength,	/* in */
		    BYTE * rgbEntropyData)	/* in */
{
	TSS_RESULT result;
	TSS_HCONTEXT tspContext;

	if (ulEntropyDataLength > 0 && rgbEntropyData == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
		return result;

	if ((result = TCS_API(tspContext)->StirRandom(tspContext, ulEntropyDataLength,
						      rgbEntropyData)))
		return result;

	return TSS_SUCCESS;
}


<|start_filename|>src/tcs/tcsi_delegate.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_utils.h"
#include "tcslog.h"
#include "req_mgr.h"

TSS_RESULT
TCSP_Delegate_Manage_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			      TPM_FAMILY_ID familyID,		/* in */
			      TPM_FAMILY_OPERATION opFlag,	/* in */
			      UINT32 opDataSize,		/* in */
			      BYTE *opData,			/* in */
			      TPM_AUTH *ownerAuth,		/* in/out */
			      UINT32 *retDataSize,		/* out */
			      BYTE **retData)			/* out */
{
	TSS_RESULT result;
	UINT64 offset = 0;
	UINT32 paramSize;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebugFn("Enter");

	if ((result = ctx_verify_context(hContext)))
		return result;

	if (ownerAuth) {
		if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
			return result;
	}

	if ((result = tpm_rqu_build(TPM_ORD_Delegate_Manage, &offset, txBlob, familyID, opFlag,
				    opDataSize, opData, ownerAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_Delegate_Manage, txBlob, paramSize, retDataSize,
				       retData, ownerAuth, NULL);
	}

	LogResult("Delegate_Manage", result);

done:
	auth_mgr_release_auth(ownerAuth, NULL, hContext);

	return result;
}

TSS_RESULT
TCSP_Delegate_CreateKeyDelegation_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
					   TCS_KEY_HANDLE hKey,		/* in */
					   UINT32 publicInfoSize,	/* in */
					   BYTE *publicInfo,		/* in */
					   TPM_ENCAUTH *encDelAuth,	/* in */
					   TPM_AUTH *keyAuth,		/* in, out */
					   UINT32 *blobSize,		/* out */
					   BYTE **blob)			/* out */
{
	TSS_RESULT result;
	TCPA_KEY_HANDLE keySlot;
	UINT64 offset = 0;
	UINT32 paramSize;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebugFn("Enter");

	if ((result = ctx_verify_context(hContext)))
		return result;

	if (keyAuth) {
		if ((result = auth_mgr_check(hContext, &keyAuth->AuthHandle)))
			return result;
	}

	if ((result = ensureKeyIsLoaded(hContext, hKey, &keySlot)))
		goto done;

	if ((result = tpm_rqu_build(TPM_ORD_Delegate_CreateKeyDelegation, &offset, txBlob, keySlot,
				    publicInfoSize, publicInfo, encDelAuth, keyAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_Delegate_CreateKeyDelegation, txBlob, paramSize,
				       blobSize, blob, keyAuth, NULL);
	}

	LogResult("Delegate_CreateKeyDelegation", result);

done:
	auth_mgr_release_auth(keyAuth, NULL, hContext);

	return result;
}

TSS_RESULT
TCSP_Delegate_CreateOwnerDelegation_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
					     TSS_BOOL increment,		/* in */
					     UINT32 publicInfoSize,		/* in */
					     BYTE *publicInfo,			/* in */
					     TPM_ENCAUTH *encDelAuth,		/* in */
					     TPM_AUTH *ownerAuth,		/* in, out */
					     UINT32 *blobSize,			/* out */
					     BYTE **blob)			/* out */
{
	TSS_RESULT result;
	UINT64 offset = 0;
	UINT32 paramSize;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebugFn("Enter");

	if ((result = ctx_verify_context(hContext)))
		return result;

	if (ownerAuth) {
		if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
			return result;
	}

	if ((result = tpm_rqu_build(TPM_ORD_Delegate_CreateOwnerDelegation, &offset, txBlob,
				    increment, publicInfoSize, publicInfo, encDelAuth, ownerAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_Delegate_CreateOwnerDelegation, txBlob, paramSize,
				       blobSize, blob, ownerAuth, NULL);
	}

	LogResult("Delegate_CreateOwnerDelegation", result);

done:
	auth_mgr_release_auth(ownerAuth, NULL, hContext);

	return result;
}

TSS_RESULT
TCSP_Delegate_LoadOwnerDelegation_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
					   TPM_DELEGATE_INDEX index,	/* in */
					   UINT32 blobSize,		/* in */
					   BYTE *blob,			/* in */
					   TPM_AUTH *ownerAuth)		/* in, out */
{
	TSS_RESULT result;
	UINT64 offset = 0;
	UINT32 paramSize;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebugFn("Enter");

	if ((result = ctx_verify_context(hContext)))
		return result;

	if (ownerAuth) {
		if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
			return result;
	}

	if ((result = tpm_rqu_build(TPM_ORD_Delegate_LoadOwnerDelegation, &offset, txBlob, index,
				    blobSize, blob, ownerAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_Delegate_LoadOwnerDelegation, txBlob, paramSize,
				       ownerAuth);
	}

	LogResult("Delegate_LoadOwnerDelegation", result);

done:
	auth_mgr_release_auth(ownerAuth, NULL, hContext);

	return result;
}

TSS_RESULT
TCSP_Delegate_ReadTable_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
				 UINT32 *familyTableSize,	/* out */
				 BYTE **familyTable,		/* out */
				 UINT32 *delegateTableSize,	/* out */
				 BYTE **delegateTable)		/* out */
{
	TSS_RESULT result;
	UINT64 offset = 0;
	UINT32 paramSize;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebugFn("Enter");

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_Delegate_ReadTable, &offset, txBlob, NULL)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_Delegate_ReadTable, txBlob, paramSize,
				       familyTableSize, familyTable, delegateTableSize,
				       delegateTable, NULL, NULL);
	}

	LogResult("Delegate_ReadTable", result);

	return result;
}

TSS_RESULT
TCSP_Delegate_UpdateVerificationCount_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
					       UINT32 inputSize,		/* in */
					       BYTE *input,			/* in */
					       TPM_AUTH *ownerAuth,		/* in, out */
					       UINT32 *outputSize,		/* out */
					       BYTE **output)			/* out */
{
	TSS_RESULT result;
	UINT64 offset = 0;
	UINT32 paramSize;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebugFn("Enter");

	if ((result = ctx_verify_context(hContext)))
		return result;

	if (ownerAuth) {
		if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
			return result;
	}

	if ((result = tpm_rqu_build(TPM_ORD_Delegate_UpdateVerification, &offset, txBlob, inputSize,
				    inputSize, input, ownerAuth, NULL)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_Delegate_UpdateVerification, txBlob, paramSize,
				       outputSize, output, ownerAuth, NULL);
	}

	LogResult("Delegate_UpdateVerificationCount", result);

done:
	auth_mgr_release_auth(ownerAuth, NULL, hContext);

	return result;
}

TSS_RESULT
TCSP_Delegate_VerifyDelegation_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
					UINT32 delegateSize,		/* in */
					BYTE *delegate)			/* in */
{
	TSS_RESULT result;
	UINT64 offset = 0;
	UINT32 paramSize;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebugFn("Enter");

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_Delegate_VerifyDelegation, &offset, txBlob,
				    delegateSize, delegateSize, delegate, NULL, NULL)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);

	LogResult("Delegate_VerifyDelegation", result);

	return result;
}

TSS_RESULT
TCSP_DSAP_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
		   TPM_ENTITY_TYPE entityType,	/* in */
		   TCS_KEY_HANDLE keyHandle,	/* in */
		   TPM_NONCE *nonceOddDSAP,	/* in */
		   UINT32 entityValueSize,	/* in */
		   BYTE *entityValue,		/* in */
		   TCS_AUTHHANDLE *authHandle,	/* out */
		   TPM_NONCE *nonceEven,	/* out */
		   TPM_NONCE *nonceEvenDSAP)	/* out */
{
	TSS_RESULT result;
	UINT64 offset = 0;
	UINT32 paramSize;
	TPM_KEY_HANDLE tpmKeyHandle;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebugFn("Enter");

	if ((result = ctx_verify_context(hContext)))
		return result;

	if (ensureKeyIsLoaded(hContext, keyHandle, &tpmKeyHandle))
		return TCSERR(TSS_E_KEY_NOT_LOADED);

	/* are the maximum number of auth sessions open? */
	if (auth_mgr_req_new(hContext) == FALSE) {
		if ((result = auth_mgr_swap_out(hContext)))
			goto done;
	}

	if ((result = tpm_rqu_build(TPM_ORD_DSAP, &offset, txBlob, entityType, tpmKeyHandle,
				    nonceOddDSAP, entityValueSize, entityValue)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		if ((result = tpm_rsp_parse(TPM_ORD_DSAP, txBlob, paramSize, authHandle,
					    nonceEven->nonce, nonceEvenDSAP->nonce)))
			goto done;

		/* success, add an entry to the table */
		result = auth_mgr_add(hContext, *authHandle);
	}
done:
	LogResult("DSAP", result);

	return result;
}


<|start_filename|>src/tcs/tcsi_oper.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_utils.h"
#include "tcslog.h"
#include "req_mgr.h"

TSS_RESULT
TCSP_SetOperatorAuth_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			      TCPA_SECRET *operatorAuth)	/* in */
{
	TSS_RESULT result;
	UINT64 offset = 0;
	UINT32 paramSize;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebugFn("Enter");

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_SetOperatorAuth, &offset, txBlob, TPM_AUTHDATA_SIZE,
				    operatorAuth->authdata)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);

	LogResult("SetOperatorAuth", result);
done:
	return result;
}



<|start_filename|>src/tspi/tspi_daa.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
//#include "trousers_types.h"
#include "spi_utils.h"
//#include "capabilities.h"
#include "tsplog.h"
//#include "tcs_tsp.h"
//#include "tspps.h"
//#include "hosttable.h"
//#include "tcsd_wrap.h"
//#include "tcsd.h"
#include "obj.h"
#include "daa/issuer.h"
#include "daa/platform.h"
#include "daa/verifier.h"
#include "daa/anonymity_revocation.h"

#include "daa/key_correct.h"
#include "daa/issuer.h"

// static TSS_HCONTEXT _hContext;

static void *tss_alloc( size_t size, TSS_HOBJECT hContext) {
	void *ret = calloc_tspi( hContext, size);

	LogDebug("[intern_alloc (%d)] -> %d", (int)size, (int)ret);
	return ret;
}

/*
static void *normal_malloc( size_t size, TSS_HOBJECT object) {
	void *ret = malloc( size);
	return ret;
}
*/

/**
This is the first out of 3 functions to execute in order to receive a DAA Credential.
It verifies the keys of the DAA Issuer and computes the TPM DAA public key.

Parameters
	- hDAA:		Handle of the DAA object
	- hTPM:		Handle of the TPM object
	- daaCounter:	DAA counter
	- issuerPk:	Handle of the DAA Issuer public key
	- issuerAuthPKsLength:	Length of the array of issuerAuthPKs
	- issuerAuthPKs:Handle of an array of RSA public keys (key chain) of the DAA Issuer used
				to authenticate the DAA Issuer public key. The size of the modulus
				must be TPM_DAA_SIZE_issuerModulus (256)
	- issuerAuthPKSignaturesLength:Length of the array of issuerAuthPKSignatures. It is equal
				to issuerAuthPKsLength . The length of an element of the array is
				TPM_DAA_SIZE_issuerModulus (256)
	- issuerAuthPKSignatures: An array of byte arrays representing signatures on the modulus
				of the above key chain (issuerAuthPKs) in more details, the array has the
				following content (S(K[1],K[0]),S(K[2],N[1]),..S(K[ k ],K[n-1]),
				S(TPM_DAA_ISSUER,K[ k ])), where S(msg,privateKey) denotes
				the signature function with msg being signed by the privateKey.
	- capitalUprimeLength: Length of capitalUprime which is ln/8. ln is defined as the size of the RSA modulus (2048).
	- capitalUprime: U?
	- identityProof: This structure contains the endorsement, platform and conformance credential.
	- joinSession: This structure contains DAA Join session information.
*/
#if 0
TSPICALL
Tspi_TPM_DAA_JoinInit(TSS_HDAA                 hDAA,				// in
		      TSS_HTPM                 hTPM,				// in
		      UINT32                   daaCounter,			// in
		      TSS_HDAA_DATA            issuerPk,			// in
		      UINT32                   issuerAuthPKsLength,		// in
		      TSS_HKEY*                issuerAuthPKs,			// in
		      UINT32                   issuerAuthPKSignaturesLength,	// in
		      BYTE**                   issuerAuthPKSignatures,		// in
		      UINT32*                  capitalUprimeLength,		// out
		      BYTE**                   capitalUprime,			// out
		      TSS_DAA_IDENTITY_PROOF** identityProof,			// out
		      TSS_DAA_JOIN_SESSION**   joinSession)			// out
{
	TSS_RESULT result;
#ifdef TSS_DEBUG
	int before = mallinfo().uordblks;
#endif

	LogDebug("-> TSPI_TPM_DAA_joinInit hDAA=%x hTPM=%x daaCounter=%x issuerPk=%x",
		(int)hDAA, (int)hTPM, daaCounter, (int)issuerPk);
	result = Tspi_TPM_DAA_JoinInit_internal(
		hDAA,
		hTPM,
		daaCounter,
		(TSS_DAA_PK *)issuerPk,
		issuerAuthPKsLength,
		(RSA **)issuerAuthPKs,
		issuerAuthPKSignaturesLength,
		issuerAuthPKSignatures,
		capitalUprimeLength,
		capitalUprime,
		identityProof,
		joinSession);
	bi_flush_memory();

	LogDebug("TSPI_TPM_DAA_joinInit ALLOC DELTA:%d",mallinfo().uordblks-before);
	LogDebug("<- TSPI_TPM_DAA_joinInit result=%d", result);
	return result;
}
#else
TSS_RESULT
Tspi_TPM_DAA_JoinInit(TSS_HTPM                 hTPM,                          /* in */
		      TSS_HDAA_ISSUER_KEY      hIssuerKey,                    /* in */
		      UINT32                   daaCounter,                    /* in */
		      UINT32                   issuerAuthPKsLength,           /* in */
		      TSS_HKEY*                issuerAuthPKs,                 /* in */
		      UINT32                   issuerAuthPKSignaturesLength,  /* in */
		      UINT32                   issuerAuthPKSignaturesLength2, /* in */
		      BYTE**                   issuerAuthPKSignatures,        /* in */
		      UINT32*                  capitalUprimeLength,           /* out */
		      BYTE**                   capitalUprime,                 /* out */
		      TSS_DAA_IDENTITY_PROOF** identityProof,                 /* out */
		      UINT32*                  joinSessionLength,             /* out */
		      BYTE**                   joinSession)                   /* out */
{
	TSS_RESULT result;
#ifdef TSS_DEBUG
	int before = mallinfo().uordblks;
#endif

	if (!capitalUprimeLength || !capitalUprime || !identityProof || !joinSessionLength ||
	    !joinSession)
		return TSPERR(TSS_E_BAD_PARAMETER);

	result = Tspi_TPM_DAA_JoinInit_internal(hTPM, hIssuerKey, daaCounter, issuerAuthPKsLength,
						issuerAuthPKs, issuerAuthPKSignaturesLength,
						issuerAuthPKSignaturesLength2,
						issuerAuthPKSignatures, capitalUprimeLength,
						capitalUprime, identityProof, joinSessionLength,
						joinSession);

	bi_flush_memory();

	LogDebug("TSPI_TPM_DAA_joinInit ALLOC DELTA:%d",mallinfo().uordblks-before);
	LogDebug("<- TSPI_TPM_DAA_joinInit result=%d", result);

	return result;
}
#endif
/**
This function is part of the DAA Issuer component. It defines the generation of a DAA Issuer
public and secret key. Further it defines the generation of a non-interactive proof (using
the Fiat-Shamir heuristic) that the public keys were chosen correctly. The latter will guarantee
the security requirements of the platform (respectively, its user), i.e., that the privacy and
anonymity of signatures will hold.
The generation of the authentication keys of the DAA Issuer, which are used to authenticate
(main) DAA Issuer keys, is not defined by this function.
This is an optional function and does not require a TPM or a TCS.

Parameters
	- hDAA:	Handle of the DAA object
	- issuerBaseNameLength: Length of issuerBaseName
	- issuerBaseName:	Unique name of the DAA Issuer
	- numberPlatformAttributes: Number of attributes that the Platform can choose and which
						will not be visible to the Issuer.
	- numberIssuerAttributes:Number of attributes that the Issuer can choose and which will
						be visible to both the Platform and the Issuer.
	- keyPair:	Handle of the main DAA Issuer key pair (private and public portion)
	- publicKeyProof:Handle of the proof of the main DAA Issuer public key
*/
#if 0
TSPICALL
Tspi_DAA_IssueSetup(TSS_HDAA       hDAA,			// in
		    UINT32         issuerBaseNameLength,	// in
		    BYTE*          issuerBaseName,		// in
		    UINT32         numberPlatformAttributes,	// in
		    UINT32         numberIssuerAttributes,	// in
		    TSS_HDAA_DATA* keyPair,			// out (TSS_KEY_PAIR)
		    TSS_HDAA_DATA* publicKeyProof)		// out (TSS_DAA_PK_PROOF)
{
	TSS_RESULT result;
	KEY_PAIR_WITH_PROOF_internal *key_proof;
	TSS_DAA_KEY_PAIR *tss_daa_key_pair;
	TSS_HCONTEXT hContext;
#ifdef TSS_DEBUG
	int before = mallinfo().uordblks;
#endif

	LogDebug( "TSPI_DAA_IssueSetup hDAA=%d  ",hDAA);
	// TODO: lock access to _hContext
	if ((result = obj_daa_get_tsp_context(hDAA, &hContext)))
		return result;
	result = generate_key_pair(numberIssuerAttributes,
						numberPlatformAttributes,
						issuerBaseNameLength,
						issuerBaseName,
						&key_proof);
	if (result != TSS_SUCCESS)
		return result;
	LogDebug("TSPI_DAA_IssueSetup convert internal structure to public allocated using tspi_alloc");
	LogDebug("key_proof->proof->length_challenge=%d  key_proof->proof->length_response=%d",
			key_proof->proof->length_challenge, key_proof->proof->length_response);
	// prepare out parameters
	*publicKeyProof = i_2_e_TSS_DAA_PK_PROOF( key_proof->proof, &tss_alloc, hContext);

	tss_daa_key_pair = (TSS_DAA_KEY_PAIR *)tss_alloc( sizeof(TSS_DAA_KEY_PAIR), hContext);
	if (tss_daa_key_pair == NULL) {
		LogError("malloc of %d bytes failed", sizeof(TSS_DAA_KEY_PAIR));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	tss_daa_key_pair->private_key = i_2_e_TSS_DAA_PRIVATE_KEY( key_proof->private_key,
								&tss_alloc,
								hContext);
	tss_daa_key_pair->public_key = i_2_e_TSS_DAA_PK( key_proof->pk,
							&tss_alloc,
							hContext);
	*keyPair = (TSS_HKEY)tss_daa_key_pair;
close:
	bi_flush_memory();

	LogDebug("TSPI_DAA_IssueSetup ALLOC DELTA:%d", mallinfo().uordblks-before);
	LogDebug( "TSPI_DAA_IssueSetup end return=%d ",result);
	return result;
}
#else
TSS_RESULT
Tspi_DAA_Issuer_GenerateKey(TSS_HDAA_ISSUER_KEY hIssuerKey,           // in
			    UINT32              issuerBaseNameLength, // in
			    BYTE*               issuerBaseName)       // in
{
	TSS_RESULT result;
	KEY_PAIR_WITH_PROOF_internal *key_proof;
	TSS_DAA_KEY_PAIR *tss_daa_key_pair;
	TSS_HCONTEXT tspContext;
	UINT32 numberPlatformAttributes, numberIssuerAttributes;
#ifdef TSS_DEBUG
	int before = mallinfo().uordblks;
#endif

	if ((result = obj_daaissuerkey_get_tsp_context(hIssuerKey, &tspContext)))
		return result;

	if ((result = obj_daaissuerkey_get_attribs(hIssuerKey, &numberIssuerAttributes,
						   &numberPlatformAttributes)))
		return result;

	if ((result = generate_key_pair(numberIssuerAttributes, numberPlatformAttributes,
					issuerBaseNameLength, issuerBaseName, &key_proof)))
		return result;

	LogDebugFn("convert internal structure to public allocated using tspi_alloc");
	LogDebug("key_proof->proof->length_challenge=%d  key_proof->proof->length_response=%d",
		 key_proof->proof->length_challenge, key_proof->proof->length_response);

	// prepare out parameters
	*publicKeyProof = i_2_e_TSS_DAA_PK_PROOF( key_proof->proof, &tss_alloc, tspContext);

	tss_daa_key_pair = (TSS_DAA_KEY_PAIR *)tss_alloc( sizeof(TSS_DAA_KEY_PAIR), tspContext);
	if (tss_daa_key_pair == NULL) {
		LogError("malloc of %d bytes failed", sizeof(TSS_DAA_KEY_PAIR));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	tss_daa_key_pair->private_key = i_2_e_TSS_DAA_PRIVATE_KEY( key_proof->private_key,
								&tss_alloc,
								tspContext);
	tss_daa_key_pair->public_key = i_2_e_TSS_DAA_PK( key_proof->pk,
							&tss_alloc,
							tspContext);
	*keyPair = (TSS_HKEY)tss_daa_key_pair;
close:
	bi_flush_memory();

	LogDebug("TSPI_DAA_IssueSetup ALLOC DELTA:%d", mallinfo().uordblks-before);
	LogDebug( "TSPI_DAA_IssueSetup end return=%d ",result);
	return result;
}
#endif
/**
This function is part of the DAA Issuer component. It's the first function out of 2 in order to
issue a DAA Credential for a TCG Platform. It assumes that the endorsement key and its
associated credentials are from a genuine and valid TPM. (Verification of the credentials is
 a process defined by the TCG Infrastructure WG.)
This is an optional function and does not require a TPM or a TCS.
*/
TSPICALL
Tspi_DAA_IssueInit(TSS_HDAA                      hDAA,                          // in
		   TSS_HKEY                      issuerAuthPK,                  // in
		   TSS_HDAA_DATA                 issuerKeyPair,		    // in (TSS_DAA_KEY_PAIR)
		   TSS_DAA_IDENTITY_PROOF*       identityProof,                 // in
		   UINT32                        capitalUprimeLength,           // in
		   BYTE*                         capitalUprime,                 // in
		   UINT32                        daaCounter,                    // in
		   UINT32*                       nonceIssuerLength,             // out
		   BYTE**                        nonceIssuer,                   // out
		   UINT32*                       authenticationChallengeLength, // out
		   BYTE**                        authenticationChallenge,       // out
		   TSS_DAA_JOIN_ISSUER_SESSION** joinSession)                   // out
{
	TSS_RESULT result;
#ifdef TSS_DEBUG
	int before = mallinfo().uordblks;
#endif

	LogDebug("Tspi_DAA_IssueInit_internal hDAA=%d daaCounter=%d", (int)hDAA, (int)daaCounter);
	result = Tspi_DAA_IssueInit_internal(
		hDAA,			// in
		issuerAuthPK,		// in
		issuerKeyPair,		// in
		identityProof,		// in
		capitalUprimeLength,	// in
		capitalUprime,		// in
		daaCounter,	// in
		nonceIssuerLength,	// out
		nonceIssuer,	// out
		authenticationChallengeLength,	// out
		authenticationChallenge,	// out
		joinSession	// out
	);
	bi_flush_memory();

	LogDebug("Tspi_DAA_IssueInit_internal ALLOC DELTA:%d", mallinfo().uordblks-before);

	return result;
}

/**
This function verifies the DAA public key of a DAA Issuer with respect to its associated proof.
This is a resource consuming task. It can be done by trusted third party (certification).
This is an optional function and does not require a TPM or a TCS.
Parameters:
	- hDAA: Handle of the DAA object
	- issuerPk: DAA Issuer public key
	- issuerPkProof: Proofs the correctness of the DAA Issuer public key
	- isCorrect: Proofs the correctness of the DAA Issuer public key
*/
TSPICALL
Tspi_DAA_IssuerKeyVerification(TSS_HDAA          hDAA,		// in
			       TSS_HDAA_DATA     issuerPk,	// in (TSS_DAA_PK)
			       TSS_HDAA_DATA     issuerPkProof,	// in (TSS_DAA_PK_PROOF)
			       TSS_BOOL*         isCorrect)	// out
{
	TSS_RESULT result;
	int is_correct;
#ifdef TSS_DEBUG
	int before = mallinfo().uordblks;
#endif

	LogDebug("TSPI_DAA_IssuerKeyVerification hDAA=%ld issuerPk=%ld issuerPkProof=%ld",
		(long)hDAA, (long)issuerPk, (long)issuerPkProof);
	TSS_DAA_PK_internal *pk_internal = e_2_i_TSS_DAA_PK( (TSS_DAA_PK *)issuerPk);
	TSS_DAA_PK_PROOF_internal *proof_internal = e_2_i_TSS_DAA_PK_PROOF( issuerPkProof);
	LogDebug( "challenge=[%s]", dump_byte_array( proof_internal->length_challenge,
							proof_internal->challenge));
	result = is_pk_correct( pk_internal, proof_internal, &is_correct );
	if( is_correct) *isCorrect = TRUE;
	else *isCorrect = FALSE;
	bi_flush_memory();
#ifdef TSS_DEBUG
	LogDebug("TSPI_DAA_IssuerKeyVerification ALLOC DELTA:%d", mallinfo().uordblks-before);
#endif
	return result;
}

/**
This function is part of the DAA Issuer component. It?s the last function out of 2 in order to
issue DAA Credential for a TCG Platform. It detects rogue TPM according to published rogue
TPM DAA keys.
This is an optional function and does not require a TPM or a TCS.
*/
TSPICALL
Tspi_DAA_IssueCredential(TSS_HDAA                      hDAA,			// in
			 UINT32                        attributesIssuerLength,	// in
			 BYTE**                        attributesIssuer,	// in
			 TSS_DAA_CREDENTIAL_REQUEST*   credentialRequest,	// in
			 TSS_DAA_JOIN_ISSUER_SESSION*  joinSession,		// in
			 TSS_DAA_CRED_ISSUER**         credIssuer)		// out
{
	TSS_RESULT result;
#ifdef TSS_DEBUG
	int before = mallinfo().uordblks;
#endif

	LogDebug("Tspi_DAA_IssueCredential hDAA=%d attributesIssuerLength=%d",
		(int)hDAA,
		(int)attributesIssuerLength);
	result = Tspi_DAA_IssueCredential_internal(
		hDAA,
		attributesIssuerLength,
		attributesIssuer,
		credentialRequest,
		joinSession,
		credIssuer
	);
	bi_flush_memory();
#ifdef TSS_DEBUG
	LogDebug("Tspi_DAA_IssueCredential ALLOC DELTA:%d", mallinfo().uordblks-before);
#endif
	return result;
}


/**
This function is part of the DAA Verifier component. It is the first function out of 2 in order
to verify a DAA credential of a TCG platform. It creates a challenge for the TCG platform.last
function out of 2 in order to issue a This is an optional function and does not require a
TPM or a TCS.
*/
TSPICALL
Tspi_DAA_VerifyInit(TSS_HDAA hDAA,			// in
		    UINT32*  nonceVerifierLength,	// out
		    BYTE**   nonceVerifier,		// out
		    UINT32*  baseNameLength,		// out
		    BYTE**   baseName)			// out
{
	TSS_RESULT result;
#ifdef TSS_DEBUG
	int before = mallinfo().uordblks;
#endif

	// TODO which interface to use ? with or without baseName ?
	LogDebug("Tspi_DAA_VerifyInit hDAA=%d", (int)hDAA);
	result = Tspi_DAA_VerifyInit_internal( hDAA,
						nonceVerifierLength,
						nonceVerifier,
						baseNameLength,
						baseName);
	bi_flush_memory();
#ifdef TSS_DEBUG
	LogDebug("Tspi_DAA_VerifyInit ALLOC DELTA:%d", mallinfo().uordblks-before);
#endif
	return result;
}


/**
This function is part of the DAA Verifier component. It is the last function out of 2 in
order to verify a DAA Credential of a TCG Platform. It verifies the DAA credential and
detects public rogue TPMs. This is an optional function and does not require a TPM
or a TCS.
*/
TSPICALL
Tspi_DAA_VerifySignature(TSS_HDAA           hDAA,		// in
			 TSS_DAA_SIGNATURE* daaSignature,	// in
			 TSS_HDAA_DATA      hPubKeyIssuer,	// in (TSS_DAA_PK)
			 TSS_DAA_SIGN_DATA* signData,		// in
			 UINT32             attributesLength,	// in
			 BYTE**             attributes,		// in
			 UINT32             nonceVerifierLength,// in
			 BYTE*              nonceVerifier,	// in
			 UINT32             baseNameLength,	// in
			 BYTE*              baseName,		// in
			 TSS_BOOL*          isCorrect)		// out
{
	TSS_RESULT result;
#ifdef TSS_DEBUG
	int before = mallinfo().uordblks;
#endif

	LogDebug("Tspi_DAA_VerifySignature hDAA=%d", (int)hDAA);
	result = Tspi_DAA_VerifySignature_internal( hDAA,
						daaSignature,
						hPubKeyIssuer,
						signData,
						attributesLength,
						attributes,
						nonceVerifierLength,
						nonceVerifier,
						baseNameLength,
						baseName,
						isCorrect);
	bi_flush_memory();
#ifdef TSS_DEBUG
	LogDebug("Tspi_DAA_VerifySignature ALLOC DELTA:%d", mallinfo().uordblks-before);
#endif
	return result;
}


/**
This function is part of the DAA Issuer component. It is the last function out of 2 in
order to issue a DAA Credential for a TCG Platform. It detects rogue TPM according
to published rogue TPM DAA keys.
This is an optional function and does not require a TPM or a TCS.

Parameters
	- hDAA: 	Handle of the DAA object
	- daaPublicKey: 	daaPublickKey
	- keyPair: Public and private key of the DAA Anonymity Revocation Authority to encrypt
			the pseudonym of a DAA Signature
*/
TSPICALL
Tspi_DAA_RevokeSetup(TSS_HDAA       hDAA,		// in
		     TSS_HDAA_DATA  daaPublicKey,	// in
		     TSS_HDAA_DATA* arPublicKey,	// out (TSS_DAA_AR_PK)
		     TSS_HDAA_DATA* arPrivateKey)	// out (TSS_DAA_AR_SK)
{
	TSS_RESULT result;
#ifdef TSS_DEBUG
	int before = mallinfo().uordblks;
#endif

	result = Tspi_DAA_RevokeSetup_internal(
		hDAA,			// in
//TODO: remove cast when the above interface is changed
		daaPublicKey,	// in
		keyPair		// out
	);
	bi_flush_memory();
#ifdef TSS_DEBUG
	LogDebug("Tspi_DAA_RevokeSetup ALLOC DELTA:%d", mallinfo().uordblks-before);
#endif
	return TSS_SUCCESS;
}


/**
This function is part of the DAA Anonymity Revocation Authority component. It defines the
Cramer-Shoup decryption algorithm to revoke the anonymity of a DAA Signature. The pseudonym,
with respect to either the DAA Verifier?s base name, the DAA Issuer?s base name or (just for
completeness) a random base name, can be revealed.
The pseudonym with respect to a DAA Signature and the used base name is V N . An encryption of
V N is the tuple (d1,d 2 ,d 3,d 4 ) and is decrypted using the secret key ( 0 5 x ,?, x ), the
decryption condition and the DAA public key.
This is an optional function and does not require a TPM or a TCS.

Parameters:
	- hDAA:					Handle of the DAA object
	- encryptedPseudonym: 			encryptedPseudonym
	- decryptCondition: 			Condition for the decryption of the pseudonym.
	- arPrivateKey:				arPrivateKey
	- daaPublicKey:				daaPublicKey
	- pseudonym:				pseudonym
*/
TSPICALL
Tspi_DAA_ARDecrypt(TSS_HDAA                     hDAA,			// in
		   TSS_DAA_PSEUDONYM_ENCRYPTED* encryptedPseudonym,	// in
		   TSS_HHASH                    decryptCondition,	// in
		   TSS_HDAA_DATA                arPrivateKey,		// in (TSS_DAA_AR_SK)
		   TSS_HDAA_DATA                daaPublicKey,		// in (TSS_DAA_PK)
		   TSS_DAA_PSEUDONYM_PLAIN**    pseudonym)		// out
{
	TSS_RESULT result;
#ifdef TSS_DEBUG
	int before = mallinfo().uordblks;
#endif

	result = Tspi_DAA_ARDecrypt_internal(
		hDAA,			// in
		encryptedPseudonym,	// in
		decryptCondition,	// in
//TODO: remove cast when the above interface is changed
		(void *)arPrivateKey,		// in
		(void *)daaPublicKey,		// in
		pseudonym		// out
	);
	bi_flush_memory();
#ifdef TSS_DEBUG
	LogDebug("Tspi_DAA_ARDecrypt ALLOC DELTA:%d", mallinfo().uordblks-before);
#endif
	return result;
}

/**
This is the second out of 3 functions to execute in order to receive a DAA Credential. It
computes the credential request for the DAA Issuer, which also includes the Platform
DAA public key and the attributes that were chosen by the Platform, and which are not
visible to the DAA Issuer. The Platform can commit to the attribute values it has chosen.
*/
TSPICALL
Tspi_TPM_DAA_JoinCreateDaaPubKey(TSS_HDAA                     hDAA,	                    // in
				 TSS_HTPM                     hTPM,	                    // in
				 UINT32                       authenticationChallengeLength,// in
				 BYTE*                        authenticationChallenge,      // in
				 UINT32                       nonceIssuerLength,            // in
				 BYTE*                        nonceIssuer,                  // in
				 UINT32                       attributesPlatformLength,     // in
				 BYTE**                       attributesPlatform,           // in
				 TSS_DAA_JOIN_SESSION*        joinSession,                // in, out
				 TSS_DAA_CREDENTIAL_REQUEST** credentialRequest)            // out
{
	TSS_RESULT result;
#ifdef TSS_DEBUG
	int before = mallinfo().uordblks;
#endif

	LogDebug("Tspi_TPM_DAA_JoinCreateDaaPubKey hDAA=%d joinSession=%d",
			(int)hDAA, (int)joinSession);
	result = Tspi_TPM_DAA_JoinCreateDaaPubKey_internal(
		hDAA,	// in
		hTPM,	// in
		authenticationChallengeLength,	// in
		authenticationChallenge,	// in
		nonceIssuerLength,	// in
		nonceIssuer,	// in
		attributesPlatformLength,	// in
		attributesPlatform,	// in
		joinSession,	// in, out
		credentialRequest	// out
	);
	bi_flush_memory();
#ifdef TSS_DEBUG
	LogDebug("Tspi_TPM_DAA_JoinCreateDaaPubKey ALLOC DELTA:%d", mallinfo().uordblks-before);
#endif
	return result;
}


/**
This is the last out of 3 functions to execute in order to receive a DAA Credential.
It verifies the issued credential from the DAA Issuer and computes the final DAA Credential.
*/
TSPICALL
Tspi_TPM_DAA_JoinStoreCredential(TSS_HDAA              hDAA,		// in
				 TSS_HTPM              hTPM,		// in
				 TSS_DAA_CRED_ISSUER*  credIssuer,	// in
				 TSS_DAA_JOIN_SESSION* joinSession,	// in
				 TSS_HDAA_DATA*        phDaaCredential)	// out (TSS_DAA_CREDENTIAL)
{
	TSS_RESULT result;
#ifdef TSS_DEBUG
	int before = mallinfo().uordblks;
#endif

	LogDebug("Tspi_TPM_DAA_JoinStoreCredential hDAA=%d credIssuer=%d joinSession=%d",
		(int)hDAA, (int)&credIssuer, (int)&joinSession);
	result = Tspi_TPM_DAA_JoinStoreCredential_internal(hDAA,
							hTPM,
							credIssuer,
							joinSession,
							phDaaCredential);
	bi_flush_memory();
#ifdef TSS_DEBUG
	LogDebug("Tspi_TPM_DAA_JoinStoreCredential ALLOC DELTA:%d", mallinfo().uordblks-before);
#endif
	return result;
}


/**
This function creates a DAA Signature that proofs ownership of the DAA Credential and
includes a signature on either a public AIK or a message.
If anonymity revocation is enabled, the value Nv is not provided in the clear anymore but
encrypted under the public key of anonymity revocation authority, a trusted third party (TTP).
Thus the DAA Verifier cannot check for revocation or link a transaction/signature to prior ones.
Depending on how z is chosen, the protocol either allows to implementing anonymity revocation
(i.e., using the DAA Issuer long-term base name bsn I as the DAA Verifier base name bsnV ), or
having the TTP doing the linking of different signatures for the same DAA Verifier (i.e.,
using the DAA Verifier base name ).
*/
TSPICALL
Tspi_TPM_DAA_Sign(TSS_HDAA                 hDAA,			// in
		  TSS_HTPM                 hTPM,			// in
		  TSS_HDAA_DATA            hDaaCredential,		// in (TSS_DAA_CREDENTIAL)
		  TSS_DAA_SELECTED_ATTRIB* revealAttributes,		// in
		  UINT32                   verifierBaseNameLength,	// in
		  BYTE*                    verifierBaseName,		// in
		  UINT32                   verifierNonceLength,		// in
		  BYTE*                    verifierNonce,		// in
		  TSS_DAA_SIGN_DATA*       signData,			// in
		  TSS_DAA_SIGNATURE**      daaSignature)		// out
{
	TSS_RESULT result;
#ifdef TSS_DEBUG
	int before = mallinfo().uordblks;
#endif

	LogDebug("-> TSPI_TPM_DAA_Sign hDAA=%ld hTPM=%ld ", (long)hDAA, (long)hTPM);

	result = Tspi_TPM_DAA_Sign_internal(hDAA,
					hTPM,
					hDaaCredential,
					revealAttributes,
					verifierBaseNameLength,
					verifierBaseName,
					verifierNonceLength,
					verifierNonce,
					signData,
					daaSignature);
	bi_flush_memory();
#ifdef TSS_DEBUG
	LogDebug("TSPI_TPM_DAA_joinInit ALLOC DELTA:%d", mallinfo().uordblks-before);
#endif
	LogDebug("<- TSPI_TPM_DAA_joinInit result=%d", result);
	return result;
}


<|start_filename|>src/include/tsplog.h<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */


#ifndef _TSPLOG_H_
#define _TSPLOG_H_

#include <stdio.h>
#include <syslog.h>
#include <stdlib.h>

/* Debug logging */
#ifdef TSS_DEBUG
/* log to stdout */
#define LogMessage(dest, priority, layer, fmt, ...) \
	do { \
		if (getenv("TSS_DEBUG_OFF") == NULL) { \
			fprintf(dest, "%s %s %s:%d " fmt "\n", priority, layer, __FILE__, __LINE__, ## __VA_ARGS__); \
		} \
	} while (0)

#define LogDebug(fmt, ...)	LogMessage(stdout, "LOG_DEBUG", APPID, fmt, ##__VA_ARGS__)
#define LogDebugFn(fmt, ...)	LogMessage(stdout, "LOG_DEBUG", APPID, "%s: " fmt, __FUNCTION__, ##__VA_ARGS__)
#define LogDebugData(sz,blb)	LogBlobData(APPID, sz, blb)

/* Error logging */
#define LogError(fmt, ...)	LogMessage(stderr, "LOG_ERR", APPID, "ERROR: " fmt, ##__VA_ARGS__)
/* Warn logging */
#define LogWarn(fmt, ...)	LogMessage(stdout, "LOG_WARNING", APPID, "WARNING: " fmt, ##__VA_ARGS__)
/* Info Logging */
#define LogInfo(fmt, ...)	LogMessage(stdout, "LOG_INFO", APPID, fmt, ##__VA_ARGS__)
/* Return Value logging */
extern TSS_RESULT LogTSPERR(TSS_RESULT, char *, int);
#else
#define LogDebug(fmt, ...)
#define LogDebugFn(fmt, ...)
#define LogDebugData(sz,blb)
#define LogError(fmt, ...)
#define LogWarn(fmt, ...)
#define LogInfo(fmt, ...)
#endif

void LogBlobData(char *appid, unsigned long sizeOfBlob, unsigned char *blob);

#endif


<|start_filename|>src/include/tss/tss_structs.h<|end_filename|>
/*++

TSS structures for TSS

*/

#ifndef __TSS_STRUCTS_H__
#define __TSS_STRUCTS_H__

#include <tss/platform.h>
#include <tss/tss_typedef.h>
#include <tss/tpm.h>

typedef struct tdTSS_VERSION 
{
    BYTE   bMajor;
    BYTE   bMinor;
    BYTE   bRevMajor;
    BYTE   bRevMinor;
} TSS_VERSION;

typedef struct tdTSS_PCR_EVENT 
{
    TSS_VERSION   versionInfo;
    UINT32        ulPcrIndex;
    TSS_EVENTTYPE eventType;
    UINT32        ulPcrValueLength;
#ifdef __midl
    [size_is(ulPcrValueLength)] 
#endif
    BYTE*         rgbPcrValue;
    UINT32        ulEventLength;
#ifdef __midl
    [size_is(ulEventLength)] 
#endif 
    BYTE*         rgbEvent;
} TSS_PCR_EVENT;


typedef struct tdTSS_EVENT_CERT
{
    TSS_VERSION       versionInfo;
    UINT32    ulCertificateHashLength;
#ifdef __midl
    [size_is(ulCertificateHashLength)] 
#endif
    BYTE*     rgbCertificateHash;
    UINT32    ulEntityDigestLength;
#ifdef __midl
    [size_is(ulEntityDigestLength)] 
#endif
    BYTE*     rgbentityDigest;
    TSS_BOOL  fDigestChecked;
    TSS_BOOL  fDigestVerified;
    UINT32    ulIssuerLength;
#ifdef __midl
    [size_is(ulIssuerLength)]
#endif
    BYTE*     rgbIssuer;
} TSS_EVENT_CERT;

typedef struct tdTSS_UUID 
{
    UINT32  ulTimeLow;
    UINT16  usTimeMid;
    UINT16  usTimeHigh;
    BYTE   bClockSeqHigh;
    BYTE   bClockSeqLow;
    BYTE   rgbNode[6];
} TSS_UUID;

typedef struct tdTSS_KM_KEYINFO 
{
    TSS_VERSION  versionInfo;
    TSS_UUID     keyUUID;
    TSS_UUID     parentKeyUUID;
    BYTE         bAuthDataUsage;   // whether auth is needed to load child keys
    TSS_BOOL     fIsLoaded;           // TRUE: actually loaded in TPM
    UINT32       ulVendorDataLength;  // may be 0
#ifdef __midl
    [size_is(ulVendorDataLength)]
#endif
    BYTE        *rgbVendorData;       // may be NULL
} TSS_KM_KEYINFO;


typedef struct tdTSS_KM_KEYINFO2
{
    TSS_VERSION  versionInfo;
    TSS_UUID     keyUUID;
    TSS_UUID     parentKeyUUID;
    BYTE         bAuthDataUsage;   // whether auth is needed to load child keys
    TSS_FLAG     persistentStorageType;
    TSS_FLAG     persistentStorageTypeParent;
    TSS_BOOL     fIsLoaded;           // TRUE: actually loaded in TPM
    UINT32       ulVendorDataLength;  // may be 0
#ifdef __midl
    [size_is(ulVendorDataLength)]
#endif
    BYTE        *rgbVendorData;       // may be NULL
} TSS_KM_KEYINFO2;


typedef struct tdTSS_NONCE
{
    BYTE  nonce[TPM_SHA1BASED_NONCE_LEN];
} TSS_NONCE;


typedef struct tdTSS_VALIDATION
{ 
    TSS_VERSION  versionInfo;
    UINT32       ulExternalDataLength;
#ifdef __midl
    [size_is(ulExternalDataLength)]
#endif
    BYTE*        rgbExternalData;
    UINT32       ulDataLength;
#ifdef __midl
    [size_is(ulDataLength)]
#endif
    BYTE*     rgbData;
    UINT32    ulValidationDataLength;
#ifdef __midl
    [size_is(ulValidationDataLength)]
#endif
    BYTE*     rgbValidationData;
} TSS_VALIDATION;


typedef struct tdTSS_CALLBACK
{
    PVOID            callback;
    PVOID            appData;
    TSS_ALGORITHM_ID alg;
} TSS_CALLBACK;


typedef struct tdTSS_DAA_PK
{
    TSS_VERSION versionInfo;
    UINT32      modulusLength;
#ifdef __midl
    [size_is(modulusLength)] 
#endif
    BYTE*       modulus;
    UINT32      capitalSLength;
#ifdef __midl
    [size_is(capitalSLength)] 
#endif
    BYTE*       capitalS;
    UINT32      capitalZLength;
#ifdef __midl
    [size_is(capitalZLength)] 
#endif
    BYTE*       capitalZ;
    UINT32      capitalR0Length;
#ifdef __midl
    [size_is(capitalR0Length)] 
#endif
    BYTE*       capitalR0;
    UINT32      capitalR1Length;
#ifdef __midl
    [size_is(capitalR1Length)] 
#endif
    BYTE*       capitalR1;
    UINT32      gammaLength;
#ifdef __midl
    [size_is(gammaLength)] 
#endif
    BYTE*       gamma;
    UINT32      capitalGammaLength;
#ifdef __midl
    [size_is(capitalGammaLength)] 
#endif
    BYTE*       capitalGamma;
    UINT32      rhoLength;
#ifdef __midl
    [size_is(rhoLength)] 
#endif
    BYTE*       rho;
    UINT32      capitalYLength;         // Length of first dimenstion
    UINT32      capitalYLength2;        // Length of second dimension
#ifdef __midl
    [size_is(capitalYLength,capitalYLength2)] 
#endif
    BYTE**      capitalY;
    UINT32      capitalYPlatformLength;
    UINT32      issuerBaseNameLength;
#ifdef __midl
    [size_is(issuerBaseName)] 
#endif
    BYTE*       issuerBaseName;
    UINT32      numPlatformAttributes;
    UINT32      numIssuerAttributes;
} TSS_DAA_PK;

typedef struct tdTSS_DAA_PK_PROOF
{
    TSS_VERSION versionInfo;
    UINT32      challengeLength;
#ifdef __midl
    [size_is(challengeLength)] 
#endif
    BYTE*       challenge;
    UINT32      responseLength;         // Length of first dimension
    UINT32      responseLength2;        // Length of second dimension
#ifdef __midl
    [size_is(responseLength,responseLength2)] 
#endif
    BYTE**      response;
} TSS_DAA_PK_PROOF;

typedef struct tdTSS_DAA_SK
{
    TSS_VERSION versionInfo;
    UINT32      productPQprimeLength;
#ifdef __midl
    [size_is(productPQprimeLength)] 
#endif
    BYTE*       productPQprime;
} TSS_DAA_SK;


typedef struct tdTSS_DAA_KEY_PAIR
{
    TSS_VERSION versionInfo;
    TSS_DAA_SK  secretKey;
    TSS_DAA_PK  publicKey;
} TSS_DAA_KEY_PAIR;

typedef struct tdTSS_DAA_AR_PK
{
    TSS_VERSION versionInfo;
    UINT32      etaLength;
#ifdef __midl
    [size_is(etaLength)] 
#endif
    BYTE*       eta;
    UINT32      lambda1Length;
#ifdef __midl
    [size_is(lambda1Length)] 
#endif
    BYTE*       lambda1;
    UINT32      lambda2Length;
#ifdef __midl
    [size_is(lambda2Length)] 
#endif
    BYTE*       lambda2;
    UINT32      lambda3Length;
#ifdef __midl
    [size_is(lambda3Length)] 
#endif
    BYTE*       lambda3;
} TSS_DAA_AR_PK;

typedef struct tdTSS_DAA_AR_SK
{
    TSS_VERSION versionInfo;
    UINT32      x0Length;
#ifdef __midl
    [size_is(x0Length)] 
#endif
    BYTE*       x0;
    UINT32      x1Length;
#ifdef __midl
    [size_is(x1Length)] 
#endif
    BYTE*       x1;
    UINT32      x2Length;
#ifdef __midl
    [size_is(x2Length)] 
#endif
    BYTE*       x2;
    UINT32      x3Length;
#ifdef __midl
    [size_is(x3Length)] 
#endif
    BYTE*       x3;
    UINT32      x4Length;
#ifdef __midl
    [size_is(x4Length)] 
#endif
    BYTE*       x4;
    UINT32      x5Length;
#ifdef __midl
    [size_is(x5Length)] 
#endif
    BYTE*       x5;
} TSS_DAA_AR_SK;

typedef struct tdTSS_DAA_AR_KEY_PAIR
{
    TSS_VERSION   versionInfo;
    TSS_DAA_AR_SK secretKey;
    TSS_DAA_AR_PK publicKey;
} TSS_DAA_AR_KEY_PAIR;

typedef struct tdTSS_DAA_CRED_ISSUER
{
    TSS_VERSION versionInfo;
    UINT32      capitalALength;
#ifdef __midl
    [size_is(capitalALength)] 
#endif
    BYTE*       capitalA;
    UINT32      eLength;
#ifdef __midl
    [size_is(eLength)] 
#endif
    BYTE*       e;
    UINT32      vPrimePrimeLength;
#ifdef __midl
    [size_is(vPrimePrimeLength)] 
#endif
    BYTE*       vPrimePrime;
    UINT32      attributesIssuerLength;         // Length of first dimension
    UINT32      attributesIssuerLength2;        // Length of second dimension
#ifdef __midl
    [size_is(attributesIssuerLength,attributesIssuerLength2)] 
#endif
    BYTE**      attributesIssuer;
    UINT32      cPrimeLength;
#ifdef __midl
    [size_is(cPrimeLength)] 
#endif
    BYTE*       cPrime;
    UINT32      sELength;
#ifdef __midl
    [size_is(sELength)] 
#endif
    BYTE*       sE;
} TSS_DAA_CRED_ISSUER;

typedef struct tdTSS_DAA_CREDENTIAL
{
    TSS_VERSION versionInfo;
    UINT32      capitalALength;
#ifdef __midl
    [size_is(capitalALength)] 
#endif
    BYTE*       capitalA;
    UINT32      exponentLength;
#ifdef __midl
    [size_is(exponentLength)] 
#endif
    BYTE*       exponent;
    UINT32      vBar0Length;
#ifdef __midl
    [size_is(vBar0Length)] 
#endif
    BYTE*       vBar0;
    UINT32      vBar1Length;
#ifdef __midl
    [size_is(vBar1Length)] 
#endif
    BYTE*       vBar1;
    UINT32      attributesLength;       // Length of first dimension
    UINT32      attributesLength2;      // Length of second dimension
#ifdef __midl
    [size_is(attributesLength,attributesLength2)] 
#endif
    BYTE**      attributes;
    TSS_DAA_PK  issuerPK;
    UINT32      tpmSpecificEncLength;
#ifdef __midl
    [size_is(tpmSpecificEncLength)]
#endif
    BYTE*       tpmSpecificEnc;
    UINT32      daaCounter;
} TSS_DAA_CREDENTIAL;

typedef struct tdTSS_DAA_ATTRIB_COMMIT
{
    TSS_VERSION versionInfo;
    UINT32      betaLength;
#ifdef __midl
    [size_is(betaLength)]
#endif
    BYTE*       beta;
    UINT32      sMuLength;
#ifdef __midl
    [size_is(sMuLength)]
#endif
    BYTE*       sMu;
} TSS_DAA_ATTRIB_COMMIT;

typedef struct tdTSS_DAA_CREDENTIAL_REQUEST
{
    TSS_VERSION versionInfo;
    UINT32      capitalULength;
#ifdef __midl
    [size_is(capitalULength)]
#endif
    BYTE*       capitalU;
    UINT32      capitalNiLength;
#ifdef __midl
    [size_is(capitalNiLength)]
#endif
    BYTE*       capitalNi;
    UINT32      authenticationProofLength;
#ifdef __midl
    [size_is(authenticationProofLength)]
#endif
    BYTE*       authenticationProof;
    UINT32      challengeLength;
#ifdef __midl
    [size_is(challengeLength)]
#endif
    BYTE*       challenge;
    UINT32      nonceTpmLength;
#ifdef __midl
    [size_is(nonceTpmLength)]
#endif
    BYTE*       nonceTpm;
    UINT32      noncePlatformLength;
#ifdef __midl
    [size_is(noncePlatformLength)]
#endif
    BYTE*       noncePlatform;
    UINT32      sF0Length;
#ifdef __midl
    [size_is(sF0Length)]
#endif
    BYTE*       sF0;
    UINT32      sF1Length;
#ifdef __midl
    [size_is(sF1Length)]
#endif
    BYTE*       sF1;
    UINT32      sVprimeLength;
#ifdef __midl
    [size_is(sVprimeLength)]
#endif
    BYTE*       sVprime;
    UINT32      sVtildePrimeLength;
#ifdef __midl
    [size_is(sVtildePrimeLength)]
#endif
    BYTE*       sVtildePrime;
    UINT32      sALength;       // Length of first dimension
    UINT32      sALength2;      // Length of second dimension
#ifdef __midl
    [size_is(sALength,sALength2)]
#endif
    BYTE**      sA;
    UINT32      attributeCommitmentsLength;
    TSS_DAA_ATTRIB_COMMIT* attributeCommitments;
} TSS_DAA_CREDENTIAL_REQUEST;

typedef struct tdTSS_DAA_SELECTED_ATTRIB
{
    TSS_VERSION versionInfo;
    UINT32      indicesListLength;
#ifdef __midl
    [size_is(indicesListLength)]
#endif
    TSS_BOOL*   indicesList;
} TSS_DAA_SELECTED_ATTRIB;

typedef struct tdTSS_DAA_PSEUDONYM
{
    TSS_VERSION versionInfo;
    TSS_FLAG    payloadFlag;
    UINT32      payloadLength;
#ifdef __midl
    [size_is(payloadLength)]
#endif
    BYTE*       payload;
} TSS_DAA_PSEUDONYM;

typedef struct tdTSS_DAA_PSEUDONYM_PLAIN
{
    TSS_VERSION versionInfo;
    UINT32      capitalNvLength;
#ifdef __midl
    [size_is(capitalNvLength)]
#endif
    BYTE*       capitalNv;
} TSS_DAA_PSEUDONYM_PLAIN;

typedef struct tdTSS_DAA_PSEUDONYM_ENCRYPTED
{
    TSS_VERSION versionInfo;
    UINT32      delta1Length;
#ifdef __midl
    [size_is(delta1Length)]
#endif
    BYTE*       delta1;
    UINT32      delta2Length;
#ifdef __midl
    [size_is(delta2Length)]
#endif
    BYTE*       delta2;
    UINT32      delta3Length;
#ifdef __midl
    [size_is(delta3Length)]
#endif
    BYTE*       delta3;
    UINT32      delta4Length;
#ifdef __midl
    [size_is(delta4Length)]
#endif
    BYTE*       delta4;
    UINT32      sTauLength;
#ifdef __midl
    [size_is(sTauLength)]
#endif
    BYTE*       sTau;
} TSS_DAA_PSEUDONYM_ENCRYPTED;

typedef struct tdTSS_DAA_SIGN_CALLBACK
{
    TSS_VERSION versionInfo;
    TSS_HHASH   challenge;
    TSS_FLAG    payloadFlag;
    UINT32      payloadLength;
#ifdef __midl
    [size_is(payloadLength)]
#endif
    BYTE*       payload;
} TSS_DAA_SIGN_CALLBACK;

typedef struct tdTSS_DAA_SIGNATURE
{
    TSS_VERSION            versionInfo;
    UINT32                 zetaLength;
#ifdef __midl
    [size_is(zetaLength)]
#endif
    BYTE*                  zeta;
    UINT32                 capitalTLength;
#ifdef __midl
    [size_is(capitalTLength)]
#endif
    BYTE*                  capitalT;
    UINT32                 challengeLength;
#ifdef __midl
    [size_is(challengeLength)]
#endif
    BYTE*                  challenge;
    UINT32                 nonceTpmLength;
#ifdef __midl
    [size_is(nonceTpmLength)]
#endif
    BYTE*                  nonceTpm;
    UINT32                 sVLength;
#ifdef __midl
    [size_is(sVLength)]
#endif
    BYTE*                  sV;
    UINT32                 sF0Length;
#ifdef __midl
    [size_is(sF0Length)]
#endif
    BYTE*                  sF0;
    UINT32                 sF1Length;
#ifdef __midl
    [size_is(sF1Length)]
#endif
    BYTE*                  sF1;
    UINT32                 sELength;
#ifdef __midl
    [size_is(sELength)]
#endif
    BYTE*                  sE;
    UINT32                 sALength;    // Length of first dimension
    UINT32                 sALength2;   // Length of second dimension
#ifdef __midl
    [size_is(sALength,sALength2)]
#endif
    BYTE**                 sA;
    UINT32                 attributeCommitmentsLength;
#ifdef __midl
    [size_is(attributeCommitmentsLength)]
#endif
    TSS_DAA_ATTRIB_COMMIT* attributeCommitments;
    TSS_DAA_PSEUDONYM      signedPseudonym;
    TSS_DAA_SIGN_CALLBACK  callbackResult;
} TSS_DAA_SIGNATURE;

typedef struct tdTSS_DAA_IDENTITY_PROOF
{
    TSS_VERSION versionInfo;
    UINT32      endorsementLength;
#ifdef __midl
    [size_is(endorsementLength)]
#endif
    BYTE*       endorsementCredential;
    UINT32      platformLength;
#ifdef __midl
    [size_is(platformLength)]
#endif
    BYTE*       platform;
    UINT32      conformanceLength;
#ifdef __midl
    [size_is(conformanceLength)]
#endif
    BYTE*       conformance;
} TSS_DAA_IDENTITY_PROOF;


////////////////////////////////////////////////////////////////////

typedef UINT32 TSS_FAMILY_ID;
typedef BYTE   TSS_DELEGATION_LABEL;
// Values are TSS_DELEGATIONTYPE_KEY or TSS_DELEGATIONTYPE_OWNER
typedef UINT32 TSS_DELEGATION_TYPE;

typedef struct tdTSS_PCR_INFO_SHORT
{
    UINT32               sizeOfSelect;
#ifdef __midl
    [size_is(sizeOfSelect)]
#endif
    BYTE                *selection;
    BYTE                 localityAtRelease;
    UINT32               sizeOfDigestAtRelease;
#ifdef __midl
    [size_is(sizeOfDigestAtRelease)]
#endif
    BYTE                *digestAtRelease;
} TSS_PCR_INFO_SHORT;

typedef struct tdTSS_FAMILY_TABLE_ENTRY
{
    TSS_FAMILY_ID        familyID;
    TSS_DELEGATION_LABEL label;
    UINT32               verificationCount;
    TSS_BOOL             enabled;
    TSS_BOOL             locked;
} TSS_FAMILY_TABLE_ENTRY;

typedef struct tdTSS_DELEGATION_TABLE_ENTRY
{
    UINT32               tableIndex;
    TSS_DELEGATION_LABEL label;
    TSS_PCR_INFO_SHORT   pcrInfo;
    UINT32               per1;
    UINT32               per2;
    TSS_FAMILY_ID        familyID;
    UINT32               verificationCount;
} TSS_DELEGATION_TABLE_ENTRY;

typedef struct tdTSS_PLATFORM_CLASS
{
    UINT32 platformClassSimpleIdentifier;
    UINT32 platformClassURISize;
    BYTE*  pPlatformClassURI;
} TSS_PLATFORM_CLASS;

#endif // __TSS_STRUCTS_H__



<|start_filename|>src/include/tss/tcs_error.h<|end_filename|>
/*++
 
TSS Core Service error return codes 
 
--*/

#ifndef __TCS_ERROR_H__
#define __TCS_ERROR_H__


#ifndef TSS_E_BASE
#define TSS_E_BASE      0x00000000L
#endif // TSS_E_BASE

// The context handle supplied is invalid.
#define TCS_E_INVALID_CONTEXTHANDLE  (UINT32)(TSS_E_BASE + 0x0C1L) 

// The key handle supplied is invalid.
#define TCS_E_INVALID_KEYHANDLE  (UINT32)(TSS_E_BASE + 0x0C2L) 

// The authorization session handle supplied is invalid.
#define TCS_E_INVALID_AUTHHANDLE  (UINT32)(TSS_E_BASE + 0x0C3L)

// the auth session has been closed by the TPM
#define TCS_E_INVALID_AUTHSESSION  (UINT32)(TSS_E_BASE + 0x0C4L) 

// the key has been unloaded 
#define TCS_E_INVALID_KEY   (UINT32)(TSS_E_BASE + 0x0C5L) 

// Key addressed by the application key handle does not match the key addressed
// by the given UUID.
#define TCS_E_KEY_MISMATCH   (UINT32)(TSS_E_BASE + 0x0C8L)

// Key adressed by Key's UUID cannot be loaded because one of the required
// parent keys needs authorization.
#define TCS_E_KM_LOADFAILED   (UINT32)(TSS_E_BASE + 0x0CAL)

// The Key Cache Manager could not reload the key into the TPM.
#define TCS_E_KEY_CONTEXT_RELOAD  (UINT32)(TSS_E_BASE + 0x0CCL)

// Bad memory index
#define TCS_E_BAD_INDEX                           (UINT32)(TSS_E_BASE + 0x0CDL)


// These TCS_E_ macros are defined by name in the TSS spec, however
// they are defined to have the same values as the TSS_E_ equivalents.
#define TCS_SUCCESS                        TSS_SUCCESS
#define TCS_E_KEY_ALREADY_REGISTERED       TSS_E_KEY_ALREADY_REGISTERED
#define TCS_E_KEY_NOT_REGISTERED           TSS_E_KEY_NOT_REGISTERED
#define TCS_E_BAD_PARAMETER                TSS_E_BAD_PARAMETER
#define TCS_E_OUTOFMEMORY                  TSS_E_OUTOFMEMORY
#define TCS_E_SIZE                         TSS_E_SIZE
#define TCS_E_NOTIMPL                      TSS_E_NOTIMPL
#define TCS_E_INTERNAL_ERROR               TSS_E_INTERNAL_ERROR

#endif // __TCS_ERROR_H__


<|start_filename|>src/include/tsp_seal.h<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2007
 *
 */

#ifndef _TSP_SEAL_H_
#define _TSP_SEAL_H_

TSS_RESULT	sealx_mask_cb(UINT32, BYTE *, UINT32, BYTE *, BYTE *, UINT32, BYTE *, BYTE *);

#endif


<|start_filename|>src/tcs/tcsi_maint.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcsps.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "req_mgr.h"
#include "tcsd_wrap.h"
#include "tcsd.h"

TSS_RESULT
TCSP_CreateMaintenanceArchive_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
				       TSS_BOOL generateRandom,	/* in */
				       TPM_AUTH * ownerAuth,	/* in, out */
				       UINT32 * randomSize,	/* out */
				       BYTE ** random,	/* out */
				       UINT32 * archiveSize,	/* out */
				       BYTE ** archive)	/* out */
{
	TSS_RESULT result;
	UINT32 paramSize;
	UINT64 offset = 0;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Create Main Archive");

	if ((result = ctx_verify_context(hContext)))
		goto done;

	if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
		goto done;

	if ((result = tpm_rqu_build(TPM_ORD_CreateMaintenanceArchive, &offset, txBlob,
				    generateRandom, ownerAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_CreateMaintenanceArchive, txBlob, paramSize,
				       randomSize, random, archiveSize, archive, ownerAuth);
	}
	LogResult("Create Main Archive", result);
done:
	auth_mgr_release_auth(ownerAuth, NULL, hContext);
	return result;
}

TSS_RESULT
TCSP_LoadMaintenanceArchive_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
				     UINT32 dataInSize,	/* in */
				     BYTE * dataIn,	/* in */
				     TPM_AUTH * ownerAuth,	/* in, out */
				     UINT32 * dataOutSize,	/* out */
				     BYTE ** dataOut)	/* out */
{
	TSS_RESULT result;
	UINT32 paramSize;
	UINT64 offset = 0;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Load Maint Archive");

	if ((result = ctx_verify_context(hContext)))
		goto done;

	if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
		goto done;

	if ((result = tpm_rqu_build(TPM_ORD_LoadMaintenanceArchive, &offset, txBlob, dataInSize,
				    dataInSize, dataIn, ownerAuth, NULL)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_LoadMaintenanceArchive, txBlob, paramSize,
				       dataOutSize, dataOut, ownerAuth, NULL);
	}
	LogResult("Load Maint Archive", result);
done:
	auth_mgr_release_auth(ownerAuth, NULL, hContext);
	return result;
}

TSS_RESULT
TCSP_KillMaintenanceFeature_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
				     TPM_AUTH * ownerAuth)	/* in, out */
{
	TSS_RESULT result;
	UINT32 paramSize;
	UINT64 offset = 0;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	if ((result = ctx_verify_context(hContext)))
		goto done;

	if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
		goto done;

	if ((result = tpm_rqu_build(TPM_ORD_KillMaintenanceFeature, &offset, txBlob, ownerAuth)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);

	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_KillMaintenanceFeature, txBlob, paramSize,
				       ownerAuth);
	}
done:
	auth_mgr_release_auth(ownerAuth, NULL, hContext);
	return result;
}

TSS_RESULT
TCSP_LoadManuMaintPub_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			       TCPA_NONCE antiReplay,	/* in */
			       UINT32 PubKeySize,	/* in */
			       BYTE * PubKey,	/* in */
			       TCPA_DIGEST * checksum)	/* out */
{
	TSS_RESULT result;
	UINT32 paramSize;
	UINT64 offset = 0;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering Load Manu Maint Pub");

	if ((result = tpm_rqu_build(TPM_ORD_LoadManuMaintPub, &offset, txBlob, TPM_NONCE_SIZE,
				    antiReplay.nonce, PubKeySize, PubKey, NULL)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_LoadManuMaintPub, txBlob, paramSize, NULL,
				       checksum->digest);
	}
	LogResult("Load Manu Maint Pub", result);
	return result;
}

TSS_RESULT
TCSP_ReadManuMaintPub_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			       TCPA_NONCE antiReplay,	/* in */
			       TCPA_DIGEST * checksum)	/* out */
{
	TSS_RESULT result;
	UINT32 paramSize;
	UINT64 offset = 0;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering Read Manu Maint Pub");

	if ((result = tpm_rqu_build(TPM_ORD_ReadManuMaintPub, &offset, txBlob, TPM_NONCE_SIZE,
				    antiReplay.nonce)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_ReadManuMaintPub, txBlob, paramSize, NULL,
				       checksum->digest);
	}
	LogResult("Read Manu Maint Pub", result);
	return result;
}



<|start_filename|>src/tspi/obj_hash.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2005, 2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"

TSS_RESULT
obj_hash_add(TSS_HCONTEXT tspContext, UINT32 type, TSS_HOBJECT *phObject)
{
	TSS_RESULT result;
	struct tr_hash_obj *hash = calloc(1, sizeof(struct tr_hash_obj));

	if (hash == NULL) {
		LogError("malloc of %zd bytes failed.",
				sizeof(struct tr_hash_obj));
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	if ((type == TSS_HASH_SHA1) ||
	    (type == TSS_HASH_DEFAULT)) {
		hash->type = TSS_HASH_SHA1;
		hash->hashSize = 20;
	} else if (type == TSS_HASH_OTHER) {
		hash->type = TSS_HASH_OTHER;
		hash->hashSize = 0;
	}

	if ((result = obj_list_add(&hash_list, tspContext, 0, hash, phObject))) {
		free(hash);
		return result;
	}

	return TSS_SUCCESS;
}

TSS_BOOL
obj_is_hash(TSS_HOBJECT hObject)
{
	TSS_BOOL answer = FALSE;

	if ((obj_list_get_obj(&hash_list, hObject))) {
		answer = TRUE;
		obj_list_put(&hash_list);
	}

	return answer;
}

TSS_RESULT
obj_hash_get_tsp_context(TSS_HHASH hHash, TSS_HCONTEXT *tspContext)
{
	struct tsp_object *obj;

	if ((obj = obj_list_get_obj(&hash_list, hHash)) == NULL)
		return TSPERR(TSS_E_INVALID_HANDLE);

	*tspContext = obj->tspContext;

	obj_list_put(&hash_list);

	return TSS_SUCCESS;
}

TSS_RESULT
obj_hash_set_value(TSS_HHASH hHash, UINT32 size, BYTE *value)
{
	struct tsp_object *obj;
	struct tr_hash_obj *hash;
	TSS_RESULT result = TSS_SUCCESS;

	if ((obj = obj_list_get_obj(&hash_list, hHash)) == NULL)
		return TSPERR(TSS_E_INVALID_HANDLE);

	hash = (struct tr_hash_obj *)obj->data;

	if (hash->type != TSS_HASH_OTHER &&
	    size != TCPA_SHA1_160_HASH_LEN) {
		result = TSPERR(TSS_E_HASH_INVALID_LENGTH);
		goto done;
	}

	free(hash->hashData);

	if ((hash->hashData = calloc(1, size)) == NULL) {
		LogError("malloc of %d bytes failed.", size);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto done;
	}
	hash->hashSize = size;
	memcpy(hash->hashData, value, size);

done:
	obj_list_put(&hash_list);

	return result;
}

TSS_RESULT
obj_hash_get_value(TSS_HHASH hHash, UINT32 *size, BYTE **value)
{
	struct tsp_object *obj;
	struct tr_hash_obj *hash;
	TSS_RESULT result = TSS_SUCCESS;

	if ((obj = obj_list_get_obj(&hash_list, hHash)) == NULL)
		return TSPERR(TSS_E_INVALID_HANDLE);

	hash = (struct tr_hash_obj *)obj->data;

	if (hash->hashData == NULL) {
		result = TSPERR(TSS_E_HASH_NO_DATA);
		goto done;
	}

	if ((*value = calloc_tspi(obj->tspContext, hash->hashSize)) == NULL) {
		LogError("malloc of %d bytes failed.", hash->hashSize);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto done;
	}
	*size = hash->hashSize;
	memcpy(*value, hash->hashData, *size);

done:
	obj_list_put(&hash_list);

	return result;
}

TSS_RESULT
obj_hash_update_value(TSS_HHASH hHash, UINT32 size, BYTE *data)
{
	struct tsp_object *obj;
	struct tr_hash_obj *hash;
	TSS_RESULT result = TSS_SUCCESS;

	if ((obj = obj_list_get_obj(&hash_list, hHash)) == NULL)
		return TSPERR(TSS_E_INVALID_HANDLE);

	hash = (struct tr_hash_obj *)obj->data;

	if (hash->type != TSS_HASH_SHA1 &&
	    hash->type != TSS_HASH_DEFAULT) {
		result = TSPERR(TSS_E_FAIL);
		goto done;
	}

	if (hash->hashUpdateBuffer == NULL) {
		hash->hashUpdateBuffer = calloc(1, size);
		if (hash->hashUpdateBuffer == NULL) {
			LogError("malloc of %u bytes failed.", size);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
	} else {
		hash->hashUpdateBuffer = realloc(hash->hashUpdateBuffer,
				size + hash->hashUpdateSize);

		if (hash->hashUpdateBuffer == NULL) {
			LogError("malloc of %u bytes failed.", size + hash->hashUpdateSize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
	}

	memcpy(&hash->hashUpdateBuffer[hash->hashUpdateSize], data, size);
	hash->hashUpdateSize += size;

	if (hash->hashData == NULL) {
		hash->hashData = calloc(1, TCPA_SHA1_160_HASH_LEN);
		if (hash->hashData == NULL) {
			LogError("malloc of %d bytes failed.", TCPA_SHA1_160_HASH_LEN);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
	}

	result = Trspi_Hash(TSS_HASH_SHA1, hash->hashUpdateSize, hash->hashUpdateBuffer,
			    hash->hashData);

done:
	obj_list_put(&hash_list);

	return result;
}

void
__tspi_hash_free(void *data)
{
	struct tr_hash_obj *hash = (struct tr_hash_obj *)data;

	free(hash->hashData);
	free(hash->hashUpdateBuffer);
	free(hash);
}

/*
 * remove hash object hObject from the list
 */
TSS_RESULT
obj_hash_remove(TSS_HOBJECT hObject, TSS_HCONTEXT tspContext)
{
	TSS_RESULT result;

	if ((result = obj_list_remove(&hash_list, &__tspi_hash_free, hObject, tspContext)))
		return result;

	return TSS_SUCCESS;
}



<|start_filename|>src/tspi/daa/daa_parameter.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2006
 *
 */

#include "daa_parameter.h"

setenv("TCSD_FOREGROUND", "1", 1);

static EVP_MD *digest = NULL;

extern EVP_MD *DAA_PARAM_get_message_digest(void) {
	if( digest == NULL) {
		OpenSSL_add_all_digests();
		digest = EVP_get_digestbyname( DAA_PARAM_MESSAGE_DIGEST_ALGORITHM);
	}
	return digest;
}

// from common.c (ltp-tss)
char *err_string(TSS_RESULT r)
{
	/* Check the return code to see if it is common to all layers.
	 * If so, return it.
	 */
	switch (TSS_ERROR_CODE(r)) {
		case TSS_SUCCESS:	return "TSS_SUCCESS";
		default:
			break;
	}

	/* The return code is either unknown, or specific to a layer */
	if (TSS_ERROR_LAYER(r) == TSS_LAYER_TPM) {
		switch (TSS_ERROR_CODE(r)) {
			case TCPA_E_AUTHFAIL:		return "TCPA_E_AUTHFAIL";
			case TCPA_E_BADINDEX:		return "TCPA_E_BADINDEX";
			case TCPA_E_AUDITFAILURE:	return "TCPA_E_AUDITFAILURE";
			case TCPA_E_CLEAR_DISABLED:	return "TCPA_E_CLEAR_DISABLED";
			case TCPA_E_DEACTIVATED:	return "TCPA_E_DEACTIVATED";
			case TCPA_E_DISABLED:		return "TCPA_E_DISABLED";
			case TCPA_E_DISABLED_CMD:	return "TCPA_E_DISABLED_CMD";
			case TCPA_E_FAIL:		return "TCPA_E_FAIL";
			case TCPA_E_INACTIVE:		return "TCPA_E_INACTIVE";
			case TCPA_E_INSTALL_DISABLED:	return "TCPA_E_INSTALL_DISABLED";
			case TCPA_E_INVALID_KEYHANDLE:	return "TCPA_E_INVALID_KEYHANDLE";
			case TCPA_E_KEYNOTFOUND:	return "TCPA_E_KEYNOTFOUND";
			case TCPA_E_NEED_SELFTEST:	return "TCPA_E_NEED_SELFTEST";
			case TCPA_E_MIGRATEFAIL:	return "TCPA_E_MIGRATEFAIL";
			case TCPA_E_NO_PCR_INFO:	return "TCPA_E_NO_PCR_INFO";
			case TCPA_E_NOSPACE:		return "TCPA_E_NOSPACE";
			case TCPA_E_NOSRK:		return "TCPA_E_NOSRK";
			case TCPA_E_NOTSEALED_BLOB:	return "TCPA_E_NOTSEALED_BLOB";
			case TCPA_E_OWNER_SET:		return "TCPA_E_OWNER_SET";
			case TCPA_E_RESOURCES:		return "TCPA_E_RESOURCES";
			case TCPA_E_SHORTRANDOM:	return "TCPA_E_SHORTRANDOM";
			case TCPA_E_SIZE:		return "TCPA_E_SIZE";
			case TCPA_E_WRONGPCRVAL:	return "TCPA_E_WRONGPCRVAL";
			case TCPA_E_BAD_PARAM_SIZE:	return "TCPA_E_BAD_PARAM_SIZE";
			case TCPA_E_SHA_THREAD:		return "TCPA_E_SHA_THREAD";
			case TCPA_E_SHA_ERROR:		return "TCPA_E_SHA_ERROR";
			case TCPA_E_FAILEDSELFTEST:	return "TCPA_E_FAILEDSELFTEST";
			case TCPA_E_AUTH2FAIL:		return "TCPA_E_AUTH2FAIL";
			case TCPA_E_BADTAG:		return "TCPA_E_BADTAG";
			case TCPA_E_IOERROR:		return "TCPA_E_IOERROR";
			case TCPA_E_ENCRYPT_ERROR:	return "TCPA_E_ENCRYPT_ERROR";
			case TCPA_E_DECRYPT_ERROR:	return "TCPA_E_DECRYPT_ERROR";
			case TCPA_E_INVALID_AUTHHANDLE:	return "TCPA_E_INVALID_AUTHHANDLE";
			case TCPA_E_NO_ENDORSEMENT:	return "TCPA_E_NO_ENDORSEMENT";
			case TCPA_E_INVALID_KEYUSAGE:	return "TCPA_E_INVALID_KEYUSAGE";
			case TCPA_E_WRONG_ENTITYTYPE:	return "TCPA_E_WRONG_ENTITYTYPE";
			case TCPA_E_INVALID_POSTINIT:	return "TCPA_E_INVALID_POSTINIT";
			case TCPA_E_INAPPROPRIATE_SIG:	return "TCPA_E_INAPPROPRIATE_SIG";
			case TCPA_E_BAD_KEY_PROPERTY:	return "TCPA_E_BAD_KEY_PROPERTY";
			case TCPA_E_BAD_MIGRATION:	return "TCPA_E_BAD_MIGRATION";
			case TCPA_E_BAD_SCHEME:		return "TCPA_E_BAD_SCHEME";
			case TCPA_E_BAD_DATASIZE:	return "TCPA_E_BAD_DATASIZE";
			case TCPA_E_BAD_MODE:		return "TCPA_E_BAD_MODE";
			case TCPA_E_BAD_PRESENCE:	return "TCPA_E_BAD_PRESENCE";
			case TCPA_E_BAD_VERSION:	return "TCPA_E_BAD_VERSION";
			case TCPA_E_RETRY:		return "TCPA_E_RETRY";
			default:			return "UNKNOWN TPM ERROR";
		}
	} else if (TSS_ERROR_LAYER(r) == TSS_LAYER_TDDL) {
		switch (TSS_ERROR_CODE(r)) {
			case TSS_E_FAIL:			return "TSS_E_FAIL";
			case TSS_E_BAD_PARAMETER:		return "TSS_E_BAD_PARAMETER";
			case TSS_E_INTERNAL_ERROR:		return "TSS_E_INTERNAL_ERROR";
			case TSS_E_NOTIMPL:			return "TSS_E_NOTIMPL";
			case TSS_E_PS_KEY_NOTFOUND:		return "TSS_E_PS_KEY_NOTFOUND";
			case TSS_E_KEY_ALREADY_REGISTERED:	return "TSS_E_KEY_ALREADY_REGISTERED";
			case TSS_E_CANCELED:			return "TSS_E_CANCELED";
			case TSS_E_TIMEOUT:			return "TSS_E_TIMEOUT";
			case TSS_E_OUTOFMEMORY:			return "TSS_E_OUTOFMEMORY";
			case TSS_E_TPM_UNEXPECTED:		return "TSS_E_TPM_UNEXPECTED";
			case TSS_E_COMM_FAILURE:		return "TSS_E_COMM_FAILURE";
			case TSS_E_TPM_UNSUPPORTED_FEATURE:	return "TSS_E_TPM_UNSUPPORTED_FEATURE";
			case TDDL_E_COMPONENT_NOT_FOUND:	return "TDDL_E_COMPONENT_NOT_FOUND";
			case TDDL_E_ALREADY_OPENED:		return "TDDL_E_ALREADY_OPENED";
			case TDDL_E_BADTAG:			return "TDDL_E_BADTAG";
			case TDDL_E_INSUFFICIENT_BUFFER:	return "TDDL_E_INSUFFICIENT_BUFFER";
			case TDDL_E_COMMAND_COMPLETED:		return "TDDL_E_COMMAND_COMPLETED";
			case TDDL_E_ALREADY_CLOSED:		return "TDDL_E_ALREADY_CLOSED";
			case TDDL_E_IOERROR:			return "TDDL_E_IOERROR";
			default:				return "UNKNOWN TDDL ERROR";
		}
	} else if (TSS_ERROR_LAYER(r) == TSS_LAYER_TCS) {
		switch (TSS_ERROR_CODE(r)) {
			case TSS_E_FAIL:			return "TSS_E_FAIL";
			case TSS_E_BAD_PARAMETER:		return "TSS_E_BAD_PARAMETER";
			case TSS_E_INTERNAL_ERROR:		return "TSS_E_INTERNAL_ERROR";
			case TSS_E_NOTIMPL:			return "TSS_E_NOTIMPL";
			case TSS_E_PS_KEY_NOTFOUND:		return "TSS_E_PS_KEY_NOTFOUND";
			case TSS_E_KEY_ALREADY_REGISTERED:	return "TSS_E_KEY_ALREADY_REGISTERED";
			case TSS_E_CANCELED:			return "TSS_E_CANCELED";
			case TSS_E_TIMEOUT:			return "TSS_E_TIMEOUT";
			case TSS_E_OUTOFMEMORY:			return "TSS_E_OUTOFMEMORY";
			case TSS_E_TPM_UNEXPECTED:		return "TSS_E_TPM_UNEXPECTED";
			case TSS_E_COMM_FAILURE:		return "TSS_E_COMM_FAILURE";
			case TSS_E_TPM_UNSUPPORTED_FEATURE:	return "TSS_E_TPM_UNSUPPORTED_FEATURE";
			case TCS_E_KEY_MISMATCH:		return "TCS_E_KEY_MISMATCH";
			case TCS_E_KM_LOADFAILED:		return "TCS_E_KM_LOADFAILED";
			case TCS_E_KEY_CONTEXT_RELOAD:		return "TCS_E_KEY_CONTEXT_RELOAD";
			case TCS_E_INVALID_CONTEXTHANDLE:	return "TCS_E_INVALID_CONTEXTHANDLE";
			case TCS_E_INVALID_KEYHANDLE:		return "TCS_E_INVALID_KEYHANDLE";
			case TCS_E_INVALID_AUTHHANDLE:		return "TCS_E_INVALID_AUTHHANDLE";
			case TCS_E_INVALID_AUTHSESSION:		return "TCS_E_INVALID_AUTHSESSION";
			case TCS_E_INVALID_KEY:			return "TCS_E_INVALID_KEY";
			default:				return "UNKNOWN TCS ERROR";
		}
	} else {
		switch (TSS_ERROR_CODE(r)) {
			case TSS_E_FAIL:			return "TSS_E_FAIL";
			case TSS_E_BAD_PARAMETER:		return "TSS_E_BAD_PARAMETER";
			case TSS_E_INTERNAL_ERROR:		return "TSS_E_INTERNAL_ERROR";
			case TSS_E_NOTIMPL:			return "TSS_E_NOTIMPL";
			case TSS_E_PS_KEY_NOTFOUND:		return "TSS_E_PS_KEY_NOTFOUND";
			case TSS_E_KEY_ALREADY_REGISTERED:	return "TSS_E_KEY_ALREADY_REGISTERED";
			case TSS_E_CANCELED:			return "TSS_E_CANCELED";
			case TSS_E_TIMEOUT:			return "TSS_E_TIMEOUT";
			case TSS_E_OUTOFMEMORY:			return "TSS_E_OUTOFMEMORY";
			case TSS_E_TPM_UNEXPECTED:		return "TSS_E_TPM_UNEXPECTED";
			case TSS_E_COMM_FAILURE:		return "TSS_E_COMM_FAILURE";
			case TSS_E_TPM_UNSUPPORTED_FEATURE:	return "TSS_E_TPM_UNSUPPORTED_FEATURE";
			case TSS_E_INVALID_OBJECT_TYPE:		return "TSS_E_INVALID_OBJECT_TYPE";
			case TSS_E_INVALID_OBJECT_INITFLAG:	return "TSS_E_INVALID_OBJECT_INITFLAG";
			case TSS_E_INVALID_HANDLE:		return "TSS_E_INVALID_HANDLE";
			case TSS_E_NO_CONNECTION:		return "TSS_E_NO_CONNECTION";
			case TSS_E_CONNECTION_FAILED:		return "TSS_E_CONNECTION_FAILED";
			case TSS_E_CONNECTION_BROKEN:		return "TSS_E_CONNECTION_BROKEN";
			case TSS_E_HASH_INVALID_ALG:		return "TSS_E_HASH_INVALID_ALG";
			case TSS_E_HASH_INVALID_LENGTH:		return "TSS_E_HASH_INVALID_LENGTH";
			case TSS_E_HASH_NO_DATA:		return "TSS_E_HASH_NO_DATA";
			case TSS_E_SILENT_CONTEXT:		return "TSS_E_SILENT_CONTEXT";
			case TSS_E_INVALID_ATTRIB_FLAG:		return "TSS_E_INVALID_ATTRIB_FLAG";
			case TSS_E_INVALID_ATTRIB_SUBFLAG:	return "TSS_E_INVALID_ATTRIB_SUBFLAG";
			case TSS_E_INVALID_ATTRIB_DATA:		return "TSS_E_INVALID_ATTRIB_DATA";
			case TSS_E_NO_PCRS_SET:			return "TSS_E_NO_PCRS_SET";
			case TSS_E_KEY_NOT_LOADED:		return "TSS_E_KEY_NOT_LOADED";
			case TSS_E_KEY_NOT_SET:			return "TSS_E_KEY_NOT_SET";
			case TSS_E_VALIDATION_FAILED:		return "TSS_E_VALIDATION_FAILED";
			case TSS_E_TSP_AUTHREQUIRED:		return "TSS_E_TSP_AUTHREQUIRED";
			case TSS_E_TSP_AUTH2REQUIRED:		return "TSS_E_TSP_AUTH2REQUIRED";
			case TSS_E_TSP_AUTHFAIL:		return "TSS_E_TSP_AUTHFAIL";
			case TSS_E_TSP_AUTH2FAIL:		return "TSS_E_TSP_AUTH2FAIL";
			case TSS_E_KEY_NO_MIGRATION_POLICY:	return "TSS_E_KEY_NO_MIGRATION_POLICY";
			case TSS_E_POLICY_NO_SECRET:		return "TSS_E_POLICY_NO_SECRET";
			case TSS_E_INVALID_OBJ_ACCESS:		return "TSS_E_INVALID_OBJ_ACCESS";
			case TSS_E_INVALID_ENCSCHEME:		return "TSS_E_INVALID_ENCSCHEME";
			case TSS_E_INVALID_SIGSCHEME:		return "TSS_E_INVALID_SIGSCHEME";
			case TSS_E_ENC_INVALID_LENGTH:		return "TSS_E_ENC_INVALID_LENGTH";
			case TSS_E_ENC_NO_DATA:			return "TSS_E_ENC_NO_DATA";
			case TSS_E_ENC_INVALID_TYPE:		return "TSS_E_ENC_INVALID_TYPE";
			case TSS_E_INVALID_KEYUSAGE:		return "TSS_E_INVALID_KEYUSAGE";
			case TSS_E_VERIFICATION_FAILED:		return "TSS_E_VERIFICATION_FAILED";
			case TSS_E_HASH_NO_IDENTIFIER:		return "TSS_E_HASH_NO_IDENTIFIER";
			default:	return "UNKNOWN TSS ERROR";
		}
	}
}


<|start_filename|>src/include/tss/tss_error_basics.h<|end_filename|>
/*++

Basic defines for TSS error return codes
 
--*/

#ifndef __TSS_ERROR_BASICS_H__
#define __TSS_ERROR_BASICS_H__


//
// definitions for the various TSS-SW layers
//
#ifndef TSS_LAYER_TPM
#define TSS_LAYER_TPM   0x0000L     // definition for TPM layer
#endif // TSS_LAYER_TPM

#define TSS_LAYER_TDDL   0x1000L     // definition for TDDL layer
#define TSS_LAYER_TCS   0x2000L     // definition for TCS layer

#ifndef TSS_LAYER_TSP
#define TSS_LAYER_TSP   0x3000L     // definition for TSP layer
#endif // TSS_LAYER_TSP


//
// definitions for the start points of layer specific error codes
//
#ifndef TSS_COMMON_OFFSET
#define TSS_COMMON_OFFSET   0x000L     
#endif // TSS_COMMON_OFFSET

#define TSS_TDDL_OFFSET    0x080L     
#define TSS_TCSI_OFFSET    0x0C0L     

#ifndef TSS_TSPI_OFFSET
#define TSS_TSPI_OFFSET    0x100L     
#endif // TSS_TSPI_OFFSET

#ifndef TSS_VENDOR_OFFSET
#define TSS_VENDOR_OFFSET   0x800L       
#endif // TSS_VENDOR_OFFSET
 
// do not exceed TSS_MAX_ERROR for vendor specific code values:               
#ifndef TSS_MAX_ERROR              
#define TSS_MAX_ERROR    0xFFFL 
#endif // TSS_MAX_ERROR


/* Macros for the construction and interpretation of error codes */
#define TPM_ERROR(code)        (code)
#define TDDL_ERROR(code)       ((code) ? (TSS_LAYER_TDDL | (code)) : (code))
#define TCS_ERROR(code)        ((code) ? (TSS_LAYER_TCS | (code)) : (code))
#define TSP_ERROR(code)        ((code) ? (TSS_LAYER_TSP | (code)) : (code))
#define ERROR_LAYER(error)     ((error) & 0xf000)
#define ERROR_CODE(error)      ((error) & 0x0fff)

#endif // __TSS_ERROR_BASICS_H__



<|start_filename|>src/include/authsess.h<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2007
 *
 */

#ifndef _AUTHSESS_H_
#define _AUTHSESS_H_

struct authsess {
	TPM_AUTH *pAuth;
	TPM_AUTH auth;

	/* XOR masks created before each use of an OSAP session */
	TPM_ENCAUTH encAuthUse;
	TPM_ENCAUTH encAuthMig;

	TSS_HCONTEXT tspContext;
	TPM_COMMAND_CODE command;

	TSS_HOBJECT obj_parent;
	TSS_HPOLICY hUsageParent;
	UINT32 parentMode;
	TPM_SECRET parentSecret;
	TSS_CALLBACK cb_xor, cb_hmac, cb_sealx;

	TPM_ENTITY_TYPE entity_type;
	UINT32 entityValueSize;
	BYTE *entityValue;

	TSS_HOBJECT obj_child;
	TSS_HPOLICY hUsageChild, hMigChild;
	UINT32 uMode, mMode;

	/* Created during OSAP or DSAP protocol initiation */
	TPM_NONCE nonceOddxSAP;
	TPM_NONCE nonceEvenxSAP;
	TPM_HMAC sharedSecret;

	//MUTEX_DECLARE(lock);
	//struct authsess *next;
};

TSS_RESULT authsess_oiap_get(TSS_HOBJECT, TPM_COMMAND_CODE, TPM_DIGEST *, TPM_AUTH *);
TSS_RESULT authsess_oiap_put(TPM_AUTH *, TPM_DIGEST *);

TSS_RESULT authsess_xsap_init(TSS_HCONTEXT, TSS_HOBJECT, TSS_HOBJECT, TSS_BOOL, TPM_COMMAND_CODE, TPM_ENTITY_TYPE, struct authsess **);
TSS_RESULT authsess_xsap_hmac(struct authsess *, TPM_DIGEST *);
TSS_RESULT authsess_xsap_verify(struct authsess *, TPM_DIGEST *);
void       authsess_free(struct authsess *);

#define TSS_AUTH_POLICY_REQUIRED	TRUE
#define TSS_AUTH_POLICY_NOT_REQUIRED	FALSE

#endif


<|start_filename|>src/tspi/daa/utils/list.c<|end_filename|>

/*
* Licensed Materials - Property of IBM
*
* trousers - An open source TCG Software Stack
*
* (C) Copyright International Business Machines Corp. 2006
*
*/

#include <stdio.h>
#include <stdlib.h>
#include <list.h>

#include "tsplog.h"

list_ptr list_new( void) {
	list_ptr list = (list_ptr)malloc( sizeof( list_struct));

	if( list == NULL) return NULL;
	list->head = NULL;
	return list;
}

void list_add(list_ptr list, void *obj) {
	list->current = (node_t *) malloc (sizeof(struct _list_t));
	if (list->current == NULL) {
		LogError("[list_add] malloc of %d bytes failed", sizeof(struct _list_t));
		return;
	}
	if( list->head == NULL) {
		list->head = list->current;
	} else
		list->previous->next = list->current;
	list->current->obj = obj;
	list->current->next = NULL;
	list->previous = list->current;
}

void list_dump(list_ptr list) {
	node_t *current;

	if( list->head == NULL) // if head has not been altered
		puts("no data"); // list is empty
	else {
		current = list->head; // go to first node
		do {
			printf("%d\n", (int)current->obj); // print value at current node
			current = current->next; // traverse through the list
		} while(current != NULL); // until current node is NULL
	}
}

void list_freeall(list_ptr list) {
	node_t *current = list->head; // go to first node
	node_t *next;

	if( list->head != NULL) {
		current = list->head; // go to first node
		do {
			next = current->next;
			free(current);
			current = next;
		} while(current != NULL); // until current node is NULL
	}
}


<|start_filename|>src/tspi/tspi_pcr_comp12.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2007
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


TSS_RESULT
Tspi_PcrComposite_SetPcrLocality(TSS_HPCRS hPcrComposite,	/* in */
				 UINT32    LocalityValue)	/* in */
{
	/* LocalityValue must be some combination of TPM_LOC_* values logically or'd together */
	if (!LocalityValue || (LocalityValue & (~TSS_LOCALITY_ALL)))
		return TSPERR(TSS_E_BAD_PARAMETER);

	return obj_pcrs_set_locality(hPcrComposite, LocalityValue);
}

TSS_RESULT
Tspi_PcrComposite_GetPcrLocality(TSS_HPCRS hPcrComposite,	/* in */
				 UINT32*   pLocalityValue)	/* out */
{
	if (pLocalityValue == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	return obj_pcrs_get_locality(hPcrComposite, pLocalityValue);

}

TSS_RESULT
Tspi_PcrComposite_GetCompositeHash(TSS_HPCRS hPcrComposite,	/* in */
				   UINT32*   pLen,		/* out */
				   BYTE**    ppbHashData)	/* out */
{
	if (pLen == NULL || ppbHashData == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	return obj_pcrs_get_digest_at_release(hPcrComposite, pLen, ppbHashData);

}

TSS_RESULT
Tspi_PcrComposite_SelectPcrIndexEx(TSS_HPCRS hPcrComposite,	/* in */
				   UINT32    ulPcrIndex,	/* in */
				   UINT32    Direction)		/* in */
{
	if (Direction != TSS_PCRS_DIRECTION_CREATION && Direction != TSS_PCRS_DIRECTION_RELEASE)
		return TSPERR(TSS_E_BAD_PARAMETER);

	return obj_pcrs_select_index_ex(hPcrComposite, Direction, ulPcrIndex);
}


<|start_filename|>src/tspi/daa/big_integer/bi.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2006
 *
 */

#include <bi.h>

#include "tcslog.h"

#undef INLINE_DECL
#define INLINE_DECL

/***********************************************************************************
	CONSTANT
*************************************************************************************/

bi_t bi_0;
bi_t bi_1;
bi_t bi_2;

/***********************************************************************************
	WORK VARIABLE
*************************************************************************************/

// Buffer to load bi from a file . A static field is used, this should not be
// refere in any SPI calls.
#define BUFFER_SIZE 10000
static char buffer[BUFFER_SIZE]; // used for loading bi

#define SAFETY_PARAM 80

// keep the list of allocated memory, usually used for the format functions
list_ptr allocs = NULL;

/***********************************************************************************
	DUMP LIB
*************************************************************************************/

// !! to use only for debugging
// do not used it in the same call, as a static buffer is used
char *dump_byte_array(int len, unsigned char *array) {
	int i, j=0;
	char c, str[3];

	for( i=0; i<len; i++) {
		c = array[i];
		sprintf( str, "%02X", (int)(c & 0xFF));
		buffer[j] = str[0];
		buffer[j+1] = str[1];
		j+=2;
	}
	buffer[j] = 0;
	return buffer;
}

/* convert <strings> and return it into a byte array <result> of length <length> */
unsigned char *retrieve_byte_array( int *len, const char *strings) {
	int index_str = 0, index_result = 0;
	int str_len = strlen( strings);
	char read_buffer[3];
	int c;
	unsigned char *result;

	read_buffer[2]=0;
	*len = ( str_len >> 1);
	#ifdef BI_DEBUG
	printf("[%s]\n", strings);
	printf("[retrieve_byte_array] strlen=%d len=%d\n", str_len, *len);
	#endif
	result = (unsigned char *)malloc( *len+1);
	if( result == NULL) {
		LogError("malloc of %d bytes failed", *len+1);
		return NULL;
	}
	if( (str_len & 1) ==1) {
		// impair =>   1 12 23 -> 01 12 23
		read_buffer[0]='0';
		read_buffer[1]=strings[index_str++];
		sscanf( read_buffer, "%2X", &c);
		#ifdef BI_DEBUG
		printf("[c'=%2X|%s]", (int)(c & 0xFF), read_buffer);
		#endif
		result[index_result++] = c&0xFF;
		(*len)++;
	}
	while( index_str < str_len) {
		read_buffer[0] = strings[ index_str++];
		read_buffer[1] = strings[ index_str++];
		sscanf( read_buffer, "%02X", &c);
		#ifdef BI_DEBUG
		printf("[c'=%2X|%s]", (int)(c & 0xFF), read_buffer);
		#endif
		result[index_result++] = c&0xFF;
	}
	return result;
}

/* create a <big integer> array */
INLINE_DECL void bi_new_array( bi_array array, const int length) {
	int i=0;

	bi_new_array2( array, length);
	if( array->array == NULL) return;
	for( i = 0; i< length; i++) {
		array->array[i] = bi_new_ptr();
	}
}

/* create a <big integer> array */
INLINE_DECL void bi_new_array2( bi_array array, const int length) {
	array->length = length;
	array->array = (bi_ptr *)malloc( sizeof(bi_ptr) * length);
	if( array->array == NULL) {
		LogError("malloc of %d bytes failed", sizeof(bi_ptr)*length);
		return;
	}
}

/* free resources allocated to the big integer <i> */
INLINE_DECL void bi_free_array(bi_array array) {
	int length = array->length;
	int i=0;

	for( i = 0; i< length; i++) {
		bi_free_ptr( array->array[i]);
	}
	free( array->array);
}

/* copy length pointers from the array <src, offset_src> to array <dest, offset_dest> */
INLINE_DECL void bi_copy_array(bi_array_ptr src,
				int offset_src,
				bi_array_ptr dest,
				int offset_dest,
				int length) {
	int i=0;

	for( i = 0; i< length; i++) {
		dest->array[ offset_dest + i] = src->array[ offset_src + i];
	}
}

/* debug function -> dump a field of type bi_array */
void dump_bi_array( char *field, const bi_array_ptr array) {
	int i;

	for( i=0; i<array->length; i++) {
		printf("%s->array[%d] = %s\n", field, i, bi_2_hex_char(array->array[i]));
	}
}

/***********************************************************************************
	SAFE RANDOM
*************************************************************************************/

/* Returns a random number in the range of [0,element-1] */
bi_ptr compute_random_number( bi_ptr result, const bi_ptr element) {
	bi_urandom( result, bi_length( element) + SAFETY_PARAM);
	bi_mod( result, result, element);
	return result;
}

/***********************************************************************************
	SAVE / LOAD
*************************************************************************************/

/* load an big integer from an open file handler */
void bi_load( bi_ptr bi, FILE *file) {
	int i=0;
	char c;

	fgets( buffer, BUFFER_SIZE, file);
	do {
		c = buffer[i];
		i++;
	} while( c != 0 && c != ' ');
	buffer[i-1] = 0;
	bi_set_as_hex( bi, buffer);
}

/* load an big integer array from an open file handler */
void bi_load_array( bi_array_ptr array, FILE *file) {
	int i, j = 0, length;
	char c;

	fgets( buffer, BUFFER_SIZE, file);
	do {
		c = buffer[ j];
		j++;
	} while( c != 0 && c != ' ');
	buffer[ j -1] = 0;
	sscanf( buffer, "%d", &length);
	bi_new_array( array, length);
	for( i=0; i<array->length; i++) {
		bi_load( array->array[i], file);
	}
}

/* save an big integer to an open file handler */
void bi_save( const bi_ptr bi, const char *name, FILE *file) {
	fprintf( file, "%s # %s [%ld]\n", bi_2_hex_char( bi), name, bi_nbin_size( bi));
}

/* save an big integer array to an open file handler */
void bi_save_array( const bi_array_ptr array, const char *name, FILE *file) {
	int i;
	char new_name[100];

	fprintf(file, "%d # %s.length\n", array->length, name);
	for( i=0; i<array->length; i++) {
		sprintf( new_name, "%s[%d]", name, i);
		bi_save( array->array[i], new_name, file);
	}
}

/* convert <bi> to a byte array of length result, the beginning of */
/* this buffer is feel with '0' if needed */
void bi_2_byte_array( unsigned char *result, int length, bi_ptr bi) {
	int i, result_length;

	bi_2_nbin1( &result_length, buffer, bi);
	int delta = length - result_length;
	#ifdef BI_DEBUG
	fprintf( stderr, "[bi_2_byte_array] result_length=%d length=%d\n", result_length, length);
	#endif
	if( delta < 0) {
		LogError( "[bi_2_byte_array] asked length:%d  found:%d\n", length, result_length);
		return;
	}
	for( i=0; i<delta; i++) result[i] = 0;
	for( ; i<length; i++) 	result[ i] = buffer[ i - delta];
}


<|start_filename|>src/tspi/tsp_caps_tpm.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2006
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


/*
 * This function provides a funnel through which all the TCSP_SetCapability requests can be
 * sent.  This will keep the owner auth code from being duplicated around the TSP.
 */
TSS_RESULT
TSP_SetCapability(TSS_HCONTEXT tspContext,
		  TSS_HTPM hTPM,
		  TSS_HPOLICY hTPMPolicy,
		  TPM_CAPABILITY_AREA tcsCapArea,
		  UINT32 subCap,
		  TSS_BOOL value)
{
	TSS_RESULT result;
	Trspi_HashCtx hashCtx;
	TPM_DIGEST digest;
	TPM_AUTH auth;

	subCap = endian32(subCap);

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_SetCapability);
	result |= Trspi_Hash_UINT32(&hashCtx, tcsCapArea);
	result |= Trspi_Hash_UINT32(&hashCtx, (UINT32)sizeof(UINT32));
	result |= Trspi_HashUpdate(&hashCtx, (UINT32)sizeof(UINT32), (BYTE *)&subCap);
	result |= Trspi_Hash_UINT32(&hashCtx, (UINT32)sizeof(TSS_BOOL));
	result |= Trspi_Hash_BOOL(&hashCtx, value);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
		return result;

	if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_SetCapability, hTPMPolicy, FALSE,
					      &digest, &auth)))
		return result;

	if ((result = TCS_API(tspContext)->SetCapability(tspContext, tcsCapArea, sizeof(UINT32),
							 (BYTE *)&subCap, sizeof(TSS_BOOL),
							 (BYTE *)&value, &auth)))
		return result;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, result);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_SetCapability);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
		return result;

	return obj_policy_validate_auth_oiap(hTPMPolicy, &digest, &auth);
}

#ifdef TSS_BUILD_TRANSPORT
TSS_RESULT
Transport_GetTPMCapability(TSS_HCONTEXT        tspContext,	/* in */
			   TPM_CAPABILITY_AREA capArea,	/* in */
			   UINT32              subCapLen,	/* in */
			   BYTE*               subCap,	/* in */
			   UINT32*             respLen,	/* out */
			   BYTE**              resp)	/* out */
{
	TSS_RESULT result;
	UINT32 decLen = 0, dataLen;
	BYTE *dec = NULL;
	UINT64 offset;
	TCS_HANDLE handlesLen = 0;
	BYTE *data;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	dataLen = (2 * sizeof(UINT32)) + subCapLen;
	if ((data = malloc(dataLen)) == NULL) {
		LogError("malloc of %u bytes failed", dataLen);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	offset = 0;
	Trspi_LoadBlob_UINT32(&offset, capArea, data);
	Trspi_LoadBlob_UINT32(&offset, subCapLen, data);
	Trspi_LoadBlob(&offset, subCapLen, data, subCap);

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_GetCapability, dataLen,
						    data, NULL, &handlesLen, NULL, NULL, NULL,
						    &decLen, &dec))) {
		free(data);
		return result;
	}
	free(data);

	offset = 0;
	Trspi_UnloadBlob_UINT32(&offset, respLen, dec);

	if ((*resp = malloc(*respLen)) == NULL) {
		free(dec);
		LogError("malloc of %u bytes failed", *respLen);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	Trspi_UnloadBlob(&offset, *respLen, dec, *resp);
	free(dec);

	return result;

}

TSS_RESULT
Transport_SetCapability(TSS_HCONTEXT tspContext,	/* in */
			TCPA_CAPABILITY_AREA capArea,	/* in */
			UINT32 subCapSize,	/* in */
			BYTE * subCap,	/* in */
			UINT32 valueSize,	/* in */
			BYTE * value,	/* in */
			TPM_AUTH *ownerAuth) /* in, out */
{
	TSS_RESULT result;
	UINT32 dataLen;
	UINT64 offset;
	TCS_HANDLE handlesLen = 0;
	BYTE *data;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	dataLen = (3 * sizeof(UINT32)) + subCapSize + valueSize;
	if ((data = malloc(dataLen)) == NULL) {
		LogError("malloc of %u bytes failed", dataLen);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	offset = 0;
	Trspi_LoadBlob_UINT32(&offset, capArea, data);
	Trspi_LoadBlob_UINT32(&offset, subCapSize, data);
	Trspi_LoadBlob(&offset, subCapSize, data, subCap);
	Trspi_LoadBlob_UINT32(&offset, valueSize, data);
	Trspi_LoadBlob(&offset, valueSize, data, value);

	result = obj_context_transport_execute(tspContext, TPM_ORD_SetCapability, dataLen, data,
					       NULL, &handlesLen, NULL, NULL, NULL, NULL, NULL);

	free(data);
	return result;
}
#endif


<|start_filename|>src/tspi/rpc/tcstp/rpc_tick.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "hosttable.h"
#include "tcsd_wrap.h"
#include "obj.h"
#include "rpc_tcstp_tsp.h"


TSS_RESULT
RPC_ReadCurrentTicks_TP(struct host_table_entry* hte,
			 UINT32*                  pulCurrentTime,	/* out */
			 BYTE**                   prgbCurrentTime)	/* out */
{
	TSS_RESULT result;

	initData(&hte->comm, 1);
	hte->comm.hdr.u.ordinal = TCSD_ORD_READCURRENTTICKS;
	LogDebugFn("IN: TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_UINT32, 0, pulCurrentTime, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		*prgbCurrentTime = malloc(*pulCurrentTime);
		if (*prgbCurrentTime == NULL) {
			*pulCurrentTime = 0;
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}

		if (getData(TCSD_PACKET_TYPE_PBYTE, 1, *prgbCurrentTime, *pulCurrentTime,
			    &hte->comm)) {
			free(*prgbCurrentTime);
			*prgbCurrentTime = NULL;
			*pulCurrentTime = 0;
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
	}
done:
	return result;
}

TSS_RESULT
RPC_TickStampBlob_TP(struct host_table_entry* hte,
		      TCS_KEY_HANDLE           hKey,			/* in */
		      TPM_NONCE*               antiReplay,		/* in */
		      TPM_DIGEST*              digestToStamp,		/* in */
		      TPM_AUTH*                privAuth,		/* in, out */
		      UINT32*                  pulSignatureLength,	/* out */
		      BYTE**                   prgbSignature,		/* out */
		      UINT32*                  pulTickCountLength,	/* out */
		      BYTE**                   prgbTickCount)		/* out */

{
	TSS_RESULT result;
	UINT32 i;

	initData(&hte->comm, 5);
	hte->comm.hdr.u.ordinal = TCSD_ORD_TICKSTAMPBLOB;
	LogDebugFn("IN: TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &hKey, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_NONCE, 2, antiReplay, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_DIGEST, 3, digestToStamp, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (privAuth) {
		if (setData(TCSD_PACKET_TYPE_AUTH, 4, privAuth, 0, &hte->comm))
			return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		i = 0;
		if (privAuth) {
			if (getData(TCSD_PACKET_TYPE_AUTH, i++, privAuth, 0, &hte->comm)) {
				result = TSPERR(TSS_E_INTERNAL_ERROR);
				goto done;
			}
		}

		if (getData(TCSD_PACKET_TYPE_UINT32, i++, pulSignatureLength, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		*prgbSignature = malloc(*pulSignatureLength);
		if (*prgbSignature == NULL) {
			*pulSignatureLength = 0;
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}

		if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *prgbSignature, *pulSignatureLength,
			    &hte->comm)) {
			free(*prgbSignature);
			*prgbSignature = NULL;
			*pulSignatureLength = 0;
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		if (getData(TCSD_PACKET_TYPE_UINT32, i++, pulTickCountLength, 0, &hte->comm)) {
			free(*prgbSignature);
			*prgbSignature = NULL;
			*pulSignatureLength = 0;
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		*prgbTickCount = malloc(*pulTickCountLength);
		if (*prgbTickCount == NULL) {
			free(*prgbSignature);
			*prgbSignature = NULL;
			*pulSignatureLength = 0;
			*pulTickCountLength = 0;
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}

		if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *prgbTickCount, *pulTickCountLength,
			    &hte->comm)) {
			free(*prgbSignature);
			*prgbSignature = NULL;
			*pulSignatureLength = 0;
			free(*prgbTickCount);
			*prgbTickCount = NULL;
			*pulTickCountLength = 0;
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
	}
done:
	return result;
}


<|start_filename|>src/tspi/daa/daa_issuer/keypair_generator.c<|end_filename|>
/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2006
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#include "bi.h"
#include "list.h"
#include "daa_structs.h"
#include "daa_parameter.h"
#include "issuer.h"

static const int ELEMENT = 0;
static const int EXPONENT = 1;

extern void prime_init();
extern void compute_safe_prime(bi_ptr result, int bit_length, int prime_certainty);

bi_ptr
compute_random_number_star( bi_ptr result, const bi_ptr element)
{
	bi_t bi_tmp;

	bi_new(bi_tmp);
	do {
		compute_random_number(result, element);
	} while (!bi_equals_si(bi_gcd(bi_tmp, result, element), 1));

	bi_free(bi_tmp);

	return result;
}

/* Compute a generator of the group of quadratic residue modulo n. The
 *  generator will not be part of the subgroup of size 2.
 * n: modulus */
void
compute_generator_quadratic_residue(bi_t qr, bi_t n)
{
	bi_t bi_tmp, bi_tmp1;

	bi_new(bi_tmp);
	bi_new(bi_tmp1);

	do {
		compute_random_number(qr, n);
		// qr = (qr ^ bi_2) % n
		bi_mod_exp(qr, qr, bi_2, n);
	} while (bi_cmp_si(qr, 1) == 0 ||
		bi_cmp_si(bi_gcd(bi_tmp, n, bi_sub_si(bi_tmp1, qr, 1)), 1) != 0);

	bi_free(bi_tmp);
	bi_free(bi_tmp1);
}

void
compute_group_element(bi_ptr result[],
		      bi_ptr generator,
		      bi_ptr product_PQprime,
		      bi_ptr n)
{
	bi_t bi_tmp;

	bi_new(bi_tmp);
	compute_random_number(bi_tmp, product_PQprime);

	// bi_tmp++
	bi_inc(bi_tmp);

	// result[ELEMENT] := (generator ^ bi_tmp) mod n
	bi_mod_exp(result[ELEMENT], generator, bi_tmp, n);
	bi_set(result[EXPONENT], bi_tmp);
	bi_free(bi_tmp);
}


TSS_RESULT
generate_key_pair(UINT32                         num_attributes_issuer,
		  UINT32                         num_attributes_receiver,
		  UINT32                         base_nameLength,
		  BYTE*                          base_name,
		  KEY_PAIR_WITH_PROOF_internal** key_pair_with_proof)
{
	TSS_RESULT result = TSS_SUCCESS;
	int length_mod = DAA_PARAM_SIZE_RSA_MODULUS;
	int length;
	int i;
	TSS_DAA_PK_internal *public_key = NULL;
	BYTE *buffer = NULL;
	bi_ptr pPrime = NULL;
	bi_ptr qPrime = NULL;
	bi_ptr n = NULL;
	bi_ptr p = NULL;
	bi_ptr q = NULL;
	bi_ptr capital_s = NULL;
	bi_ptr capital_z = NULL;
	bi_ptr product_PQprime = NULL;
	bi_ptr pair[2] = {NULL, NULL};
	bi_ptr xz = NULL;
	bi_ptr capital_r0 = NULL;
	bi_ptr x0 = NULL;
	bi_ptr capital_r1 = NULL;
	bi_ptr x1 = NULL;
	bi_array_ptr x = NULL;
	bi_array_ptr capital_r = NULL;
	bi_array_ptr capitalRReceiver = NULL;
	bi_array_ptr capitalRIssuer = NULL;
	bi_ptr gamma = NULL;
	bi_ptr capital_gamma = NULL;
	bi_ptr rho = NULL;
	bi_ptr r = NULL;
	bi_ptr rho_double = NULL;
	bi_t bi_tmp, bi_tmp1, bi_tmp2;

	bi_new(bi_tmp);
	bi_new(bi_tmp1);
	bi_new(bi_tmp2);
	*key_pair_with_proof = NULL;

	// STEP 1
	LogDebug("Step 1 of 8 - compute modulus n (please wait: long process)\n");

	// FUTURE USAGE if( IS_DEBUG==0)
	prime_init();
	p = bi_new_ptr();
	q = bi_new_ptr();
	n = bi_new_ptr();

	do {
		// FUTURE USAGE
		/* compute_safe_prime( p, length_mod / 2);
		do {
			compute_safe_prime( q,
							length_mod - (length_mod >> 1));
		} while( bi_cmp( p, q) ==0);
		} else */
		{
			bi_generate_safe_prime(p, length_mod / 2);
			bi_generate_safe_prime(q, length_mod - (length_mod / 2));
			LogDebug(".");
		}
		// n = p*q
		bi_mul(n, p, q);
	} while(bi_length(n) != length_mod);

	pPrime = bi_new_ptr();
	bi_sub(pPrime, p, bi_1);

	// pPrime = (p - 1) >> 1
	bi_shift_right(pPrime, pPrime, 1);
	qPrime = bi_new_ptr();
	bi_sub(qPrime, q, bi_1);

	// qPrime = (q - 1) >> 1
	bi_shift_right( qPrime, qPrime, 1);
	if (bi_is_probable_prime(pPrime) == 0) {
		LogError("!! pPrime not a prime number: %s", bi_2_hex_char(pPrime));
		result = TSPERR(TSS_E_INTERNAL_ERROR);
		goto close;
	}
	if (bi_is_probable_prime(qPrime) == 0) {
		LogError("!! qPrime not a prime number: %s", bi_2_hex_char(qPrime));
		result = TSPERR(TSS_E_INTERNAL_ERROR);
		goto close;
	}
	LogDebug("p=%s", bi_2_hex_char(p));
	LogDebug("q=%s", bi_2_hex_char(q));
	LogDebug("n=%s", bi_2_hex_char(n));

	// STEP 2
	LogDebug("Step 2 - choose random generator of QR_n");
	capital_s = bi_new_ptr();
	compute_generator_quadratic_residue(capital_s, n);
	LogDebug("capital_s=%s", bi_2_hex_char(capital_s));

	// STEP 3 & 4
	LogDebug("Step 3 & 4 - compute group elements");
	product_PQprime = bi_new_ptr();
	bi_mul( product_PQprime, pPrime, qPrime);
	pair[ELEMENT] = bi_new_ptr();
	pair[EXPONENT] = bi_new_ptr();

	LogDebug("product_PQprime=%s [%ld]", bi_2_hex_char(product_PQprime),
		 bi_nbin_size(product_PQprime));

	compute_group_element(pair, capital_s, product_PQprime, n);
	capital_z = bi_new_ptr();
	bi_set(capital_z, pair[ELEMENT]);
	xz = bi_new_ptr();
	bi_set(xz,  pair[EXPONENT]);

	// attributes bases
	compute_group_element(pair, capital_s, product_PQprime, n);
	capital_r0 = bi_new_ptr();
	bi_set(capital_r0, pair[ELEMENT]);
	x0 = bi_new_ptr();
	bi_set(x0, pair[EXPONENT]);

	compute_group_element(pair, capital_s, product_PQprime, n);
	capital_r1 = bi_new_ptr();
	bi_set(capital_r1, pair[ELEMENT]);
	x1 = bi_new_ptr();
	bi_set(x1, pair[EXPONENT]);

	// additional attribute bases
	length = num_attributes_issuer + num_attributes_receiver;
	x = ALLOC_BI_ARRAY();
	bi_new_array(x, length);
	capital_r = ALLOC_BI_ARRAY();
	bi_new_array(capital_r, length);

	for (i = 0; i < length; i++) {
		compute_group_element(pair, capital_s, product_PQprime, n);
		bi_set(capital_r->array[i], pair[ELEMENT]);
		bi_set(x->array[i], pair[EXPONENT]);
	}

	// split capitalR into Receiver and Issuer part
	capitalRReceiver = ALLOC_BI_ARRAY();
	bi_new_array2(capitalRReceiver, num_attributes_receiver);
	for (i = 0; i < num_attributes_receiver; i++)
		capitalRReceiver->array[i] = capital_r->array[i];
	capitalRIssuer = ALLOC_BI_ARRAY();
	bi_new_array2(capitalRIssuer, num_attributes_issuer);
	for (i = 0; i < num_attributes_issuer; i++)
		capitalRIssuer->array[i] = capital_r->array[i + num_attributes_receiver];

	// STEP 6a
	LogDebug("Step 6");
	gamma = bi_new_ptr();
	capital_gamma = bi_new_ptr();
	rho = bi_new_ptr();
	r = bi_new_ptr();
	rho_double = bi_new_ptr();

	bi_generate_prime(rho, DAA_PARAM_SIZE_RHO);
	if (bi_length(rho) != DAA_PARAM_SIZE_RHO) {
		LogError("rho bit length=%ld", bi_length(rho));
		result = TSPERR(TSS_E_INTERNAL_ERROR);
		goto close;
	}

	do {
		length = DAA_PARAM_SIZE_MODULUS_GAMMA - DAA_PARAM_SIZE_RHO;
		do {
			bi_urandom(r, length);
		} while(bi_length(r) != length || bi_equals_si(bi_mod(bi_tmp, r, rho), 0));

		// rho is not a dividor of r
		bi_mul( capital_gamma, rho, r);
		// capital_gamma ++
		bi_inc( capital_gamma);
#ifdef DAA_DEBUG
		if (bi_length(capital_gamma) != DAA_PARAM_SIZE_MODULUS_GAMMA) {
			printf("|"); fflush(stdout);
		} else {
			printf("."); fflush(stdout);
		}
#endif
	} while (bi_length(capital_gamma) != DAA_PARAM_SIZE_MODULUS_GAMMA ||
		 bi_is_probable_prime(capital_gamma) == 0 );

	// STEP 6b
	if (bi_equals(bi_sub_si(bi_tmp, capital_gamma, 1),
			bi_mod(bi_tmp1, bi_mul(bi_tmp2, rho, r), n)) == 0) {
		LogWarn("capital_gamma-1 != (rho * r) mod n  tmp=%s  tmp1=%s",
			bi_2_hex_char(bi_tmp), bi_2_hex_char(bi_tmp1));
	}

	if (bi_equals(bi_div(bi_tmp, bi_sub_si(bi_tmp1, capital_gamma, 1), rho), r ) == 0) {
		LogWarn("( capital_gamma - 1)/rho != r");
	}

	LogDebug("capital_gamma=%s\n", bi_2_hex_char(capital_gamma));
	do {
		compute_random_number_star(gamma, capital_gamma);
		// gamma = (gamma ^ r) mod capital_gamma
		bi_mod_exp(gamma, gamma, r, capital_gamma);
	} while (bi_equals(gamma, bi_1));
	// STEP 7
	buffer = (BYTE *)malloc(base_nameLength);
	if (buffer == NULL) {
		LogError("malloc of %u bytes failed", base_nameLength);
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}
	memcpy(buffer, base_name, base_nameLength);
	// all fields are linked to the struct with direct reference
	public_key = create_DAA_PK(n, capital_s, capital_z, capital_r0, capital_r1, gamma,
				   capital_gamma, rho, capitalRReceiver, capitalRIssuer,
				   base_nameLength, buffer);

	// STEP 8
	// TODO dynamically load DAAKeyCorrectnessProof
	LogDebug("Step 8: generate proof (please wait: long process)");
	TSS_DAA_PK_PROOF_internal *correctness_proof = generate_proof(product_PQprime, public_key,
								      xz, x0, x1, x);
	if (correctness_proof == NULL) {
		LogError("creation of correctness_proof failed");
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}

	*key_pair_with_proof = (KEY_PAIR_WITH_PROOF_internal *)
					malloc(sizeof(KEY_PAIR_WITH_PROOF_internal));
	if (*key_pair_with_proof == NULL) {
		LogError("malloc of %zd bytes failed", sizeof(KEY_PAIR_WITH_PROOF_internal));
		result = TSPERR(TSS_E_OUTOFMEMORY);
		goto close;
	}

	(*key_pair_with_proof)->pk = public_key;
	(*key_pair_with_proof)->proof = correctness_proof;
	// all fields are linked to the struct with direct reference
	(*key_pair_with_proof)->private_key = create_TSS_DAA_PRIVATE_KEY(pPrime, qPrime);
close:
	if (result != TSS_SUCCESS) {
		// remove everything, even numbers that should be stored in a struct
		FREE_BI(pPrime);	// kept if no error
		FREE_BI(qPrime);	// kept if no error
		FREE_BI(n);	// kept if no error
		// FREE_BI( p);
		// FREE_BI( q);
		FREE_BI(capital_s);	// kept if no error
		FREE_BI(capital_z);	// kept if no error
		// FREE_BI(product_PQprime);
		// FREE_BI(pair[ELEMENT]);
		// FREE_BI(pair[EXPONENT]);
		// FREE_BI(xz);
		FREE_BI(capital_r0);	// kept if no error
		// FREE_BI(x0);
		FREE_BI(capital_r1);	// kept if no error
		// FREE_BI( x1);
		// bi_array_ptr x = NULL;
		// bi_array_ptr capital_r = NULL;
		// bi_array_ptr capitalRReceiver = NULL;
		// bi_array_ptr capitalRIssuer = NULL;
		FREE_BI( gamma);	// kept if no error
		FREE_BI( capital_gamma);	// kept if no error
		FREE_BI( rho);	// kept if no error
		// FREE_BI( r);
		// FREE_BI( rho_double);
		if (buffer!=NULL)
			free(buffer);

		if (public_key != NULL)
			free(public_key);

		if (*key_pair_with_proof != NULL)
			free(*key_pair_with_proof);
	}
	/*
	Fields kept by structures
	TSS_DAA_PK: 	n
				capital_s
				capital_z
				capital_r0
				capital_r1
				gamma
				capital_gamma
				rho
				capitalRReceiver
				capitalRIssuer
				base_nameLength
				buffer
	TSS_DAA_PRIVATE_KEY:
				pPrime
				qPrime
	*/
	bi_free(bi_tmp);
	bi_free(bi_tmp1);
	bi_free(bi_tmp2);
	FREE_BI(p);
	FREE_BI(q);
	FREE_BI(product_PQprime);
	FREE_BI(pair[ELEMENT]);
	FREE_BI(pair[EXPONENT]);
	FREE_BI(xz);
	FREE_BI(x0);
	FREE_BI(x0);
	// bi_array_ptr x = NULL;
	// bi_array_ptr capital_r = NULL;
	// bi_array_ptr capitalRReceiver = NULL;
	// bi_array_ptr capitalRIssuer = NULL;
	FREE_BI(r);
	FREE_BI(rho_double);

	return result;
}


<|start_filename|>src/tspi/rpc/tcstp/rpc_evlog.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "hosttable.h"
#include "tcsd_wrap.h"
#include "obj.h"
#include "rpc_tcstp_tsp.h"


TSS_RESULT
RPC_LogPcrEvent_TP(struct host_table_entry *hte,
			       TSS_PCR_EVENT Event,	/*  in  */
			       UINT32 * pNumber	/*  out */
    ) {
	TSS_RESULT result;

	initData(&hte->comm, 2);
	hte->comm.hdr.u.ordinal = TCSD_ORD_LOGPCREVENT;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	if (setData(TCSD_PACKET_TYPE_PCR_EVENT, 1, &Event, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_UINT32, 0, pNumber, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
	}

	return result;
}

TSS_RESULT
RPC_GetPcrEvent_TP(struct host_table_entry *hte,
			       UINT32 PcrIndex,	/* in */
			       UINT32 * pNumber,	/* in, out */
			       TSS_PCR_EVENT ** ppEvent	/* out */
    ) {
	TSS_RESULT result;
	BYTE lengthOnly = (ppEvent == NULL) ? TRUE : FALSE;

	initData(&hte->comm, 4);
	hte->comm.hdr.u.ordinal = TCSD_ORD_GETPCREVENT;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &PcrIndex, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	if (setData(TCSD_PACKET_TYPE_UINT32, 2, pNumber, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	if (setData(TCSD_PACKET_TYPE_BYTE, 3, &lengthOnly, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_UINT32, 0, pNumber, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		if (ppEvent) {
			*ppEvent = malloc(sizeof(TSS_PCR_EVENT));
			if (*ppEvent == NULL) {
				LogError("malloc of %zd bytes failed.",
					 sizeof(TSS_PCR_EVENT));
				result = TSPERR(TSS_E_OUTOFMEMORY);
				goto done;
			}

			if (getData(TCSD_PACKET_TYPE_PCR_EVENT, 1, *ppEvent, 0, &hte->comm)) {
				free(*ppEvent);
				*ppEvent = NULL;
				result = TSPERR(TSS_E_INTERNAL_ERROR);
			}
		}
	}

done:
	return result;
}

TSS_RESULT
RPC_GetPcrEventsByPcr_TP(struct host_table_entry *hte,
				     UINT32 PcrIndex,	/* in */
				     UINT32 FirstEvent,	/* in */
				     UINT32 * pEventCount,	/* in, out */
				     TSS_PCR_EVENT ** ppEvents	/* out */
    ) {
	TSS_RESULT result;
	UINT32 i, j;

	initData(&hte->comm, 4);
	hte->comm.hdr.u.ordinal = TCSD_ORD_GETPCREVENTBYPCR;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &PcrIndex, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	if (setData(TCSD_PACKET_TYPE_UINT32, 2, &FirstEvent, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	if (setData(TCSD_PACKET_TYPE_UINT32, 3, pEventCount, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_UINT32, 0, pEventCount, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		if (*pEventCount > 0) {
			*ppEvents = calloc_tspi(hte->tspContext,
						sizeof(TSS_PCR_EVENT) * (*pEventCount));
			if (*ppEvents == NULL) {
				LogError("malloc of %zd bytes failed.", sizeof(TSS_PCR_EVENT) * (*pEventCount));
				result = TSPERR(TSS_E_OUTOFMEMORY);
				goto done;
			}

			i = 1;
			for (j = 0; j < (*pEventCount); j++) {
				if (getData(TCSD_PACKET_TYPE_PCR_EVENT, i++, &((*ppEvents)[j]), 0, &hte->comm)) {
					free(*ppEvents);
					*ppEvents = NULL;
					result = TSPERR(TSS_E_INTERNAL_ERROR);
					goto done;
				}
			}
		} else {
			*ppEvents = NULL;
		}
	}

done:
	return result;
}

TSS_RESULT
RPC_GetPcrEventLog_TP(struct host_table_entry *hte,
				  UINT32 * pEventCount,	/* out */
				  TSS_PCR_EVENT ** ppEvents	/* out */
    ) {
	TSS_RESULT result;
	int i, j;

	initData(&hte->comm, 1);
	hte->comm.hdr.u.ordinal = TCSD_ORD_GETPCREVENTLOG;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_UINT32, 0, pEventCount, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		if (*pEventCount > 0) {
			*ppEvents = calloc_tspi(hte->tspContext,
						sizeof(TSS_PCR_EVENT) * (*pEventCount));
			if (*ppEvents == NULL) {
				LogError("malloc of %zd bytes failed.",
					 sizeof(TSS_PCR_EVENT) * (*pEventCount));
				result = TSPERR(TSS_E_OUTOFMEMORY);
				goto done;
			}

			i = 1;
			for (j = 0; (UINT32)j < (*pEventCount); j++) {
				if (getData(TCSD_PACKET_TYPE_PCR_EVENT, i++, &((*ppEvents)[j]), 0, &hte->comm)) {
					free(*ppEvents);
					*ppEvents = NULL;
					result = TSPERR(TSS_E_INTERNAL_ERROR);
					goto done;
				}
			}
		} else {
			*ppEvents = NULL;
		}
	}

done:
	return result;
}


<|start_filename|>src/tcs/tcsi_daa.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcsps.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "req_mgr.h"
#include "tcsd_wrap.h"
#include "tcsd.h"


TSS_RESULT
TCSP_DaaJoin_internal(TCS_CONTEXT_HANDLE hContext, /* in */
		      TPM_HANDLE handle, /* in */
		      BYTE stage,               /* in */
		      UINT32 inputSize0,   /* in */
		      BYTE *inputData0,   /* in */
		      UINT32 inputSize1, /* in */
		      BYTE *inputData1, /* in */
		      TPM_AUTH * ownerAuth,	/* in, out */
		      UINT32 *outputSize, /* out */
		      BYTE **outputData)  /* out */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebugFn("Enter");
	if ( (result = ctx_verify_context(hContext)) != TSS_SUCCESS)
		return result;
	if( (result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)) != TSS_SUCCESS)
		goto done;

#if 0
	offset = 10;
	LoadBlob_UINT32( &offset, handle, txBlob);
	LogDebug("load BYTE: stage: %x", stage);
	LoadBlob( &offset, sizeof(BYTE), txBlob, &stage);

	LogDebug("load UNIT32: inputSize0: %x  (oldOffset=%" PRIu64 ")", inputSize0, offset);
	LoadBlob_UINT32(&offset, inputSize0, txBlob);
	LogDebug("load Data: inputData0: %X   (oldOffset=%" PRIu64 ")", (int)inputData0, offset);
	LoadBlob(&offset, inputSize0, txBlob, inputData0);
	LogDebug("load UINT32: inputSize1:%x  (oldOffset=%" PRIu64 ")", inputSize1, offset);
	LoadBlob_UINT32(&offset, inputSize1, txBlob);
	if( inputSize1>0) {
		LogDebug("load Data: inputData1: %X  (oldOffset=%" PRIu64 ")", (int)inputData1, offset);
		LoadBlob(&offset, inputSize1, txBlob, inputData1);
	}
	LogDebug("load Auth: ownerAuth: %X  (oldOffset=%" PRIu64 ")", (int)ownerAuth, offset);
	LoadBlob_Auth(&offset, txBlob, ownerAuth);

	LogDebug("load Header: ordinal: %X  (oldOffset=%" PRIu64 ")", TPM_ORD_DAA_Join, offset);
	LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, offset, TPM_ORD_DAA_Join, txBlob);
#else
	if ((result = tpm_rqu_build(TPM_ORD_DAA_Join, &offset, txBlob, handle, stage, inputSize0,
				    inputData0, inputSize1, inputData1, ownerAuth)))
		goto done;
#endif

	LogDebug("req_mgr_submit_req  (oldOffset=%" PRIu64 ")", offset);
	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	LogDebug("UnloadBlob  (paramSize=%d) result=%d", paramSize, result);
	if (!result) {
#if 0
		offset = 10;
		UnloadBlob_UINT32( &offset, outputSize, txBlob);
		LogDebug("Unload outputSize=%d", *outputSize);
		*outputData = malloc(*outputSize);
		if( *outputData == NULL) {
			LogError("malloc of %u bytes failed.", *outputSize);
			result = TCSERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		LogDebug("Unload outputData");
		UnloadBlob( &offset, *outputSize, txBlob, *outputData);
		LogDebug("Unload Auth");
		UnloadBlob_Auth(&offset, txBlob, ownerAuth);
#else
		result = tpm_rsp_parse(TPM_ORD_DAA_Join, txBlob, paramSize, outputSize, outputData,
				       ownerAuth);
#endif
	}
done:
	LogDebug("Leaving DaaJoin with result:%d", result);
	auth_mgr_release_auth(ownerAuth, NULL, hContext);
	return result;
}

TSS_RESULT TCSP_DaaSign_internal(TCS_CONTEXT_HANDLE hContext, /* in */
				 TPM_HANDLE handle, /* in */
				 BYTE stage,               /* in */
				 UINT32 inputSize0,   /* in */
				 BYTE *inputData0,   /* in */
				 UINT32 inputSize1, /* in */
				 BYTE *inputData1, /* in */
				 TPM_AUTH * ownerAuth,	/* in, out */
				 UINT32 *outputSize, /* out */
				 BYTE **outputData)  /* out */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebugFn("Enter");
	if ( (result = ctx_verify_context(hContext)) != TSS_SUCCESS)
		return result;

	if( (result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)) != TSS_SUCCESS)
		goto done;

#if 0
	offset = 10;
	LoadBlob_UINT32( &offset, handle, txBlob);
	LogDebug("load BYTE: stage: %x", stage);
	LoadBlob( &offset, sizeof(BYTE), txBlob, &stage);

	LogDebug("load UNIT32: inputSize0: %x  (oldOffset=%" PRIu64 ")", inputSize0, offset);
	LoadBlob_UINT32(&offset, inputSize0, txBlob);
	LogDebug("load Data: inputData0: %X   (oldOffset=%" PRIu64 ")", (int)inputData0, offset);
	LoadBlob(&offset, inputSize0, txBlob, inputData0);
	LogDebug("load UINT32: inputSize1:%x  (oldOffset=%" PRIu64 ")", inputSize1, offset);
	LoadBlob_UINT32(&offset, inputSize1, txBlob);
	if( inputSize1>0) {
		LogDebug("load Data: inputData1: %X  (oldOffset=%" PRIu64 ")", (int)inputData1, offset);
		LoadBlob(&offset, inputSize1, txBlob, inputData1);
	}
	LogDebug("load Auth: ownerAuth: %X  (oldOffset=%" PRIu64 ")", (int)ownerAuth, offset);
	LoadBlob_Auth(&offset, txBlob, ownerAuth);

	LogDebug("load Header: ordinal: %X  (oldOffset=%" PRIu64 ")", TPM_ORD_DAA_Sign, offset);
	LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, offset, TPM_ORD_DAA_Sign, txBlob);
#else
	if ((result = tpm_rqu_build(TPM_ORD_DAA_Sign, &offset, txBlob, handle, stage, inputSize0,
				    inputData0, inputSize1, inputData1, ownerAuth)))
		goto done;
#endif

	LogDebug("req_mgr_submit_req  (oldOffset=%" PRIu64 ")", offset);
	if ((result = req_mgr_submit_req(txBlob))) goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	LogDebug("UnloadBlob  (paramSize=%d) result=%d", paramSize, result);
	if (!result) {
#if 0
		offset = 10;
		UnloadBlob_UINT32( &offset, outputSize, txBlob);
		LogDebug("Unload outputSize=%d", *outputSize);
		*outputData = malloc(*outputSize);
		if( *outputData == NULL) {
			LogError("malloc of %u bytes failed.", *outputSize);
			result = TCSERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		LogDebug("Unload outputData");
		UnloadBlob(&offset, *outputSize, txBlob, *outputData);
		LogDebug("Unload Auth");
		UnloadBlob_Auth(&offset, txBlob, ownerAuth);
#else
		result = tpm_rsp_parse(TPM_ORD_DAA_Sign, txBlob, paramSize, outputSize, outputData,
				       ownerAuth);
#endif
	}
done:
	LogDebug("Leaving DaaSign with result:%d", result);
	auth_mgr_release_auth(ownerAuth, NULL, hContext);
	return result;
}



<|start_filename|>src/include/auth_mgr.h<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */

#ifndef _AUTH_MGR_H_
#define _AUTH_MGR_H_

struct auth_map
{
	TSS_BOOL full;
	TPM_AUTHHANDLE tpm_handle;
	TCS_CONTEXT_HANDLE tcs_ctx;
	BYTE *swap; /* These 'swap' variables manage blobs received from TPM_SaveAuthContext */
	UINT32 swap_size;
};

/*
 * it appears that there's no way to query a v1.1 TPM for the
 * max number of simultaneous auth sessions. We'll make the
 * default relatively large and let the TPM return
 * TCPA_RESOURCES to tell us when we cross the line.
 */
#define TSS_DEFAULT_AUTH_TABLE_SIZE	16
#define TSS_DEFAULT_OVERFLOW_AUTHS	16

struct _auth_mgr
{
	short max_auth_sessions;
	short open_auth_sessions;
	UINT32 sleeping_threads;
	COND_VAR **overflow;	/* queue of TCS contexts waiting for an auth session to become
				 * available */
	unsigned int of_head, of_tail;	/* head and tail of the overflow queue */
	struct auth_map *auth_mapper; /* table of currently tracked auth sessions */
	UINT32 auth_mapper_size, overflow_size;
} auth_mgr;

MUTEX_DECLARE_INIT(auth_mgr_lock);

TSS_RESULT TPM_SaveAuthContext(TPM_AUTHHANDLE, UINT32 *, BYTE **);
TSS_RESULT TPM_LoadAuthContext(UINT32, BYTE *, TPM_AUTHHANDLE *);

#endif


<|start_filename|>src/tspi/rpc/tcstp/rpc_oper.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2007
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "tsplog.h"
#include "hosttable.h"
#include "tcsd_wrap.h"
#include "rpc_tcstp_tsp.h"


TSS_RESULT
RPC_SetOperatorAuth_TP(struct host_table_entry *hte,
			TCPA_SECRET *operatorAuth)	/* in */
{
	TSS_RESULT result;

	initData(&hte->comm, 2);
	hte->comm.hdr.u.ordinal = TCSD_ORD_SETOPERATORAUTH;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_SECRET, 1, operatorAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	return result;
}



<|start_filename|>src/tcs/tcs_req_mgr.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <syslog.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

#include "trousers/tss.h"
#include "tcs_tsp.h"
#include "tcs_utils.h"
#include "tddl.h"
#include "req_mgr.h"
#include "tcslog.h"

static struct tpm_req_mgr *trm;

#ifdef TSS_DEBUG
#define TSS_TPM_DEBUG
#endif

TSS_RESULT
req_mgr_submit_req(BYTE *blob)
{
	TSS_RESULT result;
	BYTE loc_buf[TSS_TPM_TXBLOB_SIZE];
	UINT32 size = TSS_TPM_TXBLOB_SIZE;
	UINT32 retry = TSS_REQ_MGR_MAX_RETRIES;

	MUTEX_LOCK(trm->queue_lock);

#ifdef TSS_TPM_DEBUG
	LogBlobData("To TPM:", Decode_UINT32(&blob[2]), blob);
#endif

	do {
		result = Tddli_TransmitData(blob, Decode_UINT32(&blob[2]), loc_buf, &size);
	} while (!result && (Decode_UINT32(&loc_buf[6]) == TCPA_E_RETRY) && --retry);

	if (!result)
		memcpy(blob, loc_buf, Decode_UINT32(&loc_buf[2]));

#ifdef TSS_TPM_DEBUG
	LogBlobData("From TPM:", size, loc_buf);
#endif

	MUTEX_UNLOCK(trm->queue_lock);

	return result;
}

TSS_RESULT
req_mgr_init()
{
	if ((trm = calloc(1, sizeof(struct tpm_req_mgr))) == NULL) {
		LogError("malloc of %zd bytes failed.", sizeof(struct tpm_req_mgr));
		return TSS_E_OUTOFMEMORY;
	}

	MUTEX_INIT(trm->queue_lock);

	return Tddli_Open();
}

TSS_RESULT
req_mgr_final()
{
	free(trm);

	return Tddli_Close();
}



<|start_filename|>src/tcs/tcs_counter.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcsps.h"
#include "tcslog.h"


void
UnloadBlob_COUNTER_VALUE(UINT64 *offset, BYTE *blob, TPM_COUNTER_VALUE *ctr)
{
	if (!ctr) {
		UnloadBlob_UINT16(offset, NULL, blob);
		UnloadBlob(offset, 4, blob, NULL);
		UnloadBlob_UINT32(offset, NULL, blob);
		return;
	}

	UnloadBlob_UINT16(offset, &ctr->tag, blob);
	UnloadBlob(offset, 4, blob, (BYTE *)&ctr->label);
	UnloadBlob_UINT32(offset, &ctr->counter, blob);
}

void
LoadBlob_COUNTER_VALUE(UINT64 *offset, BYTE *blob, TPM_COUNTER_VALUE *ctr)
{
	LoadBlob_UINT16(offset, ctr->tag, blob);
	LoadBlob(offset, 4, blob, (BYTE *)&ctr->label);
	LoadBlob_UINT32(offset, ctr->counter, blob);
}


<|start_filename|>src/tspi/rpc/tcstp/rpc_ek.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "hosttable.h"
#include "tcsd_wrap.h"
#include "obj.h"
#include "rpc_tcstp_tsp.h"


TSS_RESULT
RPC_CreateEndorsementKeyPair_TP(struct host_table_entry *hte,
					     TCPA_NONCE antiReplay,	/* in */
					     UINT32 endorsementKeyInfoSize,	/* in */
					     BYTE * endorsementKeyInfo,	/* in */
					     UINT32 * endorsementKeySize,	/* out */
					     BYTE ** endorsementKey,	/* out */
					     TCPA_DIGEST * checksum	/* out */
    ) {

	TSS_RESULT result;

	initData(&hte->comm, 4);
	hte->comm.hdr.u.ordinal = TCSD_ORD_CREATEENDORSEMENTKEYPAIR;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_NONCE, 1, &antiReplay, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 2, &endorsementKeyInfoSize, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 3, endorsementKeyInfo, endorsementKeyInfoSize, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_UINT32, 0, endorsementKeySize, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		*endorsementKey = (BYTE *) malloc(*endorsementKeySize);
		if (*endorsementKey == NULL) {
			LogError("malloc of %u bytes failed.", *endorsementKeySize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, 1, *endorsementKey, *endorsementKeySize, &hte->comm)) {
			free(*endorsementKey);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_DIGEST, 2, &(checksum->digest), 0, &hte->comm)) {
			free(*endorsementKey);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		}
	}

done:
	return result;
}

TSS_RESULT
RPC_ReadPubek_TP(struct host_table_entry *hte,
			      TCPA_NONCE antiReplay,	/* in */
			      UINT32 * pubEndorsementKeySize,	/* out */
			      BYTE ** pubEndorsementKey,	/* out */
			      TCPA_DIGEST * checksum	/* out */
    ) {
	TSS_RESULT result;

	initData(&hte->comm, 2);
	hte->comm.hdr.u.ordinal = TCSD_ORD_READPUBEK;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);
	/*      &hte->comm.numParms = 2; */

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_NONCE, 1, &antiReplay, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_UINT32, 0, pubEndorsementKeySize, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		*pubEndorsementKey = (BYTE *) malloc(*pubEndorsementKeySize);
		if (*pubEndorsementKey == NULL) {
			LogError("malloc of %u bytes failed.", *pubEndorsementKeySize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, 1, *pubEndorsementKey, *pubEndorsementKeySize, &hte->comm)) {
			free(*pubEndorsementKey);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_DIGEST, 2, &(checksum->digest), 0, &hte->comm)) {
			free(*pubEndorsementKey);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		}
	}
done:
	return result;
}

TSS_RESULT
RPC_DisablePubekRead_TP(struct host_table_entry *hte,
				     TPM_AUTH * ownerAuth	/* in, out */
    ) {
	TSS_RESULT result;

	initData(&hte->comm, 2);
	hte->comm.hdr.u.ordinal = TCSD_ORD_DISABLEPUBEKREAD;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

        if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
                return TSPERR(TSS_E_INTERNAL_ERROR);

	if (setData(TCSD_PACKET_TYPE_AUTH, 1, ownerAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

        result = sendTCSDPacket(hte);

        if (result == TSS_SUCCESS)
                result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
	}

	return result;
}

TSS_RESULT
RPC_OwnerReadPubek_TP(struct host_table_entry *hte,
				   TPM_AUTH * ownerAuth,	/* in, out */
				   UINT32 * pubEndorsementKeySize,	/* out */
				   BYTE ** pubEndorsementKey	/* out */
    ) {

        TSS_RESULT result;

	initData(&hte->comm, 2);
        hte->comm.hdr.u.ordinal = TCSD_ORD_OWNERREADPUBEK;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

        if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
                return TSPERR(TSS_E_INTERNAL_ERROR);
        if (setData(TCSD_PACKET_TYPE_AUTH, 1, ownerAuth, 0, &hte->comm))
                return TSPERR(TSS_E_INTERNAL_ERROR);

        result = sendTCSDPacket(hte);

        if (result == TSS_SUCCESS)
                result = hte->comm.hdr.u.result;

        if (result == TSS_SUCCESS) {
                if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm)){
			free(*pubEndorsementKey);
                        result = TSPERR(TSS_E_INTERNAL_ERROR);
		}

                if (getData(TCSD_PACKET_TYPE_UINT32, 1, pubEndorsementKeySize, 0, &hte->comm)) {
                        result = TSPERR(TSS_E_INTERNAL_ERROR);
                        goto done;
                }

                *pubEndorsementKey = (BYTE *) malloc(*pubEndorsementKeySize);
                if (*pubEndorsementKey == NULL) {
                        LogError("malloc of %u bytes failed.", *pubEndorsementKeySize);
                        result = TSPERR(TSS_E_OUTOFMEMORY);
                        goto done;
                }

                if (getData(TCSD_PACKET_TYPE_PBYTE, 2, *pubEndorsementKey, *pubEndorsementKeySize, &hte->comm)) {
                        free(*pubEndorsementKey);
                        result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
                }
        }

done:
	return result;
}

#ifdef TSS_BUILD_TSS12
TSS_RESULT
RPC_CreateRevocableEndorsementKeyPair_TP(struct host_table_entry *hte,
					 TPM_NONCE antiReplay,		/* in */
					 UINT32 endorsementKeyInfoSize,/* in */
					 BYTE * endorsementKeyInfo,	/* in */
					 TSS_BOOL genResetAuth,	/* in */
					 TPM_DIGEST * eKResetAuth,	/* in, out */
					 UINT32 * endorsementKeySize,	/* out */
					 BYTE ** endorsementKey,	/* out */
					 TPM_DIGEST * checksum)	/* out */
{
	TSS_RESULT result;

	initData(&hte->comm, 6);
	hte->comm.hdr.u.ordinal = TCSD_ORD_CREATEREVOCABLEENDORSEMENTKEYPAIR;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_NONCE, 1, &antiReplay, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 2, &endorsementKeyInfoSize, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 3, endorsementKeyInfo, endorsementKeyInfoSize, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_BOOL, 4, &genResetAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_DIGEST, 5, eKResetAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_DIGEST, 0, &(eKResetAuth->digest), 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_UINT32, 1, endorsementKeySize, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		*endorsementKey = (BYTE *) malloc(*endorsementKeySize);
		if (*endorsementKey == NULL) {
			LogError("malloc of %u bytes failed.", *endorsementKeySize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, 2, *endorsementKey, *endorsementKeySize, &hte->comm)) {
			free(*endorsementKey);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_DIGEST, 3, &(checksum->digest), 0, &hte->comm)) {
			free(*endorsementKey);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		}
	}

done:
	return result;
}

TSS_RESULT
RPC_RevokeEndorsementKeyPair_TP(struct host_table_entry *hte,
				TPM_DIGEST *EKResetAuth)	/* in */
{
	TSS_RESULT result;

	initData(&hte->comm, 2);
	hte->comm.hdr.u.ordinal = TCSD_ORD_REVOKEENDORSEMENTKEYPAIR;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_DIGEST, 1, EKResetAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	return result;
}
#endif


<|start_filename|>src/tcs/tcsi_caps.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcsps.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "tcsd_wrap.h"
#include "tcsd.h"

extern struct tcsd_config tcsd_options;

TSS_RESULT
internal_TCSGetCap(TCS_CONTEXT_HANDLE hContext,
		   TCPA_CAPABILITY_AREA capArea,
		   UINT32 subCap,
		   UINT32 * respSize, BYTE ** resp)
{
	UINT32 u32value = 0;
	UINT64 offset;
	TPM_VERSION tcsVersion = INTERNAL_CAP_VERSION;
	struct tcsd_config *config = &tcsd_options;
	struct platform_class *platClass;
	TSS_BOOL bValue = FALSE;

	LogDebug("Checking Software Cap of TCS");
	switch (capArea) {
	case TSS_TCSCAP_ALG:
		LogDebug("TSS_TCSCAP_ALG");

		switch (subCap) {
		case TSS_ALG_RSA:
			*respSize = sizeof(TSS_BOOL);
			bValue = INTERNAL_CAP_TCS_ALG_RSA;
			break;
		case TSS_ALG_DES:
			*respSize = sizeof(TSS_BOOL);
			bValue = INTERNAL_CAP_TCS_ALG_DES;
			break;
		case TSS_ALG_3DES:
			*respSize = sizeof(TSS_BOOL);
			bValue = INTERNAL_CAP_TCS_ALG_3DES;
			break;
		case TSS_ALG_SHA:
			*respSize = sizeof(TSS_BOOL);
			bValue = INTERNAL_CAP_TCS_ALG_SHA;
			break;
		case TSS_ALG_AES:
			*respSize = sizeof(TSS_BOOL);
			bValue = INTERNAL_CAP_TCS_ALG_AES;
			break;
		case TSS_ALG_HMAC:
			*respSize = sizeof(TSS_BOOL);
			bValue = INTERNAL_CAP_TCS_ALG_HMAC;
			break;
		case TSS_ALG_DEFAULT:
			*respSize = sizeof(UINT32);
			u32value = INTERNAL_CAP_TCS_ALG_DEFAULT;
			break;
		case TSS_ALG_DEFAULT_SIZE:
			*respSize = sizeof(UINT32);
			u32value = INTERNAL_CAP_TCS_ALG_DEFAULT_SIZE;
			break;
		default:
			*respSize = 0;
			LogDebugFn("Bad subcap");
			return TCSERR(TSS_E_BAD_PARAMETER);
		}

		if ((*resp = malloc(*respSize)) == NULL) {
			LogError("malloc of %u bytes failed.", *respSize);
			*respSize = 0;
			return TCSERR(TSS_E_OUTOFMEMORY);
		}

		offset = 0;
		if (*respSize == sizeof(TSS_BOOL))
			*(TSS_BOOL *)(*resp) = bValue;
		else
			*(UINT32 *)(*resp) = u32value;
		break;
	case TSS_TCSCAP_VERSION:
		LogDebug("TSS_TCSCAP_VERSION");
		if ((*resp = calloc(1, sizeof(TSS_VERSION))) == NULL) {
			LogError("malloc of %zd bytes failed.", sizeof(TSS_VERSION));
			return TCSERR(TSS_E_OUTOFMEMORY);
		}
		offset = 0;
		LoadBlob_VERSION(&offset, *resp, &tcsVersion);
		*respSize = sizeof(TSS_VERSION);
		break;
	case TSS_TCSCAP_PERSSTORAGE:
		LogDebug("TSS_TCSCAP_PERSSTORAGE");
		if ((*resp = malloc(sizeof(TSS_BOOL))) == NULL) {
			LogError("malloc of %zd byte failed.", sizeof(TSS_BOOL));
			return TCSERR(TSS_E_OUTOFMEMORY);
		}
		*(TSS_BOOL *)(*resp) = INTERNAL_CAP_TCS_PERSSTORAGE;
		*respSize = sizeof(TSS_BOOL);
		break;
	case TSS_TCSCAP_CACHING:
		LogDebug("TSS_TCSCAP_CACHING");

		if (subCap == TSS_TCSCAP_PROP_KEYCACHE)
			bValue = INTERNAL_CAP_TCS_CACHING_KEYCACHE;
		else if (subCap == TSS_TCSCAP_PROP_AUTHCACHE)
			bValue = INTERNAL_CAP_TCS_CACHING_AUTHCACHE;
		else {
			LogDebugFn("Bad subcap");
			return TCSERR(TSS_E_BAD_PARAMETER);
		}

		if ((*resp = malloc(sizeof(TSS_BOOL))) == NULL) {
			LogError("malloc of %zd byte failed.", sizeof(TSS_BOOL));
			return TCSERR(TSS_E_OUTOFMEMORY);
		}
		*respSize = sizeof(TSS_BOOL);
		*(TSS_BOOL *)(*resp) = bValue;
		break;
	case TSS_TCSCAP_MANUFACTURER:
		if (subCap == TSS_TCSCAP_PROP_MANUFACTURER_ID) {
			if ((*resp = malloc(sizeof(UINT32))) == NULL) {
				LogError("malloc of %zd byte failed.", sizeof(UINT32));
				return TCSERR(TSS_E_OUTOFMEMORY);
			}
			*(UINT32 *)(*resp) = INTERNAL_CAP_MANUFACTURER_ID;
			*respSize = sizeof(UINT32);
		} else if (subCap == TSS_TCSCAP_PROP_MANUFACTURER_STR) {
			BYTE str[] = INTERNAL_CAP_MANUFACTURER_STR;

			if ((*resp = malloc(INTERNAL_CAP_MANUFACTURER_STR_LEN)) == NULL) {
				LogError("malloc of %d bytes failed.",
					 INTERNAL_CAP_MANUFACTURER_STR_LEN);
				return TCSERR(TSS_E_OUTOFMEMORY);
			}
			memcpy(*resp, str, INTERNAL_CAP_MANUFACTURER_STR_LEN);
			*respSize = INTERNAL_CAP_MANUFACTURER_STR_LEN;
		} else {
			LogDebugFn("Bad subcap");
			return TCSERR(TSS_E_BAD_PARAMETER);
		}
		break;
	case TSS_TCSCAP_TRANSPORT:
		/* A zero value here means the TSP is asking whether we support transport sessions
		 * at all */
		if (subCap == TSS_TCSCAP_TRANS_EXCLUSIVE || subCap == 0) {
			*respSize = sizeof(TSS_BOOL);
			if ((*resp = malloc(sizeof(TSS_BOOL))) == NULL) {
				LogError("malloc of %zd byte failed.", sizeof(TSS_BOOL));
				return TCSERR(TSS_E_OUTOFMEMORY);
			}

			if (subCap == TSS_TCSCAP_TRANS_EXCLUSIVE)
				*(TSS_BOOL *)(*resp) = config->exclusive_transport ? TRUE : FALSE;
			else
				*(TSS_BOOL *)(*resp) = TRUE;
		} else {
			LogDebugFn("Bad subcap");
			return TCSERR(TSS_E_BAD_PARAMETER);
		}
		break;
	case TSS_TCSCAP_PLATFORM_CLASS:
		LogDebug("TSS_TCSCAP_PLATFORM_CLASS");

		switch (subCap) {
		case TSS_TCSCAP_PROP_HOST_PLATFORM:
			/* Return the TSS_PLATFORM_CLASS */
			LogDebugFn("TSS_TCSCAP_PROP_HOST_PLATFORM");
			platClass = config->host_platform_class;
			/* Computes the size of host platform structure */
			*respSize = (2 * sizeof(UINT32)) + platClass->classURISize;
			*resp = malloc(*respSize);
			if (*resp == NULL) {
				LogError("malloc of %u bytes failed.", *respSize);
				return TCSERR(TSS_E_OUTOFMEMORY);
			}
			memset(*resp, 0, *respSize);
			offset = 0;
			LoadBlob_UINT32(&offset, platClass->simpleID, *resp);
			LoadBlob_UINT32(&offset, platClass->classURISize, *resp);
			memcpy(&(*resp)[offset], platClass->classURI, platClass->classURISize);
			LogBlob(*respSize, *resp);
			break;
		case TSS_TCSCAP_PROP_ALL_PLATFORMS:
			/* Return an array of TSS_PLATFORM_CLASSes, when existent */
			LogDebugFn("TSS_TCSCAP_PROP_ALL_PLATFORMS");
			*respSize = 0;
			*resp = NULL;
			if ((platClass = config->all_platform_classes) != NULL) {
				/* Computes the size of all Platform Structures */
				while (platClass != NULL) {
					*respSize += (2 * sizeof(UINT32)) + platClass->classURISize;
					platClass = platClass->next;
				}
				*resp = malloc(*respSize);
				if (*resp == NULL) {
					LogError("malloc of %u bytes failed.", *respSize);
					return TCSERR(TSS_E_OUTOFMEMORY);
				}
				memset(*resp, 0, *respSize);
				offset = 0;
				/* Concatenates all the structures on the BYTE * resp */
				platClass = config->all_platform_classes;
				while (platClass != NULL){
					LoadBlob_UINT32(&offset, platClass->simpleID, *resp);
					LoadBlob_UINT32(&offset, platClass->classURISize, *resp);
					memcpy(&(*resp)[offset], platClass->classURI,
					       platClass->classURISize);
					offset += platClass->classURISize;
					platClass = platClass->next;
				}
				LogBlob(*respSize, *resp);
			}
			break;
		default:
			LogDebugFn("Bad subcap");
			return TCSERR(TSS_E_BAD_PARAMETER);
		}
		break;
	default:
		LogDebugFn("Bad cap area");
		return TCSERR(TSS_E_BAD_PARAMETER);
	}

	return TSS_SUCCESS;
}

TSS_RESULT
TCS_GetCapability_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			   TCPA_CAPABILITY_AREA capArea,	/* in */
			   UINT32 subCapSize,	/* in */
			   BYTE * subCap,	/* in */
			   UINT32 * respSize,	/* out */
			   BYTE ** resp	/* out */
    )
{
	TSS_RESULT result;
	UINT32 ulSubCap;

	if ((result = ctx_verify_context(hContext)))
		return result;

	if (subCapSize == sizeof(UINT32))
		ulSubCap = *(UINT32 *)subCap;
	else if (subCapSize == 0)
		ulSubCap = 0;
	else
		return TCSERR(TSS_E_BAD_PARAMETER);

	return internal_TCSGetCap(hContext, capArea, ulSubCap, respSize, resp);
}



<|start_filename|>src/tspi/tsp_key.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */


#include <stdlib.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


void
free_key_refs(TSS_KEY *key)
{
	free(key->algorithmParms.parms);
	key->algorithmParms.parms = NULL;
	key->algorithmParms.parmSize = 0;

	free(key->pubKey.key);
	key->pubKey.key = NULL;
	key->pubKey.keyLength = 0;

	free(key->encData);
	key->encData = NULL;
	key->encSize = 0;

	free(key->PCRInfo);
	key->PCRInfo = NULL;
	key->PCRInfoSize = 0;
}

void
LoadBlob_TSS_KEY(UINT64 *offset, BYTE *blob, TSS_KEY *key)
{
	if (key->hdr.key12.tag == TPM_TAG_KEY12)
		Trspi_LoadBlob_KEY12(offset, blob, (TPM_KEY12 *)key);
	else
		Trspi_LoadBlob_KEY(offset, blob, (TCPA_KEY *)key);
}

TSS_RESULT
UnloadBlob_TSS_KEY(UINT64 *offset, BYTE *blob, TSS_KEY *key)
{
	UINT16 tag;
	UINT64 keyOffset = *offset;
	TSS_RESULT result;

	Trspi_UnloadBlob_UINT16(&keyOffset, &tag, blob);
	if (tag == TPM_TAG_KEY12)
		result = Trspi_UnloadBlob_KEY12(offset, blob, (TPM_KEY12 *)key);
	else
		result = Trspi_UnloadBlob_KEY(offset, blob, (TCPA_KEY *)key);

	return result;
}

TSS_RESULT
Hash_TSS_KEY(Trspi_HashCtx *c, TSS_KEY *key)
{
	TSS_RESULT result;

	if (key->hdr.key12.tag == TPM_TAG_KEY12)
		result = Trspi_Hash_KEY12(c, (TPM_KEY12 *)key);
	else
		result = Trspi_Hash_KEY(c, (TCPA_KEY *)key);

	return result;
}

void
LoadBlob_TSS_PRIVKEY_DIGEST(UINT64 *offset, BYTE *blob, TSS_KEY *key)
{
	if (key->hdr.key12.tag == TPM_TAG_KEY12)
		Trspi_LoadBlob_PRIVKEY_DIGEST12(offset, blob, (TPM_KEY12 *)key);
	else
		Trspi_LoadBlob_PRIVKEY_DIGEST(offset, blob, (TCPA_KEY *)key);
}

TSS_RESULT
Hash_TSS_PRIVKEY_DIGEST(Trspi_HashCtx *c, TSS_KEY *key)
{
	TSS_RESULT result;

	if (key->hdr.key12.tag == TPM_TAG_KEY12)
		result = Trspi_Hash_PRIVKEY_DIGEST12(c, (TPM_KEY12 *)key);
	else
		result = Trspi_Hash_PRIVKEY_DIGEST(c, (TCPA_KEY *)key);

	return result;
}

#ifdef TSS_BUILD_TRANSPORT
TSS_RESULT
Transport_EvictKey(TSS_HCONTEXT tspContext,
		   TCS_KEY_HANDLE hKey)
{
	TSS_RESULT result;
	UINT32 handlesLen;
	TCS_HANDLE *handles, handle;
	TPM_DIGEST pubKeyHash;
	Trspi_HashCtx hashCtx;


	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest)))
		return result;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
		return result;

	handlesLen = 1;
	handle = hKey;
	handles = &handle;

	result = obj_context_transport_execute(tspContext, TPM_ORD_EvictKey, 0, NULL, &pubKeyHash,
					       &handlesLen, &handles, NULL, NULL, NULL, NULL);

	return result;
}

TSS_RESULT
Transport_GetPubKey(TSS_HCONTEXT tspContext,
		    TCS_KEY_HANDLE hKey,
		    TPM_AUTH *pAuth,
		    UINT32 *pcPubKeySize,
		    BYTE **prgbPubKey)
{
	TSS_RESULT result;
	UINT32 handlesLen, decLen;
	TCS_HANDLE *handles, handle;
	BYTE *dec = NULL;
	TPM_DIGEST pubKeyHash;
	Trspi_HashCtx hashCtx;


	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest)))
		return result;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
		return result;

	handlesLen = 1;
	handle = hKey;
	handles = &handle;

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_GetPubKey, 0, NULL,
						    &pubKeyHash, &handlesLen, &handles, pAuth, NULL,
						    &decLen, &dec)))
		return result;

	*prgbPubKey = dec;
	*pcPubKeySize = decLen;

	return result;
}

TSS_RESULT
Transport_CreateWrapKey(TSS_HCONTEXT tspContext,	/* in */
			TCS_KEY_HANDLE hWrappingKey,	/* in */
			TPM_ENCAUTH *KeyUsageAuth,	/* in */
			TPM_ENCAUTH *KeyMigrationAuth,	/* in */
			UINT32 keyInfoSize,		/* in */
			BYTE * keyInfo,			/* in */
			UINT32 * keyDataSize,		/* out */
			BYTE ** keyData,		/* out */
			TPM_AUTH * pAuth)		/* in, out */
{
	TSS_RESULT result;
	UINT32 handlesLen, decLen;
	TCS_HANDLE *handles, handle;
	BYTE *dec = NULL;
	TPM_DIGEST pubKeyHash;
	Trspi_HashCtx hashCtx;
	UINT64 offset;
	BYTE *data;


	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	if ((result = obj_tcskey_get_pubkeyhash(hWrappingKey, pubKeyHash.digest)))
		return result;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
		return result;

	handlesLen = 1;
	handle = hWrappingKey;
	handles = &handle;

	if ((data = malloc(2 * sizeof(TPM_ENCAUTH) + keyInfoSize)) == NULL) {
		LogError("malloc of %zd bytes failed", 2 * sizeof(TPM_ENCAUTH) + keyInfoSize);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	offset = 0;
	Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, KeyUsageAuth->authdata);
	Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, KeyMigrationAuth->authdata);
	Trspi_LoadBlob(&offset, keyInfoSize, data, keyInfo);

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_CreateWrapKey,
						    (2 * sizeof(TPM_ENCAUTH) + keyInfoSize), data,
						    &pubKeyHash, &handlesLen, &handles, pAuth, NULL,
						    &decLen, &dec)))
		goto done;

	*keyDataSize = decLen;
	*keyData = dec;
done:
	free(data);

	return result;
}

TSS_RESULT
Transport_LoadKeyByBlob(TSS_HCONTEXT     tspContext,
			TCS_KEY_HANDLE   hParentKey,
			UINT32           ulBlobLength,
			BYTE*            rgbBlobData,
			TPM_AUTH*        pAuth,
			TCS_KEY_HANDLE*  phKey,
			TPM_KEY_HANDLE*  phSlot)
{
	TSS_RESULT result;
	UINT32 handlesLen, decLen;
	TCS_HANDLE *handles, handle;
	BYTE *dec = NULL;
	TPM_DIGEST pubKeyHash;
	Trspi_HashCtx hashCtx;


	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	if ((result = obj_tcskey_get_pubkeyhash(hParentKey, pubKeyHash.digest)))
		return result;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
		return result;

	handlesLen = 1;
	handle = hParentKey;
	handles = &handle;

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_LoadKey2, ulBlobLength,
						    rgbBlobData, &pubKeyHash, &handlesLen,
						    &handles, pAuth, NULL, &decLen, &dec)))
		return result;

	if (handlesLen == 1)
		*phKey = *(TCS_KEY_HANDLE *)handles;
	else
		result = TSPERR(TSS_E_INTERNAL_ERROR);

	free(dec);

	return result;
}

/* This function both encrypts the handle of the pubkey being requested and requires the hash
 * of that pubkey for the transport log when logging is enabled. */
TSS_RESULT
Transport_OwnerReadInternalPub(TSS_HCONTEXT tspContext,   /* in */
			       TCS_KEY_HANDLE hKey,           /* in */
			       TPM_AUTH* pOwnerAuth,          /* in, out */
			       UINT32* punPubKeySize, /* out */
			       BYTE** ppbPubKeyData)          /* out */
{
	UINT64 offset;
	TSS_RESULT result;
	UINT32 handlesLen = 0, decLen;
	TPM_DIGEST pubKeyHash;
	Trspi_HashCtx hashCtx;
	BYTE *dec = NULL, data[sizeof(TCS_KEY_HANDLE)];


	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest)))
		return result;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
		return result;

	offset = 0;
	Trspi_LoadBlob_UINT32(&offset, hKey, data);

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_OwnerReadInternalPub,
						    sizeof(data), data, &pubKeyHash, &handlesLen,
						    NULL, pOwnerAuth, NULL, &decLen, &dec)))
		return result;

	*punPubKeySize = decLen;
	*ppbPubKeyData = dec;

	return result;
}
#endif



<|start_filename|>src/include/obj.h<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */

#ifndef _OBJ_H_
#define _OBJ_H_

#include "threads.h"

/* definitions */

/* When TRUE, the object has PCRs associated with it */
#define TSS_OBJ_FLAG_PCRS	0x00000001
/* When TRUE, the object has a usage auth secret associated with it */
#define TSS_OBJ_FLAG_USAGEAUTH	0x00000002
/* When TRUE, the object has a migration auth secret associated with it */
#define TSS_OBJ_FLAG_MIGAUTH	0x00000004
/* When TRUE, the object has previously been registered in USER PS */
#define TSS_OBJ_FLAG_USER_PS	0x00000008
/* When TRUE, the object has previously been registered in SYSTEM PS */
#define TSS_OBJ_FLAG_SYSTEM_PS	0x00000010
/* When TRUE, the key has been created and cannot be altered */
#define TSS_OBJ_FLAG_KEY_SET	0x00000020

/* structures */
struct tsp_object {
	UINT32 handle;
	UINT32 tspContext;
	TSS_FLAG flags;
	void *data;
	struct tsp_object *next;
};

struct obj_list {
	struct tsp_object *head;
	MUTEX_DECLARE(lock);
};

/* prototypes */
TSS_RESULT	   obj_getTpmObject(UINT32, TSS_HOBJECT *);
TSS_HOBJECT	   obj_GetPolicyOfObject(UINT32, UINT32);
void		   __tspi_obj_list_init();
TSS_HOBJECT	   obj_get_next_handle();
TSS_RESULT	   obj_list_add(struct obj_list *, UINT32, TSS_FLAG, void *, TSS_HOBJECT *);
TSS_RESULT	   obj_list_remove(struct obj_list *, void (*)(void *), TSS_HOBJECT, TSS_HCONTEXT);
void		   obj_list_put(struct obj_list *);
struct tsp_object *obj_list_get_obj(struct obj_list *, UINT32);
struct tsp_object *obj_list_get_tspcontext(struct obj_list *, UINT32);
void		   obj_list_close(struct obj_list *, void (*)(void *), TSS_HCONTEXT);
void		   obj_connectContext(TSS_HCONTEXT, TCS_CONTEXT_HANDLE);
void		   obj_close_context(TSS_HCONTEXT);
void               obj_lists_remove_policy_refs(TSS_HPOLICY, TSS_HCONTEXT);

/* prototypes for functions that may traverse more than one list */
TSS_RESULT	   obj_tcskey_get_pubkeyhash(TCS_KEY_HANDLE, BYTE *);

#include "obj_tpm.h"
#include "obj_context.h"
#include "obj_hash.h"
#include "obj_pcrs.h"
#include "obj_policy.h"
#include "obj_rsakey.h"
#include "obj_encdata.h"
#include "obj_daacred.h"
#include "obj_daaarakey.h"
#include "obj_daaissuerkey.h"
#include "obj_nv.h"
#include "obj_delfamily.h"
#include "obj_migdata.h"


TPM_LIST_DECLARE_EXTERN;
CONTEXT_LIST_DECLARE_EXTERN;
HASH_LIST_DECLARE_EXTERN;
PCRS_LIST_DECLARE_EXTERN;
POLICY_LIST_DECLARE_EXTERN;
RSAKEY_LIST_DECLARE_EXTERN;
ENCDATA_LIST_DECLARE_EXTERN;
DAACRED_LIST_DECLARE_EXTERN;
DAAARAKEY_LIST_DECLARE_EXTERN;
DAAISSUERKEY_LIST_DECLARE_EXTERN;
NVSTORE_LIST_DECLARE_EXTERN;
DELFAMILY_LIST_DECLARE_EXTERN;
MIGDATA_LIST_DECLARE_EXTERN;

#endif


<|start_filename|>src/tcs/tcsi_seal.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcsps.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "req_mgr.h"
#include "tcsd_wrap.h"
#include "tcsd.h"

TSS_RESULT
TCSP_Seal_Internal(UINT32 sealOrdinal,		/* in */
		   TCS_CONTEXT_HANDLE hContext,	/* in */
		   TCS_KEY_HANDLE keyHandle,	/* in */
		   TCPA_ENCAUTH encAuth,	/* in */
		   UINT32 pcrInfoSize,	/* in */
		   BYTE * PcrInfo,	/* in */
		   UINT32 inDataSize,	/* in */
		   BYTE * inData,	/* in */
		   TPM_AUTH * pubAuth,	/* in, out */
		   UINT32 * SealedDataSize,	/* out */
		   BYTE ** SealedData)	/* out */
{
	UINT64 offset = 0;
	TSS_RESULT result;
	UINT32 paramSize;
	TCPA_KEY_HANDLE keySlot;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering Seal");
	if (!pubAuth)
		return TCSERR(TSS_E_BAD_PARAMETER);

	if ((result = ctx_verify_context(hContext)))
		goto done;

	if ((result = auth_mgr_check(hContext, &pubAuth->AuthHandle)))
		goto done;

	if ((result = ensureKeyIsLoaded(hContext, keyHandle, &keySlot)))
		goto done;

	/* XXX What's this check for? */
	if (keySlot == 0) {
		result = TCSERR(TSS_E_FAIL);
		goto done;
	}

	if ((result = tpm_rqu_build(sealOrdinal, &offset, txBlob, keySlot, encAuth.authdata,
				    pcrInfoSize, PcrInfo, inDataSize, inData, pubAuth)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	offset = 10;
	result = UnloadBlob_Header(txBlob, &paramSize);

	if (!result) {
		result = tpm_rsp_parse(sealOrdinal, txBlob, paramSize, SealedDataSize,
				       SealedData, pubAuth);
	}
	LogResult("Seal", result);
done:
	auth_mgr_release_auth(pubAuth, NULL, hContext);
	return result;
}

TSS_RESULT
TCSP_Unseal_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
		     TCS_KEY_HANDLE parentHandle,	/* in */
		     UINT32 SealedDataSize,	/* in */
		     BYTE * SealedData,	/* in */
		     TPM_AUTH * parentAuth,	/* in, out */
		     TPM_AUTH * dataAuth,	/* in, out */
		     UINT32 * DataSize,	/* out */
		     BYTE ** Data)	/* out */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	TCPA_KEY_HANDLE keySlot;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering Unseal");

	if (dataAuth == NULL)
		return TCSERR(TSS_E_BAD_PARAMETER);

	if ((result = ctx_verify_context(hContext)))
		goto done;

	if (parentAuth != NULL) {
		LogDebug("Auth used");
		if ((result = auth_mgr_check(hContext, &parentAuth->AuthHandle)))
			goto done;
	} else {
		LogDebug("No Auth");
	}

	if ((result = auth_mgr_check(hContext, &dataAuth->AuthHandle)))
		goto done;

	if ((result = ensureKeyIsLoaded(hContext, parentHandle, &keySlot)))
		goto done;

	/* XXX What's this check for? */
	if (keySlot == 0) {
		result = TCSERR(TSS_E_FAIL);
		goto done;
	}

	if ((result = tpm_rqu_build(TPM_ORD_Unseal, &offset, txBlob, keySlot, SealedDataSize,
				    SealedData, parentAuth, dataAuth)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	offset = 10;
	result = UnloadBlob_Header(txBlob, &paramSize);

	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_Unseal, txBlob, paramSize, DataSize, Data,
				       parentAuth, dataAuth);
	}
	LogResult("Unseal", result);
done:
	auth_mgr_release_auth(parentAuth, dataAuth, hContext);
	return result;
}


<|start_filename|>src/tcs/tcs_ps.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcsps.h"
#include "tcslog.h"
#include "tddl.h"
#include "req_mgr.h"
#include "tcsd_wrap.h"
#include "tcsd.h"


TSS_RESULT
get_vendor_data(struct key_disk_cache *d, UINT32 *size, BYTE **data)
{
	if (d->vendor_data_size == 0) {
		*size = 0;
		*data = NULL;

		return TSS_SUCCESS;
	}

	return ps_get_vendor_data(d, size, data);
}

TSS_RESULT
fill_key_info(struct key_disk_cache *d, struct key_mem_cache *m, TSS_KM_KEYINFO *key_info)
{
	BYTE tmp_blob[2048];
	UINT16 tmp_blob_size = 2048;
	TSS_KEY tmp_key;
	UINT64 offset;
	TSS_RESULT result;

	if (m == NULL) {
		key_info->fIsLoaded = FALSE;

		/* read key from disk */
		if ((result = ps_get_key_by_cache_entry(d, (BYTE *)&tmp_blob, &tmp_blob_size)))
			return result;

		offset = 0;
		/* XXX add a real context handle here */
		if ((result = UnloadBlob_TSS_KEY(&offset, tmp_blob, &tmp_key)))
			return result;

		if (tmp_key.hdr.key12.tag == TPM_TAG_KEY12) {
			key_info->versionInfo.bMajor = TSS_SPEC_MAJOR;
			key_info->versionInfo.bMinor = TSS_SPEC_MINOR;
			key_info->versionInfo.bRevMajor = 0;
			key_info->versionInfo.bRevMajor = 0;
		} else
			memcpy(&key_info->versionInfo, &tmp_key.hdr.key11.ver, sizeof(TSS_VERSION));
		memcpy(&key_info->bAuthDataUsage, &tmp_key.authDataUsage,
		       sizeof(TCPA_AUTH_DATA_USAGE));
		destroy_key_refs(&tmp_key);
	} else {
		if (m->tpm_handle == NULL_TPM_HANDLE)
			key_info->fIsLoaded = FALSE;
		else
			key_info->fIsLoaded = TRUE;

		if (m->blob->hdr.key12.tag == TPM_TAG_KEY12) {
			key_info->versionInfo.bMajor = TSS_SPEC_MAJOR;
			key_info->versionInfo.bMinor = TSS_SPEC_MINOR;
			key_info->versionInfo.bRevMajor = 0;
			key_info->versionInfo.bRevMajor = 0;
		} else
			memcpy(&key_info->versionInfo, &m->blob->hdr.key11.ver, sizeof(TSS_VERSION));
		memcpy(&key_info->bAuthDataUsage, &m->blob->authDataUsage,
		       sizeof(TCPA_AUTH_DATA_USAGE));
	}

	memcpy(&key_info->keyUUID, &d->uuid, sizeof(TSS_UUID));
	memcpy(&key_info->parentKeyUUID, &d->parent_uuid, sizeof(TSS_UUID));

	return get_vendor_data(d, &key_info->ulVendorDataLength, &key_info->rgbVendorData);
}

TSS_RESULT
fill_key_info2(struct key_disk_cache *d, struct key_mem_cache *m, TSS_KM_KEYINFO2 *key_info)
{
	BYTE tmp_blob[2048];
	UINT16 tmp_blob_size = 2048;
	TSS_KEY tmp_key;
	UINT64 offset;
	TSS_RESULT result;

	if (m == NULL) {
		key_info->fIsLoaded = FALSE;

		/* read key from disk */
		if ((result = ps_get_key_by_cache_entry(d, (BYTE *)&tmp_blob, &tmp_blob_size)))
			return result;

		offset = 0;
		/* XXX add a real context handle here */
		if ((result = UnloadBlob_TSS_KEY(&offset, tmp_blob, &tmp_key)))
			return result;

		if (tmp_key.hdr.key12.tag == TPM_TAG_KEY12) {
			key_info->versionInfo.bMajor = TSS_SPEC_MAJOR;
			key_info->versionInfo.bMinor = TSS_SPEC_MINOR;
			key_info->versionInfo.bRevMajor = 0;
			key_info->versionInfo.bRevMajor = 0;
		} else
			memcpy(&key_info->versionInfo, &tmp_key.hdr.key11.ver, sizeof(TSS_VERSION));
		memcpy(&key_info->bAuthDataUsage, &tmp_key.authDataUsage,
		       sizeof(TCPA_AUTH_DATA_USAGE));
		destroy_key_refs(&tmp_key);
	} else {
		if (m->tpm_handle == NULL_TPM_HANDLE)
			key_info->fIsLoaded = FALSE;
		else
			key_info->fIsLoaded = TRUE;

		if (m->blob->hdr.key12.tag == TPM_TAG_KEY12) {
			key_info->versionInfo.bMajor = TSS_SPEC_MAJOR;
			key_info->versionInfo.bMinor = TSS_SPEC_MINOR;
			key_info->versionInfo.bRevMajor = 0;
			key_info->versionInfo.bRevMajor = 0;
		} else
			memcpy(&key_info->versionInfo, &m->blob->hdr.key11.ver, sizeof(TSS_VERSION));
		memcpy(&key_info->bAuthDataUsage, &m->blob->authDataUsage,
		       sizeof(TCPA_AUTH_DATA_USAGE));
	}

	memcpy(&key_info->keyUUID, &d->uuid, sizeof(TSS_UUID));
	memcpy(&key_info->parentKeyUUID, &d->parent_uuid, sizeof(TSS_UUID));

	/* Fill the two new TSS_KM_KEYINFO2 fields here */
	key_info->persistentStorageTypeParent = d->flags & CACHE_FLAG_PARENT_PS_SYSTEM ?
						TSS_PS_TYPE_SYSTEM : TSS_PS_TYPE_USER;
	key_info->persistentStorageType = TSS_PS_TYPE_SYSTEM;

	return get_vendor_data(d, &key_info->ulVendorDataLength, &key_info->rgbVendorData);
}

TSS_RESULT
key_mgr_load_by_uuid(TCS_CONTEXT_HANDLE hContext,
		     TSS_UUID *uuid,
		     TCS_LOADKEY_INFO *pInfo,
		     TCS_KEY_HANDLE *phKeyTCSI)
{
	TSS_RESULT result;

	MUTEX_LOCK(mem_cache_lock);

	result = TCSP_LoadKeyByUUID_Internal(hContext, uuid, pInfo, phKeyTCSI);

	LogDebug("Key %s loaded by UUID w/ TCS handle: 0x%x",
		result ? "NOT" : "successfully", result ? 0 : *phKeyTCSI);

	MUTEX_UNLOCK(mem_cache_lock);

	return result;
}



<|start_filename|>src/tcs/tcsi_key.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "tcsps.h"
#include "req_mgr.h"


TSS_RESULT
TCSP_LoadKeyByBlob_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			    TCS_KEY_HANDLE hUnwrappingKey,	/* in */
			    UINT32 cWrappedKeyBlobSize,		/* in */
			    BYTE * rgbWrappedKeyBlob,		/* in */
			    TPM_AUTH * pAuth,			/* in, out */
			    TCS_KEY_HANDLE * phKeyTCSI,		/* out */
			    TCS_KEY_HANDLE * phKeyHMAC)		/* out */
{
	return LoadKeyByBlob_Internal(TPM_ORD_LoadKey, hContext, hUnwrappingKey,
				      cWrappedKeyBlobSize, rgbWrappedKeyBlob, pAuth, phKeyTCSI,
				      phKeyHMAC);
}

TSS_RESULT
TCSP_LoadKey2ByBlob_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			     TCS_KEY_HANDLE hUnwrappingKey,	/* in */
			     UINT32 cWrappedKeyBlobSize,	/* in */
			     BYTE * rgbWrappedKeyBlob,		/* in */
			     TPM_AUTH * pAuth,			/* in, out */
			     TCS_KEY_HANDLE * phKeyTCSI)	/* out */
{
	return LoadKeyByBlob_Internal(TPM_ORD_LoadKey2, hContext, hUnwrappingKey,
				      cWrappedKeyBlobSize, rgbWrappedKeyBlob, pAuth, phKeyTCSI,
				      NULL);
}

TSS_RESULT
LoadKeyByBlob_Internal(UINT32 ord,	/* The ordinal to use, LoadKey or LoadKey2 */
		       TCS_CONTEXT_HANDLE hContext,	/* in */
		       TCS_KEY_HANDLE hUnwrappingKey,	/* in */
		       UINT32 cWrappedKeyBlobSize,		/* in */
		       BYTE * rgbWrappedKeyBlob,		/* in */
		       TPM_AUTH * pAuth,			/* in, out */
		       TCS_KEY_HANDLE * phKeyTCSI,		/* out */
		       TCS_KEY_HANDLE * phKeyHMAC)		/* out */
{
	UINT64 offset;
	TSS_RESULT result;
	UINT32 paramSize;
	TPM_KEY_HANDLE parentSlot, newSlot;
	TCS_KEY_HANDLE newHandle = NULL_TCS_HANDLE;
	TSS_BOOL canLoad;
	TSS_KEY key;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	if ((result = ctx_verify_context(hContext)))
		return result;

	LogDebugFn("Enter");
	LogDebugUnrollKey(rgbWrappedKeyBlob);

	if ((result = get_slot(hContext, hUnwrappingKey, &parentSlot)))
		return result;

	offset = 0;
	memset(&key, 0, sizeof(TSS_KEY));
	if ((result = UnloadBlob_TSS_KEY(&offset, rgbWrappedKeyBlob, &key)))
		return result;

	if (!pAuth) {
		LogDebugFn("Checking if LoadKeyByBlob can be avoided by using existing key");

		if ((newHandle = mc_get_handle_by_pub(&key.pubKey, hUnwrappingKey))) {
			LogDebugFn("tcs key handle exists");

			newSlot = mc_get_slot_by_handle(newHandle);
			if (newSlot && (isKeyLoaded(newSlot) == TRUE)) {
				LogDebugFn("Don't need to reload this key.");
				*phKeyTCSI = newHandle;
				if (phKeyHMAC)
					*phKeyHMAC = newSlot;
				return TSS_SUCCESS;
			}
		}
	}

        LogDebugFn("calling canILoadThisKey");
	if ((result = canILoadThisKey(&(key.algorithmParms), &canLoad)))
		goto error;

	if (canLoad == FALSE) {
		LogDebugFn("calling evictFirstKey");
		/* Evict a key that isn't the parent */
		if ((result = evictFirstKey(hUnwrappingKey)))
			goto error;
	}

	offset = 0;
	if ((result = tpm_rqu_build(ord, &offset, txBlob, parentSlot, cWrappedKeyBlobSize,
				    rgbWrappedKeyBlob, pAuth, NULL)))
		goto error;

	LogDebugFn("Submitting request to the TPM");
	if ((result = req_mgr_submit_req(txBlob)))
		goto error;

	if ((result = UnloadBlob_Header(txBlob, &paramSize))) {
		LogDebugFn("UnloadBlob_Header failed: rc=0x%x", result);
		goto error;
	}

	if ((result = tpm_rsp_parse(ord, txBlob, paramSize, &newSlot, pAuth)))
		goto error;

	if ((result = load_key_final(hContext, hUnwrappingKey, &newHandle, rgbWrappedKeyBlob,
				     newSlot)))
		goto error;

	/* Setup the outHandles */
	*phKeyTCSI = newHandle;
	if (phKeyHMAC)
		*phKeyHMAC = newSlot;

	LogDebugFn("Key handles for loadKeyByBlob slot:%.8X tcshandle:%.8X", newSlot, newHandle);
error:
	auth_mgr_release_auth(pAuth, NULL, hContext);
	return result;
}

TSS_RESULT
TCSP_EvictKey_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
		       TCS_KEY_HANDLE hKey)		/* in */
{
	TSS_RESULT result;
	TCPA_KEY_HANDLE tpm_handle;

	if ((result = ctx_verify_context(hContext)))
		return result;

	tpm_handle = mc_get_slot_by_handle(hKey);
	if (tpm_handle == NULL_TPM_HANDLE)
		return TSS_SUCCESS;	/*let's call this success if the key is already evicted */

	if ((result = internal_EvictByKeySlot(tpm_handle)))
		return result;

	result = mc_set_slot_by_slot(tpm_handle, NULL_TPM_HANDLE);

	return result;
}

TSS_RESULT
TCSP_CreateWrapKey_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			    TCS_KEY_HANDLE hWrappingKey,	/* in */
			    TCPA_ENCAUTH KeyUsageAuth,		/* in */
			    TCPA_ENCAUTH KeyMigrationAuth,	/* in */
			    UINT32 keyInfoSize,			/* in */
			    BYTE * keyInfo,			/* in */
			    UINT32 * keyDataSize,		/* out */
			    BYTE ** keyData,			/* out */
			    TPM_AUTH * pAuth)			/* in, out */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	TCPA_KEY_HANDLE parentSlot;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering Create Wrap Key");

	if ((result = ctx_verify_context(hContext)))
		goto done;

	if (pAuth) {
		if ((result = auth_mgr_check(hContext, &pAuth->AuthHandle)))
			goto done;
	}

	/* Since hWrappingKey must already be loaded, we can fail immediately if
	 * mc_get_slot_by_handle_lock() fails.*/
	parentSlot = mc_get_slot_by_handle_lock(hWrappingKey);
	if (parentSlot == NULL_TPM_HANDLE) {
		result = TCSERR(TSS_E_FAIL);
		goto done;
	}

	if ((result = tpm_rqu_build(TPM_ORD_CreateWrapKey, &offset, txBlob, parentSlot,
				    KeyUsageAuth.authdata, KeyMigrationAuth.authdata, keyInfoSize,
				    keyInfo, pAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_CreateWrapKey, txBlob, paramSize, keyDataSize,
				       keyData, pAuth);
	}
	LogResult("Create Wrap Key", result);

done:
	auth_mgr_release_auth(pAuth, NULL, hContext);
	return result;
}

TSS_RESULT
TCSP_GetPubKey_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			TCS_KEY_HANDLE hKey,		/* in */
			TPM_AUTH * pAuth,		/* in, out */
			UINT32 * pcPubKeySize,		/* out */
			BYTE ** prgbPubKey)		/* out */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	TCPA_KEY_HANDLE keySlot;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering Get pub key");
	if ((result = ctx_verify_context(hContext)))
		goto done;

	if (pAuth != NULL) {
		LogDebug("Auth Used");
		if ((result = auth_mgr_check(hContext, &pAuth->AuthHandle)))
			goto done;
	} else {
		LogDebug("No Auth");
	}

	if (ensureKeyIsLoaded(hContext, hKey, &keySlot)) {
		result = TCSERR(TCS_E_KM_LOADFAILED);
		goto done;
	}

	LogDebug("GetPubKey: handle: 0x%x, slot: 0x%x", hKey, keySlot);
	if ((result = tpm_rqu_build(TPM_ORD_GetPubKey, &offset, txBlob, keySlot, pAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	offset = 10;
	result = UnloadBlob_Header(txBlob, &paramSize);

	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_GetPubKey, txBlob, paramSize, pcPubKeySize,
				       prgbPubKey, pAuth);
	}
	LogResult("Get Public Key", result);
done:
	auth_mgr_release_auth(pAuth, NULL, hContext);
	return result;
}

TSS_RESULT
TCSP_OwnerReadInternalPub_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
				   TCS_KEY_HANDLE hKey,	/* in */
				   TPM_AUTH * pOwnerAuth,	/* in, out */
				   UINT32 * punPubKeySize,	/* out */
				   BYTE ** ppbPubKeyData)	/* out */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering OwnerReadInternalPub");
	if ((result = ctx_verify_context(hContext)))
		goto done;

	LogDebug("OwnerReadInternalPub: handle: 0x%x", hKey);
	if (hKey != TPM_KH_SRK && hKey != TPM_KH_EK) {
		result = TCSERR(TSS_E_FAIL);
		LogDebug("OwnerReadInternalPub - Unsupported Key Handle");
		goto done;
	}

	if ((result = auth_mgr_check(hContext, &pOwnerAuth->AuthHandle)))
		goto done;

	if ((result = tpm_rqu_build(TPM_ORD_OwnerReadInternalPub, &offset, txBlob, hKey,
				    pOwnerAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_OwnerReadInternalPub, txBlob, paramSize,
				       punPubKeySize, ppbPubKeyData, pOwnerAuth);
	}
	LogResult("OwnerReadInternalPub", result);
done:
	auth_mgr_release_auth(pOwnerAuth, NULL, hContext);
	return result;
}

TSS_RESULT
TCSP_KeyControlOwner_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			      TCS_KEY_HANDLE hTcsKey,		/* in */
			      UINT32 ulPubKeyLength,		/* in */
			      BYTE* rgbPubKey,			/* in */
			      UINT32 attribName,		/* in */
			      TSS_BOOL attribValue,		/* in */
			      TPM_AUTH* pOwnerAuth,		/* in,out */
			      TSS_UUID* pUuidData)		/* out */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	TPM_KEY_HANDLE hTpmKey;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebugFn("Enter");
	if ((result = ctx_verify_context(hContext))) {
		LogDebug("Invalid TSS Context");
		goto done;
	}

	if ((result = get_slot_lite(hContext, hTcsKey, &hTpmKey))) {
		LogDebug("Can't get TPM Keyhandle for TCS key 0x%x", hTcsKey);
		goto done;
	}
	LogDebugFn("TCS hKey=0x%x, TPM hKey=0x%x", hTcsKey, hTpmKey);

	if ((result = auth_mgr_check(hContext, &pOwnerAuth->AuthHandle))) {
		LogDebug("Owner Authentication failed");
		goto done;
	}

	if ((result = mc_find_next_ownerevict_uuid(pUuidData))) {
		LogDebugFn("mc_find_next_ownerevict_uuid failed: rc=0x%x", result);
		goto done;
	}

	if ((result = tpm_rqu_build(TPM_ORD_KeyControlOwner, &offset, txBlob, hTpmKey,
				    ulPubKeyLength, rgbPubKey, attribName, attribValue,
				    pOwnerAuth))) {
		LogDebugFn("rqu build failed");
		goto done;
	}

	if ((result = req_mgr_submit_req(txBlob))) {
	        LogDebugFn("Request submission failed");
		goto done;
	}

	if ((result = UnloadBlob_Header(txBlob, &paramSize))) {
		LogDebugFn("UnloadBlob_Header failed: rc=0x%x", result);
		goto done;
	}

	if ((result = tpm_rsp_parse(TPM_ORD_KeyControlOwner, txBlob, paramSize, pOwnerAuth))) {
		LogDebugFn("tpm_rsp_parse failed: rc=0x%x", result);
		goto done;
	}

	if ((result = mc_set_uuid(hTcsKey, pUuidData))){
		LogDebugFn("mc_set_uuid failed: rc=0x%x", result);
		goto done;
	}

	LogResult("KeyControlOwner", result);
done:
	auth_mgr_release_auth(pOwnerAuth, NULL, hContext);
	return result;
}



<|start_filename|>src/tspi/tsp_random.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004, 2007
 *
 */


#include <stdlib.h>
#include <syslog.h>
#include <unistd.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "tsplog.h"
#include "obj.h"


#ifdef TSS_BUILD_TRANSPORT
TSS_RESULT
Transport_GetRandom(TSS_HCONTEXT tspContext,	/* in */
		    UINT32 bytesRequested,	/* in */
		    BYTE ** randomBytes)	/* out */
{
	TSS_RESULT result;
        UINT32 decLen = 0;
        BYTE *dec = NULL;
        UINT64 offset;
	TCS_HANDLE handlesLen = 0;
        BYTE data[sizeof(UINT32)];

	if ((result = obj_context_transport_init(tspContext)))
		return result;

        LogDebugFn("Executing in a transport session");

        offset = 0;
        Trspi_LoadBlob_UINT32(&offset, bytesRequested, data);

        if ((result = obj_context_transport_execute(tspContext, TPM_ORD_GetRandom, sizeof(data),
                                                    data, NULL, &handlesLen, NULL, NULL, NULL,
						    &decLen, &dec)))
                return result;

	*randomBytes = dec;

        return result;

}

TSS_RESULT
Transport_StirRandom(TSS_HCONTEXT tspContext,	/* in */
		     UINT32 inDataSize,	/* in */
		     BYTE * inData)	/* in */
{
	TSS_RESULT result;
        UINT64 offset;
	UINT32 dataLen;
	TCS_HANDLE handlesLen = 0;
        BYTE *data;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

        LogDebugFn("Executing in a transport session");

	dataLen = sizeof(UINT32) + inDataSize;
	if ((data = malloc(dataLen)) == NULL) {
                LogError("malloc of %u bytes failed", dataLen);
                return TSPERR(TSS_E_OUTOFMEMORY);
	}

        offset = 0;
        Trspi_LoadBlob_UINT32(&offset, inDataSize, data);
        Trspi_LoadBlob(&offset, inDataSize, data, inData);

	result = obj_context_transport_execute(tspContext, TPM_ORD_StirRandom, dataLen, data, NULL,
					       &handlesLen, NULL, NULL, NULL, NULL, NULL);
	free(data);

	return result;
}
#endif



<|start_filename|>src/tspi/tspi_pcr_comp.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"

TSS_RESULT
Tspi_PcrComposite_SetPcrValue(TSS_HPCRS hPcrComposite,	/* in */
			      UINT32 ulPcrIndex,	/* in */
			      UINT32 ulPcrValueLength,	/* in */
			      BYTE * rgbPcrValue)	/* in */
{
	if (ulPcrValueLength == 0 || rgbPcrValue == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if (ulPcrValueLength != TCPA_SHA1_160_HASH_LEN)
		return TSPERR(TSS_E_BAD_PARAMETER);

	return obj_pcrs_set_value(hPcrComposite, ulPcrIndex, ulPcrValueLength, rgbPcrValue);
}

TSS_RESULT
Tspi_PcrComposite_GetPcrValue(TSS_HPCRS hPcrComposite,		/* in */
			      UINT32 ulPcrIndex,		/* in */
			      UINT32 * pulPcrValueLength,	/* out */
			      BYTE ** prgbPcrValue)		/* out */
{
	if (pulPcrValueLength == NULL || prgbPcrValue == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	return obj_pcrs_get_value(hPcrComposite, ulPcrIndex, pulPcrValueLength,
					prgbPcrValue);

}

TSS_RESULT
Tspi_PcrComposite_SelectPcrIndex(TSS_HPCRS hPcrComposite,	/* in */
				 UINT32 ulPcrIndex)		/* in */
{
	return obj_pcrs_select_index(hPcrComposite, ulPcrIndex);
}


<|start_filename|>src/tspi/tspi_hash.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


TSS_RESULT
Tspi_Hash_SetHashValue(TSS_HHASH hHash,			/* in */
		       UINT32 ulHashValueLength,	/* in */
		       BYTE * rgbHashValue)		/* in */
{
	if (ulHashValueLength == 0 || rgbHashValue == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	return obj_hash_set_value(hHash, ulHashValueLength, rgbHashValue);
}

TSS_RESULT
Tspi_Hash_GetHashValue(TSS_HHASH hHash,			/* in */
		       UINT32 * pulHashValueLength,	/* out */
		       BYTE ** prgbHashValue)		/* out */
{
	if (pulHashValueLength == NULL || prgbHashValue == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	return obj_hash_get_value(hHash, pulHashValueLength, prgbHashValue);
}

TSS_RESULT
Tspi_Hash_UpdateHashValue(TSS_HHASH hHash,	/* in */
			  UINT32 ulDataLength,	/* in */
			  BYTE *rgbData)	/* in */
{
	if (rgbData == NULL && ulDataLength != 0)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if (ulDataLength == 0)
		return TSS_SUCCESS;

	return obj_hash_update_value(hHash, ulDataLength, rgbData);
}


<|start_filename|>src/tspi/tsp_admin.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2007
 *
 */


#include <stdlib.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


#ifdef TSS_BUILD_TRANSPORT
TSS_RESULT
Transport_GetCapabilityOwner(TSS_HCONTEXT tspContext,      /* in */
			     TPM_AUTH * pOwnerAuth,        /* in/out */
			     TCPA_VERSION * pVersion,      /* out */
			     UINT32 * pNonVolatileFlags,   /* out */
			     UINT32 * pVolatileFlags)      /* out */
{
	UINT64 offset;
	TSS_RESULT result;
	UINT32 handlesLen = 0, decLen;
	BYTE *dec;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_GetCapabilityOwner, 0, NULL,
						    NULL, &handlesLen, NULL, pOwnerAuth, NULL,
						    &decLen, &dec)))
		return result;

	offset = 0;
	Trspi_UnloadBlob_TCPA_VERSION(&offset, dec, pVersion);
	Trspi_UnloadBlob_UINT32(&offset, pNonVolatileFlags, dec);
	Trspi_UnloadBlob_UINT32(&offset, pVolatileFlags, dec);

	free(dec);

	return result;
}

TSS_RESULT
Transport_SetOwnerInstall(TSS_HCONTEXT tspContext, /* in */
			  TSS_BOOL state)  /* in */
{
	TSS_RESULT result;
	UINT32 handlesLen = 0;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	result = obj_context_transport_execute(tspContext, TPM_ORD_SetOwnerInstall,
					       sizeof(TSS_BOOL), (BYTE *)&state, NULL, &handlesLen,
					       NULL, NULL, NULL, NULL, NULL);

	return result;
}

TSS_RESULT
Transport_DisableOwnerClear(TSS_HCONTEXT tspContext,       /* in */
			    TPM_AUTH * ownerAuth)  /* in, out */
{
	TSS_RESULT result;
	UINT32 handlesLen = 0;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	result = obj_context_transport_execute(tspContext, TPM_ORD_DisableOwnerClear, 0, NULL, NULL,
					       &handlesLen, NULL, ownerAuth, NULL, NULL, NULL);

	return result;
}

TSS_RESULT
Transport_DisableForceClear(TSS_HCONTEXT tspContext)       /* in */
{
	TSS_RESULT result;
	UINT32 handlesLen = 0;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	result = obj_context_transport_execute(tspContext, TPM_ORD_DisableForceClear, 0, NULL, NULL,
					       &handlesLen, NULL, NULL, NULL, NULL, NULL);

	return result;
}

TSS_RESULT
Transport_OwnerSetDisable(TSS_HCONTEXT tspContext, /* in */
			  TSS_BOOL disableState,   /* in */
			  TPM_AUTH * ownerAuth)    /* in, out */
{
	TSS_RESULT result;
	UINT32 handlesLen = 0;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	result = obj_context_transport_execute(tspContext, TPM_ORD_OwnerSetDisable,
					       sizeof(TSS_BOOL), (BYTE *)&disableState, NULL,
					       &handlesLen, NULL, ownerAuth, NULL, NULL, NULL);

	return result;
}

TSS_RESULT
Transport_PhysicalDisable(TSS_HCONTEXT tspContext) /* in */
{
	TSS_RESULT result;
	UINT32 handlesLen = 0;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	result = obj_context_transport_execute(tspContext, TPM_ORD_PhysicalDisable, 0, NULL, NULL,
					       &handlesLen, NULL, NULL, NULL, NULL, NULL);

	return result;
}

TSS_RESULT
Transport_PhysicalEnable(TSS_HCONTEXT tspContext)  /* in */
{
	TSS_RESULT result;
	UINT32 handlesLen = 0;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	result = obj_context_transport_execute(tspContext, TPM_ORD_PhysicalEnable, 0, NULL, NULL,
					       &handlesLen, NULL, NULL, NULL, NULL, NULL);

	return result;
}

TSS_RESULT
Transport_PhysicalSetDeactivated(TSS_HCONTEXT tspContext,  /* in */
				 TSS_BOOL state)   /* in */
{
	TSS_RESULT result;
	UINT32 handlesLen = 0;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	result = obj_context_transport_execute(tspContext, TPM_ORD_PhysicalSetDeactivated,
					       sizeof(TSS_BOOL), (BYTE *)&state, NULL, &handlesLen,
					       NULL, NULL, NULL, NULL, NULL);

	return result;
}

TSS_RESULT
Transport_SetTempDeactivated(TSS_HCONTEXT tspContext)      /* in */
{
	TSS_RESULT result;
	UINT32 handlesLen = 0;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	result = obj_context_transport_execute(tspContext, TPM_ORD_SetTempDeactivated, 0, NULL,
					       NULL, &handlesLen, NULL, NULL, NULL, NULL, NULL);

	return result;
}

TSS_RESULT
Transport_SetTempDeactivated2(TSS_HCONTEXT tspContext,     /* in */
			      TPM_AUTH *operatorAuth)      /* in, out */
{
	TSS_RESULT result;
	UINT32 handlesLen = 0;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	result = obj_context_transport_execute(tspContext, TPM_ORD_SetTempDeactivated, 0, NULL,
					       NULL, &handlesLen, NULL, operatorAuth, NULL, NULL,
					       NULL);

	return result;
}

TSS_RESULT
Transport_DisablePubekRead(TSS_HCONTEXT tspContext,        /* in */
			   TPM_AUTH * ownerAuth)   /* in, out */
{
	TSS_RESULT result;
	UINT32 handlesLen = 0;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	result = obj_context_transport_execute(tspContext, TPM_ORD_DisablePubekRead, 0, NULL, NULL,
					       &handlesLen, NULL, ownerAuth, NULL, NULL, NULL);

	return result;
}

TSS_RESULT
Transport_ResetLockValue(TSS_HCONTEXT tspContext,  /* in */
			 TPM_AUTH * ownerAuth)     /* in, out */
{
	TSS_RESULT result;
	UINT32 handlesLen = 0;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	result = obj_context_transport_execute(tspContext, TPM_ORD_ResetLockValue, 0, NULL, NULL,
					       &handlesLen, NULL, ownerAuth, NULL, NULL, NULL);

	return result;
}

TSS_RESULT
Transport_PhysicalPresence(TSS_HCONTEXT tspContext,        /* in */
			   TCPA_PHYSICAL_PRESENCE fPhysicalPresence)       /* in */
{
	TSS_RESULT result;
	UINT32 handlesLen = 0;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	result = obj_context_transport_execute(tspContext, TSC_ORD_PhysicalPresence,
					       sizeof(TCPA_PHYSICAL_PRESENCE),
					       (BYTE *)&fPhysicalPresence, NULL, &handlesLen, NULL,
					       NULL, NULL, NULL, NULL);

	return result;
}

TSS_RESULT
Transport_FlushSpecific(TSS_HCONTEXT tspContext, /* in */
			TCS_HANDLE hResHandle, /* in */
			TPM_RESOURCE_TYPE resourceType) /* in */
{
	UINT64 offset;
	TSS_RESULT result;
	UINT32 handlesLen = 1;
	TCS_HANDLE *handles, handle;
	BYTE data[sizeof(UINT32)];

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	handle = hResHandle;
	handles = &handle;

	offset = 0;
	Trspi_LoadBlob_UINT32(&offset, resourceType, data);

	result = obj_context_transport_execute(tspContext, TPM_ORD_FlushSpecific, sizeof(data),
					       data, NULL, &handlesLen, &handles, NULL, NULL, NULL,
					       NULL);

	return result;
}
#endif



<|start_filename|>src/tcs/tcsi_sign.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcsps.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "req_mgr.h"
#include "tcsd_wrap.h"
#include "tcsd.h"


TSS_RESULT
TCSP_Sign_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
		   TCS_KEY_HANDLE keyHandle,	/* in */
		   UINT32 areaToSignSize,	/* in */
		   BYTE * areaToSign,	/* in */
		   TPM_AUTH * privAuth,	/* in, out */
		   UINT32 * sigSize,	/* out */
		   BYTE ** sig	/* out */
    )
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	TCPA_KEY_HANDLE keySlot;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering Sign");
	if ((result = ctx_verify_context(hContext)))
		return result;

	if (privAuth != NULL) {
		LogDebug("Auth Used");
		if ((result = auth_mgr_check(hContext, &privAuth->AuthHandle)))
			goto done;
	} else {
		LogDebug("No Auth");
	}

	if ((result = ensureKeyIsLoaded(hContext, keyHandle, &keySlot)))
		goto done;

	if ((result = tpm_rqu_build(TPM_ORD_Sign, &offset, txBlob, keySlot, areaToSignSize,
				    areaToSign, privAuth)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_Sign, txBlob, paramSize, sigSize, sig, privAuth,
				       NULL);
	}
	LogResult("sign", result);
done:
	auth_mgr_release_auth(privAuth, NULL, hContext);
	return result;
}



<|start_filename|>src/include/capabilities.h<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */

#ifndef _CAPABILITIES_H_
#define _CAPABILITIES_H_

/* This header has all of the software capabilities that are returned either via
 * Tspi_Context_GetCapability or TCS_GetCapability.
 */

/* TSP */
/* BOOL */
#define INTERNAL_CAP_TSP_ALG_RSA		TRUE
#define INTERNAL_CAP_TSP_ALG_SHA		TRUE
#define INTERNAL_CAP_TSP_ALG_3DES		FALSE
#define INTERNAL_CAP_TSP_ALG_DES		FALSE
#define INTERNAL_CAP_TSP_ALG_HMAC		TRUE
#define INTERNAL_CAP_TSP_ALG_AES		TRUE
#define INTERNAL_CAP_TSP_PERSSTORAGE		TRUE

/* UINT32 */
#define INTERNAL_CAP_TSP_ALG_DEFAULT		TSS_ALG_RSA
#define INTERNAL_CAP_TSP_ALG_DEFAULT_SIZE	TSS_KEY_SIZEVAL_2048BIT

/* 1 indicates byte-stream return values, 0 indicates ASN.1 encoded return values */
#define INTERNAL_CAP_TSP_RETURNVALUE_INFO	1

/* 0 is unknown platform version/type. Currently the spec is too vague on possible values for this
 * information to define anything here. */
#define INTERNAL_CAP_TSP_PLATFORM_VERSION	0
#define INTERNAL_CAP_TSP_PLATFORM_TYPE		0

/* TCS */
/* BOOL */
#define INTERNAL_CAP_TCS_ALG_RSA		FALSE
#define INTERNAL_CAP_TCS_ALG_AES		FALSE
#define INTERNAL_CAP_TCS_ALG_3DES		FALSE
#define INTERNAL_CAP_TCS_ALG_DES		FALSE
#define INTERNAL_CAP_TCS_ALG_SHA		TRUE
#define INTERNAL_CAP_TCS_ALG_HMAC		FALSE
#define INTERNAL_CAP_TCS_PERSSTORAGE		TRUE
#define INTERNAL_CAP_TCS_CACHING_KEYCACHE	FALSE
#define INTERNAL_CAP_TCS_CACHING_AUTHCACHE	TRUE

/* UINT32 */
#define INTERNAL_CAP_TCS_ALG_DEFAULT		TSS_ALG_RSA
#define INTERNAL_CAP_TCS_ALG_DEFAULT_SIZE	TSS_KEY_SIZEVAL_2048BIT

/* Common between both TSP and TCS */
#define INTERNAL_CAP_VERSION			{ 1, 2, TSS_VER_MAJOR, TSS_VER_MINOR }

#define INTERNAL_CAP_MANUFACTURER_ID		0x49424D00
#define INTERNAL_CAP_MANUFACTURER_STR		{ 'I', 0, 'B', 0, 'M', 0, 0, 0 }
#define INTERNAL_CAP_MANUFACTURER_STR_LEN	8

#endif


<|start_filename|>src/tcs/tcsi_tick.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "tcsps.h"
#include "req_mgr.h"


TSS_RESULT
TCSP_ReadCurrentTicks_Internal(TCS_CONTEXT_HANDLE hContext,
			       UINT32*            pulCurrentTime,
			       BYTE**             prgbCurrentTime)
{
	TSS_RESULT result;
	UINT32 paramSize;
	UINT64 offset = 0;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_GetTicks, &offset, txBlob, NULL)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result)
		result = tpm_rsp_parse(TPM_ORD_GetTicks, txBlob, paramSize, pulCurrentTime,
				       prgbCurrentTime, NULL);

done:
	return result;
}

TSS_RESULT
TCSP_TickStampBlob_Internal(TCS_CONTEXT_HANDLE hContext,
			    TCS_KEY_HANDLE     hKey,
			    TPM_NONCE*         antiReplay,
			    TPM_DIGEST*        digestToStamp,
			    TPM_AUTH*          privAuth,
			    UINT32*            pulSignatureLength,
			    BYTE**             prgbSignature,
			    UINT32*            pulTickCountLength,
			    BYTE**             prgbTickCount)
{
	TSS_RESULT result;
	UINT32 paramSize;
	UINT64 offset = 0;
	TPM_KEY_HANDLE keySlot;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	if ((result = ctx_verify_context(hContext)))
		return result;

	if (privAuth) {
		if ((result = auth_mgr_check(hContext, &privAuth->AuthHandle)))
			goto done;
	}

	if ((result = ensureKeyIsLoaded(hContext, hKey, &keySlot)))
		goto done;

	if ((result = tpm_rqu_build(TPM_ORD_TickStampBlob, &offset, txBlob, keySlot, antiReplay,
				    digestToStamp, privAuth)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	if ((result = UnloadBlob_Header(txBlob, &paramSize))) {
		LogDebugFn("UnloadBlob_Header failed: rc=0x%x", result);
		goto done;
	}

	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_TickStampBlob, txBlob, paramSize, pulTickCountLength,
				       prgbTickCount, pulSignatureLength, prgbSignature, privAuth);
	}
done:
	return result;
}

void
UnloadBlob_CURRENT_TICKS(UINT64 *offset, BYTE *b, TPM_CURRENT_TICKS *t)
{
	if (!t) {
		UnloadBlob_UINT16(offset, NULL, b);
		UnloadBlob_UINT64(offset, NULL, b);
		UnloadBlob_UINT16(offset, NULL, b);
		UnloadBlob(offset, sizeof(TPM_NONCE), b, NULL);

		return;
	}

	UnloadBlob_UINT16(offset, &t->tag, b);
	UnloadBlob_UINT64(offset, &t->currentTicks, b);
	UnloadBlob_UINT16(offset, &t->tickRate, b);
	UnloadBlob(offset, sizeof(TPM_NONCE), b, (BYTE *)&t->tickNonce);
}


<|start_filename|>src/tspi/tspi_sign.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"

TSS_RESULT
Tspi_Hash_Sign(TSS_HHASH hHash,			/* in */
	       TSS_HKEY hKey,			/* in */
	       UINT32 * pulSignatureLength,	/* out */
	       BYTE ** prgbSignature)		/* out */
{
	TPM_AUTH privAuth;
	TPM_AUTH *pPrivAuth = &privAuth;
	TCPA_DIGEST digest;
	TCPA_RESULT result;
	TSS_HPOLICY hPolicy;
	TCS_KEY_HANDLE tcsKeyHandle;
	TSS_BOOL usesAuth;
	TSS_HCONTEXT tspContext;
	UINT32 ulDataLen;
	BYTE *data;
	Trspi_HashCtx hashCtx;

	if (pulSignatureLength == NULL || prgbSignature == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if ((result = obj_hash_get_tsp_context(hHash, &tspContext)))
		return result;

	if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, &hPolicy, &usesAuth)))
		return result;

	if ((result = obj_hash_get_value(hHash, &ulDataLen, &data)))
		return result;

	if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKeyHandle)))
		goto done;

	if (usesAuth) {
		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Sign);
		result |= Trspi_Hash_UINT32(&hashCtx, ulDataLen);
		result |= Trspi_HashUpdate(&hashCtx, ulDataLen, data);
		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
			goto done;

		pPrivAuth = &privAuth;

		if ((result = secret_PerformAuth_OIAP(hKey, TPM_ORD_Sign, hPolicy, FALSE, &digest,
						      &privAuth)))
			goto done;
	} else {
		pPrivAuth = NULL;
	}

	if ((result = TCS_API(tspContext)->Sign(tspContext, tcsKeyHandle, ulDataLen, data,
						pPrivAuth, pulSignatureLength, prgbSignature)))
		goto done;

	if (usesAuth) {
		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
		result |= Trspi_Hash_UINT32(&hashCtx, result);
		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Sign);
		result |= Trspi_Hash_UINT32(&hashCtx, *pulSignatureLength);
		result |= Trspi_HashUpdate(&hashCtx, *pulSignatureLength, *prgbSignature);
		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
			free(*prgbSignature);
			goto done;
		}

		if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &privAuth))) {
			free(*prgbSignature);
			goto done;
		}
	}

	if ((result = __tspi_add_mem_entry(tspContext, *prgbSignature)))
		free(*prgbSignature);

done:
	free_tspi(tspContext, data);
	return result;
}

TSS_RESULT
Tspi_Hash_VerifySignature(TSS_HHASH hHash,		/* in */
			  TSS_HKEY hKey,		/* in */
			  UINT32 ulSignatureLength,	/* in */
			  BYTE * rgbSignature)		/* in */
{
	TCPA_RESULT result;
	BYTE *pubKey = NULL;
	UINT32 pubKeySize;
	BYTE *hashData = NULL;
	UINT32 hashDataSize;
	UINT32 sigScheme;
	TSS_HCONTEXT tspContext;

	if (ulSignatureLength > 0 && rgbSignature == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext)))
		return result;

	if ((result = obj_rsakey_get_modulus(hKey, &pubKeySize, &pubKey)))
		return result;

	if ((result = obj_rsakey_get_ss(hKey, &sigScheme))) {
		free_tspi(tspContext, pubKey);
		return result;
	}

	if ((result = obj_hash_get_value(hHash, &hashDataSize, &hashData))) {
		free_tspi(tspContext, pubKey);
		return result;
	}

	if (sigScheme == TSS_SS_RSASSAPKCS1V15_SHA1) {
		result = Trspi_Verify(TSS_HASH_SHA1, hashData, hashDataSize, pubKey, pubKeySize,
				      rgbSignature, ulSignatureLength);
	} else if (sigScheme == TSS_SS_RSASSAPKCS1V15_DER) {
		result = Trspi_Verify(TSS_HASH_OTHER, hashData, hashDataSize, pubKey, pubKeySize,
				      rgbSignature, ulSignatureLength);
	} else {
		result = TSPERR(TSS_E_INVALID_SIGSCHEME);
	}

	free_tspi(tspContext, pubKey);
	free_tspi(tspContext, hashData);

	return result;
}


<|start_filename|>src/tspi/tsp_counter.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


#ifdef TSS_BUILD_TRANSPORT
TSS_RESULT
Transport_ReadCounter(TSS_HCONTEXT       tspContext,          /* in */
		      TSS_COUNTER_ID     idCounter,           /* in */
		      TPM_COUNTER_VALUE* counterValue)        /* out */
{
	TSS_RESULT result;
	UINT32 decLen = 0;
	BYTE *dec = NULL;
	UINT64 offset;
	TCS_HANDLE handlesLen = 0;
	BYTE data[sizeof(UINT32)];

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	offset = 0;
	Trspi_LoadBlob_UINT32(&offset, idCounter, data);

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_ReadCounter, sizeof(data),
						    data, NULL, &handlesLen, NULL, NULL, NULL,
						    &decLen, &dec)))
		return result;

	offset = 0;
	Trspi_UnloadBlob_COUNTER_VALUE(&offset, dec, counterValue);

	free(dec);

	return TSS_SUCCESS;
}
#endif


<|start_filename|>src/include/req_mgr.h<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */


#ifndef _REQ_MGR_H_
#define _REQ_MGR_H_

#include "threads.h"

struct tpm_req_mgr
{
	MUTEX_DECLARE(queue_lock);
};

TSS_RESULT req_mgr_init();
TSS_RESULT req_mgr_final();
TSS_RESULT req_mgr_submit_req(BYTE *);

#endif


<|start_filename|>src/tspi/tspi_delegate.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "obj.h"
#include "tsp_delegate.h"
#include "tsplog.h"


TSS_RESULT
Tspi_TPM_Delegate_AddFamily(TSS_HTPM        hTpm,	/* in, must not be NULL */
			    BYTE            bLabel,	/* in */
			    TSS_HDELFAMILY* phFamily)	/* out */
{
	TPM_FAMILY_ID familyID = 0;
	UINT32 outDataSize;
	BYTE *outData = NULL;
	UINT64 offset;
	TSS_RESULT result;

	if (phFamily == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);
	*phFamily = NULL_HDELFAMILY;

	if ((result = do_delegate_manage(hTpm, familyID, TPM_FAMILY_CREATE, sizeof(bLabel), &bLabel,
					 &outDataSize, &outData)))
		return result;

	offset = 0;
	Trspi_UnloadBlob_UINT32(&offset, &familyID, outData);

	/* Create or update the delfamily object */
	if ((result = update_delfamily_object(hTpm, familyID)))
		goto done;

	obj_delfamily_find_by_familyid(hTpm, familyID, phFamily);
	if (*phFamily == NULL_HDELFAMILY)
		result = TSPERR(TSS_E_INTERNAL_ERROR);

done:
	free(outData);

	return result;
}

TSS_RESULT
Tspi_TPM_Delegate_GetFamily(TSS_HTPM        hTpm,	/* in, must not NULL */
			    UINT32          ulFamilyID,	/* in */
			    TSS_HDELFAMILY* phFamily)	/* out */
{
	TSS_RESULT result;

	if (phFamily == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);
	*phFamily = NULL_HDELFAMILY;

	/* Update the delfamily object */
	if ((result = update_delfamily_object(hTpm, ulFamilyID)))
		return result;

	obj_delfamily_find_by_familyid(hTpm, ulFamilyID, phFamily);
	if (*phFamily == NULL_HDELFAMILY)
		result = TSPERR(TSS_E_BAD_PARAMETER);

	return result;
}

TSS_RESULT
Tspi_TPM_Delegate_InvalidateFamily(TSS_HTPM       hTpm,		/* in, must not be NULL */
				   TSS_HDELFAMILY hFamily)	/* in */
{
	TPM_FAMILY_ID familyID;
	UINT32 outDataSize;
	BYTE *outData = NULL;
	TSS_RESULT result;

	if ((result = obj_delfamily_get_familyid(hFamily, &familyID)))
		return result;

	if ((result = do_delegate_manage(hTpm, familyID, TPM_FAMILY_INVALIDATE,	0, NULL,
					 &outDataSize, &outData)))
		return result;

	/* Delete the delfamily object */
	result = obj_delfamily_remove(hFamily, hTpm);

	free(outData);

	return result;
}

TSS_RESULT
Tspi_TPM_Delegate_CreateDelegation(TSS_HOBJECT    hObject,	/* in */
				   BYTE           bLabel,	/* in */
				   UINT32         ulFlags,	/* in */
				   TSS_HPCRS      hPcrs,	/* in */
				   TSS_HDELFAMILY hFamily,	/* in */
				   TSS_HPOLICY    hDelegation)	/* in, out */
{
	TSS_RESULT result;

	if (obj_is_tpm(hObject)) {
		if ((result = create_owner_delegation(hObject, bLabel, ulFlags, hPcrs, hFamily,
						      hDelegation)))
			return result;
	} else if (obj_is_rsakey(hObject)) {
		if ((result = create_key_delegation(hObject, bLabel, ulFlags, hPcrs, hFamily,
						    hDelegation)))
			return result;
	} else
		return TSPERR(TSS_E_INVALID_HANDLE);

	return TSS_SUCCESS;
}

TSS_RESULT
Tspi_TPM_Delegate_CacheOwnerDelegation(TSS_HTPM    hTpm,	/* in */
				       TSS_HPOLICY hDelegation,	/* in */
				       UINT32      ulIndex,	/* in */
				       UINT32      ulFlags)	/* in */
{
	TSS_HCONTEXT hContext;
	TSS_HPOLICY hPolicy;
	UINT32 blobSize;
	BYTE *blob = NULL;
	UINT32 secretMode = TSS_SECRET_MODE_NONE;
	Trspi_HashCtx hashCtx;
	TCPA_DIGEST digest;
	TPM_AUTH ownerAuth, *pAuth;
	TSS_RESULT result;

	if ((result = obj_tpm_get_tsp_context(hTpm, &hContext)))
		return result;

	if ((result = obj_tpm_get_policy(hTpm, TSS_POLICY_USAGE, &hPolicy)))
		return result;

	if ((result = obj_policy_get_delegation_blob(hDelegation, TSS_DELEGATIONTYPE_OWNER,
			&blobSize, &blob)))
		return result;

	if (ulFlags & ~TSS_DELEGATE_CACHEOWNERDELEGATION_OVERWRITEEXISTING) {
		result = TSPERR(TSS_E_BAD_PARAMETER);
		goto done;
	}

	if ((ulFlags & TSS_DELEGATE_CACHEOWNERDELEGATION_OVERWRITEEXISTING) == 0) {
		TPM_DELEGATE_PUBLIC public;

		/* Verify there is nothing occupying the specified row */
		result = get_delegate_index(hContext, ulIndex, &public);
		if (result == TSS_SUCCESS) {
			free(public.pcrInfo.pcrSelection.pcrSelect);
			result = TSPERR(TSS_E_DELFAMILY_ROWEXISTS);
			goto done;
		}
	}

	if (hPolicy != NULL_HPOLICY) {
		if ((result = obj_policy_get_mode(hPolicy, &secretMode)))
			goto done;
	}

	if (secretMode != TSS_SECRET_MODE_NONE) {
		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_LoadOwnerDelegation);
		result |= Trspi_Hash_UINT32(&hashCtx, ulIndex);
		result |= Trspi_Hash_UINT32(&hashCtx, blobSize);
		result |= Trspi_HashUpdate(&hashCtx, blobSize, blob);
		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
			goto done;

		pAuth = &ownerAuth;
		if ((result = secret_PerformAuth_OIAP(hTpm, TPM_ORD_Delegate_LoadOwnerDelegation,
				hPolicy, FALSE, &digest, pAuth)))
			goto done;
	} else
		pAuth = NULL;

	if ((result = TCS_API(hContext)->Delegate_LoadOwnerDelegation(hContext, ulIndex, blobSize,
								      blob, pAuth)))
		goto done;

	if (pAuth) {
		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
		result |= Trspi_Hash_UINT32(&hashCtx, result);
		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_LoadOwnerDelegation);
		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
			goto done;

		if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth)))
			goto done;
	}

	result = obj_policy_set_delegation_index(hDelegation, ulIndex);

done:
	free_tspi(hContext, blob);

	return result;
}

TSS_RESULT
Tspi_TPM_Delegate_UpdateVerificationCount(TSS_HTPM    hTpm,		/* in */
					  TSS_HPOLICY hDelegation)	/* in, out */
{
	TSS_HCONTEXT hContext;
	TSS_HPOLICY hPolicy;
	UINT32 secretMode = TSS_SECRET_MODE_NONE;
	Trspi_HashCtx hashCtx;
	TCPA_DIGEST digest;
	TPM_AUTH ownerAuth, *pAuth;
	TSS_BOOL indexSet;
	UINT32 inputSize;
	BYTE *input = NULL;
	UINT32 outputSize;
	BYTE *output = NULL;
	UINT64 offset;
	TSS_RESULT result;

	if ((result = obj_tpm_get_tsp_context(hTpm, &hContext)))
		return result;

	if ((result = obj_tpm_get_policy(hTpm, TSS_POLICY_USAGE, &hPolicy)))
		return result;

	if (hPolicy != NULL_HPOLICY) {
		if ((result = obj_policy_get_mode(hPolicy, &secretMode)))
			goto done;
	}

	if ((result = obj_policy_is_delegation_index_set(hDelegation, &indexSet)))
		return result;
	if (indexSet) {
		UINT32 index;

		if ((result = obj_policy_get_delegation_index(hDelegation, &index)))
			return result;
		inputSize = sizeof(UINT32);
		input = calloc_tspi(hContext, inputSize);
		if (!input) {
			LogError("malloc of %zd bytes failed.", sizeof(UINT32));
			return TSPERR(TSS_E_OUTOFMEMORY);
		}
		offset = 0;
		Trspi_LoadBlob_UINT32(&offset, index, input);
	} else {
		if ((result = obj_policy_get_delegation_blob(hDelegation, 0,
				&inputSize, &input)))
			return result;
	}

	if (secretMode != TSS_SECRET_MODE_NONE) {
		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_UpdateVerification);
		result |= Trspi_Hash_UINT32(&hashCtx, inputSize);
		result |= Trspi_HashUpdate(&hashCtx, inputSize, input);
		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
			goto done;

		pAuth = &ownerAuth;
		if ((result = secret_PerformAuth_OIAP(hTpm, TPM_ORD_Delegate_UpdateVerification,
				hPolicy, FALSE, &digest, pAuth)))
			goto done;
	} else
		pAuth = NULL;

	if ((result = TCS_API(hContext)->Delegate_UpdateVerificationCount(hContext, inputSize,
									  input, pAuth, &outputSize,
									  &output)))
		goto done;

	if (pAuth) {
		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
		result |= Trspi_Hash_UINT32(&hashCtx, result);
		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_UpdateVerification);
		result |= Trspi_Hash_UINT32(&hashCtx, outputSize);
		result |= Trspi_HashUpdate(&hashCtx, outputSize, output);
		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
			goto done;

		if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth)))
			goto done;
	}

	result = obj_policy_set_delegation_blob(hDelegation, 0, outputSize, output);

done:
	free_tspi(hContext, input);
	free(output);

	return result;
}

TSS_RESULT
Tspi_TPM_Delegate_VerifyDelegation(TSS_HPOLICY hDelegation)	/* in, out */
{
	TSS_HCONTEXT hContext;
	UINT32 delegateSize;
	BYTE *delegate = NULL;
	TSS_RESULT result;

	if ((result = obj_policy_get_tsp_context(hDelegation, &hContext)))
		return result;

	if ((result = obj_policy_get_delegation_blob(hDelegation, 0, &delegateSize, &delegate)))
		return result;

	result = TCS_API(hContext)->Delegate_VerifyDelegation(hContext, delegateSize, delegate);

	free_tspi(hContext, delegate);

	return result;
}

TSS_RESULT
Tspi_TPM_Delegate_ReadTables(TSS_HCONTEXT                 hContext,		/* in */
			     UINT32*                      pulFamilyTableSize,	/* out */
			     TSS_FAMILY_TABLE_ENTRY**     ppFamilyTable,	/* out */
			     UINT32*                      pulDelegateTableSize,	/* out */
			     TSS_DELEGATION_TABLE_ENTRY** ppDelegateTable)	/* out */
{
	UINT32 tpmFamilyTableSize, tpmDelegateTableSize;
	BYTE *tpmFamilyTable = NULL, *tpmDelegateTable = NULL;
	TPM_FAMILY_TABLE_ENTRY tpmFamilyEntry;
	TSS_FAMILY_TABLE_ENTRY tssFamilyEntry, *tssFamilyTable = NULL;
	UINT32 tssFamilyTableSize = 0;
	TPM_DELEGATE_PUBLIC tpmDelegatePublic;
	TSS_DELEGATION_TABLE_ENTRY tssDelegateEntry, *tssDelegateTable = NULL;
	UINT32 tssDelegateTableSize = 0;
	UINT32 tableIndex;
	UINT64 tpmOffset;
	UINT64 tssOffset;
	TSS_RESULT result;

	if (!pulFamilyTableSize || !ppFamilyTable || !pulDelegateTableSize || !ppDelegateTable)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if (!obj_is_context(hContext))
		return TSPERR(TSS_E_INVALID_HANDLE);

	if ((result = TCS_API(hContext)->Delegate_ReadTable(hContext, &tpmFamilyTableSize,
							    &tpmFamilyTable, &tpmDelegateTableSize,
							    &tpmDelegateTable)))
		return result;

	if (tpmFamilyTableSize > 0) {
		/* Create the TSS_FAMILY_TABLE_ENTRY array */
		for (tpmOffset = 0, tssOffset = 0; tpmOffset < tpmFamilyTableSize;) {
			Trspi_UnloadBlob_TPM_FAMILY_TABLE_ENTRY(&tpmOffset, tpmFamilyTable,
				&tpmFamilyEntry);

			/* No pointers in the family table entries, so no
			   assignments required before doing LoadBlob */
			Trspi_LoadBlob_TSS_FAMILY_TABLE_ENTRY(&tssOffset, NULL, &tssFamilyEntry);
		}

		if ((tssFamilyTable = calloc_tspi(hContext, tssOffset)) == NULL) {
			LogError("malloc of %" PRIu64 " bytes failed.", tssOffset);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		for (tpmOffset = 0, tssOffset = 0; tpmOffset < tpmFamilyTableSize; tssFamilyTableSize++) {
			Trspi_UnloadBlob_TPM_FAMILY_TABLE_ENTRY(&tpmOffset, tpmFamilyTable,
				&tpmFamilyEntry);

			tssFamilyEntry.familyID = tpmFamilyEntry.familyID;
			tssFamilyEntry.label = tpmFamilyEntry.label.label;
			tssFamilyEntry.verificationCount = tpmFamilyEntry.verificationCount;
			tssFamilyEntry.enabled =
				(tpmFamilyEntry.flags & TPM_FAMFLAG_ENABLE) ? TRUE : FALSE;
			tssFamilyEntry.locked =
				(tpmFamilyEntry.flags & TPM_FAMFLAG_DELEGATE_ADMIN_LOCK) ? TRUE : FALSE;
			Trspi_LoadBlob_TSS_FAMILY_TABLE_ENTRY(&tssOffset, (BYTE *)tssFamilyTable,
				&tssFamilyEntry);
		}
	}

	if (tpmDelegateTableSize > 0) {
		/* Create the TSS_DELEGATION_TABLE_ENTRY array */
		for (tpmOffset = 0, tssOffset = 0; tpmOffset < tpmDelegateTableSize;) {
			Trspi_UnloadBlob_UINT32(&tpmOffset, &tableIndex, tpmDelegateTable);
			if ((result = Trspi_UnloadBlob_TPM_DELEGATE_PUBLIC(&tpmOffset, tpmDelegateTable,
					&tpmDelegatePublic))) {
				free_tspi(hContext, tssFamilyTable);
				goto done;
			}

			/* Some pointers in the delegate table entries, so
			   do some assignments before doing LoadBlob */
			tssDelegateEntry.pcrInfo.sizeOfSelect =
				tpmDelegatePublic.pcrInfo.pcrSelection.sizeOfSelect;
			tssDelegateEntry.pcrInfo.selection =
				tpmDelegatePublic.pcrInfo.pcrSelection.pcrSelect;
			tssDelegateEntry.pcrInfo.sizeOfDigestAtRelease =
				sizeof(tpmDelegatePublic.pcrInfo.digestAtRelease.digest);
			tssDelegateEntry.pcrInfo.digestAtRelease =
				tpmDelegatePublic.pcrInfo.digestAtRelease.digest;
			Trspi_LoadBlob_TSS_DELEGATION_TABLE_ENTRY(&tssOffset, NULL,
				&tssDelegateEntry);

			free(tpmDelegatePublic.pcrInfo.pcrSelection.pcrSelect);
		}

		if ((tssDelegateTable = calloc_tspi(hContext, tssOffset)) == NULL) {
			LogError("malloc of %" PRIu64 " bytes failed.", tssOffset);
			free_tspi(hContext, tssFamilyTable);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		for (tpmOffset = 0, tssOffset = 0; tpmOffset < tpmDelegateTableSize; tssDelegateTableSize++) {
			Trspi_UnloadBlob_UINT32(&tpmOffset, &tableIndex, tpmDelegateTable);
			if ((result = Trspi_UnloadBlob_TPM_DELEGATE_PUBLIC(&tpmOffset,
					tpmDelegateTable, &tpmDelegatePublic))) {
				free_tspi(hContext, tssFamilyTable);
				free_tspi(hContext, tssDelegateTable);
				goto done;
			}

			tssDelegateEntry.tableIndex = tableIndex;
			tssDelegateEntry.label = tpmDelegatePublic.label.label;
			tssDelegateEntry.pcrInfo.sizeOfSelect =
				tpmDelegatePublic.pcrInfo.pcrSelection.sizeOfSelect;
			tssDelegateEntry.pcrInfo.selection =
				tpmDelegatePublic.pcrInfo.pcrSelection.pcrSelect;
			tssDelegateEntry.pcrInfo.localityAtRelease =
				tpmDelegatePublic.pcrInfo.localityAtRelease;
			tssDelegateEntry.pcrInfo.sizeOfDigestAtRelease =
				sizeof(tpmDelegatePublic.pcrInfo.digestAtRelease.digest);
			tssDelegateEntry.pcrInfo.digestAtRelease =
				tpmDelegatePublic.pcrInfo.digestAtRelease.digest;
			tssDelegateEntry.per1 = tpmDelegatePublic.permissions.per1;
			tssDelegateEntry.per2 = tpmDelegatePublic.permissions.per2;
			tssDelegateEntry.familyID = tpmDelegatePublic.familyID;
			tssDelegateEntry.verificationCount = tpmDelegatePublic.verificationCount;
			Trspi_LoadBlob_TSS_DELEGATION_TABLE_ENTRY(&tssOffset,
				(BYTE *)tssDelegateTable, &tssDelegateEntry);

			free(tpmDelegatePublic.pcrInfo.pcrSelection.pcrSelect);
		}
	}

	*ppFamilyTable = tssFamilyTable;
	*pulFamilyTableSize = tssFamilyTableSize;
	*ppDelegateTable = tssDelegateTable;
	*pulDelegateTableSize = tssDelegateTableSize;

done:
	free(tpmFamilyTable);
	free(tpmDelegateTable);

	return result;
}



<|start_filename|>src/tspi/tsp_seal.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "obj.h"
#include "tsplog.h"
#include "authsess.h"


#ifdef TSS_BUILD_SEALX
TSS_RESULT
sealx_mask_cb(PVOID lpAppData,
	      TSS_HKEY hEncKey,
	      TSS_HENCDATA hEncData,
	      TSS_ALGORITHM_ID algId,
	      UINT32 ulSizeNonces,
	      BYTE *rgbNonceEven,
	      BYTE *rgbNonceOdd,
	      BYTE *rgbNonceEvenOSAP,
	      BYTE *rgbNonceOddOSAP,
	      UINT32 ulDataLength,
	      BYTE *rgbDataToMask,
	      BYTE *rgbMaskedData)
{
	UINT32 mgf1SeedLen, sharedSecretLen = sizeof(TPM_DIGEST);
	BYTE *mgf1Seed, *mgf1Buffer;
	UINT32 i;
	TSS_RESULT result;
	struct authsess *sess = (struct authsess *)lpAppData;

	mgf1SeedLen = (ulSizeNonces * 2) + strlen("XOR") + sharedSecretLen;
	if ((mgf1Seed = (BYTE *)calloc(1, mgf1SeedLen)) == NULL) {
		LogError("malloc of %u bytes failed.", mgf1SeedLen);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}
	mgf1Buffer = mgf1Seed;
	memcpy(mgf1Buffer, rgbNonceEven, ulSizeNonces);
	mgf1Buffer += ulSizeNonces;
	memcpy(mgf1Buffer, rgbNonceOdd, ulSizeNonces);
	mgf1Buffer += ulSizeNonces;
	memcpy(mgf1Buffer, "XOR", strlen("XOR"));
	mgf1Buffer += strlen("XOR");
	memcpy(mgf1Buffer, sess->sharedSecret.digest, sharedSecretLen);

	if ((result = Trspi_MGF1(TSS_HASH_SHA1, mgf1SeedLen, mgf1Seed, ulDataLength,
				 rgbMaskedData)))
		goto done;

	for (i = 0; i < ulDataLength; i++)
		rgbMaskedData[i] ^= rgbDataToMask[i];

done:
	free(mgf1Seed);

	return result;
}
#endif

#ifdef TSS_BUILD_TRANSPORT
TSS_RESULT
Transport_Seal(TSS_HCONTEXT tspContext,    /* in */
	       TCS_KEY_HANDLE keyHandle,   /* in */
	       TCPA_ENCAUTH *encAuth,       /* in */
	       UINT32 pcrInfoSize, /* in */
	       BYTE * PcrInfo,     /* in */
	       UINT32 inDataSize,  /* in */
	       BYTE * inData,      /* in */
	       TPM_AUTH * pubAuth, /* in, out */
	       UINT32 * SealedDataSize,    /* out */
	       BYTE ** SealedData) /* out */
{
	TSS_RESULT result;
	UINT32 handlesLen, decLen, dataLen;
	TCS_HANDLE *handles, handle;
	TPM_DIGEST pubKeyHash;
	Trspi_HashCtx hashCtx;
	UINT64 offset;
	BYTE *data, *dec;


	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	if ((result = obj_tcskey_get_pubkeyhash(keyHandle, pubKeyHash.digest)))
		return result;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
		return result;

	handlesLen = 1;
	handle = keyHandle;
	handles = &handle;

	dataLen = (2 * sizeof(UINT32)) + sizeof(TPM_ENCAUTH) + pcrInfoSize + inDataSize;
	if ((data = malloc(dataLen)) == NULL) {
		LogError("malloc of %u bytes failed", dataLen);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	offset = 0;
	Trspi_LoadBlob_DIGEST(&offset, data, (TPM_DIGEST *)encAuth);
	Trspi_LoadBlob_UINT32(&offset, pcrInfoSize, data);
	Trspi_LoadBlob(&offset, pcrInfoSize, data, PcrInfo);
	Trspi_LoadBlob_UINT32(&offset, inDataSize, data);
	Trspi_LoadBlob(&offset, inDataSize, data, inData);

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Seal, dataLen, data,
						    &pubKeyHash, &handlesLen, &handles, pubAuth,
						    NULL, &decLen, &dec)))
		return result;

	*SealedDataSize = decLen;
	*SealedData = dec;

	return result;
}

TSS_RESULT
Transport_Sealx(TSS_HCONTEXT tspContext,   /* in */
		TCS_KEY_HANDLE keyHandle,  /* in */
		TCPA_ENCAUTH *encAuth,      /* in */
		UINT32 pcrInfoSize,        /* in */
		BYTE * PcrInfo,    /* in */
		UINT32 inDataSize, /* in */
		BYTE * inData,     /* in */
		TPM_AUTH * pubAuth,        /* in, out */
		UINT32 * SealedDataSize,   /* out */
		BYTE ** SealedData)        /* out */
{
	TSS_RESULT result;
	UINT32 handlesLen, decLen, dataLen;
	TCS_HANDLE *handles, handle;
	TPM_DIGEST pubKeyHash;
	Trspi_HashCtx hashCtx;
	UINT64 offset;
	BYTE *data, *dec;


	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	if ((result = obj_tcskey_get_pubkeyhash(keyHandle, pubKeyHash.digest)))
		return result;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
		return result;

	handlesLen = 1;
	handle = keyHandle;
	handles = &handle;

	dataLen = (2 * sizeof(UINT32)) + sizeof(TPM_ENCAUTH) + pcrInfoSize + inDataSize;
	if ((data = malloc(dataLen)) == NULL) {
		LogError("malloc of %u bytes failed", dataLen);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	offset = 0;
	Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, encAuth->authdata);
	Trspi_LoadBlob_UINT32(&offset, pcrInfoSize, data);
	Trspi_LoadBlob(&offset, pcrInfoSize, data, PcrInfo);
	Trspi_LoadBlob_UINT32(&offset, inDataSize, data);
	Trspi_LoadBlob(&offset, inDataSize, data, inData);

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Sealx, dataLen, data,
						    &pubKeyHash, &handlesLen, &handles, pubAuth,
						    NULL, &decLen, &dec)))
		return result;

	*SealedDataSize = decLen;
	*SealedData = dec;

	return result;
}

TSS_RESULT
Transport_Unseal(TSS_HCONTEXT tspContext,  /* in */
		 TCS_KEY_HANDLE parentHandle,      /* in */
		 UINT32 SealedDataSize,    /* in */
		 BYTE * SealedData,        /* in */
		 TPM_AUTH * parentAuth,    /* in, out */
		 TPM_AUTH * dataAuth,      /* in, out */
		 UINT32 * DataSize,        /* out */
		 BYTE ** Data)     /* out */
{
	UINT64 offset;
	TSS_RESULT result;
	UINT32 handlesLen, decLen;
	TCS_HANDLE *handles, handle;
	TPM_DIGEST pubKeyHash;
	Trspi_HashCtx hashCtx;
	BYTE *dec;


	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	if ((result = obj_tcskey_get_pubkeyhash(parentHandle, pubKeyHash.digest)))
		return result;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
		return result;

	handlesLen = 1;
	handle = parentHandle;
	handles = &handle;

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Unseal, SealedDataSize,
						    SealedData, &pubKeyHash, &handlesLen, &handles,
						    parentAuth, dataAuth, &decLen, &dec)))
		return result;

	offset = 0;
	Trspi_UnloadBlob_UINT32(&offset, DataSize, dec);

	if ((*Data = malloc(*DataSize)) == NULL) {
		free(dec);
		LogError("malloc of %u bytes failed", *DataSize);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}
	Trspi_UnloadBlob(&offset, *DataSize, dec, *Data);

	free(dec);

	return result;
}
#endif


<|start_filename|>src/tcs/tcsi_pcr.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 * (C) <NAME> 2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcsps.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "req_mgr.h"
#include "tcsd_wrap.h"
#include "tcsd.h"


TSS_RESULT
TCSP_Extend_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
		     TCPA_PCRINDEX pcrNum,	/* in */
		     TCPA_DIGEST inDigest,	/* in */
		     TCPA_PCRVALUE * outDigest)	/* out */
{
	UINT64 offset = 0;
	TSS_RESULT result;
	UINT32 paramSize;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering Extend");
	if ((result = ctx_verify_context(hContext)))
		return result;

	/* PCRs are numbered 0 - (NUM_PCRS - 1), thus the >= */
	if (pcrNum >= tpm_metrics.num_pcrs)
		return TCSERR(TSS_E_BAD_PARAMETER);

	if (tcsd_options.kernel_pcrs & (1 << pcrNum)) {
		LogInfo("PCR %d is configured to be kernel controlled. Extend request denied.",
				pcrNum);
		return TCSERR(TSS_E_FAIL);
	}

	if (tcsd_options.firmware_pcrs & (1 << pcrNum)) {
		LogInfo("PCR %d is configured to be firmware controlled. Extend request denied.",
				pcrNum);
		return TCSERR(TSS_E_FAIL);
	}

	if ((result = tpm_rqu_build(TPM_ORD_Extend, &offset, txBlob, pcrNum, TPM_DIGEST_SIZE,
				    inDigest.digest, NULL, NULL)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_Extend, txBlob, paramSize, NULL, outDigest->digest);
	}
	LogResult("Extend", result);
	return result;
}

TSS_RESULT
TCSP_PcrRead_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
		      TCPA_PCRINDEX pcrNum,		/* in */
		      TCPA_PCRVALUE * outDigest)	/* out */
{
	UINT64 offset = 0;
	TSS_RESULT result;
	UINT32 paramSize;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering PCRRead");

	if ((result = ctx_verify_context(hContext)))
		return result;

	/* PCRs are numbered 0 - (NUM_PCRS - 1), thus the >= */
	if (pcrNum >= tpm_metrics.num_pcrs)
		return TCSERR(TSS_E_BAD_PARAMETER);

	if ((result = tpm_rqu_build(TPM_ORD_PcrRead, &offset, txBlob, pcrNum, NULL)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_PcrRead, txBlob, paramSize, NULL, outDigest->digest);
	}
	LogResult("PCR Read", result);
	return result;
}

TSS_RESULT
TCSP_PcrReset_Internal(TCS_CONTEXT_HANDLE hContext,      /* in */
		       UINT32 pcrDataSizeIn,             /* in */
		       BYTE * pcrDataIn)                 /* in */
{
	UINT64 offset = 0;
	TSS_RESULT result;
	UINT32 paramSize;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering PCRReset");

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_PCR_Reset, &offset, txBlob, pcrDataSizeIn, pcrDataIn)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);
	LogResult("PCR Reset", result);
	return result;
}


<|start_filename|>src/tspi/tspi_pcr_events.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


TSS_RESULT
Tspi_TPM_GetEvent(TSS_HTPM hTPM,		/* in */
		  UINT32 ulPcrIndex,		/* in */
		  UINT32 ulEventNumber,		/* in */
		  TSS_PCR_EVENT * pPcrEvent)	/* out */
{
	TSS_HCONTEXT tspContext;
	TSS_RESULT result;
	TSS_PCR_EVENT *event = NULL;

	if (pPcrEvent == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
		return result;

	if ((result = RPC_GetPcrEvent(tspContext, ulPcrIndex, &ulEventNumber, &event)))
		return result;

	memcpy(pPcrEvent, event, sizeof(TSS_PCR_EVENT));
	free(event);

	return TSS_SUCCESS;
}

TSS_RESULT
Tspi_TPM_GetEvents(TSS_HTPM hTPM,			/* in */
		   UINT32 ulPcrIndex,			/* in */
		   UINT32 ulStartNumber,		/* in */
		   UINT32 * pulEventNumber,		/* in, out */
		   TSS_PCR_EVENT ** prgbPcrEvents)	/* out */
{
	TSS_HCONTEXT tspContext;
	TSS_RESULT result;
	TSS_PCR_EVENT *events = NULL;

	if (pulEventNumber == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
		return result;

	if (prgbPcrEvents) {
		if ((result = RPC_GetPcrEventsByPcr(tspContext, ulPcrIndex, ulStartNumber,
						    pulEventNumber, &events)))
			return result;

		*prgbPcrEvents = events;
	} else {
		/* if the pointer to receive events is NULL, the app only
		 * wants a total number of events for this PCR. */
		if ((result = RPC_GetPcrEvent(tspContext, ulPcrIndex, pulEventNumber, NULL)))
			return result;
	}

	return TSS_SUCCESS;
}

TSS_RESULT
Tspi_TPM_GetEventLog(TSS_HTPM hTPM,			/* in */
		     UINT32 * pulEventNumber,		/* out */
		     TSS_PCR_EVENT ** prgbPcrEvents)	/* out */
{
	TSS_HCONTEXT tspContext;
	TSS_RESULT result;

	if (pulEventNumber == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
		return result;

	/* if the pointer to receive events is NULL, the app only wants a
	 * total number of events for all PCRs. */
	if (prgbPcrEvents == NULL) {
		UINT16 numPcrs = get_num_pcrs(tspContext);
		UINT32 i, numEvents = 0;

		if (numPcrs == 0) {
			LogDebugFn("Error querying the TPM for its number of PCRs");
			return TSPERR(TSS_E_INTERNAL_ERROR);
		}

		*pulEventNumber = 0;
		for (i = 0; i < numPcrs; i++) {
			if ((result = RPC_GetPcrEvent(tspContext, i, &numEvents, NULL)))
				return result;

			*pulEventNumber += numEvents;
		}
	} else
		return RPC_GetPcrEventLog(tspContext, pulEventNumber, prgbPcrEvents);

	return TSS_SUCCESS;
}



<|start_filename|>src/tcs/tcs_quote2.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcsps.h"
#include "tcslog.h"
#include "tddl.h"
#include "req_mgr.h"
#include "tcsd_wrap.h"
#include "tcsd.h"

TSS_RESULT
UnloadBlob_PCR_INFO_SHORT(UINT64 *offset, BYTE *blob, TPM_PCR_INFO_SHORT *pcrInfoOut)
{
	TSS_RESULT result;
	BYTE locAtRelease;
	TPM_DIGEST digest;

	LogDebugFn("UnloadBlob_PCR_INFO_SHORT.");
	/* Only adjust the offset until the end of this data type */
	if (!pcrInfoOut) {
		if ((result = UnloadBlob_PCR_SELECTION(offset, blob, NULL)))
			return result;
		/* What should go to &pcrInfoOut->localityAtRelease */
		UnloadBlob_BYTE(offset, NULL, blob);
		/* What should go to &pcrInfoOut->digestAtRelease */
		UnloadBlob_DIGEST(offset, blob, NULL);
		return TSS_SUCCESS;
	}

	/* Normal retrieve or TPM_PCR_INFO_SHORT (not used yet, kept for
	 * integrity purposes.
	 * TPM_PCR_SELECTION pcrSelection
	 * TPM_LOCALITY_SELECTION localityAtRelease
	 * TPM_COMPOSITE_HASH digestAtRelease
	 *  */
	if ((result = UnloadBlob_PCR_SELECTION(offset, blob, &pcrInfoOut->pcrSelection)))
		return result;

	UnloadBlob_BYTE(offset, &locAtRelease, blob);
	pcrInfoOut->localityAtRelease = locAtRelease;
	UnloadBlob_DIGEST(offset, blob, &digest);
	pcrInfoOut->digestAtRelease = digest;

	return TSS_SUCCESS;
}




<|start_filename|>src/tspi/rpc/tcstp/rpc_daa.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "hosttable.h"
#include "tcsd_wrap.h"
#include "obj.h"
#include "rpc_tcstp_tsp.h"


TSS_RESULT
RPC_DaaJoin_TP(struct host_table_entry *hte,
		TPM_HANDLE handle, // in
		BYTE stage, // in
		UINT32 inputSize0, // in
		BYTE* inputData0, // in
		UINT32 inputSize1, // in
		BYTE* inputData1, // in
		TPM_AUTH* ownerAuth, // in/out
		UINT32* outputSize, // out
		BYTE** outputData) // out
{
	TSS_RESULT result;
	UINT32 i;

	LogDebugFn("stage=%d", stage);
	initData(&hte->comm, 8);
	hte->comm.hdr.u.ordinal = TCSD_ORD_DAAJOIN;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);
	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &handle, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_BYTE, 2, &stage, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 3, &inputSize0, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	LogDebugFn("inputSize0=<network>=%d <host>=%d", inputSize0, inputSize0);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 4, inputData0, inputSize0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 5, &inputSize1, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	LogDebugFn("inputSize1=<network>=%d <host>=%d", inputSize1, inputSize1);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 6, inputData1, inputSize1, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if( ownerAuth) {
		if (setData(TCSD_PACKET_TYPE_AUTH, 7, ownerAuth, 0, &hte->comm))
			return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	result = sendTCSDPacket(hte);
	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		i = 0;
		LogDebugFn("getData outputSize");

		if( ownerAuth) {
			if (getData(TCSD_PACKET_TYPE_AUTH, i++, ownerAuth, 0, &hte->comm)) {
				result = TSPERR(TSS_E_INTERNAL_ERROR);
				goto done;
			}
		}
		if (getData(TCSD_PACKET_TYPE_UINT32, i++, outputSize, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		*outputData = (BYTE *) malloc(*outputSize);
		if (*outputData == NULL) {
			LogError("malloc of %u bytes failed.", *outputSize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		LogDebugFn("getData outputData (outputSize=%u)", *outputSize);
		if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *outputData, *outputSize, &hte->comm)) {
			free(*outputData);
			*outputData = NULL;
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
	}

done:
	LogDebugFn("result=%u", result);
	return result;
}

TSS_RESULT
RPC_DaaSign_TP(struct host_table_entry *hte,
		TPM_HANDLE handle, // in
		BYTE stage, // in
		UINT32 inputSize0, // in
		BYTE* inputData0, // in
		UINT32 inputSize1, // in
		BYTE* inputData1, // in
		TPM_AUTH* ownerAuth, // in/out
		UINT32* outputSize, // out
		BYTE** outputData) // out
{
	TSS_RESULT result;
	UINT32 i;

	LogDebugFn("stage=%d", stage);
	initData(&hte->comm, 8);
	hte->comm.hdr.u.ordinal = TCSD_ORD_DAASIGN;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);
	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &handle, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_BYTE, 2, &stage, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 3, &inputSize0, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	LogDebugFn("inputSize0=<network>=%d <host>=%d", inputSize0, inputSize0);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 4, inputData0, inputSize0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 5, &inputSize1, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	LogDebugFn("inputSize1=<network>=%d <host>=%d", inputSize1, inputSize1);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 6, inputData1, inputSize1, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if( ownerAuth) {
		if (setData(TCSD_PACKET_TYPE_AUTH, 7, ownerAuth, 0, &hte->comm))
			return TSPERR(TSS_E_INTERNAL_ERROR);
	}
	LogDebugFn("sendTCSDPacket: 0x%x", (int)hte);
	result = sendTCSDPacket(hte);
	//
	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;
	//
	if (result == TSS_SUCCESS) {
		i = 0;
		LogDebugFn("getData outputSize");

		if( ownerAuth) {
			if (getData(TCSD_PACKET_TYPE_AUTH, i++, ownerAuth, 0, &hte->comm)) {
				result = TSPERR(TSS_E_INTERNAL_ERROR);
				goto done;
			}
		}
		if (getData(TCSD_PACKET_TYPE_UINT32, i++, outputSize, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		*outputData = (BYTE *) malloc(*outputSize);
		if (*outputData == NULL) {
			LogError("malloc of %u bytes failed.", *outputSize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		LogDebugFn("getData outputData (outputSize=%d)", *outputSize);
		if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *outputData, *outputSize, &hte->comm)) {
			free(*outputData);
			*outputData = NULL;
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
	}

done:
	LogDebugFn("result=%u", result);
	return result;
}



<|start_filename|>src/include/memmgr.h<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */

#ifndef _MEMMGR_H_
#define _MEMMGR_H_

/*
 * For each TSP context, there is one memTable, which holds a list of memEntry's,
 * each of which holds a pointer to some malloc'd memory that's been returned to
 * the user. The memTable also can point to other memTable's which would be
 * created if multiple TSP contexts were opened.
 *
 */

struct memEntry {
	void *memPointer;
	struct memEntry *nextEntry;
};

struct memTable {
	TSS_HCONTEXT tspContext;
	struct memEntry *entries;
	struct memTable *nextTable;
};

MUTEX_DECLARE_INIT(memtable_lock);

struct memTable *SpiMemoryTable = NULL;

#endif


<|start_filename|>src/include/tss/tcpa_struct.h<|end_filename|>

#ifndef __TCPA_STRUCT_H__
#define __TCPA_STRUCT_H__

#warning including deprecated header file tcpa_struct.h

#endif


<|start_filename|>src/tcs/tcsi_context.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */


#include <stdlib.h>
#include <stdio.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"


TSS_RESULT
TCS_OpenContext_Internal(TCS_CONTEXT_HANDLE * hContext)	/* out  */
{
	*hContext = make_context();
	if (*hContext == 0)
		return TCSERR(TSS_E_OUTOFMEMORY);

	return TSS_SUCCESS;
}

TSS_RESULT
TCS_CloseContext_Internal(TCS_CONTEXT_HANDLE hContext)	/* in */
{
	TSS_RESULT result;

	LogDebug("Closing context %.8X", hContext);

	if ((result = ctx_verify_context(hContext)))
		return result;

	destroy_context(hContext);

	/* close all auth handles associated with hContext */
	auth_mgr_close_context(hContext);

	KEY_MGR_ref_count();

	LogDebug("Context %.8X closed", hContext);
	return TSS_SUCCESS;
}

TSS_RESULT
TCS_FreeMemory_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			BYTE *pMemory)			/* in */
{
	free(pMemory);

	return TSS_SUCCESS;
}


<|start_filename|>src/tspi/tsp_maint.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"

#ifdef TSS_BUILD_TRANSPORT
TSS_RESULT
Transport_CreateMaintenanceArchive(TSS_HCONTEXT tspContext,	/* in */
				   TSS_BOOL generateRandom,	/* in */
				   TPM_AUTH * ownerAuth,	/* in, out */
				   UINT32 * randomSize,	/* out */
				   BYTE ** random,	/* out */
				   UINT32 * archiveSize,	/* out */
				   BYTE ** archive)	/* out */
{
	UINT64 offset;
	TSS_RESULT result;
	UINT32 handlesLen = 0, decLen;
	BYTE *dec;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_CreateMaintenanceArchive,
						    sizeof(TSS_BOOL), (BYTE *)&generateRandom, NULL,
						    &handlesLen, NULL, ownerAuth, NULL, &decLen,
						    &dec)))
		return result;

	offset = 0;
	Trspi_UnloadBlob_UINT32(&offset, randomSize, dec);
	if (*randomSize > 0) {
		if ((*random = malloc(*randomSize)) == NULL) {
			*randomSize = 0;
			free(dec);
			LogError("malloc of %u bytes failed", *randomSize);
			return TSPERR(TSS_E_OUTOFMEMORY);
		}
		Trspi_UnloadBlob(&offset, *randomSize, dec, *random);
	}

	Trspi_UnloadBlob_UINT32(&offset, archiveSize, dec);
	if ((*archive = malloc(*archiveSize)) == NULL) {
		free(*random);
		*random = NULL;
		*randomSize = 0;
		free(dec);
		LogError("malloc of %u bytes failed", *archiveSize);
		*archiveSize = 0;
		return TSPERR(TSS_E_OUTOFMEMORY);
	}
	Trspi_UnloadBlob(&offset, *archiveSize, dec, *archive);
	free(dec);

	return result;
}

TSS_RESULT
Transport_LoadMaintenanceArchive(TSS_HCONTEXT tspContext,	/* in */
				 UINT32 dataInSize,	/* in */
				 BYTE * dataIn, /* in */
				 TPM_AUTH * ownerAuth,	/* in, out */
				 UINT32 * dataOutSize,	/* out */
				 BYTE ** dataOut)	/* out */
{
	UINT64 offset;
	TSS_RESULT result;
	UINT32 handlesLen = 0, decLen;
	BYTE *dec;


	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_LoadMaintenanceArchive,
						    dataInSize, dataIn, NULL, &handlesLen, NULL,
						    ownerAuth, NULL, &decLen, &dec)))
		return result;

	offset = 0;
	Trspi_UnloadBlob_UINT32(&offset, dataOutSize, dec);

	/* sacrifice 4 bytes */
	*dataOut = &dec[offset];

	return result;
}

TSS_RESULT
Transport_KillMaintenanceFeature(TSS_HCONTEXT tspContext,	/* in */
				 TPM_AUTH * ownerAuth)	/* in, out */
{
	TSS_RESULT result;
	UINT32 handlesLen = 0;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	return obj_context_transport_execute(tspContext, TPM_ORD_KillMaintenanceFeature, 0, NULL,
					     NULL, &handlesLen, NULL, ownerAuth, NULL, NULL, NULL);
}

TSS_RESULT
Transport_LoadManuMaintPub(TSS_HCONTEXT tspContext,	/* in */
			   TCPA_NONCE antiReplay,	/* in */
			   UINT32 PubKeySize,	/* in */
			   BYTE * PubKey,	/* in */
			   TCPA_DIGEST * checksum)	/* out */
{
	UINT64 offset;
	TSS_RESULT result;
	UINT32 handlesLen = 0, dataLen, decLen;
	BYTE *data, *dec;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	dataLen = sizeof(TCPA_NONCE) + PubKeySize;
	if ((data = malloc(dataLen)) == NULL) {
		LogError("malloc of %u bytes failed", dataLen);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	offset = 0;
	Trspi_LoadBlob(&offset, TPM_SHA1_160_HASH_LEN, data, antiReplay.nonce);
	Trspi_LoadBlob(&offset, PubKeySize, data, PubKey);

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_LoadManuMaintPub,
						    dataLen, data, NULL, &handlesLen, NULL, NULL,
						    NULL, &decLen, &dec))) {
		free(data);
		return result;
	}
	free(data);

	offset = 0;
	Trspi_UnloadBlob_DIGEST(&offset, dec, checksum);
	free(dec);

	return result;
}

TSS_RESULT
Transport_ReadManuMaintPub(TSS_HCONTEXT tspContext,	/* in */
			   TCPA_NONCE antiReplay,	/* in */
			   TCPA_DIGEST * checksum)	/* out */
{
	UINT64 offset;
	TSS_RESULT result;
	UINT32 handlesLen = 0, decLen;
	BYTE *dec;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_ReadManuMaintPub,
						    sizeof(TCPA_NONCE), antiReplay.nonce, NULL,
						    &handlesLen, NULL, NULL, NULL, &decLen,
						    &dec)))
		return result;

	offset = 0;
	Trspi_UnloadBlob_DIGEST(&offset, dec, checksum);
	free(dec);

	return result;
}
#endif



<|start_filename|>src/tcs/tcsi_audit.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_utils.h"
#include "tcslog.h"
#include "req_mgr.h"

TSS_RESULT
TCSP_SetOrdinalAuditStatus_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
				    TPM_AUTH *ownerAuth,		/* in/out */
				    UINT32 ulOrdinal,			/* in */
				    TSS_BOOL bAuditState)		/* in */
{
	TSS_RESULT result;
	UINT64 offset = 0;
	UINT32 paramSize;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebugFn("Enter");

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_SetOrdinalAuditStatus, &offset, txBlob, ulOrdinal,
				    bAuditState, ownerAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	offset = 10;
	result = UnloadBlob_Header(txBlob, &paramSize);

	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_SetOrdinalAuditStatus, txBlob, paramSize, ownerAuth);
	}

	LogResult("SetOrdinalAuditStatus", result);

done:
	auth_mgr_release_auth(ownerAuth, NULL, hContext);

	return result;
}

TSS_RESULT
TCSP_GetAuditDigest_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			     UINT32 startOrdinal,		/* in */
			     TPM_DIGEST *auditDigest,		/* out */
			     UINT32 *counterValueSize,		/* out */
			     BYTE **counterValue,		/* out */
			     TSS_BOOL *more,			/* out */
			     UINT32 *ordSize,			/* out */
			     UINT32 **ordList)			/* out */
{
	TSS_RESULT result;
	UINT64 offset = 0;
	UINT32 paramSize;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebugFn("Enter");

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_GetAuditDigest, &offset, txBlob, startOrdinal, NULL)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		if ((result = tpm_rsp_parse(TPM_ORD_GetAuditDigest, txBlob, paramSize, auditDigest,
					    counterValueSize, counterValue, more, ordSize,
					    ordList)))
			goto done;

		/* ordSize is returned from the TPM as the number of bytes in ordList
		   so ordSize needs to be converted to comply with the TSS spec which
		   returns the number of ordinals contained in ordList */
		*ordSize = *ordSize / sizeof(UINT32);
	}

	LogResult("GetAuditDigest", result);

done:
	return result;
}

TSS_RESULT
TCSP_GetAuditDigestSigned_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
				   TCS_KEY_HANDLE keyHandle,	/* in */
				   TSS_BOOL closeAudit,		/* in */
				   TPM_NONCE antiReplay,	/* in */
				   TPM_AUTH *privAuth,		/* in/out */
				   UINT32 *counterValueSize,	/* out */
				   BYTE **counterValue,		/* out */
				   TPM_DIGEST *auditDigest,	/* out */
				   TPM_DIGEST *ordinalDigest,	/* out */
				   UINT32 *sigSize,		/* out */
				   BYTE **sig)			/* out */
{
	TSS_RESULT result;
	TCPA_KEY_HANDLE keySlot;
	UINT64 offset = 0;//, old_offset;
	UINT32 paramSize;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebugFn("Enter");

	if ((result = ctx_verify_context(hContext)))
		return result;

	if (privAuth != NULL)
		if ((result = auth_mgr_check(hContext, &privAuth->AuthHandle)))
			return result;

	if ((result = ensureKeyIsLoaded(hContext, keyHandle, &keySlot)))
		goto done;

	if ((result = tpm_rqu_build(TPM_ORD_GetAuditDigestSigned, &offset, txBlob, keySlot,
				    closeAudit, antiReplay.nonce, privAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_GetAuditDigestSigned, txBlob, paramSize,
				       counterValueSize, counterValue, auditDigest, ordinalDigest,
				       sigSize, sig, privAuth);
	}

	LogResult("GetAuditDigestSigned", result);

done:
	auth_mgr_release_auth(privAuth, NULL, hContext);

	return result;
}


<|start_filename|>src/tcs/tcsi_changeauth.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcsps.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "req_mgr.h"
#include "tcsd_wrap.h"
#include "tcsd.h"


TSS_RESULT
TCSP_ChangeAuth_Internal(TCS_CONTEXT_HANDLE contextHandle,	/* in */
			 TCS_KEY_HANDLE parentHandle,	/* in */
			 TCPA_PROTOCOL_ID protocolID,	/* in */
			 TCPA_ENCAUTH newAuth,	/* in */
			 TCPA_ENTITY_TYPE entityType,	/* in */
			 UINT32 encDataSize,	/* in */
			 BYTE *encData,	/* in */
			 TPM_AUTH *ownerAuth,	/* in, out */
			 TPM_AUTH *entityAuth,	/* in, out */
			 UINT32 *outDataSize,	/* out */
			 BYTE **outData	/* out */
    )
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	TCPA_KEY_HANDLE keySlot;
	TCS_KEY_HANDLE tcsKeyHandleToEvict;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering Changeauth");
	if ((result = ctx_verify_context(contextHandle)))
		goto done;

	if ((result = auth_mgr_check(contextHandle, &ownerAuth->AuthHandle)))
		goto done;
	if ((result = auth_mgr_check(contextHandle, &entityAuth->AuthHandle)))
		goto done;

	if ((result = ensureKeyIsLoaded(contextHandle, parentHandle, &keySlot)))
		goto done;

	if ((result = tpm_rqu_build(TPM_ORD_ChangeAuth, &offset, txBlob, keySlot, protocolID,
				    newAuth.authdata, entityType, encDataSize, encData, ownerAuth,
				    entityAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_ChangeAuth, txBlob, paramSize, outDataSize, outData,
				       ownerAuth, entityAuth);

		/* if the malloc above failed, terminate the 2 new auth handles and exit */
		if (result)
			goto done;

		/*
		 * Check if ET is a key.  If it is, we need to
		 *	1 - Evict the key if loaded
		 *	2 - update the mem cache entry
		 */
		if (entityType == TCPA_ET_KEYHANDLE || entityType == TCPA_ET_KEY) {
			LogDebug("entity type is a key. Check if mem cache needs updating...");
			tcsKeyHandleToEvict = mc_get_handle_by_encdata(encData);
			LogDebug("tcsKeyHandle being evicted is %.8X", tcsKeyHandleToEvict);
			/*---	If it was found in knowledge, replace it */
			if (tcsKeyHandleToEvict != 0) {
				internal_EvictByKeySlot(keySlot);
				mc_update_encdata(encData, *outData);
			}

		}
	}
	LogResult("ChangeAuth", result);
done:
	auth_mgr_release_auth(ownerAuth, entityAuth, contextHandle);
	return result;
}

TSS_RESULT
TCSP_ChangeAuthOwner_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			      TCPA_PROTOCOL_ID protocolID,	/* in */
			      TCPA_ENCAUTH newAuth,	/* in */
			      TCPA_ENTITY_TYPE entityType,	/* in */
			      TPM_AUTH * ownerAuth	/* in, out */
    )
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering ChangeAuthOwner");

	if ((result = ctx_verify_context(hContext)))
		goto done;

	if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
		goto done;

	if ((result = tpm_rqu_build(TPM_ORD_ChangeAuthOwner, &offset, txBlob, protocolID,
				    newAuth.authdata, entityType, ownerAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_ChangeAuthOwner, txBlob, paramSize, ownerAuth);
	}

	LogResult("ChangeAuthOwner", result);
done:
	auth_mgr_release_auth(ownerAuth, NULL, hContext);
	return result;
}

TSS_RESULT
TCSP_ChangeAuthAsymStart_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
				  TCS_KEY_HANDLE idHandle,	/* in */
				  TCPA_NONCE antiReplay,	/* in */
				  UINT32 KeySizeIn,	/* in */
				  BYTE * KeyDataIn,	/* in */
				  TPM_AUTH * pAuth,	/* in, out */
				  UINT32 * KeySizeOut,	/* out */
				  BYTE ** KeyDataOut,	/* out */
				  UINT32 * CertifyInfoSize,	/* out */
				  BYTE ** CertifyInfo,	/* out */
				  UINT32 * sigSize,	/* out */
				  BYTE ** sig,	/* out */
				  TCS_KEY_HANDLE * ephHandle	/* out */
    )
{
#if 0
#warning Locking trouble in evictFirstKey
	UINT64 offset;
	UINT32 paramSize;
	TSS_RESULT result;
	UINT32 keySlot;
	TCPA_CERTIFY_INFO certifyInfo;
	TSS_KEY tempKey;
	UINT32 tempSize;
	TCPA_KEY_PARMS keyParmsContainer;
	TSS_BOOL canLoad;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering ChangeAuthAsymStart");
	if ((result = ctx_verify_context(hContext)))
		goto done;

	if (pAuth != NULL) {
		LogDebug("Auth Command");
		if ((result = auth_mgr_check(hContext, pAuth->AuthHandle)))
			goto done;
	} else {
		LogDebug("No Auth");
	}

	if ((result = ensureKeyIsLoaded(hContext, idHandle, &keySlot)))
		goto done;

	LogDebug("Checking for room to load the eph key");
	offset = 0;
	if ((result = UnloadBlob_KEY_PARMS(&offset, KeyDataIn, &keyParmsContainer)))
		goto done;

	/* if we can't load the key, evict keys until we can */
	if ((result = canILoadThisKey(&keyParmsContainer, &canLoad)))
		goto done;

	while (canLoad == FALSE) {
		/* Evict a key that isn't the parent */
		if ((result = evictFirstKey(idHandle)))
			goto done;

		if ((result = canILoadThisKey(&keyParmsContainer, &canLoad)))
			goto done;
	}

	offset = 10;
	LoadBlob_UINT32(&offset, keySlot, txBlob);
	LoadBlob(&offset, TCPA_NONCE_SIZE, txBlob, antiReplay.nonce);
/*	LoadBlob_KEY_PARMS( &offset, txBlob, &tempKeyParms ); */
/*	LoadBlob_UINT32( &offset, KeySizeIn, txBlob ); */
	LoadBlob(&offset, KeySizeIn, txBlob, KeyDataIn);

	if (pAuth != NULL) {
		LoadBlob_Auth(&offset, txBlob, pAuth);
		LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, offset,
				TPM_ORD_ChangeAuthAsymStart, txBlob);
	} else {
		LoadBlob_Header(TPM_TAG_RQU_COMMAND, offset,
				TPM_ORD_ChangeAuthAsymStart, txBlob);
	}

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	offset = 10;
	result = UnloadBlob_Header(txBlob, &paramSize);
	if (result == 0) {
		UnloadBlob_CERTIFY_INFO(&offset, txBlob, &certifyInfo);
		*CertifyInfoSize = offset - 10;
		*CertifyInfo = malloc(*CertifyInfoSize);
		if (*CertifyInfo == NULL) {
			LogError("malloc of %u bytes failed.", *CertifyInfoSize);
			result = TCSERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		memcpy(*CertifyInfo, &txBlob[offset - *CertifyInfoSize],
		       *CertifyInfoSize);
		UnloadBlob_UINT32(&offset, sigSize, txBlob);
		*sig = malloc(*sigSize);
		if (*sig == NULL) {
			LogError("malloc of %u bytes failed.", *sigSize);
			result = TCSERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		UnloadBlob(&offset, *sigSize, txBlob, *sig);
		UnloadBlob_UINT32(&offset, ephHandle, txBlob);
		tempSize = offset;
		UnloadBlob_TSS_KEY(&offset, txBlob, &tempKey);
		*KeySizeOut = offset - tempSize;
		*KeyDataOut = malloc(*KeySizeOut);
		if (*KeyDataOut == NULL) {
			LogError("malloc of %u bytes failed.", *KeySizeOut);
			result = TCSERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		memcpy(*KeyDataOut, &txBlob[offset - *KeySizeOut], *KeySizeOut);
		if (pAuth != NULL)
			UnloadBlob_Auth(&offset, txBlob, pAuth);
	}

	LogResult("ChangeAuthAsymStart", result);
done:
	auth_mgr_release_auth(pAuth, NULL, hContext);
	return result;
#else
	return TCSERR(TSS_E_NOTIMPL);
#endif
}

TSS_RESULT
TCSP_ChangeAuthAsymFinish_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
				   TCS_KEY_HANDLE parentHandle,	/* in */
				   TCS_KEY_HANDLE ephHandle,	/* in */
				   TCPA_ENTITY_TYPE entityType,	/* in */
				   TCPA_HMAC newAuthLink,	/* in */
				   UINT32 newAuthSize,	/* in */
				   BYTE * encNewAuth,	/* in */
				   UINT32 encDataSizeIn,	/* in */
				   BYTE * encDataIn,	/* in */
				   TPM_AUTH * ownerAuth,	/* in, out */
				   UINT32 * encDataSizeOut,	/* out */
				   BYTE ** encDataOut,	/* out */
				   TCPA_SALT_NONCE * saltNonce,	/* out */
				   TCPA_DIGEST * changeProof	/* out */
    )
{
#if 0
	UINT64 offset;
	UINT32 paramSize;
	TSS_RESULT result;
	UINT32 keySlot;
#if 0
	TCPA_CERTIFY_INFO certifyInfo;
	TSS_KEY tempKey;
	UINT32 tempSize;
	TSS_UUID *uuidKeyToEvict;
#endif
	TCS_KEY_HANDLE tcsKeyHandleToEvict;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering ChangeAuthAsymFinish");
	if ((result = ctx_verify_context(hContext)))
		goto done;

	if (ownerAuth != NULL) {
		LogDebug("Auth used");
		if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
			goto done;
	} else {
		LogDebug("No Auth");
	}
	if ((result = ensureKeyIsLoaded(hContext, parentHandle, &keySlot)))
		goto done;

	offset = 10;
	LoadBlob_UINT32(&offset, keySlot, txBlob);
	LoadBlob_UINT32(&offset, ephHandle, txBlob);
	LoadBlob_UINT16(&offset, entityType, txBlob);
	LoadBlob(&offset, 20, txBlob, newAuthLink.digest);
	LoadBlob_UINT32(&offset, newAuthSize, txBlob);
	LoadBlob(&offset, newAuthSize, txBlob, encNewAuth);
	LoadBlob_UINT32(&offset, encDataSizeIn, txBlob);
	LoadBlob(&offset, encDataSizeIn, txBlob, encDataIn);

	if (ownerAuth != NULL) {
		LoadBlob_Auth(&offset, txBlob, ownerAuth);
		LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, offset,
				TPM_ORD_ChangeAuthAsymFinish, txBlob);
	} else {
		LoadBlob_Header(TPM_TAG_RQU_COMMAND, offset,
				TPM_ORD_ChangeAuthAsymFinish, txBlob);
	}

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	offset = 10;
	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		UnloadBlob_UINT32(&offset, encDataSizeOut, txBlob);
		*encDataOut = calloc(1, *encDataSizeOut);
		if (*encDataOut == NULL) {
			LogError("malloc of %u bytes failed.", *encDataSizeOut);
			result = TCSERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		UnloadBlob(&offset, *encDataSizeOut, txBlob, *encDataOut);
		UnloadBlob(&offset, 20, txBlob, saltNonce->nonce);
		UnloadBlob(&offset, 20, txBlob, changeProof->digest);
		if (ownerAuth != NULL)
			UnloadBlob_Auth(&offset, txBlob, ownerAuth);

		/* Check if ET is a key.  If it is, we need to
		 *	1 - Evict the key if loaded
		 *	2 - update the mem cache entry
		 */
		if (entityType == TCPA_ET_KEYHANDLE ||
		    entityType == TCPA_ET_KEY) {
			tcsKeyHandleToEvict = mc_get_handle_by_encdata(encDataIn);
			/* If it was found in mem cache, replace it */
			if (tcsKeyHandleToEvict != 0) {
				key_mgr_evict(hContext, tcsKeyHandleToEvict);
				mc_update_encdata(encDataIn, *encDataOut);
			}
		}
	}

	LogResult("ChangeAuthAsymFinish", result);
done:
	auth_mgr_release_auth(ownerAuth, NULL, hContext);
	return result;
#else
	return TCSERR(TSS_E_NOTIMPL);
#endif
}



<|start_filename|>src/tcs/tcs_migration.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2006
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcsps.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "req_mgr.h"
#include "tcsd_wrap.h"
#include "tcsd.h"

TSS_RESULT
UnloadBlob_MIGRATIONKEYAUTH(UINT64 *offset, BYTE *blob, TCPA_MIGRATIONKEYAUTH *mkAuth)
{
	TSS_RESULT result;

	if (!mkAuth) {
		if ((result = UnloadBlob_PUBKEY(offset, blob, NULL)))
			return result;

		UnloadBlob_UINT16(offset, NULL, blob);
		UnloadBlob(offset, 20, blob, NULL);

		return TSS_SUCCESS;
	}

	if ((result = UnloadBlob_PUBKEY(offset, blob, &mkAuth->migrationKey)))
		return result;

	UnloadBlob_UINT16(offset, &mkAuth->migrationScheme, blob);
	UnloadBlob(offset, 20, blob, mkAuth->digest.digest);

	return result;
}


<|start_filename|>src/include/tddl.h<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004, 2005
 *
 */


#ifndef _TDDL_H_
#define _TDDL_H_

#include <threads.h>
#include "tcsd_wrap.h"
#include "tcsd.h"

struct tpm_device_node {
	char *path;
#define TDDL_TRANSMIT_IOCTL	1
#define TDDL_TRANSMIT_RW	2
	int transmit;
	int fd;
};

#define TDDL_TXBUF_SIZE		2048
#define TDDL_UNDEF		-1

TSS_RESULT Tddli_Open(void);

TSS_RESULT Tddli_TransmitData(BYTE *pTransmitBuf,
			UINT32 TransmitBufLen,
			BYTE *pReceiveBuf,
			UINT32 *pReceiveBufLen);

TSS_RESULT Tddli_Close(void);

#endif


<|start_filename|>src/tspi/tsp_get_flags.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <errno.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


TSS_RESULT
get_tpm_flags(TSS_HCONTEXT tspContext, TSS_HTPM hTPM, UINT32 *volFlags, UINT32 *nonVolFlags)
{
	TCPA_DIGEST digest;
	TPM_AUTH auth;
	TCPA_VERSION version;
	TSS_RESULT result;
	TSS_HPOLICY hPolicy;
	Trspi_HashCtx hashCtx;

	if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hPolicy)))
		return result;

	/* do an owner authorized get capability call */
	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_GetCapabilityOwner);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
		return result;

	if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_GetCapabilityOwner, hPolicy, FALSE,
					      &digest, &auth)))
		return result;

	if ((result = TCS_API(tspContext)->GetCapabilityOwner(tspContext, &auth, &version,
							      nonVolFlags, volFlags)))
		return result;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, result);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_GetCapabilityOwner);
	result |= Trspi_Hash_VERSION(&hashCtx, (TSS_VERSION *)&version);
	result |= Trspi_Hash_UINT32(&hashCtx, *nonVolFlags);
	result |= Trspi_Hash_UINT32(&hashCtx, *volFlags);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
		return result;

	return obj_policy_validate_auth_oiap(hPolicy, &digest, &auth);
}


<|start_filename|>src/include/tcs_int_literals.h<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */

#ifndef _TCS_INT_LITERALS_H_
#define _TCS_INT_LITERALS_H_

#define	TPM_VENDOR_UNKNOWN  0
#define TPM_VENDOR_ATMEL	1
#define TPM_VENDOR_IFX		2
#define TPM_VENDOR_NATL		3

#define TPM_PARAMSIZE_OFFSET 0x02

#define NULL_TPM_HANDLE	((TCPA_KEY_HANDLE)-1)
#define NULL_TCS_HANDLE	((TCS_KEY_HANDLE)-1)
#define SRK_TPM_HANDLE	(0x40000000)
#define EK_TPM_HANDLE	(0x40000001)

#define FIXED_TCS_MANUFACTURER "IBM "

#endif


<|start_filename|>src/tspi/daa/daa_issuer/prime_gen.c<|end_filename|>
/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004, 2005
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "bi.h"
#include "list.h"
#include "tsplog.h"

static unsigned long *primes;
static int primes_length;

/* Generates a random number of bit_length bit length. The first two bits and the last bit of this
 * number are always set, therefore the number is odd and >= (2^(bit_length-1)+2^(bit_length-2)+1)
 *
 * bit_length: The length of the number to be generated, in bits
 * return: a random number of bitLength bit length with first and last bits set
 */
void
random_odd_bi(bi_ptr bi, int bit_length)
{
	if (bit_length > 0) {
		bi_urandom(bi, bit_length);
		//bi_generate_prime(bi, bit_length);
		bi_setbit(bi, 0);
		bi_setbit(bi, bit_length - 1);
		bi_setbit(bi, bit_length - 2);
	}
}

/* This method generates small prime numbers up to a specified bounds using the Sieve of
 * Eratosthenes algorithm.
 *
 * prime_bound: the upper bound for the primes to be generated
 * starting_prime: the first prime in the list of primes that is returned
 * return: list of primes up to the specified bound. Each prime is of type bi_ptr
 */
void
generate_small_primes(int prime_bound, int starting_prime)
{
	list_ptr res;
	int length;
	int *is_primes;
	int i;
	int k;
	int prime;
	node_t *current;

	primes_length = 0;
	res = list_new();
	if (allocs == NULL) {
		LogError("malloc of list failed");
		return;
	}
	if ((prime_bound <= 1) || (starting_prime > prime_bound))
		return;

	if (starting_prime <= 2) {
		starting_prime = 2;
		list_add(res, bi_2);
	}
	length = (prime_bound - 1) >> 1; // length = (prime_bound -1) / 2;
	is_primes = (int *)malloc(sizeof(int)*length);
	if (is_primes == NULL) {
		LogError("malloc of %zd bytes failed", sizeof(int) * length);
		return;
	}

	for (i = 0; i < length; i++)
		is_primes[i] = 1;

	for (i = 0; i < length; i++) {
		if (is_primes[i] == 1) {
			prime = 2 * i + 3;
			for (k = i + prime; k < length; k+= prime)
				is_primes[k] = 0;

			if (prime >= starting_prime) {
				list_add(res, (void *)prime);
				primes_length++;
			}
		}
	}
	// converti the list to a table
	current = res->head; // go to first node
	primes  = (unsigned long *)malloc(sizeof(unsigned long) * primes_length);
	if (primes == NULL) {
		LogError("malloc of %d bytes failed",
			sizeof(unsigned long)*primes_length);
		return;
	}

	i = 0;
	while (current != NULL) {
		primes[i++] = (unsigned long)current->obj;
		current = current->next; // traverse through the list
	}

	free(is_primes);
	list_freeall(res);
}

void
prime_init()
{
	generate_small_primes(16384, 3);
}

/* Test whether the provided pDash or p = 2*pDash + 1 are divisible by any of the small primes
 * saved in the listOfSmallPrimes. A limit for the largest prime to be tested against can be
 * specified, but it will be ignored if it exeeds the number of precalculated primes.
 *
 * p_dash: the number to be tested (p_dash)
 * prime_bound: the limit for the small primes to be tested against.
 */
static int
test_small_prime_factors(const bi_ptr p_dash, const unsigned long prime_bound)
{
	int sievePassed = 1;
	unsigned long r;
	unsigned long small_prime;
	bi_t temp; bi_new(temp);

	small_prime = 1;
	int i = 0;
	while (i < primes_length && small_prime < prime_bound ) {
		small_prime = primes[i++];
		// r = p_dash % small_prime
		bi_mod_si(temp, p_dash, small_prime);
		r = bi_get_si(temp);
		// test if pDash = 0 (mod smallPrime)
		if (r == 0) {
			sievePassed = 0;
			break;
		}
		// test if p = 0 (mod smallPrime) (or r == smallPrime - r - 1)
		if (r == (small_prime - r - 1)) {
			sievePassed = 0;
			break;
		}
	}
	bi_free(temp);

	return sievePassed;
}

/* Tests if a is a Miller-Rabin witness for n
 *
 * a: number which is supposed to be the witness
 * n: number to be tested against
 * return: true if a is Miller-Rabin witness for n, false otherwise
 */
int
is_miller_rabin_witness(const bi_ptr a, const bi_ptr n)
{
	bi_t n_1;
	bi_t temp;
	bi_t _2_power_t;
	bi_t u;
	bi_t x0;
	bi_t x1;
	int t = -1;
	int i;

	bi_new(n_1);
	bi_new(temp);
	bi_new(_2_power_t);
	bi_new(u);

	// n1 = n - 1
	bi_sub_si(n_1, n, 1);

	// test if n-1 = 2^t*u with t >= 1 && u even
	do {
		t++;
		// _2_power_t = bi_1 << t  ( ==  2 ^ t)
		bi_shift_left(_2_power_t, bi_1, t);
		// u = n_1 / (2 ^ t)
		bi_div(u, n_1, _2_power_t);
	} while (bi_equals_si(bi_mod(temp, u, bi_2), 0));

	bi_new(x0);
	bi_new(x1);

	// x1 = (a ^ u ) % n
	bi_mod_exp(x1, a, u, n);

	// finished to use u, _2_power_t and temp
	bi_free(u);
	bi_free(_2_power_t);
	bi_free(temp);
	for (i = 0; i < t; i++) {
		bi_set(x0, x1);

		// x1 = (x0 ^ 2) % n
		bi_mod_exp(x1, x0, bi_2, n);
		if (bi_equals_si(x1, 1) && !bi_equals_si(x0, 1) && !bi_equals(x0, n_1) != 0) {
			bi_free(x0);
			bi_free(x1);
			bi_free(n_1);
			return 1;
		}
	}

	bi_free(x0);
	bi_free(x1);
	bi_free(n_1);

	if (!bi_equals(x1, bi_1))
		return 1;

	return 0;
}

bi_ptr
compute_trivial_safe_prime(bi_ptr result, int bit_length)
{
	LogDebugFn("Enter");
	do {
		bi_generate_prime(result, bit_length-1);
		bi_shift_left(result, result, 1);	// result := result << 1
		bi_add_si(result, result, 1);	// result := result -1
		if (getenv("TSS_DEBUG_OFF") == NULL) {
			printf(".");
			fflush(stdout);
		}
	} while (bi_is_probable_prime(result)==0);

	return result;
}

/* The main method to compute a random safe prime of the specified bit length.
 * IMPORTANT: The computer prime will have two first bits and the last bit set to 1 !!
 * i.e. > (2^(bitLength-1)+2^(bitLength-2)+1). This is done to be sure that if two primes of
 * bitLength n are multiplied, the result will have the bitLenght of 2*n exactly This
 * implementation uses the algorithm proposed by <NAME> and <NAME> in "Signature
 * Schemes Based on the strong RSA Assumption" May 9, 2000.
 *
 * bitLength: the bit length of the safe prime to be computed.
 * return: a number which is considered to be safe prime
 */
bi_ptr
compute_safe_prime(bi_ptr p, int bit_length)
{
	bi_ptr p_dash;
	bi_ptr temp_p;
	bi_ptr p_minus_1;
	int stop;
	unsigned long prime_bound;

	LogDebug("compute Safe Prime: length: %d bits\n", bit_length);

	p_dash = bi_new_ptr();
	temp_p = bi_new_ptr();
	p_minus_1 = bi_new_ptr();

	/* some heuristic checks to limit the number of small primes to check against and the
	 * number of Miller-Rabin primality tests at the end */
	if (bit_length <= 256) {
		prime_bound = 768;
	} else if (bit_length <= 512) {
		prime_bound = 3072;
	} else if (bit_length <= 768) {
		prime_bound = 6144;
	} else if (bit_length <= 1024) {
		prime_bound = 1024;
	} else {
		prime_bound = 16384;
	}

	do {
		stop = 0;
		/* p_dash = generated random with basic bit settings (odd) */
		random_odd_bi(p_dash, bit_length - 1);

		if (test_small_prime_factors(p_dash, prime_bound) == 0)  {
			LogDebugFn("1");
			continue;
		}
		/* test if p_dash or p are divisible by some small primes */
		if (is_miller_rabin_witness(bi_2, p_dash)) {
			LogDebugFn("2");
			continue;
		}
		/* test if 2^(pDash) = +1/-1 (mod p)
		 * bi can not handle negative operation, we compare to (p-1) instead of -1
		 * calculate p = 2*pDash+1 -> (pDash << 1) + 1
		 */
		bi_shift_left(p, p_dash, 1);
		bi_add(p, p, bi_1);

		// p_minus_1:= p - 1
		bi_sub(p_minus_1, p, bi_1);

		//  temp_p := ( 2 ^ p_dash ) mod p
		bi_mod_exp(temp_p, bi_2, p_dash, p);
		if (!bi_equals_si(temp_p, 1)  && !bi_equals(temp_p, p_minus_1) ) {
			LogDebugFn("3");
			continue;
		}

		// test if pDash or p are divisible by some small primes
		if (is_miller_rabin_witness(bi_2, p_dash)) {
			LogDebugFn("4");
			continue;
		}
		// test the library dependent probable_prime
		if (bi_is_probable_prime(p_dash))
			stop = 1;
	} while (stop == 0);

	bi_free(p_minus_1);
	bi_free(temp_p);
	bi_free(p_dash);

	LogDebug("found Safe Prime: %s bits", bi_2_hex_char(p));

	return p;
}


<|start_filename|>src/tspi/rpc/tcstp/rpc_maint.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "hosttable.h"
#include "tcsd_wrap.h"
#include "obj.h"
#include "rpc_tcstp_tsp.h"


TSS_RESULT
RPC_CreateMaintenanceArchive_TP(struct host_table_entry *hte,
					     TSS_BOOL generateRandom,	/* in */
					     TPM_AUTH * ownerAuth,	/* in, out */
					     UINT32 * randomSize,	/* out */
					     BYTE ** random,	/* out */
					     UINT32 * archiveSize,	/* out */
					     BYTE ** archive	/* out */
    ) {
	TSS_RESULT result;

	initData(&hte->comm, 3);
	hte->comm.hdr.u.ordinal = TCSD_ORD_CREATEMAINTENANCEARCHIVE;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_BOOL, 1, &generateRandom, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_AUTH, 2, ownerAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		if (getData(TCSD_PACKET_TYPE_UINT32, 1, randomSize, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);

		if (*randomSize > 0) {
			*random = malloc(*randomSize);
			if (*random == NULL) {
				LogError("malloc of %u bytes failed.", *randomSize);
				result = TSPERR(TSS_E_OUTOFMEMORY);
				goto done;
			}

			if (getData(TCSD_PACKET_TYPE_PBYTE, 2, *random, *randomSize, &hte->comm)) {
				free(*random);
				result = TSPERR(TSS_E_INTERNAL_ERROR);
				goto done;
			}
		} else {
			*random = NULL;
		}

		/* Assume all elements are in the list, even when *randomSize == 0. */
		if (getData(TCSD_PACKET_TYPE_UINT32, 3, archiveSize, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);

		if (*archiveSize > 0) {
			*archive = malloc(*archiveSize);
			if (*archive == NULL) {
				free(*random);
				LogError("malloc of %u bytes failed.", *archiveSize);
				result = TSPERR(TSS_E_OUTOFMEMORY);
				goto done;
			}

			if (getData(TCSD_PACKET_TYPE_PBYTE, 4, *archive, *archiveSize, &hte->comm)) {
				free(*random);
				free(*archive);
				result = TSPERR(TSS_E_INTERNAL_ERROR);
				goto done;
			}
		} else {
			*archive = NULL;
		}
	}
done:
	return result;
}

TSS_RESULT
RPC_LoadMaintenanceArchive_TP(struct host_table_entry *hte,
					   UINT32 dataInSize,	/* in */
					   BYTE * dataIn,	/* in */
					   TPM_AUTH * ownerAuth,	/* in, out */
					   UINT32 * dataOutSize,	/* out */
					   BYTE ** dataOut	/* out */
    ) {
	TSS_RESULT result;

	initData(&hte->comm, 4);
	hte->comm.hdr.u.ordinal = TCSD_ORD_LOADMAINTENANCEARCHIVE;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &dataInSize, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 2, &dataIn, dataInSize, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_AUTH, 3, ownerAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		if (getData(TCSD_PACKET_TYPE_UINT32, 1, dataOutSize, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);

		if (*dataOutSize > 0) {
			*dataOut = malloc(*dataOutSize);
			if (*dataOut == NULL) {
				LogError("malloc of %u bytes failed.", *dataOutSize);
				result = TSPERR(TSS_E_OUTOFMEMORY);
				goto done;
			}

			if (getData(TCSD_PACKET_TYPE_PBYTE, 2, *dataOut, *dataOutSize, &hte->comm)) {
				free(*dataOut);
				result = TSPERR(TSS_E_INTERNAL_ERROR);
				goto done;
			}
		} else {
			*dataOut = NULL;
		}
	}
done:
	return result;
}

TSS_RESULT
RPC_KillMaintenanceFeature_TP(struct host_table_entry *hte,
					   TPM_AUTH * ownerAuth	/* in , out */
    ) {
	TSS_RESULT result;

	initData(&hte->comm, 2);
	hte->comm.hdr.u.ordinal = TCSD_ORD_KILLMAINTENANCEFEATURE;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_AUTH, 1, ownerAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
	}

	return result;
}

TSS_RESULT
RPC_LoadManuMaintPub_TP(struct host_table_entry *hte,
				     TCPA_NONCE antiReplay,	/* in */
				     UINT32 PubKeySize,	/* in */
				     BYTE * PubKey,	/* in */
				     TCPA_DIGEST * checksum	/* out */
    ) {
	TSS_RESULT result;

	initData(&hte->comm, 4);
	hte->comm.hdr.u.ordinal = TCSD_ORD_LOADMANUFACTURERMAINTENANCEPUB;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_NONCE, 1, &antiReplay, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 2, &PubKeySize, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 3, PubKey, PubKeySize, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_DIGEST, 0, checksum, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
	}

	return result;
}

TSS_RESULT
RPC_ReadManuMaintPub_TP(struct host_table_entry *hte,
				     TCPA_NONCE antiReplay,	/* in */
				     TCPA_DIGEST * checksum	/* out */
    ) {
	TSS_RESULT result;

	initData(&hte->comm, 2);
	hte->comm.hdr.u.ordinal = TCSD_ORD_READMANUFACTURERMAINTENANCEPUB;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_NONCE, 1, &antiReplay, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_DIGEST, 0, checksum, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
	}

	return result;
}


<|start_filename|>src/include/tss/tcpa_defines.h<|end_filename|>

#ifndef __TCPA_DEFINES_H__
#define __TCPA_DEFINES_H__

#warning including deprecated header file tcpa_defines.h

#endif


<|start_filename|>src/include/tcs_aik.h<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2006-2007
 *
 */

#ifndef _TCS_AIK_H_
#define _TCS_AIK_H_

void get_credential(UINT32, UINT32 *, BYTE **);

#endif


<|start_filename|>src/tcs/tcsi_auth.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcsps.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "req_mgr.h"
#include "tcsd_wrap.h"
#include "tcsd.h"


TSS_RESULT
TCSP_OIAP_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
		   TCS_AUTHHANDLE *authHandle,	/* out */
		   TCPA_NONCE *nonce0)	/* out */
{
	UINT64 offset = 0;
	TSS_RESULT result;
	UINT32 paramSize;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering TCSI_OIAP");

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_OIAP, &offset, txBlob, NULL)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_OIAP, txBlob, paramSize, authHandle, nonce0->nonce);
	}

	LogResult("OIAP", result);
	return result;
}

TSS_RESULT
TCSP_OSAP_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
		   TCPA_ENTITY_TYPE entityType,	/* in */
		   UINT32 entityValue,	/* in */
		   TCPA_NONCE nonceOddOSAP,	/* in */
		   TCS_AUTHHANDLE * authHandle,	/* out */
		   TCPA_NONCE * nonceEven,	/* out */
		   TCPA_NONCE * nonceEvenOSAP)	/* out */
{
	UINT64 offset = 0;
	TSS_RESULT result;
	UINT32 paramSize;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering OSAP");
	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_OSAP, &offset, txBlob, entityType, entityValue,
				    nonceOddOSAP.nonce)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_OSAP, txBlob, paramSize, authHandle,
				       nonceEven->nonce, nonceEvenOSAP->nonce);
	}
	LogResult("OSAP", result);

	return result;
}

TSS_RESULT
internal_TerminateHandle(TCS_AUTHHANDLE handle)
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	if ((result = tpm_rqu_build(TPM_ORD_Terminate_Handle, &offset, txBlob, handle, NULL)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	return UnloadBlob_Header(txBlob, &paramSize);
}



<|start_filename|>src/tspi/tsp_sign.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2007
 *
 */


#include <stdlib.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


#ifdef TSS_BUILD_TRANSPORT
TSS_RESULT
Transport_Sign(TSS_HCONTEXT tspContext,    /* in */
	       TCS_KEY_HANDLE keyHandle,   /* in */
	       UINT32 areaToSignSize,      /* in */
	       BYTE * areaToSign,  /* in */
	       TPM_AUTH * privAuth,        /* in, out */
	       UINT32 * sigSize,   /* out */
	       BYTE ** sig)        /* out */
{
	UINT64 offset;
	TSS_RESULT result;
	UINT32 handlesLen, decLen, dataLen;
	TCS_HANDLE *handles, handle;
	TPM_DIGEST pubKeyHash;
	Trspi_HashCtx hashCtx;
	BYTE *dec, *data;


	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	if ((result = obj_tcskey_get_pubkeyhash(keyHandle, pubKeyHash.digest)))
		return result;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
		return result;

	handlesLen = 1;
	handle = keyHandle;
	handles = &handle;

	dataLen = sizeof(UINT32) + areaToSignSize;
	if ((data = malloc(dataLen)) == NULL) {
		LogError("malloc of %u bytes failed", dataLen);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	offset = 0;
	Trspi_LoadBlob_UINT32(&offset, areaToSignSize, data);
	Trspi_LoadBlob(&offset, areaToSignSize, data, areaToSign);

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Sign, dataLen, data,
						    &pubKeyHash, &handlesLen, &handles,
						    privAuth, NULL, &decLen, &dec))) {
		free(data);
		return result;
	}
	free(data);

	offset = 0;
	Trspi_UnloadBlob_UINT32(&offset, sigSize, dec);

	if ((*sig = malloc(*sigSize)) == NULL) {
		free(dec);
		LogError("malloc of %u bytes failed", *sigSize);
		*sigSize = 0;
		return TSPERR(TSS_E_OUTOFMEMORY);
	}
	Trspi_UnloadBlob(&offset, *sigSize, dec, *sig);

	return result;
}
#endif



<|start_filename|>src/tspi/tsp_changeauth.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <errno.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"
#include "authsess.h"


TSS_RESULT
Trspi_UnloadBlob_STORED_DATA(UINT64 *offset, BYTE *blob, TCPA_STORED_DATA *data)
{
	Trspi_UnloadBlob_TCPA_VERSION(offset, blob, &data->ver);
	Trspi_UnloadBlob_UINT32(offset, &data->sealInfoSize, blob);

	if (data->sealInfoSize > 0) {
		data->sealInfo = malloc(data->sealInfoSize);
		if (data->sealInfo == NULL) {
			LogError("malloc of %d bytes failed.", data->sealInfoSize);
			return TSPERR(TSS_E_OUTOFMEMORY);
		}
		Trspi_UnloadBlob(offset, data->sealInfoSize, blob, data->sealInfo);
	} else {
		data->sealInfo = NULL;
	}

	Trspi_UnloadBlob_UINT32(offset, &data->encDataSize, blob);

	if (data->encDataSize > 0) {
		data->encData = malloc(data->encDataSize);
		if (data->encData == NULL) {
			LogError("malloc of %d bytes failed.", data->encDataSize);
			free(data->sealInfo);
			data->sealInfo = NULL;
			return TSPERR(TSS_E_OUTOFMEMORY);
		}

		Trspi_UnloadBlob(offset, data->encDataSize, blob, data->encData);
	} else {
		data->encData = NULL;
	}

	return TSS_SUCCESS;
}

void
Trspi_LoadBlob_STORED_DATA(UINT64 *offset, BYTE *blob, TCPA_STORED_DATA *data)
{
	Trspi_LoadBlob_TCPA_VERSION(offset, blob, data->ver);
	Trspi_LoadBlob_UINT32(offset, data->sealInfoSize, blob);
	Trspi_LoadBlob(offset, data->sealInfoSize, blob, data->sealInfo);
	Trspi_LoadBlob_UINT32(offset, data->encDataSize, blob);
	Trspi_LoadBlob(offset, data->encDataSize, blob, data->encData);
}

TSS_RESULT
changeauth_owner(TSS_HCONTEXT tspContext,
		 TSS_HOBJECT hObjectToChange,
		 TSS_HOBJECT hParentObject,
		 TSS_HPOLICY hNewPolicy)
{
	TPM_DIGEST digest;
	TSS_RESULT result;
	Trspi_HashCtx hashCtx;
	struct authsess *xsap = NULL;

	if ((result = authsess_xsap_init(tspContext, hObjectToChange, hNewPolicy,
					TSS_AUTH_POLICY_REQUIRED, TPM_ORD_ChangeAuthOwner,
					TPM_ET_OWNER, &xsap)))
		return result;

	/* calculate auth data */
	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthOwner);
	result |= Trspi_Hash_UINT16(&hashCtx, TCPA_PID_ADCP);
	result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata);
	result |= Trspi_Hash_UINT16(&hashCtx, TCPA_ET_OWNER);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
		goto error;

	if ((result = authsess_xsap_hmac(xsap, &digest)))
		goto error;

	if ((result = TCS_API(tspContext)->ChangeAuthOwner(tspContext, TCPA_PID_ADCP,
							   &xsap->encAuthUse, TPM_ET_OWNER,
							   xsap->pAuth)))
		goto error;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_SUCCESS);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthOwner);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
		goto error;

	result = authsess_xsap_verify(xsap, &digest);
error:
	authsess_free(xsap);

	return result;
}

TSS_RESULT
changeauth_srk(TSS_HCONTEXT tspContext,
	       TSS_HOBJECT hObjectToChange,
	       TSS_HOBJECT hParentObject,
	       TSS_HPOLICY hNewPolicy)
{
	TPM_DIGEST digest;
	TSS_RESULT result;
	Trspi_HashCtx hashCtx;
	struct authsess *xsap = NULL;


	if ((result = authsess_xsap_init(tspContext, hParentObject, hNewPolicy,
					 TSS_AUTH_POLICY_REQUIRED, TPM_ORD_ChangeAuthOwner,
					 TPM_ET_OWNER, &xsap)))
		return result;

	/* calculate auth data */
	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthOwner);
	result |= Trspi_Hash_UINT16(&hashCtx, TCPA_PID_ADCP);
	result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata);
	result |= Trspi_Hash_UINT16(&hashCtx, TCPA_ET_SRK);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
		goto error;

	if ((result = authsess_xsap_hmac(xsap, &digest)))
		goto error;

	if ((result = TCS_API(tspContext)->ChangeAuthOwner(tspContext, TCPA_PID_ADCP,
							   &xsap->encAuthUse, TPM_ET_SRK,
							   xsap->pAuth)))
		goto error;

	/* Validate the Auths */
	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_SUCCESS);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthOwner);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
		goto error;

	result = authsess_xsap_verify(xsap, &digest);
error:
	authsess_free(xsap);

	return result;
}

TSS_RESULT
changeauth_encdata(TSS_HCONTEXT tspContext,
		   TSS_HOBJECT hObjectToChange,
		   TSS_HOBJECT hParentObject,
		   TSS_HPOLICY hNewPolicy)
{
	TPM_DIGEST digest;
	TSS_RESULT result;
	Trspi_HashCtx hashCtx;
	TSS_HPOLICY hPolicy;
	TCS_KEY_HANDLE keyHandle;
	UINT64 offset;
	struct authsess *xsap = NULL;
	TPM_STORED_DATA storedData;
	UINT32 dataBlobLength, newEncSize;
	BYTE *dataBlob, *newEncData;
	TPM_AUTH auth2;

	/*  get the secret for the parent */
	if ((result = obj_encdata_get_policy(hObjectToChange, TSS_POLICY_USAGE, &hPolicy)))
		return result;

	/*  get the data Object  */
	if ((result = obj_encdata_get_data(hObjectToChange, &dataBlobLength, &dataBlob)))
		return result;

	offset = 0;
	if ((result = Trspi_UnloadBlob_STORED_DATA(&offset, dataBlob, &storedData)))
		return result;

	if ((result = obj_rsakey_get_tcs_handle(hParentObject, &keyHandle)))
		return result;

	if ((result = authsess_xsap_init(tspContext, hParentObject, hNewPolicy,
					 TSS_AUTH_POLICY_REQUIRED, TPM_ORD_ChangeAuth,
					 TPM_ET_KEYHANDLE, &xsap)))
		return result;

	/* caluculate auth data */
	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuth);
	result |= Trspi_Hash_UINT16(&hashCtx, TPM_PID_ADCP);
	result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata);
	result |= Trspi_Hash_UINT16(&hashCtx, TPM_ET_DATA);
	result |= Trspi_Hash_UINT32(&hashCtx, storedData.encDataSize);
	result |= Trspi_HashUpdate(&hashCtx, storedData.encDataSize, storedData.encData);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
		goto error;

	if ((result = authsess_xsap_hmac(xsap, &digest)))
		goto error;

	if ((result = secret_PerformAuth_OIAP(hObjectToChange, TPM_ORD_ChangeAuth,
					hPolicy, FALSE, &digest, &auth2)))
		goto error;

	if ((result = TCS_API(tspContext)->ChangeAuth(tspContext, keyHandle, TPM_PID_ADCP,
						      &xsap->encAuthUse, TPM_ET_DATA,
						      storedData.encDataSize, storedData.encData,
						      xsap->pAuth, &auth2, &newEncSize,
						      &newEncData)))
		goto error;

	/* Validate the Auths */
	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_SUCCESS);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuth);
	result |= Trspi_Hash_UINT32(&hashCtx, newEncSize);
	result |= Trspi_HashUpdate(&hashCtx, newEncSize, newEncData);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
		goto error;

	if ((result = authsess_xsap_verify(xsap, &digest)))
		goto error;

	if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth2)))
		goto error;

	memcpy(storedData.encData, newEncData, newEncSize);
	free(newEncData);
	storedData.encDataSize = newEncSize;

	offset = 0;
	Trspi_LoadBlob_STORED_DATA(&offset, dataBlob, &storedData);

	result = obj_encdata_set_data(hObjectToChange, offset, dataBlob);

error:
	authsess_free(xsap);
	free(storedData.sealInfo);
	free(storedData.encData);

	return result;

}

TSS_RESULT
changeauth_key(TSS_HCONTEXT tspContext,
	       TSS_HOBJECT hObjectToChange,
	       TSS_HOBJECT hParentObject,
	       TSS_HPOLICY hNewPolicy)
{
	TPM_DIGEST digest;
	Trspi_HashCtx hashCtx;
	TSS_RESULT result;
	TSS_KEY keyToChange;
	TCS_KEY_HANDLE keyHandle;
	struct authsess *xsap = NULL;
	UINT32 objectLength;
	TSS_HPOLICY hPolicy;
	BYTE *keyBlob;
	UINT32 newEncSize;
	BYTE *newEncData;
	TPM_AUTH auth2;
	UINT64 offset;


	if ((result = obj_rsakey_get_blob(hObjectToChange, &objectLength, &keyBlob)))
		return result;

	offset = 0;
	if ((result = UnloadBlob_TSS_KEY(&offset, keyBlob, &keyToChange))) {
		LogDebug("UnloadBlob_TSS_KEY failed. "
				"result=0x%x", result);
		return result;
	}

	if ((result = obj_rsakey_get_policy(hObjectToChange, TSS_POLICY_USAGE, &hPolicy, NULL)))
		return result;

	if ((result = obj_rsakey_get_tcs_handle(hParentObject, &keyHandle)))
		return result;

	if ((result = authsess_xsap_init(tspContext, hParentObject, hNewPolicy,
					 TSS_AUTH_POLICY_REQUIRED, TPM_ORD_ChangeAuth,
					 keyHandle == TPM_KEYHND_SRK ?
					 TPM_ET_SRK : TPM_ET_KEYHANDLE, &xsap)))
		return result;

	/* caluculate auth data */
	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuth);
	result |= Trspi_Hash_UINT16(&hashCtx, TCPA_PID_ADCP);
	result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata);
	result |= Trspi_Hash_UINT16(&hashCtx, TCPA_ET_KEY);
	result |= Trspi_Hash_UINT32(&hashCtx, keyToChange.encSize);
	result |= Trspi_HashUpdate(&hashCtx, keyToChange.encSize,
			keyToChange.encData);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
		goto error;

	if ((result = authsess_xsap_hmac(xsap, &digest)))
		goto error;

	if ((result = secret_PerformAuth_OIAP(hObjectToChange, TPM_ORD_ChangeAuth,
					hPolicy, FALSE, &digest, &auth2)))
		goto error;

	if ((result = TCS_API(tspContext)->ChangeAuth(tspContext, keyHandle, TPM_PID_ADCP,
						      &xsap->encAuthUse, TPM_ET_KEY,
						      keyToChange.encSize, keyToChange.encData,
						      xsap->pAuth, &auth2, &newEncSize,
						      &newEncData)))
		goto error;

	/* Validate the Auths */
	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, result);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuth);
	result |= Trspi_Hash_UINT32(&hashCtx, newEncSize);
	result |= Trspi_HashUpdate(&hashCtx, newEncSize, newEncData);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
		goto error;

	if ((result = authsess_xsap_verify(xsap, &digest)))
		goto error;

	if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth2)))
		return result;

	memcpy(keyToChange.encData, newEncData, newEncSize);
	free(newEncData);

	offset = 0;
	LoadBlob_TSS_KEY(&offset, keyBlob, &keyToChange);
	objectLength = offset;

	result = obj_rsakey_set_tcpakey(hObjectToChange, objectLength, keyBlob);
error:
	authsess_free(xsap);

	return result;
}


#ifdef TSS_BUILD_TRANSPORT
TSS_RESULT
Transport_ChangeAuth(TSS_HCONTEXT tspContext,	/* in */
		     TCS_KEY_HANDLE parentHandle,	/* in */
		     TCPA_PROTOCOL_ID protocolID,	/* in */
		     TCPA_ENCAUTH *newAuth,	/* in */
		     TCPA_ENTITY_TYPE entityType,	/* in */
		     UINT32 encDataSize,	/* in */
		     BYTE * encData,	/* in */
		     TPM_AUTH * ownerAuth,	/* in, out */
		     TPM_AUTH * entityAuth,	/* in, out */
		     UINT32 * outDataSize,	/* out */
		     BYTE ** outData)	/* out */
{
	TSS_RESULT result;
	UINT32 handlesLen, dataLen, decLen;
	TCS_HANDLE *handles, handle;
	BYTE *dec = NULL;
	TPM_DIGEST pubKeyHash;
	Trspi_HashCtx hashCtx;
	UINT64 offset;
	BYTE *data;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	if ((result = obj_tcskey_get_pubkeyhash(parentHandle, pubKeyHash.digest)))
		return result;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
		return result;

	handlesLen = 1;
	handle = parentHandle;
	handles = &handle;

	dataLen = sizeof(TCPA_PROTOCOL_ID) + sizeof(TCPA_ENCAUTH)
					   + sizeof(TCPA_ENTITY_TYPE)
					   + sizeof(UINT32)
					   + encDataSize;
	if ((data = malloc(dataLen)) == NULL) {
		LogError("malloc of %u bytes failed", dataLen);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	offset = 0;
	Trspi_LoadBlob_UINT16(&offset, protocolID, data);
	Trspi_LoadBlob(&offset, sizeof(TCPA_ENCAUTH), data, newAuth->authdata);
	Trspi_LoadBlob_UINT16(&offset, entityType, data);
	Trspi_LoadBlob_UINT32(&offset, encDataSize, data);
	Trspi_LoadBlob(&offset, encDataSize, data, encData);

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_ChangeAuth, dataLen, data,
						    &pubKeyHash, &handlesLen, &handles,
						    ownerAuth, entityAuth, &decLen, &dec))) {
		free(data);
		return result;
	}
	free(data);

	offset = 0;
	Trspi_UnloadBlob_UINT32(&offset, outDataSize, dec);

	if ((*outData = malloc(*outDataSize)) == NULL) {
		free(dec);
		LogError("malloc of %u bytes failed", *outDataSize);
		*outDataSize = 0;
		return TSPERR(TSS_E_OUTOFMEMORY);
	}
	Trspi_UnloadBlob(&offset, *outDataSize, dec, *outData);

	free(dec);

	return result;
}

TSS_RESULT
Transport_ChangeAuthOwner(TSS_HCONTEXT tspContext,	/* in */
			  TCPA_PROTOCOL_ID protocolID,	/* in */
			  TCPA_ENCAUTH *newAuth,	/* in */
			  TCPA_ENTITY_TYPE entityType,	/* in */
			  TPM_AUTH * ownerAuth)	/* in, out */
{
	TSS_RESULT result;
	UINT32 handlesLen = 0;
	UINT64 offset;
	BYTE data[sizeof(TCPA_PROTOCOL_ID) + sizeof(TCPA_ENCAUTH) + sizeof(TCPA_ENTITY_TYPE)];

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	offset = 0;
	Trspi_LoadBlob_UINT16(&offset, protocolID, data);
	Trspi_LoadBlob(&offset, sizeof(TCPA_ENCAUTH), data, newAuth->authdata);
	Trspi_LoadBlob_UINT16(&offset, entityType, data);

	return obj_context_transport_execute(tspContext, TPM_ORD_ChangeAuthOwner, sizeof(data),
					     data, NULL, &handlesLen, NULL, ownerAuth, NULL, NULL,
					     NULL);
}
#endif


<|start_filename|>src/include/tss/tcs_structs.h<|end_filename|>
/*++

TSS Core Service structures

*/

#ifndef __TCS_STRUCT_H__
#define __TCS_STRUCT_H__

#include <tss/tpm.h>
#include <tss/tss_structs.h>
#include <tss/tcs_typedef.h>

typedef struct tdTCS_AUTH
{
    TCS_AUTHHANDLE  AuthHandle;
    TPM_NONCE       NonceOdd;   // system  
    TPM_NONCE       NonceEven;   // TPM   
    TSS_BOOL        fContinueAuthSession;
    TPM_AUTHDATA    HMAC;
} TCS_AUTH;

// This is kept for legacy compatibility
typedef TCS_AUTH    TPM_AUTH;


typedef struct tdTCS_LOADKEY_INFO
{
    TSS_UUID   keyUUID;
    TSS_UUID   parentKeyUUID;
    TPM_DIGEST  paramDigest; // SHA1 digest of the TPM_LoadKey
                             // Command input parameters
                             // As defined in TPM Main Specification
    TPM_AUTH   authData;     // Data regarding a valid auth
                             // Session including the
                             // HMAC digest
} TCS_LOADKEY_INFO;

#endif // __TCS_STRUCT_H__



<|start_filename|>src/tspi/rpc/tcstp/rpc_counter.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "hosttable.h"
#include "tcsd_wrap.h"
#include "obj.h"
#include "rpc_tcstp_tsp.h"


TSS_RESULT
RPC_ReadCounter_TP(struct host_table_entry* hte,
		    TSS_COUNTER_ID           idCounter,		/* in */
		    TPM_COUNTER_VALUE*       counterValue)	/* out */
{
	TSS_RESULT result;

	initData(&hte->comm, 2);
	hte->comm.hdr.u.ordinal = TCSD_ORD_READCOUNTER;
	LogDebugFn("IN: TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &idCounter, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_COUNTER_VALUE, 0, counterValue, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
	}

	return result;
}

TSS_RESULT
RPC_CreateCounter_TP(struct host_table_entry* hte,
		      UINT32                   LabelSize,	/* in (=4) */
		      BYTE*                    pLabel,		/* in */
		      TPM_ENCAUTH              CounterAuth,	/* in */
		      TPM_AUTH*                pOwnerAuth,	/* in, out */
		      TSS_COUNTER_ID*          idCounter,	/* out */
		      TPM_COUNTER_VALUE*       counterValue)	/* out */
{
	TSS_RESULT result;

	initData(&hte->comm, 5);
	hte->comm.hdr.u.ordinal = TCSD_ORD_CREATECOUNTER;
	LogDebugFn("IN: TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &LabelSize, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 2, &pLabel, LabelSize, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_ENCAUTH, 3, &CounterAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_AUTH, 4, pOwnerAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_AUTH, 0, pOwnerAuth, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_UINT32, 1, idCounter, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_COUNTER_VALUE, 2, counterValue, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
	}
done:
	return result;
}

TSS_RESULT
RPC_IncrementCounter_TP(struct host_table_entry* hte,
			 TSS_COUNTER_ID           idCounter,	/* in */
			 TPM_AUTH*                pCounterAuth,	/* in, out */
			 TPM_COUNTER_VALUE*       counterValue)	/* out */
{
	TSS_RESULT result;

	initData(&hte->comm, 3);
	hte->comm.hdr.u.ordinal = TCSD_ORD_INCREMENTCOUNTER;
	LogDebugFn("IN: TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &idCounter, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_AUTH, 2, pCounterAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_AUTH, 0, pCounterAuth, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_COUNTER_VALUE, 1, counterValue, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
	}
done:
	return result;
}

TSS_RESULT
RPC_ReleaseCounter_TP(struct host_table_entry* hte,
		       TSS_COUNTER_ID           idCounter,	/* in */
		       TPM_AUTH*                pCounterAuth)	/* in, out */
{
	TSS_RESULT result;

	initData(&hte->comm, 3);
	hte->comm.hdr.u.ordinal = TCSD_ORD_RELEASECOUNTER;
	LogDebugFn("IN: TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &idCounter, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_AUTH, 2, pCounterAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_AUTH, 0, pCounterAuth, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
	}

	return result;
}

TSS_RESULT
RPC_ReleaseCounterOwner_TP(struct host_table_entry* hte,
			    TSS_COUNTER_ID           idCounter,		/* in */
			    TPM_AUTH*                pOwnerAuth)	/* in, out */
{
	TSS_RESULT result;

	initData(&hte->comm, 3);
	hte->comm.hdr.u.ordinal = TCSD_ORD_RELEASECOUNTEROWNER;
	LogDebugFn("IN: TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &idCounter, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_AUTH, 2, pOwnerAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_AUTH, 0, pOwnerAuth, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
	}

	return result;
}


<|start_filename|>src/tcs/tcs_quote.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcsps.h"
#include "tcslog.h"
#include "tddl.h"
#include "req_mgr.h"
#include "tcsd_wrap.h"
#include "tcsd.h"


TSS_RESULT
UnloadBlob_PCR_SELECTION(UINT64 *offset, BYTE *blob, TCPA_PCR_SELECTION *pcr)
{
	if (!pcr) {
		UINT16 size;

		UnloadBlob_UINT16(offset, &size, blob);

		if (size > 0)
			UnloadBlob(offset, size, blob, NULL);

		return TSS_SUCCESS;
	}

	UnloadBlob_UINT16(offset, &pcr->sizeOfSelect, blob);
	pcr->pcrSelect = malloc(pcr->sizeOfSelect);
        if (pcr->pcrSelect == NULL) {
		LogError("malloc of %hu bytes failed.", pcr->sizeOfSelect);
		pcr->sizeOfSelect = 0;
                return TCSERR(TSS_E_OUTOFMEMORY);
        }
	UnloadBlob(offset, pcr->sizeOfSelect, blob, pcr->pcrSelect);

	return TSS_SUCCESS;
}

void
LoadBlob_PCR_SELECTION(UINT64 *offset, BYTE * blob, TCPA_PCR_SELECTION pcr)
{
	LoadBlob_UINT16(offset, pcr.sizeOfSelect, blob);
	LoadBlob(offset, pcr.sizeOfSelect, blob, pcr.pcrSelect);
}

TSS_RESULT
UnloadBlob_PCR_COMPOSITE(UINT64 *offset, BYTE *blob, TCPA_PCR_COMPOSITE *out)
{
	TSS_RESULT rc;

	if (!out) {
		UINT32 size;

		if ((rc = UnloadBlob_PCR_SELECTION(offset, blob, NULL)))
			return rc;

		UnloadBlob_UINT32(offset, &size, blob);
		if (size > 0)
			UnloadBlob(offset, size, blob, NULL);

		return TSS_SUCCESS;
	}

	if ((rc = UnloadBlob_PCR_SELECTION(offset, blob, &out->select)))
		return rc;

	UnloadBlob_UINT32(offset, &out->valueSize, blob);
	out->pcrValue = malloc(out->valueSize);
        if (out->pcrValue == NULL) {
		LogError("malloc of %u bytes failed.", out->valueSize);
		out->valueSize = 0;
                return TCSERR(TSS_E_OUTOFMEMORY);
        }
	UnloadBlob(offset, out->valueSize, blob, (BYTE *) out->pcrValue);

	return TSS_SUCCESS;
}


<|start_filename|>src/tspi/daa/daa_anonymityrevocation/csencryption_result.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2006
 *
 */

#include "daa_parameter.h"
#include "daa_structs.h"
#include "anonymity_revocation.h"
#include "verifier.h"
#include "tsplog.h"

CS_ENCRYPTION_RESULT *create_CS_ENCRYPTION_RESULT(
	bi_ptr c1,
	bi_ptr c2,
	bi_ptr c3,
	bi_ptr c4
) {
	CS_ENCRYPTION_RESULT *result =
		(CS_ENCRYPTION_RESULT *)malloc( sizeof(CS_ENCRYPTION_RESULT));

	if (result == NULL) {
		LogError("malloc of %d bytes failed", sizeof(CS_ENCRYPTION_RESULT));
		return NULL;
	}
	result->c1 = c1;
	result->c2 = c2;
	result->c3 = c3;
	result->c4 = c4;
	return result;
}

CS_ENCRYPTION_RESULT_RANDOMNESS *create_CS_ENCRYPTION_RESULT_RANDOMNESS(
	CS_ENCRYPTION_RESULT *cs_encryption_result,
	bi_ptr randomness
) {
	CS_ENCRYPTION_RESULT_RANDOMNESS *result =
		(CS_ENCRYPTION_RESULT_RANDOMNESS *)
			malloc(sizeof(CS_ENCRYPTION_RESULT_RANDOMNESS));

	if (result == NULL) {
		LogError("malloc of %d bytes failed",
			sizeof(CS_ENCRYPTION_RESULT_RANDOMNESS));
		return NULL;
	}
	result->randomness = randomness;
	result->result = cs_encryption_result;
	return result;
}

bi_ptr compute_u( const EVP_MD *digest,
		const bi_ptr c1,
		const bi_ptr c2,
		const bi_ptr c3,
		const BYTE *condition,
		const int conditionLength
) {
	BYTE *buffer, *bytes;
	int c1_size = bi_nbin_size( c1);
	int c2_size = bi_nbin_size( c2);
	int c3_size = bi_nbin_size( c3);
	int index = 0;
	int length;
	bi_ptr value;
	int bufferLength = c1_size + c2_size + c3_size + conditionLength;

	buffer = (BYTE *)malloc( bufferLength);
	if (buffer == NULL) {
		LogError("malloc of %d bytes failed", bufferLength);
		return NULL;
	}
	bi_2_byte_array( &buffer[index], c1_size, c1);
	index += c1_size;
	bi_2_byte_array( &buffer[index], c2_size, c2);
	index += c2_size;
	bi_2_byte_array( &buffer[index], c3_size, c3);
	index += c3_size;
	memcpy( &buffer[index], condition, conditionLength);
	index += conditionLength;
	length = DAA_PARAM_LENGTH_MFG1_ANONYMITY_REVOCATION / 8; // 25 /8
	bytes = compute_bytes( bufferLength, buffer, length, digest);
	if( bytes == NULL) return NULL;
	value = bi_set_as_nbin( length, bytes);
	free( bytes);
	free( buffer);
	return value;
}

CS_ENCRYPTION_RESULT_RANDOMNESS* internal_compute_encryption_proof(
	const bi_ptr msg,
	const bi_ptr delta1,
	const bi_ptr delta2,
	const bi_ptr delta3,
	const bi_ptr randomness,
	const CS_PUBLIC_KEY *key,
	const struct tdTSS_DAA_PK_internal *daa_key,
	const BYTE *condition,
	const int conditionLength,
	const EVP_MD *digest
) {
	bi_ptr modulus = daa_key->modulus;
	bi_ptr gamma = daa_key->gamma;
	bi_ptr c1 = bi_new_ptr( );
	bi_ptr c2 = bi_new_ptr( );
	bi_ptr c3 = bi_new_ptr( );
	bi_ptr c4;
	bi_ptr exp;
	bi_t bi_tmp;
	bi_t bi_tmp1;

	bi_new( bi_tmp);
	bi_new( bi_tmp1);
	if( bi_cmp( msg, modulus) >= 0) {
		LogError("IllegalArgument: msg to big for key size");
		bi_free_ptr( c1);
		bi_free_ptr( c2);
		bi_free_ptr( c3);
		bi_free( bi_tmp);
		bi_free( bi_tmp1);
		return NULL;
	}
	bi_mod_exp( c1, gamma, randomness, modulus);
	bi_mod_exp( c2, key->eta, randomness, modulus);
	// c3=msg * (key->lambda3 ^ randomness) % mopdulus)
	bi_mul( c3, msg, bi_mod_exp( bi_tmp, key->lambda3, randomness, modulus));
	bi_mod( c3, c3, modulus);	// c3 = c3 % modulus
	if( delta1 != NULL) {
		if( !( delta2!=NULL && delta3!=NULL)) {
			LogError("Illegal Arguments: delta2==NULL or delta3==NULL");
			bi_free_ptr( c1);
			bi_free_ptr( c2);
			bi_free_ptr( c3);
			bi_free( bi_tmp);
			bi_free( bi_tmp1);
			return NULL;
		}
		exp = compute_u( digest, delta1, delta2, delta3, condition, conditionLength);
	} else {
		if( !( delta2==NULL && delta3==NULL)) {
			LogError("Illegal Arguments: delta2!=NULL or delta3!=NULL");
			bi_free_ptr( c1);
			bi_free_ptr( c2);
			bi_free_ptr( c3);
			bi_free( bi_tmp);
			bi_free( bi_tmp1);
			return NULL;
		}
		exp = compute_u( digest, c1, c2, c3, condition, conditionLength);
	}
	// exp = exp * randomness
	bi_mul( exp, exp, randomness);
	// exp = exp % daa_key->rho
	bi_mod( exp, exp, daa_key->rho);
	// bi_tmp = (key->lambda1 ^ randomness) % modulus
	bi_mod_exp( bi_tmp, key->lambda1, randomness, modulus);
	// bi_tmp1 = (key->lambda2 ^ exp) % modulus
	bi_mod_exp( bi_tmp1, key->lambda2, exp, modulus);
	c4 = bi_new_ptr();
	// c4 = bi_tmp * bi_tmp1
	bi_mul( c4, bi_tmp, bi_tmp1);
	// c4 = c4 % modulus
	bi_mod( c4, c4, modulus);
	bi_free_ptr( exp);
	bi_free( bi_tmp1);
	bi_free( bi_tmp);
	return create_CS_ENCRYPTION_RESULT_RANDOMNESS(
		create_CS_ENCRYPTION_RESULT( c1, c2, c3, c4),
		randomness);
}

/*
Cramer-Shoup EncryptionProof
from com.ibm.zurich.tcg.daa.anonymityrevocation.CSEncryptionProof
 */
CS_ENCRYPTION_RESULT_RANDOMNESS *compute_ecryption_proof(
	const bi_ptr msg,
	const bi_ptr delta1,
	const bi_ptr delta2,
	const bi_ptr delta3,
	const bi_ptr randomness,
	const CS_PUBLIC_KEY *key,
	const struct tdTSS_DAA_PK_internal *daa_key,
	const BYTE *condition,
	const int conditionLength,
	const EVP_MD *digest
) {
	if( delta1 == NULL || delta2 == NULL || delta3 == NULL) {
		LogError("Illegal Argument: deltas (delta1:%ld delta2:%ld delta3:%ld)",
				(long)delta1, (long)delta2, (long)delta3);
		return NULL;
	}
	if( bi_cmp( randomness, daa_key->rho) >=0 || bi_cmp_si( randomness, 0) < 0) {
		LogError("randomness >= rho || randomness < 0 \n\trandomness:%s\n\trho:%s\n",
				bi_2_dec_char( randomness), bi_2_dec_char( daa_key->rho));
		return NULL;
	}
	return internal_compute_encryption_proof( msg,
						delta1,
						delta2,
						delta3,
						randomness,
						key,
						daa_key,
						condition,
						conditionLength,
						digest);
}


<|start_filename|>src/tspi/rpc/tcstp/rpc_changeauth.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "hosttable.h"
#include "tcsd_wrap.h"
#include "obj.h"
#include "rpc_tcstp_tsp.h"


TSS_RESULT
RPC_ChangeAuth_TP(struct host_table_entry *hte,
			       TCS_KEY_HANDLE parentHandle,	/* in */
			       TCPA_PROTOCOL_ID protocolID,	/* in */
			       TCPA_ENCAUTH *newAuth,	/* in */
			       TCPA_ENTITY_TYPE entityType,	/* in */
			       UINT32 encDataSize,	/* in */
			       BYTE * encData,	/* in */
			       TPM_AUTH * ownerAuth,	/* in, out */
			       TPM_AUTH * entityAuth,	/* in, out */
			       UINT32 * outDataSize,	/* out */
			       BYTE ** outData)	/* out */
{
	TSS_RESULT result;

	initData(&hte->comm, 9);
	hte->comm.hdr.u.ordinal = TCSD_ORD_CHANGEAUTH;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &parentHandle, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT16, 2, &protocolID, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_ENCAUTH, 3, newAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT16, 4, &entityType, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 5, &encDataSize, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 6, encData, encDataSize, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_AUTH, 7, ownerAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_AUTH, 8, entityAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_AUTH, 1, entityAuth, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_UINT32, 2, outDataSize, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		*outData = (BYTE *) malloc(*outDataSize);
		if (*outData == NULL) {
			LogError("malloc of %u bytes failed.", *outDataSize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, 3, *outData, *outDataSize, &hte->comm)) {
			free(*outData);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		}
	}

done:
	return result;
}

TSS_RESULT
RPC_ChangeAuthOwner_TP(struct host_table_entry *hte,
				    TCPA_PROTOCOL_ID protocolID,	/* in */
				    TCPA_ENCAUTH *newAuth,	/* in */
				    TCPA_ENTITY_TYPE entityType,	/* in */
				    TPM_AUTH * ownerAuth	/* in, out */
    ) {
	TSS_RESULT result;

	initData(&hte->comm, 5);
	hte->comm.hdr.u.ordinal = TCSD_ORD_CHANGEAUTHOWNER;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT16, 1, &protocolID, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_ENCAUTH, 2, newAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT16, 3, &entityType, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_AUTH, 4, ownerAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (hte->comm.hdr.u.result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
	}

	return result;
}

TSS_RESULT
RPC_ChangeAuthAsymStart_TP(struct host_table_entry *hte,
					TCS_KEY_HANDLE idHandle,	/* in */
					TCPA_NONCE antiReplay,	/* in */
					UINT32 KeySizeIn,	/* in */
					BYTE * KeyDataIn,	/* in */
					TPM_AUTH * pAuth,	/* in, out */
					UINT32 * KeySizeOut,	/* out */
					BYTE ** KeyDataOut,	/* out */
					UINT32 * CertifyInfoSize,	/* out */
					BYTE ** CertifyInfo,	/* out */
					UINT32 * sigSize,	/* out */
					BYTE ** sig,	/* out */
					TCS_KEY_HANDLE * ephHandle	/* out */
    ) {
	return TSPERR(TSS_E_NOTIMPL);
}

TSS_RESULT
RPC_ChangeAuthAsymFinish_TP(struct host_table_entry *hte,
					 TCS_KEY_HANDLE parentHandle,	/* in */
					 TCS_KEY_HANDLE ephHandle,	/* in */
					 TCPA_ENTITY_TYPE entityType,	/* in */
					 TCPA_HMAC newAuthLink,	/* in */
					 UINT32 newAuthSize,	/* in */
					 BYTE * encNewAuth,	/* in */
					 UINT32 encDataSizeIn,	/* in */
					 BYTE * encDataIn,	/* in */
					 TPM_AUTH * ownerAuth,	/* in, out */
					 UINT32 * encDataSizeOut,	/* out */
					 BYTE ** encDataOut,	/* out */
					 TCPA_SALT_NONCE * saltNonce,	/* out */
					 TCPA_DIGEST * changeProof	/* out */
    ) {
	return TSPERR(TSS_E_NOTIMPL);
}


<|start_filename|>src/tspi/rpc/tcstp/rpc_dir.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "hosttable.h"
#include "tcsd_wrap.h"
#include "obj.h"
#include "rpc_tcstp_tsp.h"


TSS_RESULT
RPC_DirWriteAuth_TP(struct host_table_entry *hte,
				 TCPA_DIRINDEX dirIndex,	/* in */
				 TCPA_DIRVALUE *newContents,	/* in */
				 TPM_AUTH * ownerAuth	/* in, out */
    ) {
	TSS_RESULT result;

	initData(&hte->comm, 4);
	hte->comm.hdr.u.ordinal = TCSD_ORD_DIRWRITEAUTH;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &dirIndex, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_DIGEST, 2, newContents, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_AUTH, 3, ownerAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
	}

	return result;
}

TSS_RESULT
RPC_DirRead_TP(struct host_table_entry *hte,
			    TCPA_DIRINDEX dirIndex,	/* in */
			    TCPA_DIRVALUE * dirValue	/* out */
    ) {
	TSS_RESULT result;

	initData(&hte->comm, 2);
	hte->comm.hdr.u.ordinal = TCSD_ORD_DIRREAD;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &dirIndex, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (hte->comm.hdr.u.result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_DIGEST, 0, dirValue, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
	}

	return result;
}


<|start_filename|>src/tcs/tcs_seal.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcs_utils.h"
#include "tcslog.h"


TSS_RESULT
UnloadBlob_STORED_DATA(UINT64 *offset, BYTE *blob, TCPA_STORED_DATA *data)
{
	if (!data) {
		UINT32 size;

		UnloadBlob_VERSION(offset, blob, NULL);

		UnloadBlob_UINT32(offset, &size, blob);

		if (size > 0)
			UnloadBlob(offset, size, blob, NULL);

		UnloadBlob_UINT32(offset, &size, blob);

		if (size > 0)
			UnloadBlob(offset, size, blob, NULL);

		return TSS_SUCCESS;
	}

	UnloadBlob_VERSION(offset, blob, (TPM_VERSION *)&data->ver);

	UnloadBlob_UINT32(offset, &data->sealInfoSize, blob);

	if (data->sealInfoSize > 0) {
		data->sealInfo = (BYTE *)calloc(1, data->sealInfoSize);
		if (data->sealInfo == NULL) {
			LogError("malloc of %u bytes failed.", data->sealInfoSize);
			data->sealInfoSize = 0;
			return TCSERR(TSS_E_OUTOFMEMORY);
		}
		UnloadBlob(offset, data->sealInfoSize, blob, data->sealInfo);
	} else {
		data->sealInfo = NULL;
	}

	UnloadBlob_UINT32(offset, &data->encDataSize, blob);

	if (data->encDataSize > 0) {
		data->encData = (BYTE *)calloc(1, data->encDataSize);
		if (data->encData == NULL) {
			LogError("malloc of %u bytes failed.", data->encDataSize);
			data->encDataSize = 0;
			free(data->sealInfo);
			data->sealInfo = NULL;
			data->sealInfoSize = 0;
			return TCSERR(TSS_E_OUTOFMEMORY);
		}
		UnloadBlob(offset, data->encDataSize, blob, data->encData);
	} else {
		data->encData = NULL;
	}

	return TSS_SUCCESS;
}


<|start_filename|>src/tspi/gtk/interface.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004, 2005
 *
 */

/*
 * DO NOT EDIT THIS FILE - it is generated by Glade.
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>

#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>

#include "callbacks.h"
#include "interface.h"
#include "support.h"

#define GLADE_HOOKUP_OBJECT(component,widget,name) \
  g_object_set_data_full (G_OBJECT (component), name, \
    gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref)

#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \
  g_object_set_data (G_OBJECT (component), name, widget)

GtkWidget*
create_password_dialog (struct userdata *ud, char *message)
{
  GtkWidget *dialog1;
  GtkWidget *dialog_vbox1;
  GtkWidget *vbox1;
  GtkWidget *entry;
  GtkWidget *alignment1;
  GtkWidget *table2;
  GtkWidget *label1;
  GtkWidget *alignment2;
  GtkWidget *table1;
  GtkWidget *dialog_action_area1;
  GtkWidget *cancelbutton1;
  GtkWidget *okbutton1;
  GtkTooltips *tooltips;

  tooltips = gtk_tooltips_new ();

  dialog1 = gtk_dialog_new ();
  gtk_widget_set_size_request (dialog1, 300, 150);
  //gtk_tooltips_set_tip (tooltips, dialog1, _("This is a box for entering dialogue"), NULL);
  gtk_window_set_title (GTK_WINDOW (dialog1), _("TSS Password"));
  //gtk_window_set_title (GTK_WINDOW (dialog1), message);
  gtk_window_set_position (GTK_WINDOW (dialog1), GTK_WIN_POS_CENTER);
  gtk_window_set_default_size (GTK_WINDOW (dialog1), 300, 150);

  dialog_vbox1 = GTK_DIALOG (dialog1)->vbox;
  gtk_widget_show (dialog_vbox1);

  vbox1 = gtk_vbox_new (TRUE, 0);
  gtk_widget_show (vbox1);
  gtk_box_pack_start (GTK_BOX (dialog_vbox1), vbox1, TRUE, TRUE, 0);

  alignment1 = gtk_alignment_new (0.5, 0.5, 1, 1);
  gtk_widget_show (alignment1);
  gtk_box_pack_start (GTK_BOX (vbox1), alignment1, FALSE, FALSE, 0);

  table2 = gtk_table_new (3, 3, FALSE);
  gtk_widget_show (table2);
  gtk_container_add (GTK_CONTAINER (alignment1), table2);

  //label1 = gtk_label_new (_("Please enter a password, or not."));
  label1 = gtk_label_new (message);
  gtk_widget_show (label1);
  gtk_table_attach (GTK_TABLE (table2), label1, 1, 2, 1, 2,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);
  gtk_label_set_justify (GTK_LABEL (label1), GTK_JUSTIFY_LEFT);
  gtk_misc_set_alignment (GTK_MISC (label1), 0, 0.5);

  alignment2 = gtk_alignment_new (0.5, 0.5, 1, 1);
  gtk_widget_show (alignment2);
  gtk_box_pack_start (GTK_BOX (vbox1), alignment2, TRUE, TRUE, 0);

  table1 = gtk_table_new (2, 3, FALSE);
  gtk_widget_show (table1);
  gtk_container_add (GTK_CONTAINER (alignment2), table1);

  entry = gtk_entry_new ();
  gtk_widget_show (entry);
  gtk_table_attach (GTK_TABLE (table1), entry, 1, 2, 0, 1,
                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);
  //gtk_tooltips_set_tip (tooltips, entry, _("This is where you enter the characters of your password, using the computer input device of your choice."), NULL);
  gtk_entry_set_max_length (GTK_ENTRY (entry), 255);
  gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE);

  dialog_action_area1 = GTK_DIALOG (dialog1)->action_area;
  gtk_widget_show (dialog_action_area1);
  gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END);

  cancelbutton1 = gtk_button_new_from_stock ("gtk-cancel");
  gtk_widget_show (cancelbutton1);
  gtk_dialog_add_action_widget (GTK_DIALOG (dialog1), cancelbutton1, GTK_RESPONSE_CANCEL);
  GTK_WIDGET_SET_FLAGS (cancelbutton1, GTK_CAN_DEFAULT);
  //gtk_tooltips_set_tip (tooltips, cancelbutton1, _("Depress this button in order to indicate that you would like to cancel the submitting of authorization data at this time."), NULL);

  okbutton1 = gtk_button_new_from_stock ("gtk-ok");
  gtk_widget_show (okbutton1);
  gtk_dialog_add_action_widget (GTK_DIALOG (dialog1), okbutton1, GTK_RESPONSE_OK);
  GTK_WIDGET_SET_FLAGS (okbutton1, GTK_CAN_DEFAULT);
  //gtk_tooltips_set_tip (tooltips, okbutton1, _("Depress this button in order to indicate that you have completed the entry of your authorization data."), NULL);

  /* We need to pass the window in to destroy it */
  ud->window = dialog1;
  /* Here we need a pointer to the entry to grab the text out of it */
  ud->entry = entry;

  g_signal_connect ((gpointer) dialog1, "close",
                    G_CALLBACK (on_dialog1_close),
                    ud);

  g_signal_connect ((gpointer) dialog1, "destroy",
                    G_CALLBACK (on_inputdialog1_destroy),
                    ud);

  g_signal_connect ((gpointer) entry, "activate",
                    G_CALLBACK (enter_event),
                    ud);

  g_signal_connect ((gpointer) cancelbutton1, "clicked",
                    G_CALLBACK (on_cancelbutton1_clicked),
                    ud);

  g_signal_connect ((gpointer) okbutton1, "clicked",
                    G_CALLBACK (on_okbutton1_clicked),
                    ud);

  /* Store pointers to all widgets, for use by lookup_widget(). */
  GLADE_HOOKUP_OBJECT_NO_REF (dialog1, dialog1, "dialog1");
  GLADE_HOOKUP_OBJECT_NO_REF (dialog1, dialog_vbox1, "dialog_vbox1");
  GLADE_HOOKUP_OBJECT (dialog1, vbox1, "vbox1");
  GLADE_HOOKUP_OBJECT (dialog1, alignment1, "alignment1");
  GLADE_HOOKUP_OBJECT (dialog1, table2, "table2");
  GLADE_HOOKUP_OBJECT (dialog1, label1, "label1");
  GLADE_HOOKUP_OBJECT (dialog1, alignment2, "alignment2");
  GLADE_HOOKUP_OBJECT (dialog1, table1, "table1");
  GLADE_HOOKUP_OBJECT (dialog1, entry, "entry");
  GLADE_HOOKUP_OBJECT_NO_REF (dialog1, dialog_action_area1, "dialog_action_area1");
  GLADE_HOOKUP_OBJECT (dialog1, cancelbutton1, "cancelbutton1");
  GLADE_HOOKUP_OBJECT (dialog1, okbutton1, "okbutton1");
  GLADE_HOOKUP_OBJECT_NO_REF (dialog1, tooltips, "tooltips");

  return dialog1;
}

GtkWidget*
create_new_password_dialog (struct userdata *ud, char *message)
{
  GtkWidget *dialog1;
  GtkWidget *dialog_vbox1;
  GtkWidget *vbox1;
  GtkWidget *table2;
  GtkWidget *label7;
  GtkWidget *table1;
  GtkWidget *label5;
  GtkWidget *label6;
  GtkWidget *entryPassword;
  GtkWidget *entryConfirm;
  GtkWidget *dialog_action_area1;
  GtkWidget *cancelbutton2;
  GtkWidget *okbutton2;

  dialog1 = gtk_dialog_new ();
  gtk_widget_set_size_request (dialog1, 300, 150);
  gtk_window_set_title (GTK_WINDOW (dialog1), "TSS Password");
  //gtk_window_set_title (GTK_WINDOW (dialog1), message);

  dialog_vbox1 = GTK_DIALOG (dialog1)->vbox;
  gtk_widget_show (dialog_vbox1);

  vbox1 = gtk_vbox_new (FALSE, 0);
  gtk_widget_show (vbox1);
  gtk_box_pack_start (GTK_BOX (dialog_vbox1), vbox1, TRUE, TRUE, 0);

  table2 = gtk_table_new (3, 3, FALSE);
  gtk_widget_show (table2);
  gtk_box_pack_start (GTK_BOX (vbox1), table2, TRUE, TRUE, 0);

  //label7 = gtk_label_new (_("Please enter a new password below."));
  label7 = gtk_label_new (message);
  gtk_widget_show (label7);
  gtk_table_attach (GTK_TABLE (table2), label7, 1, 2, 1, 2,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);
  gtk_label_set_justify (GTK_LABEL (label7), GTK_JUSTIFY_LEFT);
  gtk_misc_set_alignment (GTK_MISC (label7), 0, 0.5);

  table1 = gtk_table_new (5, 5, FALSE);
  gtk_widget_show (table1);
  gtk_box_pack_start (GTK_BOX (vbox1), table1, TRUE, TRUE, 0);

  label5 = gtk_label_new (_("Password:"));
  gtk_widget_show (label5);
  gtk_table_attach (GTK_TABLE (table1), label5, 1, 2, 1, 2,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);
  gtk_label_set_justify (GTK_LABEL (label5), GTK_JUSTIFY_LEFT);
  gtk_misc_set_alignment (GTK_MISC (label5), 0, 0.5);

  label6 = gtk_label_new (_("Confirm:"));
  gtk_widget_show (label6);
  gtk_table_attach (GTK_TABLE (table1), label6, 1, 2, 3, 4,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);
  gtk_label_set_justify (GTK_LABEL (label6), GTK_JUSTIFY_LEFT);
  gtk_misc_set_alignment (GTK_MISC (label6), 0, 0.5);

  entryPassword = gtk_entry_new ();
  gtk_widget_show (entryPassword);
  gtk_table_attach (GTK_TABLE (table1), entryPassword, 3, 4, 1, 2,
                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);
  gtk_entry_set_max_length (GTK_ENTRY (entryPassword), 255);
  gtk_entry_set_visibility (GTK_ENTRY (entryPassword), FALSE);

  entryConfirm = gtk_entry_new ();
  gtk_widget_show (entryConfirm);
  gtk_table_attach (GTK_TABLE (table1), entryConfirm, 3, 4, 3, 4,
                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);
  gtk_entry_set_max_length (GTK_ENTRY (entryConfirm), 255);
  gtk_entry_set_visibility (GTK_ENTRY (entryConfirm), FALSE);

  dialog_action_area1 = GTK_DIALOG (dialog1)->action_area;
  gtk_widget_show (dialog_action_area1);
  gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END);

  cancelbutton2 = gtk_button_new_from_stock ("gtk-cancel");
  gtk_widget_show (cancelbutton2);
  gtk_dialog_add_action_widget (GTK_DIALOG (dialog1), cancelbutton2, GTK_RESPONSE_CANCEL);
  GTK_WIDGET_SET_FLAGS (cancelbutton2, GTK_CAN_DEFAULT);

  okbutton2 = gtk_button_new_from_stock ("gtk-ok");
  gtk_widget_show (okbutton2);
  gtk_dialog_add_action_widget (GTK_DIALOG (dialog1), okbutton2, GTK_RESPONSE_OK);
  GTK_WIDGET_SET_FLAGS (okbutton2, GTK_CAN_DEFAULT);

  /* We need to pass the window in to destroy it */
  ud->window = dialog1;
  /* Here we need a pointer to the entries to grab text out of them */
  ud->entryPass = <PASSWORD>;
  ud->entryConf = entryConfirm;

  g_signal_connect ((gpointer) dialog1, "destroy",
                    G_CALLBACK (on_inputdialog1_destroy),
                    ud);

  g_signal_connect ((gpointer) entryPassword, "activate",
                    G_CALLBACK (on_entryPassword_activate),
                    ud);
  g_signal_connect ((gpointer) entryConfirm, "activate",
                    G_CALLBACK (on_entryConfirm_activate),
                    ud);
  g_signal_connect ((gpointer) cancelbutton2, "clicked",
                    G_CALLBACK (on_cancelbutton2_clicked),
                    ud);
  g_signal_connect ((gpointer) okbutton2, "clicked",
                    G_CALLBACK (on_okbutton2_clicked),
                    ud);

  /* Store pointers to all widgets, for use by lookup_widget(). */
  GLADE_HOOKUP_OBJECT_NO_REF (dialog1, dialog1, "dialog1");
  GLADE_HOOKUP_OBJECT_NO_REF (dialog1, dialog_vbox1, "dialog_vbox1");
  GLADE_HOOKUP_OBJECT (dialog1, vbox1, "vbox1");
  GLADE_HOOKUP_OBJECT (dialog1, table2, "table2");
  GLADE_HOOKUP_OBJECT (dialog1, label7, "label7");
  GLADE_HOOKUP_OBJECT (dialog1, table1, "table1");
  GLADE_HOOKUP_OBJECT (dialog1, label5, "label5");
  GLADE_HOOKUP_OBJECT (dialog1, label6, "label6");
  GLADE_HOOKUP_OBJECT (dialog1, entryPassword, "entryPassword");
  GLADE_HOOKUP_OBJECT (dialog1, entryConfirm, "entryConfirm");
  GLADE_HOOKUP_OBJECT_NO_REF (dialog1, dialog_action_area1, "dialog_action_area1");
  GLADE_HOOKUP_OBJECT (dialog1, cancelbutton2, "cancelbutton2");
  GLADE_HOOKUP_OBJECT (dialog1, okbutton2, "okbutton2");

  return dialog1;
}




<|start_filename|>src/tspi/tspi_oper.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "obj.h"
#include "tsplog.h"


TSS_RESULT
Tspi_TPM_SetOperatorAuth(TSS_HTPM    hTpm,		/* in */
			 TSS_HPOLICY hOperatorPolicy)	/* in */
{
	TSS_HCONTEXT tspContext;
	UINT32 type;
	TCPA_SECRET operatorAuth;
	TSS_RESULT result = TSS_SUCCESS;

	if ((result = obj_tpm_get_tsp_context(hTpm, &tspContext)))
		return result;

	if ((result = obj_policy_get_type(hOperatorPolicy, &type)))
		return result;

	if (type != TSS_POLICY_OPERATOR)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if ((result = obj_policy_get_secret(hOperatorPolicy, TR_SECRET_CTX_NEW, &operatorAuth)))
		return result;

	if ((result = TCS_API(tspContext)->SetOperatorAuth(tspContext, &operatorAuth)))
		return result;

	if ((result = obj_tpm_set_policy(hTpm, hOperatorPolicy)))
		return result;

	return result;
}


<|start_filename|>src/tspi/tsp_dir.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2007
 *
 */


#include <stdlib.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


#ifdef TSS_BUILD_TRANSPORT
TSS_RESULT
Transport_DirWriteAuth(TSS_HCONTEXT tspContext,    /* in */
		       TCPA_DIRINDEX dirIndex,     /* in */
		       TCPA_DIRVALUE *newContents,  /* in */
		       TPM_AUTH * ownerAuth)       /* in, out */
{
	TSS_RESULT result;
	UINT32 handlesLen = 0;
	UINT64 offset;
	BYTE data[sizeof(TCPA_DIRINDEX) + sizeof(TCPA_DIRVALUE)];


	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	offset = 0;
	Trspi_LoadBlob_UINT32(&offset, dirIndex, data);
	Trspi_LoadBlob_DIGEST(&offset, data, (TPM_DIGEST *)newContents);

	result = obj_context_transport_execute(tspContext, TPM_ORD_DirWriteAuth, sizeof(data), data,
					       NULL, &handlesLen, NULL, ownerAuth, NULL, NULL,
					       NULL);

	return result;
}

TSS_RESULT
Transport_DirRead(TSS_HCONTEXT tspContext, /* in */
		  TCPA_DIRINDEX dirIndex,  /* in */
		  TCPA_DIRVALUE * dirValue)        /* out */
{
	TSS_RESULT result;
	UINT32 handlesLen = 0, decLen;
	UINT64 offset;
	BYTE data[sizeof(TCPA_DIRINDEX)], *dec;


	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	offset = 0;
	Trspi_LoadBlob_UINT32(&offset, dirIndex, data);

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_DirRead, sizeof(data), data,
						    NULL, &handlesLen, NULL, NULL, NULL, &decLen,
						    &dec)))
		return result;

	offset = 0;
	Trspi_UnloadBlob_DIGEST(&offset, dec, dirValue);

	return result;
}
#endif



<|start_filename|>src/tspi/tsp_asym.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


/* encrypt some data with the RSA public key of 'key', using the padding appropriate for the key */
TSS_RESULT
__tspi_rsa_encrypt(TSS_HKEY key,
	    UINT32   inDataLen,
	    BYTE*    inData,
	    UINT32*  outDataLen,
	    BYTE*    outData)
{
	BYTE *blob;
	UINT32 blobLen;
	UINT64 offset;
	TSS_RESULT result;
	TSS_HCONTEXT tspContext;
	TPM_PUBKEY pubKey;

	if (!inData || !outDataLen || !outData)
		return TSPERR(TSS_E_INTERNAL_ERROR);

	if ((result = obj_rsakey_get_tsp_context(key, &tspContext)))
		return result;

	if ((result = obj_rsakey_get_pub_blob(key, &blobLen, &blob)))
		return result;

	offset = 0;
	if ((result = Trspi_UnloadBlob_PUBKEY(&offset, blob, &pubKey))) {
		free_tspi(tspContext, blob);
		return result;
	}
	free_tspi(tspContext, blob);

	if (pubKey.pubKey.keyLength < inDataLen) {
		result = TSPERR(TSS_E_ENC_INVALID_LENGTH);
		goto done;
	}

	if (pubKey.algorithmParms.encScheme == TPM_ES_RSAESPKCSv15 ||
	    pubKey.algorithmParms.encScheme == TSS_ES_RSAESPKCSV15) {
		if ((result = Trspi_RSA_PKCS15_Encrypt(inData, inDataLen, outData, outDataLen,
						       pubKey.pubKey.key, pubKey.pubKey.keyLength)))
			goto done;
	} else {
		if ((result = Trspi_TPM_RSA_OAEP_Encrypt(inData, inDataLen, outData, outDataLen,
							 pubKey.pubKey.key,
							 pubKey.pubKey.keyLength)))
			goto done;
	}

done:
	free(pubKey.pubKey.key);
	free(pubKey.algorithmParms.parms);
	return result;
}

TSS_RESULT
__tspi_rsa_verify(TSS_HKEY key,
	   UINT32   type,
	   UINT32   hashLen,
	   BYTE*    hash,
	   UINT32   sigLen,
	   BYTE*    sig)
{
	BYTE *blob;
	UINT32 blobLen;
	UINT64 offset;
	TSS_RESULT result;
	TSS_HCONTEXT tspContext;
	TPM_PUBKEY pubKey;

	if (!hash || !sig)
		return TSPERR(TSS_E_INTERNAL_ERROR);

	if ((result = obj_rsakey_get_tsp_context(key, &tspContext)))
		return result;

	if ((result = obj_rsakey_get_pub_blob(key, &blobLen, &blob)))
		return result;

	offset = 0;
	if ((result = Trspi_UnloadBlob_PUBKEY(&offset, blob, &pubKey))) {
		free_tspi(tspContext, blob);
		return result;
	}
	free_tspi(tspContext, blob);

	result = Trspi_Verify(type, hash, hashLen, pubKey.pubKey.key, pubKey.pubKey.keyLength,
			      sig, sigLen);

	free(pubKey.pubKey.key);
	free(pubKey.algorithmParms.parms);

	return result;
}


<|start_filename|>src/tspi/tsp_nv.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2007
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


#ifdef TSS_BUILD_TRANSPORT
TSS_RESULT
Transport_NV_DefineOrReleaseSpace(TSS_HCONTEXT tspContext,	/* in */
				  UINT32 cPubInfoSize,	/* in */
				  BYTE* pPubInfo,		/* in */
				  TCPA_ENCAUTH encAuth,	/* in */
				  TPM_AUTH* pAuth)		/* in, out */
{
	TSS_RESULT result;
	UINT32 dataLen;
	UINT64 offset;
	TCS_HANDLE handlesLen = 0;
	BYTE *data;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	dataLen = sizeof(TCPA_ENCAUTH) + cPubInfoSize;
	if ((data = malloc(dataLen)) == NULL) {
		LogError("malloc of %u bytes failed", dataLen);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	offset = 0;
	Trspi_LoadBlob(&offset, cPubInfoSize, data, pPubInfo);
	Trspi_LoadBlob(&offset, TPM_SHA1_160_HASH_LEN, data, encAuth.authdata);

	result = obj_context_transport_execute(tspContext, TPM_ORD_NV_DefineSpace, dataLen, data,
					       NULL, &handlesLen, NULL, pAuth, NULL, NULL, NULL);
	free(data);

	return result;
}

TSS_RESULT
Transport_NV_WriteValue(TSS_HCONTEXT tspContext,	/* in */
			TSS_NV_INDEX hNVStore,	/* in */
			UINT32 offset,		/* in */
			UINT32 ulDataLength,		/* in */
			BYTE* rgbDataToWrite,	/* in */
			TPM_AUTH* privAuth)		/* in, out */
{
	TSS_RESULT result;
	UINT32 dataLen;
	UINT64 offset64;
	TCS_HANDLE handlesLen = 0;
	BYTE *data;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	dataLen = sizeof(TSS_NV_INDEX) + (2 * sizeof(UINT32)) + ulDataLength;
	if ((data = malloc(dataLen)) == NULL) {
		LogError("malloc of %u bytes failed", dataLen);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	offset64 = 0;
	Trspi_LoadBlob_UINT32(&offset64, hNVStore, data);
	Trspi_LoadBlob_UINT32(&offset64, offset, data);
	Trspi_LoadBlob_UINT32(&offset64, ulDataLength, data);
	Trspi_LoadBlob(&offset64, ulDataLength, data, rgbDataToWrite);

	result = obj_context_transport_execute(tspContext, TPM_ORD_NV_WriteValue, dataLen, data,
					       NULL, &handlesLen, NULL, privAuth, NULL, NULL, NULL);
	free(data);

	return result;
}

TSS_RESULT
Transport_NV_WriteValueAuth(TSS_HCONTEXT tspContext,	/* in */
			    TSS_NV_INDEX hNVStore,		/* in */
			    UINT32 offset,			/* in */
			    UINT32 ulDataLength,		/* in */
			    BYTE* rgbDataToWrite,		/* in */
			    TPM_AUTH* NVAuth)		/* in, out */
{
	TSS_RESULT result;
	UINT32 dataLen;
	UINT64 offset64;
	TCS_HANDLE handlesLen = 0;
	BYTE *data;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	dataLen = sizeof(TSS_NV_INDEX) + (2 * sizeof(UINT32)) + ulDataLength;
	if ((data = malloc(dataLen)) == NULL) {
		LogError("malloc of %u bytes failed", dataLen);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	offset64 = 0;
	Trspi_LoadBlob_UINT32(&offset64, hNVStore, data);
	Trspi_LoadBlob_UINT32(&offset64, offset, data);
	Trspi_LoadBlob_UINT32(&offset64, ulDataLength, data);
	Trspi_LoadBlob(&offset64, ulDataLength, data, rgbDataToWrite);

	result = obj_context_transport_execute(tspContext, TPM_ORD_NV_WriteValueAuth, dataLen, data,
					       NULL, &handlesLen, NULL, NVAuth, NULL, NULL, NULL);
	free(data);

	return result;
}


TSS_RESULT
Transport_NV_ReadValue(TSS_HCONTEXT tspContext,	/* in */
		       TSS_NV_INDEX hNVStore,	/* in */
		       UINT32 offset,		/* in */
		       UINT32* pulDataLength,	/* in, out */
		       TPM_AUTH* privAuth,		/* in, out */
		       BYTE** rgbDataRead)		/* out */
{
	TSS_RESULT result;
	UINT32 dataLen, decLen;
	UINT64 offset64;
	TCS_HANDLE handlesLen = 0;
	BYTE *data, *dec;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	dataLen = sizeof(TSS_NV_INDEX) + sizeof(UINT32) + *pulDataLength;
	if ((data = malloc(dataLen)) == NULL) {
		LogError("malloc of %u bytes failed", dataLen);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	offset64 = 0;
	Trspi_LoadBlob_UINT32(&offset64, hNVStore, data);
	Trspi_LoadBlob_UINT32(&offset64, offset, data);
	Trspi_LoadBlob_UINT32(&offset64, *pulDataLength, data);

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_NV_ReadValue, dataLen, data,
						    NULL, &handlesLen, NULL, privAuth, NULL,
						    &decLen, &dec))) {
		free(data);
		return result;
	}
	free(data);

	offset64 = 0;
	Trspi_UnloadBlob_UINT32(&offset64, pulDataLength, dec);

	if ((*rgbDataRead = malloc(*pulDataLength)) == NULL) {
		free(dec);
		LogError("malloc of %u bytes failed", *pulDataLength);
		*pulDataLength = 0;
		return TSPERR(TSS_E_OUTOFMEMORY);
	}
	Trspi_UnloadBlob(&offset64, *pulDataLength, dec, *rgbDataRead);
	free(dec);

	return result;
}


TSS_RESULT
Transport_NV_ReadValueAuth(TSS_HCONTEXT tspContext,	/* in */
			   TSS_NV_INDEX hNVStore,    /* in */
			   UINT32 offset,		/* in */
			   UINT32* pulDataLength,    /* in, out */
			   TPM_AUTH* NVAuth,		/* in, out */
			   BYTE** rgbDataRead)       /* out */
{
	TSS_RESULT result;
	UINT32 dataLen, decLen;
	UINT64 offset64;
	TCS_HANDLE handlesLen = 0;
	BYTE *data, *dec;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	dataLen = sizeof(TSS_NV_INDEX) + sizeof(UINT32) + *pulDataLength;
	if ((data = malloc(dataLen)) == NULL) {
		LogError("malloc of %u bytes failed", dataLen);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	offset64 = 0;
	Trspi_LoadBlob_UINT32(&offset64, hNVStore, data);
	Trspi_LoadBlob_UINT32(&offset64, offset, data);
	Trspi_LoadBlob_UINT32(&offset64, *pulDataLength, data);

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_NV_ReadValueAuth, dataLen,
						    data, NULL, &handlesLen, NULL, NVAuth, NULL,
						    &decLen, &dec))) {
		free(data);
		return result;
	}
	free(data);

	offset64 = 0;
	Trspi_UnloadBlob_UINT32(&offset64, pulDataLength, dec);

	if ((*rgbDataRead = malloc(*pulDataLength)) == NULL) {
		free(dec);
		LogError("malloc of %u bytes failed", *pulDataLength);
		*pulDataLength = 0;
		return TSPERR(TSS_E_OUTOFMEMORY);
	}
	Trspi_UnloadBlob(&offset64, *pulDataLength, dec, *rgbDataRead);
	free(dec);

	return result;
}

#endif


<|start_filename|>src/tcs/tcsi_cmk.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_utils.h"
#include "tcslog.h"
#include "req_mgr.h"

TSS_RESULT
TCSP_CMK_SetRestrictions_Internal(TCS_CONTEXT_HANDLE	hContext,	/* in */
				  TSS_CMK_DELEGATE	Restriction,	/* in */
				  TPM_AUTH*		ownerAuth)	/* in */
{
	TSS_RESULT result;
	UINT64 offset = 0;
	UINT32 paramSize;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebugFn("Enter");

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_CMK_SetRestrictions, &offset, txBlob,
				    Restriction, ownerAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_CMK_SetRestrictions, txBlob, paramSize,
				       ownerAuth);
	}

	LogResult("CMK_SetRestrictions", result);

done:
	auth_mgr_release_auth(ownerAuth, NULL, hContext);

	return result;
}

TSS_RESULT
TCSP_CMK_ApproveMA_Internal(TCS_CONTEXT_HANDLE	hContext,		/* in */
			    TPM_DIGEST		migAuthorityDigest,	/* in */
			    TPM_AUTH*		ownerAuth,		/* in, out */
			    TPM_HMAC*		HmacMigAuthDigest)	/* out */
{
	TSS_RESULT result;
	UINT64 offset = 0;
	UINT32 paramSize;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebugFn("Enter");

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_CMK_ApproveMA, &offset, txBlob,
				    &migAuthorityDigest, ownerAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_CMK_ApproveMA, txBlob, paramSize,
				       HmacMigAuthDigest, ownerAuth);
	}

	LogResult("CMK_SetRestrictions", result);

done:
	auth_mgr_release_auth(ownerAuth, NULL, hContext);

	return result;
}

TSS_RESULT
TCSP_CMK_CreateKey_Internal(TCS_CONTEXT_HANDLE	hContext,		/* in */
			    TCS_KEY_HANDLE	hWrappingKey,		/* in */
			    TPM_ENCAUTH		KeyUsageAuth,		/* in */
			    TPM_HMAC		MigAuthApproval,	/* in */
			    TPM_DIGEST		MigAuthorityDigest,	/* in */
			    UINT32*		keyDataSize,		/* in, out */
			    BYTE**		prgbKeyData,		/* in, out */
			    TPM_AUTH*		pAuth)			/* in, out */
{
	TSS_RESULT result;
	UINT64 offset = 0;
	UINT32 paramSize;
	UINT32 parentSlot;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebugFn("Enter");

	if ((result = ctx_verify_context(hContext))) {
		free(*prgbKeyData);
		return result;
	}

	if ((result = get_slot(hContext, hWrappingKey, &parentSlot))) {
		free(*prgbKeyData);
		return result;
	}

	if (pAuth) {
		if ((result = auth_mgr_check(hContext, &pAuth->AuthHandle))) {
			free(*prgbKeyData);
			return result;
		}
	}

	if ((result = tpm_rqu_build(TPM_ORD_CMK_CreateKey, &offset, txBlob,
				    parentSlot, &KeyUsageAuth, *keyDataSize, *prgbKeyData,
				    &MigAuthApproval, &MigAuthorityDigest, pAuth))) {
		free(*prgbKeyData);
		goto done;
	}
	free(*prgbKeyData);

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_CMK_CreateKey, txBlob, paramSize,
				       keyDataSize, prgbKeyData, pAuth);
	}

	LogResult("CMK_SetRestrictions", result);

done:
	auth_mgr_release_auth(pAuth, NULL, hContext);

	return result;
}

TSS_RESULT
TCSP_CMK_CreateTicket_Internal(TCS_CONTEXT_HANDLE	hContext,		/* in */
			       UINT32			PublicVerifyKeySize,	/* in */
			       BYTE*			PublicVerifyKey,	/* in */
			       TPM_DIGEST		SignedData,		/* in */
			       UINT32			SigValueSize,		/* in */
			       BYTE*			SigValue,		/* in */
			       TPM_AUTH*		pOwnerAuth,		/* in, out */
			       TPM_HMAC*		SigTicket)		/* out */
{
	TSS_RESULT result;
	UINT64 offset = 0;
	UINT32 paramSize;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebugFn("Enter");

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = auth_mgr_check(hContext, &pOwnerAuth->AuthHandle)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_CMK_CreateTicket, &offset, txBlob,
				    PublicVerifyKeySize, PublicVerifyKey, &SignedData,
				    SigValueSize, SigValue, pOwnerAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_CMK_CreateTicket, txBlob, paramSize,
				       SigTicket, pOwnerAuth);
	}

	LogResult("CMK_SetRestrictions", result);

done:
	auth_mgr_release_auth(pOwnerAuth, NULL, hContext);

	return result;
}

TSS_RESULT
TCSP_CMK_CreateBlob_Internal(TCS_CONTEXT_HANDLE	hContext,		/* in */
			     TCS_KEY_HANDLE	parentHandle,		/* in */
			     TSS_MIGRATE_SCHEME	migrationType,		/* in */
			     UINT32		MigrationKeyAuthSize,	/* in */
			     BYTE*		MigrationKeyAuth,	/* in */
			     TPM_DIGEST		PubSourceKeyDigest,	/* in */
			     UINT32		msaListSize,		/* in */
			     BYTE*		msaList,		/* in */
			     UINT32		restrictTicketSize,	/* in */
			     BYTE*		restrictTicket,		/* in */
			     UINT32		sigTicketSize,		/* in */
			     BYTE*		sigTicket,		/* in */
			     UINT32		encDataSize,		/* in */
			     BYTE*		encData,		/* in */
			     TPM_AUTH*		parentAuth,		/* in, out */
			     UINT32*		randomSize,		/* out */
			     BYTE**		random,			/* out */
			     UINT32*		outDataSize,		/* out */
			     BYTE**		outData)		/* out */
{
	TSS_RESULT result;
	UINT64 offset = 0;
	UINT32 paramSize;
	UINT32 parentSlot;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebugFn("Enter");

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = get_slot(hContext, parentHandle, &parentSlot)))
		return result;

	if (parentAuth) {
		if ((result = auth_mgr_check(hContext, &parentAuth->AuthHandle)))
			return result;
	}

	if ((result = tpm_rqu_build(TPM_ORD_CMK_CreateBlob, &offset, txBlob,
				    parentSlot, migrationType, MigrationKeyAuthSize,
				    MigrationKeyAuth, &PubSourceKeyDigest, msaListSize, msaList,
				    restrictTicketSize, restrictTicket, sigTicketSize, sigTicket,
				    encDataSize, encData, parentAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_CMK_CreateBlob, txBlob, paramSize,
				       randomSize, random, outDataSize, outData, parentAuth, NULL);
	}

	LogResult("CMK_SetRestrictions", result);

done:
	auth_mgr_release_auth(parentAuth, NULL, hContext);

	return result;
}

TSS_RESULT
TCSP_CMK_ConvertMigration_Internal(TCS_CONTEXT_HANDLE	hContext,	/* in */
				   TCS_KEY_HANDLE	parentHandle,	/* in */
				   TPM_CMK_AUTH		restrictTicket,	/* in */
				   TPM_HMAC		sigTicket,	/* in */
				   UINT32		keyDataSize,	/* in */
				   BYTE*		prgbKeyData,	/* in */
				   UINT32		msaListSize,	/* in */
				   BYTE*		msaList,	/* in */
				   UINT32		randomSize,	/* in */
				   BYTE*		random,		/* in */
				   TPM_AUTH*		parentAuth,	/* in, out */
				   UINT32*		outDataSize,	/* out */
				   BYTE**		outData)	/* out */
{
	TSS_RESULT result;
	UINT64 offset = 0;
	UINT32 paramSize;
	UINT32 parentSlot;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebugFn("Enter");

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = get_slot(hContext, parentHandle, &parentSlot)))
		return result;

	if (parentAuth) {
		if ((result = auth_mgr_check(hContext, &parentAuth->AuthHandle)))
			return result;
	}

	if ((result = tpm_rqu_build(TPM_ORD_CMK_ConvertMigration, &offset, txBlob,
				    parentSlot, &restrictTicket, &sigTicket,
				    keyDataSize, prgbKeyData, msaListSize, msaList,
				    randomSize, random, parentAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_CMK_ConvertMigration, txBlob, paramSize,
				       outDataSize, outData, parentAuth, NULL);
	}

	LogResult("CMK_SetRestrictions", result);

done:
	auth_mgr_release_auth(parentAuth, NULL, hContext);

	return result;
}



<|start_filename|>src/tspi/daa/big_integer/bi_openssl.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2006
 *
 */

#ifdef BI_OPENSSL

#define INSIDE_LIB

#include <time.h>
#include <stdio.h>
#include <stdlib.h>

#include <bi.h>

#include "tcslog.h"

#undef INLINE_DECL
#define INLINE_DECL

#include <string.h>
#include <openssl/rand.h>

BN_CTX *context;
static int initialized = 0;

void * (*bi_alloc)(size_t size);

/* return true if <i> is a probably prime  */
INLINE_DECL int bi_is_probable_prime( const bi_ptr i) {
	/*
	* start tests using some small prime numbers. Continue by performing a Miller-Rabin
	* probabilistic primality test with checks iterations, and with  some iterations that
	* yields a false positive rate of at most 2^-80 for random input.
	* return:
	*	0 if the number is composite
	*	1 if it is prime with an error probability of less than 0.25^checks, and on error.
	*/
	return BN_is_prime_fasttest( i, BN_prime_checks, NULL, context, NULL, 1);
}

/*  <result> := ( <g> ^ <e> ) mod <m>  */
INLINE_DECL bi_ptr bi_mod_exp_si( bi_ptr result, const bi_ptr g, const bi_ptr e, const long m) {
	bi_t bi_tmp;

	bi_new( bi_tmp);
	BN_set_word( bi_tmp, m);
#ifdef BI_DEBUG
	printf("[bi_mod_exp] (g=%s ^ e=%s) mod=%s\n",
		BN_bn2dec( g),
		BN_bn2dec( e),
		BN_bn2dec( bi_tmp));
#endif
	BN_mod_exp( result, g, e, bi_tmp, context);	// result := (g ^ e) mod bi_tmp9
#ifdef BI_DEBUG
	printf("[bi_mod_exp] res=%s\n", BN_bn2dec( result));
#endif
	bi_free( bi_tmp);
	return result;
}

/* multiple-exponentiation */
/* <result> := mod( Multi( <g>i, <e>i), number of byte <m>) with  0 <= i <= <n> */
bi_ptr bi_multi_mod_exp( bi_ptr result,
			const int n,
			const bi_t g[],
			const long e[],
			const int m
) {
	BIGNUM *temp = BN_new();
	BIGNUM *bi_m = BN_new();
	BIGNUM *bi_e = BN_new();
	int i;

	BN_set_word( bi_m, m);
	BN_set_word( bi_e, e[0]);
	// result := (g[0] ^ e[0]) mod bi_m
	BN_mod_exp( result, g[0], bi_e, bi_m, context);
	for( i=1; i<n; i++) {
		BN_set_word( bi_e, e[i]);
		// temp := (g[i] ^ e[i]) mod bi_m
		BN_mod_exp( temp, g[i], bi_e, bi_m, context);
		// result := result * temp
		BN_mul( result, result, temp, context);
	}
	BN_mod( result, result, bi_m, context);
	BN_free(bi_e);
	BN_free(bi_m);
	BN_free(temp);
	return result;
}


/***********************************************************************************
  					          INIT/RELEASE LIBRARY
************************************************************************************/

/* bi_alloc_p allocation function used only for exporting a bi struct,
so for bi_2_nbin? for example. if define as NULL, a stdlib malloc() will be used
*/
void bi_init( void * (*bi_alloc_p)(size_t size)) {
	if( initialized == 1) return;
	if( bi_alloc_p == NULL) bi_alloc = &malloc;
	else bi_alloc = bi_alloc_p;
	bi_new( bi_0);
	bi_set_as_si( bi_1, 0);
	bi_new( bi_1);
	bi_set_as_si( bi_1, 1);
	bi_new( bi_2);
	bi_set_as_si( bi_2, 2);
	allocs = list_new();
	if( allocs == NULL) {
		LogError("malloc of list failed");
		return;
	}
	LogDebug("bi_init() -> openssl lib\n");
	LogDebug("bi_init() -> seed status = %d\n", RAND_status());
	context = BN_CTX_new();
	if( RAND_status() != 1) {
		LogError("! PRNG has not been seeded with enough data\n");
#ifdef INTERACTIVE
		printf("type some characters to regenerate a random seed\n");
		fflush(stdout);
		int c, i=0, seed;
		char str[2] = "a";
		while( RAND_status() !=1 ) {
			c = fgetc(stdin);
			time_t temps;
			time( &temps);
			seed += temps +( c << i);
			i++;
			str[0]=c;
			RAND_seed( str, 1);
		}
#endif
	}
	initialized = 1;
}

void bi_release(void) {
	if( initialized) {
		bi_flush_memory();
		bi_free( bi_0);
		bi_free( bi_1);
		bi_free( bi_2);
		BN_CTX_free( context);
		initialized = 0;
	}
}

void bi_flush_memory(void) {
	node_t *current;
	list_ptr list = allocs;

	if( list->head == NULL) return; // list is empty
	else {
		current = list->head; // go to first node
		do {
			LogDebug("[flush memory] free %lx\n", (long)current->obj);
			free( current->obj);
			current = current->next; // traverse through the list
		} while(current != NULL); // until current node is NULL
	}
	list_freeall( allocs);
	allocs = list_new();
	if( allocs == NULL) {
		LogError("malloc of list failed");
		return;
	}
}

int bi_is_initialized(void) {
	return initialized;
}

#endif


<|start_filename|>src/include/tss/tcs_typedef.h<|end_filename|>
/*++

Global typedefs for TSS Core Service
 
*/

#ifndef __TCS_TYPEDEF_H__
#define __TCS_TYPEDEF_H__

#include <tss/tss_structs.h>
#include <tss/tpm.h>

typedef UINT32  TCS_AUTHHANDLE;
typedef UINT32  TCS_CONTEXT_HANDLE;
typedef UINT32  TCS_KEY_HANDLE;
typedef UINT32  TCS_HANDLE;


// Substitution definitions for TCS-IDL
typedef TPM_ENCAUTH                TCG_ENCAUTH;
typedef TPM_NONCE                  TCG_NONCE;
typedef TPM_ENTITY_TYPE            TCG_ENTITY_TYPE;
typedef TPM_PCRINDEX               TCG_PCRINDEX;
typedef TPM_DIGEST                 TCG_DIGEST;
typedef TPM_PCRVALUE               TCG_PCRVALUE;
typedef TPM_DIRVALUE               TCG_DIRVALUE;
typedef TPM_DIRINDEX               TCG_DIRINDEX;



#endif // __TCS_TYPEDEF_H__



<|start_filename|>src/include/tss/platform.h<|end_filename|>
/*++

There are platform dependent and general defines.

--*/

#ifndef TSS_PLATFORM_H
#define TSS_PLATFORM_H


/* The default implementation is to use stdint.h, a part of the C99 standard.
 * Systems that don't support this are handled on a case-by-case basis.
 */

#if !defined(WIN32)
#include <stdint.h>
   typedef uint8_t            BYTE;
   typedef int8_t             TSS_BOOL;
   typedef uint16_t           UINT16;
   typedef uint32_t           UINT32;
   typedef uint64_t           UINT64;

   typedef uint16_t           TSS_UNICODE;
   typedef void*              PVOID;

#elif defined(WIN32)
#include <basetsd.h>
   typedef  unsigned char    BYTE;  
   typedef  signed char      TSS_BOOL;
#ifndef _BASETSD_H_
   // basetsd.h provides definitions of UINT16, UINT32 and UINT64.
   typedef  unsigned short   UINT16;
   typedef  unsigned long    UINT32;
   typedef  unsigned __int64 UINT64;
#endif
   typedef  unsigned short   TSS_UNICODE;
   typedef  void*            PVOID;
#endif


/* Include this so that applications that use names as defined in the
 * 1.1 TSS specification can still compile
 */
#include <tss/compat11b.h>

#endif // TSS_PLATFORM_H


<|start_filename|>src/tspi/rpc/tcstp/rpc_context.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "tsplog.h"
#include "hosttable.h"
#include "tcsd_wrap.h"
#include "rpc_tcstp_tsp.h"


TSS_RESULT
RPC_OpenContext_TP(struct host_table_entry* hte,
		       UINT32*                  tpm_version,
		       TCS_CONTEXT_HANDLE*      tcsContext)
{
	TSS_RESULT result;

	initData(&hte->comm, 0);
	hte->comm.hdr.u.ordinal = TCSD_ORD_OPENCONTEXT;
	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_UINT32, 0, tcsContext, 0, &hte->comm))
			return TSPERR(TSS_E_INTERNAL_ERROR);

		LogDebugFn("Received TCS Context: 0x%x", *tcsContext);

		if (getData(TCSD_PACKET_TYPE_UINT32, 1, tpm_version, 0, &hte->comm))
			return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	return result;
}

TSS_RESULT
RPC_CloseContext_TP(struct host_table_entry *hte)
{
	TSS_RESULT result;

	initData(&hte->comm, 1);
	hte->comm.hdr.u.ordinal = TCSD_ORD_CLOSECONTEXT;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	return result;
}

TSS_RESULT
RPC_FreeMemory_TP(struct host_table_entry *hte,
		  BYTE * pMemory)		/*  in */
{
	free(pMemory);

	return TSS_SUCCESS;
}


<|start_filename|>src/tspi/rpc/tcstp/rpc_caps_tpm.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "hosttable.h"
#include "tcsd_wrap.h"
#include "obj.h"
#include "rpc_tcstp_tsp.h"


TSS_RESULT
RPC_GetTPMCapability_TP(struct host_table_entry *hte,
		      TCPA_CAPABILITY_AREA capArea,	/* in */
		      UINT32 subCapSize,		/* in */
		      BYTE * subCap,			/* in */
		      UINT32 * respSize,		/* out */
		      BYTE ** resp)			/* out */
{
	TSS_RESULT result;

	initData(&hte->comm, 4);
	hte->comm.hdr.u.ordinal = TCSD_ORD_GETCAPABILITY;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &capArea, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 2, &subCapSize, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 3, subCap, subCapSize, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_UINT32, 0, respSize, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		*resp = (BYTE *) malloc(*respSize);
		if (*resp == NULL) {
			LogError("malloc of %u bytes failed.", *respSize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, 1, *resp, *respSize, &hte->comm)) {
			free(*resp);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		}
	}

done:
	return result;
}

TSS_RESULT
RPC_GetCapabilitySigned_TP(struct host_table_entry *hte,
					TCS_KEY_HANDLE keyHandle,	/* in */
					TCPA_NONCE antiReplay,	/* in */
					TCPA_CAPABILITY_AREA capArea,	/* in */
					UINT32 subCapSize,	/* in */
					BYTE * subCap,	/* in */
					TPM_AUTH * privAuth,	/* in, out */
					TCPA_VERSION * Version,	/* out */
					UINT32 * respSize,	/* out */
					BYTE ** resp,	/* out */
					UINT32 * sigSize,	/* out */
					BYTE ** sig)	/* out */
{
	return TSPERR(TSS_E_NOTIMPL);
}

TSS_RESULT
RPC_GetCapabilityOwner_TP(struct host_table_entry *hte,
				       TPM_AUTH * pOwnerAuth,	/* out */
				       TCPA_VERSION * pVersion,	/* out */
				       UINT32 * pNonVolatileFlags,	/* out */
				       UINT32 * pVolatileFlags)	/* out */
{
	TSS_RESULT result;

	initData(&hte->comm, 2);
	hte->comm.hdr.u.ordinal = TCSD_ORD_GETCAPABILITYOWNER;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_AUTH, 1, pOwnerAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_VERSION, 0, pVersion, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		if (getData(TCSD_PACKET_TYPE_UINT32, 1, pNonVolatileFlags, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		if (getData(TCSD_PACKET_TYPE_UINT32, 2, pVolatileFlags, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		if (getData(TCSD_PACKET_TYPE_AUTH, 3, pOwnerAuth, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
	}

	return result;
}

TSS_RESULT
RPC_SetCapability_TP(struct host_table_entry *hte,
		      TCPA_CAPABILITY_AREA capArea,	/* in */
		      UINT32 subCapSize,	/* in */
		      BYTE * subCap,	/* in */
		      UINT32 valueSize,	/* in */
		      BYTE * value,	/* in */
		      TPM_AUTH * pOwnerAuth)	/* in, out */
{
	TSS_RESULT result;

	initData(&hte->comm, 7);
	hte->comm.hdr.u.ordinal = TCSD_ORD_SETCAPABILITY;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &capArea, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 2, &subCapSize, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 3, subCap, subCapSize, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 4, &valueSize, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 5, value, valueSize, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (pOwnerAuth) {
		if (setData(TCSD_PACKET_TYPE_AUTH, 6, pOwnerAuth, 0, &hte->comm))
			return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_AUTH, 0, pOwnerAuth, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
	}

	return result;
}


<|start_filename|>src/tcs/tcsi_own.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "tcsps.h"
#include "req_mgr.h"


TSS_RESULT
TCSP_TakeOwnership_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			    UINT16 protocolID,	/* in */
			    UINT32 encOwnerAuthSize,	/* in  */
			    BYTE * encOwnerAuth,	/* in */
			    UINT32 encSrkAuthSize,	/* in */
			    BYTE * encSrkAuth,	/* in */
			    UINT32 srkInfoSize,	/*in */
			    BYTE * srkInfo,	/*in */
			    TPM_AUTH * ownerAuth,	/* in, out */
			    UINT32 * srkKeySize,	/*out */
			    BYTE ** srkKey)	/*out */
{
	UINT64 offset;
	UINT32 paramSize;
	TSS_RESULT result;
	TSS_KEY srkKeyContainer;
	BYTE fake_pubkey[256] = { 0, }, fake_srk[2048] = { 0, };
	BYTE oldAuthDataUsage;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	if ((result = ctx_verify_context(hContext)))
		goto done;

	if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
		goto done;

	/* Check on the Atmel Bug Patch */
	offset = 0;
	UnloadBlob_TSS_KEY(&offset, srkInfo, &srkKeyContainer);
	oldAuthDataUsage = srkKeyContainer.authDataUsage;
	LogDebug("auth data usage is %.2X", oldAuthDataUsage);

	offset = 0;
	if ((result = tpm_rqu_build(TPM_ORD_TakeOwnership, &offset, txBlob, protocolID,
				    encOwnerAuthSize, encOwnerAuth, encSrkAuthSize, encSrkAuth,
				    srkInfoSize, srkInfo, ownerAuth)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		if ((result = tpm_rsp_parse(TPM_ORD_TakeOwnership, txBlob, paramSize, srkKeySize,
					    srkKey, ownerAuth)))
			goto done;

		offset = 0;
		if ((result = UnloadBlob_TSS_KEY(&offset, *srkKey, &srkKeyContainer))) {
			*srkKeySize = 0;
			free(*srkKey);
			goto done;
		}

		if (srkKeyContainer.authDataUsage != oldAuthDataUsage) {
			LogDebug("AuthDataUsage was changed by TPM.  Atmel Bug. Fixing it in PS");
			srkKeyContainer.authDataUsage = oldAuthDataUsage;
		}

#ifdef TSS_BUILD_PS
		{
			BYTE *save;

			/* Once the key file is created, it stays forever. There could be
			 * migratable keys in the hierarchy that are still useful to someone.
			 */
			result = ps_remove_key(&SRK_UUID);
			if (result != TSS_SUCCESS && result != TCSERR(TSS_E_PS_KEY_NOTFOUND)) {
				destroy_key_refs(&srkKeyContainer);
				LogError("Error removing SRK from key file.");
				*srkKeySize = 0;
				free(*srkKey);
				goto done;
			}

			/* Set the SRK pubkey to all 0's before writing the SRK to disk, this is for
			 * privacy reasons as outlined in the TSS spec */
			save = srkKeyContainer.pubKey.key;
			srkKeyContainer.pubKey.key = fake_pubkey;
			offset = 0;
			LoadBlob_TSS_KEY(&offset, fake_srk, &srkKeyContainer);

			if ((result = ps_write_key(&SRK_UUID, &NULL_UUID, NULL, 0, fake_srk,
						   offset))) {
				destroy_key_refs(&srkKeyContainer);
				LogError("Error writing SRK to disk");
				*srkKeySize = 0;
				free(*srkKey);
				goto done;
			}

			srkKeyContainer.pubKey.key = save;
		}
#endif
		if ((result = mc_add_entry_init(SRK_TPM_HANDLE, SRK_TPM_HANDLE, &srkKeyContainer,
					        &SRK_UUID))) {
			destroy_key_refs(&srkKeyContainer);
			LogError("Error creating SRK mem cache entry");
			*srkKeySize = 0;
			free(*srkKey);
		}
		destroy_key_refs(&srkKeyContainer);
	}
	LogResult("TakeOwnership", result);
done:
	auth_mgr_release_auth(ownerAuth, NULL, hContext);
	return result;
}

TSS_RESULT
TCSP_OwnerClear_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			 TPM_AUTH * ownerAuth)	/* in, out */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering OwnerClear");

	if ((result = ctx_verify_context(hContext)))
		goto done;

	if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
		goto done;

	if ((result = tpm_rqu_build(TPM_ORD_OwnerClear, &offset, txBlob, ownerAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_OwnerClear, txBlob, paramSize, ownerAuth);
	}
	LogResult("Ownerclear", result);
done:
	auth_mgr_release_auth(ownerAuth, NULL, hContext);
	return result;
}



<|start_filename|>src/tcs/tcsi_random.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcsps.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "req_mgr.h"
#include "tcsd_wrap.h"
#include "tcsd.h"


/*
 * Get a random number generated by the TPM.  Most (all?) TPMs return a maximum number of random
 * bytes that's less than the max allowed to be returned at the TSP level, which is 4K bytes.
 * According to the TPM compliance work posted here: http://www.prosec.rub.de/tpmcompliance.html,
 * some TPMs return as little as 132 bytes per query, which would require about 30 loops to get 4K.
 * We'll be extremely conservative here and loop 50 times, since it won't affect performance on
 * TPMs that return more bytes.
 */
TSS_RESULT
TCSP_GetRandom_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			UINT32 * bytesRequested,	/* in, out */
			BYTE ** randomBytes)	/* out */
{
	UINT64 offset;
	TSS_RESULT result;
	UINT32 paramSize, totalReturned = 0, bytesReturned, retries = 50;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE], *rnd_tmp = NULL, *rnd_tmp2 = NULL;

	LogDebugFn("%u bytes", *bytesRequested);

	if ((result = ctx_verify_context(hContext)))
		return result;

	do {
		offset = 0;
		if ((result = tpm_rqu_build(TPM_ORD_GetRandom, &offset, txBlob,
					    *bytesRequested - totalReturned, NULL)))
			break;

		if ((result = req_mgr_submit_req(txBlob)))
			break;;

		result = UnloadBlob_Header(txBlob, &paramSize);
		if (!result) {
#if 0
			offset = 10;
			UnloadBlob_UINT32(&offset, &bytesReturned, txBlob);

			LogDebugFn("received %u bytes from the TPM", bytesReturned);

			rnd_tmp = realloc(rnd_tmp, totalReturned + bytesReturned);
			if (rnd_tmp == NULL) {
				LogError("malloc of %u bytes failed.", bytesReturned);
				return TCSERR(TSS_E_OUTOFMEMORY);
			}
			UnloadBlob(&offset, bytesReturned, txBlob, &rnd_tmp[totalReturned]);
#else
			/* XXX */
			if ((result = tpm_rsp_parse(TPM_ORD_GetRandom, txBlob, paramSize,
						    &bytesReturned, &rnd_tmp, NULL, NULL)))
				break;

			rnd_tmp2 = realloc(*randomBytes, totalReturned + bytesReturned);
			if (rnd_tmp2 == NULL) {
				free(rnd_tmp);
				rnd_tmp = NULL;
				LogError("malloc of %u bytes failed.", bytesReturned);
				result = TCSERR(TSS_E_OUTOFMEMORY);
				break;
			}
			*randomBytes = rnd_tmp2;
			memcpy(*randomBytes + totalReturned, rnd_tmp, bytesReturned);
			free(rnd_tmp);
			rnd_tmp = NULL;
#endif
			totalReturned += bytesReturned;
		} else {
			free(rnd_tmp);
			return result;
		}
	} while (totalReturned < *bytesRequested && retries--);

	if (totalReturned != *bytesRequested) {
		LogDebugFn("Only %u random bytes recieved from TPM.", totalReturned);
		free(rnd_tmp);
		result = TCSERR(TSS_E_FAIL);
#if 0
	} else
		*randomBytes = rnd_tmp;
#else
	}
#endif

	return result;
}

TSS_RESULT
TCSP_StirRandom_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			 UINT32 inDataSize,	/* in */
			 BYTE * inData)	/* in */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering stir random");

	if (inDataSize > 255) {
		LogDebugFn("inData is too large! (%u bytes)", inDataSize);
		return TCSERR(TSS_E_BAD_PARAMETER);
	}

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_StirRandom, &offset, txBlob, inDataSize, inDataSize,
				    inData, NULL, NULL)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);
	LogResult("Stir random", result);
	return result;
}



<|start_filename|>src/tspi/tsp_certify.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2007
 *
 */


#include <stdlib.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


#ifdef TSS_BUILD_TRANSPORT
TSS_RESULT
Transport_CertifyKey(TSS_HCONTEXT tspContext,	/* in */
		     TCS_KEY_HANDLE certHandle,	/* in */
		     TCS_KEY_HANDLE keyHandle,	/* in */
		     TPM_NONCE * antiReplay,	/* in */
		     TPM_AUTH * certAuth,	/* in, out */
		     TPM_AUTH * keyAuth,	/* in, out */
		     UINT32 * CertifyInfoSize,	/* out */
		     BYTE ** CertifyInfo,	/* out */
		     UINT32 * outDataSize,	/* out */
		     BYTE ** outData)		/* out */
{
	TSS_RESULT result;
	UINT32 handlesLen, decLen;
	TCS_HANDLE *handles, handle[2];
	BYTE *dec = NULL;
	TPM_DIGEST pubKeyHash1, pubKeyHash2;
	Trspi_HashCtx hashCtx;
	UINT64 offset;
	BYTE data[sizeof(TPM_NONCE)];


	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	if ((result = obj_tcskey_get_pubkeyhash(certHandle, pubKeyHash1.digest)))
		return result;

	if ((result = obj_tcskey_get_pubkeyhash(keyHandle, pubKeyHash2.digest)))
		return result;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash1.digest);
	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash2.digest);
	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash1.digest)))
		return result;

	handlesLen = 2;
	handle[0] = certHandle;
	handle[1] = keyHandle;
	handles = &handle[0];

	offset = 0;
	Trspi_LoadBlob_NONCE(&offset, data, antiReplay);

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_CertifyKey, sizeof(data),
						    data, &pubKeyHash1, &handlesLen, &handles,
						    certAuth, keyAuth, &decLen, &dec)))
		return result;

	offset = 0;
	Trspi_UnloadBlob_CERTIFY_INFO(&offset, dec, NULL);
	*CertifyInfoSize = offset;

	if ((*CertifyInfo = malloc(*CertifyInfoSize)) == NULL) {
		free(dec);
		LogError("malloc of %u bytes failed", *CertifyInfoSize);
		*CertifyInfoSize = 0;
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	offset = 0;
	Trspi_UnloadBlob(&offset, *CertifyInfoSize, dec, *CertifyInfo);
	Trspi_UnloadBlob_UINT32(&offset, outDataSize, dec);

	if ((*outData = malloc(*outDataSize)) == NULL) {
		free(*CertifyInfo);
		*CertifyInfo = NULL;
		*CertifyInfoSize = 0;
		free(dec);
		LogError("malloc of %u bytes failed", *outDataSize);
		*outDataSize = 0;
		return TSPERR(TSS_E_OUTOFMEMORY);
	}
	Trspi_UnloadBlob(&offset, *outDataSize, dec, *outData);

	free(dec);

	return result;
}
#endif



<|start_filename|>src/tspi/tspi_bind.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


TSS_RESULT
Tspi_Data_Bind(TSS_HENCDATA hEncData,	/* in */
	       TSS_HKEY hEncKey,	/* in */
	       UINT32 ulDataLength,	/* in */
	       BYTE *rgbDataToBind)	/* in */
{
	UINT32 encDataLength;
	BYTE encData[256];
	BYTE *keyData;
	UINT32 keyDataLength;
	TCPA_BOUND_DATA boundData;
	UINT64 offset;
	BYTE bdblob[256];
	TCPA_RESULT result;
	TSS_KEY keyContainer;
	TSS_HCONTEXT tspContext;

	if (rgbDataToBind == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if (!obj_is_encdata(hEncData))
		return TSPERR(TSS_E_INVALID_HANDLE);

	if ((result = obj_rsakey_get_tsp_context(hEncKey, &tspContext)))
		return result;

	/* XXX Just get the pubkey here */
	if ((result = obj_rsakey_get_blob(hEncKey, &keyDataLength, &keyData)))
		return result;

	offset = 0;
	if ((result = UnloadBlob_TSS_KEY(&offset, keyData, &keyContainer))) {
		free_tspi(tspContext, keyData);
		return result;
	}
	free_tspi(tspContext, keyData);

	if (keyContainer.keyUsage != TPM_KEY_BIND &&
	    keyContainer.keyUsage != TPM_KEY_LEGACY) {
		result = TSPERR(TSS_E_INVALID_KEYUSAGE);
		goto done;
	}

	if (keyContainer.pubKey.keyLength < ulDataLength) {
		result = TSPERR(TSS_E_ENC_INVALID_LENGTH);
		goto done;
	}

	if (keyContainer.algorithmParms.encScheme == TCPA_ES_RSAESPKCSv15 &&
	    keyContainer.keyUsage == TPM_KEY_LEGACY) {
		if ((result = Trspi_RSA_PKCS15_Encrypt(rgbDataToBind, ulDataLength, encData,
						       &encDataLength, keyContainer.pubKey.key,
						       keyContainer.pubKey.keyLength)))
			goto done;
	} else if (keyContainer.algorithmParms.encScheme == TCPA_ES_RSAESPKCSv15 &&
		   keyContainer.keyUsage == TPM_KEY_BIND) {
		boundData.payload = TCPA_PT_BIND;

		memcpy(&boundData.ver, &VERSION_1_1, sizeof(TCPA_VERSION));

		boundData.payloadData = malloc(ulDataLength);
		if (boundData.payloadData == NULL) {
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		memcpy(boundData.payloadData, rgbDataToBind, ulDataLength);

		offset = 0;
		Trspi_LoadBlob_BOUND_DATA(&offset, boundData, ulDataLength, bdblob);

		if ((result = Trspi_RSA_PKCS15_Encrypt(bdblob, offset, encData,
						       &encDataLength, keyContainer.pubKey.key,
						       keyContainer.pubKey.keyLength))) {
			free(boundData.payloadData);
			goto done;
		}
		free(boundData.payloadData);
	} else {
		boundData.payload = TCPA_PT_BIND;

		memcpy(&boundData.ver, &VERSION_1_1, sizeof(TCPA_VERSION));

		boundData.payloadData = malloc(ulDataLength);
		if (boundData.payloadData == NULL) {
			LogError("malloc of %u bytes failed.", ulDataLength);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		memcpy(boundData.payloadData, rgbDataToBind, ulDataLength);

		offset = 0;
		Trspi_LoadBlob_BOUND_DATA(&offset, boundData, ulDataLength, bdblob);

		if ((result = Trspi_RSA_Encrypt(bdblob, offset, encData, &encDataLength,
						keyContainer.pubKey.key,
						keyContainer.pubKey.keyLength))) {
			free(boundData.payloadData);
			goto done;
		}

		free(boundData.payloadData);
	}

	if ((result = obj_encdata_set_data(hEncData, encDataLength, encData))) {
		LogError("Error in calling SetAttribData on the encrypted data object.");
		result = TSPERR(TSS_E_INTERNAL_ERROR);
		goto done;
	}
done:
	free_key_refs(&keyContainer);
	return result;
}

TSS_RESULT
Tspi_Data_Unbind(TSS_HENCDATA hEncData,		/* in */
		 TSS_HKEY hKey,			/* in */
		 UINT32 * pulUnboundDataLength,	/* out */
		 BYTE ** prgbUnboundData)	/* out */
{
	TCPA_RESULT result;
	TPM_AUTH privAuth;
	TCPA_DIGEST digest;
	TSS_HPOLICY hPolicy;
	BYTE *encData;
	UINT32 encDataSize;
	TCS_KEY_HANDLE tcsKeyHandle;
	TSS_BOOL usesAuth;
	TPM_AUTH *pPrivAuth;
        TSS_HCONTEXT tspContext;
	Trspi_HashCtx hashCtx;

	if (pulUnboundDataLength == NULL || prgbUnboundData == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if ((result = obj_encdata_get_tsp_context(hEncData, &tspContext)))
		return result;

	if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, &hPolicy, &usesAuth)))
		return result;

	if ((result = obj_encdata_get_data(hEncData, &encDataSize, &encData)))
		return result == (TSS_E_INVALID_OBJ_ACCESS | TSS_LAYER_TSP) ?
		       TSPERR(TSS_E_ENC_NO_DATA) :
		       result;

	if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKeyHandle)))
		return result;

	if (usesAuth) {
		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_UnBind);
		result |= Trspi_Hash_UINT32(&hashCtx, encDataSize);
		result |= Trspi_HashUpdate(&hashCtx, encDataSize, encData);
		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
			return result;

		if ((result = secret_PerformAuth_OIAP(hKey, TPM_ORD_UnBind, hPolicy, FALSE, &digest,
						      &privAuth)))
			return result;
		pPrivAuth = &privAuth;
	} else {
		pPrivAuth = NULL;
	}

	if ((result = TCS_API(tspContext)->UnBind(tspContext, tcsKeyHandle, encDataSize, encData,
						  pPrivAuth, pulUnboundDataLength,
						  prgbUnboundData)))
		return result;

	if (usesAuth) {
		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
		result |= Trspi_Hash_UINT32(&hashCtx, result);
		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_UnBind);
		result |= Trspi_Hash_UINT32(&hashCtx, *pulUnboundDataLength);
		result |= Trspi_HashUpdate(&hashCtx, *pulUnboundDataLength, *prgbUnboundData);
		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
			goto error;

		if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &privAuth)))
			goto error;
	}

	if ((result = __tspi_add_mem_entry(tspContext, *prgbUnboundData)))
		goto error;

	return TSS_SUCCESS;
error:
	free(*prgbUnboundData);
	*prgbUnboundData = NULL;
	*pulUnboundDataLength = 0;
	return result;
}



<|start_filename|>src/tcs/tcsi_ek.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004, 2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcsps.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "req_mgr.h"
#include "tcsd_wrap.h"
#include "tcsd.h"

TSS_RESULT
TCSP_CreateEndorsementKeyPair_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
				       TCPA_NONCE antiReplay,	/* in */
				       UINT32 endorsementKeyInfoSize,	/* in */
				       BYTE * endorsementKeyInfo,	/* in */
				       UINT32 * endorsementKeySize,	/* out */
				       BYTE ** endorsementKey,	/* out */
				       TCPA_DIGEST * checksum)	/* out */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_CreateEndorsementKeyPair, &offset, txBlob,
				    antiReplay.nonce, endorsementKeyInfoSize,
				    endorsementKeyInfo)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_CreateEndorsementKeyPair, txBlob, paramSize,
				       endorsementKeySize, endorsementKey, checksum->digest);
	}
	LogDebug("Leaving CreateEKPair with result: 0x%x", result);
	return result;
}

TSS_RESULT
TCSP_ReadPubek_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			TCPA_NONCE antiReplay,	/* in */
			UINT32 * pubEndorsementKeySize,	/* out */
			BYTE ** pubEndorsementKey,	/* out */
			TCPA_DIGEST * checksum)	/* out */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebugFn("Enter");

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_ReadPubek, &offset, txBlob, TPM_NONCE_SIZE,
				    antiReplay.nonce)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_ReadPubek, txBlob, paramSize, pubEndorsementKeySize,
				       pubEndorsementKey, checksum->digest);
	}
	LogDebugFn("result: 0x%x", result);
	return result;
}

TSS_RESULT
TCSP_DisablePubekRead_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			       TPM_AUTH * ownerAuth)	/* in, out */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("DisablePubekRead");

	if ((result = ctx_verify_context(hContext)))
		goto done;

	if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
		goto done;

	if ((result = tpm_rqu_build(TPM_ORD_DisablePubekRead, &offset, txBlob, ownerAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_DisablePubekRead, txBlob, paramSize, ownerAuth);
	}
done:
	auth_mgr_release_auth(ownerAuth, NULL, hContext);
	return result;
}

TSS_RESULT
TCSP_OwnerReadPubek_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			     TPM_AUTH * ownerAuth,	/* in, out */
			     UINT32 * pubEndorsementKeySize,	/* out */
			     BYTE ** pubEndorsementKey)	/* out */
{
	UINT32 paramSize;
	TSS_RESULT result;
	UINT64 offset = 0;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering OwnerReadPubek");

	if ((result = ctx_verify_context(hContext)))
		goto done;

	if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle)))
		goto done;

	if ((result = tpm_rqu_build(TPM_ORD_OwnerReadPubek, &offset, txBlob, ownerAuth)))
		goto done;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);

	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_OwnerReadPubek, txBlob, paramSize,
				       pubEndorsementKeySize, pubEndorsementKey, ownerAuth);
	}
	LogResult("Owner Read Pubek", result);
done:
	auth_mgr_release_auth(ownerAuth, NULL, hContext);
	return result;
}

TSS_RESULT
TCSP_CreateRevocableEndorsementKeyPair_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
						TPM_NONCE antiReplay,	/* in */
						UINT32 endorsementKeyInfoSize,	/* in */
						BYTE * endorsementKeyInfo,	/* in */
						TSS_BOOL genResetAuth,	/* in */
						TPM_DIGEST * eKResetAuth, /* in, out */
						UINT32 * endorsementKeySize,	/* out */
						BYTE ** endorsementKey,	/* out */
						TPM_DIGEST * checksum)	/* out */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_CreateRevocableEK, &offset, txBlob,
				    antiReplay.nonce, endorsementKeyInfoSize,
				    endorsementKeyInfo, genResetAuth, eKResetAuth->digest)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_CreateRevocableEK, txBlob, paramSize,
				endorsementKeySize, endorsementKey, checksum->digest,
				eKResetAuth->digest);
	}

	LogDebug("Leaving CreateRevocableEKPair with result: 0x%x", result);
	return result;
}

TSS_RESULT
TCSP_RevokeEndorsementKeyPair_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
				       TPM_DIGEST EKResetAuth)		/* in */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_RevokeTrust, &offset, txBlob, EKResetAuth.digest)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);

	LogDebug("Leaving RevokeEKPair with result: 0x%x", result);
	return result;
}



<|start_filename|>src/include/tss/tddli.h<|end_filename|>
/*++

TPM Device Driver Library interface
 
--*/

#ifndef __TDDLI_H__
#define __TDDLI_H__

#include <tss/tss_typedef.h>
#include <tss/tddl_error.h>

#if !defined(TDDLI)
#ifdef WIN32
// --- This should be used on Windows platforms
#ifdef TDDLI_EXPORTS
#define TDDLI __declspec(dllexport)
#else
#define TDDLI __declspec(dllimport)
#endif
#else
#define TDDLI 
#endif
#endif /* !defined(TDDLI) */


#define TDDL_CAP_VERSION   0x0100
#define TDDL_CAP_VER_DRV   0x0101
#define TDDL_CAP_VER_FW    0x0102
#define TDDL_CAP_VER_FW_DATE   0x0103

#define TDDL_CAP_PROPERTY   0x0200
#define TDDL_CAP_PROP_MANUFACTURER  0x0201
#define TDDL_CAP_PROP_MODULE_TYPE  0x0202
#define TDDL_CAP_PROP_GLOBAL_STATE  0x0203


//--------------------------------------------------------------------
// TDDL specific helper redefinitions

#ifdef __cplusplus
extern "C" {
#endif

    //establish a connection to the TPM device driver
    TDDLI TSS_RESULT Tddli_Open(void);
 
    //close a open connection to the TPM device driver
    TDDLI TSS_RESULT Tddli_Close(void);

    //cancels the last outstanding TPM command
    TDDLI TSS_RESULT Tddli_Cancel(void);

    // read the attributes returned by the TPM HW/FW
    TDDLI TSS_RESULT Tddli_GetCapability(
        UINT32        CapArea,
        UINT32        SubCap,
        BYTE         *pCapBuf,
        UINT32       *puntCapBufLen);

    // set parameters to the TPM HW/FW
    TDDLI TSS_RESULT Tddli_SetCapability(
        UINT32        CapArea,
        UINT32        SubCap,
        BYTE         *pCapBuf,
        UINT32        puntCapBufLen);

    // get status of the TPM driver and device
    TDDLI TSS_RESULT Tddli_GetStatus(
        UINT32        ReqStatusType,
        UINT32       *puntStatus);

    // send any data to the TPM module
    TDDLI TSS_RESULT Tddli_TransmitData(
        BYTE         *pTransmitBuf,
        UINT32        TransmitBufLen,
        BYTE         *pReceiveBuf,
        UINT32       *puntReceiveBufLen);

    TDDLI TSS_RESULT Tddli_SetPowerManagement(
        TSS_BOOL      SendSaveStateCommand,       // in
        UINT32       *QuerySetNewTPMPowerState);  // in, out

    TDDLI TSS_RESULT Tddli_PowerManagementControl(
        TSS_BOOL      SendPowerManager,           // in
        UINT32       *DriverManagesPowerStates);  // out

    
#ifdef __cplusplus
}
#endif

#endif // __TDDLI_H__



<|start_filename|>src/tspi/tspi_counter.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


TSS_RESULT
Tspi_TPM_ReadCounter(TSS_HTPM hTPM,		/* in */
		     UINT32*  counterValue)	/* out */
{
	TSS_HCONTEXT tspContext;
	TCPA_RESULT result;
	TSS_COUNTER_ID counterID;
	TPM_COUNTER_VALUE counter_value;

	if (counterValue == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
		return result;

	if ((result = obj_tpm_get_current_counter(hTPM, &counterID)))
		return result;

	if ((result = TCS_API(tspContext)->ReadCounter(tspContext, counterID, &counter_value)))
		return result;

	*counterValue = counter_value.counter;

	return TSS_SUCCESS;
}


<|start_filename|>src/tspi/rpc/tcstp/rpc_aik.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "hosttable.h"
#include "tcsd_wrap.h"
#include "obj.h"
#include "rpc_tcstp_tsp.h"


TSS_RESULT
RPC_MakeIdentity_TP(struct host_table_entry *hte,
		    TCPA_ENCAUTH identityAuth,	/* in */
		    TCPA_CHOSENID_HASH IDLabel_PrivCAHash,	/* in */
		    UINT32 idKeyInfoSize,	/* in */
		    BYTE * idKeyInfo,	/* in */
		    TPM_AUTH * pSrkAuth,	/* in, out */
		    TPM_AUTH * pOwnerAuth,	/* in, out */
		    UINT32 * idKeySize,	/* out */
		    BYTE ** idKey,	/* out */
		    UINT32 * pcIdentityBindingSize,	/* out */
		    BYTE ** prgbIdentityBinding,	/* out */
		    UINT32 * pcEndorsementCredentialSize,	/* out */
		    BYTE ** prgbEndorsementCredential,	/* out */
		    UINT32 * pcPlatformCredentialSize,	/* out */
		    BYTE ** prgbPlatformCredential,	/* out */
		    UINT32 * pcConformanceCredentialSize,	/* out */
		    BYTE ** prgbConformanceCredential)	/* out */
{
	TSS_RESULT result;
	int i;

	initData(&hte->comm, 7);
	hte->comm.hdr.u.ordinal = TCSD_ORD_MAKEIDENTITY;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_ENCAUTH, 1, &identityAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_DIGEST, 2, &IDLabel_PrivCAHash, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 3, &idKeyInfoSize, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 4, idKeyInfo, idKeyInfoSize, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	i = 5;
	if (pSrkAuth) {
		if (setData(TCSD_PACKET_TYPE_AUTH, i++, pSrkAuth, 0, &hte->comm))
			return TSPERR(TSS_E_INTERNAL_ERROR);
	}
	if (setData(TCSD_PACKET_TYPE_AUTH, i++, pOwnerAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	i = 0;
	if (result == TSS_SUCCESS) {
		i = 0;
		if (pSrkAuth) {
			if (getData(TCSD_PACKET_TYPE_AUTH, i++, pSrkAuth, 0, &hte->comm)) {
				result = TSPERR(TSS_E_INTERNAL_ERROR);
				goto done;
			}
		}
		if (getData(TCSD_PACKET_TYPE_AUTH, i++, pOwnerAuth, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_UINT32, i++, idKeySize, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		*idKey = (BYTE *) malloc(*idKeySize);
		if (*idKey == NULL) {
			LogError("malloc of %u bytes failed.", *idKeySize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *idKey, *idKeySize, &hte->comm)) {
			free(*idKey);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_UINT32, i++, pcIdentityBindingSize, 0, &hte->comm)) {
			free(*idKey);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		*prgbIdentityBinding = (BYTE *) malloc(*pcIdentityBindingSize);
		if (*prgbIdentityBinding == NULL) {
			LogError("malloc of %u bytes failed.", *pcIdentityBindingSize);
			free(*idKey);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *prgbIdentityBinding, *pcIdentityBindingSize, &hte->comm)) {
			free(*idKey);
			free(*prgbIdentityBinding);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_UINT32, i++, pcEndorsementCredentialSize, 0, &hte->comm)) {
			free(*idKey);
			free(*prgbIdentityBinding);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		*prgbEndorsementCredential = (BYTE *) malloc(*pcEndorsementCredentialSize);
		if (*prgbEndorsementCredential == NULL) {
			LogError("malloc of %u bytes failed.", *pcEndorsementCredentialSize);
			free(*idKey);
			free(*prgbIdentityBinding);
			*prgbIdentityBinding = NULL;
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *prgbEndorsementCredential, *pcEndorsementCredentialSize, &hte->comm)) {
			free(*idKey);
			free(*prgbIdentityBinding);
			*prgbIdentityBinding = NULL;
			free(*prgbEndorsementCredential);
			*prgbEndorsementCredential = NULL;
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_UINT32, i++, pcPlatformCredentialSize, 0, &hte->comm)) {
			free(*idKey);
			free(*prgbIdentityBinding);
			*prgbIdentityBinding = NULL;
			free(*prgbEndorsementCredential);
			*prgbEndorsementCredential = NULL;
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		*prgbPlatformCredential = (BYTE *) malloc(*pcPlatformCredentialSize);
		if (*prgbPlatformCredential == NULL) {
			LogError("malloc of %u bytes failed.", *pcPlatformCredentialSize);
			free(*idKey);
			free(*prgbIdentityBinding);
			*prgbIdentityBinding = NULL;
			free(*prgbEndorsementCredential);
			*prgbEndorsementCredential = NULL;
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *prgbPlatformCredential, *pcPlatformCredentialSize, &hte->comm)) {
			free(*idKey);
			free(*prgbIdentityBinding);
			*prgbIdentityBinding = NULL;
			free(*prgbEndorsementCredential);
			*prgbEndorsementCredential = NULL;
			free(*prgbPlatformCredential);
			*prgbPlatformCredential = NULL;
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_UINT32, i++, pcConformanceCredentialSize, 0, &hte->comm)) {
			free(*idKey);
			free(*prgbIdentityBinding);
			*prgbIdentityBinding = NULL;
			free(*prgbEndorsementCredential);
			*prgbEndorsementCredential = NULL;
			free(*prgbPlatformCredential);
			*prgbPlatformCredential = NULL;
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		*prgbConformanceCredential = (BYTE *) malloc(*pcConformanceCredentialSize);
		if (*prgbConformanceCredential == NULL) {
			LogError("malloc of %u bytes failed.", *pcConformanceCredentialSize);
			free(*idKey);
			free(*prgbIdentityBinding);
			*prgbIdentityBinding = NULL;
			free(*prgbEndorsementCredential);
			*prgbEndorsementCredential = NULL;
			free(*prgbPlatformCredential);
			*prgbPlatformCredential = NULL;
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *prgbConformanceCredential, *pcConformanceCredentialSize, &hte->comm)) {
			free(*idKey);
			free(*prgbIdentityBinding);
			*prgbIdentityBinding = NULL;
			free(*prgbEndorsementCredential);
			*prgbEndorsementCredential = NULL;
			free(*prgbPlatformCredential);
			*prgbPlatformCredential = NULL;
			free(*prgbConformanceCredential);
			*prgbConformanceCredential = NULL;
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		}
	}

done:
	return result;
}

TSS_RESULT
RPC_GetCredential_TP(struct host_table_entry *hte,
		     UINT32 ulCredentialType,          /* in */
		     UINT32 ulCredentialAccessMode,    /* in */
		     UINT32 * pulCredentialSize,       /* out */
		     BYTE ** prgbCredentialData)       /* out */
{
	TSS_RESULT result;

	initData(&hte->comm, 3);
	hte->comm.hdr.u.ordinal = TCSD_ORD_GETCREDENTIAL;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &ulCredentialType, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 2, &ulCredentialAccessMode, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_UINT32, 0, pulCredentialSize, 0, &hte->comm)) {
			return TSPERR(TSS_E_INTERNAL_ERROR);
		}

		*prgbCredentialData = (BYTE *) malloc(*pulCredentialSize);
		if (*prgbCredentialData == NULL) {
			LogError("malloc of %u bytes failed.", *pulCredentialSize);
			return TSPERR(TSS_E_OUTOFMEMORY);
		}

		if (getData(TCSD_PACKET_TYPE_PBYTE, 1, *prgbCredentialData,
			    *pulCredentialSize, &hte->comm)) {
			free(*prgbCredentialData);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
                }
	}
	return result;
}

TSS_RESULT
RPC_ActivateTPMIdentity_TP(struct host_table_entry *hte,
			   TCS_KEY_HANDLE idKey,	/* in */
			   UINT32 blobSize,	/* in */
			   BYTE * blob,	/* in */
			   TPM_AUTH * idKeyAuth,	/* in, out */
			   TPM_AUTH * ownerAuth,	/* in, out */
			   UINT32 * SymmetricKeySize,	/* out */
			   BYTE ** SymmetricKey)	/* out */
{
	TSS_RESULT result;
	int i = 0;

	initData(&hte->comm, 6);
	hte->comm.hdr.u.ordinal = TCSD_ORD_ACTIVATETPMIDENTITY;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, i++, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, i++, &idKey, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, i++, &blobSize, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, i++, blob, blobSize, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	if (idKeyAuth) {
		if (setData(TCSD_PACKET_TYPE_AUTH, i++, idKeyAuth, 0, &hte->comm))
			return TSPERR(TSS_E_INTERNAL_ERROR);
	}
	if (setData(TCSD_PACKET_TYPE_AUTH, i++, ownerAuth, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		i = 0;
		if (idKeyAuth) {
			if (getData(TCSD_PACKET_TYPE_AUTH, i++, idKeyAuth, 0, &hte->comm))
				result = TSPERR(TSS_E_INTERNAL_ERROR);
		}
		if (getData(TCSD_PACKET_TYPE_AUTH, i++, ownerAuth, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_UINT32, i++, SymmetricKeySize, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}

		*SymmetricKey = malloc(*SymmetricKeySize);
		if (*SymmetricKey == NULL) {
			LogError("malloc of %u bytes failed.", *SymmetricKeySize);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *SymmetricKey, *SymmetricKeySize, &hte->comm)) {
			free(*SymmetricKey);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		}
	}
done:
	return result;
}


<|start_filename|>src/tspi/tspi_policy.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <errno.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


TSS_RESULT
Tspi_GetPolicyObject(TSS_HOBJECT hObject,	/* in */
		     TSS_FLAG policyType,	/* in */
		     TSS_HPOLICY * phPolicy)	/* out */
{
	TSS_RESULT result;

	if (phPolicy == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if (obj_is_tpm(hObject)) {
		result = obj_tpm_get_policy(hObject, policyType, phPolicy);
#ifdef TSS_BUILD_NV
	} else if (obj_is_nvstore(hObject)) {
		result = obj_nvstore_get_policy(hObject, policyType, phPolicy);
#endif
#ifdef TSS_BUILD_RSAKEY_LIST
	} else if (obj_is_rsakey(hObject)) {
		result = obj_rsakey_get_policy(hObject, policyType, phPolicy, NULL);
#endif
#ifdef TSS_BUILD_ENCDATA_LIST
	} else if (obj_is_encdata(hObject)) {
		result = obj_encdata_get_policy(hObject, policyType, phPolicy);
#endif
	} else {
		if (obj_is_policy(hObject) || obj_is_hash(hObject) ||
		    obj_is_pcrs(hObject) || obj_is_context(hObject))
			result = TSPERR(TSS_E_BAD_PARAMETER);
		else
			result = TSPERR(TSS_E_INVALID_HANDLE);
	}

	if (result == TSS_SUCCESS && *phPolicy == NULL_HPOLICY)
		result = TSPERR(TSS_E_INTERNAL_ERROR);

	return result;
}

TSS_RESULT
Tspi_Policy_SetSecret(TSS_HPOLICY hPolicy,	/* in */
		      TSS_FLAG secretMode,	/* in */
		      UINT32 ulSecretLength,	/* in */
		      BYTE * rgbSecret)		/* in */
{
	TSS_RESULT result;
	TSS_HCONTEXT tspContext;

	if ((result = obj_policy_get_tsp_context(hPolicy, &tspContext)))
		return result;

	if (obj_context_is_silent(tspContext) && secretMode == TSS_SECRET_MODE_POPUP)
		return TSPERR(TSS_E_SILENT_CONTEXT);

	return obj_policy_set_secret(hPolicy, secretMode, ulSecretLength, rgbSecret);
}

TSS_RESULT
Tspi_Policy_FlushSecret(TSS_HPOLICY hPolicy)	/* in */
{
	return obj_policy_flush_secret(hPolicy);
}

TSS_RESULT
Tspi_Policy_AssignToObject(TSS_HPOLICY hPolicy,	/* in */
			   TSS_HOBJECT hObject)	/* in */
{
	TSS_RESULT result;

	if (obj_is_tpm(hObject)) {
		result = obj_tpm_set_policy(hObject, hPolicy);
#ifdef TSS_BUILD_NV
	} else if (obj_is_nvstore(hObject)) {
		result = obj_nvstore_set_policy(hObject, hPolicy);
#endif
#ifdef TSS_BUILD_RSAKEY_LIST
	} else if (obj_is_rsakey(hObject)) {
		result = obj_rsakey_set_policy(hObject, hPolicy);
#endif
#ifdef TSS_BUILD_ENCDATA_LIST
	} else if (obj_is_encdata(hObject)) {
		result = obj_encdata_set_policy(hObject, hPolicy);
#endif
	} else {
		result = TSPERR(TSS_E_BAD_PARAMETER);
	}

	return result;
}


<|start_filename|>src/tspi/rpc/tcstp/rpc_pcr_extend.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "hosttable.h"
#include "tcsd_wrap.h"
#include "obj.h"
#include "rpc_tcstp_tsp.h"


TSS_RESULT
RPC_Extend_TP(struct host_table_entry *hte,
			   TCPA_PCRINDEX pcrNum,	/* in */
			   TCPA_DIGEST inDigest,	/* in */
			   TCPA_PCRVALUE * outDigest	/* out */
    ) {
	TSS_RESULT result;

	initData(&hte->comm, 3);
	hte->comm.hdr.u.ordinal = TCSD_ORD_EXTEND;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &pcrNum, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_DIGEST, 2, &inDigest, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_DIGEST, 0, outDigest, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
	}

	return result;
}

TSS_RESULT
RPC_PcrRead_TP(struct host_table_entry *hte,
			    TCPA_PCRINDEX pcrNum,	/* in */
			    TCPA_PCRVALUE * outDigest	/* out */
    ) {
	TSS_RESULT result;

	initData(&hte->comm, 2);
	hte->comm.hdr.u.ordinal = TCSD_ORD_PCRREAD;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &pcrNum, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_DIGEST, 0, outDigest, 0, &hte->comm))
			result = TSPERR(TSS_E_INTERNAL_ERROR);
	}

	return result;
}

TSS_RESULT
RPC_PcrReset_TP(struct host_table_entry *hte,
		 UINT32 pcrDataSizeIn,		 /* in */
		 BYTE * pcrDataIn)		 /* in */
{
	TSS_RESULT result;

	initData(&hte->comm, 3);
	hte->comm.hdr.u.ordinal = TCSD_ORD_PCRRESET;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &pcrDataSizeIn, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 2, pcrDataIn, pcrDataSizeIn, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	return result;
}


<|start_filename|>src/tspi/rpc/tcstp/rpc_random.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "hosttable.h"
#include "tcsd_wrap.h"
#include "obj.h"
#include "rpc_tcstp_tsp.h"


TSS_RESULT
RPC_GetRandom_TP(struct host_table_entry *hte,
		  UINT32 bytesRequested,	/* in */
		  BYTE ** randomBytes)	/* out */
{
	TSS_RESULT result;

	initData(&hte->comm, 2);
	hte->comm.hdr.u.ordinal = TCSD_ORD_GETRANDOM;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &bytesRequested, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	if (result == TSS_SUCCESS) {
		if (getData(TCSD_PACKET_TYPE_UINT32, 0, &bytesRequested, 0, &hte->comm)) {
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
		*randomBytes = (BYTE *) malloc(bytesRequested);
		if (*randomBytes == NULL) {
			LogError("malloc of %u bytes failed.", bytesRequested);
			result = TSPERR(TSS_E_OUTOFMEMORY);
			goto done;
		}
		if (getData(TCSD_PACKET_TYPE_PBYTE, 1, *randomBytes, bytesRequested, &hte->comm)) {
			free(*randomBytes);
			result = TSPERR(TSS_E_INTERNAL_ERROR);
		}
	}

done:
	return result;
}

TSS_RESULT
RPC_StirRandom_TP(struct host_table_entry *hte,
		   UINT32 inDataSize,	/* in */
		   BYTE * inData)	/* in */
{
	TSS_RESULT result;

	initData(&hte->comm, 3);
	hte->comm.hdr.u.ordinal = TCSD_ORD_STIRRANDOM;
	LogDebugFn("TCS Context: 0x%x", hte->tcsContext);

	if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_UINT32, 1, &inDataSize, 0, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);
	if (setData(TCSD_PACKET_TYPE_PBYTE, 2, inData, inDataSize, &hte->comm))
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result = sendTCSDPacket(hte);

	if (result == TSS_SUCCESS)
		result = hte->comm.hdr.u.result;

	return result;
}


<|start_filename|>src/include/tss/tddl_error.h<|end_filename|>
/*++

TPM Device Driver Library error return codes 
 
--*/

#ifndef __TDDL_ERROR_H__
#define __TDDL_ERROR_H__

#include <tss/tss_error_basics.h>
#include <tss/tss_error.h>


#ifndef TSS_E_BASE
#define TSS_E_BASE      0x00000000L
#endif // TSS_E_BASE


//
// specific error codes returned by the TPM device driver library
// offset TSS_TDDL_OFFSET
//
#define TDDL_E_FAIL 		TSS_E_FAIL
#define TDDL_E_TIMEOUT 		TSS_E_TIMEOUT

// The connection was already established.
#define TDDL_E_ALREADY_OPENED   (UINT32)(TSS_E_BASE + 0x081L)

// The device was not connected.
#define TDDL_E_ALREADY_CLOSED   (UINT32)(TSS_E_BASE + 0x082L)

// The receive buffer is too small.
#define TDDL_E_INSUFFICIENT_BUFFER  (UINT32)(TSS_E_BASE + 0x083L)

// The command has already completed.
#define TDDL_E_COMMAND_COMPLETED  (UINT32)(TSS_E_BASE + 0x084L)

// TPM aborted processing of command.
#define TDDL_E_COMMAND_ABORTED  (UINT32)(TSS_E_BASE + 0x085L)

//  The request could not be performed because of an I/O device error.
#define TDDL_E_IOERROR    (UINT32)(TSS_E_BASE + 0x087L)

// Unsupported TAG is requested
#define TDDL_E_BADTAG    (UINT32)(TSS_E_BASE + 0x088L)

// the requested TPM component was not found
#define TDDL_E_COMPONENT_NOT_FOUND  (UINT32)(TSS_E_BASE + 0x089L)

#endif // __TDDL_ERROR_H__



<|start_filename|>src/tspi/tsp_own.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <errno.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


TSS_RESULT
secret_TakeOwnership(TSS_HKEY hEndorsementPubKey,
		     TSS_HTPM hTPM,
		     TSS_HKEY hKeySRK,
		     TPM_AUTH * auth,
		     UINT32 * encOwnerAuthLength,
		     BYTE * encOwnerAuth, UINT32 * encSRKAuthLength, BYTE * encSRKAuth)
{
	TSS_RESULT result;
	UINT32 endorsementKeySize;
	BYTE *endorsementKey;
	TSS_KEY dummyKey;
	UINT64 offset;
	TCPA_SECRET ownerSecret;
	TCPA_SECRET srkSecret;
	TCPA_DIGEST digest;
	TSS_HPOLICY hSrkPolicy;
	TSS_HPOLICY hOwnerPolicy;
	UINT32 srkKeyBlobLength;
	BYTE *srkKeyBlob;
	TSS_HCONTEXT tspContext;
	UINT32 ownerMode, srkMode;
	Trspi_HashCtx hashCtx;


	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
		return result;

	/*************************************************
	 *	First, get the policy objects and check them for how
	 *		to handle the secrets.  If they cannot be found
	 *		or there is an error, then we must fail
	 **************************************************/

	/* First get the Owner Policy */
	if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hOwnerPolicy)))
		return result;

	/* Now get the SRK Policy */
	if ((result = obj_rsakey_get_policy(hKeySRK, TSS_POLICY_USAGE, &hSrkPolicy, NULL)))
		return result;

	if ((result = obj_policy_get_mode(hOwnerPolicy, &ownerMode)))
		return result;

	if ((result = obj_policy_get_mode(hSrkPolicy, &srkMode)))
		return result;

	/* If the policy callback's aren't the same, that's an error if one is callback */
	if (srkMode == TSS_SECRET_MODE_CALLBACK || ownerMode == TSS_SECRET_MODE_CALLBACK) {
		if (srkMode != TSS_SECRET_MODE_CALLBACK || ownerMode != TSS_SECRET_MODE_CALLBACK) {
			LogError("Policy callback modes for SRK policy and Owner policy differ.");
			return TSPERR(TSS_E_BAD_PARAMETER);
		}
	}

	if (ownerMode != TSS_SECRET_MODE_CALLBACK) {
		/* First, get the Endorsement Public Key for Encrypting */
		if ((result = obj_rsakey_get_blob(hEndorsementPubKey, &endorsementKeySize,
						  &endorsementKey)))
			return result;

		/* now stick it in a Key Structure */
		offset = 0;
		if ((result = UnloadBlob_TSS_KEY(&offset, endorsementKey, &dummyKey))) {
			free_tspi(tspContext, endorsementKey);
			return result;
		}
		free_tspi(tspContext, endorsementKey);

		if ((result = obj_policy_get_secret(hOwnerPolicy, TR_SECRET_CTX_NEW,
						    &ownerSecret))) {
			free(dummyKey.pubKey.key);
			free(dummyKey.algorithmParms.parms);
			return result;
		}

		if ((result = obj_policy_get_secret(hSrkPolicy, TR_SECRET_CTX_NEW, &srkSecret))) {
			free(dummyKey.pubKey.key);
			free(dummyKey.algorithmParms.parms);
			return result;
		}

		/* Encrypt the Owner, SRK Authorizations */
		if ((result = Trspi_RSA_Encrypt(ownerSecret.authdata, 20, encOwnerAuth,
						encOwnerAuthLength, dummyKey.pubKey.key,
						dummyKey.pubKey.keyLength))) {
			free(dummyKey.pubKey.key);
			free(dummyKey.algorithmParms.parms);
			return result;
		}

		if ((result = Trspi_RSA_Encrypt(srkSecret.authdata, 20, encSRKAuth,
						encSRKAuthLength, dummyKey.pubKey.key,
						dummyKey.pubKey.keyLength))) {
			free(dummyKey.pubKey.key);
			free(dummyKey.algorithmParms.parms);
			return result;
		}

		free(dummyKey.pubKey.key);
		free(dummyKey.algorithmParms.parms);
	} else {
		*encOwnerAuthLength = 256;
		*encSRKAuthLength = 256;
		if ((result = obj_policy_do_takeowner(hOwnerPolicy, hTPM, hEndorsementPubKey,
						      *encOwnerAuthLength, encOwnerAuth)))
			return result;
	}

	if ((result = obj_rsakey_get_blob(hKeySRK, &srkKeyBlobLength, &srkKeyBlob)))
		return result;

	/* Authorizatin Digest Calculation */
	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_TakeOwnership);
	result |= Trspi_Hash_UINT16(&hashCtx, TCPA_PID_OWNER);
	result |= Trspi_Hash_UINT32(&hashCtx, *encOwnerAuthLength);
	result |= Trspi_HashUpdate(&hashCtx, *encOwnerAuthLength, encOwnerAuth);
	result |= Trspi_Hash_UINT32(&hashCtx, *encSRKAuthLength);
	result |= Trspi_HashUpdate(&hashCtx, *encSRKAuthLength, encSRKAuth);
	result |= Trspi_HashUpdate(&hashCtx, srkKeyBlobLength, srkKeyBlob);
	free_tspi(tspContext, srkKeyBlob);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
		return result;

	/* HMAC for the final digest */
	if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_TakeOwnership, hOwnerPolicy, FALSE,
					      &digest, auth)))
		return result;

	return TSS_SUCCESS;
}

#ifdef TSS_BUILD_TRANSPORT
TSS_RESULT
Transport_OwnerClear(TSS_HCONTEXT tspContext,	/* in */
		     TPM_AUTH * ownerAuth)	/* in, out */
{
	TSS_RESULT result;
	UINT32 handlesLen = 0;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	return obj_context_transport_execute(tspContext, TPM_ORD_OwnerClear, 0, NULL, NULL,
					     &handlesLen, NULL, ownerAuth, NULL, NULL, NULL);
}

TSS_RESULT
Transport_ForceClear(TSS_HCONTEXT tspContext)	/* in */
{
	TSS_RESULT result;
	UINT32 handlesLen = 0;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	return obj_context_transport_execute(tspContext, TPM_ORD_ForceClear, 0, NULL, NULL,
					     &handlesLen, NULL, NULL, NULL, NULL, NULL);
}
#endif



<|start_filename|>src/include/biosem.h<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2006
 *
 */

#ifndef _BIOSEM_H_
#define _BIOSEM_H_

int bios_open(void *, FILE **);
TSS_RESULT bios_get_entries_by_pcr(FILE *, UINT32, UINT32, UINT32 *, TSS_PCR_EVENT **);
TSS_RESULT bios_get_entry(FILE *, UINT32, UINT32 *, TSS_PCR_EVENT **);
int bios_close(FILE *);

extern struct ext_log_source bios_source;

/* this should be large if we're reading out of /proc */
#define BIOS_READ_SIZE	4096

typedef struct {
	UINT32 pcrIndex;
	UINT32 eventType;
	BYTE   digest[20];
	UINT32 eventDataSize;
	BYTE   event[0];/* (eventSize) bytes of event data follows */
} TCG_PCClientPCREventStruc;

#define EVLOG_SOURCE_BIOS	1

#endif


<|start_filename|>src/tspi/tsp_bind.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2007
 *
 */


#include <stdlib.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


#ifdef TSS_BUILD_TRANSPORT
TSS_RESULT
Transport_UnBind(TSS_HCONTEXT tspContext,	/* in */
		 TCS_KEY_HANDLE keyHandle,	/* in */
		 UINT32 inDataSize,	/* in */
		 BYTE * inData,	/* in */
		 TPM_AUTH * privAuth,	/* in, out */
		 UINT32 * outDataSize,	/* out */
		 BYTE ** outData)	/* out */
{
	TSS_RESULT result;
	UINT32 handlesLen, dataLen, decLen;
	TCS_HANDLE *handles, handle;
	TPM_DIGEST pubKeyHash;
	Trspi_HashCtx hashCtx;
	BYTE *dec, *data;
	UINT64 offset;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	if ((result = obj_tcskey_get_pubkeyhash(keyHandle, pubKeyHash.digest)))
		return result;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
		return result;

	handlesLen = 1;
	handle = keyHandle;
	handles = &handle;

	dataLen = sizeof(UINT32) + inDataSize;
	if ((data = malloc(dataLen)) == NULL) {
		LogError("malloc of %u bytes failed", dataLen);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	offset = 0;
	Trspi_LoadBlob_UINT32(&offset, inDataSize, data);
	Trspi_LoadBlob(&offset, inDataSize, data, inData);

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_UnBind, dataLen, data,
						    &pubKeyHash, &handlesLen, &handles,
						    privAuth, NULL, &decLen, &dec))) {
		free(data);
		return result;
	}
	free(data);

	offset = 0;
	Trspi_UnloadBlob_UINT32(&offset, outDataSize, dec);

	if ((*outData = malloc(*outDataSize)) == NULL) {
		free(dec);
		LogError("malloc of %u bytes failed", *outDataSize);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}
	Trspi_UnloadBlob(&offset, *outDataSize, dec, *outData);

	free(dec);

	return TSS_SUCCESS;
}
#endif



<|start_filename|>src/tspi/tspi_tick.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


TSS_RESULT
Tspi_Hash_TickStampBlob(TSS_HHASH       hHash,			/* in */
			TSS_HKEY        hIdentKey,		/* in */
			TSS_VALIDATION* pValidationData)	/* in */
{
	TSS_RESULT result;
	TSS_HCONTEXT tspContext;
	TCS_KEY_HANDLE tcsKey;
	TSS_HPOLICY hPolicy;
	TPM_DIGEST digest;
	TSS_BOOL usesAuth;
	TPM_AUTH auth, *pAuth;
	UINT32 hashLen, sigLen, tcLen, signInfoLen;
	BYTE *hash, *sig, *tc, *signInfo = NULL;
	UINT64 offset;
	Trspi_HashCtx hashCtx;

	if (pValidationData == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if ((result = obj_hash_get_tsp_context(hHash, &tspContext)))
		return result;

	if (pValidationData->ulExternalDataLength != sizeof(TPM_NONCE))
		return TSPERR(TSS_E_BAD_PARAMETER);

	if ((result = obj_hash_get_value(hHash, &hashLen, &hash)))
		return result;

	if (hashLen != sizeof(TPM_DIGEST)) {
		free_tspi(tspContext, hash);
		return TSPERR(TSS_E_HASH_INVALID_LENGTH);
	}

	if ((result = obj_rsakey_get_policy(hIdentKey, TSS_POLICY_USAGE, &hPolicy, &usesAuth)))
		return result;

	if ((result = obj_rsakey_get_tcs_handle(hIdentKey, &tcsKey)))
		return result;

	if (usesAuth) {
		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_TickStampBlob);
		result |= Trspi_HashUpdate(&hashCtx, sizeof(TPM_NONCE),
					   pValidationData->rgbExternalData);
		result |= Trspi_HashUpdate(&hashCtx, sizeof(TPM_DIGEST), hash);
		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
			free_tspi(tspContext, hash);
			return result;
		}

		if ((result = secret_PerformAuth_OIAP(hIdentKey, TPM_ORD_TickStampBlob, hPolicy,
						      FALSE, &digest, &auth))) {
			free_tspi(tspContext, hash);
			return result;
		}
		pAuth = &auth;
	} else
		pAuth = NULL;

	if ((result = TCS_API(tspContext)->TickStampBlob(tspContext, tcsKey,
						(TPM_NONCE *)pValidationData->rgbExternalData,
						(TPM_DIGEST *)hash, pAuth, &sigLen, &sig, &tcLen,
						&tc))) {
		free_tspi(tspContext, hash);
		return result;
	}

	if (usesAuth) {
		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
		result |= Trspi_Hash_UINT32(&hashCtx, result);
		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_TickStampBlob);
		result |= Trspi_HashUpdate(&hashCtx, tcLen, tc);
		result |= Trspi_Hash_UINT32(&hashCtx, sigLen);
		result |= Trspi_HashUpdate(&hashCtx, sigLen, sig);
		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
			free_tspi(tspContext, hash);
			free(sig);
			free(tc);
			return result;
		}

		if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth))) {
			free_tspi(tspContext, hash);
			free(sig);
			free(tc);
			return result;
		}
	}
	
	/*                 tag       fixed      replay          length(Data)                 Data        */
	signInfoLen = sizeof(UINT16) + 4 + sizeof(TPM_NONCE) + sizeof(UINT32) + sizeof(TPM_DIGEST) + tcLen;
	if ((signInfo = calloc_tspi(tspContext, signInfoLen)) == NULL) {
		free_tspi(tspContext, hash);
		free(sig);
		free(tc);
		return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	offset = 0;
	Trspi_LoadBlob_UINT16(&offset, TPM_TAG_SIGNINFO, signInfo);
	Trspi_LoadBlob_BYTE(&offset, 'T', signInfo);
	Trspi_LoadBlob_BYTE(&offset, 'S', signInfo);
	Trspi_LoadBlob_BYTE(&offset, 'T', signInfo);
	Trspi_LoadBlob_BYTE(&offset, 'P', signInfo);
	Trspi_LoadBlob(&offset, sizeof(TPM_NONCE), signInfo, pValidationData->rgbExternalData);
	Trspi_LoadBlob_UINT32(&offset, sizeof(TPM_DIGEST) + tcLen, signInfo);
	Trspi_LoadBlob(&offset, sizeof(TPM_DIGEST), signInfo, hash);
	Trspi_LoadBlob(&offset, (size_t)tcLen, signInfo, tc);

	free(tc);
	free_tspi(tspContext, hash);

	pValidationData->rgbData = signInfo;
	pValidationData->ulDataLength = signInfoLen;
		
	/* tag sig so that it can be free'd by the app through Tspi_Context_FreeMemory */
	if ((result = __tspi_add_mem_entry(tspContext, sig))) {
		free_tspi(tspContext, signInfo);
		free(sig);
		return result;
	}

	pValidationData->rgbValidationData = sig;
	pValidationData->ulValidationDataLength = sigLen;

	return TSS_SUCCESS;
}

TSS_RESULT
Tspi_TPM_ReadCurrentTicks(TSS_HTPM           hTPM,	/* in */
			  TPM_CURRENT_TICKS* tickCount)	/* out */
{
	TSS_RESULT result;
	TSS_HCONTEXT tspContext;
	UINT32 tcLen;
	BYTE *tc;
	UINT64 offset;

	if (tickCount == NULL)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
		return result;

	if ((result = TCS_API(tspContext)->ReadCurrentTicks(tspContext, &tcLen, &tc)))
		return result;

	offset = 0;
	Trspi_UnloadBlob_CURRENT_TICKS(&offset, tc, tickCount);
	free(tc);

	return result;
}


<|start_filename|>src/tcs/tcsi_selftest.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcsps.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "req_mgr.h"
#include "tcsd_wrap.h"
#include "tcsd.h"


TSS_RESULT
TCSP_SelfTestFull_Internal(TCS_CONTEXT_HANDLE hContext)	/* in */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering Self Test Full");
	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_SelfTestFull, &offset, txBlob, NULL)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);
	LogResult("Self Test Full", result);
	return result;
}

TSS_RESULT
TCSP_CertifySelfTest_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			      TCS_KEY_HANDLE keyHandle,	/* in */
			      TCPA_NONCE antiReplay,	/* in */
			      TPM_AUTH * privAuth,	/* in, out */
			      UINT32 * sigSize,	/* out */
			      BYTE ** sig)	/* out */
{
	UINT64 offset = 0;
	UINT32 paramSize;
	TSS_RESULT result;
	TCPA_KEY_HANDLE keySlot;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering Certify Self Test");

	if ((result = ctx_verify_context(hContext)))
		goto done;

	if (privAuth != NULL) {
		LogDebug("Auth Used");
		if ((result = auth_mgr_check(hContext, &privAuth->AuthHandle)))
			goto done;
	} else {
		LogDebug("No Auth");
	}

	if ((result = ensureKeyIsLoaded(hContext, keyHandle, &keySlot)))
		goto done;

	if ((result = tpm_rqu_build(TPM_ORD_CertifySelfTest, &offset, txBlob, keySlot,
				    TPM_NONCE_SIZE, antiReplay.nonce, privAuth, NULL)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		goto done;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_CertifySelfTest, txBlob, paramSize, sigSize, sig,
				       privAuth, NULL);
	}
	LogResult("Certify Self Test", result);
done:
	auth_mgr_release_auth(privAuth, NULL, hContext);
	return result;
}

TSS_RESULT
TCSP_GetTestResult_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			    UINT32 * outDataSize,	/* out */
			    BYTE ** outData)	/* out */
{
	TSS_RESULT result;
	UINT32 paramSize;
	UINT64 offset = 0;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebug("Entering Get Test Result");
	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = tpm_rqu_build(TPM_ORD_GetTestResult, &offset, txBlob, NULL)))
		return result;

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &paramSize);
	if (!result) {
		result = tpm_rsp_parse(TPM_ORD_GetTestResult, txBlob, paramSize, outDataSize,
				       outData, NULL, NULL);
	}
	LogResult("Get Test Result", result);
	return result;
}



<|start_filename|>src/trspi/crypto/openssl/hash.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

/*
 * hash.c - openssl TSS crypto routines
 *
 * <NAME> <<EMAIL>>
 *
 */

#include <string.h>

#include <openssl/opensslv.h>
#include <openssl/rsa.h>  // for some reason the MGF1 prototype is in here
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/err.h>
#include <openssl/sha.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "tsplog.h"

#ifdef TSS_DEBUG
#define DEBUG_print_openssl_errors() \
	do { \
		ERR_load_crypto_strings(); \
		ERR_print_errors_fp(stderr); \
	} while (0)
#else
#define DEBUG_print_openssl_errors()
#endif

#if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
#define OpenSSL_MGF1(m,mlen,s,slen,md)	PKCS1_MGF1(m,mlen,s,slen,md)
#else
int MGF1(unsigned char *, long, const unsigned char *, long);
#define OpenSSL_MGF1(m,mlen,s,slen,md)	MGF1(m,mlen,s,slen)
#endif

/*
 * Hopefully this will make the code clearer since
 * OpenSSL returns 1 on success
 */
#define EVP_SUCCESS 1

TSS_RESULT
Trspi_Hash(UINT32 HashType, UINT32 BufSize, BYTE* Buf, BYTE* Digest)
{
	EVP_MD_CTX md_ctx;
	unsigned int result_size;
	int rv;

	switch (HashType) {
		case TSS_HASH_SHA1:
			rv = EVP_DigestInit(&md_ctx, EVP_sha1());
			break;
		default:
			rv = TSPERR(TSS_E_BAD_PARAMETER);
			goto out;
			break;
	}

	if (rv != EVP_SUCCESS) {
		rv = TSPERR(TSS_E_INTERNAL_ERROR);
		goto err;
	}

	rv = EVP_DigestUpdate(&md_ctx, Buf, BufSize);
	if (rv != EVP_SUCCESS) {
		rv = TSPERR(TSS_E_INTERNAL_ERROR);
		goto err;
	}

	result_size = EVP_MD_CTX_size(&md_ctx);
	rv = EVP_DigestFinal(&md_ctx, Digest, &result_size);
	if (rv != EVP_SUCCESS) {
		rv = TSPERR(TSS_E_INTERNAL_ERROR);
		goto err;
	} else
		rv = TSS_SUCCESS;

	goto out;

err:
	DEBUG_print_openssl_errors();
out:
        return rv;
}

TSS_RESULT
Trspi_HashInit(Trspi_HashCtx *ctx, UINT32 HashType)
{
	int rv;
	EVP_MD *md;

	switch (HashType) {
		case TSS_HASH_SHA1:
			md = (EVP_MD *)EVP_sha1();
			break;
		default:
			return TSPERR(TSS_E_BAD_PARAMETER);
			break;
	}

	if ((ctx->ctx = malloc(sizeof(EVP_MD_CTX))) == NULL)
		return TSPERR(TSS_E_OUTOFMEMORY);

	rv = EVP_DigestInit((EVP_MD_CTX *)ctx->ctx, (const EVP_MD *)md);

	if (rv != EVP_SUCCESS) {
		DEBUG_print_openssl_errors();
		return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	return TSS_SUCCESS;
}

TSS_RESULT
Trspi_HashUpdate(Trspi_HashCtx *ctx, UINT32 size, BYTE *data)
{
	int rv;

	if (ctx == NULL || ctx->ctx == NULL)
		return TSPERR(TSS_E_INTERNAL_ERROR);

	if (data == NULL && size)
		return TSPERR(TSS_E_BAD_PARAMETER);

	if (!size)
		return TSS_SUCCESS;

	rv = EVP_DigestUpdate(ctx->ctx, data, size);
	if (rv != EVP_SUCCESS) {
		DEBUG_print_openssl_errors();
		free(ctx->ctx);
		ctx->ctx = NULL;
		return TSPERR(TSS_E_INTERNAL_ERROR);
	}

	return TSS_SUCCESS;
}

TSS_RESULT
Trspi_HashFinal(Trspi_HashCtx *ctx, BYTE *digest)
{
	int rv;
	UINT32 result_size;

	if (ctx == NULL || ctx->ctx == NULL)
		return TSPERR(TSS_E_INTERNAL_ERROR);

	result_size = EVP_MD_CTX_size((EVP_MD_CTX *)ctx->ctx);
	rv = EVP_DigestFinal(ctx->ctx, digest, &result_size);
	if (rv != EVP_SUCCESS)
		return TSPERR(TSS_E_INTERNAL_ERROR);

	free(ctx->ctx);
	ctx->ctx = NULL;

	return TSS_SUCCESS;
}

UINT32
Trspi_HMAC(UINT32 HashType, UINT32 SecretSize, BYTE* Secret, UINT32 BufSize, BYTE* Buf, BYTE* hmacOut)
{
	/*HMAC_CTX hmac_ctx;*/
	const EVP_MD *md;
	unsigned int len;
	int rv = TSS_SUCCESS;

	switch (HashType) {
		case TSS_HASH_SHA1:
			md = EVP_sha1();
			break;
		default:
			rv = TSPERR(TSS_E_BAD_PARAMETER);
			goto out;
			break;
	}

	len = EVP_MD_size(md);

	HMAC(md, Secret, SecretSize, Buf, BufSize, hmacOut, &len);
out:
	return rv;
}

TSS_RESULT
Trspi_MGF1(UINT32 alg, UINT32 seedLen, BYTE *seed, UINT32 outLen, BYTE *out)
{
	const EVP_MD *md;
	long olen = outLen, slen = seedLen;
	int rv = TSS_SUCCESS;

	switch (alg) {
		case TSS_HASH_SHA1:
			md = EVP_sha1();
			break;
		default:
			rv = TSPERR(TSS_E_BAD_PARAMETER);
			goto out;
			break;
	}

	rv = OpenSSL_MGF1(out, olen, seed, slen, md);
out:
	return rv;
}


<|start_filename|>src/include/tcsd_ops.h<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2005, 2007
 *
 */


#ifndef _TCSD_COMMANDS_H_
#define _TCSD_COMMANDS_H_

#include "tcsd_wrap.h"

#define OPENCONTEXT			TCSD_ORD_OPENCONTEXT
#define CLOSECONTEXT			TCSD_ORD_CLOSECONTEXT
#define FREEMEMORY			TCSD_ORD_FREEMEMORY
#define TCSGETCAPABILITY		TCSD_ORD_TCSGETCAPABILITY
#define REGISTERKEY			TCSD_ORD_REGISTERKEY
#define UNREGISTERKEY			TCSD_ORD_UNREGISTERKEY
#define GETREGISTEREDKEYBLOB		TCSD_ORD_GETREGISTEREDKEYBLOB
#define GETREGISTEREDKEYBYPUBLICINFO	TCSD_ORD_GETREGISTEREDKEYBYPUBLICINFO
#define GETPUBKEY			TCSD_ORD_GETPUBKEY
#define LOADKEYBYBLOB			TCSD_ORD_LOADKEYBYBLOB
#define LOADKEYBYUUID			TCSD_ORD_LOADKEYBYUUID
#define CREATEWRAPKEY			TCSD_ORD_CREATEWRAPKEY
#define GETPCREVENTLOG			TCSD_ORD_GETPCREVENTLOG
#define OIAP				TCSD_ORD_OIAP
#define OSAP				TCSD_ORD_OSAP
#define TERMINATEHANDLE			TCSD_ORD_TERMINATEHANDLE
#define PCRREAD				TCSD_ORD_PCRREAD
#define PCRRESET			TCSD_ORD_PCRRESET
#define QUOTE				TCSD_ORD_QUOTE
#define SEAL				TCSD_ORD_SEAL
#define UNSEAL				TCSD_ORD_UNSEAL
#define UNBIND				TCSD_ORD_UNBIND
#define CERTIFYKEY			TCSD_ORD_CERTIFYKEY
#define SIGN				TCSD_ORD_SIGN
#define GETRANDOM			TCSD_ORD_GETRANDOM
#define STIRRANDOM			TCSD_ORD_STIRRANDOM
#define GETCAPABILITY			TCSD_ORD_GETCAPABILITY
#define READPUBEK			TCSD_ORD_READPUBEK
#define SELFTESTFULL			TCSD_ORD_SELFTESTFULL
#define CERTIFYSELFTEST			TCSD_ORD_CERTIFYSELFTEST
#define CONTINUESELFTEST		TCSD_ORD_CONTINUESELFTEST
#define GETTESTRESULT			TCSD_ORD_GETTESTRESULT
/* below this line are ordinals that probably shouldn't be allowed for non-localhosts */
#if 0
#define OWNERREADPUBEK			TCSD_ORD_OWNERREADPUBEK
#define GETPCREVENT			TCSD_ORD_GETPCREVENT
#define GETPCREVENTBYPCR		TCSD_ORD_GETPCREVENTBYPCR
#define GETCAPABILITYSIGNED		TCSD_ORD_GETCAPABILITYSIGNED
#define ENUMREGISTEREDKEYS		TCSD_ORD_ENUMREGISTEREDKEYS
#define ENUMREGISTEREDKEYS2		TCSD_ORD_ENUMREGISTEREDKEYS2
#define GETREGISTEREDKEY		TCSD_ORD_GETREGISTEREDKEY
#define EXTEND				TCSD_ORD_EXTEND
#define LOGPCREVENT			TCSD_ORD_LOGPCREVENT
#define EVICTKEY			TCSD_ORD_EVICTKEY
#define DISABLEPUBEKREAD		TCSD_ORD_DISABLEPUBEKREAD
#define SETOWNERINSTALL			TCSD_ORD_SETOWNERINSTALL
#define MAKEIDENTITY			TCSD_ORD_MAKEIDENTITY
#define MAKEIDENTITY2			TCSD_ORD_MAKEIDENTITY2
#define TAKEOWNERSHIP			TCSD_ORD_TAKEOWNERSHIP
#define CREATEENDORSEMENTKEYPAIR	TCSD_ORD_CREATEENDORSEMENTKEYPAIR
#define GETCAPABILITYOWNER		TCSD_ORD_GETCAPABILITYOWNER
#define ACTIVATETPMIDENTITY		TCSD_ORD_ACTIVATETPMIDENTITY
#define AUTHORIZEMIGRATIONKEY		TCSD_ORD_AUTHORIZEMIGRATIONKEY
#define CHANGEAUTH			TCSD_ORD_CHANGEAUTH
#define CHANGEAUTHOWNER			TCSD_ORD_CHANGEAUTHOWNER
#define CHANGEAUTHASYMSTART		TCSD_ORD_CHANGEAUTHASYMSTART
#define CHANGEAUTHASYMFINISH		TCSD_ORD_CHANGEAUTHASYMFINISH
#define DIRREAD				TCSD_ORD_DIRREAD
#define DIRWRITEAUTH			TCSD_ORD_DIRWRITEAUTH
#define CREATEMIGRATIONBLOB		TCSD_ORD_CREATEMIGRATIONBLOB
#define CONVERTMIGRATIONBLOB		TCSD_ORD_CONVERTMIGRATIONBLOB
#define OWNERSETDISABLE			TCSD_ORD_OWNERSETDISABLE
#define OWNERCLEAR			TCSD_ORD_OWNERCLEAR
#define DISABLEOWNERCLEAR		TCSD_ORD_DISABLEOWNERCLEAR
#define FORCECLEAR			TCSD_ORD_FORCECLEAR
#define DISABLEFORCECLEAR		TCSD_ORD_DISABLEFORCECLEAR
#define PHYSICALDISABLE			TCSD_ORD_PHYSICALDISABLE
#define PHYSICALENABLE			TCSD_ORD_PHYSICALENABLE
#define PHYSICALSETDEACTIVATED		TCSD_ORD_PHYSICALSETDEACTIVATED
#define SETTEMPDEACTIVATED		TCSD_ORD_SETTEMPDEACTIVATED
#define PHYSICALPRESENCE		TCSD_ORD_PHYSICALPRESENCE
#define FIELDUPGRADE			TCSD_ORD_FIELDUPGRADE
#define SETRIDIRECTION			TCSD_ORD_SETRIDIRECTION
#define CREATEMAINTENANCEARCHIVE	TCSD_ORD_CREATEMAINTENANCEARCHIVE
#define LOADMAINTENANCEARCHIVE		TCSD_ORD_LOADMAINTENANCEARCHIVE
#define KILLMAINTENANCEFEATURE		TCSD_ORD_KILLMAINTENANCEFEATURE
#define LOADMANUFECTURERMAINTENANCEPUB	TCSD_ORD_LOADMANUFECTURERMAINTENANCEPUB
#define READMANUFECTURERMAINTENANCEPUB	TCSD_ORD_READMANUFECTURERMAINTENANCEPUB
#define SETTEMPDEACTIVATED2		TCSD_ORD_SETTEMPDEACTIVATED2
#endif

/* TCSD ordinal sub-command sets */
#define SUBOP_CONTEXT			OPENCONTEXT, CLOSECONTEXT
#define SUBOP_RANDOM			STIRRANDOM, GETRANDOM
#define SUBOP_AUTHSESS			OIAP, OSAP, TERMINATEHANDLE
#define SUBOP_LOADKEYBYUUID		LOADKEYBYUUID, GETREGISTEREDKEYBLOB, FREEMEMORY
#define SUBOP_SELFTEST			SELFTESTFULL, CERTIFYSELFTEST, CONTINUESELFTEST, GETTESTRESULT 

/* Top level TCSD operations which can be enabled to be used by remote hosts. Each of these
 * should have a corresponding on/off switch in the tcsd.conf file
 */
#define TCSD_OP_SEAL				SEAL, SUBOP_LOADKEYBYUUID, SUBOP_RANDOM, SUBOP_AUTHSESS, SUBOP_CONTEXT, 0
#define TCSD_OP_UNSEAL				UNSEAL, SUBOP_LOADKEYBYUUID, SUBOP_RANDOM, SUBOP_AUTHSESS, SUBOP_CONTEXT, 0
#define TCSD_OP_GETREGISTEREDKEYBYPUBLICINFO	GETREGISTEREDKEYBYPUBLICINFO, SUBOP_CONTEXT, 0
#define TCSD_OP_GETPUBKEY			GETPUBKEY, SUBOP_RANDOM, SUBOP_AUTHSESS, SUBOP_CONTEXT, 0
#define TCSD_OP_LOADKEY				LOADKEYBYBLOB, SUBOP_LOADKEYBYUUID, SUBOP_CONTEXT, SUBOP_AUTHSESS, SUBOP_RANDOM, 0
#define TCSD_OP_REGISTERKEY			REGISTERKEY, SUBOP_CONTEXT, SUBOP_LOADKEYBYUUID, LOADKEYBYBLOB, 0
#define TCSD_OP_UNREGISTERKEY			UNREGISTERKEY, SUBOP_CONTEXT, 0
#define TCSD_OP_CREATEKEY			CREATEWRAPKEY, SUBOP_CONTEXT, SUBOP_AUTHSESS, SUBOP_LOADKEYBYUUID, SUBOP_RANDOM, 0
#define TCSD_OP_SIGN				SIGN, SUBOP_CONTEXT, SUBOP_AUTHSESS, SUBOP_RANDOM, FREEMEMORY, 0
#define TCSD_OP_RANDOM				SUBOP_RANDOM, SUBOP_CONTEXT, FREEMEMORY, 0
#define TCSD_OP_GETCAPABILITY			GETCAPABILITY, TCSGETCAPABILITY, SUBOP_CONTEXT, FREEMEMORY, 0
#define TCSD_OP_UNBIND				UNBIND, SUBOP_CONTEXT, SUBOP_AUTHSESS, SUBOP_RANDOM, 0
#define TCSD_OP_QUOTE				QUOTE, SUBOP_CONTEXT, SUBOP_AUTHSESS, SUBOP_RANDOM, 0
#define TCSD_OP_READPUBEK			READPUBEK, SUBOP_CONTEXT, SUBOP_AUTHSESS, SUBOP_RANDOM, 0
#define TCSD_OP_SELFTEST			SUBOP_SELFTEST, SUBOP_CONTEXT, FREEMEMORY, 0

struct tcsd_op {
	char *name;
	int op[];
};

struct tcsd_op tcsd_op_seal = {"seal", {TCSD_OP_SEAL}};
struct tcsd_op tcsd_op_unseal = {"unseal", {TCSD_OP_UNSEAL}};
struct tcsd_op tcsd_op_registerkey = {"registerkey", {TCSD_OP_REGISTERKEY}};
struct tcsd_op tcsd_op_unregisterkey = {"unregisterkey", {TCSD_OP_UNREGISTERKEY}};
struct tcsd_op tcsd_op_getregisteredkeybypublicinfo = {"getregisteredkeybypublicinfo", {TCSD_OP_GETREGISTEREDKEYBYPUBLICINFO}};
struct tcsd_op tcsd_op_getpubkey = {"getpubkey", {TCSD_OP_GETPUBKEY}};
struct tcsd_op tcsd_op_loadkey = {"loadkey", {TCSD_OP_LOADKEY}};
struct tcsd_op tcsd_op_createkey = {"createkey", {TCSD_OP_CREATEKEY}};
struct tcsd_op tcsd_op_sign = {"sign", {TCSD_OP_SIGN}};
struct tcsd_op tcsd_op_random = {"random", {TCSD_OP_RANDOM}};
struct tcsd_op tcsd_op_getcapability = {"getcapability", {TCSD_OP_GETCAPABILITY}};
struct tcsd_op tcsd_op_unbind = {"unbind", {TCSD_OP_UNBIND}};
struct tcsd_op tcsd_op_quote = {"quote", {TCSD_OP_QUOTE}};
struct tcsd_op tcsd_op_readpubek = {"readpubek", {TCSD_OP_READPUBEK}};
struct tcsd_op tcsd_op_selftest = {"selftest", {TCSD_OP_SELFTEST}};

struct tcsd_op *tcsd_ops[] = {
	&tcsd_op_seal,
	&tcsd_op_unseal,
	&tcsd_op_registerkey,
	&tcsd_op_unregisterkey,
	&tcsd_op_getregisteredkeybypublicinfo,
	&tcsd_op_getpubkey,
	&tcsd_op_loadkey,
	&tcsd_op_createkey,
	&tcsd_op_sign,
	&tcsd_op_random,
	&tcsd_op_getcapability,
	&tcsd_op_unbind,
	&tcsd_op_quote,
	&tcsd_op_readpubek,
	&tcsd_op_selftest,
	NULL
};

#endif


<|start_filename|>src/tspi/tsp_pcr_extend.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <errno.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


#ifdef TSS_BUILD_TRANSPORT
TSS_RESULT
Transport_Extend(TSS_HCONTEXT tspContext,	/* in */
		 TCPA_PCRINDEX pcrNum,	/* in */
		 TCPA_DIGEST inDigest,	/* in */
		 TCPA_PCRVALUE * outDigest)	/* out */
{
	TSS_RESULT result;
	UINT64 offset;
	TCS_HANDLE handlesLen = 0;
	UINT32 decLen;
	BYTE data[sizeof(TCPA_PCRINDEX) + sizeof(TCPA_DIGEST)], *dec;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	offset = 0;
	Trspi_LoadBlob_UINT32(&offset, pcrNum, data);
	Trspi_LoadBlob(&offset, TPM_SHA1_160_HASH_LEN, data, inDigest.digest);

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Extend, sizeof(data), data,
						    NULL, &handlesLen, NULL, NULL, NULL, &decLen,
						    &dec)))
		return result;

	offset = 0;
	Trspi_UnloadBlob(&offset, decLen, dec, outDigest->digest);

	free(dec);

	return TSS_SUCCESS;
}

TSS_RESULT
Transport_PcrRead(TSS_HCONTEXT tspContext,	/* in */
		  TCPA_PCRINDEX pcrNum,	/* in */
		  TCPA_PCRVALUE * outDigest)	/* out */
{
	TSS_RESULT result;
	UINT64 offset;
	TCS_HANDLE handlesLen = 0;
	UINT32 decLen;
	BYTE data[sizeof(TCPA_PCRINDEX)], *dec;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	offset = 0;
	Trspi_LoadBlob_UINT32(&offset, pcrNum, data);

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_PcrRead, sizeof(data),
						    data, NULL, &handlesLen, NULL, NULL, NULL,
						    &decLen, &dec)))
		return result;

	offset = 0;
	Trspi_UnloadBlob(&offset, decLen, dec, outDigest->digest);

	free(dec);

	return TSS_SUCCESS;
}


TSS_RESULT
Transport_PcrReset(TSS_HCONTEXT tspContext,	/* in */
		   UINT32 pcrDataSizeIn,	/* in */
		   BYTE * pcrDataIn)		/* in */
{
	TSS_RESULT result;
	TCS_HANDLE handlesLen = 0;

	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	return obj_context_transport_execute(tspContext, TPM_ORD_PCR_Reset, pcrDataSizeIn,
					     pcrDataIn, NULL, &handlesLen, NULL, NULL, NULL, NULL,
					     NULL);
}
#endif


<|start_filename|>src/tcs/tcs_auth_mgr.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>

#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcslog.h"
#include "tcsd_wrap.h"
#include "tcsd.h"
#include "auth_mgr.h"
#include "req_mgr.h"


MUTEX_DECLARE_EXTERN(tcsp_lock);

/* Note: The after taking the auth_mgr_lock in any of the functions below, the
 * mem_cache_lock cannot be taken without risking a deadlock. So, the auth_mgr
 * functions must be "self-contained" wrt locking */

/* no locking done in init since its called by only a single thread */
TSS_RESULT
auth_mgr_init()
{
	memset(&auth_mgr, 0, sizeof(struct _auth_mgr));

	auth_mgr.max_auth_sessions = tpm_metrics.num_auths;

	auth_mgr.overflow = calloc(TSS_DEFAULT_OVERFLOW_AUTHS, sizeof(COND_VAR *));
	if (auth_mgr.overflow == NULL) {
		LogError("malloc of %zd bytes failed",
			 (TSS_DEFAULT_OVERFLOW_AUTHS * sizeof(COND_VAR *)));
		return TCSERR(TSS_E_OUTOFMEMORY);
	}
	auth_mgr.overflow_size = TSS_DEFAULT_OVERFLOW_AUTHS;

	auth_mgr.auth_mapper = calloc(TSS_DEFAULT_AUTH_TABLE_SIZE, sizeof(struct auth_map));
	if (auth_mgr.auth_mapper == NULL) {
		LogError("malloc of %zd bytes failed",
			 (TSS_DEFAULT_AUTH_TABLE_SIZE * sizeof(struct auth_map)));
		return TCSERR(TSS_E_OUTOFMEMORY);
	}
	auth_mgr.auth_mapper_size = TSS_DEFAULT_AUTH_TABLE_SIZE;

	return TSS_SUCCESS;
}

TSS_RESULT
auth_mgr_final()
{
	UINT32 i;

	/* wake up any sleeping threads, so they can be joined */
	for (i = 0; i < auth_mgr.overflow_size; i++) {
		if (auth_mgr.overflow[i] != NULL)
			COND_SIGNAL(auth_mgr.overflow[i]);
	}

	free(auth_mgr.overflow);
	free(auth_mgr.auth_mapper);

	return TSS_SUCCESS;
}

TSS_RESULT
auth_mgr_save_ctx(TCS_CONTEXT_HANDLE hContext)
{
       TSS_RESULT result = TSS_SUCCESS;
	UINT32 i;

	for (i = 0; i < auth_mgr.auth_mapper_size; i++) {
		if (auth_mgr.auth_mapper[i].full == TRUE &&
		    auth_mgr.auth_mapper[i].swap == NULL &&
		    auth_mgr.auth_mapper[i].tcs_ctx != hContext) {
			LogDebug("Calling TPM_SaveAuthContext for TCS CTX %x. Swapping out: TCS %x "
				 "TPM %x", hContext, auth_mgr.auth_mapper[i].tcs_ctx,
				 auth_mgr.auth_mapper[i].tpm_handle);

			if ((result = TPM_SaveAuthContext(auth_mgr.auth_mapper[i].tpm_handle,
							  &auth_mgr.auth_mapper[i].swap_size,
							  &auth_mgr.auth_mapper[i].swap))) {
				LogDebug("TPM_SaveAuthContext failed: 0x%x", result);
				return result;
			}
                       break;
		}
	}

       return result;
}

/* if there's a TCS context waiting to get auth, wake it up or swap it in */
void
auth_mgr_swap_in()
{
	if (auth_mgr.overflow[auth_mgr.of_tail] != NULL) {
		LogDebug("waking up thread %lddd, auth slot has opened", THREAD_ID);
		/* wake up the next sleeping thread in order and increment tail */
		COND_SIGNAL(auth_mgr.overflow[auth_mgr.of_tail]);
		auth_mgr.overflow[auth_mgr.of_tail] = NULL;
		auth_mgr.of_tail = (auth_mgr.of_tail + 1) % auth_mgr.overflow_size;
	} else {
		/* else nobody needs to be swapped in, so continue */
		LogDebug("no threads need to be signaled.");
	}
}

/* we need to swap out an auth context or add a waiting context to the overflow queue */
TSS_RESULT
auth_mgr_swap_out(TCS_CONTEXT_HANDLE hContext)
{
	COND_VAR *cond;

	/* If the TPM can do swapping and it succeeds, return, else cond wait below */
	if (tpm_metrics.authctx_swap && !auth_mgr_save_ctx(hContext))
		return TSS_SUCCESS;

	if ((cond = ctx_get_cond_var(hContext)) == NULL) {
		LogError("Auth swap variable not found for TCS context 0x%x", hContext);
		return TCSERR(TSS_E_INTERNAL_ERROR);
	}

	/* Test whether we are the last awake thread.  If we are, we can't go to sleep
	 * since then there'd be no worker thread to wake the others up. This situation
	 * can arise when we're on a busy system who's TPM doesn't support auth ctx
	 * swapping.
	 */
	if (auth_mgr.sleeping_threads == (tcsd_options.num_threads - 1)) {
		LogError("auth mgr failing: too many threads already waiting");
		LogTPMERR(TCPA_E_RESOURCES, __FILE__, __LINE__);
		return TCPA_E_RESOURCES;
	}

	if (auth_mgr.overflow[auth_mgr.of_head] == NULL) {
		auth_mgr.overflow[auth_mgr.of_head] = cond;
		auth_mgr.of_head = (auth_mgr.of_head + 1) % auth_mgr.overflow_size;
		/* go to sleep */
		LogDebug("thread %lddd going to sleep until auth slot opens", THREAD_ID);
		auth_mgr.sleeping_threads++;
		COND_WAIT(cond, &tcsp_lock);
		auth_mgr.sleeping_threads--;
	} else if (auth_mgr.overflow_size + TSS_DEFAULT_OVERFLOW_AUTHS < UINT_MAX) {
		COND_VAR **tmp = auth_mgr.overflow;

		LogDebugFn("Table of sleeping threads is full (%hu), growing to %hu entries",
			   auth_mgr.sleeping_threads,
			   auth_mgr.overflow_size + TSS_DEFAULT_OVERFLOW_AUTHS);

		auth_mgr.overflow = calloc(auth_mgr.overflow_size + TSS_DEFAULT_OVERFLOW_AUTHS,
					   sizeof(COND_VAR *));
		if (auth_mgr.overflow == NULL) {
			LogDebugFn("malloc of %zd bytes failed",
				   (auth_mgr.overflow_size + TSS_DEFAULT_OVERFLOW_AUTHS) *
				   sizeof(COND_VAR *));
			auth_mgr.overflow = tmp;
			return TCSERR(TSS_E_OUTOFMEMORY);
		}
		auth_mgr.overflow_size += TSS_DEFAULT_OVERFLOW_AUTHS;

		LogDebugFn("Success.");
		memcpy(auth_mgr.overflow, tmp, auth_mgr.sleeping_threads * sizeof(COND_VAR *));
		free(tmp);

		/* XXX This could temporarily wake threads up out of order */
		auth_mgr.of_head = auth_mgr.sleeping_threads;
		auth_mgr.of_tail = 0;
		auth_mgr.overflow[auth_mgr.of_head] = cond;
		auth_mgr.of_head = (auth_mgr.of_head + 1) % auth_mgr.overflow_size;
		LogDebug("thread %lddd going to sleep until auth slot opens", THREAD_ID);
		auth_mgr.sleeping_threads++;
		COND_WAIT(cond, &tcsp_lock);
		auth_mgr.sleeping_threads--;
	} else {
		LogError("Auth table overflow is full (%u entries), some will fail.",
			 auth_mgr.overflow_size);
		return TCSERR(TSS_E_INTERNAL_ERROR);
	}

	return TSS_SUCCESS;
}

/* close all auth contexts associated with this TCS_CONTEXT_HANDLE */
TSS_RESULT
auth_mgr_close_context(TCS_CONTEXT_HANDLE tcs_handle)
{
	UINT32 i;
	TSS_RESULT result;

	for (i = 0; i < auth_mgr.auth_mapper_size; i++) {
		if (auth_mgr.auth_mapper[i].full == TRUE &&
		    auth_mgr.auth_mapper[i].tcs_ctx == tcs_handle) {
			if (auth_mgr.auth_mapper[i].swap) {
				/* This context is swapped out of the TPM, so we can just free the
				 * blob */
				free(auth_mgr.auth_mapper[i].swap);
				auth_mgr.auth_mapper[i].swap = NULL;
				auth_mgr.auth_mapper[i].swap_size = 0;
			} else {
				result = TCSP_FlushSpecific_Common(auth_mgr.auth_mapper[i].tpm_handle,
								   TPM_RT_AUTH);

				/* Ok, probably dealing with a 1.1 TPM */
				if (result == TPM_E_BAD_ORDINAL)
                                       result = internal_TerminateHandle(
                                           auth_mgr.auth_mapper[i].tpm_handle);

				if (result == TCPA_E_INVALID_AUTHHANDLE) {
					LogDebug("Tried to close an invalid auth handle: %x",
						 auth_mgr.auth_mapper[i].tpm_handle);
				} else if (result != TCPA_SUCCESS) {
					LogDebug("TPM_TerminateHandle returned %d", result);
				}
			}
                       /* clear the slot */
			auth_mgr.open_auth_sessions--;
			auth_mgr.auth_mapper[i].full = FALSE;
                       auth_mgr.auth_mapper[i].tpm_handle = 0;
                       auth_mgr.auth_mapper[i].tcs_ctx = 0;
			LogDebug("released auth for TCS %x TPM %x", tcs_handle,
                               auth_mgr.auth_mapper[i].tpm_handle);

			auth_mgr_swap_in();
		}
	}

	return TSS_SUCCESS;
}

void
auth_mgr_release_auth(TPM_AUTH *auth0, TPM_AUTH *auth1, TCS_CONTEXT_HANDLE tcs_handle)
{
	if (auth0)
		auth_mgr_release_auth_handle(auth0->AuthHandle, tcs_handle,
					     auth0->fContinueAuthSession);

	if (auth1)
		auth_mgr_release_auth_handle(auth1->AuthHandle, tcs_handle,
					     auth1->fContinueAuthSession);
}

/* unload the auth ctx associated with this auth handle */
TSS_RESULT
auth_mgr_release_auth_handle(TCS_AUTHHANDLE tpm_auth_handle, TCS_CONTEXT_HANDLE tcs_handle,
			     TSS_BOOL cont)
{
	UINT32 i;
	TSS_RESULT result = TSS_SUCCESS;

	for (i = 0; i < auth_mgr.auth_mapper_size; i++) {
		if (auth_mgr.auth_mapper[i].full == TRUE &&
		    auth_mgr.auth_mapper[i].tpm_handle == tpm_auth_handle &&
		    auth_mgr.auth_mapper[i].tcs_ctx == tcs_handle) {
			if (!cont) {
                               /*
                                * This function should not be necessary, but
                                * if the main operation resulted in an error,
                                * the TPM may still hold the auth handle
                                * and it must be freed.  Most of the time
                                * this call will result in TPM_E_INVALID_AUTHHANDLE
                                * error which can be ignored.
                                */
                               result = TCSP_FlushSpecific_Common(
                                   auth_mgr.auth_mapper[i].tpm_handle,
                                   TPM_RT_AUTH);

				/* Ok, probably dealing with a 1.1 TPM */
				if (result == TPM_E_BAD_ORDINAL)
                                       result = internal_TerminateHandle(
                                           auth_mgr.auth_mapper[i].tpm_handle);

				if (result == TCPA_E_INVALID_AUTHHANDLE) {
					LogDebug("Tried to close an invalid auth handle: %x",
						 auth_mgr.auth_mapper[i].tpm_handle);
				} else if (result != TCPA_SUCCESS) {
					LogDebug("TPM_TerminateHandle returned %d", result);
				}

                               if (result == TPM_SUCCESS) {
                                       LogDebug("released auth for TCS %x TPM %x",
                                                auth_mgr.auth_mapper[i].tcs_ctx, tpm_auth_handle);
                               }
                               /*
                                * Mark it as released, the "cont" flag indicates
                                * that it is no longer needed.
                                */
                               auth_mgr.open_auth_sessions--;
                               auth_mgr.auth_mapper[i].full = FALSE;
                               auth_mgr.auth_mapper[i].tpm_handle = 0;
                               auth_mgr.auth_mapper[i].tcs_ctx = 0;
                               auth_mgr_swap_in();
			}
                       /* If the cont flag is TRUE, we have to keep the handle */
		}
	}

	return result;
}

TSS_RESULT
auth_mgr_check(TCS_CONTEXT_HANDLE tcsContext, TPM_AUTHHANDLE *tpm_auth_handle)
{
	UINT32 i;
	TSS_RESULT result = TSS_SUCCESS;

	for (i = 0; i < auth_mgr.auth_mapper_size; i++) {
		if (auth_mgr.auth_mapper[i].full == TRUE &&
		    auth_mgr.auth_mapper[i].tpm_handle == *tpm_auth_handle &&
		    auth_mgr.auth_mapper[i].tcs_ctx == tcsContext) {
			/* We have a record of this session, now swap it into the TPM if need be. */
			if (auth_mgr.auth_mapper[i].swap) {
				LogDebugFn("TPM_LoadAuthContext for TCS %x TPM %x", tcsContext,
					   auth_mgr.auth_mapper[i].tpm_handle);

				result = TPM_LoadAuthContext(auth_mgr.auth_mapper[i].swap_size,
							     auth_mgr.auth_mapper[i].swap,
							     tpm_auth_handle);
				if (result == TSS_SUCCESS) {
					free(auth_mgr.auth_mapper[i].swap);
					auth_mgr.auth_mapper[i].swap = NULL;
					auth_mgr.auth_mapper[i].swap_size = 0;

					LogDebugFn("TPM_LoadAuthContext succeeded. Old TPM: %x, New"
						   " TPM: %x", auth_mgr.auth_mapper[i].tpm_handle,
						   *tpm_auth_handle);

					auth_mgr.auth_mapper[i].tpm_handle = *tpm_auth_handle;
				} else if (result == TPM_E_RESOURCES) {
					if ((result = auth_mgr_swap_out(tcsContext))) {
						LogDebugFn("TPM_LoadAuthContext failed with TPM_E_R"
							   "ESOURCES and swapping out failed, retur"
							   "ning error");
						return result;
					}

					LogDebugFn("Retrying TPM_LoadAuthContext after swap"
						   " out...");
					result =
					      TPM_LoadAuthContext(auth_mgr.auth_mapper[i].swap_size,
								  auth_mgr.auth_mapper[i].swap,
								  tpm_auth_handle);
					free(auth_mgr.auth_mapper[i].swap);
					auth_mgr.auth_mapper[i].swap = NULL;
					auth_mgr.auth_mapper[i].swap_size = 0;
				} else {
					LogDebug("TPM_LoadAuthContext failed: 0x%x.", result);
				}
			}

			return result;
		}
	}

	LogDebugFn("Can't find auth for TCS handle %x, should be %x", tcsContext, *tpm_auth_handle);
	return TCSERR(TSS_E_INTERNAL_ERROR);
}

TSS_RESULT
auth_mgr_add(TCS_CONTEXT_HANDLE tcsContext, TCS_AUTHHANDLE tpm_auth_handle)
{
	struct auth_map *tmp = auth_mgr.auth_mapper;
	UINT32 i;

	for (i = 0; i < auth_mgr.auth_mapper_size; i++) {
		if (auth_mgr.auth_mapper[i].full == FALSE) {
			auth_mgr.auth_mapper[i].tpm_handle = tpm_auth_handle;
			auth_mgr.auth_mapper[i].tcs_ctx = tcsContext;
			auth_mgr.auth_mapper[i].full = TRUE;
			auth_mgr.open_auth_sessions++;
			LogDebug("added auth for TCS %x TPM %x", tcsContext, tpm_auth_handle);

			return TSS_SUCCESS;
		}
	}


	LogDebugFn("Thread %ld growing the auth table to %u entries", THREAD_ID,
		   auth_mgr.auth_mapper_size + TSS_DEFAULT_AUTH_TABLE_SIZE);

	auth_mgr.auth_mapper = calloc(auth_mgr.auth_mapper_size +
				      TSS_DEFAULT_AUTH_TABLE_SIZE, sizeof(struct auth_map));
	if (auth_mgr.auth_mapper == NULL) {
		auth_mgr.auth_mapper = tmp;
		return TCSERR(TSS_E_OUTOFMEMORY);
	} else {
		memcpy(auth_mgr.auth_mapper, tmp,
				auth_mgr.auth_mapper_size * sizeof(struct auth_map));
		auth_mgr.auth_mapper_size += TSS_DEFAULT_AUTH_TABLE_SIZE;
		LogDebugFn("Success.");
		return TSS_SUCCESS;
	}
}

/* A thread wants a new OIAP or OSAP session with the TPM. Returning TRUE indicates that we should
 * allow it to open the session, FALSE to indicate that the request should be queued or have
 * another thread's session swapped out to make room for it.
 */
TSS_BOOL
auth_mgr_req_new(TCS_CONTEXT_HANDLE hContext)
{
	UINT32 i, opened = 0;

	for (i = 0; i < auth_mgr.auth_mapper_size; i++) {
		if (auth_mgr.auth_mapper[i].full == TRUE &&
		    auth_mgr.auth_mapper[i].tcs_ctx  == hContext) {
			opened++;
		}
	}

	/* If this TSP has already opened its max open auth handles, deny another open */
	if (opened >= MAX(2, (UINT32)auth_mgr.max_auth_sessions/2)) {
		LogDebug("Max opened auth handles already opened.");
		return FALSE;
	}

	/* if we have one opened already and there's a slot available, ok */
	if (opened && ((auth_mgr.max_auth_sessions - auth_mgr.open_auth_sessions) >= 1))
		return TRUE;

	/* we don't already have one open and there are at least 2 slots left */
	if ((auth_mgr.max_auth_sessions - auth_mgr.open_auth_sessions) >= 2)
		return TRUE;

	LogDebug("Request for new auth handle denied by TCS. (%d opened sessions)", opened);

	return FALSE;
}

TSS_RESULT
auth_mgr_oiap(TCS_CONTEXT_HANDLE hContext,	/* in */
	      TCS_AUTHHANDLE *authHandle,	/* out */
	      TCPA_NONCE *nonce0)		/* out */
{
	TSS_RESULT result;

	/* are the maximum number of auth sessions open? */
	if (auth_mgr_req_new(hContext) == FALSE) {
		if ((result = auth_mgr_swap_out(hContext)))
			goto done;
	}

	if ((result = TCSP_OIAP_Internal(hContext, authHandle, nonce0)))
		goto done;

	/* success, add an entry to the table */
	result = auth_mgr_add(hContext, *authHandle);
done:
	return result;
}

TSS_RESULT
auth_mgr_osap(TCS_CONTEXT_HANDLE hContext,	/* in */
	      TCPA_ENTITY_TYPE entityType,	/* in */
	      UINT32 entityValue,		/* in */
	      TCPA_NONCE nonceOddOSAP,		/* in */
	      TCS_AUTHHANDLE *authHandle,	/* out */
	      TCPA_NONCE *nonceEven,		/* out */
	      TCPA_NONCE *nonceEvenOSAP)	/* out */
{
	TSS_RESULT result;
	UINT32 newEntValue = 0;

	/* if ET is not KEYHANDLE or KEY, newEntValue is a don't care */
	if (entityType == TCPA_ET_KEYHANDLE || entityType == TCPA_ET_KEY) {
		if (ensureKeyIsLoaded(hContext, entityValue, &newEntValue))
			return TCSERR(TSS_E_FAIL);
	} else {
		newEntValue = entityValue;
	}

	/* are the maximum number of auth sessions open? */
	if (auth_mgr_req_new(hContext) == FALSE) {
		if ((result = auth_mgr_swap_out(hContext)))
			goto done;
	}

	if ((result = TCSP_OSAP_Internal(hContext, entityType, newEntValue, nonceOddOSAP,
					 authHandle, nonceEven, nonceEvenOSAP)))
		goto done;

	/* success, add an entry to the table */
	result = auth_mgr_add(hContext, *authHandle);
done:
	return result;
}

/* This function is only called directly from the TSP, we use other internal routines to free
 * our handles. */
TSS_RESULT
TCSP_TerminateHandle_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
			      TCS_AUTHHANDLE handle)	/* in */
{
	TSS_RESULT result;

	LogDebug("Entering TCSI_TerminateHandle");
	if ((result = ctx_verify_context(hContext)))
		return result;

	if ((result = auth_mgr_check(hContext, &handle)))
		return result;

	result = auth_mgr_release_auth_handle(handle, hContext, TRUE);

	LogResult("Terminate Handle", result);
	return result;
}

TSS_RESULT
TPM_SaveAuthContext(TPM_AUTHHANDLE handle, UINT32 *size, BYTE **blob)
{
	UINT64 offset;
	UINT32 trash, bsize;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	offset = 10;
	LoadBlob_UINT32(&offset, handle, txBlob);
	LoadBlob_Header(TPM_TAG_RQU_COMMAND, offset, TPM_ORD_SaveAuthContext, txBlob);

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &trash);

	LogDebug("total packet size received from TPM: %u", trash);

	if (!result) {
		offset = 10;
		UnloadBlob_UINT32(&offset, &bsize, txBlob);

		LogDebug("Reported blob size from TPM: %u", bsize);

		*blob = malloc(bsize);
		if (*blob == NULL) {
			LogError("malloc of %u bytes failed.", bsize);
			return TCSERR(TSS_E_OUTOFMEMORY);
		}
		UnloadBlob(&offset, bsize, txBlob, *blob);
		*size = bsize;
	}

	return result;
}

TSS_RESULT
TPM_LoadAuthContext(UINT32 size, BYTE *blob, TPM_AUTHHANDLE *handle)
{
	UINT64 offset;
	UINT32 trash;
	TSS_RESULT result;
	BYTE txBlob[TSS_TPM_TXBLOB_SIZE];

	LogDebugFn("Loading %u byte auth blob back into TPM", size);

	offset = 10;
	LoadBlob_UINT32(&offset, size, txBlob);
	LoadBlob(&offset, size, txBlob, blob);
	LoadBlob_Header(TPM_TAG_RQU_COMMAND, offset, TPM_ORD_LoadAuthContext, txBlob);

	if ((result = req_mgr_submit_req(txBlob)))
		return result;

	result = UnloadBlob_Header(txBlob, &trash);

	if (!result) {
		offset = 10;
		UnloadBlob_UINT32(&offset, handle, txBlob);
	}

	return result;
}


<|start_filename|>src/tspi/tsp_audit.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2007
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "tsplog.h"
#include "obj.h"


TSS_RESULT
__tspi_audit_set_ordinal_audit_status(TSS_HTPM hTpm,
				TSS_FLAG flag,
				TSS_FLAG subFlag,
				UINT32 ulOrdinal)
{
	TSS_BOOL bAuditState;
	TSS_HCONTEXT tspContext;
	TSS_HPOLICY hPolicy;
	TPM_AUTH ownerAuth;
	Trspi_HashCtx hashCtx;
	TCPA_DIGEST digest;
	TSS_RESULT result = TSS_SUCCESS;

	if (flag != TSS_TSPATTRIB_TPM_ORDINAL_AUDIT_STATUS)
		return TSPERR(TSS_E_BAD_PARAMETER);

	switch (subFlag) {
		case TPM_CAP_PROP_TPM_SET_ORDINAL_AUDIT:
			bAuditState = TRUE;
			break;

		case TPM_CAP_PROP_TPM_CLEAR_ORDINAL_AUDIT:
			bAuditState = FALSE;
			break;

		default:
			return TSPERR(TSS_E_BAD_PARAMETER);
	}

	if ((result = obj_tpm_get_tsp_context(hTpm, &tspContext)))
		return result;

	if ((result = obj_tpm_get_policy(hTpm, TSS_POLICY_USAGE, &hPolicy)))
		return result;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_SetOrdinalAuditStatus);
	result |= Trspi_Hash_UINT32(&hashCtx, ulOrdinal);
	result |= Trspi_Hash_BOOL(&hashCtx, bAuditState);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
		return result;

	if ((result = secret_PerformAuth_OIAP(hTpm, TPM_ORD_SetOrdinalAuditStatus,
					      hPolicy, FALSE, &digest, &ownerAuth)))
		return result;

	if ((result = TCS_API(tspContext)->SetOrdinalAuditStatus(tspContext, &ownerAuth, ulOrdinal,
								 bAuditState)))
		return result;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, result);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_SetOrdinalAuditStatus);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
		return result;

	return obj_policy_validate_auth_oiap(hPolicy, &digest, &ownerAuth);
}

#ifdef TSS_BUILD_TRANSPORT
TSS_RESULT
Transport_SetOrdinalAuditStatus(TSS_HCONTEXT tspContext,        /* in */
				TPM_AUTH *ownerAuth,          /* in/out */
				UINT32 ulOrdinal,             /* in */
				TSS_BOOL bAuditState) /* in */
{
        TSS_RESULT result;
        UINT32 handlesLen = 0;
        UINT64 offset;
        BYTE data[sizeof(UINT32) + sizeof(TSS_BOOL)];


	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	offset = 0;
	Trspi_LoadBlob_UINT32(&offset, ulOrdinal, data);
	Trspi_LoadBlob_BOOL(&offset, bAuditState, data);

	result = obj_context_transport_execute(tspContext, TPM_ORD_SetOrdinalAuditStatus,
					       sizeof(data), data, NULL, &handlesLen, NULL,
					       ownerAuth, NULL, NULL, NULL);
	return result;
}

TSS_RESULT
Transport_GetAuditDigest(TSS_HCONTEXT tspContext,       /* in */
			 UINT32 startOrdinal,         /* in */
			 TPM_DIGEST *auditDigest,             /* out */
			 UINT32 *counterValueSize,            /* out */
			 BYTE **counterValue,         /* out */
			 TSS_BOOL *more,                      /* out */
			 UINT32 *ordSize,                     /* out */
			 UINT32 **ordList)                    /* out */
{
        TSS_RESULT result;
        UINT32 handlesLen = 0, decLen;
        BYTE *dec = NULL;
        UINT64 offset;
        BYTE data[sizeof(UINT32)];


	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	offset = 0;
	Trspi_LoadBlob_UINT32(&offset, startOrdinal, data);

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_GetAuditDigest,
						    sizeof(data), data, NULL, &handlesLen, NULL,
						    NULL, NULL, &decLen, &dec)))
		return result;

	offset = 0;
	Trspi_UnloadBlob_COUNTER_VALUE(&offset, dec, NULL);

	*counterValueSize = (UINT32)offset;
	if ((*counterValue = malloc(*counterValueSize)) == NULL) {
		free(dec);
		LogError("malloc of %u bytes failed", *counterValueSize);
		*counterValueSize = 0;
		return TSPERR(TSS_E_OUTOFMEMORY);
	}
	offset = 0;
	Trspi_UnloadBlob(&offset, *counterValueSize, dec, *counterValue);

	Trspi_UnloadBlob_DIGEST(&offset, dec, auditDigest);
	Trspi_UnloadBlob_BOOL(&offset, more, dec);

	Trspi_UnloadBlob_UINT32(&offset, ordSize, dec);

	if ((*ordList = malloc(*ordSize)) == NULL) {
		free(dec);
		free(*counterValue);
		*counterValue = NULL;
		*counterValueSize = 0;
		LogError("malloc of %u bytes failed", *ordSize);
		*ordSize = 0;
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	Trspi_UnloadBlob(&offset, *ordSize, dec, *(BYTE **)ordList);
	*ordSize /= sizeof(UINT32);

	return TSS_SUCCESS;
}

TSS_RESULT
Transport_GetAuditDigestSigned(TSS_HCONTEXT tspContext,       /* in */
			       TCS_KEY_HANDLE keyHandle,      /* in */
			       TSS_BOOL closeAudit,           /* in */
			       TPM_NONCE *antiReplay,         /* in */
			       TPM_AUTH *privAuth,            /* in/out */
			       UINT32 *counterValueSize,      /* out */
			       BYTE **counterValue,           /* out */
			       TPM_DIGEST *auditDigest,       /* out */
			       TPM_DIGEST *ordinalDigest,     /* out */
			       UINT32 *sigSize,               /* out */
			       BYTE **sig)                    /* out */
{
        TSS_RESULT result;
        UINT32 handlesLen, decLen;
        TCS_HANDLE *handles, handle;
        BYTE *dec = NULL;
        TPM_DIGEST pubKeyHash;
        Trspi_HashCtx hashCtx;
        UINT64 offset;
        BYTE data[sizeof(TSS_BOOL) + sizeof(TPM_NONCE)];


	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	if ((result = obj_tcskey_get_pubkeyhash(keyHandle, pubKeyHash.digest)))
		return result;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
		return result;

	handlesLen = 1;
	handle = keyHandle;
	handles = &handle;

	offset = 0;
	Trspi_LoadBlob_BOOL(&offset, closeAudit, data);
	Trspi_LoadBlob_NONCE(&offset, data, antiReplay);

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_GetAuditDigestSigned,
						    sizeof(data), data, &pubKeyHash, &handlesLen,
						    &handles, privAuth, NULL, &decLen, &dec)))
		return result;

	offset = 0;
	Trspi_UnloadBlob_COUNTER_VALUE(&offset, dec, NULL);

	*counterValueSize = (UINT32)offset;
	if ((*counterValue = malloc(*counterValueSize)) == NULL) {
		free(dec);
		LogError("malloc of %u bytes failed", *counterValueSize);
		*counterValueSize = 0;
		return TSPERR(TSS_E_OUTOFMEMORY);
	}
	offset = 0;
	Trspi_UnloadBlob(&offset, *counterValueSize, dec, *counterValue);

	Trspi_UnloadBlob_DIGEST(&offset, dec, auditDigest);
	Trspi_UnloadBlob_DIGEST(&offset, dec, ordinalDigest);

	Trspi_UnloadBlob_UINT32(&offset, sigSize, dec);

	if ((*sig = malloc(*sigSize)) == NULL) {
		free(dec);
		free(*counterValue);
		*counterValue = NULL;
		*counterValueSize = 0;
		LogError("malloc of %u bytes failed", *sigSize);
		*counterValueSize = 0;
		return TSPERR(TSS_E_OUTOFMEMORY);
	}
	Trspi_UnloadBlob(&offset, *sigSize, dec, *sig);

	return TSS_SUCCESS;
}
#endif


<|start_filename|>src/tspi/gtk/callbacks.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004
 *
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <gtk/gtk.h>
#include <string.h>

#undef TRUE
#undef FALSE

#include "callbacks.h"
#include "interface.h"
#include "support.h"
#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "tsplog.h"


/* Callbacks for the simple password dialog */

void
on_inputdialog1_destroy(GtkObject *object, struct userdata *user_data)
{
	gtk_widget_destroy(user_data->window);
	gtk_main_quit();
}


void
on_dialog1_close(GtkDialog *dialog, struct userdata *user_data)
{
	gtk_widget_destroy(user_data->window);
	gtk_main_quit();
}


void
on_cancelbutton1_clicked(GtkButton *button, struct userdata *user_data)
{
	LogDebugFn();
	gtk_widget_destroy(user_data->window);
	user_data->string_len = 0;
	gtk_main_quit();
}


void
on_okbutton1_clicked(GtkButton *button, struct userdata	*user_data)
{
	const gchar *entry_text = gtk_entry_get_text (GTK_ENTRY(user_data->entry));

	LogDebugFn();
	user_data->string = (char *)Trspi_Native_To_UNICODE((BYTE *)entry_text,
							    &user_data->string_len);
	gtk_widget_destroy(user_data->window);

	gtk_main_quit();
}


gboolean
enter_event(GtkWidget *widget, struct userdata *user_data)
{
	const gchar *entry_text = gtk_entry_get_text (GTK_ENTRY(user_data->entry));

	LogDebugFn();
	user_data->string = (char *)Trspi_Native_To_UNICODE((BYTE *)entry_text,
							    &user_data->string_len);
	gtk_widget_destroy(user_data->window);

	gtk_main_quit();
	return TRUE;
}


/* Callbacks for the new password dialog */
void
on_entryPassword_activate(GtkEntry *entry, struct userdata *user_data)
{
	const gchar *entryPass_text = gtk_entry_get_text (GTK_ENTRY(user_data->entryPass));
	const gchar *entryConf_text = gtk_entry_get_text (GTK_ENTRY(user_data->entryConf));
	int len = strlen(entryConf_text);

	if (strlen(entryConf_text) == strlen(entryPass_text)) {
		if (!memcmp(entryPass_text, entryConf_text, len)) {
			user_data->string = (char *)Trspi_Native_To_UNICODE((BYTE *)entryConf_text,
									    &user_data->string_len);
			gtk_widget_destroy(user_data->window);
			gtk_main_quit();

			LogDebugFn("string len ptr: %p, value = %u", &user_data->string_len,
				   user_data->string_len);
			return;
		}
	}

	gtk_widget_grab_focus(user_data->entryConf);
}

void
on_entryConfirm_activate(GtkEntry *entry, struct userdata *user_data)
{
	const gchar *entryPass_text = gtk_entry_get_text (GTK_ENTRY(user_data->entryPass));
	const gchar *entryConf_text = gtk_entry_get_text (GTK_ENTRY(user_data->entryConf));
	unsigned len = strlen(entryConf_text);

	if (strlen(entryConf_text) == strlen(entryPass_text)) {
		if (!memcmp(entryPass_text, entryConf_text, len)) {
			user_data->string = (char *)Trspi_Native_To_UNICODE((BYTE *)entryConf_text,
									    &user_data->string_len);
			gtk_widget_destroy(user_data->window);
			gtk_main_quit();

			LogDebugFn("string len ptr: %p, value = %u", &user_data->string_len,
				   user_data->string_len);
			return;
		}
	}

	gtk_widget_grab_focus(user_data->entryPass);
}

void
on_cancelbutton2_clicked(GtkButton *button, struct userdata *user_data)
{
	LogDebugFn();
	gtk_widget_destroy(user_data->window);
	user_data->string_len = 0;
	gtk_main_quit();
}

void
on_okbutton2_clicked(GtkButton *button, struct userdata *user_data)
{
	const gchar *entryPass_text = gtk_entry_get_text (GTK_ENTRY(user_data->entryPass));
	const gchar *entryConf_text = gtk_entry_get_text (GTK_ENTRY(user_data->entryConf));
	unsigned len = strlen(entryConf_text);

	if (strlen(entryConf_text) == strlen(entryPass_text)) {
		if (!memcmp(entryPass_text, entryConf_text, len)) {
			user_data->string = (char *)Trspi_Native_To_UNICODE((BYTE *)entryConf_text,
									    &user_data->string_len);
			gtk_widget_destroy(user_data->window);
			gtk_main_quit();

			LogDebugFn("string len ptr: %p, value = %u", &user_data->string_len,
				   user_data->string_len);
			return;
		}
	}

	gtk_widget_grab_focus(user_data->entryPass);
}


<|start_filename|>src/include/tss/compat11b.h<|end_filename|>

#ifndef __COMPAT11B_H__
#define __COMPAT11B_H__

#include <tss/tpm.h>

#define TCPA_Vendor_Specific32  TPM_Vendor_Specific32
#define TCPA_Vendor_Specific8   TPM_Vendor_Specific8

typedef TSS_UNICODE             UNICODE;
typedef TPM_DIGEST              TCPA_DIGEST;
typedef TPM_NONCE               TCPA_NONCE;
typedef TPM_NONCE               TCPA_SALT_NONCE;
typedef TPM_PUBKEY              TCPA_PUBKEY;
typedef TPM_SECRET              TCPA_SECRET;
typedef TPM_KEY                 TCPA_KEY;
typedef TPM_DIRVALUE            TCPA_DIRVALUE;
typedef TPM_COMMAND_CODE        TCPA_COMMAND_CODE;
typedef TPM_BOUND_DATA          TCPA_BOUND_DATA;
typedef TPM_STRUCT_VER          TCPA_VERSION;
typedef TPM_RESULT              TCPA_RESULT;
typedef TPM_PAYLOAD_TYPE        TCPA_PAYLOAD_TYPE;
typedef TPM_STORE_PRIVKEY       TCPA_STORE_PRIVKEY;
typedef TPM_CHOSENID_HASH       TCPA_CHOSENID_HASH;
typedef TPM_SYMMETRIC_KEY       TCPA_SYMMETRIC_KEY;
typedef TPM_PCR_INFO            TCPA_PCR_INFO;
typedef TPM_PCR_SELECTION       TCPA_PCR_SELECTION;
typedef TPM_STORED_DATA         TCPA_STORED_DATA;
typedef TPM_SEALED_DATA         TCPA_SEALED_DATA;
typedef TPM_KEY_FLAGS           TCPA_KEY_FLAGS;
typedef TPM_KEY_PARMS           TCPA_KEY_PARMS;
typedef TPM_STORE_PUBKEY        TCPA_STORE_PUBKEY;
typedef TPM_MIGRATIONKEYAUTH    TCPA_MIGRATIONKEYAUTH;
typedef TPM_RSA_KEY_PARMS       TCPA_RSA_KEY_PARMS;
typedef TPM_CERTIFY_INFO        TCPA_CERTIFY_INFO;
typedef TPM_STORE_ASYMKEY       TCPA_STORE_ASYMKEY;
typedef TPM_ENCAUTH             TCPA_ENCAUTH;
typedef TPM_PCRINDEX            TCPA_PCRINDEX;
typedef TPM_PCRVALUE            TCPA_PCRVALUE;
typedef TPM_DIRINDEX            TCPA_DIRINDEX;
typedef TPM_PROTOCOL_ID         TCPA_PROTOCOL_ID;
typedef TPM_ALGORITHM_ID        TCPA_ALGORITHM_ID;
typedef TPM_ENTITY_TYPE         TCPA_ENTITY_TYPE;
typedef TPM_CAPABILITY_AREA     TCPA_CAPABILITY_AREA;
typedef TPM_HMAC                TCPA_HMAC;
typedef TPM_MIGRATE_SCHEME      TCPA_MIGRATE_SCHEME;
typedef TPM_PHYSICAL_PRESENCE   TCPA_PHYSICAL_PRESENCE;
typedef TPM_KEY_HANDLE          TCPA_KEY_HANDLE;
typedef TPM_KEY_HANDLE_LIST     TCPA_KEY_HANDLE_LIST;
typedef TPM_PCR_COMPOSITE       TCPA_PCR_COMPOSITE;
typedef TPM_AUTH_DATA_USAGE     TCPA_AUTH_DATA_USAGE;
typedef TPM_AUTHDATA            TCPA_AUTHDATA;
typedef TPM_KEY_USAGE           TCPA_KEY_USAGE;
typedef TPM_COMPOSITE_HASH      TCPA_COMPOSITE_HASH;
typedef TPM_QUOTE_INFO          TCPA_QUOTE_INFO;
typedef TPM_TAG                 TCPA_TAG;
typedef TPM_ENC_SCHEME          TCPA_ENC_SCHEME;
typedef TPM_SIG_SCHEME          TCPA_SIG_SCHEME;
typedef TPM_STARTUP_TYPE        TCPA_STARTUP_TYPE;
typedef TPM_AUTHHANDLE          TCPA_AUTHHANDLE;
typedef TPM_SYM_CA_ATTESTATION  TCPA_SYM_CA_ATTESTATION;
typedef TPM_ASYM_CA_CONTENTS    TCPA_ASYM_CA_CONTENTS;
typedef TPM_IDENTITY_REQ        TCPA_IDENTITY_REQ;
typedef TPM_IDENTITY_PROOF      TCPA_IDENTITY_PROOF;

// These were removed from the 1.2 TPM spec
typedef UINT32                  TCPA_ENCHANDLE;
typedef UINT32                  TCPA_EVENTTYPE;
typedef struct tdTCPA_AUDIT_EVENT {
    TCPA_COMMAND_CODE ordinal;
    TCPA_RESULT       returncode;
} TCPA_AUDIT_EVENT;

#define TCPA_SHA1_160_HASH_LEN          TPM_SHA1_160_HASH_LEN
#define TCPA_SHA1BASED_NONCE_LEN        TPM_SHA1BASED_NONCE_LEN

#define redirection             TSS_KEYFLAG_REDIRECTION
#define migratable              TSS_KEYFLAG_MIGRATABLE
#define volatileKey             TSS_KEYFLAG_VOLATILEKEY

#define TCPA_ET_KEYHANDLE       TPM_ET_KEYHANDLE
#define TCPA_ET_KEY             TPM_ET_KEY
#define TCPA_ET_OWNER           TPM_ET_OWNER
#define TCPA_ET_SRK             TPM_ET_SRK
#define TCPA_ET_DATA            TPM_ET_DATA

#define TCPA_PID_OIAP           TPM_PID_OIAP
#define TCPA_PID_OSAP           TPM_PID_OSAP
#define TCPA_PID_ADIP           TPM_PID_ADIP
#define TCPA_PID_ADCP           TPM_PID_ADCP
#define TCPA_PID_OWNER          TPM_PID_OWNER

#define TCPA_PT_ASYM            TPM_PT_ASYM
#define TCPA_PT_BIND            TPM_PT_BIND
#define TCPA_PT_MIGRATE         TPM_PT_MIGRATE
#define TCPA_PT_MAINT           TPM_PT_MAINT
#define TCPA_PT_SEAL            TPM_PT_SEAL

#define TCPA_CAP_ALG            TPM_CAP_ALG
#define TCPA_CAP_ORD            TPM_CAP_ORD
#define TCPA_CAP_PID            TPM_CAP_PID
#define TCPA_CAP_FLAG           TPM_CAP_FLAG
#define TCPA_CAP_VERSION        TPM_CAP_VERSION
#define TCPA_CAP_PROPERTY       TPM_CAP_PROPERTY
#define TCPA_CAP_KEY_HANDLE     TPM_CAP_KEY_HANDLE
#define TCPA_CAP_CHECK_LOADED   TPM_CAP_CHECK_LOADED

#define TCPA_ALG_RSA            TPM_ALG_RSA
#define TCPA_ALG_DES            TPM_ALG_DES
#define TCPA_ALG_3DES           TPM_ALG_3DES
#define TCPA_ALG_SHA            TPM_ALG_SHA
#define TCPA_ALG_HMAC           TPM_ALG_HMAC
#define TCPA_ALG_AES            TPM_ALG_AES

#define TCPA_PROTECTED_ORDINAL          TPM_PROTECTED_ORDINAL
#define TCPA_UNPROTECTED_ORDINAL        TPM_UNPROTECTED_ORDINAL
#define TCPA_CONNECTION_ORDINAL         TPM_CONNECTION_ORDINAL

#define TCPA_PROTECTED_COMMAND          TPM_PROTECTED_COMMAND
#define TCPA_UNPROTECTED_COMMAND        TPM_UNPROTECTED_COMMAND
#define TCPA_CONNECTION_COMMAND         TPM_CONNECTION_COMMAND
#define TCPA_VENDOR_COMMAND             TPM_VENDOR_COMMAND

#define TCPA_MAIN               TPM_MAIN
#define TCPA_PC                 TPM_PC
#define TCPA_PDA                TPM_PDA
#define TCPA_CELL_PHONE         TPM_CELL_PHONE

#define TCPA_MS_MIGRATE                 TPM_MS_MIGRATE
#define TCPA_MS_REWRAP                  TPM_MS_REWRAP
#define TCPA_MS_MAINT                   TPM_MS_MAINT

#define TCPA_ES_NONE                    TPM_ES_NONE
#define TCPA_ES_RSAESPKCSv15            TPM_ES_RSAESPKCSv15
#define TCPA_ES_RSAESOAEP_SHA1_MGF1     TPM_ES_RSAESOAEP_SHA1_MGF1

#define TCPA_SS_NONE                    TPM_SS_NONE
#define TCPA_SS_RSASSAPKCS1v15_SHA1     TPM_SS_RSASSAPKCS1v15_SHA1
#define TCPA_SS_RSASSAPKCS1v15_DER      TPM_SS_RSASSAPKCS1v15_DER
#define	TCPA_SS_RSASSAPKCS1v15_INFO	TPM_SS_RSASSAPKCS1v15_INFO

#define TCPA_PHYSICAL_PRESENCE_LIFETIME_LOCK    TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK
#define TCPA_PHYSICAL_PRESENCE_HW_ENABLE        TPM_PHYSICAL_PRESENCE_HW_ENABLE
#define TCPA_PHYSICAL_PRESENCE_CMD_ENABLE       TPM_PHYSICAL_PRESENCE_CMD_ENABLE
#define TCPA_PHYSICAL_PRESENCE_LOCK             TPM_PHYSICAL_PRESENCE_LOCK
#define TCPA_PHYSICAL_PRESENCE_PRESENT          TPM_PHYSICAL_PRESENCE_PRESENT
#define TCPA_PHYSICAL_PRESENCE_NOTPRESENT       TPM_PHYSICAL_PRESENCE_NOTPRESENT

#define TCPA_SUCCESS                    TPM_SUCCESS
#define TCPA_E_BASE                     TPM_E_BASE
#define TCPA_E_NON_FATAL                TPM_E_NON_FATAL
#define TCPA_E_AUTHFAIL                 TPM_E_AUTHFAIL
#define TCPA_E_BAD_PARAMETER            TPM_E_BAD_PARAMETER
#define TCPA_E_BADINDEX                 TPM_E_BADINDEX
#define TCPA_E_AUDITFAILURE             TPM_E_AUDITFAILURE
#define TCPA_E_CLEAR_DISABLED           TPM_E_CLEAR_DISABLED
#define TCPA_E_DEACTIVATED              TPM_E_DEACTIVATED
#define TCPA_E_DISABLED                 TPM_E_DISABLED
#define TCPA_E_DISABLED_CMD             TPM_E_DISABLED_CMD
#define TCPA_E_FAIL                     TPM_E_FAIL
#define TCPA_E_INACTIVE                 TPM_E_BAD_ORDINAL
#define TCPA_E_INSTALL_DISABLED         TPM_E_INSTALL_DISABLED
#define TCPA_E_INVALID_KEYHANDLE        TPM_E_INVALID_KEYHANDLE
#define TCPA_E_KEYNOTFOUND              TPM_E_KEYNOTFOUND
#define TCPA_E_NEED_SELFTEST            TPM_E_INAPPROPRIATE_ENC
#define TCPA_E_MIGRATEFAIL              TPM_E_MIGRATEFAIL
#define TCPA_E_NO_PCR_INFO              TPM_E_INVALID_PCR_INFO
#define TCPA_E_NOSPACE                  TPM_E_NOSPACE
#define TCPA_E_NOSRK                    TPM_E_NOSRK
#define TCPA_E_NOTSEALED_BLOB           TPM_E_NOTSEALED_BLOB
#define TCPA_E_OWNER_SET                TPM_E_OWNER_SET
#define TCPA_E_RESOURCES                TPM_E_RESOURCES
#define TCPA_E_SHORTRANDOM              TPM_E_SHORTRANDOM
#define TCPA_E_SIZE                     TPM_E_SIZE
#define TCPA_E_WRONGPCRVAL              TPM_E_WRONGPCRVAL
#define TCPA_E_BAD_PARAM_SIZE           TPM_E_BAD_PARAM_SIZE
#define TCPA_E_SHA_THREAD               TPM_E_SHA_THREAD
#define TCPA_E_SHA_ERROR                TPM_E_SHA_ERROR
#define TCPA_E_FAILEDSELFTEST           TPM_E_FAILEDSELFTEST
#define TCPA_E_AUTH2FAIL                TPM_E_AUTH2FAIL
#define TCPA_E_BADTAG                   TPM_E_BADTAG
#define TCPA_E_IOERROR                  TPM_E_IOERROR
#define TCPA_E_ENCRYPT_ERROR            TPM_E_ENCRYPT_ERROR
#define TCPA_E_DECRYPT_ERROR            TPM_E_DECRYPT_ERROR
#define TCPA_E_INVALID_AUTHHANDLE       TPM_E_INVALID_AUTHHANDLE
#define TCPA_E_NO_ENDORSEMENT           TPM_E_NO_ENDORSEMENT
#define TCPA_E_INVALID_KEYUSAGE         TPM_E_INVALID_KEYUSAGE
#define TCPA_E_WRONG_ENTITYTYPE         TPM_E_WRONG_ENTITYTYPE
#define TCPA_E_INVALID_POSTINIT         TPM_E_INVALID_POSTINIT
#define TCPA_E_INAPPROPRIATE_SIG        TPM_E_INAPPROPRIATE_SIG
#define TCPA_E_BAD_KEY_PROPERTY         TPM_E_BAD_KEY_PROPERTY
#define TCPA_E_BAD_MIGRATION            TPM_E_BAD_MIGRATION
#define TCPA_E_BAD_SCHEME               TPM_E_BAD_SCHEME
#define TCPA_E_BAD_DATASIZE             TPM_E_BAD_DATASIZE
#define TCPA_E_BAD_MODE                 TPM_E_BAD_MODE
#define TCPA_E_BAD_PRESENCE             TPM_E_BAD_PRESENCE
#define TCPA_E_BAD_VERSION              TPM_E_BAD_VERSION
#define TCPA_E_RETRY                    TPM_E_RETRY

#endif


<|start_filename|>src/tspi/tsp_migration.c<|end_filename|>

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2007
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"

#ifdef TSS_BUILD_TRANSPORT
TSS_RESULT
Transport_CreateMigrationBlob(TSS_HCONTEXT tspContext,	/* in */
			      TCS_KEY_HANDLE parentHandle,	/* in */
			      TCPA_MIGRATE_SCHEME migrationType,	/* in */
			      UINT32 MigrationKeyAuthSize,	/* in */
			      BYTE * MigrationKeyAuth,	/* in */
			      UINT32 encDataSize,	/* in */
			      BYTE * encData,	/* in */
			      TPM_AUTH * parentAuth,	/* in, out */
			      TPM_AUTH * entityAuth,	/* in, out */
			      UINT32 * randomSize,	/* out */
			      BYTE ** random,	/* out */
			      UINT32 * outDataSize,	/* out */
			      BYTE ** outData)	/* out */
{
	UINT64 offset;
	TSS_RESULT result;
	UINT32 handlesLen, dataLen, decLen;
	TCS_HANDLE *handles, handle;
	TPM_DIGEST pubKeyHash;
	Trspi_HashCtx hashCtx;
	BYTE *data, *dec;


	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	if ((result = obj_tcskey_get_pubkeyhash(parentHandle, pubKeyHash.digest)))
		return result;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
		return result;

	handlesLen = 1;
	handle = parentHandle;
	handles = &handle;

	dataLen = sizeof(TCPA_MIGRATE_SCHEME)
		  + MigrationKeyAuthSize
		  + sizeof(UINT32)
		  + encDataSize;
	if ((data = malloc(dataLen)) == NULL) {
		LogError("malloc of %u bytes failed", dataLen);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	offset = 0;
	Trspi_LoadBlob_UINT16(&offset, migrationType, data);
	Trspi_LoadBlob(&offset, MigrationKeyAuthSize, data, MigrationKeyAuth);
	Trspi_LoadBlob_UINT32(&offset, encDataSize, data);
	Trspi_LoadBlob(&offset, encDataSize, data, encData);

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_CreateMigrationBlob,
						    dataLen, data, &pubKeyHash, &handlesLen,
						    &handles, parentAuth, entityAuth, &decLen,
						    &dec))) {
		free(data);
		return result;
	}
	free(data);

	offset = 0;
	Trspi_UnloadBlob_UINT32(&offset, randomSize, dec);

	if ((*random = malloc(*randomSize)) == NULL) {
		free(dec);
		LogError("malloc of %u bytes failed", *randomSize);
		*randomSize = 0;
		return TSPERR(TSS_E_OUTOFMEMORY);
	}
	Trspi_UnloadBlob(&offset, *randomSize, dec, *random);

	Trspi_UnloadBlob_UINT32(&offset, outDataSize, dec);

	if ((*outData = malloc(*outDataSize)) == NULL) {
		free(*random);
		*random = NULL;
		*randomSize = 0;
		free(dec);
		LogError("malloc of %u bytes failed", *outDataSize);
		*outDataSize = 0;
		return TSPERR(TSS_E_OUTOFMEMORY);
	}
	Trspi_UnloadBlob(&offset, *outDataSize, dec, *outData);
	free(dec);

	return result;
}

TSS_RESULT
Transport_ConvertMigrationBlob(TSS_HCONTEXT tspContext,	/* in */
			       TCS_KEY_HANDLE parentHandle,	/* in */
			       UINT32 inDataSize,	/* in */
			       BYTE * inData,	/* in */
			       UINT32 randomSize,	/* in */
			       BYTE * random,	/* in */
			       TPM_AUTH * parentAuth,	/* in, out */
			       UINT32 * outDataSize,	/* out */
			       BYTE ** outData)	/* out */
{
	UINT64 offset;
	TSS_RESULT result;
	UINT32 handlesLen, dataLen, decLen;
	TCS_HANDLE *handles, handle;
	TPM_DIGEST pubKeyHash;
	Trspi_HashCtx hashCtx;
	BYTE *data, *dec;


	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	if ((result = obj_tcskey_get_pubkeyhash(parentHandle, pubKeyHash.digest)))
		return result;

	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
		return result;

	handlesLen = 1;
	handle = parentHandle;
	handles = &handle;

	dataLen = (2 * sizeof(UINT32)) + randomSize + inDataSize;
	if ((data = malloc(dataLen)) == NULL) {
		LogError("malloc of %u bytes failed", dataLen);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	offset = 0;
	Trspi_LoadBlob_UINT32(&offset, inDataSize, data);
	Trspi_LoadBlob(&offset, inDataSize, data, inData);
	Trspi_LoadBlob_UINT32(&offset, randomSize, data);
	Trspi_LoadBlob(&offset, randomSize, data, random);

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_ConvertMigrationBlob,
						    dataLen, data, &pubKeyHash, &handlesLen,
						    &handles, parentAuth, NULL, &decLen, &dec))) {
		free(data);
		return result;
	}
	free(data);

	offset = 0;
	Trspi_UnloadBlob_UINT32(&offset, outDataSize, dec);

	if ((*outData = malloc(*outDataSize)) == NULL) {
		free(dec);
		LogError("malloc of %u bytes failed", *outDataSize);
		*outDataSize = 0;
		return TSPERR(TSS_E_OUTOFMEMORY);
	}
	Trspi_UnloadBlob(&offset, *outDataSize, dec, *outData);
	free(dec);

	return result;
}

TSS_RESULT
Transport_AuthorizeMigrationKey(TSS_HCONTEXT tspContext,	/* in */
				TCPA_MIGRATE_SCHEME migrateScheme,	/* in */
				UINT32 MigrationKeySize,	/* in */
				BYTE * MigrationKey,	/* in */
				TPM_AUTH * ownerAuth,	/* in, out */
				UINT32 * MigrationKeyAuthSize,	/* out */
				BYTE ** MigrationKeyAuth)	/* out */
{
	UINT64 offset;
	UINT16 tpmMigrateScheme;
	TSS_RESULT result;
	UINT32 handlesLen = 0, dataLen, decLen;
	BYTE *data, *dec;


	if ((result = obj_context_transport_init(tspContext)))
		return result;

	LogDebugFn("Executing in a transport session");

	/* The TSS_MIGRATE_SCHEME must be changed to a TPM_MIGRATE_SCHEME here, since the TCS
	 * expects a TSS migrate scheme, but this could be wrapped by the TSP before it gets to the
	 * TCS. */
	switch (migrateScheme) {
		case TSS_MS_MIGRATE:
			tpmMigrateScheme = TCPA_MS_MIGRATE;
			break;
		case TSS_MS_REWRAP:
			tpmMigrateScheme = TCPA_MS_REWRAP;
			break;
		case TSS_MS_MAINT:
			tpmMigrateScheme = TCPA_MS_MAINT;
			break;
#ifdef TSS_BUILD_CMK
		case TSS_MS_RESTRICT_MIGRATE:
			tpmMigrateScheme = TPM_MS_RESTRICT_MIGRATE;
			break;

		case TSS_MS_RESTRICT_APPROVE_DOUBLE:
			tpmMigrateScheme = TPM_MS_RESTRICT_APPROVE_DOUBLE;
			break;
#endif
		default:
			return TSPERR(TSS_E_BAD_PARAMETER);
			break;
	}

	dataLen = sizeof(TCPA_MIGRATE_SCHEME) + MigrationKeySize;
	if ((data = malloc(dataLen)) == NULL) {
		LogError("malloc of %u bytes failed", dataLen);
		return TSPERR(TSS_E_OUTOFMEMORY);
	}

	offset = 0;
	Trspi_LoadBlob_UINT16(&offset, tpmMigrateScheme, data);
	Trspi_LoadBlob(&offset, MigrationKeySize, data, MigrationKey);

	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_AuthorizeMigrationKey,
						    dataLen, data, NULL, &handlesLen, NULL,
						    ownerAuth, NULL, &decLen, &dec))) {
		free(data);
		return result;
	}
	free(data);

	*MigrationKeyAuthSize = decLen;
	*MigrationKeyAuth = dec;

	return result;
}

#endif

