~ubuntu-branches/ubuntu/precise/trousers/precise-proposed

« back to all changes in this revision

Viewing changes to src/tcs/tcsem.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 <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