/*
 * Virtio crypto Support
 *
 * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
 *
 * Authors:
 *    Gonglei <arei.gonglei@huawei.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or
 * (at your option) any later version.  See the COPYING file in the
 * top-level directory.
 */

#include "qemu/osdep.h"
#include "qemu/iov.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "qapi/error.h"
#include "qemu/error-report.h"

#include "hw/virtio/virtio.h"
#include "hw/virtio/virtio-crypto.h"
#include "hw/qdev-properties.h"
#include "standard-headers/linux/virtio_ids.h"
#include "sysemu/cryptodev-vhost.h"

#define VIRTIO_CRYPTO_VM_VERSION 1

typedef struct VirtIOCryptoSessionReq {
    VirtIODevice *vdev;
    VirtQueue *vq;
    VirtQueueElement *elem;
    CryptoDevBackendSessionInfo info;
    CryptoDevCompletionFunc cb;
} VirtIOCryptoSessionReq;

static void virtio_crypto_free_create_session_req(VirtIOCryptoSessionReq *sreq)
{
    switch (sreq->info.op_code) {
    case VIRTIO_CRYPTO_CIPHER_CREATE_SESSION:
        g_free(sreq->info.u.sym_sess_info.cipher_key);
        g_free(sreq->info.u.sym_sess_info.auth_key);
        break;

    case VIRTIO_CRYPTO_AKCIPHER_CREATE_SESSION:
        g_free(sreq->info.u.asym_sess_info.key);
        break;

    case VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION:
    case VIRTIO_CRYPTO_HASH_DESTROY_SESSION:
    case VIRTIO_CRYPTO_MAC_DESTROY_SESSION:
    case VIRTIO_CRYPTO_AEAD_DESTROY_SESSION:
    case VIRTIO_CRYPTO_AKCIPHER_DESTROY_SESSION:
        break;

    default:
        error_report("Unknown opcode: %u", sreq->info.op_code);
    }
    g_free(sreq);
}

/*
 * Transfer virtqueue index to crypto queue index.
 * The control virtqueue is after the data virtqueues
 * so the input value doesn't need to be adjusted
 */
static inline int virtio_crypto_vq2q(int queue_index)
{
    return queue_index;
}

static int
virtio_crypto_cipher_session_helper(VirtIODevice *vdev,
           CryptoDevBackendSymSessionInfo *info,
           struct virtio_crypto_cipher_session_para *cipher_para,
           struct iovec **iov, unsigned int *out_num)
{
    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);
    unsigned int num = *out_num;

    info->cipher_alg = ldl_le_p(&cipher_para->algo);
    info->key_len = ldl_le_p(&cipher_para->keylen);
    info->direction = ldl_le_p(&cipher_para->op);
    DPRINTF("cipher_alg=%" PRIu32 ", info->direction=%" PRIu32 "\n",
             info->cipher_alg, info->direction);

    if (info->key_len > vcrypto->conf.max_cipher_key_len) {
        error_report("virtio-crypto length of cipher key is too big: %u",
                     info->key_len);
        return -VIRTIO_CRYPTO_ERR;
    }
    /* Get cipher key */
    if (info->key_len > 0) {
        size_t s;
        DPRINTF("keylen=%" PRIu32 "\n", info->key_len);

        info->cipher_key = g_malloc(info->key_len);
        s = iov_to_buf(*iov, num, 0, info->cipher_key, info->key_len);
        if (unlikely(s != info->key_len)) {
            virtio_error(vdev, "virtio-crypto cipher key incorrect");
            return -EFAULT;
        }
        iov_discard_front(iov, &num, info->key_len);
        *out_num = num;
    }

    return 0;
}

static int
virtio_crypto_create_sym_session(VirtIOCrypto *vcrypto,
               struct virtio_crypto_sym_create_session_req *sess_req,
               uint32_t queue_id,
               uint32_t opcode,
               struct iovec *iov, unsigned int out_num,
               VirtIOCryptoSessionReq *sreq)
{
    VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
    CryptoDevBackendSymSessionInfo *sym_info = &sreq->info.u.sym_sess_info;
    int queue_index;
    uint32_t op_type;
    int ret;

    op_type = ldl_le_p(&sess_req->op_type);
    sreq->info.op_code = opcode;

    sym_info = &sreq->info.u.sym_sess_info;
    sym_info->op_type = op_type;

    if (op_type == VIRTIO_CRYPTO_SYM_OP_CIPHER) {
        ret = virtio_crypto_cipher_session_helper(vdev, sym_info,
                           &sess_req->u.cipher.para,
                           &iov, &out_num);
        if (ret < 0) {
            return ret;
        }
    } else if (op_type == VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) {
        size_t s;
        /* cipher part */
        ret = virtio_crypto_cipher_session_helper(vdev, sym_info,
                           &sess_req->u.chain.para.cipher_param,
                           &iov, &out_num);
        if (ret < 0) {
            return ret;
        }
        /* hash part */
        sym_info->alg_chain_order = ldl_le_p(
                                     &sess_req->u.chain.para.alg_chain_order);
        sym_info->add_len = ldl_le_p(&sess_req->u.chain.para.aad_len);
        sym_info->hash_mode = ldl_le_p(&sess_req->u.chain.para.hash_mode);
        if (sym_info->hash_mode == VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH) {
            sym_info->hash_alg =
                ldl_le_p(&sess_req->u.chain.para.u.mac_param.algo);
            sym_info->auth_key_len = ldl_le_p(
                             &sess_req->u.chain.para.u.mac_param.auth_key_len);
            sym_info->hash_result_len = ldl_le_p(
                           &sess_req->u.chain.para.u.mac_param.hash_result_len);
            if (sym_info->auth_key_len > vcrypto->conf.max_auth_key_len) {
                error_report("virtio-crypto length of auth key is too big: %u",
                             sym_info->auth_key_len);
                return -VIRTIO_CRYPTO_ERR;
            }
            /* get auth key */
            if (sym_info->auth_key_len > 0) {
                sym_info->auth_key = g_malloc(sym_info->auth_key_len);
                s = iov_to_buf(iov, out_num, 0, sym_info->auth_key,
                               sym_info->auth_key_len);
                if (unlikely(s != sym_info->auth_key_len)) {
                    virtio_error(vdev,
                          "virtio-crypto authenticated key incorrect");
                    return -EFAULT;
                }
                iov_discard_front(&iov, &out_num, sym_info->auth_key_len);
            }
        } else if (sym_info->hash_mode == VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN) {
            sym_info->hash_alg = ldl_le_p(
                             &sess_req->u.chain.para.u.hash_param.algo);
            sym_info->hash_result_len = ldl_le_p(
                        &sess_req->u.chain.para.u.hash_param.hash_result_len);
        } else {
            /* VIRTIO_CRYPTO_SYM_HASH_MODE_NESTED */
            error_report("unsupported hash mode");
            return -VIRTIO_CRYPTO_NOTSUPP;
        }
    } else {
        /* VIRTIO_CRYPTO_SYM_OP_NONE */
        error_report("unsupported cipher op_type: VIRTIO_CRYPTO_SYM_OP_NONE");
        return -VIRTIO_CRYPTO_NOTSUPP;
    }

    queue_index = virtio_crypto_vq2q(queue_id);
    return cryptodev_backend_create_session(vcrypto->cryptodev, &sreq->info,
                                            queue_index, sreq->cb, sreq);
}

