integritysetup: add recalculate-reset flag.

The new dm-integrity option in kernel 5.13 can restart
recalculation from the beginning of the device.
It can be used to change the integrity checksum function.

This patch adds support to libcryptsetup for this flag
and adds --integrity-recalculate-rest option to integritysetup.

Fixes: #631.
This commit is contained in:
Milan Broz
2021-03-30 21:39:52 +02:00
parent 530bcfd4fa
commit ec3a9746a9
8 changed files with 44 additions and 2 deletions

View File

@@ -1122,6 +1122,8 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot);
#define CRYPT_ACTIVATE_NO_READ_WORKQUEUE (1 << 24)
/** dm-crypt: bypass internal workqueue and process write requests synchronously. */
#define CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE (1 << 25)
/** dm-integrity: reset automatic recalculation */
#define CRYPT_ACTIVATE_RECALCULATE_RESET (1 << 26)
/**
* Active device runtime attributes

View File

@@ -235,6 +235,9 @@ static void _dm_set_integrity_compat(struct crypt_device *cd,
if (_dm_satisfies_version(1, 7, 0, integrity_maj, integrity_min, integrity_patch))
_dm_flags |= DM_INTEGRITY_FIX_HMAC_SUPPORTED;
if (_dm_satisfies_version(1, 8, 0, integrity_maj, integrity_min, integrity_patch))
_dm_flags |= DM_INTEGRITY_RESET_RECALC_SUPPORTED;
_dm_integrity_checked = true;
}
@@ -927,6 +930,12 @@ static char *get_dm_integrity_params(const struct dm_target *tgt, uint32_t flags
strncat(features, feature, sizeof(features) - strlen(features) - 1);
}
if (flags & CRYPT_ACTIVATE_RECALCULATE_RESET) {
num_options++;
snprintf(feature, sizeof(feature), "reset_recalculate ");
strncat(features, feature, sizeof(features) - strlen(features) - 1);
}
if (flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) {
num_options++;
snprintf(feature, sizeof(feature), "allow_discards ");
@@ -1700,6 +1709,10 @@ int dm_create_device(struct crypt_device *cd, const char *name,
!(dmt_flags & DM_INTEGRITY_RECALC_SUPPORTED))
log_err(cd, _("Requested automatic recalculation of integrity tags is not supported."));
if (r == -EINVAL && dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_RECALCULATE_RESET) &&
!(dmt_flags & DM_INTEGRITY_RESET_RECALC_SUPPORTED))
log_err(cd, _("Requested automatic recalculation of integrity tags is not supported."));
if (r == -EINVAL && dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
!(dmt_flags & DM_INTEGRITY_DISCARDS_SUPPORTED))
log_err(cd, _("Discard/TRIM is not supported."));
@@ -2481,6 +2494,8 @@ static int _dm_target_query_integrity(struct crypt_device *cd,
}
} else if (!strcmp(arg, "recalculate")) {
*act_flags |= CRYPT_ACTIVATE_RECALCULATE;
} else if (!strcmp(arg, "reset_recalculate")) {
*act_flags |= CRYPT_ACTIVATE_RECALCULATE_RESET;
} else if (!strcmp(arg, "fix_padding")) {
tgt->u.integrity.fix_padding = true;
} else if (!strcmp(arg, "fix_hmac")) {

View File

@@ -73,6 +73,7 @@ static inline uint32_t act2dmflags(uint32_t act_flags)
#define DM_VERITY_PANIC_CORRUPTION_SUPPORTED (1 << 24) /* dm-verity panic on corruption */
#define DM_CRYPT_NO_WORKQUEUE_SUPPORTED (1 << 25) /* dm-crypt suppot for bypassing workqueues */
#define DM_INTEGRITY_FIX_HMAC_SUPPORTED (1 << 26) /* hmac covers also superblock */
#define DM_INTEGRITY_RESET_RECALC_SUPPORTED (1 << 27) /* dm-integrity automatic recalculation supported */
typedef enum { DM_CRYPT = 0, DM_VERITY, DM_INTEGRITY, DM_LINEAR, DM_ERROR, DM_ZERO, DM_UNKNOWN } dm_target_type;
enum tdirection { TARGET_SET = 1, TARGET_QUERY };

View File

