- Fix reading statistics for VDO pools with VDO 8
Resolves: rhbz#1994220 - vdo_stats: Default to 100 % savings for invalid savings values Resolves: rhbz#2025880 - Add support for creating and unlocking standalone integrity devices Resolves: rhbz#2011365
This commit is contained in:
parent
bd37303947
commit
22b10e5b01
@ -0,0 +1,80 @@
|
||||
From e0fcbae856454dba9df3f8df800d74fde66731e5 Mon Sep 17 00:00:00 2001
|
||||
From: Vojtech Trefny <vtrefny@redhat.com>
|
||||
Date: Tue, 31 Aug 2021 14:07:23 +0200
|
||||
Subject: [PATCH] lvm: Fix reading statistics for VDO pools with VDO 8
|
||||
|
||||
The statistics are no longer available in /sys/kvdo, in the latest
|
||||
version of kvdo we need to use /sys/block/<pool>/vdo/statistics.
|
||||
|
||||
Resolves: rhbz#1994220
|
||||
---
|
||||
src/plugins/vdo_stats.c | 42 +++++++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 38 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/plugins/vdo_stats.c b/src/plugins/vdo_stats.c
|
||||
index ed04b51..2e244aa 100644
|
||||
--- a/src/plugins/vdo_stats.c
|
||||
+++ b/src/plugins/vdo_stats.c
|
||||
@@ -133,6 +133,23 @@ static void add_computed_stats (GHashTable *stats) {
|
||||
add_journal_stats (stats);
|
||||
}
|
||||
|
||||
+static gchar* _dm_node_from_name (const gchar *map_name, GError **error) {
|
||||
+ gchar *dev_path = NULL;
|
||||
+ gchar *ret = NULL;
|
||||
+ gchar *dev_mapper_path = g_strdup_printf ("/dev/mapper/%s", map_name);
|
||||
+
|
||||
+ dev_path = bd_utils_resolve_device (dev_mapper_path, error);
|
||||
+ g_free (dev_mapper_path);
|
||||
+ if (!dev_path)
|
||||
+ /* error is already populated */
|
||||
+ return NULL;
|
||||
+
|
||||
+ ret = g_path_get_basename (dev_path);
|
||||
+ g_free (dev_path);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
GHashTable __attribute__ ((visibility ("hidden")))
|
||||
*vdo_get_stats_full (const gchar *name, GError **error) {
|
||||
GHashTable *stats;
|
||||
@@ -141,14 +158,31 @@ GHashTable __attribute__ ((visibility ("hidden")))
|
||||
const gchar *direntry;
|
||||
gchar *s;
|
||||
gchar *val = NULL;
|
||||
+ g_autofree gchar *dm_node = NULL;
|
||||
|
||||
- /* TODO: does the `name` need to be escaped? */
|
||||
- stats_dir = g_build_path (G_DIR_SEPARATOR_S, VDO_SYS_PATH, name, "statistics", NULL);
|
||||
+ /* try "new" (kvdo >= 8) path first -- /sys/block/dm-X/vdo/statistics */
|
||||
+ dm_node = _dm_node_from_name (name, error);
|
||||
+ if (dm_node == NULL) {
|
||||
+ g_prefix_error (error, "Failed to get DM node for %s: ", name);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ stats_dir = g_build_path (G_DIR_SEPARATOR_S, "/sys/block", dm_node, "vdo/statistics", NULL);
|
||||
dir = g_dir_open (stats_dir, 0, error);
|
||||
if (dir == NULL) {
|
||||
- g_prefix_error (error, "Error reading statistics from %s: ", stats_dir);
|
||||
+ g_debug ("Failed to read VDO stats using the new API, falling back to %s: %s",
|
||||
+ VDO_SYS_PATH, (*error)->message);
|
||||
g_free (stats_dir);
|
||||
- return NULL;
|
||||
+ g_clear_error (error);
|
||||
+
|
||||
+ /* lets try /sys/kvdo */
|
||||
+ stats_dir = g_build_path (G_DIR_SEPARATOR_S, VDO_SYS_PATH, name, "statistics", NULL);
|
||||
+ dir = g_dir_open (stats_dir, 0, error);
|
||||
+ if (dir == NULL) {
|
||||
+ g_prefix_error (error, "Error reading statistics from %s: ", stats_dir);
|
||||
+ g_free (stats_dir);
|
||||
+ return NULL;
|
||||
+ }
|
||||
}
|
||||
|
||||
stats = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
||||
--
|
||||
2.31.1
|
||||
|
@ -0,0 +1,30 @@
|
||||
From 940346f14ee5644f2593817b4196c18de8a713f0 Mon Sep 17 00:00:00 2001
|
||||
From: Vojtech Trefny <vtrefny@redhat.com>
|
||||
Date: Mon, 22 Nov 2021 14:16:02 +0100
|
||||
Subject: [PATCH] vdo_stats: Default to 100 % savings for invalid savings
|
||||
values
|
||||
|
||||
We are currently using "-1" when VDO logical_blocks_used is 0
|
||||
which doesn't match the LVM logic which returns 100 so to make
|
||||
both values in vdo_info and vdo_stats equal we should return 100
|
||||
in this case too.
|
||||
---
|
||||
src/plugins/vdo_stats.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/plugins/vdo_stats.c b/src/plugins/vdo_stats.c
|
||||
index 3ec2d60..f3f0390 100644
|
||||
--- a/src/plugins/vdo_stats.c
|
||||
+++ b/src/plugins/vdo_stats.c
|
||||
@@ -96,7 +96,7 @@ static void add_block_stats (GHashTable *stats) {
|
||||
g_hash_table_replace (stats, g_strdup ("oneKBlocksUsed"), g_strdup_printf ("%"G_GINT64_FORMAT, (data_blocks_used + overhead_blocks_used) * block_size / 1024));
|
||||
g_hash_table_replace (stats, g_strdup ("oneKBlocksAvailable"), g_strdup_printf ("%"G_GINT64_FORMAT, (physical_blocks - data_blocks_used - overhead_blocks_used) * block_size / 1024));
|
||||
g_hash_table_replace (stats, g_strdup ("usedPercent"), g_strdup_printf ("%.0f", 100.0 * (gfloat) (data_blocks_used + overhead_blocks_used) / (gfloat) physical_blocks + 0.5));
|
||||
- savings = (logical_blocks_used > 0) ? (gint64) (100.0 * (gfloat) (logical_blocks_used - data_blocks_used) / (gfloat) logical_blocks_used) : -1;
|
||||
+ savings = (logical_blocks_used > 0) ? (gint64) (100.0 * (gfloat) (logical_blocks_used - data_blocks_used) / (gfloat) logical_blocks_used) : 100;
|
||||
g_hash_table_replace (stats, g_strdup ("savings"), g_strdup_printf ("%"G_GINT64_FORMAT, savings));
|
||||
if (savings >= 0)
|
||||
g_hash_table_replace (stats, g_strdup ("savingPercent"), g_strdup_printf ("%"G_GINT64_FORMAT, savings));
|
||||
--
|
||||
2.31.1
|
||||
|
966
0010-Add-support-for-creating-and-activating-integrity-de.patch
Normal file
966
0010-Add-support-for-creating-and-activating-integrity-de.patch
Normal file
@ -0,0 +1,966 @@
|
||||
From 37f1aff5f5f967d6a4440d176f3de877aab789ac Mon Sep 17 00:00:00 2001
|
||||
From: Vojtech Trefny <vtrefny@redhat.com>
|
||||
Date: Mon, 20 Sep 2021 16:38:16 +0200
|
||||
Subject: [PATCH 1/3] Add support for creating and activating integrity devices
|
||||
|
||||
This adds support for create, open and close actions for standalone
|
||||
integrity devices using cryptsetup.
|
||||
---
|
||||
configure.ac | 4 +-
|
||||
src/lib/plugin_apis/crypto.api | 157 +++++++++++++++++
|
||||
src/plugins/crypto.c | 261 +++++++++++++++++++++++++++-
|
||||
src/plugins/crypto.h | 41 +++++
|
||||
src/python/gi/overrides/BlockDev.py | 24 +++
|
||||
tests/crypto_test.py | 97 ++++++++++-
|
||||
6 files changed, 576 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index abe1412..13830ae 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -210,7 +210,9 @@ AS_IF([test "x$with_crypto" != "xno"],
|
||||
AS_IF([$PKG_CONFIG --atleast-version=2.0.3 libcryptsetup],
|
||||
[AC_DEFINE([LIBCRYPTSETUP_2])], [])
|
||||
AS_IF([$PKG_CONFIG --atleast-version=2.3.0 libcryptsetup],
|
||||
- [AC_DEFINE([LIBCRYPTSETUP_BITLK])], [])
|
||||
+ [AC_DEFINE([LIBCRYPTSETUP_23])], [])
|
||||
+ AS_IF([$PKG_CONFIG --atleast-version=2.4.0 libcryptsetup],
|
||||
+ [AC_DEFINE([LIBCRYPTSETUP_24])], [])
|
||||
AS_IF([test "x$with_escrow" != "xno"],
|
||||
[LIBBLOCKDEV_PKG_CHECK_MODULES([NSS], [nss >= 3.18.0])
|
||||
LIBBLOCKDEV_CHECK_HEADER([volume_key/libvolume_key.h], [$GLIB_CFLAGS $NSS_CFLAGS], [libvolume_key.h not available])],
|
||||
diff --git a/src/lib/plugin_apis/crypto.api b/src/lib/plugin_apis/crypto.api
|
||||
index ef0217f..40e32c8 100644
|
||||
--- a/src/lib/plugin_apis/crypto.api
|
||||
+++ b/src/lib/plugin_apis/crypto.api
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <glib.h>
|
||||
#include <blockdev/utils.h>
|
||||
+#include <libcryptsetup.h>
|
||||
|
||||
#define BD_CRYPTO_LUKS_METADATA_SIZE G_GUINT64_CONSTANT (2097152ULL) // 2 MiB
|
||||
|
||||
@@ -245,6 +246,115 @@ GType bd_crypto_luks_extra_get_type () {
|
||||
return type;
|
||||
}
|
||||
|
||||
+#define BD_CRYPTO_TYPE_INTEGRITY_EXTRA (bd_crypto_integrity_extra_get_type ())
|
||||
+GType bd_crypto_integrity_extra_get_type();
|
||||
+
|
||||
+/**
|
||||
+ * BDCryptoIntegrityExtra:
|
||||
+ * @sector_size: integrity sector size
|
||||
+ * @journal_size: size of journal in bytes
|
||||
+ * @journal_watermark: journal flush watermark in percents; in bitmap mode sectors-per-bit
|
||||
+ * @journal_commit_time: journal commit time (or bitmap flush time) in ms
|
||||
+ * @interleave_sectors: number of interleave sectors (power of two)
|
||||
+ * @tag_size: tag size per-sector in bytes
|
||||
+ * @buffer_sectors: number of sectors in one buffer
|
||||
+ */
|
||||
+typedef struct BDCryptoIntegrityExtra {
|
||||
+ guint32 sector_size;
|
||||
+ guint64 journal_size;
|
||||
+ guint journal_watermark;
|
||||
+ guint journal_commit_time;
|
||||
+ guint32 interleave_sectors;
|
||||
+ guint32 tag_size;
|
||||
+ guint32 buffer_sectors;
|
||||
+} BDCryptoIntegrityExtra;
|
||||
+
|
||||
+/**
|
||||
+ * bd_crypto_integrity_extra_copy: (skip)
|
||||
+ * @extra: (allow-none): %BDCryptoIntegrityExtra to copy
|
||||
+ *
|
||||
+ * Creates a new copy of @extra.
|
||||
+ */
|
||||
+BDCryptoIntegrityExtra* bd_crypto_integrity_extra_copy (BDCryptoIntegrityExtra *extra) {
|
||||
+ if (extra == NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
+ BDCryptoIntegrityExtra *new_extra = g_new0 (BDCryptoIntegrityExtra, 1);
|
||||
+
|
||||
+ new_extra->sector_size = extra->sector_size;
|
||||
+ new_extra->journal_size = extra->journal_size;
|
||||
+ new_extra->journal_watermark = extra->journal_watermark;
|
||||
+ new_extra->journal_commit_time = extra->journal_commit_time;
|
||||
+ new_extra->interleave_sectors = extra->interleave_sectors;
|
||||
+ new_extra->tag_size = extra->tag_size;
|
||||
+ new_extra->buffer_sectors = extra->buffer_sectors;
|
||||
+
|
||||
+ return new_extra;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * bd_crypto_integrity_extra_free: (skip)
|
||||
+ * @extra: (allow-none): %BDCryptoIntegrityExtra to free
|
||||
+ *
|
||||
+ * Frees @extra.
|
||||
+ */
|
||||
+void bd_crypto_integrity_extra_free (BDCryptoIntegrityExtra *extra) {
|
||||
+ if (extra == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ g_free (extra);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * bd_crypto_integrity_extra_new: (constructor)
|
||||
+ * @sector_size: integrity sector size, 0 for default (512)
|
||||
+ * @journal_size: size of journal in bytes
|
||||
+ * @journal_watermark: journal flush watermark in percents; in bitmap mode sectors-per-bit
|
||||
+ * @journal_commit_time: journal commit time (or bitmap flush time) in ms
|
||||
+ * @interleave_sectors: number of interleave sectors (power of two)
|
||||
+ * @tag_size: tag size per-sector in bytes
|
||||
+ * @buffer_sectors: number of sectors in one buffer
|
||||
+ *
|
||||
+ * Returns: (transfer full): a new Integrity extra argument
|
||||
+ */
|
||||
+BDCryptoIntegrityExtra* bd_crypto_integrity_extra_new (guint64 sector_size, guint64 journal_size, guint journal_watermark, guint journal_commit_time, guint64 interleave_sectors, guint64 tag_size, guint64 buffer_sectors) {
|
||||
+ BDCryptoIntegrityExtra *ret = g_new0 (BDCryptoIntegrityExtra, 1);
|
||||
+ ret->sector_size = sector_size;
|
||||
+ ret->journal_size = journal_size;
|
||||
+ ret->journal_watermark = journal_watermark;
|
||||
+ ret->journal_commit_time = journal_commit_time;
|
||||
+ ret->interleave_sectors = interleave_sectors;
|
||||
+ ret->tag_size = tag_size;
|
||||
+ ret->buffer_sectors = buffer_sectors;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+GType bd_crypto_integrity_extra_get_type () {
|
||||
+ static GType type = 0;
|
||||
+
|
||||
+ if (G_UNLIKELY(type == 0)) {
|
||||
+ type = g_boxed_type_register_static("BDCryptoIntegrityExtra",
|
||||
+ (GBoxedCopyFunc) bd_crypto_integrity_extra_copy,
|
||||
+ (GBoxedFreeFunc) bd_crypto_integrity_extra_free);
|
||||
+ }
|
||||
+
|
||||
+ return type;
|
||||
+}
|
||||
+
|
||||
+typedef enum {
|
||||
+ BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL = CRYPT_ACTIVATE_NO_JOURNAL,
|
||||
+ BD_CRYPTO_INTEGRITY_OPEN_RECOVERY = CRYPT_ACTIVATE_RECOVERY,
|
||||
+#ifdef CRYPT_ACTIVATE_NO_JOURNAL_BITMAP
|
||||
+ BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL_BITMAP = CRYPT_ACTIVATE_NO_JOURNAL_BITMAP,
|
||||
+#endif
|
||||
+ BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE = CRYPT_ACTIVATE_RECALCULATE,
|
||||
+#ifdef CRYPT_ACTIVATE_RECALCULATE_RESET
|
||||
+ BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE_RESET = CRYPT_ACTIVATE_RECALCULATE_RESET,
|
||||
+#endif
|
||||
+ BD_CRYPTO_INTEGRITY_OPEN_ALLOW_DISCARDS = CRYPT_ACTIVATE_ALLOW_DISCARDS,
|
||||
+} BDCryptoIntegrityOpenFlags;
|
||||
+
|
||||
#define BD_CRYPTO_TYPE_LUKS_INFO (bd_crypto_luks_info_get_type ())
|
||||
GType bd_crypto_luks_info_get_type();
|
||||
|
||||
@@ -857,6 +967,53 @@ BDCryptoLUKSInfo* bd_crypto_luks_info (const gchar *luks_device, GError **error)
|
||||
*/
|
||||
BDCryptoIntegrityInfo* bd_crypto_integrity_info (const gchar *device, GError **error);
|
||||
|
||||
+/**
|
||||
+ * bd_crypto_integrity_format:
|
||||
+ * @device: a device to format as integrity
|
||||
+ * @algorithm: integrity algorithm specification (e.g. "crc32c" or "sha256") or %NULL to use the default
|
||||
+ * @wipe: whether to wipe the device after format; a device that is not initially wiped will contain invalid checksums
|
||||
+ * @key_data: (allow-none) (array length=key_size): integrity key or %NULL if not needed
|
||||
+ * @key_size: size the integrity key and @key_data
|
||||
+ * @extra: (allow-none): extra arguments for integrity format creation
|
||||
+ * @error: (out): place to store error (if any)
|
||||
+ *
|
||||
+ * Formats the given @device as integrity according to the other parameters given.
|
||||
+ *
|
||||
+ * Returns: whether the given @device was successfully formatted as integrity or not
|
||||
+ * (the @error) contains the error in such cases)
|
||||
+ *
|
||||
+ * Tech category: %BD_CRYPTO_TECH_INTEGRITY-%BD_CRYPTO_TECH_MODE_CREATE
|
||||
+ */
|
||||
+gboolean bd_crypto_integrity_format (const gchar *device, const gchar *algorithm, gboolean wipe, const guint8* key_data, gsize key_size, BDCryptoIntegrityExtra *extra, GError **error);
|
||||
+
|
||||
+/**
|
||||
+ * bd_crypto_integrity_open:
|
||||
+ * @device: integrity device to open
|
||||
+ * @name: name for the opened @device
|
||||
+ * @algorithm: (allow-none): integrity algorithm specification (e.g. "crc32c" or "sha256") or %NULL to use the default
|
||||
+ * @key_data: (allow-none) (array length=key_size): integrity key or %NULL if not needed
|
||||
+ * @key_size: size the integrity key and @key_data
|
||||
+ * @flags: flags for the integrity device activation
|
||||
+ * @extra: (allow-none): extra arguments for integrity open
|
||||
+ * @error: (out): place to store error (if any)
|
||||
+ *
|
||||
+ * Returns: whether the @device was successfully opened or not
|
||||
+ *
|
||||
+ * Tech category: %BD_CRYPTO_TECH_INTEGRITY-%BD_CRYPTO_TECH_MODE_OPEN_CLOSE
|
||||
+ */
|
||||
+gboolean bd_crypto_integrity_open (const gchar *device, const gchar *name, const gchar *algorithm, const guint8* key_data, gsize key_size, BDCryptoIntegrityOpenFlags flags, BDCryptoIntegrityExtra *extra, GError **error);
|
||||
+
|
||||
+/**
|
||||
+ * bd_crypto_integrity_close:
|
||||
+ * @integrity_device: integrity device to close
|
||||
+ * @error: (out): place to store error (if any)
|
||||
+ *
|
||||
+ * Returns: whether the given @integrity_device was successfully closed or not
|
||||
+ *
|
||||
+ * Tech category: %BD_CRYPTO_TECH_INTEGRITY-%BD_CRYPTO_TECH_MODE_OPEN_CLOSE
|
||||
+ */
|
||||
+gboolean bd_crypto_integrity_close (const gchar *integrity_device, GError **error);
|
||||
+
|
||||
/**
|
||||
* bd_crypto_device_seems_encrypted:
|
||||
* @device: the queried device
|
||||
diff --git a/src/plugins/crypto.c b/src/plugins/crypto.c
|
||||
index 4fad9a8..b1b0700 100644
|
||||
--- a/src/plugins/crypto.c
|
||||
+++ b/src/plugins/crypto.c
|
||||
@@ -50,6 +50,18 @@
|
||||
|
||||
#define SECTOR_SIZE 512
|
||||
|
||||
+#define DEFAULT_LUKS_KEYSIZE_BITS 256
|
||||
+#define DEFAULT_LUKS_CIPHER "aes-xts-plain64"
|
||||
+
|
||||
+#ifdef LIBCRYPTSETUP_23
|
||||
+/* 0 for autodetect since 2.3.0 */
|
||||
+#define DEFAULT_INTEGRITY_TAG_SIZE 0
|
||||
+#else
|
||||
+/* we need some sane default for older versions, users should specify tag size when using
|
||||
+ other algorithms than the default crc32c */
|
||||
+#define DEFAULT_INTEGRITY_TAG_SIZE 4
|
||||
+#endif
|
||||
+
|
||||
#define UNUSED __attribute__((unused))
|
||||
|
||||
/**
|
||||
@@ -146,6 +158,43 @@ BDCryptoLUKSExtra* bd_crypto_luks_extra_new (guint64 data_alignment, const gchar
|
||||
return ret;
|
||||
}
|
||||
|
||||
+BDCryptoIntegrityExtra* bd_crypto_integrity_extra_new (guint64 sector_size, guint64 journal_size, guint journal_watermark, guint journal_commit_time, guint64 interleave_sectors, guint64 tag_size, guint64 buffer_sectors) {
|
||||
+ BDCryptoIntegrityExtra *ret = g_new0 (BDCryptoIntegrityExtra, 1);
|
||||
+ ret->sector_size = sector_size;
|
||||
+ ret->journal_size = journal_size;
|
||||
+ ret->journal_watermark = journal_watermark;
|
||||
+ ret->journal_commit_time = journal_commit_time;
|
||||
+ ret->interleave_sectors = interleave_sectors;
|
||||
+ ret->tag_size = tag_size;
|
||||
+ ret->buffer_sectors = buffer_sectors;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+BDCryptoIntegrityExtra* bd_crypto_integrity_extra_copy (BDCryptoIntegrityExtra *extra) {
|
||||
+ if (extra == NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
+ BDCryptoIntegrityExtra *new_extra = g_new0 (BDCryptoIntegrityExtra, 1);
|
||||
+
|
||||
+ new_extra->sector_size = extra->sector_size;
|
||||
+ new_extra->journal_size = extra->journal_size;
|
||||
+ new_extra->journal_watermark = extra->journal_watermark;
|
||||
+ new_extra->journal_commit_time = extra->journal_commit_time;
|
||||
+ new_extra->interleave_sectors = extra->interleave_sectors;
|
||||
+ new_extra->tag_size = extra->tag_size;
|
||||
+ new_extra->buffer_sectors = extra->buffer_sectors;
|
||||
+
|
||||
+ return new_extra;
|
||||
+}
|
||||
+
|
||||
+void bd_crypto_integrity_extra_free (BDCryptoIntegrityExtra *extra) {
|
||||
+ if (extra == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ g_free (extra);
|
||||
+}
|
||||
+
|
||||
void bd_crypto_luks_info_free (BDCryptoLUKSInfo *info) {
|
||||
if (info == NULL)
|
||||
return;
|
||||
@@ -346,15 +395,15 @@ gboolean bd_crypto_is_tech_avail (BDCryptoTech tech, guint64 mode, GError **erro
|
||||
"Integrity technology requires libcryptsetup >= 2.0");
|
||||
return FALSE;
|
||||
#endif
|
||||
- ret = mode & (BD_CRYPTO_TECH_MODE_QUERY);
|
||||
+ ret = mode & (BD_CRYPTO_TECH_MODE_CREATE|BD_CRYPTO_TECH_MODE_OPEN_CLOSE|BD_CRYPTO_TECH_MODE_QUERY);
|
||||
if (ret != mode) {
|
||||
g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_TECH_UNAVAIL,
|
||||
- "Only 'query' supported for Integrity");
|
||||
+ "Only 'create', 'open' and 'query' supported for Integrity");
|
||||
return FALSE;
|
||||
} else
|
||||
return TRUE;
|
||||
case BD_CRYPTO_TECH_BITLK:
|
||||
-#ifndef LIBCRYPTSETUP_BITLK
|
||||
+#ifndef LIBCRYPTSETUP_23
|
||||
g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_TECH_UNAVAIL,
|
||||
"BITLK technology requires libcryptsetup >= 2.3.0");
|
||||
return FALSE;
|
||||
@@ -2035,6 +2084,208 @@ BDCryptoIntegrityInfo* bd_crypto_integrity_info (const gchar *device, GError **e
|
||||
}
|
||||
#endif
|
||||
|
||||
+static int _wipe_progress (guint64 size, guint64 offset, void *usrptr) {
|
||||
+ /* "convert" the progress from 0-100 to 50-100 because wipe starts at 50 in bd_crypto_integrity_format */
|
||||
+ gdouble progress = 50 + (((gdouble) offset / size) * 100) / 2;
|
||||
+ bd_utils_report_progress (*(guint64 *) usrptr, progress, "Integrity device wipe in progress");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * bd_crypto_integrity_format:
|
||||
+ * @device: a device to format as integrity
|
||||
+ * @algorithm: integrity algorithm specification (e.g. "crc32c" or "sha256")
|
||||
+ * @wipe: whether to wipe the device after format; a device that is not initially wiped will contain invalid checksums
|
||||
+ * @key_data: (allow-none) (array length=key_size): integrity key or %NULL if not needed
|
||||
+ * @key_size: size the integrity key and @key_data
|
||||
+ * @extra: (allow-none): extra arguments for integrity format creation
|
||||
+ * @error: (out): place to store error (if any)
|
||||
+ *
|
||||
+ * Formats the given @device as integrity according to the other parameters given.
|
||||
+ *
|
||||
+ * Returns: whether the given @device was successfully formatted as integrity or not
|
||||
+ * (the @error) contains the error in such cases)
|
||||
+ *
|
||||
+ * Tech category: %BD_CRYPTO_TECH_INTEGRITY-%BD_CRYPTO_TECH_MODE_CREATE
|
||||
+ */
|
||||
+gboolean bd_crypto_integrity_format (const gchar *device, const gchar *algorithm, gboolean wipe, const guint8* key_data, gsize key_size, BDCryptoIntegrityExtra *extra, GError **error) {
|
||||
+ struct crypt_device *cd = NULL;
|
||||
+ gint ret;
|
||||
+ guint64 progress_id = 0;
|
||||
+ gchar *msg = NULL;
|
||||
+ struct crypt_params_integrity params = ZERO_INIT;
|
||||
+ g_autofree gchar *tmp_name = NULL;
|
||||
+ g_autofree gchar *tmp_path = NULL;
|
||||
+ g_autofree gchar *dev_name = NULL;
|
||||
+
|
||||
+ msg = g_strdup_printf ("Started formatting '%s' as integrity device", device);
|
||||
+ progress_id = bd_utils_report_started (msg);
|
||||
+ g_free (msg);
|
||||
+
|
||||
+ ret = crypt_init (&cd, device);
|
||||
+ if (ret != 0) {
|
||||
+ g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE,
|
||||
+ "Failed to initialize device: %s", strerror_l (-ret, c_locale));
|
||||
+ bd_utils_report_finished (progress_id, (*error)->message);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (extra) {
|
||||
+ params.sector_size = extra->sector_size;
|
||||
+ params.journal_size = extra->journal_size;
|
||||
+ params.journal_watermark = extra->journal_watermark;
|
||||
+ params.journal_commit_time = extra->journal_commit_time;
|
||||
+ params.interleave_sectors = extra->interleave_sectors;
|
||||
+ params.tag_size = extra->tag_size;
|
||||
+ params.buffer_sectors = extra->buffer_sectors;
|
||||
+ }
|
||||
+
|
||||
+ params.integrity_key_size = key_size;
|
||||
+ params.integrity = algorithm;
|
||||
+ params.tag_size = params.tag_size ? params.tag_size : DEFAULT_INTEGRITY_TAG_SIZE;
|
||||
+
|
||||
+ ret = crypt_format (cd, CRYPT_INTEGRITY, NULL, NULL, NULL, NULL, 0, ¶ms);
|
||||
+ if (ret != 0) {
|
||||
+ g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_FORMAT_FAILED,
|
||||
+ "Failed to format device: %s", strerror_l (-ret, c_locale));
|
||||
+ crypt_free (cd);
|
||||
+ bd_utils_report_finished (progress_id, (*error)->message);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (wipe) {
|
||||
+ bd_utils_report_progress (progress_id, 50, "Format created");
|
||||
+
|
||||
+ dev_name = g_path_get_basename (device);
|
||||
+ tmp_name = g_strdup_printf ("bd-temp-integrity-%s-%d", dev_name, g_random_int ());
|
||||
+ tmp_path = g_strdup_printf ("%s/%s", crypt_get_dir (), tmp_name);
|
||||
+
|
||||
+ ret = crypt_activate_by_volume_key (cd, tmp_name, (const char *) key_data, key_size,
|
||||
+ CRYPT_ACTIVATE_PRIVATE | CRYPT_ACTIVATE_NO_JOURNAL);
|
||||
+ if (ret != 0) {
|
||||
+ g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE,
|
||||
+ "Failed to activate the newly created integrity device for wiping: %s",
|
||||
+ strerror_l (-ret, c_locale));
|
||||
+ crypt_free (cd);
|
||||
+ bd_utils_report_finished (progress_id, (*error)->message);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ bd_utils_report_progress (progress_id, 50, "Starting to wipe the newly created integrity device");
|
||||
+ ret = crypt_wipe (cd, tmp_path, CRYPT_WIPE_ZERO, 0, 0, 1048576,
|
||||
+ 0, &_wipe_progress, &progress_id);
|
||||
+ bd_utils_report_progress (progress_id, 100, "Wipe finished");
|
||||
+ if (ret != 0) {
|
||||
+ g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE,
|
||||
+ "Failed to wipe the newly created integrity device: %s",
|
||||
+ strerror_l (-ret, c_locale));
|
||||
+
|
||||
+ ret = crypt_deactivate (cd, tmp_name);
|
||||
+ if (ret != 0)
|
||||
+ g_warning ("Failed to deactivate temporary device %s", tmp_name);
|
||||
+
|
||||
+ crypt_free (cd);
|
||||
+ bd_utils_report_finished (progress_id, (*error)->message);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ ret = crypt_deactivate (cd, tmp_name);
|
||||
+ if (ret != 0)
|
||||
+ g_warning ("Failed to deactivate temporary device %s", tmp_name);
|
||||
+
|
||||
+ } else
|
||||
+ bd_utils_report_finished (progress_id, "Completed");
|
||||
+
|
||||
+ crypt_free (cd);
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * bd_crypto_integrity_open:
|
||||
+ * @device: integrity device to open
|
||||
+ * @name: name for the opened @device
|
||||
+ * @algorithm: (allow-none): integrity algorithm specification (e.g. "crc32c" or "sha256") or %NULL to use the default
|
||||
+ * @key_data: (allow-none) (array length=key_size): integrity key or %NULL if not needed
|
||||
+ * @key_size: size the integrity key and @key_data
|
||||
+ * @flags: flags for the integrity device activation
|
||||
+ * @extra: (allow-none): extra arguments for integrity open
|
||||
+ * @error: (out): place to store error (if any)
|
||||
+ *
|
||||
+ * Returns: whether the @device was successfully opened or not
|
||||
+ *
|
||||
+ * Tech category: %BD_CRYPTO_TECH_INTEGRITY-%BD_CRYPTO_TECH_MODE_OPEN_CLOSE
|
||||
+ */
|
||||
+gboolean bd_crypto_integrity_open (const gchar *device, const gchar *name, const gchar *algorithm, const guint8* key_data, gsize key_size, BDCryptoIntegrityOpenFlags flags, BDCryptoIntegrityExtra *extra, GError **error) {
|
||||
+ struct crypt_device *cd = NULL;
|
||||
+ gint ret = 0;
|
||||
+ guint64 progress_id = 0;
|
||||
+ gchar *msg = NULL;
|
||||
+ struct crypt_params_integrity params = ZERO_INIT;
|
||||
+
|
||||
+ params.integrity = algorithm;
|
||||
+ params.integrity_key_size = key_size;
|
||||
+
|
||||
+ if (extra) {
|
||||
+ params.sector_size = extra->sector_size;
|
||||
+ params.journal_size = extra->journal_size;
|
||||
+ params.journal_watermark = extra->journal_watermark;
|
||||
+ params.journal_commit_time = extra->journal_commit_time;
|
||||
+ params.interleave_sectors = extra->interleave_sectors;
|
||||
+ params.tag_size = extra->tag_size;
|
||||
+ params.buffer_sectors = extra->buffer_sectors;
|
||||
+ }
|
||||
+
|
||||
+ msg = g_strdup_printf ("Started opening '%s' integrity device", device);
|
||||
+ progress_id = bd_utils_report_started (msg);
|
||||
+ g_free (msg);
|
||||
+
|
||||
+ ret = crypt_init (&cd, device);
|
||||
+ if (ret != 0) {
|
||||
+ g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE,
|
||||
+ "Failed to initialize device: %s", strerror_l (-ret, c_locale));
|
||||
+ bd_utils_report_finished (progress_id, (*error)->message);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ ret = crypt_load (cd, CRYPT_INTEGRITY, ¶ms);
|
||||
+ if (ret != 0) {
|
||||
+ g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE,
|
||||
+ "Failed to load device's parameters: %s", strerror_l (-ret, c_locale));
|
||||
+ crypt_free (cd);
|
||||
+ bd_utils_report_finished (progress_id, (*error)->message);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ ret = crypt_activate_by_volume_key (cd, name, (const char *) key_data, key_size, flags);
|
||||
+ if (ret < 0) {
|
||||
+ g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE,
|
||||
+ "Failed to activate device: %s", strerror_l (-ret, c_locale));
|
||||
+
|
||||
+ crypt_free (cd);
|
||||
+ bd_utils_report_finished (progress_id, (*error)->message);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ crypt_free (cd);
|
||||
+ bd_utils_report_finished (progress_id, "Completed");
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * bd_crypto_integrity_close:
|
||||
+ * @integrity_device: integrity device to close
|
||||
+ * @error: (out): place to store error (if any)
|
||||
+ *
|
||||
+ * Returns: whether the given @integrity_device was successfully closed or not
|
||||
+ *
|
||||
+ * Tech category: %BD_CRYPTO_TECH_INTEGRITY-%BD_CRYPTO_TECH_MODE_OPEN_CLOSE
|
||||
+ */
|
||||
+gboolean bd_crypto_integrity_close (const gchar *integrity_device, GError **error) {
|
||||
+ return _crypto_close (integrity_device, "integrity", error);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* bd_crypto_device_seems_encrypted:
|
||||
* @device: the queried device
|
||||
@@ -2472,7 +2723,7 @@ gboolean bd_crypto_escrow_device (const gchar *device, const gchar *passphrase,
|
||||
*
|
||||
* Tech category: %BD_CRYPTO_TECH_BITLK-%BD_CRYPTO_TECH_MODE_OPEN_CLOSE
|
||||
*/
|
||||
-#ifndef LIBCRYPTSETUP_BITLK
|
||||
+#ifndef LIBCRYPTSETUP_23
|
||||
gboolean bd_crypto_bitlk_open (const gchar *device UNUSED, const gchar *name UNUSED, const guint8* pass_data UNUSED, gsize data_len UNUSED, gboolean read_only UNUSED, GError **error) {
|
||||
/* this will return FALSE and set error, because BITLK technology is not available */
|
||||
return bd_crypto_is_tech_avail (BD_CRYPTO_TECH_BITLK, BD_CRYPTO_TECH_MODE_OPEN_CLOSE, error);
|
||||
@@ -2542,7 +2793,7 @@ gboolean bd_crypto_bitlk_open (const gchar *device, const gchar *name, const gui
|
||||
*
|
||||
* Tech category: %BD_CRYPTO_TECH_BITLK-%BD_CRYPTO_TECH_MODE_OPEN_CLOSE
|
||||
*/
|
||||
-#ifndef LIBCRYPTSETUP_BITLK
|
||||
+#ifndef LIBCRYPTSETUP_23
|
||||
gboolean bd_crypto_bitlk_close (const gchar *bitlk_device UNUSED, GError **error) {
|
||||
/* this will return FALSE and set error, because BITLK technology is not available */
|
||||
return bd_crypto_is_tech_avail (BD_CRYPTO_TECH_BITLK, BD_CRYPTO_TECH_MODE_OPEN_CLOSE, error);
|
||||
diff --git a/src/plugins/crypto.h b/src/plugins/crypto.h
|
||||
index a38724d..166e558 100644
|
||||
--- a/src/plugins/crypto.h
|
||||
+++ b/src/plugins/crypto.h
|
||||
@@ -116,6 +116,43 @@ void bd_crypto_luks_extra_free (BDCryptoLUKSExtra *extra);
|
||||
BDCryptoLUKSExtra* bd_crypto_luks_extra_copy (BDCryptoLUKSExtra *extra);
|
||||
BDCryptoLUKSExtra* bd_crypto_luks_extra_new (guint64 data_alignment, const gchar *data_device, const gchar *integrity, guint64 sector_size, const gchar *label, const gchar *subsystem, BDCryptoLUKSPBKDF *pbkdf);
|
||||
|
||||
+/**
|
||||
+ * BDCryptoIntegrityExtra:
|
||||
+ * @sector_size: integrity sector size
|
||||
+ * @journal_size: size of journal in bytes
|
||||
+ * @journal_watermark: journal flush watermark in percents; in bitmap mode sectors-per-bit
|
||||
+ * @journal_commit_time: journal commit time (or bitmap flush time) in ms
|
||||
+ * @interleave_sectors: number of interleave sectors (power of two)
|
||||
+ * @tag_size: tag size per-sector in bytes
|
||||
+ * @buffer_sectors: number of sectors in one buffer
|
||||
+ */
|
||||
+typedef struct BDCryptoIntegrityExtra {
|
||||
+ guint32 sector_size;
|
||||
+ guint64 journal_size;
|
||||
+ guint journal_watermark;
|
||||
+ guint journal_commit_time;
|
||||
+ guint32 interleave_sectors;
|
||||
+ guint32 tag_size;
|
||||
+ guint32 buffer_sectors;
|
||||
+} BDCryptoIntegrityExtra;
|
||||
+
|
||||
+void bd_crypto_integrity_extra_free (BDCryptoIntegrityExtra *extra);
|
||||
+BDCryptoIntegrityExtra* bd_crypto_integrity_extra_copy (BDCryptoIntegrityExtra *extra);
|
||||
+BDCryptoIntegrityExtra* bd_crypto_integrity_extra_new (guint64 sector_size, guint64 journal_size, guint journal_watermark, guint journal_commit_time, guint64 interleave_sectors, guint64 tag_size, guint64 buffer_sectors);
|
||||
+
|
||||
+typedef enum {
|
||||
+ BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL = CRYPT_ACTIVATE_NO_JOURNAL,
|
||||
+ BD_CRYPTO_INTEGRITY_OPEN_RECOVERY = CRYPT_ACTIVATE_RECOVERY,
|
||||
+#ifdef CRYPT_ACTIVATE_NO_JOURNAL_BITMAP
|
||||
+ BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL_BITMAP = CRYPT_ACTIVATE_NO_JOURNAL_BITMAP,
|
||||
+#endif
|
||||
+ BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE = CRYPT_ACTIVATE_RECALCULATE,
|
||||
+#ifdef CRYPT_ACTIVATE_RECALCULATE_RESET
|
||||
+ BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE_RESET = CRYPT_ACTIVATE_RECALCULATE_RESET,
|
||||
+#endif
|
||||
+ BD_CRYPTO_INTEGRITY_OPEN_ALLOW_DISCARDS = CRYPT_ACTIVATE_ALLOW_DISCARDS,
|
||||
+} BDCryptoIntegrityOpenFlags;
|
||||
+
|
||||
/**
|
||||
* BDCryptoLUKSInfo:
|
||||
* @version: LUKS version
|
||||
@@ -209,6 +246,10 @@ gboolean bd_crypto_luks_header_restore (const gchar *device, const gchar *backup
|
||||
BDCryptoLUKSInfo* bd_crypto_luks_info (const gchar *luks_device, GError **error);
|
||||
BDCryptoIntegrityInfo* bd_crypto_integrity_info (const gchar *device, GError **error);
|
||||
|
||||
+gboolean bd_crypto_integrity_format (const gchar *device, const gchar *algorithm, gboolean wipe, const guint8* key_data, gsize key_size, BDCryptoIntegrityExtra *extra, GError **error);
|
||||
+gboolean bd_crypto_integrity_open (const gchar *device, const gchar *name, const gchar *algorithm, const guint8* key_data, gsize key_size, BDCryptoIntegrityOpenFlags flags, BDCryptoIntegrityExtra *extra, GError **error);
|
||||
+gboolean bd_crypto_integrity_close (const gchar *integrity_device, GError **error);
|
||||
+
|
||||
gboolean bd_crypto_device_seems_encrypted (const gchar *device, GError **error);
|
||||
gboolean bd_crypto_tc_open (const gchar *device, const gchar *name, const guint8* pass_data, gsize data_len, gboolean read_only, GError **error);
|
||||
gboolean bd_crypto_tc_open_full (const gchar *device, const gchar *name, const guint8* pass_data, gsize data_len, const gchar **keyfiles, gboolean hidden, gboolean system, gboolean veracrypt, guint32 veracrypt_pim, gboolean read_only, GError **error);
|
||||
diff --git a/src/python/gi/overrides/BlockDev.py b/src/python/gi/overrides/BlockDev.py
|
||||
index 715a262..71bcd31 100644
|
||||
--- a/src/python/gi/overrides/BlockDev.py
|
||||
+++ b/src/python/gi/overrides/BlockDev.py
|
||||
@@ -276,6 +276,30 @@ def crypto_bitlk_open(device, name, passphrase, read_only=False):
|
||||
__all__.append("crypto_bitlk_open")
|
||||
|
||||
|
||||
+class CryptoIntegrityExtra(BlockDev.CryptoIntegrityExtra):
|
||||
+ def __new__(cls, sector_size=0, journal_size=0, journal_watermark=0, journal_commit_time=0, interleave_sectors=0, tag_size=0, buffer_sectors=0):
|
||||
+ ret = BlockDev.CryptoIntegrityExtra.new(sector_size, journal_size, journal_watermark, journal_commit_time, interleave_sectors, tag_size, buffer_sectors)
|
||||
+ ret.__class__ = cls
|
||||
+ return ret
|
||||
+ def __init__(self, *args, **kwargs): # pylint: disable=unused-argument
|
||||
+ super(CryptoIntegrityExtra, self).__init__() #pylint: disable=bad-super-call
|
||||
+CryptoIntegrityExtra = override(CryptoIntegrityExtra)
|
||||
+__all__.append("CryptoIntegrityExtra")
|
||||
+
|
||||
+
|
||||
+_crypto_integrity_format = BlockDev.crypto_integrity_format
|
||||
+@override(BlockDev.crypto_integrity_format)
|
||||
+def crypto_integrity_format(device, algorithm=None, wipe=True, key_data=None, extra=None):
|
||||
+ return _crypto_integrity_format(device, algorithm, wipe, key_data, extra)
|
||||
+__all__.append("crypto_integrity_format")
|
||||
+
|
||||
+_crypto_integrity_open = BlockDev.crypto_integrity_open
|
||||
+@override(BlockDev.crypto_integrity_open)
|
||||
+def crypto_integrity_open(device, name, algorithm, key_data=None, flags=0, extra=None):
|
||||
+ return _crypto_integrity_open(device, name, algorithm, key_data, flags, extra)
|
||||
+__all__.append("crypto_integrity_open")
|
||||
+
|
||||
+
|
||||
_dm_create_linear = BlockDev.dm_create_linear
|
||||
@override(BlockDev.dm_create_linear)
|
||||
def dm_create_linear(map_name, device, length, uuid=None):
|
||||
diff --git a/tests/crypto_test.py b/tests/crypto_test.py
|
||||
index 0aecc03..1c6832e 100644
|
||||
--- a/tests/crypto_test.py
|
||||
+++ b/tests/crypto_test.py
|
||||
@@ -2,6 +2,7 @@ import unittest
|
||||
import os
|
||||
import tempfile
|
||||
import overrides_hack
|
||||
+import secrets
|
||||
import shutil
|
||||
import subprocess
|
||||
import six
|
||||
@@ -42,6 +43,8 @@ class CryptoTestCase(unittest.TestCase):
|
||||
|
||||
requested_plugins = BlockDev.plugin_specs_from_names(("crypto", "loop"))
|
||||
|
||||
+ _dm_name = "libblockdevTestLUKS"
|
||||
+
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
unittest.TestCase.setUpClass()
|
||||
@@ -72,7 +75,7 @@ class CryptoTestCase(unittest.TestCase):
|
||||
|
||||
def _clean_up(self):
|
||||
try:
|
||||
- BlockDev.crypto_luks_close("libblockdevTestLUKS")
|
||||
+ BlockDev.crypto_luks_close(self._dm_name)
|
||||
except:
|
||||
pass
|
||||
|
||||
@@ -964,7 +967,8 @@ class CryptoTestInfo(CryptoTestCase):
|
||||
succ = BlockDev.crypto_luks_close("libblockdevTestLUKS")
|
||||
self.assertTrue(succ)
|
||||
|
||||
-class CryptoTestIntegrity(CryptoTestCase):
|
||||
+
|
||||
+class CryptoTestLUKS2Integrity(CryptoTestCase):
|
||||
@tag_test(TestTags.SLOW)
|
||||
@unittest.skipUnless(HAVE_LUKS2, "LUKS 2 not supported")
|
||||
def test_luks2_integrity(self):
|
||||
@@ -1151,3 +1155,92 @@ class CryptoTestBitlk(CryptoTestCase):
|
||||
succ = BlockDev.crypto_bitlk_close("libblockdevTestBitlk")
|
||||
self.assertTrue(succ)
|
||||
self.assertFalse(os.path.exists("/dev/mapper/libblockdevTestBitlk"))
|
||||
+
|
||||
+
|
||||
+class CryptoTestIntegrity(CryptoTestCase):
|
||||
+
|
||||
+ _dm_name = "libblockdevTestIntegrity"
|
||||
+
|
||||
+ @unittest.skipUnless(HAVE_LUKS2, "Integrity not supported")
|
||||
+ def test_integrity(self):
|
||||
+ # basic format+open+close test
|
||||
+ succ = BlockDev.crypto_integrity_format(self.loop_dev, "sha256", False)
|
||||
+ self.assertTrue(succ)
|
||||
+
|
||||
+ succ = BlockDev.crypto_integrity_open(self.loop_dev, self._dm_name, "sha256")
|
||||
+ self.assertTrue(succ)
|
||||
+ self.assertTrue(os.path.exists("/dev/mapper/%s" % self._dm_name))
|
||||
+
|
||||
+ info = BlockDev.crypto_integrity_info(self._dm_name)
|
||||
+ self.assertEqual(info.algorithm, "sha256")
|
||||
+
|
||||
+ succ = BlockDev.crypto_integrity_close(self._dm_name)
|
||||
+ self.assertTrue(succ)
|
||||
+ self.assertFalse(os.path.exists("/dev/mapper/%s" % self._dm_name))
|
||||
+
|
||||
+ # same now with a keyed algorithm
|
||||
+ key = list(secrets.token_bytes(64))
|
||||
+
|
||||
+ succ = BlockDev.crypto_integrity_format(self.loop_dev, "hmac(sha256)", False, key)
|
||||
+ self.assertTrue(succ)
|
||||
+
|
||||
+ succ = BlockDev.crypto_integrity_open(self.loop_dev, self._dm_name, "hmac(sha256)", key)
|
||||
+ self.assertTrue(succ)
|
||||
+ self.assertTrue(os.path.exists("/dev/mapper/%s" % self._dm_name))
|
||||
+
|
||||
+ info = BlockDev.crypto_integrity_info(self._dm_name)
|
||||
+ self.assertEqual(info.algorithm, "hmac(sha256)")
|
||||
+
|
||||
+ succ = BlockDev.crypto_integrity_close(self._dm_name)
|
||||
+ self.assertTrue(succ)
|
||||
+ self.assertFalse(os.path.exists("/dev/mapper/%s" % self._dm_name))
|
||||
+
|
||||
+ # same with some custom parameters
|
||||
+ extra = BlockDev.CryptoIntegrityExtra(sector_size=4096, interleave_sectors=65536)
|
||||
+ succ = BlockDev.crypto_integrity_format(self.loop_dev, "crc32c", wipe=False, extra=extra)
|
||||
+ self.assertTrue(succ)
|
||||
+
|
||||
+ succ = BlockDev.crypto_integrity_open(self.loop_dev, self._dm_name, "crc32c")
|
||||
+ self.assertTrue(succ)
|
||||
+ self.assertTrue(os.path.exists("/dev/mapper/%s" % self._dm_name))
|
||||
+
|
||||
+ info = BlockDev.crypto_integrity_info(self._dm_name)
|
||||
+ self.assertEqual(info.algorithm, "crc32c")
|
||||
+ self.assertEqual(info.sector_size, 4096)
|
||||
+ self.assertEqual(info.interleave_sectors, 65536)
|
||||
+
|
||||
+ succ = BlockDev.crypto_integrity_close(self._dm_name)
|
||||
+ self.assertTrue(succ)
|
||||
+ self.assertFalse(os.path.exists("/dev/mapper/%s" % self._dm_name))
|
||||
+
|
||||
+ @tag_test(TestTags.SLOW)
|
||||
+ @unittest.skipUnless(HAVE_LUKS2, "Integrity not supported")
|
||||
+ def test_integrity_wipe(self):
|
||||
+ # also check that wipe progress reporting works
|
||||
+ progress_log = []
|
||||
+
|
||||
+ def _my_progress_func(_task, _status, completion, msg):
|
||||
+ progress_log.append((completion, msg))
|
||||
+
|
||||
+ succ = BlockDev.utils_init_prog_reporting(_my_progress_func)
|
||||
+ self.assertTrue(succ)
|
||||
+ self.addCleanup(BlockDev.utils_init_prog_reporting, None)
|
||||
+
|
||||
+ succ = BlockDev.crypto_integrity_format(self.loop_dev, "sha256", True)
|
||||
+ self.assertTrue(succ)
|
||||
+
|
||||
+ # at least one message "Integrity device wipe in progress" should be logged
|
||||
+ self.assertTrue(any(prog[1] == "Integrity device wipe in progress" for prog in progress_log))
|
||||
+
|
||||
+ succ = BlockDev.crypto_integrity_open(self.loop_dev, self._dm_name, "sha256")
|
||||
+ self.assertTrue(succ)
|
||||
+ self.assertTrue(os.path.exists("/dev/mapper/%s" % self._dm_name))
|
||||
+
|
||||
+ # check the devices was wiped and the checksums recalculated
|
||||
+ # (mkfs reads some blocks first so without checksums it would fail)
|
||||
+ ret, _out, err = run_command("mkfs.ext2 /dev/mapper/%s " % self._dm_name)
|
||||
+ self.assertEqual(ret, 0, msg="Failed to create ext2 filesystem on integrity: %s" % err)
|
||||
+
|
||||
+ succ = BlockDev.crypto_integrity_close(self._dm_name)
|
||||
+ self.assertTrue(succ)
|
||||
+ self.assertFalse(os.path.exists("/dev/mapper/%s" % self._dm_name))
|
||||
--
|
||||
2.31.1
|
||||
|
||||
|
||||
From 4dcb7a42a2cb33f7a63021d72889c9a9688adfd3 Mon Sep 17 00:00:00 2001
|
||||
From: Vojtech Trefny <vtrefny@redhat.com>
|
||||
Date: Thu, 30 Sep 2021 16:01:40 +0200
|
||||
Subject: [PATCH 2/3] Create smaller test images for integrity tests
|
||||
|
||||
We are going to overwrite the entire device in test_integrity_wipe
|
||||
so we need to make sure the sparse actually fits to /tmp which
|
||||
can be smaller than 1 GiB.
|
||||
---
|
||||
tests/crypto_test.py | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tests/crypto_test.py b/tests/crypto_test.py
|
||||
index 1c6832e..b7ec251 100644
|
||||
--- a/tests/crypto_test.py
|
||||
+++ b/tests/crypto_test.py
|
||||
@@ -44,6 +44,7 @@ class CryptoTestCase(unittest.TestCase):
|
||||
requested_plugins = BlockDev.plugin_specs_from_names(("crypto", "loop"))
|
||||
|
||||
_dm_name = "libblockdevTestLUKS"
|
||||
+ _sparse_size = 1024**3
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
@@ -57,8 +58,8 @@ class CryptoTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.addCleanup(self._clean_up)
|
||||
- self.dev_file = create_sparse_tempfile("crypto_test", 1024**3)
|
||||
- self.dev_file2 = create_sparse_tempfile("crypto_test2", 1024**3)
|
||||
+ self.dev_file = create_sparse_tempfile("crypto_test", self._sparse_size)
|
||||
+ self.dev_file2 = create_sparse_tempfile("crypto_test2", self._sparse_size)
|
||||
try:
|
||||
self.loop_dev = create_lio_device(self.dev_file)
|
||||
except RuntimeError as e:
|
||||
@@ -1160,6 +1161,7 @@ class CryptoTestBitlk(CryptoTestCase):
|
||||
class CryptoTestIntegrity(CryptoTestCase):
|
||||
|
||||
_dm_name = "libblockdevTestIntegrity"
|
||||
+ _sparse_size = 100 * 1024**2
|
||||
|
||||
@unittest.skipUnless(HAVE_LUKS2, "Integrity not supported")
|
||||
def test_integrity(self):
|
||||
--
|
||||
2.31.1
|
||||
|
||||
|
||||
From 3b82f9085c0df2e58b673716cdefd747495738e2 Mon Sep 17 00:00:00 2001
|
||||
From: Vojtech Trefny <vtrefny@redhat.com>
|
||||
Date: Wed, 20 Oct 2021 10:27:41 +0200
|
||||
Subject: [PATCH 3/3] crypto: Do not use libcryptsetup flags directly in
|
||||
crypto.h
|
||||
|
||||
We can "translate" our flags in the implementation instead to
|
||||
avoid including libcryptsetup.h in our header and API files.
|
||||
---
|
||||
src/lib/plugin_apis/crypto.api | 17 ++++++-----------
|
||||
src/plugins/crypto.c | 34 +++++++++++++++++++++++++++++++++-
|
||||
src/plugins/crypto.h | 16 ++++++----------
|
||||
tests/crypto_test.py | 14 ++++++++++++++
|
||||
4 files changed, 59 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/src/lib/plugin_apis/crypto.api b/src/lib/plugin_apis/crypto.api
|
||||
index 40e32c8..cf87979 100644
|
||||
--- a/src/lib/plugin_apis/crypto.api
|
||||
+++ b/src/lib/plugin_apis/crypto.api
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <glib.h>
|
||||
#include <blockdev/utils.h>
|
||||
-#include <libcryptsetup.h>
|
||||
|
||||
#define BD_CRYPTO_LUKS_METADATA_SIZE G_GUINT64_CONSTANT (2097152ULL) // 2 MiB
|
||||
|
||||
@@ -343,16 +342,12 @@ GType bd_crypto_integrity_extra_get_type () {
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
- BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL = CRYPT_ACTIVATE_NO_JOURNAL,
|
||||
- BD_CRYPTO_INTEGRITY_OPEN_RECOVERY = CRYPT_ACTIVATE_RECOVERY,
|
||||
-#ifdef CRYPT_ACTIVATE_NO_JOURNAL_BITMAP
|
||||
- BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL_BITMAP = CRYPT_ACTIVATE_NO_JOURNAL_BITMAP,
|
||||
-#endif
|
||||
- BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE = CRYPT_ACTIVATE_RECALCULATE,
|
||||
-#ifdef CRYPT_ACTIVATE_RECALCULATE_RESET
|
||||
- BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE_RESET = CRYPT_ACTIVATE_RECALCULATE_RESET,
|
||||
-#endif
|
||||
- BD_CRYPTO_INTEGRITY_OPEN_ALLOW_DISCARDS = CRYPT_ACTIVATE_ALLOW_DISCARDS,
|
||||
+ BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL = 1 << 0,
|
||||
+ BD_CRYPTO_INTEGRITY_OPEN_RECOVERY = 1 << 1,
|
||||
+ BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL_BITMAP = 1 << 2,
|
||||
+ BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE = 1 << 3,
|
||||
+ BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE_RESET = 1 << 4,
|
||||
+ BD_CRYPTO_INTEGRITY_OPEN_ALLOW_DISCARDS = 1 << 5,
|
||||
} BDCryptoIntegrityOpenFlags;
|
||||
|
||||
#define BD_CRYPTO_TYPE_LUKS_INFO (bd_crypto_luks_info_get_type ())
|
||||
diff --git a/src/plugins/crypto.c b/src/plugins/crypto.c
|
||||
index b1b0700..8a4d64a 100644
|
||||
--- a/src/plugins/crypto.c
|
||||
+++ b/src/plugins/crypto.c
|
||||
@@ -2223,6 +2223,7 @@ gboolean bd_crypto_integrity_open (const gchar *device, const gchar *name, const
|
||||
guint64 progress_id = 0;
|
||||
gchar *msg = NULL;
|
||||
struct crypt_params_integrity params = ZERO_INIT;
|
||||
+ guint32 activate_flags = 0;
|
||||
|
||||
params.integrity = algorithm;
|
||||
params.integrity_key_size = key_size;
|
||||
@@ -2237,6 +2238,37 @@ gboolean bd_crypto_integrity_open (const gchar *device, const gchar *name, const
|
||||
params.buffer_sectors = extra->buffer_sectors;
|
||||
}
|
||||
|
||||
+
|
||||
+ if (flags & BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL)
|
||||
+ activate_flags |= CRYPT_ACTIVATE_NO_JOURNAL;
|
||||
+ if (flags & BD_CRYPTO_INTEGRITY_OPEN_RECOVERY)
|
||||
+ activate_flags |= CRYPT_ACTIVATE_RECOVERY;
|
||||
+ if (flags & BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE)
|
||||
+ activate_flags |= CRYPT_ACTIVATE_RECALCULATE;
|
||||
+ if (flags & BD_CRYPTO_INTEGRITY_OPEN_ALLOW_DISCARDS)
|
||||
+ activate_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
|
||||
+ if (flags & BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL_BITMAP) {
|
||||
+#ifndef CRYPT_ACTIVATE_NO_JOURNAL_BITMAP
|
||||
+ g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_TECH_UNAVAIL,
|
||||
+ "Cannot activate %s with bitmap, installed version of cryptsetup doesn't support this option.", device);
|
||||
+ bd_utils_report_finished (progress_id, (*error)->message);
|
||||
+ return FALSE;
|
||||
+#else
|
||||
+ activate_flags |= CRYPT_ACTIVATE_NO_JOURNAL_BITMAP;
|
||||
+#endif
|
||||
+ }
|
||||
+
|
||||
+ if (flags & BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE_RESET) {
|
||||
+#ifndef CRYPT_ACTIVATE_RECALCULATE_RESET
|
||||
+ g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_TECH_UNAVAIL,
|
||||
+ "Cannot reset integrity recalculation while activating %s, installed version of cryptsetup doesn't support this option.", device);
|
||||
+ bd_utils_report_finished (progress_id, (*error)->message);
|
||||
+ return FALSE;
|
||||
+#else
|
||||
+ activate_flags |= CRYPT_ACTIVATE_RECALCULATE_RESET;
|
||||
+#endif
|
||||
+ }
|
||||
+
|
||||
msg = g_strdup_printf ("Started opening '%s' integrity device", device);
|
||||
progress_id = bd_utils_report_started (msg);
|
||||
g_free (msg);
|
||||
@@ -2258,7 +2290,7 @@ gboolean bd_crypto_integrity_open (const gchar *device, const gchar *name, const
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
- ret = crypt_activate_by_volume_key (cd, name, (const char *) key_data, key_size, flags);
|
||||
+ ret = crypt_activate_by_volume_key (cd, name, (const char *) key_data, key_size, activate_flags);
|
||||
if (ret < 0) {
|
||||
g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE,
|
||||
"Failed to activate device: %s", strerror_l (-ret, c_locale));
|
||||
diff --git a/src/plugins/crypto.h b/src/plugins/crypto.h
|
||||
index 166e558..b5f133c 100644
|
||||
--- a/src/plugins/crypto.h
|
||||
+++ b/src/plugins/crypto.h
|
||||
@@ -141,16 +141,12 @@ BDCryptoIntegrityExtra* bd_crypto_integrity_extra_copy (BDCryptoIntegrityExtra *
|
||||
BDCryptoIntegrityExtra* bd_crypto_integrity_extra_new (guint64 sector_size, guint64 journal_size, guint journal_watermark, guint journal_commit_time, guint64 interleave_sectors, guint64 tag_size, guint64 buffer_sectors);
|
||||
|
||||
typedef enum {
|
||||
- BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL = CRYPT_ACTIVATE_NO_JOURNAL,
|
||||
- BD_CRYPTO_INTEGRITY_OPEN_RECOVERY = CRYPT_ACTIVATE_RECOVERY,
|
||||
-#ifdef CRYPT_ACTIVATE_NO_JOURNAL_BITMAP
|
||||
- BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL_BITMAP = CRYPT_ACTIVATE_NO_JOURNAL_BITMAP,
|
||||
-#endif
|
||||
- BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE = CRYPT_ACTIVATE_RECALCULATE,
|
||||
-#ifdef CRYPT_ACTIVATE_RECALCULATE_RESET
|
||||
- BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE_RESET = CRYPT_ACTIVATE_RECALCULATE_RESET,
|
||||
-#endif
|
||||
- BD_CRYPTO_INTEGRITY_OPEN_ALLOW_DISCARDS = CRYPT_ACTIVATE_ALLOW_DISCARDS,
|
||||
+ BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL = 1 << 0,
|
||||
+ BD_CRYPTO_INTEGRITY_OPEN_RECOVERY = 1 << 1,
|
||||
+ BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL_BITMAP = 1 << 2,
|
||||
+ BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE = 1 << 3,
|
||||
+ BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE_RESET = 1 << 4,
|
||||
+ BD_CRYPTO_INTEGRITY_OPEN_ALLOW_DISCARDS = 1 << 5,
|
||||
} BDCryptoIntegrityOpenFlags;
|
||||
|
||||
/**
|
||||
diff --git a/tests/crypto_test.py b/tests/crypto_test.py
|
||||
index b7ec251..673d8b8 100644
|
||||
--- a/tests/crypto_test.py
|
||||
+++ b/tests/crypto_test.py
|
||||
@@ -1215,6 +1215,20 @@ class CryptoTestIntegrity(CryptoTestCase):
|
||||
self.assertTrue(succ)
|
||||
self.assertFalse(os.path.exists("/dev/mapper/%s" % self._dm_name))
|
||||
|
||||
+ # open with flags
|
||||
+ succ = BlockDev.crypto_integrity_open(self.loop_dev, self._dm_name, "crc32c",
|
||||
+ flags=BlockDev.CryptoIntegrityOpenFlags.ALLOW_DISCARDS)
|
||||
+ self.assertTrue(succ)
|
||||
+ self.assertTrue(os.path.exists("/dev/mapper/%s" % self._dm_name))
|
||||
+
|
||||
+ # check that discard is enabled for the mapped device
|
||||
+ _ret, out, _err = run_command("dmsetup table %s" % self._dm_name)
|
||||
+ self.assertIn("allow_discards", out)
|
||||
+
|
||||
+ succ = BlockDev.crypto_integrity_close(self._dm_name)
|
||||
+ self.assertTrue(succ)
|
||||
+ self.assertFalse(os.path.exists("/dev/mapper/%s" % self._dm_name))
|
||||
+
|
||||
@tag_test(TestTags.SLOW)
|
||||
@unittest.skipUnless(HAVE_LUKS2, "Integrity not supported")
|
||||
def test_integrity_wipe(self):
|
||||
--
|
||||
2.31.1
|
||||
|
@ -125,7 +125,7 @@
|
||||
|
||||
Name: libblockdev
|
||||
Version: 2.25
|
||||
Release: 9%{?dist}
|
||||
Release: 10%{?dist}
|
||||
Summary: A library for low-level manipulation with block devices
|
||||
License: LGPLv2+
|
||||
URL: https://github.com/storaged-project/libblockdev
|
||||
@ -138,6 +138,9 @@ Patch4: 0004-Adapt-to-dosfstools-4.2-changes.patch
|
||||
Patch5: 0005-Add-workarounds-for-some-LVM-test-issues.patch
|
||||
Patch6: 0006-Misc-test-fixes-backport.patch
|
||||
Patch7: 0007-lvm-devices-file-support.patch
|
||||
Patch8: 0008-lvm-Fix-reading-statistics-for-VDO-pools-with-VDO-8.patch
|
||||
Patch9: 0009-vdo_stats-Default-to-100-savings-for-invalid-savings.patch
|
||||
Patch10: 0010-Add-support-for-creating-and-activating-integrity-de.patch
|
||||
|
||||
BuildRequires: make
|
||||
BuildRequires: glib2-devel
|
||||
@ -697,6 +700,9 @@ A meta-package that pulls all the libblockdev plugins as dependencies.
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
%patch10 -p1
|
||||
|
||||
%build
|
||||
autoreconf -ivf
|
||||
@ -1000,6 +1006,14 @@ find %{buildroot} -type f -name "*.la" | xargs %{__rm}
|
||||
%files plugins-all
|
||||
|
||||
%changelog
|
||||
* Wed Dec 08 2021 Vojtech Trefny <vtrefny@redhat.com> - 2.25-10
|
||||
- Fix reading statistics for VDO pools with VDO 8
|
||||
Resolves: rhbz#1994220
|
||||
- vdo_stats: Default to 100 % savings for invalid savings values
|
||||
Resolves: rhbz#2025880
|
||||
- Add support for creating and unlocking standalone integrity devices
|
||||
Resolves: rhbz#2011365
|
||||
|
||||
* Tue Nov 30 2021 Vojtech Trefny <vtrefny@redhat.com> - 2.25-9
|
||||
- Fix patch for 'Add support LVM devices file management'
|
||||
Resolves: rhbz#1983705
|
||||
|
Loading…
Reference in New Issue
Block a user