static int
virtio_crypto_create_asym_session(VirtIOCrypto *vcrypto,
               struct virtio_crypto_akcipher_create_session_req *sess_req,
               uint32_t queue_id, uint32_t opcode,
               struct iovec *iov, unsigned int out_num,
               VirtIOCryptoSessionReq *sreq)
{
    VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
    CryptoDevBackendAsymSessionInfo *asym_info = &sreq->info.u.asym_sess_info;
    int queue_index;
    uint32_t algo, keytype, keylen;

    sreq->info.op_code = opcode;
    algo = ldl_le_p(&sess_req->para.algo);
    keytype = ldl_le_p(&sess_req->para.keytype);
    keylen = ldl_le_p(&sess_req->para.keylen);

    if ((keytype != VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PUBLIC)
         && (keytype != VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PRIVATE)) {
        error_report("unsupported asym keytype: %d", keytype);
        return -VIRTIO_CRYPTO_NOTSUPP;
    }

    if (keylen) {
        asym_info->key = g_malloc(keylen);
        if (iov_to_buf(iov, out_num, 0, asym_info->key, keylen) != keylen) {
            virtio_error(vdev, "virtio-crypto asym key incorrect");
            return -EFAULT;
        }
        iov_discard_front(&iov, &out_num, keylen);
    }

    asym_info = &sreq->info.u.asym_sess_info;
    asym_info->algo = algo;
    asym_info->keytype = keytype;
    asym_info->keylen = keylen;
    switch (asym_info->algo) {
    case VIRTIO_CRYPTO_AKCIPHER_RSA:
        asym_info->u.rsa.padding_algo =
            ldl_le_p(&sess_req->para.u.rsa.padding_algo);
        asym_info->u.rsa.hash_algo =
            ldl_le_p(&sess_req->para.u.rsa.hash_algo);
        break;

    /* TODO DSA&ECDSA handling */

    default:
        return -VIRTIO_CRYPTO_ERR;
    }

    queue_index = virtio_crypto_vq2q(queue_id);
    return cryptodev_backend_create_session(vcrypto->cryptodev, &sreq->info,
                                            queue_index, sreq->cb, sreq);
}

static int
virtio_crypto_handle_close_session(VirtIOCrypto *vcrypto,
         struct virtio_crypto_destroy_session_req *close_sess_req,
         uint32_t queue_id,
         VirtIOCryptoSessionReq *sreq)
{
    uint64_t session_id;

    session_id = ldq_le_p(&close_sess_req->session_id);
    DPRINTF("close session, id=%" PRIu64 "\n", session_id);

    return cryptodev_backend_close_session(
                vcrypto->cryptodev, session_id, queue_id, sreq->cb, sreq);
}

static void virtio_crypto_create_session_completion(void *opaque, int ret)
{
    VirtIOCryptoSessionReq *sreq = (VirtIOCryptoSessionReq *)opaque;
    VirtQueue *vq = sreq->vq;
    VirtQueueElement *elem = sreq->elem;
    VirtIODevice *vdev = sreq->vdev;
    struct virtio_crypto_session_input input;
    struct iovec *in_iov = elem->in_sg;
    unsigned in_num = elem->in_num;
    size_t s;

    memset(&input, 0, sizeof(input));
    /* Serious errors, need to reset virtio crypto device */
    if (ret == -EFAULT) {
        virtqueue_detach_element(vq, elem, 0);
        goto out;
    } else if (ret == -VIRTIO_CRYPTO_NOTSUPP) {
        stl_le_p(&input.status, VIRTIO_CRYPTO_NOTSUPP);
    } else if (ret == -VIRTIO_CRYPTO_KEY_REJECTED) {
        stl_le_p(&input.status, VIRTIO_CRYPTO_KEY_REJECTED);
    } else if (ret != VIRTIO_CRYPTO_OK) {
        stl_le_p(&input.status, VIRTIO_CRYPTO_ERR);
    } else {
        /* Set the session id */
        stq_le_p(&input.session_id, sreq->info.session_id);
        stl_le_p(&input.status, VIRTIO_CRYPTO_OK);
    }

    s = iov_from_buf(in_iov, in_num, 0, &input, sizeof(input));
    if (unlikely(s != sizeof(input))) {
        virtio_error(vdev, "virtio-crypto input incorrect");
        virtqueue_detach_element(vq, elem, 0);
        goto out;
    }
    virtqueue_push(vq, elem, sizeof(input));
    virtio_notify(vdev, vq);

out:
    g_free(elem);
    virtio_crypto_free_create_session_req(sreq);
}

