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

Side by Side Diff: dm-bht.c

Issue 6072008: verity: extract the compare part out of compute_and_compare (Closed) Base URL: http://git.chromium.org/git/dm-verity.git@master
Patch Set: Created 10 years 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 | no next file » | 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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 u8 computed_hex[DM_BHT_MAX_DIGEST_SIZE * 2 + 1]; 86 u8 computed_hex[DM_BHT_MAX_DIGEST_SIZE * 2 + 1];
87 dm_bht_bin_to_hex(given, given_hex, bht->digest_size); 87 dm_bht_bin_to_hex(given, given_hex, bht->digest_size);
88 dm_bht_bin_to_hex(computed, computed_hex, bht->digest_size); 88 dm_bht_bin_to_hex(computed, computed_hex, bht->digest_size);
89 DMERR_LIMIT("%s != %s", given_hex, computed_hex); 89 DMERR_LIMIT("%s != %s", given_hex, computed_hex);
90 } 90 }
91 91
92 /* Used for turning verifiers into computers */ 92 /* Used for turning verifiers into computers */
93 typedef int (*dm_bht_compare_cb)(struct dm_bht *, u8 *, u8 *); 93 typedef int (*dm_bht_compare_cb)(struct dm_bht *, u8 *, u8 *);
94 94
95 /** 95 /**
96 * dm_bht_compute_and_compare: hashes a page of data; compares it to a hash 96 * dm_bht_compute_and_compare: hashes a page of data; compares it to a hash
Will Drewry 2011/01/11 21:38:45 please update the comment
97 */ 97 */
98 static int dm_bht_compute_and_compare(struct dm_bht *bht, 98 static int dm_bht_compute_hash(struct dm_bht *bht, struct hash_desc *hash_desc,
99 » » » » struct hash_desc *hash_desc, 99 » » » struct page *page, u8 *digest)
100 » » » » struct page *page,
101 » » » » u8 *expected_digest,
102 » » » » dm_bht_compare_cb compare_cb)
103 { 100 {
104 struct scatterlist sg; 101 struct scatterlist sg;
105 u8 digest[DM_BHT_MAX_DIGEST_SIZE];
106 int result;
107 102
108 sg_init_table(&sg, 1); 103 sg_init_table(&sg, 1);
109 sg_set_page(&sg, page, PAGE_SIZE, 0); 104 sg_set_page(&sg, page, PAGE_SIZE, 0);
110 /* Note, this is synchronous. */ 105 /* Note, this is synchronous. */
111 if (crypto_hash_init(hash_desc)) { 106 if (crypto_hash_init(hash_desc)) {
112 DMCRIT("failed to reinitialize crypto hash (proc:%d)", 107 DMCRIT("failed to reinitialize crypto hash (proc:%d)",
113 smp_processor_id()); 108 smp_processor_id());
114 return -EINVAL; 109 return -EINVAL;
115 } 110 }
116 if (crypto_hash_digest(hash_desc, &sg, PAGE_SIZE, digest)) { 111 if (crypto_hash_digest(hash_desc, &sg, PAGE_SIZE, digest)) {
117 DMCRIT("crypto_hash_digest failed"); 112 DMCRIT("crypto_hash_digest failed");
118 return -EINVAL; 113 return -EINVAL;
119 } 114 }
120 115
121 » result = compare_cb(bht, expected_digest, digest); 116 » return 0;
122 #ifdef CONFIG_DM_DEBUG
123 » if (result)
124 » » dm_bht_log_mismatch(bht, expected_digest, digest);
125 #endif
126 » return result;
127 } 117 }
128 118
129 static __always_inline struct dm_bht_level *dm_bht_get_level(struct dm_bht *bht, 119 static __always_inline struct dm_bht_level *dm_bht_get_level(struct dm_bht *bht,
130 unsigned int depth) 120 unsigned int depth)
131 { 121 {
132 return &bht->levels[depth]; 122 return &bht->levels[depth];
133 } 123 }
134 124
135 static __always_inline unsigned int dm_bht_get_level_shift(struct dm_bht *bht, 125 static __always_inline unsigned int dm_bht_get_level_shift(struct dm_bht *bht,
136 unsigned int depth) 126 unsigned int depth)
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 return DM_BHT_ENTRY_ERROR_MISMATCH; 699 return DM_BHT_ENTRY_ERROR_MISMATCH;
710 } 700 }
711 /* Could do a cmpxchg, but this should be safe. */ 701 /* Could do a cmpxchg, but this should be safe. */
712 atomic_set(&bht->root_state, DM_BHT_ENTRY_VERIFIED); 702 atomic_set(&bht->root_state, DM_BHT_ENTRY_VERIFIED);
713 return 0; 703 return 0;
714 } 704 }
715 705
716 /* dm_bht_verify_path 706 /* dm_bht_verify_path
717 * Verifies the path from block_index to depth=0. Returns 0 on ok. 707 * Verifies the path from block_index to depth=0. Returns 0 on ok.
718 */ 708 */
719 static int dm_bht_verify_path(struct dm_bht *bht, unsigned int block_index, 709 static int dm_bht_verify_path(struct dm_bht *bht, unsigned int block_index)
720 » » » dm_bht_compare_cb compare_cb)
721 { 710 {
722 unsigned int depth = bht->depth - 1; 711 unsigned int depth = bht->depth - 1;
723 struct dm_bht_entry *entry = dm_bht_get_entry(bht, depth, block_index); 712 struct dm_bht_entry *entry = dm_bht_get_entry(bht, depth, block_index);
724 struct hash_desc *hash_desc = &bht->hash_desc[smp_processor_id()]; 713 struct hash_desc *hash_desc = &bht->hash_desc[smp_processor_id()];
725 714
726 while (depth > 0) { 715 while (depth > 0) {
716 u8 digest[DM_BHT_MAX_DIGEST_SIZE];
727 struct dm_bht_entry *parent; 717 struct dm_bht_entry *parent;
718 struct page *page;
728 u8 *node; 719 u8 *node;
729 int state; 720 int state;
730 721
731 DMDEBUG("verify_path for b=%u on d=%d", block_index, depth); 722 DMDEBUG("verify_path for b=%u on d=%d", block_index, depth);
732 state = atomic_read(&entry->state); 723 state = atomic_read(&entry->state);
733 if (state == DM_BHT_ENTRY_VERIFIED) { 724 if (state == DM_BHT_ENTRY_VERIFIED) {
734 DMDEBUG("verify_path node %u is verified in parent", 725 DMDEBUG("verify_path node %u is verified in parent",
735 block_index); 726 block_index);
736 entry = dm_bht_get_entry(bht, --depth, block_index); 727 entry = dm_bht_get_entry(bht, --depth, block_index);
737 continue; 728 continue;
(...skipping 16 matching lines...) Expand all
754 745
755 /* We need to check that this entry matches the expected 746 /* We need to check that this entry matches the expected
756 * hash in the parent->nodes. 747 * hash in the parent->nodes.
757 */ 748 */
758 parent = dm_bht_get_entry(bht, depth - 1, block_index); 749 parent = dm_bht_get_entry(bht, depth - 1, block_index);
759 /* This call is only safe if all nodes along the path 750 /* This call is only safe if all nodes along the path
760 * are already populated (i.e. READY) via dm_bht_populate. 751 * are already populated (i.e. READY) via dm_bht_populate.
761 */ 752 */
762 BUG_ON(atomic_read(&parent->state) < DM_BHT_ENTRY_READY); 753 BUG_ON(atomic_read(&parent->state) < DM_BHT_ENTRY_READY);
763 node = dm_bht_get_node(bht, parent, depth, block_index); 754 node = dm_bht_get_node(bht, parent, depth, block_index);
755 page = virt_to_page(entry->nodes);
764 756
765 » » if (dm_bht_compute_and_compare(bht, hash_desc, 757 » » if (dm_bht_compute_hash(bht, hash_desc,»page, digest) ||
Will Drewry 2011/01/11 21:38:45 is there a tab hiding before page or is it a rietv
766 » » » » » virt_to_page(entry->nodes), 758 » » dm_bht_compare_hash(bht, digest, node)) {
767 » » » » » node, compare_cb)) {
768 DMERR("failed to verify entry's hash against parent " 759 DMERR("failed to verify entry's hash against parent "
769 "(d=%u,bi=%u)", depth, block_index); 760 "(d=%u,bi=%u)", depth, block_index);
770 goto mismatch; 761 goto mismatch;
771 } 762 }
772 763
773 if (bht->verify_mode != DM_BHT_FULL_REVERIFY) 764 if (bht->verify_mode != DM_BHT_FULL_REVERIFY)
774 atomic_cmpxchg(&entry->state, 765 atomic_cmpxchg(&entry->state,
775 DM_BHT_ENTRY_READY, 766 DM_BHT_ENTRY_READY,
776 DM_BHT_ENTRY_VERIFIED); 767 DM_BHT_ENTRY_VERIFIED);
777 768
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 } else if (state <= DM_BHT_ENTRY_ERROR) { 844 } else if (state <= DM_BHT_ENTRY_ERROR) {
854 DMCRIT("leaf entry for block %u is invalid", 845 DMCRIT("leaf entry for block %u is invalid",
855 block_index); 846 block_index);
856 return state; 847 return state;
857 } else if (state == DM_BHT_ENTRY_PENDING) { 848 } else if (state == DM_BHT_ENTRY_PENDING) {
858 DMERR("leaf data is pending for block %u", block_index); 849 DMERR("leaf data is pending for block %u", block_index);
859 return 1; 850 return 1;
860 } 851 }
861 852
862 hash_desc = &bht->hash_desc[smp_processor_id()]; 853 hash_desc = &bht->hash_desc[smp_processor_id()];
863 » dm_bht_compute_and_compare(bht, hash_desc, virt_to_page(block_data), 854 » dm_bht_compute_hash(bht, hash_desc, virt_to_page(block_data),
864 » » » » dm_bht_node(bht, entry, node_index), 855 » » » dm_bht_node(bht, entry, node_index));
865 » » » » &dm_bht_update_hash);
866 return 0; 856 return 0;
867 } 857 }
868 EXPORT_SYMBOL(dm_bht_store_block); 858 EXPORT_SYMBOL(dm_bht_store_block);
869 859
870 /** 860 /**
871 * dm_bht_zeroread_callback - read callback which always returns 0s 861 * dm_bht_zeroread_callback - read callback which always returns 0s
872 * @ctx: ignored 862 * @ctx: ignored
873 * @start: ignored 863 * @start: ignored
874 * @data: buffer to write 0s to 864 * @data: buffer to write 0s to
875 * @count: number of sectors worth of data to write 865 * @count: number of sectors worth of data to write
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 if (r < 0) { 914 if (r < 0) {
925 DMCRIT("an error occurred while reading entry"); 915 DMCRIT("an error occurred while reading entry");
926 goto out; 916 goto out;
927 } 917 }
928 918
929 for (i = 0; i < level->count; i++, entry++) { 919 for (i = 0; i < level->count; i++, entry++) {
930 for (j = 0; j < count; j++, child++) { 920 for (j = 0; j < count; j++, child++) {
931 struct page *pg = virt_to_page(child->nodes); 921 struct page *pg = virt_to_page(child->nodes);
932 u8 *node = dm_bht_node(bht, entry, j); 922 u8 *node = dm_bht_node(bht, entry, j);
933 923
934 » » » » r = dm_bht_compute_and_compare(bht, hash_desc, 924 » » » » r = dm_bht_compute_hash(bht, hash_desc,
935 » » » » » » pg, node, dm_bht_update_hash); 925 » » » » » » » pg, node);
936 if (r) { 926 if (r) {
937 DMERR("Failed to update (d=%u,i=%u)", 927 DMERR("Failed to update (d=%u,i=%u)",
938 depth, i); 928 depth, i);
939 goto out; 929 goto out;
940 } 930 }
941 } 931 }
942 } 932 }
943 } 933 }
944 /* Don't forget the root digest! */ 934 /* Don't forget the root digest! */
945 DMDEBUG("Calling verify_root with update_hash"); 935 DMDEBUG("Calling verify_root with update_hash");
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
1133 /* If the entry which contains the block hash is marked verified, then 1123 /* If the entry which contains the block hash is marked verified, then
1134 * it means that its hash has been check with the parent. In addition, 1124 * it means that its hash has been check with the parent. In addition,
1135 * since that is only possible via verify_path, it transitively means 1125 * since that is only possible via verify_path, it transitively means
1136 * it is verified to the root of the tree. If the depth is 1, then it 1126 * it is verified to the root of the tree. If the depth is 1, then it
1137 * means the entry was verified during root verification. 1127 * means the entry was verified during root verification.
1138 */ 1128 */
1139 if (entry_state == DM_BHT_ENTRY_VERIFIED || bht->depth == 1) 1129 if (entry_state == DM_BHT_ENTRY_VERIFIED || bht->depth == 1)
1140 return unverified; 1130 return unverified;
1141 1131
1142 /* Now check levels in between */ 1132 /* Now check levels in between */
1143 » unverified = dm_bht_verify_path(bht, 1133 » unverified = dm_bht_verify_path(bht, block_index);
1144 » » » » » block_index,
1145 » » » » » dm_bht_compare_hash);
1146 if (unverified) 1134 if (unverified)
1147 DMERR_LIMIT("Failed to verify intermediary nodes for block: %u ( %d)", 1135 DMERR_LIMIT("Failed to verify intermediary nodes for block: %u ( %d)",
1148 block_index, unverified); 1136 block_index, unverified);
1149 return unverified; 1137 return unverified;
1150 } 1138 }
1151 EXPORT_SYMBOL(dm_bht_verify_block); 1139 EXPORT_SYMBOL(dm_bht_verify_block);
1152 1140
1153 /** 1141 /**
1154 * dm_bht_destroy - cleans up all memory used by @bht 1142 * dm_bht_destroy - cleans up all memory used by @bht
1155 * @bht: pointer to a dm_bht_create()d bht 1143 * @bht: pointer to a dm_bht_create()d bht
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
1306 DMERR("no root digest exists to export"); 1294 DMERR("no root digest exists to export");
1307 if (available > 0) 1295 if (available > 0)
1308 *hexdigest = 0; 1296 *hexdigest = 0;
1309 return -1; 1297 return -1;
1310 } 1298 }
1311 dm_bht_bin_to_hex(bht->root_digest, hexdigest, bht->digest_size); 1299 dm_bht_bin_to_hex(bht->root_digest, hexdigest, bht->digest_size);
1312 return 0; 1300 return 0;
1313 } 1301 }
1314 EXPORT_SYMBOL(dm_bht_root_hexdigest); 1302 EXPORT_SYMBOL(dm_bht_root_hexdigest);
1315 1303
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698