All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/11] crypto: improve robustness of LUKS metadata validation
@ 2022-09-06  8:41 Daniel P. Berrangé
  2022-09-06  8:41 ` [PATCH 01/11] crypto: sanity check that LUKS header strings are NUL-terminated Daniel P. Berrangé
                   ` (11 more replies)
  0 siblings, 12 replies; 18+ messages in thread
From: Daniel P. Berrangé @ 2022-09-06  8:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Daniel P. Berrangé, Richard W.M. Jones

Richard pointed out that we didn't do all that much validation against
bad parameters in the LUKS header metadata. This series adds a bunch
more validation checks along with unit tests to demonstrate they are
having effect against maliciously crafted headers.

Daniel P. Berrangé (11):
  crypto: sanity check that LUKS header strings are NUL-terminated
  crypto: enforce that LUKS stripes is always a fixed value
  crypto: enforce that key material doesn't overlap with LUKS header
  crypto: validate that LUKS payload doesn't overlap with header
  crypto: strengthen the check for key slots overlapping with LUKS
    header
  crypto: check that LUKS PBKDF2 iterations count is non-zero
  crypto: split LUKS header definitions off into file
  crypto: split off helpers for converting LUKS header endianess
  crypto: quote algorithm names in error messages
  crypto: ensure LUKS tests run with GNUTLS crypto provider
  crypto: add test cases for many malformed LUKS header scenarios

 crypto/block-luks-priv.h       | 143 ++++++++++++++++
 crypto/block-luks.c            | 228 +++++++++++--------------
 tests/unit/test-crypto-block.c | 302 ++++++++++++++++++++++++++++++++-
 3 files changed, 542 insertions(+), 131 deletions(-)
 create mode 100644 crypto/block-luks-priv.h

-- 
2.37.2



^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 01/11] crypto: sanity check that LUKS header strings are NUL-terminated
  2022-09-06  8:41 [PATCH 00/11] crypto: improve robustness of LUKS metadata validation Daniel P. Berrangé
@ 2022-09-06  8:41 ` Daniel P. Berrangé
  2022-09-06  9:30   ` Richard W.M. Jones
  2022-09-06  8:41 ` [PATCH 02/11] crypto: enforce that LUKS stripes is always a fixed value Daniel P. Berrangé
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 18+ messages in thread
From: Daniel P. Berrangé @ 2022-09-06  8:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Daniel P. Berrangé, Richard W.M. Jones

The LUKS spec requires that header strings are NUL-terminated, and our
code relies on that. Protect against maliciously crafted headers by
adding validation.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
 crypto/block-luks.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index f62be6836b..27d1b34c1d 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -554,6 +554,24 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp)
         return -1;
     }
 
+    if (!memchr(luks->header.cipher_name, '\0',
+                sizeof(luks->header.cipher_name))) {
+        error_setg(errp, "LUKS header cipher name is not NUL terminated");
+        return -1;
+    }
+
+    if (!memchr(luks->header.cipher_mode, '\0',
+                sizeof(luks->header.cipher_mode))) {
+        error_setg(errp, "LUKS header cipher mode is not NUL terminated");
+        return -1;
+    }
+
+    if (!memchr(luks->header.hash_spec, '\0',
+                sizeof(luks->header.hash_spec))) {
+        error_setg(errp, "LUKS header hash spec is not NUL terminated");
+        return -1;
+    }
+
     /* Check all keyslots for corruption  */
     for (i = 0 ; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS ; i++) {
 
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 02/11] crypto: enforce that LUKS stripes is always a fixed value
  2022-09-06  8:41 [PATCH 00/11] crypto: improve robustness of LUKS metadata validation Daniel P. Berrangé
  2022-09-06  8:41 ` [PATCH 01/11] crypto: sanity check that LUKS header strings are NUL-terminated Daniel P. Berrangé
@ 2022-09-06  8:41 ` Daniel P. Berrangé
  2022-09-06  9:09   ` Richard W.M. Jones
  2022-09-06  8:41 ` [PATCH 03/11] crypto: enforce that key material doesn't overlap with LUKS header Daniel P. Berrangé
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 18+ messages in thread
From: Daniel P. Berrangé @ 2022-09-06  8:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Daniel P. Berrangé, Richard W.M. Jones

Although the LUKS stripes are encoded in the keyslot header and so
potentially configurable, in pratice the cryptsetup impl mandates
this has the fixed value 4000. To avoid incompatibility apply the
same enforcement in QEMU too. This also caps the memory usage for
key material when QEMU tries to open a LUKS volume.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
 crypto/block-luks.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index 27d1b34c1d..81744e2a8e 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -582,8 +582,9 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp)
                                                    header_sectors,
                                                    slot1->stripes);
 
-        if (slot1->stripes == 0) {
-            error_setg(errp, "Keyslot %zu is corrupted (stripes == 0)", i);
+        if (slot1->stripes != QCRYPTO_BLOCK_LUKS_STRIPES) {
+            error_setg(errp, "Keyslot %zu is corrupted (stripes %d != %d)",
+                       i, slot1->stripes, QCRYPTO_BLOCK_LUKS_STRIPES);
             return -1;
         }
 
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 03/11] crypto: enforce that key material doesn't overlap with LUKS header
  2022-09-06  8:41 [PATCH 00/11] crypto: improve robustness of LUKS metadata validation Daniel P. Berrangé
  2022-09-06  8:41 ` [PATCH 01/11] crypto: sanity check that LUKS header strings are NUL-terminated Daniel P. Berrangé
  2022-09-06  8:41 ` [PATCH 02/11] crypto: enforce that LUKS stripes is always a fixed value Daniel P. Berrangé
@ 2022-09-06  8:41 ` Daniel P. Berrangé
  2022-09-06  8:41 ` [PATCH 04/11] crypto: validate that LUKS payload doesn't overlap with header Daniel P. Berrangé
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Daniel P. Berrangé @ 2022-09-06  8:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Daniel P. Berrangé, Richard W.M. Jones

We already check that key material doesn't overlap between key slots,
and that it doesn't overlap with the payload. We didn't check for
overlap with the LUKS header.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
 crypto/block-luks.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index 81744e2a8e..6ef9a89ffa 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -595,6 +595,14 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp)
             return -1;
         }
 
+        if (start1 < DIV_ROUND_UP(sizeof(QCryptoBlockLUKSHeader),
+                                  QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)) {
+            error_setg(errp,
+                       "Keyslot %zu is overlapping with the LUKS header",
+                       i);
+            return -1;
+        }
+
         if (start1 + len1 > luks->header.payload_offset_sector) {
             error_setg(errp,
                        "Keyslot %zu is overlapping with the encrypted payload",
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 04/11] crypto: validate that LUKS payload doesn't overlap with header
  2022-09-06  8:41 [PATCH 00/11] crypto: improve robustness of LUKS metadata validation Daniel P. Berrangé
                   ` (2 preceding siblings ...)
  2022-09-06  8:41 ` [PATCH 03/11] crypto: enforce that key material doesn't overlap with LUKS header Daniel P. Berrangé
@ 2022-09-06  8:41 ` Daniel P. Berrangé
  2022-09-06  9:19   ` Richard W.M. Jones
  2022-09-06  8:41 ` [PATCH 05/11] crypto: strengthen the check for key slots overlapping with LUKS header Daniel P. Berrangé
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 18+ messages in thread
From: Daniel P. Berrangé @ 2022-09-06  8:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Daniel P. Berrangé, Richard W.M. Jones

We already validate that LUKS keyslots don't overlap with the
header, or with each other. This closes the remain hole in
validation of LUKS file regions.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
 crypto/block-luks.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index 6ef9a89ffa..f22bc63e54 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -572,6 +572,13 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp)
         return -1;
     }
 
