summaryrefslogtreecommitdiff
path: root/src/tcs/tcs_evlog_imaem.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tcs/tcs_evlog_imaem.c')
-rw-r--r--src/tcs/tcs_evlog_imaem.c352
1 files changed, 352 insertions, 0 deletions
diff --git a/src/tcs/tcs_evlog_imaem.c b/src/tcs/tcs_evlog_imaem.c
new file mode 100644
index 0000000..fbdd29a
--- /dev/null
+++ b/src/tcs/tcs_evlog_imaem.c
@@ -0,0 +1,352 @@
+
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2004-2006
+ *
+ */
+
+/*
+ * imaem.c
+ *
+ * Routines for handling PCR events from the Integrity Measurement
+ * Architecture.
+ *
+ * The external event source format used by IMA:
+ *
+ * 4 bytes PCR Index (bin)
+ * 20 bytes SHA1 template (bin)
+ * 4 bytes template name_len
+ * 1-255 bytes template name
+ * 20 bytes SHA1 IMA(bin)
+ * 4 bytes IMA name len
+ * 1-255 bytes eventname
+ * 1 byte separator = '\0'
+ *
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <limits.h>
+#include <unistd.h>
+
+#include "trousers/tss.h"
+#include "trousers_types.h"
+#include "tcs_tsp.h"
+#include "tcs_utils.h"
+#include "tcs_int_literals.h"
+#include "capabilities.h"
+#include "tcsps.h"
+#include "tcslog.h"
+#include "tcsem.h"
+
+#ifdef EVLOG_SOURCE_IMA
+
+struct ext_log_source ima_source = {
+ ima_open,
+ ima_get_entries_by_pcr,
+ ima_get_entry,
+ ima_close
+};
+
+int
+ima_open(void *source, FILE **handle)
+{
+ FILE *fd;
+
+ if ((fd = fopen((char *)source, "r")) == NULL) {
+ LogError("Error opening PCR log file %s: %s",
+ (char *)source, strerror(errno));
+ return -1;
+ }
+
+ *handle = fd;
+ return 0;
+}
+
+TSS_RESULT
+ima_get_entries_by_pcr(FILE *handle, UINT32 pcr_index, UINT32 first,
+ UINT32 *count, TSS_PCR_EVENT **events)
+{
+ int pcr_value;
+ char page[IMA_READ_SIZE];
+ int error_path = 1, ptr = 0;
+ UINT32 copied_events = 0, i;
+ struct event_wrapper *list = calloc(1, sizeof(struct event_wrapper));
+ struct event_wrapper *cur = list;
+ TSS_RESULT result = TCSERR(TSS_E_INTERNAL_ERROR);
+ FILE *fp = (FILE *) handle;
+ uint len;
+ char name[255];
+
+ if (list == NULL) {
+ LogError("malloc of %zd bytes failed.", sizeof(struct event_wrapper));
+ return TCSERR(TSS_E_OUTOFMEMORY);
+ }
+
+ if (*count == 0) {
+ result = TSS_SUCCESS;
+ goto free_list;
+ }
+
+ if (!fp) {
+ perror("unable to open file\n");
+ return 1;
+ }
+ rewind(fp);
+
+ while (fread(page, 24, 1, fp)) {
+ /* copy the initial 4 bytes (PCR index) XXX endianess ignored */
+ ptr = 0;
+ memcpy(&pcr_value, &page[ptr], sizeof(int));
+ cur->event.ulPcrIndex = pcr_value;
+ ptr += sizeof(int);
+
+ /* grab this entry */
+ cur->event.ulPcrValueLength = 20;
+ cur->event.rgbPcrValue = malloc(cur->event.ulPcrValueLength);
+ if (cur->event.rgbPcrValue == NULL) {
+ LogError("malloc of %d bytes failed.", 20);
+ result = TCSERR(TSS_E_OUTOFMEMORY);
+ goto free_list;
+ }
+
+ /* copy the template SHA1 XXX endianess ignored */
+ memcpy(cur->event.rgbPcrValue, &page[ptr],
+ cur->event.ulPcrValueLength);
+
+/* Get the template name size, template name */
+{
+ char digest[20];
+
+ if (fread(&len, 1, sizeof(len), fp) != (sizeof(len))) {
+ LogError("Failed to read event log file");
+ result = TCSERR(TSS_E_INTERNAL_ERROR);
+ goto free_list;
+ }
+
+ memset(name, 0, sizeof name);
+ if (fread(name, 1, len, fp) != len) {
+ LogError("Failed to read event log file");
+ result = TCSERR(TSS_E_INTERNAL_ERROR);
+ goto free_list;
+ }
+ if (fread(digest, 1, sizeof digest, fp) != (sizeof(digest))) {
+ LogError("Failed to read event log file");
+ result = TCSERR(TSS_E_INTERNAL_ERROR);
+ goto free_list;
+ }
+}
+ /* Get the template data namelen and data */
+ if (fread(&cur->event.ulEventLength, 1, sizeof(int), fp) != sizeof(int)) {
+ LogError("Failed to read event log file");
+ result = TCSERR(TSS_E_INTERNAL_ERROR);
+ goto free_list;
+ }
+ cur->event.rgbEvent = malloc(cur->event.ulEventLength + 1);
+ if (cur->event.rgbEvent == NULL) {
+ free(cur->event.rgbPcrValue);
+ LogError("malloc of %u bytes failed.",
+ cur->event.ulEventLength);
+ result = TCSERR(TSS_E_OUTOFMEMORY);
+ goto free_list;
+ }
+ memset(cur->event.rgbEvent, 0, cur->event.ulEventLength);
+ if (fread(cur->event.rgbEvent, 1, cur->event.ulEventLength, fp) != cur->event.ulEventLength) {
+ free(cur->event.rgbPcrValue);
+ LogError("Failed to read event log file");
+ result = TCSERR(TSS_E_INTERNAL_ERROR);
+ goto free_list;
+ }
+
+ copied_events++;
+printf("%d %s ", copied_events, name);
+
+printf("%s\n", cur->event.rgbEvent);
+ if (copied_events == *count)
+ goto copy_events;
+
+ cur->next = calloc(1, sizeof(struct event_wrapper));
+ if (cur->next == NULL) {
+ LogError("malloc of %zd bytes failed.",
+ sizeof(struct event_wrapper));
+ result = TCSERR(TSS_E_OUTOFMEMORY);
+ goto free_list;
+ }
+ cur = cur->next;
+ }
+
+copy_events:
+ /* we've copied all the events we need to from this PCR, now
+ * copy them all into one contiguous memory block
+ */
+printf("copied_events: %d\n", copied_events);
+ *events = calloc(copied_events, sizeof(TSS_PCR_EVENT));
+ if (*events == NULL) {
+ LogError("malloc of %zd bytes failed.", copied_events * sizeof(TSS_PCR_EVENT));
+ result = TCSERR(TSS_E_OUTOFMEMORY);
+ goto free_list;
+ }
+
+ cur = list;
+ for (i = 0; i < copied_events; i++) {
+ memcpy(&((*events)[i]), &(cur->event), sizeof(TSS_PCR_EVENT));
+ cur = cur->next;
+ }
+
+ *count = copied_events;
+ /* assume we're in an error path until we get here */
+ error_path = 0;
+ result = TSS_SUCCESS;
+
+free_list:
+ cur = list->next;
+ while (cur != NULL) {
+ if (error_path) {
+ free(cur->event.rgbEvent);
+ free(cur->event.rgbPcrValue);
+ }
+ free(list);
+ list = cur;
+ cur = list->next;
+ }
+ free(list);
+ return result;
+}
+
+TSS_RESULT
+ima_get_entry(FILE *handle, UINT32 pcr_index, UINT32 *num, TSS_PCR_EVENT **ppEvent)
+{
+ int pcr_value, ptr = 0;
+ uint len;
+ char page[IMA_READ_SIZE];
+ UINT32 seen_indices = 0;
+ TSS_RESULT result = TCSERR(TSS_E_INTERNAL_ERROR);
+ TSS_PCR_EVENT *event = NULL;
+ FILE *fp = (FILE *) handle;
+ char name[255];
+
+ rewind(fp);
+ while (fread(page, 24, 1, fp)) {
+ /* copy the initial 4 bytes (PCR index) XXX endianess ignored */
+ ptr = 0;
+ memcpy(&pcr_value, &page[ptr], sizeof(int));
+
+ if (pcr_index == (UINT32)pcr_value) {
+ event = calloc(1, sizeof(TSS_PCR_EVENT));
+ event->ulPcrIndex = pcr_value;
+ ptr += sizeof(int);
+ /* This is the case where we're looking for a specific event number in a
+ * specific PCR index. When we've reached the correct event, malloc
+ * space for it, copy it in, then break out of the while loop */
+ if (ppEvent && seen_indices == *num) {
+ /* grab this entry */
+ event->ulPcrValueLength = 20;
+ event->rgbPcrValue = malloc(event->ulPcrValueLength);
+ if (event->rgbPcrValue == NULL) {
+ LogError("malloc of %d bytes failed.", 20);
+ free(event);
+ result = TCSERR(TSS_E_OUTOFMEMORY);
+ goto done;
+ }
+
+ /* copy the template SHA1 XXX endianess ignored */
+ memcpy(event->rgbPcrValue, &page[ptr],
+ event->ulPcrValueLength);
+
+ /* Get the template name size, template name */
+ {
+ char digest[20];
+
+ if (fread(&len, 1, sizeof(len), fp) != sizeof(len)) {
+ free(event);
+ LogError("Failed to read event log file");
+ result = TCSERR(TSS_E_INTERNAL_ERROR);
+ goto done;
+ }
+ memset(name, 0, sizeof name);
+ if (fread(name, 1, len, fp) != len) {
+ free(event);
+ LogError("Failed to read event log file");
+ result = TCSERR(TSS_E_INTERNAL_ERROR);
+ goto done;
+ }
+ if (fread(digest, 1, sizeof(digest), fp) != sizeof(digest)) {
+ free(event);
+ LogError("Failed to read event log file");
+ result = TCSERR(TSS_E_INTERNAL_ERROR);
+ goto done;
+ }
+ }
+ /* Get the template data namelen and data */
+ if (fread(&event->ulEventLength, 1, sizeof(int), fp) != sizeof(int)) {
+ free(event);
+ LogError("Failed to read event log file");
+ result = TCSERR(TSS_E_INTERNAL_ERROR);
+ goto done;
+ }
+ event->rgbEvent = malloc(event->ulEventLength + 1);
+ if (event->rgbEvent == NULL) {
+ free(event->rgbPcrValue);
+ free(event);
+ LogError("malloc of %u bytes failed.",
+ event->ulEventLength);
+ result = TCSERR(TSS_E_OUTOFMEMORY);
+ goto done;
+ }
+ memset(event->rgbEvent, 0, event->ulEventLength);
+ if (fread(event->rgbEvent, 1, event->ulEventLength, fp) != event->ulEventLength ) {
+ free(event->rgbPcrValue);
+ free(event);
+ LogError("Failed to read event log file");
+ result = TCSERR(TSS_E_INTERNAL_ERROR);
+ goto done;
+ }
+
+ *ppEvent = event;
+ result = TSS_SUCCESS;
+ break;
+ }
+ }
+ if (fread(&len, 1, sizeof(len), fp) != sizeof(len)) {
+ free(event->rgbPcrValue);
+ free(event);
+ LogError("Failed to read event log file");
+ result = TCSERR(TSS_E_INTERNAL_ERROR);
+ goto done;
+ }
+ fseek(fp, len + 20, SEEK_CUR);
+ if (fread(&len, 1, sizeof(len), fp) != sizeof(len)) {
+ free(event->rgbPcrValue);
+ free(event);
+ LogError("Failed to read event log file");
+ result = TCSERR(TSS_E_INTERNAL_ERROR);
+ goto done;
+ }
+ fseek(fp, len, SEEK_CUR);
+ seen_indices++;
+ printf("%d - index\n", seen_indices);
+ }
+done:
+ if (ppEvent == NULL)
+ *num = seen_indices;
+
+ return result;
+}
+
+int
+ima_close(FILE *handle)
+{
+ fclose((FILE *)handle);
+
+ return 0;
+}
+#endif