Blame 0010-Add-support-for-creating-and-activating-integrity-de.patch

Vojtech Trefny 22b10e
From 37f1aff5f5f967d6a4440d176f3de877aab789ac Mon Sep 17 00:00:00 2001
Vojtech Trefny 22b10e
From: Vojtech Trefny <vtrefny@redhat.com>
Vojtech Trefny 22b10e
Date: Mon, 20 Sep 2021 16:38:16 +0200
Vojtech Trefny 22b10e
Subject: [PATCH 1/3] Add support for creating and activating integrity devices
Vojtech Trefny 22b10e
Vojtech Trefny 22b10e
This adds support for create, open and close actions for standalone
Vojtech Trefny 22b10e
integrity devices using cryptsetup.
Vojtech Trefny 22b10e
---
Vojtech Trefny 22b10e
 configure.ac                        |   4 +-
Vojtech Trefny 22b10e
 src/lib/plugin_apis/crypto.api      | 157 +++++++++++++++++
Vojtech Trefny 22b10e
 src/plugins/crypto.c                | 261 +++++++++++++++++++++++++++-
Vojtech Trefny 22b10e
 src/plugins/crypto.h                |  41 +++++
Vojtech Trefny 22b10e
 src/python/gi/overrides/BlockDev.py |  24 +++
Vojtech Trefny 22b10e
 tests/crypto_test.py                |  97 ++++++++++-
Vojtech Trefny 22b10e
 6 files changed, 576 insertions(+), 8 deletions(-)
Vojtech Trefny 22b10e
Vojtech Trefny 22b10e
diff --git a/configure.ac b/configure.ac
Vojtech Trefny 22b10e
index abe1412..13830ae 100644
Vojtech Trefny 22b10e
--- a/configure.ac
Vojtech Trefny 22b10e
+++ b/configure.ac
Vojtech Trefny 22b10e
@@ -210,7 +210,9 @@ AS_IF([test "x$with_crypto" != "xno"],
Vojtech Trefny 22b10e
       AS_IF([$PKG_CONFIG --atleast-version=2.0.3 libcryptsetup],
Vojtech Trefny 22b10e
             [AC_DEFINE([LIBCRYPTSETUP_2])], [])
Vojtech Trefny 22b10e
       AS_IF([$PKG_CONFIG --atleast-version=2.3.0 libcryptsetup],
Vojtech Trefny 22b10e
-            [AC_DEFINE([LIBCRYPTSETUP_BITLK])], [])
Vojtech Trefny 22b10e
+            [AC_DEFINE([LIBCRYPTSETUP_23])], [])
Vojtech Trefny 22b10e
+      AS_IF([$PKG_CONFIG --atleast-version=2.4.0 libcryptsetup],
Vojtech Trefny 22b10e
+            [AC_DEFINE([LIBCRYPTSETUP_24])], [])
Vojtech Trefny 22b10e
       AS_IF([test "x$with_escrow" != "xno"],
Vojtech Trefny 22b10e
             [LIBBLOCKDEV_PKG_CHECK_MODULES([NSS], [nss >= 3.18.0])
Vojtech Trefny 22b10e
              LIBBLOCKDEV_CHECK_HEADER([volume_key/libvolume_key.h], [$GLIB_CFLAGS $NSS_CFLAGS], [libvolume_key.h not available])],
Vojtech Trefny 22b10e
diff --git a/src/lib/plugin_apis/crypto.api b/src/lib/plugin_apis/crypto.api
Vojtech Trefny 22b10e
index ef0217f..40e32c8 100644
Vojtech Trefny 22b10e
--- a/src/lib/plugin_apis/crypto.api
Vojtech Trefny 22b10e
+++ b/src/lib/plugin_apis/crypto.api
Vojtech Trefny 22b10e
@@ -1,5 +1,6 @@
Vojtech Trefny 22b10e
 #include <glib.h>
Vojtech Trefny 22b10e
 #include <blockdev/utils.h>
Vojtech Trefny 22b10e
+#include <libcryptsetup.h>
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
 #define BD_CRYPTO_LUKS_METADATA_SIZE G_GUINT64_CONSTANT (2097152ULL) // 2 MiB
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
@@ -245,6 +246,115 @@ GType bd_crypto_luks_extra_get_type () {
Vojtech Trefny 22b10e
     return type;
Vojtech Trefny 22b10e
 }
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
+#define BD_CRYPTO_TYPE_INTEGRITY_EXTRA (bd_crypto_integrity_extra_get_type ())
Vojtech Trefny 22b10e
+GType bd_crypto_integrity_extra_get_type();
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+/**
Vojtech Trefny 22b10e
+ * BDCryptoIntegrityExtra:
Vojtech Trefny 22b10e
+ * @sector_size: integrity sector size
Vojtech Trefny 22b10e
+ * @journal_size: size of journal in bytes
Vojtech Trefny 22b10e
+ * @journal_watermark: journal flush watermark in percents; in bitmap mode sectors-per-bit
Vojtech Trefny 22b10e
+ * @journal_commit_time: journal commit time (or bitmap flush time) in ms
Vojtech Trefny 22b10e
+ * @interleave_sectors: number of interleave sectors (power of two)
Vojtech Trefny 22b10e
+ * @tag_size: tag size per-sector in bytes
Vojtech Trefny 22b10e
+ * @buffer_sectors: number of sectors in one buffer
Vojtech Trefny 22b10e
+ */
Vojtech Trefny 22b10e
+typedef struct BDCryptoIntegrityExtra {
Vojtech Trefny 22b10e
+    guint32 sector_size;
Vojtech Trefny 22b10e
+    guint64 journal_size;
Vojtech Trefny 22b10e
+    guint journal_watermark;
Vojtech Trefny 22b10e
+    guint journal_commit_time;
Vojtech Trefny 22b10e
+    guint32 interleave_sectors;
Vojtech Trefny 22b10e
+    guint32 tag_size;
Vojtech Trefny 22b10e
+    guint32 buffer_sectors;
Vojtech Trefny 22b10e
+} BDCryptoIntegrityExtra;
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+/**
Vojtech Trefny 22b10e
+ * bd_crypto_integrity_extra_copy: (skip)
Vojtech Trefny 22b10e
+ * @extra: (allow-none): %BDCryptoIntegrityExtra to copy
Vojtech Trefny 22b10e
+ *
Vojtech Trefny 22b10e
+ * Creates a new copy of @extra.
Vojtech Trefny 22b10e
+ */
Vojtech Trefny 22b10e
+BDCryptoIntegrityExtra* bd_crypto_integrity_extra_copy (BDCryptoIntegrityExtra *extra) {
Vojtech Trefny 22b10e
+    if (extra == NULL)
Vojtech Trefny 22b10e
+        return NULL;
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    BDCryptoIntegrityExtra *new_extra = g_new0 (BDCryptoIntegrityExtra, 1);
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    new_extra->sector_size = extra->sector_size;
Vojtech Trefny 22b10e
+    new_extra->journal_size = extra->journal_size;
Vojtech Trefny 22b10e
+    new_extra->journal_watermark = extra->journal_watermark;
Vojtech Trefny 22b10e
+    new_extra->journal_commit_time = extra->journal_commit_time;
Vojtech Trefny 22b10e
+    new_extra->interleave_sectors = extra->interleave_sectors;
Vojtech Trefny 22b10e
+    new_extra->tag_size = extra->tag_size;
Vojtech Trefny 22b10e
+    new_extra->buffer_sectors = extra->buffer_sectors;
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    return new_extra;
Vojtech Trefny 22b10e
+}
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+/**
Vojtech Trefny 22b10e
+ * bd_crypto_integrity_extra_free: (skip)
Vojtech Trefny 22b10e
+ * @extra: (allow-none): %BDCryptoIntegrityExtra to free
Vojtech Trefny 22b10e
+ *
Vojtech Trefny 22b10e
+ * Frees @extra.
Vojtech Trefny 22b10e
+ */
Vojtech Trefny 22b10e
+void bd_crypto_integrity_extra_free (BDCryptoIntegrityExtra *extra) {
Vojtech Trefny 22b10e
+    if (extra == NULL)
Vojtech Trefny 22b10e
+        return;
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    g_free (extra);
Vojtech Trefny 22b10e
+}
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+/**
Vojtech Trefny 22b10e
+ * bd_crypto_integrity_extra_new: (constructor)
Vojtech Trefny 22b10e
+ * @sector_size: integrity sector size, 0 for default (512)
Vojtech Trefny 22b10e
+ * @journal_size: size of journal in bytes
Vojtech Trefny 22b10e
+ * @journal_watermark: journal flush watermark in percents; in bitmap mode sectors-per-bit
Vojtech Trefny 22b10e
+ * @journal_commit_time: journal commit time (or bitmap flush time) in ms
Vojtech Trefny 22b10e
+ * @interleave_sectors: number of interleave sectors (power of two)
Vojtech Trefny 22b10e
+ * @tag_size: tag size per-sector in bytes
Vojtech Trefny 22b10e
+ * @buffer_sectors: number of sectors in one buffer
Vojtech Trefny 22b10e
+ *
Vojtech Trefny 22b10e
+ * Returns: (transfer full): a new Integrity extra argument
Vojtech Trefny 22b10e
+ */
Vojtech Trefny 22b10e
+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) {
Vojtech Trefny 22b10e
+    BDCryptoIntegrityExtra *ret = g_new0 (BDCryptoIntegrityExtra, 1);
Vojtech Trefny 22b10e
+    ret->sector_size = sector_size;
Vojtech Trefny 22b10e
+    ret->journal_size = journal_size;
Vojtech Trefny 22b10e
+    ret->journal_watermark = journal_watermark;
Vojtech Trefny 22b10e
+    ret->journal_commit_time = journal_commit_time;
Vojtech Trefny 22b10e
+    ret->interleave_sectors = interleave_sectors;
Vojtech Trefny 22b10e
+    ret->tag_size = tag_size;
Vojtech Trefny 22b10e
+    ret->buffer_sectors = buffer_sectors;
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    return ret;
Vojtech Trefny 22b10e
+}
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+GType bd_crypto_integrity_extra_get_type () {
Vojtech Trefny 22b10e
+    static GType type = 0;
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    if (G_UNLIKELY(type == 0)) {
Vojtech Trefny 22b10e
+        type = g_boxed_type_register_static("BDCryptoIntegrityExtra",
Vojtech Trefny 22b10e
+                                            (GBoxedCopyFunc) bd_crypto_integrity_extra_copy,
Vojtech Trefny 22b10e
+                                            (GBoxedFreeFunc) bd_crypto_integrity_extra_free);
Vojtech Trefny 22b10e
+    }
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    return type;
Vojtech Trefny 22b10e
+}
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+typedef enum {
Vojtech Trefny 22b10e
+    BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL         = CRYPT_ACTIVATE_NO_JOURNAL,
Vojtech Trefny 22b10e
+    BD_CRYPTO_INTEGRITY_OPEN_RECOVERY           = CRYPT_ACTIVATE_RECOVERY,
Vojtech Trefny 22b10e
+#ifdef CRYPT_ACTIVATE_NO_JOURNAL_BITMAP
Vojtech Trefny 22b10e
+    BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL_BITMAP  = CRYPT_ACTIVATE_NO_JOURNAL_BITMAP,
Vojtech Trefny 22b10e
+#endif
Vojtech Trefny 22b10e
+    BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE        = CRYPT_ACTIVATE_RECALCULATE,
Vojtech Trefny 22b10e
+#ifdef CRYPT_ACTIVATE_RECALCULATE_RESET
Vojtech Trefny 22b10e
+    BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE_RESET  = CRYPT_ACTIVATE_RECALCULATE_RESET,
Vojtech Trefny 22b10e
+#endif
Vojtech Trefny 22b10e
+    BD_CRYPTO_INTEGRITY_OPEN_ALLOW_DISCARDS     = CRYPT_ACTIVATE_ALLOW_DISCARDS,
Vojtech Trefny 22b10e
+} BDCryptoIntegrityOpenFlags;
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
 #define BD_CRYPTO_TYPE_LUKS_INFO (bd_crypto_luks_info_get_type ())
