mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-11 19:00:02 +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) */
|
||||
uint64_t data_size; /**< data area size (in data blocks) */
|
||||
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 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) {
|
||||
num_options += 8;
|
||||
snprintf(fec_features, sizeof(fec_features)-1,
|
||||
" use_fec_from_device %s fec_start 0 fec_blocks %" PRIu64 " fec_roots %" PRIu32,
|
||||
device_block_path(dmd->u.verity.fec_device),
|
||||
" use_fec_from_device %s fec_start %" PRIu64 " fec_blocks %" PRIu64 " fec_roots %" PRIu32,
|
||||
device_block_path(dmd->u.verity.fec_device), dmd->u.verity.fec_offset,
|
||||
vp->data_size + dmd->u.verity.hash_blocks, vp->fec_roots);
|
||||
} else
|
||||
*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.hash_block_size = params.hash_block_size;
|
||||
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.flags = params.flags;
|
||||
cd->u.verity.hdr.salt_size = params.salt_size;
|
||||
@@ -1023,6 +1024,11 @@ static int _crypt_format_verity(struct crypt_device *cd,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (params->fec_area_offset % 512) {
|
||||
log_err(cd, _("Unsupported VERITY FEC offset.\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!(cd->type = strdup(CRYPT_VERITY)))
|
||||
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.hash_block_size = params->hash_block_size;
|
||||
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.flags = params->flags;
|
||||
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_blocks; /* size of hash device (in hash blocks) */
|
||||
uint64_t fec_offset; /* FEC offset in blocks (not header) */
|
||||
struct crypt_params_verity *vp;
|
||||
} verity;
|
||||
} u;
|
||||
|
||||
@@ -67,6 +67,21 @@ struct fec_context {
|
||||
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) */
|
||||
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;
|
||||
}
|
||||
|
||||
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 */
|
||||
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_size = root_hash_size;
|
||||
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.flags = activation_flags;
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
off_t hash_position = (off_t)params->hash_area_offset;
|
||||
int levels;
|
||||
off_t hash_position = 0;
|
||||
int levels = 0;
|
||||
|
||||
if (hash_levels(params->hash_block_size, crypt_get_volume_key_size(cd),
|
||||
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 const char *salt_string = NULL;
|
||||
static uint64_t hash_offset = 0;
|
||||
static uint64_t fec_offset = 0;
|
||||
static const char *opt_uuid = NULL;
|
||||
static int opt_restart_on_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->data_size = data_blocks;
|
||||
params->hash_area_offset = hash_offset;
|
||||
params->fec_area_offset = fec_offset;
|
||||
params->hash_type = hash_type;
|
||||
params->flags = flags;
|
||||
|
||||
@@ -155,6 +157,7 @@ static int _activate(const char *dm_device,
|
||||
if (use_superblock) {
|
||||
params.flags = flags;
|
||||
params.hash_area_offset = hash_offset;
|
||||
params.fec_area_offset = fec_offset;
|
||||
params.fec_device = fec_device;
|
||||
params.fec_roots = fec_roots;
|
||||
r = crypt_load(cd, CRYPT_VERITY, ¶ms);
|
||||
@@ -326,6 +329,7 @@ static int action_dump(int arg)
|
||||
return r;
|
||||
|
||||
params.hash_area_offset = hash_offset;
|
||||
params.fec_area_offset = fec_offset;
|
||||
r = crypt_load(cd, CRYPT_VERITY, ¶ms);
|
||||
if (!r)
|
||||
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") },
|
||||
{ "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") },
|
||||
{ "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") },
|
||||
{ "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 },
|
||||
@@ -459,6 +464,9 @@ int main(int argc, const char **argv)
|
||||
case 2:
|
||||
hash_offset = ull_value;
|
||||
break;
|
||||
case 3:
|
||||
fec_offset = ull_value;
|
||||
break;
|
||||
}
|
||||
|
||||
if (r < 0)
|
||||
|
||||
Reference in New Issue
Block a user