[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v3 04/10] cryptodev: introduce gcrypt lib as a n
From: |
Daniel P. Berrange |
Subject: |
Re: [Qemu-devel] [PATCH v3 04/10] cryptodev: introduce gcrypt lib as a new cryptodev backend |
Date: |
Mon, 19 Sep 2016 09:56:13 +0100 |
User-agent: |
Mutt/1.7.0 (2016-08-17) |
On Mon, Sep 19, 2016 at 04:16:16PM +0800, Gonglei wrote:
> Signed-off-by: Gonglei <address@hidden>
> ---
> crypto/Makefile.objs | 1 +
> crypto/cryptodev-gcrypt.c | 329
> ++++++++++++++++++++++++++++++++++++++++++++++
> qemu-options.hx | 18 +++
> 3 files changed, 348 insertions(+)
> create mode 100644 crypto/cryptodev-gcrypt.c
>
> diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs
> index f7f3c4f..bd8aea7 100644
> --- a/crypto/Makefile.objs
> +++ b/crypto/Makefile.objs
> @@ -27,6 +27,7 @@ crypto-obj-y += block.o
> crypto-obj-y += block-qcow.o
> crypto-obj-y += block-luks.o
> crypto-obj-y += cryptodev.o
> +crypto-obj-$(CONFIG_GCRYPT) += cryptodev-gcrypt.o
This can be just crypto-obj-y +=
> # Let the userspace emulators avoid linking gnutls/etc
> crypto-aes-obj-y = aes.o
> diff --git a/crypto/cryptodev-gcrypt.c b/crypto/cryptodev-gcrypt.c
> new file mode 100644
> index 0000000..66a0e5e
> --- /dev/null
> +++ b/crypto/cryptodev-gcrypt.c
> +/**
> + * @TYPE_QCRYPTO_CRYPTODEV_BACKEND_GCRYPT:
> + * name of backend that uses gcrypt library
> + */
> +#define TYPE_QCRYPTO_CRYPTODEV_BACKEND_GCRYPT "cryptodev-backend-gcrypt"
I'd suggest we just call this backend "builtin", so do a
replace of "gcrypt" with "builtin" throughout.
> +static void qcrypto_cryptodev_backend_gcrypt_init(
> + QCryptoCryptoDevBackend *backend, Error **errp)
> +{
> + /* Only support one queue */
> + int queues = MAX(backend->conf.peers.queues, 1);
> + int i;
Nitpick, I prefer to see 'size_t' for list iterators
that are always positive. Similar comment in other
places in this series using int i
> + QCryptoCryptoDevBackendClientState *cc;
> +
> + for (i = 0; i < queues; i++) {
> + cc = qcrypto_cryptodev_backend_new_client(
> + "cryptodev-gcrypt", NULL);
> + snprintf(cc->info_str, sizeof(cc->info_str),
> + "cryptodev-gcrypt%d", i);
> + cc->queue_index = i;
> +
> + backend->conf.peers.ccs[i] = cc;
> + }
> +
> + backend->conf.crypto_services =
> + 1u << VIRTIO_CRYPTO_SERVICE_CIPHER |
> + 1u << VIRTIO_CRYPTO_SERVICE_HASH |
> + 1u << VIRTIO_CRYPTO_SERVICE_MAC;
> + backend->conf.cipher_algo_l = 1u << VIRTIO_CRYPTO_CIPHER_AES_CBC;
> + backend->conf.hash_algo = 1u << VIRTIO_CRYPTO_HASH_SHA1;
> +}
> +
> +static int
> +qcrypto_cryptodev_backend_gcrypt_get_unused_session_index(
> + QCryptoCryptoDevBackendGcrypt *gcrypt)
> +{
> + int i;
> +
> + for (i = 0; i < MAX_NUM_SESSIONS; i++) {
> + if (gcrypt->sessions[i] == NULL) {
> + return i;
> + }
> + }
> +
> + return -1;
> +}
> +
> +static int qcrypto_cryptodev_backend_gcrypt_create_cipher_session(
> + QCryptoCryptoDevBackendGcrypt *gcrypt,
> + QCryptoCryptoDevBackendSymSessionInfo *sess_info,
> + Error **errp)
> +{
> + int algo;
> + int mode;
> + QCryptoCipher *cipher;
> + int index;
> + QCryptoCryptoDevBackendGcryptSession *sess;
> +
> + if (sess_info->op_type != VIRTIO_CRYPTO_SYM_OP_CIPHER) {
> + error_setg(errp, "unsupported optype :%u", sess_info->op_type);
> + return -1;
> + }
> +
> + index =
> qcrypto_cryptodev_backend_gcrypt_get_unused_session_index(gcrypt);
> + if (index < 0) {
> + error_setg(errp, "the total number of created session exceed %u",
> + MAX_NUM_SESSIONS);
> + return -1;
> + }
> +
> + switch (sess_info->cipher_alg) {
> + case VIRTIO_CRYPTO_CIPHER_AES_ECB:
> + if (sess_info->key_len == 128 / 8) {
> + algo = QCRYPTO_CIPHER_ALG_AES_128;
> + } else if (sess_info->key_len == 192 / 8) {
> + algo = QCRYPTO_CIPHER_ALG_AES_192;
> + } else if (sess_info->key_len == 256 / 8) {
> + algo = QCRYPTO_CIPHER_ALG_AES_256;
> + } else {
> + error_setg(errp, "unsupported key length :%u",
> + sess_info->key_len);
> + return -1;
> + }
> + mode = QCRYPTO_CIPHER_MODE_ECB;
> + break;
> + case VIRTIO_CRYPTO_CIPHER_AES_CBC:
> + if (sess_info->key_len == 128 / 8) {
> + algo = QCRYPTO_CIPHER_ALG_AES_128;
> + } else if (sess_info->key_len == 192 / 8) {
> + algo = QCRYPTO_CIPHER_ALG_AES_192;
> + } else if (sess_info->key_len == 256 / 8) {
> + algo = QCRYPTO_CIPHER_ALG_AES_256;
> + } else {
> + error_setg(errp, "unsupported key length :%u",
> + sess_info->key_len);
> + return -1;
> + }
> + mode = QCRYPTO_CIPHER_MODE_CBC;
> + break;
> + case VIRTIO_CRYPTO_CIPHER_AES_CTR:
Although the QEMU cipher.h API does not export CTR mode currently
it should be trivial to add it. So feel free to add a patch at
the start of the series implementing CTR mode in the cipher API.
Both gcrypt and nettle have support for it which is all we need.
> + default:
> + error_setg(errp, "unsupported cipher alg :%u",
> + sess_info->cipher_alg);
> + return -1;
> + }
> +
> + cipher = qcrypto_cipher_new(algo, mode,
> + sess_info->cipher_key,
> + sess_info->key_len,
> + errp);
> + if (!cipher) {
> + return -1;
> + }
> +
> + sess = g_new0(QCryptoCryptoDevBackendGcryptSession, 1);
> + sess->cipher = cipher;
> + sess->direction = sess_info->direction;
> + sess->type = sess_info->op_type;
> +
> + gcrypt->sessions[index] = sess;
> +
> + return index;
> +}
> +
> +static int64_t qcrypto_cryptodev_backend_gcrypt_sym_create_session(
> + QCryptoCryptoDevBackend *backend,
> + QCryptoCryptoDevBackendSymSessionInfo *sess_info,
> + uint32_t queue_index, Error **errp)
> +{
> + QCryptoCryptoDevBackendGcrypt *gcrypt =
> + QCRYPTO_CRYPTODEV_BACKEND_GCRYPT(backend);
> + int64_t session_id = -1;
> + int ret;
> +
> + switch (sess_info->op_code) {
> + case VIRTIO_CRYPTO_CIPHER_CREATE_SESSION:
> + ret = qcrypto_cryptodev_backend_gcrypt_create_cipher_session(
> + gcrypt, sess_info, errp);
> + if (ret < 0) {
> + return ret;
> + } else {
> + session_id = ret;
> + }
> + break;
> + case VIRTIO_CRYPTO_HASH_CREATE_SESSION:
> + case VIRTIO_CRYPTO_MAC_CREATE_SESSION:
> + default:
> + error_setg(errp, "unsupported opcode :%" PRIu32 "",
> + sess_info->op_code);
> + return -1;
> + }
> +
> + return session_id;
> +}
> +
> +static int qcrypto_cryptodev_backend_gcrypt_sym_close_session(
> + QCryptoCryptoDevBackend *backend,
> + uint64_t session_id, Error **errp)
> +{
> + QCryptoCryptoDevBackendGcrypt *gcrypt =
> + QCRYPTO_CRYPTODEV_BACKEND_GCRYPT(backend);
> +
> + if (session_id >= MAX_NUM_SESSIONS ||
> + gcrypt->sessions[session_id] == NULL) {
> + error_setg(errp, "Cannot find a valid session id: %" PRIu64 "",
> + session_id);
> + return -1;
> + }
> +
> + qcrypto_cipher_free(gcrypt->sessions[session_id]->cipher);
> + g_free(gcrypt->sessions[session_id]);
> + gcrypt->sessions[session_id] = NULL;
> + return 0;
> +}
> +
> +static int qcrypto_cryptodev_backend_gcrypt_sym_operation(
> + QCryptoCryptoDevBackend *backend,
> + QCryptoCryptoDevBackendSymOpInfo *op_info,
> + uint32_t queue_index, Error **errp)
> +{
> + QCryptoCryptoDevBackendGcrypt *gcrypt =
> + QCRYPTO_CRYPTODEV_BACKEND_GCRYPT(backend);
> + QCryptoCryptoDevBackendGcryptSession *sess;
> + int ret;
> +
> + if (op_info->session_id >= MAX_NUM_SESSIONS ||
> + gcrypt->sessions[op_info->session_id] == NULL) {
> + error_setg(errp, "Cannot find a valid session id: %" PRIu64 "",
> + op_info->session_id);
> + return -VIRTIO_CRYPTO_OP_INVSESS;
> + }
> +
> + sess = gcrypt->sessions[op_info->session_id];
> +
> + ret = qcrypto_cipher_setiv(sess->cipher, op_info->iv,
> + op_info->iv_len, errp);
> + if (ret < 0) {
> + return -VIRTIO_CRYPTO_OP_ERR;
> + }
> +
> + if (sess->direction == VIRTIO_CRYPTO_OP_ENCRYPT) {
> + ret = qcrypto_cipher_encrypt(sess->cipher, op_info->src,
> + op_info->dst, op_info->src_len, errp);
> + if (ret < 0) {
> + return -VIRTIO_CRYPTO_OP_ERR;
> + }
> + } else {
> + ret = qcrypto_cipher_decrypt(sess->cipher, op_info->src,
> + op_info->dst, op_info->src_len, errp);
> + if (ret < 0) {
> + return -VIRTIO_CRYPTO_OP_ERR;
> + }
> + }
> + return 0;
> +}
Regards,
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
- [Qemu-devel] [PATCH v3 02/10] cryptodev: add symmetric algorithm operation stuff, (continued)
- [Qemu-devel] [PATCH v3 02/10] cryptodev: add symmetric algorithm operation stuff, Gonglei, 2016/09/19
- [Qemu-devel] [PATCH v3 05/10] virtio-crypto: add virtio crypto device emulation, Gonglei, 2016/09/19
- [Qemu-devel] [PATCH v3 01/10] cryptodev: introduce cryptodev backend interface, Gonglei, 2016/09/19
- [Qemu-devel] [PATCH v3 07/10] virtio-crypto: set capacity of algorithms supported, Gonglei, 2016/09/19
- [Qemu-devel] [PATCH v3 09/10] virtio-crypto: add data queue processing handler, Gonglei, 2016/09/19
- [Qemu-devel] [PATCH v3 10/10] cryptodev: introduce an unified wrapper for crypto operation, Gonglei, 2016/09/19
- [Qemu-devel] [PATCH v3 06/10] virtio-crypto-pci: add virtio crypto pci support, Gonglei, 2016/09/19
- [Qemu-devel] [PATCH v3 04/10] cryptodev: introduce gcrypt lib as a new cryptodev backend, Gonglei, 2016/09/19
- [Qemu-devel] [PATCH v3 03/10] virtio-crypto: introduce virtio_crypto.h, Gonglei, 2016/09/19
- [Qemu-devel] [PATCH v3 08/10] virtio-crypto: add control queue handler, Gonglei, 2016/09/19
- Re: [Qemu-devel] [PATCH v3 00/10] virtio-crypto: introduce framework and device emulation, no-reply, 2016/09/19
- Re: [Qemu-devel] [PATCH v3 00/10] virtio-crypto: introduce framework and device emulation, Gonglei (Arei), 2016/09/22