+    if (luks->header.payload_offset_sector <
+        DIV_ROUND_UP(QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET,
+                     QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)) {
+        error_setg(errp, "LUKS payload is overlapping with the header");
+        return -1;
+    }
+
     /* Check all keyslots for corruption  */
     for (i = 0 ; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS ; i++) {
 
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 05/11] crypto: strengthen the check for key slots overlapping with LUKS header
  2022-09-06  8:41 [PATCH 00/11] crypto: improve robustness of LUKS metadata validation Daniel P. Berrangé
                   ` (3 preceding siblings ...)
  2022-09-06  8:41 ` [PATCH 04/11] crypto: validate that LUKS payload doesn't overlap with header Daniel P. Berrangé
@ 2022-09-06  8:41 ` Daniel P. Berrangé
  2022-09-06  8:41 ` [PATCH 06/11] crypto: check that LUKS PBKDF2 iterations count is non-zero Daniel P. Berrangé
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Daniel P. Berrangé @ 2022-09-06  8:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Daniel P. Berrangé, Richard W.M. Jones

The LUKS header data on disk is a fixed size, however, there's expected
to be a gap between the end of the header and the first key slot to get
alignment with the 2nd sector on 4k drives. This wasn't originally part
of the LUKS spec, but was always part of the reference implementation,
so it is worth validating this.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
 crypto/block-luks.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index f22bc63e54..e6ee8506b2 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -602,7 +602,7 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp)
             return -1;
         }
 