Vojtech Trefny 22b10e
 GType bd_crypto_luks_info_get_type();
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
@@ -857,6 +967,53 @@ BDCryptoLUKSInfo* bd_crypto_luks_info (const gchar *luks_device, GError **error)
Vojtech Trefny 22b10e
  */
Vojtech Trefny 22b10e
 BDCryptoIntegrityInfo* bd_crypto_integrity_info (const gchar *device, GError **error);
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
+/**
Vojtech Trefny 22b10e
+ * bd_crypto_integrity_format:
Vojtech Trefny 22b10e
+ * @device: a device to format as integrity
Vojtech Trefny 22b10e
+ * @algorithm: integrity algorithm specification (e.g. "crc32c" or "sha256") or %NULL to use the default
Vojtech Trefny 22b10e
+ * @wipe: whether to wipe the device after format; a device that is not initially wiped will contain invalid checksums
Vojtech Trefny 22b10e
+ * @key_data: (allow-none) (array length=key_size): integrity key or %NULL if not needed
Vojtech Trefny 22b10e
+ * @key_size: size the integrity key and @key_data
Vojtech Trefny 22b10e
+ * @extra: (allow-none): extra arguments for integrity format creation
Vojtech Trefny 22b10e
+ * @error: (out): place to store error (if any)
Vojtech Trefny 22b10e
+ *
Vojtech Trefny 22b10e
+ * Formats the given @device as integrity according to the other parameters given.
Vojtech Trefny 22b10e
+ *
Vojtech Trefny 22b10e
+ * Returns: whether the given @device was successfully formatted as integrity or not
Vojtech Trefny 22b10e
+ * (the @error) contains the error in such cases)
Vojtech Trefny 22b10e
+ *
Vojtech Trefny 22b10e
+ * Tech category: %BD_CRYPTO_TECH_INTEGRITY-%BD_CRYPTO_TECH_MODE_CREATE
Vojtech Trefny 22b10e
+ */
Vojtech Trefny 22b10e
+gboolean bd_crypto_integrity_format (const gchar *device, const gchar *algorithm, gboolean wipe, const guint8* key_data, gsize key_size, BDCryptoIntegrityExtra *extra, GError **error);
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+/**
Vojtech Trefny 22b10e
+ * bd_crypto_integrity_open:
Vojtech Trefny 22b10e
+ * @device: integrity device to open
Vojtech Trefny 22b10e
+ * @name: name for the opened @device
Vojtech Trefny 22b10e
+ * @algorithm: (allow-none): integrity algorithm specification (e.g. "crc32c" or "sha256") or %NULL to use the default
Vojtech Trefny 22b10e
+ * @key_data: (allow-none) (array length=key_size): integrity key or %NULL if not needed
Vojtech Trefny 22b10e
+ * @key_size: size the integrity key and @key_data
Vojtech Trefny 22b10e
+ * @flags: flags for the integrity device activation
Vojtech Trefny 22b10e
+ * @extra: (allow-none): extra arguments for integrity open
Vojtech Trefny 22b10e
+ * @error: (out): place to store error (if any)
Vojtech Trefny 22b10e
+ *
Vojtech Trefny 22b10e
+ * Returns: whether the @device was successfully opened or not
Vojtech Trefny 22b10e
+ *
Vojtech Trefny 22b10e
+ * Tech category: %BD_CRYPTO_TECH_INTEGRITY-%BD_CRYPTO_TECH_MODE_OPEN_CLOSE
Vojtech Trefny 22b10e
+ */
Vojtech Trefny 22b10e
+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);
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+/**
Vojtech Trefny 22b10e
+ * bd_crypto_integrity_close:
Vojtech Trefny 22b10e
+ * @integrity_device: integrity device to close
Vojtech Trefny 22b10e
+ * @error: (out): place to store error (if any)
Vojtech Trefny 22b10e
+ *
Vojtech Trefny 22b10e
+ * Returns: whether the given @integrity_device was successfully closed or not
Vojtech Trefny 22b10e
+ *
Vojtech Trefny 22b10e
+ * Tech category: %BD_CRYPTO_TECH_INTEGRITY-%BD_CRYPTO_TECH_MODE_OPEN_CLOSE
Vojtech Trefny 22b10e
+ */
Vojtech Trefny 22b10e
+gboolean bd_crypto_integrity_close (const gchar *integrity_device, GError **error);
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
 /**
Vojtech Trefny 22b10e
  * bd_crypto_device_seems_encrypted:
Vojtech Trefny 22b10e
  * @device: the queried device
Vojtech Trefny 22b10e
diff --git a/src/plugins/crypto.c b/src/plugins/crypto.c
Vojtech Trefny 22b10e
index 4fad9a8..b1b0700 100644
Vojtech Trefny 22b10e
--- a/src/plugins/crypto.c
Vojtech Trefny 22b10e
+++ b/src/plugins/crypto.c
Vojtech Trefny 22b10e
@@ -50,6 +50,18 @@
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
 #define SECTOR_SIZE 512
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
+#define DEFAULT_LUKS_KEYSIZE_BITS 256
Vojtech Trefny 22b10e
+#define DEFAULT_LUKS_CIPHER "aes-xts-plain64"
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+#ifdef LIBCRYPTSETUP_23
Vojtech Trefny 22b10e
+/* 0 for autodetect since 2.3.0 */
Vojtech Trefny 22b10e
+#define DEFAULT_INTEGRITY_TAG_SIZE 0
Vojtech Trefny 22b10e
+#else
Vojtech Trefny 22b10e
+/* we need some sane default for older versions, users should specify tag size when using
Vojtech Trefny 22b10e
+   other algorithms than the default crc32c */
Vojtech Trefny 22b10e
+#define DEFAULT_INTEGRITY_TAG_SIZE 4
Vojtech Trefny 22b10e
+#endif
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
 #define UNUSED __attribute__((unused))
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
 /**
Vojtech Trefny 22b10e
@@ -146,6 +158,43 @@ BDCryptoLUKSExtra* bd_crypto_luks_extra_new (guint64 data_alignment, const gchar
Vojtech Trefny 22b10e
     return ret;
Vojtech Trefny 22b10e
 }
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
+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) {
Vojtech Trefny 22b10e
+    BDCryptoIntegrityExtra *ret = g_new0 (BDCryptoIntegrityExtra, 1);
Vojtech Trefny 22b10e
+    ret->sector_size = sector_size;
Vojtech Trefny 22b10e
+    ret->journal_size = journal_size;
Vojtech Trefny 22b10e
+    ret->journal_watermark = journal_watermark;
Vojtech Trefny 22b10e
+    ret->journal_commit_time = journal_commit_time;
Vojtech Trefny 22b10e
+    ret->interleave_sectors = interleave_sectors;
Vojtech Trefny 22b10e
+    ret->tag_size = tag_size;
Vojtech Trefny 22b10e
+    ret->buffer_sectors = buffer_sectors;
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    return ret;
Vojtech Trefny 22b10e
+}
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+BDCryptoIntegrityExtra* bd_crypto_integrity_extra_copy (BDCryptoIntegrityExtra *extra) {
Vojtech Trefny 22b10e
+    if (extra == NULL)
Vojtech Trefny 22b10e
+        return NULL;
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    BDCryptoIntegrityExtra *new_extra = g_new0 (BDCryptoIntegrityExtra, 1);
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    new_extra->sector_size = extra->sector_size;
Vojtech Trefny 22b10e
+    new_extra->journal_size = extra->journal_size;
Vojtech Trefny 22b10e
+    new_extra->journal_watermark = extra->journal_watermark;
Vojtech Trefny 22b10e
+    new_extra->journal_commit_time = extra->journal_commit_time;
Vojtech Trefny 22b10e
+    new_extra->interleave_sectors = extra->interleave_sectors;
Vojtech Trefny 22b10e
+    new_extra->tag_size = extra->tag_size;
Vojtech Trefny 22b10e
+    new_extra->buffer_sectors = extra->buffer_sectors;
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    return new_extra;
Vojtech Trefny 22b10e
+}
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+void bd_crypto_integrity_extra_free (BDCryptoIntegrityExtra *extra) {
Vojtech Trefny 22b10e
+    if (extra == NULL)
Vojtech Trefny 22b10e
+        return;
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    g_free (extra);
Vojtech Trefny 22b10e
+}
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
 void bd_crypto_luks_info_free (BDCryptoLUKSInfo *info) {
Vojtech Trefny 22b10e
     if (info == NULL)
Vojtech Trefny 22b10e
         return;
Vojtech Trefny 22b10e
@@ -346,15 +395,15 @@ gboolean bd_crypto_is_tech_avail (BDCryptoTech tech, guint64 mode, GError **erro
Vojtech Trefny 22b10e
                          "Integrity technology requires libcryptsetup >= 2.0");
Vojtech Trefny 22b10e
             return FALSE;
Vojtech Trefny 22b10e
 #endif
Vojtech Trefny 22b10e
-            ret = mode & (BD_CRYPTO_TECH_MODE_QUERY);
Vojtech Trefny 22b10e
+            ret = mode & (BD_CRYPTO_TECH_MODE_CREATE|BD_CRYPTO_TECH_MODE_OPEN_CLOSE|BD_CRYPTO_TECH_MODE_QUERY);
Vojtech Trefny 22b10e
             if (ret != mode) {
Vojtech Trefny 22b10e
                 g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_TECH_UNAVAIL,
Vojtech Trefny 22b10e
-                             "Only 'query' supported for Integrity");
Vojtech Trefny 22b10e
+                             "Only 'create', 'open' and 'query' supported for Integrity");
Vojtech Trefny 22b10e
                 return FALSE;
Vojtech Trefny 22b10e
             } else
Vojtech Trefny 22b10e
                 return TRUE;
Vojtech Trefny 22b10e
         case BD_CRYPTO_TECH_BITLK:
Vojtech Trefny 22b10e
-#ifndef LIBCRYPTSETUP_BITLK
Vojtech Trefny 22b10e
+#ifndef LIBCRYPTSETUP_23
Vojtech Trefny 22b10e
             g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_TECH_UNAVAIL,
Vojtech Trefny 22b10e
                          "BITLK technology requires libcryptsetup >= 2.3.0");
Vojtech Trefny 22b10e
             return FALSE;
Vojtech Trefny 22b10e
@@ -2035,6 +2084,208 @@ BDCryptoIntegrityInfo* bd_crypto_integrity_info (const gchar *device, GError **e
Vojtech Trefny 22b10e
 }
Vojtech Trefny 22b10e
 #endif
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
+static int _wipe_progress (guint64 size, guint64 offset, void *usrptr) {
Vojtech Trefny 22b10e
+    /* "convert" the progress from 0-100 to 50-100 because wipe starts at 50 in bd_crypto_integrity_format */
Vojtech Trefny 22b10e
+    gdouble progress = 50 + (((gdouble) offset / size) * 100) / 2;
Vojtech Trefny 22b10e
+    bd_utils_report_progress (*(guint64 *) usrptr, progress, "Integrity device wipe in progress");
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    return 0;
Vojtech Trefny 22b10e
+}
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+/**
Vojtech Trefny 22b10e
+ * bd_crypto_integrity_format:
Vojtech Trefny 22b10e
+ * @device: a device to format as integrity
Vojtech Trefny 22b10e
+ * @algorithm: integrity algorithm specification (e.g. "crc32c" or "sha256")
Vojtech Trefny 22b10e
+ * @wipe: whether to wipe the device after format; a device that is not initially wiped will contain invalid checksums
Vojtech Trefny 22b10e
+ * @key_data: (allow-none) (array length=key_size): integrity key or %NULL if not needed
Vojtech Trefny 22b10e
+ * @key_size: size the integrity key and @key_data
Vojtech Trefny 22b10e
+ * @extra: (allow-none): extra arguments for integrity format creation
Vojtech Trefny 22b10e
+ * @error: (out): place to store error (if any)
Vojtech Trefny 22b10e
+ *
Vojtech Trefny 22b10e
+ * Formats the given @device as integrity according to the other parameters given.
Vojtech Trefny 22b10e
+ *
Vojtech Trefny 22b10e
+ * Returns: whether the given @device was successfully formatted as integrity or not
Vojtech Trefny 22b10e
+ * (the @error) contains the error in such cases)
Vojtech Trefny 22b10e
+ *
Vojtech Trefny 22b10e
+ * Tech category: %BD_CRYPTO_TECH_INTEGRITY-%BD_CRYPTO_TECH_MODE_CREATE
Vojtech Trefny 22b10e
+ */
Vojtech Trefny 22b10e
+gboolean bd_crypto_integrity_format (const gchar *device, const gchar *algorithm, gboolean wipe, const guint8* key_data, gsize key_size, BDCryptoIntegrityExtra *extra, GError **error) {
Vojtech Trefny 22b10e
+    struct crypt_device *cd = NULL;
Vojtech Trefny 22b10e
+    gint ret;
Vojtech Trefny 22b10e
+    guint64 progress_id = 0;
Vojtech Trefny 22b10e
+    gchar *msg = NULL;
Vojtech Trefny 22b10e
+    struct crypt_params_integrity params = ZERO_INIT;
Vojtech Trefny 22b10e
+    g_autofree gchar *tmp_name = NULL;
Vojtech Trefny 22b10e
+    g_autofree gchar *tmp_path = NULL;
Vojtech Trefny 22b10e
+    g_autofree gchar *dev_name = NULL;
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    msg = g_strdup_printf ("Started formatting '%s' as integrity device", device);
Vojtech Trefny 22b10e
+    progress_id = bd_utils_report_started (msg);
Vojtech Trefny 22b10e
+    g_free (msg);
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    ret = crypt_init (&cd, device);
Vojtech Trefny 22b10e
+    if (ret != 0) {
Vojtech Trefny 22b10e
+        g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE,
Vojtech Trefny 22b10e
+                     "Failed to initialize device: %s", strerror_l (-ret, c_locale));
Vojtech Trefny 22b10e
+        bd_utils_report_finished (progress_id, (*error)->message);
Vojtech Trefny 22b10e
+        return FALSE;
Vojtech Trefny 22b10e
+    }
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    if (extra) {
Vojtech Trefny 22b10e
+        params.sector_size = extra->sector_size;
Vojtech Trefny 22b10e
+        params.journal_size = extra->journal_size;
Vojtech Trefny 22b10e
+        params.journal_watermark = extra->journal_watermark;
Vojtech Trefny 22b10e
+        params.journal_commit_time = extra->journal_commit_time;
Vojtech Trefny 22b10e
+        params.interleave_sectors = extra->interleave_sectors;
Vojtech Trefny 22b10e
+        params.tag_size = extra->tag_size;
Vojtech Trefny 22b10e
+        params.buffer_sectors = extra->buffer_sectors;
Vojtech Trefny 22b10e
+    }
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    params.integrity_key_size = key_size;
Vojtech Trefny 22b10e
+    params.integrity = algorithm;
Vojtech Trefny 22b10e
+    params.tag_size = params.tag_size ? params.tag_size : DEFAULT_INTEGRITY_TAG_SIZE;
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    ret = crypt_format (cd, CRYPT_INTEGRITY, NULL, NULL, NULL, NULL, 0, &params);
Vojtech Trefny 22b10e
+    if (ret != 0) {
Vojtech Trefny 22b10e
+        g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_FORMAT_FAILED,
Vojtech Trefny 22b10e
+                     "Failed to format device: %s", strerror_l (-ret, c_locale));
Vojtech Trefny 22b10e
+        crypt_free (cd);
Vojtech Trefny 22b10e
+        bd_utils_report_finished (progress_id, (*error)->message);
Vojtech Trefny 22b10e
+        return FALSE;
Vojtech Trefny 22b10e
+    }
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    if (wipe) {
Vojtech Trefny 22b10e
+        bd_utils_report_progress (progress_id, 50, "Format created");
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        dev_name = g_path_get_basename (device);
Vojtech Trefny 22b10e
+        tmp_name = g_strdup_printf ("bd-temp-integrity-%s-%d", dev_name, g_random_int ());
Vojtech Trefny 22b10e
+        tmp_path = g_strdup_printf ("%s/%s", crypt_get_dir (), tmp_name);
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        ret = crypt_activate_by_volume_key (cd, tmp_name, (const char *) key_data, key_size,
Vojtech Trefny 22b10e
+                                            CRYPT_ACTIVATE_PRIVATE | CRYPT_ACTIVATE_NO_JOURNAL);
Vojtech Trefny 22b10e
+        if (ret != 0) {
Vojtech Trefny 22b10e
+            g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE,
Vojtech Trefny 22b10e
+                         "Failed to activate the newly created integrity device for wiping: %s",
Vojtech Trefny 22b10e
+                         strerror_l (-ret, c_locale));
Vojtech Trefny 22b10e
+            crypt_free (cd);
Vojtech Trefny 22b10e
+            bd_utils_report_finished (progress_id, (*error)->message);
Vojtech Trefny 22b10e
+            return FALSE;
Vojtech Trefny 22b10e
+        }
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        bd_utils_report_progress (progress_id, 50, "Starting to wipe the newly created integrity device");
Vojtech Trefny 22b10e
+        ret = crypt_wipe (cd, tmp_path, CRYPT_WIPE_ZERO, 0, 0, 1048576,
Vojtech Trefny 22b10e
+                          0, &_wipe_progress, &progress_id);
Vojtech Trefny 22b10e
+        bd_utils_report_progress (progress_id, 100, "Wipe finished");
Vojtech Trefny 22b10e
+        if (ret != 0) {
Vojtech Trefny 22b10e
+            g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE,
Vojtech Trefny 22b10e
+                         "Failed to wipe the newly created integrity device: %s",
Vojtech Trefny 22b10e
+                         strerror_l (-ret, c_locale));
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+            ret = crypt_deactivate (cd, tmp_name);
Vojtech Trefny 22b10e
+            if (ret != 0)
Vojtech Trefny 22b10e
+                g_warning ("Failed to deactivate temporary device %s", tmp_name);
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+            crypt_free (cd);
Vojtech Trefny 22b10e
+            bd_utils_report_finished (progress_id, (*error)->message);
Vojtech Trefny 22b10e
+            return FALSE;
Vojtech Trefny 22b10e
+        }
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        ret = crypt_deactivate (cd, tmp_name);
Vojtech Trefny 22b10e
+        if (ret != 0)
Vojtech Trefny 22b10e
+            g_warning ("Failed to deactivate temporary device %s", tmp_name);
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    } else
Vojtech Trefny 22b10e
+        bd_utils_report_finished (progress_id, "Completed");
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    crypt_free (cd);
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    return TRUE;
Vojtech Trefny 22b10e
+}
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+/**
Vojtech Trefny 22b10e
+ * bd_crypto_integrity_open:
Vojtech Trefny 22b10e
+ * @device: integrity device to open
Vojtech Trefny 22b10e
+ * @name: name for the opened @device
Vojtech Trefny 22b10e
+ * @algorithm: (allow-none): integrity algorithm specification (e.g. "crc32c" or "sha256") or %NULL to use the default
Vojtech Trefny 22b10e
+ * @key_data: (allow-none) (array length=key_size): integrity key or %NULL if not needed
Vojtech Trefny 22b10e
+ * @key_size: size the integrity key and @key_data
Vojtech Trefny 22b10e
+ * @flags: flags for the integrity device activation
Vojtech Trefny 22b10e
+ * @extra: (allow-none): extra arguments for integrity open
Vojtech Trefny 22b10e
+ * @error: (out): place to store error (if any)
Vojtech Trefny 22b10e
+ *
Vojtech Trefny 22b10e
+ * Returns: whether the @device was successfully opened or not
Vojtech Trefny 22b10e
+ *
Vojtech Trefny 22b10e
+ * Tech category: %BD_CRYPTO_TECH_INTEGRITY-%BD_CRYPTO_TECH_MODE_OPEN_CLOSE
Vojtech Trefny 22b10e
+ */
Vojtech Trefny 22b10e
+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) {
Vojtech Trefny 22b10e
+    struct crypt_device *cd = NULL;
Vojtech Trefny 22b10e
+    gint ret = 0;
Vojtech Trefny 22b10e
+    guint64 progress_id = 0;
Vojtech Trefny 22b10e
+    gchar *msg = NULL;
Vojtech Trefny 22b10e
+    struct crypt_params_integrity params = ZERO_INIT;
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    params.integrity = algorithm;
Vojtech Trefny 22b10e
+    params.integrity_key_size = key_size;
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    if (extra) {
Vojtech Trefny 22b10e
+        params.sector_size = extra->sector_size;
Vojtech Trefny 22b10e
+        params.journal_size = extra->journal_size;
Vojtech Trefny 22b10e
+        params.journal_watermark = extra->journal_watermark;
Vojtech Trefny 22b10e
+        params.journal_commit_time = extra->journal_commit_time;
Vojtech Trefny 22b10e
+        params.interleave_sectors = extra->interleave_sectors;
Vojtech Trefny 22b10e
+        params.tag_size = extra->tag_size;
Vojtech Trefny 22b10e
+        params.buffer_sectors = extra->buffer_sectors;
Vojtech Trefny 22b10e
+    }
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    msg = g_strdup_printf ("Started opening '%s' integrity device", device);
Vojtech Trefny 22b10e
+    progress_id = bd_utils_report_started (msg);
Vojtech Trefny 22b10e
+    g_free (msg);
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    ret = crypt_init (&cd, device);
Vojtech Trefny 22b10e
+    if (ret != 0) {
Vojtech Trefny 22b10e
+        g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE,
Vojtech Trefny 22b10e
+                     "Failed to initialize device: %s", strerror_l (-ret, c_locale));
Vojtech Trefny 22b10e
+        bd_utils_report_finished (progress_id, (*error)->message);
Vojtech Trefny 22b10e
+        return FALSE;
Vojtech Trefny 22b10e
+    }
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    ret = crypt_load (cd, CRYPT_INTEGRITY, &params);
Vojtech Trefny 22b10e
+    if (ret != 0) {
Vojtech Trefny 22b10e
+        g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE,
Vojtech Trefny 22b10e
+                     "Failed to load device's parameters: %s", strerror_l (-ret, c_locale));
Vojtech Trefny 22b10e
+        crypt_free (cd);
Vojtech Trefny 22b10e
+        bd_utils_report_finished (progress_id, (*error)->message);
Vojtech Trefny 22b10e
+        return FALSE;
Vojtech Trefny 22b10e
+    }
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    ret = crypt_activate_by_volume_key (cd, name, (const char *) key_data, key_size, flags);
Vojtech Trefny 22b10e
+    if (ret < 0) {
Vojtech Trefny 22b10e
+        g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE,
Vojtech Trefny 22b10e
+                     "Failed to activate device: %s", strerror_l (-ret, c_locale));
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        crypt_free (cd);
Vojtech Trefny 22b10e
+        bd_utils_report_finished (progress_id, (*error)->message);
Vojtech Trefny 22b10e
+        return FALSE;
Vojtech Trefny 22b10e
+    }
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    crypt_free (cd);
Vojtech Trefny 22b10e
+    bd_utils_report_finished (progress_id, "Completed");
Vojtech Trefny 22b10e
+    return TRUE;
Vojtech Trefny 22b10e
+}
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+/**
Vojtech Trefny 22b10e
+ * bd_crypto_integrity_close:
Vojtech Trefny 22b10e
+ * @integrity_device: integrity device to close
Vojtech Trefny 22b10e
+ * @error: (out): place to store error (if any)
Vojtech Trefny 22b10e
+ *
Vojtech Trefny 22b10e
+ * Returns: whether the given @integrity_device was successfully closed or not
Vojtech Trefny 22b10e
+ *
Vojtech Trefny 22b10e
+ * Tech category: %BD_CRYPTO_TECH_INTEGRITY-%BD_CRYPTO_TECH_MODE_OPEN_CLOSE
Vojtech Trefny 22b10e
+ */
Vojtech Trefny 22b10e
+gboolean bd_crypto_integrity_close (const gchar *integrity_device, GError **error) {
Vojtech Trefny 22b10e
+    return _crypto_close (integrity_device, "integrity", error);
Vojtech Trefny 22b10e
+}
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
 /**
Vojtech Trefny 22b10e
  * bd_crypto_device_seems_encrypted:
Vojtech Trefny 22b10e
  * @device: the queried device
Vojtech Trefny 22b10e
@@ -2472,7 +2723,7 @@ gboolean bd_crypto_escrow_device (const gchar *device, const gchar *passphrase,
Vojtech Trefny 22b10e
  *
Vojtech Trefny 22b10e
  * Tech category: %BD_CRYPTO_TECH_BITLK-%BD_CRYPTO_TECH_MODE_OPEN_CLOSE
Vojtech Trefny 22b10e
  */