static void virtio_crypto_destroy_session_completion(void *opaque, int ret)
{
    VirtIOCryptoSessionReq *sreq = (VirtIOCryptoSessionReq *)opaque;
    VirtQueue *vq = sreq->vq;
    VirtQueueElement *elem = sreq->elem;
    VirtIODevice *vdev = sreq->vdev;
    struct iovec *in_iov = elem->in_sg;
    unsigned in_num = elem->in_num;
    uint8_t status;
    size_t s;

    if (ret < 0) {
        status = VIRTIO_CRYPTO_ERR;
    } else {
        status = VIRTIO_CRYPTO_OK;
    }
    s = iov_from_buf(in_iov, in_num, 0, &status, sizeof(status));
    if (unlikely(s != sizeof(status))) {
        virtio_error(vdev, "virtio-crypto status incorrect");
        virtqueue_detach_element(vq, elem, 0);
        goto out;
    }
    virtqueue_push(vq, elem, sizeof(status));
    virtio_notify(vdev, vq);

out:
    g_free(elem);
    g_free(sreq);
}

static void virtio_crypto_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
{
    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);
    struct virtio_crypto_op_ctrl_req ctrl;
    VirtQueueElement *elem;
    VirtIOCryptoSessionReq *sreq;
    unsigned out_num;
    unsigned in_num;
    uint32_t queue_id;
    uint32_t opcode;
    struct virtio_crypto_session_input input;
    size_t s;
    int ret;
    struct iovec *out_iov;
    struct iovec *in_iov;

    for (;;) {
        g_autofree struct iovec *out_iov_copy = NULL;

        elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
        if (!elem) {
            break;
        }
        if (elem->out_num < 1 || elem->in_num < 1) {
            virtio_error(vdev, "virtio-crypto ctrl missing headers");
            virtqueue_detach_element(vq, elem, 0);
            g_free(elem);
            break;
        }

        out_num = elem->out_num;
        out_iov_copy = g_memdup2(elem->out_sg, sizeof(out_iov[0]) * out_num);
        out_iov = out_iov_copy;

        in_num = elem->in_num;
        in_iov = elem->in_sg;

        if (unlikely(iov_to_buf(out_iov, out_num, 0, &ctrl, sizeof(ctrl))
                    != sizeof(ctrl))) {
            virtio_error(vdev, "virtio-crypto request ctrl_hdr too short");
            virtqueue_detach_element(vq, elem, 0);
            g_free(elem);
            break;
        }
        iov_discard_front(&out_iov, &out_num, sizeof(ctrl));

        opcode = ldl_le_p(&ctrl.header.opcode);
        queue_id = ldl_le_p(&ctrl.header.queue_id);

        sreq = g_new0(VirtIOCryptoSessionReq, 1);
        sreq->vdev = vdev;
        sreq->vq = vq;
        sreq->elem = elem;

        switch (opcode) {
        case VIRTIO_CRYPTO_CIPHER_CREATE_SESSION:
            sreq->cb = virtio_crypto_create_session_completion;
            ret = virtio_crypto_create_sym_session(vcrypto,
                            &ctrl.u.sym_create_session,
                            queue_id, opcode,
                            out_iov, out_num,
                            sreq);
            if (ret < 0) {
                virtio_crypto_create_session_completion(sreq, ret);
            }
            break;

        case VIRTIO_CRYPTO_AKCIPHER_CREATE_SESSION:
            sreq->cb = virtio_crypto_create_session_completion;
            ret = virtio_crypto_create_asym_session(vcrypto,
                             &ctrl.u.akcipher_create_session,
                             queue_id, opcode,
                             out_iov, out_num,
                             sreq);
            if (ret < 0) {
                virtio_crypto_create_session_completion(sreq, ret);
            }
            break;

        case VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION:
        case VIRTIO_CRYPTO_HASH_DESTROY_SESSION:
        case VIRTIO_CRYPTO_MAC_DESTROY_SESSION:
        case VIRTIO_CRYPTO_AEAD_DESTROY_SESSION:
        case VIRTIO_CRYPTO_AKCIPHER_DESTROY_SESSION:
            sreq->cb = virtio_crypto_destroy_session_completion;
            ret = virtio_crypto_handle_close_session(vcrypto,
                   &ctrl.u.destroy_session, queue_id,
                   sreq);
            if (ret < 0) {
                virtio_crypto_destroy_session_completion(sreq, ret);
            }
            break;

        case VIRTIO_CRYPTO_HASH_CREATE_SESSION:
        case VIRTIO_CRYPTO_MAC_CREATE_SESSION:
        case VIRTIO_CRYPTO_AEAD_CREATE_SESSION:
        default:
            memset(&input, 0, sizeof(input));
            error_report("virtio-crypto unsupported ctrl opcode: %d", opcode);
            stl_le_p(&input.status, VIRTIO_CRYPTO_NOTSUPP);
            s = iov_from_buf(in_iov, in_num, 0, &input, sizeof(input));
            if (unlikely(s != sizeof(input))) {
                virtio_error(vdev, "virtio-crypto input incorrect");
                virtqueue_detach_element(vq, elem, 0);
            } else {
                virtqueue_push(vq, elem, sizeof(input));
                virtio_notify(vdev, vq);
            }
            g_free(sreq);
            g_free(elem);

            break;
        } /* end switch case */

    } /* end for loop */
}

static void virtio_crypto_init_request(VirtIOCrypto *vcrypto, VirtQueue *vq,
                                VirtIOCryptoReq *req)
{
    req->vcrypto = vcrypto;
    req->vq = vq;
    req->in = NULL;
    req->in_iov = NULL;
    req->in_num = 0;
    req->in_len = 0;
    req->flags = QCRYPTODEV_BACKEND_ALGO_TYPE__MAX;
    memset(&req->op_info, 0x00, sizeof(req->op_info));
}

static void virtio_crypto_free_request(VirtIOCryptoReq *req)
{
    if (!req) {
        return;
    }

    if (req->flags == QCRYPTODEV_BACKEND_ALGO_TYPE_SYM) {
        size_t max_len;
        CryptoDevBackendSymOpInfo *op_info = req->op_info.u.sym_op_info;

        if (op_info) {
            max_len = op_info->iv_len +
                      op_info->aad_len +
                      op_info->src_len +
                      op_info->dst_len +
                      op_info->digest_result_len;

            /* Zeroize and free request data structure */
            memset(op_info, 0, sizeof(*op_info) + max_len);
            g_free(op_info);
        }
    } else if (req->flags == QCRYPTODEV_BACKEND_ALGO_TYPE_ASYM) {
        CryptoDevBackendAsymOpInfo *op_info = req->op_info.u.asym_op_info;
        if (op_info) {
            g_free(op_info->src);
            g_free(op_info->dst);
            memset(op_info, 0, sizeof(*op_info));
            g_free(op_info);
        }
    }

    g_free(req->in_iov);
    g_free(req);
}

