/*
 * QEMU Cryptodev backend for QEMU cipher APIs
 *
 * Copyright (c) 2022 Bytedance.Inc
 *
 * Authors:
 *    lei he <helei.sig11@bytedance.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 "crypto/cipher.h"
#include "crypto/akcipher.h"
#include "qapi/error.h"
#include "qemu/main-loop.h"
#include "qemu/thread.h"
#include "qemu/error-report.h"
#include "qemu/queue.h"
#include "qom/object.h"
#include "system/cryptodev.h"
#include "standard-headers/linux/virtio_crypto.h"

#include <keyutils.h>
#include <sys/eventfd.h>

/**
 * @TYPE_CRYPTODEV_BACKEND_LKCF:
 * name of backend that uses linux kernel crypto framework
 */
#define TYPE_CRYPTODEV_BACKEND_LKCF "cryptodev-backend-lkcf"

OBJECT_DECLARE_SIMPLE_TYPE(CryptoDevBackendLKCF, CRYPTODEV_BACKEND_LKCF)

#define INVALID_KEY_ID -1
#define MAX_SESSIONS 256
#define NR_WORKER_THREAD 64

#define KCTL_KEY_TYPE_PKEY "asymmetric"
/**
 * Here the key is uploaded to the thread-keyring of worker thread, at least
 * util linux-6.0:
 * 1. process keyring seems to behave unexpectedly if main-thread does not
 * create the keyring before creating any other thread.
 * 2. at present, the guest kernel never perform multiple operations on a
 * session.
 * 3. it can reduce the load of the main-loop because the key passed by the
 * guest kernel has been already checked.
 */
#define KCTL_KEY_RING KEY_SPEC_THREAD_KEYRING

typedef struct CryptoDevBackendLKCFSession {
    uint8_t *key;
    size_t keylen;
    QCryptoAkCipherKeyType keytype;
    QCryptoAkCipherOptions akcipher_opts;
} CryptoDevBackendLKCFSession;

typedef struct CryptoDevLKCFTask CryptoDevLKCFTask;
struct CryptoDevLKCFTask {
    CryptoDevBackendLKCFSession *sess;
    CryptoDevBackendOpInfo *op_info;
    CryptoDevCompletionFunc cb;
    void *opaque;
    int status;
    CryptoDevBackendLKCF *lkcf;
    QSIMPLEQ_ENTRY(CryptoDevLKCFTask) queue;
};

typedef struct CryptoDevBackendLKCF {
    CryptoDevBackend parent_obj;
    CryptoDevBackendLKCFSession *sess[MAX_SESSIONS];
    QSIMPLEQ_HEAD(, CryptoDevLKCFTask) requests;
    QSIMPLEQ_HEAD(, CryptoDevLKCFTask) responses;
    QemuMutex mutex;
    QemuCond cond;
    QemuMutex rsp_mutex;

    /**
     * There is no async interface for asymmetric keys like AF_ALG sockets,
     * we don't seem to have better way than create a lots of thread.
     */
    QemuThread worker_threads[NR_WORKER_THREAD];
    bool running;
    int eventfd;
} CryptoDevBackendLKCF;

static void *cryptodev_lkcf_worker(void *arg);
static int cryptodev_lkcf_close_session(CryptoDevBackend *backend,
                                        uint64_t session_id,
                                        uint32_t queue_index,
                                        CryptoDevCompletionFunc cb,
                                        void *opaque);

static void cryptodev_lkcf_handle_response(void *opaque)
{
    CryptoDevBackendLKCF *lkcf = (CryptoDevBackendLKCF *)opaque;
    QSIMPLEQ_HEAD(, CryptoDevLKCFTask) responses;
    CryptoDevLKCFTask *task, *next;
    eventfd_t nevent;

    QSIMPLEQ_INIT(&responses);
    eventfd_read(lkcf->eventfd, &nevent);

    qemu_mutex_lock(&lkcf->rsp_mutex);
    QSIMPLEQ_PREPEND(&responses, &lkcf->responses);
    qemu_mutex_unlock(&lkcf->rsp_mutex);

    QSIMPLEQ_FOREACH_SAFE(task, &responses, queue, next) {
        if (task->cb) {
            task->cb(task->opaque, task->status);
        }
        g_free(task);
    }
}

