/*
 *  Emulator TPM driver
 *
 *  Copyright (c) 2017 Intel Corporation
 *  Author: Amarnath Valluri <amarnath.valluri@intel.com>
 *
 *  Copyright (c) 2010 - 2013, 2018 IBM Corporation
 *  Authors:
 *    Stefan Berger <stefanb@us.ibm.com>
 *
 *  Copyright (C) 2011 IAIK, Graz University of Technology
 *    Author: Andreas Niederl
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>
 *
 */

#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qemu/sockets.h"
#include "io/channel-socket.h"
#include "sysemu/tpm_backend.h"
#include "sysemu/tpm_util.h"
#include "tpm_int.h"
#include "tpm_ioctl.h"
#include "migration/blocker.h"
#include "migration/vmstate.h"
#include "qapi/error.h"
#include "qapi/clone-visitor.h"
#include "qapi/qapi-visit-tpm.h"
#include "chardev/char-fe.h"
#include "trace.h"

#define TYPE_TPM_EMULATOR "tpm-emulator"
#define TPM_EMULATOR(obj) \
    OBJECT_CHECK(TPMEmulator, (obj), TYPE_TPM_EMULATOR)

#define TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(S, cap) (((S)->caps & (cap)) == (cap))

/* data structures */

/* blobs from the TPM; part of VM state when migrating */
typedef struct TPMBlobBuffers {
    uint32_t permanent_flags;
    TPMSizedBuffer permanent;

    uint32_t volatil_flags;
    TPMSizedBuffer volatil;

    uint32_t savestate_flags;
    TPMSizedBuffer savestate;
} TPMBlobBuffers;

typedef struct TPMEmulator {
    TPMBackend parent;

    TPMEmulatorOptions *options;
    CharBackend ctrl_chr;
    QIOChannel *data_ioc;
    TPMVersion tpm_version;
    ptm_cap caps; /* capabilities of the TPM */
    uint8_t cur_locty_number; /* last set locality */
    Error *migration_blocker;

    QemuMutex mutex;

    unsigned int established_flag:1;
    unsigned int established_flag_cached:1;

    TPMBlobBuffers state_blobs;
} TPMEmulator;

struct tpm_error {
    uint32_t tpm_result;
    const char *string;
};

static const struct tpm_error tpm_errors[] = {
    /* TPM 1.2 error codes */
    { TPM_BAD_PARAMETER   , "a parameter is bad" },
    { TPM_FAIL            , "operation failed" },
    { TPM_KEYNOTFOUND     , "key could not be found" },
    { TPM_BAD_PARAM_SIZE  , "bad parameter size"},
    { TPM_ENCRYPT_ERROR   , "encryption error" },
    { TPM_DECRYPT_ERROR   , "decryption error" },
    { TPM_BAD_KEY_PROPERTY, "bad key property" },
    { TPM_BAD_MODE        , "bad (encryption) mode" },
    { TPM_BAD_VERSION     , "bad version identifier" },
    { TPM_BAD_LOCALITY    , "bad locality" },
    /* TPM 2 error codes */
    { TPM_RC_FAILURE     , "operation failed" },
    { TPM_RC_LOCALITY    , "bad locality"     },
    { TPM_RC_INSUFFICIENT, "insufficient amount of data" },
};

static const char *tpm_emulator_strerror(uint32_t tpm_result)
{
    size_t i;

    for (i = 0; i < ARRAY_SIZE(tpm_errors); i++) {
        if (tpm_errors[i].tpm_result == tpm_result) {
            return tpm_errors[i].string;
        }
    }
    return "";
}

static int tpm_emulator_ctrlcmd(TPMEmulator *tpm, unsigned long cmd, void *msg,
                                size_t msg_len_in, size_t msg_len_out)
{
    CharBackend *dev = &tpm->ctrl_chr;
    uint32_t cmd_no = cpu_to_be32(cmd);
    ssize_t n = sizeof(uint32_t) + msg_len_in;
    uint8_t *buf = NULL;
    int ret = -1;

    qemu_mutex_lock(&tpm->mutex);

    buf = g_alloca(n);
    memcpy(buf, &cmd_no, sizeof(cmd_no));
    memcpy(buf + sizeof(cmd_no), msg, msg_len_in);

    n = qemu_chr_fe_write_all(dev, buf, n);
    if (n <= 0) {
        goto end;
    }

    if (msg_len_out != 0) {
        n = qemu_chr_fe_read_all(dev, msg, msg_len_out);
        if (n <= 0) {
            goto end;
        }
    }

    ret = 0;

end:
    qemu_mutex_unlock(&tpm->mutex);
    return ret;
}

