ia64/xen-unstable

view tools/vtpm/vtpm.patch @ 19731:01748ccc4da3

Intel VT-d: fix Stoakley boot issue with iommu=1

Signed-off-by: Weidong Han <Weidong.han@intel.com>
Signed-off-by: Allen Kay <allen.m.kay@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 05 09:25:50 2009 +0100 (2009-06-05)
parents 5ea409d66ee4
children
line source
1 diff -uprN tpm_emulator/AUTHORS vtpm/AUTHORS
2 --- tpm_emulator/AUTHORS 2006-12-08 12:51:29.000000000 -0800
3 +++ vtpm/AUTHORS 2006-12-13 16:38:52.000000000 -0800
4 @@ -1,3 +1,3 @@
5 Mario Strasser <mast@gmx.net>
6 Heiko Stamer <stamer@gaos.org> [DAA]
7 -INTEL Corp <> [Dropped to Ring3]
8 +INTEL Corp <> [VTPM Extensions]
9 diff -uprN tpm_emulator/ChangeLog vtpm/ChangeLog
10 --- tpm_emulator/ChangeLog 2006-12-08 12:51:29.000000000 -0800
11 +++ vtpm/ChangeLog 2006-12-13 16:38:52.000000000 -0800
12 @@ -1,5 +1,6 @@
13 ????-??-?? Intel Corp
14 * Moved module out of kernel to run as a ring 3 app
15 + * Modified save_to_file and load_from_file to call xen VTPM manager
17 2006-06-23 Mario Strasser <mast@gmx.net>
18 * tpm_startup.c: behaviour of ST_CLEAR and storage of
19 diff -uprN tpm_emulator/linux_module.h vtpm/linux_module.h
20 --- tpm_emulator/linux_module.h 2006-12-08 12:51:29.000000000 -0800
21 +++ vtpm/linux_module.h 2007-01-09 14:49:06.000000000 -0800
22 @@ -44,18 +44,26 @@
23 #define TPM_DEVICE_NAME "tpm"
24 #define TPM_MODULE_NAME "tpm_emulator"
26 +/* debug and log output functions */
27 +extern int dmi_id;
28 +
29 #ifdef DEBUG
30 -#define debug(fmt, ...) printf("TPMD: %s:%d: Debug: " fmt "\n", \
31 - __FILE__, __LINE__, ## __VA_ARGS__)
32 +#define debug(fmt, ...) printf("TPMD[%d]: %s:%d: Debug: " fmt "\n", \
33 + dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
34 +#define debug_nostop(fmt, ...) printf("TPMD[%d]: %s:%d: Debug: " fmt, \
35 + dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
36 +#define debug_more(fmt, ...) printf( fmt, ## __VA_ARGS__ )
37 #else
38 #define debug(fmt, ...)
39 +#define debug_nostop(fmt, ...)
40 +#define debug_more(fmt, ...)
41 #endif
42 -#define info(fmt, ...) printf("TPMD: %s:%d: Info: " fmt "\n", \
43 - __FILE__, __LINE__, ## __VA_ARGS__)
44 -#define error(fmt, ...) printf("TPMD: %s:%d: Error: " fmt "\n", \
45 - __FILE__, __LINE__, ## __VA_ARGS__)
46 -#define alert(fmt, ...) printf("TPMD: %s:%d: Alert: " fmt "\n", \
47 - __FILE__, __LINE__, ## __VA_ARGS__)
48 +#define info(fmt, ...) printf("TPMD[%d]: %s:%d: Info: " fmt "\n", \
49 + dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
50 +#define error(fmt, ...) printf("TPMD[%d]: %s:%d: Error: " fmt "\n", \
51 + dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
52 +#define alert(fmt, ...) printf("TPMD[%d]: %s:%d: Alert: " fmt "\n", \
53 + dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
55 /* memory allocation */
57 diff -uprN tpm_emulator/Makefile vtpm/Makefile
58 --- tpm_emulator/Makefile 2006-12-08 12:51:29.000000000 -0800
59 +++ vtpm/Makefile 2006-12-13 16:38:52.000000000 -0800
60 @@ -7,7 +7,7 @@
61 COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/)
63 # module settings
64 -BIN := tpm_emulator
65 +BIN := vtpmd
66 VERSION_MAJOR := 0
67 VERSION_MINOR := 4
68 VERSION_BUILD := $(shell date +"%s")
69 @@ -22,7 +22,7 @@ TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin
71 CC := gcc
72 CFLAGS += -g -Wall $(INCLUDE) -DDEBUG
73 -CFLAGS += -I. -Itpm
74 +CFLAGS += -I. -Itpm -I../../vtpm_manager/manager
76 # Is the simulator running in it's own vm?
77 #CFLAGS += -DVTPM_MULTI_VM
78 @@ -62,7 +62,6 @@ $(BIN): $(src)/crypto/gmp.h $(src)/crypt
80 install: $(BIN)
81 $(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR)
82 - @if [ ! -d "/var/tpm" ]; then mkdir /var/tpm; fi
84 clean:
85 rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a $(OBJS)
86 @@ -98,3 +97,4 @@ version:
87 @echo "#endif /* _TPM_VERSION_H_ */" >> $(src)/tpm_version.h
89 .PHONY: all install clean dist gmp version
90 +
91 diff -uprN tpm_emulator/tpm/tpm_capability.c vtpm/tpm/tpm_capability.c
92 --- tpm_emulator/tpm/tpm_capability.c 2006-06-23 03:37:07.000000000 -0700
93 +++ vtpm/tpm/tpm_capability.c 2007-01-10 10:00:49.000000000 -0800
94 @@ -136,8 +136,18 @@ static TPM_RESULT cap_property(UINT32 su
96 case TPM_CAP_PROP_TIS_TIMEOUT:
97 debug("[TPM_CAP_PROP_TIS_TIMEOUT]");
98 - /* TODO: TPM_CAP_PROP_TIS_TIMEOUT */
99 - return TPM_FAIL;
100 + /* TODO: TPM_CAP_PROP_TIS_TIMEOUT: Measure these values and determine correct ones */
101 + UINT32 len = *respSize = 16;
102 + BYTE *ptr = *resp = tpm_malloc(*respSize);
103 + if (ptr == NULL ||
104 + tpm_marshal_UINT32(&ptr, &len, 200000) ||
105 + tpm_marshal_UINT32(&ptr, &len, 200000) ||
106 + tpm_marshal_UINT32(&ptr, &len, 200000) ||
107 + tpm_marshal_UINT32(&ptr, &len, 200000)) {
108 + tpm_free(*resp);
109 + return TPM_FAIL;
110 + }
111 + return TPM_SUCCESS;
113 case TPM_CAP_PROP_STARTUP_EFFECT:
114 debug("[TPM_CAP_PROP_STARTUP_EFFECT]");
115 @@ -190,7 +200,11 @@ static TPM_RESULT cap_property(UINT32 su
117 case TPM_CAP_PROP_DURATION:
118 debug("[TPM_CAP_PROP_DURATION]");
119 - /* TODO: TPM_CAP_PROP_DURATION */
120 + /* TODO: TPM_CAP_PROP_DURATION: Measure these values and return accurate ones */
121 + BYTE dur[]= {0x0,0x0,0x0,0xc,0x0,0x7,0xa1,0x20,0x0,0x1e,0x84,0x80,0x11,0xe1,0xa3,0x0};
122 + *respSize = 16;
123 + *resp = tpm_malloc(*respSize);
124 + memcpy(*resp,dur,16);
125 return TPM_FAIL;
127 case TPM_CAP_PROP_ACTIVE_COUNTER:
128 diff -uprN tpm_emulator/tpm/tpm_cmd_handler.c vtpm/tpm/tpm_cmd_handler.c
129 --- tpm_emulator/tpm/tpm_cmd_handler.c 2008-02-27 16:35:41.000000000 -0500
130 +++ vtpm/tpm/tpm_cmd_handler.c 2008-02-28 14:43:28.000000000 -0500
131 @@ -94,12 +94,18 @@ void tpm_compute_out_param_digest(TPM_CO
132 sha1_ctx_t sha1;
133 UINT32 res = CPU_TO_BE32(rsp->result);
134 UINT32 ord = CPU_TO_BE32(ordinal);
135 + UINT32 offset = 0;
137 /* compute SHA1 hash */
138 sha1_init(&sha1);
139 sha1_update(&sha1, (BYTE*)&res, 4);
140 sha1_update(&sha1, (BYTE*)&ord, 4);
141 - sha1_update(&sha1, rsp->param, rsp->paramSize);
142 + if (ordinal == TPM_ORD_LoadKey2) {
143 + offset = 4;
144 + }
145 + if (rsp->paramSize - offset > 0) {
146 + sha1_update(&sha1, rsp->param + offset, rsp->paramSize - offset);
147 + }
148 sha1_final(&sha1, rsp->auth1->digest);
149 if (rsp->auth2 != NULL) memcpy(rsp->auth2->digest,
150 rsp->auth1->digest, sizeof(rsp->auth1->digest));
151 diff -uprN tpm_emulator/tpm/tpm_data.c vtpm/tpm/tpm_data.c
152 --- tpm_emulator/tpm/tpm_data.c 2008-02-27 16:35:41.000000000 -0500
153 +++ vtpm/tpm/tpm_data.c 2008-02-27 16:35:40.000000000 -0500
154 @@ -1,6 +1,7 @@
155 /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
156 * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
157 * Swiss Federal Institute of Technology (ETH) Zurich
158 + * Copyright (C) 2005 INTEL Corp
159 *
160 * This module is free software; you can redistribute it and/or modify
161 * it under the terms of the GNU General Public License as published
162 @@ -15,10 +16,15 @@
163 * $Id: tpm_data.c 98 2006-05-07 14:16:29Z hstamer $
164 */
166 +#include <sys/types.h>
167 +#include <sys/stat.h>
168 +#include <fcntl.h>
169 +#include <unistd.h>
170 +
171 #include "tpm_emulator.h"
172 #include "tpm_structures.h"
173 #include "tpm_marshalling.h"
174 -#include "linux_module.h"
175 +#include "vtpm_manager.h"
177 TPM_DATA tpmData;
179 @@ -158,45 +164,232 @@ void tpm_release_data(void)
180 #include <sys/types.h>
181 #include <sys/stat.h>
182 #include <fcntl.h>
183 -#include <unistd.h>
185 -#define TPM_STORAGE_FILE "/var/tpm/tpm_emulator-1.2." STR(VERSION_MAJOR) "." STR(VERSION_MINOR)
186 + static int vtpm_tx_fh=-1, vtpm_rx_fh=-1;
187 +
188 +#ifdef VTPM_MUTLI_VM
189 + #define DEV_FE "/dev/tpm"
190 +#else
191 + #define VTPM_RX_FIFO_D "/var/vtpm/fifos/vtpm_rsp_to_%d.fifo"
192 + #define VTPM_TX_FIFO "/var/vtpm/fifos/vtpm_cmd_from_all.fifo"
193 +
194 + extern int dmi_id;
195 + static char *vtpm_rx_name=NULL;
196 +#endif
198 static int write_to_file(uint8_t *data, size_t data_length)
199 {
200 - int res;
201 - int fp;
202 - fp = open(TPM_STORAGE_FILE, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
203 - res = write(fp, data, data_length);
204 - close(fp);
205 - return (res == data_length) ? 0 : -1;
206 + int res, out_data_size, in_header_size;
207 + BYTE *ptr, *out_data, *in_header;
208 + UINT32 result, len, in_rsp_size;
209 + UINT16 tag = VTPM_TAG_REQ;
210 +
211 + printf("Saving NVM\n");
212 + if (vtpm_tx_fh < 0) {
213 +#ifdef VTPM_MUTLI_VM
214 + vtpm_tx_fh = open(DEV_FE, O_RDWR);
215 +#else
216 + vtpm_tx_fh = open(VTPM_TX_FIFO, O_WRONLY);
217 +#endif
218 + }
219 +
220 + if (vtpm_tx_fh < 0) {
221 + return -1;
222 + }
223 +
224 + // Send request to VTPM Manager to encrypt data
225 +#ifdef VTPM_MUTLI_VM
226 + out_data_size = len = VTPM_COMMAND_HEADER_SIZE_CLT + data_length;
227 +#else
228 + out_data_size = len = VTPM_COMMAND_HEADER_SIZE_SRV + data_length;
229 +#endif
230 +
231 + out_data = ptr = (BYTE *) malloc(len);
232 +
233 + if (ptr == NULL
234 +#ifndef VTPM_MUTLI_VM
235 + || tpm_marshal_UINT32(&ptr, &len, dmi_id)
236 +#endif
237 + || tpm_marshal_UINT16(&ptr, &len, tag)
238 +#ifdef VTPM_MUTLI_VM
239 + || tpm_marshal_UINT32(&ptr, &len, out_data_size)
240 +#else
241 + || tpm_marshal_UINT32(&ptr, &len, out_data_size - sizeof(uint32_t))
242 +#endif
243 + || tpm_marshal_UINT32(&ptr, &len, VTPM_ORD_SAVENVM)
244 + || tpm_marshal_BYTE_ARRAY(&ptr, &len, data, data_length)) {
245 + free(out_data);
246 + return -1;
247 + }
248 +
249 + printf("\tSending SaveNVM Command.\n");
250 + res = write(vtpm_tx_fh, out_data, out_data_size);
251 + free(out_data);
252 + if (res != out_data_size) return -1;
253 +
254 + if (vtpm_rx_fh < 0) {
255 +#ifdef VTPM_MUTLI_VM
256 + vtpm_rx_fh = vtpm_tx_fh
257 +#else
258 + if (vtpm_rx_name == NULL) {
259 + vtpm_rx_name = malloc(10 + strlen(VTPM_RX_FIFO_D));
260 + sprintf(vtpm_rx_name, VTPM_RX_FIFO_D, (uint32_t) dmi_id);
261 + }
262 + vtpm_rx_fh = open(vtpm_rx_name, O_RDONLY);
263 +#endif
264 + }
265 +
266 + if (vtpm_rx_fh < 0) {
267 + return -1;
268 + }
269 +
270 + // Read Header of response so we can get the size & status
271 +#ifdef VTPM_MUTLI_VM
272 + in_header_size = len = VTPM_COMMAND_HEADER_SIZE_CLT;
273 +#else
274 + in_header_size = len = VTPM_COMMAND_HEADER_SIZE_SRV;
275 +#endif
276 + in_header = ptr = malloc(in_header_size);
277 +
278 + printf("\tReading SaveNVM header.\n");
279 + res = read(vtpm_rx_fh, in_header, in_header_size);
280 +
281 + if ( (res != in_header_size)
282 +#ifndef VTPM_MUTLI_VM
283 + || tpm_unmarshal_UINT32(&ptr, &len, (UINT32*)&dmi_id)
284 +#endif
285 + || tpm_unmarshal_UINT16(&ptr, &len, &tag)
286 + || tpm_unmarshal_UINT32(&ptr, &len, &in_rsp_size)
287 + || tpm_unmarshal_UINT32(&ptr, &len, &result) ) {
288 + free(in_header);
289 + return -1;
290 + }
291 + free(in_header);
292 +
293 + if (result != VTPM_SUCCESS) {
294 + return -1;
295 + }
296 +
297 +#ifdef VTPM_MUTLI_VM
298 + close(vtpm_tx_fh); close(vtpm_rx_fh);
299 +#endif
300 +
301 + printf("\tFinishing up SaveNVM\n");
302 + return (0);
303 }
305 static int read_from_file(uint8_t **data, size_t *data_length)
306 {
307 - int res;
308 - int fp, file_status;
309 - struct stat file_info;
310 - fp = open(TPM_STORAGE_FILE, O_RDONLY, 0);
311 - file_status = fstat(fp, &file_info);
312 - if (file_status < 0) {
313 - close(fp);
314 - return -1;
315 - }
316 + int res, out_data_size, in_header_size;
317 + uint8_t *ptr, *out_data, *in_header;
318 + UINT16 tag = VTPM_TAG_REQ;
319 + UINT32 len, in_rsp_size, result;
320 +#ifdef VTPM_MUTLI_VM
321 + int vtpm_rx_fh, vtpm_tx_fh;
322 +#endif
323 +
324 + printf("Loading NVM.\n");
325 + if (vtpm_tx_fh < 0) {
326 +#ifdef VTPM_MUTLI_VM
327 + vtpm_tx_fh = open(DEV_FE, O_RDWR);
328 +#else
329 + vtpm_tx_fh = open(VTPM_TX_FIFO, O_WRONLY);
330 +#endif
331 + }
333 - *data_length = file_info.st_size;
334 - *data = tpm_malloc(*data_length);
335 - if (*data == NULL) {
336 - close(fp);
337 + if (vtpm_tx_fh < 0) {
338 + return -1;
339 + }
340 +
341 + // Send request to VTPM Manager to encrypt data
342 +#ifdef VTPM_MUTLI_VM
343 + out_data_size = len = VTPM_COMMAND_HEADER_SIZE_CLT;
344 +#else
345 + out_data_size = len = VTPM_COMMAND_HEADER_SIZE_SRV;
346 +#endif
347 + out_data = ptr = (BYTE *) malloc(len);
348 +
349 + if (ptr == NULL
350 +#ifndef VTPM_MUTLI_VM
351 + || tpm_marshal_UINT32(&ptr, &len, dmi_id)
352 +#endif
353 + || tpm_marshal_UINT16(&ptr, &len, tag)
354 +#ifdef VTPM_MUTLI_VM
355 + || tpm_marshal_UINT32(&ptr, &len, out_data_size)
356 +#else
357 + || tpm_marshal_UINT32(&ptr, &len, out_data_size - sizeof(uint32_t))
358 +#endif
359 + || tpm_marshal_UINT32(&ptr, &len, VTPM_ORD_LOADNVM)) {
360 + free(out_data);
361 return -1;
362 }
363 - res = read(fp, *data, *data_length);
364 - close(fp);
365 +
366 + printf("\tSending LoadNVM command\n");
367 + res = write(vtpm_tx_fh, out_data, out_data_size);
368 + free(out_data);
369 + if (res != out_data_size) return -1;
370 +
371 + if (vtpm_rx_fh < 0) {
372 +#ifdef VTPM_MUTLI_VM
373 + vtpm_rx_fh = vtpm_tx_fh;
374 +#else
375 + if (vtpm_rx_name == NULL) {
376 + vtpm_rx_name = malloc(10 + strlen(VTPM_RX_FIFO_D));
377 + sprintf(vtpm_rx_name, VTPM_RX_FIFO_D, (uint32_t) dmi_id);
378 + }
379 + vtpm_rx_fh = open(vtpm_rx_name, O_RDONLY);
380 +#endif
381 + }
382 +
383 + if (vtpm_rx_fh < 0) {
384 + return -1;
385 + }
386 +
387 + // Read Header of response so we can get the size & status
388 +#ifdef VTPM_MUTLI_VM
389 + in_header_size = len = VTPM_COMMAND_HEADER_SIZE_CLT;
390 +#else
391 + in_header_size = len = VTPM_COMMAND_HEADER_SIZE_SRV;
392 +#endif
393 + in_header = ptr = malloc(in_header_size);
394 +
395 + printf("\tReading LoadNVM header\n");
396 + res = read(vtpm_rx_fh, in_header, in_header_size);
397 +
398 + if ( (res != in_header_size)
399 +#ifndef VTPM_MUTLI_VM
400 + || tpm_unmarshal_UINT32(&ptr, &len, (UINT32*)&dmi_id)
401 +#endif
402 + || tpm_unmarshal_UINT16(&ptr, &len, &tag)
403 + || tpm_unmarshal_UINT32(&ptr, &len, &in_rsp_size)
404 + || tpm_unmarshal_UINT32(&ptr, &len, &result) ) {
405 + free(in_header);
406 + return -1;
407 + }
408 + free(in_header);
409 +
410 + if (result != VTPM_SUCCESS) {
411 + return -1;
412 + }
413 +
414 + // Read Encrypted data from VTPM Manager
415 + *data_length = in_rsp_size - VTPM_COMMAND_HEADER_SIZE_CLT;
416 + *data = (uint8_t *) malloc(*data_length);
417 +
418 + printf("\tReading clear data from LoadNVM.\n");
419 + res = read(vtpm_rx_fh, *data, *data_length);
420 +#ifdef VTPM_MUTLI_VM
421 + close(vtpm_rx_fh);close(vtpm_tx_fh);
422 +#endif
423 +
424 + printf("\tReturing from loading NVM\n");
425 if (res != *data_length) {
426 - tpm_free(*data);
427 - return -1;
428 + free(*data);
429 + return -1;
430 + } else {
431 + return 0;
432 }
433 - return 0;
434 +
435 }
437 #else
438 diff -uprN tpm_emulator/tpmd.c vtpm/tpmd.c
439 --- tpm_emulator/tpmd.c 2006-12-08 12:51:29.000000000 -0800
440 +++ vtpm/tpmd.c 2007-01-09 14:48:56.000000000 -0800
441 @@ -21,12 +21,24 @@
442 #include <sys/stat.h>
443 #include <fcntl.h>
444 #include <sys/time.h>
445 +#include <sys/socket.h>
446 +#include <sys/un.h>
447 +#include <errno.h>
449 #include "tpm_emulator.h"
450 +#include "vtpm_manager.h"
452 -#define TPM_RX_FNAME "/var/tpm/tpm_in.fifo"
453 -#define TPM_TX_FNAME "/var/tpm/tpm_out.fifo"
454 +#ifdef VTPM_MULTI_VM
455 + #define DEV_BE "/dev/vtpm"
456 +#else
457 + #define PVM_RX_FIFO_D "/var/vtpm/fifos/tpm_cmd_to_%d.fifo"
458 + #define PVM_TX_FIFO "/var/vtpm/fifos/tpm_rsp_from_all.fifo"
460 + #define HVM_RX_FIFO_D "/var/vtpm/socks/%d.socket"
461 +#endif
462 +
463 + int dmi_id;
464 +
465 #define BUFFER_SIZE 2048
467 static int devurandom=0;
468 @@ -38,7 +50,7 @@ void get_random_bytes(void *buf, int nby
469 }
471 if (read(devurandom, buf, nbytes) != nbytes) {
472 - printf("Can't get random number.\n");
473 + error("Can't get random number.\n");
474 exit(-1);
475 }
476 }
477 @@ -52,105 +64,182 @@ uint64_t tpm_get_ticks(void)
479 int main(int argc, char **argv)
480 {
481 - uint8_t in[BUFFER_SIZE], *out;
482 + uint8_t type, in[BUFFER_SIZE], *out, *addressed_out;
483 + char *vtpm_rx_file=NULL;
484 uint32_t out_size;
485 int in_size, written;
486 - int i;
487 - struct stat file_info;
488 + int i, guest_id=-1;
490 - int tpm_tx_fh=-1, tpm_rx_fh=-1;
491 +#ifndef VTPM_MULTI_VM
492 + int sockfd = -1;
493 + struct sockaddr_un addr;
494 + struct sockaddr_un client_addr;
495 + unsigned int client_length;
496 +
497 +#endif
498 +
499 + int vtpm_tx_fh=-1, vtpm_rx_fh=-1;
500 +#ifdef VTPM_MULTI_VM
501 if (argc < 2) {
502 - printf("Usage: tpmd clear|save|deactivated\n" );
503 + error("Usage: tpmd clear|save|deactivated\n" );
504 +#else
505 + if (argc < 4) {
506 + error("Usage: tpmd clear|save|deactivated pvm|hvm vtpmid\n" );
507 +#endif
508 return -1;
509 }
511 +#ifndef VTPM_MULTI_VM
512 + /* setup type of vm */
513 + if (!strcmp(argv[2], "pvm")) {
514 + type = VTPM_TYPE_PVM; // Get commands from vTPM Manager through fifo
515 + } else if (!strcmp(argv[2], "hvm")) {
516 + type = VTPM_TYPE_HVM; // Get commands from qemu via socket
517 + } else {
518 + error("invalid vTPM type '%s'.\n", argv[2]);
519 + }
520 +
521 + dmi_id = atoi(argv[3]);
522 +
523 + if (type == VTPM_TYPE_PVM) {
524 + vtpm_rx_file = malloc(10 + strlen(PVM_RX_FIFO_D));
525 + sprintf(vtpm_rx_file, PVM_RX_FIFO_D, (uint32_t) dmi_id);
526 + } else {
527 + vtpm_rx_file = malloc(10 + strlen(HVM_RX_FIFO_D));
528 + sprintf(vtpm_rx_file, HVM_RX_FIFO_D, (uint32_t) dmi_id);
529 +
530 + if ( (sockfd = socket(PF_UNIX,SOCK_STREAM,0)) < 0) {
531 + error("Unable to create socket. errno = %d\n", errno);
532 + exit (-1);
533 + }
534 +
535 + memset(&addr, 0, sizeof(addr));
536 + addr.sun_family = AF_UNIX;
537 + strcpy(addr.sun_path,vtpm_rx_file );
538 + unlink(addr.sun_path);
539 + }
540 +#endif
541 +
542 +#ifdef VTPM_MULTI_VM
543 + info("Initializing tpm state: %s\n", argv[1]);
544 +#else
545 + info("Initializing tpm state: %s, type: %s, id: %d\n", argv[1], argv[2], dmi_id);
546 +#endif
547 +
548 /* initialize TPM emulator */
549 if (!strcmp(argv[1], "clear")) {
550 - printf("Initializing tpm: %s\n", argv[1]);
551 tpm_emulator_init(1);
552 - } else if (!strcmp(argv[1], "save")) {
553 - printf("Initializing tpm: %s\n", argv[1]);
554 + } else if (!strcmp(argv[1], "save")) {
555 tpm_emulator_init(2);
556 } else if (!strcmp(argv[1], "deactivated")) {
557 - printf("Initializing tpm: %s\n", argv[1]);
558 tpm_emulator_init(3);
559 } else {
560 - printf("invalid startup mode '%s'; must be 'clear', "
561 + error("invalid startup mode '%s'; must be 'clear', "
562 "'save' (default) or 'deactivated", argv[1]);
563 return -1;
564 }
565 -
566 - if ( stat(TPM_RX_FNAME, &file_info) == -1) {
567 - if ( mkfifo(TPM_RX_FNAME, S_IWUSR | S_IRUSR ) ) {
568 - printf("Failed to create fifo %s.\n", TPM_RX_FNAME);
569 - return -1;
570 - }
571 - }
572 -
573 - if ( stat(TPM_TX_FNAME, &file_info) == -1) {
574 - if ( mkfifo(TPM_TX_FNAME, S_IWUSR | S_IRUSR ) ) {
575 - printf("Failed to create fifo %s.\n", TPM_TX_FNAME);
576 - return -1;
577 - }
578 - }
579 -
580 +
581 while (1) {
582 abort_command:
583 - if (tpm_rx_fh < 0) {
584 - tpm_rx_fh = open(TPM_RX_FNAME, O_RDONLY);
585 + if (vtpm_rx_fh < 0) {
586 +#ifdef VTPM_MUTLI_VM
587 + vtpm_rx_fh = open(DEV_BE, O_RDWR);
588 +#else
589 + if (type == VTPM_TYPE_PVM) {
590 + vtpm_rx_fh = open(vtpm_rx_file, O_RDONLY);
591 + } else {
592 + if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
593 + error("Unable to bind(). errno = %d\n", errno);
594 + exit (-1);
595 + }
596 +
597 + if (listen(sockfd, 10) <0) {
598 + error("Unable to listen(). errno = %d\n", errno);
599 + exit (-1);
600 + }
601 +
602 + memset(&client_addr, 0, sizeof(client_addr));
603 + client_length = sizeof(client_addr);
604 +
605 + vtpm_rx_fh = vtpm_tx_fh = accept(sockfd, (struct sockaddr *)&client_addr, &client_length);
606 + }
607 +#endif
608 }
610 - if (tpm_rx_fh < 0) {
611 - printf("ERROR: failed to open devices to listen to guest.\n");
612 + if (vtpm_rx_fh < 0) {
613 + error("Failed to open devices to listen to guest.\n");
614 return -1;
615 }
617 - if (tpm_tx_fh < 0) {
618 - tpm_tx_fh = open(TPM_TX_FNAME, O_WRONLY);
619 - }
620 -
621 - if (tpm_tx_fh < 0) {
622 - printf("ERROR: failed to open devices to respond to guest.\n");
623 - return -1;
624 - }
625 -
626 - in_size = read(tpm_rx_fh, in, BUFFER_SIZE);
627 + in_size = read(vtpm_rx_fh, in, BUFFER_SIZE);
628 if (in_size < 6) { // Magic size of minium TPM command
629 - printf("Recv[%d] to small: 0x", in_size);
630 + info("Recv incomplete command of %d bytes.", in_size);
631 if (in_size <= 0) {
632 - close(tpm_rx_fh);
633 - tpm_rx_fh = -1;
634 + close(vtpm_rx_fh);
635 + vtpm_rx_fh = -1;
636 goto abort_command;
637 }
638 } else {
639 - printf("Recv[%d]: 0x", in_size);
640 + debug_nostop("Recv[%d]: 0x", in_size);
641 for (i=0; i< in_size; i++)
642 - printf("%x ", in[i]);
643 - printf("\n");
644 + debug_more("%x ", in[i]);
645 + debug_more("\n");
646 }
648 -
649 - if (tpm_handle_command(in, in_size, &out, &out_size) != 0) {
650 - printf("ERROR: Handler Failed.\n");
651 + if (guest_id == -1) {
652 + guest_id = *((uint32_t *) in);
653 + } else {
654 + if (guest_id != *((uint32_t *) in) ) {
655 + error("WARNING: More than one guest attached\n");
656 + }
657 + }
658 +
659 + if (vtpm_tx_fh < 0) {
660 +#ifdef VTPM_MUTLI_VM
661 + vtpm_tx_fh = open(DEV_BE, O_RDWR);
662 + vtpm_rx_fh = vtpm_tx_fh;
663 +#else
664 + if (type == VTPM_TYPE_PVM) {
665 + vtpm_tx_fh = open(PVM_TX_FIFO, O_WRONLY);
666 + } // No need to open the other direction for HVM
667 +#endif
668 + }
669 +
670 + if (vtpm_tx_fh < 0) {
671 + error("Failed to open devices to respond to guest.\n");
672 + return -1;
673 + }
674 +
675 + // Handle the command, but skip the domain id header
676 + if (tpm_handle_command(in + sizeof(uint32_t), in_size - sizeof(uint32_t), &out, &out_size) != 0) {
677 + error("Handler Failed.\n");
678 }
680 - written = write(tpm_tx_fh, out, out_size);
681 + addressed_out = (uint8_t *) tpm_malloc(sizeof(uint32_t) + out_size);
682 + *(uint32_t *) addressed_out = *(uint32_t *) in;
683 + memcpy(addressed_out + sizeof(uint32_t), out, out_size);
684 +
685 + written = write(vtpm_tx_fh, addressed_out, out_size + sizeof(uint32_t));
687 - if (written != out_size ) {
688 - printf("ERROR: Part of response not written %d/%d.\nAttempt: ", written, out_size);
689 + if (written != out_size + sizeof(uint32_t)) {
690 + error("Part of response not written %d/%d.\n", written, out_size);
691 } else {
692 - printf("Sent[%Zu]: ", out_size);
693 + debug_nostop("Sent[%Zu]: ", out_size + sizeof(uint32_t));
694 + for (i=0; i< out_size+ sizeof(uint32_t); i++)
695 + debug_more("%x ", addressed_out[i]);
696 + debug_more("\n");
697 }
698 - for (i=0; i< out_size; i++)
699 - printf("%x ", out[i]);
700 - printf("\n");
701 tpm_free(out);
702 + tpm_free(addressed_out);
704 } // loop
706 tpm_emulator_shutdown();
708 - close(tpm_tx_fh);
709 - close(tpm_rx_fh);
710 + close(vtpm_tx_fh);
711 +#ifndef VTPM_MUTLI_VM
712 + close(vtpm_rx_fh);
713 + free (vtpm_rx_file);
714 +#endif
716 }