static int cryptodev_lkcf_set_op_desc(QCryptoAkCipherOptions *opts,
                                      char *key_desc,
                                      size_t desc_len,
                                      Error **errp)
{
    QCryptoAkCipherOptionsRSA *rsa_opt;
    if (opts->alg != QCRYPTO_AK_CIPHER_ALGO_RSA) {
        error_setg(errp, "Unsupported alg: %u", opts->alg);
        return -1;
    }

    rsa_opt = &opts->u.rsa;
    if (rsa_opt->padding_alg == QCRYPTO_RSA_PADDING_ALGO_PKCS1) {
        snprintf(key_desc, desc_len, "enc=%s hash=%s",
                 QCryptoRSAPaddingAlgo_str(rsa_opt->padding_alg),
                 QCryptoHashAlgo_str(rsa_opt->hash_alg));

    } else {
        snprintf(key_desc, desc_len, "enc=%s",
                 QCryptoRSAPaddingAlgo_str(rsa_opt->padding_alg));
    }
    return 0;
}

static int cryptodev_lkcf_set_rsa_opt(int virtio_padding_alg,
                                      int virtio_hash_alg,
                                      QCryptoAkCipherOptionsRSA *opt,
                                      Error **errp)
{
    if (virtio_padding_alg == VIRTIO_CRYPTO_RSA_PKCS1_PADDING) {
        opt->padding_alg = QCRYPTO_RSA_PADDING_ALGO_PKCS1;

        switch (virtio_hash_alg) {
        case VIRTIO_CRYPTO_RSA_MD5:
            opt->hash_alg = QCRYPTO_HASH_ALGO_MD5;
            break;

        case VIRTIO_CRYPTO_RSA_SHA1:
            opt->hash_alg = QCRYPTO_HASH_ALGO_SHA1;
            break;

        case VIRTIO_CRYPTO_RSA_SHA256:
            opt->hash_alg = QCRYPTO_HASH_ALGO_SHA256;
            break;

        case VIRTIO_CRYPTO_RSA_SHA512:
            opt->hash_alg = QCRYPTO_HASH_ALGO_SHA512;
            break;

        default:
            error_setg(errp, "Unsupported rsa hash algo: %d", virtio_hash_alg);
            return -1;
        }
        return 0;
    }

    if (virtio_padding_alg == VIRTIO_CRYPTO_RSA_RAW_PADDING) {
        opt->padding_alg = QCRYPTO_RSA_PADDING_ALGO_RAW;
        return 0;
    }

    error_setg(errp, "Unsupported rsa padding algo: %u", virtio_padding_alg);
    return -1;
}

static int cryptodev_lkcf_get_unused_session_index(CryptoDevBackendLKCF *lkcf)
{
    size_t i;

    for (i = 0; i < MAX_SESSIONS; i++) {
        if (lkcf->sess[i] == NULL) {
            return i;
        }
    }
    return -1;
}

