block: convert qcrypto_block_encrypt|decrypt to take bytes offset

Instead of sector offset, take the bytes offset when encrypting
or decrypting data.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Message-id: 20170927125340.12360-6-berrange@redhat.com
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
Daniel P. Berrange 2017-09-27 13:53:39 +01:00 committed by Max Reitz
parent a73466fbad
commit 4609742a49
9 changed files with 56 additions and 41 deletions

View File

@ -398,7 +398,6 @@ block_crypto_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
int ret = 0; int ret = 0;
uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block); uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block); uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block);
uint64_t sector_num = offset / sector_size;
assert(!flags); assert(!flags);
assert(payload_offset < INT64_MAX); assert(payload_offset < INT64_MAX);
@ -430,15 +429,14 @@ block_crypto_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
goto cleanup; goto cleanup;
} }
if (qcrypto_block_decrypt(crypto->block, sector_num, cipher_data, if (qcrypto_block_decrypt(crypto->block, offset + bytes_done,
cur_bytes, NULL) < 0) { cipher_data, cur_bytes, NULL) < 0) {
ret = -EIO; ret = -EIO;
goto cleanup; goto cleanup;
} }
qemu_iovec_from_buf(qiov, bytes_done, cipher_data, cur_bytes); qemu_iovec_from_buf(qiov, bytes_done, cipher_data, cur_bytes);
sector_num += cur_bytes / sector_size;
bytes -= cur_bytes; bytes -= cur_bytes;
bytes_done += cur_bytes; bytes_done += cur_bytes;
} }
@ -463,7 +461,6 @@ block_crypto_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
int ret = 0; int ret = 0;
uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block); uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block);
uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block); uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block);
uint64_t sector_num = offset / sector_size;
assert(!flags); assert(!flags);
assert(payload_offset < INT64_MAX); assert(payload_offset < INT64_MAX);
@ -488,8 +485,8 @@ block_crypto_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
qemu_iovec_to_buf(qiov, bytes_done, cipher_data, cur_bytes); qemu_iovec_to_buf(qiov, bytes_done, cipher_data, cur_bytes);
if (qcrypto_block_encrypt(crypto->block, sector_num, cipher_data, if (qcrypto_block_encrypt(crypto->block, offset + bytes_done,
cur_bytes, NULL) < 0) { cipher_data, cur_bytes, NULL) < 0) {
ret = -EIO; ret = -EIO;
goto cleanup; goto cleanup;
} }
@ -503,7 +500,6 @@ block_crypto_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
goto cleanup; goto cleanup;
} }
sector_num += cur_bytes / sector_size;
bytes -= cur_bytes; bytes -= cur_bytes;
bytes_done += cur_bytes; bytes_done += cur_bytes;
} }

View File

