diff options
author | Nikita Ioffe <ioffe@google.com> | 2020-01-05 04:25:47 +0000 |
---|---|---|
committer | Nikita Ioffe <ioffe@google.com> | 2020-01-05 04:25:47 +0000 |
commit | 971e4ba1c8e27dfebb52e6a83629456ba07ec1f9 (patch) | |
tree | 21f94c1cd0d9e3fcf5329f2479d4bdd355a4cf0e /verity | |
parent | 9fff8e3a7e5ddaa6ddc3551d532a548deacb032f (diff) | |
download | extras-971e4ba1c8e27dfebb52e6a83629456ba07ec1f9.tar.gz |
Add utility to calculate digest from the root of verity tree
This function will help verifying that external hashtree wasn't
tampered. See another change in this topic for more context.
Test: atest build_verity_tree_test
Bug: 145670581
Change-Id: I10a8141a60eec142c77cde0048f0abf44b3406bb
Diffstat (limited to 'verity')
-rw-r--r-- | verity/build_verity_tree_test.cpp | 25 | ||||
-rw-r--r-- | verity/hash_tree_builder.cpp | 12 | ||||
-rw-r--r-- | verity/include/verity/hash_tree_builder.h | 4 |
3 files changed, 38 insertions, 3 deletions
diff --git a/verity/build_verity_tree_test.cpp b/verity/build_verity_tree_test.cpp index 864ebdc9..8e1f114a 100644 --- a/verity/build_verity_tree_test.cpp +++ b/verity/build_verity_tree_test.cpp @@ -157,6 +157,31 @@ TEST_F(BuildVerityTreeTest, StreamingDataPartialBlocks) { HashTreeBuilder::BytesArrayToString(builder->root_hash())); } +TEST_F(BuildVerityTreeTest, CalculateRootDigest) { + std::vector<unsigned char> data(256 * 4096); + for (size_t i = 0; i < 256; i++) { + std::fill_n(data.begin() + i * 4096, 4096, i); + } + + ASSERT_TRUE(builder->Initialize(data.size(), salt_hex)); + + size_t offset = 0; + while (offset < data.size()) { + size_t data_length = std::min<size_t>(rand() % 40960, data.size() - offset); + ASSERT_TRUE(builder->Update(data.data() + offset, data_length)); + offset += data_length; + } + + ASSERT_TRUE(builder->BuildHashTree()); + ASSERT_EQ(2u, verity_tree().size()); + ASSERT_EQ(2 * 4096u, verity_tree()[0].size()); + std::string expected_root_digest = HashTreeBuilder::BytesArrayToString(builder->root_hash()); + + std::vector<unsigned char> actual_root_digest; + ASSERT_TRUE(builder->CalculateRootDigest(verity_tree().back(), &actual_root_digest)); + ASSERT_EQ(expected_root_digest, HashTreeBuilder::BytesArrayToString(actual_root_digest)); +} + TEST_F(BuildVerityTreeTest, SHA1MultipleBlocks) { std::vector<unsigned char> data(128 * 4096, 0xff); diff --git a/verity/hash_tree_builder.cpp b/verity/hash_tree_builder.cpp index d061ca5c..79d30405 100644 --- a/verity/hash_tree_builder.cpp +++ b/verity/hash_tree_builder.cpp @@ -213,6 +213,14 @@ bool HashTreeBuilder::Update(const unsigned char* data, size_t len) { return HashBlocks(data, len, &verity_tree_[0]); } +bool HashTreeBuilder::CalculateRootDigest(const std::vector<unsigned char>& root_verity, + std::vector<unsigned char>* root_digest) { + if (root_verity.size() != block_size_) { + return false; + } + return HashBlocks(root_verity.data(), block_size_, root_digest); +} + bool HashTreeBuilder::BuildHashTree() { // Expects only the base level in the verity_tree_. CHECK_EQ(1, verity_tree_.size()); @@ -247,9 +255,7 @@ bool HashTreeBuilder::BuildHashTree() { } CHECK_EQ(block_size_, verity_tree_.back().size()); - HashBlocks(verity_tree_.back().data(), block_size_, &root_hash_); - - return true; + return CalculateRootDigest(verity_tree_.back(), &root_hash_); } bool HashTreeBuilder::CheckHashTree( diff --git a/verity/include/verity/hash_tree_builder.h b/verity/include/verity/hash_tree_builder.h index da47d0fe..7e870bf4 100644 --- a/verity/include/verity/hash_tree_builder.h +++ b/verity/include/verity/hash_tree_builder.h @@ -65,6 +65,10 @@ class HashTreeBuilder { // nullptr if the algorithm is unrecongnized or not supported. static const EVP_MD* HashFunction(const std::string& hash_name); + // Calculates the digest of the root of a verity tree. + bool CalculateRootDigest(const std::vector<unsigned char>& root_verity, + std::vector<unsigned char>* root_digest); + private: friend class BuildVerityTreeTest; // Calculates the hash of one single block. Write the result to |out|, a |