crypto: add support for querying parameters for block encryption
When creating new block encryption volumes, we accept a list of parameters to control the formatting process. It is useful to be able to query what those parameters were for existing block devices. Add a qcrypto_block_get_info() method which returns a QCryptoBlockInfo instance to report this data. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> Message-id: 1469192015-16487-2-git-send-email-berrange@redhat.com Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
parent
54a16a63d0
commit
40c8502822
@ -201,6 +201,15 @@ QEMU_BUILD_BUG_ON(sizeof(struct QCryptoBlockLUKSHeader) != 592);
|
|||||||
|
|
||||||
struct QCryptoBlockLUKS {
|
struct QCryptoBlockLUKS {
|
||||||
QCryptoBlockLUKSHeader header;
|
QCryptoBlockLUKSHeader header;
|
||||||
|
|
||||||
|
/* Cache parsed versions of what's in header fields,
|
||||||
|
* as we can't rely on QCryptoBlock.cipher being
|
||||||
|
* non-NULL */
|
||||||
|
QCryptoCipherAlgorithm cipher_alg;
|
||||||
|
QCryptoCipherMode cipher_mode;
|
||||||
|
QCryptoIVGenAlgorithm ivgen_alg;
|
||||||
|
QCryptoHashAlgorithm ivgen_hash_alg;
|
||||||
|
QCryptoHashAlgorithm hash_alg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -847,6 +856,12 @@ qcrypto_block_luks_open(QCryptoBlock *block,
|
|||||||
block->payload_offset = luks->header.payload_offset *
|
block->payload_offset = luks->header.payload_offset *
|
||||||
QCRYPTO_BLOCK_LUKS_SECTOR_SIZE;
|
QCRYPTO_BLOCK_LUKS_SECTOR_SIZE;
|
||||||
|
|
||||||
|
luks->cipher_alg = cipheralg;
|
||||||
|
luks->cipher_mode = ciphermode;
|
||||||
|
luks->ivgen_alg = ivalg;
|
||||||
|
luks->ivgen_hash_alg = ivhash;
|
||||||
|
luks->hash_alg = hash;
|
||||||
|
|
||||||
g_free(masterkey);
|
g_free(masterkey);
|
||||||
g_free(password);
|
g_free(password);
|
||||||
|
|
||||||
@ -1271,6 +1286,12 @@ qcrypto_block_luks_create(QCryptoBlock *block,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
luks->cipher_alg = luks_opts.cipher_alg;
|
||||||
|
luks->cipher_mode = luks_opts.cipher_mode;
|
||||||
|
luks->ivgen_alg = luks_opts.ivgen_alg;
|
||||||
|
luks->ivgen_hash_alg = luks_opts.ivgen_hash_alg;
|
||||||
|
luks->hash_alg = luks_opts.hash_alg;
|
||||||
|
|
||||||
memset(masterkey, 0, luks->header.key_bytes);
|
memset(masterkey, 0, luks->header.key_bytes);
|
||||||
g_free(masterkey);
|
g_free(masterkey);
|
||||||
memset(slotkey, 0, luks->header.key_bytes);
|
memset(slotkey, 0, luks->header.key_bytes);
|
||||||
@ -1305,6 +1326,51 @@ qcrypto_block_luks_create(QCryptoBlock *block,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int qcrypto_block_luks_get_info(QCryptoBlock *block,
|
||||||
|
QCryptoBlockInfo *info,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
QCryptoBlockLUKS *luks = block->opaque;
|
||||||
|
QCryptoBlockInfoLUKSSlot *slot;
|
||||||
|
QCryptoBlockInfoLUKSSlotList *slots = NULL, **prev = &info->u.luks.slots;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
info->u.luks.cipher_alg = luks->cipher_alg;
|
||||||
|
info->u.luks.cipher_mode = luks->cipher_mode;
|
||||||
|
info->u.luks.ivgen_alg = luks->ivgen_alg;
|
||||||
|
if (info->u.luks.ivgen_alg == QCRYPTO_IVGEN_ALG_ESSIV) {
|
||||||
|
info->u.luks.has_ivgen_hash_alg = true;
|
||||||
|
info->u.luks.ivgen_hash_alg = luks->ivgen_hash_alg;
|
||||||
|
}
|
||||||
|
info->u.luks.hash_alg = luks->hash_alg;
|
||||||
|
info->u.luks.payload_offset = block->payload_offset;
|
||||||
|
info->u.luks.master_key_iters = luks->header.master_key_iterations;
|
||||||
|
info->u.luks.uuid = g_strndup((const char *)luks->header.uuid,
|
||||||
|
sizeof(luks->header.uuid));
|
||||||
|
|
||||||
|
for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) {
|
||||||
|
slots = g_new0(QCryptoBlockInfoLUKSSlotList, 1);
|
||||||
|
*prev = slots;
|
||||||
|
|
||||||
|
slots->value = slot = g_new0(QCryptoBlockInfoLUKSSlot, 1);
|
||||||
|
slot->active = luks->header.key_slots[i].active ==
|
||||||
|
QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED;
|
||||||
|
slot->key_offset = luks->header.key_slots[i].key_offset
|
||||||
|
* QCRYPTO_BLOCK_LUKS_SECTOR_SIZE;
|
||||||
|
if (slot->active) {
|
||||||
|
slot->has_iters = true;
|
||||||
|
slot->iters = luks->header.key_slots[i].iterations;
|
||||||
|
slot->has_stripes = true;
|
||||||
|
slot->stripes = luks->header.key_slots[i].stripes;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev = &slots->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void qcrypto_block_luks_cleanup(QCryptoBlock *block)
|
static void qcrypto_block_luks_cleanup(QCryptoBlock *block)
|
||||||
{
|
{
|
||||||
g_free(block->opaque);
|
g_free(block->opaque);
|
||||||
@ -1342,6 +1408,7 @@ qcrypto_block_luks_encrypt(QCryptoBlock *block,
|
|||||||
const QCryptoBlockDriver qcrypto_block_driver_luks = {
|
const QCryptoBlockDriver qcrypto_block_driver_luks = {
|
||||||
.open = qcrypto_block_luks_open,
|
.open = qcrypto_block_luks_open,
|
||||||
.create = qcrypto_block_luks_create,
|
.create = qcrypto_block_luks_create,
|
||||||
|
.get_info = qcrypto_block_luks_get_info,
|
||||||
.cleanup = qcrypto_block_luks_cleanup,
|
.cleanup = qcrypto_block_luks_cleanup,
|
||||||
.decrypt = qcrypto_block_luks_decrypt,
|
.decrypt = qcrypto_block_luks_decrypt,
|
||||||
.encrypt = qcrypto_block_luks_encrypt,
|
.encrypt = qcrypto_block_luks_encrypt,
|
||||||
|
@ -105,6 +105,23 @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QCryptoBlockInfo *qcrypto_block_get_info(QCryptoBlock *block,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
QCryptoBlockInfo *info = g_new0(QCryptoBlockInfo, 1);
|
||||||
|
|
||||||
|
info->format = block->format;
|
||||||
|
|
||||||
|
if (block->driver->get_info &&
|
||||||
|
block->driver->get_info(block, info, errp) < 0) {
|
||||||
|
g_free(info);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int qcrypto_block_decrypt(QCryptoBlock *block,
|
int qcrypto_block_decrypt(QCryptoBlock *block,
|
||||||
uint64_t startsector,
|
uint64_t startsector,
|
||||||
uint8_t *buf,
|
uint8_t *buf,
|
||||||
|
@ -53,6 +53,10 @@ struct QCryptoBlockDriver {
|
|||||||
void *opaque,
|
void *opaque,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
|
|
||||||
|
int (*get_info)(QCryptoBlock *block,
|
||||||
|
QCryptoBlockInfo *info,
|
||||||
|
Error **errp);
|
||||||
|
|
||||||
void (*cleanup)(QCryptoBlock *block);
|
void (*cleanup)(QCryptoBlock *block);
|
||||||
|
|
||||||
int (*encrypt)(QCryptoBlock *block,
|
int (*encrypt)(QCryptoBlock *block,
|
||||||
|
@ -138,6 +138,22 @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options,
|
|||||||
void *opaque,
|
void *opaque,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qcrypto_block_get_info:
|
||||||
|
* @block: the block encryption object
|
||||||
|
* @errp: pointer to a NULL-initialized error object
|
||||||
|
*
|
||||||
|
* Get information about the configuration options for the
|
||||||
|
* block encryption object. This includes details such as
|
||||||
|
* the cipher algorithms, modes, and initialization vector
|
||||||
|
* generators.
|
||||||
|
*
|
||||||
|
* Returns: a block encryption info object, or NULL on error
|
||||||
|
*/
|
||||||
|
QCryptoBlockInfo *qcrypto_block_get_info(QCryptoBlock *block,
|
||||||
|
Error **errp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @qcrypto_block_decrypt:
|
* @qcrypto_block_decrypt:
|
||||||
* @block: the block encryption object
|
* @block: the block encryption object
|
||||||
|
@ -224,3 +224,90 @@
|
|||||||
'discriminator': 'format',
|
'discriminator': 'format',
|
||||||
'data': { 'qcow': 'QCryptoBlockOptionsQCow',
|
'data': { 'qcow': 'QCryptoBlockOptionsQCow',
|
||||||
'luks': 'QCryptoBlockCreateOptionsLUKS' } }
|
'luks': 'QCryptoBlockCreateOptionsLUKS' } }
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# QCryptoBlockInfoBase:
|
||||||
|
#
|
||||||
|
# The common information that applies to all full disk
|
||||||
|
# encryption formats
|
||||||
|
#
|
||||||
|
# @format: the encryption format
|
||||||
|
#
|
||||||
|
# Since: 2.7
|
||||||
|
##
|
||||||
|
{ 'struct': 'QCryptoBlockInfoBase',
|
||||||
|
'data': { 'format': 'QCryptoBlockFormat' }}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# QCryptoBlockInfoLUKSSlot:
|
||||||
|
#
|
||||||
|
# Information about the LUKS block encryption key
|
||||||
|
# slot options
|
||||||
|
#
|
||||||
|
# @active: whether the key slot is currently in use
|
||||||
|
# @key-offset: offset to the key material in bytes
|
||||||
|
# @iters: #optional number of PBKDF2 iterations for key material
|
||||||
|
# @stripes: #optional number of stripes for splitting key material
|
||||||
|
#
|
||||||
|
# Since: 2.7
|
||||||
|
##
|
||||||
|
{ 'struct': 'QCryptoBlockInfoLUKSSlot',
|
||||||
|
'data': {'active': 'bool',
|
||||||
|
'*iters': 'int',
|
||||||
|
'*stripes': 'int',
|
||||||
|
'key-offset': 'int' } }
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# QCryptoBlockInfoLUKS:
|
||||||
|
#
|
||||||
|
# Information about the LUKS block encryption options
|
||||||
|
#
|
||||||
|
# @cipher-alg: the cipher algorithm for data encryption
|
||||||
|
# @cipher-mode: the cipher mode for data encryption
|
||||||
|
# @ivgen-alg: the initialization vector generator
|
||||||
|
# @ivgen-hash-alg: #optional the initialization vector generator hash
|
||||||
|
# @hash-alg: the master key hash algorithm
|
||||||
|
# @payload-offset: offset to the payload data in bytes
|
||||||
|
# @master-key-iters: number of PBKDF2 iterations for key material
|
||||||
|
# @uuid: unique identifier for the volume
|
||||||
|
# @slots: information about each key slot
|
||||||
|
#
|
||||||
|
# Since: 2.7
|
||||||
|
##
|
||||||
|
{ 'struct': 'QCryptoBlockInfoLUKS',
|
||||||
|
'data': {'cipher-alg': 'QCryptoCipherAlgorithm',
|
||||||
|
'cipher-mode': 'QCryptoCipherMode',
|
||||||
|
'ivgen-alg': 'QCryptoIVGenAlgorithm',
|
||||||
|
'*ivgen-hash-alg': 'QCryptoHashAlgorithm',
|
||||||
|
'hash-alg': 'QCryptoHashAlgorithm',
|
||||||
|
'payload-offset': 'int',
|
||||||
|
'master-key-iters': 'int',
|
||||||
|
'uuid': 'str',
|
||||||
|
'slots': [ 'QCryptoBlockInfoLUKSSlot' ] }}
|
||||||
|
|
||||||
|
##
|
||||||
|
# QCryptoBlockInfoQCow:
|
||||||
|
#
|
||||||
|
# Information about the QCow block encryption options
|
||||||
|
#
|
||||||
|
# Since: 2.7
|
||||||
|
##
|
||||||
|
{ 'struct': 'QCryptoBlockInfoQCow',
|
||||||
|
'data': { }}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# QCryptoBlockInfo:
|
||||||
|
#
|
||||||
|
# Information about the block encryption options
|
||||||
|
#
|
||||||
|
# Since: 2.7
|
||||||
|
##
|
||||||
|
{ 'union': 'QCryptoBlockInfo',
|
||||||
|
'base': 'QCryptoBlockInfoBase',
|
||||||
|
'discriminator': 'format',
|
||||||
|
'data': { 'qcow': 'QCryptoBlockInfoQCow',
|
||||||
|
'luks': 'QCryptoBlockInfoLUKS' } }
|
||||||
|
Loading…
Reference in New Issue
Block a user