// ===================================================================
//
// Copyright (c) 2005, Intel Corp.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Intel Corporation nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
// ===================================================================
//
// tcs.c
//
// This file contains the functions that implement a TCS.
//
// ==================================================================
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include "tcg.h"
#include "bsg.h"
#include "tcs.h"
#include "contextmgr.h"
#include "tpmddl.h"
#include "log.h"
#include "hashtable.h"
#include "hashtable_itr.h"
// Static Global Vars for the TCS
static int TCS_m_nCount = 0;
#define TCPA_MAX_BUFFER_LENGTH 0x2000
static BYTE InBuf [TCPA_MAX_BUFFER_LENGTH];
static BYTE OutBuf[TCPA_MAX_BUFFER_LENGTH];
struct hashtable *context_ht;
// -------------------------- Hash table functions --------------------
static unsigned int hashfunc32(void *ky) {
return (* (UINT32 *) ky);
}
static int equals32(void *k1, void *k2) {
return (*(UINT32 *) k1 == *(UINT32 *) k2);
}
CONTEXT_HANDLE *LookupContext( TCS_CONTEXT_HANDLE hContext) {
return( (CONTEXT_HANDLE *) hashtable_search(context_ht, &hContext) );
}
// ---------------------------------------------------------------------------------
// Initialization/Uninitialization SubComponent API
// ---------------------------------------------------------------------------------
TPM_RESULT TCS_create() {
TDDL_RESULT hRes = TDDL_E_FAIL;
TPM_RESULT result = TPM_FAIL;
if (TCS_m_nCount == 0) {
vtpmloginfo(VTPM_LOG_TCS, "Constructing new TCS:\n");
hRes = TDDL_Open();
context_ht = create_hashtable(10, hashfunc32, equals32);
if ((hRes == TDDL_SUCCESS) && (context_ht != NULL)) {
result = TPM_SUCCESS;
TCS_m_nCount++;
} else {
result = TPM_IOERROR;
hashtable_destroy(context_ht, 1);
}
} else
TCS_m_nCount++;
return(result);
}
void TCS_destroy()
{
TCS_m_nCount--;
if (TCS_m_nCount == 0) {
vtpmloginfo(VTPM_LOG_TCS, "Destructing TCS:\n");
TDDL_Close();
struct hashtable_itr *context_itr;
TCS_CONTEXT_HANDLE *hContext;
// Close all the TCS contexts. TCS should evict keys based on this
if (hashtable_count(context_ht) > 0) {
context_itr = hashtable_iterator(context_ht);
do {
hContext = (TCS_CONTEXT_HANDLE *) hashtable_iterator_key(context_itr);
if (TCS_CloseContext(*hContext) != TPM_SUCCESS)
vtpmlogerror(VTPM_LOG_TCS, "Failed to close context %d properly.\n", *hContext);
} while (hashtable_iterator_advance(context_itr));
free(context_itr);
}
hashtable_destroy(context_ht, 1);
}
}
TPM_RESULT TCS_Malloc( TCS_CONTEXT_HANDLE hContext, // in
UINT32 MemSize, // in
BYTE** ppMemPtr) {// out
TPM_RESULT returnCode = TPM_FAIL;
CONTEXT_HANDLE* pContextHandle = LookupContext(hContext);
if (pContextHandle != NULL && ppMemPtr != NULL) {
*ppMemPtr = (BYTE *)AddMemBlock(pContextHandle, MemSize);
returnCode = TPM_SUCCESS;
}
return returnCode;
}
TPM_RESULT TCS_FreeMemory( TCS_CONTEXT_HANDLE hContext, // in
BYTE* pMemory) { // in
TPM_RESULT returnCode = TPM_FAIL;
CONTEXT_HANDLE* pContextHandle = LookupContext(hContext);
if ( (pContextHandle != NULL && pMemory != NULL) &&
(DeleteMemBlock(pContextHandle, pMemory) == TRUE) )
returnCode = TPM_SUCCESS;
return returnCode;
}
TPM_RESULT TCS_OpenContext(TCS_CONTEXT_HANDLE* hContext) { // out
TPM_RESULT returnCode = TPM_FAIL;
TCS_CONTEXT_HANDLE *newContext;
vtpmloginfo(VTPM_LOG_TCS, "Calling TCS_OpenContext:\n");
if (hContext) {
CONTEXT_HANDLE* pContextHandle = (CONTEXT_HANDLE *) malloc(sizeof(CONTEXT_HANDLE));
if (pContextHandle == NULL)
return TPM_SIZE;
// initialize to 0
pContextHandle->nBlockCount = 0;
pContextHandle->pTopBlock = NULL;
pContextHandle->pHandleList = NULL;
// Create New Block
AddMemBlock(pContextHandle, BLOCK_SIZE);
newContext = (TCS_CONTEXT_HANDLE *) malloc(sizeof(TCS_CONTEXT_HANDLE));
*newContext = (TCS_CONTEXT_HANDLE) (((uintptr_t) pContextHandle >> 2) & 0xffffffff);