integrity: support Inline tags format and activation

Support inline format in API with crypt_format_inline().

Add --integrity-inline option to integritysetup.
This commit is contained in:
Milan Broz
2025-02-17 13:32:27 +01:00
parent 49ccafe38a
commit 006ebd832f
10 changed files with 218 additions and 44 deletions

View File

@@ -31,6 +31,8 @@ static int INTEGRITY_read_superblock(struct crypt_device *cd,
{ {
int devfd, r; int devfd, r;
log_dbg(cd, "Reading kernel dm-integrity metadata on %s.", device_path(device));
devfd = device_open(cd, device, O_RDONLY); devfd = device_open(cd, device, O_RDONLY);
if(devfd < 0) if(devfd < 0)
return -EINVAL; return -EINVAL;
@@ -71,8 +73,10 @@ int INTEGRITY_read_sb(struct crypt_device *cd,
if (r) if (r)
return r; return r;
if (params) {
params->sector_size = SECTOR_SIZE << sb.log2_sectors_per_block; params->sector_size = SECTOR_SIZE << sb.log2_sectors_per_block;
params->tag_size = sb.integrity_tag_size; params->tag_size = sb.integrity_tag_size;
}
if (flags) if (flags)
*flags = sb.flags; *flags = sb.flags;
@@ -248,6 +252,9 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd,
if (sb_flags & SB_FLAG_RECALCULATING) if (sb_flags & SB_FLAG_RECALCULATING)
dmd->flags |= CRYPT_ACTIVATE_RECALCULATE; dmd->flags |= CRYPT_ACTIVATE_RECALCULATE;
if (sb_flags & SB_FLAG_INLINE)
dmd->flags |= (CRYPT_ACTIVATE_NO_JOURNAL | CRYPT_ACTIVATE_INLINE_MODE);
r = INTEGRITY_data_sectors(cd, INTEGRITY_metadata_device(cd), r = INTEGRITY_data_sectors(cd, INTEGRITY_metadata_device(cd),
crypt_get_data_offset(cd) * SECTOR_SIZE, &dmd->size); crypt_get_data_offset(cd) * SECTOR_SIZE, &dmd->size);
if (r < 0) if (r < 0)
@@ -273,8 +280,9 @@ int INTEGRITY_activate_dmd_device(struct crypt_device *cd,
if (!single_segment(dmd) || tgt->type != DM_INTEGRITY) if (!single_segment(dmd) || tgt->type != DM_INTEGRITY)
return -EINVAL; return -EINVAL;
log_dbg(cd, "Trying to activate INTEGRITY device on top of %s, using name %s, tag size %d, provided sectors %" PRIu64".", log_dbg(cd, "Trying to activate INTEGRITY device on top of %s, using name %s, tag size %d%s, provided sectors %" PRIu64".",
device_path(tgt->data_device), name, tgt->u.integrity.tag_size, dmd->size); device_path(tgt->data_device), name, tgt->u.integrity.tag_size,
(sb_flags & SB_FLAG_INLINE) ? " (inline)" :"", dmd->size);
r = create_or_reload_device(cd, name, type, dmd); r = create_or_reload_device(cd, name, type, dmd);
@@ -298,6 +306,12 @@ int INTEGRITY_activate_dmd_device(struct crypt_device *cd,
return -ENOTSUP; return -ENOTSUP;
} }
if (r < 0 && (sb_flags & SB_FLAG_INLINE) && !dm_flags(cd, DM_INTEGRITY, &dmi_flags) &&
!(dmi_flags & DM_INTEGRITY_INLINE_MODE_SUPPORTED)) {
log_err(cd, _("Kernel does not support dm-integrity inline mode."));
return -ENOTSUP;
}
return r; return r;
} }
@@ -393,7 +407,9 @@ int INTEGRITY_format(struct crypt_device *cd,
struct volume_key *integrity_key, struct volume_key *integrity_key,
struct volume_key *journal_crypt_key, struct volume_key *journal_crypt_key,
struct volume_key *journal_mac_key, struct volume_key *journal_mac_key,
uint64_t backing_device_sectors) uint64_t backing_device_sectors,
uint32_t *sb_flags,
bool integrity_inline)
{ {
uint64_t dmi_flags; uint64_t dmi_flags;
char reduced_device_name[70], tmp_name[64], tmp_uuid[40]; char reduced_device_name[70], tmp_name[64], tmp_uuid[40];
@@ -440,6 +456,9 @@ int INTEGRITY_format(struct crypt_device *cd,
p_data_device = crypt_data_device(cd); p_data_device = crypt_data_device(cd);
} }
if (integrity_inline)
dmdi.flags |= (CRYPT_ACTIVATE_NO_JOURNAL | CRYPT_ACTIVATE_INLINE_MODE);
r = dm_integrity_target_set(cd, tgt, 0, dmdi.size, p_metadata_device, r = dm_integrity_target_set(cd, tgt, 0, dmdi.size, p_metadata_device,
p_data_device, crypt_get_integrity_tag_size(cd), p_data_device, crypt_get_integrity_tag_size(cd),
data_offset_sectors, crypt_get_sector_size(cd), integrity_key, data_offset_sectors, crypt_get_sector_size(cd), integrity_key,
@@ -447,8 +466,8 @@ int INTEGRITY_format(struct crypt_device *cd,
if (r < 0) if (r < 0)
goto err; goto err;
log_dbg(cd, "Trying to format INTEGRITY device on top of %s, tmp name %s, tag size %d.", log_dbg(cd, "Trying to format INTEGRITY device on top of %s, tmp name %s, tag size %d%s.",
device_path(tgt->data_device), tmp_name, tgt->u.integrity.tag_size); device_path(tgt->data_device), tmp_name, tgt->u.integrity.tag_size, integrity_inline ? " (inline)" : "");
r = device_block_adjust(cd, tgt->data_device, DEV_EXCL, tgt->u.integrity.offset, NULL, NULL); r = device_block_adjust(cd, tgt->data_device, DEV_EXCL, tgt->u.integrity.offset, NULL, NULL);
if (r < 0 && (dm_flags(cd, DM_INTEGRITY, &dmi_flags) || !(dmi_flags & DM_INTEGRITY_SUPPORTED))) { if (r < 0 && (dm_flags(cd, DM_INTEGRITY, &dmi_flags) || !(dmi_flags & DM_INTEGRITY_SUPPORTED))) {
@@ -469,6 +488,12 @@ int INTEGRITY_format(struct crypt_device *cd,
goto err; goto err;
r = dm_remove_device(cd, tmp_name, CRYPT_DEACTIVATE_FORCE); r = dm_remove_device(cd, tmp_name, CRYPT_DEACTIVATE_FORCE);
if (r)
goto err;
/* reload sb_flags from superblock (important for SB_FLAG_INLINE) */
if (sb_flags)
r = INTEGRITY_read_sb(cd, NULL, sb_flags);
err: err:
dm_targets_free(cd, &dmdi); dm_targets_free(cd, &dmdi);
if (reduced_device) { if (reduced_device) {

View File

@@ -9,6 +9,7 @@
#define _CRYPTSETUP_INTEGRITY_H #define _CRYPTSETUP_INTEGRITY_H
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
struct crypt_device; struct crypt_device;
struct device; struct device;
@@ -68,7 +69,9 @@ int INTEGRITY_format(struct crypt_device *cd,
struct volume_key *integrity_key, struct volume_key *integrity_key,
struct volume_key *journal_crypt_key, struct volume_key *journal_crypt_key,
struct volume_key *journal_mac_key, struct volume_key *journal_mac_key,
uint64_t backing_device_sectors); uint64_t backing_device_sectors,
uint32_t *sb_flags,
bool integrity_inline);
int INTEGRITY_activate(struct crypt_device *cd, int INTEGRITY_activate(struct crypt_device *cd,
const char *name, const char *name,

View File

@@ -703,6 +703,35 @@ int crypt_format_luks2_opal(struct crypt_device *cd,
struct crypt_params_luks2 *params, struct crypt_params_luks2 *params,
struct crypt_params_hw_opal *opal_params); struct crypt_params_hw_opal *opal_params);
/**
* Create (format) new integrity-protected device using integrity inline mode (HW sector tags).
* This can be used for @e INTEGRITY and @e LUKS2 with integrity protection
*
* @pre @e cd contains initialized and not formatted device context (device type must @b not be set)
*
* @param cd crypt device handle
* @param type type of device (optional params struct must be of this type)
* @param cipher (e.g. "aes") or @e NULL for @e INTEGRITY
* @param cipher_mode including IV specification (e.g. "xts-plain") or @e NULL for @e INTEGRITY
* @param uuid requested UUID or @e NULL if it should be generated
* @param volume_key pre-generated integrity/volume key (if needed) or @e NULL
* @param volume_key_size size of volume/integrity key in bytes.
* @param params crypt type specific parameters (see @link crypt-type @endlink)
*
* @returns @e 0 on success or negative errno value otherwise.
*
* @note Journal parameters must be set to zero in integrity part of @e params.
* Only tag_size, sector_size, buffer_sectors, integrity options should be set.
*/
int crypt_format_inline(struct crypt_device *cd,
const char *type,
const char *cipher,
const char *cipher_mode,
const char *uuid,
const char *volume_key,
size_t volume_key_size,
void *params);
/** /**
* Set format compatibility flags. * Set format compatibility flags.
* *

View File

@@ -193,4 +193,5 @@ CRYPTSETUP_2.8 {
crypt_keyslot_context_init_by_vk_in_keyring; crypt_keyslot_context_init_by_vk_in_keyring;
crypt_reencrypt_init_by_keyslot_context; crypt_reencrypt_init_by_keyslot_context;
crypt_get_old_volume_key_size; crypt_get_old_volume_key_size;
crypt_format_inline;
} CRYPTSETUP_2.7; } CRYPTSETUP_2.7;

View File

@@ -2200,7 +2200,8 @@ static int _crypt_format_luks2(struct crypt_device *cd,
goto out; goto out;
} }
} }
r = INTEGRITY_format(cd, params ? params->integrity_params : NULL, integrity_key, NULL, NULL, 0); r = INTEGRITY_format(cd, params ? params->integrity_params : NULL,
integrity_key, NULL, NULL, 0, NULL, false);
if (r) if (r)
log_err(cd, _("Cannot format integrity for device %s."), log_err(cd, _("Cannot format integrity for device %s."),
data_device_path(cd)); data_device_path(cd));
@@ -2658,7 +2659,7 @@ int crypt_format_luks2_opal(struct crypt_device *cd,
* Create reduced dm-integrity device only if locking range size does * Create reduced dm-integrity device only if locking range size does
* not match device size. * not match device size.
*/ */
device_size_bytes != range_size_bytes ? range_size_bytes / SECTOR_SIZE : 0); device_size_bytes != range_size_bytes ? range_size_bytes / SECTOR_SIZE : 0, NULL, false);
if (r) if (r)
log_err(cd, _("Cannot format integrity for device %s."), log_err(cd, _("Cannot format integrity for device %s."),
data_device_path(cd)); data_device_path(cd));
@@ -2940,7 +2941,8 @@ out:
static int _crypt_format_integrity(struct crypt_device *cd, static int _crypt_format_integrity(struct crypt_device *cd,
const char *uuid, const char *uuid,
struct crypt_params_integrity *params, struct crypt_params_integrity *params,
const char *integrity_key, size_t integrity_key_size) const char *integrity_key, size_t integrity_key_size,
bool integrity_inline)
{ {
int r; int r;
uint32_t integrity_tag_size; uint32_t integrity_tag_size;
@@ -3037,7 +3039,9 @@ static int _crypt_format_integrity(struct crypt_device *cd,
} }
} }
r = INTEGRITY_format(cd, params, ik, cd->u.integrity.journal_crypt_key, cd->u.integrity.journal_mac_key, 0); r = INTEGRITY_format(cd, params, ik, cd->u.integrity.journal_crypt_key,
cd->u.integrity.journal_mac_key, 0, &cd->u.integrity.sb_flags,
integrity_inline);
if (r) if (r)
log_err(cd, _("Cannot format integrity for device %s."), mdata_device_path(cd)); log_err(cd, _("Cannot format integrity for device %s."), mdata_device_path(cd));
@@ -3054,6 +3058,75 @@ out:
return r; return r;
} }
int crypt_format_inline(struct crypt_device *cd,
const char *type,
const char *cipher,
const char *cipher_mode,
const char *uuid,
const char *volume_key,
size_t volume_key_size,
void *params)
{
const struct crypt_params_integrity *iparams;
struct device *idevice;
size_t sector_size, required_sector_size;
int r;
if (!cd || !params)
return -EINVAL;
if (cd->type) {
log_dbg(cd, "Context already formatted as %s.", cd->type);
return -EINVAL;
}
log_dbg(cd, "Formatting device %s as type %s with inline tags.", mdata_device_path(cd) ?: "(none)", type);
if (isINTEGRITY(type)) {
iparams = params;
idevice = crypt_metadata_device(cd);
required_sector_size = iparams->sector_size;
/* Unused in standalone integrity */
if (cipher || cipher_mode)
return -EINVAL;
} else {
log_err(cd, _("Unknown or unsupported device type %s requested."), type);
return -EINVAL;
}
/* In inline mode journal will be never used, check that params are not set */
if (iparams && (iparams->journal_size || iparams->journal_watermark || iparams->journal_commit_time ||
iparams->interleave_sectors || iparams->journal_integrity || iparams->journal_integrity_key ||
iparams->journal_integrity_key_size || iparams->journal_crypt || iparams->journal_crypt_key ||
iparams->journal_integrity_key_size))
return -EINVAL;
/* Inline must use sectors size as hardware device */
sector_size = device_block_size(cd, idevice);
if (!sector_size)
return -EINVAL;
/* No autodetection, use device sector size */
if (sector_size != required_sector_size) {
log_err(cd, _("Sector must be the same as device hardware sector (%zu bytes)."), sector_size);
return -EINVAL;
}
if (isINTEGRITY(type))
r = _crypt_format_integrity(cd, uuid, params, volume_key, volume_key_size, true);
else
r = -EINVAL;
if (r < 0) {
crypt_set_null_type(cd);
crypt_free_volume_key(cd->volume_key);
cd->volume_key = NULL;
}
return r;
}
static int _crypt_format(struct crypt_device *cd, static int _crypt_format(struct crypt_device *cd,
const char *type, const char *type,
const char *cipher, const char *cipher,
@@ -3096,9 +3169,9 @@ static int _crypt_format(struct crypt_device *cd,
else if (isVERITY(type)) else if (isVERITY(type))
r = _crypt_format_verity(cd, uuid, params); r = _crypt_format_verity(cd, uuid, params);
else if (isINTEGRITY(type)) else if (isINTEGRITY(type))
r = _crypt_format_integrity(cd, uuid, params, volume_key, volume_key_size); r = _crypt_format_integrity(cd, uuid, params, volume_key, volume_key_size, false);
else { else {
log_err(cd, _("Unknown crypt device type %s requested."), type); log_err(cd, _("Unknown or unsupported device type %s requested."), type);
r = -EINVAL; r = -EINVAL;
} }

View File

@@ -155,6 +155,19 @@ because we don't have to write the data twice, but it is also less
reliable, because if data corruption happens when the machine crashes, reliable, because if data corruption happens when the machine crashes,
it may not be detected. it may not be detected.
*--integrity-inline*::
Store integrity tags to hardware sector integrity fields.
The device must support sectors with additional protection information
(PI, also known as DIF - data integrity field) of the requested size.
Another storage subsystem must not use the additional field
(the device must present a "nop" profile in the kernel).
Note that some devices must be reformatted at a low level to support
this option; for NVMe devices, see nvme(1) id-ns LBA profiles.
+
No journal or bitmap is used in this mode. The device should operate
with native speed (without any overhead).
This option is available since the Linux kernel version 6.11.
*--integrity-key-file FILE*:: *--integrity-key-file FILE*::
The file with the integrity key. The file with the integrity key.

View File

@@ -112,11 +112,6 @@ static int action_format(void)
{ {
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
struct crypt_params_integrity params = { struct crypt_params_integrity params = {
.journal_size = ARG_UINT64(OPT_JOURNAL_SIZE_ID),
.interleave_sectors = ARG_UINT32(OPT_INTERLEAVE_SECTORS_ID),
/* in bitmap mode we have to overload these values... */
.journal_watermark = ARG_SET(OPT_INTEGRITY_BITMAP_MODE_ID) ? ARG_UINT32(OPT_BITMAP_SECTORS_PER_BIT_ID) : ARG_UINT32(OPT_JOURNAL_WATERMARK_ID),
.journal_commit_time = ARG_SET(OPT_INTEGRITY_BITMAP_MODE_ID) ? ARG_UINT32(OPT_BITMAP_FLUSH_TIME_ID) : ARG_UINT32(OPT_JOURNAL_COMMIT_TIME_ID),
.buffer_sectors = ARG_UINT32(OPT_BUFFER_SECTORS_ID), .buffer_sectors = ARG_UINT32(OPT_BUFFER_SECTORS_ID),
.tag_size = ARG_UINT32(OPT_TAG_SIZE_ID), .tag_size = ARG_UINT32(OPT_TAG_SIZE_ID),
.sector_size = ARG_UINT32(OPT_SECTOR_SIZE_ID), .sector_size = ARG_UINT32(OPT_SECTOR_SIZE_ID),
@@ -133,6 +128,13 @@ static int action_format(void)
} }
params.integrity = integrity; params.integrity = integrity;
if (!ARG_SET(OPT_INTEGRITY_INLINE_ID)) {
params.journal_size = ARG_UINT64(OPT_JOURNAL_SIZE_ID);
params.interleave_sectors = ARG_UINT32(OPT_INTERLEAVE_SECTORS_ID);
/* in bitmap mode we have to overload these values... */
params.journal_watermark = ARG_SET(OPT_INTEGRITY_BITMAP_MODE_ID) ? ARG_UINT32(OPT_BITMAP_SECTORS_PER_BIT_ID) : ARG_UINT32(OPT_JOURNAL_WATERMARK_ID);
params.journal_commit_time = ARG_SET(OPT_INTEGRITY_BITMAP_MODE_ID) ? ARG_UINT32(OPT_BITMAP_FLUSH_TIME_ID) : ARG_UINT32(OPT_JOURNAL_COMMIT_TIME_ID);
if (ARG_SET(OPT_JOURNAL_INTEGRITY_ID)) { if (ARG_SET(OPT_JOURNAL_INTEGRITY_ID)) {
r = crypt_parse_hash_integrity_mode(ARG_STR(OPT_JOURNAL_INTEGRITY_ID), journal_integrity); r = crypt_parse_hash_integrity_mode(ARG_STR(OPT_JOURNAL_INTEGRITY_ID), journal_integrity);
if (r < 0) { if (r < 0) {
@@ -151,6 +153,8 @@ static int action_format(void)
params.journal_crypt = journal_crypt; params.journal_crypt = journal_crypt;
} }
}
r = _read_keys(&integrity_key, &params); r = _read_keys(&integrity_key, &params);
if (r) if (r)
goto out; goto out;
@@ -196,13 +200,18 @@ static int action_format(void)
if (ARG_SET(OPT_INTEGRITY_LEGACY_HMAC_ID)) if (ARG_SET(OPT_INTEGRITY_LEGACY_HMAC_ID))
crypt_set_compatibility(cd, CRYPT_COMPAT_LEGACY_INTEGRITY_HMAC); crypt_set_compatibility(cd, CRYPT_COMPAT_LEGACY_INTEGRITY_HMAC);
r = crypt_format(cd, CRYPT_INTEGRITY, NULL, NULL, NULL, integrity_key, params.integrity_key_size, &params); if (ARG_SET(OPT_INTEGRITY_INLINE_ID))
r = crypt_format_inline(cd, CRYPT_INTEGRITY, NULL, NULL, NULL,
integrity_key, params.integrity_key_size, &params);
else
r = crypt_format(cd, CRYPT_INTEGRITY, NULL, NULL, NULL,
integrity_key, params.integrity_key_size, &params);
if (r < 0) /* FIXME: call wipe signatures again */ if (r < 0) /* FIXME: call wipe signatures again */
goto out; goto out;
if (!ARG_SET(OPT_BATCH_MODE_ID) && !crypt_get_integrity_info(cd, &params2)) if (!ARG_SET(OPT_BATCH_MODE_ID) && !crypt_get_integrity_info(cd, &params2))
log_std(_("Formatted with tag size %u, internal integrity %s.\n"), log_std(_("Formatted with tag size %u%s, internal integrity %s.\n"),
params2.tag_size, params2.integrity); params2.tag_size, ARG_SET(OPT_INTEGRITY_INLINE_ID) ? " (inline hw tags)" : "", params2.integrity);
if (!ARG_SET(OPT_NO_WIPE_ID)) { if (!ARG_SET(OPT_NO_WIPE_ID)) {
r = _wipe_data_device(cd, integrity_key); r = _wipe_data_device(cd, integrity_key);
@@ -227,6 +236,7 @@ static int action_resize(void)
uint64_t old_dev_size; uint64_t old_dev_size;
char path[PATH_MAX]; char path[PATH_MAX];
char *backing_file = NULL; char *backing_file = NULL;
uint32_t reactivate_flags;
struct tools_progress_params prog_parms = { struct tools_progress_params prog_parms = {
.frequency = ARG_UINT32(OPT_PROGRESS_FREQUENCY_ID), .frequency = ARG_UINT32(OPT_PROGRESS_FREQUENCY_ID),
.batch_mode = ARG_SET(OPT_BATCH_MODE_ID), .batch_mode = ARG_SET(OPT_BATCH_MODE_ID),
@@ -256,12 +266,14 @@ static int action_resize(void)
if (r) if (r)
goto out; goto out;
if (!new_dev_size) {
r = crypt_get_active_device(cd, action_argv[0], &cad); r = crypt_get_active_device(cd, action_argv[0], &cad);
if (r) if (r)
goto out; goto out;
reactivate_flags = CRYPT_ACTIVATE_REFRESH | (cad.flags & CRYPT_ACTIVATE_INLINE_MODE);
if (!new_dev_size)
new_dev_size = cad.size; new_dev_size = cad.size;
}
if (new_dev_size > old_dev_size) { if (new_dev_size > old_dev_size) {
if (ARG_SET(OPT_WIPE_ID)) { if (ARG_SET(OPT_WIPE_ID)) {
@@ -279,8 +291,8 @@ static int action_resize(void)
set_int_block(0); set_int_block(0);
} else { } else {
log_dbg("Setting recalculate flag"); log_dbg("Setting recalculate flag");
r = crypt_activate_by_volume_key(cd, action_argv[0], NULL, 0, CRYPT_ACTIVATE_REFRESH | CRYPT_ACTIVATE_RECALCULATE); reactivate_flags |= CRYPT_ACTIVATE_RECALCULATE;
r = crypt_activate_by_volume_key(cd, action_argv[0], NULL, 0, reactivate_flags);
if (r == -ENOTSUP) if (r == -ENOTSUP)
log_err(_("Setting recalculate flag is not supported, you may consider using --wipe instead.")); log_err(_("Setting recalculate flag is not supported, you may consider using --wipe instead."));
} }
@@ -482,7 +494,11 @@ static int action_status(void)
if (cad.flags & CRYPT_ACTIVATE_NO_JOURNAL_BITMAP) { if (cad.flags & CRYPT_ACTIVATE_NO_JOURNAL_BITMAP) {
log_std(" bitmap 512-byte sectors per bit: %u\n", ip.journal_watermark); log_std(" bitmap 512-byte sectors per bit: %u\n", ip.journal_watermark);
log_std(" bitmap flush interval: %u [ms]\n", ip.journal_commit_time); log_std(" bitmap flush interval: %u [ms]\n", ip.journal_commit_time);
} if (cad.flags & CRYPT_ACTIVATE_NO_JOURNAL) { }
if (cad.flags & CRYPT_ACTIVATE_INLINE_MODE) {
log_std(" inline mode\n");
}
if (cad.flags & CRYPT_ACTIVATE_NO_JOURNAL) {
log_std(" journal: not active\n"); log_std(" journal: not active\n");
} else { } else {
log_std(" journal size: %" PRIu64 " [bytes]\n", ip.journal_size); log_std(" journal size: %" PRIu64 " [bytes]\n", ip.journal_size);
@@ -753,6 +769,16 @@ int main(int argc, const char **argv)
usage(popt_context, EXIT_FAILURE, _("Bitmap options can be used only in bitmap mode."), usage(popt_context, EXIT_FAILURE, _("Bitmap options can be used only in bitmap mode."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (ARG_SET(OPT_INTEGRITY_INLINE_ID) && (ARG_SET(OPT_INTEGRITY_BITMAP_MODE_ID) ||
ARG_SET(OPT_JOURNAL_INTEGRITY_ID) || ARG_SET(OPT_JOURNAL_CRYPT_ID) ||
ARG_SET(OPT_JOURNAL_WATERMARK_ID) || ARG_SET(OPT_JOURNAL_COMMIT_TIME_ID)))
usage(popt_context, EXIT_FAILURE, _("Inline mode cannot be combined with journal or bitmap options."),
poptGetInvocationName(popt_context));
if (ARG_SET(OPT_INTEGRITY_INLINE_ID) && ARG_SET(OPT_DATA_DEVICE_ID))
usage(popt_context, EXIT_FAILURE, _("Inline mode cannot be combined with separate data device."),
poptGetInvocationName(popt_context));
if (ARG_SET(OPT_CANCEL_DEFERRED_ID) && ARG_SET(OPT_DEFERRED_ID)) if (ARG_SET(OPT_CANCEL_DEFERRED_ID) && ARG_SET(OPT_DEFERRED_ID))
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("Options --cancel-deferred and --deferred cannot be used at the same time."), _("Options --cancel-deferred and --deferred cannot be used at the same time."),

View File

@@ -34,6 +34,8 @@ ARG(OPT_INTEGRITY, 'I', POPT_ARG_STRING, N_("Data integrity algorithm"), NULL, C
ARG(OPT_INTEGRITY_BITMAP_MODE, 'B', POPT_ARG_NONE, N_("Use bitmap to track changes and disable journal for integrity device"), NULL, CRYPT_ARG_BOOL, {}, {}) ARG(OPT_INTEGRITY_BITMAP_MODE, 'B', POPT_ARG_NONE, N_("Use bitmap to track changes and disable journal for integrity device"), NULL, CRYPT_ARG_BOOL, {}, {})
ARG(OPT_INTEGRITY_INLINE, '\0', POPT_ARG_NONE, N_("Use inline integrity mode (HW sector tags)"), NULL, CRYPT_ARG_BOOL, {}, OPT_INTEGRITY_INLINE_ACTIONS)
ARG(OPT_INTEGRITY_KEY_FILE, '\0', POPT_ARG_STRING, N_("Read the integrity key from a file"), NULL, CRYPT_ARG_STRING, {}, {}) ARG(OPT_INTEGRITY_KEY_FILE, '\0', POPT_ARG_STRING, N_("Read the integrity key from a file"), NULL, CRYPT_ARG_STRING, {}, {})
ARG(OPT_INTEGRITY_KEY_SIZE, '\0', POPT_ARG_STRING, N_("The size of the data integrity key"), N_("BITS"), CRYPT_ARG_UINT32, {}, {}) ARG(OPT_INTEGRITY_KEY_SIZE, '\0', POPT_ARG_STRING, N_("The size of the data integrity key"), N_("BITS"), CRYPT_ARG_UINT32, {}, {})

View File

@@ -23,6 +23,7 @@
#define OPT_DEFERRED_ACTIONS { CLOSE_ACTION } #define OPT_DEFERRED_ACTIONS { CLOSE_ACTION }
#define OPT_DEVICE_SIZE_ACTIONS { RESIZE_ACTION } #define OPT_DEVICE_SIZE_ACTIONS { RESIZE_ACTION }
#define OPT_DISABLE_BLKID_ACTIONS { FORMAT_ACTION } #define OPT_DISABLE_BLKID_ACTIONS { FORMAT_ACTION }
#define OPT_INTEGRITY_INLINE_ACTIONS { FORMAT_ACTION }
#define OPT_INTEGRITY_RECALCULATE_ACTIONS { OPEN_ACTION } #define OPT_INTEGRITY_RECALCULATE_ACTIONS { OPEN_ACTION }
#define OPT_INTERLEAVE_SECTORS_ACTIONS { FORMAT_ACTION } #define OPT_INTERLEAVE_SECTORS_ACTIONS { FORMAT_ACTION }
#define OPT_JOURNAL_SIZE_ACTIONS { FORMAT_ACTION } #define OPT_JOURNAL_SIZE_ACTIONS { FORMAT_ACTION }

View File

@@ -62,6 +62,7 @@
#define OPT_INTEGRITY_BITMAP_MODE "integrity-bitmap-mode" #define OPT_INTEGRITY_BITMAP_MODE "integrity-bitmap-mode"
#define OPT_INTEGRITY_KEY_FILE "integrity-key-file" #define OPT_INTEGRITY_KEY_FILE "integrity-key-file"
#define OPT_INTEGRITY_KEY_SIZE "integrity-key-size" #define OPT_INTEGRITY_KEY_SIZE "integrity-key-size"
#define OPT_INTEGRITY_INLINE "integrity-inline"
#define OPT_INTEGRITY_LEGACY_PADDING "integrity-legacy-padding" #define OPT_INTEGRITY_LEGACY_PADDING "integrity-legacy-padding"
#define OPT_INTEGRITY_LEGACY_HMAC "integrity-legacy-hmac" #define OPT_INTEGRITY_LEGACY_HMAC "integrity-legacy-hmac"
#define OPT_INTEGRITY_LEGACY_RECALC "integrity-legacy-recalculate" #define OPT_INTEGRITY_LEGACY_RECALC "integrity-legacy-recalculate"