blob: 5eca3f182f99fa8bf758e44379059060e8f5b018 [file] [log] [blame]
/* Software-based Trusted Platform Module (TPM) Emulator
* Copyright (C) 2004-2010 Mario Strasser <mast@gmx.net>
*
* This module is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* This module is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* $Id: tpm_eviction.c 364 2010-02-11 10:24:45Z mast $
*/
#include "tpm_emulator.h"
#include "tpm_commands.h"
#include "tpm_handles.h"
#include "tpm_data.h"
#include "crypto/rsa.h"
/*
* Eviction ([TPM_Part3], Section 22)
* The TPM has numerous resources held inside of the TPM that may need
* eviction. The need for eviction occurs when the number or resources
* in use by the TPM exceed the available space. In version 1.1 there were
* separate commands to evict separate resource types. This new command
* set uses the resource types defined for context saving and creates a
* generic command that will evict all resource types.
*/
static void dump_sessions(void)
{
int i;
for (i = 0; i < TPM_MAX_SESSIONS; i++) {
if (tpmData.stany.data.sessions[i].type != TPM_ST_INVALID) {
debug("session[%d] = %08x", i, INDEX_TO_AUTH_HANDLE(i));
}
}
}
TPM_RESULT TPM_FlushSpecific(TPM_HANDLE handle,
TPM_RESOURCE_TYPE resourceType)
{
TPM_SESSION_DATA *session;
TPM_DAA_SESSION_DATA *sessionDAA;
TPM_KEY_DATA *key;
int i;
info("TPM_FlushSpecific()");
debug("handle = %08x, resourceType = %08x", handle, resourceType);
switch (resourceType) {
case TPM_RT_CONTEXT:
for (i = 0; i < TPM_MAX_SESSION_LIST; i++)
if (tpmData.stany.data.contextList[i] == handle) break;
if (i != TPM_MAX_SESSION_LIST)
tpmData.stany.data.contextList[i] = 0;
return TPM_SUCCESS;
case TPM_RT_KEY:
key = tpm_get_key(handle);
if (key != NULL) {
if (key->keyControl & TPM_KEY_CONTROL_OWNER_EVICT)
return TPM_KEY_OWNER_CONTROL;
if (handle == TPM_KH_SRK) return TPM_FAIL;
tpm_rsa_release_private_key(&key->key);
memset(key, 0, sizeof(*key));
tpm_invalidate_sessions(handle);
}
return TPM_SUCCESS;
case TPM_RT_HASH:
case TPM_RT_COUNTER:
case TPM_RT_DELEGATE:
return TPM_INVALID_RESOURCE;
case TPM_RT_AUTH:
session = tpm_get_auth(handle);
if (session != NULL)
memset(session, 0, sizeof(*session));
dump_sessions();
return TPM_SUCCESS;
case TPM_RT_TRANS:
session = tpm_get_transport(handle);
if (session != NULL)
memset(session, 0, sizeof(*session));
dump_sessions();
return TPM_SUCCESS;
case TPM_RT_DAA_TPM:
sessionDAA = tpm_get_daa(handle);
if (sessionDAA != NULL) {
memset(sessionDAA, 0, sizeof(*sessionDAA));
if (handle == tpmData.stany.data.currentDAA)
tpmData.stany.data.currentDAA = 0;
tpm_invalidate_sessions(handle);
}
return TPM_SUCCESS;
}
return TPM_INVALID_RESOURCE;
}