static int tpm_emulator_unix_tx_bufs(TPMEmulator *tpm_emu,
                                     const uint8_t *in, uint32_t in_len,
                                     uint8_t *out, uint32_t out_len,
                                     bool *selftest_done,
                                     Error **errp)
{
    ssize_t ret;
    bool is_selftest = false;

    if (selftest_done) {
        *selftest_done = false;
        is_selftest = tpm_util_is_selftest(in, in_len);
    }

    ret = qio_channel_write_all(tpm_emu->data_ioc, (char *)in, in_len, errp);
    if (ret != 0) {
        return -1;
    }

    ret = qio_channel_read_all(tpm_emu->data_ioc, (char *)out,
              sizeof(struct tpm_resp_hdr), errp);
    if (ret != 0) {
        return -1;
    }

    ret = qio_channel_read_all(tpm_emu->data_ioc,
              (char *)out + sizeof(struct tpm_resp_hdr),
              tpm_cmd_get_size(out) - sizeof(struct tpm_resp_hdr), errp);
    if (ret != 0) {
        return -1;
    }

    if (is_selftest) {
        *selftest_done = tpm_cmd_get_errcode(out) == 0;
    }

    return 0;
}

static int tpm_emulator_set_locality(TPMEmulator *tpm_emu, uint8_t locty_number,
                                     Error **errp)
{
    ptm_loc loc;

    if (tpm_emu->cur_locty_number == locty_number) {
        return 0;
    }

    trace_tpm_emulator_set_locality(locty_number);

    memset(&loc, 0, sizeof(loc));
    loc.u.req.loc = locty_number;
    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_LOCALITY, &loc,
                             sizeof(loc), sizeof(loc)) < 0) {
        error_setg(errp, "tpm-emulator: could not set locality : %s",
                   strerror(errno));
        return -1;
    }

    loc.u.resp.tpm_result = be32_to_cpu(loc.u.resp.tpm_result);
    if (loc.u.resp.tpm_result != 0) {
        error_setg(errp, "tpm-emulator: TPM result for set locality : 0x%x",
                   loc.u.resp.tpm_result);
        return -1;
    }

    tpm_emu->cur_locty_number = locty_number;

    return 0;
}

static void tpm_emulator_handle_request(TPMBackend *tb, TPMBackendCmd *cmd,
                                        Error **errp)
{
    TPMEmulator *tpm_emu = TPM_EMULATOR(tb);

    trace_tpm_emulator_handle_request();

    if (tpm_emulator_set_locality(tpm_emu, cmd->locty, errp) < 0 ||
        tpm_emulator_unix_tx_bufs(tpm_emu, cmd->in, cmd->in_len,
                                  cmd->out, cmd->out_len,
                                  &cmd->selftest_done, errp) < 0) {
        tpm_util_write_fatal_error_response(cmd->out, cmd->out_len);
    }
}

static int tpm_emulator_probe_caps(TPMEmulator *tpm_emu)
{
    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_CAPABILITY,
                             &tpm_emu->caps, 0, sizeof(tpm_emu->caps)) < 0) {
        error_report("tpm-emulator: probing failed : %s", strerror(errno));
        return -1;
    }

    tpm_emu->caps = be64_to_cpu(tpm_emu->caps);

    trace_tpm_emulator_probe_caps(tpm_emu->caps);

    return 0;
}

