/*
 * QEMU Cryptodev backend for QEMU cipher APIs
 *
 * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
 *
 * Authors:
 *    Gonglei <arei.gonglei@huawei.com>
 *
 * 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 "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qemu/error-report.h"
#include "hw/virtio/vhost-user.h"
#include "standard-headers/linux/virtio_crypto.h"
#include "system/cryptodev-vhost.h"
#include "chardev/char-fe.h"
#include "system/cryptodev-vhost-user.h"
#include "qom/object.h"


/**
 * @TYPE_CRYPTODEV_BACKEND_VHOST_USER:
 * name of backend that uses vhost user server
 */
#define TYPE_CRYPTODEV_BACKEND_VHOST_USER "cryptodev-vhost-user"

OBJECT_DECLARE_SIMPLE_TYPE(CryptoDevBackendVhostUser, CRYPTODEV_BACKEND_VHOST_USER)


struct CryptoDevBackendVhostUser {
    CryptoDevBackend parent_obj;

    VhostUserState vhost_user;
    CharFrontend chr;
    char *chr_name;
    bool opened;
    CryptoDevBackendVhost *vhost_crypto[MAX_CRYPTO_QUEUE_NUM];
};

static int
cryptodev_vhost_user_running(
             CryptoDevBackendVhost *crypto)
{
    return crypto ? 1 : 0;
}

CryptoDevBackendVhost *
cryptodev_vhost_user_get_vhost(
                         CryptoDevBackendClient *cc,
                         CryptoDevBackend *b,
                         uint16_t queue)
{
    CryptoDevBackendVhostUser *s =
                      CRYPTODEV_BACKEND_VHOST_USER(b);
    assert(cc->type == QCRYPTODEV_BACKEND_TYPE_VHOST_USER);
    assert(queue < MAX_CRYPTO_QUEUE_NUM);

    return s->vhost_crypto[queue];
}

static void cryptodev_vhost_user_stop(int queues,
                          CryptoDevBackendVhostUser *s)
{
    size_t i;

    for (i = 0; i < queues; i++) {
        if (!cryptodev_vhost_user_running(s->vhost_crypto[i])) {
            continue;
        }

        cryptodev_vhost_cleanup(s->vhost_crypto[i]);
        s->vhost_crypto[i] = NULL;
    }
}

static int
cryptodev_vhost_user_start(int queues,
                         CryptoDevBackendVhostUser *s)
{
    CryptoDevBackendVhostOptions options;
    CryptoDevBackend *b = CRYPTODEV_BACKEND(s);
    int max_queues;
    size_t i;

    for (i = 0; i < queues; i++) {
        if (cryptodev_vhost_user_running(s->vhost_crypto[i])) {
            continue;
        }

        options.opaque = &s->vhost_user;
        options.backend_type = VHOST_BACKEND_TYPE_USER;
        options.cc = b->conf.peers.ccs[i];
        s->vhost_crypto[i] = cryptodev_vhost_init(&options);
        if (!s->vhost_crypto[i]) {
            error_report("failed to init vhost_crypto for queue %zu", i);
            goto err;
        }

        if (i == 0) {
            max_queues =
              cryptodev_vhost_get_max_queues(s->vhost_crypto[i]);
            if (queues > max_queues) {
                error_report("you are asking more queues than supported: %d",
                             max_queues);
                goto err;
            }
        }
    }

    return 0;

err:
    cryptodev_vhost_user_stop(i + 1, s);
    return -1;
}

static Chardev *
cryptodev_vhost_claim_chardev(CryptoDevBackendVhostUser *s,
                                    Error **errp)
{
    Chardev *chr;

    if (s->chr_name == NULL) {
        error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
                   "chardev", "a valid character device");
        return NULL;
    }

    chr = qemu_chr_find(s->chr_name);
    if (chr == NULL) {
        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
                  "Device '%s' not found", s->chr_name);
        return NULL;
    }

    return chr;
}

static void cryptodev_vhost_user_event(void *opaque, QEMUChrEvent event)
{
    CryptoDevBackendVhostUser *s = opaque;
    CryptoDevBackend *b = CRYPTODEV_BACKEND(s);
    int queues = b->conf.peers.queues;

    assert(queues < MAX_CRYPTO_QUEUE_NUM);

    switch (event) {
    case CHR_EVENT_OPENED:
        if (cryptodev_vhost_user_start(queues, s) < 0) {
            exit(1);
        }
        b->ready = true;
        break;
    case CHR_EVENT_CLOSED:
        b->ready = false;
        cryptodev_vhost_user_stop(queues, s);
        break;
    case CHR_EVENT_BREAK:
    case CHR_EVENT_MUX_IN:
    case CHR_EVENT_MUX_OUT:
        /* Ignore */
        break;
    }
}

