From b063e843fa03c6af076ae9f5bce73e97211d8989 Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Tue, 26 Jun 2018 03:10:48 +0100 Subject: [PATCH] crypto/virtio: fix IV physical address The physical address of IV required by Virtio was computed using crypto operations' physical address plus the offset. However not all crypto ops will have physical address field initialized and compute it runtimely is costly. This patch fixes this problem by adding iv field in virtio_crypto_op_cookie and does a memcpy of iv instead. Fixes: 82adb12a1fce ("crypto/virtio: support burst enqueue/dequeue") Cc: stable@dpdk.org Signed-off-by: Fan Zhang Reviewed-by: Jay Zhou --- drivers/crypto/virtio/virtio_cryptodev.c | 6 ++++++ drivers/crypto/virtio/virtio_cryptodev.h | 3 +++ drivers/crypto/virtio/virtio_rxtx.c | 14 +++++++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/virtio/virtio_cryptodev.c b/drivers/crypto/virtio/virtio_cryptodev.c index df88953f6a..f9c890bb35 100644 --- a/drivers/crypto/virtio/virtio_cryptodev.c +++ b/drivers/crypto/virtio/virtio_cryptodev.c @@ -1223,6 +1223,12 @@ virtio_crypto_sym_pad_op_ctrl_req( /* Get cipher xform from crypto xform chain */ cipher_xform = virtio_crypto_get_cipher_xform(xform); if (cipher_xform) { + if (cipher_xform->iv.length > VIRTIO_CRYPTO_MAX_IV_SIZE) { + VIRTIO_CRYPTO_SESSION_LOG_ERR( + "cipher IV size cannot be longer than %u", + VIRTIO_CRYPTO_MAX_IV_SIZE); + return -1; + } if (is_chainned) ret = virtio_crypto_sym_pad_cipher_param( &ctrl->u.sym_create_session.u.chain.para diff --git a/drivers/crypto/virtio/virtio_cryptodev.h b/drivers/crypto/virtio/virtio_cryptodev.h index e402c0309a..0fd7b722ef 100644 --- a/drivers/crypto/virtio/virtio_cryptodev.h +++ b/drivers/crypto/virtio/virtio_cryptodev.h @@ -16,6 +16,8 @@ #define NUM_ENTRY_VIRTIO_CRYPTO_OP 7 +#define VIRTIO_CRYPTO_MAX_IV_SIZE 16 + extern uint8_t cryptodev_virtio_driver_id; enum virtio_crypto_cmd_id { @@ -29,6 +31,7 @@ struct virtio_crypto_op_cookie { struct virtio_crypto_op_data_req data_req; struct virtio_crypto_inhdr inhdr; struct vring_desc desc[NUM_ENTRY_VIRTIO_CRYPTO_OP]; + uint8_t iv[VIRTIO_CRYPTO_MAX_IV_SIZE]; }; /* diff --git a/drivers/crypto/virtio/virtio_rxtx.c b/drivers/crypto/virtio/virtio_rxtx.c index 4503928438..4f695f3e69 100644 --- a/drivers/crypto/virtio/virtio_rxtx.c +++ b/drivers/crypto/virtio/virtio_rxtx.c @@ -203,6 +203,8 @@ virtqueue_crypto_sym_enqueue_xmit( uint16_t req_data_len = sizeof(struct virtio_crypto_op_data_req); uint32_t indirect_vring_addr_offset = req_data_len + sizeof(struct virtio_crypto_inhdr); + uint32_t indirect_iv_addr_offset = indirect_vring_addr_offset + + sizeof(struct vring_desc) * NUM_ENTRY_VIRTIO_CRYPTO_OP; struct rte_crypto_sym_op *sym_op = cop->sym; struct virtio_crypto_session *session = (struct virtio_crypto_session *)get_session_private_data( @@ -259,7 +261,17 @@ virtqueue_crypto_sym_enqueue_xmit( /* indirect vring: iv of cipher */ if (session->iv.length) { - desc[idx].addr = cop->phys_addr + session->iv.offset; + if (cop->phys_addr) + desc[idx].addr = cop->phys_addr + session->iv.offset; + else { + rte_memcpy(crypto_op_cookie->iv, + rte_crypto_op_ctod_offset(cop, + uint8_t *, session->iv.offset), + session->iv.length); + desc[idx].addr = indirect_op_data_req_phys_addr + + indirect_iv_addr_offset; + } + desc[idx].len = session->iv.length; desc[idx++].flags = VRING_DESC_F_NEXT; } -- 2.20.1