-        if (start1 < DIV_ROUND_UP(sizeof(QCryptoBlockLUKSHeader),
+        if (start1 < DIV_ROUND_UP(QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET,
                                   QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)) {
             error_setg(errp,
                        "Keyslot %zu is overlapping with the LUKS header",
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 06/11] crypto: check that LUKS PBKDF2 iterations count is non-zero
  2022-09-06  8:41 [PATCH 00/11] crypto: improve robustness of LUKS metadata validation Daniel P. Berrangé
                   ` (4 preceding siblings ...)
  2022-09-06  8:41 ` [PATCH 05/11] crypto: strengthen the check for key slots overlapping with LUKS header Daniel P. Berrangé
@ 2022-09-06  8:41 ` Daniel P. Berrangé
  2022-09-06  9:26   ` Richard W.M. Jones
  2022-09-06  8:41 ` [PATCH 07/11] crypto: split LUKS header definitions off into file Daniel P. Berrangé
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 18+ messages in thread
From: Daniel P. Berrangé @ 2022-09-06  8:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Daniel P. Berrangé, Richard W.M. Jones

Both the master key and key slot passphrases are run through the PBKDF2
algorithm. The iterations count is expected to be generally very large
(many 10's or 100's of 1000s). It is hard to define a low level cutoff,
but we can certainly say that iterations count should be non-zero. A
zero count likely indicates an initialization mistake so reject it.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
 crypto/block-luks.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index e6ee8506b2..254490c256 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -579,6 +579,11 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp)
         return -1;
     }
 
+    if (luks->header.master_key_iterations == 0) {
+        error_setg(errp, "LUKS key iteration count is zero");
+        return -1;
+    }
+
     /* Check all keyslots for corruption  */
     for (i = 0 ; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS ; i++) {
 
@@ -602,6 +607,12 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp)
             return -1;
         }
 
+        if (slot1->active == QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED &&
+            slot1->iterations == 0) {
+            error_setg(errp, "Keyslot %zu iteration count is zero", i);
+            return -1;
+        }
+
         if (start1 < DIV_ROUND_UP(QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET,
                                   QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)) {
             error_setg(errp,
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 07/11] crypto: split LUKS header definitions off into file
  2022-09-06  8:41 [PATCH 00/11] crypto: improve robustness of LUKS metadata validation Daniel P. Berrangé
                   ` (5 preceding siblings ...)
  2022-09-06  8:41 ` [PATCH 06/11] crypto: check that LUKS PBKDF2 iterations count is non-zero Daniel P. Berrangé
@ 2022-09-06  8:41 ` Daniel P. Berrangé
  2022-09-06  8:41 ` [PATCH 08/11] crypto: split off helpers for converting LUKS header endianess Daniel P. Berrangé
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Daniel P. Berrangé @ 2022-09-06  8:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Daniel P. Berrangé, Richard W.M. Jones

This will allow unit testing code to use the structs.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
 crypto/block-luks-priv.h | 137 +++++++++++++++++++++++++++++++++++++++
 crypto/block-luks.c      |  94 +--------------------------
 2 files changed, 138 insertions(+), 93 deletions(-)
 create mode 100644 crypto/block-luks-priv.h

diff --git a/crypto/block-luks-priv.h b/crypto/block-luks-priv.h
new file mode 100644
index 0000000000..1516571dcb
--- /dev/null
+++ b/crypto/block-luks-priv.h
@@ -0,0 +1,137 @@
+/*
+ * QEMU Crypto block device encryption LUKS format
+ *
+ * Copyright (c) 2015-2016 Red Hat, Inc.
+ *
+ * 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 "qapi/error.h"
+#include "qemu/bswap.h"
+
+#include "block-luks.h"
+
+#include "crypto/hash.h"
+#include "crypto/afsplit.h"
+#include "crypto/pbkdf.h"
+#include "crypto/secret.h"
+#include "crypto/random.h"
+#include "qemu/uuid.h"
+
+#include "qemu/coroutine.h"
+#include "qemu/bitmap.h"
+
+/*
+ * Reference for the LUKS format implemented here is
+ *
+ *   docs/on-disk-format.pdf
+ *
+ * in 'cryptsetup' package source code
+ *
+ * This file implements the 1.2.1 specification, dated
+ * Oct 16, 2011.
+ */
+
+typedef struct QCryptoBlockLUKSHeader QCryptoBlockLUKSHeader;
+typedef struct QCryptoBlockLUKSKeySlot QCryptoBlockLUKSKeySlot;
+
+
+/* The following constants are all defined by the LUKS spec */
+#define QCRYPTO_BLOCK_LUKS_VERSION 1
+
+#define QCRYPTO_BLOCK_LUKS_MAGIC_LEN 6
+#define QCRYPTO_BLOCK_LUKS_CIPHER_NAME_LEN 32
+#define QCRYPTO_BLOCK_LUKS_CIPHER_MODE_LEN 32
+#define QCRYPTO_BLOCK_LUKS_HASH_SPEC_LEN 32
+#define QCRYPTO_BLOCK_LUKS_DIGEST_LEN 20
+#define QCRYPTO_BLOCK_LUKS_SALT_LEN 32
+#define QCRYPTO_BLOCK_LUKS_UUID_LEN 40
+#define QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS 8
+#define QCRYPTO_BLOCK_LUKS_STRIPES 4000
+#define QCRYPTO_BLOCK_LUKS_MIN_SLOT_KEY_ITERS 1000
+#define QCRYPTO_BLOCK_LUKS_MIN_MASTER_KEY_ITERS 1000
+#define QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET 4096
+
+#define QCRYPTO_BLOCK_LUKS_KEY_SLOT_DISABLED 0x0000DEAD
+#define QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED 0x00AC71F3
+
+#define QCRYPTO_BLOCK_LUKS_SECTOR_SIZE 512LL
+
+#define QCRYPTO_BLOCK_LUKS_DEFAULT_ITER_TIME_MS 2000
+#define QCRYPTO_BLOCK_LUKS_ERASE_ITERATIONS 40
+
+static const char qcrypto_block_luks_magic[QCRYPTO_BLOCK_LUKS_MAGIC_LEN] = {
+    'L', 'U', 'K', 'S', 0xBA, 0xBE
+};
+
+/*
+ * This struct is written to disk in big-endian format,
+ * but operated upon in native-endian format.
+ */
+struct QCryptoBlockLUKSKeySlot {
+    /* state of keyslot, enabled/disable */
+    uint32_t active;
+    /* iterations for PBKDF2 */
+    uint32_t iterations;
+    /* salt for PBKDF2 */
+    uint8_t salt[QCRYPTO_BLOCK_LUKS_SALT_LEN];
+    /* start sector of key material */
+    uint32_t key_offset_sector;
+    /* number of anti-forensic stripes */
+    uint32_t stripes;
+};
+
+/*
+ * This struct is written to disk in big-endian format,
+ * but operated upon in native-endian format.
+ */
+struct QCryptoBlockLUKSHeader {
+    /* 'L', 'U', 'K', 'S', '0xBA', '0xBE' */
+    char magic[QCRYPTO_BLOCK_LUKS_MAGIC_LEN];
+
+    /* LUKS version, currently 1 */
+    uint16_t version;
+
+    /* cipher name specification (aes, etc) */
+    char cipher_name[QCRYPTO_BLOCK_LUKS_CIPHER_NAME_LEN];
+
+    /* cipher mode specification (cbc-plain, xts-essiv:sha256, etc) */
+    char cipher_mode[QCRYPTO_BLOCK_LUKS_CIPHER_MODE_LEN];
+
+    /* hash specification (sha256, etc) */
+    char hash_spec[QCRYPTO_BLOCK_LUKS_HASH_SPEC_LEN];
+
+    /* start offset of the volume data (in 512 byte sectors) */
+    uint32_t payload_offset_sector;
+
+    /* Number of key bytes */
+    uint32_t master_key_len;
+
+    /* master key checksum after PBKDF2 */
+    uint8_t master_key_digest[QCRYPTO_BLOCK_LUKS_DIGEST_LEN];
+
+    /* salt for master key PBKDF2 */
+    uint8_t master_key_salt[QCRYPTO_BLOCK_LUKS_SALT_LEN];
+
+    /* iterations for master key PBKDF2 */
+    uint32_t master_key_iterations;
+
+    /* UUID of the partition in standard ASCII representation */
+    uint8_t uuid[QCRYPTO_BLOCK_LUKS_UUID_LEN];
+
+    /* key slots */
+    QCryptoBlockLUKSKeySlot key_slots[QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS];
+};
diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index 254490c256..375cce44cd 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -23,6 +23,7 @@
 #include "qemu/bswap.h"
 
 #include "block-luks.h"
+#include "block-luks-priv.h"
 
 #include "crypto/hash.h"
 #include "crypto/afsplit.h"
@@ -46,37 +47,6 @@
  */
 
 typedef struct QCryptoBlockLUKS QCryptoBlockLUKS;
-typedef struct QCryptoBlockLUKSHeader QCryptoBlockLUKSHeader;
-typedef struct QCryptoBlockLUKSKeySlot QCryptoBlockLUKSKeySlot;
-
-
-/* The following constants are all defined by the LUKS spec */
-#define QCRYPTO_BLOCK_LUKS_VERSION 1
-
-#define QCRYPTO_BLOCK_LUKS_MAGIC_LEN 6
-#define QCRYPTO_BLOCK_LUKS_CIPHER_NAME_LEN 32
-#define QCRYPTO_BLOCK_LUKS_CIPHER_MODE_LEN 32
-#define QCRYPTO_BLOCK_LUKS_HASH_SPEC_LEN 32
-#define QCRYPTO_BLOCK_LUKS_DIGEST_LEN 20
-#define QCRYPTO_BLOCK_LUKS_SALT_LEN 32
-#define QCRYPTO_BLOCK_LUKS_UUID_LEN 40
-#define QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS 8
-#define QCRYPTO_BLOCK_LUKS_STRIPES 4000
-#define QCRYPTO_BLOCK_LUKS_MIN_SLOT_KEY_ITERS 1000
-#define QCRYPTO_BLOCK_LUKS_MIN_MASTER_KEY_ITERS 1000
-#define QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET 4096
-
-#define QCRYPTO_BLOCK_LUKS_KEY_SLOT_DISABLED 0x0000DEAD
-#define QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED 0x00AC71F3
-
-#define QCRYPTO_BLOCK_LUKS_SECTOR_SIZE 512LL
-
-#define QCRYPTO_BLOCK_LUKS_DEFAULT_ITER_TIME_MS 2000
-#define QCRYPTO_BLOCK_LUKS_ERASE_ITERATIONS 40
-
-static const char qcrypto_block_luks_magic[QCRYPTO_BLOCK_LUKS_MAGIC_LEN] = {
-    'L', 'U', 'K', 'S', 0xBA, 0xBE
-};
 
 typedef struct QCryptoBlockLUKSNameMap QCryptoBlockLUKSNameMap;
 struct QCryptoBlockLUKSNameMap {
@@ -134,69 +104,7 @@ qcrypto_block_luks_cipher_name_map[] = {
     { "twofish", qcrypto_block_luks_cipher_size_map_twofish },
 };
 
-
-/*
- * This struct is written to disk in big-endian format,
- * but operated upon in native-endian format.
- */
-struct QCryptoBlockLUKSKeySlot {
-    /* state of keyslot, enabled/disable */
-    uint32_t active;
-    /* iterations for PBKDF2 */
-    uint32_t iterations;
-    /* salt for PBKDF2 */
-    uint8_t salt[QCRYPTO_BLOCK_LUKS_SALT_LEN];
-    /* start sector of key material */
-    uint32_t key_offset_sector;
-    /* number of anti-forensic stripes */
-    uint32_t stripes;
-};
-
 QEMU_BUILD_BUG_ON(sizeof(struct QCryptoBlockLUKSKeySlot) != 48);
-
-
-/*
- * This struct is written to disk in big-endian format,
- * but operated upon in native-endian format.
- */
-struct QCryptoBlockLUKSHeader {
-    /* 'L', 'U', 'K', 'S', '0xBA', '0xBE' */
-    char magic[QCRYPTO_BLOCK_LUKS_MAGIC_LEN];
-
-    /* LUKS version, currently 1 */
-    uint16_t version;
-
-    /* cipher name specification (aes, etc) */
-    char cipher_name[QCRYPTO_BLOCK_LUKS_CIPHER_NAME_LEN];
-
-    /* cipher mode specification (cbc-plain, xts-essiv:sha256, etc) */
-    char cipher_mode[QCRYPTO_BLOCK_LUKS_CIPHER_MODE_LEN];
-
-    /* hash specification (sha256, etc) */
-    char hash_spec[QCRYPTO_BLOCK_LUKS_HASH_SPEC_LEN];
-
-    /* start offset of the volume data (in 512 byte sectors) */
-    uint32_t payload_offset_sector;
-
-    /* Number of key bytes */
-    uint32_t master_key_len;
-
-    /* master key checksum after PBKDF2 */
-    uint8_t master_key_digest[QCRYPTO_BLOCK_LUKS_DIGEST_LEN];
-
-    /* salt for master key PBKDF2 */
-    uint8_t master_key_salt[QCRYPTO_BLOCK_LUKS_SALT_LEN];
-
-    /* iterations for master key PBKDF2 */
-    uint32_t master_key_iterations;
-
-    /* UUID of the partition in standard ASCII representation */
-    uint8_t uuid[QCRYPTO_BLOCK_LUKS_UUID_LEN];
-
-    /* key slots */
-    QCryptoBlockLUKSKeySlot key_slots[QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS];
-};
-
 QEMU_BUILD_BUG_ON(sizeof(struct QCryptoBlockLUKSHeader) != 592);
 
 
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 08/11] crypto: split off helpers for converting LUKS header endianess
  2022-09-06  8:41 [PATCH 00/11] crypto: improve robustness of LUKS metadata validation Daniel P. Berrangé
                   ` (6 preceding siblings ...)
  2022-09-06  8:41 ` [PATCH 07/11] crypto: split LUKS header definitions off into file Daniel P. Berrangé
@ 2022-09-06  8:41 ` Daniel P. Berrangé
  2022-09-06  8:41 ` [PATCH 09/11] crypto: quote algorithm names in error messages Daniel P. Berrangé
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Daniel P. Berrangé @ 2022-09-06  8:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Daniel P. Berrangé, Richard W.M. Jones

The unit test suite is shortly going to want to convert header
endianness separately from the main I/O functions.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
 crypto/block-luks-priv.h |  6 +++
 crypto/block-luks.c      | 79 ++++++++++++++++++++++++----------------
 2 files changed, 53 insertions(+), 32 deletions(-)

diff --git a/crypto/block-luks-priv.h b/crypto/block-luks-priv.h
index 1516571dcb..90a20d432b 100644
--- a/crypto/block-luks-priv.h
+++ b/crypto/block-luks-priv.h
@@ -135,3 +135,9 @@ struct QCryptoBlockLUKSHeader {
     /* key slots */
     QCryptoBlockLUKSKeySlot key_slots[QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS];
 };
+
+
+void
+qcrypto_block_luks_to_disk_endian(QCryptoBlockLUKSHeader *hdr);
+void
+qcrypto_block_luks_from_disk_endian(QCryptoBlockLUKSHeader *hdr);
diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index 375cce44cd..bb89c10225 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -348,6 +348,51 @@ qcrypto_block_luks_splitkeylen_sectors(const QCryptoBlockLUKS *luks,
     return ROUND_UP(splitkeylen_sectors, header_sectors);
 }
 
+
+void
+qcrypto_block_luks_to_disk_endian(QCryptoBlockLUKSHeader *hdr)
+{
+    size_t i;
+
+    /*
+     * Everything on disk uses Big Endian (tm), so flip header fields
+     * before writing them
+     */
+    cpu_to_be16s(&hdr->version);
+    cpu_to_be32s(&hdr->payload_offset_sector);
+    cpu_to_be32s(&hdr->master_key_len);
+    cpu_to_be32s(&hdr->master_key_iterations);
+
+    for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) {
+        cpu_to_be32s(&hdr->key_slots[i].active);
+        cpu_to_be32s(&hdr->key_slots[i].iterations);
+        cpu_to_be32s(&hdr->key_slots[i].key_offset_sector);
+        cpu_to_be32s(&hdr->key_slots[i].stripes);
+    }
+}
+
+void
+qcrypto_block_luks_from_disk_endian(QCryptoBlockLUKSHeader *hdr)
+{
+    size_t i;
+
+    /*
+     * The header is always stored in big-endian format, so
+     * convert everything to native
+     */
+    be16_to_cpus(&hdr->version);
+    be32_to_cpus(&hdr->payload_offset_sector);
+    be32_to_cpus(&hdr->master_key_len);
+    be32_to_cpus(&hdr->master_key_iterations);
+
+    for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) {
+        be32_to_cpus(&hdr->key_slots[i].active);
+        be32_to_cpus(&hdr->key_slots[i].iterations);
+        be32_to_cpus(&hdr->key_slots[i].key_offset_sector);
+        be32_to_cpus(&hdr->key_slots[i].stripes);
+    }
+}
+
 /*
  * Stores the main LUKS header, taking care of endianess
  */
@@ -359,28 +404,13 @@ qcrypto_block_luks_store_header(QCryptoBlock *block,
 {
     const QCryptoBlockLUKS *luks = block->opaque;
     Error *local_err = NULL;
-    size_t i;
     g_autofree QCryptoBlockLUKSHeader *hdr_copy = NULL;
 
     /* Create a copy of the header */
     hdr_copy = g_new0(QCryptoBlockLUKSHeader, 1);
     memcpy(hdr_copy, &luks->header, sizeof(QCryptoBlockLUKSHeader));
 
-    /*
-     * Everything on disk uses Big Endian (tm), so flip header fields
-     * before writing them
-     */
-    cpu_to_be16s(&hdr_copy->version);
-    cpu_to_be32s(&hdr_copy->payload_offset_sector);
-    cpu_to_be32s(&hdr_copy->master_key_len);
-    cpu_to_be32s(&hdr_copy->master_key_iterations);
-
-    for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) {
-        cpu_to_be32s(&hdr_copy->key_slots[i].active);
-        cpu_to_be32s(&hdr_copy->key_slots[i].iterations);
-        cpu_to_be32s(&hdr_copy->key_slots[i].key_offset_sector);
-        cpu_to_be32s(&hdr_copy->key_slots[i].stripes);
-    }
+    qcrypto_block_luks_to_disk_endian(hdr_copy);
 
     /* Write out the partition header and key slot headers */
     writefunc(block, 0, (const uint8_t *)hdr_copy, sizeof(*hdr_copy),
@@ -404,7 +434,6 @@ qcrypto_block_luks_load_header(QCryptoBlock *block,
                                 Error **errp)
 {
     int rv;
-    size_t i;
     QCryptoBlockLUKS *luks = block->opaque;
 
     /*
@@ -420,21 +449,7 @@ qcrypto_block_luks_load_header(QCryptoBlock *block,
         return rv;
     }
 
-    /*
-     * The header is always stored in big-endian format, so
-     * convert everything to native
-     */
-    be16_to_cpus(&luks->header.version);
-    be32_to_cpus(&luks->header.payload_offset_sector);
-    be32_to_cpus(&luks->header.master_key_len);
-    be32_to_cpus(&luks->header.master_key_iterations);
-
-    for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) {
-        be32_to_cpus(&luks->header.key_slots[i].active);
-        be32_to_cpus(&luks->header.key_slots[i].iterations);
-        be32_to_cpus(&luks->header.key_slots[i].key_offset_sector);
-        be32_to_cpus(&luks->header.key_slots[i].stripes);
-    }
+    qcrypto_block_luks_from_disk_endian(&luks->header);
 
     return 0;
 }
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 09/11] crypto: quote algorithm names in error messages
  2022-09-06  8:41 [PATCH 00/11] crypto: improve robustness of LUKS metadata validation Daniel P. Berrangé
                   ` (7 preceding siblings ...)
  2022-09-06  8:41 ` [PATCH 08/11] crypto: split off helpers for converting LUKS header endianess Daniel P. Berrangé
@ 2022-09-06  8:41 ` Daniel P. Berrangé
  2022-09-06  8:41 ` [PATCH 10/11] crypto: ensure LUKS tests run with GNUTLS crypto provider Daniel P. Berrangé
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Daniel P. Berrangé @ 2022-09-06  8:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Daniel P. Berrangé, Richard W.M. Jones

If given a malformed LUKS header, it is possible that the algorithm
names end up being an empty string. This leads to confusing error
messages unless quoting is used to highlight where the empty string
is subsituted in the error message.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
 crypto/block-luks.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index bb89c10225..df2b4105d6 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -162,7 +162,7 @@ static int qcrypto_block_luks_cipher_name_lookup(const char *name,
         }
     }
 
-    error_setg(errp, "Algorithm %s with key size %d bytes not supported",
+    error_setg(errp, "Algorithm '%s' with key size %d bytes not supported",
                name, key_bytes);
     return 0;
 }
@@ -198,7 +198,7 @@ static int qcrypto_block_luks_name_lookup(const char *name,
     int ret = qapi_enum_parse(map, name, -1, NULL);
 
     if (ret < 0) {
-        error_setg(errp, "%s %s not supported", type, name);
+        error_setg(errp, "%s '%s' not supported", type, name);
         return 0;
     }
     return ret;
@@ -592,7 +592,7 @@ qcrypto_block_luks_parse_header(QCryptoBlockLUKS *luks, Error **errp)
      */
     ivgen_name = strchr(cipher_mode, '-');
     if (!ivgen_name) {
-        error_setg(errp, "Unexpected cipher mode string format %s",
+        error_setg(errp, "Unexpected cipher mode string format '%s'",
                    luks->header.cipher_mode);
         return -1;
     }
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 10/11] crypto: ensure LUKS tests run with GNUTLS crypto provider
  2022-09-06  8:41 [PATCH 00/11] crypto: improve robustness of LUKS metadata validation Daniel P. Berrangé
                   ` (8 preceding siblings ...)
  2022-09-06  8:41 ` [PATCH 09/11] crypto: quote algorithm names in error messages Daniel P. Berrangé
@ 2022-09-06  8:41 ` Daniel P. Berrangé
  2022-09-06  8:41 ` [PATCH 11/11] crypto: add test cases for many malformed LUKS header scenarios Daniel P. Berrangé
  2022-09-06  9:31 ` [PATCH 00/11] crypto: improve robustness of LUKS metadata validation Richard W.M. Jones
  11 siblings, 0 replies; 18+ messages in thread
From: Daniel P. Berrangé @ 2022-09-06  8:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Daniel P. Berrangé, Richard W.M. Jones

GNUTLS is supported as a crypto provider since

  commit cc4c7c738297958b3d1d16269f57d71d22f5a9ff
  Author: Daniel P. Berrangé <berrange@redhat.com>
  Date:   Wed Jun 30 17:20:02 2021 +0100

    crypto: introduce build system for gnutls crypto backend

So enable the LUKS tests in this config.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
 tests/unit/test-crypto-block.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tests/unit/test-crypto-block.c b/tests/unit/test-crypto-block.c
index 3417b67be5..2a044a14cc 100644
--- a/tests/unit/test-crypto-block.c
+++ b/tests/unit/test-crypto-block.c
@@ -30,7 +30,8 @@
 #endif
 
 #if (defined(_WIN32) || defined RUSAGE_THREAD) && \
-    (defined(CONFIG_NETTLE) || defined(CONFIG_GCRYPT))
+    (defined(CONFIG_NETTLE) || defined(CONFIG_GCRYPT) ||
+     defined(CONFIG_GNUTLS_CRYPTO))
 #define TEST_LUKS
 #else
 #undef TEST_LUKS
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 11/11] crypto: add test cases for many malformed LUKS header scenarios
  2022-09-06  8:41 [PATCH 00/11] crypto: improve robustness of LUKS metadata validation Daniel P. Berrangé
                   ` (9 preceding siblings ...)
  2022-09-06  8:41 ` [PATCH 10/11] crypto: ensure LUKS tests run with GNUTLS crypto provider Daniel P. Berrangé
@ 2022-09-06  8:41 ` Daniel P. Berrangé
  2022-09-06  9:31 ` [PATCH 00/11] crypto: improve robustness of LUKS metadata validation Richard W.M. Jones
  11 siblings, 0 replies; 18+ messages in thread
From: Daniel P. Berrangé @ 2022-09-06  8:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Daniel P. Berrangé, Richard W.M. Jones

Validate that we diagnose each malformed LUKS header scenario with a
distinct error report.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
 tests/unit/test-crypto-block.c | 299 +++++++++++++++++++++++++++++++++
 1 file changed, 299 insertions(+)

diff --git a/tests/unit/test-crypto-block.c b/tests/unit/test-crypto-block.c
index 2a044a14cc..4aab2b60cd 100644
--- a/tests/unit/test-crypto-block.c
+++ b/tests/unit/test-crypto-block.c
@@ -22,6 +22,7 @@
 #include "qapi/error.h"
 #include "crypto/init.h"
 #include "crypto/block.h"
+#include "crypto/block-luks-priv.h"
 #include "qemu/buffer.h"
 #include "qemu/module.h"
 #include "crypto/secret.h"
@@ -345,6 +346,230 @@ static void test_block(gconstpointer opaque)
 }
 
 
+#ifdef TEST_LUKS
+typedef const char *(*LuksHeaderDoBadStuff)(QCryptoBlockLUKSHeader *hdr);
+
+static void
+test_luks_bad_header(gconstpointer data)
+{
+    LuksHeaderDoBadStuff badstuff = data;
+    QCryptoBlock *blk;
+    Buffer buf;
+    Object *sec = test_block_secret();
+    QCryptoBlockLUKSHeader hdr;
+    Error *err = NULL;
+    const char *msg;
+
+    memset(&buf, 0, sizeof(buf));
+    buffer_init(&buf, "header");
+
+    /* Correctly create the volume initially */
+    blk = qcrypto_block_create(&luks_create_opts_default, NULL,
+                               test_block_init_func,
+                               test_block_write_func,
+                               &buf,
+                               &error_abort);
+    g_assert(blk);
+
+    qcrypto_block_free(blk);
+
+    /* Mangle it in some unpleasant way */
+    g_assert(buf.offset >= sizeof(hdr));
+    memcpy(&hdr, buf.buffer, sizeof(hdr));
+    qcrypto_block_luks_to_disk_endian(&hdr);
+
+    msg = badstuff(&hdr);
+
+    qcrypto_block_luks_from_disk_endian(&hdr);
+    memcpy(buf.buffer, &hdr, sizeof(hdr));
+
+    /* Check that we fail to open it again */
+    blk = qcrypto_block_open(&luks_open_opts, NULL,
+                             test_block_read_func,
+                             &buf,
+                             0,
+                             1,
+                             &err);
+    g_assert(!blk);
+    g_assert(err);
+
+    g_assert_cmpstr(error_get_pretty(err), ==, msg);
+    error_free(err);
+
+    object_unparent(sec);
+
+    buffer_free(&buf);
+}
+
+static const char *luks_bad_null_term_cipher_name(QCryptoBlockLUKSHeader *hdr)
+{
+    /* Replace NUL termination with spaces */
+    char *offset = hdr->cipher_name + strlen(hdr->cipher_name);
+    memset(offset, ' ', sizeof(hdr->cipher_name) - (offset - hdr->cipher_name));
+
+    return "LUKS header cipher name is not NUL terminated";
+}
+
+static const char *luks_bad_null_term_cipher_mode(QCryptoBlockLUKSHeader *hdr)
+{
+    /* Replace NUL termination with spaces */
+    char *offset = hdr->cipher_mode + strlen(hdr->cipher_mode);
+    memset(offset, ' ', sizeof(hdr->cipher_mode) - (offset - hdr->cipher_mode));
+
+    return "LUKS header cipher mode is not NUL terminated";
+}
+
+static const char *luks_bad_null_term_hash_spec(QCryptoBlockLUKSHeader *hdr)
+{
+    /* Replace NUL termination with spaces */
+    char *offset = hdr->hash_spec + strlen(hdr->hash_spec);
+    memset(offset, ' ', sizeof(hdr->hash_spec) - (offset - hdr->hash_spec));
+
+    return "LUKS header hash spec is not NUL terminated";
+}
+
+static const char *luks_bad_cipher_name_empty(QCryptoBlockLUKSHeader *hdr)
+{
+    memcpy(hdr->cipher_name, "", 1);
+
+    return "Algorithm '' with key size 32 bytes not supported";
+}
+
+static const char *luks_bad_cipher_name_unknown(QCryptoBlockLUKSHeader *hdr)
+{
+    memcpy(hdr->cipher_name, "aess", 5);
+
+    return "Algorithm 'aess' with key size 32 bytes not supported";
+}
+
+static const char *luks_bad_cipher_xts_size(QCryptoBlockLUKSHeader *hdr)
+{
+    hdr->master_key_len = 33;
+
+    return "XTS cipher key length should be a multiple of 2";
+}
+
+static const char *luks_bad_cipher_cbc_size(QCryptoBlockLUKSHeader *hdr)
+{
+    hdr->master_key_len = 33;
+    memcpy(hdr->cipher_mode, "cbc-essiv", 10);
+
+    return "Algorithm 'aes' with key size 33 bytes not supported";
+}
+
+static const char *luks_bad_cipher_mode_empty(QCryptoBlockLUKSHeader *hdr)
+{
+    memcpy(hdr->cipher_mode, "", 1);
+
+    return "Unexpected cipher mode string format ''";
+}
+
+static const char *luks_bad_cipher_mode_unknown(QCryptoBlockLUKSHeader *hdr)
+{
+    memcpy(hdr->cipher_mode, "xfs", 4);
+
+    return "Unexpected cipher mode string format 'xfs'";
+}
+
+static const char *luks_bad_ivgen_separator(QCryptoBlockLUKSHeader *hdr)
+{
+    memcpy(hdr->cipher_mode, "xts:plain64", 12);
+
+    return "Unexpected cipher mode string format 'xts:plain64'";
+}
+
+static const char *luks_bad_ivgen_name_empty(QCryptoBlockLUKSHeader *hdr)
+{
+    memcpy(hdr->cipher_mode, "xts-", 5);
+
+    return "IV generator '' not supported";
+}
+
+static const char *luks_bad_ivgen_name_unknown(QCryptoBlockLUKSHeader *hdr)
+{
+    memcpy(hdr->cipher_mode, "xts-plain65", 12);
+
+    return "IV generator 'plain65' not supported";
+}
+
+static const char *luks_bad_ivgen_hash_empty(QCryptoBlockLUKSHeader *hdr)
+{
+    memcpy(hdr->cipher_mode, "xts-plain65:", 13);
+
+    return "Hash algorithm '' not supported";
+}
+
+static const char *luks_bad_ivgen_hash_unknown(QCryptoBlockLUKSHeader *hdr)
+{
+    memcpy(hdr->cipher_mode, "xts-plain65:sha257", 19);
+
+    return "Hash algorithm 'sha257' not supported";
+}
+
+static const char *luks_bad_hash_spec_empty(QCryptoBlockLUKSHeader *hdr)
+{
+    memcpy(hdr->hash_spec, "", 1);
+
+    return "Hash algorithm '' not supported";
+}
+
+static const char *luks_bad_hash_spec_unknown(QCryptoBlockLUKSHeader *hdr)
+{
+    memcpy(hdr->hash_spec, "sha2566", 8);
+
+    return "Hash algorithm 'sha2566' not supported";
+}
+
+static const char *luks_bad_stripes(QCryptoBlockLUKSHeader *hdr)
+{
+    hdr->key_slots[0].stripes = 3999;
+
+    return "Keyslot 0 is corrupted (stripes 3999 != 4000)";
+}
+
+static const char *luks_bad_key_overlap_header(QCryptoBlockLUKSHeader *hdr)
+{
+    hdr->key_slots[0].key_offset_sector = 2;
+
+    return "Keyslot 0 is overlapping with the LUKS header";
+}
+
+static const char *luks_bad_key_overlap_key(QCryptoBlockLUKSHeader *hdr)
+{
+    hdr->key_slots[0].key_offset_sector = hdr->key_slots[1].key_offset_sector;
+
+    return "Keyslots 0 and 1 are overlapping in the header";
+}
+
+static const char *luks_bad_key_overlap_payload(QCryptoBlockLUKSHeader *hdr)
+{
+    hdr->key_slots[0].key_offset_sector = hdr->payload_offset_sector + 42;
+
+    return "Keyslot 0 is overlapping with the encrypted payload";
+}
+
+static const char *luks_bad_payload_overlap_header(QCryptoBlockLUKSHeader *hdr)
+{
+    hdr->payload_offset_sector = 2;
+
+    return "LUKS payload is overlapping with the header";
+}
+
+static const char *luks_bad_key_iterations(QCryptoBlockLUKSHeader *hdr)
+{
+    hdr->key_slots[0].iterations = 0;
+
+    return "Keyslot 0 iteration count is zero";
+}
+
+static const char *luks_bad_iterations(QCryptoBlockLUKSHeader *hdr)
+{
+    hdr->master_key_iterations = 0;
+
+    return "LUKS key iteration count is zero";
+}
+#endif
+
 int main(int argc, char **argv)
 {
     gsize i;
@@ -365,5 +590,79 @@ int main(int argc, char **argv)
         }
     }
 
