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:
Milan Broz
2018-11-07 16:33:17 +01:00
parent 0fed68dd16
commit d06defd885
6 changed files with 46 additions and 4 deletions

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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.

View File

@@ -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, &params);
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 ||

View File

@@ -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