[PATCH] cryptodev-vhost-user: add asymmetric crypto support

Gowrishankar Muthukrishnan posted 1 patch 11 months, 3 weeks ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20230514065519.2335265-1-gmuthukrishn@marvell.com
Maintainers: "Gonglei (Arei)" <arei.gonglei@huawei.com>, Zhenwei Pi <pizhenwei@bytedance.com>, "Michael S. Tsirkin" <mst@redhat.com>
There is a newer version of this series
backends/cryptodev-vhost-user.c |  9 +++---
hw/virtio/vhost-user.c          | 52 ++++++++++++++++++++++++---------
2 files changed, 43 insertions(+), 18 deletions(-)
[PATCH] cryptodev-vhost-user: add asymmetric crypto support
Posted by Gowrishankar Muthukrishnan 11 months, 3 weeks ago
Add asymmetric crypto support in vhost_user backend.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 backends/cryptodev-vhost-user.c |  9 +++---
 hw/virtio/vhost-user.c          | 52 ++++++++++++++++++++++++---------
 2 files changed, 43 insertions(+), 18 deletions(-)

diff --git a/backends/cryptodev-vhost-user.c b/backends/cryptodev-vhost-user.c
index b1d9eb735f..c3283ba84a 100644
--- a/backends/cryptodev-vhost-user.c
+++ b/backends/cryptodev-vhost-user.c
@@ -232,9 +232,9 @@ static void cryptodev_vhost_user_init(
     backend->conf.max_auth_key_len = VHOST_USER_MAX_AUTH_KEY_LEN;
 }
 