+#ifdef TEST_LUKS
+    if (g_test_slow()) {
+        g_test_add_data_func("/crypto/block/luks/bad/cipher-name-nul-term",
+                             luks_bad_null_term_cipher_name,
+                             test_luks_bad_header);
+        g_test_add_data_func("/crypto/block/luks/bad/cipher-mode-nul-term",
+                             luks_bad_null_term_cipher_mode,
+                             test_luks_bad_header);
+        g_test_add_data_func("/crypto/block/luks/bad/hash-spec-nul-term",
+                             luks_bad_null_term_hash_spec,
+                             test_luks_bad_header);
+        g_test_add_data_func("/crypto/block/luks/bad/cipher-name-empty",
+                             luks_bad_cipher_name_empty,
+                             test_luks_bad_header);
+        g_test_add_data_func("/crypto/block/luks/bad/cipher-name-unknown",
+                             luks_bad_cipher_name_unknown,
+                             test_luks_bad_header);
+        g_test_add_data_func("/crypto/block/luks/bad/cipher-xts-size",
+                             luks_bad_cipher_xts_size,
+                             test_luks_bad_header);
+        g_test_add_data_func("/crypto/block/luks/bad/cipher-cbc-size",
+                             luks_bad_cipher_cbc_size,
+                             test_luks_bad_header);
+        g_test_add_data_func("/crypto/block/luks/bad/cipher-mode-empty",
+                             luks_bad_cipher_mode_empty,
+                             test_luks_bad_header);
+        g_test_add_data_func("/crypto/block/luks/bad/cipher-mode-unknown",
+                             luks_bad_cipher_mode_unknown,
+                             test_luks_bad_header);
+        g_test_add_data_func("/crypto/block/luks/bad/ivgen-separator",
+                             luks_bad_ivgen_separator,
+                             test_luks_bad_header);
+        g_test_add_data_func("/crypto/block/luks/bad/ivgen-name-empty",
+                             luks_bad_ivgen_name_empty,
+                             test_luks_bad_header);
+        g_test_add_data_func("/crypto/block/luks/bad/ivgen-name-unknown",
+                             luks_bad_ivgen_name_unknown,
+                             test_luks_bad_header);
+        g_test_add_data_func("/crypto/block/luks/bad/ivgen-hash-empty",
+                             luks_bad_ivgen_hash_empty,
+                             test_luks_bad_header);
+        g_test_add_data_func("/crypto/block/luks/bad/ivgen-hash-unknown",
+                             luks_bad_ivgen_hash_unknown,
+                             test_luks_bad_header);
+        g_test_add_data_func("/crypto/block/luks/bad/hash-spec-empty",
+                             luks_bad_hash_spec_empty,
+                             test_luks_bad_header);
+        g_test_add_data_func("/crypto/block/luks/bad/hash-spec-unknown",
+                             luks_bad_hash_spec_unknown,
+                             test_luks_bad_header);
+        g_test_add_data_func("/crypto/block/luks/bad/stripes",
+                             luks_bad_stripes,
+                             test_luks_bad_header);
+        g_test_add_data_func("/crypto/block/luks/bad/key-overlap-header",
+                             luks_bad_key_overlap_header,
+                             test_luks_bad_header);
+        g_test_add_data_func("/crypto/block/luks/bad/key-overlap-key",
+                             luks_bad_key_overlap_key,
+                             test_luks_bad_header);
+        g_test_add_data_func("/crypto/block/luks/bad/key-overlap-payload",
+                             luks_bad_key_overlap_payload,
+                             test_luks_bad_header);
+        g_test_add_data_func("/crypto/block/luks/bad/payload-overlap-header",
+                             luks_bad_payload_overlap_header,
+                             test_luks_bad_header);
+        g_test_add_data_func("/crypto/block/luks/bad/iterations",
+                             luks_bad_iterations,
+                             test_luks_bad_header);
+        g_test_add_data_func("/crypto/block/luks/bad/key-iterations",
+                             luks_bad_key_iterations,
+                             test_luks_bad_header);
+    }
+#endif
+
     return g_test_run();
 }
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH 02/11] crypto: enforce that LUKS stripes is always a fixed value
  2022-09-06  8:41 ` [PATCH 02/11] crypto: enforce that LUKS stripes is always a fixed value Daniel P. Berrangé
@ 2022-09-06  9:09   ` Richard W.M. Jones
  0 siblings, 0 replies; 18+ messages in thread