static int tpm_emulator_check_caps(TPMEmulator *tpm_emu)
{
    ptm_cap caps = 0;
    const char *tpm = NULL;

    /* check for min. required capabilities */
    switch (tpm_emu->tpm_version) {
    case TPM_VERSION_1_2:
        caps = PTM_CAP_INIT | PTM_CAP_SHUTDOWN | PTM_CAP_GET_TPMESTABLISHED |
               PTM_CAP_SET_LOCALITY | PTM_CAP_SET_DATAFD | PTM_CAP_STOP |
               PTM_CAP_SET_BUFFERSIZE;
        tpm = "1.2";
        break;
    case TPM_VERSION_2_0:
        caps = PTM_CAP_INIT | PTM_CAP_SHUTDOWN | PTM_CAP_GET_TPMESTABLISHED |
               PTM_CAP_SET_LOCALITY | PTM_CAP_RESET_TPMESTABLISHED |
               PTM_CAP_SET_DATAFD | PTM_CAP_STOP | PTM_CAP_SET_BUFFERSIZE;
        tpm = "2";
        break;
    case TPM_VERSION_UNSPEC:
        error_report("tpm-emulator: TPM version has not been set");
        return -1;
    }

    if (!TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(tpm_emu, caps)) {
        error_report("tpm-emulator: TPM does not implement minimum set of "
                     "required capabilities for TPM %s (0x%x)", tpm, (int)caps);
        return -1;
    }

    return 0;
}

static int tpm_emulator_stop_tpm(TPMBackend *tb)
{
    TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
    ptm_res res;

    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_STOP, &res, 0, sizeof(res)) < 0) {
        error_report("tpm-emulator: Could not stop TPM: %s",
                     strerror(errno));
        return -1;
    }

    res = be32_to_cpu(res);
    if (res) {
        error_report("tpm-emulator: TPM result for CMD_STOP: 0x%x %s", res,
                     tpm_emulator_strerror(res));
        return -1;
    }

    return 0;
}

static int tpm_emulator_set_buffer_size(TPMBackend *tb,
                                        size_t wanted_size,
                                        size_t *actual_size)
{
    TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
    ptm_setbuffersize psbs;

    if (tpm_emulator_stop_tpm(tb) < 0) {
        return -1;
    }

    psbs.u.req.buffersize = cpu_to_be32(wanted_size);

    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_BUFFERSIZE, &psbs,
                             sizeof(psbs.u.req), sizeof(psbs.u.resp)) < 0) {
        error_report("tpm-emulator: Could not set buffer size: %s",
                     strerror(errno));
        return -1;
    }

    psbs.u.resp.tpm_result = be32_to_cpu(psbs.u.resp.tpm_result);
    if (psbs.u.resp.tpm_result != 0) {
        error_report("tpm-emulator: TPM result for set buffer size : 0x%x %s",
                     psbs.u.resp.tpm_result,
                     tpm_emulator_strerror(psbs.u.resp.tpm_result));
        return -1;
    }

    if (actual_size) {
        *actual_size = be32_to_cpu(psbs.u.resp.buffersize);
    }

    trace_tpm_emulator_set_buffer_size(
            be32_to_cpu(psbs.u.resp.buffersize),
            be32_to_cpu(psbs.u.resp.minsize),
            be32_to_cpu(psbs.u.resp.maxsize));

    return 0;
}

static int tpm_emulator_startup_tpm_resume(TPMBackend *tb, size_t buffersize,
                                     bool is_resume)
{
    TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
    ptm_init init = {
        .u.req.init_flags = 0,
    };
    ptm_res res;

    trace_tpm_emulator_startup_tpm_resume(is_resume, buffersize);

    if (buffersize != 0 &&
        tpm_emulator_set_buffer_size(tb, buffersize, NULL) < 0) {
        goto err_exit;
    }

    if (is_resume) {
        init.u.req.init_flags |= cpu_to_be32(PTM_INIT_FLAG_DELETE_VOLATILE);
    }

    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_INIT, &init, sizeof(init),
                             sizeof(init)) < 0) {
        error_report("tpm-emulator: could not send INIT: %s",
                     strerror(errno));
        goto err_exit;
    }

    res = be32_to_cpu(init.u.resp.tpm_result);
    if (res) {
        error_report("tpm-emulator: TPM result for CMD_INIT: 0x%x %s", res,
                     tpm_emulator_strerror(res));
        goto err_exit;
    }
    return 0;

err_exit:
    return -1;
}

