Message ID | 20190830205608.18192-7-mlevitsk@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | RFC crypto/luks: encryption key managment using amend interface | expand |
On Fri, Aug 30, 2019 at 11:56:04PM +0300, Maxim Levitsky wrote: > --- > block/qcow2.c | 79 ++++++++++++++++++++++++++++++++++++++++----------- > 1 file changed, 63 insertions(+), 16 deletions(-) > > @@ -4888,9 +4899,22 @@ 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 supported"); > + return -ENOTSUP; > + > + } Perhaps ' - encryption not present', and -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); > @@ -4927,7 +4951,7 @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts, > "images"); > return -EINVAL; > } > - } else { > + } else { Accidental change > /* if this point is reached, this probably means a new option was > * added without having it covered here */ > abort(); > @@ -4940,7 +4964,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) */ > @@ -4954,6 +4979,28 @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts, > } > } > > + if (encryption_update) { > + Redundant blank line > + QCryptoBlockCreateOptions *cryptoopts; > + > + cryptoopts = qcow2_extract_crypto_create_opts(opts, "luks", errp); > + if (!cryptoopts) > + return -EINVAL; > + > + helper_cb_info.current_operation = QCOW2_UPDATING_ENCRYPTION; > + > + ret = qcrypto_block_amend_options(s->crypto, > + qcow2_crypto_hdr_read_func, > + qcow2_crypto_hdr_write_func, > + bs, > + cryptoopts, > + force, > + errp); > + if (ret) { Check ret < 0 > + return ret; > + } > + } > + Regards, Daniel
On Fri, 2019-09-06 at 15:06 +0100, Daniel P. Berrangé wrote: > On Fri, Aug 30, 2019 at 11:56:04PM +0300, Maxim Levitsky wrote: > > --- > > block/qcow2.c | 79 ++++++++++++++++++++++++++++++++++++++++----------- > > 1 file changed, 63 insertions(+), 16 deletions(-) > > > > @@ -4888,9 +4899,22 @@ 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 supported"); > > + return -ENOTSUP; > > + > > + } > > Perhaps ' - encryption not present', and -EINVAL Agree. Fixed. > > > + > > + 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); > > @@ -4927,7 +4951,7 @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts, > > "images"); > > return -EINVAL; > > } > > - } else { > > + } else { > > Accidental change Fixed. > > > /* if this point is reached, this probably means a new option was > > * added without having it covered here */ > > abort(); > > @@ -4940,7 +4964,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) */ > > @@ -4954,6 +4979,28 @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts, > > } > > } > > > > + if (encryption_update) { > > + > > Redundant blank line Fixed. > > > + QCryptoBlockCreateOptions *cryptoopts; > > + > > + cryptoopts = qcow2_extract_crypto_create_opts(opts, "luks", errp); > > + if (!cryptoopts) > > + return -EINVAL; > > + > > + helper_cb_info.current_operation = QCOW2_UPDATING_ENCRYPTION; > > + > > + ret = qcrypto_block_amend_options(s->crypto, > > + qcow2_crypto_hdr_read_func, > > + qcow2_crypto_hdr_write_func, > > + bs, > > + cryptoopts, > > + force, > > + errp); > > + if (ret) { > > Check ret < 0 Fixed. > > > + return ret; > > + } > > + } > > + > > Regards, > Daniel Best regards, Maxim Levitsky
diff --git a/block/qcow2.c b/block/qcow2.c index 376bb416fd..8dff4c6b5f 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -171,6 +171,25 @@ static ssize_t qcow2_crypto_hdr_write_func(QCryptoBlock *block, size_t offset, return ret; } +static QCryptoBlockCreateOptions* +qcow2_extract_crypto_create_opts(QemuOpts *opts, const char *fmt, Error **errp) +{ + QDict *cryptoopts_qdict; + QCryptoBlockCreateOptions *cryptoopts; + 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); + + /* 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); + return cryptoopts; +} + /* * read qcow2 extension and fill bs @@ -4366,20 +4385,10 @@ 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; 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); - - /* 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); + cryptoopts = qcow2_extract_crypto_create_opts(opts, "luks", errp); if (!cryptoopts) { return false; } @@ -4756,6 +4765,7 @@ typedef enum Qcow2AmendOperation { * invocation from an operation change */ QCOW2_NO_OPERATION = 0, + QCOW2_UPDATING_ENCRYPTION, QCOW2_CHANGING_REFCOUNT_ORDER, QCOW2_DOWNGRADING, } Qcow2AmendOperation; @@ -4840,6 +4850,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)) { @@ -4888,9 +4899,22 @@ 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 supported"); + return -ENOTSUP; + + } + + 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); @@ -4927,7 +4951,7 @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts, "images"); return -EINVAL; } - } else { + } else { /* if this point is reached, this probably means a new option was * added without having it covered here */ abort(); @@ -4940,7 +4964,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) */ @@ -4954,6 +4979,28 @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts, } } + if (encryption_update) { + + QCryptoBlockCreateOptions *cryptoopts; + + cryptoopts = qcow2_extract_crypto_create_opts(opts, "luks", errp); + if (!cryptoopts) + return -EINVAL; + + helper_cb_info.current_operation = QCOW2_UPDATING_ENCRYPTION; + + ret = qcrypto_block_amend_options(s->crypto, + qcow2_crypto_hdr_read_func, + qcow2_crypto_hdr_write_func, + bs, + cryptoopts, + force, + errp); + if (ret) { + return ret; + } + } + if (s->refcount_bits != refcount_bits) { int refcount_order = ctz32(refcount_bits);