crypto: Modify the qcrypto_block_create to support creation flags
Expand the signature of qcrypto_block_create to enable the formation of LUKS volumes with detachable headers. To accomplish that, introduce QCryptoBlockCreateFlags to instruct the creation process to set the payload_offset_sector to 0. Signed-off-by: Hyman Huang <yong.huang@smartx.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
433957bb7f
commit
d74523a3b3
@ -369,6 +369,7 @@ block_crypto_co_create_generic(BlockDriverState *bs, int64_t size,
|
|||||||
block_crypto_create_init_func,
|
block_crypto_create_init_func,
|
||||||
block_crypto_create_write_func,
|
block_crypto_create_write_func,
|
||||||
&data,
|
&data,
|
||||||
|
0,
|
||||||
errp);
|
errp);
|
||||||
|
|
||||||
if (!crypto) {
|
if (!crypto) {
|
||||||
|
@ -885,7 +885,7 @@ qcow_co_create(BlockdevCreateOptions *opts, Error **errp)
|
|||||||
header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
|
header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
|
||||||
|
|
||||||
crypto = qcrypto_block_create(qcow_opts->encrypt, "encrypt.",
|
crypto = qcrypto_block_create(qcow_opts->encrypt, "encrypt.",
|
||||||
NULL, NULL, NULL, errp);
|
NULL, NULL, NULL, 0, errp);
|
||||||
if (!crypto) {
|
if (!crypto) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto exit;
|
goto exit;
|
||||||
|
@ -3216,7 +3216,7 @@ qcow2_set_up_encryption(BlockDriverState *bs,
|
|||||||
crypto = qcrypto_block_create(cryptoopts, "encrypt.",
|
crypto = qcrypto_block_create(cryptoopts, "encrypt.",
|
||||||
qcow2_crypto_hdr_init_func,
|
qcow2_crypto_hdr_init_func,
|
||||||
qcow2_crypto_hdr_write_func,
|
qcow2_crypto_hdr_write_func,
|
||||||
bs, errp);
|
bs, 0, errp);
|
||||||
if (!crypto) {
|
if (!crypto) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -1315,6 +1315,7 @@ qcrypto_block_luks_create(QCryptoBlock *block,
|
|||||||
const char *hash_alg;
|
const char *hash_alg;
|
||||||
g_autofree char *cipher_mode_spec = NULL;
|
g_autofree char *cipher_mode_spec = NULL;
|
||||||
uint64_t iters;
|
uint64_t iters;
|
||||||
|
uint64_t detached_header_size;
|
||||||
|
|
||||||
memcpy(&luks_opts, &options->u.luks, sizeof(luks_opts));
|
memcpy(&luks_opts, &options->u.luks, sizeof(luks_opts));
|
||||||
if (!luks_opts.has_iter_time) {
|
if (!luks_opts.has_iter_time) {
|
||||||
@ -1543,19 +1544,32 @@ qcrypto_block_luks_create(QCryptoBlock *block,
|
|||||||
slot->stripes = QCRYPTO_BLOCK_LUKS_STRIPES;
|
slot->stripes = QCRYPTO_BLOCK_LUKS_STRIPES;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The total size of the LUKS headers is the partition header + key
|
if (block->detached_header) {
|
||||||
|
/*
|
||||||
|
* For a detached LUKS header image, set the payload_offset_sector
|
||||||
|
* to 0 to specify the starting point for read/write
|
||||||
|
*/
|
||||||
|
luks->header.payload_offset_sector = 0;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* The total size of the LUKS headers is the partition header + key
|
||||||
* slot headers, rounded up to the nearest sector, combined with
|
* slot headers, rounded up to the nearest sector, combined with
|
||||||
* the size of each master key material region, also rounded up
|
* the size of each master key material region, also rounded up
|
||||||
* to the nearest sector */
|
* to the nearest sector
|
||||||
|
*/
|
||||||
luks->header.payload_offset_sector = header_sectors +
|
luks->header.payload_offset_sector = header_sectors +
|
||||||
QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS * split_key_sectors;
|
QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS * split_key_sectors;
|
||||||
|
}
|
||||||
|
|
||||||
block->sector_size = QCRYPTO_BLOCK_LUKS_SECTOR_SIZE;
|
block->sector_size = QCRYPTO_BLOCK_LUKS_SECTOR_SIZE;
|
||||||
block->payload_offset = luks->header.payload_offset_sector *
|
block->payload_offset = luks->header.payload_offset_sector *
|
||||||
block->sector_size;
|
block->sector_size;
|
||||||
|
detached_header_size =
|
||||||
|
(header_sectors + QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS *
|
||||||
|
split_key_sectors) * block->sector_size;
|
||||||
|
|
||||||
/* Reserve header space to match payload offset */
|
/* Reserve header space to match payload offset */
|
||||||
initfunc(block, block->payload_offset, opaque, &local_err);
|
initfunc(block, detached_header_size, opaque, &local_err);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -87,6 +87,7 @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options,
|
|||||||
QCryptoBlockInitFunc initfunc,
|
QCryptoBlockInitFunc initfunc,
|
||||||
QCryptoBlockWriteFunc writefunc,
|
QCryptoBlockWriteFunc writefunc,
|
||||||
void *opaque,
|
void *opaque,
|
||||||
|
unsigned int flags,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
QCryptoBlock *block = g_new0(QCryptoBlock, 1);
|
QCryptoBlock *block = g_new0(QCryptoBlock, 1);
|
||||||
@ -102,6 +103,7 @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options,
|
|||||||
}
|
}
|
||||||
|
|
||||||
block->driver = qcrypto_block_drivers[options->format];
|
block->driver = qcrypto_block_drivers[options->format];
|
||||||
|
block->detached_header = flags & QCRYPTO_BLOCK_CREATE_DETACHED;
|
||||||
|
|
||||||
if (block->driver->create(block, options, optprefix, initfunc,
|
if (block->driver->create(block, options, optprefix, initfunc,
|
||||||
writefunc, opaque, errp) < 0) {
|
writefunc, opaque, errp) < 0) {
|
||||||
@ -146,7 +148,7 @@ qcrypto_block_calculate_payload_offset(QCryptoBlockCreateOptions *create_opts,
|
|||||||
qcrypto_block_create(create_opts, optprefix,
|
qcrypto_block_create(create_opts, optprefix,
|
||||||
qcrypto_block_headerlen_hdr_init_func,
|
qcrypto_block_headerlen_hdr_init_func,
|
||||||
qcrypto_block_headerlen_hdr_write_func,
|
qcrypto_block_headerlen_hdr_write_func,
|
||||||
len, errp);
|
len, 0, errp);
|
||||||
return crypto != NULL;
|
return crypto != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,8 @@ struct QCryptoBlock {
|
|||||||
size_t niv;
|
size_t niv;
|
||||||
uint64_t payload_offset; /* In bytes */
|
uint64_t payload_offset; /* In bytes */
|
||||||
uint64_t sector_size; /* In bytes */
|
uint64_t sector_size; /* In bytes */
|
||||||
|
|
||||||
|
bool detached_header; /* True if disk has a detached LUKS header */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QCryptoBlockDriver {
|
struct QCryptoBlockDriver {
|
||||||
|
@ -116,6 +116,10 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options,
|
|||||||
size_t n_threads,
|
size_t n_threads,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
QCRYPTO_BLOCK_CREATE_DETACHED = (1 << 0),
|
||||||
|
} QCryptoBlockCreateFlags;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qcrypto_block_create:
|
* qcrypto_block_create:
|
||||||
* @options: the encryption options
|
* @options: the encryption options
|
||||||
@ -123,6 +127,7 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options,
|
|||||||
* @initfunc: callback for initializing volume header
|
* @initfunc: callback for initializing volume header
|
||||||
* @writefunc: callback for writing data to the volume header
|
* @writefunc: callback for writing data to the volume header
|
||||||
* @opaque: data to pass to @initfunc and @writefunc
|
* @opaque: data to pass to @initfunc and @writefunc
|
||||||
|
* @flags: bitmask of QCryptoBlockCreateFlags values
|
||||||
* @errp: pointer to a NULL-initialized error object
|
* @errp: pointer to a NULL-initialized error object
|
||||||
*
|
*
|
||||||
* Create a new block encryption object for initializing
|
* Create a new block encryption object for initializing
|
||||||
@ -134,6 +139,11 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options,
|
|||||||
* generating new master keys, etc as required. Any existing
|
* generating new master keys, etc as required. Any existing
|
||||||
* data present on the volume will be irrevocably destroyed.
|
* data present on the volume will be irrevocably destroyed.
|
||||||
*
|
*
|
||||||
|
* If @flags contains QCRYPTO_BLOCK_CREATE_DETACHED then
|
||||||
|
* the open process will set the payload_offset_sector to 0
|
||||||
|
* to specify the starting point for the read/write of a
|
||||||
|
* detached LUKS header image.
|
||||||
|
*
|
||||||
* If any part of initializing the encryption context
|
* If any part of initializing the encryption context
|
||||||
* fails an error will be returned. This could be due
|
* fails an error will be returned. This could be due
|
||||||
* to the volume being in the wrong format, a cipher
|
* to the volume being in the wrong format, a cipher
|
||||||
@ -147,6 +157,7 @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options,
|
|||||||
QCryptoBlockInitFunc initfunc,
|
QCryptoBlockInitFunc initfunc,
|
||||||
QCryptoBlockWriteFunc writefunc,
|
QCryptoBlockWriteFunc writefunc,
|
||||||
void *opaque,
|
void *opaque,
|
||||||
|
unsigned int flags,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -283,6 +283,7 @@ static void test_block(gconstpointer opaque)
|
|||||||
test_block_init_func,
|
test_block_init_func,
|
||||||
test_block_write_func,
|
test_block_write_func,
|
||||||
&header,
|
&header,
|
||||||
|
0,
|
||||||
&error_abort);
|
&error_abort);
|
||||||
g_assert(blk);
|
g_assert(blk);
|
||||||
|
|
||||||
@ -362,6 +363,7 @@ test_luks_bad_header(gconstpointer data)
|
|||||||
test_block_init_func,
|
test_block_init_func,
|
||||||
test_block_write_func,
|
test_block_write_func,
|
||||||
&buf,
|
&buf,
|
||||||
|
0,
|
||||||
&error_abort);
|
&error_abort);
|
||||||
g_assert(blk);
|
g_assert(blk);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user