static void
virtio_crypto_sym_input_data_helper(VirtIODevice *vdev,
                VirtIOCryptoReq *req,
                uint32_t status,
                CryptoDevBackendSymOpInfo *sym_op_info)
{
    size_t s, len;
    struct iovec *in_iov = req->in_iov;

    if (status != VIRTIO_CRYPTO_OK) {
        return;
    }

    len = sym_op_info->src_len;
    /* Save the cipher result */
    s = iov_from_buf(in_iov, req->in_num, 0, sym_op_info->dst, len);
    if (s != len) {
        virtio_error(vdev, "virtio-crypto dest data incorrect");
        return;
    }

    iov_discard_front(&in_iov, &req->in_num, len);

    if (sym_op_info->op_type ==
                      VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) {
        /* Save the digest result */
        s = iov_from_buf(in_iov, req->in_num, 0,
                         sym_op_info->digest_result,
                         sym_op_info->digest_result_len);
        if (s != sym_op_info->digest_result_len) {
            virtio_error(vdev, "virtio-crypto digest result incorrect");
        }
    }
}

static void
virtio_crypto_akcipher_input_data_helper(VirtIODevice *vdev,
        VirtIOCryptoReq *req, int32_t status,
        CryptoDevBackendAsymOpInfo *asym_op_info)
{
    size_t s, len;
    struct iovec *in_iov = req->in_iov;

    if (status != VIRTIO_CRYPTO_OK) {
        return;
    }

    len = asym_op_info->dst_len;
    if (!len) {
        return;
    }

    s = iov_from_buf(in_iov, req->in_num, 0, asym_op_info->dst, len);
    if (s != len) {
        virtio_error(vdev, "virtio-crypto asym dest data incorrect");
        return;
    }

    iov_discard_front(&in_iov, &req->in_num, len);

    /* For akcipher, dst_len may be changed after operation */
    req->in_len = sizeof(struct virtio_crypto_inhdr) + asym_op_info->dst_len;
}

static void virtio_crypto_req_complete(void *opaque, int ret)
{
    VirtIOCryptoReq *req = (VirtIOCryptoReq *)opaque;
    VirtIOCrypto *vcrypto = req->vcrypto;
    VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
    uint8_t status = -ret;

    if (req->flags == QCRYPTODEV_BACKEND_ALGO_TYPE_SYM) {
        virtio_crypto_sym_input_data_helper(vdev, req, status,
                                            req->op_info.u.sym_op_info);
    } else if (req->flags == QCRYPTODEV_BACKEND_ALGO_TYPE_ASYM) {
        virtio_crypto_akcipher_input_data_helper(vdev, req, status,
                                             req->op_info.u.asym_op_info);
    }
    stb_p(&req->in->status, status);
    virtqueue_push(req->vq, &req->elem, req->in_len);
    virtio_notify(vdev, req->vq);
    virtio_crypto_free_request(req);
}

static VirtIOCryptoReq *
virtio_crypto_get_request(VirtIOCrypto *s, VirtQueue *vq)
{
    VirtIOCryptoReq *req = virtqueue_pop(vq, sizeof(VirtIOCryptoReq));

    if (req) {
        virtio_crypto_init_request(s, vq, req);
    }
    return req;
}

static CryptoDevBackendSymOpInfo *
virtio_crypto_sym_op_helper(VirtIODevice *vdev,
           struct virtio_crypto_cipher_para *cipher_para,
           struct virtio_crypto_alg_chain_data_para *alg_chain_para,
           struct iovec *iov, unsigned int out_num)
{
    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);
    CryptoDevBackendSymOpInfo *op_info;
    uint32_t src_len = 0, dst_len = 0;
    uint32_t iv_len = 0;
    uint32_t aad_len = 0, hash_result_len = 0;
    uint32_t hash_start_src_offset = 0, len_to_hash = 0;
    uint32_t cipher_start_src_offset = 0, len_to_cipher = 0;

    uint64_t max_len, curr_size = 0;
    size_t s;

    /* Plain cipher */
    if (cipher_para) {
        iv_len = ldl_le_p(&cipher_para->iv_len);
        src_len = ldl_le_p(&cipher_para->src_data_len);
        dst_len = ldl_le_p(&cipher_para->dst_data_len);
    } else if (alg_chain_para) { /* Algorithm chain */
        iv_len = ldl_le_p(&alg_chain_para->iv_len);
        src_len = ldl_le_p(&alg_chain_para->src_data_len);
        dst_len = ldl_le_p(&alg_chain_para->dst_data_len);

        aad_len = ldl_le_p(&alg_chain_para->aad_len);
        hash_result_len = ldl_le_p(&alg_chain_para->hash_result_len);
        hash_start_src_offset = ldl_le_p(
                         &alg_chain_para->hash_start_src_offset);
        cipher_start_src_offset = ldl_le_p(
                         &alg_chain_para->cipher_start_src_offset);
        len_to_cipher = ldl_le_p(&alg_chain_para->len_to_cipher);
        len_to_hash = ldl_le_p(&alg_chain_para->len_to_hash);
    } else {
        return NULL;
    }

    if (unlikely(src_len != dst_len)) {
        virtio_error(vdev, "sym request src len is different from dst len");
        return NULL;
    }

    max_len = (uint64_t)iv_len + aad_len + src_len + dst_len + hash_result_len;
    if (unlikely(max_len > vcrypto->conf.max_size)) {
        virtio_error(vdev, "virtio-crypto too big length");
        return NULL;
    }

    op_info = g_malloc0(sizeof(CryptoDevBackendSymOpInfo) + max_len);
    op_info->iv_len = iv_len;
    op_info->src_len = src_len;
    op_info->dst_len = dst_len;
    op_info->aad_len = aad_len;
    op_info->digest_result_len = hash_result_len;
    op_info->hash_start_src_offset = hash_start_src_offset;
    op_info->len_to_hash = len_to_hash;
    op_info->cipher_start_src_offset = cipher_start_src_offset;
    op_info->len_to_cipher = len_to_cipher;
    /* Handle the initialization vector */
    if (op_info->iv_len > 0) {
        DPRINTF("iv_len=%" PRIu32 "\n", op_info->iv_len);
        op_info->iv = op_info->data + curr_size;

        s = iov_to_buf(iov, out_num, 0, op_info->iv, op_info->iv_len);
        if (unlikely(s != op_info->iv_len)) {
            virtio_error(vdev, "virtio-crypto iv incorrect");
            goto err;
        }
        iov_discard_front(&iov, &out_num, op_info->iv_len);
        curr_size += op_info->iv_len;
    }

    /* Handle additional authentication data if exists */
    if (op_info->aad_len > 0) {
        DPRINTF("aad_len=%" PRIu32 "\n", op_info->aad_len);
        op_info->aad_data = op_info->data + curr_size;

        s = iov_to_buf(iov, out_num, 0, op_info->aad_data, op_info->aad_len);
        if (unlikely(s != op_info->aad_len)) {
            virtio_error(vdev, "virtio-crypto additional auth data incorrect");
            goto err;
        }
        iov_discard_front(&iov, &out_num, op_info->aad_len);

        curr_size += op_info->aad_len;
    }

    /* Handle the source data */
    if (op_info->src_len > 0) {
        DPRINTF("src_len=%" PRIu32 "\n", op_info->src_len);
        op_info->src = op_info->data + curr_size;

        s = iov_to_buf(iov, out_num, 0, op_info->src, op_info->src_len);
        if (unlikely(s != op_info->src_len)) {
            virtio_error(vdev, "virtio-crypto source data incorrect");
            goto err;
        }
        iov_discard_front(&iov, &out_num, op_info->src_len);

        curr_size += op_info->src_len;
    }

    /* Handle the destination data */
    op_info->dst = op_info->data + curr_size;
    curr_size += op_info->dst_len;

    DPRINTF("dst_len=%" PRIu32 "\n", op_info->dst_len);

    /* Handle the hash digest result */
    if (hash_result_len > 0) {
        DPRINTF("hash_result_len=%" PRIu32 "\n", hash_result_len);
        op_info->digest_result = op_info->data + curr_size;
    }

    return op_info;

