/*
 * 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_akcipher(CryptoDevBackend *backend)
{
    QCryptoAkCipherOptions opts;

    opts.alg = QCRYPTO_AKCIPHER_ALG_RSA;
    opts.u.rsa.padding_alg = QCRYPTO_RSA_PADDING_ALG_RAW;
    if (qcrypto_akcipher_supports(&opts)) {
        backend->conf.crypto_services |=
                     (1u << QCRYPTODEV_BACKEND_SERVICE_AKCIPHER);
        backend->conf.akcipher_algo = 1u << VIRTIO_CRYPTO_AKCIPHER_RSA;
    }
}

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();
    cc->info_str = g_strdup_printf("cryptodev-builtin0");
    cc->queue_index = 0;
    cc->type = QCRYPTODEV_BACKEND_TYPE_BUILTIN;
    backend->conf.peers.ccs[0] = cc;

    backend->conf.crypto_services =
                         1u << QCRYPTODEV_BACKEND_SERVICE_CIPHER |
                         1u << QCRYPTODEV_BACKEND_SERVICE_HASH |
                         1u << QCRYPTODEV_BACKEND_SERVICE_MAC;
    backend->conf.cipher_algo_l = 1u << VIRTIO_CRYPTO_CIPHER_AES_CBC;
    backend->conf.hash_algo = 1u << VIRTIO_CRYPTO_HASH_SHA1;
    /*
     * 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_builtin_init_akcipher(backend);

    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_setg(&local_error, "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)
{
    CryptoDevBackendBuiltin *builtin =
                      CRYPTODEV_BACKEND_BUILTIN(backend);
    CryptoDevBackendBuiltinSession *sess;
    CryptoDevBackendSymOpInfo *sym_op_info;
    CryptoDevBackendAsymOpInfo *asym_op_info;
    QCryptodevBackendAlgType 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_setg(&local_error, "Cannot find a valid session id: %" PRIu64 "",
                   op_info->session_id);
        return -VIRTIO_CRYPTO_INVSESS;
    }

    sess = builtin->sessions[op_info->session_id];
    if (algtype == QCRYPTODEV_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 == QCRYPTODEV_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 (op_info->cb) {
        op_info->cb(op_info->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);
