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

Side by Side Diff: dm-bht.c

Issue 6724017: verity: collapse check_block into verify_path (Closed) Base URL: http://git.chromium.org/git/dm-verity.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 | 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 573 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 u8 hex[DM_BHT_MAX_DIGEST_SIZE * 2 + 1]; 584 u8 hex[DM_BHT_MAX_DIGEST_SIZE * 2 + 1];
585 #endif 585 #endif
586 memcpy(known, computed, bht->digest_size); 586 memcpy(known, computed, bht->digest_size);
587 #ifdef CONFIG_DM_DEBUG 587 #ifdef CONFIG_DM_DEBUG
588 dm_bht_bin_to_hex(computed, hex, bht->digest_size); 588 dm_bht_bin_to_hex(computed, hex, bht->digest_size);
589 DMDEBUG("updating with hash: %s", hex); 589 DMDEBUG("updating with hash: %s", hex);
590 #endif 590 #endif
591 return 0; 591 return 0;
592 } 592 }
593 593
594 /* Check the disk block against the leaf hash. */
595 static int dm_bht_check_block(struct dm_bht *bht, unsigned int block_index,
596 const void *block)
597 {
598 unsigned int depth = bht->depth;
599 struct dm_bht_entry *parent = dm_bht_get_entry(bht, depth - 1,
600 block_index);
601 u8 digest[DM_BHT_MAX_DIGEST_SIZE];
602 u8 *node;
603
604 /* This call is only safe if all nodes along the path
605 * are already populated (i.e. READY) via dm_bht_populate.
606 */
607 BUG_ON(atomic_read(&parent->state) < DM_BHT_ENTRY_READY);
608
609 node = dm_bht_get_node(bht, parent, depth, block_index);
610 if (dm_bht_compute_hash(bht, block, digest) ||
611 dm_bht_compare_hash(bht, digest, node)) {
612 DMERR("failed to verify entry's hash against parent "
613 "(d=%u,bi=%u)", depth, block_index);
614 return DM_BHT_ENTRY_ERROR_MISMATCH;
615 }
616 return 0;
617 }
618
619 /* Walk all entries at level 0 to compute the root digest. 594 /* Walk all entries at level 0 to compute the root digest.
620 * 0 on success. 595 * 0 on success.
621 */ 596 */
622 static int dm_bht_compute_root(struct dm_bht *bht, u8 *digest) 597 static int dm_bht_compute_root(struct dm_bht *bht, u8 *digest)
623 { 598 {
624 struct dm_bht_entry *entry; 599 struct dm_bht_entry *entry;
625 unsigned int count; 600 unsigned int count;
626 struct scatterlist sg; /* feeds digest() */ 601 struct scatterlist sg; /* feeds digest() */
627 struct hash_desc *hash_desc; 602 struct hash_desc *hash_desc;
628 hash_desc = &bht->hash_desc[smp_processor_id()]; 603 hash_desc = &bht->hash_desc[smp_processor_id()];
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 DMCRIT("invalid root digest: %d", status); 650 DMCRIT("invalid root digest: %d", status);
676 dm_bht_log_mismatch(bht, bht->root_digest, digest); 651 dm_bht_log_mismatch(bht, bht->root_digest, digest);
677 return DM_BHT_ENTRY_ERROR_MISMATCH; 652 return DM_BHT_ENTRY_ERROR_MISMATCH;
678 } 653 }
679 /* Could do a cmpxchg, but this should be safe. */ 654 /* Could do a cmpxchg, but this should be safe. */
680 atomic_set(&bht->root_state, DM_BHT_ENTRY_VERIFIED); 655 atomic_set(&bht->root_state, DM_BHT_ENTRY_VERIFIED);
681 return 0; 656 return 0;
682 } 657 }
683 658
684 /* dm_bht_verify_path 659 /* dm_bht_verify_path
685 * Verifies the path from block_index to depth=0. Returns 0 on ok. 660 * Verifies the path. Returns 0 on ok.
686 */ 661 */
687 static int dm_bht_verify_path(struct dm_bht *bht, unsigned int block_index) 662 static int dm_bht_verify_path(struct dm_bht *bht, unsigned int block_index,
663 » » » const void *block)
688 { 664 {
689 » unsigned int depth = bht->depth - 1; 665 » unsigned int depth = bht->depth;
690 » struct dm_bht_entry *entry = dm_bht_get_entry(bht, depth, block_index); 666 » struct dm_bht_entry *entry;
691 » int state = atomic_read(&entry->state); 667 » int state;
692 668
693 » while (depth > 0 && state != DM_BHT_ENTRY_VERIFIED) { 669 » do {
694 u8 digest[DM_BHT_MAX_DIGEST_SIZE]; 670 u8 digest[DM_BHT_MAX_DIGEST_SIZE];
695 struct dm_bht_entry *parent;
696 u8 *node; 671 u8 *node;
697 672
698 » » /* We need to check that this entry matches the expected 673 » » /* Need to check that the hash of the current block is accurate
699 » » * hash in the parent->nodes. 674 » » * in its parent.
700 */ 675 */
701 » » parent = dm_bht_get_entry(bht, depth - 1, block_index); 676 » » entry = dm_bht_get_entry(bht, depth - 1, block_index);
702 » » state = atomic_read(&parent->state); 677 » » state = atomic_read(&entry->state);
703 /* This call is only safe if all nodes along the path 678 /* This call is only safe if all nodes along the path
704 * are already populated (i.e. READY) via dm_bht_populate. 679 * are already populated (i.e. READY) via dm_bht_populate.
705 */ 680 */
706 BUG_ON(state < DM_BHT_ENTRY_READY); 681 BUG_ON(state < DM_BHT_ENTRY_READY);
707 » » node = dm_bht_get_node(bht, parent, depth, block_index); 682 » » node = dm_bht_get_node(bht, entry, depth, block_index);
708 683
709 » » if (dm_bht_compute_hash(bht, entry->nodes, digest) || 684 » » if (dm_bht_compute_hash(bht, block, digest) ||
710 dm_bht_compare_hash(bht, digest, node)) 685 dm_bht_compare_hash(bht, digest, node))
711 goto mismatch; 686 goto mismatch;
712 687
713 » » entry = parent; 688 » » /* Keep the containing block of hashes to be verified in the
714 » » depth--; 689 » » * next pass.
715 » } 690 » » */
691 » » block = entry->nodes;
692 » } while (--depth > 0 && state != DM_BHT_ENTRY_VERIFIED);
716 693
717 /* Mark path to leaf as verified. */ 694 /* Mark path to leaf as verified. */
718 for (depth++; depth < bht->depth; depth++) { 695 for (depth++; depth < bht->depth; depth++) {
719 entry = dm_bht_get_entry(bht, depth, block_index); 696 entry = dm_bht_get_entry(bht, depth, block_index);
720 atomic_cmpxchg(&entry->state, 697 atomic_cmpxchg(&entry->state,
721 DM_BHT_ENTRY_READY, 698 DM_BHT_ENTRY_READY,
722 DM_BHT_ENTRY_VERIFIED); 699 DM_BHT_ENTRY_VERIFIED);
723 } 700 }
724 701
725 DMDEBUG("verify_path: node %u is verified to root", block_index); 702 DMDEBUG("verify_path: node %u is verified to root", block_index);
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
1038 * @block: virtual address of the block data in memory 1015 * @block: virtual address of the block data in memory
1039 * (must be aligned to block size) 1016 * (must be aligned to block size)
1040 * 1017 *
1041 * Returns 0 on success, 1 on missing data, and a negative error 1018 * Returns 0 on success, 1 on missing data, and a negative error
1042 * code on verification failure. All supporting functions called 1019 * code on verification failure. All supporting functions called
1043 * should return similarly. 1020 * should return similarly.
1044 */ 1021 */
1045 int dm_bht_verify_block(struct dm_bht *bht, unsigned int block_index, 1022 int dm_bht_verify_block(struct dm_bht *bht, unsigned int block_index,
1046 const void *block) 1023 const void *block)
1047 { 1024 {
1048 » int unverified = 0; 1025 » int r = 0;
1049 1026
1050 /* Make sure that the root has been verified */ 1027 /* Make sure that the root has been verified */
1051 if (atomic_read(&bht->root_state) != DM_BHT_ENTRY_VERIFIED) { 1028 if (atomic_read(&bht->root_state) != DM_BHT_ENTRY_VERIFIED) {
1052 » » unverified = dm_bht_verify_root(bht, dm_bht_compare_hash); 1029 » » r = dm_bht_verify_root(bht, dm_bht_compare_hash);
1053 » » if (unverified) { 1030 » » if (r) {
1054 » » » DMERR_LIMIT("Failed to verify root: %d", unverified); 1031 » » » DMERR_LIMIT("Failed to verify root: %d", r);
1055 » » » return unverified; 1032 » » » goto out;
1056 } 1033 }
1057 } 1034 }
1058 1035
1059 » /* Now check that the digest supplied matches the leaf hash */ 1036 » /* Now check levels in between */
1060 » unverified = dm_bht_check_block(bht, block_index, block); 1037 » r = dm_bht_verify_path(bht, block_index, block);
1061 » if (unverified) { 1038 » if (r)
1062 » » DMERR_LIMIT("Block check failed for %u: %d", block_index, 1039 » » DMERR_LIMIT("Failed to verify block: %u (%d)", block_index, r);
1063 » » » » unverified);
1064 » » return unverified;
1065 » }
1066 1040
1067 » /* Now check levels in between */ 1041 out:
1068 » unverified = dm_bht_verify_path(bht, block_index); 1042 » return r;
1069 » if (unverified)
1070 » » DMERR_LIMIT("Failed to verify intermediary nodes for block: %u ( %d)",
1071 » » block_index, unverified);
1072 » return unverified;
1073 } 1043 }
1074 EXPORT_SYMBOL(dm_bht_verify_block); 1044 EXPORT_SYMBOL(dm_bht_verify_block);
1075 1045
1076 /** 1046 /**
1077 * dm_bht_destroy - cleans up all memory used by @bht 1047 * dm_bht_destroy - cleans up all memory used by @bht
1078 * @bht: pointer to a dm_bht_create()d bht 1048 * @bht: pointer to a dm_bht_create()d bht
1079 * 1049 *
1080 * Returns 0 on success. Does not free @bht itself. 1050 * Returns 0 on success. Does not free @bht itself.
1081 */ 1051 */
1082 int dm_bht_destroy(struct dm_bht *bht) 1052 int dm_bht_destroy(struct dm_bht *bht)
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
1218 DMERR("no root digest exists to export"); 1188 DMERR("no root digest exists to export");
1219 if (available > 0) 1189 if (available > 0)
1220 *hexdigest = 0; 1190 *hexdigest = 0;
1221 return -1; 1191 return -1;
1222 } 1192 }
1223 dm_bht_bin_to_hex(bht->root_digest, hexdigest, bht->digest_size); 1193 dm_bht_bin_to_hex(bht->root_digest, hexdigest, bht->digest_size);
1224 return 0; 1194 return 0;
1225 } 1195 }
1226 EXPORT_SYMBOL(dm_bht_root_hexdigest); 1196 EXPORT_SYMBOL(dm_bht_root_hexdigest);
1227 1197
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