static void cryptodev_lkcf_init(CryptoDevBackend *backend, Error **errp)
{
    /* Only support one queue */
    int queues = backend->conf.peers.queues, i;
    CryptoDevBackendClient *cc;
    CryptoDevBackendLKCF *lkcf =
        CRYPTODEV_BACKEND_LKCF(backend);

    if (queues != 1) {
        error_setg(errp,
                   "Only support one queue in cryptodev-builtin backend");
        return;
    }
    lkcf->eventfd = eventfd(0, 0);
    if (lkcf->eventfd < 0) {
        error_setg_errno(errp, errno, "Failed to create eventfd");
        return;
    }

    cc = cryptodev_backend_new_client();
    cc->info_str = g_strdup_printf("cryptodev-lkcf0");
    cc->queue_index = 0;
    cc->type = QCRYPTODEV_BACKEND_TYPE_LKCF;
    backend->conf.peers.ccs[0] = cc;

    backend->conf.crypto_services =
        1u << QCRYPTODEV_BACKEND_SERVICE_TYPE_AKCIPHER;
    backend->conf.akcipher_algo = 1u << VIRTIO_CRYPTO_AKCIPHER_RSA;
    lkcf->running = true;

    QSIMPLEQ_INIT(&lkcf->requests);
    QSIMPLEQ_INIT(&lkcf->responses);
    qemu_mutex_init(&lkcf->mutex);
    qemu_mutex_init(&lkcf->rsp_mutex);
    qemu_cond_init(&lkcf->cond);
    for (i = 0; i < NR_WORKER_THREAD; i++) {
        qemu_thread_create(&lkcf->worker_threads[i], "lkcf-worker",
                           cryptodev_lkcf_worker, lkcf, 0);
    }
    qemu_set_fd_handler(
        lkcf->eventfd, cryptodev_lkcf_handle_response, NULL, lkcf);
    cryptodev_backend_set_ready(backend, true);
}

static void cryptodev_lkcf_cleanup(CryptoDevBackend *backend, Error **errp)
{
    CryptoDevBackendLKCF *lkcf = CRYPTODEV_BACKEND_LKCF(backend);
    size_t i;
    int queues = backend->conf.peers.queues;
    CryptoDevBackendClient *cc;
    CryptoDevLKCFTask *task, *next;

    qemu_mutex_lock(&lkcf->mutex);
    lkcf->running = false;
    qemu_mutex_unlock(&lkcf->mutex);
    qemu_cond_broadcast(&lkcf->cond);

    close(lkcf->eventfd);
    for (i = 0; i < NR_WORKER_THREAD; i++) {
        qemu_thread_join(&lkcf->worker_threads[i]);
    }

    QSIMPLEQ_FOREACH_SAFE(task, &lkcf->requests, queue, next) {
        if (task->cb) {
            task->cb(task->opaque, task->status);
        }
        g_free(task);
    }

    QSIMPLEQ_FOREACH_SAFE(task, &lkcf->responses, queue, next) {
        if (task->cb) {
            task->cb(task->opaque, task->status);
        }
        g_free(task);
    }

    qemu_mutex_destroy(&lkcf->mutex);
    qemu_cond_destroy(&lkcf->cond);
    qemu_mutex_destroy(&lkcf->rsp_mutex);

    for (i = 0; i < MAX_SESSIONS; i++) {
        if (lkcf->sess[i] != NULL) {
            cryptodev_lkcf_close_session(backend, i, 0, NULL, NULL);
        }
    }

    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;
        }
    }

    cryptodev_backend_set_ready(backend, false);
}

