From nobody Sat May 4 00:02:23 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 154419935918417.08849243106647; Fri, 7 Dec 2018 08:15:59 -0800 (PST) Received: from localhost ([::1]:46929 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gVIn5-0007wU-Pw for importer@patchew.org; Fri, 07 Dec 2018 11:15:47 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41792) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gVIlO-0006re-Ul for qemu-devel@nongnu.org; Fri, 07 Dec 2018 11:14:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gVIlK-0002cB-PC for qemu-devel@nongnu.org; Fri, 07 Dec 2018 11:14:02 -0500 Received: from relay.sw.ru ([185.231.240.75]:47224) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gVIlK-0002LP-B1; Fri, 07 Dec 2018 11:13:58 -0500 Received: from [10.28.8.145] (helo=kvm.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1gVIlE-0005Hz-7s; Fri, 07 Dec 2018 19:13:52 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Fri, 7 Dec 2018 19:13:47 +0300 Message-Id: <20181207161351.4380-2-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20181207161351.4380-1-vsementsov@virtuozzo.com> References: <20181207161351.4380-1-vsementsov@virtuozzo.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 185.231.240.75 Subject: [Qemu-devel] [PATCH v3 1/5] crypto/block-luks: fix memory leak in qcrypto_block_luks_create 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: kwolf@redhat.com, vsementsov@virtuozzo.com, berto@igalia.com, mreitz@redhat.com, den@openvz.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Free block->cipher and block->ivgen on error path. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Daniel P. Berrang=C3=A9 Reviewed-by: Alberto Garcia --- crypto/block-luks.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crypto/block-luks.c b/crypto/block-luks.c index 5738124773..51e24d23ca 100644 --- a/crypto/block-luks.c +++ b/crypto/block-luks.c @@ -1341,6 +1341,9 @@ qcrypto_block_luks_create(QCryptoBlock *block, qcrypto_ivgen_free(ivgen); qcrypto_cipher_free(cipher); =20 + qcrypto_cipher_free(block->cipher); + qcrypto_ivgen_free(block->ivgen); + g_free(luks); return -1; } --=20 2.18.0 From nobody Sat May 4 00:02:23 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1544199490078943.5622397688653; Fri, 7 Dec 2018 08:18:10 -0800 (PST) Received: from localhost ([::1]:46940 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gVIpM-00013G-RK for importer@patchew.org; Fri, 07 Dec 2018 11:18:08 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41788) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gVIlO-0006rb-Sh for qemu-devel@nongnu.org; Fri, 07 Dec 2018 11:14:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gVIlK-0002bU-Lg for qemu-devel@nongnu.org; Fri, 07 Dec 2018 11:14:02 -0500 Received: from relay.sw.ru ([185.231.240.75]:47210) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gVIlK-0002LK-Au; Fri, 07 Dec 2018 11:13:58 -0500 Received: from [10.28.8.145] (helo=kvm.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1gVIlE-0005Hz-PS; Fri, 07 Dec 2018 19:13:52 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Fri, 7 Dec 2018 19:13:48 +0300 Message-Id: <20181207161351.4380-3-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20181207161351.4380-1-vsementsov@virtuozzo.com> References: <20181207161351.4380-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 185.231.240.75 Subject: [Qemu-devel] [PATCH v3 2/5] crypto/block: refactor qcrypto_block_*crypt_helper functions 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: kwolf@redhat.com, vsementsov@virtuozzo.com, berto@igalia.com, mreitz@redhat.com, den@openvz.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" qcrypto_block_encrypt_helper and qcrypto_block_decrypt_helper are almost identical, let's reduce code duplication and simplify further improvements. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Alberto Garcia --- crypto/block.c | 81 +++++++++++++++++++------------------------------- 1 file changed, 31 insertions(+), 50 deletions(-) diff --git a/crypto/block.c b/crypto/block.c index e59d1140fe..8d0e4bdbb2 100644 --- a/crypto/block.c +++ b/crypto/block.c @@ -190,14 +190,21 @@ void qcrypto_block_free(QCryptoBlock *block) } =20 =20 -int qcrypto_block_decrypt_helper(QCryptoCipher *cipher, - size_t niv, - QCryptoIVGen *ivgen, - int sectorsize, - uint64_t offset, - uint8_t *buf, - size_t len, - Error **errp) +typedef int (*QCryptoCipherEncDecFunc)(QCryptoCipher *cipher, + const void *in, + void *out, + size_t len, + Error **errp); + +static int do_qcrypto_block_encdec(QCryptoCipher *cipher, + size_t niv, + QCryptoIVGen *ivgen, + int sectorsize, + uint64_t offset, + uint8_t *buf, + size_t len, + QCryptoCipherEncDecFunc func, + Error **errp) { uint8_t *iv; int ret =3D -1; @@ -226,8 +233,7 @@ int qcrypto_block_decrypt_helper(QCryptoCipher *cipher, } =20 nbytes =3D len > sectorsize ? sectorsize : len; - if (qcrypto_cipher_decrypt(cipher, buf, buf, - nbytes, errp) < 0) { + if (func(cipher, buf, buf, nbytes, errp) < 0) { goto cleanup; } =20 @@ -243,7 +249,7 @@ int qcrypto_block_decrypt_helper(QCryptoCipher *cipher, } =20 =20 -int qcrypto_block_encrypt_helper(QCryptoCipher *cipher, +int qcrypto_block_decrypt_helper(QCryptoCipher *cipher, size_t niv, QCryptoIVGen *ivgen, int sectorsize, @@ -252,45 +258,20 @@ int qcrypto_block_encrypt_helper(QCryptoCipher *ciphe= r, size_t len, Error **errp) { - uint8_t *iv; - int ret =3D -1; - uint64_t startsector =3D offset / sectorsize; - - assert(QEMU_IS_ALIGNED(offset, sectorsize)); - assert(QEMU_IS_ALIGNED(len, sectorsize)); - - iv =3D niv ? g_new0(uint8_t, niv) : NULL; - - while (len > 0) { - size_t nbytes; - if (niv) { - if (qcrypto_ivgen_calculate(ivgen, - startsector, - iv, niv, - errp) < 0) { - goto cleanup; - } + return do_qcrypto_block_encdec(cipher, niv, ivgen, sectorsize, offset, + buf, len, qcrypto_cipher_decrypt, errp); +} =20 - if (qcrypto_cipher_setiv(cipher, - iv, niv, - errp) < 0) { - goto cleanup; - } - } =20 - nbytes =3D len > sectorsize ? sectorsize : len; - if (qcrypto_cipher_encrypt(cipher, buf, buf, - nbytes, errp) < 0) { - goto cleanup; - } - - startsector++; - buf +=3D nbytes; - len -=3D nbytes; - } - - ret =3D 0; - cleanup: - g_free(iv); - return ret; +int qcrypto_block_encrypt_helper(QCryptoCipher *cipher, + size_t niv, + QCryptoIVGen *ivgen, + int sectorsize, + uint64_t offset, + uint8_t *buf, + size_t len, + Error **errp) +{ + return do_qcrypto_block_encdec(cipher, niv, ivgen, sectorsize, offset, + buf, len, qcrypto_cipher_encrypt, errp); } --=20 2.18.0 From nobody Sat May 4 00:02:23 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1544199597644677.3185886016479; Fri, 7 Dec 2018 08:19:57 -0800 (PST) Received: from localhost ([::1]:46947 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gVIr5-0002hp-Ii for importer@patchew.org; Fri, 07 Dec 2018 11:19:55 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41790) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gVIlO-0006rd-U2 for qemu-devel@nongnu.org; Fri, 07 Dec 2018 11:14:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gVIlK-0002c1-Oj for qemu-devel@nongnu.org; Fri, 07 Dec 2018 11:14:02 -0500 Received: from relay.sw.ru ([185.231.240.75]:47222) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gVIlK-0002LO-Ay; Fri, 07 Dec 2018 11:13:58 -0500 Received: from [10.28.8.145] (helo=kvm.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1gVIlF-0005Hz-0j; Fri, 07 Dec 2018 19:13:53 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Fri, 7 Dec 2018 19:13:49 +0300 Message-Id: <20181207161351.4380-4-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20181207161351.4380-1-vsementsov@virtuozzo.com> References: <20181207161351.4380-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 185.231.240.75 Subject: [Qemu-devel] [PATCH v3 3/5] crypto/block: rename qcrypto_block_*crypt_helper 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: kwolf@redhat.com, vsementsov@virtuozzo.com, berto@igalia.com, mreitz@redhat.com, den@openvz.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Rename qcrypto_block_*crypt_helper to qcrypto_cipher_*crypt_helper, as it's not about QCryptoBlock. This is needed to introduce qcrypto_block_*crypt_helper in the next commit, which will have QCryptoBlock pointer and than will be able to use additional fields of it, which in turn will be used to implement thread-safe QCryptoBlock operations. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Alberto Garcia --- crypto/blockpriv.h | 34 +++++++++++----------- crypto/block-luks.c | 44 ++++++++++++++-------------- crypto/block-qcow.c | 16 +++++------ crypto/block.c | 70 +++++++++++++++++++++++---------------------- 4 files changed, 83 insertions(+), 81 deletions(-) diff --git a/crypto/blockpriv.h b/crypto/blockpriv.h index 41840abcec..54bbe1eb6a 100644 --- a/crypto/blockpriv.h +++ b/crypto/blockpriv.h @@ -78,22 +78,22 @@ struct QCryptoBlockDriver { }; =20 =20 -int qcrypto_block_decrypt_helper(QCryptoCipher *cipher, - size_t niv, - QCryptoIVGen *ivgen, - int sectorsize, - uint64_t offset, - uint8_t *buf, - size_t len, - Error **errp); - -int qcrypto_block_encrypt_helper(QCryptoCipher *cipher, - size_t niv, - QCryptoIVGen *ivgen, - int sectorsize, - uint64_t offset, - uint8_t *buf, - size_t len, - Error **errp); +int qcrypto_block_cipher_decrypt_helper(QCryptoCipher *cipher, + size_t niv, + QCryptoIVGen *ivgen, + int sectorsize, + uint64_t offset, + uint8_t *buf, + size_t len, + Error **errp); + +int qcrypto_block_cipher_encrypt_helper(QCryptoCipher *cipher, + size_t niv, + QCryptoIVGen *ivgen, + int sectorsize, + uint64_t offset, + uint8_t *buf, + size_t len, + Error **errp); =20 #endif /* QCRYPTO_BLOCKPRIV_H */ diff --git a/crypto/block-luks.c b/crypto/block-luks.c index 51e24d23ca..353a400595 100644 --- a/crypto/block-luks.c +++ b/crypto/block-luks.c @@ -504,14 +504,14 @@ qcrypto_block_luks_load_key(QCryptoBlock *block, * to reset the encryption cipher every time the master * key crosses a sector boundary. */ - if (qcrypto_block_decrypt_helper(cipher, - niv, - ivgen, - QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, - 0, - splitkey, - splitkeylen, - errp) < 0) { + if (qcrypto_block_cipher_decrypt_helper(cipher, + niv, + ivgen, + QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, + 0, + splitkey, + splitkeylen, + errp) < 0) { goto cleanup; } =20 @@ -1219,12 +1219,12 @@ qcrypto_block_luks_create(QCryptoBlock *block, =20 /* Now we encrypt the split master key with the key generated * from the user's password, before storing it */ - if (qcrypto_block_encrypt_helper(cipher, block->niv, ivgen, - QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, - 0, - splitkey, - splitkeylen, - errp) < 0) { + if (qcrypto_block_cipher_encrypt_helper(cipher, block->niv, ivgen, + QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, + 0, + splitkey, + splitkeylen, + errp) < 0) { goto error; } =20 @@ -1409,10 +1409,10 @@ qcrypto_block_luks_decrypt(QCryptoBlock *block, { assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)); assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)); - return qcrypto_block_decrypt_helper(block->cipher, - block->niv, block->ivgen, - QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, - offset, buf, len, errp); + return qcrypto_block_cipher_decrypt_helper(block->cipher, + block->niv, block->ivgen, + QCRYPTO_BLOCK_LUKS_SECTOR_S= IZE, + offset, buf, len, errp); } =20 =20 @@ -1425,10 +1425,10 @@ qcrypto_block_luks_encrypt(QCryptoBlock *block, { assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)); assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)); - return qcrypto_block_encrypt_helper(block->cipher, - block->niv, block->ivgen, - QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, - offset, buf, len, errp); + return qcrypto_block_cipher_encrypt_helper(block->cipher, + block->niv, block->ivgen, + QCRYPTO_BLOCK_LUKS_SECTOR_S= IZE, + offset, buf, len, errp); } =20 =20 diff --git a/crypto/block-qcow.c b/crypto/block-qcow.c index 7606231e79..3b6722deb0 100644 --- a/crypto/block-qcow.c +++ b/crypto/block-qcow.c @@ -152,10 +152,10 @@ qcrypto_block_qcow_decrypt(QCryptoBlock *block, { assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE)); assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE)); - return qcrypto_block_decrypt_helper(block->cipher, - block->niv, block->ivgen, - QCRYPTO_BLOCK_QCOW_SECTOR_SIZE, - offset, buf, len, errp); + return qcrypto_block_cipher_decrypt_helper(block->cipher, + block->niv, block->ivgen, + QCRYPTO_BLOCK_QCOW_SECTOR_S= IZE, + offset, buf, len, errp); } =20 =20 @@ -168,10 +168,10 @@ qcrypto_block_qcow_encrypt(QCryptoBlock *block, { assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE)); assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE)); - return qcrypto_block_encrypt_helper(block->cipher, - block->niv, block->ivgen, - QCRYPTO_BLOCK_QCOW_SECTOR_SIZE, - offset, buf, len, errp); + return qcrypto_block_cipher_encrypt_helper(block->cipher, + block->niv, block->ivgen, + QCRYPTO_BLOCK_QCOW_SECTOR_S= IZE, + offset, buf, len, errp); } =20 =20 diff --git a/crypto/block.c b/crypto/block.c index 8d0e4bdbb2..d43139dbc7 100644 --- a/crypto/block.c +++ b/crypto/block.c @@ -191,20 +191,20 @@ void qcrypto_block_free(QCryptoBlock *block) =20 =20 typedef int (*QCryptoCipherEncDecFunc)(QCryptoCipher *cipher, - const void *in, - void *out, - size_t len, - Error **errp); - -static int do_qcrypto_block_encdec(QCryptoCipher *cipher, - size_t niv, - QCryptoIVGen *ivgen, - int sectorsize, - uint64_t offset, - uint8_t *buf, - size_t len, - QCryptoCipherEncDecFunc func, - Error **errp) + const void *in, + void *out, + size_t len, + Error **errp); + +static int do_qcrypto_block_cipher_encdec(QCryptoCipher *cipher, + size_t niv, + QCryptoIVGen *ivgen, + int sectorsize, + uint64_t offset, + uint8_t *buf, + size_t len, + QCryptoCipherEncDecFunc func, + Error **errp) { uint8_t *iv; int ret =3D -1; @@ -249,29 +249,31 @@ static int do_qcrypto_block_encdec(QCryptoCipher *cip= her, } =20 =20 -int qcrypto_block_decrypt_helper(QCryptoCipher *cipher, - size_t niv, - QCryptoIVGen *ivgen, - int sectorsize, - uint64_t offset, - uint8_t *buf, - size_t len, - Error **errp) +int qcrypto_block_cipher_decrypt_helper(QCryptoCipher *cipher, + size_t niv, + QCryptoIVGen *ivgen, + int sectorsize, + uint64_t offset, + uint8_t *buf, + size_t len, + Error **errp) { - return do_qcrypto_block_encdec(cipher, niv, ivgen, sectorsize, offset, - buf, len, qcrypto_cipher_decrypt, errp); + return do_qcrypto_block_cipher_encdec(cipher, niv, ivgen, sectorsize, + offset, buf, len, + qcrypto_cipher_decrypt, errp); } =20 =20 -int qcrypto_block_encrypt_helper(QCryptoCipher *cipher, - size_t niv, - QCryptoIVGen *ivgen, - int sectorsize, - uint64_t offset, - uint8_t *buf, - size_t len, - Error **errp) +int qcrypto_block_cipher_encrypt_helper(QCryptoCipher *cipher, + size_t niv, + QCryptoIVGen *ivgen, + int sectorsize, + uint64_t offset, + uint8_t *buf, + size_t len, + Error **errp) { - return do_qcrypto_block_encdec(cipher, niv, ivgen, sectorsize, offset, - buf, len, qcrypto_cipher_encrypt, errp); + return do_qcrypto_block_cipher_encdec(cipher, niv, ivgen, sectorsize, + offset, buf, len, + qcrypto_cipher_encrypt, errp); } --=20 2.18.0 From nobody Sat May 4 00:02:23 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1544199359310392.5606159335455; Fri, 7 Dec 2018 08:15:59 -0800 (PST) Received: from localhost ([::1]:46928 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gVIn7-0007wR-0t for importer@patchew.org; Fri, 07 Dec 2018 11:15:49 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41794) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gVIlO-0006rg-UE for qemu-devel@nongnu.org; Fri, 07 Dec 2018 11:14:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gVIlK-0002bl-Nl for qemu-devel@nongnu.org; Fri, 07 Dec 2018 11:14:02 -0500 Received: from relay.sw.ru ([185.231.240.75]:47214) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gVIlK-0002LM-Az; Fri, 07 Dec 2018 11:13:58 -0500 Received: from [10.28.8.145] (helo=kvm.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1gVIlF-0005Hz-52; Fri, 07 Dec 2018 19:13:53 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Fri, 7 Dec 2018 19:13:50 +0300 Message-Id: <20181207161351.4380-5-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20181207161351.4380-1-vsementsov@virtuozzo.com> References: <20181207161351.4380-1-vsementsov@virtuozzo.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 185.231.240.75 Subject: [Qemu-devel] [PATCH v3 4/5] crypto/block: introduce qcrypto_block_*crypt_helper functions 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: kwolf@redhat.com, vsementsov@virtuozzo.com, berto@igalia.com, mreitz@redhat.com, den@openvz.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Introduce QCryptoBlock-based functions and use them where possible. This is needed to implement thread-safe encrypt/decrypt operations. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Daniel P. Berrang=C3=A9 Reviewed-by: Alberto Garcia --- crypto/blockpriv.h | 14 ++++++++++++++ crypto/block-luks.c | 14 ++++++-------- crypto/block-qcow.c | 14 ++++++-------- crypto/block.c | 28 ++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 16 deletions(-) diff --git a/crypto/blockpriv.h b/crypto/blockpriv.h index 54bbe1eb6a..438c08bec2 100644 --- a/crypto/blockpriv.h +++ b/crypto/blockpriv.h @@ -96,4 +96,18 @@ int qcrypto_block_cipher_encrypt_helper(QCryptoCipher *c= ipher, size_t len, Error **errp); =20 +int qcrypto_block_decrypt_helper(QCryptoBlock *block, + int sectorsize, + uint64_t offset, + uint8_t *buf, + size_t len, + Error **errp); + +int qcrypto_block_encrypt_helper(QCryptoBlock *block, + int sectorsize, + uint64_t offset, + uint8_t *buf, + size_t len, + Error **errp); + #endif /* QCRYPTO_BLOCKPRIV_H */ diff --git a/crypto/block-luks.c b/crypto/block-luks.c index 353a400595..e486e7ee94 100644 --- a/crypto/block-luks.c +++ b/crypto/block-luks.c @@ -1409,10 +1409,9 @@ qcrypto_block_luks_decrypt(QCryptoBlock *block, { assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)); assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)); - return qcrypto_block_cipher_decrypt_helper(block->cipher, - block->niv, block->ivgen, - QCRYPTO_BLOCK_LUKS_SECTOR_S= IZE, - offset, buf, len, errp); + return qcrypto_block_decrypt_helper(block, + QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, + offset, buf, len, errp); } =20 =20 @@ -1425,10 +1424,9 @@ qcrypto_block_luks_encrypt(QCryptoBlock *block, { assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)); assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)); - return qcrypto_block_cipher_encrypt_helper(block->cipher, - block->niv, block->ivgen, - QCRYPTO_BLOCK_LUKS_SECTOR_S= IZE, - offset, buf, len, errp); + return qcrypto_block_encrypt_helper(block, + QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, + offset, buf, len, errp); } =20 =20 diff --git a/crypto/block-qcow.c b/crypto/block-qcow.c index 3b6722deb0..36bf5f09b7 100644 --- a/crypto/block-qcow.c +++ b/crypto/block-qcow.c @@ -152,10 +152,9 @@ qcrypto_block_qcow_decrypt(QCryptoBlock *block, { assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE)); assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE)); - return qcrypto_block_cipher_decrypt_helper(block->cipher, - block->niv, block->ivgen, - QCRYPTO_BLOCK_QCOW_SECTOR_S= IZE, - offset, buf, len, errp); + return qcrypto_block_decrypt_helper(block, + QCRYPTO_BLOCK_QCOW_SECTOR_SIZE, + offset, buf, len, errp); } =20 =20 @@ -168,10 +167,9 @@ qcrypto_block_qcow_encrypt(QCryptoBlock *block, { assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE)); assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE)); - return qcrypto_block_cipher_encrypt_helper(block->cipher, - block->niv, block->ivgen, - QCRYPTO_BLOCK_QCOW_SECTOR_S= IZE, - offset, buf, len, errp); + return qcrypto_block_encrypt_helper(block, + QCRYPTO_BLOCK_QCOW_SECTOR_SIZE, + offset, buf, len, errp); } =20 =20 diff --git a/crypto/block.c b/crypto/block.c index d43139dbc7..3fe3de2ef8 100644 --- a/crypto/block.c +++ b/crypto/block.c @@ -277,3 +277,31 @@ int qcrypto_block_cipher_encrypt_helper(QCryptoCipher = *cipher, offset, buf, len, qcrypto_cipher_encrypt, errp); } + + +int qcrypto_block_decrypt_helper(QCryptoBlock *block, + int sectorsize, + uint64_t offset, + uint8_t *buf, + size_t len, + Error **errp) +{ + return do_qcrypto_block_cipher_encdec(block->cipher, block->niv, + block->ivgen, + sectorsize, offset, buf, len, + qcrypto_cipher_decrypt, errp); +} + + +int qcrypto_block_encrypt_helper(QCryptoBlock *block, + int sectorsize, + uint64_t offset, + uint8_t *buf, + size_t len, + Error **errp) +{ + return do_qcrypto_block_cipher_encdec(block->cipher, block->niv, + block->ivgen, + sectorsize, offset, buf, len, + qcrypto_cipher_encrypt, errp); +} --=20 2.18.0 From nobody Sat May 4 00:02:23 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 154419949264024.720244969848522; Fri, 7 Dec 2018 08:18:12 -0800 (PST) Received: from localhost ([::1]:46941 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gVIpO-00014Z-UB for importer@patchew.org; Fri, 07 Dec 2018 11:18:10 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41793) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gVIlO-0006rf-U7 for qemu-devel@nongnu.org; Fri, 07 Dec 2018 11:14:05 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gVIlK-0002cg-T4 for qemu-devel@nongnu.org; Fri, 07 Dec 2018 11:14:02 -0500 Received: from relay.sw.ru ([185.231.240.75]:47220) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gVIlK-0002LN-Az; Fri, 07 Dec 2018 11:13:58 -0500 Received: from [10.28.8.145] (helo=kvm.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1gVIlF-0005Hz-9g; Fri, 07 Dec 2018 19:13:53 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Fri, 7 Dec 2018 19:13:51 +0300 Message-Id: <20181207161351.4380-6-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20181207161351.4380-1-vsementsov@virtuozzo.com> References: <20181207161351.4380-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 185.231.240.75 Subject: [Qemu-devel] [PATCH v3 5/5] crypto: support multiple threads accessing one QCryptoBlock 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: kwolf@redhat.com, vsementsov@virtuozzo.com, berto@igalia.com, mreitz@redhat.com, den@openvz.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The two thing that should be handled are cipher and ivgen. For ivgen the solution is just mutex, as iv calculations should not be long in comparison with encryption/decryption. And for cipher let's just keep per-thread ciphers. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Alberto Garcia --- crypto/blockpriv.h | 16 ++++- include/crypto/block.h | 2 + block/crypto.c | 1 + block/qcow.c | 2 +- block/qcow2.c | 4 +- crypto/block-luks.c | 22 +++--- crypto/block-qcow.c | 20 +++--- crypto/block.c | 146 +++++++++++++++++++++++++++++++++----- tests/test-crypto-block.c | 3 + 9 files changed, 172 insertions(+), 44 deletions(-) diff --git a/crypto/blockpriv.h b/crypto/blockpriv.h index 438c08bec2..5438e822fd 100644 --- a/crypto/blockpriv.h +++ b/crypto/blockpriv.h @@ -22,6 +22,7 @@ #define QCRYPTO_BLOCKPRIV_H =20 #include "crypto/block.h" +#include "qemu/thread.h" =20 typedef struct QCryptoBlockDriver QCryptoBlockDriver; =20 @@ -31,8 +32,12 @@ struct QCryptoBlock { const QCryptoBlockDriver *driver; void *opaque; =20 - QCryptoCipher *cipher; + QCryptoCipher **ciphers; + size_t n_ciphers; + size_t n_free_ciphers; QCryptoIVGen *ivgen; + QemuMutex mutex; + QCryptoHashAlgorithm kdfhash; size_t niv; uint64_t payload_offset; /* In bytes */ @@ -46,6 +51,7 @@ struct QCryptoBlockDriver { QCryptoBlockReadFunc readfunc, void *opaque, unsigned int flags, + size_t n_threads, Error **errp); =20 int (*create)(QCryptoBlock *block, @@ -110,4 +116,12 @@ int qcrypto_block_encrypt_helper(QCryptoBlock *block, size_t len, Error **errp); =20 +int qcrypto_block_init_cipher(QCryptoBlock *block, + QCryptoCipherAlgorithm alg, + QCryptoCipherMode mode, + const uint8_t *key, size_t nkey, + size_t n_threads, Error **errp); + +void qcrypto_block_free_cipher(QCryptoBlock *block); + #endif /* QCRYPTO_BLOCKPRIV_H */ diff --git a/include/crypto/block.h b/include/crypto/block.h index cd18f46d56..e729d5bd66 100644 --- a/include/crypto/block.h +++ b/include/crypto/block.h @@ -75,6 +75,7 @@ typedef enum { * @readfunc: callback for reading data from the volume * @opaque: data to pass to @readfunc * @flags: bitmask of QCryptoBlockOpenFlags values + * @n_threads: allow concurrent I/O from up to @n_threads threads * @errp: pointer to a NULL-initialized error object * * Create a new block encryption object for an existing @@ -107,6 +108,7 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOption= s *options, QCryptoBlockReadFunc readfunc, void *opaque, unsigned int flags, + size_t n_threads, Error **errp); =20 /** diff --git a/block/crypto.c b/block/crypto.c index 33ee01bebd..f0a5f6b987 100644 --- a/block/crypto.c +++ b/block/crypto.c @@ -229,6 +229,7 @@ static int block_crypto_open_generic(QCryptoBlockFormat= format, block_crypto_read_func, bs, cflags, + 1, errp); =20 if (!crypto->block) { diff --git a/block/qcow.c b/block/qcow.c index 4518cb4c35..0a235bf393 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -213,7 +213,7 @@ static int qcow_open(BlockDriverState *bs, QDict *optio= ns, int flags, cflags |=3D QCRYPTO_BLOCK_OPEN_NO_IO; } s->crypto =3D qcrypto_block_open(crypto_opts, "encrypt.", - NULL, NULL, cflags, errp); + NULL, NULL, cflags, 1, errp); if (!s->crypto) { ret =3D -EINVAL; goto fail; diff --git a/block/qcow2.c b/block/qcow2.c index 991d6ac91b..bc8868c36a 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -294,7 +294,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, = uint64_t start_offset, } s->crypto =3D qcrypto_block_open(s->crypto_opts, "encrypt.", qcow2_crypto_hdr_read_func, - bs, cflags, errp); + bs, cflags, 1, errp); if (!s->crypto) { return -EINVAL; } @@ -1445,7 +1445,7 @@ static int coroutine_fn qcow2_do_open(BlockDriverStat= e *bs, QDict *options, cflags |=3D QCRYPTO_BLOCK_OPEN_NO_IO; } s->crypto =3D qcrypto_block_open(s->crypto_opts, "encrypt.", - NULL, NULL, cflags, errp); + NULL, NULL, cflags, 1, errp); if (!s->crypto) { ret =3D -EINVAL; goto fail; diff --git a/crypto/block-luks.c b/crypto/block-luks.c index e486e7ee94..6bac79c3ab 100644 --- a/crypto/block-luks.c +++ b/crypto/block-luks.c @@ -636,6 +636,7 @@ qcrypto_block_luks_open(QCryptoBlock *block, QCryptoBlockReadFunc readfunc, void *opaque, unsigned int flags, + size_t n_threads, Error **errp) { QCryptoBlockLUKS *luks; @@ -836,11 +837,10 @@ qcrypto_block_luks_open(QCryptoBlock *block, goto fail; } =20 - block->cipher =3D qcrypto_cipher_new(cipheralg, - ciphermode, - masterkey, masterkeylen, - errp); - if (!block->cipher) { + ret =3D qcrypto_block_init_cipher(block, cipheralg, ciphermode, + masterkey, masterkeylen, n_threads, + errp); + if (ret < 0) { ret =3D -ENOTSUP; goto fail; } @@ -863,7 +863,7 @@ qcrypto_block_luks_open(QCryptoBlock *block, =20 fail: g_free(masterkey); - qcrypto_cipher_free(block->cipher); + qcrypto_block_free_cipher(block); qcrypto_ivgen_free(block->ivgen); g_free(luks); g_free(password); @@ -1030,11 +1030,9 @@ qcrypto_block_luks_create(QCryptoBlock *block, =20 =20 /* Setup the block device payload encryption objects */ - block->cipher =3D qcrypto_cipher_new(luks_opts.cipher_alg, - luks_opts.cipher_mode, - masterkey, luks->header.key_bytes, - errp); - if (!block->cipher) { + if (qcrypto_block_init_cipher(block, luks_opts.cipher_alg, + luks_opts.cipher_mode, masterkey, + luks->header.key_bytes, 1, errp) < 0) { goto error; } =20 @@ -1341,7 +1339,7 @@ qcrypto_block_luks_create(QCryptoBlock *block, qcrypto_ivgen_free(ivgen); qcrypto_cipher_free(cipher); =20 - qcrypto_cipher_free(block->cipher); + qcrypto_block_free_cipher(block); qcrypto_ivgen_free(block->ivgen); =20 g_free(luks); diff --git a/crypto/block-qcow.c b/crypto/block-qcow.c index 36bf5f09b7..cefb3b2a7b 100644 --- a/crypto/block-qcow.c +++ b/crypto/block-qcow.c @@ -44,6 +44,7 @@ qcrypto_block_qcow_has_format(const uint8_t *buf G_GNUC_U= NUSED, static int qcrypto_block_qcow_init(QCryptoBlock *block, const char *keysecret, + size_t n_threads, Error **errp) { char *password; @@ -71,11 +72,11 @@ qcrypto_block_qcow_init(QCryptoBlock *block, goto fail; } =20 - block->cipher =3D qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_128, - QCRYPTO_CIPHER_MODE_CBC, - keybuf, G_N_ELEMENTS(keybuf), - errp); - if (!block->cipher) { + ret =3D qcrypto_block_init_cipher(block, QCRYPTO_CIPHER_ALG_AES_128, + QCRYPTO_CIPHER_MODE_CBC, + keybuf, G_N_ELEMENTS(keybuf), + n_threads, errp); + if (ret < 0) { ret =3D -ENOTSUP; goto fail; } @@ -86,7 +87,7 @@ qcrypto_block_qcow_init(QCryptoBlock *block, return 0; =20 fail: - qcrypto_cipher_free(block->cipher); + qcrypto_block_free_cipher(block); qcrypto_ivgen_free(block->ivgen); return ret; } @@ -99,6 +100,7 @@ qcrypto_block_qcow_open(QCryptoBlock *block, QCryptoBlockReadFunc readfunc G_GNUC_UNUSED, void *opaque G_GNUC_UNUSED, unsigned int flags, + size_t n_threads, Error **errp) { if (flags & QCRYPTO_BLOCK_OPEN_NO_IO) { @@ -112,8 +114,8 @@ qcrypto_block_qcow_open(QCryptoBlock *block, optprefix ? optprefix : ""); return -1; } - return qcrypto_block_qcow_init(block, - options->u.qcow.key_secret, errp); + return qcrypto_block_qcow_init(block, options->u.qcow.key_secret, + n_threads, errp); } } =20 @@ -133,7 +135,7 @@ qcrypto_block_qcow_create(QCryptoBlock *block, return -1; } /* QCow2 has no special header, since everything is hardwired */ - return qcrypto_block_qcow_init(block, options->u.qcow.key_secret, errp= ); + return qcrypto_block_qcow_init(block, options->u.qcow.key_secret, 1, e= rrp); } =20 =20 diff --git a/crypto/block.c b/crypto/block.c index 3fe3de2ef8..d70d401f87 100644 --- a/crypto/block.c +++ b/crypto/block.c @@ -52,6 +52,7 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions = *options, QCryptoBlockReadFunc readfunc, void *opaque, unsigned int flags, + size_t n_threads, Error **errp) { QCryptoBlock *block =3D g_new0(QCryptoBlock, 1); @@ -69,11 +70,14 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOption= s *options, block->driver =3D qcrypto_block_drivers[options->format]; =20 if (block->driver->open(block, options, optprefix, - readfunc, opaque, flags, errp) < 0) { + readfunc, opaque, flags, n_threads, errp) < 0) + { g_free(block); return NULL; } =20 + qemu_mutex_init(&block->mutex); + return block; } =20 @@ -105,6 +109,8 @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOp= tions *options, return NULL; } =20 + qemu_mutex_init(&block->mutex); + return block; } =20 @@ -148,12 +154,97 @@ int qcrypto_block_encrypt(QCryptoBlock *block, =20 QCryptoCipher *qcrypto_block_get_cipher(QCryptoBlock *block) { - return block->cipher; + /* Ciphers should be accessed through pop/push method to be thread-saf= e. + * Better, they should not be accessed externally at all (note, that + * pop/push are static functions) + * This function is used only in test with one thread (it's safe to sk= ip + * pop/push interface), so it's enough to assert it here: + */ + assert(block->n_ciphers <=3D 1); + return block->ciphers ? block->ciphers[0] : NULL; +} + + +static QCryptoCipher *qcrypto_block_pop_cipher(QCryptoBlock *block) +{ + QCryptoCipher *cipher; + + qemu_mutex_lock(&block->mutex); + + assert(block->n_free_ciphers > 0); + block->n_free_ciphers--; + cipher =3D block->ciphers[block->n_free_ciphers]; + + qemu_mutex_unlock(&block->mutex); + + return cipher; +} + + +static void qcrypto_block_push_cipher(QCryptoBlock *block, + QCryptoCipher *cipher) +{ + qemu_mutex_lock(&block->mutex); + + assert(block->n_free_ciphers < block->n_ciphers); + block->ciphers[block->n_free_ciphers] =3D cipher; + block->n_free_ciphers++; + + qemu_mutex_unlock(&block->mutex); +} + + +int qcrypto_block_init_cipher(QCryptoBlock *block, + QCryptoCipherAlgorithm alg, + QCryptoCipherMode mode, + const uint8_t *key, size_t nkey, + size_t n_threads, Error **errp) +{ + size_t i; + + assert(!block->ciphers && !block->n_ciphers && !block->n_free_ciphers); + + block->ciphers =3D g_new0(QCryptoCipher *, n_threads); + + for (i =3D 0; i < n_threads; i++) { + block->ciphers[i] =3D qcrypto_cipher_new(alg, mode, key, nkey, err= p); + if (!block->ciphers[i]) { + qcrypto_block_free_cipher(block); + return -1; + } + block->n_ciphers++; + block->n_free_ciphers++; + } + + return 0; } =20 =20 +void qcrypto_block_free_cipher(QCryptoBlock *block) +{ + size_t i; + + if (!block->ciphers) { + return; + } + + assert(block->n_ciphers =3D=3D block->n_free_ciphers); + + for (i =3D 0; i < block->n_ciphers; i++) { + qcrypto_cipher_free(block->ciphers[i]); + } + + g_free(block->ciphers); + block->ciphers =3D NULL; + block->n_ciphers =3D block->n_free_ciphers =3D 0; +} + QCryptoIVGen *qcrypto_block_get_ivgen(QCryptoBlock *block) { + /* ivgen should be accessed under mutex. However, this function is use= d only + * in test with one thread, so it's enough to assert it here: + */ + assert(block->n_ciphers <=3D 1); return block->ivgen; } =20 @@ -184,8 +275,9 @@ void qcrypto_block_free(QCryptoBlock *block) =20 block->driver->cleanup(block); =20 - qcrypto_cipher_free(block->cipher); + qcrypto_block_free_cipher(block); qcrypto_ivgen_free(block->ivgen); + qemu_mutex_destroy(&block->mutex); g_free(block); } =20 @@ -199,6 +291,7 @@ typedef int (*QCryptoCipherEncDecFunc)(QCryptoCipher *c= ipher, static int do_qcrypto_block_cipher_encdec(QCryptoCipher *cipher, size_t niv, QCryptoIVGen *ivgen, + QemuMutex *ivgen_mutex, int sectorsize, uint64_t offset, uint8_t *buf, @@ -218,10 +311,15 @@ static int do_qcrypto_block_cipher_encdec(QCryptoCiph= er *cipher, while (len > 0) { size_t nbytes; if (niv) { - if (qcrypto_ivgen_calculate(ivgen, - startsector, - iv, niv, - errp) < 0) { + if (ivgen_mutex) { + qemu_mutex_lock(ivgen_mutex); + } + ret =3D qcrypto_ivgen_calculate(ivgen, startsector, iv, niv, e= rrp); + if (ivgen_mutex) { + qemu_mutex_unlock(ivgen_mutex); + } + + if (ret < 0) { goto cleanup; } =20 @@ -258,7 +356,7 @@ int qcrypto_block_cipher_decrypt_helper(QCryptoCipher *= cipher, size_t len, Error **errp) { - return do_qcrypto_block_cipher_encdec(cipher, niv, ivgen, sectorsize, + return do_qcrypto_block_cipher_encdec(cipher, niv, ivgen, NULL, sector= size, offset, buf, len, qcrypto_cipher_decrypt, errp); } @@ -273,12 +371,11 @@ int qcrypto_block_cipher_encrypt_helper(QCryptoCipher= *cipher, size_t len, Error **errp) { - return do_qcrypto_block_cipher_encdec(cipher, niv, ivgen, sectorsize, + return do_qcrypto_block_cipher_encdec(cipher, niv, ivgen, NULL, sector= size, offset, buf, len, qcrypto_cipher_encrypt, errp); } =20 - int qcrypto_block_decrypt_helper(QCryptoBlock *block, int sectorsize, uint64_t offset, @@ -286,12 +383,17 @@ int qcrypto_block_decrypt_helper(QCryptoBlock *block, size_t len, Error **errp) { - return do_qcrypto_block_cipher_encdec(block->cipher, block->niv, - block->ivgen, - sectorsize, offset, buf, len, - qcrypto_cipher_decrypt, errp); -} + int ret; + QCryptoCipher *cipher =3D qcrypto_block_pop_cipher(block); =20 + ret =3D do_qcrypto_block_cipher_encdec(cipher, block->niv, block->ivge= n, + &block->mutex, sectorsize, offset= , buf, + len, qcrypto_cipher_decrypt, errp= ); + + qcrypto_block_push_cipher(block, cipher); + + return ret; +} =20 int qcrypto_block_encrypt_helper(QCryptoBlock *block, int sectorsize, @@ -300,8 +402,14 @@ int qcrypto_block_encrypt_helper(QCryptoBlock *block, size_t len, Error **errp) { - return do_qcrypto_block_cipher_encdec(block->cipher, block->niv, - block->ivgen, - sectorsize, offset, buf, len, - qcrypto_cipher_encrypt, errp); + int ret; + QCryptoCipher *cipher =3D qcrypto_block_pop_cipher(block); + + ret =3D do_qcrypto_block_cipher_encdec(cipher, block->niv, block->ivge= n, + &block->mutex, sectorsize, offset= , buf, + len, qcrypto_cipher_encrypt, errp= ); + + qcrypto_block_push_cipher(block, cipher); + + return ret; } diff --git a/tests/test-crypto-block.c b/tests/test-crypto-block.c index fae4ffc453..d309d044ef 100644 --- a/tests/test-crypto-block.c +++ b/tests/test-crypto-block.c @@ -305,6 +305,7 @@ static void test_block(gconstpointer opaque) test_block_read_func, &header, 0, + 1, NULL); g_assert(blk =3D=3D NULL); =20 @@ -313,6 +314,7 @@ static void test_block(gconstpointer opaque) test_block_read_func, &header, QCRYPTO_BLOCK_OPEN_NO_IO, + 1, &error_abort); =20 g_assert(qcrypto_block_get_cipher(blk) =3D=3D NULL); @@ -327,6 +329,7 @@ static void test_block(gconstpointer opaque) test_block_read_func, &header, 0, + 1, &error_abort); g_assert(blk); =20 --=20 2.18.0