~ubuntu-branches/ubuntu/gutsy/trousers/gutsy

« back to all changes in this revision

Viewing changes to src/tcs/cxt.c

  • Committer: Bazaar Package Importer
  • Author(s): William Lima
  • Date: 2007-04-18 16:39:38 UTC
  • Revision ID: james.westby@ubuntu.com-20070418163938-opscl2mvvi76jiec
Tags: upstream-0.2.9.1
ImportĀ upstreamĀ versionĀ 0.2.9.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/*
 
3
 * Licensed Materials - Property of IBM
 
4
 *
 
5
 * trousers - An open source TCG Software Stack
 
6
 *
 
7
 * (C) Copyright International Business Machines Corp. 2004
 
8
 *
 
9
 */
 
10
 
 
11
 
 
12
#include <time.h>
 
13
#include <stdio.h>
 
14
#include <string.h>
 
15
#include <stdlib.h>
 
16
#include <pthread.h>
 
17
 
 
18
#include "trousers/tss.h"
 
19
#include "spi_internal_types.h"
 
20
#include "tcs_internal_types.h"
 
21
#include "tcs_tsp.h"
 
22
#include "tcs_utils.h"
 
23
#include "tcs_int_literals.h"
 
24
#include "capabilities.h"
 
25
#include "tcslog.h"
 
26
 
 
27
 
 
28
unsigned long nextContextHandle = 0xA0000000;
 
29
struct tcs_context *tcs_context_table = NULL;
 
30
 
 
31
pthread_mutex_t tcs_ctx_lock = PTHREAD_MUTEX_INITIALIZER;
 
32
 
 
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);
 
40
 
 
41
/*=========================================================================== */
 
42
TSS_BOOL initContextHandle = 1;
 
43
 
 
44
TCS_CONTEXT_HANDLE
 
45
getNextHandle()
 
46
{
 
47
        UINT32 tempRand;
 
48
        time_t currentTime;
 
49
 
 
50
        if (initContextHandle) {
 
51
                currentTime = time(NULL);
 
52
                srand(currentTime);
 
53
                tempRand = rand();
 
54
                tempRand = tempRand << 16;
 
55
                tempRand &= 0x00FF0000;
 
56
                nextContextHandle |= tempRand;
 
57
                initContextHandle = 0;
 
58
        }
 
59
        currentTime = time(NULL);
 
60
        srand(currentTime + 1);
 
61
        tempRand = rand();
 
62
/*      srandom( currentTime + 1 ); */
 
63
/*      tempRand = random(); */
 
64
        tempRand = tempRand << 8;
 
65
        tempRand &= 0x0000FF00;
 
66
        if (nextContextHandle == 0)
 
67
                return getNextHandle();
 
68
/*              nextContextHandle++; */
 
69
        else
 
70
                return ((nextContextHandle++) | tempRand);
 
71
}
 
72
 
 
73
struct tcs_context *
 
74
create_tcs_context()
 
75
{
 
76
        struct tcs_context *ret = (struct tcs_context *)calloc(1, sizeof(struct tcs_context));
 
77
 
 
78
        if (ret != NULL) {
 
79
                ret->handle = getNextHandle();
 
80
                if (tpm_metrics.authctx_swap) {
 
81
                        ret->u_auth.blob = NULL;
 
82
                } else {
 
83
                        pthread_cond_init(&(ret->u_auth.cond), NULL);
 
84
                }
 
85
        }
 
86
        return ret;
 
87
}
 
88
 
 
89
struct tcs_context *
 
90
get_context(TCS_CONTEXT_HANDLE handle)
 
91
{
 
92
        struct tcs_context *index;
 
93
        index = tcs_context_table;
 
94
        while (index) {
 
95
                if (index->handle == handle)
 
96
                        break;
 
97
                index = index->next;
 
98
        }
 
99
 
 
100
        return index;
 
101
}
 
102
 
 
103
struct tcs_context *
 
104
get_previous_context(TCS_CONTEXT_HANDLE handle)
 
105
{
 
106
        struct tcs_context *index;
 
107
        index = tcs_context_table;
 
108
        while (index) {
 
109
                if (index->next) {
 
110
                        if (index->next->handle == handle)
 
111
                                return index;
 
112
                }
 
113
                index = index->next;
 
114
        }
 
115
 
 
116
        return 0;
 
117
}
 
118
 
 
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.
 
121
 */
 
122
void
 
123
ctx_ref_count_keys(struct tcs_context *c)
 
124
{
 
125
        struct keys_loaded *cur, *prev;
 
126
 
 
127
        if (c == NULL)
 
128
                return;
 
129
 
 
130
        cur = prev = c->keys;
 
131
 
 
132
        while (cur != NULL) {
 
133
                key_mgr_dec_ref_count(cur->key_handle);
 
134
                cur = cur->next;
 
135
                free(prev);
 
136
                prev = cur;
 
137
        }
 
138
}
 
139
 
 
140
void
 
141
destroy_context(TCS_CONTEXT_HANDLE handle)
 
