Home | History | Annotate | Line # | Download | only in tcs
      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 <limits.h>
     16 
     17 #include "trousers/tss.h"
     18 #include "trousers_types.h"
     19 #include "tcs_tsp.h"
     20 #include "tcs_utils.h"
     21 #include "tcs_int_literals.h"
     22 #include "capabilities.h"
     23 #include "tcsd_wrap.h"
     24 #include "tcsd.h"
     25 #include "tcslog.h"
     26 #include "tcsem.h"
     27 
     28 
     29 struct event_log *tcs_event_log = NULL;
     30 
     31 TSS_RESULT
     32 event_log_init()
     33 {
     34 	if (tcs_event_log != NULL)
     35 		return TSS_SUCCESS;
     36 
     37 	tcs_event_log = calloc(1, sizeof(struct event_log));
     38 	if (tcs_event_log == NULL) {
     39 		LogError("malloc of %zd bytes failed.", sizeof(struct event_log));
     40 		return TCSERR(TSS_E_OUTOFMEMORY);
     41 	}
     42 
     43 	MUTEX_INIT(tcs_event_log->lock);
     44 
     45 	/* allocate as many event lists as there are PCR's */
     46 	tcs_event_log->lists = calloc(tpm_metrics.num_pcrs, sizeof(struct event_wrapper *));
     47 	if (tcs_event_log->lists == NULL) {
     48 		LogError("malloc of %zd bytes failed.",
     49 				tpm_metrics.num_pcrs * sizeof(struct event_wrapper *));
     50 		free(tcs_event_log);
     51 		return TCSERR(TSS_E_OUTOFMEMORY);
     52 	}
     53 
     54 	/* assign external event log sources here */
     55 	//tcs_event_log->firmware_source = EVLOG_IMA_SOURCE;
     56 	tcs_event_log->firmware_source = EVLOG_BIOS_SOURCE;
     57 	tcs_event_log->kernel_source = EVLOG_IMA_SOURCE;
     58 
     59 	return TSS_SUCCESS;
     60 }
     61 
     62 TSS_RESULT
     63 event_log_final()
     64 {
     65 	struct event_wrapper *cur, *next;
     66 	UINT32 i;
     67 
     68 	MUTEX_LOCK(tcs_event_log->lock);
     69 
     70 	for (i = 0; i < tpm_metrics.num_pcrs; i++) {
     71 		cur = tcs_event_log->lists[i];
     72 		while (cur != NULL) {
     73 			next = cur->next;
     74 			free(cur->event.rgbPcrValue);
     75 			free(cur->event.rgbEvent);
     76 			free(cur);
     77 			cur = next;
     78 		}
     79 	}
     80 
     81 	MUTEX_UNLOCK(tcs_event_log->lock);
     82 
     83 	free(tcs_event_log->lists);
     84 	free(tcs_event_log);
     85 
     86 	return TSS_SUCCESS;
     87 }
     88 
     89 TSS_RESULT
     90 copy_pcr_event(TSS_PCR_EVENT *dest, TSS_PCR_EVENT *source)
     91 {
     92 	memcpy(dest, source, sizeof(TSS_PCR_EVENT));
     93 	return TSS_SUCCESS;
     94 }
     95 
     96 TSS_RESULT
     97 event_log_add(TSS_PCR_EVENT *event, UINT32 *pNumber)
     98 {
     99 	struct event_wrapper *new, *tmp;
    100 	TSS_RESULT result;
    101 	UINT32 i;
    102 
    103 	MUTEX_LOCK(tcs_event_log->lock);
    104 
    105 	new = calloc(1, sizeof(struct event_wrapper));
    106 	if (new == NULL) {
    107 		LogError("malloc of %zd bytes failed.", sizeof(struct event_wrapper));
    108 		MUTEX_UNLOCK(tcs_event_log->lock);
    109 		return TCSERR(TSS_E_OUTOFMEMORY);
    110 	}
    111 
    112 	if ((result = copy_pcr_event(&(new->event), event))) {
    113 		free(new);
    114 		MUTEX_UNLOCK(tcs_event_log->lock);
    115 		return result;
    116 	}
    117 
    118 	/* go to the end of the list to add the element, so that they're in order */
    119 	i = 0;
    120 	if (tcs_event_log->lists[event->ulPcrIndex] == NULL) {
    121 		tcs_event_log->lists[event->ulPcrIndex] = new;
    122 	} else {
    123 		i++;
    124 		tmp = tcs_event_log->lists[event->ulPcrIndex];
    125 		while (tmp->next != NULL) {
    126 			i++;
    127 			tmp = tmp->next;
    128 		}
    129 		tmp->next = new;
    130 	}
    131 
    132 	*pNumber = ++i;
    133 
    134 	MUTEX_UNLOCK(tcs_event_log->lock);
    135 
    136 	return TSS_SUCCESS;
    137 }
    138 
    139 TSS_PCR_EVENT *
    140 get_pcr_event(UINT32 pcrIndex, UINT32 eventNumber)
    141 {
    142 	struct event_wrapper *tmp;
    143 	UINT32 counter = 0;
    144 
    145 	MUTEX_LOCK(tcs_event_log->lock);
    146 
    147 	tmp = tcs_event_log->lists[pcrIndex];
    148 	for (; tmp; tmp = tmp->next) {
    149 		if (counter == eventNumber) {
    150 			break;
    151 		}
    152 		counter++;
    153 	}
    154 
    155 	MUTEX_UNLOCK(tcs_event_log->lock);
    156 
    157 	return (tmp ? &(tmp->event) : NULL);
    158 }
    159 
    160 /* the lock should be held before calling this function */
    161 UINT32
    162 get_num_events(UINT32 pcrIndex)
    163 {
    164 	struct event_wrapper *tmp;
    165 	UINT32 counter = 0;
    166 
    167 	tmp = tcs_event_log->lists[pcrIndex];
    168 	for (; tmp; tmp = tmp->next) {
    169 		counter++;
    170 	}
    171 
    172 	return counter;
    173 }
    174 
    175 TSS_PCR_EVENT *
    176 concat_pcr_events(TSS_PCR_EVENT **list_so_far, UINT32 list_size, TSS_PCR_EVENT *addition,
    177 		  UINT32 addition_size)
    178 {
    179 	TSS_PCR_EVENT *ret;
    180 
    181 	ret = realloc(*list_so_far, (list_size + addition_size) * sizeof(TSS_PCR_EVENT));
    182 	if (ret == NULL) {
    183 		LogError("malloc of %zd bytes failed",
    184 			 (list_size + addition_size) * sizeof(TSS_PCR_EVENT));
    185 		return ret;
    186 	}
    187 
    188 	memcpy(&ret[list_size], addition, addition_size * sizeof(TSS_PCR_EVENT));
    189 	return ret;
    190 }
    191 
    192 /* XXX make this a macro */
    193 UINT32
    194 get_pcr_event_size(TSS_PCR_EVENT *e)
    195 {
    196 	return (sizeof(TSS_PCR_EVENT) + e->ulEventLength + e->ulPcrValueLength);
    197 }
    198 
    199 void
    200 free_external_events(UINT32 eventCount, TSS_PCR_EVENT *ppEvents)
    201 {
    202 	UINT32 j;
    203 
    204 	if (!ppEvents)
    205 		return;
    206 
    207 	for (j = 0; j < eventCount; j++) {
    208 		/* This is a fairly heinous hack, but PCR event logs can get really large
    209 		 * and without it, there is a real potential to exhaust memory by leaks.
    210 		 * The PCR event logs that we pull out of securityfs have had their
    211 		 * rgbPcrValue and rgbEvent pointers malloc'd dynamically as the
    212 		 * securityfs log was parsed. The other event log lists that are
    213 		 * maintained by the TCSD don't need to have this data free'd, since that
    214 		 * will happen at shutdown time only. So, for each PCR index that's
    215 		 * read from securityfs, we need to free its pointers after that data has
    216 		 * been set in the packet to send back to the TSP. */
    217 		if ((tcsd_options.kernel_pcrs & (1 << ppEvents[j].ulPcrIndex)) ||
    218 		    (tcsd_options.firmware_pcrs & (1 << ppEvents[j].ulPcrIndex))) {
    219 			free(ppEvents[j].rgbPcrValue);
    220 			free(ppEvents[j].rgbEvent);
    221 		}
    222 	}
    223 }
    224