@@ -33,7 +33,7 @@ Open a mapping with <name> backed by device <device>.
\fB<options>\fR can be [\-\-data\-device, \-\-batch\-mode, \-\-journal\-watermark,
\-\-journal\-commit\-time, \-\-buffer\-sectors, \-\-integrity, \-\-integrity\-key\-size,
\-\-integrity\-key\-file, \-\-integrity\-no\-journal, \-\-integrity\-recalculate,
\-\-integrity\-recovery\-mode, \-\-allow\-discards]
\-\-integrity\-recalculate-reset,\-\-integrity\-recovery\-mode, \-\-allow\-discards]
.PP
\fIclose\fR <name>
@@ -87,6 +87,12 @@ The device can be used during automatic integrity recalculation but becomes full
integrity protected only after the background operation is finished.
This option is available since the Linux kernel version 4.19.
.TP
.B "\-\-integrity\-recalculate\-reset"
Restart recalculation from the beginning of the device.
It can be used to change the integrity checksum function.
Note it does not change the tag length.
This option is available since the Linux kernel version 5.13.
.TP
.B "\-\-journal\-watermark PERCENT"
Journal watermark in percents. When the size of the journal exceeds this watermark,
the journal flush will be started.

View File

@@ -263,6 +263,9 @@ static int action_open(void)
if (ARG_SET(OPT_INTEGRITY_RECALCULATE_ID) || ARG_SET(OPT_INTEGRITY_LEGACY_RECALC_ID))
activate_flags |= CRYPT_ACTIVATE_RECALCULATE;
if (ARG_SET(OPT_INTEGRITY_RECALCULATE_RESET_ID))
activate_flags |= CRYPT_ACTIVATE_RECALCULATE_RESET;
if (ARG_SET(OPT_ALLOW_DISCARDS_ID))
activate_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;

View File

@@ -81,6 +81,8 @@ ARG(OPT_INTEGRITY_BITMAP_MODE, 'B', POPT_ARG_NONE, N_("Use bitmap to track chang
ARG(OPT_INTEGRITY_RECALCULATE, '\0', POPT_ARG_NONE, N_("Recalculate initial tags automatically."), NULL, CRYPT_ARG_BOOL, {}, OPT_INTEGRITY_RECALCULATE_ACTIONS)
ARG(OPT_INTEGRITY_RECALCULATE_RESET, '\0', POPT_ARG_NONE, N_("Reset automatic recalculate position."), NULL, CRYPT_ARG_BOOL, {}, OPT_INTEGRITY_RECALCULATE_ACTIONS)
ARG(OPT_INTEGRITY_RECOVERY_MODE, 'R', POPT_ARG_NONE, N_("Recovery mode (no journal, no tag checking)"), NULL, CRYPT_ARG_BOOL, {}, {})
ARG(OPT_SECTOR_SIZE, 's', POPT_ARG_STRING, N_("Sector size"), N_("bytes"), CRYPT_ARG_UINT32, { .u32_value = 512 }, OPT_SECTOR_SIZE_ACTIONS)

View File

@@ -70,6 +70,7 @@
#define OPT_INTEGRITY_NO_JOURNAL "integrity-no-journal"
#define OPT_INTEGRITY_NO_WIPE "integrity-no-wipe"
#define OPT_INTEGRITY_RECALCULATE "integrity-recalculate"
#define OPT_INTEGRITY_RECALCULATE_RESET "integrity-recalculate-reset"
#define OPT_INTEGRITY_RECOVERY_MODE "integrity-recovery-mode"
#define OPT_INTERLEAVE_SECTORS "interleave-sectors"
#define OPT_ITER_TIME "iter-time"

View File

@@ -64,6 +64,9 @@ function dm_integrity_features()
[ $VER_MIN -gt 6 ] && {
DM_INTEGRITY_HMAC_FIX=1
}
[ $VER_MIN -gt 7 ] && {
DM_INTEGRITY_RESET=1
}
}
add_device() {
@@ -383,7 +386,16 @@ if [ -n "$DM_INTEGRITY_RECALC" ] ; then
dd if=/dev/mapper/$DEV_NAME of=/dev/null bs=1M 2>/dev/null || fail "Cannot recalculate tags in-kernel"
int_check_sum_only 08f63eb27fb9ce2ce903b0a56429c68ce5e209253ba42154841ef045a53839d7
$INTSETUP close $DEV_NAME || fail "Cannot deactivate device."
echo "[OK]"
echo -n "[OK]"
if [ -n "$DM_INTEGRITY_RESET" ] ; then
$INTSETUP open $DEV $DEV_NAME -I sha256 --integrity-recalculate-reset || fail "Cannot activate device."
dd if=/dev/mapper/$DEV_NAME of=/dev/null bs=1M 2>/dev/null || fail "Cannot reset recalculate tags in-kernel"
int_check_sum_only 08f63eb27fb9ce2ce903b0a56429c68ce5e209253ba42154841ef045a53839d7
$INTSETUP close $DEV_NAME || fail "Cannot deactivate device."
echo "[RESET OK]"
else
echo "[RESET N/A]"
fi
else
echo "[N/A]"
fi