/*
 *  passthrough TPM driver
 *
 *  Copyright (c) 2010 - 2013 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.1 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 "sysemu/tpm_backend.h"
#include "sysemu/tpm_util.h"
#include "tpm_int.h"
#include "qapi/clone-visitor.h"
#include "qapi/qapi-visit-tpm.h"
#include "trace.h"
#include "qom/object.h"

#define TYPE_TPM_PASSTHROUGH "tpm-passthrough"
OBJECT_DECLARE_SIMPLE_TYPE(TPMPassthruState, TPM_PASSTHROUGH)

/* data structures */
struct TPMPassthruState {
    TPMBackend parent;

    TPMPassthroughOptions *options;
    const char *tpm_dev;
    int tpm_fd;
    bool tpm_executing;
    bool tpm_op_canceled;
    int cancel_fd;

    TPMVersion tpm_version;
    size_t tpm_buffersize;
};


#define TPM_PASSTHROUGH_DEFAULT_DEVICE "/dev/tpm0"

/* functions */

static void tpm_passthrough_cancel_cmd(TPMBackend *tb);

static int tpm_passthrough_unix_read(int fd, uint8_t *buf, uint32_t len)
{
    int ret;
 reread:
    ret = read(fd, buf, len);
    if (ret < 0) {
        if (errno != EINTR && errno != EAGAIN) {
            return -1;
        }
        goto reread;
    }
    return ret;
}

static void tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt,
                                         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;

    /* FIXME: protect shared variables or use other sync mechanism */
    tpm_pt->tpm_op_canceled = false;
    tpm_pt->tpm_executing = true;
    *selftest_done = false;

    is_selftest = tpm_util_is_selftest(in, in_len);

    ret = qemu_write_full(tpm_pt->tpm_fd, in, in_len);
    if (ret != in_len) {
        if (!tpm_pt->tpm_op_canceled || errno != ECANCELED) {
            error_setg_errno(errp, errno, "tpm_passthrough: error while "
                             "transmitting data to TPM");
        }
        goto err_exit;
    }

    tpm_pt->tpm_executing = false;

    ret = tpm_passthrough_unix_read(tpm_pt->tpm_fd, out, out_len);
    if (ret < 0) {
        if (!tpm_pt->tpm_op_canceled || errno != ECANCELED) {
            error_setg_errno(errp, errno, "tpm_passthrough: error while "
                             "reading data from TPM");
        }
    } else if (ret < sizeof(struct tpm_resp_hdr) ||
               tpm_cmd_get_size(out) != ret) {
        ret = -1;
        error_setg_errno(errp, errno, "tpm_passthrough: received invalid "
                     "response packet from TPM");
    }

    if (is_selftest && (ret >= sizeof(struct tpm_resp_hdr))) {
        *selftest_done = tpm_cmd_get_errcode(out) == 0;
    }

err_exit:
    if (ret < 0) {
        tpm_util_write_fatal_error_response(out, out_len);
    }

    tpm_pt->tpm_executing = false;
}

static void tpm_passthrough_handle_request(TPMBackend *tb, TPMBackendCmd *cmd,
                                           Error **errp)
{
    TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);

    trace_tpm_passthrough_handle_request(cmd);

    tpm_passthrough_unix_tx_bufs(tpm_pt, cmd->in, cmd->in_len,
                                 cmd->out, cmd->out_len, &cmd->selftest_done,
                                 errp);
}

static void tpm_passthrough_reset(TPMBackend *tb)
{
    trace_tpm_passthrough_reset();

    tpm_passthrough_cancel_cmd(tb);
}

static bool tpm_passthrough_get_tpm_established_flag(TPMBackend *tb)
{
    return false;
}

static int tpm_passthrough_reset_tpm_established_flag(TPMBackend *tb,
                                                      uint8_t locty)
{
    /* only a TPM 2.0 will support this */
    return 0;
}