static void cryptodev_lkcf_execute_task(CryptoDevLKCFTask *task)
{
    CryptoDevBackendLKCFSession *session = task->sess;
    CryptoDevBackendAsymOpInfo *asym_op_info;
    bool kick = false;
    int ret, status, op_code = task->op_info->op_code;
    size_t p8info_len;
    g_autofree uint8_t *p8info = NULL;
    Error *local_error = NULL;
    key_serial_t key_id = INVALID_KEY_ID;
    char op_desc[64];
    g_autoptr(QCryptoAkCipher) akcipher = NULL;

    /**
     * We only offload private key session:
     * 1. currently, the Linux kernel can only accept public key wrapped
     * with X.509 certificates, but unfortunately the cost of making a
     * ceritificate with public key is too expensive.
     * 2. generally, public key related compution is fast, just compute it with
     * thread-pool.
     */
    if (session->keytype == QCRYPTO_AK_CIPHER_KEY_TYPE_PRIVATE) {
        if (qcrypto_akcipher_export_p8info(&session->akcipher_opts,
                                           session->key, session->keylen,
                                           &p8info, &p8info_len,
                                           &local_error) != 0 ||
            cryptodev_lkcf_set_op_desc(&session->akcipher_opts, op_desc,
                                       sizeof(op_desc), &local_error) != 0) {
            error_report_err(local_error);
            status = -VIRTIO_CRYPTO_ERR;
            goto out;
        } else {
            key_id = add_key(KCTL_KEY_TYPE_PKEY, "lkcf-backend-priv-key",
                             p8info, p8info_len, KCTL_KEY_RING);
        }
    }

    if (key_id < 0) {
        if (!qcrypto_akcipher_supports(&session->akcipher_opts)) {
            status = -VIRTIO_CRYPTO_NOTSUPP;
            goto out;
        }
        akcipher = qcrypto_akcipher_new(&session->akcipher_opts,
                                        session->keytype,
                                        session->key, session->keylen,
                                        &local_error);
        if (!akcipher) {
            error_report_err(local_error);
            status = -VIRTIO_CRYPTO_ERR;
            goto out;
        }
    }

    asym_op_info = task->op_info->u.asym_op_info;
    switch (op_code) {
    case VIRTIO_CRYPTO_AKCIPHER_ENCRYPT:
        if (key_id >= 0) {
            ret = keyctl_pkey_encrypt(key_id, op_desc,
                asym_op_info->src, asym_op_info->src_len,
                asym_op_info->dst, asym_op_info->dst_len);
        } else {
            ret = qcrypto_akcipher_encrypt(akcipher,
                asym_op_info->src, asym_op_info->src_len,
                asym_op_info->dst, asym_op_info->dst_len, &local_error);
        }
        break;

    case VIRTIO_CRYPTO_AKCIPHER_DECRYPT:
        if (key_id >= 0) {
            ret = keyctl_pkey_decrypt(key_id, op_desc,
                asym_op_info->src, asym_op_info->src_len,
                asym_op_info->dst, asym_op_info->dst_len);
        } else {
            ret = qcrypto_akcipher_decrypt(akcipher,
                asym_op_info->src, asym_op_info->src_len,
                asym_op_info->dst, asym_op_info->dst_len, &local_error);
        }
        break;

    case VIRTIO_CRYPTO_AKCIPHER_SIGN:
        if (key_id >= 0) {
            ret = keyctl_pkey_sign(key_id, op_desc,
                asym_op_info->src, asym_op_info->src_len,
                asym_op_info->dst, asym_op_info->dst_len);
        } else {
            ret = qcrypto_akcipher_sign(akcipher,
                asym_op_info->src, asym_op_info->src_len,
                asym_op_info->dst, asym_op_info->dst_len, &local_error);
        }
        break;

    case VIRTIO_CRYPTO_AKCIPHER_VERIFY:
        if (key_id >= 0) {
            ret = keyctl_pkey_verify(key_id, op_desc,
                asym_op_info->src, asym_op_info->src_len,
                asym_op_info->dst, asym_op_info->dst_len);
        } else {
            ret = qcrypto_akcipher_verify(akcipher,
                asym_op_info->src, asym_op_info->src_len,
                asym_op_info->dst, asym_op_info->dst_len, &local_error);
        }
        break;

    default:
        error_setg(&local_error, "Unknown opcode: %u", op_code);
        status = -VIRTIO_CRYPTO_ERR;
        goto out;
    }

    if (ret < 0) {
        if (!local_error) {
            if (errno != EKEYREJECTED) {
                error_report("Failed do operation with keyctl: %d", errno);
            }
        } else {
            error_report_err(local_error);
        }
        status = op_code == VIRTIO_CRYPTO_AKCIPHER_VERIFY ?
            -VIRTIO_CRYPTO_KEY_REJECTED : -VIRTIO_CRYPTO_ERR;
    } else {
        status = VIRTIO_CRYPTO_OK;
        asym_op_info->dst_len = ret;
    }

out:
    if (key_id >= 0) {
        keyctl_unlink(key_id, KCTL_KEY_RING);
    }
    task->status = status;

    qemu_mutex_lock(&task->lkcf->rsp_mutex);
    if (QSIMPLEQ_EMPTY(&task->lkcf->responses)) {
        kick = true;
    }
    QSIMPLEQ_INSERT_TAIL(&task->lkcf->responses, task, queue);
    qemu_mutex_unlock(&task->lkcf->rsp_mutex);

    if (kick) {
        eventfd_write(task->lkcf->eventfd, 1);
    }
}

