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