static void cryptodev_vhost_user_init(
             CryptoDevBackend *backend, Error **errp)
{
    int queues = backend->conf.peers.queues;
    size_t i;
    Error *local_err = NULL;
    Chardev *chr;
    CryptoDevBackendClient *cc;
    CryptoDevBackendVhostUser *s =
                      CRYPTODEV_BACKEND_VHOST_USER(backend);

    chr = cryptodev_vhost_claim_chardev(s, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }

    s->opened = true;

    for (i = 0; i < queues; i++) {
        cc = cryptodev_backend_new_client();
        cc->info_str = g_strdup_printf("cryptodev-vhost-user%zu to %s ",
                                       i, chr->label);
        cc->queue_index = i;
        cc->type = QCRYPTODEV_BACKEND_TYPE_VHOST_USER;

        backend->conf.peers.ccs[i] = cc;

        if (i == 0) {
            if (!qemu_chr_fe_init(&s->chr, chr, errp)) {
                return;
            }
        }
    }

    if (!vhost_user_init(&s->vhost_user, &s->chr, errp)) {
        return;
    }

    qemu_chr_fe_set_handlers(&s->chr, NULL, NULL,
                     cryptodev_vhost_user_event, NULL, s, NULL, true);

    backend->conf.crypto_services =
                         1u << QCRYPTODEV_BACKEND_SERVICE_TYPE_CIPHER |
                         1u << QCRYPTODEV_BACKEND_SERVICE_TYPE_HASH |
                         1u << QCRYPTODEV_BACKEND_SERVICE_TYPE_MAC;
    backend->conf.cipher_algo_l = 1u << VIRTIO_CRYPTO_CIPHER_AES_CBC;
    backend->conf.hash_algo = 1u << VIRTIO_CRYPTO_HASH_SHA1;

    backend->conf.max_size = UINT64_MAX;
    backend->conf.max_cipher_key_len = VHOST_USER_MAX_CIPHER_KEY_LEN;
    backend->conf.max_auth_key_len = VHOST_USER_MAX_AUTH_KEY_LEN;
}

static int64_t cryptodev_vhost_user_crypto_create_session(
           CryptoDevBackend *backend,
           CryptoDevBackendSessionInfo *sess_info,
           uint32_t queue_index, Error **errp)
{
    CryptoDevBackendClient *cc =
                   backend->conf.peers.ccs[queue_index];
    CryptoDevBackendVhost *vhost_crypto;
    uint64_t session_id = 0;
    int ret;

    vhost_crypto = cryptodev_vhost_user_get_vhost(cc, backend, queue_index);
    if (vhost_crypto) {
        struct vhost_dev *dev = &(vhost_crypto->dev);
        ret = dev->vhost_ops->vhost_crypto_create_session(dev,
                                                          sess_info,
                                                          &session_id);
        if (ret < 0) {
            return -1;
        } else {
            return session_id;
        }
    }
    return -1;
}

static int cryptodev_vhost_user_create_session(
           CryptoDevBackend *backend,
           CryptoDevBackendSessionInfo *sess_info,
           uint32_t queue_index,
           CryptoDevCompletionFunc cb,
           void *opaque)
{
    uint32_t op_code = sess_info->op_code;
    int64_t ret;
    Error *local_error = NULL;
    int status;

    switch (op_code) {
    case VIRTIO_CRYPTO_CIPHER_CREATE_SESSION:
    case VIRTIO_CRYPTO_AKCIPHER_CREATE_SESSION:
    case VIRTIO_CRYPTO_HASH_CREATE_SESSION:
    case VIRTIO_CRYPTO_MAC_CREATE_SESSION:
    case VIRTIO_CRYPTO_AEAD_CREATE_SESSION:
        ret = cryptodev_vhost_user_crypto_create_session(backend, sess_info,
                   queue_index, &local_error);
        break;

    default:
        error_report("Unsupported opcode :%" PRIu32 "", sess_info->op_code);
        return -VIRTIO_CRYPTO_NOTSUPP;
    }

    if (local_error) {
        error_report_err(local_error);
    }
    if (ret < 0) {
        status = -VIRTIO_CRYPTO_ERR;
    } else {
        sess_info->session_id = ret;
        status = VIRTIO_CRYPTO_OK;
    }
    if (cb) {
        cb(opaque, status);
    }
    return 0;
}