static void tpm_passthrough_cancel_cmd(TPMBackend *tb)
{
    TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
    int n;

    /*
     * As of Linux 3.7 the tpm_tis driver does not properly cancel
     * commands on all TPM manufacturers' TPMs.
     * Only cancel if we're busy so we don't cancel someone else's
     * command, e.g., a command executed on the host.
     */
    if (tpm_pt->tpm_executing) {
        if (tpm_pt->cancel_fd >= 0) {
            tpm_pt->tpm_op_canceled = true;
            n = write(tpm_pt->cancel_fd, "-", 1);
            if (n != 1) {
                error_report("Canceling TPM command failed: %s",
                             strerror(errno));
            }
        } else {
            error_report("Cannot cancel TPM command due to missing "
                         "TPM sysfs cancel entry");
        }
    }
}

static TPMVersion tpm_passthrough_get_tpm_version(TPMBackend *tb)
{
    TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);

    return tpm_pt->tpm_version;
}

static size_t tpm_passthrough_get_buffer_size(TPMBackend *tb)
{
    TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
    int ret;

    ret = tpm_util_get_buffer_size(tpm_pt->tpm_fd, tpm_pt->tpm_version,
                                   &tpm_pt->tpm_buffersize);
    if (ret < 0) {
        tpm_pt->tpm_buffersize = 4096;
    }
    return tpm_pt->tpm_buffersize;
}

/*
 * Unless path or file descriptor set has been provided by user,
 * determine the sysfs cancel file following kernel documentation
 * in Documentation/ABI/stable/sysfs-class-tpm.
 * From /dev/tpm0 create /sys/class/tpm/tpm0/device/cancel
 * before 4.0: /sys/class/misc/tpm0/device/cancel
 */
static int tpm_passthrough_open_sysfs_cancel(TPMPassthruState *tpm_pt)
{
    int fd = -1;
    char *dev;
    char path[PATH_MAX];

    if (tpm_pt->options->cancel_path) {
        fd = qemu_open_old(tpm_pt->options->cancel_path, O_WRONLY);
        if (fd < 0) {
            error_report("tpm_passthrough: Could not open TPM cancel path: %s",
                         strerror(errno));
        }
        return fd;
    }

    dev = strrchr(tpm_pt->tpm_dev, '/');
    if (!dev) {
        error_report("tpm_passthrough: Bad TPM device path %s",
                     tpm_pt->tpm_dev);
        return -1;
    }

    dev++;
    if (snprintf(path, sizeof(path), "/sys/class/tpm/%s/device/cancel",
                 dev) < sizeof(path)) {
        fd = qemu_open_old(path, O_WRONLY);
        if (fd < 0) {
            if (snprintf(path, sizeof(path), "/sys/class/misc/%s/device/cancel",
                         dev) < sizeof(path)) {
                fd = qemu_open_old(path, O_WRONLY);
            }
        }
    }

    if (fd < 0) {
        error_report("tpm_passthrough: Could not guess TPM cancel path");
    } else {
        tpm_pt->options->cancel_path = g_strdup(path);
    }

    return fd;
}

static int
tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt, QemuOpts *opts)
{
    const char *value;

    value = qemu_opt_get(opts, "cancel-path");
    if (value) {
        tpm_pt->options->cancel_path = g_strdup(value);
    }

    value = qemu_opt_get(opts, "path");
    if (value) {
        tpm_pt->options->path = g_strdup(value);
    }

    tpm_pt->tpm_dev = value ? value : TPM_PASSTHROUGH_DEFAULT_DEVICE;
    tpm_pt->tpm_fd = qemu_open_old(tpm_pt->tpm_dev, O_RDWR);
    if (tpm_pt->tpm_fd < 0) {
        error_report("Cannot access TPM device using '%s': %s",
                     tpm_pt->tpm_dev, strerror(errno));
        return -1;
    }

    if (tpm_util_test_tpmdev(tpm_pt->tpm_fd, &tpm_pt->tpm_version)) {
        error_report("'%s' is not a TPM device.",
                     tpm_pt->tpm_dev);
        return -1;
    }

    tpm_pt->cancel_fd = tpm_passthrough_open_sysfs_cancel(tpm_pt);
    if (tpm_pt->cancel_fd < 0) {
        return -1;
    }

    return 0;
}

