Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(730)

Side by Side Diff: drivers/md/dm-bht.c

Issue 6626037: CHROMIUM: verity: do all hashing in dm-bht.c (Closed) Base URL: http://git.chromium.org/git/kernel.git@master
Patch Set: Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | drivers/md/dm-verity.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 The Chromium OS Authors <chromium-os-dev@chromium.org> 2 * Copyright (C) 2010 The Chromium OS Authors <chromium-os-dev@chromium.org>
3 * 3 *
4 * Device-Mapper block hash tree interface. 4 * Device-Mapper block hash tree interface.
5 * See Documentation/device-mapper/dm-bht.txt for details. 5 * See Documentation/device-mapper/dm-bht.txt for details.
6 * 6 *
7 * This file is released under the GPL. 7 * This file is released under the GPL.
8 */ 8 */
9 9
10 #include <asm/atomic.h> 10 #include <asm/atomic.h>
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 156
157 return &level->entries[index]; 157 return &level->entries[index];
158 } 158 }
159 159
160 static inline u8 *dm_bht_get_node(struct dm_bht *bht, 160 static inline u8 *dm_bht_get_node(struct dm_bht *bht,
161 struct dm_bht_entry *entry, 161 struct dm_bht_entry *entry,
162 unsigned int depth, 162 unsigned int depth,
163 unsigned int block_index) 163 unsigned int block_index)
164 { 164 {
165 unsigned int index = dm_bht_index_at_level(bht, depth, block_index); 165 unsigned int index = dm_bht_index_at_level(bht, depth, block_index);
166 struct dm_bht_level *level = dm_bht_get_level(bht, depth);
167
168 BUG_ON(index >= level->count);
169 166
170 return dm_bht_node(bht, entry, index % bht->node_count); 167 return dm_bht_node(bht, entry, index % bht->node_count);
171 } 168 }
172 169
173 170
174 /*----------------------------------------------- 171 /*-----------------------------------------------
175 * Implementation functions 172 * Implementation functions
176 *-----------------------------------------------*/ 173 *-----------------------------------------------*/
177 174
178 static int dm_bht_initialize_entries(struct dm_bht *bht); 175 static int dm_bht_initialize_entries(struct dm_bht *bht);
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 memcpy(known, computed, bht->digest_size); 580 memcpy(known, computed, bht->digest_size);
584 #ifdef CONFIG_DM_DEBUG 581 #ifdef CONFIG_DM_DEBUG
585 dm_bht_bin_to_hex(computed, hex, bht->digest_size); 582 dm_bht_bin_to_hex(computed, hex, bht->digest_size);
586 DMDEBUG("updating with hash: %s", hex); 583 DMDEBUG("updating with hash: %s", hex);
587 #endif 584 #endif
588 return 0; 585 return 0;
589 } 586 }
590 587
591 /* digest length and bht must be checked already */ 588 /* digest length and bht must be checked already */
592 static int dm_bht_check_block(struct dm_bht *bht, unsigned int block_index, 589 static int dm_bht_check_block(struct dm_bht *bht, unsigned int block_index,
593 » » » u8 *digest, int *entry_state) 590 » » » const void *buf, int *entry_state)
Will Drewry 2011/03/08 20:53:59 nit: might prefer something more meaningful like "
594 { 591 {
595 » int depth; 592 » unsigned int depth = bht->depth;
596 » unsigned int index; 593 » struct dm_bht_entry *parent = dm_bht_get_entry(bht, depth - 1,
597 » struct dm_bht_entry *entry; 594 » » » » » » block_index);
598 595 » struct hash_desc *hash_desc = &bht->hash_desc[smp_processor_id()];
599 » /* The leaves contain the block hashes */ 596 » u8 digest[DM_BHT_MAX_DIGEST_SIZE];
600 » depth = bht->depth - 1; 597 » u8 *node;
601
602 » /* Index into the bottom level. Each entry in this level contains
603 » * nodes whose hashes are the direct hashes of one block of data on
604 » * disk.
605 » */
606 » index = block_index >> bht->node_count_shift;
607 » entry = &bht->levels[depth].entries[index];
608 598
609 /* This call is only safe if all nodes along the path 599 /* This call is only safe if all nodes along the path
610 * are already populated (i.e. READY) via dm_bht_populate. 600 * are already populated (i.e. READY) via dm_bht_populate.
611 */ 601 */
612 » BUG_ON(atomic_read(&entry->state) < DM_BHT_ENTRY_READY); 602 » *entry_state = atomic_read(&parent->state);
603 » BUG_ON(*entry_state < DM_BHT_ENTRY_READY);
613 604
614 » /* Index into the entry data */ 605 » node = dm_bht_get_node(bht, parent, depth, block_index);
615 » index = (block_index % bht->node_count) * bht->digest_size; 606 » if (dm_bht_compute_hash(bht, hash_desc, virt_to_page(buf), digest) ||
616 » if (memcmp(&entry->nodes[index], digest, bht->digest_size)) { 607 » dm_bht_compare_hash(bht, digest, node)) {
617 » » DMCRIT("digest mismatch for block %u", block_index); 608 » » DMERR("failed to verify entry's hash against parent "
618 » » dm_bht_log_mismatch(bht, &entry->nodes[index], digest); 609 » » "(d=%u,bi=%u)", depth, block_index);
619 return DM_BHT_ENTRY_ERROR_MISMATCH; 610 return DM_BHT_ENTRY_ERROR_MISMATCH;
620 } 611 }
621 return 0; 612 return 0;
622 } 613 }
623 614
624 /* Walk all entries at level 0 to compute the root digest. 615 /* Walk all entries at level 0 to compute the root digest.
625 * 0 on success. 616 * 0 on success.
626 */ 617 */
627 static int dm_bht_compute_root(struct dm_bht *bht, u8 *digest) 618 static int dm_bht_compute_root(struct dm_bht *bht, u8 *digest)
628 { 619 {
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
1062 * @bht: pointer to a dm_bht_create()d bht 1053 * @bht: pointer to a dm_bht_create()d bht
1063 * @block_index:specific block data is expected from 1054 * @block_index:specific block data is expected from
1064 * @digest: computed digest for the given block to be checked 1055 * @digest: computed digest for the given block to be checked
1065 * @digest_len: length of @digest 1056 * @digest_len: length of @digest
1066 * 1057 *
1067 * Returns 0 on success, 1 on missing data, and a negative error 1058 * Returns 0 on success, 1 on missing data, and a negative error
1068 * code on verification failure. All supporting functions called 1059 * code on verification failure. All supporting functions called
1069 * should return similarly. 1060 * should return similarly.
1070 */ 1061 */
1071 int dm_bht_verify_block(struct dm_bht *bht, unsigned int block_index, 1062 int dm_bht_verify_block(struct dm_bht *bht, unsigned int block_index,
1072 » » » » u8 *digest, unsigned int digest_len) 1063 » » » const void *buf)
Will Drewry 2011/03/08 20:53:59 Please update the comments.
1073 { 1064 {
1074 int unverified = 0; 1065 int unverified = 0;
1075 int entry_state = 0; 1066 int entry_state = 0;
1076 1067
1077 /* TODO(wad) do we really need this? */
1078 if (digest_len != bht->digest_size) {
1079 DMERR("invalid digest_len passed to verify_block");
1080 return -EINVAL;
1081 }
1082
1083 /* Make sure that the root has been verified */ 1068 /* Make sure that the root has been verified */
1084 if (atomic_read(&bht->root_state) != DM_BHT_ENTRY_VERIFIED) { 1069 if (atomic_read(&bht->root_state) != DM_BHT_ENTRY_VERIFIED) {
1085 unverified = dm_bht_verify_root(bht, dm_bht_compare_hash); 1070 unverified = dm_bht_verify_root(bht, dm_bht_compare_hash);
1086 if (unverified) { 1071 if (unverified) {
1087 DMERR_LIMIT("Failed to verify root: %d", unverified); 1072 DMERR_LIMIT("Failed to verify root: %d", unverified);
1088 return unverified; 1073 return unverified;
1089 } 1074 }
1090 } 1075 }
1091 1076
1092 /* Now check that the digest supplied matches the leaf hash */ 1077 /* Now check that the digest supplied matches the leaf hash */
1093 » unverified = dm_bht_check_block(bht, block_index, digest, &entry_state); 1078 » unverified = dm_bht_check_block(bht, block_index, buf, &entry_state);
1094 if (unverified) { 1079 if (unverified) {
1095 DMERR_LIMIT("Block check failed for %u: %d", block_index, 1080 DMERR_LIMIT("Block check failed for %u: %d", block_index,
1096 unverified); 1081 unverified);
1097 return unverified; 1082 return unverified;
1098 } 1083 }
1099 1084
1100 /* If the entry which contains the block hash is marked verified, then 1085 /* If the entry which contains the block hash is marked verified, then
1101 * it means that its hash has been check with the parent. In addition, 1086 * it means that its hash has been check with the parent. In addition,
1102 * since that is only possible via verify_path, it transitively means 1087 * since that is only possible via verify_path, it transitively means
1103 * it is verified to the root of the tree. If the depth is 1, then it 1088 * it is verified to the root of the tree. If the depth is 1, then it
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1271 DMERR("no root digest exists to export"); 1256 DMERR("no root digest exists to export");
1272 if (available > 0) 1257 if (available > 0)
1273 *hexdigest = 0; 1258 *hexdigest = 0;
1274 return -1; 1259 return -1;
1275 } 1260 }
1276 dm_bht_bin_to_hex(bht->root_digest, hexdigest, bht->digest_size); 1261 dm_bht_bin_to_hex(bht->root_digest, hexdigest, bht->digest_size);
1277 return 0; 1262 return 0;
1278 } 1263 }
1279 EXPORT_SYMBOL(dm_bht_root_hexdigest); 1264 EXPORT_SYMBOL(dm_bht_root_hexdigest);
1280 1265
OLDNEW
« no previous file with comments | « no previous file | drivers/md/dm-verity.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698