142
{
 
143
        struct tcs_context *toKill;
 
144
        struct tcs_context *previous;
 
145
 
 
146
        pthread_mutex_lock(&tcs_ctx_lock);
 
147
 
 
148
        toKill = get_context(handle);
 
149
        previous = get_previous_context(handle);
 
150
 
 
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;
 
155
        } else {
 
156
                pthread_mutex_unlock(&tcs_ctx_lock);
 
157
                return;
 
158
        }
 
159
 
 
160
        pthread_mutex_unlock(&tcs_ctx_lock);
 
161
 
 
162
        ctx_ref_count_keys(toKill);
 
163
        free(toKill);
 
164
}
 
165
 
 
166
TCS_CONTEXT_HANDLE
 
167
make_context()
 
168
{
 
169
        struct tcs_context *index;
 
170
 
 
171
        pthread_mutex_lock(&tcs_ctx_lock);
 
172
 
 
173
        index = tcs_context_table;
 
174
 
 
175
        if (!index) {
 
176
                tcs_context_table = create_tcs_context();
 
177
                if (tcs_context_table == NULL) {
 
178
                        LogError("Malloc Failure.");
 
179
                        pthread_mutex_unlock(&tcs_ctx_lock);
 
180
                        return 0;
 
181
                }
 
182
                index = tcs_context_table;
 
183
        } else {
 
184
                while (index->next) {
 
185
                        index = index->next;
 
186
                }
 
187
                index->next = create_tcs_context();
 
188
                if (index->next == NULL) {
 
189
                        LogError("Malloc Failure.");
 
190
                        pthread_mutex_unlock(&tcs_ctx_lock);
 
191
                        return 0;
 
192
                }
 
193
                index = index->next;
 
194
        }
 
195
 
 
196
        pthread_mutex_unlock(&tcs_ctx_lock);
 
197
 
 
198
        return index->handle;
 
199
}
 
200
 
 
201
 
 
202
TCPA_RESULT
 
203
ctx_verify_context(TCS_CONTEXT_HANDLE tcsContext)
 
204
{
 
205
        struct tcs_context *c;
 
206
 
 
207
        if (tcsContext == InternalContext) {
 
208
                LogDebug("Success: %.8X is an Internal Context", tcsContext);
 
209
                return TSS_SUCCESS;
 
210
        }
 
211
 
 
212
        pthread_mutex_lock(&tcs_ctx_lock);
 
213
 
 
214
        c = get_context(tcsContext);
 
215
 
 
216
        pthread_mutex_unlock(&tcs_ctx_lock);
 
217
 
 
218
        if (c == NULL) {
 
219
                LogDebug("Fail: Context %.8X not found", tcsContext);
 
220
                return TCSERR(TCS_E_INVALID_CONTEXTHANDLE);
 
221
        }
 
222
 
 
223
        return TSS_SUCCESS;
 
224
}
 
225
 
 
226
 
 
227
pthread_cond_t *
 
228
ctx_get_cond_var(TCS_CONTEXT_HANDLE tcs_handle)
 
229
{
 
230
        struct tcs_context *c;
 
231
        pthread_cond_t *ret = NULL;
 
232
 
 
233
        pthread_mutex_lock(&tcs_ctx_lock);
 
234
 
 
235
        c = get_context(tcs_handle);
 
236
 
 
237
        if (c != NULL)
 
238
                ret = &(c->u_auth.cond);
 
239
 
 
240
        pthread_mutex_unlock(&tcs_ctx_lock);
 
241
 
 
242
        return ret;
 
243
}
 
244
 
 
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.
 
247
 */
 
248
TSS_RESULT
 
249
ctx_mark_key_loaded(TCS_CONTEXT_HANDLE ctx_handle,
 
250
                   TCS_KEY_HANDLE key_handle)
 
251
{
 
252
        struct tcs_context *c;
 
253
        struct keys_loaded *k = NULL, *new;
 
254
        TSS_RESULT result = TCSERR(TSS_E_FAIL);
 
255
 
 
256
        pthread_mutex_lock(&tcs_ctx_lock);
 
257
 
 
258
        c = get_context(ctx_handle);
 
259
 
 
260
        if (c != NULL) {
 
261
                k = c->keys;
 
262
                while (k != NULL) {
 
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.
 
267
                                 */
 
268
                                result = TSS_SUCCESS;
 
269
                                break;
 
270
                        }
 
271
 
 
272
                        k = k->next;
 
273
                }
 
274
        } else {
 
275
                pthread_mutex_unlock(&tcs_ctx_lock);
 
276
                return result;
 
277
        }
 
278
 
 
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.
 
281
         */
 
282
        if (k == NULL) {
 
283
                new = calloc(1, sizeof(struct keys_loaded));
 
284
                if (new == NULL) {
 
285
                        LogError("malloc of %zd bytes failed.", sizeof(struct keys_loaded));
 
286
                        pthread_mutex_unlock(&tcs_ctx_lock);
 
287
                        return TCSERR(TSS_E_OUTOFMEMORY);
 
288
                }
 
289
 
 
290
                new->key_handle = key_handle;
 
291
                new->next = c->keys;
 
292
                c->keys = new;
 
293
                result = key_mgr_inc_ref_count(new->key_handle);
 
294
        }
 
295
 
 
296
        pthread_mutex_unlock(&tcs_ctx_lock);
 
297
 
 
298
        return result;
 
299
}
 
300