From: Richard W.M. Jones @ 2022-09-06  9:09 UTC (permalink / raw)
  To: Daniel P. Berrangé; +Cc: qemu-devel

On Tue, Sep 06, 2022 at 09:41:38AM +0100, Daniel P. Berrangé wrote:
> Although the LUKS stripes are encoded in the keyslot header and so
> potentially configurable, in pratice the cryptsetup impl mandates
> this has the fixed value 4000. To avoid incompatibility apply the
> same enforcement in QEMU too. This also caps the memory usage for
> key material when QEMU tries to open a LUKS volume.
> 
> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
> ---
>  crypto/block-luks.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/crypto/block-luks.c b/crypto/block-luks.c
> index 27d1b34c1d..81744e2a8e 100644
> --- a/crypto/block-luks.c
> +++ b/crypto/block-luks.c
> @@ -582,8 +582,9 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp)
>                                                     header_sectors,
>                                                     slot1->stripes);
>  
> -        if (slot1->stripes == 0) {
> -            error_setg(errp, "Keyslot %zu is corrupted (stripes == 0)", i);
> +        if (slot1->stripes != QCRYPTO_BLOCK_LUKS_STRIPES) {
> +            error_setg(errp, "Keyslot %zu is corrupted (stripes %d != %d)",
> +                       i, slot1->stripes, QCRYPTO_BLOCK_LUKS_STRIPES);
>              return -1;
>          }

In nbdkit I decided to just check that this number < 10000, but I
agree that the only important implementation (the kernel) always fixes
this at 4000 (cryptsetup.git/lib/keymanage.c), so:

Reviewed-by: Richard W.M. Jones <rjones@redhat.com>

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-builder quickly builds VMs from scratch
http://libguestfs.org/virt-builder.1.html



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 04/11] crypto: validate that LUKS payload doesn't overlap with header
  2022-09-06  8:41 ` [PATCH 04/11] crypto: validate that LUKS payload doesn't overlap with header Daniel P. Berrangé
@ 2022-09-06  9:19   ` Richard W.M. Jones
  0 siblings, 0 replies; 18+ messages in thread
