diff options
Diffstat (limited to 'hw/virtio/virtio-crypto.c')
-rw-r--r-- | hw/virtio/virtio-crypto.c | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c index 2f2467e..296472f 100644 --- a/hw/virtio/virtio-crypto.c +++ b/hw/virtio/virtio-crypto.c @@ -337,7 +337,18 @@ static void virtio_crypto_free_request(VirtIOCryptoReq *req) { if (req) { if (req->flags == CRYPTODEV_BACKEND_ALG_SYM) { - g_free(req->u.sym_op_info); + size_t max_len; + CryptoDevBackendSymOpInfo *op_info = req->u.sym_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); } g_free(req); } @@ -355,7 +366,7 @@ virtio_crypto_sym_input_data_helper(VirtIODevice *vdev, return; } - len = sym_op_info->dst_len; + len = sym_op_info->src_len; /* Save the cipher result */ s = iov_from_buf(req->in_iov, req->in_num, 0, sym_op_info->dst, len); if (s != len) { @@ -416,7 +427,7 @@ virtio_crypto_sym_op_helper(VirtIODevice *vdev, uint32_t hash_start_src_offset = 0, len_to_hash = 0; uint32_t cipher_start_src_offset = 0, len_to_cipher = 0; - size_t max_len, curr_size = 0; + uint64_t max_len, curr_size = 0; size_t s; /* Plain cipher */ @@ -441,7 +452,7 @@ virtio_crypto_sym_op_helper(VirtIODevice *vdev, return NULL; } - max_len = iv_len + aad_len + src_len + dst_len + hash_result_len; + 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; @@ -732,7 +743,7 @@ static void virtio_crypto_reset(VirtIODevice *vdev) VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev); /* multiqueue is disabled by default */ vcrypto->curr_queues = 1; - if (!vcrypto->cryptodev->ready) { + if (!cryptodev_backend_is_ready(vcrypto->cryptodev)) { vcrypto->status &= ~VIRTIO_CRYPTO_S_HW_READY; } else { vcrypto->status |= VIRTIO_CRYPTO_S_HW_READY; @@ -792,13 +803,14 @@ static void virtio_crypto_device_realize(DeviceState *dev, Error **errp) } vcrypto->ctrl_vq = virtio_add_queue(vdev, 64, virtio_crypto_handle_ctrl); - if (!vcrypto->cryptodev->ready) { + 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, Error **errp) @@ -818,6 +830,7 @@ static void virtio_crypto_device_unrealize(DeviceState *dev, Error **errp) g_free(vcrypto->vqs); virtio_cleanup(vdev); + cryptodev_backend_set_used(vcrypto->cryptodev, false); } static const VMStateDescription vmstate_virtio_crypto = { @@ -875,6 +888,20 @@ static void virtio_crypto_class_init(ObjectClass *klass, void *data) vdc->reset = virtio_crypto_reset; } +static void +virtio_crypto_check_cryptodev_is_used(Object *obj, const char *name, + Object *val, Error **errp) +{ + if (cryptodev_backend_is_used(CRYPTODEV_BACKEND(val))) { + char *path = object_get_canonical_path_component(val); + error_setg(errp, + "can't use already used cryptodev backend: %s", path); + g_free(path); + } else { + qdev_prop_allow_set_link_before_realize(obj, name, val, errp); + } +} + static void virtio_crypto_instance_init(Object *obj) { VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(obj); @@ -888,7 +915,7 @@ static void virtio_crypto_instance_init(Object *obj) object_property_add_link(obj, "cryptodev", TYPE_CRYPTODEV_BACKEND, (Object **)&vcrypto->conf.cryptodev, - qdev_prop_allow_set_link_before_realize, + virtio_crypto_check_cryptodev_is_used, OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL); } |