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