verity: collapse check_block into verify_path
There was a lot of common code between the two functions.
BUG=9752
TEST=Ran tests in verity.git. Ran platform_DMVerityCorruption on H/W.
Signed-off-by: Mandeep Singh Baines <msb@chromium.org>
kernel.git Review URL: http://codereview.chromium.org/6686017
TBRing. Already LGTMed and committed to kernel.git
Change-Id: I1112fedfd7823e1aa54cd3100fbfa8eaf1e3d304
R=wad@chromium.org,taysom@chromium.org,ups@chromium.org
Review URL: http://codereview.chromium.org/6724017
diff --git a/dm-bht.c b/dm-bht.c
index 5f03081..0449b58 100644
--- a/dm-bht.c
+++ b/dm-bht.c
@@ -591,31 +591,6 @@
return 0;
}
-/* Check the disk block against the leaf hash. */
-static int dm_bht_check_block(struct dm_bht *bht, unsigned int block_index,
- const void *block)
-{
- unsigned int depth = bht->depth;
- struct dm_bht_entry *parent = dm_bht_get_entry(bht, depth - 1,
- block_index);
- u8 digest[DM_BHT_MAX_DIGEST_SIZE];
- u8 *node;
-
- /* This call is only safe if all nodes along the path
- * are already populated (i.e. READY) via dm_bht_populate.
- */
- BUG_ON(atomic_read(&parent->state) < DM_BHT_ENTRY_READY);
-
- node = dm_bht_get_node(bht, parent, depth, block_index);
- if (dm_bht_compute_hash(bht, block, digest) ||
- dm_bht_compare_hash(bht, digest, node)) {
- DMERR("failed to verify entry's hash against parent "
- "(d=%u,bi=%u)", depth, block_index);
- return DM_BHT_ENTRY_ERROR_MISMATCH;
- }
- return 0;
-}
-
/* Walk all entries at level 0 to compute the root digest.
* 0 on success.
*/
@@ -682,37 +657,39 @@
}
/* dm_bht_verify_path
- * Verifies the path from block_index to depth=0. Returns 0 on ok.
+ * Verifies the path. Returns 0 on ok.
*/
-static int dm_bht_verify_path(struct dm_bht *bht, unsigned int block_index)
+static int dm_bht_verify_path(struct dm_bht *bht, unsigned int block_index,
+ const void *block)
{
- unsigned int depth = bht->depth - 1;
- struct dm_bht_entry *entry = dm_bht_get_entry(bht, depth, block_index);
- int state = atomic_read(&entry->state);
+ unsigned int depth = bht->depth;
+ struct dm_bht_entry *entry;
+ int state;
- while (depth > 0 && state != DM_BHT_ENTRY_VERIFIED) {
+ do {
u8 digest[DM_BHT_MAX_DIGEST_SIZE];
- struct dm_bht_entry *parent;
u8 *node;
- /* We need to check that this entry matches the expected
- * hash in the parent->nodes.
+ /* Need to check that the hash of the current block is accurate
+ * in its parent.
*/
- parent = dm_bht_get_entry(bht, depth - 1, block_index);
- state = atomic_read(&parent->state);
+ entry = dm_bht_get_entry(bht, depth - 1, block_index);
+ state = atomic_read(&entry->state);
/* This call is only safe if all nodes along the path
* are already populated (i.e. READY) via dm_bht_populate.
*/
BUG_ON(state < DM_BHT_ENTRY_READY);
- node = dm_bht_get_node(bht, parent, depth, block_index);
+ node = dm_bht_get_node(bht, entry, depth, block_index);
- if (dm_bht_compute_hash(bht, entry->nodes, digest) ||
+ if (dm_bht_compute_hash(bht, block, digest) ||
dm_bht_compare_hash(bht, digest, node))
goto mismatch;
- entry = parent;
- depth--;
- }
+ /* Keep the containing block of hashes to be verified in the
+ * next pass.
+ */
+ block = entry->nodes;
+ } while (--depth > 0 && state != DM_BHT_ENTRY_VERIFIED);
/* Mark path to leaf as verified. */
for (depth++; depth < bht->depth; depth++) {
@@ -1045,31 +1022,24 @@
int dm_bht_verify_block(struct dm_bht *bht, unsigned int block_index,
const void *block)
{
- int unverified = 0;
+ int r = 0;
/* Make sure that the root has been verified */
if (atomic_read(&bht->root_state) != DM_BHT_ENTRY_VERIFIED) {
- unverified = dm_bht_verify_root(bht, dm_bht_compare_hash);
- if (unverified) {
- DMERR_LIMIT("Failed to verify root: %d", unverified);
- return unverified;
+ r = dm_bht_verify_root(bht, dm_bht_compare_hash);
+ if (r) {
+ DMERR_LIMIT("Failed to verify root: %d", r);
+ goto out;
}
}
- /* Now check that the digest supplied matches the leaf hash */
- unverified = dm_bht_check_block(bht, block_index, block);
- if (unverified) {
- DMERR_LIMIT("Block check failed for %u: %d", block_index,
- unverified);
- return unverified;
- }
-
/* Now check levels in between */
- unverified = dm_bht_verify_path(bht, block_index);
- if (unverified)
- DMERR_LIMIT("Failed to verify intermediary nodes for block: %u (%d)",
- block_index, unverified);
- return unverified;
+ r = dm_bht_verify_path(bht, block_index, block);
+ if (r)
+ DMERR_LIMIT("Failed to verify block: %u (%d)", block_index, r);
+
+out:
+ return r;
}
EXPORT_SYMBOL(dm_bht_verify_block);