diff mbox

[v7,12/12] virtio-crypto: perfect algorithms chainning support

Message ID 1476342726-104488-13-git-send-email-arei.gonglei@huawei.com (mailing list archive)
State New, archived
Headers show

Commit Message

Gonglei (Arei) Oct. 13, 2016, 7:12 a.m. UTC
For one source buffer, we can do cipher and hash operations
partly in algorithms chainning mode. We updated the
corresponding part in virtio crypto specification firstly.

The cryptodev-builtin backend doesn't support algorithm
chainning, so let's add a check for it.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
---
 backends/cryptodev-builtin.c                   |  6 +++
 hw/virtio/virtio-crypto.c                      | 62 ++++++++++++++++----------
 include/standard-headers/linux/virtio_crypto.h | 11 ++++-
 include/sysemu/cryptodev.h                     | 13 +++++-
 4 files changed, 66 insertions(+), 26 deletions(-)

Comments

Stefan Hajnoczi Oct. 16, 2016, 1:30 p.m. UTC | #1
On Thu, Oct 13, 2016 at 03:12:06PM +0800, Gonglei wrote:
> diff --git a/include/standard-headers/linux/virtio_crypto.h b/include/standard-headers/linux/virtio_crypto.h
> index f2a059e..9ae02fb 100644
> --- a/include/standard-headers/linux/virtio_crypto.h
> +++ b/include/standard-headers/linux/virtio_crypto.h
> @@ -326,7 +326,15 @@ struct virtio_crypto_mac_data_req {
>  };
>  
>  struct virtio_crypto_alg_chain_data_para {
> -    struct virtio_crypto_cipher_para cipher;
> +    __virtio32 iv_len;
> +    /* Length of source data */
> +    __virtio32 src_data_len;
> +    /* Length of destination data */
> +    __virtio32 dst_data_len;
> +    /* Starting point for cipher processing in source data */
> +    __virtio32 cipher_start_src_offset;
> +    /* Length of the source data that the cipher will be computed on */
> +    __virtio32 len_to_cipher;
>      /* Starting point for hash processing in source data */
>      __virtio32 hash_start_src_offset;
>      /* Length of the source data that the hash will be computed on */
> @@ -335,6 +343,7 @@ struct virtio_crypto_alg_chain_data_para {
>      __virtio32 aad_len;
>      /* Length of the hash result */
>      __virtio32 hash_result_len;
> +    __virtio32 reserved;
>  };
>  
>  struct virtio_crypto_alg_chain_data_req {

This is supposed to be an external header file from Linux.  QEMU patches
normally don't change the file except to import an updated version.

Please import the final version once in the patch series and don't
modify it.
Gonglei (Arei) Oct. 17, 2016, 6:33 a.m. UTC | #2
> -----Original Message-----
> From: Stefan Hajnoczi [mailto:stefanha@gmail.com]
> Sent: Sunday, October 16, 2016 9:30 PM
> Subject: Re: [Qemu-devel] [PATCH v7 12/12] virtio-crypto: perfect algorithms
> chainning support
> 
> On Thu, Oct 13, 2016 at 03:12:06PM +0800, Gonglei wrote:
> > diff --git a/include/standard-headers/linux/virtio_crypto.h
> b/include/standard-headers/linux/virtio_crypto.h
> > index f2a059e..9ae02fb 100644
> > --- a/include/standard-headers/linux/virtio_crypto.h
> > +++ b/include/standard-headers/linux/virtio_crypto.h
> > @@ -326,7 +326,15 @@ struct virtio_crypto_mac_data_req {
> >  };
> >
> >  struct virtio_crypto_alg_chain_data_para {
> > -    struct virtio_crypto_cipher_para cipher;
> > +    __virtio32 iv_len;
> > +    /* Length of source data */
> > +    __virtio32 src_data_len;
> > +    /* Length of destination data */
> > +    __virtio32 dst_data_len;
> > +    /* Starting point for cipher processing in source data */
> > +    __virtio32 cipher_start_src_offset;
> > +    /* Length of the source data that the cipher will be computed on */
> > +    __virtio32 len_to_cipher;
> >      /* Starting point for hash processing in source data */
> >      __virtio32 hash_start_src_offset;
> >      /* Length of the source data that the hash will be computed on */
> > @@ -335,6 +343,7 @@ struct virtio_crypto_alg_chain_data_para {
> >      __virtio32 aad_len;
> >      /* Length of the hash result */
> >      __virtio32 hash_result_len;
> > +    __virtio32 reserved;
> >  };
> >
> >  struct virtio_crypto_alg_chain_data_req {
> 
> This is supposed to be an external header file from Linux.  QEMU patches
> normally don't change the file except to import an updated version.
> 
> Please import the final version once in the patch series and don't
> modify it.

You are right. Will fix it. :)


Regards,
-Gonglei
diff mbox

Patch

diff --git a/backends/cryptodev-builtin.c b/backends/cryptodev-builtin.c
index dc0a364..9ad79ad 100644
--- a/backends/cryptodev-builtin.c
+++ b/backends/cryptodev-builtin.c
@@ -265,6 +265,12 @@  static int cryptodev_builtin_sym_operation(
         return -VIRTIO_CRYPTO_INVSESS;
     }
 
+    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;
+    }
+
     sess = builtin->sessions[op_info->session_id];
 
     ret = qcrypto_cipher_setiv(sess->cipher, op_info->iv,
diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index fc78a86..2455ebb 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -390,21 +390,42 @@  virtio_crypto_get_request(VirtIOCrypto *s, VirtQueue *vq)
 
 static CryptoDevBackendSymOpInfo *
 virtio_crypto_sym_op_helper(VirtIODevice *vdev,
-           struct virtio_crypto_cipher_para *para,
-           uint32_t aad_len,
-           struct iovec *iov, unsigned int out_num,
-           uint32_t hash_result_len,
-           uint32_t hash_start_src_offset)
+           struct virtio_crypto_cipher_para *cipher_para,
+           struct virtio_crypto_alg_chain_data_para *alg_chain_para,
+           struct iovec *iov, unsigned int out_num)
 {
     CryptoDevBackendSymOpInfo *op_info;
-    uint32_t src_len, dst_len;
-    uint32_t iv_len;
+    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;
+
     size_t max_len, curr_size = 0;
     size_t s;
 
-    iv_len = virtio_ldl_p(vdev, &para->iv_len);
-    src_len = virtio_ldl_p(vdev, &para->src_data_len);
-    dst_len = virtio_ldl_p(vdev, &para->dst_data_len);
+    /* Plain cipher */
+    if (cipher_para) {
+        iv_len = virtio_ldl_p(vdev, &cipher_para->iv_len);
+        src_len = virtio_ldl_p(vdev, &cipher_para->src_data_len);
+        dst_len = virtio_ldl_p(vdev, &cipher_para->dst_data_len);
+    } else if (alg_chain_para) { /* Algorithm chain */
+        iv_len = virtio_ldl_p(vdev, &alg_chain_para->iv_len);
+        src_len = virtio_ldl_p(vdev, &alg_chain_para->src_data_len);
+        dst_len = virtio_ldl_p(vdev, &alg_chain_para->dst_data_len);
+
+        aad_len = virtio_ldl_p(vdev, &alg_chain_para->aad_len);
+        hash_result_len = virtio_ldl_p(vdev,
+                              &alg_chain_para->hash_result_len);
+        hash_start_src_offset = virtio_ldl_p(vdev,
+                         &alg_chain_para->hash_start_src_offset);
+        cipher_start_src_offset = virtio_ldl_p(vdev,
+                         &alg_chain_para->cipher_start_src_offset);
+        len_to_cipher = virtio_ldl_p(vdev, &alg_chain_para->len_to_cipher);
+        len_to_hash = virtio_ldl_p(vdev, &alg_chain_para->len_to_hash);
+    } else {
+        return NULL;
+    }
 
     max_len = iv_len + aad_len + src_len + dst_len + hash_result_len;
     op_info = g_malloc0(sizeof(CryptoDevBackendSymOpInfo) + max_len);
@@ -414,6 +435,9 @@  virtio_crypto_sym_op_helper(VirtIODevice *vdev,
     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 initilization vector */
     if (op_info->iv_len > 0) {
         DPRINTF("iv_len=%" PRIu32 "\n", op_info->iv_len);
@@ -491,25 +515,15 @@  virtio_crypto_handle_sym_req(VirtIOCrypto *vcrypto,
 
     if (op_type == VIRTIO_CRYPTO_SYM_OP_CIPHER) {
         op_info = virtio_crypto_sym_op_helper(vdev, &req->u.cipher.para,
-                                              0, iov, out_num, 0, 0);
+                                              NULL, iov, out_num);
         if (!op_info) {
             return -EFAULT;
         }
         op_info->op_type = op_type;
     } else if (op_type == VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) {
-        uint32_t aad_len, hash_result_len;
-        uint32_t hash_start_src_offset;
-
-        aad_len = virtio_ldl_p(vdev, &req->u.chain.para.aad_len);
-        hash_result_len = virtio_ldl_p(vdev,
-                              &req->u.chain.para.hash_result_len);
-        hash_start_src_offset = virtio_ldl_p(vdev,
-                         &req->u.chain.para.hash_start_src_offset);
-        /* cipher part */
-        op_info = virtio_crypto_sym_op_helper(vdev, &req->u.chain.para.cipher,
-                                              aad_len, iov, out_num,
-                                              hash_result_len,
-                                              hash_start_src_offset);
+        op_info = virtio_crypto_sym_op_helper(vdev, NULL,
+                                              &req->u.chain.para,
+                                              iov, out_num);
         if (!op_info) {
             return -EFAULT;
         }
diff --git a/include/standard-headers/linux/virtio_crypto.h b/include/standard-headers/linux/virtio_crypto.h
index f2a059e..9ae02fb 100644
--- a/include/standard-headers/linux/virtio_crypto.h
+++ b/include/standard-headers/linux/virtio_crypto.h
@@ -326,7 +326,15 @@  struct virtio_crypto_mac_data_req {
 };
 
 struct virtio_crypto_alg_chain_data_para {
-    struct virtio_crypto_cipher_para cipher;
+    __virtio32 iv_len;
+    /* Length of source data */
+    __virtio32 src_data_len;
+    /* Length of destination data */
+    __virtio32 dst_data_len;
+    /* Starting point for cipher processing in source data */
+    __virtio32 cipher_start_src_offset;
+    /* Length of the source data that the cipher will be computed on */
+    __virtio32 len_to_cipher;
     /* Starting point for hash processing in source data */
     __virtio32 hash_start_src_offset;
     /* Length of the source data that the hash will be computed on */
@@ -335,6 +343,7 @@  struct virtio_crypto_alg_chain_data_para {
     __virtio32 aad_len;
     /* Length of the hash result */
     __virtio32 hash_result_len;
+    __virtio32 reserved;
 };
 
 struct virtio_crypto_alg_chain_data_req {
diff --git a/include/sysemu/cryptodev.h b/include/sysemu/cryptodev.h
index f55b79e..f9a4b36 100644
--- a/include/sysemu/cryptodev.h
+++ b/include/sysemu/cryptodev.h
@@ -108,7 +108,15 @@  typedef struct CryptoDevBackendSymSessionInfo {
  * @dst_len: byte length of destination data
  * @digest_result_len: byte length of hash digest result
  * @hash_start_src_offset: Starting point for hash processing, specified
- *                 as number of bytes from start of packet in source data
+ *  as number of bytes from start of packet in source data, only used for
+ *  algorithm chain
+ * @cipher_start_src_offset: Starting point for cipher processing, specified
+ *  as number of bytes from start of packet in source data, only used for
+ *  algorithm chain
+ * @len_to_hash: byte length of source data on which the hash
+ *  operation will be computed, only used for algorithm chain
+ * @len_to_cipher: byte length of source data on which the cipher
+ *  operation will be computed, only used for algorithm chain
  * @op_type: operation type (refer to virtio_crypto.h)
  * @iv: point to the initialization vector or counter
  * @src: point to the source data
@@ -126,6 +134,9 @@  typedef struct CryptoDevBackendSymOpInfo {
     uint32_t dst_len;
     uint32_t digest_result_len;
     uint32_t hash_start_src_offset;
+    uint32_t cipher_start_src_offset;
+    uint32_t len_to_hash;
+    uint32_t len_to_cipher;
     uint8_t op_type;
     uint8_t *iv;
     uint8_t *src;