/*
 * 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 "sysemu/cryptodev.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "standard-headers/linux/virtio_crypto.h"
#include "crypto/cipher.h"
#include "crypto/akcipher.h"
#include "qom/object.h"


/**
 * @TYPE_CRYPTODEV_BACKEND_BUILTIN:
 * name of backend that uses QEMU cipher API
 */
#define TYPE_CRYPTODEV_BACKEND_BUILTIN "cryptodev-backend-builtin"

OBJECT_DECLARE_SIMPLE_TYPE(CryptoDevBackendBuiltin, CRYPTODEV_BACKEND_BUILTIN)


typedef struct CryptoDevBackendBuiltinSession {
    QCryptoCipher *cipher;
    uint8_t direction; /* encryption or decryption */
    uint8_t type; /* cipher? hash? aead? */
    QCryptoAkCipher *akcipher;
    QTAILQ_ENTRY(CryptoDevBackendBuiltinSession) next;
} CryptoDevBackendBuiltinSession;

/* Max number of symmetric/asymmetric sessions */
#define MAX_NUM_SESSIONS 256

#define CRYPTODEV_BUITLIN_MAX_AUTH_KEY_LEN    512
#define CRYPTODEV_BUITLIN_MAX_CIPHER_KEY_LEN  64

struct CryptoDevBackendBuiltin {
    CryptoDevBackend parent_obj;

    CryptoDevBackendBuiltinSession *sessions[MAX_NUM_SESSIONS];
};

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

    if (queues != 1) {
        error_setg(errp,
                  "Only support one queue in cryptdov-builtin backend");
        return;
    }

    cc = cryptodev_backend_new_client(
              "cryptodev-builtin", NULL);
    cc->info_str = g_strdup_printf("cryptodev-builtin0");
    cc->queue_index = 0;
    cc->type = CRYPTODEV_BACKEND_TYPE_BUILTIN;
    backend->conf.peers.ccs[0] = cc;

    backend->conf.crypto_services =
                         1u << VIRTIO_CRYPTO_SERVICE_CIPHER |
                         1u << VIRTIO_CRYPTO_SERVICE_HASH |
                         1u << VIRTIO_CRYPTO_SERVICE_MAC |
                         1u << VIRTIO_CRYPTO_SERVICE_AKCIPHER;
    backend->conf.cipher_algo_l = 1u << VIRTIO_CRYPTO_CIPHER_AES_CBC;
    backend->conf.hash_algo = 1u << VIRTIO_CRYPTO_HASH_SHA1;
    backend->conf.akcipher_algo = 1u << VIRTIO_CRYPTO_AKCIPHER_RSA;
    /*
     * Set the Maximum length of crypto request.
     * Why this value? Just avoid to overflow when
     * memory allocation for each crypto request.
     */
    backend->conf.max_size = LONG_MAX - sizeof(CryptoDevBackendOpInfo);
    backend->conf.max_cipher_key_len = CRYPTODEV_BUITLIN_MAX_CIPHER_KEY_LEN;
    backend->conf.max_auth_key_len = CRYPTODEV_BUITLIN_MAX_AUTH_KEY_LEN;

    cryptodev_backend_set_ready(backend, true);
}

static int
cryptodev_builtin_get_unused_session_index(
                 CryptoDevBackendBuiltin *builtin)
{
    size_t i;

    for (i = 0; i < MAX_NUM_SESSIONS; i++) {
        if (builtin->sessions[i] == NULL) {
            return i;
        }
    }

    return -1;
}

#define AES_KEYSIZE_128 16
#define AES_KEYSIZE_192 24
#define AES_KEYSIZE_256 32
#define AES_KEYSIZE_128_XTS AES_KEYSIZE_256
#define AES_KEYSIZE_256_XTS 64