static int tpm_emulator_startup_tpm(TPMBackend *tb, size_t buffersize)
{
    return tpm_emulator_startup_tpm_resume(tb, buffersize, false);
}

static bool tpm_emulator_get_tpm_established_flag(TPMBackend *tb)
{
    TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
    ptm_est est;

    if (tpm_emu->established_flag_cached) {
        return tpm_emu->established_flag;
    }

    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_TPMESTABLISHED, &est,
                             0, sizeof(est)) < 0) {
        error_report("tpm-emulator: Could not get the TPM established flag: %s",
                     strerror(errno));
        return false;
    }
    trace_tpm_emulator_get_tpm_established_flag(est.u.resp.bit);

    tpm_emu->established_flag_cached = 1;
    tpm_emu->established_flag = (est.u.resp.bit != 0);

    return tpm_emu->established_flag;
}

static int tpm_emulator_reset_tpm_established_flag(TPMBackend *tb,
                                                   uint8_t locty)
{
    TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
    ptm_reset_est reset_est;
    ptm_res res;

    /* only a TPM 2.0 will support this */
    if (tpm_emu->tpm_version != TPM_VERSION_2_0) {
        return 0;
    }

    reset_est.u.req.loc = tpm_emu->cur_locty_number;
    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_RESET_TPMESTABLISHED,
                             &reset_est, sizeof(reset_est),
                             sizeof(reset_est)) < 0) {
        error_report("tpm-emulator: Could not reset the establishment bit: %s",
                     strerror(errno));
        return -1;
    }

    res = be32_to_cpu(reset_est.u.resp.tpm_result);
    if (res) {
        error_report(
            "tpm-emulator: TPM result for rest established flag: 0x%x %s",
            res, tpm_emulator_strerror(res));
        return -1;
    }

    tpm_emu->established_flag_cached = 0;

    return 0;
}

static void tpm_emulator_cancel_cmd(TPMBackend *tb)
{
    TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
    ptm_res res;

    if (!TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(tpm_emu, PTM_CAP_CANCEL_TPM_CMD)) {
        trace_tpm_emulator_cancel_cmd_not_supt();
        return;
    }

    /* FIXME: make the function non-blocking, or it may block a VCPU */
    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_CANCEL_TPM_CMD, &res, 0,
                             sizeof(res)) < 0) {
        error_report("tpm-emulator: Could not cancel command: %s",
                     strerror(errno));
    } else if (res != 0) {
        error_report("tpm-emulator: Failed to cancel TPM: 0x%x",
                     be32_to_cpu(res));
    }
}

static TPMVersion tpm_emulator_get_tpm_version(TPMBackend *tb)
{
    TPMEmulator *tpm_emu = TPM_EMULATOR(tb);

    return tpm_emu->tpm_version;
}

static size_t tpm_emulator_get_buffer_size(TPMBackend *tb)
{
    size_t actual_size;

    if (tpm_emulator_set_buffer_size(tb, 0, &actual_size) < 0) {
        return 4096;
    }

    return actual_size;
}

static int tpm_emulator_block_migration(TPMEmulator *tpm_emu)
{
    Error *err = NULL;
    ptm_cap caps = PTM_CAP_GET_STATEBLOB | PTM_CAP_SET_STATEBLOB |
                   PTM_CAP_STOP;

    if (!TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(tpm_emu, caps)) {
        error_setg(&tpm_emu->migration_blocker,
                   "Migration disabled: TPM emulator does not support "
                   "migration");
        migrate_add_blocker(tpm_emu->migration_blocker, &err);
        if (err) {
            error_report_err(err);
            error_free(tpm_emu->migration_blocker);
            tpm_emu->migration_blocker = NULL;

            return -1;
        }
    }

    return 0;
}

static int tpm_emulator_prepare_data_fd(TPMEmulator *tpm_emu)
{
    ptm_res res;
    Error *err = NULL;
    int fds[2] = { -1, -1 };

    if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
        error_report("tpm-emulator: Failed to create socketpair");
        return -1;
    }

    qemu_chr_fe_set_msgfds(&tpm_emu->ctrl_chr, fds + 1, 1);

    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_DATAFD, &res, 0,
                             sizeof(res)) < 0 || res != 0) {
        error_report("tpm-emulator: Failed to send CMD_SET_DATAFD: %s",
                     strerror(errno));
        goto err_exit;
    }

    tpm_emu->data_ioc = QIO_CHANNEL(qio_channel_socket_new_fd(fds[0], &err));
    if (err) {
        error_prepend(&err, "tpm-emulator: Failed to create io channel: ");
        error_report_err(err);
        goto err_exit;
    }

    closesocket(fds[1]);

    return 0;

