/*
 * TPM configuration
 *
 * Copyright (C) 2011-2013 IBM Corporation
 *
 * Authors:
 *  Stefan Berger    <stefanb@us.ibm.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 *
 * Based on net.c
 */
#include "config-host.h"

#include "monitor/monitor.h"
#include "qapi/qmp/qerror.h"
#include "tpm_int.h"
#include "tpm/tpm.h"
#include "qemu/config-file.h"
#include "qmp-commands.h"

static QLIST_HEAD(, TPMBackend) tpm_backends =
    QLIST_HEAD_INITIALIZER(tpm_backends);


#define TPM_MAX_MODELS      1
#define TPM_MAX_DRIVERS     1

static TPMDriverOps const *be_drivers[TPM_MAX_DRIVERS] = {
    NULL,
};

static enum TpmModel tpm_models[TPM_MAX_MODELS] = {
    -1,
};

int tpm_register_model(enum TpmModel model)
{
    int i;

    for (i = 0; i < TPM_MAX_MODELS; i++) {
        if (tpm_models[i] == -1) {
            tpm_models[i] = model;
            return 0;
        }
    }
    error_report("Could not register TPM model");
    return 1;
}

static bool tpm_model_is_registered(enum TpmModel model)
{
    int i;

    for (i = 0; i < TPM_MAX_MODELS; i++) {
        if (tpm_models[i] == model) {
            return true;
        }
    }
    return false;
}

/*
 * Write an error message in the given output buffer.
 */
void tpm_write_fatal_error_response(uint8_t *out, uint32_t out_len)
{
    if (out_len >= sizeof(struct tpm_resp_hdr)) {
        struct tpm_resp_hdr *resp = (struct tpm_resp_hdr *)out;

        resp->tag = cpu_to_be16(TPM_TAG_RSP_COMMAND);
        resp->len = cpu_to_be32(sizeof(struct tpm_resp_hdr));
        resp->errcode = cpu_to_be32(TPM_FAIL);
    }
}

const TPMDriverOps *tpm_get_backend_driver(const char *type)
{
    int i;

    for (i = 0; i < TPM_MAX_DRIVERS && be_drivers[i] != NULL; i++) {
        if (!strcmp(TpmType_lookup[be_drivers[i]->type], type)) {
            return be_drivers[i];
        }
    }

    return NULL;
}

#ifdef CONFIG_TPM

int tpm_register_driver(const TPMDriverOps *tdo)
{
    int i;

    for (i = 0; i < TPM_MAX_DRIVERS; i++) {
        if (!be_drivers[i]) {
            be_drivers[i] = tdo;
            return 0;
        }
    }
    error_report("Could not register TPM driver");
    return 1;
}

/*
 * Walk the list of available TPM backend drivers and display them on the
 * screen.
 */
void tpm_display_backend_drivers(void)
{
    int i;

    fprintf(stderr, "Supported TPM types (choose only one):\n");

    for (i = 0; i < TPM_MAX_DRIVERS && be_drivers[i] != NULL; i++) {
        fprintf(stderr, "%12s   %s\n",
                TpmType_lookup[be_drivers[i]->type], be_drivers[i]->desc());
    }
    fprintf(stderr, "\n");
}

/*
 * Find the TPM with the given Id
 */
TPMBackend *qemu_find_tpm(const char *id)
{
    TPMBackend *drv;

    if (id) {
        QLIST_FOREACH(drv, &tpm_backends, list) {
            if (!strcmp(drv->id, id)) {
                return drv;
            }
        }
    }

    return NULL;
}

static int configure_tpm(QemuOpts *opts)
{
    const char *value;
    const char *id;
    const TPMDriverOps *be;
    TPMBackend *drv;

    if (!QLIST_EMPTY(&tpm_backends)) {
        error_report("Only one TPM is allowed.\n");
        return 1;
    }

    id = qemu_opts_id(opts);
    if (id == NULL) {
        qerror_report(QERR_MISSING_PARAMETER, "id");
        return 1;
    }

    value = qemu_opt_get(opts, "type");
    if (!value) {
        qerror_report(QERR_MISSING_PARAMETER, "type");
        tpm_display_backend_drivers();
        return 1;
    }

    be = tpm_get_backend_driver(value);
    if (be == NULL) {
        qerror_report(QERR_INVALID_PARAMETER_VALUE, "type",
                      "a TPM backend type");
        tpm_display_backend_drivers();
        return 1;
    }

    drv = be->create(opts, id);
    if (!drv) {
        return 1;
    }

    QLIST_INSERT_HEAD(&tpm_backends, drv, list);

    return 0;
}

