mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Verity: dump device sizes.
Calculating device sizes for verity devices is a little bit tricky, Data, hash and FEC can share devices or it can be a separate devices. This patch prints used device sizes in veritysetup dump command, but it requires that user specifies all values that are not stored in superblock (like a FEC device and FEC roots).
This commit is contained in:
@@ -5116,7 +5116,8 @@ int crypt_dump(struct crypt_device *cd)
|
||||
return LUKS2_hdr_dump(cd, &cd->u.luks2.hdr);
|
||||
else if (isVERITY(cd->type))
|
||||
return VERITY_dump(cd, &cd->u.verity.hdr,
|
||||
cd->u.verity.root_hash, cd->u.verity.root_hash_size);
|
||||
cd->u.verity.root_hash, cd->u.verity.root_hash_size,
|
||||
cd->u.verity.fec_device);
|
||||
else if (isTCRYPT(cd->type))
|
||||
return TCRYPT_dump(cd, &cd->u.tcrypt.hdr, &cd->u.tcrypt.params);
|
||||
else if (isINTEGRITY(cd->type))
|
||||
|
||||
@@ -355,15 +355,40 @@ out:
|
||||
int VERITY_dump(struct crypt_device *cd,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
const char *root_hash,
|
||||
unsigned int root_hash_size)
|
||||
unsigned int root_hash_size,
|
||||
struct device *fec_device)
|
||||
{
|
||||
uint64_t hash_blocks, verity_blocks, fec_blocks = 0, rs_blocks = 0;
|
||||
bool fec_on_hash_device = false;
|
||||
|
||||
hash_blocks = VERITY_hash_blocks(cd, verity_hdr);
|
||||
verity_blocks = VERITY_hash_offset_block(verity_hdr) + hash_blocks;
|
||||
|
||||
if (fec_device && verity_hdr->fec_roots) {
|
||||
fec_blocks = VERITY_FEC_blocks(cd, fec_device, verity_hdr);
|
||||
rs_blocks = VERITY_FEC_RS_blocks(fec_blocks, verity_hdr->fec_roots);
|
||||
fec_on_hash_device = device_is_identical(crypt_metadata_device(cd), fec_device) > 0;
|
||||
/*
|
||||
* No way to access fec_area_offset directly.
|
||||
* Assume FEC area starts directly after hash blocks.
|
||||
*/
|
||||
if (fec_on_hash_device)
|
||||
verity_blocks += rs_blocks;
|
||||
}
|
||||
|
||||
log_std(cd, "VERITY header information for %s\n", device_path(crypt_metadata_device(cd)));
|
||||
log_std(cd, "UUID: \t%s\n", crypt_get_uuid(cd) ?: "");
|
||||
log_std(cd, "Hash type: \t%u\n", verity_hdr->hash_type);
|
||||
log_std(cd, "Data blocks: \t%" PRIu64 "\n", verity_hdr->data_size);
|
||||
log_std(cd, "Data block size: \t%u\n", verity_hdr->data_block_size);
|
||||
log_std(cd, "Hash blocks: \t%" PRIu64 "\n", hash_blocks);
|
||||
log_std(cd, "Hash block size: \t%u\n", verity_hdr->hash_block_size);
|
||||
log_std(cd, "Hash algorithm: \t%s\n", verity_hdr->hash_name);
|
||||
if (fec_device && fec_blocks) {
|
||||
log_std(cd, "FEC RS roots: \t%" PRIu32 "\n", verity_hdr->fec_roots);
|
||||
log_std(cd, "FEC blocks: \t%" PRIu64 "\n", rs_blocks);
|
||||
}
|
||||
|
||||
log_std(cd, "Salt: \t");
|
||||
if (verity_hdr->salt_size)
|
||||
crypt_log_hex(cd, verity_hdr->salt, verity_hdr->salt_size, "", 0, NULL);
|
||||
@@ -377,5 +402,12 @@ int VERITY_dump(struct crypt_device *cd,
|
||||
log_std(cd, "\n");
|
||||
}
|
||||
|
||||
/* As dump can take only hash device, we have no idea about offsets here. */
|
||||
if (verity_hdr->hash_area_offset == 0)
|
||||
log_std(cd, "Hash device size: \t%" PRIu64 " [bytes]\n", verity_blocks * verity_hdr->hash_block_size);
|
||||
|
||||
if (fec_device && verity_hdr->fec_area_offset == 0 && fec_blocks && !fec_on_hash_device)
|
||||
log_std(cd, "FEC device size: \t%" PRIu64 " [bytes]\n", rs_blocks * verity_hdr->data_block_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -74,12 +74,14 @@ uint64_t VERITY_hash_blocks(struct crypt_device *cd, struct crypt_params_verity
|
||||
uint64_t VERITY_FEC_blocks(struct crypt_device *cd,
|
||||
struct device *fec_device,
|
||||
struct crypt_params_verity *params);
|
||||
uint64_t VERITY_FEC_RS_blocks(uint64_t blocks, uint32_t roots);
|
||||
|
||||
int VERITY_UUID_generate(char **uuid_string);
|
||||
|
||||
int VERITY_dump(struct crypt_device *cd,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
const char *root_hash,
|
||||
unsigned int root_hash_size);
|
||||
unsigned int root_hash_size,
|
||||
struct device *fec_device);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -202,6 +202,22 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int VERITY_FEC_validate(struct crypt_device *cd, struct crypt_params_verity *params)
|
||||
{
|
||||
if (params->data_block_size != params->hash_block_size) {
|
||||
log_err(cd, _("Block sizes must match for FEC."));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (params->fec_roots > FEC_RSM - FEC_MIN_RSN ||
|
||||
params->fec_roots < FEC_RSM - FEC_MAX_RSN) {
|
||||
log_err(cd, _("Invalid number of parity bytes."));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int VERITY_FEC_process(struct crypt_device *cd,
|
||||
struct crypt_params_verity *params,
|
||||
struct device *fec_device, int check_fec,
|
||||
@@ -224,16 +240,9 @@ int VERITY_FEC_process(struct crypt_device *cd,
|
||||
};
|
||||
|
||||
/* validate parameters */
|
||||
if (params->data_block_size != params->hash_block_size) {
|
||||
log_err(cd, _("Block sizes must match for FEC."));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (params->fec_roots > FEC_RSM - FEC_MIN_RSN ||
|
||||
params->fec_roots < FEC_RSM - FEC_MAX_RSN) {
|
||||
log_err(cd, _("Invalid number of parity bytes."));
|
||||
return -EINVAL;
|
||||
}
|
||||
r = VERITY_FEC_validate(cd, params);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!inputs[0].count) {
|
||||
log_err(cd, _("Invalid FEC segment length."));
|
||||
@@ -281,12 +290,16 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
/* All blocks that are covered by FEC */
|
||||
uint64_t VERITY_FEC_blocks(struct crypt_device *cd,
|
||||
struct device *fec_device,
|
||||
struct crypt_params_verity *params)
|
||||
{
|
||||
uint64_t blocks = 0;
|
||||
|
||||
if (!fec_device || VERITY_FEC_validate(cd, params) < 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* FEC covers this data:
|
||||
* | protected data | hash area | padding (optional foreign metadata) |
|
||||
@@ -315,3 +328,9 @@ uint64_t VERITY_FEC_blocks(struct crypt_device *cd,
|
||||
|
||||
return blocks;
|
||||
}
|
||||
|
||||
/* Blocks needed to store FEC data, blocks must be validated/calculated by VERITY_FEC_blocks() */
|
||||
uint64_t VERITY_FEC_RS_blocks(uint64_t blocks, uint32_t roots)
|
||||
{
|
||||
return FEC_div_round_up(blocks, FEC_RSM - roots) * roots;
|
||||
}
|
||||
|
||||
@@ -459,6 +459,9 @@ static int action_dump(void)
|
||||
|
||||
params.hash_area_offset = ARG_UINT64(OPT_HASH_OFFSET_ID);
|
||||
params.fec_area_offset = ARG_UINT64(OPT_FEC_OFFSET_ID);
|
||||
params.fec_device = ARG_STR(OPT_FEC_DEVICE_ID);
|
||||
params.fec_roots = ARG_UINT32(OPT_FEC_ROOTS_ID);
|
||||
|
||||
r = crypt_load(cd, CRYPT_VERITY, ¶ms);
|
||||
if (!r)
|
||||
crypt_dump(cd);
|
||||
|
||||
Reference in New Issue
Block a user