From patchwork Thu Sep 8 03:42:33 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gonglei (Arei)" X-Patchwork-Id: 9320379 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id BCC256077F for ; Thu, 8 Sep 2016 03:55:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AA12629553 for ; Thu, 8 Sep 2016 03:55:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9EE0529558; Thu, 8 Sep 2016 03:55:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id DA9CC29555 for ; Thu, 8 Sep 2016 03:55:51 +0000 (UTC) Received: from localhost ([::1]:44805 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bhqRK-00060s-HG for patchwork-qemu-devel@patchwork.kernel.org; Wed, 07 Sep 2016 23:55:50 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56374) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bhqIv-0004vo-5B for qemu-devel@nongnu.org; Wed, 07 Sep 2016 23:47:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bhqIq-0006BJ-Vc for qemu-devel@nongnu.org; Wed, 07 Sep 2016 23:47:08 -0400 Received: from szxga02-in.huawei.com ([119.145.14.65]:19210) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bhqIq-0006Ao-7t for qemu-devel@nongnu.org; Wed, 07 Sep 2016 23:47:04 -0400 Received: from 172.24.1.136 (EHLO szxeml422-hub.china.huawei.com) ([172.24.1.136]) by szxrg02-dlp.huawei.com (MOS 4.3.7-GA FastPath queued) with ESMTP id DMU12973; Thu, 08 Sep 2016 11:43:09 +0800 (CST) Received: from localhost (10.177.18.62) by szxeml422-hub.china.huawei.com (10.82.67.152) with Microsoft SMTP Server id 14.3.235.1; Thu, 8 Sep 2016 11:43:01 +0800 From: Gonglei To: , Date: Thu, 8 Sep 2016 11:42:33 +0800 Message-ID: <1473306156-176628-12-git-send-email-arei.gonglei@huawei.com> X-Mailer: git-send-email 2.6.3.windows.1 In-Reply-To: <1473306156-176628-1-git-send-email-arei.gonglei@huawei.com> References: <1473306156-176628-1-git-send-email-arei.gonglei@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.177.18.62] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020206.57D0DE4E.0094, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2013-06-18 04:22:30, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: acafa0b7ee6a906796483f4e890fdbc3 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] X-Received-From: 119.145.14.65 Subject: [Qemu-devel] [PATCH v1 11/14] virtio-crypto: add control queue handler X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: weidong.huang@huawei.com, mst@redhat.com, john.griffin@intel.com, jianjay.zhou@huawei.com, Varun.Sethi@freescale.com, denglingli@chinamobile.com, hanweidong@huawei.com, agraf@suse.de, Gonglei , nmorey@kalray.eu, vincent.jardin@6wind.com, Ola.Liljedahl@arm.com, luonengjun@huawei.com, xin.zeng@intel.com, peter.huangpeng@huawei.com, liang.j.ma@intel.com, stefanha@redhat.com, cornelia.huck@de.ibm.com, Jani.Kokkonen@huawei.com, brian.a.keating@intel.com, claudio.fontana@huawei.com, mike.caraman@nxp.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Realize the Symmetric algos session creation handler, including plain cipher and chainning algorithms. Signed-off-by: Gonglei --- 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)