From: Richard W.M. Jones @ 2022-09-06  9:19 UTC (permalink / raw)
  To: Daniel P. Berrangé; +Cc: qemu-devel

On Tue, Sep 06, 2022 at 09:41:40AM +0100, Daniel P. Berrangé wrote:
> We already validate that LUKS keyslots don't overlap with the
> header, or with each other. This closes the remain hole in

remain -> remaining

> validation of LUKS file regions.
> 
> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
> ---
>  crypto/block-luks.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/crypto/block-luks.c b/crypto/block-luks.c
> index 6ef9a89ffa..f22bc63e54 100644
> --- a/crypto/block-luks.c
> +++ b/crypto/block-luks.c
> @@ -572,6 +572,13 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp)
>          return -1;
>      }
>  
> +    if (luks->header.payload_offset_sector <
> +        DIV_ROUND_UP(QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET,
> +                     QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)) {
> +        error_setg(errp, "LUKS payload is overlapping with the header");
> +        return -1;
> +    }
> +
>      /* Check all keyslots for corruption  */
>      for (i = 0 ; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS ; i++) {
>  
> -- 
> 2.37.2

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
Fedora Windows cross-compiler. Compile Windows programs, test, and
build Windows installers. Over 100 libraries supported.
http://fedoraproject.org/wiki/MinGW



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 06/11] crypto: check that LUKS PBKDF2 iterations count is non-zero
  2022-09-06  8:41 ` [PATCH 06/11] crypto: check that LUKS PBKDF2 iterations count is non-zero Daniel P. Berrangé
@ 2022-09-06  9:26   ` Richard W.M. Jones
  2022-10-27 11:59     ` Daniel P. Berrangé
  0 siblings, 1 reply; 18+ messages in thread
From: Richard W.M. Jones @ 2022-09-06  9:26 UTC (permalink / raw)
  To: Daniel P. Berrangé; +Cc: qemu-devel

On Tue, Sep 06, 2022 at 09:41:42AM +0100, Daniel P. Berrangé wrote:
> Both the master key and key slot passphrases are run through the PBKDF2
> algorithm. The iterations count is expected to be generally very large
> (many 10's or 100's of 1000s). It is hard to define a low level cutoff,
> but we can certainly say that iterations count should be non-zero. A
> zero count likely indicates an initialization mistake so reject it.
> 
> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
> ---
>  crypto/block-luks.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/crypto/block-luks.c b/crypto/block-luks.c
> index e6ee8506b2..254490c256 100644
> --- a/crypto/block-luks.c
> +++ b/crypto/block-luks.c
> @@ -579,6 +579,11 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp)
>          return -1;
>      }
>  
> +    if (luks->header.master_key_iterations == 0) {
> +        error_setg(errp, "LUKS key iteration count is zero");
> +        return -1;
> +    }
> +
>      /* Check all keyslots for corruption  */
>      for (i = 0 ; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS ; i++) {
>  
> @@ -602,6 +607,12 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp)
>              return -1;
>          }
>  
> +        if (slot1->active == QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED &&
> +            slot1->iterations == 0) {
> +            error_setg(errp, "Keyslot %zu iteration count is zero", i);
> +            return -1;
> +        }
> +
>          if (start1 < DIV_ROUND_UP(QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET,
>                                    QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)) {
>              error_setg(errp,

Equivalent checks were missing in nbdkit - I've added them.

I wonder if there's a problem that a very large number here would
cause long delays opening the device.  In general it's not very clear
to me if the aim is to prevent malicious LUKS input, or if we're just
trying to sanity check the device hasn't been corrupted or improperly
prepared.  The test above is the latter, I think.

Nevertheless as this is an improvement over the current situation:

Reviewed-by: Richard W.M. Jones <rjones@redhat.com>

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-builder quickly builds VMs from scratch
http://libguestfs.org/virt-builder.1.html



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 01/11] crypto: sanity check that LUKS header strings are NUL-terminated
  2022-09-06  8:41 ` [PATCH 01/11] crypto: sanity check that LUKS header strings are NUL-terminated Daniel P. Berrangé
