]> git.proxmox.com Git - swtpm.git/blob - src/swtpm/cuse_tpm.c
swtpm: Add command line parameter for pidfile
[swtpm.git] / src / swtpm / cuse_tpm.c
1 /*
2 * ptm - CUSE based TPM PassThrough Multiplexer for QEMU.
3 *
4 * (c) Copyright IBM Corporation 2014, 2015.
5 *
6 * This program instantiates one /dev/vtpm* device, and
7 * calls libtpms to handle requests
8 *
9 * The following code was derived from
10 * http://fuse.sourceforge.net/doxygen/cusexmp_8c.html
11 *
12 * It's original header states:
13 *
14 * CUSE example: Character device in Userspace
15 * Copyright (C) 2008-2009 SUSE Linux Products GmbH
16 * Copyright (C) 2008-2009 Tejun Heo <tj@kernel.org>
17 * This program can be distributed under the terms of the GNU GPL.
18 * See the file COPYING.
19 *
20 *
21 * Authors: David Safford safford@us.ibm.com
22 * Stefan Berger stefanb@us.ibm.com
23 *
24 */
25
26 /*
27 * Note: It's possible for multiple process to open access to
28 * the same character device. Concurrency problems may arise
29 * if those processes all write() to the device and then try
30 * to pick up the results. Proper usage of the device is to
31 * have one process (QEMU) use ioctl, read and write and have
32 * other processes (libvirt, etc.) only use ioctl.
33 */
34 #define FUSE_USE_VERSION 29
35
36 #include <stddef.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
41 #include <dirent.h>
42 #include <errno.h>
43 #include <stdbool.h>
44 #include <sys/types.h>
45 #include <ctype.h>
46 #include <pwd.h>
47 #include <grp.h>
48 #include <arpa/inet.h>
49
50 #include <libtpms/tpm_library.h>
51 #include <libtpms/tpm_tis.h>
52 #include <libtpms/tpm_error.h>
53 #include <libtpms/tpm_memory.h>
54 #include <libtpms/tpm_nvfilename.h>
55
56 #include "cuse_lowlevel.h"
57 #include "fuse_opt.h"
58 #include "tpm_ioctl.h"
59 #include "swtpm.h"
60 #include "swtpm_nvfile.h"
61 #include "key.h"
62 #include "logging.h"
63 #include "main.h"
64 #include "common.h"
65 #include "pidfile.h"
66
67 #include <glib.h>
68
69 #define TPM_REQ_MAX 4096
70 static unsigned char *ptm_request, *ptm_response;
71 static uint32_t ptm_req_len, ptm_res_len, ptm_res_tot;
72 static TPM_MODIFIER_INDICATOR locality;
73 static int tpm_running;
74 static int thread_busy;
75 static GThreadPool *pool;
76 static struct passwd *passwd;
77
78 #if GLIB_MAJOR_VERSION >= 2
79 # if GLIB_MINOR_VERSION >= 32
80
81 GCond thread_busy_signal;
82 GMutex thread_busy_lock;
83 GMutex file_ops_lock;
84 # define THREAD_BUSY_SIGNAL &thread_busy_signal
85 # define THREAD_BUSY_LOCK &thread_busy_lock
86 # define FILE_OPS_LOCK &file_ops_lock
87
88 # else
89
90 GCond *thread_busy_signal;
91 GMutex *thread_busy_lock;
92 GMutex *file_ops_lock;
93 # define THREAD_BUSY_SIGNAL thread_busy_signal
94 # define THREAD_BUSY_LOCK thread_busy_lock
95 # define FILE_OPS_LOCK file_ops_lock
96
97 # endif
98 #else
99
100 #error Unsupport glib version
101
102 #endif
103
104 struct ptm_param {
105 unsigned major;
106 unsigned minor;
107 char *dev_name;
108 int is_help;
109 const char *prgname;
110 char *runas;
111 char *logging;
112 char *keydata;
113 char *migkeydata;
114 char *piddata;
115 };
116
117
118 enum msg_type {
119 MESSAGE_TPM_CMD = 1,
120 MESSAGE_IOCTL,
121 };
122
123 struct thread_message {
124 enum msg_type type;
125 fuse_req_t req;
126 };
127
128 #define min(a,b) ((a) < (b) ? (a) : (b))
129
130 struct stateblob {
131 uint8_t type;
132 uint8_t *data;
133 uint32_t length;
134 TPM_BOOL is_encrypted;
135 };
136
137 typedef struct stateblob_desc {
138 uint32_t blobtype;
139 TPM_BOOL decrypt;
140 TPM_BOOL is_encrypted;
141 unsigned char *data;
142 uint32_t data_length;
143 } stateblob_desc;
144
145 typedef enum tx_state_type {
146 TX_STATE_RW_COMMAND = 1,
147 TX_STATE_SET_STATE_BLOB = 2,
148 TX_STATE_GET_STATE_BLOB = 3,
149 } tx_state_type;
150
151 typedef struct transfer_state {
152 tx_state_type state;
153 /* while in TX_STATE_GET/SET_STATEBLOB */
154 uint32_t blobtype;
155 TPM_BOOL blob_is_encrypted;
156 /* while in TX_STATE_GET */
157 uint32_t offset;
158 } transfer_state;
159
160 /* function prototypes */
161
162 static TPM_RESULT
163 ptm_set_stateblob_append(uint32_t blobtype,
164 const unsigned char *data, uint32_t length,
165 bool is_encrypted, bool is_last);
166
167 static int
168 cached_stateblob_get(uint32_t offset,
169 unsigned char **bufptr, size_t *length);
170
171
172 static const char *usage =
173 "usage: %s [options]\n"
174 "\n"
175 "The following options are supported:\n"
176 "\n"
177 "-n NAME|--name=NAME : device name (mandatory)\n"
178 "-M MAJ|--maj=MAJ : device major number\n"
179 "-m MIN|--min=MIN : device minor number\n"
180 "--key file=<path>[,mode=aes-cbc][,format=hex|binary][,remove=[true|false]]\n"
181 " : use an AES key for the encryption of the TPM's state\n"
182 " files; use the given mode for the block encryption;\n"
183 " the key is to be provided as a hex string or in binary\n"
184 " format; the keyfile can be automatically removed using\n"
185 " the remove parameter\n"
186 "--key pwdfile=<path>[,mode=aes-cbc][,remove=[true|false]]\n"
187 " : provide a passphrase in a file; the AES key will be\n"
188 " derived from this passphrase\n"
189 "--migration-key file=<path>,[,mode=aes-cbc][,format=hex|binary][,remove=[true|false]]\n"
190 " : use an AES key for the encryption of the TPM's state\n"
191 " when it is retrieved from the TPM via ioctls;\n"
192 " Setting this key ensures that the TPM's state will always\n"
193 " be encrypted when migrated\n"
194 "--migration-key pwdfile=<path>[,mode=aes-cbc][,remove=[true|false]]\n"
195 " : provide a passphrase in a file; the AES key will be\n"
196 " derived from this passphrase\n"
197 "--log file=<path>|fd=<filedescriptor>\n"
198 " : write the TPM's log into the given file rather than\n"
199 " to the console; provide '-' for path to avoid logging\n"
200 "-h|--help : display this help screen and terminate\n"
201 "\n"
202 "Make sure that TPM_PATH environment variable points to directory\n"
203 "where TPM's NV storage file is kept\n"
204 "\n";
205
206 const static unsigned char TPM_Resp_FatalError[] = {
207 0x00, 0xC4, /* TPM Response */
208 0x00, 0x00, 0x00, 0x0A, /* length (10) */
209 0x00, 0x00, 0x00, 0x09 /* TPM_FAIL */
210 };
211
212 const static unsigned char TPM_ResetEstablishmentBit[] = {
213 0x00, 0xC1, /* TPM Request */
214 0x00, 0x00, 0x00, 0x0A, /* length (10) */
215 0x40, 0x00, 0x00, 0x0B /* TPM_ORD_ResetEstablishmentBit */
216 };
217
218 typedef struct TPM_Response_Header {
219 uint16_t tag;
220 uint32_t paramSize;
221 uint32_t returnCode;
222 } __attribute__ ((packed)) TPM_Response_Header;
223
224 static TPM_RESULT
225 ptm_io_getlocality(TPM_MODIFIER_INDICATOR *loc, uint32_t tpmnum)
226 {
227 *loc = locality;
228 return TPM_SUCCESS;
229 }
230
231 static struct libtpms_callbacks cbs = {
232 .sizeOfStruct = sizeof(struct libtpms_callbacks),
233 .tpm_nvram_init = SWTPM_NVRAM_Init,
234 .tpm_nvram_loaddata = SWTPM_NVRAM_LoadData,
235 .tpm_nvram_storedata = SWTPM_NVRAM_StoreData,
236 .tpm_nvram_deletename = SWTPM_NVRAM_DeleteName,
237 .tpm_io_getlocality = ptm_io_getlocality,
238 };
239
240 static struct thread_message msg;
241
242 static transfer_state tx_state;
243
244 /* worker_thread_wait_done
245 *
246 * Wait while the TPM worker thread is busy
247 */
248 static void worker_thread_wait_done(void)
249 {
250 g_mutex_lock(THREAD_BUSY_LOCK);
251 while (thread_busy) {
252 #if GLIB_MINOR_VERSION >= 32
253 gint64 end_time = g_get_monotonic_time() +
254 1 * G_TIME_SPAN_SECOND;
255 g_cond_wait_until(THREAD_BUSY_SIGNAL,
256 THREAD_BUSY_LOCK,
257 end_time);
258 #else
259 GTimeVal abs_time;
260 /*
261 * seems like occasionally the g_cond_signal did not wake up
262 * the sleeping task; so we poll [TIS Test in BIOS]
263 */
264 abs_time.tv_sec = 1;
265 abs_time.tv_usec = 0;
266 g_cond_timed_wait(THREAD_BUSY_SIGNAL,
267 THREAD_BUSY_LOCK,
268 &abs_time);
269 #endif
270 }
271 g_mutex_unlock(THREAD_BUSY_LOCK);
272 }
273
274 /* worker_thread_mark_busy
275 *
276 * Mark the worker thread as busy; call this with the lock held
277 */
278 static void worker_thread_mark_busy(void)
279 {
280 g_mutex_lock(THREAD_BUSY_LOCK);
281 thread_busy = 1;
282 g_mutex_unlock(THREAD_BUSY_LOCK);
283 }
284
285 /* work_tread_mark_done
286 *
287 * Mark the worker thread as done and wake
288 * up the waiting thread
289 */
290 static void worker_thread_mark_done(void)
291 {
292 g_mutex_lock(THREAD_BUSY_LOCK);
293 thread_busy = 0;
294 g_cond_signal(THREAD_BUSY_SIGNAL);
295 g_mutex_unlock(THREAD_BUSY_LOCK);
296 }
297
298 /* worker_thread_is_busy
299 *
300 * Determine whether the worker thread is busy
301 */
302 static int worker_thread_is_busy()
303 {
304 return thread_busy;
305 }
306
307 static void worker_thread(gpointer data, gpointer user_data)
308 {
309 struct thread_message *msg = (struct thread_message *)data;
310
311 switch (msg->type) {
312 case MESSAGE_TPM_CMD:
313 TPMLIB_Process(&ptm_response, &ptm_res_len, &ptm_res_tot,
314 ptm_request, ptm_req_len);
315 break;
316 case MESSAGE_IOCTL:
317 break;
318 }
319
320 /* results are ready */
321 worker_thread_mark_done();
322 }
323
324 /* worker_thread_end
325 *
326 * finish the worker thread
327 */
328 static void worker_thread_end()
329 {
330 if (pool) {
331 worker_thread_wait_done();
332 g_thread_pool_free(pool, TRUE, TRUE);
333 pool = NULL;
334 }
335 }
336
337 /* _TPM_IO_TpmEstablished_Reset
338 *
339 * Reset the TPM Established bit
340 */
341 static TPM_RESULT
342 _TPM_IO_TpmEstablished_Reset(fuse_req_t req,
343 TPM_MODIFIER_INDICATOR locty)
344 {
345 TPM_RESULT res = TPM_FAIL;
346 TPM_Response_Header *tpmrh;
347 TPM_MODIFIER_INDICATOR orig_locality = locality;
348
349 locality = locty;
350
351 ptm_req_len = sizeof(TPM_ResetEstablishmentBit);
352 memcpy(ptm_request, TPM_ResetEstablishmentBit, ptm_req_len);
353 msg.type = MESSAGE_TPM_CMD;
354 msg.req = req;
355
356 worker_thread_mark_busy();
357
358 g_thread_pool_push(pool, &msg, NULL);
359
360 worker_thread_wait_done();
361
362 if (ptm_res_len >= sizeof(TPM_Response_Header)) {
363 tpmrh = (TPM_Response_Header *)ptm_response;
364 res = ntohl(tpmrh->returnCode);
365 }
366
367 locality = orig_locality;
368
369 return res;
370 }
371
372 static int tpm_start(uint32_t flags)
373 {
374 DIR *dir;
375 char * tpmdir = NULL;
376
377 /* temporary - the backend script lacks the perms to do this */
378 if (tpmdir == NULL) {
379 tpmdir = getenv("TPM_PATH");
380 if (!tpmdir) {
381 logprintf(STDOUT_FILENO,
382 "Error: TPM_PATH is not set\n");
383 return -1;
384 }
385 }
386 dir = opendir(tpmdir);
387 if (dir) {
388 closedir(dir);
389 } else {
390 if (mkdir(tpmdir, 0775)) {
391 logprintf(STDERR_FILENO,
392 "Error: Could not open TPM_PATH dir\n");
393 return -1;
394 }
395 }
396
397 pool = g_thread_pool_new(worker_thread,
398 NULL,
399 1,
400 TRUE,
401 NULL);
402 if (!pool) {
403 logprintf(STDERR_FILENO,
404 "Error: Could not create the thread pool.\n");
405 return -1;
406 }
407
408 if (TPMLIB_RegisterCallbacks(&cbs) != TPM_SUCCESS) {
409 logprintf(STDERR_FILENO,
410 "Error: Could not register the callbacks.\n");
411 goto error_del_pool;
412 }
413
414 if (TPMLIB_MainInit() != TPM_SUCCESS) {
415 logprintf(STDERR_FILENO,
416 "Error: Could not start the CUSE TPM.\n");
417 goto error_del_pool;
418 }
419
420 if (flags & PTM_INIT_FLAG_DELETE_VOLATILE) {
421 uint32_t tpm_number = 0;
422 char *name = TPM_VOLATILESTATE_NAME;
423 if (SWTPM_NVRAM_DeleteName(tpm_number,
424 name,
425 FALSE) != TPM_SUCCESS) {
426 logprintf(STDERR_FILENO,
427 "Error: Could not delete the volatile "
428 "state of the TPM.\n");
429 goto error_terminate;
430 }
431 }
432
433 if(!ptm_request)
434 ptm_request = malloc(4096);
435 if(!ptm_request) {
436 logprintf(STDERR_FILENO,
437 "Error: Could not allocate memory for request buffer.\n");
438 goto error_terminate;
439 }
440
441 logprintf(STDOUT_FILENO,
442 "CUSE TPM successfully initialized.\n");
443
444 return 0;
445
446 error_del_pool:
447 g_thread_pool_free(pool, TRUE, TRUE);
448 pool = NULL;
449
450 error_terminate:
451 TPMLIB_Terminate();
452 return -1;
453 }
454
455 /*
456 * convert the blobtype integer into a string that libtpms
457 * understands
458 */
459 static const char *ptm_get_blobname(uint32_t blobtype)
460 {
461 switch (blobtype) {
462 case PTM_BLOB_TYPE_PERMANENT:
463 return TPM_PERMANENT_ALL_NAME;
464 case PTM_BLOB_TYPE_VOLATILE:
465 return TPM_VOLATILESTATE_NAME;
466 case PTM_BLOB_TYPE_SAVESTATE:
467 return TPM_SAVESTATE_NAME;
468 default:
469 return NULL;
470 }
471 }
472
473 static void ptm_open(fuse_req_t req, struct fuse_file_info *fi)
474 {
475 tx_state.state = TX_STATE_RW_COMMAND;
476
477 fuse_reply_open(req, fi);
478 }
479
480 /* ptm_write_fatal_error_response
481 *
482 * Write a fatal error response
483 */
484 static void ptm_write_fatal_error_response(void)
485 {
486 if (ptm_response == NULL ||
487 ptm_res_tot < sizeof(TPM_Resp_FatalError)) {
488 ptm_res_tot = sizeof(TPM_Resp_FatalError);
489 TPM_Realloc(&ptm_response, ptm_res_tot);
490 }
491 if (ptm_response) {
492 ptm_res_len = sizeof(TPM_Resp_FatalError);
493 memcpy(ptm_response,
494 TPM_Resp_FatalError,
495 sizeof(TPM_Resp_FatalError));
496 }
497 }
498
499 static void ptm_read_cmd(fuse_req_t req, size_t size)
500 {
501 int len;
502
503 if (tpm_running) {
504 /* wait until results are ready */
505 worker_thread_wait_done();
506 }
507
508 len = ptm_res_len;
509
510 if (ptm_res_len > size) {
511 len = size;
512 ptm_res_len -= size;
513 } else {
514 ptm_res_len = 0;
515 }
516
517 fuse_reply_buf(req, (const char *)ptm_response, len);
518 }
519
520 /*
521 * ptm_read_stateblob: get a stateblob via the read() interface
522 * @req: the fuse_req_t
523 * @size: the number of bytes to read
524 *
525 * The internal offset into the buffer is advanced by the number
526 * of bytes that were copied.
527 */
528 static void ptm_read_stateblob(fuse_req_t req, size_t size)
529 {
530 unsigned char *bufptr = NULL;
531 size_t numbytes;
532 size_t tocopy;
533
534 if (cached_stateblob_get(tx_state.offset, &bufptr, &numbytes) < 0) {
535 fuse_reply_err(req, EIO);
536 tx_state.state = TX_STATE_RW_COMMAND;
537 } else {
538 tocopy = MIN(size, numbytes);
539 tx_state.offset += tocopy;
540
541 fuse_reply_buf(req, (char *)bufptr, tocopy);
542 /* last transfer indicated by less bytes available than requested */
543 if (numbytes < size) {
544 tx_state.state = TX_STATE_RW_COMMAND;
545 }
546 }
547 }
548
549 static void ptm_read(fuse_req_t req, size_t size, off_t off,
550 struct fuse_file_info *fi)
551 {
552 switch (tx_state.state) {
553 case TX_STATE_RW_COMMAND:
554 ptm_read_cmd(req, size);
555 break;
556 case TX_STATE_SET_STATE_BLOB:
557 fuse_reply_err(req, EIO);
558 tx_state.state = TX_STATE_RW_COMMAND;
559 break;
560 case TX_STATE_GET_STATE_BLOB:
561 ptm_read_stateblob(req, size);
562 break;
563 }
564 }
565
566 static void ptm_write_cmd(fuse_req_t req, const char *buf, size_t size)
567 {
568 ptm_req_len = size;
569 ptm_res_len = 0;
570
571 /* prevent other threads from writing or doing ioctls */
572 g_mutex_lock(FILE_OPS_LOCK);
573
574 if (tpm_running) {
575 /* ensure that we only ever work on one TPM command */
576 if (worker_thread_is_busy()) {
577 fuse_reply_err(req, EBUSY);
578 goto cleanup;
579 }
580
581 /* have command processed by thread pool */
582 if (ptm_req_len > TPM_REQ_MAX)
583 ptm_req_len = TPM_REQ_MAX;
584
585 memcpy(ptm_request, buf, ptm_req_len);
586 msg.type = MESSAGE_TPM_CMD;
587 msg.req = req;
588
589 worker_thread_mark_busy();
590
591 g_thread_pool_push(pool, &msg, NULL);
592
593 fuse_reply_write(req, ptm_req_len);
594 } else {
595 /* TPM not initialized; return error */
596 ptm_write_fatal_error_response();
597 fuse_reply_write(req, ptm_req_len);
598 }
599
600 cleanup:
601 g_mutex_unlock(FILE_OPS_LOCK);
602
603 return;
604 }
605
606 /*
607 * ptm_write_stateblob: Write the state blob using the write() interface
608 *
609 * @req: the fuse_req_t
610 * @buf: the buffer with the data
611 * @size: the number of bytes in the buffer
612 *
613 * The data are appended to an existing buffer that was created with the
614 * initial ioctl().
615 */
616 static void ptm_write_stateblob(fuse_req_t req, const char *buf, size_t size)
617 {
618 TPM_RESULT res;
619
620 res = ptm_set_stateblob_append(tx_state.blobtype,
621 (unsigned char *)buf, size,
622 tx_state.blob_is_encrypted,
623 (size == 0));
624 if (res) {
625 tx_state.state = TX_STATE_RW_COMMAND;
626 fuse_reply_err(req, EIO);
627 } else {
628 fuse_reply_write(req, size);
629 }
630 }
631
632 /*
633 * ptm_write: low-level write() interface; calls approriate function depending
634 * on what is being transferred using the write()
635 */
636 static void ptm_write(fuse_req_t req, const char *buf, size_t size,
637 off_t off, struct fuse_file_info *fi)
638 {
639 switch (tx_state.state) {
640 case TX_STATE_RW_COMMAND:
641 ptm_write_cmd(req, buf, size);
642 break;
643 case TX_STATE_GET_STATE_BLOB:
644 fuse_reply_err(req, EIO);
645 tx_state.state = TX_STATE_RW_COMMAND;
646 break;
647 case TX_STATE_SET_STATE_BLOB:
648 ptm_write_stateblob(req, buf, size);
649 break;
650 }
651 }
652
653 static stateblob_desc cached_stateblob;
654
655 static bool
656 cached_stateblob_is_loaded(uint32_t blobtype, TPM_BOOL decrypt)
657 {
658 return (cached_stateblob.data != NULL) &&
659 (cached_stateblob.blobtype == blobtype) &&
660 (cached_stateblob.decrypt == decrypt);
661 }
662
663 /*
664 * cached_stateblob_free: Free any previously loaded state blob
665 */
666 static void
667 cached_stateblob_free(void)
668 {
669 TPM_Free(cached_stateblob.data);
670 cached_stateblob.data = NULL;
671 cached_stateblob.data_length = 0;
672 }
673
674 /*
675 * cached_stateblob_get_bloblength: get the total length of the cached blob
676 */
677 static uint32_t
678 cached_stateblob_get_bloblength(void)
679 {
680 return cached_stateblob.data_length;
681 }
682
683 /*
684 * cached_statblob_get: get stateblob data without copying them
685 *
686 * @offset: at which offset to get the data
687 * @bufptr: pointer to a buffer pointer used to return buffer start
688 * @length: pointer used to return number of available bytes in returned buffer
689 */
690 static int
691 cached_stateblob_get(uint32_t offset,
692 unsigned char **bufptr, size_t *length)
693 {
694 if (cached_stateblob.data == NULL ||
695 offset > cached_stateblob.data_length)
696 return -1;
697
698 *bufptr = &cached_stateblob.data[offset];
699 *length = cached_stateblob.data_length - offset;
700
701 return 0;
702 }
703
704 /*
705 * cached_stateblob_load: load a state blob into the cache
706 *
707 * blobtype: the type of blob
708 * decrypt: whether the blob is to be decrypted
709 */
710 static TPM_RESULT
711 cached_stateblob_load(uint32_t blobtype, TPM_BOOL decrypt)
712 {
713 TPM_RESULT res = 0;
714 const char *blobname = ptm_get_blobname(blobtype);
715 uint32_t tpm_number = 0;
716
717 if (!blobname)
718 return TPM_BAD_PARAMETER;
719
720 cached_stateblob_free();
721
722 if (blobtype == PTM_BLOB_TYPE_VOLATILE)
723 res = SWTPM_NVRAM_Store_Volatile();
724
725 if (res == 0)
726 res = SWTPM_NVRAM_GetStateBlob(&cached_stateblob.data,
727 &cached_stateblob.data_length,
728 tpm_number, blobname, decrypt,
729 &cached_stateblob.is_encrypted);
730
731 /* make sure the volatile state file is gone */
732 if (blobtype == PTM_BLOB_TYPE_VOLATILE)
733 SWTPM_NVRAM_DeleteName(tpm_number, blobname, FALSE);
734
735 if (res == 0) {
736 cached_stateblob.blobtype = blobtype;
737 cached_stateblob.decrypt = decrypt;
738 }
739
740 return res;
741 }
742
743 /*
744 * cached_state_blob_copy: copy the cached state blob to a destination buffer
745 *
746 * dest: destination buffer
747 * destlen: size of the buffer
748 * srcoffset: offset to copy from
749 * copied: variable to return the number of copied bytes
750 * is_encrypted: variable to return whether the blob is encrypted
751 */
752 static int
753 cached_stateblob_copy(void *dest, size_t destlen, uint32_t srcoffset,
754 uint32_t *copied, TPM_BOOL *is_encrypted)
755 {
756 int ret = -1;
757
758 *copied = 0;
759
760 if (cached_stateblob.data != NULL && cached_stateblob.data_length > 0) {
761
762 if (srcoffset < cached_stateblob.data_length) {
763 *copied = min(cached_stateblob.data_length - srcoffset, destlen);
764
765 memcpy(dest, &cached_stateblob.data[srcoffset], *copied);
766
767 *is_encrypted = cached_stateblob.is_encrypted;
768 }
769
770 ret = 0;
771 }
772
773 return ret;
774 }
775
776 /*
777 * ptm_get_stateblob_part: get part of a state blob
778 */
779 static TPM_RESULT
780 ptm_get_stateblob_part(uint32_t blobtype,
781 unsigned char *buffer, size_t buffer_size,
782 uint32_t offset, uint32_t *copied,
783 TPM_BOOL decrypt, TPM_BOOL *is_encrypted)
784 {
785 TPM_RESULT res = 0;
786
787 if (!cached_stateblob_is_loaded(blobtype, decrypt)) {
788 res = cached_stateblob_load(blobtype, decrypt);
789 }
790
791 if (res == 0) {
792 cached_stateblob_copy(buffer, buffer_size,
793 offset, copied, is_encrypted);
794 }
795
796 return res;
797 }
798
799 /*
800 * ptm_get_stateblob: Get the state blob from the TPM using ioctl()
801 */
802 static void
803 ptm_get_stateblob(fuse_req_t req, ptm_getstate *pgs)
804 {
805 TPM_RESULT res = 0;
806 uint32_t blobtype = pgs->u.req.type;
807 TPM_BOOL decrypt =
808 ((pgs->u.req.state_flags & PTM_STATE_FLAG_DECRYPTED) != 0);
809 TPM_BOOL is_encrypted = FALSE;
810 uint32_t copied = 0;
811 uint32_t offset = pgs->u.req.offset;
812 uint32_t totlength;
813
814 res = ptm_get_stateblob_part(blobtype,
815 pgs->u.resp.data, sizeof(pgs->u.resp.data),
816 pgs->u.req.offset, &copied,
817 decrypt, &is_encrypted);
818
819 totlength = cached_stateblob_get_bloblength();
820
821 pgs->u.resp.state_flags = 0;
822 if (is_encrypted)
823 pgs->u.resp.state_flags |= PTM_STATE_FLAG_ENCRYPTED;
824
825 pgs->u.resp.length = copied;
826 pgs->u.resp.totlength = totlength;
827 pgs->u.resp.tpm_result = res;
828
829 if (res == 0) {
830 if (offset + copied < totlength) {
831 /* last byte was not copied */
832 tx_state.state = TX_STATE_GET_STATE_BLOB;
833 tx_state.blobtype = pgs->u.req.type;
834 tx_state.blob_is_encrypted = is_encrypted;
835 tx_state.offset = copied;
836 } else {
837 /* last byte was copied */
838 tx_state.state = TX_STATE_RW_COMMAND;
839 }
840 } else {
841 /* error occurred */
842 tx_state.state = TX_STATE_RW_COMMAND;
843 }
844
845 fuse_reply_ioctl(req, 0, pgs, sizeof(pgs->u.resp));
846 }
847
848 /*
849 * ptm_set_stateblob_append: Append a piece of TPM state blob and transfer to TPM
850 *
851 * blobtype: the type of blob
852 * data: the data to append
853 * length: length of the data
854 * is_encrypted: whether the blob is encrypted
855 * is_last: whether this is the last part of the TPM state blob; if it is, the TPM
856 * state blob will then be transferred to the TPM
857 */
858 static TPM_RESULT
859 ptm_set_stateblob_append(uint32_t blobtype,
860 const unsigned char *data, uint32_t length,
861 bool is_encrypted, bool is_last)
862 {
863 const char *blobname;
864 TPM_RESULT res = 0;
865 static struct stateblob stateblob;
866
867 if (stateblob.type != blobtype) {
868 /* clear old data */
869 TPM_Free(stateblob.data);
870 stateblob.data = NULL;
871 stateblob.length = 0;
872 stateblob.type = blobtype;
873 stateblob.is_encrypted = is_encrypted;
874
875 /*
876 * on the first call for a new state blob we allow 0 bytes to be written
877 * this allows the user to transfer via write()
878 */
879 if (length == 0)
880 return 0;
881 }
882
883 /* append */
884 res = TPM_Realloc(&stateblob.data, stateblob.length + length);
885 if (res != 0) {
886 /* error */
887 TPM_Free(stateblob.data);
888 stateblob.data = NULL;
889 stateblob.length = 0;
890 stateblob.type = 0;
891
892 return res;
893 }
894
895 memcpy(&stateblob.data[stateblob.length], data, length);
896 stateblob.length += length;
897
898 if (!is_last) {
899 /* full packet -- expecting more data */
900 return res;
901 }
902 blobname = ptm_get_blobname(blobtype);
903
904 if (blobname) {
905 res = SWTPM_NVRAM_SetStateBlob(stateblob.data,
906 stateblob.length,
907 stateblob.is_encrypted,
908 0 /* tpm_number */,
909 blobname);
910 } else {
911 res = TPM_BAD_PARAMETER;
912 }
913
914 TPM_Free(stateblob.data);
915 stateblob.data = NULL;
916 stateblob.length = 0;
917 stateblob.type = 0;
918
919 /* transfer of blob is complete */
920 tx_state.state = TX_STATE_RW_COMMAND;
921
922 return res;
923 }
924
925 static void
926 ptm_set_stateblob(fuse_req_t req, ptm_setstate *pss)
927 {
928 TPM_RESULT res = 0;
929 TPM_BOOL is_encrypted =
930 ((pss->u.req.state_flags & PTM_STATE_FLAG_ENCRYPTED) != 0);
931 bool is_last = (sizeof(pss->u.req.data) != pss->u.req.length);
932
933 if (pss->u.req.length > sizeof(pss->u.req.data)) {
934 res = TPM_BAD_PARAMETER;
935 goto send_response;
936 }
937
938 /* transfer of blob initiated */
939 tx_state.state = TX_STATE_SET_STATE_BLOB;
940 tx_state.blobtype = pss->u.req.type;
941 tx_state.blob_is_encrypted = is_encrypted;
942 tx_state.offset = 0;
943
944 res = ptm_set_stateblob_append(pss->u.req.type,
945 pss->u.req.data,
946 pss->u.req.length,
947 is_encrypted,
948 is_last);
949
950 if (res)
951 tx_state.state = TX_STATE_RW_COMMAND;
952
953 send_response:
954 pss->u.resp.tpm_result = res;
955
956 fuse_reply_ioctl(req, 0, pss, sizeof(*pss));
957 }
958
959 /*
960 * ptm_ioctl : ioctl execution
961 *
962 * req: the fuse_req_t used to send response with
963 * cmd: the ioctl request code
964 * arg: the pointer the application used for calling the ioctl (3rd param)
965 * fi:
966 * flags: some flags provided by fuse
967 * in_buf: the copy of the input buffer
968 * in_bufsz: size of the input buffer; provided by fuse and has size of
969 * needed buffer
970 * out_bufsz: size of the output buffer; provided by fuse and has size of
971 * needed buffer
972 */
973 static void ptm_ioctl(fuse_req_t req, int cmd, void *arg,
974 struct fuse_file_info *fi, unsigned flags,
975 const void *in_buf, size_t in_bufsz, size_t out_bufsz)
976 {
977 TPM_RESULT res;
978 bool exit_prg = FALSE;
979 ptm_init *init_p;
980
981 if (flags & FUSE_IOCTL_COMPAT) {
982 fuse_reply_err(req, ENOSYS);
983 return;
984 }
985
986 /* some commands have to wait until the worker thread is done */
987 switch(cmd) {
988 case PTM_GET_CAPABILITY:
989 case PTM_SET_LOCALITY:
990 case PTM_CANCEL_TPM_CMD:
991 case PTM_GET_CONFIG:
992 /* no need to wait */
993 break;
994 case PTM_INIT:
995 case PTM_SHUTDOWN:
996 case PTM_GET_TPMESTABLISHED:
997 case PTM_RESET_TPMESTABLISHED:
998 case PTM_HASH_START:
999 case PTM_HASH_DATA:
1000 case PTM_HASH_END:
1001 case PTM_STORE_VOLATILE:
1002 case PTM_GET_STATEBLOB:
1003 case PTM_SET_STATEBLOB:
1004 if (tpm_running)
1005 worker_thread_wait_done();
1006 break;
1007 }
1008
1009 /* prevent other threads from writing or doing ioctls */
1010 g_mutex_lock(FILE_OPS_LOCK);
1011
1012 switch (cmd) {
1013 case PTM_GET_CAPABILITY:
1014 if (out_bufsz != sizeof(ptm_cap)) {
1015 struct iovec iov = { arg, sizeof(uint8_t) };
1016 fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0);
1017 } else {
1018 ptm_cap ptm_caps;
1019 ptm_caps = PTM_CAP_INIT | PTM_CAP_SHUTDOWN
1020 | PTM_CAP_GET_TPMESTABLISHED
1021 | PTM_CAP_SET_LOCALITY
1022 | PTM_CAP_HASHING
1023 | PTM_CAP_CANCEL_TPM_CMD
1024 | PTM_CAP_STORE_VOLATILE
1025 | PTM_CAP_RESET_TPMESTABLISHED
1026 | PTM_CAP_GET_STATEBLOB
1027 | PTM_CAP_SET_STATEBLOB
1028 | PTM_CAP_STOP
1029 | PTM_CAP_GET_CONFIG;
1030 fuse_reply_ioctl(req, 0, &ptm_caps, sizeof(ptm_caps));
1031 }
1032 break;
1033
1034 case PTM_INIT:
1035 if (in_bufsz != sizeof(ptm_init)) {
1036 struct iovec iov = { arg, sizeof(uint8_t) };
1037 fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0);
1038 } else {
1039 init_p = (ptm_init *)in_buf;
1040
1041 worker_thread_end();
1042
1043 TPMLIB_Terminate();
1044
1045 tpm_running = 0;
1046 if ((res = tpm_start(init_p->u.req.init_flags))) {
1047 logprintf(STDERR_FILENO,
1048 "Error: Could not initialize the TPM.\n");
1049 } else {
1050 tpm_running = 1;
1051 }
1052 fuse_reply_ioctl(req, 0, &res, sizeof(res));
1053 }
1054 break;
1055
1056 case PTM_STOP:
1057 worker_thread_end();
1058
1059 res = TPM_SUCCESS;
1060 TPMLIB_Terminate();
1061
1062 tpm_running = 0;
1063
1064 TPM_Free(ptm_response);
1065 ptm_response = NULL;
1066
1067 fuse_reply_ioctl(req, 0, &res, sizeof(res));
1068
1069 break;
1070
1071 case PTM_SHUTDOWN:
1072 worker_thread_end();
1073
1074 res = TPM_SUCCESS;
1075 TPMLIB_Terminate();
1076
1077 TPM_Free(ptm_response);
1078 ptm_response = NULL;
1079
1080 fuse_reply_ioctl(req, 0, &res, sizeof(res));
1081 exit_prg = TRUE;
1082
1083 break;
1084
1085 case PTM_GET_TPMESTABLISHED:
1086 if (!tpm_running)
1087 goto error_not_running;
1088
1089 if (out_bufsz != sizeof(ptm_est)) {
1090 struct iovec iov = { arg, sizeof(uint8_t) };
1091 fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0);
1092 } else {
1093 ptm_est te;
1094 te.u.resp.tpm_result = TPM_IO_TpmEstablished_Get(&te.u.resp.bit);
1095 fuse_reply_ioctl(req, 0, &te, sizeof(te));
1096 }
1097 break;
1098
1099 case PTM_RESET_TPMESTABLISHED:
1100 if (!tpm_running)
1101 goto error_not_running;
1102
1103 if (in_bufsz != sizeof(ptm_reset_est)) {
1104 struct iovec iov = { arg, sizeof(uint32_t) };
1105 fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0);
1106 } else {
1107 ptm_reset_est *re = (ptm_reset_est *)in_buf;
1108 if (re->u.req.loc > 4) {
1109 res = TPM_BAD_LOCALITY;
1110 } else {
1111 res = _TPM_IO_TpmEstablished_Reset(req, re->u.req.loc);
1112 fuse_reply_ioctl(req, 0, &res, sizeof(res));
1113 }
1114 }
1115 break;
1116
1117 case PTM_SET_LOCALITY:
1118 if (in_bufsz != sizeof(ptm_loc)) {
1119 struct iovec iov = { arg, sizeof(uint32_t) };
1120 fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0);
1121 } else {
1122 ptm_loc *l = (ptm_loc *)in_buf;
1123 if (l->u.req.loc > 4) {
1124 res = TPM_BAD_LOCALITY;
1125 } else {
1126 res = 0;
1127 locality = l->u.req.loc;
1128 }
1129 fuse_reply_ioctl(req, 0, &res, sizeof(res));
1130 }
1131 break;
1132
1133 case PTM_HASH_START:
1134 if (!tpm_running)
1135 goto error_not_running;
1136
1137 res = TPM_IO_Hash_Start();
1138 fuse_reply_ioctl(req, 0, &res, sizeof(res));
1139 break;
1140
1141 case PTM_HASH_DATA:
1142 if (!tpm_running)
1143 goto error_not_running;
1144
1145 if (in_bufsz != sizeof(ptm_hdata)) {
1146 struct iovec iov = { arg, sizeof(uint32_t) };
1147 fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0);
1148 } else {
1149 ptm_hdata *data = (ptm_hdata *)in_buf;
1150 if (data->u.req.length <= sizeof(data->u.req.data)) {
1151 res = TPM_IO_Hash_Data(data->u.req.data,
1152 data->u.req.length);
1153 } else {
1154 res = TPM_FAIL;
1155 }
1156 fuse_reply_ioctl(req, 0, &res, sizeof(res));
1157 }
1158 break;
1159
1160 case PTM_HASH_END:
1161 if (!tpm_running)
1162 goto error_not_running;
1163
1164 res = TPM_IO_Hash_End();
1165 fuse_reply_ioctl(req, 0, &res, sizeof(res));
1166 break;
1167
1168 case PTM_CANCEL_TPM_CMD:
1169 if (!tpm_running)
1170 goto error_not_running;
1171
1172 /* for cancellation to work, the TPM would have to
1173 * execute in another thread that polls on a cancel
1174 * flag
1175 */
1176 res = TPM_FAIL;
1177 fuse_reply_ioctl(req, 0, &res, sizeof(res));
1178 break;
1179
1180 case PTM_STORE_VOLATILE:
1181 if (!tpm_running)
1182 goto error_not_running;
1183
1184 res = SWTPM_NVRAM_Store_Volatile();
1185 fuse_reply_ioctl(req, 0, &res, sizeof(res));
1186
1187 cached_stateblob_free();
1188 break;
1189
1190 case PTM_GET_STATEBLOB:
1191 if (!tpm_running)
1192 goto error_not_running;
1193
1194 if (in_bufsz != sizeof(ptm_getstate)) {
1195 struct iovec iov = { arg, sizeof(uint32_t) };
1196 fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0);
1197 } else {
1198 ptm_get_stateblob(req, (ptm_getstate *)in_buf);
1199 }
1200 break;
1201
1202 case PTM_SET_STATEBLOB:
1203 if (tpm_running)
1204 goto error_running;
1205
1206 /* tpm state dir must be set */
1207 SWTPM_NVRAM_Init();
1208
1209 if (in_bufsz != sizeof(ptm_setstate)) {
1210 struct iovec iov = { arg, sizeof(uint32_t) };
1211 fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0);
1212 } else {
1213 ptm_set_stateblob(req, (ptm_setstate *)in_buf);
1214 }
1215 break;
1216
1217 case PTM_GET_CONFIG:
1218 if (out_bufsz != sizeof(ptm_getconfig)) {
1219 struct iovec iov = { arg, sizeof(uint32_t) };
1220 fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0);
1221 } else {
1222 ptm_getconfig pgs;
1223 pgs.u.resp.tpm_result = 0;
1224 pgs.u.resp.flags = 0;
1225 if (SWTPM_NVRAM_Has_FileKey())
1226 pgs.u.resp.flags |= PTM_CONFIG_FLAG_FILE_KEY;
1227 if (SWTPM_NVRAM_Has_MigrationKey())
1228 pgs.u.resp.flags |= PTM_CONFIG_FLAG_MIGRATION_KEY;
1229 fuse_reply_ioctl(req, 0, &pgs, sizeof(pgs));
1230 }
1231 break;
1232
1233 default:
1234 fuse_reply_err(req, EINVAL);
1235 }
1236
1237 cleanup:
1238 g_mutex_unlock(FILE_OPS_LOCK);
1239
1240 if (exit_prg) {
1241 logprintf(STDOUT_FILENO,
1242 "CUSE TPM is shutting down.\n");
1243 exit(0);
1244 }
1245
1246 return;
1247
1248 error_running:
1249 error_not_running:
1250 res = TPM_BAD_ORDINAL;
1251 fuse_reply_ioctl(req, 0, &res, sizeof(res));
1252
1253 goto cleanup;
1254 }
1255
1256 static void ptm_init_done(void *userdata)
1257 {
1258 /* at this point the entry in /dev/ is available */
1259 if (pidfile_write(getpid()) < 0) {
1260 exit(-13);
1261 }
1262
1263 if (passwd) {
1264 if (initgroups(passwd->pw_name, passwd->pw_gid) < 0) {
1265 logprintf(STDERR_FILENO,
1266 "Error: initgroups(%s, %d) failed.\n",
1267 passwd->pw_name, passwd->pw_gid);
1268 exit(-10);
1269 }
1270 if (setgid(passwd->pw_gid) < 0) {
1271 logprintf(STDERR_FILENO,
1272 "Error: setgid(%d) failed.\n",
1273 passwd->pw_gid);
1274 exit(-11);
1275 }
1276 if (setuid(passwd->pw_uid) < 0) {
1277 logprintf(STDERR_FILENO,
1278 "Error: setuid(%d) failed.\n",
1279 passwd->pw_uid);
1280 exit(-12);
1281 }
1282 }
1283 }
1284
1285 static const struct cuse_lowlevel_ops ptm_clop = {
1286 .open = ptm_open,
1287 .read = ptm_read,
1288 .write = ptm_write,
1289 .ioctl = ptm_ioctl,
1290 .init_done = ptm_init_done,
1291 };
1292
1293 #define PTM_OPT(t, p) { t, offsetof(struct ptm_param, p), 1 }
1294
1295 static const struct fuse_opt ptm_opts[] = {
1296 PTM_OPT("-M %u", major),
1297 PTM_OPT("--maj=%u", major),
1298 PTM_OPT("-m %u", minor),
1299 PTM_OPT("--min=%u", minor),
1300 PTM_OPT("-n %s", dev_name),
1301 PTM_OPT("--name=%s", dev_name),
1302 PTM_OPT("-r %s", runas),
1303 PTM_OPT("--runas=%s", runas),
1304 PTM_OPT("--log %s", logging),
1305 PTM_OPT("--key %s", keydata),
1306 PTM_OPT("--migration-key %s", migkeydata),
1307 PTM_OPT("--pid %s", piddata),
1308 FUSE_OPT_KEY("-h", 0),
1309 FUSE_OPT_KEY("--help", 0),
1310 FUSE_OPT_KEY("-v", 1),
1311 FUSE_OPT_KEY("--version", 1),
1312 FUSE_OPT_END
1313 };
1314
1315 static int ptm_process_arg(void *data, const char *arg, int key,
1316 struct fuse_args *outargs)
1317 {
1318 struct ptm_param *param = data;
1319
1320 switch (key) {
1321 case 0:
1322 param->is_help = 1;
1323 fprintf(stdout, usage, param->prgname);
1324 return fuse_opt_add_arg(outargs, "-ho");
1325 case 1:
1326 param->is_help = 1;
1327 fprintf(stdout, "TPM emulator CUSE interface version %d.%d.%d, "
1328 "Copyright (c) 2014 IBM Corp.\n",
1329 SWTPM_VER_MAJOR,
1330 SWTPM_VER_MINOR,
1331 SWTPM_VER_MICRO);
1332 return 0;
1333 default:
1334 return -1;
1335 }
1336 return 0;
1337 }
1338
1339 int main(int argc, char **argv)
1340 {
1341 struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
1342 struct ptm_param param = {
1343 .major = 0,
1344 .minor = 0,
1345 .dev_name = NULL,
1346 .is_help = 0,
1347 .prgname = argv[0],
1348 .runas = NULL,
1349 .logging = NULL,
1350 .keydata = NULL,
1351 .migkeydata = NULL,
1352 };
1353 char dev_name[128] = "DEVNAME=";
1354 const char *dev_info_argv[] = { dev_name };
1355 struct cuse_info ci;
1356 int ret;
1357
1358 if ((ret = fuse_opt_parse(&args, &param, ptm_opts, ptm_process_arg))) {
1359 fprintf(stderr, "Error: Could not parse option\n");
1360 return ret;
1361 }
1362
1363 if (!param.is_help) {
1364 if (!param.dev_name) {
1365 fprintf(stderr, "Error: device name missing\n");
1366 return -2;
1367 }
1368 strncat(dev_name, param.dev_name, sizeof(dev_name) - 9);
1369 } else {
1370 return 0;
1371 }
1372
1373 if (handle_log_options(param.logging) < 0 ||
1374 handle_key_options(param.keydata) < 0 ||
1375 handle_migration_key_options(param.migkeydata) < 0 ||
1376 handle_pid_options(param.piddata) < 0)
1377 return -3;
1378
1379 if (setuid(0)) {
1380 fprintf(stderr, "Error: Unable to setuid root. uid = %d, "
1381 "euid = %d, gid = %d\n", getuid(), geteuid(), getgid());
1382 return -4;
1383 }
1384
1385 if (param.runas) {
1386 if (!(passwd = getpwnam(param.runas))) {
1387 fprintf(stderr, "User '%s' does not exist\n",
1388 param.runas);
1389 return -5;
1390 }
1391 }
1392
1393 memset(&ci, 0, sizeof(ci));
1394 ci.dev_major = param.major;
1395 ci.dev_minor = param.minor;
1396 ci.dev_info_argc = 1;
1397 ci.dev_info_argv = dev_info_argv;
1398
1399 #if GLIB_MINOR_VERSION >= 32
1400 g_mutex_init(THREAD_BUSY_LOCK);
1401 g_cond_init(THREAD_BUSY_SIGNAL);
1402 g_mutex_init(FILE_OPS_LOCK);
1403 #else
1404 g_thread_init(NULL);
1405 THREAD_BUSY_LOCK = g_mutex_new();
1406 THREAD_BUSY_SIGNAL = g_cond_new();
1407 FILE_OPS_LOCK = g_mutex_new();
1408 #endif
1409
1410 return cuse_lowlevel_main(args.argc, args.argv, &ci, &ptm_clop,
1411 &param);
1412 }