3
* Licensed Materials - Property of IBM
5
* trousers - An open source TCG Software Stack
7
* (C) Copyright International Business Machines Corp. 2004
18
#include "trousers/tss.h"
19
#include "spi_internal_types.h"
20
#include "tcs_internal_types.h"
22
#include "tcs_utils.h"
23
#include "tcs_int_literals.h"
24
#include "capabilities.h"
28
unsigned long nextContextHandle = 0xA0000000;
29
struct tcs_context *tcs_context_table = NULL;
31
pthread_mutex_t tcs_ctx_lock = PTHREAD_MUTEX_INITIALIZER;
33
/*================================================================= */
34
/*================================================================= */
35
/* Proto's for just this file */
36
TCS_CONTEXT_HANDLE getNextHandle();
37
struct tcs_context *create_tcs_context();
38
struct tcs_context *get_context(TCS_CONTEXT_HANDLE);
39
struct tcs_context *get_previous_context(TCS_CONTEXT_HANDLE);
41
/*=========================================================================== */
42
TSS_BOOL initContextHandle = 1;
50
if (initContextHandle) {
51
currentTime = time(NULL);
54
tempRand = tempRand << 16;
55
tempRand &= 0x00FF0000;
56
nextContextHandle |= tempRand;
57
initContextHandle = 0;
59
currentTime = time(NULL);
60
srand(currentTime + 1);
62
/* srandom( currentTime + 1 ); */
63
/* tempRand = random(); */
64
tempRand = tempRand << 8;
65
tempRand &= 0x0000FF00;
66
if (nextContextHandle == 0)
67
return getNextHandle();
68
/* nextContextHandle++; */
70
return ((nextContextHandle++) | tempRand);
76
struct tcs_context *ret = (struct tcs_context *)calloc(1, sizeof(struct tcs_context));
79
ret->handle = getNextHandle();
80
if (tpm_metrics.authctx_swap) {
81
ret->u_auth.blob = NULL;
83
pthread_cond_init(&(ret->u_auth.cond), NULL);
90
get_context(TCS_CONTEXT_HANDLE handle)
92
struct tcs_context *index;
93
index = tcs_context_table;
95
if (index->handle == handle)
104
get_previous_context(TCS_CONTEXT_HANDLE handle)
106
struct tcs_context *index;
107
index = tcs_context_table;
110
if (index->next->handle == handle)
119
/* runs through the list of all keys loaded by context c and decrements
120
* their ref count by 1, then free's their structures.
123
ctx_ref_count_keys(struct tcs_context *c)
125
struct keys_loaded *cur, *prev;
130
cur = prev = c->keys;
132
while (cur != NULL) {
133
key_mgr_dec_ref_count(cur->key_handle);
141
destroy_context(TCS_CONTEXT_HANDLE handle)
143
struct tcs_context *toKill;
144
struct tcs_context *previous;
146
pthread_mutex_lock(&tcs_ctx_lock);
148
toKill = get_context(handle);
149
previous = get_previous_context(handle);
151
if (!previous && tcs_context_table->handle == handle) { /*this means that toKill is the first one */
152
tcs_context_table = tcs_context_table->next;
153
} else if (previous && toKill) { /*both are found */
154
previous->next = toKill->next;
156
pthread_mutex_unlock(&tcs_ctx_lock);
160
pthread_mutex_unlock(&tcs_ctx_lock);
162
ctx_ref_count_keys(toKill);
169
struct tcs_context *index;
171
pthread_mutex_lock(&tcs_ctx_lock);
173
index = tcs_context_table;
176
tcs_context_table = create_tcs_context();
177
if (tcs_context_table == NULL) {
178
LogError("Malloc Failure.");
179
pthread_mutex_unlock(&tcs_ctx_lock);
182
index = tcs_context_table;
184
while (index->next) {
187
index->next = create_tcs_context();
188
if (index->next == NULL) {
189
LogError("Malloc Failure.");
190
pthread_mutex_unlock(&tcs_ctx_lock);
196
pthread_mutex_unlock(&tcs_ctx_lock);
198
return index->handle;
203
ctx_verify_context(TCS_CONTEXT_HANDLE tcsContext)
205
struct tcs_context *c;
207
if (tcsContext == InternalContext) {
208
LogDebug("Success: %.8X is an Internal Context", tcsContext);
212
pthread_mutex_lock(&tcs_ctx_lock);
214
c = get_context(tcsContext);
216
pthread_mutex_unlock(&tcs_ctx_lock);
219
LogDebug("Fail: Context %.8X not found", tcsContext);
220
return TCSERR(TCS_E_INVALID_CONTEXTHANDLE);
228
ctx_get_cond_var(TCS_CONTEXT_HANDLE tcs_handle)
230
struct tcs_context *c;
231
pthread_cond_t *ret = NULL;
233
pthread_mutex_lock(&tcs_ctx_lock);
235
c = get_context(tcs_handle);
238
ret = &(c->u_auth.cond);
240
pthread_mutex_unlock(&tcs_ctx_lock);
245
/* make a new entry in the per-context list of loaded keys. If the list already
246
* contains a pointer to the key in memory, just return success.
249
ctx_mark_key_loaded(TCS_CONTEXT_HANDLE ctx_handle,
250
TCS_KEY_HANDLE key_handle)
252
struct tcs_context *c;
253
struct keys_loaded *k = NULL, *new;
254
TSS_RESULT result = TCSERR(TSS_E_FAIL);
256
pthread_mutex_lock(&tcs_ctx_lock);
258
c = get_context(ctx_handle);
263
if (k->key_handle == key_handle) {
264
/* we've previously created a pointer to key_handle in the global
265
* list of loaded keys and incremented that key's reference count,
266
* so there's no need to do anything.
268
result = TSS_SUCCESS;
275
pthread_mutex_unlock(&tcs_ctx_lock);
279
/* if we have no record of this key being loaded by this context, create a new
280
* entry and increment the key's reference count in the global list.
283
new = calloc(1, sizeof(struct keys_loaded));
285
LogError("malloc of %zd bytes failed.", sizeof(struct keys_loaded));
286
pthread_mutex_unlock(&tcs_ctx_lock);
287
return TCSERR(TSS_E_OUTOFMEMORY);
290
new->key_handle = key_handle;
293
result = key_mgr_inc_ref_count(new->key_handle);
296
pthread_mutex_unlock(&tcs_ctx_lock);