@ 2022-09-06  9:30   ` Richard W.M. Jones
  0 siblings, 0 replies; 18+ messages in thread
From: Richard W.M. Jones @ 2022-09-06  9:30 UTC (permalink / raw)
  To: Daniel P. Berrangé; +Cc: qemu-devel

On Tue, Sep 06, 2022 at 09:41:37AM +0100, Daniel P. Berrangé wrote:
> The LUKS spec requires that header strings are NUL-terminated, and our
> code relies on that. Protect against maliciously crafted headers by
> adding validation.
> 
> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
> ---
>  crypto/block-luks.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/crypto/block-luks.c b/crypto/block-luks.c
> index f62be6836b..27d1b34c1d 100644
> --- a/crypto/block-luks.c
> +++ b/crypto/block-luks.c
> @@ -554,6 +554,24 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp)
>          return -1;
>      }
>  
> +    if (!memchr(luks->header.cipher_name, '\0',
> +                sizeof(luks->header.cipher_name))) {
> +        error_setg(errp, "LUKS header cipher name is not NUL terminated");
> +        return -1;
> +    }
> +
> +    if (!memchr(luks->header.cipher_mode, '\0',
> +                sizeof(luks->header.cipher_mode))) {
> +        error_setg(errp, "LUKS header cipher mode is not NUL terminated");
> +        return -1;
> +    }
> +
> +    if (!memchr(luks->header.hash_spec, '\0',
> +                sizeof(luks->header.hash_spec))) {
> +        error_setg(errp, "LUKS header hash spec is not NUL terminated");
> +        return -1;
> +    }
> +
>      /* Check all keyslots for corruption  */
>      for (i = 0 ; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS ; i++) {

I think this was the error I originally wrote to you about, and I
think it's the most important fix because non-terminated strings seem
(possibly) exploitable.

FWIW nbdkit does this which is slightly different:

  char cipher_name[33], cipher_mode[33], hash_spec[33];

  /* Copy the header fields locally and ensure they are \0 terminated. */
  memcpy (cipher_name, h->phdr.cipher_name, 32);
  cipher_name[32] = 0;
  memcpy (cipher_mode, h->phdr.cipher_mode, 32);
  cipher_mode[32] = 0;
  memcpy (hash_spec, h->phdr.hash_spec, 32);
  hash_spec[32] = 0;

Anyway the change above looks good so:

Reviewed-by: Richard W.M. Jones <rjones@redhat.com>

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
Fedora Windows cross-compiler. Compile Windows programs, test, and
build Windows installers. Over 100 libraries supported.
http://fedoraproject.org/wiki/MinGW



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 00/11] crypto: improve robustness of LUKS metadata validation
  2022-09-06  8:41 [PATCH 00/11] crypto: improve robustness of LUKS metadata validation Daniel P. Berrangé
                   ` (10 preceding siblings ...)
  2022-09-06  8:41 ` [PATCH 11/11] crypto: add test cases for many malformed LUKS header scenarios Daniel P. Berrangé
@ 2022-09-06  9:31 ` Richard W.M. Jones
  11 siblings, 0 replies; 18+ messages in thread
