verity: remove the depth parameter from bht_create

We want to only support regular tries with a single root hash block.

BUG=chromium-os9752
TEST=Ran dm-verity.git unit tests. Ran platform_DMVerityCorruption on H/W.

Change-Id: I49a8b74b8343c4cb5aa871a81b45f06025fe1011

R=wad@chromium.org,taysom@chromium.org,ups@chromium.org

Review URL: http://codereview.chromium.org/6811030
diff --git a/dm-bht.c b/dm-bht.c
index 1665c74..e3da9c5 100644
--- a/dm-bht.c
+++ b/dm-bht.c
@@ -204,8 +204,8 @@
  * Callers can offset into devices by storing the data in the io callbacks.
  * TODO(wad) bust up into smaller helpers
  */
-int dm_bht_create(struct dm_bht *bht, unsigned int depth,
-		  unsigned int block_count, const char *alg_name)
+int dm_bht_create(struct dm_bht *bht, unsigned int block_count,
+		  const char *alg_name)
 {
 	int status = 0;
 	int cpu = 0;
@@ -282,20 +282,11 @@
 		goto bad_node_count;
 	}
 
-	/* if depth == 0, create a "regular" trie with a single root block */
-	if (depth == 0)
-		depth = DIV_ROUND_UP(fls(block_count - 1),
-				     bht->node_count_shift);
-	if (depth > UINT_MAX / sizeof(struct dm_bht_level)) {
-		DMERR("bht depth is invalid: %u", depth);
-		status = -EINVAL;
-		goto bad_depth;
-	}
-	DMDEBUG("Setting depth to %u.", depth);
-	bht->depth = depth;
+	bht->depth = DIV_ROUND_UP(fls(block_count - 1), bht->node_count_shift);
+	DMDEBUG("Setting depth to %u.", bht->depth);
 
 	/* Ensure that we can safely shift by this value. */