static TPMBackend *tpm_passthrough_create(QemuOpts *opts)
{
    Object *obj = object_new(TYPE_TPM_PASSTHROUGH);

    if (tpm_passthrough_handle_device_opts(TPM_PASSTHROUGH(obj), opts)) {
        object_unref(obj);
        return NULL;
    }

    return TPM_BACKEND(obj);
}

static int tpm_passthrough_startup_tpm(TPMBackend *tb, size_t buffersize)
{
    TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);

    if (buffersize && buffersize < tpm_pt->tpm_buffersize) {
        error_report("Requested buffer size of %zu is smaller than host TPM's "
                     "fixed buffer size of %zu",
                     buffersize, tpm_pt->tpm_buffersize);
        return -1;
    }

    return 0;
}

static TpmTypeOptions *tpm_passthrough_get_tpm_options(TPMBackend *tb)
{
    TpmTypeOptions *options = g_new0(TpmTypeOptions, 1);

    options->type = TPM_TYPE_PASSTHROUGH;
    options->u.passthrough.data = QAPI_CLONE(TPMPassthroughOptions,
                                             TPM_PASSTHROUGH(tb)->options);

    return options;
}

static const QemuOptDesc tpm_passthrough_cmdline_opts[] = {
    TPM_STANDARD_CMDLINE_OPTS,
    {
        .name = "cancel-path",
        .type = QEMU_OPT_STRING,
        .help = "Sysfs file entry for canceling TPM commands",
    },
    {
        .name = "path",
        .type = QEMU_OPT_STRING,
        .help = "Path to TPM device on the host",
    },
    { /* end of list */ },
};

static void tpm_passthrough_inst_init(Object *obj)
{
    TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(obj);

    tpm_pt->options = g_new0(TPMPassthroughOptions, 1);
    tpm_pt->tpm_fd = -1;
    tpm_pt->cancel_fd = -1;
}

static void tpm_passthrough_inst_finalize(Object *obj)
{
    TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(obj);

    tpm_passthrough_cancel_cmd(TPM_BACKEND(obj));

    if (tpm_pt->tpm_fd >= 0) {
        qemu_close(tpm_pt->tpm_fd);
    }
    if (tpm_pt->cancel_fd >= 0) {
        qemu_close(tpm_pt->cancel_fd);
    }
    qapi_free_TPMPassthroughOptions(tpm_pt->options);
}

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

    tbc->type = TPM_TYPE_PASSTHROUGH;
    tbc->opts = tpm_passthrough_cmdline_opts;
    tbc->desc = "Passthrough TPM backend driver";
    tbc->create = tpm_passthrough_create;
    tbc->startup_tpm = tpm_passthrough_startup_tpm;
    tbc->reset = tpm_passthrough_reset;
    tbc->cancel_cmd = tpm_passthrough_cancel_cmd;
    tbc->get_tpm_established_flag = tpm_passthrough_get_tpm_established_flag;
    tbc->reset_tpm_established_flag =
        tpm_passthrough_reset_tpm_established_flag;
    tbc->get_tpm_version = tpm_passthrough_get_tpm_version;
    tbc->get_buffer_size = tpm_passthrough_get_buffer_size;
    tbc->get_tpm_options = tpm_passthrough_get_tpm_options;
    tbc->handle_request = tpm_passthrough_handle_request;
}

static const TypeInfo tpm_passthrough_info = {
    .name = TYPE_TPM_PASSTHROUGH,
    .parent = TYPE_TPM_BACKEND,
    .instance_size = sizeof(TPMPassthruState),
    .class_init = tpm_passthrough_class_init,
    .instance_init = tpm_passthrough_inst_init,
    .instance_finalize = tpm_passthrough_inst_finalize,
};

static void tpm_passthrough_register(void)
{
    type_register_static(&tpm_passthrough_info);
}

type_init(tpm_passthrough_register)