err:
    g_free(op_info);
    return NULL;
}

static int
virtio_crypto_handle_sym_req(VirtIOCrypto *vcrypto,
               struct virtio_crypto_sym_data_req *req,
               CryptoDevBackendOpInfo *op_info,
               struct iovec *iov, unsigned int out_num)
{
    VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
    CryptoDevBackendSymOpInfo *sym_op_info;
    uint32_t op_type;

    op_type = ldl_le_p(&req->op_type);
    if (op_type == VIRTIO_CRYPTO_SYM_OP_CIPHER) {
        sym_op_info = virtio_crypto_sym_op_helper(vdev, &req->u.cipher.para,
                                              NULL, iov, out_num);
        if (!sym_op_info) {
            return -EFAULT;
        }
    } else if (op_type == VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) {
        sym_op_info = virtio_crypto_sym_op_helper(vdev, NULL,
                                              &req->u.chain.para,
                                              iov, out_num);
        if (!sym_op_info) {
            return -EFAULT;
        }
    } else {
        /* VIRTIO_CRYPTO_SYM_OP_NONE */
        error_report("virtio-crypto unsupported cipher type");
        return -VIRTIO_CRYPTO_NOTSUPP;
    }

    sym_op_info->op_type = op_type;
    op_info->u.sym_op_info = sym_op_info;

    return 0;
}

static int
virtio_crypto_handle_asym_req(VirtIOCrypto *vcrypto,
               struct virtio_crypto_akcipher_data_req *req,
               CryptoDevBackendOpInfo *op_info,
               struct iovec *iov, unsigned int out_num)
{
    VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
    CryptoDevBackendAsymOpInfo *asym_op_info;
    uint32_t src_len;
    uint32_t dst_len;
    uint32_t len;
    uint8_t *src = NULL;
    uint8_t *dst = NULL;

    asym_op_info = g_new0(CryptoDevBackendAsymOpInfo, 1);
    src_len = ldl_le_p(&req->para.src_data_len);
    dst_len = ldl_le_p(&req->para.dst_data_len);

    if (src_len > 0) {
        src = g_malloc0(src_len);
        len = iov_to_buf(iov, out_num, 0, src, src_len);
        if (unlikely(len != src_len)) {
            virtio_error(vdev, "virtio-crypto asym src data incorrect"
                         "expected %u, actual %u", src_len, len);
            goto err;
        }

        iov_discard_front(&iov, &out_num, src_len);
    }

    if (dst_len > 0) {
        dst = g_malloc0(dst_len);

        if (op_info->op_code == VIRTIO_CRYPTO_AKCIPHER_VERIFY) {
            len = iov_to_buf(iov, out_num, 0, dst, dst_len);
            if (unlikely(len != dst_len)) {
                virtio_error(vdev, "virtio-crypto asym dst data incorrect"
                             "expected %u, actual %u", dst_len, len);
                goto err;
            }

            iov_discard_front(&iov, &out_num, dst_len);
        }
    }

    asym_op_info->src_len = src_len;
    asym_op_info->dst_len = dst_len;
    asym_op_info->src = src;
    asym_op_info->dst = dst;
    op_info->u.asym_op_info = asym_op_info;

    return 0;

 err:
    g_free(asym_op_info);
    g_free(src);
    g_free(dst);

    return -EFAULT;
}

