From nobody Wed Apr 24 13:17:09 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 1543949415807192.5160622001821; Tue, 4 Dec 2018 10:50:15 -0800 (PST) Received: from localhost ([::1]:58523 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gUFlu-0007N2-C6 for importer@patchew.org; Tue, 04 Dec 2018 13:50:14 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50439) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gUFiv-00041N-Fc for qemu-devel@nongnu.org; Tue, 04 Dec 2018 13:47:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gUFiq-0001E8-34 for qemu-devel@nongnu.org; Tue, 04 Dec 2018 13:47:08 -0500 Received: from relay.sw.ru ([185.231.240.75]:50666) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gUFip-0001Cu-QZ; Tue, 04 Dec 2018 13:47:04 -0500 Received: from [10.28.8.145] (helo=kvm.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1gUFik-0001hc-TK; Tue, 04 Dec 2018 21:46:59 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Tue, 4 Dec 2018 21:46:53 +0300 Message-Id: <20181204184657.78028-2-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20181204184657.78028-1-vsementsov@virtuozzo.com> References: <20181204184657.78028-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 for-3.1? 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, den@openvz.org, vsementsov@virtuozzo.com, mreitz@redhat.com 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" Free block->cipher and block->ivgen on error path. Signed-off-by: Vladimir Sementsov-Ogievskiy --- 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 Wed Apr 24 13:17:09 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 1543949459164506.09423415106346; Tue, 4 Dec 2018 10:50:59 -0800 (PST) Received: from localhost ([::1]:58529 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gUFmb-0007x0-Ra for importer@patchew.org; Tue, 04 Dec 2018 13:50:57 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50437) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gUFiv-00041M-EC for qemu-devel@nongnu.org; Tue, 04 Dec 2018 13:47:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gUFip-0001Dg-UQ for qemu-devel@nongnu.org; Tue, 04 Dec 2018 13:47:08 -0500 Received: from relay.sw.ru ([185.231.240.75]:50664) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gUFip-0001Cv-Jp; Tue, 04 Dec 2018 13:47:03 -0500 Received: from [10.28.8.145] (helo=kvm.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1gUFil-0001hc-2K; Tue, 04 Dec 2018 21:46:59 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Tue, 4 Dec 2018 21:46:54 +0300 Message-Id: <20181204184657.78028-3-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20181204184657.78028-1-vsementsov@virtuozzo.com> References: <20181204184657.78028-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 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, den@openvz.org, vsementsov@virtuozzo.com, mreitz@redhat.com 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 --- crypto/block.c | 81 +++++++++++++++++++------------------------------- 1 file changed, 31 insertions(+), 50 deletions(-) diff --git a/crypto/block.c b/crypto/block.c index e59d1140fe..f4101f0841 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 (*QCryptoCipherEncryptFunc)(QCryptoCipher *cipher, + const void *in, + void *out, + size_t len, + Error **errp); + +static int do_qcrypto_block_encrypt(QCryptoCipher *cipher, + size_t niv, + QCryptoIVGen *ivgen, + int sectorsize, + uint64_t offset, + uint8_t *buf, + size_t len, + QCryptoCipherEncryptFunc 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; - } - - if (qcrypto_cipher_setiv(cipher, - iv, niv, - errp) < 0) { - goto cleanup; - } - } - - nbytes =3D len > sectorsize ? sectorsize : len; - if (qcrypto_cipher_encrypt(cipher, buf, buf, - nbytes, errp) < 0) { - goto cleanup; - } + return do_qcrypto_block_encrypt(cipher, niv, ivgen, sectorsize, offset, + buf, len, qcrypto_cipher_decrypt, errp= ); +} =20 - startsector++; - buf +=3D nbytes; - len -=3D nbytes; - } =20 - 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_encrypt(cipher, niv, ivgen, sectorsize, offset, + buf, len, qcrypto_cipher_encrypt, errp= ); } --=20 2.18.0 From nobody Wed Apr 24 13:17:09 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 1543949585478263.252463051713; Tue, 4 Dec 2018 10:53:05 -0800 (PST) Received: from localhost ([::1]:58545 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gUFoe-00018R-AM for importer@patchew.org; Tue, 04 Dec 2018 13:53:04 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50440) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gUFiv-00041O-FW for qemu-devel@nongnu.org; Tue, 04 Dec 2018 13:47:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gUFip-0001Dh-UH for qemu-devel@nongnu.org; Tue, 04 Dec 2018 13:47:08 -0500 Received: from relay.sw.ru ([185.231.240.75]:50656) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gUFip-0001Cs-Jn; Tue, 04 Dec 2018 13:47:03 -0500 Received: from [10.28.8.145] (helo=kvm.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1gUFil-0001hc-G8; Tue, 04 Dec 2018 21:46:59 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Tue, 4 Dec 2018 21:46:55 +0300 Message-Id: <20181204184657.78028-4-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20181204184657.78028-1-vsementsov@virtuozzo.com> References: <20181204184657.78028-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 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, den@openvz.org, vsementsov@virtuozzo.com, mreitz@redhat.com 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 --- crypto/blockpriv.h | 34 +++++++++++++------------- crypto/block-luks.c | 44 +++++++++++++++++----------------- crypto/block-qcow.c | 16 ++++++------- crypto/block.c | 58 ++++++++++++++++++++++----------------------- 4 files changed, 76 insertions(+), 76 deletions(-) diff --git a/crypto/blockpriv.h b/crypto/blockpriv.h index 41840abcec..347a7c010a 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_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_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..72dd51051d 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_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_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_cipher_decrypt_helper(block->cipher, + block->niv, block->ivgen, + QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, + 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_cipher_encrypt_helper(block->cipher, + block->niv, block->ivgen, + QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, + offset, buf, len, errp); } =20 =20 diff --git a/crypto/block-qcow.c b/crypto/block-qcow.c index 7606231e79..536ef4ee98 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_cipher_decrypt_helper(block->cipher, + block->niv, block->ivgen, + QCRYPTO_BLOCK_QCOW_SECTOR_SIZE, + 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_cipher_encrypt_helper(block->cipher, + block->niv, block->ivgen, + QCRYPTO_BLOCK_QCOW_SECTOR_SIZE, + offset, buf, len, errp); } =20 =20 diff --git a/crypto/block.c b/crypto/block.c index f4101f0841..540b27e581 100644 --- a/crypto/block.c +++ b/crypto/block.c @@ -196,15 +196,15 @@ typedef int (*QCryptoCipherEncryptFunc)(QCryptoCipher= *cipher, size_t len, Error **errp); =20 -static int do_qcrypto_block_encrypt(QCryptoCipher *cipher, - size_t niv, - QCryptoIVGen *ivgen, - int sectorsize, - uint64_t offset, - uint8_t *buf, - size_t len, - QCryptoCipherEncryptFunc func, - Error **errp) +static int do_qcrypto_cipher_encrypt(QCryptoCipher *cipher, + size_t niv, + QCryptoIVGen *ivgen, + int sectorsize, + uint64_t offset, + uint8_t *buf, + size_t len, + QCryptoCipherEncryptFunc func, + Error **errp) { uint8_t *iv; int ret =3D -1; @@ -249,29 +249,29 @@ static int do_qcrypto_block_encrypt(QCryptoCipher *ci= pher, } =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_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_encrypt(cipher, niv, ivgen, sectorsize, offset, - buf, len, qcrypto_cipher_decrypt, errp= ); + return do_qcrypto_cipher_encrypt(cipher, niv, ivgen, sectorsize, offse= t, + buf, len, qcrypto_cipher_decrypt, err= p); } =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_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_encrypt(cipher, niv, ivgen, sectorsize, offset, - buf, len, qcrypto_cipher_encrypt, errp= ); + return do_qcrypto_cipher_encrypt(cipher, niv, ivgen, sectorsize, offse= t, + buf, len, qcrypto_cipher_encrypt, err= p); } --=20 2.18.0 From nobody Wed Apr 24 13:17:09 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 15439496283886.723824188139361; Tue, 4 Dec 2018 10:53:48 -0800 (PST) Received: from localhost ([::1]:58546 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gUFpE-0002Ak-49 for importer@patchew.org; Tue, 04 Dec 2018 13:53:40 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50442) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gUFiv-00041Q-Fa for qemu-devel@nongnu.org; Tue, 04 Dec 2018 13:47:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gUFiq-0001E2-1t for qemu-devel@nongnu.org; Tue, 04 Dec 2018 13:47:08 -0500 Received: from relay.sw.ru ([185.231.240.75]:50658) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gUFip-0001Ct-NK; Tue, 04 Dec 2018 13:47:03 -0500 Received: from [10.28.8.145] (helo=kvm.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1gUFil-0001hc-P2; Tue, 04 Dec 2018 21:46:59 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Tue, 4 Dec 2018 21:46:56 +0300 Message-Id: <20181204184657.78028-5-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20181204184657.78028-1-vsementsov@virtuozzo.com> References: <20181204184657.78028-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 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, den@openvz.org, vsementsov@virtuozzo.com, mreitz@redhat.com 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" 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 --- crypto/blockpriv.h | 14 ++++++++++++++ crypto/block-luks.c | 14 ++++++-------- crypto/block-qcow.c | 14 ++++++-------- crypto/block.c | 26 ++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 16 deletions(-) diff --git a/crypto/blockpriv.h b/crypto/blockpriv.h index 347a7c010a..e9fe3e5687 100644 --- a/crypto/blockpriv.h +++ b/crypto/blockpriv.h @@ -96,4 +96,18 @@ int qcrypto_cipher_encrypt_helper(QCryptoCipher *cipher, 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 72dd51051d..bbffd80fff 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_cipher_decrypt_helper(block->cipher, - block->niv, block->ivgen, - QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, - 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_cipher_encrypt_helper(block->cipher, - block->niv, block->ivgen, - QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, - 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 536ef4ee98..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_cipher_decrypt_helper(block->cipher, - block->niv, block->ivgen, - QCRYPTO_BLOCK_QCOW_SECTOR_SIZE, - 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_cipher_encrypt_helper(block->cipher, - block->niv, block->ivgen, - QCRYPTO_BLOCK_QCOW_SECTOR_SIZE, - 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 540b27e581..3edd9ec251 100644 --- a/crypto/block.c +++ b/crypto/block.c @@ -275,3 +275,29 @@ int qcrypto_cipher_encrypt_helper(QCryptoCipher *ciphe= r, return do_qcrypto_cipher_encrypt(cipher, niv, ivgen, sectorsize, offse= t, buf, len, qcrypto_cipher_encrypt, err= p); } + + +int qcrypto_block_decrypt_helper(QCryptoBlock *block, + int sectorsize, + uint64_t offset, + uint8_t *buf, + size_t len, + Error **errp) +{ + return do_qcrypto_cipher_encrypt(block->cipher, block->niv, block->ivg= en, + 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_cipher_encrypt(block->cipher, block->niv, block->ivg= en, + sectorsize, offset, buf, len, + qcrypto_cipher_encrypt, errp); +} --=20 2.18.0 From nobody Wed Apr 24 13:17:09 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 1543949380989547.5091931744067; Tue, 4 Dec 2018 10:49:40 -0800 (PST) Received: from localhost ([::1]:58519 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gUFlL-0006yU-HO for importer@patchew.org; Tue, 04 Dec 2018 13:49:39 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50443) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gUFiv-00041R-Fj for qemu-devel@nongnu.org; Tue, 04 Dec 2018 13:47:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gUFiq-0001Dx-1H for qemu-devel@nongnu.org; Tue, 04 Dec 2018 13:47:08 -0500 Received: from relay.sw.ru ([185.231.240.75]:50672) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gUFip-0001Cx-J5; Tue, 04 Dec 2018 13:47:03 -0500 Received: from [10.28.8.145] (helo=kvm.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1gUFil-0001hc-Vf; Tue, 04 Dec 2018 21:47:00 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Tue, 4 Dec 2018 21:46:57 +0300 Message-Id: <20181204184657.78028-6-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20181204184657.78028-1-vsementsov@virtuozzo.com> References: <20181204184657.78028-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 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, den@openvz.org, vsementsov@virtuozzo.com, mreitz@redhat.com 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 --- crypto/blockpriv.h | 16 ++++- include/crypto/block.h | 16 ++++- block/crypto.c | 1 + block/qcow.c | 2 +- block/qcow2.c | 4 +- crypto/block-luks.c | 25 +++---- crypto/block-qcow.c | 20 +++--- crypto/block.c | 135 ++++++++++++++++++++++++++++++++------ tests/test-crypto-block.c | 2 + 9 files changed, 176 insertions(+), 45 deletions(-) diff --git a/crypto/blockpriv.h b/crypto/blockpriv.h index e9fe3e5687..86dae49210 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; + int n_ciphers; + int 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, + int 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, + int 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..d54044323a 100644 --- a/include/crypto/block.h +++ b/include/crypto/block.h @@ -75,6 +75,8 @@ typedef enum { * @readfunc: callback for reading data from the volume * @opaque: data to pass to @readfunc * @flags: bitmask of QCryptoBlockOpenFlags values + * @n_threads: prepare block to multi tasking with up to + * @n_threads threads * @errp: pointer to a NULL-initialized error object * * Create a new block encryption object for an existing @@ -107,6 +109,7 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOption= s *options, QCryptoBlockReadFunc readfunc, void *opaque, unsigned int flags, + int n_threads, Error **errp); =20 /** @@ -202,12 +205,23 @@ int qcrypto_block_encrypt(QCryptoBlock *block, * qcrypto_block_get_cipher: * @block: the block encryption object * - * Get the cipher to use for payload encryption + * Get the cipher to use for payload encryption. Must be paired with + * qcrypto_block_put_cipher. * * Returns: the cipher object */ QCryptoCipher *qcrypto_block_get_cipher(QCryptoBlock *block); =20 +/** + * qcrypto_block_put_cipher: + * @block: the block encryption object + * + * Put cipher back to the block. Must follow qcrypto_block_get_cipher. + * + * Returns: the cipher object + */ +void qcrypto_block_put_cipher(QCryptoBlock *block, QCryptoCipher *cipher); + /** * qcrypto_block_get_ivgen: * @block: the block encryption object 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 bbffd80fff..41fb0aa2e7 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, + int 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); @@ -888,6 +888,7 @@ qcrypto_block_luks_create(QCryptoBlock *block, void *opaque, Error **errp) { + int ret; QCryptoBlockLUKS *luks; QCryptoBlockCreateOptionsLUKS luks_opts; Error *local_err =3D NULL; @@ -1030,11 +1031,11 @@ 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) { + ret =3D qcrypto_block_init_cipher(block, luks_opts.cipher_alg, + luks_opts.cipher_mode, + masterkey, luks->header.key_bytes, + 1, errp); + if (ret < 0) { goto error; } =20 @@ -1341,7 +1342,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..e668145561 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, + int 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, + int 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 3edd9ec251..58c2ba1987 100644 --- a/crypto/block.c +++ b/crypto/block.c @@ -52,10 +52,13 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOption= s *options, QCryptoBlockReadFunc readfunc, void *opaque, unsigned int flags, + int n_threads, Error **errp) { QCryptoBlock *block =3D g_new0(QCryptoBlock, 1); =20 + qemu_mutex_init(&block->mutex); + block->format =3D options->format; =20 if (options->format >=3D G_N_ELEMENTS(qcrypto_block_drivers) || @@ -69,7 +72,8 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions = *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; } @@ -87,6 +91,8 @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOpti= ons *options, { QCryptoBlock *block =3D g_new0(QCryptoBlock, 1); =20 + qemu_mutex_init(&block->mutex); + block->format =3D options->format; =20 if (options->format >=3D G_N_ELEMENTS(qcrypto_block_drivers) || @@ -148,12 +154,83 @@ int qcrypto_block_encrypt(QCryptoBlock *block, =20 QCryptoCipher *qcrypto_block_get_cipher(QCryptoBlock *block) { - return block->cipher; + 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; +} + + +void qcrypto_block_put_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); } =20 =20 +int qcrypto_block_init_cipher(QCryptoBlock *block, + QCryptoCipherAlgorithm alg, + QCryptoCipherMode mode, + const uint8_t *key, size_t nkey, + int n_threads, Error **errp) +{ + int 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; +} + + +void qcrypto_block_free_cipher(QCryptoBlock *block) +{ + int 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=3D 1); return block->ivgen; } =20 @@ -184,7 +261,7 @@ 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); g_free(block); } @@ -199,6 +276,7 @@ typedef int (*QCryptoCipherEncryptFunc)(QCryptoCipher *= cipher, static int do_qcrypto_cipher_encrypt(QCryptoCipher *cipher, size_t niv, QCryptoIVGen *ivgen, + QemuMutex *ivgen_mutex, int sectorsize, uint64_t offset, uint8_t *buf, @@ -218,10 +296,15 @@ static int do_qcrypto_cipher_encrypt(QCryptoCipher *c= ipher, 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,8 +341,9 @@ int qcrypto_cipher_decrypt_helper(QCryptoCipher *cipher, size_t len, Error **errp) { - return do_qcrypto_cipher_encrypt(cipher, niv, ivgen, sectorsize, offse= t, - buf, len, qcrypto_cipher_decrypt, err= p); + return do_qcrypto_cipher_encrypt(cipher, niv, ivgen, NULL, sectorsize, + offset, buf, len, qcrypto_cipher_decr= ypt, + errp); } =20 =20 @@ -272,11 +356,11 @@ int qcrypto_cipher_encrypt_helper(QCryptoCipher *ciph= er, size_t len, Error **errp) { - return do_qcrypto_cipher_encrypt(cipher, niv, ivgen, sectorsize, offse= t, - buf, len, qcrypto_cipher_encrypt, err= p); + return do_qcrypto_cipher_encrypt(cipher, niv, ivgen, NULL, sectorsize, + offset, buf, len, qcrypto_cipher_encr= ypt, + errp); } =20 - int qcrypto_block_decrypt_helper(QCryptoBlock *block, int sectorsize, uint64_t offset, @@ -284,11 +368,17 @@ int qcrypto_block_decrypt_helper(QCryptoBlock *block, size_t len, Error **errp) { - return do_qcrypto_cipher_encrypt(block->cipher, block->niv, block->ivg= en, - sectorsize, offset, buf, len, - qcrypto_cipher_decrypt, errp); -} + int ret; + QCryptoCipher *cipher =3D qcrypto_block_get_cipher(block); =20 + ret =3D do_qcrypto_cipher_encrypt(cipher, block->niv, block->ivgen, + &block->mutex, sectorsize, offset, buf= , len, + qcrypto_cipher_decrypt, errp); + + qcrypto_block_put_cipher(block, cipher); + + return ret; +} =20 int qcrypto_block_encrypt_helper(QCryptoBlock *block, int sectorsize, @@ -297,7 +387,14 @@ int qcrypto_block_encrypt_helper(QCryptoBlock *block, size_t len, Error **errp) { - return do_qcrypto_cipher_encrypt(block->cipher, block->niv, block->ivg= en, - sectorsize, offset, buf, len, - qcrypto_cipher_encrypt, errp); + int ret; + QCryptoCipher *cipher =3D qcrypto_block_get_cipher(block); + + ret =3D do_qcrypto_cipher_encrypt(cipher, block->niv, block->ivgen, + &block->mutex, sectorsize, offset, buf= , len, + qcrypto_cipher_encrypt, errp); + + qcrypto_block_put_cipher(block, cipher); + + return ret; } diff --git a/tests/test-crypto-block.c b/tests/test-crypto-block.c index fae4ffc453..097497b5bf 100644 --- a/tests/test-crypto-block.c +++ b/tests/test-crypto-block.c @@ -269,6 +269,8 @@ static void test_block_assert_setup(const struct QCrypt= oBlockTestData *data, qcrypto_ivgen_get_algorithm(ivgen)); g_assert_cmpint(data->ivgen_hash, =3D=3D, qcrypto_ivgen_get_hash(ivgen)); + + qcrypto_block_put_cipher(blk, cipher); } =20 =20 --=20 2.18.0