static void *cryptodev_lkcf_worker(void *arg)
{
    CryptoDevBackendLKCF *backend = (CryptoDevBackendLKCF *)arg;
    CryptoDevLKCFTask *task;

    for (;;) {
        task = NULL;
        qemu_mutex_lock(&backend->mutex);
        while (backend->running && QSIMPLEQ_EMPTY(&backend->requests)) {
            qemu_cond_wait(&backend->cond, &backend->mutex);
        }
        if (backend->running) {
            task = QSIMPLEQ_FIRST(&backend->requests);
            QSIMPLEQ_REMOVE_HEAD(&backend->requests, queue);
        }
        qemu_mutex_unlock(&backend->mutex);

        /* stopped */
        if (!task) {
            break;
        }
        cryptodev_lkcf_execute_task(task);
   }

   return NULL;
}

static int cryptodev_lkcf_operation(
    CryptoDevBackend *backend,
    CryptoDevBackendOpInfo *op_info)
{
    CryptoDevBackendLKCF *lkcf =
        CRYPTODEV_BACKEND_LKCF(backend);
    CryptoDevBackendLKCFSession *sess;
    QCryptodevBackendAlgoType algtype = op_info->algtype;
    CryptoDevLKCFTask *task;

    if (op_info->session_id >= MAX_SESSIONS ||
        lkcf->sess[op_info->session_id] == NULL) {
        error_report("Cannot find a valid session id: %" PRIu64 "",
                     op_info->session_id);
        return -VIRTIO_CRYPTO_INVSESS;
    }

    sess = lkcf->sess[op_info->session_id];
    if (algtype != QCRYPTODEV_BACKEND_ALGO_TYPE_ASYM) {
        error_report("algtype not supported: %u", algtype);
        return -VIRTIO_CRYPTO_NOTSUPP;
    }

    task = g_new0(CryptoDevLKCFTask, 1);
    task->op_info = op_info;
    task->cb = op_info->cb;
    task->opaque = op_info->opaque;
    task->sess = sess;
    task->lkcf = lkcf;
    task->status = -VIRTIO_CRYPTO_ERR;

    qemu_mutex_lock(&lkcf->mutex);
    QSIMPLEQ_INSERT_TAIL(&lkcf->requests, task, queue);
    qemu_mutex_unlock(&lkcf->mutex);
    qemu_cond_signal(&lkcf->cond);

    return VIRTIO_CRYPTO_OK;
}