static int
virtio_crypto_handle_request(VirtIOCryptoReq *request)
{
    VirtIOCrypto *vcrypto = request->vcrypto;
    VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
    VirtQueueElement *elem = &request->elem;
    int queue_index = virtio_crypto_vq2q(virtio_get_queue_index(request->vq));
    struct virtio_crypto_op_data_req req;
    int ret;
    g_autofree struct iovec *in_iov_copy = NULL;
    g_autofree struct iovec *out_iov_copy = NULL;
    struct iovec *in_iov;
    struct iovec *out_iov;
    unsigned in_num;
    unsigned out_num;
    uint32_t opcode;
    CryptoDevBackendOpInfo *op_info = &request->op_info;

    if (elem->out_num < 1 || elem->in_num < 1) {
        virtio_error(vdev, "virtio-crypto dataq missing headers");
        return -1;
    }

    out_num = elem->out_num;
    out_iov_copy = g_memdup2(elem->out_sg, sizeof(out_iov[0]) * out_num);
    out_iov = out_iov_copy;

    in_num = elem->in_num;
    in_iov_copy = g_memdup2(elem->in_sg, sizeof(in_iov[0]) * in_num);
    in_iov = in_iov_copy;

    if (unlikely(iov_to_buf(out_iov, out_num, 0, &req, sizeof(req))
                != sizeof(req))) {
        virtio_error(vdev, "virtio-crypto request outhdr too short");
        return -1;
    }
    iov_discard_front(&out_iov, &out_num, sizeof(req));

    if (in_iov[in_num - 1].iov_len <
            sizeof(struct virtio_crypto_inhdr)) {
        virtio_error(vdev, "virtio-crypto request inhdr too short");
        return -1;
    }
    /* We always touch the last byte, so just see how big in_iov is. */
    request->in_len = iov_size(in_iov, in_num);
    request->in = (void *)in_iov[in_num - 1].iov_base
              + in_iov[in_num - 1].iov_len
              - sizeof(struct virtio_crypto_inhdr);
    iov_discard_back(in_iov, &in_num, sizeof(struct virtio_crypto_inhdr));

    /*
     * The length of operation result, including dest_data
     * and digest_result if exists.
     */
    request->in_num = in_num;
    request->in_iov = in_iov;
    /* now, we free the in_iov_copy inside virtio_crypto_free_request */
    in_iov_copy = NULL;

    opcode = ldl_le_p(&req.header.opcode);
    op_info->session_id = ldq_le_p(&req.header.session_id);
    op_info->op_code = opcode;
    op_info->queue_index = queue_index;
    op_info->cb = virtio_crypto_req_complete;
    op_info->opaque = request;

    switch (opcode) {
    case VIRTIO_CRYPTO_CIPHER_ENCRYPT:
    case VIRTIO_CRYPTO_CIPHER_DECRYPT:
        op_info->algtype = request->flags = QCRYPTODEV_BACKEND_ALGO_TYPE_SYM;
        ret = virtio_crypto_handle_sym_req(vcrypto,
                         &req.u.sym_req, op_info,
                         out_iov, out_num);
        goto check_result;

    case VIRTIO_CRYPTO_AKCIPHER_ENCRYPT:
    case VIRTIO_CRYPTO_AKCIPHER_DECRYPT:
    case VIRTIO_CRYPTO_AKCIPHER_SIGN:
    case VIRTIO_CRYPTO_AKCIPHER_VERIFY:
        op_info->algtype = request->flags = QCRYPTODEV_BACKEND_ALGO_TYPE_ASYM;
        ret = virtio_crypto_handle_asym_req(vcrypto,
                         &req.u.akcipher_req, op_info,
                         out_iov, out_num);

check_result:
        /* Serious errors, need to reset virtio crypto device */
        if (ret == -EFAULT) {
            return -1;
        } else if (ret == -VIRTIO_CRYPTO_NOTSUPP) {
            virtio_crypto_req_complete(request, -VIRTIO_CRYPTO_NOTSUPP);
        } else {
            ret = cryptodev_backend_crypto_operation(vcrypto->cryptodev,
                                    op_info);
            if (ret < 0) {
                virtio_crypto_req_complete(request, ret);
            }
        }
        break;

    case VIRTIO_CRYPTO_HASH:
    case VIRTIO_CRYPTO_MAC:
    case VIRTIO_CRYPTO_AEAD_ENCRYPT:
    case VIRTIO_CRYPTO_AEAD_DECRYPT:
    default:
        error_report("virtio-crypto unsupported dataq opcode: %u",
                     opcode);
        virtio_crypto_req_complete(request, -VIRTIO_CRYPTO_NOTSUPP);
    }

    return 0;
}

static void virtio_crypto_handle_dataq(VirtIODevice *vdev, VirtQueue *vq)
{
    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);
    VirtIOCryptoReq *req;

    while ((req = virtio_crypto_get_request(vcrypto, vq))) {
        if (virtio_crypto_handle_request(req) < 0) {
            virtqueue_detach_element(req->vq, &req->elem, 0);
            virtio_crypto_free_request(req);
            break;
        }
    }
}

static void virtio_crypto_dataq_bh(void *opaque)
{
    VirtIOCryptoQueue *q = opaque;
    VirtIOCrypto *vcrypto = q->vcrypto;
    VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);

    /* This happens when device was stopped but BH wasn't. */
    if (!vdev->vm_running) {
        return;
    }

    /* Just in case the driver is not ready on more */
    if (unlikely(!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK))) {
        return;
    }

    for (;;) {
        virtio_crypto_handle_dataq(vdev, q->dataq);
        virtio_queue_set_notification(q->dataq, 1);

        /* Are we done or did the guest add more buffers? */
        if (virtio_queue_empty(q->dataq)) {
            break;
        }

        virtio_queue_set_notification(q->dataq, 0);
    }
}

static void
virtio_crypto_handle_dataq_bh(VirtIODevice *vdev, VirtQueue *vq)
{
    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);
    VirtIOCryptoQueue *q =
         &vcrypto->vqs[virtio_crypto_vq2q(virtio_get_queue_index(vq))];

    /* This happens when device was stopped but VCPU wasn't. */
    if (!vdev->vm_running) {
        return;
    }
    virtio_queue_set_notification(vq, 0);
    qemu_bh_schedule(q->dataq_bh);
}

static uint64_t virtio_crypto_get_features(VirtIODevice *vdev,
                                           uint64_t features,
                                           Error **errp)
{
    return features;
}

static void virtio_crypto_reset(VirtIODevice *vdev)
{
    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);
    /* multiqueue is disabled by default */
    vcrypto->curr_queues = 1;
    if (!cryptodev_backend_is_ready(vcrypto->cryptodev)) {
        vcrypto->status &= ~VIRTIO_CRYPTO_S_HW_READY;
    } else {
        vcrypto->status |= VIRTIO_CRYPTO_S_HW_READY;
    }
}

