@@ -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
new file mode 100644
@@ -0,0 +1,171 @@
+/*
+ * QEMU Crypto Device Implement
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ * Gonglei <arei.gonglei@huawei.com>
+ *
+ * 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;
+}
new file mode 100644
@@ -0,0 +1,67 @@
+/*
+ * QEMU Crypto Device Implement
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ * Gonglei <arei.gonglei@huawei.com>
+ *
+ * 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__ */
@@ -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 */
@@ -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
@@ -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.7
+##
+{ 'struct': 'CryptoLegacyHWOptions',
+ 'data': {
+ '*cryptodev': 'str',
+ '*model': 'str',
+ '*vectors': 'uint32' } }
+
+##
+# @CryptoClientOptions
+#
+# A discriminated record of crypto device traits.
+#
+# Since 2.7
+#
+##
+{ '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.7
+##
+{ 'struct': 'Cryptodev',
+ 'data': {
+ 'id': 'str',
+ 'opts': 'CryptoClientOptions' } }
@@ -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
@@ -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)) {
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 <arei.gonglei@huawei.com> --- crypto/Makefile.objs | 1 + crypto/crypto.c | 171 ++++++++++++++++++++++++++++++++++++++++++++++++ include/crypto/crypto.h | 67 +++++++++++++++++++ include/qemu/typedefs.h | 1 + include/sysemu/sysemu.h | 1 + qapi-schema.json | 46 +++++++++++++ qemu-options.hx | 3 + vl.c | 13 ++++ 8 files changed, 303 insertions(+) create mode 100644 crypto/crypto.c create mode 100644 include/crypto/crypto.h