mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Add automatic recalculation to dm-integrity.
Linux kernel since version 4.18 supports automatic background recalculation of integrity tags for dm-integrity. This patch adds new integritysetup --integrity-recalculate options that uses this option.
This commit is contained in:
@@ -977,6 +977,8 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot);
|
||||
#define CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE (1 << 15)
|
||||
/** allow activation check including unbound keyslots (keyslots without segments) */
|
||||
#define CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY (1 << 16)
|
||||
/** dm-integrity: activate automatic recalculation */
|
||||
#define CRYPT_ACTIVATE_RECALCULATE (1 << 17)
|
||||
|
||||
/**
|
||||
* Active device runtime attributes
|
||||
|
||||
@@ -209,6 +209,9 @@ static void _dm_set_integrity_compat(struct crypt_device *cd,
|
||||
|
||||
_dm_flags |= DM_INTEGRITY_SUPPORTED;
|
||||
|
||||
if (_dm_satisfies_version(1, 2, 0, integrity_maj, integrity_min, integrity_patch))
|
||||
_dm_flags |= DM_INTEGRITY_RECALC_SUPPORTED;
|
||||
|
||||
_dm_integrity_checked = true;
|
||||
}
|
||||
|
||||
@@ -683,7 +686,7 @@ out:
|
||||
|
||||
}
|
||||
|
||||
static char *get_dm_integrity_params(struct crypt_dm_active_device *dmd, uint32_t flags)
|
||||
static char *get_dm_integrity_params(struct crypt_dm_active_device *dmd, uint32_t flags, uint32_t dmflags)
|
||||
{
|
||||
int r, max_size, num_options = 0;
|
||||
char *params, *hexkey, mode;
|
||||
@@ -801,6 +804,12 @@ static char *get_dm_integrity_params(struct crypt_dm_active_device *dmd, uint32_
|
||||
crypt_safe_free(hexkey);
|
||||
}
|
||||
|
||||
if ((dmflags & DM_INTEGRITY_RECALC_SUPPORTED) && (flags & CRYPT_ACTIVATE_RECALCULATE)) {
|
||||
num_options++;
|
||||
snprintf(feature, sizeof(feature), "recalculate ");
|
||||
strncat(features, feature, sizeof(features) - strlen(features) - 1);
|
||||
}
|
||||
|
||||
if (flags & CRYPT_ACTIVATE_RECOVERY)
|
||||
mode = 'R';
|
||||
else if (flags & CRYPT_ACTIVATE_NO_JOURNAL)
|
||||
@@ -1194,14 +1203,14 @@ int dm_create_device(struct crypt_device *cd, const char *name,
|
||||
return -ENOTSUP;
|
||||
|
||||
dmd_flags = dmd->flags;
|
||||
dmt_flags = 0;
|
||||
dm_flags(cd, dmd->target, &dmt_flags);
|
||||
|
||||
if (dmd->target == DM_CRYPT)
|
||||
table_params = get_dm_crypt_params(dmd, dmd_flags);
|
||||
else if (dmd->target == DM_VERITY)
|
||||
table_params = get_dm_verity_params(dmd->u.verity.vp, dmd, dmd_flags);
|
||||
else if (dmd->target == DM_INTEGRITY)
|
||||
table_params = get_dm_integrity_params(dmd, dmd_flags);
|
||||
table_params = get_dm_integrity_params(dmd, dmd_flags, dmt_flags);
|
||||
else
|
||||
goto out;
|
||||
|
||||
@@ -1928,6 +1937,8 @@ static int _dm_query_integrity(struct crypt_device *cd,
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(arg, "recalculate")) {
|
||||
dmd->flags |= CRYPT_ACTIVATE_RECALCULATE;
|
||||
} else /* unknown option */
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ struct device;
|
||||
#define DM_SECTOR_SIZE_SUPPORTED (1 << 13) /* support for sector size setting in dm-crypt/dm-integrity */
|
||||
#define DM_CAPI_STRING_SUPPORTED (1 << 14) /* support for cryptoapi format cipher definition */
|
||||
#define DM_DEFERRED_SUPPORTED (1 << 15) /* deferred removal of device */
|
||||
#define DM_INTEGRITY_RECALC_SUPPORTED (1 << 16) /* dm-integrity automatic recalculation supported */
|
||||
|
||||
typedef enum { DM_CRYPT = 0, DM_VERITY, DM_INTEGRITY, DM_UNKNOWN } dm_target_type;
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ Open a mapping with <name> backed by device <device>.
|
||||
|
||||
\fB<options>\fR can be [\-\-batch\-mode, \-\-journal\-watermark, \-\-journal\-commit\-time,
|
||||
\-\-buffer\-sectors, \-\-integrity, \-\-integrity\-key\-size, \-\-integrity\-key\-file,
|
||||
\-\-integrity\-no\-journal, \-\-integrity\-recovery\-mode]
|
||||
\-\-integrity\-no\-journal, \-\-integrity\-recalculate, \-\-integrity\-recovery\-mode]
|
||||
|
||||
.PP
|
||||
\fIclose\fR <name>
|
||||
@@ -77,6 +77,12 @@ Size of the journal.
|
||||
.B "\-\-interleave\-sectors SECTORS"
|
||||
The number of interleaved sectors.
|
||||
.TP
|
||||
.B "\-\-integrity\-recalculate"
|
||||
Automatically recalculate integrity tags in kernel on activation.
|
||||
The device can be used during automatic integrity recalculation but becomes fully
|
||||
integrity protected only after the backgroud operation is finished.
|
||||
This option is available since the Linux kernel version 4.19.
|
||||
.TP
|
||||
.B "\-\-journal\-watermark PERCENT"
|
||||
Journal watermark in percents. When the size of the journal exceeds this watermark,
|
||||
the journal flush will be started.
|
||||
|
||||
@@ -54,6 +54,8 @@ static int opt_journal_crypt_key_size = 0;
|
||||
static int opt_integrity_nojournal = 0;
|
||||
static int opt_integrity_recovery = 0;
|
||||
|
||||
static int opt_integrity_recalculate = 0;
|
||||
|
||||
static int opt_version_mode = 0;
|
||||
|
||||
static const char **action_argv;
|
||||
@@ -299,6 +301,9 @@ static int action_open(int arg)
|
||||
if (opt_integrity_recovery)
|
||||
activate_flags |= CRYPT_ACTIVATE_RECOVERY;
|
||||
|
||||
if (opt_integrity_recalculate)
|
||||
activate_flags |= CRYPT_ACTIVATE_RECALCULATE;
|
||||
|
||||
r = _read_keys(&integrity_key, ¶ms);
|
||||
if (r)
|
||||
goto out;
|
||||
@@ -530,6 +535,7 @@ int main(int argc, const char **argv)
|
||||
|
||||
{ "integrity-no-journal", 'D', POPT_ARG_NONE, &opt_integrity_nojournal, 0, N_("Disable journal for integrity device"), NULL },
|
||||
{ "integrity-recovery-mode", 'R', POPT_ARG_NONE, &opt_integrity_recovery, 0, N_("Recovery mode (no journal, no tag checking)"), NULL },
|
||||
{ "integrity-recalculate", '\0', POPT_ARG_NONE, &opt_integrity_recalculate, 0, N_("Recalculate initial tags automatically."), NULL },
|
||||
POPT_TABLEEND
|
||||
};
|
||||
poptContext popt_context;
|
||||
@@ -606,6 +612,11 @@ int main(int argc, const char **argv)
|
||||
if (!strcmp(aname, "format") && opt_tag_size == 0)
|
||||
opt_tag_size = DEFAULT_TAG_SIZE;
|
||||
|
||||
if (opt_integrity_recalculate && strcmp(aname, "open"))
|
||||
usage(popt_context, EXIT_FAILURE,
|
||||
_("Option --integrity-recalculate can be used only for open action."),
|
||||
poptGetInvocationName(popt_context));
|
||||
|
||||
if (opt_interleave_sectors < 0 || opt_journal_watermark < 0 ||
|
||||
opt_journal_commit_time < 0 || opt_tag_size < 0 ||
|
||||
opt_sector_size < 0 || opt_buffer_sectors < 0 ||
|
||||
|
||||
@@ -311,4 +311,15 @@ int_mode sha256 32 512
|
||||
int_mode hmac-sha256 32 512 $KEY_FILE 32
|
||||
int_mode hmac-sha256 32 4096 $KEY_FILE 32
|
||||
|
||||
echo -n "Recalculate tags in-kernel:"
|
||||
$INTSETUP format -q $DEV --no-wipe || fail "Cannot format device."
|
||||
$INTSETUP open $DEV $DEV_NAME --integrity-recalculate || fail "Cannot activate device with journal."
|
||||
$INTSETUP dump $DEV | grep -q recalculating
|
||||
if [ $? -eq 0 ] ; then
|
||||
dd if=/dev/mapper/$DEV_NAME of=/dev/null bs=1M 2>/dev/null || fail "Cannot tags recalculate in-kernel"
|
||||
echo "[OK]"
|
||||
else
|
||||
echo "[N/A]"
|
||||
fi
|
||||
|
||||
cleanup
|
||||
|
||||
Reference in New Issue
Block a user