err_exit:
    closesocket(fds[0]);
    closesocket(fds[1]);
    return -1;
}

static int tpm_emulator_handle_device_opts(TPMEmulator *tpm_emu, QemuOpts *opts)
{
    const char *value;
    Error *err = NULL;
    Chardev *dev;

    value = qemu_opt_get(opts, "chardev");
    if (!value) {
        error_report("tpm-emulator: parameter 'chardev' is missing");
        goto err;
    }

    dev = qemu_chr_find(value);
    if (!dev) {
        error_report("tpm-emulator: tpm chardev '%s' not found", value);
        goto err;
    }

    if (!qemu_chr_fe_init(&tpm_emu->ctrl_chr, dev, &err)) {
        error_prepend(&err, "tpm-emulator: No valid chardev found at '%s':",
                      value);
        error_report_err(err);
        goto err;
    }

    tpm_emu->options->chardev = g_strdup(value);

    if (tpm_emulator_prepare_data_fd(tpm_emu) < 0) {
        goto err;
    }

    /* FIXME: tpm_util_test_tpmdev() accepts only on socket fd, as it also used
     * by passthrough driver, which not yet using GIOChannel.
     */
    if (tpm_util_test_tpmdev(QIO_CHANNEL_SOCKET(tpm_emu->data_ioc)->fd,
                             &tpm_emu->tpm_version)) {
        error_report("'%s' is not emulating TPM device. Error: %s",
                      tpm_emu->options->chardev, strerror(errno));
        goto err;
    }

    switch (tpm_emu->tpm_version) {
    case TPM_VERSION_1_2:
        trace_tpm_emulator_handle_device_opts_tpm12();
        break;
    case TPM_VERSION_2_0:
        trace_tpm_emulator_handle_device_opts_tpm2();
        break;
    default:
        trace_tpm_emulator_handle_device_opts_unspec();
    }

    if (tpm_emulator_probe_caps(tpm_emu) ||
        tpm_emulator_check_caps(tpm_emu)) {
        goto err;
    }

    return tpm_emulator_block_migration(tpm_emu);

err:
    trace_tpm_emulator_handle_device_opts_startup_error();

    return -1;
}

static TPMBackend *tpm_emulator_create(QemuOpts *opts)
{
    TPMBackend *tb = TPM_BACKEND(object_new(TYPE_TPM_EMULATOR));

    if (tpm_emulator_handle_device_opts(TPM_EMULATOR(tb), opts)) {
        object_unref(OBJECT(tb));
        return NULL;
    }

    return tb;
}

static TpmTypeOptions *tpm_emulator_get_tpm_options(TPMBackend *tb)
{
    TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
    TpmTypeOptions *options = g_new0(TpmTypeOptions, 1);

    options->type = TPM_TYPE_OPTIONS_KIND_EMULATOR;
    options->u.emulator.data = QAPI_CLONE(TPMEmulatorOptions, tpm_emu->options);

    return options;
}

static const QemuOptDesc tpm_emulator_cmdline_opts[] = {
    TPM_STANDARD_CMDLINE_OPTS,
    {
        .name = "chardev",
        .type = QEMU_OPT_STRING,
        .help = "Character device to use for out-of-band control messages",
    },
    { /* end of list */ },
};

/*
 * Transfer a TPM state blob from the TPM into a provided buffer.
 *
 * @tpm_emu: TPMEmulator
 * @type: the type of blob to transfer
 * @tsb: the TPMSizeBuffer to fill with the blob
 * @flags: the flags to return to the caller
 */