static int cryptodev_lkcf_create_asym_session(
    CryptoDevBackendLKCF *lkcf,
    CryptoDevBackendAsymSessionInfo *sess_info,
    uint64_t *session_id)
{
    Error *local_error = NULL;
    int index;
    g_autofree CryptoDevBackendLKCFSession *sess =
        g_new0(CryptoDevBackendLKCFSession, 1);

    switch (sess_info->algo) {
    case VIRTIO_CRYPTO_AKCIPHER_RSA:
        sess->akcipher_opts.alg = QCRYPTO_AK_CIPHER_ALGO_RSA;
        if (cryptodev_lkcf_set_rsa_opt(
            sess_info->u.rsa.padding_algo, sess_info->u.rsa.hash_algo,
            &sess->akcipher_opts.u.rsa, &local_error) != 0) {
            error_report_err(local_error);
            return -VIRTIO_CRYPTO_ERR;
        }
        break;

    default:
        error_report("Unsupported asym alg %u", sess_info->algo);
        return -VIRTIO_CRYPTO_NOTSUPP;
    }

    switch (sess_info->keytype) {
    case VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PUBLIC:
        sess->keytype = QCRYPTO_AK_CIPHER_KEY_TYPE_PUBLIC;
        break;

    case VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PRIVATE:
        sess->keytype = QCRYPTO_AK_CIPHER_KEY_TYPE_PRIVATE;
        break;

    default:
        error_report("Unknown akcipher keytype: %u", sess_info->keytype);
        return -VIRTIO_CRYPTO_ERR;
    }

    index = cryptodev_lkcf_get_unused_session_index(lkcf);
    if (index < 0) {
        error_report("Total number of sessions created exceeds %u",
                     MAX_SESSIONS);
        return -VIRTIO_CRYPTO_ERR;
    }

    sess->keylen = sess_info->keylen;
    sess->key = g_malloc(sess_info->keylen);
    memcpy(sess->key, sess_info->key, sess_info->keylen);

    lkcf->sess[index] = g_steal_pointer(&sess);
    *session_id = index;

    return VIRTIO_CRYPTO_OK;
}

static int cryptodev_lkcf_create_session(
    CryptoDevBackend *backend,
    CryptoDevBackendSessionInfo *sess_info,
    uint32_t queue_index,
    CryptoDevCompletionFunc cb,
    void *opaque)
{
    CryptoDevBackendAsymSessionInfo *asym_sess_info;
    CryptoDevBackendLKCF *lkcf =
        CRYPTODEV_BACKEND_LKCF(backend);
    int ret;

    switch (sess_info->op_code) {
    case VIRTIO_CRYPTO_AKCIPHER_CREATE_SESSION:
        asym_sess_info = &sess_info->u.asym_sess_info;
        ret = cryptodev_lkcf_create_asym_session(
            lkcf, asym_sess_info, &sess_info->session_id);
        break;

    default:
        ret = -VIRTIO_CRYPTO_NOTSUPP;
        error_report("Unsupported opcode: %" PRIu32 "",
                     sess_info->op_code);
        break;
    }
    if (cb) {
        cb(opaque, ret);
    }
    return 0;
}

static int cryptodev_lkcf_close_session(CryptoDevBackend *backend,
                                        uint64_t session_id,
                                        uint32_t queue_index,
                                        CryptoDevCompletionFunc cb,
                                        void *opaque)
{
    CryptoDevBackendLKCF *lkcf = CRYPTODEV_BACKEND_LKCF(backend);
    CryptoDevBackendLKCFSession *session;

    assert(session_id < MAX_SESSIONS && lkcf->sess[session_id]);
    session = lkcf->sess[session_id];
    lkcf->sess[session_id] = NULL;

    g_free(session->key);
    g_free(session);

    if (cb) {
        cb(opaque, VIRTIO_CRYPTO_OK);
    }
    return 0;
}

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

    bc->init = cryptodev_lkcf_init;
    bc->cleanup = cryptodev_lkcf_cleanup;
    bc->create_session = cryptodev_lkcf_create_session;
    bc->close_session = cryptodev_lkcf_close_session;
    bc->do_op = cryptodev_lkcf_operation;
}

static const TypeInfo cryptodev_builtin_info = {
    .name = TYPE_CRYPTODEV_BACKEND_LKCF,
    .parent = TYPE_CRYPTODEV_BACKEND,
    .class_init = cryptodev_lkcf_class_init,
    .instance_size = sizeof(CryptoDevBackendLKCF),
};

static void cryptodev_lkcf_register_types(void)
{
    type_register_static(&cryptodev_builtin_info);
}

type_init(cryptodev_lkcf_register_types);
