From patchwork Tue Sep 13 03:52:07 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gonglei (Arei)" X-Patchwork-Id: 9328337 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 B4A666048F for ; Tue, 13 Sep 2016 03:58:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A538028DEA for ; Tue, 13 Sep 2016 03:58:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9958B2908A; Tue, 13 Sep 2016 03:58:29 +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 A323F28DEA for ; Tue, 13 Sep 2016 03:58:28 +0000 (UTC) Received: from localhost ([::1]:46329 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bjerb-0001Mh-NV for patchwork-qemu-devel@patchwork.kernel.org; Mon, 12 Sep 2016 23:58:27 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37571) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bjemn-0006Pu-9k for qemu-devel@nongnu.org; Mon, 12 Sep 2016 23:53:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bjemj-00035p-Lx for qemu-devel@nongnu.org; Mon, 12 Sep 2016 23:53:29 -0400 Received: from szxga02-in.huawei.com ([119.145.14.65]:40309) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bjemi-00034R-GY for qemu-devel@nongnu.org; Mon, 12 Sep 2016 23:53:25 -0400 Received: from 172.24.1.47 (EHLO szxeml428-hub.china.huawei.com) ([172.24.1.47]) by szxrg02-dlp.huawei.com (MOS 4.3.7-GA FastPath queued) with ESMTP id DMZ70104; Tue, 13 Sep 2016 11:52:55 +0800 (CST) Received: from localhost (10.177.18.62) by szxeml428-hub.china.huawei.com (10.82.67.183) with Microsoft SMTP Server id 14.3.235.1; Tue, 13 Sep 2016 11:52:45 +0800 From: Gonglei To: , Date: Tue, 13 Sep 2016 11:52:07 +0800 Message-ID: <1473738741-220600-2-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.0A020203.57D77818.002A, 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: 7f94872123f83de535bb77357f5d8333 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 v2 01/15] crypto: introduce cryptodev backend and crypto legacy hardware 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+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP cryptodev backend is used to realize the active work for virtual crypto device. CryptoLegacyHW device is a cryptographic hardware device seen by the virtual machine. The relationship between cryptodev backend and legacy hadware as follow: crypto_legacy_hw device (1)--->(n) cryptodev client backend Signed-off-by: Gonglei --- crypto/Makefile.objs | 1 + crypto/crypto.c | 171 ++++++++++++++++++++++++++++++++++++++++++++++++ include/crypto/crypto.h | 66 +++++++++++++++++++ include/qemu/typedefs.h | 1 + include/sysemu/sysemu.h | 1 + qapi-schema.json | 46 +++++++++++++ qemu-options.hx | 3 + vl.c | 13 ++++ 8 files changed, 302 insertions(+) create mode 100644 crypto/crypto.c create mode 100644 include/crypto/crypto.h diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs index a36d2d9..2a63cb8 100644 --- a/crypto/Makefile.objs +++ b/crypto/Makefile.objs @@ -26,6 +26,7 @@ crypto-obj-y += xts.o crypto-obj-y += block.o crypto-obj-y += block-qcow.o crypto-obj-y += block-luks.o +crypto-obj-y += crypto.o # Let the userspace emulators avoid linking gnutls/etc crypto-aes-obj-y = aes.o diff --git a/crypto/crypto.c b/crypto/crypto.c new file mode 100644 index 0000000..fbc6497 --- /dev/null +++ b/crypto/crypto.c @@ -0,0 +1,171 @@ +/* + * QEMU Crypto Device Implement + * + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. + * + * Authors: + * Gonglei + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "qemu/osdep.h" +#include "sysemu/sysemu.h" +#include "qapi/error.h" +#include "qemu/iov.h" +#include "qapi-visit.h" +#include "qapi/opts-visitor.h" + +#include "crypto/crypto.h" +#include "qemu/config-file.h" +#include "monitor/monitor.h" + + +static QTAILQ_HEAD(, CryptoClientState) crypto_clients; + +QemuOptsList qemu_cryptodev_opts = { + .name = "cryptodev", + .implied_opt_name = "type", + .head = QTAILQ_HEAD_INITIALIZER(qemu_cryptodev_opts.head), + .desc = { + /* + * no elements => accept any params + * validation will happen later + */ + { /* end of list */ } + }, +}; + +static int +crypto_init_cryptodev(void *dummy, QemuOpts *opts, Error **errp) +{ + Error *local_err = NULL; + int ret; + + ret = crypto_client_init(opts, &local_err); + if (local_err) { + error_report_err(local_err); + return -1; + } + + return ret; +} + +int crypto_init_clients(void) +{ + QTAILQ_INIT(&crypto_clients); + + if (qemu_opts_foreach(qemu_find_opts("cryptodev"), + crypto_init_cryptodev, NULL, NULL)) { + return -1; + } + + return 0; +} + +static int (* const crypto_client_init_fun[CRYPTO_CLIENT_OPTIONS_KIND__MAX])( + const CryptoClientOptions *opts, + const char *name, + CryptoClientState *peer, Error **errp); + +static int crypto_client_init1(const void *object, Error **errp) +{ + const CryptoClientOptions *opts; + const char *name; + + const Cryptodev *cryptodev = object; + opts = cryptodev->opts; + name = cryptodev->id; + + if (opts->type == CRYPTO_CLIENT_OPTIONS_KIND_LEGACY_HW || + !crypto_client_init_fun[opts->type]) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "type", + "a cryptodev backend type"); + return -1; + } + + if (crypto_client_init_fun[opts->type](opts, name, NULL, errp) < 0) { + if (errp && !*errp) { + error_setg(errp, QERR_DEVICE_INIT_FAILED, + CryptoClientOptionsKind_lookup[opts->type]); + } + return -1; + } + return 0; +} + +int crypto_client_init(QemuOpts *opts, Error **errp) +{ + void *object = NULL; + Error *err = NULL; + int ret = -1; + Visitor *v = opts_visitor_new(opts); + + visit_type_Cryptodev(v, NULL, (Cryptodev **)&object, &err); + if (!err) { + ret = crypto_client_init1(object, &err); + } + + qapi_free_Cryptodev(object); + error_propagate(errp, err); + return ret; +} + +static void crypto_client_destructor(CryptoClientState *cc) +{ + g_free(cc); +} + +static void crypto_client_setup(CryptoClientState *cc, + CryptoClientInfo *info, + CryptoClientState *peer, + const char *model, + const char *name, + CryptoClientDestructor *destructor) +{ + cc->info = info; + cc->model = g_strdup(model); + if (name) { + cc->name = g_strdup(name); + } + + if (peer) { + assert(!peer->peer); + cc->peer = peer; + peer->peer = cc; + } + QTAILQ_INSERT_TAIL(&crypto_clients, cc, next); + cc->destructor = destructor; +} + +CryptoClientState *new_crypto_client(CryptoClientInfo *info, + CryptoClientState *peer, + const char *model, + const char *name) +{ + CryptoClientState *cc; + + assert(info->size >= sizeof(CryptoClientState)); + + /* allocate the memroy of CryptoClientState's parent */ + cc = g_malloc0(info->size); + crypto_client_setup(cc, info, peer, model, name, + crypto_client_destructor); + + return cc; +} diff --git a/include/crypto/crypto.h b/include/crypto/crypto.h new file mode 100644 index 0000000..f93f6f9 --- /dev/null +++ b/include/crypto/crypto.h @@ -0,0 +1,66 @@ +/* + * QEMU Crypto Device Implement + * + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. + * + * Authors: + * Gonglei + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef QCRYPTO_CRYPTO_H__ +#define QCRYPTO_CRYPTO_H__ + +#include "qemu/queue.h" +#include "qapi-types.h" + +typedef void (CryptoPoll)(CryptoClientState *, bool); +typedef void (CryptoCleanup) (CryptoClientState *); +typedef void (CryptoClientDestructor)(CryptoClientState *); +typedef void (CryptoHWStatusChanged)(CryptoClientState *); + +typedef struct CryptoClientInfo { + CryptoClientOptionsKind type; + size_t size; + + CryptoCleanup *cleanup; + CryptoPoll *poll; + CryptoHWStatusChanged *hw_status_changed; +} CryptoClientInfo; + +struct CryptoClientState { + CryptoClientInfo *info; + int ready; + QTAILQ_ENTRY(CryptoClientState) next; + CryptoClientState *peer; + char *model; + char *name; + char info_str[256]; + CryptoClientDestructor *destructor; +}; + +int crypto_client_init(QemuOpts *opts, Error **errp); +int crypto_init_clients(void); + +CryptoClientState *new_crypto_client(CryptoClientInfo *info, + CryptoClientState *peer, + const char *model, + const char *name); + +#endif /* QCRYPTO_CRYPTO_H__ */ diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index b113fcf..82843a9 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -94,5 +94,6 @@ typedef struct SSIBus SSIBus; typedef struct uWireSlave uWireSlave; typedef struct VirtIODevice VirtIODevice; typedef struct Visitor Visitor; +typedef struct CryptoClientState CryptoClientState; #endif /* QEMU_TYPEDEFS_H */ diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index ee7c760..58e0d88 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -244,5 +244,6 @@ extern QemuOptsList qemu_netdev_opts; extern QemuOptsList qemu_net_opts; extern QemuOptsList qemu_global_opts; extern QemuOptsList qemu_mon_opts; +extern QemuOptsList qemu_cryptodev_opts; #endif diff --git a/qapi-schema.json b/qapi-schema.json index c4f3674..46f7993 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -4582,3 +4582,49 @@ # Since: 2.7 ## { 'command': 'query-hotpluggable-cpus', 'returns': ['HotpluggableCPU'] } + +## +# @CryptoLegacyHWOptions +# +# Create a new cryptographic hardware device. +# +# @cryptodev: #optional id of -cryptodev to connect to +# +# @model: #optional device model (Only virtio at present) +# +# @vectors: #optional number of MSI-x vectors, 0 to disable MSI-X +# +# Since 2.8 +## +{ 'struct': 'CryptoLegacyHWOptions', + 'data': { + '*cryptodev': 'str', + '*model': 'str', + '*vectors': 'uint32' } } + +## +# @CryptoClientOptions +# +# A discriminated record of crypto device traits. +# +# Since 2.8 +# +## +{ 'union': 'CryptoClientOptions', + 'data': {'legacy-hw': 'CryptoLegacyHWOptions'} } + +## +# @Cryptodev +# +# Captures the configuration of a crypto device. +# +# @id: identifier for monitor commands. +# +# @opts: device type specific properties +# +# Since 2.8 +## +{ 'struct': 'Cryptodev', + 'data': { + 'id': 'str', + 'opts': 'CryptoClientOptions' } } diff --git a/qemu-options.hx b/qemu-options.hx index a71aaf8..a64ce25 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3968,6 +3968,9 @@ contents of @code{iv.b64} to the second secret ETEXI +DEF("cryptodev", HAS_ARG, QEMU_OPTION_cryptodev, + "", + QEMU_ARCH_ALL) HXCOMM This is the last statement. Insert new options before this line! STEXI diff --git a/vl.c b/vl.c index ee557a1..24e86ea 100644 --- a/vl.c +++ b/vl.c @@ -119,6 +119,7 @@ int main(int argc, char **argv) #include "qapi-event.h" #include "exec/semihost.h" #include "crypto/init.h" +#include "crypto/crypto.h" #include "sysemu/replay.h" #include "qapi/qmp/qerror.h" @@ -3015,6 +3016,7 @@ int main(int argc, char **argv, char **envp) qemu_add_opts(&qemu_icount_opts); qemu_add_opts(&qemu_semihosting_config_opts); qemu_add_opts(&qemu_fw_cfg_opts); + qemu_add_opts(&qemu_cryptodev_opts); module_call_init(MODULE_INIT_OPTS); runstate_init(); @@ -3983,6 +3985,13 @@ int main(int argc, char **argv, char **envp) exit(1); } break; + case QEMU_OPTION_cryptodev: + opts = qemu_opts_parse_noisily(qemu_find_opts("cryptodev"), + optarg, false); + if (!opts) { + exit(1); + } + break; default: os_parse_cmd_args(popt->index, optarg); } @@ -4372,6 +4381,10 @@ int main(int argc, char **argv, char **envp) exit(1); } + if (crypto_init_clients() < 0) { + exit(1); + } + if (qemu_opts_foreach(qemu_find_opts("object"), user_creatable_add_opts_foreach, object_create_delayed, NULL)) {