mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
cryptsetup: add support for the "fix_padding" option
This patch adds support for fixed padding to cryptsetup. * Cryptsetup will accept superblocks version 4. * If the dm-integrity target version is greater than 1.4, cryptsetup will add a flag "fix_padding" to the dm-integrity target arguments. There is still one quirk: if we have an old libdm without DM_DEVICE_GET_TARGET_VERSION and if dm-integrity module is not loaded, cryptsetup will not detect that it can use the "fix_padding" option. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
This commit is contained in:
committed by
Milan Broz
parent
48b203a134
commit
fb4079aa4d
@@ -41,8 +41,7 @@ static int INTEGRITY_read_superblock(struct crypt_device *cd,
|
|||||||
if (read_lseek_blockwise(devfd, device_block_size(cd, device),
|
if (read_lseek_blockwise(devfd, device_block_size(cd, device),
|
||||||
device_alignment(device), sb, sizeof(*sb), offset) != sizeof(*sb) ||
|
device_alignment(device), sb, sizeof(*sb), offset) != sizeof(*sb) ||
|
||||||
memcmp(sb->magic, SB_MAGIC, sizeof(sb->magic)) ||
|
memcmp(sb->magic, SB_MAGIC, sizeof(sb->magic)) ||
|
||||||
(sb->version != SB_VERSION_1 && sb->version != SB_VERSION_2 &&
|
sb->version < SB_VERSION_1 || sb->version > SB_VERSION_4) {
|
||||||
sb->version != SB_VERSION_3)) {
|
|
||||||
log_std(cd, "No integrity superblock detected on %s.\n",
|
log_std(cd, "No integrity superblock detected on %s.\n",
|
||||||
device_path(device));
|
device_path(device));
|
||||||
r = -EINVAL;
|
r = -EINVAL;
|
||||||
@@ -203,7 +202,7 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd,
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
return dm_integrity_target_set(&dmd->segment, 0, dmd->size,
|
return dm_integrity_target_set(cd, &dmd->segment, 0, dmd->size,
|
||||||
crypt_metadata_device(cd), crypt_data_device(cd),
|
crypt_metadata_device(cd), crypt_data_device(cd),
|
||||||
crypt_get_integrity_tag_size(cd), crypt_get_data_offset(cd),
|
crypt_get_integrity_tag_size(cd), crypt_get_data_offset(cd),
|
||||||
crypt_get_sector_size(cd), vk, journal_crypt_key,
|
crypt_get_sector_size(cd), vk, journal_crypt_key,
|
||||||
@@ -289,7 +288,7 @@ int INTEGRITY_format(struct crypt_device *cd,
|
|||||||
if (params && params->integrity_key_size)
|
if (params && params->integrity_key_size)
|
||||||
vk = crypt_alloc_volume_key(params->integrity_key_size, NULL);
|
vk = crypt_alloc_volume_key(params->integrity_key_size, NULL);
|
||||||
|
|
||||||
r = dm_integrity_target_set(tgt, 0, dmdi.size, crypt_metadata_device(cd),
|
r = dm_integrity_target_set(cd, tgt, 0, dmdi.size, crypt_metadata_device(cd),
|
||||||
crypt_data_device(cd), crypt_get_integrity_tag_size(cd),
|
crypt_data_device(cd), crypt_get_integrity_tag_size(cd),
|
||||||
crypt_get_data_offset(cd), crypt_get_sector_size(cd), vk,
|
crypt_get_data_offset(cd), crypt_get_sector_size(cd), vk,
|
||||||
journal_crypt_key, journal_mac_key, params);
|
journal_crypt_key, journal_mac_key, params);
|
||||||
|
|||||||
@@ -34,10 +34,12 @@ struct crypt_dm_active_device;
|
|||||||
#define SB_VERSION_1 1
|
#define SB_VERSION_1 1
|
||||||
#define SB_VERSION_2 2
|
#define SB_VERSION_2 2
|
||||||
#define SB_VERSION_3 3
|
#define SB_VERSION_3 3
|
||||||
|
#define SB_VERSION_4 4
|
||||||
|
|
||||||
#define SB_FLAG_HAVE_JOURNAL_MAC (1 << 0)
|
#define SB_FLAG_HAVE_JOURNAL_MAC (1 << 0)
|
||||||
#define SB_FLAG_RECALCULATING (1 << 1) /* V2 only */
|
#define SB_FLAG_RECALCULATING (1 << 1) /* V2 only */
|
||||||
#define SB_FLAG_DIRTY_BITMAP (1 << 2) /* V3 only */
|
#define SB_FLAG_DIRTY_BITMAP (1 << 2) /* V3 only */
|
||||||
|
#define SB_FLAG_FIXED_PADDING (1 << 3) /* V4 only */
|
||||||
|
|
||||||
struct superblock {
|
struct superblock {
|
||||||
uint8_t magic[8];
|
uint8_t magic[8];
|
||||||
|
|||||||
@@ -218,6 +218,9 @@ static void _dm_set_integrity_compat(struct crypt_device *cd,
|
|||||||
if (_dm_satisfies_version(1, 3, 0, integrity_maj, integrity_min, integrity_patch))
|
if (_dm_satisfies_version(1, 3, 0, integrity_maj, integrity_min, integrity_patch))
|
||||||
_dm_flags |= DM_INTEGRITY_BITMAP_SUPPORTED;
|
_dm_flags |= DM_INTEGRITY_BITMAP_SUPPORTED;
|
||||||
|
|
||||||
|
if (_dm_satisfies_version(1, 4, 0, integrity_maj, integrity_min, integrity_patch))
|
||||||
|
_dm_flags |= DM_INTEGRITY_FIX_PADDING_SUPPORTED;
|
||||||
|
|
||||||
_dm_integrity_checked = true;
|
_dm_integrity_checked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -866,6 +869,11 @@ static char *get_dm_integrity_params(const struct dm_target *tgt, uint32_t flags
|
|||||||
strncat(features, feature, sizeof(features) - strlen(features) - 1);
|
strncat(features, feature, sizeof(features) - strlen(features) - 1);
|
||||||
crypt_safe_free(hexkey);
|
crypt_safe_free(hexkey);
|
||||||
}
|
}
|
||||||
|
if (tgt->u.integrity.fix_padding) {
|
||||||
|
num_options++;
|
||||||
|
snprintf(feature, sizeof(feature), "fix_padding ");
|
||||||
|
strncat(features, feature, sizeof(features) - strlen(features) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (flags & CRYPT_ACTIVATE_RECALCULATE) {
|
if (flags & CRYPT_ACTIVATE_RECALCULATE) {
|
||||||
num_options++;
|
num_options++;
|
||||||
@@ -2334,6 +2342,8 @@ static int _dm_target_query_integrity(struct crypt_device *cd,
|
|||||||
}
|
}
|
||||||
} else if (!strcmp(arg, "recalculate")) {
|
} else if (!strcmp(arg, "recalculate")) {
|
||||||
*act_flags |= CRYPT_ACTIVATE_RECALCULATE;
|
*act_flags |= CRYPT_ACTIVATE_RECALCULATE;
|
||||||
|
} else if (!strcmp(arg, "fix_padding")) {
|
||||||
|
tgt->u.integrity.fix_padding = true;
|
||||||
} else /* unknown option */
|
} else /* unknown option */
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -2868,16 +2878,21 @@ int dm_verity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t se
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dm_integrity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
int dm_integrity_target_set(struct crypt_device *cd,
|
||||||
|
struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
||||||
struct device *meta_device,
|
struct device *meta_device,
|
||||||
struct device *data_device, uint64_t tag_size, uint64_t offset,
|
struct device *data_device, uint64_t tag_size, uint64_t offset,
|
||||||
uint32_t sector_size, struct volume_key *vk,
|
uint32_t sector_size, struct volume_key *vk,
|
||||||
struct volume_key *journal_crypt_key, struct volume_key *journal_mac_key,
|
struct volume_key *journal_crypt_key, struct volume_key *journal_mac_key,
|
||||||
const struct crypt_params_integrity *ip)
|
const struct crypt_params_integrity *ip)
|
||||||
{
|
{
|
||||||
|
uint32_t dmi_flags;
|
||||||
|
|
||||||
if (!data_device)
|
if (!data_device)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
_dm_check_versions(cd, DM_INTEGRITY);
|
||||||
|
|
||||||
tgt->type = DM_INTEGRITY;
|
tgt->type = DM_INTEGRITY;
|
||||||
tgt->direction = TARGET_SET;
|
tgt->direction = TARGET_SET;
|
||||||
tgt->offset = seg_offset;
|
tgt->offset = seg_offset;
|
||||||
@@ -2893,6 +2908,9 @@ int dm_integrity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t
|
|||||||
tgt->u.integrity.journal_crypt_key = journal_crypt_key;
|
tgt->u.integrity.journal_crypt_key = journal_crypt_key;
|
||||||
tgt->u.integrity.journal_integrity_key = journal_mac_key;
|
tgt->u.integrity.journal_integrity_key = journal_mac_key;
|
||||||
|
|
||||||
|
if (!dm_flags(cd, DM_INTEGRITY, &dmi_flags) && dmi_flags & DM_INTEGRITY_FIX_PADDING_SUPPORTED)
|
||||||
|
tgt->u.integrity.fix_padding = true;
|
||||||
|
|
||||||
if (ip) {
|
if (ip) {
|
||||||
tgt->u.integrity.journal_size = ip->journal_size;
|
tgt->u.integrity.journal_size = ip->journal_size;
|
||||||
tgt->u.integrity.journal_watermark = ip->journal_watermark;
|
tgt->u.integrity.journal_watermark = ip->journal_watermark;
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ static inline uint32_t act2dmflags(uint32_t act_flags)
|
|||||||
#define DM_INTEGRITY_RECALC_SUPPORTED (1 << 16) /* dm-integrity automatic recalculation supported */
|
#define DM_INTEGRITY_RECALC_SUPPORTED (1 << 16) /* dm-integrity automatic recalculation supported */
|
||||||
#define DM_INTEGRITY_BITMAP_SUPPORTED (1 << 17) /* dm-integrity bitmap mode supported */
|
#define DM_INTEGRITY_BITMAP_SUPPORTED (1 << 17) /* dm-integrity bitmap mode supported */
|
||||||
#define DM_GET_TARGET_VERSION_SUPPORTED (1 << 18) /* dm DM_GET_TARGET version ioctl supported */
|
#define DM_GET_TARGET_VERSION_SUPPORTED (1 << 18) /* dm DM_GET_TARGET version ioctl supported */
|
||||||
|
#define DM_INTEGRITY_FIX_PADDING_SUPPORTED (1 << 19) /* supports the parameter fix_padding that fixes a bug that caused excessive padding */
|
||||||
|
|
||||||
typedef enum { DM_CRYPT = 0, DM_VERITY, DM_INTEGRITY, DM_LINEAR, DM_ERROR, DM_UNKNOWN } dm_target_type;
|
typedef enum { DM_CRYPT = 0, DM_VERITY, DM_INTEGRITY, DM_LINEAR, DM_ERROR, DM_UNKNOWN } dm_target_type;
|
||||||
enum tdirection { TARGET_SET = 1, TARGET_QUERY };
|
enum tdirection { TARGET_SET = 1, TARGET_QUERY };
|
||||||
@@ -138,6 +139,8 @@ struct dm_target {
|
|||||||
struct volume_key *journal_crypt_key;
|
struct volume_key *journal_crypt_key;
|
||||||
|
|
||||||
struct device *meta_device;
|
struct device *meta_device;
|
||||||
|
|
||||||
|
bool fix_padding;
|
||||||
} integrity;
|
} integrity;
|
||||||
struct {
|
struct {
|
||||||
uint64_t offset;
|
uint64_t offset;
|
||||||
@@ -177,7 +180,8 @@ int dm_verity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t se
|
|||||||
struct device *data_device, struct device *hash_device, struct device *fec_device,
|
struct device *data_device, struct device *hash_device, struct device *fec_device,
|
||||||
const char *root_hash, uint32_t root_hash_size, uint64_t hash_offset_block,
|
const char *root_hash, uint32_t root_hash_size, uint64_t hash_offset_block,
|
||||||
uint64_t hash_blocks, struct crypt_params_verity *vp);
|
uint64_t hash_blocks, struct crypt_params_verity *vp);
|
||||||
int dm_integrity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
int dm_integrity_target_set(struct crypt_device *cd,
|
||||||
|
struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
||||||
struct device *meta_device,
|
struct device *meta_device,
|
||||||
struct device *data_device, uint64_t tag_size, uint64_t offset, uint32_t sector_size,
|
struct device *data_device, uint64_t tag_size, uint64_t offset, uint32_t sector_size,
|
||||||
struct volume_key *vk,
|
struct volume_key *vk,
|
||||||
|
|||||||
Reference in New Issue
Block a user