From e8eab081c5ac0071e132aadb228fbbc01d1beff7 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Mon, 3 Apr 2017 10:21:37 +0200 Subject: [PATCH] Add code for activation wirh FEC device. --- lib/libdevmapper.c | 15 ++++++++++++--- lib/setup.c | 20 +++++++++++++------- lib/utils_dm.h | 2 ++ lib/verity/verity.c | 12 +++++++++++- lib/verity/verity.h | 2 ++ 5 files changed, 40 insertions(+), 11 deletions(-) diff --git a/lib/libdevmapper.c b/lib/libdevmapper.c index 849beab5..50996fa7 100644 --- a/lib/libdevmapper.c +++ b/lib/libdevmapper.c @@ -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; diff --git a/lib/setup.c b/lib/setup.c index 33b0c5c1..fa87503d 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -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) { diff --git a/lib/utils_dm.h b/lib/utils_dm.h index c87e9aa9..bdab5915 100644 --- a/lib/utils_dm.h +++ b/lib/utils_dm.h @@ -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; diff --git a/lib/verity/verity.c b/lib/verity/verity.c index 54b306be..5120fd6e 100644 --- a/lib/verity/verity.c +++ b/lib/verity/verity.c @@ -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")); diff --git a/lib/verity/verity.h b/lib/verity/verity.h index 5bd4f456..a73c428b 100644 --- a/lib/verity/verity.h +++ b/lib/verity/verity.h @@ -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);