static int tpm_emulator_get_state_blob(TPMEmulator *tpm_emu,
                                       uint8_t type,
                                       TPMSizedBuffer *tsb,
                                       uint32_t *flags)
{
    ptm_getstate pgs;
    ptm_res res;
    ssize_t n;
    uint32_t totlength, length;

    tpm_sized_buffer_reset(tsb);

    pgs.u.req.state_flags = cpu_to_be32(PTM_STATE_FLAG_DECRYPTED);
    pgs.u.req.type = cpu_to_be32(type);
    pgs.u.req.offset = 0;

    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_GET_STATEBLOB,
                             &pgs, sizeof(pgs.u.req),
                             offsetof(ptm_getstate, u.resp.data)) < 0) {
        error_report("tpm-emulator: could not get state blob type %d : %s",
                     type, strerror(errno));
        return -1;
    }

    res = be32_to_cpu(pgs.u.resp.tpm_result);
    if (res != 0 && (res & 0x800) == 0) {
        error_report("tpm-emulator: Getting the stateblob (type %d) failed "
                     "with a TPM error 0x%x %s", type, res,
                     tpm_emulator_strerror(res));
        return -1;
    }

    totlength = be32_to_cpu(pgs.u.resp.totlength);
    length = be32_to_cpu(pgs.u.resp.length);
    if (totlength != length) {
        error_report("tpm-emulator: Expecting to read %u bytes "
                     "but would get %u", totlength, length);
        return -1;
    }

    *flags = be32_to_cpu(pgs.u.resp.state_flags);

    if (totlength > 0) {
        tsb->buffer = g_try_malloc(totlength);
        if (!tsb->buffer) {
            error_report("tpm-emulator: Out of memory allocating %u bytes",
                         totlength);
            return -1;
        }

        n = qemu_chr_fe_read_all(&tpm_emu->ctrl_chr, tsb->buffer, totlength);
        if (n != totlength) {
            error_report("tpm-emulator: Could not read stateblob (type %d); "
                         "expected %u bytes, got %zd",
                         type, totlength, n);
            return -1;
        }
    }
    tsb->size = totlength;

    trace_tpm_emulator_get_state_blob(type, tsb->size, *flags);

    return 0;
}

static int tpm_emulator_get_state_blobs(TPMEmulator *tpm_emu)
{
    TPMBlobBuffers *state_blobs = &tpm_emu->state_blobs;

    if (tpm_emulator_get_state_blob(tpm_emu, PTM_BLOB_TYPE_PERMANENT,
                                    &state_blobs->permanent,
                                    &state_blobs->permanent_flags) < 0 ||
        tpm_emulator_get_state_blob(tpm_emu, PTM_BLOB_TYPE_VOLATILE,
                                    &state_blobs->volatil,
                                    &state_blobs->volatil_flags) < 0 ||
        tpm_emulator_get_state_blob(tpm_emu, PTM_BLOB_TYPE_SAVESTATE,
                                    &state_blobs->savestate,
                                    &state_blobs->savestate_flags) < 0) {
        goto err_exit;
    }

    return 0;

 err_exit:
    tpm_sized_buffer_reset(&state_blobs->volatil);
    tpm_sized_buffer_reset(&state_blobs->permanent);
    tpm_sized_buffer_reset(&state_blobs->savestate);

    return -1;
}

/*
 * Transfer a TPM state blob to the TPM emulator.
 *
 * @tpm_emu: TPMEmulator
 * @type: the type of TPM state blob to transfer
 * @tsb: TPMSizedBuffer containing the TPM state blob
 * @flags: Flags describing the (encryption) state of the TPM state blob
 */
