Add code for activation wirh FEC device.

This commit is contained in:
Milan Broz
2017-04-03 10:21:37 +02:00
parent 00419c6c41
commit e8eab081c5
5 changed files with 40 additions and 11 deletions

View File

@@ -370,7 +370,7 @@ static char *get_dm_verity_params(struct crypt_params_verity *vp,
{
int max_size, r, num_options = 0;
char *params = NULL, *hexroot = NULL, *hexsalt = NULL;
char features[256];
char features[256], fec_features[256];
if (!vp || !dmd)
return NULL;
@@ -387,6 +387,15 @@ static char *get_dm_verity_params(struct crypt_params_verity *vp,
if (flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS)
num_options++;
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),
vp->data_size + dmd->u.verity.hash_blocks, vp->fec_roots);
} else
*fec_features = '\0';
if (num_options)
snprintf(features, sizeof(features)-1, " %d%s%s%s", num_options,
(flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) ? " ignore_corruption" : "",
@@ -418,12 +427,12 @@ static char *get_dm_verity_params(struct crypt_params_verity *vp,
goto out;
r = snprintf(params, max_size,
"%u %s %s %u %u %" PRIu64 " %" PRIu64 " %s %s %s %s",
"%u %s %s %u %u %" PRIu64 " %" PRIu64 " %s %s %s%s%s",
vp->hash_type, device_block_path(dmd->data_device),
device_block_path(dmd->u.verity.hash_device),
vp->data_block_size, vp->hash_block_size,
vp->data_size, dmd->u.verity.hash_offset,
vp->hash_name, hexroot, hexsalt, features);
vp->hash_name, hexroot, hexsalt, features, fec_features);
if (r < 0 || r >= max_size) {
crypt_safe_free(params);
params = NULL;

View File

@@ -72,6 +72,7 @@ struct crypt_device {
char *root_hash;
unsigned int root_hash_size;
char *uuid;
struct device *fec_device;
} verity;
struct { /* used in CRYPT_TCRYPT */
struct crypt_params_tcrypt params;
@@ -618,6 +619,10 @@ static int _crypt_load_verity(struct crypt_device *cd, struct crypt_params_verit
(r = crypt_set_data_device(cd, params->data_device)) < 0)
return r;
if (params && params->fec_device &&
(r = device_alloc(&cd->u.verity.fec_device, params->fec_device)) < 0)
return r;
return r;
}
@@ -1039,6 +1044,10 @@ static int _crypt_format_verity(struct crypt_device *cd,
return -EINVAL;
}
if (params->fec_device &&
(r = device_alloc(&cd->u.verity.fec_device, params->fec_device)) < 0)
return r;
hash_size = crypt_hash_size(params->hash_name);
if (hash_size <= 0) {
log_err(cd, _("Hash algorithm %s not supported.\n"),
@@ -1078,6 +1087,8 @@ static int _crypt_format_verity(struct crypt_device *cd,
if (params->flags & CRYPT_VERITY_CREATE_HASH) {
r = VERITY_create(cd, &cd->u.verity.hdr,
cd->u.verity.root_hash, cd->u.verity.root_hash_size);
if (!r && params->fec_device)
r = VERITY_FEC_create(cd, &cd->u.verity.hdr);
if (r)
return r;
}
@@ -1096,12 +1107,6 @@ static int _crypt_format_verity(struct crypt_device *cd,
&cd->u.verity.hdr);
}
if (params->fec_device) {
r = VERITY_FEC_create(cd, &cd->u.verity.hdr);
if (r)
return r;
}
return r;
}
@@ -1379,6 +1384,7 @@ void crypt_free(struct crypt_device *cd)
free(CONST_CAST(void*)cd->u.verity.hdr.salt);
free(cd->u.verity.root_hash);
free(cd->u.verity.uuid);
device_free(cd->u.verity.fec_device);
} else if (!cd->type) {
free(cd->u.none.active_name);
}
@@ -2026,7 +2032,7 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
return -EINVAL;
}
r = VERITY_activate(cd, name, volume_key, volume_key_size,
r = VERITY_activate(cd, name, volume_key, volume_key_size, cd->u.verity.fec_device,
&cd->u.verity.hdr, flags|CRYPT_ACTIVATE_READONLY);
if (r == -EPERM) {

View File

@@ -76,11 +76,13 @@ struct crypt_dm_active_device {
} crypt;
struct {
struct device *hash_device;
struct device *fec_device;
const char *root_hash;
uint32_t root_hash_size;
uint64_t hash_offset; /* hash offset in blocks (not header) */
uint64_t hash_blocks; /* size of hash device (in hash blocks) */
struct crypt_params_verity *vp;
} verity;
} u;

View File

@@ -233,6 +233,7 @@ int VERITY_activate(struct crypt_device *cd,
const char *name,
const char *root_hash,
size_t root_hash_size,
struct device *fec_device,
struct crypt_params_verity *verity_hdr,
uint32_t activation_flags)
{
@@ -256,9 +257,11 @@ int VERITY_activate(struct crypt_device *cd,
dmd.target = DM_VERITY;
dmd.data_device = crypt_data_device(cd);
dmd.u.verity.hash_device = crypt_metadata_device(cd);
dmd.u.verity.fec_device = fec_device;
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.hash_offset = VERITY_hash_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;
dmd.uuid = crypt_get_uuid(cd);
@@ -274,6 +277,13 @@ int VERITY_activate(struct crypt_device *cd,
if (r)
return r;
if (dmd.u.verity.fec_device) {
r = device_block_adjust(cd, dmd.u.verity.fec_device, DEV_OK,
0, NULL, NULL);
if (r)
return r;
}
r = dm_create_device(cd, name, CRYPT_VERITY, &dmd, 0);
if (r < 0 && !(dm_flags() & DM_VERITY_SUPPORTED)) {
log_err(cd, _("Kernel doesn't support dm-verity mapping.\n"));

View File

@@ -29,6 +29,7 @@
struct crypt_device;
struct crypt_params_verity;
struct device;
int VERITY_read_sb(struct crypt_device *cd,
uint64_t sb_offset,
@@ -44,6 +45,7 @@ int VERITY_activate(struct crypt_device *cd,
const char *name,
const char *root_hash,
size_t root_hash_size,
struct device *fec_device,
struct crypt_params_verity *verity_hdr,
uint32_t activation_flags);