@ -478,7 +478,9 @@ static int get_cluster_offset(BlockDriverState *bs,
for(i = 0; i < s->cluster_sectors; i++) { for(i = 0; i < s->cluster_sectors; i++) {
if (i < n_start || i >= n_end) { if (i < n_start || i >= n_end) {
memset(s->cluster_data, 0x00, 512); memset(s->cluster_data, 0x00, 512);
if (qcrypto_block_encrypt(s->crypto, start_sect + i, if (qcrypto_block_encrypt(s->crypto,
(start_sect + i) *
BDRV_SECTOR_SIZE,
s->cluster_data, s->cluster_data,
BDRV_SECTOR_SIZE, BDRV_SECTOR_SIZE,
NULL) < 0) { NULL) < 0) {
@ -668,7 +670,8 @@ static coroutine_fn int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
} }
if (bs->encrypted) { if (bs->encrypted) {
assert(s->crypto); assert(s->crypto);
if (qcrypto_block_decrypt(s->crypto, sector_num, buf, if (qcrypto_block_decrypt(s->crypto,
sector_num * BDRV_SECTOR_SIZE, buf,
n * BDRV_SECTOR_SIZE, NULL) < 0) { n * BDRV_SECTOR_SIZE, NULL) < 0) {
ret = -EIO; ret = -EIO;
break; break;
@ -740,8 +743,8 @@ static coroutine_fn int qcow_co_writev(BlockDriverState *bs, int64_t sector_num,
} }
if (bs->encrypted) { if (bs->encrypted) {
assert(s->crypto); assert(s->crypto);
if (qcrypto_block_encrypt(s->crypto, sector_num, buf, if (qcrypto_block_encrypt(s->crypto, sector_num * BDRV_SECTOR_SIZE,
n * BDRV_SECTOR_SIZE, NULL) < 0) { buf, n * BDRV_SECTOR_SIZE, NULL) < 0) {
ret = -EIO; ret = -EIO;
break; break;
} }

View File

@ -446,15 +446,13 @@ static bool coroutine_fn do_perform_cow_encrypt(BlockDriverState *bs,
{ {
if (bytes && bs->encrypted) { if (bytes && bs->encrypted) {
BDRVQcow2State *s = bs->opaque; BDRVQcow2State *s = bs->opaque;
int64_t sector = (s->crypt_physical_offset ? int64_t offset = (s->crypt_physical_offset ?
(cluster_offset + offset_in_cluster) : (cluster_offset + offset_in_cluster) :
(src_cluster_offset + offset_in_cluster)) (src_cluster_offset + offset_in_cluster));
>> BDRV_SECTOR_BITS;
assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0); assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0);
assert((bytes & ~BDRV_SECTOR_MASK) == 0); assert((bytes & ~BDRV_SECTOR_MASK) == 0);
assert(s->crypto); assert(s->crypto);
if (qcrypto_block_encrypt(s->crypto, sector, buffer, if (qcrypto_block_encrypt(s->crypto, offset, buffer, bytes, NULL) < 0) {
bytes, NULL) < 0) {
return false; return false;
} }
} }

View File

@ -1811,7 +1811,7 @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
if (qcrypto_block_decrypt(s->crypto, if (qcrypto_block_decrypt(s->crypto,
(s->crypt_physical_offset ? (s->crypt_physical_offset ?
cluster_offset + offset_in_cluster : cluster_offset + offset_in_cluster :
offset) >> BDRV_SECTOR_BITS, offset),
cluster_data, cluster_data,
cur_bytes, cur_bytes,
NULL) < 0) { NULL) < 0) {
@ -1946,7 +1946,7 @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
if (qcrypto_block_encrypt(s->crypto, if (qcrypto_block_encrypt(s->crypto,
(s->crypt_physical_offset ? (s->crypt_physical_offset ?
cluster_offset + offset_in_cluster : cluster_offset + offset_in_cluster :
offset) >> BDRV_SECTOR_BITS, offset),
cluster_data, cluster_data,
cur_bytes, NULL) < 0) { cur_bytes, NULL) < 0) {
ret = -EIO; ret = -EIO;

View File

@ -1399,29 +1399,33 @@ static void qcrypto_block_luks_cleanup(QCryptoBlock *block)
static int static int
qcrypto_block_luks_decrypt(QCryptoBlock *block, qcrypto_block_luks_decrypt(QCryptoBlock *block,
uint64_t startsector, uint64_t offset,
uint8_t *buf, uint8_t *buf,
size_t len, size_t len,
Error **errp) Error **errp)
{ {
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, return qcrypto_block_decrypt_helper(block->cipher,
block->niv, block->ivgen, block->niv, block->ivgen,
QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE,
startsector, buf, len, errp); offset, buf, len, errp);
} }
static int static int
qcrypto_block_luks_encrypt(QCryptoBlock *block, qcrypto_block_luks_encrypt(QCryptoBlock *block,
uint64_t startsector, uint64_t offset,
uint8_t *buf, uint8_t *buf,
size_t len, size_t len,
Error **errp) Error **errp)
{ {
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, return qcrypto_block_encrypt_helper(block->cipher,
block->niv, block->ivgen, block->niv, block->ivgen,
QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE,
startsector, buf, len, errp); offset, buf, len, errp);
} }

View File

@ -143,29 +143,33 @@ qcrypto_block_qcow_cleanup(QCryptoBlock *block)
static int static int
qcrypto_block_qcow_decrypt(QCryptoBlock *block, qcrypto_block_qcow_decrypt(QCryptoBlock *block,
uint64_t startsector, uint64_t offset,
uint8_t *buf, uint8_t *buf,
size_t len, size_t len,
Error **errp) Error **errp)
{ {
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, return qcrypto_block_decrypt_helper(block->cipher,
block->niv, block->ivgen, block->niv, block->ivgen,
QCRYPTO_BLOCK_QCOW_SECTOR_SIZE, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE,
startsector, buf, len, errp); offset, buf, len, errp);
} }
static int static int
qcrypto_block_qcow_encrypt(QCryptoBlock *block, qcrypto_block_qcow_encrypt(QCryptoBlock *block,
uint64_t startsector, uint64_t offset,
uint8_t *buf, uint8_t *buf,
size_t len, size_t len,
Error **errp) Error **errp)
{ {
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, return qcrypto_block_encrypt_helper(block->cipher,
block->niv, block->ivgen, block->niv, block->ivgen,
QCRYPTO_BLOCK_QCOW_SECTOR_SIZE, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE,
startsector, buf, len, errp); offset, buf, len, errp);
} }

View File

@ -127,22 +127,22 @@ QCryptoBlockInfo *qcrypto_block_get_info(QCryptoBlock *block,
int qcrypto_block_decrypt(QCryptoBlock *block, int qcrypto_block_decrypt(QCryptoBlock *block,
uint64_t startsector, uint64_t offset,
uint8_t *buf, uint8_t *buf,
size_t len, size_t len,
Error **errp) Error **errp)
{ {
return block->driver->decrypt(block, startsector, buf, len, errp); return block->driver->decrypt(block, offset, buf, len, errp);
} }
int qcrypto_block_encrypt(QCryptoBlock *block, int qcrypto_block_encrypt(QCryptoBlock *block,
uint64_t startsector, uint64_t offset,
uint8_t *buf, uint8_t *buf,
size_t len, size_t len,
Error **errp) Error **errp)
{ {
return block->driver->encrypt(block, startsector, buf, len, errp); return block->driver->encrypt(block, offset, buf, len, errp);
} }
@ -194,13 +194,17 @@ int qcrypto_block_decrypt_helper(QCryptoCipher *cipher,
size_t niv, size_t niv,
QCryptoIVGen *ivgen, QCryptoIVGen *ivgen,
int sectorsize, int sectorsize,
uint64_t startsector, uint64_t offset,
uint8_t *buf, uint8_t *buf,
size_t len, size_t len,
Error **errp) Error **errp)
{ {
uint8_t *iv; uint8_t *iv;
int ret = -1; int ret = -1;
uint64_t startsector = offset / sectorsize;
assert(QEMU_IS_ALIGNED(offset, sectorsize));
assert(QEMU_IS_ALIGNED(len, sectorsize));
iv = niv ? g_new0(uint8_t, niv) : NULL; iv = niv ? g_new0(uint8_t, niv) : NULL;
@ -243,13 +247,17 @@ int qcrypto_block_encrypt_helper(QCryptoCipher *cipher,
size_t niv, size_t niv,
QCryptoIVGen *ivgen, QCryptoIVGen *ivgen,
int sectorsize, int sectorsize,
uint64_t startsector, uint64_t offset,
uint8_t *buf, uint8_t *buf,
size_t len, size_t len,
Error **errp) Error **errp)
{ {
uint8_t *iv; uint8_t *iv;
int ret = -1; int ret = -1;
uint64_t startsector = offset / sectorsize;
assert(QEMU_IS_ALIGNED(offset, sectorsize));
assert(QEMU_IS_ALIGNED(len, sectorsize));
iv = niv ? g_new0(uint8_t, niv) : NULL; iv = niv ? g_new0(uint8_t, niv) : NULL;

View File

@ -82,7 +82,7 @@ int qcrypto_block_decrypt_helper(QCryptoCipher *cipher,
size_t niv, size_t niv,
QCryptoIVGen *ivgen, QCryptoIVGen *ivgen,
int sectorsize, int sectorsize,
uint64_t startsector, uint64_t offset,
uint8_t *buf, uint8_t *buf,
size_t len, size_t len,
Error **errp); Error **errp);
@ -91,7 +91,7 @@ int qcrypto_block_encrypt_helper(QCryptoCipher *cipher,
size_t niv, size_t niv,
QCryptoIVGen *ivgen, QCryptoIVGen *ivgen,
int sectorsize, int sectorsize,
uint64_t startsector, uint64_t offset,
uint8_t *buf, uint8_t *buf,
size_t len, size_t len,
Error **errp); Error **errp);

View File

@ -161,18 +161,19 @@ QCryptoBlockInfo *qcrypto_block_get_info(QCryptoBlock *block,
/** /**
* @qcrypto_block_decrypt: * @qcrypto_block_decrypt:
* @block: the block encryption object * @block: the block encryption object
* @startsector: the sector from which @buf was read * @offset: the position at which @iov was read
* @buf: the buffer to decrypt * @buf: the buffer to decrypt
* @len: the length of @buf in bytes * @len: the length of @buf in bytes
* @errp: pointer to a NULL-initialized error object * @errp: pointer to a NULL-initialized error object
* *
* Decrypt @len bytes of cipher text in @buf, writing * Decrypt @len bytes of cipher text in @buf, writing
* plain text back into @buf * plain text back into @buf. @len and @offset must be
* a multiple of the encryption format sector size.
* *
* Returns 0 on success, -1 on failure * Returns 0 on success, -1 on failure
*/ */
int qcrypto_block_decrypt(QCryptoBlock *block, int qcrypto_block_decrypt(QCryptoBlock *block,
uint64_t startsector, uint64_t offset,
uint8_t *buf, uint8_t *buf,
size_t len, size_t len,
Error **errp); Error **errp);
@ -180,18 +181,19 @@ int qcrypto_block_decrypt(QCryptoBlock *block,
/** /**
* @qcrypto_block_encrypt: * @qcrypto_block_encrypt:
* @block: the block encryption object * @block: the block encryption object
* @startsector: the sector to which @buf will be written * @offset: the position at which @iov will be written
* @buf: the buffer to decrypt * @buf: the buffer to decrypt
* @len: the length of @buf in bytes * @len: the length of @buf in bytes
* @errp: pointer to a NULL-initialized error object * @errp: pointer to a NULL-initialized error object
* *
* Encrypt @len bytes of plain text in @buf, writing * Encrypt @len bytes of plain text in @buf, writing
* cipher text back into @buf * cipher text back into @buf. @len and @offset must be
* a multiple of the encryption format sector size.
* *
* Returns 0 on success, -1 on failure * Returns 0 on success, -1 on failure
*/ */
int qcrypto_block_encrypt(QCryptoBlock *block, int qcrypto_block_encrypt(QCryptoBlock *block,
uint64_t startsector, uint64_t offset,
uint8_t *buf, uint8_t *buf,
size_t len, size_t len,
Error **errp); Error **errp);