From: Richard W.M. Jones @ 2022-09-06  9:31 UTC (permalink / raw)
  To: Daniel P. Berrangé; +Cc: qemu-devel

On Tue, Sep 06, 2022 at 09:41:36AM +0100, Daniel P. Berrangé wrote:
> Richard pointed out that we didn't do all that much validation against
> bad parameters in the LUKS header metadata. This series adds a bunch
> more validation checks along with unit tests to demonstrate they are
> having effect against maliciously crafted headers.
> 
> Daniel P. Berrangé (11):
>   crypto: sanity check that LUKS header strings are NUL-terminated
>   crypto: enforce that LUKS stripes is always a fixed value
>   crypto: enforce that key material doesn't overlap with LUKS header
>   crypto: validate that LUKS payload doesn't overlap with header
>   crypto: strengthen the check for key slots overlapping with LUKS
>     header
>   crypto: check that LUKS PBKDF2 iterations count is non-zero
>   crypto: split LUKS header definitions off into file
>   crypto: split off helpers for converting LUKS header endianess
>   crypto: quote algorithm names in error messages
>   crypto: ensure LUKS tests run with GNUTLS crypto provider
>   crypto: add test cases for many malformed LUKS header scenarios
> 
>  crypto/block-luks-priv.h       | 143 ++++++++++++++++
>  crypto/block-luks.c            | 228 +++++++++++--------------
>  tests/unit/test-crypto-block.c | 302 ++++++++++++++++++++++++++++++++-
>  3 files changed, 542 insertions(+), 131 deletions(-)
>  create mode 100644 crypto/block-luks-priv.h

I think there is one typo in a commit message, but for the series:

Reviewed-by: Richard W.M. Jones <rjones@redhat.com>

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
Fedora Windows cross-compiler. Compile Windows programs, test, and
build Windows installers. Over 100 libraries supported.
http://fedoraproject.org/wiki/MinGW



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 06/11] crypto: check that LUKS PBKDF2 iterations count is non-zero
  2022-09-06  9:26   ` Richard W.M. Jones
@ 2022-10-27 11:59     ` Daniel P. Berrangé
  0 siblings, 0 replies; 18+ messages in thread
From: Daniel P. Berrangé @ 2022-10-27 11:59 UTC (permalink / raw)
  To: Richard W.M. Jones; +Cc: qemu-devel

On Tue, Sep 06, 2022 at 10:26:35AM +0100, Richard W.M. Jones wrote:
> On Tue, Sep 06, 2022 at 09:41:42AM +0100, Daniel P. Berrangé wrote:
> > Both the master key and key slot passphrases are run through the PBKDF2
> > algorithm. The iterations count is expected to be generally very large
> > (many 10's or 100's of 1000s). It is hard to define a low level cutoff,
> > but we can certainly say that iterations count should be non-zero. A
> > zero count likely indicates an initialization mistake so reject it.
> > 
> > Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
> > ---
> >  crypto/block-luks.c | 11 +++++++++++
> >  1 file changed, 11 insertions(+)
> > 
> > diff --git a/crypto/block-luks.c b/crypto/block-luks.c
> > index e6ee8506b2..254490c256 100644
> > --- a/crypto/block-luks.c
> > +++ b/crypto/block-luks.c
> > @@ -579,6 +579,11 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp)
> >          return -1;
> >      }
> >  
> > +    if (luks->header.master_key_iterations == 0) {
> > +        error_setg(errp, "LUKS key iteration count is zero");
> > +        return -1;
> > +    }
> > +
> >      /* Check all keyslots for corruption  */
> >      for (i = 0 ; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS ; i++) {
> >  
> > @@ -602,6 +607,12 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp)
> >              return -1;
> >          }
> >  
> > +        if (slot1->active == QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED &&
> > +            slot1->iterations == 0) {
> > +            error_setg(errp, "Keyslot %zu iteration count is zero", i);
> > +            return -1;
> > +        }
> > +
> >          if (start1 < DIV_ROUND_UP(QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET,
> >                                    QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)) {
> >              error_setg(errp,
> 
> Equivalent checks were missing in nbdkit - I've added them.
> 
> I wonder if there's a problem that a very large number here would
> cause long delays opening the device.  In general it's not very clear
> to me if the aim is to prevent malicious LUKS input, or if we're just
> trying to sanity check the device hasn't been corrupted or improperly
> prepared.  The test above is the latter, I think.

Yes, we're checking for corruption.

A large value of iterations will indeed make it slow to open
the device, but that is entirely the point of the iterations
parameter. It must be picked to be large enough to intentionally
make opening slow, in order to prevent brute force checking
many passwords. It is hard to claim that any specific value
is "too large", because the volume might have been created on
a machine whose CPU is way faster than the current machine,
and thus chose big iterations.

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

end of thread, other threads:[~2022-10-27 12:00 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-06  8:41 [PATCH 00/11] crypto: improve robustness of LUKS metadata validation Daniel P. Berrangé
2022-09-06  8:41 ` [PATCH 01/11] crypto: sanity check that LUKS header strings are NUL-terminated Daniel P. Berrangé
2022-09-06  9:30   ` Richard W.M. Jones
2022-09-06  8:41 ` [PATCH 02/11] crypto: enforce that LUKS stripes is always a fixed value Daniel P. Berrangé
2022-09-06  9:09   ` Richard W.M. Jones
2022-09-06  8:41 ` [PATCH 03/11] crypto: enforce that key material doesn't overlap with LUKS header Daniel P. Berrangé
2022-09-06  8:41 ` [PATCH 04/11] crypto: validate that LUKS payload doesn't overlap with header Daniel P. Berrangé
2022-09-06  9:19   ` Richard W.M. Jones
2022-09-06  8:41 ` [PATCH 05/11] crypto: strengthen the check for key slots overlapping with LUKS header Daniel P. Berrangé
2022-09-06  8:41 ` [PATCH 06/11] crypto: check that LUKS PBKDF2 iterations count is non-zero Daniel P. Berrangé
2022-09-06  9:26   ` Richard W.M. Jones
2022-10-27 11:59     ` Daniel P. Berrangé
2022-09-06  8:41 ` [PATCH 07/11] crypto: split LUKS header definitions off into file Daniel P. Berrangé
2022-09-06  8:41 ` [PATCH 08/11] crypto: split off helpers for converting LUKS header endianess Daniel P. Berrangé
2022-09-06  8:41 ` [PATCH 09/11] crypto: quote algorithm names in error messages Daniel P. Berrangé
2022-09-06  8:41 ` [PATCH 10/11] crypto: ensure LUKS tests run with GNUTLS crypto provider Daniel P. Berrangé
2022-09-06  8:41 ` [PATCH 11/11] crypto: add test cases for many malformed LUKS header scenarios Daniel P. Berrangé
2022-09-06  9:31 ` [PATCH 00/11] crypto: improve robustness of LUKS metadata validation Richard W.M. Jones

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.