static int tpm_init_tpmdev(QemuOpts *opts, void *dummy)
{
    return configure_tpm(opts);
}

/*
 * Walk the list of TPM backend drivers that are in use and call their
 * destroy function to have them cleaned up.
 */
void tpm_cleanup(void)
{
    TPMBackend *drv, *next;

    QLIST_FOREACH_SAFE(drv, &tpm_backends, list, next) {
        QLIST_REMOVE(drv, list);
        drv->ops->destroy(drv);
    }
}

/*
 * Initialize the TPM. Process the tpmdev command line options describing the
 * TPM backend.
 */
int tpm_init(void)
{
    if (qemu_opts_foreach(qemu_find_opts("tpmdev"),
                          tpm_init_tpmdev, NULL, 1) != 0) {
        return -1;
    }

    atexit(tpm_cleanup);

    return 0;
}

/*
 * Parse the TPM configuration options.
 * To display all available TPM backends the user may use '-tpmdev help'
 */
int tpm_config_parse(QemuOptsList *opts_list, const char *optarg)
{
    QemuOpts *opts;

    if (!strcmp(optarg, "help")) {
        tpm_display_backend_drivers();
        return -1;
    }
    opts = qemu_opts_parse(opts_list, optarg, 1);
    if (!opts) {
        return -1;
    }
    return 0;
}

#endif /* CONFIG_TPM */

static const TPMDriverOps *tpm_driver_find_by_type(enum TpmType type)
{
    int i;

    for (i = 0; i < TPM_MAX_DRIVERS && be_drivers[i] != NULL; i++) {
        if (be_drivers[i]->type == type) {
            return be_drivers[i];
        }
    }
    return NULL;
}

static TPMInfo *qmp_query_tpm_inst(TPMBackend *drv)
{
    TPMInfo *res = g_new0(TPMInfo, 1);
    TPMPassthroughOptions *tpo;

    res->id = g_strdup(drv->id);
    res->model = drv->fe_model;
    res->type = drv->ops->type;
    res->tpm_options = g_new0(TpmTypeOptions, 1);

    switch (res->type) {
    case TPM_TYPE_PASSTHROUGH:
        res->tpm_options->kind = TPM_TYPE_OPTIONS_KIND_TPM_PASSTHROUGH_OPTIONS;
        tpo = g_new0(TPMPassthroughOptions, 1);
        res->tpm_options->tpm_passthrough_options = tpo;
        if (drv->path) {
            tpo->path = g_strdup(drv->path);
            tpo->has_path = true;
        }
        if (drv->cancel_path) {
            tpo->cancel_path = g_strdup(drv->cancel_path);
            tpo->has_cancel_path = true;
        }
        break;
    case TPM_TYPE_MAX:
        break;
    }

    return res;
}

/*
 * Walk the list of active TPM backends and collect information about them
 * following the schema description in qapi-schema.json.
 */
TPMInfoList *qmp_query_tpm(Error **errp)
{
    TPMBackend *drv;
    TPMInfoList *info, *head = NULL, *cur_item = NULL;

    QLIST_FOREACH(drv, &tpm_backends, list) {
        if (!tpm_model_is_registered(drv->fe_model)) {
            continue;
        }
        info = g_new0(TPMInfoList, 1);
        info->value = qmp_query_tpm_inst(drv);

        if (!cur_item) {
            head = cur_item = info;
        } else {
            cur_item->next = info;
            cur_item = info;
        }
    }

    return head;
}

TpmTypeList *qmp_query_tpm_types(Error **errp)
{
    unsigned int i = 0;
    TpmTypeList *head = NULL, *prev = NULL, *cur_item;

    for (i = 0; i < TPM_TYPE_MAX; i++) {
        if (!tpm_driver_find_by_type(i)) {
            continue;
        }
        cur_item = g_new0(TpmTypeList, 1);
        cur_item->value = i;

        if (prev) {
            prev->next = cur_item;
        }
        if (!head) {
            head = cur_item;
        }
        prev = cur_item;
    }

    return head;
}

TpmModelList *qmp_query_tpm_models(Error **errp)
{
    unsigned int i = 0;
    TpmModelList *head = NULL, *prev = NULL, *cur_item;

    for (i = 0; i < TPM_MODEL_MAX; i++) {
        if (!tpm_model_is_registered(i)) {
            continue;
        }
        cur_item = g_new0(TpmModelList, 1);
        cur_item->value = i;

        if (prev) {
            prev->next = cur_item;
        }
        if (!head) {
            head = cur_item;
        }
        prev = cur_item;
    }

    return head;
}