static int cryptodev_vhost_user_close_session(
           CryptoDevBackend *backend,
           uint64_t session_id,
           uint32_t queue_index,
           CryptoDevCompletionFunc cb,
           void *opaque)
{
    CryptoDevBackendClient *cc =
                  backend->conf.peers.ccs[queue_index];
    CryptoDevBackendVhost *vhost_crypto;
    int ret = -1, status;

    vhost_crypto = cryptodev_vhost_user_get_vhost(cc, backend, queue_index);
    if (vhost_crypto) {
        struct vhost_dev *dev = &(vhost_crypto->dev);
        ret = dev->vhost_ops->vhost_crypto_close_session(dev,
                                                         session_id);
        if (ret < 0) {
            status = -VIRTIO_CRYPTO_ERR;
        } else {
            status = VIRTIO_CRYPTO_OK;
        }
    } else {
        status = -VIRTIO_CRYPTO_NOTSUPP;
    }
    if (cb) {
        cb(opaque, status);
    }
    return 0;
}

static void cryptodev_vhost_user_cleanup(
             CryptoDevBackend *backend,
             Error **errp)
{
    CryptoDevBackendVhostUser *s =
                      CRYPTODEV_BACKEND_VHOST_USER(backend);
    size_t i;
    int queues = backend->conf.peers.queues;
    CryptoDevBackendClient *cc;

    cryptodev_vhost_user_stop(queues, s);

    for (i = 0; i < queues; i++) {
        cc = backend->conf.peers.ccs[i];
        if (cc) {
            cryptodev_backend_free_client(cc);
            backend->conf.peers.ccs[i] = NULL;
        }
    }

    vhost_user_cleanup(&s->vhost_user);
}

static void cryptodev_vhost_user_set_chardev(Object *obj,
                                    const char *value, Error **errp)
{
    CryptoDevBackendVhostUser *s =
                      CRYPTODEV_BACKEND_VHOST_USER(obj);

    if (s->opened) {
        error_setg(errp, "Property 'chardev' can no longer be set");
    } else {
        g_free(s->chr_name);
        s->chr_name = g_strdup(value);
    }
}

static char *
cryptodev_vhost_user_get_chardev(Object *obj, Error **errp)
{
    CryptoDevBackendVhostUser *s =
                      CRYPTODEV_BACKEND_VHOST_USER(obj);
    Chardev *chr = qemu_chr_fe_get_driver(&s->chr);

    if (chr && chr->label) {
        return g_strdup(chr->label);
    }

    return NULL;
}

static void cryptodev_vhost_user_finalize(Object *obj)
{
    CryptoDevBackendVhostUser *s =
                      CRYPTODEV_BACKEND_VHOST_USER(obj);

    qemu_chr_fe_deinit(&s->chr, false);

    g_free(s->chr_name);
}

static void
cryptodev_vhost_user_class_init(ObjectClass *oc, const void *data)
{
    CryptoDevBackendClass *bc = CRYPTODEV_BACKEND_CLASS(oc);

    bc->init = cryptodev_vhost_user_init;
    bc->cleanup = cryptodev_vhost_user_cleanup;
    bc->create_session = cryptodev_vhost_user_create_session;
    bc->close_session = cryptodev_vhost_user_close_session;
    bc->do_op = NULL;

    object_class_property_add_str(oc, "chardev",
                                  cryptodev_vhost_user_get_chardev,
                                  cryptodev_vhost_user_set_chardev);

}

static const TypeInfo cryptodev_vhost_user_info = {
    .name = TYPE_CRYPTODEV_BACKEND_VHOST_USER,
    .parent = TYPE_CRYPTODEV_BACKEND,
    .class_init = cryptodev_vhost_user_class_init,
    .instance_finalize = cryptodev_vhost_user_finalize,
    .instance_size = sizeof(CryptoDevBackendVhostUser),
};

static void
cryptodev_vhost_user_register_types(void)
{
    type_register_static(&cryptodev_vhost_user_info);
}

type_init(cryptodev_vhost_user_register_types);
