/*
 * 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 "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 int64_t cryptodev_builtin_create_session(
           CryptoDevBackend *backend,
           CryptoDevBackendSessionInfo *sess_info,
           uint32_t queue_index, Error **errp)
{
    CryptoDevBackendBuiltin *builtin =
                      CRYPTODEV_BACKEND_BUILTIN(backend);
    CryptoDevBackendSymSessionInfo *sym_sess_info;
    CryptoDevBackendAsymSessionInfo *asym_sess_info;

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

    case VIRTIO_CRYPTO_AKCIPHER_CREATE_SESSION:
        asym_sess_info = &sess_info->u.asym_sess_info;
        return cryptodev_builtin_create_akcipher_session(
                           builtin, asym_sess_info, errp);

    case VIRTIO_CRYPTO_HASH_CREATE_SESSION:
    case VIRTIO_CRYPTO_MAC_CREATE_SESSION:
    default:
        error_setg(errp, "Unsupported opcode :%" PRIu32 "",
                   sess_info->op_code);
        return -1;
    }

    return -1;
}

static int cryptodev_builtin_close_session(
           CryptoDevBackend *backend,
           uint64_t session_id,
           uint32_t queue_index, Error **errp)
{
    CryptoDevBackendBuiltin *builtin =
                      CRYPTODEV_BACKEND_BUILTIN(backend);
    CryptoDevBackendBuiltinSession *session;

    assert(session_id < MAX_NUM_SESSIONS && builtin->sessions[session_id]);

    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;
    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, Error **errp)
{
    CryptoDevBackendBuiltin *builtin =
                      CRYPTODEV_BACKEND_BUILTIN(backend);
    CryptoDevBackendBuiltinSession *sess;
    CryptoDevBackendSymOpInfo *sym_op_info;
    CryptoDevBackendAsymOpInfo *asym_op_info;
    enum CryptoDevBackendAlgType algtype = op_info->algtype;
    int ret = -VIRTIO_CRYPTO_ERR;

    if (op_info->session_id >= MAX_NUM_SESSIONS ||
              builtin->sessions[op_info->session_id] == NULL) {
        error_setg(errp, "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;
        ret = cryptodev_builtin_sym_operation(sess, sym_op_info, errp);
    } else if (algtype == CRYPTODEV_BACKEND_ALG_ASYM) {
        asym_op_info = op_info->u.asym_op_info;
        ret = cryptodev_builtin_asym_operation(sess, op_info->op_code,
                                               asym_op_info, errp);
    }

    return ret;
}

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, &error_abort);
        }
    }

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