static int tpm_emulator_set_state_blob(TPMEmulator *tpm_emu,
                                       uint32_t type,
                                       TPMSizedBuffer *tsb,
                                       uint32_t flags)
{
    ssize_t n;
    ptm_setstate pss;
    ptm_res tpm_result;

    if (tsb->size == 0) {
        return 0;
    }

    pss = (ptm_setstate) {
        .u.req.state_flags = cpu_to_be32(flags),
        .u.req.type = cpu_to_be32(type),
        .u.req.length = cpu_to_be32(tsb->size),
    };

    /* write the header only */
    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SET_STATEBLOB, &pss,
                             offsetof(ptm_setstate, u.req.data), 0) < 0) {
        error_report("tpm-emulator: could not set state blob type %d : %s",
                     type, strerror(errno));
        return -1;
    }

    /* now the body */
    n = qemu_chr_fe_write_all(&tpm_emu->ctrl_chr, tsb->buffer, tsb->size);
    if (n != tsb->size) {
        error_report("tpm-emulator: Writing the stateblob (type %d) "
                     "failed; could not write %u bytes, but only %zd",
                     type, tsb->size, n);
        return -1;
    }

    /* now get the result */
    n = qemu_chr_fe_read_all(&tpm_emu->ctrl_chr,
                             (uint8_t *)&pss, sizeof(pss.u.resp));
    if (n != sizeof(pss.u.resp)) {
        error_report("tpm-emulator: Reading response from writing stateblob "
                     "(type %d) failed; expected %zu bytes, got %zd", type,
                     sizeof(pss.u.resp), n);
        return -1;
    }

    tpm_result = be32_to_cpu(pss.u.resp.tpm_result);
    if (tpm_result != 0) {
        error_report("tpm-emulator: Setting the stateblob (type %d) failed "
                     "with a TPM error 0x%x %s", type, tpm_result,
                     tpm_emulator_strerror(tpm_result));
        return -1;
    }

    trace_tpm_emulator_set_state_blob(type, tsb->size, flags);

    return 0;
}

/*
 * Set all the TPM state blobs.
 *
 * Returns a negative errno code in case of error.
 */
static int tpm_emulator_set_state_blobs(TPMBackend *tb)
{
    TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
    TPMBlobBuffers *state_blobs = &tpm_emu->state_blobs;

    trace_tpm_emulator_set_state_blobs();

    if (tpm_emulator_stop_tpm(tb) < 0) {
        trace_tpm_emulator_set_state_blobs_error("Could not stop TPM");
        return -EIO;
    }

    if (tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_PERMANENT,
                                    &state_blobs->permanent,
                                    state_blobs->permanent_flags) < 0 ||
        tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_VOLATILE,
                                    &state_blobs->volatil,
                                    state_blobs->volatil_flags) < 0 ||
        tpm_emulator_set_state_blob(tpm_emu, PTM_BLOB_TYPE_SAVESTATE,
                                    &state_blobs->savestate,
                                    state_blobs->savestate_flags) < 0) {
        return -EIO;
    }

    trace_tpm_emulator_set_state_blobs_done();

    return 0;
}

static int tpm_emulator_pre_save(void *opaque)
{
    TPMBackend *tb = opaque;
    TPMEmulator *tpm_emu = TPM_EMULATOR(tb);

    trace_tpm_emulator_pre_save();

    tpm_backend_finish_sync(tb);

    /* get the state blobs from the TPM */
    return tpm_emulator_get_state_blobs(tpm_emu);
}

/*
 * Load the TPM state blobs into the TPM.
 *
 * Returns negative errno codes in case of error.
 */
static int tpm_emulator_post_load(void *opaque, int version_id)
{
    TPMBackend *tb = opaque;
    int ret;

    ret = tpm_emulator_set_state_blobs(tb);
    if (ret < 0) {
        return ret;
    }

    if (tpm_emulator_startup_tpm_resume(tb, 0, true) < 0) {
        return -EIO;
    }

    return 0;
}

static const VMStateDescription vmstate_tpm_emulator = {
    .name = "tpm-emulator",
    .version_id = 0,
    .pre_save = tpm_emulator_pre_save,
    .post_load = tpm_emulator_post_load,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(state_blobs.permanent_flags, TPMEmulator),
        VMSTATE_UINT32(state_blobs.permanent.size, TPMEmulator),
        VMSTATE_VBUFFER_ALLOC_UINT32(state_blobs.permanent.buffer,
                                     TPMEmulator, 0, 0,
                                     state_blobs.permanent.size),

        VMSTATE_UINT32(state_blobs.volatil_flags, TPMEmulator),
        VMSTATE_UINT32(state_blobs.volatil.size, TPMEmulator),
        VMSTATE_VBUFFER_ALLOC_UINT32(state_blobs.volatil.buffer,
                                     TPMEmulator, 0, 0,
                                     state_blobs.volatil.size),

        VMSTATE_UINT32(state_blobs.savestate_flags, TPMEmulator),
        VMSTATE_UINT32(state_blobs.savestate.size, TPMEmulator),
        VMSTATE_VBUFFER_ALLOC_UINT32(state_blobs.savestate.buffer,
                                     TPMEmulator, 0, 0,
                                     state_blobs.savestate.size),

        VMSTATE_END_OF_LIST()
    }
};

