• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <fcntl.h>
20 
21 #include <brillo/secure_blob.h>
22 #include <gtest/gtest.h>
23 
24 #include "update_engine/common/test_utils.h"
25 #include "update_engine/common/utils.h"
26 #include "update_engine/payload_consumer/file_descriptor.h"
27 
28 namespace chromeos_update_engine {
29 
30 class VerityWriterAndroidTest : public ::testing::Test {
31  protected:
SetUp()32   void SetUp() override {
33     partition_.target_path = temp_file_.path();
34     partition_.block_size = 4096;
35     partition_.hash_tree_data_offset = 0;
36     partition_.hash_tree_data_size = 4096;
37     partition_.hash_tree_offset = 4096;
38     partition_.hash_tree_size = 4096;
39     partition_.hash_tree_algorithm = "sha1";
40     partition_.fec_roots = 2;
41     partition_fd_ = std::make_shared<EintrSafeFileDescriptor>();
42     partition_fd_->Open(partition_.target_path.c_str(), O_RDWR);
43   }
44 
45   VerityWriterAndroid verity_writer_;
46   InstallPlan::Partition partition_;
47   FileDescriptorPtr partition_fd_;
48   ScopedTempFile temp_file_;
49 };
50 
TEST_F(VerityWriterAndroidTest,SimpleTest)51 TEST_F(VerityWriterAndroidTest, SimpleTest) {
52   brillo::Blob part_data(8192);
53   test_utils::WriteFileVector(partition_.target_path, part_data);
54   ASSERT_TRUE(verity_writer_.Init(partition_));
55   ASSERT_TRUE(verity_writer_.Update(0, part_data.data(), 4096));
56   ASSERT_TRUE(verity_writer_.Update(4096, part_data.data() + 4096, 4096));
57   ASSERT_TRUE(verity_writer_.Finalize(partition_fd_, partition_fd_));
58   brillo::Blob actual_part;
59   utils::ReadFile(partition_.target_path, &actual_part);
60   // dd if=/dev/zero bs=4096 count=1 2>/dev/null | sha1sum | xxd -r -p |
61   //     hexdump -v -e '/1 "0x%02x, "'
62   brillo::Blob hash = {0x1c, 0xea, 0xf7, 0x3d, 0xf4, 0x0e, 0x53,
63                        0x1d, 0xf3, 0xbf, 0xb2, 0x6b, 0x4f, 0xb7,
64                        0xcd, 0x95, 0xfb, 0x7b, 0xff, 0x1d};
65   memcpy(part_data.data() + 4096, hash.data(), hash.size());
66   ASSERT_EQ(part_data, actual_part);
67 }
68 
TEST_F(VerityWriterAndroidTest,NoOpTest)69 TEST_F(VerityWriterAndroidTest, NoOpTest) {
70   partition_.hash_tree_data_size = 0;
71   partition_.hash_tree_size = 0;
72   brillo::Blob part_data(4096);
73   ASSERT_TRUE(verity_writer_.Init(partition_));
74   ASSERT_TRUE(verity_writer_.Update(0, part_data.data(), part_data.size()));
75   ASSERT_TRUE(verity_writer_.Update(4096, part_data.data(), part_data.size()));
76   ASSERT_TRUE(verity_writer_.Update(8192, part_data.data(), part_data.size()));
77 }
78 
TEST_F(VerityWriterAndroidTest,DiscontinuedRead)79 TEST_F(VerityWriterAndroidTest, DiscontinuedRead) {
80   partition_.hash_tree_data_size = 8192;
81   partition_.hash_tree_size = 4096;
82   brillo::Blob part_data(4096);
83   ASSERT_TRUE(verity_writer_.Init(partition_));
84   ASSERT_TRUE(verity_writer_.Update(0, part_data.data(), part_data.size()));
85   ASSERT_FALSE(verity_writer_.Update(8192, part_data.data(), part_data.size()));
86 }
87 
TEST_F(VerityWriterAndroidTest,InvalidHashAlgorithmTest)88 TEST_F(VerityWriterAndroidTest, InvalidHashAlgorithmTest) {
89   partition_.hash_tree_algorithm = "sha123";
90   ASSERT_FALSE(verity_writer_.Init(partition_));
91 }
92 
TEST_F(VerityWriterAndroidTest,WrongHashTreeSizeTest)93 TEST_F(VerityWriterAndroidTest, WrongHashTreeSizeTest) {
94   partition_.hash_tree_size = 8192;
95   ASSERT_FALSE(verity_writer_.Init(partition_));
96 }
97 
TEST_F(VerityWriterAndroidTest,SHA256Test)98 TEST_F(VerityWriterAndroidTest, SHA256Test) {
99   partition_.hash_tree_algorithm = "sha256";
100   brillo::Blob part_data(8192);
101   test_utils::WriteFileVector(partition_.target_path, part_data);
102   ASSERT_TRUE(verity_writer_.Init(partition_));
103   ASSERT_TRUE(verity_writer_.Update(0, part_data.data(), 4096));
104   ASSERT_TRUE(verity_writer_.Update(4096, part_data.data() + 4096, 4096));
105   ASSERT_TRUE(verity_writer_.Finalize(partition_fd_, partition_fd_));
106   brillo::Blob actual_part;
107   utils::ReadFile(partition_.target_path, &actual_part);
108   // dd if=/dev/zero bs=4096 count=1 2>/dev/null | sha256sum | xxd -r -p |
109   //     hexdump -v -e '/1 "0x%02x, "'
110   brillo::Blob hash = {0xad, 0x7f, 0xac, 0xb2, 0x58, 0x6f, 0xc6, 0xe9,
111                        0x66, 0xc0, 0x04, 0xd7, 0xd1, 0xd1, 0x6b, 0x02,
112                        0x4f, 0x58, 0x05, 0xff, 0x7c, 0xb4, 0x7c, 0x7a,
113                        0x85, 0xda, 0xbd, 0x8b, 0x48, 0x89, 0x2c, 0xa7};
114   memcpy(part_data.data() + 4096, hash.data(), hash.size());
115   ASSERT_EQ(part_data, actual_part);
116 }
117 
TEST_F(VerityWriterAndroidTest,NonZeroOffsetSHA256Test)118 TEST_F(VerityWriterAndroidTest, NonZeroOffsetSHA256Test) {
119   partition_.hash_tree_algorithm = "sha256";
120   partition_.hash_tree_data_offset = 100;
121   partition_.hash_tree_offset =
122       partition_.hash_tree_data_offset + partition_.hash_tree_data_size;
123   brillo::Blob part_data(8192 + partition_.hash_tree_data_offset);
124   test_utils::WriteFileVector(partition_.target_path, part_data);
125   ASSERT_TRUE(verity_writer_.Init(partition_));
126   ASSERT_TRUE(verity_writer_.Update(0, part_data.data(), 4096));
127   ASSERT_TRUE(verity_writer_.Update(4096, part_data.data() + 4096, 4096));
128   ASSERT_TRUE(verity_writer_.Update(
129       8192, part_data.data() + 8192, partition_.hash_tree_data_offset));
130   ASSERT_TRUE(verity_writer_.Finalize(partition_fd_, partition_fd_));
131   brillo::Blob actual_part;
132   utils::ReadFile(partition_.target_path, &actual_part);
133   // dd if=/dev/zero bs=4096 count=1 2>/dev/null | sha256sum | xxd -r -p |
134   //     hexdump -v -e '/1 "0x%02x, "'
135   brillo::Blob hash = {0xad, 0x7f, 0xac, 0xb2, 0x58, 0x6f, 0xc6, 0xe9,
136                        0x66, 0xc0, 0x04, 0xd7, 0xd1, 0xd1, 0x6b, 0x02,
137                        0x4f, 0x58, 0x05, 0xff, 0x7c, 0xb4, 0x7c, 0x7a,
138                        0x85, 0xda, 0xbd, 0x8b, 0x48, 0x89, 0x2c, 0xa7};
139   memcpy(
140       part_data.data() + partition_.hash_tree_offset, hash.data(), hash.size());
141   ASSERT_EQ(part_data, actual_part);
142 }
143 
TEST_F(VerityWriterAndroidTest,FECTest)144 TEST_F(VerityWriterAndroidTest, FECTest) {
145   partition_.fec_data_offset = 0;
146   partition_.fec_data_size = 4096;
147   partition_.fec_offset = 4096;
148   partition_.fec_size = 2 * 4096;
149   brillo::Blob part_data(3 * 4096, 0x1);
150   test_utils::WriteFileVector(partition_.target_path, part_data);
151   ASSERT_TRUE(verity_writer_.Init(partition_));
152   ASSERT_TRUE(verity_writer_.Update(0, part_data.data(), part_data.size()));
153   ASSERT_TRUE(verity_writer_.Finalize(partition_fd_, partition_fd_));
154   brillo::Blob actual_part;
155   utils::ReadFile(partition_.target_path, &actual_part);
156   // Write FEC data.
157   for (size_t i = 4096; i < part_data.size(); i += 2) {
158     part_data[i] = 0x8e;
159     part_data[i + 1] = 0x8f;
160   }
161   ASSERT_EQ(part_data, actual_part);
162 }
163 
164 }  // namespace chromeos_update_engine
165