bitlk: Fix working with 4k sector devices

We need to use the iv_large_sectors flag and correct sector size
for the crypt segments for these devices. Used sector size is
read from the device header. This commit also adds two new test
images with 4k sectors.

Fixes: #557
This commit is contained in:
Vojtěch Trefný
2020-05-05 18:47:49 +02:00
committed by Milan Broz
parent e759ebe0bd
commit 2e345a1059
5 changed files with 22 additions and 2 deletions

View File

@@ -111,6 +111,7 @@ struct segment {
struct bitlk_signature {
uint8_t boot_code[3];
uint8_t signature[8];
uint16_t sector_size;
} __attribute__ ((packed));
struct bitlk_superblock {
@@ -503,6 +504,13 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
goto out;
}
params->sector_size = le16_to_cpu(sig.sector_size);
if (!(params->sector_size == 512 || params->sector_size == 4096)) {
log_err(cd, _("Unsupported sector size %" PRIu16 "."), params->sector_size);
r = -EINVAL;
goto out;
}
/* read GUID and FVE metadata offsets */
if (read_lseek_blockwise(devfd, device_block_size(cd, device),
device_alignment(device), &sb, sizeof(sb), fve_offset) != sizeof(sb)) {
@@ -721,6 +729,7 @@ int BITLK_dump(struct crypt_device *cd, struct device *device, struct bitlk_meta
log_std(cd, "Info for BITLK%s device %s.\n", params->togo ? " To Go" : "", device_path(device));
log_std(cd, "Version: \t%u\n", params->metadata_version);
log_std(cd, "GUID: \t%s\n", params->guid);
log_std(cd, "Sector size: \t%u\n", params->sector_size);
log_std(cd, "Created: \t%s", ctime((time_t *)&(params->creation_time)));
log_std(cd, "Description: \t%s\n", params->description);
log_std(cd, "Cipher name: \t%s\n", params->cipher);
@@ -1155,6 +1164,9 @@ int BITLK_activate(struct crypt_device *cd,
}
}
if (params->sector_size != SECTOR_SIZE)
dmd.flags |= CRYPT_ACTIVATE_IV_LARGE_SECTORS;
r = dm_targets_allocate(&dmd.segment, num_segments);
if (r)
goto out;
@@ -1175,7 +1187,7 @@ int BITLK_activate(struct crypt_device *cd,
segments[i].iv_offset,
segments[i].iv_offset,
NULL, 0,
SECTOR_SIZE);
params->sector_size);
if (r)
goto out;

View File

@@ -95,6 +95,7 @@ struct bitlk_fvek {
};
struct bitlk_metadata {
uint16_t sector_size;
bool togo;
bool state;
BITLKEncryptionType type;

View File

@@ -1101,6 +1101,8 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot);
#define CRYPT_ACTIVATE_NO_JOURNAL_BITMAP (1 << 20)
/** device is suspended (key should be wiped from memory), output only */
#define CRYPT_ACTIVATE_SUSPENDED (1 << 21)
/** use IV sector counted in sector_size instead of default 512 bytes sectors */
#define CRYPT_ACTIVATE_IV_LARGE_SECTORS (1 << 22)
/**
* Active device runtime attributes

View File

@@ -615,6 +615,8 @@ static char *get_dm_crypt_params(const struct dm_target *tgt, uint32_t flags)
num_options++;
if (flags & CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)
num_options++;
if (flags & CRYPT_ACTIVATE_IV_LARGE_SECTORS)
num_options++;
if (tgt->u.crypt.integrity)
num_options++;
@@ -625,10 +627,11 @@ static char *get_dm_crypt_params(const struct dm_target *tgt, uint32_t flags)
*sector_feature = '\0';
if (num_options) {
snprintf(features, sizeof(features)-1, " %d%s%s%s%s%s", num_options,
snprintf(features, sizeof(features)-1, " %d%s%s%s%s%s%s", num_options,
(flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) ? " allow_discards" : "",
(flags & CRYPT_ACTIVATE_SAME_CPU_CRYPT) ? " same_cpu_crypt" : "",
(flags & CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS) ? " submit_from_crypt_cpus" : "",
(flags & CRYPT_ACTIVATE_IV_LARGE_SECTORS) ? " iv_large_sectors" : "",
sector_feature, integrity_dm);
} else
*features = '\0';
@@ -1915,6 +1918,8 @@ static int _dm_target_query_crypt(struct crypt_device *cd, uint32_t get_flags,
*act_flags |= CRYPT_ACTIVATE_SAME_CPU_CRYPT;
else if (!strcasecmp(arg, "submit_from_crypt_cpus"))
*act_flags |= CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS;
else if (!strcasecmp(arg, "iv_large_sectors"))
*act_flags |= CRYPT_ACTIVATE_IV_LARGE_SECTORS;
else if (sscanf(arg, "integrity:%u:", &val) == 1) {
tgt->u.crypt.tag_size = val;
rintegrity = strchr(arg + strlen("integrity:"), ':');

Binary file not shown.