-static int64_t cryptodev_vhost_user_sym_create_session(
+static int64_t cryptodev_vhost_user_crypto_create_session(
            CryptoDevBackend *backend,
-           CryptoDevBackendSymSessionInfo *sess_info,
+           CryptoDevBackendSessionInfo *sess_info,
            uint32_t queue_index, Error **errp)
 {
     CryptoDevBackendClient *cc =
@@ -266,18 +266,17 @@ static int cryptodev_vhost_user_create_session(
            void *opaque)
 {
     uint32_t op_code = sess_info->op_code;
-    CryptoDevBackendSymSessionInfo *sym_sess_info;
     int64_t ret;
     Error *local_error = NULL;
     int status;
 
     switch (op_code) {
     case VIRTIO_CRYPTO_CIPHER_CREATE_SESSION:
+    case VIRTIO_CRYPTO_AKCIPHER_CREATE_SESSION:
     case VIRTIO_CRYPTO_HASH_CREATE_SESSION:
     case VIRTIO_CRYPTO_MAC_CREATE_SESSION:
     case VIRTIO_CRYPTO_AEAD_CREATE_SESSION:
-        sym_sess_info = &sess_info->u.sym_sess_info;
-        ret = cryptodev_vhost_user_sym_create_session(backend, sym_sess_info,
+        ret = cryptodev_vhost_user_crypto_create_session(backend, sess_info,
                    queue_index, &local_error);
         break;
 
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index e5285df4ba..c3f5ecd112 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -11,6 +11,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "hw/virtio/vhost.h"
+#include "hw/virtio/virtio-crypto.h"
 #include "hw/virtio/vhost-user.h"
 #include "hw/virtio/vhost-backend.h"
 #include "hw/virtio/virtio.h"
@@ -173,13 +174,24 @@ typedef struct VhostUserConfig {
 
 #define VHOST_CRYPTO_SYM_HMAC_MAX_KEY_LEN    512
 #define VHOST_CRYPTO_SYM_CIPHER_MAX_KEY_LEN  64
+#define VHOST_CRYPTO_ASYM_MAX_KEY_LEN  1024
 
 typedef struct VhostUserCryptoSession {
+    uint64_t op_code;
+    union {
+        struct {
+            CryptoDevBackendSymSessionInfo session_setup_data;
+            uint8_t key[VHOST_CRYPTO_SYM_CIPHER_MAX_KEY_LEN];
+            uint8_t auth_key[VHOST_CRYPTO_SYM_HMAC_MAX_KEY_LEN];
+        } sym;
+        struct {
+            CryptoDevBackendAsymSessionInfo session_setup_data;
+            uint8_t key[VHOST_CRYPTO_ASYM_MAX_KEY_LEN];
+        } asym;
+    } u;
+
     /* session id for success, -1 on errors */
     int64_t session_id;
-    CryptoDevBackendSymSessionInfo session_setup_data;
-    uint8_t key[VHOST_CRYPTO_SYM_CIPHER_MAX_KEY_LEN];
-    uint8_t auth_key[VHOST_CRYPTO_SYM_HMAC_MAX_KEY_LEN];
 } VhostUserCryptoSession;
 
 static VhostUserConfig c __attribute__ ((unused));
@@ -2366,7 +2378,7 @@ static int vhost_user_crypto_create_session(struct vhost_dev *dev,
     int ret;
     bool crypto_session = virtio_has_feature(dev->protocol_features,
                                        VHOST_USER_PROTOCOL_F_CRYPTO_SESSION);
-    CryptoDevBackendSymSessionInfo *sess_info = session_info;
+    CryptoDevBackendSessionInfo *backend_info = session_info;
     VhostUserMsg msg = {
         .hdr.request = VHOST_USER_CREATE_CRYPTO_SESSION,
         .hdr.flags = VHOST_USER_VERSION,
@@ -2380,16 +2392,30 @@ static int vhost_user_crypto_create_session(struct vhost_dev *dev,
         return -ENOTSUP;
     }
 
-    memcpy(&msg.payload.session.session_setup_data, sess_info,
-              sizeof(CryptoDevBackendSymSessionInfo));
-    if (sess_info->key_len) {
-        memcpy(&msg.payload.session.key, sess_info->cipher_key,
-               sess_info->key_len);
-    }
-    if (sess_info->auth_key_len > 0) {
-        memcpy(&msg.payload.session.auth_key, sess_info->auth_key,
-               sess_info->auth_key_len);
+    if (backend_info->op_code == VIRTIO_CRYPTO_AKCIPHER_CREATE_SESSION) {
+        CryptoDevBackendAsymSessionInfo *sess_info = &backend_info->u.asym_sess_info;
+        memcpy(&msg.payload.session.u.asym.session_setup_data, sess_info,
+               sizeof(CryptoDevBackendAsymSessionInfo));
+        if (sess_info->keylen) {
+            memcpy(&msg.payload.session.u.asym.key, sess_info->key,
+                   sess_info->keylen);
+        }
+    } else {
+        CryptoDevBackendSymSessionInfo *sess_info = &backend_info->u.sym_sess_info;
+        memcpy(&msg.payload.session.u.sym.session_setup_data, sess_info,
+               sizeof(CryptoDevBackendSymSessionInfo));
+        if (sess_info->key_len) {
+            memcpy(&msg.payload.session.u.sym.key, sess_info->cipher_key,
+                   sess_info->key_len);
+        }
+        if (sess_info->auth_key_len > 0) {
+            memcpy(&msg.payload.session.u.sym.auth_key, sess_info->auth_key,
+                   sess_info->auth_key_len);
+        }
     }
+
+    msg.payload.session.op_code = backend_info->op_code;
+    msg.payload.session.session_id = backend_info->session_id;
     ret = vhost_user_write(dev, &msg, NULL, 0);
     if (ret < 0) {
         error_report("vhost_user_write() return %d, create session failed",
-- 
2.25.1
Re: [PATCH] cryptodev-vhost-user: add asymmetric crypto support
Posted by zhenwei pi 11 months, 3 weeks ago

On 5/14/23 14:55, Gowrishankar Muthukrishnan wrote:
> Add asymmetric crypto support in vhost_user backend.
> 
> Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
> ---
>   backends/cryptodev-vhost-user.c |  9 +++---
>   hw/virtio/vhost-user.c          | 52 ++++++++++++++++++++++++---------
>   2 files changed, 43 insertions(+), 18 deletions(-)
> 
> diff --git a/backends/cryptodev-vhost-user.c b/backends/cryptodev-vhost-user.c
> index b1d9eb735f..c3283ba84a 100644
> --- a/backends/cryptodev-vhost-user.c
> +++ b/backends/cryptodev-vhost-user.c
> @@ -232,9 +232,9 @@ static void cryptodev_vhost_user_init(
>       backend->conf.max_auth_key_len = VHOST_USER_MAX_AUTH_KEY_LEN;
>   }
>   
> -static int64_t cryptodev_vhost_user_sym_create_session(
> +static int64_t cryptodev_vhost_user_crypto_create_session(
>              CryptoDevBackend *backend,
> -           CryptoDevBackendSymSessionInfo *sess_info,
> +           CryptoDevBackendSessionInfo *sess_info,
>              uint32_t queue_index, Error **errp)
>   {
>       CryptoDevBackendClient *cc =
> @@ -266,18 +266,17 @@ static int cryptodev_vhost_user_create_session(
>              void *opaque)
>   {
>       uint32_t op_code = sess_info->op_code;
> -    CryptoDevBackendSymSessionInfo *sym_sess_info;
>       int64_t ret;
>       Error *local_error = NULL;
>       int status;
>   
>       switch (op_code) {
>       case VIRTIO_CRYPTO_CIPHER_CREATE_SESSION:
> +    case VIRTIO_CRYPTO_AKCIPHER_CREATE_SESSION:
>       case VIRTIO_CRYPTO_HASH_CREATE_SESSION:
>       case VIRTIO_CRYPTO_MAC_CREATE_SESSION:
>       case VIRTIO_CRYPTO_AEAD_CREATE_SESSION:
> -        sym_sess_info = &sess_info->u.sym_sess_info;
> -        ret = cryptodev_vhost_user_sym_create_session(backend, sym_sess_info,
> +        ret = cryptodev_vhost_user_crypto_create_session(backend, sess_info,
>                      queue_index, &local_error);
>           break;
>   
> diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
> index e5285df4ba..c3f5ecd112 100644
> --- a/hw/virtio/vhost-user.c
> +++ b/hw/virtio/vhost-user.c
> @@ -11,6 +11,7 @@
>   #include "qemu/osdep.h"
>   #include "qapi/error.h"
>   #include "hw/virtio/vhost.h"
> +#include "hw/virtio/virtio-crypto.h"
>   #include "hw/virtio/vhost-user.h"
>   #include "hw/virtio/vhost-backend.h"
>   #include "hw/virtio/virtio.h"
> @@ -173,13 +174,24 @@ typedef struct VhostUserConfig {
>   
>   #define VHOST_CRYPTO_SYM_HMAC_MAX_KEY_LEN    512
>   #define VHOST_CRYPTO_SYM_CIPHER_MAX_KEY_LEN  64
> +#define VHOST_CRYPTO_ASYM_MAX_KEY_LEN  1024
>   
>   typedef struct VhostUserCryptoSession {
> +    uint64_t op_code;
> +    union {
> +        struct {
> +            CryptoDevBackendSymSessionInfo session_setup_data;
> +            uint8_t key[VHOST_CRYPTO_SYM_CIPHER_MAX_KEY_LEN];
> +            uint8_t auth_key[VHOST_CRYPTO_SYM_HMAC_MAX_KEY_LEN];
> +        } sym;
> +        struct {
> +            CryptoDevBackendAsymSessionInfo session_setup_data;
> +            uint8_t key[VHOST_CRYPTO_ASYM_MAX_KEY_LEN];
> +        } asym;
> +    } u;
> +
>       /* session id for success, -1 on errors */
>       int64_t session_id;
> -    CryptoDevBackendSymSessionInfo session_setup_data;
> -    uint8_t key[VHOST_CRYPTO_SYM_CIPHER_MAX_KEY_LEN];
> -    uint8_t auth_key[VHOST_CRYPTO_SYM_HMAC_MAX_KEY_LEN];
>   } VhostUserCryptoSession;
>   
>   static VhostUserConfig c __attribute__ ((unused));
> @@ -2366,7 +2378,7 @@ static int vhost_user_crypto_create_session(struct vhost_dev *dev,
>       int ret;
>       bool crypto_session = virtio_has_feature(dev->protocol_features,
>                                          VHOST_USER_PROTOCOL_F_CRYPTO_SESSION);
> -    CryptoDevBackendSymSessionInfo *sess_info = session_info;
> +    CryptoDevBackendSessionInfo *backend_info = session_info;
>       VhostUserMsg msg = {
>           .hdr.request = VHOST_USER_CREATE_CRYPTO_SESSION,
>           .hdr.flags = VHOST_USER_VERSION,
> @@ -2380,16 +2392,30 @@ static int vhost_user_crypto_create_session(struct vhost_dev *dev,
>           return -ENOTSUP;
>       }
>   
> -    memcpy(&msg.payload.session.session_setup_data, sess_info,
> -              sizeof(CryptoDevBackendSymSessionInfo));
> -    if (sess_info->key_len) {
> -        memcpy(&msg.payload.session.key, sess_info->cipher_key,
> -               sess_info->key_len);
> -    }
> -    if (sess_info->auth_key_len > 0) {
> -        memcpy(&msg.payload.session.auth_key, sess_info->auth_key,
> -               sess_info->auth_key_len);
> +    if (backend_info->op_code == VIRTIO_CRYPTO_AKCIPHER_CREATE_SESSION) {
> +        CryptoDevBackendAsymSessionInfo *sess_info = &backend_info->u.asym_sess_info;
> +        memcpy(&msg.payload.session.u.asym.session_setup_data, sess_info,
> +               sizeof(CryptoDevBackendAsymSessionInfo));
> +        if (sess_info->keylen) {
> +            memcpy(&msg.payload.session.u.asym.key, sess_info->key,
> +                   sess_info->keylen);
> +        }

Hi,

Could you please test the length of msg.payload.session.u.asym.key and 
sess_info->keylen to avoid buffer overflow? and so does the following codes.

> +    } else {
> +        CryptoDevBackendSymSessionInfo *sess_info = &backend_info->u.sym_sess_info;
> +        memcpy(&msg.payload.session.u.sym.session_setup_data, sess_info,
> +               sizeof(CryptoDevBackendSymSessionInfo));
> +        if (sess_info->key_len) {
> +            memcpy(&msg.payload.session.u.sym.key, sess_info->cipher_key,
> +                   sess_info->key_len);
> +        }
> +        if (sess_info->auth_key_len > 0) {
> +            memcpy(&msg.payload.session.u.sym.auth_key, sess_info->auth_key,
> +                   sess_info->auth_key_len);
> +        }
>       }
> +
> +    msg.payload.session.op_code = backend_info->op_code;
> +    msg.payload.session.session_id = backend_info->session_id;
>       ret = vhost_user_write(dev, &msg, NULL, 0);
>       if (ret < 0) {
>           error_report("vhost_user_write() return %d, create session failed",

-- 
zhenwei pi
[PATCH v2] cryptodev-vhost-user: add asymmetric crypto support
Posted by Gowrishankar Muthukrishnan 11 months, 3 weeks ago
Add asymmetric crypto support in vhost_user backend.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
v2:
 - added buffer length check before memcpy.

---
 backends/cryptodev-vhost-user.c |  9 ++--
 hw/virtio/vhost-user.c          | 75 +++++++++++++++++++++++++++------
 2 files changed, 66 insertions(+), 18 deletions(-)

diff --git a/backends/cryptodev-vhost-user.c b/backends/cryptodev-vhost-user.c
index b1d9eb735f..c3283ba84a 100644
--- a/backends/cryptodev-vhost-user.c
+++ b/backends/cryptodev-vhost-user.c
@@ -232,9 +232,9 @@ static void cryptodev_vhost_user_init(
     backend->conf.max_auth_key_len = VHOST_USER_MAX_AUTH_KEY_LEN;
 }
 
-static int64_t cryptodev_vhost_user_sym_create_session(
+static int64_t cryptodev_vhost_user_crypto_create_session(
            CryptoDevBackend *backend,
-           CryptoDevBackendSymSessionInfo *sess_info,
+           CryptoDevBackendSessionInfo *sess_info,
            uint32_t queue_index, Error **errp)
 {
     CryptoDevBackendClient *cc =
@@ -266,18 +266,17 @@ static int cryptodev_vhost_user_create_session(
            void *opaque)
 {
     uint32_t op_code = sess_info->op_code;
-    CryptoDevBackendSymSessionInfo *sym_sess_info;
     int64_t ret;
     Error *local_error = NULL;
     int status;
 
     switch (op_code) {
     case VIRTIO_CRYPTO_CIPHER_CREATE_SESSION:
+    case VIRTIO_CRYPTO_AKCIPHER_CREATE_SESSION:
     case VIRTIO_CRYPTO_HASH_CREATE_SESSION:
     case VIRTIO_CRYPTO_MAC_CREATE_SESSION:
     case VIRTIO_CRYPTO_AEAD_CREATE_SESSION:
-        sym_sess_info = &sess_info->u.sym_sess_info;
-        ret = cryptodev_vhost_user_sym_create_session(backend, sym_sess_info,
+        ret = cryptodev_vhost_user_crypto_create_session(backend, sess_info,
                    queue_index, &local_error);
         break;
 
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index e5285df4ba..eaac1dc174 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -11,6 +11,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "hw/virtio/vhost.h"
+#include "hw/virtio/virtio-crypto.h"
 #include "hw/virtio/vhost-user.h"
 #include "hw/virtio/vhost-backend.h"
 #include "hw/virtio/virtio.h"
@@ -173,13 +174,24 @@ typedef struct VhostUserConfig {
 
 #define VHOST_CRYPTO_SYM_HMAC_MAX_KEY_LEN    512
 #define VHOST_CRYPTO_SYM_CIPHER_MAX_KEY_LEN  64
+#define VHOST_CRYPTO_ASYM_MAX_KEY_LEN  1024
 
 typedef struct VhostUserCryptoSession {
+    uint64_t op_code;
+    union {
+        struct {
+            CryptoDevBackendSymSessionInfo session_setup_data;
+            uint8_t key[VHOST_CRYPTO_SYM_CIPHER_MAX_KEY_LEN];
+            uint8_t auth_key[VHOST_CRYPTO_SYM_HMAC_MAX_KEY_LEN];
+        } sym;
+        struct {
+            CryptoDevBackendAsymSessionInfo session_setup_data;
+            uint8_t key[VHOST_CRYPTO_ASYM_MAX_KEY_LEN];
+        } asym;
+    } u;
+
     /* session id for success, -1 on errors */
     int64_t session_id;
-    CryptoDevBackendSymSessionInfo session_setup_data;
-    uint8_t key[VHOST_CRYPTO_SYM_CIPHER_MAX_KEY_LEN];
-    uint8_t auth_key[VHOST_CRYPTO_SYM_HMAC_MAX_KEY_LEN];
 } VhostUserCryptoSession;
 
 static VhostUserConfig c __attribute__ ((unused));
@@ -2366,7 +2378,7 @@ static int vhost_user_crypto_create_session(struct vhost_dev *dev,
     int ret;
     bool crypto_session = virtio_has_feature(dev->protocol_features,
                                        VHOST_USER_PROTOCOL_F_CRYPTO_SESSION);
-    CryptoDevBackendSymSessionInfo *sess_info = session_info;
+    CryptoDevBackendSessionInfo *backend_info = session_info;
     VhostUserMsg msg = {
         .hdr.request = VHOST_USER_CREATE_CRYPTO_SESSION,
         .hdr.flags = VHOST_USER_VERSION,
@@ -2380,16 +2392,53 @@ static int vhost_user_crypto_create_session(struct vhost_dev *dev,
         return -ENOTSUP;
     }
 
-    memcpy(&msg.payload.session.session_setup_data, sess_info,
-              sizeof(CryptoDevBackendSymSessionInfo));
-    if (sess_info->key_len) {
-        memcpy(&msg.payload.session.key, sess_info->cipher_key,
-               sess_info->key_len);
-    }
-    if (sess_info->auth_key_len > 0) {
-        memcpy(&msg.payload.session.auth_key, sess_info->auth_key,
-               sess_info->auth_key_len);
+    if (backend_info->op_code == VIRTIO_CRYPTO_AKCIPHER_CREATE_SESSION) {
+        CryptoDevBackendAsymSessionInfo *sess_info = &backend_info->u.asym_sess_info;
+        size_t keylen;
+
+        memcpy(&msg.payload.session.u.asym.session_setup_data, sess_info,
+               sizeof(CryptoDevBackendAsymSessionInfo));
+        if (sess_info->keylen) {
+            keylen = sizeof(msg.payload.session.u.asym.key);
+            if (sess_info->keylen > keylen) {
+                error_report("Unsupported asymmetric key size");
+                return -ENOTSUP;
+            }
+
+            memcpy(&msg.payload.session.u.asym.key, sess_info->key,
+                   sess_info->keylen);
+        }
+    } else {
+        CryptoDevBackendSymSessionInfo *sess_info = &backend_info->u.sym_sess_info;
+        size_t keylen;
+
+        memcpy(&msg.payload.session.u.sym.session_setup_data, sess_info,
+               sizeof(CryptoDevBackendSymSessionInfo));
+        if (sess_info->key_len) {
+            keylen = sizeof(msg.payload.session.u.sym.key);
+            if (sess_info->key_len > keylen) {
+                error_report("Unsupported cipher key size");
+                return -ENOTSUP;
+            }
+
+            memcpy(&msg.payload.session.u.sym.key, sess_info->cipher_key,
+                   sess_info->key_len);
+        }
+
+        if (sess_info->auth_key_len > 0) {
+            keylen = sizeof(msg.payload.session.u.sym.auth_key);
+            if (sess_info->auth_key_len > keylen) {
+                error_report("Unsupported auth key size");
+                return -ENOTSUP;
+            }
+
+            memcpy(&msg.payload.session.u.sym.auth_key, sess_info->auth_key,
+                   sess_info->auth_key_len);
+        }
     }
+
+    msg.payload.session.op_code = backend_info->op_code;
+    msg.payload.session.session_id = backend_info->session_id;
     ret = vhost_user_write(dev, &msg, NULL, 0);
     if (ret < 0) {
         error_report("vhost_user_write() return %d, create session failed",
-- 
2.25.1
Re: [PATCH v2] cryptodev-vhost-user: add asymmetric crypto support
Posted by Michael S. Tsirkin 11 months, 2 weeks ago
Pls do not v2 as reply to v1.
Start a new thread if you really want to reply to v1
with link to lore copy of v2.

-- 
MST
RE: [EXT] Re: [PATCH v2] cryptodev-vhost-user: add asymmetric crypto support
Posted by Gowrishankar Muthukrishnan 11 months, 1 week ago
> Pls do not v2 as reply to v1.
> Start a new thread if you really want to reply to v1 with link to lore copy of v2.
> 

Apologies that I am new to this forum and 'll follow this in future patches as well.
Please let me know any changes needed in v2.

Regards,
Gowrishankar