[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v1 11/14] virtio-crypto: add control queue handler
From: |
Gonglei |
Subject: |
[Qemu-devel] [PATCH v1 11/14] virtio-crypto: add control queue handler |
Date: |
Thu, 8 Sep 2016 11:42:33 +0800 |
Realize the Symmetric algos session creation handler,
including plain cipher and chainning algorithms.
Signed-off-by: Gonglei <address@hidden>
---
hw/virtio/virtio-crypto.c | 172 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 172 insertions(+)
diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index b7a7b41..b3ad974 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -26,8 +26,180 @@ static void virtio_crypto_process(VirtIOCrypto *vcrypto)
{
}
+static inline int virtio_crypto_vq2q(int queue_index)
+{
+ return queue_index;
+}
+
+static void
+virtio_crypto_cipher_session_helper(VirtIODevice *vdev,
+ CryptoSymSessionInfo *info,
+ struct virtio_crypto_cipher_session_para *cipher_para,
+ struct virtio_crypto_cipher_session_output *cipher_out)
+{
+ hwaddr key_gpa;
+ void *key_hva;
+ hwaddr len;
+
+ info->cipher_alg = virtio_ldl_p(vdev, &cipher_para->algo);
+ info->key_len = virtio_ldl_p(vdev, &cipher_para->keylen);
+ info->direction = virtio_ldl_p(vdev, &cipher_para->op);
+ len = info->key_len;
+ /* get cipher key */
+ if (len > 0) {
+ DPRINTF("keylen=%" PRIu32 "\n", info->key_len);
+ key_gpa = virtio_ldq_p(vdev, &cipher_out->key_addr);
+
+ key_hva = cpu_physical_memory_map(key_gpa, &len, 0);
+
+ info->cipher_key = g_malloc(info->key_len);
+ memcpy(info->cipher_key, key_hva, info->key_len);
+ cpu_physical_memory_unmap(key_hva, len, 0, len);
+ }
+}
+
+static int64_t
+virtio_crypto_create_sym_session(VirtIOCrypto *vcrypto,
+ struct virtio_crypto_sym_create_session_req *sess_req,
+ uint32_t queue_id,
+ uint64_t *session_id)
+{
+ VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
+ CryptoSymSessionInfo info;
+ int ret;
+ CryptoClientState *cc;
+ int queue_index;;
+ uint32_t op_type;
+ hwaddr auth_key_gpa;
+ void *auth_key_hva;
+ struct virtio_crypto_session_input *input;
+ hwaddr len;
+
+ op_type = virtio_ldl_p(vdev, &sess_req->op_type);
+ info.op_type = op_type;
+
+ if (op_type == VIRTIO_CRYPTO_SYM_OP_CIPHER) {
+ virtio_crypto_cipher_session_helper(vdev, &info,
+ &sess_req->u.cipher.para,
+ &sess_req->u.cipher.out);
+ input = &sess_req->u.cipher.input;
+ } else if (op_type == VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) {
+ /* cipher part */
+ virtio_crypto_cipher_session_helper(vdev, &info,
+ &sess_req->u.chain.para.cipher_param,
+ &sess_req->u.chain.out.cipher);
+ input = &sess_req->u.chain.input;
+ /* hash part */
+ info.alg_chain_order = virtio_ldl_p(vdev,
+ &sess_req->u.chain.para.alg_chain_order);
+ info.add_len = virtio_ldl_p(vdev,
+ &sess_req->u.chain.para.aad_len);
+ info.hash_mode = virtio_ldl_p(vdev, &sess_req->u.chain.para.hash_mode);
+ if (info.hash_mode == VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH) {
+ info.hash_alg = virtio_ldl_p(vdev,
+ &sess_req->u.chain.para.u.mac_param.algo);
+ len = info.auth_key_len = virtio_ldl_p(vdev,
+
&sess_req->u.chain.para.u.mac_param.auth_key_len);
+ info.hash_result_len = virtio_ldl_p(vdev,
+ &sess_req->u.chain.para.u.mac_param.hash_result_len);
+ /* get auth key */
+ if (len > 0) {
+ DPRINTF("keylen=%" PRIu32 "\n", info.auth_key_len);
+ auth_key_gpa = virtio_ldq_p(vdev,
+ &sess_req->u.chain.out.mac.auth_key_addr);
+ auth_key_hva = cpu_physical_memory_map(auth_key_gpa,
+ &len, false);
+ info.auth_key = g_malloc(len);
+ memcpy(info.auth_key, auth_key_hva, len);
+ cpu_physical_memory_unmap(auth_key_hva, len, false, len);
+ }
+ } else if (info.hash_mode == VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN) {
+ info.hash_alg = virtio_ldl_p(vdev,
+ &sess_req->u.chain.para.u.hash_param.algo);
+ info.hash_result_len = virtio_ldl_p(vdev,
+ &sess_req->u.chain.para.u.hash_param.hash_result_len);
+ } else {
+ /* VIRTIO_CRYPTO_SYM_HASH_MODE_NESTED */
+ error_report("unsupported hash mode");
+ goto err;
+ }
+ } else {
+ /* VIRTIO_CRYPTO_SYM_OP_NONE */
+ error_report("unsupported cipher type");
+ goto err;
+ }
+
+ queue_index = virtio_crypto_vq2q(queue_id);
+ cc = qemu_get_crypto_subqueue(vcrypto->crypto, queue_index);
+ ret = qemu_crypto_create_session(cc, &info, session_id);
+ if (ret == 0) {
+ DPRINTF("create session_id=%" PRIu64 "\n", *session_id);
+ /* Set the result, notify the frontend driver soon */
+ virtio_stl_p(vdev, &input->status, VIRTIO_CRYPTO_OP_OK);
+ virtio_stq_p(vdev, &input->session_id, *session_id);
+ return 0;
+ }
+
+err:
+ virtio_stl_p(vdev, &input->status, VIRTIO_CRYPTO_OP_ERR);
+ return -1;
+}
+
static void virtio_crypto_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
{
+ VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);
+ struct virtio_crypto_op_ctrl_req ctrl;
+ VirtQueueElement *elem;
+ size_t s;
+ struct iovec *iov;
+ unsigned int iov_cnt;
+ uint32_t queue_id;
+ uint32_t opcode;
+ uint64_t session_id = 0;
+
+ for (;;) {
+ elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
+ if (!elem) {
+ break;
+ }
+ if (elem->in_num < 1 ||
+ iov_size(elem->in_sg, elem->in_num) < sizeof(ctrl)) {
+ error_report("virtio-crypto ctrl missing headers");
+ exit(1);
+ }
+
+ iov_cnt = elem->in_num;
+ iov = elem->in_sg;
+ s = iov_to_buf(iov, iov_cnt, 0, &ctrl, sizeof(ctrl));
+ assert(s == sizeof(ctrl));
+ opcode = virtio_ldl_p(vdev, &ctrl.header.opcode);
+ queue_id = virtio_ldl_p(vdev, &ctrl.header.queue_id);
+
+ switch (opcode) {
+ case VIRTIO_CRYPTO_CIPHER_CREATE_SESSION:
+ virtio_crypto_create_sym_session(vcrypto,
+ &ctrl.u.sym_create_session,
+ queue_id,
+ &session_id);
+
+ break;
+ case VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION:
+ case VIRTIO_CRYPTO_HASH_CREATE_SESSION:
+ case VIRTIO_CRYPTO_HASH_DESTROY_SESSION:
+ case VIRTIO_CRYPTO_MAC_CREATE_SESSION:
+ case VIRTIO_CRYPTO_MAC_DESTROY_SESSION:
+ case VIRTIO_CRYPTO_AEAD_CREATE_SESSION:
+ case VIRTIO_CRYPTO_AEAD_DESTROY_SESSION:
+ default:
+ error_report("virtio-crypto unsupported ctrl opcode: %u",
+ opcode);
+ exit(1);
+ }
+
+ virtqueue_push(vq, elem, sizeof(ctrl));
+ virtio_notify(vdev, vq);
+ g_free(elem);
+ }
}
static void virtio_crypto_handle_dataq_bh(VirtIODevice *vdev, VirtQueue *vq)
--
1.7.12.4
- [Qemu-devel] [PATCH v1 00/14] virtio-crypto: introduce framework and device emulation, Gonglei, 2016/09/07
- [Qemu-devel] [PATCH v1 06/14] crypto: add internal handle logic layer, Gonglei, 2016/09/07
- [Qemu-devel] [PATCH v1 01/14] crypto: introduce cryptodev backend and crypto legacy hardware, Gonglei, 2016/09/07
- [Qemu-devel] [PATCH v1 03/14] crypto: add cryptoLegacyHW stuff, Gonglei, 2016/09/07
- [Qemu-devel] [PATCH v1 12/14] virtio-crypto: add destroy session logic, Gonglei, 2016/09/07
- [Qemu-devel] [PATCH v1 05/14] crypto: add cryptodev-linux as a cryptodev backend, Gonglei, 2016/09/07
- [Qemu-devel] [PATCH v1 07/14] virtio-crypto: introduce virtio-crypto.h, Gonglei, 2016/09/07
- [Qemu-devel] [PATCH v1 14/14] virtio-crypto: add data virtqueue processing handler, Gonglei, 2016/09/07
- [Qemu-devel] [PATCH v1 13/14] virtio-crypto: get correct input data address for each request, Gonglei, 2016/09/07
- [Qemu-devel] [PATCH v1 10/14] virtio-crypto: set capacity of crypto legacy hardware, Gonglei, 2016/09/07
- [Qemu-devel] [PATCH v1 11/14] virtio-crypto: add control queue handler,
Gonglei <=
- [Qemu-devel] [PATCH v1 09/14] virtio-crypto: add virtio crypto realization modle, Gonglei, 2016/09/07
- [Qemu-devel] [PATCH v1 08/14] virtio-crypto-pci: add virtio crypto pci support, Gonglei, 2016/09/07
- [Qemu-devel] [PATCH v1 02/14] crypto: introduce crypto queue handler, Gonglei, 2016/09/07
- [Qemu-devel] [PATCH v1 04/14] crypto: add symetric algorithms support, Gonglei, 2016/09/07
- Re: [Qemu-devel] [PATCH v1 00/14] virtio-crypto: introduce framework and device emulation, no-reply, 2016/09/08