
/*
 * 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 "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.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()
{
	int i;

	/* wake up any sleeping threads, so they can be joined */
	for (i = 0; i < TSS_DEFAULT_OVERFLOW_AUTHS; 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;
	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;
			}
		}
	}

	return TSS_SUCCESS;
}

/* 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 %zd, 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) % TSS_DEFAULT_OVERFLOW_AUTHS;
	} 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");
		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) % TSS_DEFAULT_OVERFLOW_AUTHS;
		/* go to sleep */
		LogDebug("thread %zd 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 mgr queue is full! There are currently %d "
				"TCS sessions waiting on an auth session!",
				TSS_DEFAULT_OVERFLOW_AUTHS);
		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) {
			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);
			}
			auth_mgr.open_auth_sessions--;
			auth_mgr.auth_mapper[i].full = FALSE;
			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) {
				/* Only termininate when still in use */
				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);
				}
			}
			auth_mgr.open_auth_sessions--;
			auth_mgr.auth_mapper[i].full = FALSE;
			LogDebug("released auth for TCS %x TPM %x",
				 auth_mgr.auth_mapper[i].tcs_ctx, tpm_auth_handle);
			auth_mgr_swap_in();
		}
	}

	return result;
}

TSS_RESULT
auth_mgr_check(TCS_CONTEXT_HANDLE tcsContext, TPM_AUTHHANDLE *tpm_auth_handle)
{
	UINT32 i;
	TSS_RESULT result = TCSERR(TSS_E_INTERNAL_ERROR);

	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) {
			result = TSS_SUCCESS;
			/* We have a record of this session, now swap it into the TPM if need be. */
			if (auth_mgr.auth_mapper[i].swap) {
				LogDebug("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);
				free(auth_mgr.auth_mapper[i].swap);
				auth_mgr.auth_mapper[i].swap = NULL;
				auth_mgr.auth_mapper[i].swap_size = 0;

				if (result == TSS_SUCCESS) {
					LogDebug("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 {
					LogDebug("TPM_LoadAuthContext failed: 0x%x.", result);
				}
			}

			break;
		}
	}

	if (result == TCSERR(TSS_E_INTERNAL_ERROR)) {
		LogDebug("no auth in table for TCS handle 0x%x", tcsContext);
	}
	return result;
}

TSS_RESULT
auth_mgr_add(TCS_CONTEXT_HANDLE tcsContext, TCS_AUTHHANDLE tpm_auth_handle)
{
	TSS_RESULT result = TCSERR(TSS_E_INTERNAL_ERROR);
	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;
			result = TSS_SUCCESS;
			auth_mgr.open_auth_sessions++;
			LogDebug("added auth for TCS %x TPM %x", tcsContext, tpm_auth_handle);
			break;
		}
	}

	if (result == TCSERR(TSS_E_INTERNAL_ERROR)) {
		struct auth_map *tmp = auth_mgr.auth_mapper;

		LogDebugFn("Thread %zd 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;
			result = 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;
			result = TSS_SUCCESS;
			LogDebugFn("Success.");
		}
	}

	return result;
}

/* 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;
}