static void tpm_emulator_inst_init(Object *obj)
{
    TPMEmulator *tpm_emu = TPM_EMULATOR(obj);

    trace_tpm_emulator_inst_init();

    tpm_emu->options = g_new0(TPMEmulatorOptions, 1);
    tpm_emu->cur_locty_number = ~0;
    qemu_mutex_init(&tpm_emu->mutex);

    vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY,
                     &vmstate_tpm_emulator, obj);
}

/*
 * Gracefully shut down the external TPM
 */
static void tpm_emulator_shutdown(TPMEmulator *tpm_emu)
{
    ptm_res res;

    if (!tpm_emu->options->chardev) {
        /* was never properly initialized */
        return;
    }

    if (tpm_emulator_ctrlcmd(tpm_emu, CMD_SHUTDOWN, &res, 0, sizeof(res)) < 0) {
        error_report("tpm-emulator: Could not cleanly shutdown the TPM: %s",
                     strerror(errno));
    } else if (res != 0) {
        error_report("tpm-emulator: TPM result for shutdown: 0x%x %s",
                     be32_to_cpu(res), tpm_emulator_strerror(be32_to_cpu(res)));
    }
}

static void tpm_emulator_inst_finalize(Object *obj)
{
    TPMEmulator *tpm_emu = TPM_EMULATOR(obj);
    TPMBlobBuffers *state_blobs = &tpm_emu->state_blobs;

    tpm_emulator_shutdown(tpm_emu);

    object_unref(OBJECT(tpm_emu->data_ioc));

    qemu_chr_fe_deinit(&tpm_emu->ctrl_chr, false);

    qapi_free_TPMEmulatorOptions(tpm_emu->options);

    if (tpm_emu->migration_blocker) {
        migrate_del_blocker(tpm_emu->migration_blocker);
        error_free(tpm_emu->migration_blocker);
    }

    tpm_sized_buffer_reset(&state_blobs->volatil);
    tpm_sized_buffer_reset(&state_blobs->permanent);
    tpm_sized_buffer_reset(&state_blobs->savestate);

    qemu_mutex_destroy(&tpm_emu->mutex);

    vmstate_unregister(NULL, &vmstate_tpm_emulator, obj);
}

static void tpm_emulator_class_init(ObjectClass *klass, void *data)
{
    TPMBackendClass *tbc = TPM_BACKEND_CLASS(klass);

    tbc->type = TPM_TYPE_EMULATOR;
    tbc->opts = tpm_emulator_cmdline_opts;
    tbc->desc = "TPM emulator backend driver";
    tbc->create = tpm_emulator_create;
    tbc->startup_tpm = tpm_emulator_startup_tpm;
    tbc->cancel_cmd = tpm_emulator_cancel_cmd;
    tbc->get_tpm_established_flag = tpm_emulator_get_tpm_established_flag;
    tbc->reset_tpm_established_flag = tpm_emulator_reset_tpm_established_flag;
    tbc->get_tpm_version = tpm_emulator_get_tpm_version;
    tbc->get_buffer_size = tpm_emulator_get_buffer_size;
    tbc->get_tpm_options = tpm_emulator_get_tpm_options;

    tbc->handle_request = tpm_emulator_handle_request;
}

static const TypeInfo tpm_emulator_info = {
    .name = TYPE_TPM_EMULATOR,
    .parent = TYPE_TPM_BACKEND,
    .instance_size = sizeof(TPMEmulator),
    .class_init = tpm_emulator_class_init,
    .instance_init = tpm_emulator_inst_init,
    .instance_finalize = tpm_emulator_inst_finalize,
};

static void tpm_emulator_register(void)
{
    type_register_static(&tpm_emulator_info);
}

type_init(tpm_emulator_register)
