1 /* Software-based Trusted Platform Module (TPM) Emulator
2 * Copyright (C) 2004-2010 Mario Strasser <mast@gmx.net>
3 *
4 * This module is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation; either version 2 of the License,
7 * or (at your option) any later version.
8 *
9 * This module is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * $Id: tpm_eviction.c 364 2010-02-11 10:24:45Z mast $
15 */
16
17 #include "tpm_emulator.h"
18 #include "tpm_commands.h"
19 #include "tpm_handles.h"
20 #include "tpm_data.h"
21 #include "crypto/rsa.h"
22
23 /*
24 * Eviction ([TPM_Part3], Section 22)
25 * The TPM has numerous resources held inside of the TPM that may need
26 * eviction. The need for eviction occurs when the number or resources
27 * in use by the TPM exceed the available space. In version 1.1 there were
28 * separate commands to evict separate resource types. This new command
29 * set uses the resource types defined for context saving and creates a
30 * generic command that will evict all resource types.
31 */
32
dump_sessions(void)33 static void dump_sessions(void)
34 {
35 int i;
36 for (i = 0; i < TPM_MAX_SESSIONS; i++) {
37 if (tpmData.stany.data.sessions[i].type != TPM_ST_INVALID) {
38 debug("session[%d] = %08x", i, INDEX_TO_AUTH_HANDLE(i));
39 }
40 }
41 }
42
TPM_FlushSpecific(TPM_HANDLE handle,TPM_RESOURCE_TYPE resourceType)43 TPM_RESULT TPM_FlushSpecific(TPM_HANDLE handle,
44 TPM_RESOURCE_TYPE resourceType)
45 {
46 TPM_SESSION_DATA *session;
47 TPM_DAA_SESSION_DATA *sessionDAA;
48 TPM_KEY_DATA *key;
49 int i;
50
51 info("TPM_FlushSpecific()");
52 debug("handle = %08x, resourceType = %08x", handle, resourceType);
53 switch (resourceType) {
54 case TPM_RT_CONTEXT:
55 for (i = 0; i < TPM_MAX_SESSION_LIST; i++)
56 if (tpmData.stany.data.contextList[i] == handle) break;
57 if (i != TPM_MAX_SESSION_LIST)
58 tpmData.stany.data.contextList[i] = 0;
59 return TPM_SUCCESS;
60
61 case TPM_RT_KEY:
62 key = tpm_get_key(handle);
63 if (key != NULL) {
64 if (key->keyControl & TPM_KEY_CONTROL_OWNER_EVICT)
65 return TPM_KEY_OWNER_CONTROL;
66 if (handle == TPM_KH_SRK) return TPM_FAIL;
67 tpm_rsa_release_private_key(&key->key);
68 memset(key, 0, sizeof(*key));
69 tpm_invalidate_sessions(handle);
70 }
71 return TPM_SUCCESS;
72
73 case TPM_RT_HASH:
74 case TPM_RT_COUNTER:
75 case TPM_RT_DELEGATE:
76 return TPM_INVALID_RESOURCE;
77
78 case TPM_RT_AUTH:
79 session = tpm_get_auth(handle);
80 if (session != NULL)
81 memset(session, 0, sizeof(*session));
82 dump_sessions();
83 return TPM_SUCCESS;
84
85 case TPM_RT_TRANS:
86 session = tpm_get_transport(handle);
87 if (session != NULL)
88 memset(session, 0, sizeof(*session));
89 dump_sessions();
90 return TPM_SUCCESS;
91
92 case TPM_RT_DAA_TPM:
93 sessionDAA = tpm_get_daa(handle);
94 if (sessionDAA != NULL) {
95 memset(sessionDAA, 0, sizeof(*sessionDAA));
96 if (handle == tpmData.stany.data.currentDAA)
97 tpmData.stany.data.currentDAA = 0;
98 tpm_invalidate_sessions(handle);
99 }
100 return TPM_SUCCESS;
101 }
102 return TPM_INVALID_RESOURCE;
103 }
104