xref: /openbmc/qemu/backends/tpm/tpm_emulator.c (revision af531756)
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         if (migrate_add_blocker(tpm_emu->migration_blocker, &err) < 0) {
496             error_report_err(err);
497             error_free(tpm_emu->migration_blocker);
498             tpm_emu->migration_blocker = NULL;
499 
500             return -1;
501         }
502     }
503 
504     return 0;
505 }
506 
507 static int tpm_emulator_prepare_data_fd(TPMEmulator *tpm_emu)
508 {
509     ptm_res res;
510     Error *err = NULL;
511     int fds[2] = { -1, -1 };
512 
513     if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
514         error_report("tpm-emulator: Failed to create socketpair");
515         return -1;
516     }
517 
518     qemu_chr_fe_set_msgfds(&tpm_emu->ctrl_chr, fds + 1, 1);
519 
520     if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_DATAFD, &res, 0,
521                              sizeof(res)) < 0 || res != 0) {
522         error_report("tpm-emulator: Failed to send CMD_SET_DATAFD: %s",
523                      strerror(errno));
524         goto err_exit;
525     }
526 
527     tpm_emu->data_ioc = QIO_CHANNEL(qio_channel_socket_new_fd(fds[0], &err));
528     if (err) {
529         error_prepend(&err, "tpm-emulator: Failed to create io channel: ");
530         error_report_err(err);
531         goto err_exit;
532     }
533 
534     closesocket(fds[1]);
535 
536     return 0;
537 
538 err_exit:
539     closesocket(fds[0]);
540     closesocket(fds[1]);
541     return -1;
542 }
543 
544 static int tpm_emulator_handle_device_opts(TPMEmulator *tpm_emu, QemuOpts *opts)
545 {
546     const char *value;
547     Error *err = NULL;
548     Chardev *dev;
549 
550     value = qemu_opt_get(opts, "chardev");
551     if (!value) {
552         error_report("tpm-emulator: parameter 'chardev' is missing");
553         goto err;
554     }
555 
556     dev = qemu_chr_find(value);
557     if (!dev) {
558         error_report("tpm-emulator: tpm chardev '%s' not found", value);
559         goto err;
560     }
561 
562     if (!qemu_chr_fe_init(&tpm_emu->ctrl_chr, dev, &err)) {
563         error_prepend(&err, "tpm-emulator: No valid chardev found at '%s':",
564                       value);
565         error_report_err(err);
566         goto err;
567     }
568 
569     tpm_emu->options->chardev = g_strdup(value);
570 
571     if (tpm_emulator_prepare_data_fd(tpm_emu) < 0) {
572         goto err;
573     }
574 
575     /* FIXME: tpm_util_test_tpmdev() accepts only on socket fd, as it also used
576      * by passthrough driver, which not yet using GIOChannel.
577      */
578     if (tpm_util_test_tpmdev(QIO_CHANNEL_SOCKET(tpm_emu->data_ioc)->fd,
579                              &tpm_emu->tpm_version)) {
580         error_report("'%s' is not emulating TPM device. Error: %s",
581                       tpm_emu->options->chardev, strerror(errno));
582         goto err;
583     }
584 
585     switch (tpm_emu->tpm_version) {
586     case TPM_VERSION_1_2:
587         trace_tpm_emulator_handle_device_opts_tpm12();
588         break;
589     case TPM_VERSION_2_0:
590         trace_tpm_emulator_handle_device_opts_tpm2();
591         break;
592     default:
593         trace_tpm_emulator_handle_device_opts_unspec();
594     }
595 
596     if (tpm_emulator_probe_caps(tpm_emu) ||
597         tpm_emulator_check_caps(tpm_emu)) {
598         goto err;
599     }
600 
601     return tpm_emulator_block_migration(tpm_emu);
602 
603 err:
604     trace_tpm_emulator_handle_device_opts_startup_error();
605 
606     return -1;
607 }
608 
609 static TPMBackend *tpm_emulator_create(QemuOpts *opts)
610 {
611     TPMBackend *tb = TPM_BACKEND(object_new(TYPE_TPM_EMULATOR));
612 
613     if (tpm_emulator_handle_device_opts(TPM_EMULATOR(tb), opts)) {
614         object_unref(OBJECT(tb));
615         return NULL;
616     }
617 
618     return tb;
619 }
620 
621 static TpmTypeOptions *tpm_emulator_get_tpm_options(TPMBackend *tb)
622 {
623     TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
624     TpmTypeOptions *options = g_new0(TpmTypeOptions, 1);
625 
626     options->type = TPM_TYPE_EMULATOR;
627     options->u.emulator.data = QAPI_CLONE(TPMEmulatorOptions, tpm_emu->options);
628 
629     return options;
630 }
631 
632 static const QemuOptDesc tpm_emulator_cmdline_opts[] = {
633     TPM_STANDARD_CMDLINE_OPTS,
634     {
635         .name = "chardev",
636         .type = QEMU_OPT_STRING,
637         .help = "Character device to use for out-of-band control messages",
638     },
639     { /* end of list */ },
640 };
641 
642 /*
643  * Transfer a TPM state blob from the TPM into a provided buffer.
644  *
645  * @tpm_emu: TPMEmulator
646  * @type: the type of blob to transfer
647  * @tsb: the TPMSizeBuffer to fill with the blob
648  * @flags: the flags to return to the caller
649  */
650 static int tpm_emulator_get_state_blob(TPMEmulator *tpm_emu,
651                                        uint8_t type,
652                                        TPMSizedBuffer *tsb,
653                                        uint32_t *flags)
654 {
655     ptm_getstate pgs;
656     ptm_res res;
657     ssize_t n;
658     uint32_t totlength, length;
659 
660     tpm_sized_buffer_reset(tsb);
661 
662     pgs.u.req.state_flags = cpu_to_be32(PTM_STATE_FLAG_DECRYPTED);
663     pgs.u.req.type = cpu_to_be32(type);
664     pgs.u.req.offset = 0;
665 
666     if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_STATEBLOB,
667                              &pgs, sizeof(pgs.u.req),
668                              offsetof(ptm_getstate, u.resp.data)) < 0) {
669         error_report("tpm-emulator: could not get state blob type %d : %s",
670                      type, strerror(errno));
671         return -1;
672     }
673 
674     res = be32_to_cpu(pgs.u.resp.tpm_result);
675     if (res != 0 && (res & 0x800) == 0) {
676         error_report("tpm-emulator: Getting the stateblob (type %d) failed "
677                      "with a TPM error 0x%x %s", type, res,
678                      tpm_emulator_strerror(res));
679         return -1;
680     }
681 
682     totlength = be32_to_cpu(pgs.u.resp.totlength);
683     length = be32_to_cpu(pgs.u.resp.length);
684     if (totlength != length) {
685         error_report("tpm-emulator: Expecting to read %u bytes "
686                      "but would get %u", totlength, length);
687         return -1;
688     }
689 
690     *flags = be32_to_cpu(pgs.u.resp.state_flags);
691 
692     if (totlength > 0) {
693         tsb->buffer = g_try_malloc(totlength);
694         if (!tsb->buffer) {
695             error_report("tpm-emulator: Out of memory allocating %u bytes",
696                          totlength);
697             return -1;
698         }
699 
700         n = qemu_chr_fe_read_all(&tpm_emu->ctrl_chr, tsb->buffer, totlength);
701         if (n != totlength) {
702             error_report("tpm-emulator: Could not read stateblob (type %d); "
703                          "expected %u bytes, got %zd",
704                          type, totlength, n);
705             return -1;
706         }
707     }
708     tsb->size = totlength;
709 
710     trace_tpm_emulator_get_state_blob(type, tsb->size, *flags);
711 
712     return 0;
713 }
714 
715 static int tpm_emulator_get_state_blobs(TPMEmulator *tpm_emu)
716 {
717     TPMBlobBuffers *state_blobs = &tpm_emu->state_blobs;
718 
719     if (tpm_emulator_get_state_blob(tpm_emu, PTM_BLOB_TYPE_PERMANENT,
720                                     &state_blobs->permanent,
721                                     &state_blobs->permanent_flags) < 0 ||
722         tpm_emulator_get_state_blob(tpm_emu, PTM_BLOB_TYPE_VOLATILE,
723                                     &state_blobs->volatil,
724                                     &state_blobs->volatil_flags) < 0 ||
725         tpm_emulator_get_state_blob(tpm_emu, PTM_BLOB_TYPE_SAVESTATE,
726                                     &state_blobs->savestate,
727                                     &state_blobs->savestate_flags) < 0) {
728         goto err_exit;
729     }
730 
731     return 0;
732 
733  err_exit:
734     tpm_sized_buffer_reset(&state_blobs->volatil);
735     tpm_sized_buffer_reset(&state_blobs->permanent);
736     tpm_sized_buffer_reset(&state_blobs->savestate);
737 
738     return -1;
739 }
740 
741 /*
742  * Transfer a TPM state blob to the TPM emulator.
743  *
744  * @tpm_emu: TPMEmulator
745  * @type: the type of TPM state blob to transfer
746  * @tsb: TPMSizedBuffer containing the TPM state blob
747  * @flags: Flags describing the (encryption) state of the TPM state blob
748  */
749 static int tpm_emulator_set_state_blob(TPMEmulator *tpm_emu,
750                                        uint32_t type,
751                                        TPMSizedBuffer *tsb,
752                                        uint32_t flags)
753 {
754     ssize_t n;
755     ptm_setstate pss;
756     ptm_res tpm_result;
757 
758     if (tsb->size == 0) {
759         return 0;
760     }
761 
762     pss = (ptm_setstate) {
763         .u.req.state_flags = cpu_to_be32(flags),
764         .u.req.type = cpu_to_be32(type),
765         .u.req.length = cpu_to_be32(tsb->size),
766     };
767 
768     /* write the header only */
769     if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_STATEBLOB, &pss,
770                              offsetof(ptm_setstate, u.req.data), 0) < 0) {
771         error_report("tpm-emulator: could not set state blob type %d : %s",
772                      type, strerror(errno));
773         return -1;
774     }
775 
776     /* now the body */
777     n = qemu_chr_fe_write_all(&tpm_emu->ctrl_chr, tsb->buffer, tsb->size);
778     if (n != tsb->size) {
779         error_report("tpm-emulator: Writing the stateblob (type %d) "
780                      "failed; could not write %u bytes, but only %zd",
781                      type, tsb->size, n);
782         return -1;
783     }
784 
785     /* now get the result */
786     n = qemu_chr_fe_read_all(&tpm_emu->ctrl_chr,
787                              (uint8_t *)&pss, sizeof(pss.u.resp));
788     if (n != sizeof(pss.u.resp)) {
789         error_report("tpm-emulator: Reading response from writing stateblob "
790                      "(type %d) failed; expected %zu bytes, got %zd", type,
791                      sizeof(pss.u.resp), n);
792         return -1;
793     }
794 
795     tpm_result = be32_to_cpu(pss.u.resp.tpm_result);
796     if (tpm_result != 0) {
797         error_report("tpm-emulator: Setting the stateblob (type %d) failed "
798                      "with a TPM error 0x%x %s", type, tpm_result,
799                      tpm_emulator_strerror(tpm_result));
800         return -1;
801     }
802 
803     trace_tpm_emulator_set_state_blob(type, tsb->size, flags);
804 
805     return 0;
806 }
807 
808 /*
809  * Set all the TPM state blobs.
810  *
811  * Returns a negative errno code in case of error.
812  */
813 static int tpm_emulator_set_state_blobs(TPMBackend *tb)
814 {
815     TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
816     TPMBlobBuffers *state_blobs = &tpm_emu->state_blobs;
817 
818     trace_tpm_emulator_set_state_blobs();
819 
820     if (tpm_emulator_stop_tpm(tb) < 0) {
821         trace_tpm_emulator_set_state_blobs_error("Could not stop TPM");
822         return -EIO;
823     }
824 
825     if (tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_PERMANENT,
826                                     &state_blobs->permanent,
827                                     state_blobs->permanent_flags) < 0 ||
828         tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_VOLATILE,
829                                     &state_blobs->volatil,
830                                     state_blobs->volatil_flags) < 0 ||
831         tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_SAVESTATE,
832                                     &state_blobs->savestate,
833                                     state_blobs->savestate_flags) < 0) {
834         return -EIO;
835     }
836 
837     trace_tpm_emulator_set_state_blobs_done();
838 
839     return 0;
840 }
841 
842 static int tpm_emulator_pre_save(void *opaque)
843 {
844     TPMBackend *tb = opaque;
845     TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
846 
847     trace_tpm_emulator_pre_save();
848 
849     tpm_backend_finish_sync(tb);
850 
851     /* get the state blobs from the TPM */
852     return tpm_emulator_get_state_blobs(tpm_emu);
853 }
854 
855 /*
856  * Load the TPM state blobs into the TPM.
857  *
858  * Returns negative errno codes in case of error.
859  */
860 static int tpm_emulator_post_load(void *opaque, int version_id)
861 {
862     TPMBackend *tb = opaque;
863     int ret;
864 
865     ret = tpm_emulator_set_state_blobs(tb);
866     if (ret < 0) {
867         return ret;
868     }
869 
870     if (tpm_emulator_startup_tpm_resume(tb, 0, true) < 0) {
871         return -EIO;
872     }
873 
874     return 0;
875 }
876 
877 static const VMStateDescription vmstate_tpm_emulator = {
878     .name = "tpm-emulator",
879     .version_id = 0,
880     .pre_save = tpm_emulator_pre_save,
881     .post_load = tpm_emulator_post_load,
882     .fields = (VMStateField[]) {
883         VMSTATE_UINT32(state_blobs.permanent_flags, TPMEmulator),
884         VMSTATE_UINT32(state_blobs.permanent.size, TPMEmulator),
885         VMSTATE_VBUFFER_ALLOC_UINT32(state_blobs.permanent.buffer,
886                                      TPMEmulator, 0, 0,
887                                      state_blobs.permanent.size),
888 
889         VMSTATE_UINT32(state_blobs.volatil_flags, TPMEmulator),
890         VMSTATE_UINT32(state_blobs.volatil.size, TPMEmulator),
891         VMSTATE_VBUFFER_ALLOC_UINT32(state_blobs.volatil.buffer,
892                                      TPMEmulator, 0, 0,
893                                      state_blobs.volatil.size),
894 
895         VMSTATE_UINT32(state_blobs.savestate_flags, TPMEmulator),
896         VMSTATE_UINT32(state_blobs.savestate.size, TPMEmulator),
897         VMSTATE_VBUFFER_ALLOC_UINT32(state_blobs.savestate.buffer,
898                                      TPMEmulator, 0, 0,
899                                      state_blobs.savestate.size),
900 
901         VMSTATE_END_OF_LIST()
902     }
903 };
904 
905 static void tpm_emulator_inst_init(Object *obj)
906 {
907     TPMEmulator *tpm_emu = TPM_EMULATOR(obj);
908 
909     trace_tpm_emulator_inst_init();
910 
911     tpm_emu->options = g_new0(TPMEmulatorOptions, 1);
912     tpm_emu->cur_locty_number = ~0;
913     qemu_mutex_init(&tpm_emu->mutex);
914 
915     vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY,
916                      &vmstate_tpm_emulator, obj);
917 }
918 
919 /*
920  * Gracefully shut down the external TPM
921  */
922 static void tpm_emulator_shutdown(TPMEmulator *tpm_emu)
923 {
924     ptm_res res;
925 
926     if (!tpm_emu->options->chardev) {
927         /* was never properly initialized */
928         return;
929     }
930 
931     if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SHUTDOWN, &res, 0, sizeof(res)) < 0) {
932         error_report("tpm-emulator: Could not cleanly shutdown the TPM: %s",
933                      strerror(errno));
934     } else if (res != 0) {
935         error_report("tpm-emulator: TPM result for shutdown: 0x%x %s",
936                      be32_to_cpu(res), tpm_emulator_strerror(be32_to_cpu(res)));
937     }
938 }
939 
940 static void tpm_emulator_inst_finalize(Object *obj)
941 {
942     TPMEmulator *tpm_emu = TPM_EMULATOR(obj);
943     TPMBlobBuffers *state_blobs = &tpm_emu->state_blobs;
944 
945     tpm_emulator_shutdown(tpm_emu);
946 
947     object_unref(OBJECT(tpm_emu->data_ioc));
948 
949     qemu_chr_fe_deinit(&tpm_emu->ctrl_chr, false);
950 
951     qapi_free_TPMEmulatorOptions(tpm_emu->options);
952 
953     if (tpm_emu->migration_blocker) {
954         migrate_del_blocker(tpm_emu->migration_blocker);
955         error_free(tpm_emu->migration_blocker);
956     }
957 
958     tpm_sized_buffer_reset(&state_blobs->volatil);
959     tpm_sized_buffer_reset(&state_blobs->permanent);
960     tpm_sized_buffer_reset(&state_blobs->savestate);
961 
962     qemu_mutex_destroy(&tpm_emu->mutex);
963 
964     vmstate_unregister(NULL, &vmstate_tpm_emulator, obj);
965 }
966 
967 static void tpm_emulator_class_init(ObjectClass *klass, void *data)
968 {
969     TPMBackendClass *tbc = TPM_BACKEND_CLASS(klass);
970 
971     tbc->type = TPM_TYPE_EMULATOR;
972     tbc->opts = tpm_emulator_cmdline_opts;
973     tbc->desc = "TPM emulator backend driver";
974     tbc->create = tpm_emulator_create;
975     tbc->startup_tpm = tpm_emulator_startup_tpm;
976     tbc->cancel_cmd = tpm_emulator_cancel_cmd;
977     tbc->get_tpm_established_flag = tpm_emulator_get_tpm_established_flag;
978     tbc->reset_tpm_established_flag = tpm_emulator_reset_tpm_established_flag;
979     tbc->get_tpm_version = tpm_emulator_get_tpm_version;
980     tbc->get_buffer_size = tpm_emulator_get_buffer_size;
981     tbc->get_tpm_options = tpm_emulator_get_tpm_options;
982 
983     tbc->handle_request = tpm_emulator_handle_request;
984 }
985 
986 static const TypeInfo tpm_emulator_info = {
987     .name = TYPE_TPM_EMULATOR,
988     .parent = TYPE_TPM_BACKEND,
989     .instance_size = sizeof(TPMEmulator),
990     .class_init = tpm_emulator_class_init,
991     .instance_init = tpm_emulator_inst_init,
992     .instance_finalize = tpm_emulator_inst_finalize,
993 };
994 
995 static void tpm_emulator_register(void)
996 {
997     type_register_static(&tpm_emulator_info);
998 }
999 
1000 type_init(tpm_emulator_register)
1001