static uint32_t virtio_crypto_init_services(uint32_t qservices)
{
    uint32_t vservices = 0;

    if (qservices & (1 << QCRYPTODEV_BACKEND_SERVICE_TYPE_CIPHER)) {
        vservices |= (1 << VIRTIO_CRYPTO_SERVICE_CIPHER);
    }
    if (qservices & (1 << QCRYPTODEV_BACKEND_SERVICE_TYPE_HASH)) {
        vservices |= (1 << VIRTIO_CRYPTO_SERVICE_HASH);
    }
    if (qservices & (1 << QCRYPTODEV_BACKEND_SERVICE_TYPE_MAC)) {
        vservices |= (1 << VIRTIO_CRYPTO_SERVICE_MAC);
    }
    if (qservices & (1 << QCRYPTODEV_BACKEND_SERVICE_TYPE_AEAD)) {
        vservices |= (1 << VIRTIO_CRYPTO_SERVICE_AEAD);
    }
    if (qservices & (1 << QCRYPTODEV_BACKEND_SERVICE_TYPE_AKCIPHER)) {
        vservices |= (1 << VIRTIO_CRYPTO_SERVICE_AKCIPHER);
    }

    return vservices;
}

static void virtio_crypto_init_config(VirtIODevice *vdev)
{
    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);

    vcrypto->conf.crypto_services = virtio_crypto_init_services(
                     vcrypto->conf.cryptodev->conf.crypto_services);
    vcrypto->conf.cipher_algo_l =
                     vcrypto->conf.cryptodev->conf.cipher_algo_l;
    vcrypto->conf.cipher_algo_h =
                     vcrypto->conf.cryptodev->conf.cipher_algo_h;
    vcrypto->conf.hash_algo = vcrypto->conf.cryptodev->conf.hash_algo;
    vcrypto->conf.mac_algo_l = vcrypto->conf.cryptodev->conf.mac_algo_l;
    vcrypto->conf.mac_algo_h = vcrypto->conf.cryptodev->conf.mac_algo_h;
    vcrypto->conf.aead_algo = vcrypto->conf.cryptodev->conf.aead_algo;
    vcrypto->conf.akcipher_algo = vcrypto->conf.cryptodev->conf.akcipher_algo;
    vcrypto->conf.max_cipher_key_len =
                  vcrypto->conf.cryptodev->conf.max_cipher_key_len;
    vcrypto->conf.max_auth_key_len =
                  vcrypto->conf.cryptodev->conf.max_auth_key_len;
    vcrypto->conf.max_size = vcrypto->conf.cryptodev->conf.max_size;
}

static void virtio_crypto_device_realize(DeviceState *dev, Error **errp)
{
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(dev);
    int i;

    vcrypto->cryptodev = vcrypto->conf.cryptodev;
    if (vcrypto->cryptodev == NULL) {
        error_setg(errp, "'cryptodev' parameter expects a valid object");
        return;
    } else if (cryptodev_backend_is_used(vcrypto->cryptodev)) {
        error_setg(errp, "can't use already used cryptodev backend: %s",
                   object_get_canonical_path_component(OBJECT(vcrypto->conf.cryptodev)));
        return;
    }

    vcrypto->max_queues = MAX(vcrypto->cryptodev->conf.peers.queues, 1);
    if (vcrypto->max_queues + 1 > VIRTIO_QUEUE_MAX) {
        error_setg(errp, "Invalid number of queues (= %" PRIu32 "), "
                   "must be a positive integer less than %d.",
                   vcrypto->max_queues, VIRTIO_QUEUE_MAX);
        return;
    }

    virtio_init(vdev, VIRTIO_ID_CRYPTO, vcrypto->config_size);
    vcrypto->curr_queues = 1;
    vcrypto->vqs = g_new0(VirtIOCryptoQueue, vcrypto->max_queues);
    for (i = 0; i < vcrypto->max_queues; i++) {
        vcrypto->vqs[i].dataq =
                 virtio_add_queue(vdev, 1024, virtio_crypto_handle_dataq_bh);
        vcrypto->vqs[i].dataq_bh =
                 virtio_bh_new_guarded(dev, virtio_crypto_dataq_bh,
                                       &vcrypto->vqs[i]);
        vcrypto->vqs[i].vcrypto = vcrypto;
    }

    vcrypto->ctrl_vq = virtio_add_queue(vdev, 1024, virtio_crypto_handle_ctrl);
    if (!cryptodev_backend_is_ready(vcrypto->cryptodev)) {
        vcrypto->status &= ~VIRTIO_CRYPTO_S_HW_READY;
    } else {
        vcrypto->status |= VIRTIO_CRYPTO_S_HW_READY;
    }

    virtio_crypto_init_config(vdev);
    cryptodev_backend_set_used(vcrypto->cryptodev, true);
}

static void virtio_crypto_device_unrealize(DeviceState *dev)
{
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(dev);
    VirtIOCryptoQueue *q;
    int i, max_queues;

    max_queues = vcrypto->multiqueue ? vcrypto->max_queues : 1;
    for (i = 0; i < max_queues; i++) {
        virtio_delete_queue(vcrypto->vqs[i].dataq);
        q = &vcrypto->vqs[i];
        qemu_bh_delete(q->dataq_bh);
    }

    g_free(vcrypto->vqs);
    virtio_delete_queue(vcrypto->ctrl_vq);

    virtio_cleanup(vdev);
    cryptodev_backend_set_used(vcrypto->cryptodev, false);
}

static const VMStateDescription vmstate_virtio_crypto = {
    .name = "virtio-crypto",
    .unmigratable = 1,
    .minimum_version_id = VIRTIO_CRYPTO_VM_VERSION,
    .version_id = VIRTIO_CRYPTO_VM_VERSION,
    .fields = (const VMStateField[]) {
        VMSTATE_VIRTIO_DEVICE,
        VMSTATE_END_OF_LIST()
    },
};

static Property virtio_crypto_properties[] = {
    DEFINE_PROP_LINK("cryptodev", VirtIOCrypto, conf.cryptodev,
                     TYPE_CRYPTODEV_BACKEND, CryptoDevBackend *),
    DEFINE_PROP_END_OF_LIST(),
};

