[libvirt] [PATCH v2 1/4] storage_util: Alter qemu storage encryption arguments

John Ferlan jferlan at redhat.com
Wed May 16 12:29:28 UTC 2018


https://bugzilla.redhat.com/show_bug.cgi?id=1526382

As of QEMU 2.9, qemu-img has enforced using the "encrypt.key-secret"
in order to create a qcow[2] encrypted volume. Thus, the existing code
to create an encrypted volume using qcow[2] encryption techniques will
fail, such as :

  $ qemu-img create -f qcow2 -b /dev/null \
        -o backing_fmt=raw,encryption=on \
        demo.tmp 5242880K
  Formatting 'demo.tmp', fmt=qcow2 size=5368709120 backing_file=/dev/null
  backing_fmt=raw encryption=on cluster_size=65536 lazy_refcounts=off
  refcount_bits=16
  qemu-img: demo.tmp: Parameter 'encrypt.key-secret' is required for cipher
  $

This patch will resolve this by adding the correct parameters for
the creation. The new format of parameters roughly follows that of
LUKS encryption model with a few minor differences:

   1. Usage of "encrypt.key-secret=$alias" instead of just plain
      "key-secret=$alias" as the parameter.
   2. Usage of "encrypt.format=aes" instead of "encryption=on"

The result is the following command syntax for the same example:

  $ qemu-img create -f qcow2 -b /dev/null \
        --object secret,id=OtherDemo.img_encrypt0,file=/path/to/secretFile \
        -o encrypt.format=aes,encrypt.key-secret=OtherDemo.img_encrypt0 \
        demo.tmp 5242880K
  Formatting 'test.img', fmt=qcow2 size=5368709120 backing_file=/dev/null
  backing_fmt=raw encrypt.format=aes encrypt.key-secret=sec0 cluster_size=65536
  lazy_refcounts=off refcount_bits=16
  $

Thus this patch removes the LUKS specific checks in a few places and
alters the algorithms as necessary in order to allow either form of
encryption.

The storagevolxml2argvtest.c test is adjusted to pass a dummy path to
the secret file and the outputs adjusted to illustrate the new format
for the various arguments.

This patch requires usage of the secrets object and model. There is no
plan for backwards compatibility for qcow[2] encryption. The desire is
to move towards usage of LUKS encryption anyway.

NB: Although the qemu-img convert examples change in the test output,
they are essentially still broken (they wouldn't work before this patch
either for the same reasons create fails). A follow-up patch will alter
the algorithm and syntax.

Signed-off-by: John Ferlan <jferlan at redhat.com>
---
 src/storage/storage_util.c                         | 24 +++++++++++-----------
 src/util/virqemu.c                                 | 10 +++++++--
 src/util/virqemu.h                                 |  3 ++-
 tests/storagevolxml2argvdata/qcow2-1.1.argv        |  4 +++-
 tests/storagevolxml2argvdata/qcow2-compat.argv     |  4 +++-
 .../qcow2-from-logical-compat.argv                 |  3 ++-
 tests/storagevolxml2argvdata/qcow2-lazy.argv       |  6 ++++--
 .../qcow2-nobacking-convert-prealloc-compat.argv   |  4 +++-
 .../qcow2-nobacking-prealloc-compat.argv           |  4 +++-
 .../qcow2-nocapacity-convert-prealloc.argv         |  7 ++++---
 tests/storagevolxml2argvdata/qcow2-nocapacity.argv |  4 +++-
 .../storagevolxml2argvdata/qcow2-nocow-compat.argv |  6 ++++--
 tests/storagevolxml2argvdata/qcow2-nocow.argv      |  3 ++-
 tests/storagevolxml2argvtest.c                     |  2 +-
 14 files changed, 54 insertions(+), 30 deletions(-)

diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c
index 554fc757ed..a8a6a3e401 100644
--- a/src/storage/storage_util.c
+++ b/src/storage/storage_util.c
@@ -827,11 +827,10 @@ storageBackendCreateQemuImgOpts(virStorageEncryptionInfoDefPtr enc,
         virBufferAsprintf(&buf, "backing_fmt=%s,",
                           virStorageFileFormatTypeToString(info.backingFormat));
 
-    if (info.format == VIR_STORAGE_FILE_RAW && enc) {
-        virQEMUBuildQemuImgKeySecretOpts(&buf, enc, info.secretAlias);
-    } else {
-        if (info.encryption)
-            virBufferAddLit(&buf, "encryption=on,");
+    if (enc) {
+        bool qcow = (info.format == VIR_STORAGE_FILE_QCOW ||
+                     info.format == VIR_STORAGE_FILE_QCOW2);
+        virQEMUBuildQemuImgKeySecretOpts(&buf, enc, info.secretAlias, qcow);
     }
 
     if (info.preallocate) {
@@ -1231,8 +1230,12 @@ virStorageBackendCreateQemuImgCmdFromVol(virStoragePoolObjPtr pool,
     if (info.backingPath)
         virCommandAddArgList(cmd, "-b", info.backingPath, NULL);
 
-    if (info.format == VIR_STORAGE_FILE_RAW && vol->target.encryption &&
-        vol->target.encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) {
+    if (vol->target.encryption) {
+        if (!secretPath) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("path to secret data file is required"));
+            return NULL;
+        }
         if (virAsprintf(&info.secretAlias, "%s_encrypt0", vol->name) < 0)
             goto error;
         if (storageBackendCreateQemuImgSecretObject(cmd, info.secretPath,
@@ -1344,11 +1347,8 @@ storageBackendGenerateSecretData(virStoragePoolObjPtr pool,
             return -1;
     }
 
-    if (vol->target.format == VIR_STORAGE_FILE_RAW &&
-        enc->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) {
-        if (!(*secretPath = storageBackendCreateQemuImgSecretPath(pool, vol)))
-            return -1;
-    }
+    if (!(*secretPath = storageBackendCreateQemuImgSecretPath(pool, vol)))
+        return -1;
 
     return 0;
 }
diff --git a/src/util/virqemu.c b/src/util/virqemu.c
index 04cd71605e..b20d09d945 100644
--- a/src/util/virqemu.c
+++ b/src/util/virqemu.c
@@ -307,6 +307,7 @@ virQEMUBuildBufferEscapeComma(virBufferPtr buf, const char *str)
  * @buf: buffer to build the string into
  * @enc: pointer to encryption info
  * @alias: alias to use
+ * @qcow: using qcow encryption
  *
  * Generate the string for id=$alias and any encryption options for
  * into the buffer.
@@ -315,7 +316,8 @@ virQEMUBuildBufferEscapeComma(virBufferPtr buf, const char *str)
  * it's expected other arguments are appended after the id=$alias string.
  * So either turn something like:
  *
- *     "key-secret=$alias,"
+ *     "key-secret=$alias," or
+ *     "encrypt.format=aes,encrypt.key-secret=$alias,"
  *
  * or
  *     "key-secret=$alias,cipher-alg=twofish-256,cipher-mode=cbc,
@@ -325,8 +327,12 @@ virQEMUBuildBufferEscapeComma(virBufferPtr buf, const char *str)
 void
 virQEMUBuildQemuImgKeySecretOpts(virBufferPtr buf,
                                  virStorageEncryptionInfoDefPtr enc,
-                                 const char *alias)
+                                 const char *alias,
+                                 bool qcow)
 {
+    if (qcow)
+        virBufferAddLit(buf, "encrypt.format=aes,encrypt.");
+
     virBufferAsprintf(buf, "key-secret=%s,", alias);
 
     if (!enc->cipher_name)
diff --git a/src/util/virqemu.h b/src/util/virqemu.h
index 2599481753..9a01640c6e 100644
--- a/src/util/virqemu.h
+++ b/src/util/virqemu.h
@@ -52,7 +52,8 @@ char *virQEMUBuildDriveCommandlineFromJSON(virJSONValuePtr src);
 void virQEMUBuildBufferEscapeComma(virBufferPtr buf, const char *str);
 void virQEMUBuildQemuImgKeySecretOpts(virBufferPtr buf,
                                       virStorageEncryptionInfoDefPtr enc,
-                                      const char *alias)
+                                      const char *alias,
+                                      bool qcow)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
 
 #endif /* __VIR_QEMU_H_ */
diff --git a/tests/storagevolxml2argvdata/qcow2-1.1.argv b/tests/storagevolxml2argvdata/qcow2-1.1.argv
index c4dcb1bc3c..ff3d62d0a1 100644
--- a/tests/storagevolxml2argvdata/qcow2-1.1.argv
+++ b/tests/storagevolxml2argvdata/qcow2-1.1.argv
@@ -1,3 +1,5 @@
 qemu-img create -f qcow2 -b /dev/null \
--o backing_fmt=raw,encryption=on,compat=1.1 \
+--object secret,id=OtherDemo.img_encrypt0,file=/path/to/secretFile \
+-o backing_fmt=raw,encrypt.format=aes,\
+encrypt.key-secret=OtherDemo.img_encrypt0,compat=1.1 \
 /var/lib/libvirt/images/OtherDemo.img 5242880K
diff --git a/tests/storagevolxml2argvdata/qcow2-compat.argv b/tests/storagevolxml2argvdata/qcow2-compat.argv
index 37ad2c078d..8aa8c7ce84 100644
--- a/tests/storagevolxml2argvdata/qcow2-compat.argv
+++ b/tests/storagevolxml2argvdata/qcow2-compat.argv
@@ -1,3 +1,5 @@
 qemu-img create -f qcow2 -b /dev/null \
--o backing_fmt=raw,encryption=on,compat=0.10 \
+--object secret,id=OtherDemo.img_encrypt0,file=/path/to/secretFile \
+-o backing_fmt=raw,encrypt.format=aes,\
+encrypt.key-secret=OtherDemo.img_encrypt0,compat=0.10 \
 /var/lib/libvirt/images/OtherDemo.img 5242880K
diff --git a/tests/storagevolxml2argvdata/qcow2-from-logical-compat.argv b/tests/storagevolxml2argvdata/qcow2-from-logical-compat.argv
index 5f365b1f84..849c5f0218 100644
--- a/tests/storagevolxml2argvdata/qcow2-from-logical-compat.argv
+++ b/tests/storagevolxml2argvdata/qcow2-from-logical-compat.argv
@@ -1,3 +1,4 @@
 qemu-img convert -f raw -O qcow2 \
--o encryption=on,compat=0.10 \
+--object secret,id=OtherDemo.img_encrypt0,file=/path/to/secretFile \
+-o encrypt.format=aes,encrypt.key-secret=OtherDemo.img_encrypt0,compat=0.10 \
 /dev/HostVG/Swap /var/lib/libvirt/images/OtherDemo.img
diff --git a/tests/storagevolxml2argvdata/qcow2-lazy.argv b/tests/storagevolxml2argvdata/qcow2-lazy.argv
index b7058b84cc..0c29a3fb33 100644
--- a/tests/storagevolxml2argvdata/qcow2-lazy.argv
+++ b/tests/storagevolxml2argvdata/qcow2-lazy.argv
@@ -1,3 +1,5 @@
 qemu-img create -f qcow2 -b /dev/null \
--o backing_fmt=raw,encryption=on,compat=1.1,lazy_refcounts \
-/var/lib/libvirt/images/OtherDemo.img 5242880K
+--object secret,id=OtherDemo.img_encrypt0,file=/path/to/secretFile \
+-o backing_fmt=raw,encrypt.format=aes,\
+encrypt.key-secret=OtherDemo.img_encrypt0,compat=1.1,\
+lazy_refcounts /var/lib/libvirt/images/OtherDemo.img 5242880K
diff --git a/tests/storagevolxml2argvdata/qcow2-nobacking-convert-prealloc-compat.argv b/tests/storagevolxml2argvdata/qcow2-nobacking-convert-prealloc-compat.argv
index 3d93ec8480..a95749eafa 100644
--- a/tests/storagevolxml2argvdata/qcow2-nobacking-convert-prealloc-compat.argv
+++ b/tests/storagevolxml2argvdata/qcow2-nobacking-convert-prealloc-compat.argv
@@ -1,3 +1,5 @@
 qemu-img convert -f raw -O qcow2 \
--o encryption=on,preallocation=metadata,compat=0.10 \
+--object secret,id=OtherDemo.img_encrypt0,file=/path/to/secretFile \
+-o encrypt.format=aes,encrypt.key-secret=OtherDemo.img_encrypt0,\
+preallocation=metadata,compat=0.10 \
 /var/lib/libvirt/images/sparse.img /var/lib/libvirt/images/OtherDemo.img
diff --git a/tests/storagevolxml2argvdata/qcow2-nobacking-prealloc-compat.argv b/tests/storagevolxml2argvdata/qcow2-nobacking-prealloc-compat.argv
index 903c94e33d..30b61442a4 100644
--- a/tests/storagevolxml2argvdata/qcow2-nobacking-prealloc-compat.argv
+++ b/tests/storagevolxml2argvdata/qcow2-nobacking-prealloc-compat.argv
@@ -1,3 +1,5 @@
 qemu-img create -f qcow2 \
--o encryption=on,preallocation=metadata,compat=0.10 \
+--object secret,id=OtherDemo.img_encrypt0,file=/path/to/secretFile \
+-o encrypt.format=aes,encrypt.key-secret=OtherDemo.img_encrypt0,\
+preallocation=metadata,compat=0.10 \
 /var/lib/libvirt/images/OtherDemo.img 5242880K
diff --git a/tests/storagevolxml2argvdata/qcow2-nocapacity-convert-prealloc.argv b/tests/storagevolxml2argvdata/qcow2-nocapacity-convert-prealloc.argv
index 73499178e7..51bdaaf684 100644
--- a/tests/storagevolxml2argvdata/qcow2-nocapacity-convert-prealloc.argv
+++ b/tests/storagevolxml2argvdata/qcow2-nocapacity-convert-prealloc.argv
@@ -1,4 +1,5 @@
 qemu-img convert -f raw -O qcow2 \
--o encryption=on,preallocation=falloc,compat=0.10 \
-/var/lib/libvirt/images/sparse.img \
-/var/lib/libvirt/images/OtherDemo.img
+--object secret,id=OtherDemo.img_encrypt0,file=/path/to/secretFile \
+-o encrypt.format=aes,encrypt.key-secret=OtherDemo.img_encrypt0,\
+preallocation=falloc,compat=0.10 \
+/var/lib/libvirt/images/sparse.img /var/lib/libvirt/images/OtherDemo.img
diff --git a/tests/storagevolxml2argvdata/qcow2-nocapacity.argv b/tests/storagevolxml2argvdata/qcow2-nocapacity.argv
index fd88055890..920cff8771 100644
--- a/tests/storagevolxml2argvdata/qcow2-nocapacity.argv
+++ b/tests/storagevolxml2argvdata/qcow2-nocapacity.argv
@@ -1,5 +1,7 @@
 qemu-img create \
 -f qcow2 \
 -b /dev/null \
--o backing_fmt=raw,encryption=on,compat=0.10 \
+--object secret,id=OtherDemo.img_encrypt0,file=/path/to/secretFile \
+-o backing_fmt=raw,encrypt.format=aes,\
+encrypt.key-secret=OtherDemo.img_encrypt0,compat=0.10 \
 /var/lib/libvirt/images/OtherDemo.img
diff --git a/tests/storagevolxml2argvdata/qcow2-nocow-compat.argv b/tests/storagevolxml2argvdata/qcow2-nocow-compat.argv
index d5a7547011..1c9a1a4da4 100644
--- a/tests/storagevolxml2argvdata/qcow2-nocow-compat.argv
+++ b/tests/storagevolxml2argvdata/qcow2-nocow-compat.argv
@@ -1,3 +1,5 @@
 qemu-img create -f qcow2 -b /dev/null \
--o backing_fmt=raw,encryption=on,nocow=on,compat=0.10 \
-/var/lib/libvirt/images/OtherDemo.img 5242880K
+--object secret,id=OtherDemo.img_encrypt0,file=/path/to/secretFile \
+-o backing_fmt=raw,encrypt.format=aes,\
+encrypt.key-secret=OtherDemo.img_encrypt0,nocow=on,\
+compat=0.10 /var/lib/libvirt/images/OtherDemo.img 5242880K
diff --git a/tests/storagevolxml2argvdata/qcow2-nocow.argv b/tests/storagevolxml2argvdata/qcow2-nocow.argv
index e54801c78a..68c16f8e20 100644
--- a/tests/storagevolxml2argvdata/qcow2-nocow.argv
+++ b/tests/storagevolxml2argvdata/qcow2-nocow.argv
@@ -1,3 +1,4 @@
 qemu-img create -f qcow2 -b /dev/null \
--o backing_fmt=raw,encryption=on,nocow=on \
+--object secret,id=OtherDemo.img_encrypt0,file=/path/to/secretFile \
+-o encrypt.format=aes,encrypt.key-secret=OtherDemo.img_encrypt0,nocow=on \
 /var/lib/libvirt/images/OtherDemo.img 5242880K
diff --git a/tests/storagevolxml2argvtest.c b/tests/storagevolxml2argvtest.c
index 0265a0ffe2..4286c50c6e 100644
--- a/tests/storagevolxml2argvtest.c
+++ b/tests/storagevolxml2argvtest.c
@@ -82,7 +82,7 @@ testCompareXMLToArgvFiles(bool shouldFail,
     cmd = virStorageBackendCreateQemuImgCmdFromVol(obj, vol,
                                                    inputvol, flags,
                                                    create_tool,
-                                                   NULL);
+                                                   "/path/to/secretFile");
     if (!cmd) {
         if (shouldFail) {
             virResetLastError();
-- 
2.14.3




More information about the libvir-list mailing list