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
  84struct tpm_error {
  85    uint32_t tpm_result;
  86    const char *string;
  87};
  88
  89static const struct tpm_error tpm_errors[] = {
  90    /* TPM 1.2 error codes */
  91    { TPM_BAD_PARAMETER   , "a parameter is bad" },
  92    { TPM_FAIL            , "operation failed" },
  93    { TPM_KEYNOTFOUND     , "key could not be found" },
  94    { TPM_BAD_PARAM_SIZE  , "bad parameter size"},
  95    { TPM_ENCRYPT_ERROR   , "encryption error" },
  96    { TPM_DECRYPT_ERROR   , "decryption error" },
  97    { TPM_BAD_KEY_PROPERTY, "bad key property" },
  98    { TPM_BAD_MODE        , "bad (encryption) mode" },
  99    { TPM_BAD_VERSION     , "bad version identifier" },
 100    { TPM_BAD_LOCALITY    , "bad locality" },
 101    /* TPM 2 error codes */
 102    { TPM_RC_FAILURE     , "operation failed" },
 103    { TPM_RC_LOCALITY    , "bad locality"     },
 104    { TPM_RC_INSUFFICIENT, "insufficient amount of data" },
 105};
 106
 107static const char *tpm_emulator_strerror(uint32_t tpm_result)
 108{
 109    size_t i;
 110
 111    for (i = 0; i < ARRAY_SIZE(tpm_errors); i++) {
 112        if (tpm_errors[i].tpm_result == tpm_result) {
 113            return tpm_errors[i].string;
 114        }
 115    }
 116    return "";
 117}
 118
 119static int tpm_emulator_ctrlcmd(TPMEmulator *tpm, unsigned long cmd, void *msg,
 120                                size_t msg_len_in, size_t msg_len_out)
 121{
 122    CharBackend *dev = &tpm->ctrl_chr;
 123    uint32_t cmd_no = cpu_to_be32(cmd);
 124    ssize_t n = sizeof(uint32_t) + msg_len_in;
 125    uint8_t *buf = NULL;
 126    int ret = -1;
 127
 128    qemu_mutex_lock(&tpm->mutex);
 129
 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        goto end;
 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            goto end;
 143        }
 144    }
 145
 146    ret = 0;
 147
 148end:
 149    qemu_mutex_unlock(&tpm->mutex);
 150    return ret;
 151}
 152
 153static int tpm_emulator_unix_tx_bufs(TPMEmulator *tpm_emu,
 154                                     const uint8_t *in, uint32_t in_len,
 155                                     uint8_t *out, uint32_t out_len,
 156                                     bool *selftest_done,
 157                                     Error **err)
 158{
 159    ssize_t ret;
 160    bool is_selftest = false;
 161
 162    if (selftest_done) {
 163        *selftest_done = false;
 164        is_selftest = tpm_util_is_selftest(in, in_len);
 165    }
 166
 167    ret = qio_channel_write_all(tpm_emu->data_ioc, (char *)in, in_len, err);
 168    if (ret != 0) {
 169        return -1;
 170    }
 171
 172    ret = qio_channel_read_all(tpm_emu->data_ioc, (char *)out,
 173              sizeof(struct tpm_resp_hdr), err);
 174    if (ret != 0) {
 175        return -1;
 176    }
 177
 178    ret = qio_channel_read_all(tpm_emu->data_ioc,
 179              (char *)out + sizeof(struct tpm_resp_hdr),
 180              tpm_cmd_get_size(out) - sizeof(struct tpm_resp_hdr), err);
 181    if (ret != 0) {
 182        return -1;
 183    }
 184
 185    if (is_selftest) {
 186        *selftest_done = tpm_cmd_get_errcode(out) == 0;
 187    }
 188
 189    return 0;
 190}
 191
 192static int tpm_emulator_set_locality(TPMEmulator *tpm_emu, uint8_t locty_number,
 193                                     Error **errp)
 194{
 195    ptm_loc loc;
 196
 197    if (tpm_emu->cur_locty_number == locty_number) {
 198        return 0;
 199    }
 200
 201    trace_tpm_emulator_set_locality(locty_number);
 202
 203    memset(&loc, 0, sizeof(loc));
 204    loc.u.req.loc = locty_number;
 205    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_LOCALITY, &loc,
 206                             sizeof(loc), sizeof(loc)) < 0) {
 207        error_setg(errp, "tpm-emulator: could not set locality : %s",
 208                   strerror(errno));
 209        return -1;
 210    }
 211
 212    loc.u.resp.tpm_result = be32_to_cpu(loc.u.resp.tpm_result);
 213    if (loc.u.resp.tpm_result != 0) {
 214        error_setg(errp, "tpm-emulator: TPM result for set locality : 0x%x",
 215                   loc.u.resp.tpm_result);
 216        return -1;
 217    }
 218
 219    tpm_emu->cur_locty_number = locty_number;
 220
 221    return 0;
 222}
 223
 224static void tpm_emulator_handle_request(TPMBackend *tb, TPMBackendCmd *cmd,
 225                                        Error **errp)
 226{
 227    TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
 228
 229    trace_tpm_emulator_handle_request();
 230
 231    if (tpm_emulator_set_locality(tpm_emu, cmd->locty, errp) < 0 ||
 232        tpm_emulator_unix_tx_bufs(tpm_emu, cmd->in, cmd->in_len,
 233                                  cmd->out, cmd->out_len,
 234                                  &cmd->selftest_done, errp) < 0) {
 235        tpm_util_write_fatal_error_response(cmd->out, cmd->out_len);
 236    }
 237}
 238
 239static int tpm_emulator_probe_caps(TPMEmulator *tpm_emu)
 240{
 241    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_CAPABILITY,
 242                             &tpm_emu->caps, 0, sizeof(tpm_emu->caps)) < 0) {
 243        error_report("tpm-emulator: probing failed : %s", strerror(errno));
 244        return -1;
 245    }
 246
 247    tpm_emu->caps = be64_to_cpu(tpm_emu->caps);
 248
 249    trace_tpm_emulator_probe_caps(tpm_emu->caps);
 250
 251    return 0;
 252}
 253
 254static int tpm_emulator_check_caps(TPMEmulator *tpm_emu)
 255{
 256    ptm_cap caps = 0;
 257    const char *tpm = NULL;
 258
 259    /* check for min. required capabilities */
 260    switch (tpm_emu->tpm_version) {
 261    case TPM_VERSION_1_2:
 262        caps = PTM_CAP_INIT | PTM_CAP_SHUTDOWN | PTM_CAP_GET_TPMESTABLISHED |
 263               PTM_CAP_SET_LOCALITY | PTM_CAP_SET_DATAFD | PTM_CAP_STOP |
 264               PTM_CAP_SET_BUFFERSIZE;
 265        tpm = "1.2";
 266        break;
 267    case TPM_VERSION_2_0:
 268        caps = PTM_CAP_INIT | PTM_CAP_SHUTDOWN | PTM_CAP_GET_TPMESTABLISHED |
 269               PTM_CAP_SET_LOCALITY | PTM_CAP_RESET_TPMESTABLISHED |
 270               PTM_CAP_SET_DATAFD | PTM_CAP_STOP | PTM_CAP_SET_BUFFERSIZE;
 271        tpm = "2";
 272        break;
 273    case TPM_VERSION_UNSPEC:
 274        error_report("tpm-emulator: TPM version has not been set");
 275        return -1;
 276    }
 277
 278    if (!TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(tpm_emu, caps)) {
 279        error_report("tpm-emulator: TPM does not implement minimum set of "
 280                     "required capabilities for TPM %s (0x%x)", tpm, (int)caps);
 281        return -1;
 282    }
 283
 284    return 0;
 285}
 286
 287static int tpm_emulator_stop_tpm(TPMBackend *tb)
 288{
 289    TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
 290    ptm_res res;
 291
 292    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_STOP, &res, 0, sizeof(res)) < 0) {
 293        error_report("tpm-emulator: Could not stop TPM: %s",
 294                     strerror(errno));
 295        return -1;
 296    }
 297
 298    res = be32_to_cpu(res);
 299    if (res) {
 300        error_report("tpm-emulator: TPM result for CMD_STOP: 0x%x %s", res,
 301                     tpm_emulator_strerror(res));
 302        return -1;
 303    }
 304
 305    return 0;
 306}
 307
 308static int tpm_emulator_set_buffer_size(TPMBackend *tb,
 309                                        size_t wanted_size,
 310                                        size_t *actual_size)
 311{
 312    TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
 313    ptm_setbuffersize psbs;
 314
 315    if (tpm_emulator_stop_tpm(tb) < 0) {
 316        return -1;
 317    }
 318
 319    psbs.u.req.buffersize = cpu_to_be32(wanted_size);
 320
 321    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_BUFFERSIZE, &psbs,
 322                             sizeof(psbs.u.req), sizeof(psbs.u.resp)) < 0) {
 323        error_report("tpm-emulator: Could not set buffer size: %s",
 324                     strerror(errno));
 325        return -1;
 326    }
 327
 328    psbs.u.resp.tpm_result = be32_to_cpu(psbs.u.resp.tpm_result);
 329    if (psbs.u.resp.tpm_result != 0) {
 330        error_report("tpm-emulator: TPM result for set buffer size : 0x%x %s",
 331                     psbs.u.resp.tpm_result,
 332                     tpm_emulator_strerror(psbs.u.resp.tpm_result));
 333        return -1;
 334    }
 335
 336    if (actual_size) {
 337        *actual_size = be32_to_cpu(psbs.u.resp.buffersize);
 338    }
 339
 340    trace_tpm_emulator_set_buffer_size(
 341            be32_to_cpu(psbs.u.resp.buffersize),
 342            be32_to_cpu(psbs.u.resp.minsize),
 343            be32_to_cpu(psbs.u.resp.maxsize));
 344
 345    return 0;
 346}
 347
 348static int tpm_emulator_startup_tpm_resume(TPMBackend *tb, size_t buffersize,
 349                                     bool is_resume)
 350{
 351    TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
 352    ptm_init init = {
 353        .u.req.init_flags = 0,
 354    };
 355    ptm_res res;
 356
 357    trace_tpm_emulator_startup_tpm_resume(is_resume, buffersize);
 358
 359    if (buffersize != 0 &&
 360        tpm_emulator_set_buffer_size(tb, buffersize, NULL) < 0) {
 361        goto err_exit;
 362    }
 363
 364    if (is_resume) {
 365        init.u.req.init_flags |= cpu_to_be32(PTM_INIT_FLAG_DELETE_VOLATILE);
 366    }
 367
 368    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_INIT, &init, sizeof(init),
 369                             sizeof(init)) < 0) {
 370        error_report("tpm-emulator: could not send INIT: %s",
 371                     strerror(errno));
 372        goto err_exit;
 373    }
 374
 375    res = be32_to_cpu(init.u.resp.tpm_result);
 376    if (res) {
 377        error_report("tpm-emulator: TPM result for CMD_INIT: 0x%x %s", res,
 378                     tpm_emulator_strerror(res));
 379        goto err_exit;
 380    }
 381    return 0;
 382
 383err_exit:
 384    return -1;
 385}
 386
 387static int tpm_emulator_startup_tpm(TPMBackend *tb, size_t buffersize)
 388{
 389    return tpm_emulator_startup_tpm_resume(tb, buffersize, false);
 390}
 391
 392static bool tpm_emulator_get_tpm_established_flag(TPMBackend *tb)
 393{
 394    TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
 395    ptm_est est;
 396
 397    if (tpm_emu->established_flag_cached) {
 398        return tpm_emu->established_flag;
 399    }
 400
 401    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_TPMESTABLISHED, &est,
 402                             0, sizeof(est)) < 0) {
 403        error_report("tpm-emulator: Could not get the TPM established flag: %s",
 404                     strerror(errno));
 405        return false;
 406    }
 407    trace_tpm_emulator_get_tpm_established_flag(est.u.resp.bit);
 408
 409    tpm_emu->established_flag_cached = 1;
 410    tpm_emu->established_flag = (est.u.resp.bit != 0);
 411
 412    return tpm_emu->established_flag;
 413}
 414
 415static int tpm_emulator_reset_tpm_established_flag(TPMBackend *tb,
 416                                                   uint8_t locty)
 417{
 418    TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
 419    ptm_reset_est reset_est;
 420    ptm_res res;
 421
 422    /* only a TPM 2.0 will support this */
 423    if (tpm_emu->tpm_version != TPM_VERSION_2_0) {
 424        return 0;
 425    }
 426
 427    reset_est.u.req.loc = tpm_emu->cur_locty_number;
 428    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_RESET_TPMESTABLISHED,
 429                             &reset_est, sizeof(reset_est),
 430                             sizeof(reset_est)) < 0) {
 431        error_report("tpm-emulator: Could not reset the establishment bit: %s",
 432                     strerror(errno));
 433        return -1;
 434    }
 435
 436    res = be32_to_cpu(reset_est.u.resp.tpm_result);
 437    if (res) {
 438        error_report(
 439            "tpm-emulator: TPM result for rest established flag: 0x%x %s",
 440            res, tpm_emulator_strerror(res));
 441        return -1;
 442    }
 443
 444    tpm_emu->established_flag_cached = 0;
 445
 446    return 0;
 447}
 448
 449static void tpm_emulator_cancel_cmd(TPMBackend *tb)
 450{
 451    TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
 452    ptm_res res;
 453
 454    if (!TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(tpm_emu, PTM_CAP_CANCEL_TPM_CMD)) {
 455        trace_tpm_emulator_cancel_cmd_not_supt();
 456        return;
 457    }
 458
 459    /* FIXME: make the function non-blocking, or it may block a VCPU */
 460    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_CANCEL_TPM_CMD, &res, 0,
 461                             sizeof(res)) < 0) {
 462        error_report("tpm-emulator: Could not cancel command: %s",
 463                     strerror(errno));
 464    } else if (res != 0) {
 465        error_report("tpm-emulator: Failed to cancel TPM: 0x%x",
 466                     be32_to_cpu(res));
 467    }
 468}
 469
 470static TPMVersion tpm_emulator_get_tpm_version(TPMBackend *tb)
 471{
 472    TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
 473
 474    return tpm_emu->tpm_version;
 475}
 476
 477static size_t tpm_emulator_get_buffer_size(TPMBackend *tb)
 478{
 479    size_t actual_size;
 480
 481    if (tpm_emulator_set_buffer_size(tb, 0, &actual_size) < 0) {
 482        return 4096;
 483    }
 484
 485    return actual_size;
 486}
 487
 488static int tpm_emulator_block_migration(TPMEmulator *tpm_emu)
 489{
 490    Error *err = NULL;
 491    ptm_cap caps = PTM_CAP_GET_STATEBLOB | PTM_CAP_SET_STATEBLOB |
 492                   PTM_CAP_STOP;
 493
 494    if (!TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(tpm_emu, caps)) {
 495        error_setg(&tpm_emu->migration_blocker,
 496                   "Migration disabled: TPM emulator does not support "
 497                   "migration");
 498        migrate_add_blocker(tpm_emu->migration_blocker, &err);
 499        if (err) {
 500            error_report_err(err);
 501            error_free(tpm_emu->migration_blocker);
 502            tpm_emu->migration_blocker = NULL;
 503
 504            return -1;
 505        }
 506    }
 507
 508    return 0;
 509}
 510
 511static int tpm_emulator_prepare_data_fd(TPMEmulator *tpm_emu)
 512{
 513    ptm_res res;
 514    Error *err = NULL;
 515    int fds[2] = { -1, -1 };
 516
 517    if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
 518        error_report("tpm-emulator: Failed to create socketpair");
 519        return -1;
 520    }
 521
 522    qemu_chr_fe_set_msgfds(&tpm_emu->ctrl_chr, fds + 1, 1);
 523
 524    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_DATAFD, &res, 0,
 525                             sizeof(res)) < 0 || res != 0) {
 526        error_report("tpm-emulator: Failed to send CMD_SET_DATAFD: %s",
 527                     strerror(errno));
 528        goto err_exit;
 529    }
 530
 531    tpm_emu->data_ioc = QIO_CHANNEL(qio_channel_socket_new_fd(fds[0], &err));
 532    if (err) {
 533        error_prepend(&err, "tpm-emulator: Failed to create io channel: ");
 534        error_report_err(err);
 535        goto err_exit;
 536    }
 537
 538    closesocket(fds[1]);
 539
 540    return 0;
 541
 542err_exit:
 543    closesocket(fds[0]);
 544    closesocket(fds[1]);
 545    return -1;
 546}
 547
 548static int tpm_emulator_handle_device_opts(TPMEmulator *tpm_emu, QemuOpts *opts)
 549{
 550    const char *value;
 551
 552    value = qemu_opt_get(opts, "chardev");
 553    if (value) {
 554        Error *err = NULL;
 555        Chardev *dev = qemu_chr_find(value);
 556
 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
 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, -1, &vmstate_tpm_emulator, obj);
 917}
 918
 919/*
 920 * Gracefully shut down the external TPM
 921 */
 922static void tpm_emulator_shutdown(TPMEmulator *tpm_emu)
 923{
 924    ptm_res res;
 925
 926    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SHUTDOWN, &res, 0, sizeof(res)) < 0) {
 927        error_report("tpm-emulator: Could not cleanly shutdown the TPM: %s",
 928                     strerror(errno));
 929    } else if (res != 0) {
 930        error_report("tpm-emulator: TPM result for shutdown: 0x%x %s",
 931                     be32_to_cpu(res), tpm_emulator_strerror(be32_to_cpu(res)));
 932    }
 933}
 934
 935static void tpm_emulator_inst_finalize(Object *obj)
 936{
 937    TPMEmulator *tpm_emu = TPM_EMULATOR(obj);
 938    TPMBlobBuffers *state_blobs = &tpm_emu->state_blobs;
 939
 940    tpm_emulator_shutdown(tpm_emu);
 941
 942    object_unref(OBJECT(tpm_emu->data_ioc));
 943
 944    qemu_chr_fe_deinit(&tpm_emu->ctrl_chr, false);
 945
 946    qapi_free_TPMEmulatorOptions(tpm_emu->options);
 947
 948    if (tpm_emu->migration_blocker) {
 949        migrate_del_blocker(tpm_emu->migration_blocker);
 950        error_free(tpm_emu->migration_blocker);
 951    }
 952
 953    tpm_sized_buffer_reset(&state_blobs->volatil);
 954    tpm_sized_buffer_reset(&state_blobs->permanent);
 955    tpm_sized_buffer_reset(&state_blobs->savestate);
 956
 957    qemu_mutex_destroy(&tpm_emu->mutex);
 958
 959    vmstate_unregister(NULL, &vmstate_tpm_emulator, obj);
 960}
 961
 962static void tpm_emulator_class_init(ObjectClass *klass, void *data)
 963{
 964    TPMBackendClass *tbc = TPM_BACKEND_CLASS(klass);
 965
 966    tbc->type = TPM_TYPE_EMULATOR;
 967    tbc->opts = tpm_emulator_cmdline_opts;
 968    tbc->desc = "TPM emulator backend driver";
 969    tbc->create = tpm_emulator_create;
 970    tbc->startup_tpm = tpm_emulator_startup_tpm;
 971    tbc->cancel_cmd = tpm_emulator_cancel_cmd;
 972    tbc->get_tpm_established_flag = tpm_emulator_get_tpm_established_flag;
 973    tbc->reset_tpm_established_flag = tpm_emulator_reset_tpm_established_flag;
 974    tbc->get_tpm_version = tpm_emulator_get_tpm_version;
 975    tbc->get_buffer_size = tpm_emulator_get_buffer_size;
 976    tbc->get_tpm_options = tpm_emulator_get_tpm_options;
 977
 978    tbc->handle_request = tpm_emulator_handle_request;
 979}
 980
 981static const TypeInfo tpm_emulator_info = {
 982    .name = TYPE_TPM_EMULATOR,
 983    .parent = TYPE_TPM_BACKEND,
 984    .instance_size = sizeof(TPMEmulator),
 985    .class_init = tpm_emulator_class_init,
 986    .instance_init = tpm_emulator_inst_init,
 987    .instance_finalize = tpm_emulator_inst_finalize,
 988};
 989
 990static void tpm_emulator_register(void)
 991{
 992    type_register_static(&tpm_emulator_info);
 993}
 994
 995type_init(tpm_emulator_register)
 996