static int
cryptodev_builtin_get_aes_algo(uint32_t key_len, int mode, Error **errp)
{
    int algo;

    if (key_len == AES_KEYSIZE_128) {
        algo = QCRYPTO_CIPHER_ALG_AES_128;
    } else if (key_len == AES_KEYSIZE_192) {
        algo = QCRYPTO_CIPHER_ALG_AES_192;
    } else if (key_len == AES_KEYSIZE_256) { /* equals AES_KEYSIZE_128_XTS */
        if (mode == QCRYPTO_CIPHER_MODE_XTS) {
            algo = QCRYPTO_CIPHER_ALG_AES_128;
        } else {
            algo = QCRYPTO_CIPHER_ALG_AES_256;
        }
    } else if (key_len == AES_KEYSIZE_256_XTS) {
        if (mode == QCRYPTO_CIPHER_MODE_XTS) {
            algo = QCRYPTO_CIPHER_ALG_AES_256;
        } else {
            goto err;
        }
    } else {
        goto err;
    }

    return algo;

err:
   error_setg(errp, "Unsupported key length :%u", key_len);
   return -1;
}

static int cryptodev_builtin_get_rsa_hash_algo(
    int virtio_rsa_hash, Error **errp)
{
    switch (virtio_rsa_hash) {
    case VIRTIO_CRYPTO_RSA_MD5:
        return QCRYPTO_HASH_ALG_MD5;

    case VIRTIO_CRYPTO_RSA_SHA1:
        return QCRYPTO_HASH_ALG_SHA1;

    case VIRTIO_CRYPTO_RSA_SHA256:
        return QCRYPTO_HASH_ALG_SHA256;

    case VIRTIO_CRYPTO_RSA_SHA512:
        return QCRYPTO_HASH_ALG_SHA512;

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

static int cryptodev_builtin_set_rsa_options(
                    int virtio_padding_algo,
                    int virtio_hash_algo,
                    QCryptoAkCipherOptionsRSA *opt,
                    Error **errp)
{
    if (virtio_padding_algo == VIRTIO_CRYPTO_RSA_PKCS1_PADDING) {
        int hash_alg;

        hash_alg = cryptodev_builtin_get_rsa_hash_algo(virtio_hash_algo, errp);
        if (hash_alg < 0) {
            return -1;
        }
        opt->hash_alg = hash_alg;
        opt->padding_alg = QCRYPTO_RSA_PADDING_ALG_PKCS1;
        return 0;
    }

    if (virtio_padding_algo == VIRTIO_CRYPTO_RSA_RAW_PADDING) {
        opt->padding_alg = QCRYPTO_RSA_PADDING_ALG_RAW;
        return 0;
    }

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

static int cryptodev_builtin_create_cipher_session(
                    CryptoDevBackendBuiltin *builtin,
                    CryptoDevBackendSymSessionInfo *sess_info,
                    Error **errp)
{
    int algo;
    int mode;
    QCryptoCipher *cipher;
    int index;
    CryptoDevBackendBuiltinSession *sess;

    if (sess_info->op_type != VIRTIO_CRYPTO_SYM_OP_CIPHER) {
        error_setg(errp, "Unsupported optype :%u", sess_info->op_type);
        return -1;
    }

    index = cryptodev_builtin_get_unused_session_index(builtin);
    if (index < 0) {
        error_setg(errp, "Total number of sessions created exceeds %u",
                  MAX_NUM_SESSIONS);
        return -1;
    }

    switch (sess_info->cipher_alg) {
    case VIRTIO_CRYPTO_CIPHER_AES_ECB:
        mode = QCRYPTO_CIPHER_MODE_ECB;
        algo = cryptodev_builtin_get_aes_algo(sess_info->key_len,
                                                    mode, errp);
        if (algo < 0)  {
            return -1;
        }
        break;
    case VIRTIO_CRYPTO_CIPHER_AES_CBC:
        mode = QCRYPTO_CIPHER_MODE_CBC;
        algo = cryptodev_builtin_get_aes_algo(sess_info->key_len,
                                                    mode, errp);
        if (algo < 0)  {
            return -1;
        }
        break;
    case VIRTIO_CRYPTO_CIPHER_AES_CTR:
        mode = QCRYPTO_CIPHER_MODE_CTR;
        algo = cryptodev_builtin_get_aes_algo(sess_info->key_len,
                                                    mode, errp);
        if (algo < 0)  {
            return -1;
        }
        break;
    case VIRTIO_CRYPTO_CIPHER_AES_XTS:
        mode = QCRYPTO_CIPHER_MODE_XTS;
        algo = cryptodev_builtin_get_aes_algo(sess_info->key_len,
                                                    mode, errp);
        if (algo < 0)  {
            return -1;
        }
        break;
    case VIRTIO_CRYPTO_CIPHER_3DES_ECB:
        mode = QCRYPTO_CIPHER_MODE_ECB;
        algo = QCRYPTO_CIPHER_ALG_3DES;
        break;
    case VIRTIO_CRYPTO_CIPHER_3DES_CBC:
        mode = QCRYPTO_CIPHER_MODE_CBC;
        algo = QCRYPTO_CIPHER_ALG_3DES;
        break;
    case VIRTIO_CRYPTO_CIPHER_3DES_CTR:
        mode = QCRYPTO_CIPHER_MODE_CTR;
        algo = QCRYPTO_CIPHER_ALG_3DES;
        break;
    default:
        error_setg(errp, "Unsupported cipher alg :%u",
                   sess_info->cipher_alg);
        return -1;
    }

    cipher = qcrypto_cipher_new(algo, mode,
                               sess_info->cipher_key,
                               sess_info->key_len,
                               errp);
    if (!cipher) {
        return -1;
    }

    sess = g_new0(CryptoDevBackendBuiltinSession, 1);
    sess->cipher = cipher;
    sess->direction = sess_info->direction;
    sess->type = sess_info->op_type;

    builtin->sessions[index] = sess;

    return index;
}

static int cryptodev_builtin_create_akcipher_session(
                    CryptoDevBackendBuiltin *builtin,
                    CryptoDevBackendAsymSessionInfo *sess_info,
                    Error **errp)
{
    CryptoDevBackendBuiltinSession *sess;
    QCryptoAkCipher *akcipher;
    int index;
    QCryptoAkCipherKeyType type;
    QCryptoAkCipherOptions opts;

    switch (sess_info->algo) {
    case VIRTIO_CRYPTO_AKCIPHER_RSA:
        opts.alg = QCRYPTO_AKCIPHER_ALG_RSA;
        if (cryptodev_builtin_set_rsa_options(sess_info->u.rsa.padding_algo,
            sess_info->u.rsa.hash_algo, &opts.u.rsa, errp) != 0) {
            return -1;
        }
        break;

    /* TODO support DSA&ECDSA until qemu crypto framework support these */

    default:
        error_setg(errp, "Unsupported akcipher alg %u", sess_info->algo);
        return -1;
    }

    switch (sess_info->keytype) {
    case VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PUBLIC:
        type = QCRYPTO_AKCIPHER_KEY_TYPE_PUBLIC;
        break;

    case VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PRIVATE:
        type = QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE;
        break;

    default:
        error_setg(errp, "Unsupported akcipher keytype %u", sess_info->keytype);
        return -1;
    }

    index = cryptodev_builtin_get_unused_session_index(builtin);
    if (index < 0) {
        error_setg(errp, "Total number of sessions created exceeds %u",
                   MAX_NUM_SESSIONS);
        return -1;
    }

    akcipher = qcrypto_akcipher_new(&opts, type, sess_info->key,
                                    sess_info->keylen, errp);
    if (!akcipher) {
        return -1;
    }

    sess = g_new0(CryptoDevBackendBuiltinSession, 1);
    sess->akcipher = akcipher;

    builtin->sessions[index] = sess;

    return index;
}

static int cryptodev_builtin_create_session(
           CryptoDevBackend *backend,
           CryptoDevBackendSessionInfo *sess_info,
           uint32_t queue_index,
           CryptoDevCompletionFunc cb,
           void *opaque)
{
    CryptoDevBackendBuiltin *builtin =
                      CRYPTODEV_BACKEND_BUILTIN(backend);
    CryptoDevBackendSymSessionInfo *sym_sess_info;
    CryptoDevBackendAsymSessionInfo *asym_sess_info;
    int ret, status;
    Error *local_error = NULL;

    switch (sess_info->op_code) {
    case VIRTIO_CRYPTO_CIPHER_CREATE_SESSION:
        sym_sess_info = &sess_info->u.sym_sess_info;
        ret = cryptodev_builtin_create_cipher_session(
                    builtin, sym_sess_info, &local_error);
        break;

    case VIRTIO_CRYPTO_AKCIPHER_CREATE_SESSION:
        asym_sess_info = &sess_info->u.asym_sess_info;
        ret = cryptodev_builtin_create_akcipher_session(
                           builtin, asym_sess_info, &local_error);
        break;

    case VIRTIO_CRYPTO_HASH_CREATE_SESSION:
    case VIRTIO_CRYPTO_MAC_CREATE_SESSION:
    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_builtin_close_session(
           CryptoDevBackend *backend,
           uint64_t session_id,
           uint32_t queue_index,
           CryptoDevCompletionFunc cb,
           void *opaque)
{
    CryptoDevBackendBuiltin *builtin =
                      CRYPTODEV_BACKEND_BUILTIN(backend);
    CryptoDevBackendBuiltinSession *session;

    if (session_id >= MAX_NUM_SESSIONS || !builtin->sessions[session_id]) {
        return -VIRTIO_CRYPTO_INVSESS;
    }

    session = builtin->sessions[session_id];
    if (session->cipher) {
        qcrypto_cipher_free(session->cipher);
    } else if (session->akcipher) {
        qcrypto_akcipher_free(session->akcipher);
    }

    g_free(session);
    builtin->sessions[session_id] = NULL;
    if (cb) {
        cb(opaque, VIRTIO_CRYPTO_OK);
    }
    return 0;
}

static int cryptodev_builtin_sym_operation(
                 CryptoDevBackendBuiltinSession *sess,
                 CryptoDevBackendSymOpInfo *op_info, Error **errp)
{
    int ret;

    if (op_info->op_type == VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) {
        error_setg(errp,
               "Algorithm chain is unsupported for cryptdoev-builtin");
        return -VIRTIO_CRYPTO_NOTSUPP;
    }

    if (op_info->iv_len > 0) {
        ret = qcrypto_cipher_setiv(sess->cipher, op_info->iv,
                                   op_info->iv_len, errp);
        if (ret < 0) {
            return -VIRTIO_CRYPTO_ERR;
        }
    }

    if (sess->direction == VIRTIO_CRYPTO_OP_ENCRYPT) {
        ret = qcrypto_cipher_encrypt(sess->cipher, op_info->src,
                                     op_info->dst, op_info->src_len, errp);
        if (ret < 0) {
            return -VIRTIO_CRYPTO_ERR;
        }
    } else {
        ret = qcrypto_cipher_decrypt(sess->cipher, op_info->src,
                                     op_info->dst, op_info->src_len, errp);
        if (ret < 0) {
            return -VIRTIO_CRYPTO_ERR;
        }
    }

    return VIRTIO_CRYPTO_OK;
}

static int cryptodev_builtin_asym_operation(
                 CryptoDevBackendBuiltinSession *sess, uint32_t op_code,
                 CryptoDevBackendAsymOpInfo *op_info, Error **errp)
{
    int ret;

    switch (op_code) {
    case VIRTIO_CRYPTO_AKCIPHER_ENCRYPT:
        ret = qcrypto_akcipher_encrypt(sess->akcipher,
                                       op_info->src, op_info->src_len,
                                       op_info->dst, op_info->dst_len, errp);
        break;

    case VIRTIO_CRYPTO_AKCIPHER_DECRYPT:
        ret = qcrypto_akcipher_decrypt(sess->akcipher,
                                       op_info->src, op_info->src_len,
                                       op_info->dst, op_info->dst_len, errp);
        break;

    case VIRTIO_CRYPTO_AKCIPHER_SIGN:
        ret = qcrypto_akcipher_sign(sess->akcipher,
                                    op_info->src, op_info->src_len,
                                    op_info->dst, op_info->dst_len, errp);
        break;

    case VIRTIO_CRYPTO_AKCIPHER_VERIFY:
        ret = qcrypto_akcipher_verify(sess->akcipher,
                                      op_info->src, op_info->src_len,
                                      op_info->dst, op_info->dst_len, errp);
        break;

    default:
        return -VIRTIO_CRYPTO_ERR;
    }

    if (ret < 0) {
        if (op_code == VIRTIO_CRYPTO_AKCIPHER_VERIFY) {
            return -VIRTIO_CRYPTO_KEY_REJECTED;
        }
        return -VIRTIO_CRYPTO_ERR;
    }

    /* Buffer is too short, typically the driver should handle this case */
    if (unlikely(ret > op_info->dst_len)) {
        if (errp && !*errp) {
            error_setg(errp, "dst buffer too short");
        }

        return -VIRTIO_CRYPTO_ERR;
    }

    op_info->dst_len = ret;

    return VIRTIO_CRYPTO_OK;
}

static int cryptodev_builtin_operation(
                 CryptoDevBackend *backend,
                 CryptoDevBackendOpInfo *op_info,
                 uint32_t queue_index,
                 CryptoDevCompletionFunc cb,
                 void *opaque)
{
    CryptoDevBackendBuiltin *builtin =
                      CRYPTODEV_BACKEND_BUILTIN(backend);
    CryptoDevBackendBuiltinSession *sess;
    CryptoDevBackendSymOpInfo *sym_op_info;
    CryptoDevBackendAsymOpInfo *asym_op_info;
    enum CryptoDevBackendAlgType algtype = op_info->algtype;
    int status = -VIRTIO_CRYPTO_ERR;
    Error *local_error = NULL;

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

    sess = builtin->sessions[op_info->session_id];
    if (algtype == CRYPTODEV_BACKEND_ALG_SYM) {
        sym_op_info = op_info->u.sym_op_info;
        status = cryptodev_builtin_sym_operation(sess, sym_op_info,
                                                 &local_error);
    } else if (algtype == CRYPTODEV_BACKEND_ALG_ASYM) {
        asym_op_info = op_info->u.asym_op_info;
        status = cryptodev_builtin_asym_operation(sess, op_info->op_code,
                                                  asym_op_info, &local_error);
    }

    if (local_error) {
        error_report_err(local_error);
    }
    if (cb) {
        cb(opaque, status);
    }
    return 0;
}

static void cryptodev_builtin_cleanup(
             CryptoDevBackend *backend,
             Error **errp)
{
    CryptoDevBackendBuiltin *builtin =
                      CRYPTODEV_BACKEND_BUILTIN(backend);
    size_t i;
    int queues = backend->conf.peers.queues;
    CryptoDevBackendClient *cc;

    for (i = 0; i < MAX_NUM_SESSIONS; i++) {
        if (builtin->sessions[i] != NULL) {
            cryptodev_builtin_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_builtin_class_init(ObjectClass *oc, void *data)
{
    CryptoDevBackendClass *bc = CRYPTODEV_BACKEND_CLASS(oc);

    bc->init = cryptodev_builtin_init;
    bc->cleanup = cryptodev_builtin_cleanup;
    bc->create_session = cryptodev_builtin_create_session;
    bc->close_session = cryptodev_builtin_close_session;
    bc->do_op = cryptodev_builtin_operation;
}

static const TypeInfo cryptodev_builtin_info = {
    .name = TYPE_CRYPTODEV_BACKEND_BUILTIN,
    .parent = TYPE_CRYPTODEV_BACKEND,
    .class_init = cryptodev_builtin_class_init,
    .instance_size = sizeof(CryptoDevBackendBuiltin),
};

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

type_init(cryptodev_builtin_register_types);