Vojtech Trefny 22b10e
-#ifndef LIBCRYPTSETUP_BITLK
Vojtech Trefny 22b10e
+#ifndef LIBCRYPTSETUP_23
Vojtech Trefny 22b10e
 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) {
Vojtech Trefny 22b10e
     /* this will return FALSE and set error, because BITLK technology is not available */
Vojtech Trefny 22b10e
     return bd_crypto_is_tech_avail (BD_CRYPTO_TECH_BITLK, BD_CRYPTO_TECH_MODE_OPEN_CLOSE, error);
Vojtech Trefny 22b10e
@@ -2542,7 +2793,7 @@ gboolean bd_crypto_bitlk_open (const gchar *device, const gchar *name, const gui
Vojtech Trefny 22b10e
  *
Vojtech Trefny 22b10e
  * Tech category: %BD_CRYPTO_TECH_BITLK-%BD_CRYPTO_TECH_MODE_OPEN_CLOSE
Vojtech Trefny 22b10e
  */
Vojtech Trefny 22b10e
-#ifndef LIBCRYPTSETUP_BITLK
Vojtech Trefny 22b10e
+#ifndef LIBCRYPTSETUP_23
Vojtech Trefny 22b10e
 gboolean bd_crypto_bitlk_close (const gchar *bitlk_device UNUSED, GError **error) {
Vojtech Trefny 22b10e
     /* this will return FALSE and set error, because BITLK technology is not available */
Vojtech Trefny 22b10e
     return bd_crypto_is_tech_avail (BD_CRYPTO_TECH_BITLK, BD_CRYPTO_TECH_MODE_OPEN_CLOSE, error);
Vojtech Trefny 22b10e
diff --git a/src/plugins/crypto.h b/src/plugins/crypto.h
Vojtech Trefny 22b10e
index a38724d..166e558 100644
Vojtech Trefny 22b10e
--- a/src/plugins/crypto.h
Vojtech Trefny 22b10e
+++ b/src/plugins/crypto.h
Vojtech Trefny 22b10e
@@ -116,6 +116,43 @@ void bd_crypto_luks_extra_free (BDCryptoLUKSExtra *extra);
Vojtech Trefny 22b10e
 BDCryptoLUKSExtra* bd_crypto_luks_extra_copy (BDCryptoLUKSExtra *extra);
Vojtech Trefny 22b10e
 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);
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
+/**
Vojtech Trefny 22b10e
+ * BDCryptoIntegrityExtra:
Vojtech Trefny 22b10e
+ * @sector_size: integrity sector size
Vojtech Trefny 22b10e
+ * @journal_size: size of journal in bytes
Vojtech Trefny 22b10e
+ * @journal_watermark: journal flush watermark in percents; in bitmap mode sectors-per-bit
Vojtech Trefny 22b10e
+ * @journal_commit_time: journal commit time (or bitmap flush time) in ms
Vojtech Trefny 22b10e
+ * @interleave_sectors: number of interleave sectors (power of two)
Vojtech Trefny 22b10e
+ * @tag_size: tag size per-sector in bytes
Vojtech Trefny 22b10e
+ * @buffer_sectors: number of sectors in one buffer
Vojtech Trefny 22b10e
+ */
Vojtech Trefny 22b10e
+typedef struct BDCryptoIntegrityExtra {
Vojtech Trefny 22b10e
+    guint32 sector_size;
Vojtech Trefny 22b10e
+    guint64 journal_size;
Vojtech Trefny 22b10e
+    guint journal_watermark;
Vojtech Trefny 22b10e
+    guint journal_commit_time;
Vojtech Trefny 22b10e
+    guint32 interleave_sectors;
Vojtech Trefny 22b10e
+    guint32 tag_size;
Vojtech Trefny 22b10e
+    guint32 buffer_sectors;
Vojtech Trefny 22b10e
+} BDCryptoIntegrityExtra;
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+void bd_crypto_integrity_extra_free (BDCryptoIntegrityExtra *extra);
Vojtech Trefny 22b10e
+BDCryptoIntegrityExtra* bd_crypto_integrity_extra_copy (BDCryptoIntegrityExtra *extra);
Vojtech Trefny 22b10e
+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);
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+typedef enum {
Vojtech Trefny 22b10e
+    BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL         = CRYPT_ACTIVATE_NO_JOURNAL,
Vojtech Trefny 22b10e
+    BD_CRYPTO_INTEGRITY_OPEN_RECOVERY           = CRYPT_ACTIVATE_RECOVERY,
Vojtech Trefny 22b10e
+#ifdef CRYPT_ACTIVATE_NO_JOURNAL_BITMAP
Vojtech Trefny 22b10e
+    BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL_BITMAP  = CRYPT_ACTIVATE_NO_JOURNAL_BITMAP,
Vojtech Trefny 22b10e
+#endif
Vojtech Trefny 22b10e
+    BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE        = CRYPT_ACTIVATE_RECALCULATE,
Vojtech Trefny 22b10e
+#ifdef CRYPT_ACTIVATE_RECALCULATE_RESET
Vojtech Trefny 22b10e
+    BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE_RESET  = CRYPT_ACTIVATE_RECALCULATE_RESET,
Vojtech Trefny 22b10e
+#endif
Vojtech Trefny 22b10e
+    BD_CRYPTO_INTEGRITY_OPEN_ALLOW_DISCARDS     = CRYPT_ACTIVATE_ALLOW_DISCARDS,
Vojtech Trefny 22b10e
+} BDCryptoIntegrityOpenFlags;
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
 /**
Vojtech Trefny 22b10e
  * BDCryptoLUKSInfo:
Vojtech Trefny 22b10e
  * @version: LUKS version
Vojtech Trefny 22b10e
@@ -209,6 +246,10 @@ gboolean bd_crypto_luks_header_restore (const gchar *device, const gchar *backup
Vojtech Trefny 22b10e
 BDCryptoLUKSInfo* bd_crypto_luks_info (const gchar *luks_device, GError **error);
Vojtech Trefny 22b10e
 BDCryptoIntegrityInfo* bd_crypto_integrity_info (const gchar *device, GError **error);
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
+gboolean bd_crypto_integrity_format (const gchar *device, const gchar *algorithm, gboolean wipe, const guint8* key_data, gsize key_size, BDCryptoIntegrityExtra *extra, GError **error);
Vojtech Trefny 22b10e
+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);
Vojtech Trefny 22b10e
+gboolean bd_crypto_integrity_close (const gchar *integrity_device, GError **error);
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
 gboolean bd_crypto_device_seems_encrypted (const gchar *device, GError **error);
Vojtech Trefny 22b10e
 gboolean bd_crypto_tc_open (const gchar *device, const gchar *name, const guint8* pass_data, gsize data_len, gboolean read_only, GError **error);
Vojtech Trefny 22b10e
 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);
Vojtech Trefny 22b10e
diff --git a/src/python/gi/overrides/BlockDev.py b/src/python/gi/overrides/BlockDev.py
Vojtech Trefny 22b10e
index 715a262..71bcd31 100644
Vojtech Trefny 22b10e
--- a/src/python/gi/overrides/BlockDev.py
Vojtech Trefny 22b10e
+++ b/src/python/gi/overrides/BlockDev.py
Vojtech Trefny 22b10e
@@ -276,6 +276,30 @@ def crypto_bitlk_open(device, name, passphrase, read_only=False):
Vojtech Trefny 22b10e
 __all__.append("crypto_bitlk_open")
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
+class CryptoIntegrityExtra(BlockDev.CryptoIntegrityExtra):
Vojtech Trefny 22b10e
+    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):
Vojtech Trefny 22b10e
+        ret = BlockDev.CryptoIntegrityExtra.new(sector_size, journal_size, journal_watermark, journal_commit_time, interleave_sectors, tag_size, buffer_sectors)
Vojtech Trefny 22b10e
+        ret.__class__ = cls
Vojtech Trefny 22b10e
+        return ret
Vojtech Trefny 22b10e
+    def __init__(self, *args, **kwargs):   # pylint: disable=unused-argument
Vojtech Trefny 22b10e
+        super(CryptoIntegrityExtra, self).__init__()  #pylint: disable=bad-super-call
Vojtech Trefny 22b10e
+CryptoIntegrityExtra = override(CryptoIntegrityExtra)
Vojtech Trefny 22b10e
+__all__.append("CryptoIntegrityExtra")
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+_crypto_integrity_format = BlockDev.crypto_integrity_format
Vojtech Trefny 22b10e
+@override(BlockDev.crypto_integrity_format)
Vojtech Trefny 22b10e
+def crypto_integrity_format(device, algorithm=None, wipe=True, key_data=None, extra=None):
Vojtech Trefny 22b10e
+    return _crypto_integrity_format(device, algorithm, wipe, key_data, extra)
Vojtech Trefny 22b10e
+__all__.append("crypto_integrity_format")
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+_crypto_integrity_open = BlockDev.crypto_integrity_open
Vojtech Trefny 22b10e
+@override(BlockDev.crypto_integrity_open)
Vojtech Trefny 22b10e
+def crypto_integrity_open(device, name, algorithm, key_data=None, flags=0, extra=None):
Vojtech Trefny 22b10e
+    return _crypto_integrity_open(device, name, algorithm, key_data, flags, extra)
Vojtech Trefny 22b10e
+__all__.append("crypto_integrity_open")
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
 _dm_create_linear = BlockDev.dm_create_linear
Vojtech Trefny 22b10e
 @override(BlockDev.dm_create_linear)
Vojtech Trefny 22b10e
 def dm_create_linear(map_name, device, length, uuid=None):
Vojtech Trefny 22b10e
diff --git a/tests/crypto_test.py b/tests/crypto_test.py
Vojtech Trefny 22b10e
index 0aecc03..1c6832e 100644
Vojtech Trefny 22b10e
--- a/tests/crypto_test.py
Vojtech Trefny 22b10e
+++ b/tests/crypto_test.py
Vojtech Trefny 22b10e
@@ -2,6 +2,7 @@ import unittest
Vojtech Trefny 22b10e
 import os
Vojtech Trefny 22b10e
 import tempfile
Vojtech Trefny 22b10e
 import overrides_hack
Vojtech Trefny 22b10e
+import secrets
Vojtech Trefny 22b10e
 import shutil
Vojtech Trefny 22b10e
 import subprocess
Vojtech Trefny 22b10e
 import six
Vojtech Trefny 22b10e
@@ -42,6 +43,8 @@ class CryptoTestCase(unittest.TestCase):
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
     requested_plugins = BlockDev.plugin_specs_from_names(("crypto", "loop"))
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
+    _dm_name = "libblockdevTestLUKS"
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
     @classmethod
Vojtech Trefny 22b10e
     def setUpClass(cls):
Vojtech Trefny 22b10e
         unittest.TestCase.setUpClass()
Vojtech Trefny 22b10e
@@ -72,7 +75,7 @@ class CryptoTestCase(unittest.TestCase):
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
     def _clean_up(self):
Vojtech Trefny 22b10e
         try:
Vojtech Trefny 22b10e
-            BlockDev.crypto_luks_close("libblockdevTestLUKS")
Vojtech Trefny 22b10e
+            BlockDev.crypto_luks_close(self._dm_name)
Vojtech Trefny 22b10e
         except:
Vojtech Trefny 22b10e
             pass
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
@@ -964,7 +967,8 @@ class CryptoTestInfo(CryptoTestCase):
Vojtech Trefny 22b10e
         succ = BlockDev.crypto_luks_close("libblockdevTestLUKS")
Vojtech Trefny 22b10e
         self.assertTrue(succ)
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
-class CryptoTestIntegrity(CryptoTestCase):
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+class CryptoTestLUKS2Integrity(CryptoTestCase):
Vojtech Trefny 22b10e
     @tag_test(TestTags.SLOW)
Vojtech Trefny 22b10e
     @unittest.skipUnless(HAVE_LUKS2, "LUKS 2 not supported")
Vojtech Trefny 22b10e
     def test_luks2_integrity(self):
Vojtech Trefny 22b10e
@@ -1151,3 +1155,92 @@ class CryptoTestBitlk(CryptoTestCase):
Vojtech Trefny 22b10e
         succ = BlockDev.crypto_bitlk_close("libblockdevTestBitlk")
Vojtech Trefny 22b10e
         self.assertTrue(succ)
Vojtech Trefny 22b10e
         self.assertFalse(os.path.exists("/dev/mapper/libblockdevTestBitlk"))
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+class CryptoTestIntegrity(CryptoTestCase):
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    _dm_name = "libblockdevTestIntegrity"
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    @unittest.skipUnless(HAVE_LUKS2, "Integrity not supported")
Vojtech Trefny 22b10e
+    def test_integrity(self):
Vojtech Trefny 22b10e
+        # basic format+open+close test
Vojtech Trefny 22b10e
+        succ = BlockDev.crypto_integrity_format(self.loop_dev, "sha256", False)
Vojtech Trefny 22b10e
+        self.assertTrue(succ)
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        succ = BlockDev.crypto_integrity_open(self.loop_dev, self._dm_name, "sha256")
Vojtech Trefny 22b10e
+        self.assertTrue(succ)
Vojtech Trefny 22b10e
+        self.assertTrue(os.path.exists("/dev/mapper/%s" % self._dm_name))
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        info = BlockDev.crypto_integrity_info(self._dm_name)
Vojtech Trefny 22b10e
+        self.assertEqual(info.algorithm, "sha256")
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        succ = BlockDev.crypto_integrity_close(self._dm_name)
Vojtech Trefny 22b10e
+        self.assertTrue(succ)
Vojtech Trefny 22b10e
+        self.assertFalse(os.path.exists("/dev/mapper/%s" % self._dm_name))
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        # same now with a keyed algorithm
Vojtech Trefny 22b10e
+        key = list(secrets.token_bytes(64))
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        succ = BlockDev.crypto_integrity_format(self.loop_dev, "hmac(sha256)", False, key)
Vojtech Trefny 22b10e
+        self.assertTrue(succ)
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        succ = BlockDev.crypto_integrity_open(self.loop_dev, self._dm_name, "hmac(sha256)", key)
Vojtech Trefny 22b10e
+        self.assertTrue(succ)
Vojtech Trefny 22b10e
+        self.assertTrue(os.path.exists("/dev/mapper/%s" % self._dm_name))
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        info = BlockDev.crypto_integrity_info(self._dm_name)
Vojtech Trefny 22b10e
+        self.assertEqual(info.algorithm, "hmac(sha256)")
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        succ = BlockDev.crypto_integrity_close(self._dm_name)
Vojtech Trefny 22b10e
+        self.assertTrue(succ)
Vojtech Trefny 22b10e
+        self.assertFalse(os.path.exists("/dev/mapper/%s" % self._dm_name))
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        # same with some custom parameters
Vojtech Trefny 22b10e
+        extra = BlockDev.CryptoIntegrityExtra(sector_size=4096, interleave_sectors=65536)
Vojtech Trefny 22b10e
+        succ = BlockDev.crypto_integrity_format(self.loop_dev, "crc32c", wipe=False, extra=extra)
Vojtech Trefny 22b10e
+        self.assertTrue(succ)
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        succ = BlockDev.crypto_integrity_open(self.loop_dev, self._dm_name, "crc32c")
Vojtech Trefny 22b10e
+        self.assertTrue(succ)
Vojtech Trefny 22b10e
+        self.assertTrue(os.path.exists("/dev/mapper/%s" % self._dm_name))
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        info = BlockDev.crypto_integrity_info(self._dm_name)
Vojtech Trefny 22b10e
+        self.assertEqual(info.algorithm, "crc32c")
Vojtech Trefny 22b10e
+        self.assertEqual(info.sector_size, 4096)
Vojtech Trefny 22b10e
+        self.assertEqual(info.interleave_sectors, 65536)
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        succ = BlockDev.crypto_integrity_close(self._dm_name)
Vojtech Trefny 22b10e
+        self.assertTrue(succ)
Vojtech Trefny 22b10e
+        self.assertFalse(os.path.exists("/dev/mapper/%s" % self._dm_name))
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    @tag_test(TestTags.SLOW)
Vojtech Trefny 22b10e
+    @unittest.skipUnless(HAVE_LUKS2, "Integrity not supported")
Vojtech Trefny 22b10e
+    def test_integrity_wipe(self):
Vojtech Trefny 22b10e
+        # also check that wipe progress reporting works
Vojtech Trefny 22b10e
+        progress_log = []
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        def _my_progress_func(_task, _status, completion, msg):
Vojtech Trefny 22b10e
+            progress_log.append((completion, msg))
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        succ = BlockDev.utils_init_prog_reporting(_my_progress_func)
Vojtech Trefny 22b10e
+        self.assertTrue(succ)
Vojtech Trefny 22b10e
+        self.addCleanup(BlockDev.utils_init_prog_reporting, None)
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        succ = BlockDev.crypto_integrity_format(self.loop_dev, "sha256", True)
Vojtech Trefny 22b10e
+        self.assertTrue(succ)
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        # at least one message "Integrity device wipe in progress" should be logged
Vojtech Trefny 22b10e
+        self.assertTrue(any(prog[1] == "Integrity device wipe in progress" for prog in progress_log))
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        succ = BlockDev.crypto_integrity_open(self.loop_dev, self._dm_name, "sha256")
Vojtech Trefny 22b10e
+        self.assertTrue(succ)
Vojtech Trefny 22b10e
+        self.assertTrue(os.path.exists("/dev/mapper/%s" % self._dm_name))
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        # check the devices was wiped and the checksums recalculated
Vojtech Trefny 22b10e
+        # (mkfs reads some blocks first so without checksums it would fail)
Vojtech Trefny 22b10e
+        ret, _out, err = run_command("mkfs.ext2 /dev/mapper/%s " % self._dm_name)
Vojtech Trefny 22b10e
+        self.assertEqual(ret, 0, msg="Failed to create ext2 filesystem on integrity: %s" % err)
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        succ = BlockDev.crypto_integrity_close(self._dm_name)
Vojtech Trefny 22b10e
+        self.assertTrue(succ)
Vojtech Trefny 22b10e
+        self.assertFalse(os.path.exists("/dev/mapper/%s" % self._dm_name))
Vojtech Trefny 22b10e
-- 
Vojtech Trefny 22b10e
2.31.1
Vojtech Trefny 22b10e
Vojtech Trefny 22b10e
Vojtech Trefny 22b10e
From 4dcb7a42a2cb33f7a63021d72889c9a9688adfd3 Mon Sep 17 00:00:00 2001
Vojtech Trefny 22b10e
From: Vojtech Trefny <vtrefny@redhat.com>
Vojtech Trefny 22b10e
Date: Thu, 30 Sep 2021 16:01:40 +0200
Vojtech Trefny 22b10e
Subject: [PATCH 2/3] Create smaller test images for integrity tests
Vojtech Trefny 22b10e
Vojtech Trefny 22b10e
We are going to overwrite the entire device in test_integrity_wipe
Vojtech Trefny 22b10e
so we need to make sure the sparse actually fits to /tmp which
Vojtech Trefny 22b10e
can be smaller than 1 GiB.
Vojtech Trefny 22b10e
---
Vojtech Trefny 22b10e
 tests/crypto_test.py | 6 ++++--
Vojtech Trefny 22b10e
 1 file changed, 4 insertions(+), 2 deletions(-)
Vojtech Trefny 22b10e
Vojtech Trefny 22b10e
diff --git a/tests/crypto_test.py b/tests/crypto_test.py
Vojtech Trefny 22b10e
index 1c6832e..b7ec251 100644
Vojtech Trefny 22b10e
--- a/tests/crypto_test.py
Vojtech Trefny 22b10e
+++ b/tests/crypto_test.py
Vojtech Trefny 22b10e
@@ -44,6 +44,7 @@ class CryptoTestCase(unittest.TestCase):
Vojtech Trefny 22b10e
     requested_plugins = BlockDev.plugin_specs_from_names(("crypto", "loop"))
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
     _dm_name = "libblockdevTestLUKS"
Vojtech Trefny 22b10e
+    _sparse_size = 1024**3
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
     @classmethod
Vojtech Trefny 22b10e
     def setUpClass(cls):
Vojtech Trefny 22b10e
@@ -57,8 +58,8 @@ class CryptoTestCase(unittest.TestCase):
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
     def setUp(self):
Vojtech Trefny 22b10e
         self.addCleanup(self._clean_up)
Vojtech Trefny 22b10e
-        self.dev_file = create_sparse_tempfile("crypto_test", 1024**3)
Vojtech Trefny 22b10e
-        self.dev_file2 = create_sparse_tempfile("crypto_test2", 1024**3)
Vojtech Trefny 22b10e
+        self.dev_file = create_sparse_tempfile("crypto_test", self._sparse_size)
Vojtech Trefny 22b10e
+        self.dev_file2 = create_sparse_tempfile("crypto_test2", self._sparse_size)
Vojtech Trefny 22b10e
         try:
Vojtech Trefny 22b10e
             self.loop_dev = create_lio_device(self.dev_file)
Vojtech Trefny 22b10e
         except RuntimeError as e:
Vojtech Trefny 22b10e
@@ -1160,6 +1161,7 @@ class CryptoTestBitlk(CryptoTestCase):
Vojtech Trefny 22b10e
 class CryptoTestIntegrity(CryptoTestCase):
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
     _dm_name = "libblockdevTestIntegrity"
Vojtech Trefny 22b10e
+    _sparse_size = 100 * 1024**2
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
     @unittest.skipUnless(HAVE_LUKS2, "Integrity not supported")
Vojtech Trefny 22b10e
     def test_integrity(self):
Vojtech Trefny 22b10e
-- 
Vojtech Trefny 22b10e
2.31.1
Vojtech Trefny 22b10e
Vojtech Trefny 22b10e
Vojtech Trefny 22b10e
From 3b82f9085c0df2e58b673716cdefd747495738e2 Mon Sep 17 00:00:00 2001
Vojtech Trefny 22b10e
From: Vojtech Trefny <vtrefny@redhat.com>
Vojtech Trefny 22b10e
Date: Wed, 20 Oct 2021 10:27:41 +0200
Vojtech Trefny 22b10e
Subject: [PATCH 3/3] crypto: Do not use libcryptsetup flags directly in
Vojtech Trefny 22b10e
 crypto.h
Vojtech Trefny 22b10e
Vojtech Trefny 22b10e
We can "translate" our flags in the implementation instead to
Vojtech Trefny 22b10e
avoid including libcryptsetup.h in our header and API files.
Vojtech Trefny 22b10e
---
Vojtech Trefny 22b10e
 src/lib/plugin_apis/crypto.api | 17 ++++++-----------
Vojtech Trefny 22b10e
 src/plugins/crypto.c           | 34 +++++++++++++++++++++++++++++++++-
Vojtech Trefny 22b10e
 src/plugins/crypto.h           | 16 ++++++----------
Vojtech Trefny 22b10e
 tests/crypto_test.py           | 14 ++++++++++++++
Vojtech Trefny 22b10e
 4 files changed, 59 insertions(+), 22 deletions(-)
Vojtech Trefny 22b10e
Vojtech Trefny 22b10e
diff --git a/src/lib/plugin_apis/crypto.api b/src/lib/plugin_apis/crypto.api
Vojtech Trefny 22b10e
index 40e32c8..cf87979 100644
Vojtech Trefny 22b10e
--- a/src/lib/plugin_apis/crypto.api
Vojtech Trefny 22b10e
+++ b/src/lib/plugin_apis/crypto.api
Vojtech Trefny 22b10e
@@ -1,6 +1,5 @@
Vojtech Trefny 22b10e
 #include <glib.h>
Vojtech Trefny 22b10e
 #include <blockdev/utils.h>
Vojtech Trefny 22b10e
-#include <libcryptsetup.h>
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
 #define BD_CRYPTO_LUKS_METADATA_SIZE G_GUINT64_CONSTANT (2097152ULL) // 2 MiB
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
@@ -343,16 +342,12 @@ GType bd_crypto_integrity_extra_get_type () {
Vojtech Trefny 22b10e
 }
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
 typedef enum {
Vojtech Trefny 22b10e
-    BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL         = CRYPT_ACTIVATE_NO_JOURNAL,
Vojtech Trefny 22b10e
-    BD_CRYPTO_INTEGRITY_OPEN_RECOVERY           = CRYPT_ACTIVATE_RECOVERY,
Vojtech Trefny 22b10e
-#ifdef CRYPT_ACTIVATE_NO_JOURNAL_BITMAP
Vojtech Trefny 22b10e
-    BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL_BITMAP  = CRYPT_ACTIVATE_NO_JOURNAL_BITMAP,
Vojtech Trefny 22b10e
-#endif
Vojtech Trefny 22b10e
-    BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE        = CRYPT_ACTIVATE_RECALCULATE,
Vojtech Trefny 22b10e
-#ifdef CRYPT_ACTIVATE_RECALCULATE_RESET
Vojtech Trefny 22b10e
-    BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE_RESET  = CRYPT_ACTIVATE_RECALCULATE_RESET,
Vojtech Trefny 22b10e
-#endif
Vojtech Trefny 22b10e
-    BD_CRYPTO_INTEGRITY_OPEN_ALLOW_DISCARDS     = CRYPT_ACTIVATE_ALLOW_DISCARDS,
Vojtech Trefny 22b10e
+    BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL         = 1 << 0,
Vojtech Trefny 22b10e
+    BD_CRYPTO_INTEGRITY_OPEN_RECOVERY           = 1 << 1,
Vojtech Trefny 22b10e
+    BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL_BITMAP  = 1 << 2,
Vojtech Trefny 22b10e
+    BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE        = 1 << 3,
Vojtech Trefny 22b10e
+    BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE_RESET  = 1 << 4,
Vojtech Trefny 22b10e
+    BD_CRYPTO_INTEGRITY_OPEN_ALLOW_DISCARDS     = 1 << 5,
Vojtech Trefny 22b10e
 } BDCryptoIntegrityOpenFlags;
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
 #define BD_CRYPTO_TYPE_LUKS_INFO (bd_crypto_luks_info_get_type ())
Vojtech Trefny 22b10e
diff --git a/src/plugins/crypto.c b/src/plugins/crypto.c
Vojtech Trefny 22b10e
index b1b0700..8a4d64a 100644
Vojtech Trefny 22b10e
--- a/src/plugins/crypto.c
Vojtech Trefny 22b10e
+++ b/src/plugins/crypto.c
Vojtech Trefny 22b10e
@@ -2223,6 +2223,7 @@ gboolean bd_crypto_integrity_open (const gchar *device, const gchar *name, const
Vojtech Trefny 22b10e
     guint64 progress_id = 0;
Vojtech Trefny 22b10e
     gchar *msg = NULL;
Vojtech Trefny 22b10e
     struct crypt_params_integrity params = ZERO_INIT;
Vojtech Trefny 22b10e
+    guint32 activate_flags = 0;
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
     params.integrity = algorithm;
Vojtech Trefny 22b10e
     params.integrity_key_size = key_size;
Vojtech Trefny 22b10e
@@ -2237,6 +2238,37 @@ gboolean bd_crypto_integrity_open (const gchar *device, const gchar *name, const
Vojtech Trefny 22b10e
         params.buffer_sectors = extra->buffer_sectors;
Vojtech Trefny 22b10e
     }
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    if (flags & BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL)
Vojtech Trefny 22b10e
+        activate_flags |= CRYPT_ACTIVATE_NO_JOURNAL;
Vojtech Trefny 22b10e
+    if (flags & BD_CRYPTO_INTEGRITY_OPEN_RECOVERY)
Vojtech Trefny 22b10e
+        activate_flags |= CRYPT_ACTIVATE_RECOVERY;
Vojtech Trefny 22b10e
+    if (flags & BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE)
Vojtech Trefny 22b10e
+        activate_flags |= CRYPT_ACTIVATE_RECALCULATE;
Vojtech Trefny 22b10e
+    if (flags & BD_CRYPTO_INTEGRITY_OPEN_ALLOW_DISCARDS)
Vojtech Trefny 22b10e
+        activate_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
Vojtech Trefny 22b10e
+    if (flags & BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL_BITMAP) {
Vojtech Trefny 22b10e
+#ifndef CRYPT_ACTIVATE_NO_JOURNAL_BITMAP
Vojtech Trefny 22b10e
+        g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_TECH_UNAVAIL,
Vojtech Trefny 22b10e
+                     "Cannot activate %s with bitmap, installed version of cryptsetup doesn't support this option.", device);
Vojtech Trefny 22b10e
+        bd_utils_report_finished (progress_id, (*error)->message);
Vojtech Trefny 22b10e
+        return FALSE;
Vojtech Trefny 22b10e
+#else
Vojtech Trefny 22b10e
+        activate_flags |= CRYPT_ACTIVATE_NO_JOURNAL_BITMAP;
Vojtech Trefny 22b10e
+#endif
Vojtech Trefny 22b10e
+    }
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+    if (flags & BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE_RESET) {
Vojtech Trefny 22b10e
+#ifndef CRYPT_ACTIVATE_RECALCULATE_RESET
Vojtech Trefny 22b10e
+        g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_TECH_UNAVAIL,
Vojtech Trefny 22b10e
+                     "Cannot reset integrity recalculation while activating %s, installed version of cryptsetup doesn't support this option.", device);
Vojtech Trefny 22b10e
+        bd_utils_report_finished (progress_id, (*error)->message);
Vojtech Trefny 22b10e
+        return FALSE;
Vojtech Trefny 22b10e
+#else
Vojtech Trefny 22b10e
+        activate_flags |= CRYPT_ACTIVATE_RECALCULATE_RESET;
Vojtech Trefny 22b10e
+#endif
Vojtech Trefny 22b10e
+    }
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
     msg = g_strdup_printf ("Started opening '%s' integrity device", device);
Vojtech Trefny 22b10e
     progress_id = bd_utils_report_started (msg);
Vojtech Trefny 22b10e
     g_free (msg);
Vojtech Trefny 22b10e
@@ -2258,7 +2290,7 @@ gboolean bd_crypto_integrity_open (const gchar *device, const gchar *name, const
Vojtech Trefny 22b10e
         return FALSE;
Vojtech Trefny 22b10e
     }
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
-    ret = crypt_activate_by_volume_key (cd, name, (const char *) key_data, key_size, flags);
Vojtech Trefny 22b10e
+    ret = crypt_activate_by_volume_key (cd, name, (const char *) key_data, key_size, activate_flags);
Vojtech Trefny 22b10e
     if (ret < 0) {
Vojtech Trefny 22b10e
         g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE,
Vojtech Trefny 22b10e
                      "Failed to activate device: %s", strerror_l (-ret, c_locale));
Vojtech Trefny 22b10e
diff --git a/src/plugins/crypto.h b/src/plugins/crypto.h
Vojtech Trefny 22b10e
index 166e558..b5f133c 100644
Vojtech Trefny 22b10e
--- a/src/plugins/crypto.h
Vojtech Trefny 22b10e
+++ b/src/plugins/crypto.h
Vojtech Trefny 22b10e
@@ -141,16 +141,12 @@ BDCryptoIntegrityExtra* bd_crypto_integrity_extra_copy (BDCryptoIntegrityExtra *
Vojtech Trefny 22b10e
 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);
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
 typedef enum {
Vojtech Trefny 22b10e
-    BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL         = CRYPT_ACTIVATE_NO_JOURNAL,
Vojtech Trefny 22b10e
-    BD_CRYPTO_INTEGRITY_OPEN_RECOVERY           = CRYPT_ACTIVATE_RECOVERY,
Vojtech Trefny 22b10e
-#ifdef CRYPT_ACTIVATE_NO_JOURNAL_BITMAP
Vojtech Trefny 22b10e
-    BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL_BITMAP  = CRYPT_ACTIVATE_NO_JOURNAL_BITMAP,
Vojtech Trefny 22b10e
-#endif
Vojtech Trefny 22b10e
-    BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE        = CRYPT_ACTIVATE_RECALCULATE,
Vojtech Trefny 22b10e
-#ifdef CRYPT_ACTIVATE_RECALCULATE_RESET
Vojtech Trefny 22b10e
-    BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE_RESET  = CRYPT_ACTIVATE_RECALCULATE_RESET,
Vojtech Trefny 22b10e
-#endif
Vojtech Trefny 22b10e
-    BD_CRYPTO_INTEGRITY_OPEN_ALLOW_DISCARDS     = CRYPT_ACTIVATE_ALLOW_DISCARDS,
Vojtech Trefny 22b10e
+    BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL         = 1 << 0,
Vojtech Trefny 22b10e
+    BD_CRYPTO_INTEGRITY_OPEN_RECOVERY           = 1 << 1,
Vojtech Trefny 22b10e
+    BD_CRYPTO_INTEGRITY_OPEN_NO_JOURNAL_BITMAP  = 1 << 2,
Vojtech Trefny 22b10e
+    BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE        = 1 << 3,
Vojtech Trefny 22b10e
+    BD_CRYPTO_INTEGRITY_OPEN_RECALCULATE_RESET  = 1 << 4,
Vojtech Trefny 22b10e
+    BD_CRYPTO_INTEGRITY_OPEN_ALLOW_DISCARDS     = 1 << 5,
Vojtech Trefny 22b10e
 } BDCryptoIntegrityOpenFlags;
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
 /**
Vojtech Trefny 22b10e
diff --git a/tests/crypto_test.py b/tests/crypto_test.py
Vojtech Trefny 22b10e
index b7ec251..673d8b8 100644
Vojtech Trefny 22b10e
--- a/tests/crypto_test.py
Vojtech Trefny 22b10e
+++ b/tests/crypto_test.py
Vojtech Trefny 22b10e
@@ -1215,6 +1215,20 @@ class CryptoTestIntegrity(CryptoTestCase):
Vojtech Trefny 22b10e
         self.assertTrue(succ)
Vojtech Trefny 22b10e
         self.assertFalse(os.path.exists("/dev/mapper/%s" % self._dm_name))
Vojtech Trefny 22b10e
 
Vojtech Trefny 22b10e
+        # open with flags
Vojtech Trefny 22b10e
+        succ = BlockDev.crypto_integrity_open(self.loop_dev, self._dm_name, "crc32c",
Vojtech Trefny 22b10e
+                                              flags=BlockDev.CryptoIntegrityOpenFlags.ALLOW_DISCARDS)
Vojtech Trefny 22b10e
+        self.assertTrue(succ)
Vojtech Trefny 22b10e
+        self.assertTrue(os.path.exists("/dev/mapper/%s" % self._dm_name))
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        # check that discard is enabled for the mapped device
Vojtech Trefny 22b10e
+        _ret, out, _err = run_command("dmsetup table %s" % self._dm_name)
Vojtech Trefny 22b10e
+        self.assertIn("allow_discards", out)
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
+        succ = BlockDev.crypto_integrity_close(self._dm_name)
Vojtech Trefny 22b10e
+        self.assertTrue(succ)
Vojtech Trefny 22b10e
+        self.assertFalse(os.path.exists("/dev/mapper/%s" % self._dm_name))
Vojtech Trefny 22b10e
+
Vojtech Trefny 22b10e
     @tag_test(TestTags.SLOW)
Vojtech Trefny 22b10e
     @unittest.skipUnless(HAVE_LUKS2, "Integrity not supported")
Vojtech Trefny 22b10e
     def test_integrity_wipe(self):
Vojtech Trefny 22b10e
-- 
Vojtech Trefny 22b10e
2.31.1
Vojtech Trefny 22b10e