1 // 2 // Copyright (C) 2018 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #include "update_engine/payload_consumer/verity_writer_android.h" 18 19 #include <brillo/secure_blob.h> 20 #include <gtest/gtest.h> 21 22 #include "update_engine/common/test_utils.h" 23 #include "update_engine/common/utils.h" 24 25 namespace chromeos_update_engine { 26 27 class VerityWriterAndroidTest : public ::testing::Test { 28 protected: 29 void SetUp() override { 30 partition_.target_path = temp_file_.path(); 31 partition_.block_size = 4096; 32 partition_.hash_tree_data_offset = 0; 33 partition_.hash_tree_data_size = 4096; 34 partition_.hash_tree_offset = 4096; 35 partition_.hash_tree_size = 4096; 36 partition_.hash_tree_algorithm = "sha1"; 37 partition_.fec_roots = 2; 38 } 39 40 VerityWriterAndroid verity_writer_; 41 InstallPlan::Partition partition_; 42 test_utils::ScopedTempFile temp_file_; 43 }; 44 45 TEST_F(VerityWriterAndroidTest, SimpleTest) { 46 brillo::Blob part_data(8192); 47 test_utils::WriteFileVector(partition_.target_path, part_data); 48 ASSERT_TRUE(verity_writer_.Init(partition_)); 49 EXPECT_TRUE(verity_writer_.Update(0, part_data.data(), 4096)); 50 EXPECT_TRUE(verity_writer_.Update(4096, part_data.data() + 4096, 4096)); 51 brillo::Blob actual_part; 52 utils::ReadFile(partition_.target_path, &actual_part); 53 // dd if=/dev/zero bs=4096 count=1 2>/dev/null | sha1sum | xxd -r -p | 54 // hexdump -v -e '/1 "0x%02x, "' 55 brillo::Blob hash = {0x1c, 0xea, 0xf7, 0x3d, 0xf4, 0x0e, 0x53, 56 0x1d, 0xf3, 0xbf, 0xb2, 0x6b, 0x4f, 0xb7, 57 0xcd, 0x95, 0xfb, 0x7b, 0xff, 0x1d}; 58 memcpy(part_data.data() + 4096, hash.data(), hash.size()); 59 EXPECT_EQ(part_data, actual_part); 60 } 61 62 TEST_F(VerityWriterAndroidTest, NoOpTest) { 63 partition_.hash_tree_data_size = 0; 64 partition_.hash_tree_size = 0; 65 brillo::Blob part_data(4096); 66 ASSERT_TRUE(verity_writer_.Init(partition_)); 67 EXPECT_TRUE(verity_writer_.Update(0, part_data.data(), part_data.size())); 68 EXPECT_TRUE(verity_writer_.Update(4096, part_data.data(), part_data.size())); 69 EXPECT_TRUE(verity_writer_.Update(8192, part_data.data(), part_data.size())); 70 } 71 72 TEST_F(VerityWriterAndroidTest, InvalidHashAlgorithmTest) { 73 partition_.hash_tree_algorithm = "sha123"; 74 EXPECT_FALSE(verity_writer_.Init(partition_)); 75 } 76 77 TEST_F(VerityWriterAndroidTest, WrongHashTreeSizeTest) { 78 partition_.hash_tree_size = 8192; 79 EXPECT_FALSE(verity_writer_.Init(partition_)); 80 } 81 82 TEST_F(VerityWriterAndroidTest, SHA256Test) { 83 partition_.hash_tree_algorithm = "sha256"; 84 brillo::Blob part_data(8192); 85 test_utils::WriteFileVector(partition_.target_path, part_data); 86 ASSERT_TRUE(verity_writer_.Init(partition_)); 87 EXPECT_TRUE(verity_writer_.Update(0, part_data.data(), 4096)); 88 EXPECT_TRUE(verity_writer_.Update(4096, part_data.data() + 4096, 4096)); 89 brillo::Blob actual_part; 90 utils::ReadFile(partition_.target_path, &actual_part); 91 // dd if=/dev/zero bs=4096 count=1 2>/dev/null | sha256sum | xxd -r -p | 92 // hexdump -v -e '/1 "0x%02x, "' 93 brillo::Blob hash = {0xad, 0x7f, 0xac, 0xb2, 0x58, 0x6f, 0xc6, 0xe9, 94 0x66, 0xc0, 0x04, 0xd7, 0xd1, 0xd1, 0x6b, 0x02, 95 0x4f, 0x58, 0x05, 0xff, 0x7c, 0xb4, 0x7c, 0x7a, 96 0x85, 0xda, 0xbd, 0x8b, 0x48, 0x89, 0x2c, 0xa7}; 97 memcpy(part_data.data() + 4096, hash.data(), hash.size()); 98 EXPECT_EQ(part_data, actual_part); 99 } 100 101 TEST_F(VerityWriterAndroidTest, FECTest) { 102 partition_.fec_data_offset = 0; 103 partition_.fec_data_size = 4096; 104 partition_.fec_offset = 4096; 105 partition_.fec_size = 2 * 4096; 106 brillo::Blob part_data(3 * 4096, 0x1); 107 test_utils::WriteFileVector(partition_.target_path, part_data); 108 ASSERT_TRUE(verity_writer_.Init(partition_)); 109 EXPECT_TRUE(verity_writer_.Update(0, part_data.data(), part_data.size())); 110 brillo::Blob actual_part; 111 utils::ReadFile(partition_.target_path, &actual_part); 112 // Write FEC data. 113 for (size_t i = 4096; i < part_data.size(); i += 2) { 114 part_data[i] = 0x8e; 115 part_data[i + 1] = 0x8f; 116 } 117 EXPECT_EQ(part_data, actual_part); 118 } 119 120 } // namespace chromeos_update_engine 121