* [RFC 1/8] crypto: Export util functions and structures
2023-12-04 16:06 [RFC 0/8] Support generic Luks encryption Hyman Huang
@ 2023-12-04 16:06 ` Hyman Huang
2023-12-04 16:06 ` [RFC 2/8] crypto: Introduce payload offset set function Hyman Huang
` (7 subsequent siblings)
8 siblings, 0 replies; 18+ messages in thread
From: Hyman Huang @ 2023-12-04 16:06 UTC (permalink / raw)
To: qemu-devel
Cc: Kevin Wolf, Hanna Reitz, Daniel P . Berrangé, Eric Blake,
Markus Armbruster, yong.huang
Luks driver logic is primarily reused by Gluk, which,
therefore, exports several pre-existing functions and
structures.
Signed-off-by: Hyman Huang <yong.huang@smartx.com>
---
block/crypto.c | 16 ++++------------
block/crypto.h | 23 +++++++++++++++++++++++
2 files changed, 27 insertions(+), 12 deletions(-)
diff --git a/block/crypto.c b/block/crypto.c
index 921933a5e5..6afae1de2e 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -34,14 +34,6 @@
#include "qemu/memalign.h"
#include "crypto.h"
-typedef struct BlockCrypto BlockCrypto;
-
-struct BlockCrypto {
- QCryptoBlock *block;
- bool updating_keys;
-};
-
-
static int block_crypto_probe_generic(QCryptoBlockFormat format,
const uint8_t *buf,
int buf_size,
@@ -321,7 +313,7 @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
}
-static int coroutine_fn GRAPH_UNLOCKED
+int coroutine_fn GRAPH_UNLOCKED
block_crypto_co_create_generic(BlockDriverState *bs, int64_t size,
QCryptoBlockCreateOptions *opts,
PreallocMode prealloc, Error **errp)
@@ -385,7 +377,7 @@ block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
}
-static void block_crypto_close(BlockDriverState *bs)
+void block_crypto_close(BlockDriverState *bs)
{
BlockCrypto *crypto = bs->opaque;
qcrypto_block_free(crypto->block);
@@ -404,7 +396,7 @@ static int block_crypto_reopen_prepare(BDRVReopenState *state,
*/
#define BLOCK_CRYPTO_MAX_IO_SIZE (1024 * 1024)
-static int coroutine_fn GRAPH_RDLOCK
+int coroutine_fn GRAPH_RDLOCK
block_crypto_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
@@ -466,7 +458,7 @@ block_crypto_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
}
-static int coroutine_fn GRAPH_RDLOCK
+int coroutine_fn GRAPH_RDLOCK
block_crypto_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{
diff --git a/block/crypto.h b/block/crypto.h
index 72e792c9af..06465009f0 100644
--- a/block/crypto.h
+++ b/block/crypto.h
@@ -21,6 +21,8 @@
#ifndef BLOCK_CRYPTO_H
#define BLOCK_CRYPTO_H
+#include "crypto/block.h"
+
#define BLOCK_CRYPTO_OPT_DEF_KEY_SECRET(prefix, helpstr) \
{ \
.name = prefix BLOCK_CRYPTO_OPT_QCOW_KEY_SECRET, \
@@ -131,4 +133,25 @@ block_crypto_amend_opts_init(QDict *opts, Error **errp);
QCryptoBlockOpenOptions *
block_crypto_open_opts_init(QDict *opts, Error **errp);
+typedef struct BlockCrypto BlockCrypto;
+
+struct BlockCrypto {
+ QCryptoBlock *block;
+ bool updating_keys;
+};
+
+int coroutine_fn GRAPH_UNLOCKED
+block_crypto_co_create_generic(BlockDriverState *bs, int64_t size,
+ QCryptoBlockCreateOptions *opts,
+ PreallocMode prealloc, Error **errp);
+
+int coroutine_fn GRAPH_RDLOCK
+block_crypto_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
+ QEMUIOVector *qiov, BdrvRequestFlags flags);
+
+int coroutine_fn GRAPH_RDLOCK
+block_crypto_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
+ QEMUIOVector *qiov, BdrvRequestFlags flags);
+
+void block_crypto_close(BlockDriverState *bs);
#endif /* BLOCK_CRYPTO_H */
--
2.39.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [RFC 2/8] crypto: Introduce payload offset set function
2023-12-04 16:06 [RFC 0/8] Support generic Luks encryption Hyman Huang
2023-12-04 16:06 ` [RFC 1/8] crypto: Export util functions and structures Hyman Huang
@ 2023-12-04 16:06 ` Hyman Huang
2023-12-04 16:06 ` [RFC 3/8] Gluks: Add the basic framework Hyman Huang
` (6 subsequent siblings)
8 siblings, 0 replies; 18+ messages in thread
From: Hyman Huang @ 2023-12-04 16:06 UTC (permalink / raw)
To: qemu-devel
Cc: Kevin Wolf, Hanna Reitz, Daniel P . Berrangé, Eric Blake,
Markus Armbruster, yong.huang
Implement the payload offset set function for Gluks.
Signed-off-by: Hyman Huang <yong.huang@smartx.com>
---
crypto/block.c | 4 ++++
include/crypto/block.h | 1 +
2 files changed, 5 insertions(+)
diff --git a/crypto/block.c b/crypto/block.c
index 7bb4b74a37..3dcf22a69f 100644
--- a/crypto/block.c
+++ b/crypto/block.c
@@ -319,6 +319,10 @@ QCryptoHashAlgorithm qcrypto_block_get_kdf_hash(QCryptoBlock *block)
return block->kdfhash;
}
+void qcrypto_block_set_payload_offset(QCryptoBlock *block, uint64_t offset)
+{
+ block->payload_offset = offset;
+}
uint64_t qcrypto_block_get_payload_offset(QCryptoBlock *block)
{
diff --git a/include/crypto/block.h b/include/crypto/block.h
index 4f63a37872..b47a90c529 100644
--- a/include/crypto/block.h
+++ b/include/crypto/block.h
@@ -312,4 +312,5 @@ void qcrypto_block_free(QCryptoBlock *block);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoBlock, qcrypto_block_free)
+void qcrypto_block_set_payload_offset(QCryptoBlock *block, uint64_t offset);
#endif /* QCRYPTO_BLOCK_H */
--
2.39.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [RFC 3/8] Gluks: Add the basic framework
2023-12-04 16:06 [RFC 0/8] Support generic Luks encryption Hyman Huang
2023-12-04 16:06 ` [RFC 1/8] crypto: Export util functions and structures Hyman Huang
2023-12-04 16:06 ` [RFC 2/8] crypto: Introduce payload offset set function Hyman Huang
@ 2023-12-04 16:06 ` Hyman Huang
2023-12-04 16:06 ` [RFC 4/8] Gluks: Introduce Gluks options Hyman Huang
` (5 subsequent siblings)
8 siblings, 0 replies; 18+ messages in thread
From: Hyman Huang @ 2023-12-04 16:06 UTC (permalink / raw)
To: qemu-devel
Cc: Kevin Wolf, Hanna Reitz, Daniel P . Berrangé, Eric Blake,
Markus Armbruster, yong.huang
Gluks would be a built-in format in the QEMU block layer.
Signed-off-by: Hyman Huang <yong.huang@smartx.com>
---
block/generic-luks.c | 81 ++++++++++++++++++++++++++++++++++++++++++++
block/generic-luks.h | 26 ++++++++++++++
block/meson.build | 1 +
3 files changed, 108 insertions(+)
create mode 100644 block/generic-luks.c
create mode 100644 block/generic-luks.h
diff --git a/block/generic-luks.c b/block/generic-luks.c
new file mode 100644
index 0000000000..f23e202991
--- /dev/null
+++ b/block/generic-luks.c
@@ -0,0 +1,81 @@
+/*
+ * QEMU block driver for the generic luks encryption
+ *
+ * Copyright (c) 2024 SmartX Inc
+ *
+ * Author: Hyman Huang <yong.huang@smartx.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "qemu/osdep.h"
+
+#include "block/block_int.h"
+#include "block/crypto.h"
+#include "crypto/block.h"
+
+#include "generic-luks.h"
+
+/* BDRVGLUKSState holds the state of one generic LUKS instance */
+typedef struct BDRVGLUKSState {
+ BlockCrypto crypto;
+ BdrvChild *header; /* LUKS header node */
+ uint64_t header_size; /* In bytes */
+} BDRVGLUKSState;
+
+static int gluks_open(BlockDriverState *bs, QDict *options, int flags,
+ Error **errp)
+{
+ return 0;
+}
+
+static int coroutine_fn GRAPH_UNLOCKED
+gluks_co_create_opts(BlockDriver *drv, const char *filename,
+ QemuOpts *opts, Error **errp)
+{
+ return 0;
+}
+
+static void
+gluks_child_perms(BlockDriverState *bs, BdrvChild *c,
+ const BdrvChildRole role,
+ BlockReopenQueue *reopen_queue,
+ uint64_t perm, uint64_t shared,
+ uint64_t *nperm, uint64_t *nshared)
+{
+
+}
+
+static int64_t coroutine_fn GRAPH_RDLOCK
+gluks_co_getlength(BlockDriverState *bs)
+{
+ return 0;
+}
+
+static BlockDriver bdrv_generic_luks = {
+ .format_name = "gluks",
+ .instance_size = sizeof(BDRVGLUKSState),
+ .bdrv_open = gluks_open,
+ .bdrv_co_create_opts = gluks_co_create_opts,
+ .bdrv_child_perm = gluks_child_perms,
+ .bdrv_co_getlength = gluks_co_getlength,
+};
+
+static void block_generic_luks_init(void)
+{
+ bdrv_register(&bdrv_generic_luks);
+}
+
+block_init(block_generic_luks_init);
diff --git a/block/generic-luks.h b/block/generic-luks.h
new file mode 100644
index 0000000000..2aae866fa4
--- /dev/null
+++ b/block/generic-luks.h
@@ -0,0 +1,26 @@
+/*
+ * QEMU block driver for the generic luks encryption
+ *
+ * Copyright (c) 2024 SmartX Inc
+ *
+ * Author: Hyman Huang <yong.huang@smartx.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef GENERIC_LUKS_H
+#define GENERIC_LUKS_H
+
+#endif /* GENERIC_LUKS_H */
diff --git a/block/meson.build b/block/meson.build
index 59ff6d380c..74f2da7bed 100644
--- a/block/meson.build
+++ b/block/meson.build
@@ -39,6 +39,7 @@ block_ss.add(files(
'throttle.c',
'throttle-groups.c',
'write-threshold.c',
+ 'generic-luks.c',
), zstd, zlib, gnutls)
system_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c'))
--
2.39.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [RFC 4/8] Gluks: Introduce Gluks options
2023-12-04 16:06 [RFC 0/8] Support generic Luks encryption Hyman Huang
` (2 preceding siblings ...)
2023-12-04 16:06 ` [RFC 3/8] Gluks: Add the basic framework Hyman Huang
@ 2023-12-04 16:06 ` Hyman Huang
2023-12-04 16:06 ` [RFC 5/8] qapi: Introduce Gluks types to qapi Hyman Huang
` (4 subsequent siblings)
8 siblings, 0 replies; 18+ messages in thread
From: Hyman Huang @ 2023-12-04 16:06 UTC (permalink / raw)
To: qemu-devel
Cc: Kevin Wolf, Hanna Reitz, Daniel P . Berrangé, Eric Blake,
Markus Armbruster, yong.huang
Similar to Luks, the Gluks format primarily recycles the
Luks choices with the exception of the "size" option.
Signed-off-by: Hyman Huang <yong.huang@smartx.com>
---
block/crypto.c | 4 ++--
block/generic-luks.c | 18 ++++++++++++++++++
block/generic-luks.h | 3 +++
3 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/block/crypto.c b/block/crypto.c
index 6afae1de2e..6f8528dccc 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -150,7 +150,7 @@ error:
}
-static QemuOptsList block_crypto_runtime_opts_luks = {
+QemuOptsList block_crypto_runtime_opts_luks = {
.name = "crypto",
.head = QTAILQ_HEAD_INITIALIZER(block_crypto_runtime_opts_luks.head),
.desc = {
@@ -181,7 +181,7 @@ static QemuOptsList block_crypto_create_opts_luks = {
};
-static QemuOptsList block_crypto_amend_opts_luks = {
+QemuOptsList block_crypto_amend_opts_luks = {
.name = "crypto",
.head = QTAILQ_HEAD_INITIALIZER(block_crypto_create_opts_luks.head),
.desc = {
diff --git a/block/generic-luks.c b/block/generic-luks.c
index f23e202991..ebc0365d40 100644
--- a/block/generic-luks.c
+++ b/block/generic-luks.c
@@ -35,6 +35,21 @@ typedef struct BDRVGLUKSState {
uint64_t header_size; /* In bytes */
} BDRVGLUKSState;
+static QemuOptsList gluks_create_opts_luks = {
+ .name = "crypto",
+ .head = QTAILQ_HEAD_INITIALIZER(gluks_create_opts_luks.head),
+ .desc = {
+ BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(""),
+ BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG(""),
+ BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE(""),
+ BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG(""),
+ BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG(""),
+ BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG(""),
+ BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME(""),
+ { /* end of list */ }
+ },
+};
+
static int gluks_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
{
@@ -71,6 +86,9 @@ static BlockDriver bdrv_generic_luks = {
.bdrv_co_create_opts = gluks_co_create_opts,
.bdrv_child_perm = gluks_child_perms,
.bdrv_co_getlength = gluks_co_getlength,
+
+ .create_opts = &gluks_create_opts_luks,
+ .amend_opts = &block_crypto_amend_opts_luks,
};
static void block_generic_luks_init(void)
diff --git a/block/generic-luks.h b/block/generic-luks.h
index 2aae866fa4..f18adf41ea 100644
--- a/block/generic-luks.h
+++ b/block/generic-luks.h
@@ -23,4 +23,7 @@
#ifndef GENERIC_LUKS_H
#define GENERIC_LUKS_H
+extern QemuOptsList block_crypto_runtime_opts_luks;
+extern QemuOptsList block_crypto_amend_opts_luks;
+
#endif /* GENERIC_LUKS_H */
--
2.39.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [RFC 5/8] qapi: Introduce Gluks types to qapi
2023-12-04 16:06 [RFC 0/8] Support generic Luks encryption Hyman Huang
` (3 preceding siblings ...)
2023-12-04 16:06 ` [RFC 4/8] Gluks: Introduce Gluks options Hyman Huang
@ 2023-12-04 16:06 ` Hyman Huang
2023-12-04 16:06 ` [RFC 6/8] crypto: Provide the Luks crypto driver to Gluks Hyman Huang
` (3 subsequent siblings)
8 siblings, 0 replies; 18+ messages in thread
From: Hyman Huang @ 2023-12-04 16:06 UTC (permalink / raw)
To: qemu-devel
Cc: Kevin Wolf, Hanna Reitz, Daniel P . Berrangé, Eric Blake,
Markus Armbruster, yong.huang
Primarily using the Luks types again, Gluks adds an
extra option called "header", which points to the Luks
header node's description.
Signed-off-by: Hyman Huang <yong.huang@smartx.com>
---
qapi/block-core.json | 22 +++++++++++++++++++++-
qapi/crypto.json | 10 +++++++---
2 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/qapi/block-core.json b/qapi/block-core.json
index ca390c5700..e2208f6891 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -3185,12 +3185,14 @@
#
# @snapshot-access: Since 7.0
#
+# @gluks: Since 9.0
+#
# Since: 2.9
##
{ 'enum': 'BlockdevDriver',
'data': [ 'blkdebug', 'blklogwrites', 'blkreplay', 'blkverify', 'bochs',
'cloop', 'compress', 'copy-before-write', 'copy-on-read', 'dmg',
- 'file', 'snapshot-access', 'ftp', 'ftps', 'gluster',
+ 'file', 'snapshot-access', 'ftp', 'ftps', 'gluks', 'gluster',
{'name': 'host_cdrom', 'if': 'HAVE_HOST_BLOCK_DEVICE' },
{'name': 'host_device', 'if': 'HAVE_HOST_BLOCK_DEVICE' },
'http', 'https',
@@ -3957,6 +3959,23 @@
'*debug': 'int',
'*logfile': 'str' } }
+##
+# @BlockdevOptionsGLUKS:
+#
+# Driver specific block device options for GLUKS.
+#
+# @header: reference to the definition of the luks header node.
+#
+# @key-secret: the ID of a QCryptoSecret object providing the
+# decryption key.
+#
+# Since: 9.0
+##
+{ 'struct': 'BlockdevOptionsGLUKS',
+ 'base': 'BlockdevOptionsGenericFormat',
+ 'data': { 'header': 'BlockdevRef',
+ 'key-secret': 'str' } }
+
##
# @BlockdevOptionsIoUring:
#
@@ -4680,6 +4699,7 @@
'file': 'BlockdevOptionsFile',
'ftp': 'BlockdevOptionsCurlFtp',
'ftps': 'BlockdevOptionsCurlFtps',
+ 'gluks': 'BlockdevOptionsGLUKS',
'gluster': 'BlockdevOptionsGluster',
'host_cdrom': { 'type': 'BlockdevOptionsFile',
'if': 'HAVE_HOST_BLOCK_DEVICE' },
diff --git a/qapi/crypto.json b/qapi/crypto.json
index fd3d46ebd1..9afb242b5b 100644
--- a/qapi/crypto.json
+++ b/qapi/crypto.json
@@ -154,11 +154,13 @@
#
# @luks: LUKS encryption format. Recommended for new images
#
+# @gluks: generic LUKS encryption format. (since 9.0)
+#
# Since: 2.6
##
{ 'enum': 'QCryptoBlockFormat',
# 'prefix': 'QCRYPTO_BLOCK_FORMAT',
- 'data': ['qcow', 'luks']}
+ 'data': ['qcow', 'luks', 'gluks']}
##
# @QCryptoBlockOptionsBase:
@@ -246,7 +248,8 @@
'base': 'QCryptoBlockOptionsBase',
'discriminator': 'format',
'data': { 'qcow': 'QCryptoBlockOptionsQCow',
- 'luks': 'QCryptoBlockOptionsLUKS' } }
+ 'luks': 'QCryptoBlockOptionsLUKS',
+ 'gluks': 'QCryptoBlockOptionsLUKS' } }
##
# @QCryptoBlockCreateOptions:
@@ -260,7 +263,8 @@
'base': 'QCryptoBlockOptionsBase',
'discriminator': 'format',
'data': { 'qcow': 'QCryptoBlockOptionsQCow',
- 'luks': 'QCryptoBlockCreateOptionsLUKS' } }
+ 'luks': 'QCryptoBlockCreateOptionsLUKS',
+ 'gluks': 'QCryptoBlockCreateOptionsLUKS' } }
##
# @QCryptoBlockInfoBase:
--
2.39.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [RFC 6/8] crypto: Provide the Luks crypto driver to Gluks
2023-12-04 16:06 [RFC 0/8] Support generic Luks encryption Hyman Huang
` (4 preceding siblings ...)
2023-12-04 16:06 ` [RFC 5/8] qapi: Introduce Gluks types to qapi Hyman Huang
@ 2023-12-04 16:06 ` Hyman Huang
2023-12-04 16:06 ` [RFC 7/8] Gluks: Implement the fundamental block layer driver hooks Hyman Huang
` (2 subsequent siblings)
8 siblings, 0 replies; 18+ messages in thread
From: Hyman Huang @ 2023-12-04 16:06 UTC (permalink / raw)
To: qemu-devel
Cc: Kevin Wolf, Hanna Reitz, Daniel P . Berrangé, Eric Blake,
Markus Armbruster, yong.huang
Hooks up the Luks crypto driver for Gluks.
Signed-off-by: Hyman Huang <yong.huang@smartx.com>
---
crypto/block.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/crypto/block.c b/crypto/block.c
index 3dcf22a69f..7e695c0a04 100644
--- a/crypto/block.c
+++ b/crypto/block.c
@@ -27,6 +27,7 @@
static const QCryptoBlockDriver *qcrypto_block_drivers[] = {
[Q_CRYPTO_BLOCK_FORMAT_QCOW] = &qcrypto_block_driver_qcow,
[Q_CRYPTO_BLOCK_FORMAT_LUKS] = &qcrypto_block_driver_luks,
+ [Q_CRYPTO_BLOCK_FORMAT_GLUKS] = &qcrypto_block_driver_luks,
};
--
2.39.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [RFC 7/8] Gluks: Implement the fundamental block layer driver hooks
2023-12-04 16:06 [RFC 0/8] Support generic Luks encryption Hyman Huang
` (5 preceding siblings ...)
2023-12-04 16:06 ` [RFC 6/8] crypto: Provide the Luks crypto driver to Gluks Hyman Huang
@ 2023-12-04 16:06 ` Hyman Huang
2023-12-04 16:06 ` [RFC 8/8] block: Support Gluks format image creation using qemu-img Hyman Huang
2023-12-04 16:24 ` [RFC 0/8] Support generic Luks encryption Daniel P. Berrangé
8 siblings, 0 replies; 18+ messages in thread
From: Hyman Huang @ 2023-12-04 16:06 UTC (permalink / raw)
To: qemu-devel
Cc: Kevin Wolf, Hanna Reitz, Daniel P . Berrangé, Eric Blake,
Markus Armbruster, yong.huang
Signed-off-by: Hyman Huang <yong.huang@smartx.com>
---
block/generic-luks.c | 104 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 102 insertions(+), 2 deletions(-)
diff --git a/block/generic-luks.c b/block/generic-luks.c
index ebc0365d40..32cbedc86f 100644
--- a/block/generic-luks.c
+++ b/block/generic-luks.c
@@ -23,8 +23,14 @@
#include "qemu/osdep.h"
#include "block/block_int.h"
+#include "block/block-io.h"
#include "block/crypto.h"
+#include "block/qdict.h"
#include "crypto/block.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "qemu/module.h"
+#include "qemu/option.h"
#include "generic-luks.h"
@@ -50,10 +56,89 @@ static QemuOptsList gluks_create_opts_luks = {
},
};
+static int gluks_read_func(QCryptoBlock *block,
+ size_t offset,
+ uint8_t *buf,
+ size_t buflen,
+ void *opaque,
+ Error **errp)
+{
+
+ BlockDriverState *bs = opaque;
+ BDRVGLUKSState *s = bs->opaque;
+ ssize_t ret;
+
+ GLOBAL_STATE_CODE();
+ GRAPH_RDLOCK_GUARD_MAINLOOP();
+
+ ret = bdrv_pread(s->header, offset, buflen, buf, 0);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret, "Could not read generic luks header");
+ return ret;
+ }
+ return 0;
+}
+
static int gluks_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
{
- return 0;
+ BDRVGLUKSState *s = bs->opaque;
+ QemuOpts *opts = NULL;
+ QCryptoBlockOpenOptions *open_opts = NULL;
+ QDict *cryptoopts = NULL;
+ unsigned int cflags = 0;
+ int ret;
+
+ GLOBAL_STATE_CODE();
+
+ if (!bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
+ (BDRV_CHILD_DATA | BDRV_CHILD_PRIMARY), false, errp)) {
+ return -EINVAL;
+ }
+ s->header = bdrv_open_child(NULL, options, "header", bs,
+ &child_of_bds, BDRV_CHILD_METADATA, false,
+ errp);
+ if (!s->header) {
+ return -EINVAL;
+ }
+
+ GRAPH_RDLOCK_GUARD_MAINLOOP();
+
+ opts = qemu_opts_create(&block_crypto_runtime_opts_luks,
+ NULL, 0, &error_abort);
+ if (!qemu_opts_absorb_qdict(opts, options, errp)) {
+ ret = -EINVAL;
+ goto cleanup;
+ }
+
+ cryptoopts = qemu_opts_to_qdict(opts, NULL);
+ qdict_put_str(cryptoopts, "format",
+ QCryptoBlockFormat_str(Q_CRYPTO_BLOCK_FORMAT_GLUKS));
+
+ open_opts = block_crypto_open_opts_init(cryptoopts, errp);
+ if (!open_opts) {
+ goto cleanup;
+ }
+
+ s->crypto.block = qcrypto_block_open(open_opts, NULL,
+ gluks_read_func,
+ bs,
+ cflags,
+ 1,
+ errp);
+ if (!s->crypto.block) {
+ ret = -EIO;
+ goto cleanup;
+ }
+
+ s->header_size = qcrypto_block_get_payload_offset(s->crypto.block);
+ qcrypto_block_set_payload_offset(s->crypto.block, 0);
+
+ ret = 0;
+ cleanup:
+ qobject_unref(cryptoopts);
+ qapi_free_QCryptoBlockOpenOptions(open_opts);
+ return ret;
}
static int coroutine_fn GRAPH_UNLOCKED
@@ -70,13 +155,24 @@ gluks_child_perms(BlockDriverState *bs, BdrvChild *c,
uint64_t perm, uint64_t shared,
uint64_t *nperm, uint64_t *nshared)
{
+ if (role & BDRV_CHILD_METADATA) {
+ /* assign read permission only */
+ perm |= BLK_PERM_CONSISTENT_READ;
+ /* share all permissions */
+ shared |= BLK_PERM_ALL;
+ *nperm = perm;
+ *nshared = shared;
+ return;
+ }
+
+ bdrv_default_perms(bs, c, role, reopen_queue, perm, shared, nperm, nshared);
}
static int64_t coroutine_fn GRAPH_RDLOCK
gluks_co_getlength(BlockDriverState *bs)
{
- return 0;
+ return bdrv_co_getlength(bs->file->bs);
}
static BlockDriver bdrv_generic_luks = {
@@ -87,8 +183,12 @@ static BlockDriver bdrv_generic_luks = {
.bdrv_child_perm = gluks_child_perms,
.bdrv_co_getlength = gluks_co_getlength,
+ .bdrv_close = block_crypto_close,
+ .bdrv_co_preadv = block_crypto_co_preadv,
+ .bdrv_co_pwritev = block_crypto_co_pwritev,
.create_opts = &gluks_create_opts_luks,
.amend_opts = &block_crypto_amend_opts_luks,
+ .is_format = false,
};
static void block_generic_luks_init(void)
--
2.39.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [RFC 8/8] block: Support Gluks format image creation using qemu-img
2023-12-04 16:06 [RFC 0/8] Support generic Luks encryption Hyman Huang
` (6 preceding siblings ...)
2023-12-04 16:06 ` [RFC 7/8] Gluks: Implement the fundamental block layer driver hooks Hyman Huang
@ 2023-12-04 16:06 ` Hyman Huang
2023-12-04 16:24 ` [RFC 0/8] Support generic Luks encryption Daniel P. Berrangé
8 siblings, 0 replies; 18+ messages in thread
From: Hyman Huang @ 2023-12-04 16:06 UTC (permalink / raw)
To: qemu-devel
Cc: Kevin Wolf, Hanna Reitz, Daniel P . Berrangé, Eric Blake,
Markus Armbruster, yong.huang
To create a Gluks header image, use the command as follows:
$ qemu-img create --object secret,id=sec0,data=abc123 -f gluks
> -o cipher-alg=aes-256,cipher-mode=xts -o key-secret=sec0
> cipher.gluks
Signed-off-by: Hyman Huang <yong.huang@smartx.com>
---
block.c | 5 +++++
block/generic-luks.c | 53 +++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 57 insertions(+), 1 deletion(-)
diff --git a/block.c b/block.c
index bfb0861ec6..cc9a517a25 100644
--- a/block.c
+++ b/block.c
@@ -7517,6 +7517,11 @@ void bdrv_img_create(const char *filename, const char *fmt,
goto out;
}
+ if (!strcmp(fmt, "gluks")) {
+ qemu_opt_set(opts, "size", "0M", &local_err);
+ size = 0;
+ }
+
if (size == -1) {
error_setg(errp, "Image creation needs a size parameter");
goto out;
diff --git a/block/generic-luks.c b/block/generic-luks.c
index 32cbedc86f..579f01c4b0 100644
--- a/block/generic-luks.c
+++ b/block/generic-luks.c
@@ -145,7 +145,58 @@ static int coroutine_fn GRAPH_UNLOCKED
gluks_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, Error **errp)
{
- return 0;
+ QCryptoBlockCreateOptions *create_opts = NULL;
+ BlockDriverState *bs = NULL;
+ QDict *cryptoopts;
+ int ret;
+
+ if (qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) != 0) {
+ info_report("gluks format image need not size parameter, ignore it");
+ }
+
+ cryptoopts = qemu_opts_to_qdict_filtered(opts, NULL,
+ &gluks_create_opts_luks,
+ true);
+
+ qdict_put_str(cryptoopts, "format",
+ QCryptoBlockFormat_str(Q_CRYPTO_BLOCK_FORMAT_GLUKS));
+
+ create_opts = block_crypto_create_opts_init(cryptoopts, errp);
+ if (!create_opts) {
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ /* Create protocol layer */
+ ret = bdrv_co_create_file(filename, opts, errp);
+ if (ret < 0) {
+ goto fail;
+ }
+
+ bs = bdrv_co_open(filename, NULL, NULL,
+ BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
+ if (!bs) {
+ ret = -EINVAL;
+ goto fail;
+ }
+ /* Create format layer */
+ ret = block_crypto_co_create_generic(bs, 0, create_opts, 0, errp);
+ if (ret < 0) {
+ goto fail;
+ }
+
+ ret = 0;
+fail:
+ /*
+ * If an error occurred, delete 'filename'. Even if the file existed
+ * beforehand, it has been truncated and corrupted in the process.
+ */
+ if (ret) {
+ bdrv_graph_co_rdlock();
+ bdrv_co_delete_file_noerr(bs);
+ bdrv_graph_co_rdunlock();
+ }
+ return ret;
}
static void
--
2.39.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [RFC 0/8] Support generic Luks encryption
2023-12-04 16:06 [RFC 0/8] Support generic Luks encryption Hyman Huang
` (7 preceding siblings ...)
2023-12-04 16:06 ` [RFC 8/8] block: Support Gluks format image creation using qemu-img Hyman Huang
@ 2023-12-04 16:24 ` Daniel P. Berrangé
2023-12-04 16:32 ` Yong Huang
2023-12-04 16:41 ` Yong Huang
8 siblings, 2 replies; 18+ messages in thread
From: Daniel P. Berrangé @ 2023-12-04 16:24 UTC (permalink / raw)
To: Hyman Huang
Cc: qemu-devel, Kevin Wolf, Hanna Reitz, Eric Blake,
Markus Armbruster
On Tue, Dec 05, 2023 at 12:06:17AM +0800, Hyman Huang wrote:
> This functionality was motivated by the following to-do list seen
> in crypto documents:
> https://wiki.qemu.org/Features/Block/Crypto
>
> The last chapter says we should "separate header volume":
>
> The LUKS format has ability to store the header in a separate volume
> from the payload. We should extend the LUKS driver in QEMU to support
> this use case.
>
> As a proof-of-concept, I've created this patchset, which I've named
> the Gluks: generic luks. As their name suggests, they offer encryption
> for any format that QEMU theoretically supports.
I don't see the point in creating a new driver.
I would expect detached header support to be implemented via an
optional new 'header' field in the existing driver. ie
diff --git a/qapi/block-core.json b/qapi/block-core.json
index ca390c5700..48d1f2a974 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -3352,11 +3352,15 @@
# decryption key (since 2.6). Mandatory except when doing a
# metadata-only probe of the image.
#
+# @header: optional reference to the location of a blockdev
+# storing a detached LUKS heaer
+#
# Since: 2.9
##
{ 'struct': 'BlockdevOptionsLUKS',
'base': 'BlockdevOptionsGenericFormat',
- 'data': { '*key-secret': 'str' } }
+ 'data': { '*key-secret': 'str',
+ "*header-file': 'BlockdevRef'} }
##
# @BlockdevOptionsGenericCOWFormat:
@@ -4941,9 +4945,18 @@
#
# Driver specific image creation options for LUKS.
#
-# @file: Node to create the image format on
+# @file: Node to create the image format on. Mandatory
+# unless a detached header file is specified using
+# @header.
#
-# @size: Size of the virtual disk in bytes
+# @size: Size of the virtual disk in bytes. Mandatory
+# unless a detached header file is specified using
+# @header.
+#
+# @header: optional reference to the location of a blockdev
+# storing a detached LUKS heaer. The @file option is
+# is optional when this is given, unless it is desired
+# to perform pre-allocation
#
# @preallocation: Preallocation mode for the new image (since: 4.2)
# (default: off; allowed values: off, metadata, falloc, full)
@@ -4952,8 +4965,9 @@
##
{ 'struct': 'BlockdevCreateOptionsLUKS',
'base': 'QCryptoBlockCreateOptionsLUKS',
- 'data': { 'file': 'BlockdevRef',
- 'size': 'size',
+ 'data': { '*file': 'BlockdevRef',
+ '*size': 'size',
+ '*header': 'BlockdevRef'
'*preallocation': 'PreallocMode' } }
##
It ends up giving basicallly the same workflow as you outline,
without needing the new block driver
With 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 :|
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [RFC 0/8] Support generic Luks encryption
2023-12-04 16:24 ` [RFC 0/8] Support generic Luks encryption Daniel P. Berrangé
@ 2023-12-04 16:32 ` Yong Huang
2023-12-04 16:41 ` Yong Huang
1 sibling, 0 replies; 18+ messages in thread
From: Yong Huang @ 2023-12-04 16:32 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Kevin Wolf, Hanna Reitz, Eric Blake,
Markus Armbruster
[-- Attachment #1: Type: text/plain, Size: 3469 bytes --]
On Tue, Dec 5, 2023 at 12:24 AM Daniel P. Berrangé <berrange@redhat.com>
wrote:
> On Tue, Dec 05, 2023 at 12:06:17AM +0800, Hyman Huang wrote:
> > This functionality was motivated by the following to-do list seen
> > in crypto documents:
> > https://wiki.qemu.org/Features/Block/Crypto
> >
> > The last chapter says we should "separate header volume":
> >
> > The LUKS format has ability to store the header in a separate volume
> > from the payload. We should extend the LUKS driver in QEMU to support
> > this use case.
> >
> > As a proof-of-concept, I've created this patchset, which I've named
> > the Gluks: generic luks. As their name suggests, they offer encryption
> > for any format that QEMU theoretically supports.
>
> I don't see the point in creating a new driver.
>
Indeed, this definitely makes things simple. The next version would do that
!
>
> I would expect detached header support to be implemented via an
> optional new 'header' field in the existing driver. ie
>
> diff --git a/qapi/block-core.json b/qapi/block-core.json
> index ca390c5700..48d1f2a974 100644
> --- a/qapi/block-core.json
> +++ b/qapi/block-core.json
> @@ -3352,11 +3352,15 @@
> # decryption key (since 2.6). Mandatory except when doing a
> # metadata-only probe of the image.
> #
> +# @header: optional reference to the location of a blockdev
> +# storing a detached LUKS heaer
> +#
> # Since: 2.9
> ##
> { 'struct': 'BlockdevOptionsLUKS',
> 'base': 'BlockdevOptionsGenericFormat',
> - 'data': { '*key-secret': 'str' } }
> + 'data': { '*key-secret': 'str',
> + "*header-file': 'BlockdevRef'} }
>
> ##
> # @BlockdevOptionsGenericCOWFormat:
> @@ -4941,9 +4945,18 @@
> #
> # Driver specific image creation options for LUKS.
> #
> -# @file: Node to create the image format on
> +# @file: Node to create the image format on. Mandatory
> +# unless a detached header file is specified using
> +# @header.
> #
> -# @size: Size of the virtual disk in bytes
> +# @size: Size of the virtual disk in bytes. Mandatory
> +# unless a detached header file is specified using
> +# @header.
> +#
> +# @header: optional reference to the location of a blockdev
> +# storing a detached LUKS heaer. The @file option is
> +# is optional when this is given, unless it is desired
> +# to perform pre-allocation
> #
> # @preallocation: Preallocation mode for the new image (since: 4.2)
> # (default: off; allowed values: off, metadata, falloc, full)
> @@ -4952,8 +4965,9 @@
> ##
> { 'struct': 'BlockdevCreateOptionsLUKS',
> 'base': 'QCryptoBlockCreateOptionsLUKS',
> - 'data': { 'file': 'BlockdevRef',
> - 'size': 'size',
> + 'data': { '*file': 'BlockdevRef',
> + '*size': 'size',
> + '*header': 'BlockdevRef'
> '*preallocation': 'PreallocMode' } }
>
> ##
>
> It ends up giving basicallly the same workflow as you outline,
> without needing the new block driver
>
Yes, most of the logic reuse the pre-existing Luks driver.
> With 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 :|
>
>
--
Best regards
[-- Attachment #2: Type: text/html, Size: 6230 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC 0/8] Support generic Luks encryption
2023-12-04 16:24 ` [RFC 0/8] Support generic Luks encryption Daniel P. Berrangé
2023-12-04 16:32 ` Yong Huang
@ 2023-12-04 16:41 ` Yong Huang
2023-12-04 16:51 ` Daniel P. Berrangé
1 sibling, 1 reply; 18+ messages in thread
From: Yong Huang @ 2023-12-04 16:41 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Kevin Wolf, Hanna Reitz, Eric Blake,
Markus Armbruster
[-- Attachment #1: Type: text/plain, Size: 3819 bytes --]
On Tue, Dec 5, 2023 at 12:24 AM Daniel P. Berrangé <berrange@redhat.com>
wrote:
> On Tue, Dec 05, 2023 at 12:06:17AM +0800, Hyman Huang wrote:
> > This functionality was motivated by the following to-do list seen
> > in crypto documents:
> > https://wiki.qemu.org/Features/Block/Crypto
> >
> > The last chapter says we should "separate header volume":
> >
> > The LUKS format has ability to store the header in a separate volume
> > from the payload. We should extend the LUKS driver in QEMU to support
> > this use case.
> >
> > As a proof-of-concept, I've created this patchset, which I've named
> > the Gluks: generic luks. As their name suggests, they offer encryption
> > for any format that QEMU theoretically supports.
>
> I don't see the point in creating a new driver.
>
> I would expect detached header support to be implemented via an
> optional new 'header' field in the existing driver. ie
>
> diff --git a/qapi/block-core.json b/qapi/block-core.json
> index ca390c5700..48d1f2a974 100644
> --- a/qapi/block-core.json
> +++ b/qapi/block-core.json
> @@ -3352,11 +3352,15 @@
> # decryption key (since 2.6). Mandatory except when doing a
> # metadata-only probe of the image.
> #
> +# @header: optional reference to the location of a blockdev
> +# storing a detached LUKS heaer
> +#
> # Since: 2.9
> ##
> { 'struct': 'BlockdevOptionsLUKS',
> 'base': 'BlockdevOptionsGenericFormat',
> - 'data': { '*key-secret': 'str' } }
> + 'data': { '*key-secret': 'str',
> + "*header-file': 'BlockdevRef'} }
>
> ##
> # @BlockdevOptionsGenericCOWFormat:
> @@ -4941,9 +4945,18 @@
> #
> # Driver specific image creation options for LUKS.
> #
> -# @file: Node to create the image format on
> +# @file: Node to create the image format on. Mandatory
> +# unless a detached header file is specified using
> +# @header.
> #
> -# @size: Size of the virtual disk in bytes
> +# @size: Size of the virtual disk in bytes. Mandatory
> +# unless a detached header file is specified using
> +# @header.
> +#
> +# @header: optional reference to the location of a blockdev
> +# storing a detached LUKS heaer. The @file option is
> +# is optional when this is given, unless it is desired
> +# to perform pre-allocation
> #
> # @preallocation: Preallocation mode for the new image (since: 4.2)
> # (default: off; allowed values: off, metadata, falloc, full)
> @@ -4952,8 +4965,9 @@
> ##
> { 'struct': 'BlockdevCreateOptionsLUKS',
> 'base': 'QCryptoBlockCreateOptionsLUKS',
> - 'data': { 'file': 'BlockdevRef',
> - 'size': 'size',
> + 'data': { '*file': 'BlockdevRef',
> + '*size': 'size',
> + '*header': 'BlockdevRef'
> '*preallocation': 'PreallocMode' } }
>
> ##
>
> It ends up giving basicallly the same workflow as you outline,
> without needing the new block driver
>
How about the design and usage, could it be simpler? Any advice? :)
As you can see below, the Gluks format block layer driver's design is
quite simple.
virtio-blk/vhost-user-blk...(front-end device)
^
|
Gluks (format-like disk node)
/ \
file header (blockdev reference)
/ \
file file (protocol node)
| |
disk data Luks data
>
> With 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 :|
>
>
--
Best regards
[-- Attachment #2: Type: text/html, Size: 7973 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC 0/8] Support generic Luks encryption
2023-12-04 16:41 ` Yong Huang
@ 2023-12-04 16:51 ` Daniel P. Berrangé
2023-12-04 17:32 ` Yong Huang
0 siblings, 1 reply; 18+ messages in thread
From: Daniel P. Berrangé @ 2023-12-04 16:51 UTC (permalink / raw)
To: Yong Huang
Cc: qemu-devel, Kevin Wolf, Hanna Reitz, Eric Blake,
Markus Armbruster
On Tue, Dec 05, 2023 at 12:41:16AM +0800, Yong Huang wrote:
> On Tue, Dec 5, 2023 at 12:24 AM Daniel P. Berrangé <berrange@redhat.com>
> wrote:
>
> > On Tue, Dec 05, 2023 at 12:06:17AM +0800, Hyman Huang wrote:
> > > This functionality was motivated by the following to-do list seen
> > > in crypto documents:
> > > https://wiki.qemu.org/Features/Block/Crypto
> > >
> > > The last chapter says we should "separate header volume":
> > >
> > > The LUKS format has ability to store the header in a separate volume
> > > from the payload. We should extend the LUKS driver in QEMU to support
> > > this use case.
> > >
> > > As a proof-of-concept, I've created this patchset, which I've named
> > > the Gluks: generic luks. As their name suggests, they offer encryption
> > > for any format that QEMU theoretically supports.
> >
> > I don't see the point in creating a new driver.
> >
> > I would expect detached header support to be implemented via an
> > optional new 'header' field in the existing driver. ie
> >
> > diff --git a/qapi/block-core.json b/qapi/block-core.json
> > index ca390c5700..48d1f2a974 100644
> > --- a/qapi/block-core.json
> > +++ b/qapi/block-core.json
> > @@ -3352,11 +3352,15 @@
> > # decryption key (since 2.6). Mandatory except when doing a
> > # metadata-only probe of the image.
> > #
> > +# @header: optional reference to the location of a blockdev
> > +# storing a detached LUKS heaer
> > +#
> > # Since: 2.9
> > ##
> > { 'struct': 'BlockdevOptionsLUKS',
> > 'base': 'BlockdevOptionsGenericFormat',
> > - 'data': { '*key-secret': 'str' } }
> > + 'data': { '*key-secret': 'str',
> > + "*header-file': 'BlockdevRef'} }
> >
> > ##
> > # @BlockdevOptionsGenericCOWFormat:
> > @@ -4941,9 +4945,18 @@
> > #
> > # Driver specific image creation options for LUKS.
> > #
> > -# @file: Node to create the image format on
> > +# @file: Node to create the image format on. Mandatory
> > +# unless a detached header file is specified using
> > +# @header.
> > #
> > -# @size: Size of the virtual disk in bytes
> > +# @size: Size of the virtual disk in bytes. Mandatory
> > +# unless a detached header file is specified using
> > +# @header.
> > +#
> > +# @header: optional reference to the location of a blockdev
> > +# storing a detached LUKS heaer. The @file option is
> > +# is optional when this is given, unless it is desired
> > +# to perform pre-allocation
> > #
> > # @preallocation: Preallocation mode for the new image (since: 4.2)
> > # (default: off; allowed values: off, metadata, falloc, full)
> > @@ -4952,8 +4965,9 @@
> > ##
> > { 'struct': 'BlockdevCreateOptionsLUKS',
> > 'base': 'QCryptoBlockCreateOptionsLUKS',
> > - 'data': { 'file': 'BlockdevRef',
> > - 'size': 'size',
> > + 'data': { '*file': 'BlockdevRef',
> > + '*size': 'size',
> > + '*header': 'BlockdevRef'
> > '*preallocation': 'PreallocMode' } }
> >
> > ##
> >
> > It ends up giving basicallly the same workflow as you outline,
> > without needing the new block driver
> >
>
> How about the design and usage, could it be simpler? Any advice? :)
>
>
> As you can see below, the Gluks format block layer driver's design is
> quite simple.
>
> virtio-blk/vhost-user-blk...(front-end device)
> ^
> |
> Gluks (format-like disk node)
> / \
> file header (blockdev reference)
> / \
> file file (protocol node)
> | |
> disk data Luks data
What I suggested above ends up with the exact same block driver
graph, unless I'm missing something.
With 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 :|
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC 0/8] Support generic Luks encryption
2023-12-04 16:51 ` Daniel P. Berrangé
@ 2023-12-04 17:32 ` Yong Huang
2023-12-04 17:43 ` Daniel P. Berrangé
0 siblings, 1 reply; 18+ messages in thread
From: Yong Huang @ 2023-12-04 17:32 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Kevin Wolf, Hanna Reitz, Eric Blake,
Markus Armbruster
[-- Attachment #1: Type: text/plain, Size: 5078 bytes --]
On Tue, Dec 5, 2023 at 12:51 AM Daniel P. Berrangé <berrange@redhat.com>
wrote:
> On Tue, Dec 05, 2023 at 12:41:16AM +0800, Yong Huang wrote:
> > On Tue, Dec 5, 2023 at 12:24 AM Daniel P. Berrangé <berrange@redhat.com>
> > wrote:
> >
> > > On Tue, Dec 05, 2023 at 12:06:17AM +0800, Hyman Huang wrote:
> > > > This functionality was motivated by the following to-do list seen
> > > > in crypto documents:
> > > > https://wiki.qemu.org/Features/Block/Crypto
> > > >
> > > > The last chapter says we should "separate header volume":
> > > >
> > > > The LUKS format has ability to store the header in a separate volume
> > > > from the payload. We should extend the LUKS driver in QEMU to support
> > > > this use case.
> > > >
> > > > As a proof-of-concept, I've created this patchset, which I've named
> > > > the Gluks: generic luks. As their name suggests, they offer
> encryption
> > > > for any format that QEMU theoretically supports.
> > >
> > > I don't see the point in creating a new driver.
> > >
> > > I would expect detached header support to be implemented via an
> > > optional new 'header' field in the existing driver. ie
> > >
> > > diff --git a/qapi/block-core.json b/qapi/block-core.json
> > > index ca390c5700..48d1f2a974 100644
> > > --- a/qapi/block-core.json
> > > +++ b/qapi/block-core.json
> > > @@ -3352,11 +3352,15 @@
> > > # decryption key (since 2.6). Mandatory except when doing a
> > > # metadata-only probe of the image.
> > > #
> > > +# @header: optional reference to the location of a blockdev
> > > +# storing a detached LUKS heaer
> > > +#
> > > # Since: 2.9
> > > ##
> > > { 'struct': 'BlockdevOptionsLUKS',
> > > 'base': 'BlockdevOptionsGenericFormat',
> > > - 'data': { '*key-secret': 'str' } }
> > > + 'data': { '*key-secret': 'str',
> > > + "*header-file': 'BlockdevRef'} }
> > >
> > > ##
> > > # @BlockdevOptionsGenericCOWFormat:
> > > @@ -4941,9 +4945,18 @@
> > > #
> > > # Driver specific image creation options for LUKS.
> > > #
> > > -# @file: Node to create the image format on
> > > +# @file: Node to create the image format on. Mandatory
> > > +# unless a detached header file is specified using
> > > +# @header.
> > > #
> > > -# @size: Size of the virtual disk in bytes
> > > +# @size: Size of the virtual disk in bytes. Mandatory
> > > +# unless a detached header file is specified using
> > > +# @header.
> > > +#
> > > +# @header: optional reference to the location of a blockdev
> > > +# storing a detached LUKS heaer. The @file option is
> > > +# is optional when this is given, unless it is desired
> > > +# to perform pre-allocation
> > > #
> > > # @preallocation: Preallocation mode for the new image (since: 4.2)
> > > # (default: off; allowed values: off, metadata, falloc, full)
> > > @@ -4952,8 +4965,9 @@
> > > ##
> > > { 'struct': 'BlockdevCreateOptionsLUKS',
> > > 'base': 'QCryptoBlockCreateOptionsLUKS',
> > > - 'data': { 'file': 'BlockdevRef',
> > > - 'size': 'size',
> > > + 'data': { '*file': 'BlockdevRef',
> > > + '*size': 'size',
> > > + '*header': 'BlockdevRef'
> > > '*preallocation': 'PreallocMode' } }
> > >
> > > ##
> > >
> > > It ends up giving basicallly the same workflow as you outline,
> > > without needing the new block driver
> > >
> >
> > How about the design and usage, could it be simpler? Any advice? :)
> >
> >
> > As you can see below, the Gluks format block layer driver's design is
> > quite simple.
> >
> > virtio-blk/vhost-user-blk...(front-end device)
> > ^
> > |
> > Gluks (format-like disk node)
> > / \
> > file header (blockdev reference)
> > / \
> > file file (protocol node)
> > | |
> > disk data Luks data
>
> What I suggested above ends up with the exact same block driver
> graph, unless I'm missing something.
>
I could overlook something or fail to adequately convey the goal of the
patchset. :(
Indeed, utilizing the same block driver might be effective if our only goal
is to divide the header volume, giving us an additional way to use Luks.
While supporting encryption for any disk format that QEMU is capable of
supporting is another feature of this patchset. This implies that we might
link the Luks header to other blockdev references, which might alter how
the Luks are used and make them incompatible with it. It's not
user-friendly in my opinion, and I'm not aware of a more elegant solution.
> With 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 :|
>
>
--
Best regards
[-- Attachment #2: Type: text/html, Size: 8438 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC 0/8] Support generic Luks encryption
2023-12-04 17:32 ` Yong Huang
@ 2023-12-04 17:43 ` Daniel P. Berrangé
2023-12-05 1:51 ` Yong Huang
2023-12-05 11:27 ` Kevin Wolf
0 siblings, 2 replies; 18+ messages in thread
From: Daniel P. Berrangé @ 2023-12-04 17:43 UTC (permalink / raw)
To: Yong Huang
Cc: qemu-devel, Kevin Wolf, Hanna Reitz, Eric Blake,
Markus Armbruster
On Tue, Dec 05, 2023 at 01:32:51AM +0800, Yong Huang wrote:
> On Tue, Dec 5, 2023 at 12:51 AM Daniel P. Berrangé <berrange@redhat.com>
> wrote:
>
> > On Tue, Dec 05, 2023 at 12:41:16AM +0800, Yong Huang wrote:
> > > On Tue, Dec 5, 2023 at 12:24 AM Daniel P. Berrangé <berrange@redhat.com>
> > > wrote:
> > >
> > > > On Tue, Dec 05, 2023 at 12:06:17AM +0800, Hyman Huang wrote:
> > > > > This functionality was motivated by the following to-do list seen
> > > > > in crypto documents:
> > > > > https://wiki.qemu.org/Features/Block/Crypto
> > > > >
> > > > > The last chapter says we should "separate header volume":
> > > > >
> > > > > The LUKS format has ability to store the header in a separate volume
> > > > > from the payload. We should extend the LUKS driver in QEMU to support
> > > > > this use case.
> > > > >
> > > > > As a proof-of-concept, I've created this patchset, which I've named
> > > > > the Gluks: generic luks. As their name suggests, they offer
> > encryption
> > > > > for any format that QEMU theoretically supports.
> > > >
> > > > I don't see the point in creating a new driver.
> > > >
> > > > I would expect detached header support to be implemented via an
> > > > optional new 'header' field in the existing driver. ie
> > > >
> > > > diff --git a/qapi/block-core.json b/qapi/block-core.json
> > > > index ca390c5700..48d1f2a974 100644
> > > > --- a/qapi/block-core.json
> > > > +++ b/qapi/block-core.json
> > > > @@ -3352,11 +3352,15 @@
> > > > # decryption key (since 2.6). Mandatory except when doing a
> > > > # metadata-only probe of the image.
> > > > #
> > > > +# @header: optional reference to the location of a blockdev
> > > > +# storing a detached LUKS heaer
> > > > +#
> > > > # Since: 2.9
> > > > ##
> > > > { 'struct': 'BlockdevOptionsLUKS',
> > > > 'base': 'BlockdevOptionsGenericFormat',
> > > > - 'data': { '*key-secret': 'str' } }
> > > > + 'data': { '*key-secret': 'str',
> > > > + "*header-file': 'BlockdevRef'} }
> > > >
> > > > ##
> > > > # @BlockdevOptionsGenericCOWFormat:
> > > > @@ -4941,9 +4945,18 @@
> > > > #
> > > > # Driver specific image creation options for LUKS.
> > > > #
> > > > -# @file: Node to create the image format on
> > > > +# @file: Node to create the image format on. Mandatory
> > > > +# unless a detached header file is specified using
> > > > +# @header.
> > > > #
> > > > -# @size: Size of the virtual disk in bytes
> > > > +# @size: Size of the virtual disk in bytes. Mandatory
> > > > +# unless a detached header file is specified using
> > > > +# @header.
> > > > +#
> > > > +# @header: optional reference to the location of a blockdev
> > > > +# storing a detached LUKS heaer. The @file option is
> > > > +# is optional when this is given, unless it is desired
> > > > +# to perform pre-allocation
> > > > #
> > > > # @preallocation: Preallocation mode for the new image (since: 4.2)
> > > > # (default: off; allowed values: off, metadata, falloc, full)
> > > > @@ -4952,8 +4965,9 @@
> > > > ##
> > > > { 'struct': 'BlockdevCreateOptionsLUKS',
> > > > 'base': 'QCryptoBlockCreateOptionsLUKS',
> > > > - 'data': { 'file': 'BlockdevRef',
> > > > - 'size': 'size',
> > > > + 'data': { '*file': 'BlockdevRef',
> > > > + '*size': 'size',
> > > > + '*header': 'BlockdevRef'
> > > > '*preallocation': 'PreallocMode' } }
> > > >
> > > > ##
> > > >
> > > > It ends up giving basicallly the same workflow as you outline,
> > > > without needing the new block driver
> > > >
> > >
> > > How about the design and usage, could it be simpler? Any advice? :)
> > >
> > >
> > > As you can see below, the Gluks format block layer driver's design is
> > > quite simple.
> > >
> > > virtio-blk/vhost-user-blk...(front-end device)
> > > ^
> > > |
> > > Gluks (format-like disk node)
> > > / \
> > > file header (blockdev reference)
> > > / \
> > > file file (protocol node)
> > > | |
> > > disk data Luks data
> >
> > What I suggested above ends up with the exact same block driver
> > graph, unless I'm missing something.
> >
>
> I could overlook something or fail to adequately convey the goal of the
> patchset. :(
>
> Indeed, utilizing the same block driver might be effective if our only goal
> is to divide the header volume, giving us an additional way to use Luks.
>
> While supporting encryption for any disk format that QEMU is capable of
> supporting is another feature of this patchset. This implies that we might
> link the Luks header to other blockdev references, which might alter how
> the Luks are used and make them incompatible with it. It's not
> user-friendly in my opinion, and I'm not aware of a more elegant solution.
That existing LUKS driver can already be used in combination with
any QEMU block driver, and in the case of disk formats, can be used
either above or below the format, depending on whether you want to
encrypt just the image payload, or the payload and metadata ie.
We can do
luks -> qcow2 -> file (qcow2 header and qcow2 payload protected)
or
qcow2 -> luks -> file (only qcow2 payload protected)
And in the qcow2 case, we also have support for LUKS integrated natively
into the qcow2 format, which is similar to the 2nd case, with the
benefit that we're explicit that the image requires encryption.
With 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 :|
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC 0/8] Support generic Luks encryption
2023-12-04 17:43 ` Daniel P. Berrangé
@ 2023-12-05 1:51 ` Yong Huang
2023-12-05 11:37 ` Daniel P. Berrangé
2023-12-05 11:27 ` Kevin Wolf
1 sibling, 1 reply; 18+ messages in thread
From: Yong Huang @ 2023-12-05 1:51 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Kevin Wolf, Hanna Reitz, Eric Blake,
Markus Armbruster
[-- Attachment #1: Type: text/plain, Size: 8889 bytes --]
On Tue, Dec 5, 2023 at 1:44 AM Daniel P. Berrangé <berrange@redhat.com>
wrote:
> On Tue, Dec 05, 2023 at 01:32:51AM +0800, Yong Huang wrote:
> > On Tue, Dec 5, 2023 at 12:51 AM Daniel P. Berrangé <berrange@redhat.com>
> > wrote:
> >
> > > On Tue, Dec 05, 2023 at 12:41:16AM +0800, Yong Huang wrote:
> > > > On Tue, Dec 5, 2023 at 12:24 AM Daniel P. Berrangé <
> berrange@redhat.com>
> > > > wrote:
> > > >
> > > > > On Tue, Dec 05, 2023 at 12:06:17AM +0800, Hyman Huang wrote:
> > > > > > This functionality was motivated by the following to-do list seen
> > > > > > in crypto documents:
> > > > > > https://wiki.qemu.org/Features/Block/Crypto
> > > > > >
> > > > > > The last chapter says we should "separate header volume":
> > > > > >
> > > > > > The LUKS format has ability to store the header in a separate
> volume
> > > > > > from the payload. We should extend the LUKS driver in QEMU to
> support
> > > > > > this use case.
> > > > > >
> > > > > > As a proof-of-concept, I've created this patchset, which I've
> named
> > > > > > the Gluks: generic luks. As their name suggests, they offer
> > > encryption
> > > > > > for any format that QEMU theoretically supports.
> > > > >
> > > > > I don't see the point in creating a new driver.
> > > > >
> > > > > I would expect detached header support to be implemented via an
> > > > > optional new 'header' field in the existing driver. ie
> > > > >
> > > > > diff --git a/qapi/block-core.json b/qapi/block-core.json
> > > > > index ca390c5700..48d1f2a974 100644
> > > > > --- a/qapi/block-core.json
> > > > > +++ b/qapi/block-core.json
> > > > > @@ -3352,11 +3352,15 @@
> > > > > # decryption key (since 2.6). Mandatory except when doing a
> > > > > # metadata-only probe of the image.
> > > > > #
> > > > > +# @header: optional reference to the location of a blockdev
> > > > > +# storing a detached LUKS heaer
> > > > > +#
> > > > > # Since: 2.9
> > > > > ##
> > > > > { 'struct': 'BlockdevOptionsLUKS',
> > > > > 'base': 'BlockdevOptionsGenericFormat',
> > > > > - 'data': { '*key-secret': 'str' } }
> > > > > + 'data': { '*key-secret': 'str',
> > > > > + "*header-file': 'BlockdevRef'} }
> > > > >
> > > > > ##
> > > > > # @BlockdevOptionsGenericCOWFormat:
> > > > > @@ -4941,9 +4945,18 @@
> > > > > #
> > > > > # Driver specific image creation options for LUKS.
> > > > > #
> > > > > -# @file: Node to create the image format on
> > > > > +# @file: Node to create the image format on. Mandatory
> > > > > +# unless a detached header file is specified using
> > > > > +# @header.
> > > > > #
> > > > > -# @size: Size of the virtual disk in bytes
> > > > > +# @size: Size of the virtual disk in bytes. Mandatory
> > > > > +# unless a detached header file is specified using
> > > > > +# @header.
> > > > > +#
> > > > > +# @header: optional reference to the location of a blockdev
> > > > > +# storing a detached LUKS heaer. The @file option is
> > > > > +# is optional when this is given, unless it is desired
> > > > > +# to perform pre-allocation
> > > > > #
> > > > > # @preallocation: Preallocation mode for the new image (since:
> 4.2)
> > > > > # (default: off; allowed values: off, metadata, falloc, full)
> > > > > @@ -4952,8 +4965,9 @@
> > > > > ##
> > > > > { 'struct': 'BlockdevCreateOptionsLUKS',
> > > > > 'base': 'QCryptoBlockCreateOptionsLUKS',
> > > > > - 'data': { 'file': 'BlockdevRef',
> > > > > - 'size': 'size',
> > > > > + 'data': { '*file': 'BlockdevRef',
> > > > > + '*size': 'size',
> > > > > + '*header': 'BlockdevRef'
> > > > > '*preallocation': 'PreallocMode' } }
> > > > >
> > > > > ##
> > > > >
> > > > > It ends up giving basicallly the same workflow as you outline,
> > > > > without needing the new block driver
> > > > >
> > > >
> > > > How about the design and usage, could it be simpler? Any advice? :)
> > > >
> > > >
> > > > As you can see below, the Gluks format block layer driver's design is
> > > > quite simple.
> > > >
> > > > virtio-blk/vhost-user-blk...(front-end device)
> > > > ^
> > > > |
> > > > Gluks (format-like disk node)
> > > > / \
> > > > file header (blockdev reference)
> > > > / \
> > > > file file (protocol node)
> > > > | |
> > > > disk data Luks data
> > >
> > > What I suggested above ends up with the exact same block driver
> > > graph, unless I'm missing something.
> > >
> >
> > I could overlook something or fail to adequately convey the goal of the
> > patchset. :(
> >
> > Indeed, utilizing the same block driver might be effective if our only
> goal
> > is to divide the header volume, giving us an additional way to use Luks.
> >
> > While supporting encryption for any disk format that QEMU is capable of
> > supporting is another feature of this patchset. This implies that we
> might
> > link the Luks header to other blockdev references, which might alter how
> > the Luks are used and make them incompatible with it. It's not
> > user-friendly in my opinion, and I'm not aware of a more elegant
> solution.
>
> That existing LUKS driver can already be used in combination with
> any QEMU block driver, and in the case of disk formats, can be used
> either above or below the format, depending on whether you want to
> encrypt just the image payload, or the payload and metadata ie.
>
> We can do
>
> luks -> qcow2 -> file (qcow2 header and qcow2 payload protected)
>
OK, I prefer this solution so that we can support any format implemented
by the QEMU block driver.
>
> or
>
> qcow2 -> luks -> file (only qcow2 payload protected)
>
> And in the qcow2 case, we also have support for LUKS integrated natively
> into the qcow2 format, which is similar to the 2nd case, with the
> benefit that we're explicit that the image requires encryption.
>
> With 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 :|
>
> Let me make a conclusion about our discussion, if i
misunderstand something,
point that out please:
1. To achieve the generic encryption, extending the pre-existing LUKS QEMU
block driver is suggested in practice.
2. Introducing a optional field called "header-file" that store the LUKS
header
independently, and once "header-file" was specified, we should use it to
encrypt/decrypt the blockdev node referenced by the "file" field.
The blockdev tree is like:
virtio-blk/vhost-user-blk...(frontend device)
^
|
LUKS
/ \
file header-file
/ \
data protocol node LUKS header protocol node
3. The usage of the generic LUKS is like:
Take the qcow2 as an example:
1. add a protocol blockdev node of data disk
$ virsh qemu-monitor-command vm '{"execute":"blockdev-add",
"arguments":{"node-name": "libvirt-1-storage", "driver": "file",
"filename": "/path/to/test_disk.qcow2"}}'
2. add a protocol blockdev node of Luks header as above.
$ virsh qemu-monitor-command vm '{"execute":"blockdev-add",
"arguments":{"node-name": "libvirt-2-storage", "driver": "file",
"filename": "/path/to/cipher.gluks" }}'
3. add the secret for decrypting the cipher stored in Gluks header as
above
$ virsh qemu-monitor-command vm '{"execute":"object-add",
"arguments":{"qom-type": "secret", "id":
"libvirt-2-storage-secret0", "data": "abc123"}}'
4. add the qcow2-drived blockdev format node:
$ virsh qemu-monitor-command vm '{"execute":"blockdev-add",
"arguments":{"node-name": "libvirt-1-format", "driver": "qcow2",
"file": "libvirt-1-storage"}}'
5. add the luks-drived blockdev to connect the qcow2 disk with Luks
header by specifying the field "header-file"
$ virsh qemu-monitor-command vm '{"execute":"blockdev-add",
"arguments":{"node-name": "libvirt-2-format", "driver": "luks",
"file": "libvirt-1-format", "header-file": "libvirt-2-storage",
"key-secret": "libvirt-2-format-secret0"}}'
6. add the device finally
$ virsh qemu-monitor-command vm '{"execute":"device_add",
"arguments": {"num-queues": "1", "driver": "virtio-blk-pci", "scsi":
"off", "drive": "libvirt-2-format", "id": "virtio-disk2"}}'
Anyway, thanks for the comments.
Yong.
--
Best regards
[-- Attachment #2: Type: text/html, Size: 16771 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC 0/8] Support generic Luks encryption
2023-12-05 1:51 ` Yong Huang
@ 2023-12-05 11:37 ` Daniel P. Berrangé
0 siblings, 0 replies; 18+ messages in thread
From: Daniel P. Berrangé @ 2023-12-05 11:37 UTC (permalink / raw)
To: Yong Huang
Cc: qemu-devel, Kevin Wolf, Hanna Reitz, Eric Blake,
Markus Armbruster
On Tue, Dec 05, 2023 at 09:51:21AM +0800, Yong Huang wrote:
> Let me make a conclusion about our discussion, if i
> misunderstand something,
> point that out please:
>
> 1. To achieve the generic encryption, extending the pre-existing LUKS QEMU
> block driver is suggested in practice.
yes
>
> 2. Introducing a optional field called "header-file" that store the LUKS
> header
> independently, and once "header-file" was specified, we should use it to
> encrypt/decrypt the blockdev node referenced by the "file" field.
Yes.
>
> The blockdev tree is like:
> virtio-blk/vhost-user-blk...(frontend device)
> ^
> |
> LUKS
> / \
> file header-file
> / \
> data protocol node LUKS header protocol node
That is one possible blockdev tree, but there are many possible
variations.
> 3. The usage of the generic LUKS is like:
>
> Take the qcow2 as an example:
>
> 1. add a protocol blockdev node of data disk
> $ virsh qemu-monitor-command vm '{"execute":"blockdev-add",
> "arguments":{"node-name": "libvirt-1-storage", "driver": "file",
> "filename": "/path/to/test_disk.qcow2"}}'
>
> 2. add a protocol blockdev node of Luks header as above.
> $ virsh qemu-monitor-command vm '{"execute":"blockdev-add",
> "arguments":{"node-name": "libvirt-2-storage", "driver": "file",
> "filename": "/path/to/cipher.gluks" }}'
>
> 3. add the secret for decrypting the cipher stored in Gluks header as
> above
> $ virsh qemu-monitor-command vm '{"execute":"object-add",
> "arguments":{"qom-type": "secret", "id":
> "libvirt-2-storage-secret0", "data": "abc123"}}'
>
> 4. add the qcow2-drived blockdev format node:
> $ virsh qemu-monitor-command vm '{"execute":"blockdev-add",
> "arguments":{"node-name": "libvirt-1-format", "driver": "qcow2",
> "file": "libvirt-1-storage"}}'
>
> 5. add the luks-drived blockdev to connect the qcow2 disk with Luks
> header by specifying the field "header-file"
> $ virsh qemu-monitor-command vm '{"execute":"blockdev-add",
> "arguments":{"node-name": "libvirt-2-format", "driver": "luks",
> "file": "libvirt-1-format", "header-file": "libvirt-2-storage",
> "key-secret": "libvirt-2-format-secret0"}}'
>
> 6. add the device finally
> $ virsh qemu-monitor-command vm '{"execute":"device_add",
> "arguments": {"num-queues": "1", "driver": "virtio-blk-pci", "scsi":
> "off", "drive": "libvirt-2-format", "id": "virtio-disk2"}}'
Yes, that looks like a valid sequence of steps.
With 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 :|
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC 0/8] Support generic Luks encryption
2023-12-04 17:43 ` Daniel P. Berrangé
2023-12-05 1:51 ` Yong Huang
@ 2023-12-05 11:27 ` Kevin Wolf
1 sibling, 0 replies; 18+ messages in thread
From: Kevin Wolf @ 2023-12-05 11:27 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: Yong Huang, qemu-devel, Hanna Reitz, Eric Blake,
Markus Armbruster
Am 04.12.2023 um 18:43 hat Daniel P. Berrangé geschrieben:
> On Tue, Dec 05, 2023 at 01:32:51AM +0800, Yong Huang wrote:
> > On Tue, Dec 5, 2023 at 12:51 AM Daniel P. Berrangé <berrange@redhat.com>
> > wrote:
> >
> > > On Tue, Dec 05, 2023 at 12:41:16AM +0800, Yong Huang wrote:
> > > > On Tue, Dec 5, 2023 at 12:24 AM Daniel P. Berrangé <berrange@redhat.com>
> > > > wrote:
> > > >
> > > > > On Tue, Dec 05, 2023 at 12:06:17AM +0800, Hyman Huang wrote:
> > > > > > This functionality was motivated by the following to-do list seen
> > > > > > in crypto documents:
> > > > > > https://wiki.qemu.org/Features/Block/Crypto
> > > > > >
> > > > > > The last chapter says we should "separate header volume":
> > > > > >
> > > > > > The LUKS format has ability to store the header in a separate volume
> > > > > > from the payload. We should extend the LUKS driver in QEMU to support
> > > > > > this use case.
> > > > > >
> > > > > > As a proof-of-concept, I've created this patchset, which I've named
> > > > > > the Gluks: generic luks. As their name suggests, they offer
> > > encryption
> > > > > > for any format that QEMU theoretically supports.
> > > > >
> > > > > I don't see the point in creating a new driver.
> > > > >
> > > > > I would expect detached header support to be implemented via an
> > > > > optional new 'header' field in the existing driver. ie
> > > > >
> > > > > diff --git a/qapi/block-core.json b/qapi/block-core.json
> > > > > index ca390c5700..48d1f2a974 100644
> > > > > --- a/qapi/block-core.json
> > > > > +++ b/qapi/block-core.json
> > > > > @@ -3352,11 +3352,15 @@
> > > > > # decryption key (since 2.6). Mandatory except when doing a
> > > > > # metadata-only probe of the image.
> > > > > #
> > > > > +# @header: optional reference to the location of a blockdev
> > > > > +# storing a detached LUKS heaer
> > > > > +#
> > > > > # Since: 2.9
> > > > > ##
> > > > > { 'struct': 'BlockdevOptionsLUKS',
> > > > > 'base': 'BlockdevOptionsGenericFormat',
> > > > > - 'data': { '*key-secret': 'str' } }
> > > > > + 'data': { '*key-secret': 'str',
> > > > > + "*header-file': 'BlockdevRef'} }
> > > > >
> > > > > ##
> > > > > # @BlockdevOptionsGenericCOWFormat:
> > > > > @@ -4941,9 +4945,18 @@
> > > > > #
> > > > > # Driver specific image creation options for LUKS.
> > > > > #
> > > > > -# @file: Node to create the image format on
> > > > > +# @file: Node to create the image format on. Mandatory
> > > > > +# unless a detached header file is specified using
> > > > > +# @header.
> > > > > #
> > > > > -# @size: Size of the virtual disk in bytes
> > > > > +# @size: Size of the virtual disk in bytes. Mandatory
> > > > > +# unless a detached header file is specified using
> > > > > +# @header.
> > > > > +#
> > > > > +# @header: optional reference to the location of a blockdev
> > > > > +# storing a detached LUKS heaer. The @file option is
> > > > > +# is optional when this is given, unless it is desired
> > > > > +# to perform pre-allocation
> > > > > #
> > > > > # @preallocation: Preallocation mode for the new image (since: 4.2)
> > > > > # (default: off; allowed values: off, metadata, falloc, full)
> > > > > @@ -4952,8 +4965,9 @@
> > > > > ##
> > > > > { 'struct': 'BlockdevCreateOptionsLUKS',
> > > > > 'base': 'QCryptoBlockCreateOptionsLUKS',
> > > > > - 'data': { 'file': 'BlockdevRef',
> > > > > - 'size': 'size',
> > > > > + 'data': { '*file': 'BlockdevRef',
> > > > > + '*size': 'size',
> > > > > + '*header': 'BlockdevRef'
> > > > > '*preallocation': 'PreallocMode' } }
> > > > >
> > > > > ##
> > > > >
> > > > > It ends up giving basicallly the same workflow as you outline,
> > > > > without needing the new block driver
> > > > >
> > > >
> > > > How about the design and usage, could it be simpler? Any advice? :)
> > > >
> > > >
> > > > As you can see below, the Gluks format block layer driver's design is
> > > > quite simple.
> > > >
> > > > virtio-blk/vhost-user-blk...(front-end device)
> > > > ^
> > > > |
> > > > Gluks (format-like disk node)
> > > > / \
> > > > file header (blockdev reference)
> > > > / \
> > > > file file (protocol node)
> > > > | |
> > > > disk data Luks data
> > >
> > > What I suggested above ends up with the exact same block driver
> > > graph, unless I'm missing something.
> > >
> >
> > I could overlook something or fail to adequately convey the goal of the
> > patchset. :(
> >
> > Indeed, utilizing the same block driver might be effective if our only goal
> > is to divide the header volume, giving us an additional way to use Luks.
> >
> > While supporting encryption for any disk format that QEMU is capable of
> > supporting is another feature of this patchset. This implies that we might
> > link the Luks header to other blockdev references, which might alter how
> > the Luks are used and make them incompatible with it. It's not
> > user-friendly in my opinion, and I'm not aware of a more elegant solution.
>
> That existing LUKS driver can already be used in combination with
> any QEMU block driver, and in the case of disk formats, can be used
> either above or below the format, depending on whether you want to
> encrypt just the image payload, or the payload and metadata ie.
>
> We can do
>
> luks -> qcow2 -> file (qcow2 header and qcow2 payload protected)
>
> or
>
> qcow2 -> luks -> file (only qcow2 payload protected)
The other way around actually. If you want to have qcow2 metadata
encrypted, you need to put luks between qcow2 and file so that it sees
the metadata I/O done by the qcow2 driver. If you have luks above qcow2,
then qcow2 will see only encrypted data, but will access the metadata as
usual without going through encryption.
Kevin
> And in the qcow2 case, we also have support for LUKS integrated natively
> into the qcow2 format, which is similar to the 2nd case, with the
> benefit that we're explicit that the image requires encryption.
>
> With 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 :|
>
^ permalink raw reply [flat|nested] 18+ messages in thread