From patchwork Tue Sep 13 03:52:17 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gonglei (Arei)" X-Patchwork-Id: 669127 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 ozlabs.org (Postfix) with ESMTPS id 3sY9zP1K9jz9srZ for ; Tue, 13 Sep 2016 14:04:17 +1000 (AEST) Received: from localhost ([::1]:46355 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bjexC-00068q-OJ for incoming@patchwork.ozlabs.org; Tue, 13 Sep 2016 00:04:14 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38026) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bjepw-0000TH-1k for qemu-devel@nongnu.org; Mon, 12 Sep 2016 23:56:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bjept-00040V-MT for qemu-devel@nongnu.org; Mon, 12 Sep 2016 23:56:42 -0400 Received: from szxga03-in.huawei.com ([119.145.14.66]:56178) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bjeps-000402-PR for qemu-devel@nongnu.org; Mon, 12 Sep 2016 23:56:41 -0400 Received: from 172.24.1.137 (EHLO SZXEML424-HUB.china.huawei.com) ([172.24.1.137]) by szxrg03-dlp.huawei.com (MOS 4.4.3-GA FastPath queued) with ESMTP id CHR85143; Tue, 13 Sep 2016 11:53:02 +0800 (CST) Received: from localhost (10.177.18.62) by SZXEML424-HUB.china.huawei.com (10.82.67.153) with Microsoft SMTP Server id 14.3.235.1; Tue, 13 Sep 2016 11:52:54 +0800 From: Gonglei To: , Date: Tue, 13 Sep 2016 11:52:17 +0800 Message-ID: <1473738741-220600-12-git-send-email-arei.gonglei@huawei.com> X-Mailer: git-send-email 2.6.3.windows.1 In-Reply-To: <1473738741-220600-1-git-send-email-arei.gonglei@huawei.com> References: <1473738741-220600-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.0A020204.57D7781F.0040, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2013-05-26 15:14:31, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: fecf3bbff3bc457c1944aefcc35f750d X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] X-Received-From: 119.145.14.66 Subject: [Qemu-devel] [PATCH v2 11/15] 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: claudio.fontana@huawei.com, mst@redhat.com, xin.zeng@intel.com, luonengjun@huawei.com, peter.huangpeng@huawei.com, agraf@suse.de, nmorey@kalray.eu, mike.caraman@nxp.com, Gonglei , stefanha@redhat.com, pbonzini@redhat.com, vincent.jardin@6wind.com, weidong.huang@huawei.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Realize the Symmetric algos session creation handler, including plain cipher and chainning algorithms. Signed-off-by: Gonglei --- hw/virtio/virtio-crypto.c | 175 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 174 insertions(+), 1 deletion(-) diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c index b5a108f..1090946 100644 --- a/hw/virtio/virtio-crypto.c +++ b/hw/virtio/virtio-crypto.c @@ -26,8 +26,181 @@ 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 = cipher_para->algo; + info->key_len = cipher_para->keylen; + info->direction = cipher_para->op; + len = info->key_len; + /* get cipher key */ + if (len > 0) { + DPRINTF("keylen=%" PRIu32 "\n", info->key_len); + key_gpa = 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; + + memset(&info, 0, sizeof(info)); + op_type = 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 = sess_req->u.chain.para.alg_chain_order; + info.add_len = sess_req->u.chain.para.aad_len; + info.hash_mode = sess_req->u.chain.para.hash_mode; + if (info.hash_mode == VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH) { + info.hash_alg = sess_req->u.chain.para.u.mac_param.algo; + len = info.auth_key_len = + sess_req->u.chain.para.u.mac_param.auth_key_len; + info.hash_result_len = + 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 = 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 = sess_req->u.chain.para.u.hash_param.algo; + info.hash_result_len = + 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 */ + input->status = VIRTIO_CRYPTO_OP_OK; + input->session_id = *session_id; + + g_free(info.cipher_key); + g_free(info.auth_key); + return 0; + } + +err: + g_free(info.cipher_key); + g_free(info.auth_key); + 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 = ctrl.header.opcode; + queue_id = 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) @@ -213,7 +386,7 @@ static void virtio_crypto_get_config(VirtIODevice *vdev, uint8_t *config) crypto_cfg.aead_algo = c->legacy_conf.aead_algo; crypto_cfg.primitive_algo = c->legacy_conf.primitive_algo; - memcpy(config, &crypto_cfg, c->config_size; + memcpy(config, &crypto_cfg, c->config_size); } static void virtio_crypto_set_config(VirtIODevice *vdev, const uint8_t *config)