static void virtio_crypto_get_config(VirtIODevice *vdev, uint8_t *config)
{
    VirtIOCrypto *c = VIRTIO_CRYPTO(vdev);
    struct virtio_crypto_config crypto_cfg = {};

    /*
     * Virtio-crypto device conforms to VIRTIO 1.0 which is always LE,
     * so we can use LE accessors directly.
     */
    stl_le_p(&crypto_cfg.status, c->status);
    stl_le_p(&crypto_cfg.max_dataqueues, c->max_queues);
    stl_le_p(&crypto_cfg.crypto_services, c->conf.crypto_services);
    stl_le_p(&crypto_cfg.cipher_algo_l, c->conf.cipher_algo_l);
    stl_le_p(&crypto_cfg.cipher_algo_h, c->conf.cipher_algo_h);
    stl_le_p(&crypto_cfg.hash_algo, c->conf.hash_algo);
    stl_le_p(&crypto_cfg.mac_algo_l, c->conf.mac_algo_l);
    stl_le_p(&crypto_cfg.mac_algo_h, c->conf.mac_algo_h);
    stl_le_p(&crypto_cfg.aead_algo, c->conf.aead_algo);
    stl_le_p(&crypto_cfg.max_cipher_key_len, c->conf.max_cipher_key_len);
    stl_le_p(&crypto_cfg.max_auth_key_len, c->conf.max_auth_key_len);
    stq_le_p(&crypto_cfg.max_size, c->conf.max_size);
    stl_le_p(&crypto_cfg.akcipher_algo, c->conf.akcipher_algo);

    memcpy(config, &crypto_cfg, c->config_size);
}

static bool virtio_crypto_started(VirtIOCrypto *c, uint8_t status)
{
    VirtIODevice *vdev = VIRTIO_DEVICE(c);
    return (status & VIRTIO_CONFIG_S_DRIVER_OK) &&
        (c->status & VIRTIO_CRYPTO_S_HW_READY) && vdev->vm_running;
}

static void virtio_crypto_vhost_status(VirtIOCrypto *c, uint8_t status)
{
    VirtIODevice *vdev = VIRTIO_DEVICE(c);
    int queues = c->multiqueue ? c->max_queues : 1;
    CryptoDevBackend *b = c->cryptodev;
    CryptoDevBackendClient *cc = b->conf.peers.ccs[0];

    if (!cryptodev_get_vhost(cc, b, 0)) {
        return;
    }

    if ((virtio_crypto_started(c, status)) == !!c->vhost_started) {
        return;
    }

    if (!c->vhost_started) {
        int r;

        c->vhost_started = 1;
        r = cryptodev_vhost_start(vdev, queues);
        if (r < 0) {
            error_report("unable to start vhost crypto: %d: "
                         "falling back on userspace virtio", -r);
            c->vhost_started = 0;
        }
    } else {
        cryptodev_vhost_stop(vdev, queues);
        c->vhost_started = 0;
    }
}

static void virtio_crypto_set_status(VirtIODevice *vdev, uint8_t status)
{
    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);

    virtio_crypto_vhost_status(vcrypto, status);
}

static void virtio_crypto_guest_notifier_mask(VirtIODevice *vdev, int idx,
                                           bool mask)
{
    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);
    int queue = virtio_crypto_vq2q(idx);

    assert(vcrypto->vhost_started);

    /*
     * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
     * as the macro of configure interrupt's IDX, If this driver does not
     * support, the function will return
     */

    if (idx == VIRTIO_CONFIG_IRQ_IDX) {
        return;
    }
    cryptodev_vhost_virtqueue_mask(vdev, queue, idx, mask);
}

static bool virtio_crypto_guest_notifier_pending(VirtIODevice *vdev, int idx)
{
    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);
    int queue = virtio_crypto_vq2q(idx);

    assert(vcrypto->vhost_started);

    /*
     * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
     * as the macro of configure interrupt's IDX, If this driver does not
     * support, the function will return
     */

    if (idx == VIRTIO_CONFIG_IRQ_IDX) {
        return false;
    }
    return cryptodev_vhost_virtqueue_pending(vdev, queue, idx);
}

static struct vhost_dev *virtio_crypto_get_vhost(VirtIODevice *vdev)
{
    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);
    CryptoDevBackend *b;
    CryptoDevBackendClient *cc;
    CryptoDevBackendVhost *vhost_crypto;

    b = vcrypto->cryptodev;
    if (!b) {
        return NULL;
    }

    cc = b->conf.peers.ccs[0];
    vhost_crypto = cryptodev_get_vhost(cc, b, 0);
    if (!vhost_crypto) {
        return NULL;
    }

    return &vhost_crypto->dev;
}

static void virtio_crypto_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);

    device_class_set_props(dc, virtio_crypto_properties);
    dc->vmsd = &vmstate_virtio_crypto;
    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
    vdc->realize = virtio_crypto_device_realize;
    vdc->unrealize = virtio_crypto_device_unrealize;
    vdc->get_config = virtio_crypto_get_config;
    vdc->get_features = virtio_crypto_get_features;
    vdc->reset = virtio_crypto_reset;
    vdc->set_status = virtio_crypto_set_status;
    vdc->guest_notifier_mask = virtio_crypto_guest_notifier_mask;
    vdc->guest_notifier_pending = virtio_crypto_guest_notifier_pending;
    vdc->get_vhost = virtio_crypto_get_vhost;
}

static void virtio_crypto_instance_init(Object *obj)
{
    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(obj);

    /*
     * The default config_size is sizeof(struct virtio_crypto_config).
     * Can be overridden with virtio_crypto_set_config_size.
     */
    vcrypto->config_size = sizeof(struct virtio_crypto_config);
}

static const TypeInfo virtio_crypto_info = {
    .name = TYPE_VIRTIO_CRYPTO,
    .parent = TYPE_VIRTIO_DEVICE,
    .instance_size = sizeof(VirtIOCrypto),
    .instance_init = virtio_crypto_instance_init,
    .class_init = virtio_crypto_class_init,
};

static void virtio_register_types(void)
{
    type_register_static(&virtio_crypto_info);
}

type_init(virtio_register_types)
