Annotation of embedaddon/strongswan/src/libimcv/pts/pts_ima_bios_list.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2011-2014 Andreas Steffen
3: * HSR Hochschule fuer Technik Rapperswil
4: *
5: * This program is free software; you can redistribute it and/or modify it
6: * under the terms of the GNU General Public License as published by the
7: * Free Software Foundation; either version 2 of the License, or (at your
8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9: *
10: * This program is distributed in the hope that it will be useful, but
11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13: * for more details.
14: */
15:
16: #include "pts_ima_bios_list.h"
17:
18: #include <utils/debug.h>
19:
20: #include <sys/types.h>
21: #include <sys/stat.h>
22: #include <unistd.h>
23: #include <fcntl.h>
24: #include <errno.h>
25:
26: typedef struct private_pts_ima_bios_list_t private_pts_ima_bios_list_t;
27: typedef struct bios_entry_t bios_entry_t;
28: typedef enum event_type_t event_type_t;
29:
30: enum event_type_t {
31: /* BIOS Events (TCG PC Client Specification for Conventional BIOS 1.21) */
32: EV_PREBOOT_CERT = 0x00000000,
33: EV_POST_CODE = 0x00000001,
34: EV_UNUSED = 0x00000002,
35: EV_NO_ACTION = 0x00000003,
36: EV_SEPARATOR = 0x00000004,
37: EV_ACTION = 0x00000005,
38: EV_EVENT_TAG = 0x00000006,
39: EV_S_CRTM_CONTENTS = 0x00000007,
40: EV_S_CRTM_VERSION = 0x00000008,
41: EV_CPU_MICROCODE = 0x00000009,
42: EV_PLATFORM_CONFIG_FLAGS = 0x0000000A,
43: EV_TABLE_OF_DEVICES = 0x0000000B,
44: EV_COMPACT_HASH = 0x0000000C,
45: EV_IPL = 0x0000000D,
46: EV_IPL_PARTITION_DATA = 0x0000000E,
47: EV_NONHOST_CODE = 0x0000000F,
48: EV_NONHOST_CONFIG = 0x00000010,
49: EV_NONHOST_INFO = 0x00000011,
50: EV_OMIT_BOOT_DEVICE_EVENTS = 0x00000012,
51:
52: /* EFI Events (TCG EFI Platform Specification 1.22) */
53: EV_EFI_EVENT_BASE = 0x80000000,
54: EV_EFI_VARIABLE_DRIVER_CONFIG = 0x80000001,
55: EV_EFI_VARIABLE_BOOT = 0x80000002,
56: EV_EFI_BOOT_SERVICES_APPLICATION = 0x80000003,
57: EV_EFI_BOOT_SERVICES_DRIVER = 0x80000004,
58: EV_EFI_RUNTIME_SERVICES_DRIVER = 0x80000005,
59: EV_EFI_GPT_EVENT = 0x80000006,
60: EV_EFI_ACTION = 0x80000007,
61: EV_EFI_PLATFORM_FIRMWARE_BLOB = 0x80000008,
62: EV_EFI_HANDOFF_TABLES = 0x80000009,
63:
64: EV_EFI_HCRTM_EVENT = 0x80000010,
65:
66: EV_EFI_VARIABLE_AUTHORITY = 0x800000E0
67: };
68:
69: ENUM_BEGIN(event_type_names, EV_PREBOOT_CERT, EV_OMIT_BOOT_DEVICE_EVENTS,
70: "Preboot Cert",
71: "POST Code",
72: "Unused",
73: "No Action",
74: "Separator",
75: "Action",
76: "Event Tag",
77: "S-CRTM Contents",
78: "S-CRTM Version",
79: "CPU Microcode",
80: "Platform Config Flags",
81: "Table of Devices",
82: "Compact Hash",
83: "IPL",
84: "IPL Partition Data",
85: "Nonhost Code",
86: "Nonhost Config",
87: "Nonhost Info",
88: "Omit Boot Device Events"
89: );
90: ENUM_NEXT(event_type_names, EV_EFI_EVENT_BASE, EV_EFI_HANDOFF_TABLES,
91: EV_OMIT_BOOT_DEVICE_EVENTS,
92: "EFI Event Base",
93: "EFI Variable Driver Config",
94: "EFI Variable Boot",
95: "EFI Boot Services Application",
96: "EFI Boot Services Driver",
97: "EFI Runtime Services Driver",
98: "EFI GPT Event",
99: "EFI Action",
100: "EFI Platform Firmware Blob",
101: "EFI Handoff Tables"
102: );
103: ENUM_NEXT(event_type_names, EV_EFI_HCRTM_EVENT, EV_EFI_HCRTM_EVENT,
104: EV_EFI_HANDOFF_TABLES,
105: "EFI HCRTM Event"
106: );
107: ENUM_NEXT(event_type_names, EV_EFI_VARIABLE_AUTHORITY, EV_EFI_VARIABLE_AUTHORITY,
108: EV_EFI_HCRTM_EVENT,
109: "EFI Variable Authority"
110: );
111: ENUM_END(event_type_names, EV_EFI_VARIABLE_AUTHORITY);
112:
113: /**
114: * Private data of a pts_ima_bios_list_t object.
115: *
116: */
117: struct private_pts_ima_bios_list_t {
118:
119: /**
120: * Public pts_ima_bios_list_t interface.
121: */
122: pts_ima_bios_list_t public;
123:
124: /**
125: * List of BIOS measurement entries
126: */
127: linked_list_t *list;
128:
129: /**
130: * Time when BIOS measurements were taken
131: */
132: time_t creation_time;
133:
134: };
135:
136: /**
137: * Linux IMA BIOS measurement entry
138: */
139: struct bios_entry_t {
140:
141: /**
142: * PCR register
143: */
144: uint32_t pcr;
145:
146: /**
147: * SHA1 measurement hash
148: */
149: chunk_t measurement;
150: };
151:
152: /**
153: * Free a bios_entry_t object
154: */
155: static void free_bios_entry(bios_entry_t *this)
156: {
157: free(this->measurement.ptr);
158: free(this);
159: }
160:
161: METHOD(pts_ima_bios_list_t, get_time, time_t,
162: private_pts_ima_bios_list_t *this)
163: {
164: return this->creation_time;
165: }
166:
167: METHOD(pts_ima_bios_list_t, get_count, int,
168: private_pts_ima_bios_list_t *this)
169: {
170: return this->list->get_count(this->list);
171: }
172:
173: METHOD(pts_ima_bios_list_t, get_next, status_t,
174: private_pts_ima_bios_list_t *this, uint32_t *pcr, chunk_t *measurement)
175: {
176: bios_entry_t *entry;
177: status_t status;
178:
179: status = this->list->remove_first(this->list, (void**)&entry);
180: *pcr = entry->pcr;
181: *measurement = entry->measurement;
182: free(entry);
183:
184: return status;
185: }
186:
187: METHOD(pts_ima_bios_list_t, destroy, void,
188: private_pts_ima_bios_list_t *this)
189: {
190: this->list->destroy_function(this->list, (void *)free_bios_entry);
191: free(this);
192: }
193:
194: /**
195: * See header
196: */
197: pts_ima_bios_list_t* pts_ima_bios_list_create(char *file)
198: {
199: private_pts_ima_bios_list_t *this;
200: uint32_t pcr, event_type, event_len, seek_len;
201: uint32_t buf_len = 2048;
202: uint8_t event_buf[buf_len];
203: chunk_t event;
204: bios_entry_t *entry;
205: struct stat st;
206: ssize_t res;
207: int fd;
208:
209: fd = open(file, O_RDONLY);
210: if (fd == -1)
211: {
212: DBG1(DBG_PTS, "opening '%s' failed: %s", file, strerror(errno));
213: return NULL;
214: }
215:
216: if (fstat(fd, &st) == -1)
217: {
218: DBG1(DBG_PTS, "getting statistics of '%s' failed: %s", file,
219: strerror(errno));
220: close(fd);
221: return FALSE;
222: }
223:
224: INIT(this,
225: .public = {
226: .get_time = _get_time,
227: .get_count = _get_count,
228: .get_next = _get_next,
229: .destroy = _destroy,
230: },
231: .creation_time = st.st_ctime,
232: .list = linked_list_create(),
233: );
234:
235: DBG2(DBG_PTS, "PCR Event Type (Size)");
236: while (TRUE)
237: {
238: res = read(fd, &pcr, 4);
239: if (res == 0)
240: {
241: DBG2(DBG_PTS, "loaded bios measurements '%s' (%d entries)",
242: file, this->list->get_count(this->list));
243: close(fd);
244: return &this->public;
245: }
246:
247: entry = malloc_thing(bios_entry_t);
248: entry->pcr = pcr;
249: entry->measurement = chunk_alloc(HASH_SIZE_SHA1);
250:
251: if (res != 4)
252: {
253: break;
254: }
255: if (read(fd, &event_type, 4) != 4)
256: {
257: break;
258: }
259: if (read(fd, entry->measurement.ptr, HASH_SIZE_SHA1) != HASH_SIZE_SHA1)
260: {
261: break;
262: }
263: if (read(fd, &event_len, 4) != 4)
264: {
265: break;
266: }
267: DBG2(DBG_PTS, "%2u %N (%u bytes)", pcr, event_type_names, event_type,
268: event_len);
269:
270: seek_len = (event_len > buf_len) ? event_len - buf_len : 0;
271: event_len -= seek_len;
272:
273: if (read(fd, event_buf, event_len) != event_len)
274: {
275: break;
276: }
277: event = chunk_create(event_buf, event_len);
278: DBG3(DBG_PTS,"%B", &event);
279:
280: if (event_type == EV_ACTION || event_type == EV_EFI_ACTION)
281: {
282: DBG2(DBG_PTS, " '%.*s'", event_len, event_buf);
283: }
284:
285: if (seek_len > 0 && lseek(fd, seek_len, SEEK_CUR) == -1)
286: {
287: break;
288: }
289: this->list->insert_last(this->list, entry);
290: }
291:
292: DBG1(DBG_PTS, "loading bios measurements '%s' failed: %s", file,
293: strerror(errno));
294: free_bios_entry(entry);
295: close(fd);
296: destroy(this);
297:
298: return NULL;
299: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>