~ubuntu-branches/ubuntu/hardy/trousers/hardy-proposed

« back to all changes in this revision

Viewing changes to src/tcs/tcsem.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2008-01-23 22:03:00 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080123220300-fhtqja3c0oq0gp6z
Tags: 0.3.1-4
* Added patch from Aaron M. Ucko <ucko@debian.org> to allow trousers to
  build successfully on amd64, and presumably also other 64-bit
  architectures (Closes: #457400).
* Including udev rule for /dev/tpm from William Lima
  <wlima.amadeus@gmail.com> as suggested by David Smith <dds@google.com>
  (Closes: #459682).
* Added lintian overrides.

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 <stdlib.h>
13
 
#include <stdio.h>
14
 
#include <string.h>
15
 
#include <pthread.h>
16
 
#include <limits.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 "tcsd_wrap.h"
26
 
#include "tcsd.h"
27
 
#include "tcslog.h"
28
 
#include "tcsem.h"
29
 
 
30
 
 
31
 
TCS_CONTEXT_HANDLE InternalContext = 0x30000000;
32
 
 
33
 
struct event_log *tcs_event_log = NULL;
34
 
 
35
 
TSS_RESULT
36
 
event_log_init()
37
 
{
38
 
        if (tcs_event_log != NULL)
39
 
                return TSS_SUCCESS;
40
 
 
41
 
        tcs_event_log = calloc(1, sizeof(struct event_log));
42
 
        if (tcs_event_log == NULL) {
43
 
                LogError("malloc of %zd bytes failed.", sizeof(struct event_log));
44
 
                return TCSERR(TSS_E_OUTOFMEMORY);
45
 
        }
46
 
 
47
 
        pthread_mutex_init(&(tcs_event_log->lock), NULL);
48
 
 
49
 
        /* allocate as many event lists as there are PCR's */
50
 
        tcs_event_log->lists = calloc(tpm_metrics.num_pcrs, sizeof(struct event_wrapper *));
51
 
        if (tcs_event_log->lists == NULL) {
52
 
                LogError("malloc of %zd bytes failed.",
53
 
                                tpm_metrics.num_pcrs * sizeof(struct event_wrapper *));
54
 
                free(tcs_event_log);
55
 
                return TCSERR(TSS_E_OUTOFMEMORY);
56
 
        }
57
 
 
58
 
        /* assign external event log sources here */
59
 
        tcs_event_log->firmware_source = EVLOG_BIOS_SOURCE;
60
 
        tcs_event_log->kernel_source = EVLOG_BIOS_SOURCE;
61
 
 
62
 
        return TSS_SUCCESS;
63
 
}
64
 
 
65
 
TSS_RESULT
66
 
event_log_final()
67
 
{
68
 
        struct event_wrapper *cur, *next;
69
 
        UINT32 i;
70
 
 
71
 
        pthread_mutex_lock(&(tcs_event_log->lock));
72
 
 
73
 
        for (i = 0; i < tpm_metrics.num_pcrs; i++) {
74
 
                cur = tcs_event_log->lists[i];
75
 
                while (cur != NULL) {
76
 
                        next = cur->next;
77
 
                        free(cur->event.rgbPcrValue);
78
 
                        free(cur->event.rgbEvent);
79
 
                        free(cur);
80
 
                        cur = next;
81
 
                }
82
 
        }
83
 
 
84
 
        pthread_mutex_unlock(&(tcs_event_log->lock));
85
 
 
86
 
        free(tcs_event_log->lists);
87
 
        free(tcs_event_log);
88
 
 
89
 
        return TSS_SUCCESS;
90
 
}
91
 
 
92
 
TSS_RESULT
93
 
copy_pcr_event(TSS_PCR_EVENT *dest, TSS_PCR_EVENT *source)
94
 
{
95
 
        memcpy(dest, source, sizeof(TSS_PCR_EVENT));
96
 
        return TSS_SUCCESS;
97
 
}
98
 
 
99
 
TSS_RESULT
100
 
event_log_add(TSS_PCR_EVENT *event, UINT32 *pNumber)
101
 
{
102
 
        struct event_wrapper *new, *tmp;
103
 
        TSS_RESULT result;
104
 
        UINT32 i;
105
 
 
106
 
        pthread_mutex_lock(&(tcs_event_log->lock));
107
 
 
108
 
        new = calloc(1, sizeof(struct event_wrapper));
109
 
        if (new == NULL) {
110
 
                LogError("malloc of %zd bytes failed.", sizeof(struct event_wrapper));
111
 
                pthread_mutex_unlock(&(tcs_event_log->lock));
112
 
                return TCSERR(TSS_E_OUTOFMEMORY);
113
 
        }
114
 
 
115
 
        if ((result = copy_pcr_event(&(new->event), event))) {
116
 
                free(new);
117
 
                pthread_mutex_unlock(&(tcs_event_log->lock));
118
 
                return result;
119
 
        }
120
 
 
121
 
        /* go to the end of the list to add the element, so that they're in order */
122
 
        i = 0;
123
 
        if (tcs_event_log->lists[event->ulPcrIndex] == NULL) {
124
 
                tcs_event_log->lists[event->ulPcrIndex] = new;
125
 
        } else {
126
 
                i++;
127
 
                tmp = tcs_event_log->lists[event->ulPcrIndex];
128
 
                while (tmp->next != NULL) {
129
 
                        i++;
130
 
                        tmp = tmp->next;
131
 
                }
132
 
                tmp->next = new;
133
 
        }
134
 
 
135
 
        *pNumber = ++i;
136
 
 
137
 
        pthread_mutex_unlock(&(tcs_event_log->lock));
138
 
 
139
 
        return TSS_SUCCESS;
140
 
}
141
 
 
142
 
TSS_PCR_EVENT *
143
 
get_pcr_event(UINT32 pcrIndex, UINT32 eventNumber)
144
 
{
145
 
        struct event_wrapper *tmp;
146
 
        UINT32 counter = 0;
147
 
 
148
 
        pthread_mutex_lock(&(tcs_event_log->lock));
149
 
 
150
 
        tmp = tcs_event_log->lists[pcrIndex];
151
 
        for (; tmp; tmp = tmp->next) {
152
 
                if (counter == eventNumber) {
153
 
                        break;
154
 
                }
155
 
                counter++;
156
 
        }
157
 
 
158
 
        pthread_mutex_unlock(&(tcs_event_log->lock));
159
 
 
160
 
        return (tmp ? &(tmp->event) : NULL);
161
 
}
162
 
 
163
 
/* the lock should be held before calling this function */
164
 
UINT32
165
 
get_num_events(UINT32 pcrIndex)
166
 
{
167
 
        struct event_wrapper *tmp;
168
 
        UINT32 counter = 0;
169
 
 
170
 
        tmp = tcs_event_log->lists[pcrIndex];
171
 
        for (; tmp; tmp = tmp->next) {
172
 
                counter++;
173
 
        }
174
 
 
175
 
        return counter;
176
 
}
177
 
 
178
 
TSS_RESULT
179
 
TCS_LogPcrEvent_Internal(TCS_CONTEXT_HANDLE hContext,   /* in */
180
 
                         TSS_PCR_EVENT Event,           /* in */
181
 
                         UINT32 *pNumber)               /* out */
182
 
{
183
 
        TSS_RESULT result;
184
 
 
185
 
        if((result = ctx_verify_context(hContext)))
186
 
                return result;
187
 
 
188
 
        if(Event.ulPcrIndex >= tpm_metrics.num_pcrs)
189
 
                return TCSERR(TSS_E_BAD_PARAMETER);
190
 
 
191
 
        if (tcsd_options.kernel_pcrs & (1 << Event.ulPcrIndex)) {
192
 
                LogInfo("PCR %d is configured to be kernel controlled. Event logging denied.",
193
 
                                Event.ulPcrIndex);
194
 
                return TCSERR(TSS_E_FAIL);
195
 
        }
196
 
 
197
 
        if (tcsd_options.firmware_pcrs & (1 << Event.ulPcrIndex)) {
198
 
                LogInfo("PCR %d is configured to be firmware controlled. Event logging denied.",
199
 
                                Event.ulPcrIndex);
200
 
                return TCSERR(TSS_E_FAIL);
201
 
        }
202
 
 
203
 
        return event_log_add(&Event, pNumber);
204
 
}
205
 
 
206
 
/* This routine will handle creating the TSS_PCR_EVENT structures from log
207
 
 * data produced by an external source. The external source in mind here
208
 
 * is the log of PCR extends done by the kernel from beneath the TSS
209
 
 * (via direct calls to the device driver).
210
 
 */
211
 
TSS_RESULT
212
 
TCS_GetExternalPcrEvent(UINT32 PcrIndex,                /* in */
213
 
                        UINT32 *pNumber,                /* in, out */
214
 
                        TSS_PCR_EVENT **ppEvent)        /* out */
215
 
{
216
 
        int log_handle;
217
 
        char *source;
218
 
 
219
 
        if (tcsd_options.kernel_pcrs & (1 << PcrIndex)) {
220
 
                source = tcsd_options.kernel_log_file;
221
 
 
222
 
                if (tcs_event_log->kernel_source != NULL) {
223
 
                        if (tcs_event_log->kernel_source->open((void *)source, &log_handle))
224
 
                                return TCSERR(TSS_E_INTERNAL_ERROR);
225
 
 
226
 
                        if (tcs_event_log->kernel_source->get_entry(log_handle, PcrIndex,
227
 
                                                pNumber, ppEvent)) {
228
 
                                tcs_event_log->kernel_source->close(log_handle);
229
 
                                return TCSERR(TSS_E_INTERNAL_ERROR);
230
 
                        }
231
 
 
232
 
                        tcs_event_log->kernel_source->close(log_handle);
233
 
                } else {
234
 
                        LogError("No source for externel kernel events was compiled in, but "
235
 
                                        "the tcsd is configured to use one! (see %s)",
236
 
                                        TCSD_CONFIG_FILE);
237
 
                        return TCSERR(TSS_E_INTERNAL_ERROR);
238
 
                }
239
 
        } else if (tcsd_options.firmware_pcrs & (1 << PcrIndex)) {
240
 
                source = tcsd_options.firmware_log_file;
241
 
 
242
 
                if (tcs_event_log->firmware_source != NULL) {
243
 
                        if (tcs_event_log->firmware_source->open((void *)source, &log_handle))
244
 
                                return TCSERR(TSS_E_INTERNAL_ERROR);
245
 
 
246
 
                        if (tcs_event_log->firmware_source->get_entry(log_handle, PcrIndex,
247
 
                                                pNumber, ppEvent)) {
248
 
                                tcs_event_log->firmware_source->close(log_handle);
249
 
                                return TCSERR(TSS_E_INTERNAL_ERROR);
250
 
                        }
251
 
 
252
 
                        tcs_event_log->firmware_source->close(log_handle);
253
 
                } else {
254
 
                        LogError("No source for externel firmware events was compiled in, but "
255
 
                                        "the tcsd is configured to use one! (see %s)",
256
 
                                        TCSD_CONFIG_FILE);
257
 
                        return TCSERR(TSS_E_INTERNAL_ERROR);
258
 
                }
259
 
        } else {
260
 
                LogError("PCR index %d not flagged as kernel or firmware controlled.", PcrIndex);
261
 
                return TCSERR(TSS_E_INTERNAL_ERROR);
262
 
        }
263
 
 
264
 
        return TSS_SUCCESS;
265
 
}
266
 
 
267
 
TSS_RESULT
268
 
TCS_GetPcrEvent_Internal(TCS_CONTEXT_HANDLE hContext,   /* in */
269
 
                         UINT32 PcrIndex,               /* in */
270
 
                         UINT32 *pNumber,               /* in, out */
271
 
                         TSS_PCR_EVENT **ppEvent)       /* out */
272
 
{
273
 
        TSS_RESULT result;
274
 
        TSS_PCR_EVENT *event;
275
 
 
276
 
        if ((result = ctx_verify_context(hContext)))
277
 
                return result;
278
 
 
279
 
        if(PcrIndex >= tpm_metrics.num_pcrs)
280
 
                return TCSERR(TSS_E_BAD_PARAMETER);
281
 
 
282
 
        /* if this is a kernel or firmware controlled PCR, call an external routine */
283
 
        if ((tcsd_options.kernel_pcrs & (1 << PcrIndex)) ||
284
 
            (tcsd_options.firmware_pcrs & (1 << PcrIndex))) {
285
 
                pthread_mutex_lock(&(tcs_event_log->lock));
286
 
                result =  TCS_GetExternalPcrEvent(PcrIndex, pNumber, ppEvent);
287
 
                pthread_mutex_unlock(&(tcs_event_log->lock));
288
 
 
289
 
                return result;
290
 
        }
291
 
 
292
 
        if (ppEvent == NULL) {
293
 
                pthread_mutex_lock(&(tcs_event_log->lock));
294
 
 
295
 
                *pNumber = get_num_events(PcrIndex);
296
 
 
297
 
                pthread_mutex_unlock(&(tcs_event_log->lock));
298
 
        } else {
299
 
                *ppEvent = calloc(1, sizeof(TSS_PCR_EVENT));
300
 
                if (*ppEvent == NULL) {
301
 
                        LogError("malloc of %zd bytes failed.", sizeof(TSS_PCR_EVENT));
302
 
                        return TCSERR(TSS_E_OUTOFMEMORY);
303
 
                }
304
 
 
305
 
                event = get_pcr_event(PcrIndex, *pNumber);
306
 
                if (event == NULL) {
307
 
                        free(*ppEvent);
308
 
                        return TCSERR(TSS_E_BAD_PARAMETER);
309
 
                }
310
 
 
311
 
                if ((result = copy_pcr_event(*ppEvent, event))) {
312
 
                        free(*ppEvent);
313
 
                        return result;
314
 
                }
315
 
        }
316
 
 
317
 
        return TSS_SUCCESS;
318
 
}
319
 
 
320
 
/* This routine will handle creating the TSS_PCR_EVENT structures from log
321
 
 * data produced by an external source. The external source in mind here
322
 
 * is the log of PCR extends done by the kernel from beneath the TSS
323
 
 * (via direct calls to the device driver).
324
 
 */
325
 
TSS_RESULT
326
 
TCS_GetExternalPcrEventsByPcr(UINT32 PcrIndex,          /* in */
327
 
                                UINT32 FirstEvent,              /* in */
328
 
                                UINT32 *pEventCount,            /* in, out */
329
 
                                TSS_PCR_EVENT **ppEvents)       /* out */
330
 
{
331
 
        int log_handle;
332
 
        char *source;
333
 
 
334
 
        if (tcsd_options.kernel_pcrs & (1 << PcrIndex)) {
335
 
                source = tcsd_options.kernel_log_file;
336
 
 
337
 
                if (tcs_event_log->kernel_source != NULL) {
338
 
                        if (tcs_event_log->kernel_source->open((void *)source, &log_handle))
339
 
                                return TCSERR(TSS_E_INTERNAL_ERROR);
340
 
 
341
 
                        if (tcs_event_log->kernel_source->get_entries_by_pcr(log_handle, PcrIndex,
342
 
                                                FirstEvent, pEventCount, ppEvents)) {
343
 
                                tcs_event_log->kernel_source->close(log_handle);
344
 
                                return TCSERR(TSS_E_INTERNAL_ERROR);
345
 
                        }
346
 
 
347
 
                        tcs_event_log->kernel_source->close(log_handle);
348
 
                } else {
349
 
                        LogError("No source for externel kernel events was compiled in, but "
350
 
                                        "the tcsd is configured to use one! (see %s)",
351
 
                                        TCSD_CONFIG_FILE);
352
 
                        return TCSERR(TSS_E_INTERNAL_ERROR);
353
 
                }
354
 
        } else if (tcsd_options.firmware_pcrs & (1 << PcrIndex)) {
355
 
                source = tcsd_options.firmware_log_file;
356
 
 
357
 
                if (tcs_event_log->firmware_source != NULL) {
358
 
                        if (tcs_event_log->firmware_source->open((void *)source, &log_handle))
359
 
                                return TCSERR(TSS_E_INTERNAL_ERROR);
360
 
 
361
 
                        if (tcs_event_log->firmware_source->get_entries_by_pcr(log_handle, PcrIndex,
362
 
                                                FirstEvent, pEventCount, ppEvents)) {
363
 
                                tcs_event_log->firmware_source->close(log_handle);
364
 
                                return TCSERR(TSS_E_INTERNAL_ERROR);
365
 
                        }
366
 
 
367
 
                        tcs_event_log->firmware_source->close(log_handle);
368
 
                } else {
369
 
                        LogError("No source for externel firmware events was compiled in, but "
370
 
                                        "the tcsd is configured to use one! (see %s)",
371
 
                                        TCSD_CONFIG_FILE);
372
 
                        return TCSERR(TSS_E_INTERNAL_ERROR);
373
 
                }
374
 
        } else {
375
 
                LogError("PCR index %d not flagged as kernel or firmware controlled.", PcrIndex);
376
 
                return TCSERR(TSS_E_INTERNAL_ERROR);
377
 
        }
378
 
 
379
 
        return TSS_SUCCESS;
380
 
}
381
 
 
382
 
TSS_RESULT
383
 
TCS_GetPcrEventsByPcr_Internal(TCS_CONTEXT_HANDLE hContext,     /* in */
384
 
                                UINT32 PcrIndex,                /* in */
385
 
                                UINT32 FirstEvent,              /* in */
386
 
                                UINT32 *pEventCount,            /* in, out */
387
 
                                TSS_PCR_EVENT **ppEvents)       /* out */
388
 
{
389
 
        UINT32 lastEventNumber, i, eventIndex;
390
 
        TSS_RESULT result;
391
 
        struct event_wrapper *tmp;
392
 
 
393
 
        if ((result = ctx_verify_context(hContext)))
394
 
                return result;
395
 
 
396
 
        if (PcrIndex >= tpm_metrics.num_pcrs)
397
 
                return TCSERR(TSS_E_BAD_PARAMETER);
398
 
 
399
 
        /* if this is a kernel or firmware controlled PCR, call an external routine */
400
 
        if ((tcsd_options.kernel_pcrs & (1 << PcrIndex)) ||
401
 
            (tcsd_options.firmware_pcrs & (1 << PcrIndex))) {
402
 
                pthread_mutex_lock(&(tcs_event_log->lock));
403
 
                result = TCS_GetExternalPcrEventsByPcr(PcrIndex, FirstEvent,
404
 
                                                        pEventCount, ppEvents);
405
 
                pthread_mutex_unlock(&(tcs_event_log->lock));
406
 
 
407
 
                return result;
408
 
        }
409
 
 
410
 
        pthread_mutex_lock(&(tcs_event_log->lock));
411
 
 
412
 
        lastEventNumber = get_num_events(PcrIndex);
413
 
 
414
 
        pthread_mutex_unlock(&(tcs_event_log->lock));
415
 
 
416
 
        /* if pEventCount is larger than the number of events to return, just return less.
417
 
         * *pEventCount will be set to the number returned below.
418
 
         */
419
 
        lastEventNumber = MIN(lastEventNumber, FirstEvent + *pEventCount);
420
 
 
421
 
        if (FirstEvent > lastEventNumber)
422
 
                return TCSERR(TSS_E_BAD_PARAMETER);
423
 
 
424
 
        if (lastEventNumber == 0) {
425
 
                *pEventCount = 0;
426
 
                *ppEvents = NULL;
427
 
                return TSS_SUCCESS;
428
 
        }
429
 
 
430
 
        /* FirstEvent is 0 indexed see TSS 1.1b spec section 4.7.2.2.3. That means that
431
 
         * the following calculation is not off by one. :-)
432
 
         */
433
 
        *ppEvents = calloc((lastEventNumber - FirstEvent), sizeof(TSS_PCR_EVENT));
434
 
        if (*ppEvents == NULL) {
435
 
                LogError("malloc of %zd bytes failed.",
436
 
                                sizeof(TSS_PCR_EVENT) * (lastEventNumber - FirstEvent));
437
 
                return TCSERR(TSS_E_OUTOFMEMORY);
438
 
        }
439
 
 
440
 
        pthread_mutex_lock(&(tcs_event_log->lock));
441
 
 
442
 
        tmp = tcs_event_log->lists[PcrIndex];
443
 
 
444
 
        /* move through the list until we get to the first event requested */
445
 
        for (i = 0; i < FirstEvent; i++)
446
 
                tmp = tmp->next;
447
 
 
448
 
        /* copy events from the first requested to the last requested */
449
 
        for (eventIndex = 0; i < lastEventNumber; eventIndex++, i++) {
450
 
                copy_pcr_event(&((*ppEvents)[eventIndex]), &(tmp->event));
451
 
                tmp = tmp->next;
452
 
        }
453
 
 
454
 
        pthread_mutex_unlock(&(tcs_event_log->lock));
455
 
 
456
 
        *pEventCount = eventIndex;
457
 
 
458
 
        return TSS_SUCCESS;
459
 
}
460
 
 
461
 
TSS_PCR_EVENT *
462
 
concat_pcr_events(TSS_PCR_EVENT **list_so_far, UINT32 list_size, TSS_PCR_EVENT *addition,
463
 
                  UINT32 addition_size)
464
 
{
465
 
        TSS_PCR_EVENT *ret;
466
 
 
467
 
        ret = realloc(*list_so_far, (list_size + addition_size) * sizeof(TSS_PCR_EVENT));
468
 
        if (ret == NULL) {
469
 
                LogError("malloc of %zd bytes failed",
470
 
                         (list_size + addition_size) * sizeof(TSS_PCR_EVENT));
471
 
                return ret;
472
 
        }
473
 
 
474
 
        memcpy(&ret[list_size], addition, addition_size * sizeof(TSS_PCR_EVENT));
475
 
        return ret;
476
 
}
477
 
 
478
 
TSS_RESULT
479
 
TCS_GetPcrEventLog_Internal(TCS_CONTEXT_HANDLE hContext,/* in  */
480
 
                            UINT32 *pEventCount,        /* out */
481
 
                            TSS_PCR_EVENT **ppEvents)   /* out */
482
 
{
483
 
        TSS_RESULT result;
484
 
        UINT32 i, j, event_count, aggregate_count = 0;
485
 
        struct event_wrapper *tmp;
486
 
        TSS_PCR_EVENT *event_list = NULL, *aggregate_list = NULL;
487
 
 
488
 
        if ((result = ctx_verify_context(hContext)))
489
 
                return result;
490
 
 
491
 
        pthread_mutex_lock(&(tcs_event_log->lock));
492
 
 
493
 
        /* for each PCR index, if its externally controlled, get the total number of events
494
 
         * externally, else copy the events from the TCSD list. Then tack that list onto a
495
 
         * master list to returned. */
496
 
        for (i = 0; i < tpm_metrics.num_pcrs; i++) {
497
 
                if ((tcsd_options.kernel_pcrs & (1 << i)) ||
498
 
                    (tcsd_options.firmware_pcrs & (1 << i))) {
499
 
                        /* A kernel or firmware controlled PCR event list */
500
 
                        event_count = UINT_MAX;
501
 
                        if ((result = TCS_GetExternalPcrEventsByPcr(i, 0, &event_count,
502
 
                                                                    &event_list))) {
503
 
                                LogDebug("Getting External event list for PCR %u failed", i);
504
 
                                free(aggregate_list);
505
 
                                goto error;
506
 
                        }
507
 
                        LogDebug("Retrieved %u events from PCR %u (external)", event_count, i);
508
 
                } else {
509
 
                        /* A TCSD controlled PCR event list */
510
 
                        event_count = get_num_events(i);
511
 
 
512
 
                        if (event_count == 0)
513
 
                                continue;
514
 
 
515
 
                        if ((event_list = calloc(event_count, sizeof(TSS_PCR_EVENT))) == NULL) {
516
 
                                LogError("malloc of %zd bytes failed",
517
 
                                         event_count * sizeof(TSS_PCR_EVENT));
518
 
                                result = TCSERR(TSS_E_OUTOFMEMORY);
519
 
                                free(aggregate_list);
520
 
                                goto error;
521
 
                        }
522
 
 
523
 
                        tmp = tcs_event_log->lists[i];
524
 
                        for (j = 0; j < event_count; j++) {
525
 
                                copy_pcr_event(&event_list[j], &(tmp->event));
526
 
                                tmp = tmp->next;
527
 
                        }
528
 
                }
529
 
 
530
 
                if (event_count == 0)
531
 
                        continue;
532
 
 
533
 
                /* Tack the list onto the aggregate_list */
534
 
                aggregate_list = concat_pcr_events(&aggregate_list, aggregate_count, event_list,
535
 
                                                   event_count);
536
 
                if (aggregate_list == NULL) {
537
 
                        free(event_list);
538
 
                        result = TCSERR(TSS_E_OUTOFMEMORY);
539
 
                        goto error;
540
 
                }
541
 
                aggregate_count += event_count;
542
 
                free(event_list);
543
 
        }
544
 
 
545
 
        *ppEvents = aggregate_list;
546
 
        *pEventCount = aggregate_count;
547
 
        result = TSS_SUCCESS;
548
 
error:
549
 
        pthread_mutex_unlock(&(tcs_event_log->lock));
550
 
 
551
 
        return result;
552
 
}
553