qemu/backends/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.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"
  49OBJECT_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 */
  56typedef 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
  67struct 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
  86struct tpm_error {
  87    uint32_t tpm_result;
  88    const char *string;
  89};
  90
  91static 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
 109static 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
 121static 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
 150static 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
 189static 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
 221static 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
 236static 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
 251static 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
 284static 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
 305static 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
 345static 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
 380err_exit:
 381    return -1;
 382}
 383
 384static int tpm_emulator_startup_tpm(TPMBackend *tb, size_t buffersize)
 385{
 386    return tpm_emulator_startup_tpm_resume(tb, buffersize, false);
 387}
 388
 389static 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
 412static 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
 446static 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
 467static 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
 474static 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
 485static 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
 508static 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
 539err_exit:
 540    closesocket(fds[0]);
 541    closesocket(fds[1]);
 542    return -1;
 543}
 544
 545static 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
 604err:
 605    trace_tpm_emulator_handle_device_opts_startup_error();
 606
 607    return -1;
 608}
 609
 610static 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
 622static 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
 633static 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 */
 651static 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
 716static 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 */
 750static 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 */
 814static 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
 843static 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 */
 861static 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
 878static 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
 906static 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 */
 923static 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
 941static 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
 968static 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
 987static 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
 996static void tpm_emulator_register(void)
 997{
 998    type_register_static(&tpm_emulator_info);
 999}
1000
1001type_init(tpm_emulator_register)
1002