-	if (depth * bht->node_count_shift >= sizeof(unsigned int) * 8) {
+	if (bht->depth * bht->node_count_shift >= sizeof(unsigned int) * 8) {
 		DMERR("specified depth and node_count_shift is too large");
 		status = -EINVAL;
 		goto bad_node_count;
@@ -307,7 +298,8 @@
 	 * nodes on the subsequent level or of a specific block on disk.
 	 */
 	bht->levels = (struct dm_bht_level *)
-			kcalloc(depth, sizeof(struct dm_bht_level), GFP_KERNEL);
+			kcalloc(bht->depth,
+				sizeof(struct dm_bht_level), GFP_KERNEL);
 	if (!bht->levels) {
 		DMERR("failed to allocate tree levels");
 		status = -ENOMEM;
@@ -331,7 +323,6 @@
 bad_node_count:
 bad_level_alloc:
 bad_block_count:
-bad_depth:
 	kfree(bht->root_digest);
 bad_root_digest_alloc:
 bad_digest_len:
diff --git a/dm-bht.h b/dm-bht.h
index 3106079..e7269f6 100644
--- a/dm-bht.h
+++ b/dm-bht.h
@@ -110,7 +110,6 @@
 
 /* Constructor for struct dm_bht instances. */
 int dm_bht_create(struct dm_bht *bht,
-		  unsigned int depth,
 		  unsigned int block_count,
 		  const char *alg_name);
 /* Destructor for struct dm_bht instances.  Does not free @bht */
diff --git a/dm-bht_unittest.cc b/dm-bht_unittest.cc
index 8976418..f0c090c 100644
--- a/dm-bht_unittest.cc
+++ b/dm-bht_unittest.cc
@@ -29,12 +29,10 @@
   return memptr;
 }
 
-
-
 TEST(DmBht, CreateFailOnOverflow) {
   struct dm_bht bht;
   // This should fail.
-  EXPECT_EQ(-EINVAL, dm_bht_create(&bht, 32, 1, "sha256"));
+  EXPECT_EQ(-EINVAL, dm_bht_create(&bht, UINT_MAX, "sha1"));
 }
 
 // Simple test to help valgrind/tcmalloc catch bad mem management
@@ -46,7 +44,7 @@
 
   // Store all the block hashes of blocks of 0.
   memset(reinterpret_cast<void *>(data), 0, sizeof(data));
-  EXPECT_EQ(0, dm_bht_create(&bht, 2, blocks, "sha256"));
+  EXPECT_EQ(0, dm_bht_create(&bht, blocks, "sha256"));
   dm_bht_set_read_cb(&bht, dm_bht_zeroread_callback);
   do {
     EXPECT_EQ(dm_bht_store_block(&bht, blocks - 1, data), 0);
@@ -101,11 +99,10 @@
 
  protected:
   // Creates a new dm_bht and sets it in the existing MemoryBht.
-  void NewBht(const unsigned int depth,
-              const unsigned int total_blocks,
+  void NewBht(const unsigned int total_blocks,
               const char *digest_algorithm) {
     bht_.reset(new dm_bht());
-    EXPECT_EQ(0, dm_bht_create(bht_.get(),depth, total_blocks,
+    EXPECT_EQ(0, dm_bht_create(bht_.get(), total_blocks,
                                digest_algorithm));
     if (hash_data_.get() == NULL) {
       sectors_ = dm_bht_sectors(bht_.get());
@@ -114,10 +111,9 @@
     dm_bht_set_write_cb(bht_.get(), MemoryBhtTest::WriteCallback);
     dm_bht_set_read_cb(bht_.get(), MemoryBhtTest::ReadCallback);
   }
-  void SetupBht(const unsigned int depth,
-                const unsigned int total_blocks,
+  void SetupBht(const unsigned int total_blocks,
                 const char *digest_algorithm) {
-    NewBht(depth, total_blocks, digest_algorithm);
+    NewBht(total_blocks, digest_algorithm);
 
     u8 *data = (u8 *)my_memalign(PAGE_SIZE, PAGE_SIZE);
 
@@ -137,7 +133,7 @@
     EXPECT_EQ(0, dm_bht_destroy(bht_.get()));
     // bht is now dead and mbht_ is a prepared hash image
 
-    NewBht(depth, total_blocks, digest_algorithm);
+    NewBht(total_blocks, digest_algorithm);
 
     // Load the tree from the pre-populated hash data
     for (blocks = 0; blocks < total_blocks; blocks += bht_->node_count) {
@@ -170,7 +166,7 @@
 
   memset(zero_page, 0, PAGE_SIZE);
 
-  SetupBht(2, total_blocks, "sha256");
+  SetupBht(total_blocks, "sha256");
   dm_bht_set_root_hexdigest(bht_.get(),
                             reinterpret_cast<const u8 *>(kRootDigest));
 
@@ -183,40 +179,17 @@
   free(zero_page);
 }
 
-TEST_F(MemoryBhtTest, CreateThenVerifyMultipleLevels) {
-  static const unsigned int total_blocks = 16384;
+TEST_F(MemoryBhtTest, CreateThenVerifySingleLevel) {
+  static const unsigned int total_blocks = 32;
   // Set the root hash for a 0-filled image
   static const char kRootDigest[] =
-    "c86619624d3456f711dbb94d4ad79a4b029f6fd3b5a4a90b155c856bf5b3409b";
+    "2d3a43008286f56536fa24dcdbf14d342f0548827e374210415c7be0b610d2ba";
   // A page of all zeros
   u8 *zero_page = (u8 *)my_memalign(PAGE_SIZE, PAGE_SIZE);
 
   memset(zero_page, 0, PAGE_SIZE);
 
-  SetupBht(4, total_blocks, "sha256");
-  dm_bht_set_root_hexdigest(bht_.get(),
-                            reinterpret_cast<const u8 *>(kRootDigest));
-
-  for (unsigned int blocks = 0; blocks < total_blocks; ++blocks) {
-    DLOG(INFO) << "verifying block: " << blocks;
-    EXPECT_EQ(0, dm_bht_verify_block(bht_.get(), blocks, zero_page));
-  }
-
-  EXPECT_EQ(0, dm_bht_destroy(bht_.get()));
-  free(zero_page);
-}
-
-TEST_F(MemoryBhtTest, CreateThenVerifyZeroDepth) {
-  static const unsigned int total_blocks = 16384;
-  // Set the root hash for a 0-filled image
-  static const char kRootDigest[] =
-    "45d65d6f9e5a962f4d80b5f1bd7a918152251c27bdad8c5f52b590c129833372";
-  // A page of all zeros
-  u8 *zero_page = (u8 *)my_memalign(PAGE_SIZE, PAGE_SIZE);
-
-  memset(zero_page, 0, PAGE_SIZE);
-
-  SetupBht(0, total_blocks, "sha256");
+  SetupBht(total_blocks, "sha256");
   dm_bht_set_root_hexdigest(bht_.get(),
                             reinterpret_cast<const u8 *>(kRootDigest));
 
@@ -239,7 +212,7 @@
 
   memset(zero_page, 0, PAGE_SIZE);
 
-  SetupBht(3, total_blocks, "sha256");
+  SetupBht(total_blocks, "sha256");
   dm_bht_set_root_hexdigest(bht_.get(),
                             reinterpret_cast<const u8 *>(kRootDigest));
 
@@ -256,13 +229,13 @@
   static const unsigned int total_blocks = 16383;
   // Set the root hash for a 0-filled image
   static const char kRootDigest[] =
-    "c78d187c430465bd7831fe4908247b6ab5107e3a826d933b71e85aa9a932e03c";
+    "dc8cec4220d388b05ba75c853f858bb8cc25edfb1d5d2f3be6bdf9edfa66dc6a";
   // A page of all zeros
   u8 *zero_page = (u8 *)my_memalign(PAGE_SIZE, PAGE_SIZE);
 
   memset(zero_page, 0, PAGE_SIZE);
 
-  SetupBht(4, total_blocks, "sha256");
+  SetupBht(total_blocks, "sha256");
   dm_bht_set_root_hexdigest(bht_.get(),
                             reinterpret_cast<const u8 *>(kRootDigest));
 
@@ -279,13 +252,13 @@
   static const unsigned int total_blocks = 16000;
   // Set the root hash for a 0-filled image
   static const char kRootDigest[] =
-    "13e04b6aa410187b900834aa23e45f3e5240b0c4d2fadb2d8836a357c33499f0";
+    "10832dd62c427bcf68c56c8de0d1f9c32b61d9e5ddf43c77c56a97b372ad4b07";
   // A page of all zeros
   u8 *zero_page = (u8 *)my_memalign(PAGE_SIZE, PAGE_SIZE);
 
   memset(zero_page, 0, PAGE_SIZE);
 
-  SetupBht(4, total_blocks, "sha256");
+  SetupBht(total_blocks, "sha256");
   dm_bht_set_root_hexdigest(bht_.get(),
                             reinterpret_cast<const u8 *>(kRootDigest));
 
@@ -308,7 +281,7 @@
 
   memset(zero_page, 0, PAGE_SIZE);
 
-  SetupBht(2, total_blocks, "sha256");
+  SetupBht(total_blocks, "sha256");
 
   dm_bht_set_root_hexdigest(bht_.get(),
                             reinterpret_cast<const u8 *>(kRootDigest));
@@ -347,7 +320,7 @@
 
 TEST_F(MemoryBhtTest, CreateThenVerifyBadDataBlock) {
   static const unsigned int total_blocks = 384;
-  SetupBht(2, total_blocks, "sha256");
+  SetupBht(total_blocks, "sha256");
   // Set the root hash for a 0-filled image
   static const char kRootDigest[] =
     "45d65d6f9e5a962f4d80b5f1bd7a918152251c27bdad8c5f52b590c129833372";
diff --git a/file_hasher.cc b/file_hasher.cc
index 14e9604..90c1adf 100644
--- a/file_hasher.cc
+++ b/file_hasher.cc
@@ -45,12 +45,10 @@
  
 bool FileHasher::Initialize(simple_file::File *source,
                             simple_file::File *destination,
-                            unsigned int depth,
                             unsigned int blocks,
                             const char *alg) {
   if (!alg || !source || !destination) {
      LOG(ERROR) << "Invalid arguments supplied to Initialize";
-     LOG(INFO) << "depth: " << depth;
      LOG(INFO) << "s: " << source << " d: " << destination;
      return false;
   }
@@ -73,11 +71,10 @@
   alg_ = alg;
   source_ = source;
   destination_ = destination;
-  depth_ = depth;
   block_limit_ = blocks;
 
   // Now we initialize the tree
-  if (dm_bht_create(&tree_, depth_, block_limit_, alg_)) {
+  if (dm_bht_create(&tree_, block_limit_, alg_)) {
     LOG(ERROR) << "Could not create the BH tree";
     return false;
   }
@@ -120,8 +117,8 @@
   unsigned int hash_start = 0;
   unsigned int root_end = to_sector(block_limit_ << PAGE_SHIFT);
   if (colocated) hash_start = root_end;
-  printf("0 %u verity ROOT_DEV HASH_DEV %u %u %s %s\n",
-         root_end, hash_start, depth_, alg_, digest);
+  printf("0 %u verity ROOT_DEV HASH_DEV %u 0 %s %s\n",
+         root_end, hash_start, alg_, digest);
 }
 
 }  // namespace verity
diff --git a/file_hasher.h b/file_hasher.h
index ff1b03c..2ff920b 100644
--- a/file_hasher.h
+++ b/file_hasher.h
@@ -28,7 +28,6 @@
   virtual ~FileHasher() { dm_bht_destroy(&tree_); }
   virtual bool Initialize(simple_file::File *source,
                           simple_file::File *destination,
-                          unsigned int depth,
                           unsigned int blocks,
                           const char *alg);
   virtual bool Hash();
@@ -44,7 +43,6 @@
  private:
   simple_file::File *source_;
   simple_file::File *destination_;
-  unsigned int depth_;
   unsigned int block_limit_;
   const char *alg_;
   struct dm_bht tree_;
diff --git a/verity_main.cc b/verity_main.cc
index 7f36319..8c059e2 100644
--- a/verity_main.cc
+++ b/verity_main.cc
@@ -20,7 +20,7 @@
 "- mode:	May be create or verify\n"
 "		If create, the `hash_image' will be created.\n"
 "		If verify, the `hash_image` will be used to verify `image'.\n"
-"- depth:	Integer specifying the hash tree depth (excl root node)\n"
+"- depth:	Deprecated. Must be `0'.\n"
 "- alg:		Cryptographic hash algorithm to use\n"
 "		Valid values: sha512 sha384 sha256 sha224 sha1 sha\n"
 "			      mdc2 ripemd160 md5 md4 md2\n"
@@ -50,8 +50,7 @@
 }
 }  // namespace
 
-static int verity_create(unsigned int depth,
-                         const char *alg,
+static int verity_create(const char *alg,
                          const char *image_path,
                          unsigned int image_blocks,
                          const char *hash_path);
@@ -62,9 +61,13 @@
     return 1;
   }
 
+  if (parse_depth(argv[2]) != 0) {
+    LOG(FATAL) << "depth must be 0";
+    return -1;
+  }
+
   if (parse_mode(argv[1]) == VERITY_CREATE) {
-    return verity_create(parse_depth(argv[2]),
-                         argv[3],  // alg
+    return verity_create(argv[3],  // alg
                          argv[4],  // image_path
                          parse_blocks(argv[5]),
                          argv[6]);  // hash path
@@ -74,9 +77,8 @@
   return -1;
 }
 
-static int verity_create(unsigned int depth,
-                         const char *alg,
-                         const char *image_path, 
+static int verity_create(const char *alg,
+                         const char *image_path,
                          unsigned int image_blocks,
                          const char *hash_path) {
   // Configure files
@@ -95,7 +97,6 @@
   verity::FileHasher hasher;
   LOG_IF(FATAL, !hasher.Initialize(&source,
                                    &destination,
-                                   depth,
                                    image_blocks,
                                    alg))
     << "Failed to initialize hasher";