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

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

Issue 6684008: CHROMIUM: verity: use sg_set_buf instead of sg_set_page (Closed) Base URL: http://git.chromium.org/git/kernel.git@master
Patch Set: Fix per review. 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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
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_hash: hashes a page of data 96 * dm_bht_compute_hash: hashes a page of data
97 */ 97 */
98 static int dm_bht_compute_hash(struct dm_bht *bht, struct page *page, 98 static int dm_bht_compute_hash(struct dm_bht *bht, const void *block,
99 u8 *digest) 99 u8 *digest)
100 { 100 {
101 struct hash_desc *hash_desc = &bht->hash_desc[smp_processor_id()]; 101 struct hash_desc *hash_desc = &bht->hash_desc[smp_processor_id()];
102 struct scatterlist sg; 102 struct scatterlist sg;
103 103
104 /* TODO(msb): Once we supporting block_size < PAGE_SIZE, change this to:
105 * offset_into_page + length < page_size
106 * For now just check that block is page-aligned.
107 */
108 BUG_ON(!IS_ALIGNED((uintptr_t)block, PAGE_SIZE));
109
104 sg_init_table(&sg, 1); 110 sg_init_table(&sg, 1);
105 » sg_set_page(&sg, page, PAGE_SIZE, 0); 111 » sg_set_buf(&sg, block, PAGE_SIZE);
106 /* Note, this is synchronous. */ 112 /* Note, this is synchronous. */
107 if (crypto_hash_init(hash_desc)) { 113 if (crypto_hash_init(hash_desc)) {
108 DMCRIT("failed to reinitialize crypto hash (proc:%d)", 114 DMCRIT("failed to reinitialize crypto hash (proc:%d)",
109 smp_processor_id()); 115 smp_processor_id());
110 return -EINVAL; 116 return -EINVAL;
111 } 117 }
112 if (crypto_hash_digest(hash_desc, &sg, PAGE_SIZE, digest)) { 118 if (crypto_hash_digest(hash_desc, &sg, PAGE_SIZE, digest)) {
113 DMCRIT("crypto_hash_digest failed"); 119 DMCRIT("crypto_hash_digest failed");
114 return -EINVAL; 120 return -EINVAL;
115 } 121 }
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 block_index); 600 block_index);
595 u8 digest[DM_BHT_MAX_DIGEST_SIZE]; 601 u8 digest[DM_BHT_MAX_DIGEST_SIZE];
596 u8 *node; 602 u8 *node;
597 603
598 /* This call is only safe if all nodes along the path 604 /* This call is only safe if all nodes along the path
599 * are already populated (i.e. READY) via dm_bht_populate. 605 * are already populated (i.e. READY) via dm_bht_populate.
600 */ 606 */
601 BUG_ON(atomic_read(&parent->state) < DM_BHT_ENTRY_READY); 607 BUG_ON(atomic_read(&parent->state) < DM_BHT_ENTRY_READY);
602 608
603 node = dm_bht_get_node(bht, parent, depth, block_index); 609 node = dm_bht_get_node(bht, parent, depth, block_index);
604 » if (dm_bht_compute_hash(bht, virt_to_page(block), digest) || 610 » if (dm_bht_compute_hash(bht, block, digest) ||
605 dm_bht_compare_hash(bht, digest, node)) { 611 dm_bht_compare_hash(bht, digest, node)) {
606 DMERR("failed to verify entry's hash against parent " 612 DMERR("failed to verify entry's hash against parent "
607 "(d=%u,bi=%u)", depth, block_index); 613 "(d=%u,bi=%u)", depth, block_index);
608 return DM_BHT_ENTRY_ERROR_MISMATCH; 614 return DM_BHT_ENTRY_ERROR_MISMATCH;
609 } 615 }
610 return 0; 616 return 0;
611 } 617 }
612 618
613 /* Walk all entries at level 0 to compute the root digest. 619 /* Walk all entries at level 0 to compute the root digest.
614 * 0 on success. 620 * 0 on success.
(...skipping 14 matching lines...) Expand all
629 } 635 }
630 636
631 /* Point the scatterlist to the entries, then compute the digest */ 637 /* Point the scatterlist to the entries, then compute the digest */
632 for (count = 0; count < bht->levels[0].count; ++count, ++entry) { 638 for (count = 0; count < bht->levels[0].count; ++count, ++entry) {
633 if (atomic_read(&entry->state) <= DM_BHT_ENTRY_PENDING) { 639 if (atomic_read(&entry->state) <= DM_BHT_ENTRY_PENDING) {
634 DMCRIT("data not ready to compute root: %u", 640 DMCRIT("data not ready to compute root: %u",
635 count); 641 count);
636 return 1; 642 return 1;
637 } 643 }
638 sg_init_table(&sg, 1); 644 sg_init_table(&sg, 1);
639 » » sg_set_page(&sg, virt_to_page(entry->nodes), PAGE_SIZE, 0); 645 » » sg_set_buf(&sg, entry->nodes, PAGE_SIZE);
640 if (crypto_hash_update(hash_desc, &sg, PAGE_SIZE)) { 646 if (crypto_hash_update(hash_desc, &sg, PAGE_SIZE)) {
641 DMCRIT("Failed to update crypto hash"); 647 DMCRIT("Failed to update crypto hash");
642 return -EINVAL; 648 return -EINVAL;
643 } 649 }
644 } 650 }
645 651
646 if (crypto_hash_final(hash_desc, digest)) { 652 if (crypto_hash_final(hash_desc, digest)) {
647 DMCRIT("Failed to compute final digest"); 653 DMCRIT("Failed to compute final digest");
648 return -EINVAL; 654 return -EINVAL;
649 } 655 }
(...skipping 30 matching lines...) Expand all
680 */ 686 */
681 static int dm_bht_verify_path(struct dm_bht *bht, unsigned int block_index) 687 static int dm_bht_verify_path(struct dm_bht *bht, unsigned int block_index)
682 { 688 {
683 unsigned int depth = bht->depth - 1; 689 unsigned int depth = bht->depth - 1;
684 struct dm_bht_entry *entry = dm_bht_get_entry(bht, depth, block_index); 690 struct dm_bht_entry *entry = dm_bht_get_entry(bht, depth, block_index);
685 int state = atomic_read(&entry->state); 691 int state = atomic_read(&entry->state);
686 692
687 while (depth > 0 && state != DM_BHT_ENTRY_VERIFIED) { 693 while (depth > 0 && state != DM_BHT_ENTRY_VERIFIED) {
688 u8 digest[DM_BHT_MAX_DIGEST_SIZE]; 694 u8 digest[DM_BHT_MAX_DIGEST_SIZE];
689 struct dm_bht_entry *parent; 695 struct dm_bht_entry *parent;
690 struct page *page;
691 u8 *node; 696 u8 *node;
692 697
693 /* We need to check that this entry matches the expected 698 /* We need to check that this entry matches the expected
694 * hash in the parent->nodes. 699 * hash in the parent->nodes.
695 */ 700 */
696 parent = dm_bht_get_entry(bht, depth - 1, block_index); 701 parent = dm_bht_get_entry(bht, depth - 1, block_index);
697 state = atomic_read(&parent->state); 702 state = atomic_read(&parent->state);
698 /* This call is only safe if all nodes along the path 703 /* This call is only safe if all nodes along the path
699 * are already populated (i.e. READY) via dm_bht_populate. 704 * are already populated (i.e. READY) via dm_bht_populate.
700 */ 705 */
701 BUG_ON(state < DM_BHT_ENTRY_READY); 706 BUG_ON(state < DM_BHT_ENTRY_READY);
702 node = dm_bht_get_node(bht, parent, depth, block_index); 707 node = dm_bht_get_node(bht, parent, depth, block_index);
703 page = virt_to_page(entry->nodes);
704 708
705 » » if (dm_bht_compute_hash(bht, page, digest) || 709 » » if (dm_bht_compute_hash(bht, entry->nodes, digest) ||
706 dm_bht_compare_hash(bht, digest, node)) 710 dm_bht_compare_hash(bht, digest, node))
707 goto mismatch; 711 goto mismatch;
708 712
709 entry = parent; 713 entry = parent;
710 depth--; 714 depth--;
711 } 715 }
712 716
713 /* Mark path to leaf as verified. */ 717 /* Mark path to leaf as verified. */
714 for (depth++; depth < bht->depth; depth++) { 718 for (depth++; depth < bht->depth; depth++) {
715 entry = dm_bht_get_entry(bht, depth, block_index); 719 entry = dm_bht_get_entry(bht, depth, block_index);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 atomic_set(&entry->state, DM_BHT_ENTRY_READY); 797 atomic_set(&entry->state, DM_BHT_ENTRY_READY);
794 } else if (state <= DM_BHT_ENTRY_ERROR) { 798 } else if (state <= DM_BHT_ENTRY_ERROR) {
795 DMCRIT("leaf entry for block %u is invalid", 799 DMCRIT("leaf entry for block %u is invalid",
796 block_index); 800 block_index);
797 return state; 801 return state;
798 } else if (state == DM_BHT_ENTRY_PENDING) { 802 } else if (state == DM_BHT_ENTRY_PENDING) {
799 DMERR("leaf data is pending for block %u", block_index); 803 DMERR("leaf data is pending for block %u", block_index);
800 return 1; 804 return 1;
801 } 805 }
802 806
803 » dm_bht_compute_hash(bht, virt_to_page(block_data), 807 » dm_bht_compute_hash(bht, block_data,
804 dm_bht_node(bht, entry, node_index)); 808 dm_bht_node(bht, entry, node_index));
805 return 0; 809 return 0;
806 } 810 }
807 EXPORT_SYMBOL(dm_bht_store_block); 811 EXPORT_SYMBOL(dm_bht_store_block);
808 812
809 /** 813 /**
810 * dm_bht_zeroread_callback - read callback which always returns 0s 814 * dm_bht_zeroread_callback - read callback which always returns 0s
811 * @ctx: ignored 815 * @ctx: ignored
812 * @start: ignored 816 * @start: ignored
813 * @data: buffer to write 0s to 817 * @data: buffer to write 0s to
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 863
860 r = dm_bht_maybe_read_entries(bht, read_cb_ctx, depth, 864 r = dm_bht_maybe_read_entries(bht, read_cb_ctx, depth,
861 0, level->count, true); 865 0, level->count, true);
862 if (r < 0) { 866 if (r < 0) {
863 DMCRIT("an error occurred while reading entry"); 867 DMCRIT("an error occurred while reading entry");
864 goto out; 868 goto out;
865 } 869 }
866 870
867 for (i = 0; i < level->count; i++, entry++) { 871 for (i = 0; i < level->count; i++, entry++) {
868 for (j = 0; j < count; j++, child++) { 872 for (j = 0; j < count; j++, child++) {
869 » » » » struct page *pg = virt_to_page(child->nodes); 873 » » » » u8 *block = child->nodes;
870 » » » » u8 *node = dm_bht_node(bht, entry, j); 874 » » » » u8 *digest = dm_bht_node(bht, entry, j);
871 875
872 » » » » r = dm_bht_compute_hash(bht, pg, node); 876 » » » » r = dm_bht_compute_hash(bht, block, digest);
873 if (r) { 877 if (r) {
874 DMERR("Failed to update (d=%u,i=%u)", 878 DMERR("Failed to update (d=%u,i=%u)",
875 depth, i); 879 depth, i);
876 goto out; 880 goto out;
877 } 881 }
878 } 882 }
879 } 883 }
880 } 884 }
881 /* Don't forget the root digest! */ 885 /* Don't forget the root digest! */
882 DMDEBUG("Calling verify_root with update_hash"); 886 DMDEBUG("Calling verify_root with update_hash");
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1025 return populated; 1029 return populated;
1026 } 1030 }
1027 EXPORT_SYMBOL(dm_bht_populate); 1031 EXPORT_SYMBOL(dm_bht_populate);
1028 1032
1029 1033
1030 /** 1034 /**
1031 * dm_bht_verify_block - checks that all nodes in the path for @block are valid 1035 * dm_bht_verify_block - checks that all nodes in the path for @block are valid
1032 * @bht: pointer to a dm_bht_create()d bht 1036 * @bht: pointer to a dm_bht_create()d bht
1033 * @block_index:specific block data is expected from 1037 * @block_index:specific block data is expected from
1034 * @block: virtual address of the block data in memory 1038 * @block: virtual address of the block data in memory
1039 * (must be aligned to block size)
1035 * 1040 *
1036 * Returns 0 on success, 1 on missing data, and a negative error 1041 * Returns 0 on success, 1 on missing data, and a negative error
1037 * code on verification failure. All supporting functions called 1042 * code on verification failure. All supporting functions called
1038 * should return similarly. 1043 * should return similarly.
1039 */ 1044 */
1040 int dm_bht_verify_block(struct dm_bht *bht, unsigned int block_index, 1045 int dm_bht_verify_block(struct dm_bht *bht, unsigned int block_index,
1041 const void *block) 1046 const void *block)
1042 { 1047 {
1043 int unverified = 0; 1048 int unverified = 0;
1044 1049
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1213 DMERR("no root digest exists to export"); 1218 DMERR("no root digest exists to export");
1214 if (available > 0) 1219 if (available > 0)
1215 *hexdigest = 0; 1220 *hexdigest = 0;
1216 return -1; 1221 return -1;
1217 } 1222 }
1218 dm_bht_bin_to_hex(bht->root_digest, hexdigest, bht->digest_size); 1223 dm_bht_bin_to_hex(bht->root_digest, hexdigest, bht->digest_size);
1219 return 0; 1224 return 0;
1220 } 1225 }
1221 EXPORT_SYMBOL(dm_bht_root_hexdigest); 1226 EXPORT_SYMBOL(dm_bht_root_hexdigest);
1222 1227
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