[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 07/13] qcow2: extend qemu-img amend interface with crypto opt
From: |
Daniel P . Berrangé |
Subject: |
Re: [PATCH 07/13] qcow2: extend qemu-img amend interface with crypto options |
Date: |
Tue, 28 Jan 2020 17:30:27 +0000 |
User-agent: |
Mutt/1.13.3 (2020-01-12) |
On Tue, Jan 14, 2020 at 09:33:44PM +0200, Maxim Levitsky wrote:
> Now that we have all the infrastructure in place,
> wire it in the qcow2 driver and expose this to the user.
>
> Signed-off-by: Maxim Levitsky <address@hidden>
> ---
> block/qcow2.c | 101 +++++++++++++++++++++++++++++++++++++++-----------
> 1 file changed, 79 insertions(+), 22 deletions(-)
>
> diff --git a/block/qcow2.c b/block/qcow2.c
> index c6c2deee75..1b01174aed 100644
> --- a/block/qcow2.c
> +++ b/block/qcow2.c
> @@ -173,6 +173,19 @@ static ssize_t qcow2_crypto_hdr_write_func(QCryptoBlock
> *block, size_t offset,
> return ret;
> }
>
> +static QDict*
> +qcow2_extract_crypto_opts(QemuOpts *opts, const char *fmt, Error **errp)
> +{
> + QDict *cryptoopts_qdict;
> + QDict *opts_qdict;
> +
> + /* Extract "encrypt." options into a qdict */
> + opts_qdict = qemu_opts_to_qdict(opts, NULL);
> + qdict_extract_subqdict(opts_qdict, &cryptoopts_qdict, "encrypt.");
> + qobject_unref(opts_qdict);
> + qdict_put_str(cryptoopts_qdict, "format", "luks");
> + return cryptoopts_qdict;
> +}
>
> /*
> * read qcow2 extension and fill bs
> @@ -4631,20 +4644,18 @@ static ssize_t
> qcow2_measure_crypto_hdr_write_func(QCryptoBlock *block,
> static bool qcow2_measure_luks_headerlen(QemuOpts *opts, size_t *len,
> Error **errp)
> {
> - QDict *opts_qdict;
> - QDict *cryptoopts_qdict;
> QCryptoBlockCreateOptions *cryptoopts;
> + QDict* crypto_opts_dict;
> QCryptoBlock *crypto;
>
> - /* Extract "encrypt." options into a qdict */
> - opts_qdict = qemu_opts_to_qdict(opts, NULL);
> - qdict_extract_subqdict(opts_qdict, &cryptoopts_qdict, "encrypt.");
> - qobject_unref(opts_qdict);
> + crypto_opts_dict = qcow2_extract_crypto_opts(opts, "luks", errp);
> + if (!crypto_opts_dict) {
> + return false;
> + }
> +
> + cryptoopts = block_crypto_create_opts_init(crypto_opts_dict, errp);
> + qobject_unref(crypto_opts_dict);
>
> - /* Build QCryptoBlockCreateOptions object from qdict */
> - qdict_put_str(cryptoopts_qdict, "format", "luks");
> - cryptoopts = block_crypto_create_opts_init(cryptoopts_qdict, errp);
> - qobject_unref(cryptoopts_qdict);
> if (!cryptoopts) {
> return false;
> }
> @@ -5083,6 +5094,7 @@ typedef enum Qcow2AmendOperation {
> QCOW2_NO_OPERATION = 0,
>
> QCOW2_UPGRADING,
> + QCOW2_UPDATING_ENCRYPTION,
> QCOW2_CHANGING_REFCOUNT_ORDER,
> QCOW2_DOWNGRADING,
> } Qcow2AmendOperation;
> @@ -5167,6 +5179,7 @@ static int qcow2_amend_options(BlockDriverState *bs,
> QemuOpts *opts,
> int ret;
> QemuOptDesc *desc = opts->list->desc;
> Qcow2AmendHelperCBInfo helper_cb_info;
> + bool encryption_update = false;
>
> while (desc && desc->name) {
> if (!qemu_opt_find(opts, desc->name)) {
> @@ -5215,9 +5228,17 @@ static int qcow2_amend_options(BlockDriverState *bs,
> QemuOpts *opts,
> return -ENOTSUP;
> }
> } else if (g_str_has_prefix(desc->name, "encrypt.")) {
> - error_setg(errp,
> - "Changing the encryption parameters is not
> supported");
> - return -ENOTSUP;
> + if (!s->crypto) {
> + error_setg(errp,
> + "Can't amend encryption options - encryption not
> present");
> + return -EINVAL;
> + }
> + if (s->crypt_method_header != QCOW_CRYPT_LUKS) {
> + error_setg(errp,
> + "Only LUKS encryption options can be amended");
> + return -ENOTSUP;
> + }
> + encryption_update = true;
> } else if (!strcmp(desc->name, BLOCK_OPT_CLUSTER_SIZE)) {
> cluster_size = qemu_opt_get_size(opts, BLOCK_OPT_CLUSTER_SIZE,
> cluster_size);
> @@ -5267,7 +5288,8 @@ static int qcow2_amend_options(BlockDriverState *bs,
> QemuOpts *opts,
> .original_status_cb = status_cb,
> .original_cb_opaque = cb_opaque,
> .total_operations = (new_version != old_version)
> - + (s->refcount_bits != refcount_bits)
> + + (s->refcount_bits != refcount_bits) +
> + (encryption_update == true)
> };
>
> /* Upgrade first (some features may require compat=1.1) */
> @@ -5280,6 +5302,33 @@ static int qcow2_amend_options(BlockDriverState *bs,
> QemuOpts *opts,
> }
> }
>
> + if (encryption_update) {
> + QDict *amend_opts_dict;
> + QCryptoBlockAmendOptions *amend_opts;
> +
> + helper_cb_info.current_operation = QCOW2_UPDATING_ENCRYPTION;
> + amend_opts_dict = qcow2_extract_crypto_opts(opts, "luks", errp);
> + if (!amend_opts_dict) {
> + return -EINVAL;
> + }
> + amend_opts = block_crypto_amend_opts_init(amend_opts_dict, errp);
> + qobject_unref(amend_opts_dict);
> + if (!amend_opts) {
> + return -EINVAL;
> + }
> + ret = qcrypto_block_amend_options(s->crypto,
> + qcow2_crypto_hdr_read_func,
> + qcow2_crypto_hdr_write_func,
> + bs,
> + amend_opts,
> + force,
> + errp);
> + qapi_free_QCryptoBlockAmendOptions(amend_opts);
> + if (ret < 0) {
> + return ret;
> + }
> + }
> +
> if (s->refcount_bits != refcount_bits) {
> int refcount_order = ctz32(refcount_bits);
>
> @@ -5488,14 +5537,6 @@ void qcow2_signal_corruption(BlockDriverState *bs,
> bool fatal, int64_t offset,
> .type = QEMU_OPT_STRING, \
> .help = "Encrypt the image, format choices: 'aes', 'luks'", \
> }, \
> - BLOCK_CRYPTO_OPT_DEF_KEY_SECRET("encrypt.", \
> - "ID of secret providing qcow AES key or LUKS passphrase"), \
> - BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG("encrypt."), \
> - BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE("encrypt."), \
> - BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG("encrypt."), \
> - BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG("encrypt."), \
> - BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG("encrypt."), \
> - BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME("encrypt."), \
> { \
> .name = BLOCK_OPT_CLUSTER_SIZE, \
> .type = QEMU_OPT_SIZE, \
> @@ -5526,6 +5567,14 @@ static QemuOptsList qcow2_create_opts = {
> .head = QTAILQ_HEAD_INITIALIZER(qcow2_create_opts.head),
> .desc = {
> QCOW_COMMON_OPTIONS,
> + BLOCK_CRYPTO_OPT_DEF_KEY_SECRET("encrypt.",
> + "ID of secret providing qcow AES key or LUKS passphrase"),
> + BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG("encrypt."),
> + BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE("encrypt."),
> + BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG("encrypt."),
> + BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG("encrypt."),
> + BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG("encrypt."),
> + BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME("encrypt."),
> { /* end of list */ }
> }
These two chunks should habe been in the earlier patch IMHO.
> };
> @@ -5535,6 +5584,14 @@ static QemuOptsList qcow2_amend_opts = {
> .head = QTAILQ_HEAD_INITIALIZER(qcow2_amend_opts.head),
> .desc = {
> QCOW_COMMON_OPTIONS,
> + BLOCK_CRYPTO_OPT_DEF_LUKS_KEYSLOT_UPDATE("encrypt.keys.0."),
> + BLOCK_CRYPTO_OPT_DEF_LUKS_KEYSLOT_UPDATE("encrypt.keys.1."),
> + BLOCK_CRYPTO_OPT_DEF_LUKS_KEYSLOT_UPDATE("encrypt.keys.2."),
> + BLOCK_CRYPTO_OPT_DEF_LUKS_KEYSLOT_UPDATE("encrypt.keys.3."),
> + BLOCK_CRYPTO_OPT_DEF_LUKS_KEYSLOT_UPDATE("encrypt.keys.4."),
> + BLOCK_CRYPTO_OPT_DEF_LUKS_KEYSLOT_UPDATE("encrypt.keys.5."),
> + BLOCK_CRYPTO_OPT_DEF_LUKS_KEYSLOT_UPDATE("encrypt.keys.6."),
> + BLOCK_CRYPTO_OPT_DEF_LUKS_KEYSLOT_UPDATE("encrypt.keys.7."),
> { /* end of list */ }
Same naming idea about "encrypt.key.0" or "encrypt.keyslot.0"
> }
> };
> --
> 2.17.2
>
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
- Re: [PATCH 02/13] qcrypto-luks: implement encryption key management, (continued)
- [PATCH 04/13] block: amend: separate amend and create options for qemu-img, Maxim Levitsky, 2020/01/14
- [PATCH 03/13] block: amend: add 'force' option, Maxim Levitsky, 2020/01/14
- [PATCH 05/13] block/crypto: rename two functions, Maxim Levitsky, 2020/01/14
- [PATCH 06/13] block/crypto: implement the encryption key management, Maxim Levitsky, 2020/01/14
- [PATCH 07/13] qcow2: extend qemu-img amend interface with crypto options, Maxim Levitsky, 2020/01/14
- Re: [PATCH 07/13] qcow2: extend qemu-img amend interface with crypto options,
Daniel P . Berrangé <=
- [PATCH 09/13] qemu-iotests: qemu-img tests for luks key management, Maxim Levitsky, 2020/01/14
- [PATCH 08/13] iotests: filter few more luks specific create options, Maxim Levitsky, 2020/01/14
- [PATCH 10/13] block: add generic infrastructure for x-blockdev-amend qmp command, Maxim Levitsky, 2020/01/14
- [PATCH 12/13] block/qcow2: implement blockdev-amend, Maxim Levitsky, 2020/01/14