mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-12 03:10:08 +01:00
Add FEC offset parameter for verity.
This commit is contained in:
@@ -312,6 +312,7 @@ struct crypt_params_verity {
|
|||||||
uint32_t hash_block_size; /**< hash block size (in bytes) */
|
uint32_t hash_block_size; /**< hash block size (in bytes) */
|
||||||
uint64_t data_size; /**< data area size (in data blocks) */
|
uint64_t data_size; /**< data area size (in data blocks) */
|
||||||
uint64_t hash_area_offset; /**< hash/header offset (in bytes) */
|
uint64_t hash_area_offset; /**< hash/header offset (in bytes) */
|
||||||
|
uint64_t fec_area_offset; /**< FEC/header offset (in bytes) */
|
||||||
uint32_t fec_roots; /**< Reed-Solomon FEC roots */
|
uint32_t fec_roots; /**< Reed-Solomon FEC roots */
|
||||||
uint32_t flags; /**< CRYPT_VERITY* flags */
|
uint32_t flags; /**< CRYPT_VERITY* flags */
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -390,8 +390,8 @@ static char *get_dm_verity_params(struct crypt_params_verity *vp,
|
|||||||
if (dmd->u.verity.fec_device) {
|
if (dmd->u.verity.fec_device) {
|
||||||
num_options += 8;
|
num_options += 8;
|
||||||
snprintf(fec_features, sizeof(fec_features)-1,
|
snprintf(fec_features, sizeof(fec_features)-1,
|
||||||
" use_fec_from_device %s fec_start 0 fec_blocks %" PRIu64 " fec_roots %" PRIu32,
|
" use_fec_from_device %s fec_start %" PRIu64 " fec_blocks %" PRIu64 " fec_roots %" PRIu32,
|
||||||
device_block_path(dmd->u.verity.fec_device),
|
device_block_path(dmd->u.verity.fec_device), dmd->u.verity.fec_offset,
|
||||||
vp->data_size + dmd->u.verity.hash_blocks, vp->fec_roots);
|
vp->data_size + dmd->u.verity.hash_blocks, vp->fec_roots);
|
||||||
} else
|
} else
|
||||||
*fec_features = '\0';
|
*fec_features = '\0';
|
||||||
|
|||||||
@@ -730,6 +730,7 @@ static int _init_by_name_verity(struct crypt_device *cd, const char *name)
|
|||||||
cd->u.verity.hdr.data_block_size = params.data_block_size;
|
cd->u.verity.hdr.data_block_size = params.data_block_size;
|
||||||
cd->u.verity.hdr.hash_block_size = params.hash_block_size;
|
cd->u.verity.hdr.hash_block_size = params.hash_block_size;
|
||||||
cd->u.verity.hdr.hash_area_offset = dmd.u.verity.hash_offset;
|
cd->u.verity.hdr.hash_area_offset = dmd.u.verity.hash_offset;
|
||||||
|
cd->u.verity.hdr.fec_area_offset = dmd.u.verity.fec_offset;
|
||||||
cd->u.verity.hdr.hash_type = params.hash_type;
|
cd->u.verity.hdr.hash_type = params.hash_type;
|
||||||
cd->u.verity.hdr.flags = params.flags;
|
cd->u.verity.hdr.flags = params.flags;
|
||||||
cd->u.verity.hdr.salt_size = params.salt_size;
|
cd->u.verity.hdr.salt_size = params.salt_size;
|
||||||
@@ -1023,6 +1024,11 @@ static int _crypt_format_verity(struct crypt_device *cd,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (params->fec_area_offset % 512) {
|
||||||
|
log_err(cd, _("Unsupported VERITY FEC offset.\n"));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(cd->type = strdup(CRYPT_VERITY)))
|
if (!(cd->type = strdup(CRYPT_VERITY)))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@@ -1069,6 +1075,7 @@ static int _crypt_format_verity(struct crypt_device *cd,
|
|||||||
cd->u.verity.hdr.data_block_size = params->data_block_size;
|
cd->u.verity.hdr.data_block_size = params->data_block_size;
|
||||||
cd->u.verity.hdr.hash_block_size = params->hash_block_size;
|
cd->u.verity.hdr.hash_block_size = params->hash_block_size;
|
||||||
cd->u.verity.hdr.hash_area_offset = params->hash_area_offset;
|
cd->u.verity.hdr.hash_area_offset = params->hash_area_offset;
|
||||||
|
cd->u.verity.hdr.fec_area_offset = params->fec_area_offset;
|
||||||
cd->u.verity.hdr.hash_type = params->hash_type;
|
cd->u.verity.hdr.hash_type = params->hash_type;
|
||||||
cd->u.verity.hdr.flags = params->flags;
|
cd->u.verity.hdr.flags = params->flags;
|
||||||
cd->u.verity.hdr.salt_size = params->salt_size;
|
cd->u.verity.hdr.salt_size = params->salt_size;
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ struct crypt_dm_active_device {
|
|||||||
|
|
||||||
uint64_t hash_offset; /* hash offset in blocks (not header) */
|
uint64_t hash_offset; /* hash offset in blocks (not header) */
|
||||||
uint64_t hash_blocks; /* size of hash device (in hash blocks) */
|
uint64_t hash_blocks; /* size of hash device (in hash blocks) */
|
||||||
|
uint64_t fec_offset; /* FEC offset in blocks (not header) */
|
||||||
struct crypt_params_verity *vp;
|
struct crypt_params_verity *vp;
|
||||||
} verity;
|
} verity;
|
||||||
} u;
|
} u;
|
||||||
|
|||||||
@@ -67,6 +67,21 @@ struct fec_context {
|
|||||||
size_t ninputs;
|
size_t ninputs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Calculate FEC offset in hash blocks */
|
||||||
|
uint64_t VERITY_FEC_offset_block(struct crypt_params_verity *params)
|
||||||
|
{
|
||||||
|
uint64_t fec_offset = params->fec_area_offset;
|
||||||
|
|
||||||
|
if (params->flags & CRYPT_VERITY_NO_HEADER)
|
||||||
|
return fec_offset / params->hash_block_size;
|
||||||
|
|
||||||
|
fec_offset += sizeof(struct fec_sb);
|
||||||
|
//hash_offset += params->hash_block_size - 1;
|
||||||
|
|
||||||
|
return fec_offset / params->hash_block_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* computes ceil(x / y) */
|
/* computes ceil(x / y) */
|
||||||
static inline uint64_t FEC_div_round_up(uint64_t x, uint64_t y)
|
static inline uint64_t FEC_div_round_up(uint64_t x, uint64_t y)
|
||||||
{
|
{
|
||||||
@@ -302,6 +317,12 @@ int VERITY_FEC_create(struct crypt_device *cd,
|
|||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lseek(fd, params->fec_area_offset, SEEK_SET) != params->fec_area_offset) {
|
||||||
|
log_dbg("Cannot seek to requested position in FEC device.");
|
||||||
|
TEMP_FAILURE_RETRY(close(fd));
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
/* input devices */
|
/* input devices */
|
||||||
memset(inputs, 0, sizeof(inputs));
|
memset(inputs, 0, sizeof(inputs));
|
||||||
|
|
||||||
|
|||||||
@@ -261,6 +261,7 @@ int VERITY_activate(struct crypt_device *cd,
|
|||||||
dmd.u.verity.root_hash = root_hash;
|
dmd.u.verity.root_hash = root_hash;
|
||||||
dmd.u.verity.root_hash_size = root_hash_size;
|
dmd.u.verity.root_hash_size = root_hash_size;
|
||||||
dmd.u.verity.hash_offset = VERITY_hash_offset_block(verity_hdr);
|
dmd.u.verity.hash_offset = VERITY_hash_offset_block(verity_hdr);
|
||||||
|
dmd.u.verity.fec_offset = VERITY_FEC_offset_block(verity_hdr);
|
||||||
dmd.u.verity.hash_blocks = VERITY_hash_blocks(cd, verity_hdr);
|
dmd.u.verity.hash_blocks = VERITY_hash_blocks(cd, verity_hdr);
|
||||||
dmd.flags = activation_flags;
|
dmd.flags = activation_flags;
|
||||||
dmd.size = verity_hdr->data_size * verity_hdr->data_block_size / 512;
|
dmd.size = verity_hdr->data_size * verity_hdr->data_block_size / 512;
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ int VERITY_create(struct crypt_device *cd,
|
|||||||
size_t root_hash_size);
|
size_t root_hash_size);
|
||||||
|
|
||||||
uint64_t VERITY_hash_offset_block(struct crypt_params_verity *params);
|
uint64_t VERITY_hash_offset_block(struct crypt_params_verity *params);
|
||||||
|
uint64_t VERITY_FEC_offset_block(struct crypt_params_verity *params);
|
||||||
|
|
||||||
uint64_t VERITY_hash_blocks(struct crypt_device *cd, struct crypt_params_verity *params);
|
uint64_t VERITY_hash_blocks(struct crypt_device *cd, struct crypt_params_verity *params);
|
||||||
|
|
||||||
|
|||||||
@@ -444,8 +444,8 @@ int VERITY_create(struct crypt_device *cd,
|
|||||||
|
|
||||||
uint64_t VERITY_hash_blocks(struct crypt_device *cd, struct crypt_params_verity *params)
|
uint64_t VERITY_hash_blocks(struct crypt_device *cd, struct crypt_params_verity *params)
|
||||||
{
|
{
|
||||||
off_t hash_position = (off_t)params->hash_area_offset;
|
off_t hash_position = 0;
|
||||||
int levels;
|
int levels = 0;
|
||||||
|
|
||||||
if (hash_levels(params->hash_block_size, crypt_get_volume_key_size(cd),
|
if (hash_levels(params->hash_block_size, crypt_get_volume_key_size(cd),
|
||||||
params->data_size, &hash_position, &levels, NULL, NULL))
|
params->data_size, &hash_position, &levels, NULL, NULL))
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ static int hash_block_size = DEFAULT_VERITY_HASH_BLOCK;
|
|||||||
static uint64_t data_blocks = 0;
|
static uint64_t data_blocks = 0;
|
||||||
static const char *salt_string = NULL;
|
static const char *salt_string = NULL;
|
||||||
static uint64_t hash_offset = 0;
|
static uint64_t hash_offset = 0;
|
||||||
|
static uint64_t fec_offset = 0;
|
||||||
static const char *opt_uuid = NULL;
|
static const char *opt_uuid = NULL;
|
||||||
static int opt_restart_on_corruption = 0;
|
static int opt_restart_on_corruption = 0;
|
||||||
static int opt_ignore_corruption = 0;
|
static int opt_ignore_corruption = 0;
|
||||||
@@ -76,6 +77,7 @@ static int _prepare_format(struct crypt_params_verity *params,
|
|||||||
params->hash_block_size = hash_block_size;
|
params->hash_block_size = hash_block_size;
|
||||||
params->data_size = data_blocks;
|
params->data_size = data_blocks;
|
||||||
params->hash_area_offset = hash_offset;
|
params->hash_area_offset = hash_offset;
|
||||||
|
params->fec_area_offset = fec_offset;
|
||||||
params->hash_type = hash_type;
|
params->hash_type = hash_type;
|
||||||
params->flags = flags;
|
params->flags = flags;
|
||||||
|
|
||||||
@@ -155,6 +157,7 @@ static int _activate(const char *dm_device,
|
|||||||
if (use_superblock) {
|
if (use_superblock) {
|
||||||
params.flags = flags;
|
params.flags = flags;
|
||||||
params.hash_area_offset = hash_offset;
|
params.hash_area_offset = hash_offset;
|
||||||
|
params.fec_area_offset = fec_offset;
|
||||||
params.fec_device = fec_device;
|
params.fec_device = fec_device;
|
||||||
params.fec_roots = fec_roots;
|
params.fec_roots = fec_roots;
|
||||||
r = crypt_load(cd, CRYPT_VERITY, ¶ms);
|
r = crypt_load(cd, CRYPT_VERITY, ¶ms);
|
||||||
@@ -326,6 +329,7 @@ static int action_dump(int arg)
|
|||||||
return r;
|
return r;
|
||||||
|
|
||||||
params.hash_area_offset = hash_offset;
|
params.hash_area_offset = hash_offset;
|
||||||
|
params.fec_area_offset = fec_offset;
|
||||||
r = crypt_load(cd, CRYPT_VERITY, ¶ms);
|
r = crypt_load(cd, CRYPT_VERITY, ¶ms);
|
||||||
if (!r)
|
if (!r)
|
||||||
crypt_dump(cd);
|
crypt_dump(cd);
|
||||||
@@ -417,6 +421,7 @@ int main(int argc, const char **argv)
|
|||||||
{ "data-blocks", 0, POPT_ARG_STRING, &popt_tmp, 1, N_("The number of blocks in the data file"), N_("blocks") },
|
{ "data-blocks", 0, POPT_ARG_STRING, &popt_tmp, 1, N_("The number of blocks in the data file"), N_("blocks") },
|
||||||
{ "fec-device", 0, POPT_ARG_STRING, &fec_device, 0, N_("Path to device with error correction data"), N_("path") },
|
{ "fec-device", 0, POPT_ARG_STRING, &fec_device, 0, N_("Path to device with error correction data"), N_("path") },
|
||||||
{ "hash-offset", 0, POPT_ARG_STRING, &popt_tmp, 2, N_("Starting offset on the hash device"), N_("bytes") },
|
{ "hash-offset", 0, POPT_ARG_STRING, &popt_tmp, 2, N_("Starting offset on the hash device"), N_("bytes") },
|
||||||
|
{ "fec-offset", 0, POPT_ARG_STRING, &popt_tmp, 3, N_("Starting offset on the FEC device"), N_("bytes") },
|
||||||
{ "hash", 'h', POPT_ARG_STRING, &hash_algorithm, 0, N_("Hash algorithm"), N_("string") },
|
{ "hash", 'h', POPT_ARG_STRING, &hash_algorithm, 0, N_("Hash algorithm"), N_("string") },
|
||||||
{ "salt", 's', POPT_ARG_STRING, &salt_string, 0, N_("Salt"), N_("hex string") },
|
{ "salt", 's', POPT_ARG_STRING, &salt_string, 0, N_("Salt"), N_("hex string") },
|
||||||
{ "uuid", '\0', POPT_ARG_STRING, &opt_uuid, 0, N_("UUID for device to use."), NULL },
|
{ "uuid", '\0', POPT_ARG_STRING, &opt_uuid, 0, N_("UUID for device to use."), NULL },
|
||||||
@@ -459,6 +464,9 @@ int main(int argc, const char **argv)
|
|||||||
case 2:
|
case 2:
|
||||||
hash_offset = ull_value;
|
hash_offset = ull_value;
|
||||||
break;
|
break;
|
||||||
|
case 3:
|
||||||
|
fec_offset = ull_value;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user