xref: /qemu/backends/tpm/tpm_emulator.c (revision d0fb9657)
1 /*
2  *  Emulator TPM driver
3  *
4  *  Copyright (c) 2017 Intel Corporation
5  *  Author: Amarnath Valluri <amarnath.valluri@intel.com>
6  *
7  *  Copyright (c) 2010 - 2013, 2018 IBM Corporation
8  *  Authors:
9  *    Stefan Berger <stefanb@us.ibm.com>
10  *
11  *  Copyright (C) 2011 IAIK, Graz University of Technology
12  *    Author: Andreas Niederl
13  *
14  * This library is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU Lesser General Public
16  * License as published by the Free Software Foundation; either
17  * version 2.1 of the License, or (at your option) any later version.
18  *
19  * This library is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22  * Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public
25  * License along with this library; if not, see <http://www.gnu.org/licenses/>
26  *
27  */
28 
29 #include "qemu/osdep.h"
30 #include "qemu/error-report.h"
31 #include "qemu/module.h"
32 #include "qemu/sockets.h"
33 #include "qemu/lockable.h"
34 #include "io/channel-socket.h"
35 #include "sysemu/tpm_backend.h"
36 #include "sysemu/tpm_util.h"
37 #include "tpm_int.h"
38 #include "tpm_ioctl.h"
39 #include "migration/blocker.h"
40 #include "migration/vmstate.h"
41 #include "qapi/error.h"
42 #include "qapi/clone-visitor.h"
43 #include "qapi/qapi-visit-tpm.h"
44 #include "chardev/char-fe.h"
45 #include "trace.h"
46 #include "qom/object.h"
47 
48 #define TYPE_TPM_EMULATOR "tpm-emulator"
49 OBJECT_DECLARE_SIMPLE_TYPE(TPMEmulator, TPM_EMULATOR)
50 
51 #define TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(S, cap) (((S)->caps & (cap)) == (cap))
52 
53 /* data structures */
54 
55 /* blobs from the TPM; part of VM state when migrating */
56 typedef struct TPMBlobBuffers {
57     uint32_t permanent_flags;
58     TPMSizedBuffer permanent;
59 
60     uint32_t volatil_flags;
61     TPMSizedBuffer volatil;
62 
63     uint32_t savestate_flags;
64     TPMSizedBuffer savestate;
65 } TPMBlobBuffers;
66 
67 struct TPMEmulator {
68     TPMBackend parent;
69 
70     TPMEmulatorOptions *options;
71     CharBackend ctrl_chr;
72     QIOChannel *data_ioc;
73     TPMVersion tpm_version;
74     ptm_cap caps; /* capabilities of the TPM */
75     uint8_t cur_locty_number; /* last set locality */
76     Error *migration_blocker;
77 
78     QemuMutex mutex;
79 
80     unsigned int established_flag:1;
81     unsigned int established_flag_cached:1;
82 
83     TPMBlobBuffers state_blobs;
84 };
85 
86 struct tpm_error {
87     uint32_t tpm_result;
88     const char *string;
89 };
90 
91 static const struct tpm_error tpm_errors[] = {
92     /* TPM 1.2 error codes */
93     { TPM_BAD_PARAMETER   , "a parameter is bad" },
94     { TPM_FAIL            , "operation failed" },
95     { TPM_KEYNOTFOUND     , "key could not be found" },
96     { TPM_BAD_PARAM_SIZE  , "bad parameter size"},
97     { TPM_ENCRYPT_ERROR   , "encryption error" },
98     { TPM_DECRYPT_ERROR   , "decryption error" },
99     { TPM_BAD_KEY_PROPERTY, "bad key property" },
100     { TPM_BAD_MODE        , "bad (encryption) mode" },
101     { TPM_BAD_VERSION     , "bad version identifier" },
102     { TPM_BAD_LOCALITY    , "bad locality" },
103     /* TPM 2 error codes */
104     { TPM_RC_FAILURE     , "operation failed" },
105     { TPM_RC_LOCALITY    , "bad locality"     },
106     { TPM_RC_INSUFFICIENT, "insufficient amount of data" },
107 };
108 
109 static const char *tpm_emulator_strerror(uint32_t tpm_result)
110 {
111     size_t i;
112 
113     for (i = 0; i < ARRAY_SIZE(tpm_errors); i++) {
114         if (tpm_errors[i].tpm_result == tpm_result) {
115             return tpm_errors[i].string;
116         }
117     }
118     return "";
119 }
120 
121 static int tpm_emulator_ctrlcmd(TPMEmulator *tpm, unsigned long cmd, void *msg,
122                                 size_t msg_len_in, size_t msg_len_out)
123 {
124     CharBackend *dev = &tpm->ctrl_chr;
125     uint32_t cmd_no = cpu_to_be32(cmd);
126     ssize_t n = sizeof(uint32_t) + msg_len_in;
127     uint8_t *buf = NULL;
128 
129     WITH_QEMU_LOCK_GUARD(&tpm->mutex) {
130         buf = g_alloca(n);
131         memcpy(buf, &cmd_no, sizeof(cmd_no));
132         memcpy(buf + sizeof(cmd_no), msg, msg_len_in);
133 
134         n = qemu_chr_fe_write_all(dev, buf, n);
135         if (n <= 0) {
136             return -1;
137         }
138 
139         if (msg_len_out != 0) {
140             n = qemu_chr_fe_read_all(dev, msg, msg_len_out);
141             if (n <= 0) {
142                 return -1;
143             }
144         }
145     }
146 
147     return 0;
148 }
149 
150 static int tpm_emulator_unix_tx_bufs(TPMEmulator *tpm_emu,
151                                      const uint8_t *in, uint32_t in_len,
152                                      uint8_t *out, uint32_t out_len,
153                                      bool *selftest_done,
154                                      Error **errp)
155 {
156     ssize_t ret;
157     bool is_selftest = false;
158 
159     if (selftest_done) {
160         *selftest_done = false;
161         is_selftest = tpm_util_is_selftest(in, in_len);
162     }
163 
164     ret = qio_channel_write_all(tpm_emu->data_ioc, (char *)in, in_len, errp);
165     if (ret != 0) {
166         return -1;
167     }
168 
169     ret = qio_channel_read_all(tpm_emu->data_ioc, (char *)out,
170               sizeof(struct tpm_resp_hdr), errp);
171     if (ret != 0) {
172         return -1;
173     }
174 
175     ret = qio_channel_read_all(tpm_emu->data_ioc,
176               (char *)out + sizeof(struct tpm_resp_hdr),
177               tpm_cmd_get_size(out) - sizeof(struct tpm_resp_hdr), errp);
178     if (ret != 0) {
179         return -1;
180     }
181 
182     if (is_selftest) {
183         *selftest_done = tpm_cmd_get_errcode(out) == 0;
184     }
185 
186     return 0;
187 }
188 
189 static int tpm_emulator_set_locality(TPMEmulator *tpm_emu, uint8_t locty_number,
190                                      Error **errp)
191 {
192     ptm_loc loc;
193 
194     if (tpm_emu->cur_locty_number == locty_number) {
195         return 0;
196     }
197 
198     trace_tpm_emulator_set_locality(locty_number);
199 
200     memset(&loc, 0, sizeof(loc));
201     loc.u.req.loc = locty_number;
202     if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_LOCALITY, &loc,
203                              sizeof(loc), sizeof(loc)) < 0) {
204         error_setg(errp, "tpm-emulator: could not set locality : %s",
205                    strerror(errno));
206         return -1;
207     }
208 
209     loc.u.resp.tpm_result = be32_to_cpu(loc.u.resp.tpm_result);
210     if (loc.u.resp.tpm_result != 0) {
211         error_setg(errp, "tpm-emulator: TPM result for set locality : 0x%x",
212                    loc.u.resp.tpm_result);
213         return -1;
214     }
215 
216     tpm_emu->cur_locty_number = locty_number;
217 
218     return 0;
219 }
220 
221 static void tpm_emulator_handle_request(TPMBackend *tb, TPMBackendCmd *cmd,
222                                         Error **errp)
223 {
224     TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
225 
226     trace_tpm_emulator_handle_request();
227 
228     if (tpm_emulator_set_locality(tpm_emu, cmd->locty, errp) < 0 ||
229         tpm_emulator_unix_tx_bufs(tpm_emu, cmd->in, cmd->in_len,
230                                   cmd->out, cmd->out_len,
231                                   &cmd->selftest_done, errp) < 0) {
232         tpm_util_write_fatal_error_response(cmd->out, cmd->out_len);
233     }
234 }
235 
236 static int tpm_emulator_probe_caps(TPMEmulator *tpm_emu)
237 {
238     if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_CAPABILITY,
239                              &tpm_emu->caps, 0, sizeof(tpm_emu->caps)) < 0) {
240         error_report("tpm-emulator: probing failed : %s", strerror(errno));
241         return -1;
242     }
243 
244     tpm_emu->caps = be64_to_cpu(tpm_emu->caps);
245 
246     trace_tpm_emulator_probe_caps(tpm_emu->caps);
247 
248     return 0;
249 }
250 
251 static int tpm_emulator_check_caps(TPMEmulator *tpm_emu)
252 {
253     ptm_cap caps = 0;
254     const char *tpm = NULL;
255 
256     /* check for min. required capabilities */
257     switch (tpm_emu->tpm_version) {
258     case TPM_VERSION_1_2:
259         caps = PTM_CAP_INIT | PTM_CAP_SHUTDOWN | PTM_CAP_GET_TPMESTABLISHED |
260                PTM_CAP_SET_LOCALITY | PTM_CAP_SET_DATAFD | PTM_CAP_STOP |
261                PTM_CAP_SET_BUFFERSIZE;
262         tpm = "1.2";
263         break;
264     case TPM_VERSION_2_0:
265         caps = PTM_CAP_INIT | PTM_CAP_SHUTDOWN | PTM_CAP_GET_TPMESTABLISHED |
266                PTM_CAP_SET_LOCALITY | PTM_CAP_RESET_TPMESTABLISHED |
267                PTM_CAP_SET_DATAFD | PTM_CAP_STOP | PTM_CAP_SET_BUFFERSIZE;
268         tpm = "2";
269         break;
270     case TPM_VERSION_UNSPEC:
271         error_report("tpm-emulator: TPM version has not been set");
272         return -1;
273     }
274 
275     if (!TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(tpm_emu, caps)) {
276         error_report("tpm-emulator: TPM does not implement minimum set of "
277                      "required capabilities for TPM %s (0x%x)", tpm, (int)caps);
278         return -1;
279     }
280 
281     return 0;
282 }
283 
284 static int tpm_emulator_stop_tpm(TPMBackend *tb)
285 {
286     TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
287     ptm_res res;
288 
289     if (tpm_emulator_ctrlcmd(tpm_emu, CMD_STOP, &res, 0, sizeof(res)) < 0) {
290         error_report("tpm-emulator: Could not stop TPM: %s",
291                      strerror(errno));
292         return -1;
293     }
294 
295     res = be32_to_cpu(res);
296     if (res) {
297         error_report("tpm-emulator: TPM result for CMD_STOP: 0x%x %s", res,
298                      tpm_emulator_strerror(res));
299         return -1;
300     }
301 
302     return 0;
303 }
304 
305 static int tpm_emulator_set_buffer_size(TPMBackend *tb,
306                                         size_t wanted_size,
307                                         size_t *actual_size)
308 {
309     TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
310     ptm_setbuffersize psbs;
311 
312     if (tpm_emulator_stop_tpm(tb) < 0) {
313         return -1;
314     }
315 
316     psbs.u.req.buffersize = cpu_to_be32(wanted_size);
317 
318     if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_BUFFERSIZE, &psbs,
319                              sizeof(psbs.u.req), sizeof(psbs.u.resp)) < 0) {
320         error_report("tpm-emulator: Could not set buffer size: %s",
321                      strerror(errno));
322         return -1;
323     }
324 
325     psbs.u.resp.tpm_result = be32_to_cpu(psbs.u.resp.tpm_result);
326     if (psbs.u.resp.tpm_result != 0) {
327         error_report("tpm-emulator: TPM result for set buffer size : 0x%x %s",
328                      psbs.u.resp.tpm_result,
329                      tpm_emulator_strerror(psbs.u.resp.tpm_result));
330         return -1;
331     }
332 
333     if (actual_size) {
334         *actual_size = be32_to_cpu(psbs.u.resp.buffersize);
335     }
336 
337     trace_tpm_emulator_set_buffer_size(
338             be32_to_cpu(psbs.u.resp.buffersize),
339             be32_to_cpu(psbs.u.resp.minsize),
340             be32_to_cpu(psbs.u.resp.maxsize));
341 
342     return 0;
343 }
344 
345 static int tpm_emulator_startup_tpm_resume(TPMBackend *tb, size_t buffersize,
346                                      bool is_resume)
347 {
348     TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
349     ptm_init init = {
350         .u.req.init_flags = 0,
351     };
352     ptm_res res;
353 
354     trace_tpm_emulator_startup_tpm_resume(is_resume, buffersize);
355 
356     if (buffersize != 0 &&
357         tpm_emulator_set_buffer_size(tb, buffersize, NULL) < 0) {
358         goto err_exit;
359     }
360 
361     if (is_resume) {
362         init.u.req.init_flags |= cpu_to_be32(PTM_INIT_FLAG_DELETE_VOLATILE);
363     }
364 
365     if (tpm_emulator_ctrlcmd(tpm_emu, CMD_INIT, &init, sizeof(init),
366                              sizeof(init)) < 0) {
367         error_report("tpm-emulator: could not send INIT: %s",
368                      strerror(errno));
369         goto err_exit;
370     }
371 
372     res = be32_to_cpu(init.u.resp.tpm_result);
373     if (res) {
374         error_report("tpm-emulator: TPM result for CMD_INIT: 0x%x %s", res,
375                      tpm_emulator_strerror(res));
376         goto err_exit;
377     }
378     return 0;
379 
380 err_exit:
381     return -1;
382 }
383 
384 static int tpm_emulator_startup_tpm(TPMBackend *tb, size_t buffersize)
385 {
386     return tpm_emulator_startup_tpm_resume(tb, buffersize, false);
387 }
388 
389 static bool tpm_emulator_get_tpm_established_flag(TPMBackend *tb)
390 {
391     TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
392     ptm_est est;
393 
394     if (tpm_emu->established_flag_cached) {
395         return tpm_emu->established_flag;
396     }
397 
398     if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_TPMESTABLISHED, &est,
399                              0, sizeof(est)) < 0) {
400         error_report("tpm-emulator: Could not get the TPM established flag: %s",
401                      strerror(errno));
402         return false;
403     }
404     trace_tpm_emulator_get_tpm_established_flag(est.u.resp.bit);
405 
406     tpm_emu->established_flag_cached = 1;
407     tpm_emu->established_flag = (est.u.resp.bit != 0);
408 
409     return tpm_emu->established_flag;
410 }
411 
412 static int tpm_emulator_reset_tpm_established_flag(TPMBackend *tb,
413                                                    uint8_t locty)
414 {
415     TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
416     ptm_reset_est reset_est;
417     ptm_res res;
418 
419     /* only a TPM 2.0 will support this */
420     if (tpm_emu->tpm_version != TPM_VERSION_2_0) {
421         return 0;
422     }
423 
424     reset_est.u.req.loc = tpm_emu->cur_locty_number;
425     if (tpm_emulator_ctrlcmd(tpm_emu, CMD_RESET_TPMESTABLISHED,
426                              &reset_est, sizeof(reset_est),
427                              sizeof(reset_est)) < 0) {
428         error_report("tpm-emulator: Could not reset the establishment bit: %s",
429                      strerror(errno));
430         return -1;
431     }
432 
433     res = be32_to_cpu(reset_est.u.resp.tpm_result);
434     if (res) {
435         error_report(
436             "tpm-emulator: TPM result for rest established flag: 0x%x %s",
437             res, tpm_emulator_strerror(res));
438         return -1;
439     }
440 
441     tpm_emu->established_flag_cached = 0;
442 
443     return 0;
444 }
445 
446 static void tpm_emulator_cancel_cmd(TPMBackend *tb)
447 {
448     TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
449     ptm_res res;
450 
451     if (!TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(tpm_emu, PTM_CAP_CANCEL_TPM_CMD)) {
452         trace_tpm_emulator_cancel_cmd_not_supt();
453         return;
454     }
455 
456     /* FIXME: make the function non-blocking, or it may block a VCPU */
457     if (tpm_emulator_ctrlcmd(tpm_emu, CMD_CANCEL_TPM_CMD, &res, 0,
458                              sizeof(res)) < 0) {
459         error_report("tpm-emulator: Could not cancel command: %s",
460                      strerror(errno));
461     } else if (res != 0) {
462         error_report("tpm-emulator: Failed to cancel TPM: 0x%x",
463                      be32_to_cpu(res));
464     }
465 }
466 
467 static TPMVersion tpm_emulator_get_tpm_version(TPMBackend *tb)
468 {
469     TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
470 
471     return tpm_emu->tpm_version;
472 }
473 
474 static size_t tpm_emulator_get_buffer_size(TPMBackend *tb)
475 {
476     size_t actual_size;
477 
478     if (tpm_emulator_set_buffer_size(tb, 0, &actual_size) < 0) {
479         return 4096;
480     }
481 
482     return actual_size;
483 }
484 
485 static int tpm_emulator_block_migration(TPMEmulator *tpm_emu)
486 {
487     Error *err = NULL;
488     ptm_cap caps = PTM_CAP_GET_STATEBLOB | PTM_CAP_SET_STATEBLOB |
489                    PTM_CAP_STOP;
490 
491     if (!TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(tpm_emu, caps)) {
492         error_setg(&tpm_emu->migration_blocker,
493                    "Migration disabled: TPM emulator does not support "
494                    "migration");
495         migrate_add_blocker(tpm_emu->migration_blocker, &err);
496         if (err) {
497             error_report_err(err);
498             error_free(tpm_emu->migration_blocker);
499             tpm_emu->migration_blocker = NULL;
500 
501             return -1;
502         }
503     }
504 
505     return 0;
506 }
507 
508 static int tpm_emulator_prepare_data_fd(TPMEmulator *tpm_emu)
509 {
510     ptm_res res;
511     Error *err = NULL;
512     int fds[2] = { -1, -1 };
513 
514     if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
515         error_report("tpm-emulator: Failed to create socketpair");
516         return -1;
517     }
518 
519     qemu_chr_fe_set_msgfds(&tpm_emu->ctrl_chr, fds + 1, 1);
520 
521     if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_DATAFD, &res, 0,
522                              sizeof(res)) < 0 || res != 0) {
523         error_report("tpm-emulator: Failed to send CMD_SET_DATAFD: %s",
524                      strerror(errno));
525         goto err_exit;
526     }
527 
528     tpm_emu->data_ioc = QIO_CHANNEL(qio_channel_socket_new_fd(fds[0], &err));
529     if (err) {
530         error_prepend(&err, "tpm-emulator: Failed to create io channel: ");
531         error_report_err(err);
532         goto err_exit;
533     }
534 
535     closesocket(fds[1]);
536 
537     return 0;
538 
539 err_exit:
540     closesocket(fds[0]);
541     closesocket(fds[1]);
542     return -1;
543 }
544 
545 static int tpm_emulator_handle_device_opts(TPMEmulator *tpm_emu, QemuOpts *opts)
546 {
547     const char *value;
548     Error *err = NULL;
549     Chardev *dev;
550 
551     value = qemu_opt_get(opts, "chardev");
552     if (!value) {
553         error_report("tpm-emulator: parameter 'chardev' is missing");
554         goto err;
555     }
556 
557     dev = qemu_chr_find(value);
558     if (!dev) {
559         error_report("tpm-emulator: tpm chardev '%s' not found", value);
560         goto err;
561     }
562 
563     if (!qemu_chr_fe_init(&tpm_emu->ctrl_chr, dev, &err)) {
564         error_prepend(&err, "tpm-emulator: No valid chardev found at '%s':",
565                       value);
566         error_report_err(err);
567         goto err;
568     }
569 
570     tpm_emu->options->chardev = g_strdup(value);
571 
572     if (tpm_emulator_prepare_data_fd(tpm_emu) < 0) {
573         goto err;
574     }
575 
576     /* FIXME: tpm_util_test_tpmdev() accepts only on socket fd, as it also used
577      * by passthrough driver, which not yet using GIOChannel.
578      */
579     if (tpm_util_test_tpmdev(QIO_CHANNEL_SOCKET(tpm_emu->data_ioc)->fd,
580                              &tpm_emu->tpm_version)) {
581         error_report("'%s' is not emulating TPM device. Error: %s",
582                       tpm_emu->options->chardev, strerror(errno));
583         goto err;
584     }
585 
586     switch (tpm_emu->tpm_version) {
587     case TPM_VERSION_1_2:
588         trace_tpm_emulator_handle_device_opts_tpm12();
589         break;
590     case TPM_VERSION_2_0:
591         trace_tpm_emulator_handle_device_opts_tpm2();
592         break;
593     default:
594         trace_tpm_emulator_handle_device_opts_unspec();
595     }
596 
597     if (tpm_emulator_probe_caps(tpm_emu) ||
598         tpm_emulator_check_caps(tpm_emu)) {
599         goto err;
600     }
601 
602     return tpm_emulator_block_migration(tpm_emu);
603 
604 err:
605     trace_tpm_emulator_handle_device_opts_startup_error();
606 
607     return -1;
608 }
609 
610 static TPMBackend *tpm_emulator_create(QemuOpts *opts)
611 {
612     TPMBackend *tb = TPM_BACKEND(object_new(TYPE_TPM_EMULATOR));
613 
614     if (tpm_emulator_handle_device_opts(TPM_EMULATOR(tb), opts)) {
615         object_unref(OBJECT(tb));
616         return NULL;
617     }
618 
619     return tb;
620 }
621 
622 static TpmTypeOptions *tpm_emulator_get_tpm_options(TPMBackend *tb)
623 {
624     TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
625     TpmTypeOptions *options = g_new0(TpmTypeOptions, 1);
626 
627     options->type = TPM_TYPE_OPTIONS_KIND_EMULATOR;
628     options->u.emulator.data = QAPI_CLONE(TPMEmulatorOptions, tpm_emu->options);
629 
630     return options;
631 }
632 
633 static const QemuOptDesc tpm_emulator_cmdline_opts[] = {
634     TPM_STANDARD_CMDLINE_OPTS,
635     {
636         .name = "chardev",
637         .type = QEMU_OPT_STRING,
638         .help = "Character device to use for out-of-band control messages",
639     },
640     { /* end of list */ },
641 };
642 
643 /*
644  * Transfer a TPM state blob from the TPM into a provided buffer.
645  *
646  * @tpm_emu: TPMEmulator
647  * @type: the type of blob to transfer
648  * @tsb: the TPMSizeBuffer to fill with the blob
649  * @flags: the flags to return to the caller
650  */
651 static int tpm_emulator_get_state_blob(TPMEmulator *tpm_emu,
652                                        uint8_t type,
653                                        TPMSizedBuffer *tsb,
654                                        uint32_t *flags)
655 {
656     ptm_getstate pgs;
657     ptm_res res;
658     ssize_t n;
659     uint32_t totlength, length;
660 
661     tpm_sized_buffer_reset(tsb);
662 
663     pgs.u.req.state_flags = cpu_to_be32(PTM_STATE_FLAG_DECRYPTED);
664     pgs.u.req.type = cpu_to_be32(type);
665     pgs.u.req.offset = 0;
666 
667     if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_STATEBLOB,
668                              &pgs, sizeof(pgs.u.req),
669                              offsetof(ptm_getstate, u.resp.data)) < 0) {
670         error_report("tpm-emulator: could not get state blob type %d : %s",
671                      type, strerror(errno));
672         return -1;
673     }
674 
675     res = be32_to_cpu(pgs.u.resp.tpm_result);
676     if (res != 0 && (res & 0x800) == 0) {
677         error_report("tpm-emulator: Getting the stateblob (type %d) failed "
678                      "with a TPM error 0x%x %s", type, res,
679                      tpm_emulator_strerror(res));
680         return -1;
681     }
682 
683     totlength = be32_to_cpu(pgs.u.resp.totlength);
684     length = be32_to_cpu(pgs.u.resp.length);
685     if (totlength != length) {
686         error_report("tpm-emulator: Expecting to read %u bytes "
687                      "but would get %u", totlength, length);
688         return -1;
689     }
690 
691     *flags = be32_to_cpu(pgs.u.resp.state_flags);
692 
693     if (totlength > 0) {
694         tsb->buffer = g_try_malloc(totlength);
695         if (!tsb->buffer) {
696             error_report("tpm-emulator: Out of memory allocating %u bytes",
697                          totlength);
698             return -1;
699         }
700 
701         n = qemu_chr_fe_read_all(&tpm_emu->ctrl_chr, tsb->buffer, totlength);
702         if (n != totlength) {
703             error_report("tpm-emulator: Could not read stateblob (type %d); "
704                          "expected %u bytes, got %zd",
705                          type, totlength, n);
706             return -1;
707         }
708     }
709     tsb->size = totlength;
710 
711     trace_tpm_emulator_get_state_blob(type, tsb->size, *flags);
712 
713     return 0;
714 }
715 
716 static int tpm_emulator_get_state_blobs(TPMEmulator *tpm_emu)
717 {
718     TPMBlobBuffers *state_blobs = &tpm_emu->state_blobs;
719 
720     if (tpm_emulator_get_state_blob(tpm_emu, PTM_BLOB_TYPE_PERMANENT,
721                                     &state_blobs->permanent,
722                                     &state_blobs->permanent_flags) < 0 ||
723         tpm_emulator_get_state_blob(tpm_emu, PTM_BLOB_TYPE_VOLATILE,
724                                     &state_blobs->volatil,
725                                     &state_blobs->volatil_flags) < 0 ||
726         tpm_emulator_get_state_blob(tpm_emu, PTM_BLOB_TYPE_SAVESTATE,
727                                     &state_blobs->savestate,
728                                     &state_blobs->savestate_flags) < 0) {
729         goto err_exit;
730     }
731 
732     return 0;
733 
734  err_exit:
735     tpm_sized_buffer_reset(&state_blobs->volatil);
736     tpm_sized_buffer_reset(&state_blobs->permanent);
737     tpm_sized_buffer_reset(&state_blobs->savestate);
738 
739     return -1;
740 }
741 
742 /*
743  * Transfer a TPM state blob to the TPM emulator.
744  *
745  * @tpm_emu: TPMEmulator
746  * @type: the type of TPM state blob to transfer
747  * @tsb: TPMSizedBuffer containing the TPM state blob
748  * @flags: Flags describing the (encryption) state of the TPM state blob
749  */
750 static int tpm_emulator_set_state_blob(TPMEmulator *tpm_emu,
751                                        uint32_t type,
752                                        TPMSizedBuffer *tsb,
753                                        uint32_t flags)
754 {
755     ssize_t n;
756     ptm_setstate pss;
757     ptm_res tpm_result;
758 
759     if (tsb->size == 0) {
760         return 0;
761     }
762 
763     pss = (ptm_setstate) {
764         .u.req.state_flags = cpu_to_be32(flags),
765         .u.req.type = cpu_to_be32(type),
766         .u.req.length = cpu_to_be32(tsb->size),
767     };
768 
769     /* write the header only */
770     if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_STATEBLOB, &pss,
771                              offsetof(ptm_setstate, u.req.data), 0) < 0) {
772         error_report("tpm-emulator: could not set state blob type %d : %s",
773                      type, strerror(errno));
774         return -1;
775     }
776 
777     /* now the body */
778     n = qemu_chr_fe_write_all(&tpm_emu->ctrl_chr, tsb->buffer, tsb->size);
779     if (n != tsb->size) {
780         error_report("tpm-emulator: Writing the stateblob (type %d) "
781                      "failed; could not write %u bytes, but only %zd",
782                      type, tsb->size, n);
783         return -1;
784     }
785 
786     /* now get the result */
787     n = qemu_chr_fe_read_all(&tpm_emu->ctrl_chr,
788                              (uint8_t *)&pss, sizeof(pss.u.resp));
789     if (n != sizeof(pss.u.resp)) {
790         error_report("tpm-emulator: Reading response from writing stateblob "
791                      "(type %d) failed; expected %zu bytes, got %zd", type,
792                      sizeof(pss.u.resp), n);
793         return -1;
794     }
795 
796     tpm_result = be32_to_cpu(pss.u.resp.tpm_result);
797     if (tpm_result != 0) {
798         error_report("tpm-emulator: Setting the stateblob (type %d) failed "
799                      "with a TPM error 0x%x %s", type, tpm_result,
800                      tpm_emulator_strerror(tpm_result));
801         return -1;
802     }
803 
804     trace_tpm_emulator_set_state_blob(type, tsb->size, flags);
805 
806     return 0;
807 }
808 
809 /*
810  * Set all the TPM state blobs.
811  *
812  * Returns a negative errno code in case of error.
813  */
814 static int tpm_emulator_set_state_blobs(TPMBackend *tb)
815 {
816     TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
817     TPMBlobBuffers *state_blobs = &tpm_emu->state_blobs;
818 
819     trace_tpm_emulator_set_state_blobs();
820 
821     if (tpm_emulator_stop_tpm(tb) < 0) {
822         trace_tpm_emulator_set_state_blobs_error("Could not stop TPM");
823         return -EIO;
824     }
825 
826     if (tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_PERMANENT,
827                                     &state_blobs->permanent,
828                                     state_blobs->permanent_flags) < 0 ||
829         tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_VOLATILE,
830                                     &state_blobs->volatil,
831                                     state_blobs->volatil_flags) < 0 ||
832         tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_SAVESTATE,
833                                     &state_blobs->savestate,
834                                     state_blobs->savestate_flags) < 0) {
835         return -EIO;
836     }
837 
838     trace_tpm_emulator_set_state_blobs_done();
839 
840     return 0;
841 }
842 
843 static int tpm_emulator_pre_save(void *opaque)
844 {
845     TPMBackend *tb = opaque;
846     TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
847 
848     trace_tpm_emulator_pre_save();
849 
850     tpm_backend_finish_sync(tb);
851 
852     /* get the state blobs from the TPM */
853     return tpm_emulator_get_state_blobs(tpm_emu);
854 }
855 
856 /*
857  * Load the TPM state blobs into the TPM.
858  *
859  * Returns negative errno codes in case of error.
860  */
861 static int tpm_emulator_post_load(void *opaque, int version_id)
862 {
863     TPMBackend *tb = opaque;
864     int ret;
865 
866     ret = tpm_emulator_set_state_blobs(tb);
867     if (ret < 0) {
868         return ret;
869     }
870 
871     if (tpm_emulator_startup_tpm_resume(tb, 0, true) < 0) {
872         return -EIO;
873     }
874 
875     return 0;
876 }
877 
878 static const VMStateDescription vmstate_tpm_emulator = {
879     .name = "tpm-emulator",
880     .version_id = 0,
881     .pre_save = tpm_emulator_pre_save,
882     .post_load = tpm_emulator_post_load,
883     .fields = (VMStateField[]) {
884         VMSTATE_UINT32(state_blobs.permanent_flags, TPMEmulator),
885         VMSTATE_UINT32(state_blobs.permanent.size, TPMEmulator),
886         VMSTATE_VBUFFER_ALLOC_UINT32(state_blobs.permanent.buffer,
887                                      TPMEmulator, 0, 0,
888                                      state_blobs.permanent.size),
889 
890         VMSTATE_UINT32(state_blobs.volatil_flags, TPMEmulator),
891         VMSTATE_UINT32(state_blobs.volatil.size, TPMEmulator),
892         VMSTATE_VBUFFER_ALLOC_UINT32(state_blobs.volatil.buffer,
893                                      TPMEmulator, 0, 0,
894                                      state_blobs.volatil.size),
895 
896         VMSTATE_UINT32(state_blobs.savestate_flags, TPMEmulator),
897         VMSTATE_UINT32(state_blobs.savestate.size, TPMEmulator),
898         VMSTATE_VBUFFER_ALLOC_UINT32(state_blobs.savestate.buffer,
899                                      TPMEmulator, 0, 0,
900                                      state_blobs.savestate.size),
901 
902         VMSTATE_END_OF_LIST()
903     }
904 };
905 
906 static void tpm_emulator_inst_init(Object *obj)
907 {
908     TPMEmulator *tpm_emu = TPM_EMULATOR(obj);
909 
910     trace_tpm_emulator_inst_init();
911 
912     tpm_emu->options = g_new0(TPMEmulatorOptions, 1);
913     tpm_emu->cur_locty_number = ~0;
914     qemu_mutex_init(&tpm_emu->mutex);
915 
916     vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY,
917                      &vmstate_tpm_emulator, obj);
918 }
919 
920 /*
921  * Gracefully shut down the external TPM
922  */
923 static void tpm_emulator_shutdown(TPMEmulator *tpm_emu)
924 {
925     ptm_res res;
926 
927     if (!tpm_emu->options->chardev) {
928         /* was never properly initialized */
929         return;
930     }
931 
932     if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SHUTDOWN, &res, 0, sizeof(res)) < 0) {
933         error_report("tpm-emulator: Could not cleanly shutdown the TPM: %s",
934                      strerror(errno));
935     } else if (res != 0) {
936         error_report("tpm-emulator: TPM result for shutdown: 0x%x %s",
937                      be32_to_cpu(res), tpm_emulator_strerror(be32_to_cpu(res)));
938     }
939 }
940 
941 static void tpm_emulator_inst_finalize(Object *obj)
942 {
943     TPMEmulator *tpm_emu = TPM_EMULATOR(obj);
944     TPMBlobBuffers *state_blobs = &tpm_emu->state_blobs;
945 
946     tpm_emulator_shutdown(tpm_emu);
947 
948     object_unref(OBJECT(tpm_emu->data_ioc));
949 
950     qemu_chr_fe_deinit(&tpm_emu->ctrl_chr, false);
951 
952     qapi_free_TPMEmulatorOptions(tpm_emu->options);
953 
954     if (tpm_emu->migration_blocker) {
955         migrate_del_blocker(tpm_emu->migration_blocker);
956         error_free(tpm_emu->migration_blocker);
957     }
958 
959     tpm_sized_buffer_reset(&state_blobs->volatil);
960     tpm_sized_buffer_reset(&state_blobs->permanent);
961     tpm_sized_buffer_reset(&state_blobs->savestate);
962 
963     qemu_mutex_destroy(&tpm_emu->mutex);
964 
965     vmstate_unregister(NULL, &vmstate_tpm_emulator, obj);
966 }
967 
968 static void tpm_emulator_class_init(ObjectClass *klass, void *data)
969 {
970     TPMBackendClass *tbc = TPM_BACKEND_CLASS(klass);
971 
972     tbc->type = TPM_TYPE_EMULATOR;
973     tbc->opts = tpm_emulator_cmdline_opts;
974     tbc->desc = "TPM emulator backend driver";
975     tbc->create = tpm_emulator_create;
976     tbc->startup_tpm = tpm_emulator_startup_tpm;
977     tbc->cancel_cmd = tpm_emulator_cancel_cmd;
978     tbc->get_tpm_established_flag = tpm_emulator_get_tpm_established_flag;
979     tbc->reset_tpm_established_flag = tpm_emulator_reset_tpm_established_flag;
980     tbc->get_tpm_version = tpm_emulator_get_tpm_version;
981     tbc->get_buffer_size = tpm_emulator_get_buffer_size;
982     tbc->get_tpm_options = tpm_emulator_get_tpm_options;
983 
984     tbc->handle_request = tpm_emulator_handle_request;
985 }
986 
987 static const TypeInfo tpm_emulator_info = {
988     .name = TYPE_TPM_EMULATOR,
989     .parent = TYPE_TPM_BACKEND,
990     .instance_size = sizeof(TPMEmulator),
991     .class_init = tpm_emulator_class_init,
992     .instance_init = tpm_emulator_inst_init,
993     .instance_finalize = tpm_emulator_inst_finalize,
994 };
995 
996 static void tpm_emulator_register(void)
997 {
998     type_register_static(&tpm_emulator_info);
999 }
1000 
1001 type_init(tpm_emulator_register)
1002