1 /*
2 * Copyright (C) 2019 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 <endian.h>
18
19 #include <android-base/unique_fd.h>
20 #include <base/files/file_util.h>
21 #include <base/rand_util.h>
22 #include <base/strings/string_util.h>
23 #include <libavb/libavb.h>
24
25 #include "avb_util.h"
26 #include "fs_avb_test_util.h"
27
28 // Target classes or functions to test:
29 using android::fs_mgr::AvbPartitionToDevicePatition;
30 using android::fs_mgr::DeriveAvbPartitionName;
31 using android::fs_mgr::FstabEntry;
32 using android::fs_mgr::GetAvbFooter;
33 using android::fs_mgr::GetAvbPropertyDescriptor;
34 using android::fs_mgr::GetChainPartitionInfo;
35 using android::fs_mgr::GetTotalSize;
36 using android::fs_mgr::LoadAndVerifyVbmetaByPartition;
37 using android::fs_mgr::LoadAndVerifyVbmetaByPath;
38 using android::fs_mgr::ValidatePublicKeyBlob;
39 using android::fs_mgr::VBMetaData;
40 using android::fs_mgr::VBMetaVerifyResult;
41 using android::fs_mgr::VerifyVBMetaData;
42 using android::fs_mgr::VerifyVBMetaSignature;
43
44 namespace fs_avb_host_test {
45
46 class AvbUtilTest : public BaseFsAvbTest {
47 public:
AvbUtilTest()48 AvbUtilTest(){};
49
50 protected:
~AvbUtilTest()51 ~AvbUtilTest(){};
52 // Helper function for VerifyVBMetaSignature test. Modifies vbmeta.data()
53 // in a number of places at |offset| of size |length| and checks that
54 // VerifyVBMetaSignature() returns |expected_result|.
55 bool TestVBMetaModification(VBMetaVerifyResult expected_result, const VBMetaData& vbmeta,
56 size_t offset, size_t length);
57 // Modifies a random bit for a file, in the range of [offset, offset + length - 1].
58 void ModifyFile(const base::FilePath& file_path, size_t offset, ssize_t length);
59
60 // Loads the content of avb_image_path and comparies it with the content of vbmeta.
61 bool CompareVBMeta(const base::FilePath& avb_image_path, const VBMetaData& expected_vbmeta);
62
63 // Sets the flas in vbmeta header, the image_path could be a vbmeta.img or a system.img.
64 void SetVBMetaFlags(const base::FilePath& image_path, uint32_t flags);
65 };
66
SetVBMetaFlags(const base::FilePath & image_path,uint32_t flags)67 void AvbUtilTest::SetVBMetaFlags(const base::FilePath& image_path, uint32_t flags) {
68 if (!base::PathExists(image_path)) return;
69
70 std::string image_file_name = image_path.RemoveExtension().BaseName().value();
71 bool is_vbmeta_partition =
72 base::StartsWith(image_file_name, "vbmeta", base::CompareCase::INSENSITIVE_ASCII);
73
74 android::base::unique_fd fd(open(image_path.value().c_str(), O_RDWR | O_CLOEXEC));
75 EXPECT_TRUE(fd > 0);
76
77 uint64_t vbmeta_offset = 0; // for vbmeta.img
78 if (!is_vbmeta_partition) {
79 std::unique_ptr<AvbFooter> footer = GetAvbFooter(fd);
80 EXPECT_NE(nullptr, footer);
81 vbmeta_offset = footer->vbmeta_offset;
82 }
83
84 auto flags_offset = vbmeta_offset + offsetof(AvbVBMetaImageHeader, flags);
85 uint32_t flags_data = htobe32(flags);
86 EXPECT_EQ(flags_offset, lseek64(fd, flags_offset, SEEK_SET));
87 EXPECT_EQ(sizeof flags_data, write(fd, &flags_data, sizeof flags_data));
88 }
89
TEST_F(AvbUtilTest,AvbPartitionToDevicePatition)90 TEST_F(AvbUtilTest, AvbPartitionToDevicePatition) {
91 EXPECT_EQ("system", AvbPartitionToDevicePatition("system", "", ""));
92 EXPECT_EQ("system", AvbPartitionToDevicePatition("system", "", "_b"));
93
94 EXPECT_EQ("system_a", AvbPartitionToDevicePatition("system", "_a", ""));
95 EXPECT_EQ("system_a", AvbPartitionToDevicePatition("system", "_a", "_b"));
96
97 EXPECT_EQ("system_b", AvbPartitionToDevicePatition("system_other", "", "_b"));
98 EXPECT_EQ("system_b", AvbPartitionToDevicePatition("system_other", "_a", "_b"));
99 }
100
TEST_F(AvbUtilTest,DeriveAvbPartitionName)101 TEST_F(AvbUtilTest, DeriveAvbPartitionName) {
102 // The fstab_entry to test.
103 FstabEntry fstab_entry = {
104 .blk_device = "/dev/block/dm-1", // a dm-linear device (logical)
105 .logical_partition_name = "system",
106 .mount_point = "/system",
107 .fs_type = "ext4",
108 };
109
110 // Logical partitions.
111 // non-A/B
112 fstab_entry.fs_mgr_flags.logical = true;
113 EXPECT_EQ("system", DeriveAvbPartitionName(fstab_entry, "_dont_care", "_dont_care"));
114 EXPECT_EQ("system", DeriveAvbPartitionName(fstab_entry, "_a", "_b"));
115 EXPECT_EQ("system", DeriveAvbPartitionName(fstab_entry, "", ""));
116 // Active slot.
117 fstab_entry.fs_mgr_flags.slot_select = true;
118 fstab_entry.logical_partition_name = "system_a";
119 EXPECT_EQ("system", DeriveAvbPartitionName(fstab_entry, "_a", "_dont_care"));
120 EXPECT_EQ("system", DeriveAvbPartitionName(fstab_entry, "_a", "_b"));
121 EXPECT_EQ("system", DeriveAvbPartitionName(fstab_entry, "_a", ""));
122 EXPECT_EQ("system_a", DeriveAvbPartitionName(fstab_entry, "_wont_erase_a", "_dont_care"));
123 // The other slot.
124 fstab_entry.fs_mgr_flags.slot_select = false;
125 fstab_entry.fs_mgr_flags.slot_select_other = true;
126 fstab_entry.logical_partition_name = "system_b";
127 EXPECT_EQ("system_other", DeriveAvbPartitionName(fstab_entry, "_dont_care", "_b"));
128 EXPECT_EQ("system_other", DeriveAvbPartitionName(fstab_entry, "_a", "_b"));
129 EXPECT_EQ("system_other", DeriveAvbPartitionName(fstab_entry, "", "_b"));
130 EXPECT_EQ("system_b_other", DeriveAvbPartitionName(fstab_entry, "_dont_care", "_wont_erase_b"));
131
132 // Non-logical partitions.
133 // non-A/B.
134 fstab_entry.fs_mgr_flags.logical = false;
135 fstab_entry.fs_mgr_flags.slot_select = false;
136 fstab_entry.fs_mgr_flags.slot_select_other = false;
137 fstab_entry.blk_device = "/dev/block/by-name/system";
138 EXPECT_EQ("system", DeriveAvbPartitionName(fstab_entry, "_dont_care", "_dont_care"));
139 EXPECT_EQ("system", DeriveAvbPartitionName(fstab_entry, "_a", "_b"));
140 EXPECT_EQ("system", DeriveAvbPartitionName(fstab_entry, "", ""));
141 // Active slot _a.
142 fstab_entry.fs_mgr_flags.slot_select = true;
143 fstab_entry.blk_device = "/dev/block/by-name/system_a";
144 EXPECT_EQ("system", DeriveAvbPartitionName(fstab_entry, "_a", "_dont_care"));
145 EXPECT_EQ("system", DeriveAvbPartitionName(fstab_entry, "_a", "_b"));
146 EXPECT_EQ("system", DeriveAvbPartitionName(fstab_entry, "_a", ""));
147 EXPECT_EQ("system_a", DeriveAvbPartitionName(fstab_entry, "_wont_erase_a", "_dont_care"));
148 // Inactive slot _b.
149 fstab_entry.fs_mgr_flags.slot_select = false;
150 fstab_entry.fs_mgr_flags.slot_select_other = true;
151 fstab_entry.blk_device = "/dev/block/by-name/system_b";
152 EXPECT_EQ("system_other", DeriveAvbPartitionName(fstab_entry, "dont_care", "_b"));
153 EXPECT_EQ("system_other", DeriveAvbPartitionName(fstab_entry, "_a", "_b"));
154 EXPECT_EQ("system_other", DeriveAvbPartitionName(fstab_entry, "", "_b"));
155 EXPECT_EQ("system_b_other", DeriveAvbPartitionName(fstab_entry, "dont_care", "_wont_erase_b"));
156 }
157
TEST_F(AvbUtilTest,GetFdTotalSize)158 TEST_F(AvbUtilTest, GetFdTotalSize) {
159 // Generates a raw test.img via BaseFsAvbTest.
160 const size_t image_size = 5 * 1024 * 1024;
161 base::FilePath image_path = GenerateImage("test.img", image_size);
162
163 // Checks file size is as expected via base::GetFileSize().
164 int64_t file_size;
165 ASSERT_TRUE(base::GetFileSize(image_path, &file_size));
166 EXPECT_EQ(image_size, file_size);
167
168 // Checks file size is expected via libfs_avb internal utils.
169 auto fd = OpenUniqueReadFd(image_path);
170 EXPECT_EQ(image_size, GetTotalSize(fd));
171 }
172
TEST_F(AvbUtilTest,GetFdTotalSizeWithOffset)173 TEST_F(AvbUtilTest, GetFdTotalSizeWithOffset) {
174 // Generates a raw test.img via BaseFsAvbTest.
175 const size_t image_size = 10 * 1024 * 1024;
176 base::FilePath image_path = GenerateImage("test.img", image_size);
177
178 // Checks file size is expected even with a non-zero offset at the beginning.
179 auto fd = OpenUniqueReadFd(image_path);
180 off_t initial_offset = 2019;
181 EXPECT_EQ(initial_offset, lseek(fd, initial_offset, SEEK_SET));
182 EXPECT_EQ(image_size, GetTotalSize(fd)); // checks that total size is still returned.
183 EXPECT_EQ(initial_offset, lseek(fd, 0, SEEK_CUR)); // checks original offset is restored.
184 }
185
TEST_F(AvbUtilTest,GetAvbFooter)186 TEST_F(AvbUtilTest, GetAvbFooter) {
187 // Generates a raw system.img
188 const size_t image_size = 10 * 1024 * 1024;
189 const size_t partition_size = 15 * 1024 * 1024;
190 base::FilePath system_path = GenerateImage("system.img", image_size);
191 EXPECT_NE(0U, system_path.value().size());
192
193 // Checks image size is as expected.
194 int64_t file_size;
195 ASSERT_TRUE(base::GetFileSize(system_path, &file_size));
196 EXPECT_EQ(image_size, file_size);
197
198 // Appends AVB Hashtree Footer.
199 AddAvbFooter(system_path, "hashtree", "system", partition_size, "SHA512_RSA8192", 20,
200 data_dir_.Append("testkey_rsa8192.pem"), "d00df00d",
201 "--internal_release_string \"unit test\"");
202
203 // Checks partition size is as expected, after adding footer.
204 ASSERT_TRUE(base::GetFileSize(system_path, &file_size));
205 EXPECT_EQ(partition_size, file_size);
206
207 // Checks avb footer and avb vbmeta.
208 EXPECT_EQ(
209 "Footer version: 1.0\n"
210 "Image size: 15728640 bytes\n"
211 "Original image size: 10485760 bytes\n"
212 "VBMeta offset: 10661888\n"
213 "VBMeta size: 3648 bytes\n"
214 "--\n"
215 "Minimum libavb version: 1.0\n"
216 "Header Block: 256 bytes\n"
217 "Authentication Block: 1088 bytes\n"
218 "Auxiliary Block: 2304 bytes\n"
219 "Algorithm: SHA512_RSA8192\n"
220 "Rollback Index: 20\n"
221 "Flags: 0\n"
222 "Release String: 'unit test'\n"
223 "Descriptors:\n"
224 " Hashtree descriptor:\n"
225 " Version of dm-verity: 1\n"
226 " Image Size: 10485760 bytes\n"
227 " Tree Offset: 10485760\n"
228 " Tree Size: 86016 bytes\n"
229 " Data Block Size: 4096 bytes\n"
230 " Hash Block Size: 4096 bytes\n"
231 " FEC num roots: 2\n"
232 " FEC offset: 10571776\n"
233 " FEC size: 90112 bytes\n"
234 " Hash Algorithm: sha1\n"
235 " Partition Name: system\n"
236 " Salt: d00df00d\n"
237 " Root Digest: a3d5dd307341393d85de356c384ff543ec1ed81b\n"
238 " Flags: 0\n",
239 InfoImage(system_path));
240
241 // Checks each field from GetAvbFooter(fd).
242 auto fd = OpenUniqueReadFd(system_path);
243 auto footer = GetAvbFooter(fd);
244 EXPECT_NE(nullptr, footer);
245 EXPECT_EQ(10485760, footer->original_image_size);
246 EXPECT_EQ(10661888, footer->vbmeta_offset);
247 EXPECT_EQ(3648, footer->vbmeta_size);
248 }
249
TEST_F(AvbUtilTest,GetAvbFooterErrorVerification)250 TEST_F(AvbUtilTest, GetAvbFooterErrorVerification) {
251 // Generates a raw system.img
252 const size_t image_size = 5 * 1024 * 1024;
253 base::FilePath system_path = GenerateImage("system.img", image_size);
254
255 // Checks each field from GetAvbFooter(fd).
256 auto fd = OpenUniqueReadFd(system_path);
257 auto footer = GetAvbFooter(fd);
258 EXPECT_EQ(nullptr, footer);
259 }
260
TEST_F(AvbUtilTest,GetAvbFooterInsufficientSize)261 TEST_F(AvbUtilTest, GetAvbFooterInsufficientSize) {
262 // Generates a raw system.img
263 const size_t image_size = AVB_FOOTER_SIZE - 10;
264 base::FilePath system_path = GenerateImage("system.img", image_size);
265
266 // Checks each field from GetAvbFooter(fd).
267 auto fd = OpenUniqueReadFd(system_path);
268 auto footer = GetAvbFooter(fd);
269 EXPECT_EQ(nullptr, footer);
270 }
271
TEST_F(AvbUtilTest,GetAvbPropertyDescriptor_Basic)272 TEST_F(AvbUtilTest, GetAvbPropertyDescriptor_Basic) {
273 // Makes a vbmeta.img with some properties.
274 GenerateVBMetaImage("vbmeta.img", "SHA256_RSA4096", 0, data_dir_.Append("testkey_rsa4096.pem"),
275 {}, /* include_descriptor_image_paths */
276 {}, /* chain_partitions */
277 "--prop foo:android "
278 "--prop bar:treble "
279 "--internal_release_string \"unit test\" ");
280 auto vbmeta = LoadVBMetaData("vbmeta.img");
281
282 // Puts the vbmeta into a vector, for GetAvbPropertyDescriptor to use.
283 std::vector<VBMetaData> vbmeta_images;
284 vbmeta_images.emplace_back(std::move(vbmeta));
285
286 EXPECT_EQ("android", GetAvbPropertyDescriptor("foo", vbmeta_images));
287 EXPECT_EQ("treble", GetAvbPropertyDescriptor("bar", vbmeta_images));
288 EXPECT_EQ("", GetAvbPropertyDescriptor("non-existent", vbmeta_images));
289 }
290
TEST_F(AvbUtilTest,GetAvbPropertyDescriptor_SecurityPatchLevel)291 TEST_F(AvbUtilTest, GetAvbPropertyDescriptor_SecurityPatchLevel) {
292 // Generates a raw boot.img
293 const size_t boot_image_size = 5 * 1024 * 1024;
294 const size_t boot_partition_size = 10 * 1024 * 1024;
295 base::FilePath boot_path = GenerateImage("boot.img", boot_image_size);
296 // Adds AVB Hash Footer.
297 AddAvbFooter(boot_path, "hash", "boot", boot_partition_size, "SHA256_RSA2048", 10,
298 data_dir_.Append("testkey_rsa2048.pem"), "d00df00d",
299 "--internal_release_string \"unit test\"");
300
301 // Generates a raw system.img, use a smaller size to speed-up unit test.
302 const size_t system_image_size = 10 * 1024 * 1024;
303 const size_t system_partition_size = 15 * 1024 * 1024;
304 base::FilePath system_path = GenerateImage("system.img", system_image_size);
305 // Adds AVB Hashtree Footer.
306 AddAvbFooter(system_path, "hashtree", "system", system_partition_size, "SHA512_RSA4096", 20,
307 data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
308 "--prop com.android.build.system.security_patch:2019-04-05 "
309 "--internal_release_string \"unit test\"");
310
311 // Generates chain partition descriptors.
312 base::FilePath rsa4096_public_key =
313 ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa4096.pem"));
314
315 // Makes a vbmeta.img including the 'system' chained descriptor.
316 GenerateVBMetaImage("vbmeta.img", "SHA256_RSA4096", 0, data_dir_.Append("testkey_rsa4096.pem"),
317 {boot_path}, /* include_descriptor_image_paths */
318 {{"system", 3, rsa4096_public_key}}, /* chain_partitions */
319 "--internal_release_string \"unit test\"");
320
321 auto vbmeta = LoadVBMetaData("vbmeta.img");
322 auto system_vbmeta = ExtractAndLoadVBMetaData(system_path, "system-vbmeta.img");
323
324 // Puts the vbmeta into a vector, for GetAvbPropertyDescriptor to use.
325 std::vector<VBMetaData> vbmeta_images;
326 vbmeta_images.emplace_back(std::move(vbmeta));
327 vbmeta_images.emplace_back(std::move(system_vbmeta));
328
329 EXPECT_EQ("2019-04-05",
330 GetAvbPropertyDescriptor("com.android.build.system.security_patch", vbmeta_images));
331 }
332
TEST_F(AvbUtilTest,GetVBMetaHeader)333 TEST_F(AvbUtilTest, GetVBMetaHeader) {
334 // Generates a raw boot.img
335 const size_t image_size = 5 * 1024 * 1024;
336 const size_t partition_size = 10 * 1024 * 1024;
337 base::FilePath boot_path = GenerateImage("boot.img", image_size);
338 // Appends AVB Hash Footer.
339 AddAvbFooter(boot_path, "hash", "boot", partition_size, "SHA256_RSA4096", 10,
340 data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
341 "--internal_release_string \"unit test\"");
342 // Extracts boot vbmeta from boot.img into boot-vbmeta.img.
343 base::FilePath boot_vbmeta = ExtractVBMetaImage(boot_path, "boot-vbmeta.img");
344 EXPECT_EQ(
345 "Minimum libavb version: 1.0\n"
346 "Header Block: 256 bytes\n"
347 "Authentication Block: 576 bytes\n"
348 "Auxiliary Block: 1216 bytes\n"
349 "Algorithm: SHA256_RSA4096\n"
350 "Rollback Index: 10\n"
351 "Flags: 0\n"
352 "Release String: 'unit test'\n"
353 "Descriptors:\n"
354 " Hash descriptor:\n"
355 " Image Size: 5242880 bytes\n"
356 " Hash Algorithm: sha256\n"
357 " Partition Name: boot\n"
358 " Salt: d00df00d\n"
359 " Digest: "
360 "222dd01e98284a1fcd7781f85d1392e43a530511a64eff96db197db90ebc4df1\n"
361 " Flags: 0\n",
362 InfoImage("boot-vbmeta.img"));
363
364 // Creates a VBMetaData with the content from boot-vbmeta.img.
365 std::string content;
366 EXPECT_TRUE(base::ReadFileToString(boot_vbmeta, &content));
367 VBMetaData vbmeta((uint8_t*)content.data(), content.size(), "boot-vbmeta");
368 EXPECT_EQ(content.size(), vbmeta.size());
369
370 // Checks each field returned from GetVBMetaHeader().
371 auto vbmeta_header = vbmeta.GetVBMetaHeader(false /* update_vbmeta_size */);
372 EXPECT_NE(nullptr, vbmeta_header);
373 EXPECT_EQ(576, vbmeta_header->authentication_data_block_size);
374 EXPECT_EQ(1216, vbmeta_header->auxiliary_data_block_size);
375 EXPECT_EQ(AVB_ALGORITHM_TYPE_SHA256_RSA4096, vbmeta_header->algorithm_type);
376 EXPECT_EQ(0, vbmeta_header->hash_offset);
377 EXPECT_EQ(32, vbmeta_header->hash_size);
378 EXPECT_EQ(32, vbmeta_header->signature_offset);
379 EXPECT_EQ(512, vbmeta_header->signature_size);
380 EXPECT_EQ(176, vbmeta_header->public_key_offset);
381 EXPECT_EQ(1032, vbmeta_header->public_key_size);
382 EXPECT_EQ(0, vbmeta_header->descriptors_offset);
383 EXPECT_EQ(176, vbmeta_header->descriptors_size);
384 EXPECT_EQ(10, vbmeta_header->rollback_index);
385 EXPECT_EQ(0, vbmeta_header->flags);
386 EXPECT_EQ("unit test", std::string((const char*)vbmeta_header->release_string));
387
388 // Appends some garbage to the end of the vbmeta buffer, checks it still can work.
389 std::string padding(2020, 'A'); // Generate a padding with length 2020.
390 std::string content_padding = content + padding;
391 VBMetaData vbmeta_padding((const uint8_t*)content_padding.data(), content_padding.size(),
392 "boot");
393 EXPECT_EQ(content_padding.size(), vbmeta_padding.size());
394
395 // Checks each field still can be parsed properly, even with garbage padding.
396 vbmeta_header = vbmeta_padding.GetVBMetaHeader(false /* update_vbmeta_size */);
397 EXPECT_NE(nullptr, vbmeta_header);
398 EXPECT_EQ(576, vbmeta_header->authentication_data_block_size);
399 EXPECT_EQ(1216, vbmeta_header->auxiliary_data_block_size);
400 EXPECT_EQ(AVB_ALGORITHM_TYPE_SHA256_RSA4096, vbmeta_header->algorithm_type);
401 EXPECT_EQ(0, vbmeta_header->hash_offset);
402 EXPECT_EQ(32, vbmeta_header->hash_size);
403 EXPECT_EQ(32, vbmeta_header->signature_offset);
404 EXPECT_EQ(512, vbmeta_header->signature_size);
405 EXPECT_EQ(176, vbmeta_header->public_key_offset);
406 EXPECT_EQ(1032, vbmeta_header->public_key_size);
407 EXPECT_EQ(0, vbmeta_header->descriptors_offset);
408 EXPECT_EQ(176, vbmeta_header->descriptors_size);
409 EXPECT_EQ(10, vbmeta_header->rollback_index);
410 EXPECT_EQ(0, vbmeta_header->flags);
411 EXPECT_EQ("unit test", std::string((const char*)vbmeta_header->release_string));
412
413 // Checks vbmeta size is updated to the actual size without padding.
414 vbmeta_header = vbmeta_padding.GetVBMetaHeader(true /* update_vbmeta_size */);
415 EXPECT_EQ(content_padding.size() - padding.size(), vbmeta_padding.size());
416 }
417
TEST_F(AvbUtilTest,ValidatePublicKeyBlob)418 TEST_F(AvbUtilTest, ValidatePublicKeyBlob) {
419 // Generates a raw key.bin
420 const size_t key_size = 2048;
421 base::FilePath key_path = GenerateImage("key.bin", key_size);
422
423 uint8_t key_data[key_size];
424 EXPECT_EQ(key_size, base::ReadFile(key_path, (char*)key_data, key_size));
425
426 std::string expected_key_blob;
427 EXPECT_TRUE(base::ReadFileToString(key_path, &expected_key_blob));
428 EXPECT_TRUE(ValidatePublicKeyBlob(key_data, key_size, expected_key_blob));
429
430 key_data[10] ^= 0x80; // toggles a bit and expects a failure
431 EXPECT_FALSE(ValidatePublicKeyBlob(key_data, key_size, expected_key_blob));
432 key_data[10] ^= 0x80; // toggles the bit again, should pass
433 EXPECT_TRUE(ValidatePublicKeyBlob(key_data, key_size, expected_key_blob));
434 }
435
TEST_F(AvbUtilTest,VerifyEmptyPublicKeyBlob)436 TEST_F(AvbUtilTest, VerifyEmptyPublicKeyBlob) {
437 // Generates a raw key.bin
438 const size_t key_size = 2048;
439 base::FilePath key_path = GenerateImage("key.bin", key_size);
440
441 uint8_t key_data[key_size];
442 EXPECT_EQ(key_size, base::ReadFile(key_path, (char*)key_data, key_size));
443
444 std::string expected_key_blob = ""; // empty means no expectation, thus return true.
445 EXPECT_TRUE(ValidatePublicKeyBlob(key_data, key_size, expected_key_blob));
446 }
447
TEST_F(AvbUtilTest,ValidatePublicKeyBlob_MultipleAllowedKeys)448 TEST_F(AvbUtilTest, ValidatePublicKeyBlob_MultipleAllowedKeys) {
449 base::FilePath rsa2048_public_key =
450 ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa2048.pem"));
451 base::FilePath rsa4096_public_key =
452 ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa4096.pem"));
453 base::FilePath rsa8192_public_key =
454 ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa8192.pem"));
455
456 std::vector<std::string> allowed_key_paths;
457 allowed_key_paths.push_back(rsa2048_public_key.value());
458 allowed_key_paths.push_back(rsa4096_public_key.value());
459
460 std::string expected_key_blob_2048;
461 EXPECT_TRUE(base::ReadFileToString(rsa2048_public_key, &expected_key_blob_2048));
462 std::string expected_key_blob_4096;
463 EXPECT_TRUE(base::ReadFileToString(rsa4096_public_key, &expected_key_blob_4096));
464 std::string expected_key_blob_8192;
465 EXPECT_TRUE(base::ReadFileToString(rsa8192_public_key, &expected_key_blob_8192));
466
467 EXPECT_TRUE(ValidatePublicKeyBlob(expected_key_blob_2048, allowed_key_paths));
468 EXPECT_TRUE(ValidatePublicKeyBlob(expected_key_blob_4096, allowed_key_paths));
469
470 EXPECT_FALSE(ValidatePublicKeyBlob(expected_key_blob_8192, allowed_key_paths));
471 EXPECT_FALSE(ValidatePublicKeyBlob("invalid_content", allowed_key_paths));
472 EXPECT_FALSE(ValidatePublicKeyBlob("", allowed_key_paths));
473
474 allowed_key_paths.push_back(rsa8192_public_key.value());
475 EXPECT_TRUE(ValidatePublicKeyBlob(expected_key_blob_8192, allowed_key_paths));
476 }
477
TEST_F(AvbUtilTest,VerifyVBMetaSignature)478 TEST_F(AvbUtilTest, VerifyVBMetaSignature) {
479 const size_t image_size = 10 * 1024 * 1024;
480 const size_t partition_size = 15 * 1024 * 1024;
481 auto signing_key = data_dir_.Append("testkey_rsa4096.pem");
482 auto vbmeta = GenerateImageAndExtractVBMetaData("system", image_size, partition_size,
483 "hashtree", signing_key, "SHA256_RSA4096",
484 10 /* rollback_index */);
485
486 auto expected_public_key_blob = ExtractPublicKeyAvbBlob(signing_key);
487 EXPECT_EQ(VBMetaVerifyResult::kSuccess,
488 VerifyVBMetaSignature(vbmeta, expected_public_key_blob,
489 nullptr /* out_public_key_data */));
490
491 // Converts the expected key into an 'unexpected' key.
492 expected_public_key_blob[10] ^= 0x80;
493 EXPECT_EQ(VBMetaVerifyResult::kErrorVerification,
494 VerifyVBMetaSignature(vbmeta, expected_public_key_blob,
495 nullptr /* out_public_key_data */));
496 }
497
TEST_F(AvbUtilTest,VerifyVBMetaSignatureOutputPublicKeyData)498 TEST_F(AvbUtilTest, VerifyVBMetaSignatureOutputPublicKeyData) {
499 const size_t image_size = 10 * 1024 * 1024;
500 const size_t partition_size = 15 * 1024 * 1024;
501 auto signing_key = data_dir_.Append("testkey_rsa4096.pem");
502 auto vbmeta = GenerateImageAndExtractVBMetaData("system", image_size, partition_size,
503 "hashtree", signing_key, "SHA256_RSA4096",
504 10 /* rollback_index */);
505 std::string out_public_key_data;
506 auto expected_public_key_blob = ExtractPublicKeyAvbBlob(signing_key);
507 EXPECT_EQ(VBMetaVerifyResult::kSuccess,
508 VerifyVBMetaSignature(vbmeta, expected_public_key_blob, &out_public_key_data));
509 EXPECT_EQ(out_public_key_data, expected_public_key_blob);
510
511 // Converts the expected key into an 'unexpected' key.
512 expected_public_key_blob[10] ^= 0x80;
513 EXPECT_EQ(VBMetaVerifyResult::kErrorVerification,
514 VerifyVBMetaSignature(vbmeta, expected_public_key_blob, &out_public_key_data));
515 EXPECT_NE(out_public_key_data, expected_public_key_blob);
516 }
517
TestVBMetaModification(VBMetaVerifyResult expected_result,const VBMetaData & vbmeta,size_t offset,size_t length)518 bool AvbUtilTest::TestVBMetaModification(VBMetaVerifyResult expected_result,
519 const VBMetaData& vbmeta, size_t offset, size_t length) {
520 uint8_t* d = reinterpret_cast<uint8_t*>(vbmeta.data());
521 const int kNumCheckIntervals = 8;
522
523 // Tests |kNumCheckIntervals| modifications in the start, middle, and
524 // end of the given sub-array at offset with size.
525 for (int n = 0; n <= kNumCheckIntervals; n++) {
526 size_t o = std::min(length * n / kNumCheckIntervals, length - 1) + offset;
527 d[o] ^= 0x80;
528 VBMetaVerifyResult result = VerifyVBMetaSignature(vbmeta, "" /* expected_public_key_blob */,
529 nullptr /* out_public_key_data */);
530 d[o] ^= 0x80;
531 if (result != expected_result) {
532 return false;
533 }
534 }
535
536 return true;
537 }
538
TEST_F(AvbUtilTest,VerifyVBMetaSignatureWithModification)539 TEST_F(AvbUtilTest, VerifyVBMetaSignatureWithModification) {
540 const size_t image_size = 10 * 1024 * 1024;
541 const size_t partition_size = 15 * 1024 * 1024;
542 auto signing_key = data_dir_.Append("testkey_rsa4096.pem");
543 auto vbmeta = GenerateImageAndExtractVBMetaData("system", image_size, partition_size,
544 "hashtree", signing_key, "SHA256_RSA4096",
545 10 /* rollback_index */);
546
547 auto header = vbmeta.GetVBMetaHeader(true /* update_vbmeta_size */);
548 size_t header_block_offset = 0;
549 size_t authentication_block_offset = header_block_offset + sizeof(AvbVBMetaImageHeader);
550 size_t auxiliary_block_offset =
551 authentication_block_offset + header->authentication_data_block_size;
552
553 // Should detect modifications in the auxiliary data block.
554 EXPECT_TRUE(TestVBMetaModification(VBMetaVerifyResult::kErrorVerification, vbmeta,
555 auxiliary_block_offset, header->auxiliary_data_block_size));
556
557 // Sholud detect modifications in the hash part of authentication data block.
558 EXPECT_TRUE(TestVBMetaModification(VBMetaVerifyResult::kErrorVerification, vbmeta,
559 authentication_block_offset + header->hash_offset,
560 header->hash_size));
561
562 // Sholud detect modifications in the signature part of authentication data block.
563 EXPECT_TRUE(TestVBMetaModification(VBMetaVerifyResult::kErrorVerification, vbmeta,
564 authentication_block_offset + header->signature_offset,
565 header->signature_size));
566 }
567
TEST_F(AvbUtilTest,VerifyVBMetaSignatureNotSigned)568 TEST_F(AvbUtilTest, VerifyVBMetaSignatureNotSigned) {
569 const size_t image_size = 10 * 1024 * 1024;
570 const size_t partition_size = 15 * 1024 * 1024;
571 auto vbmeta = GenerateImageAndExtractVBMetaData(
572 "system", image_size, partition_size, "hashtree", {} /* avb_signing_key */,
573 "" /* avb_algorithm */, 10 /* rollback_index */);
574
575 EXPECT_EQ(VBMetaVerifyResult::kErrorVerification,
576 VerifyVBMetaSignature(vbmeta, "" /* expected_public_key_blob */,
577 nullptr /* out_public_key_data */));
578 }
579
TEST_F(AvbUtilTest,VerifyVBMetaSignatureInvalidVBMeta)580 TEST_F(AvbUtilTest, VerifyVBMetaSignatureInvalidVBMeta) {
581 const size_t buffer_size = 5 * 1024 * 1024;
582 std::vector<uint8_t> vbmeta_buffer(buffer_size);
583 for (size_t n = 0; n < buffer_size; n++) {
584 vbmeta_buffer[n] = uint8_t(n);
585 }
586
587 VBMetaData invalid_vbmeta((const uint8_t*)vbmeta_buffer.data(), vbmeta_buffer.size(),
588 "invalid_vbmeta");
589 EXPECT_EQ(VBMetaVerifyResult::kError,
590 VerifyVBMetaSignature(invalid_vbmeta, "" /* expected_public_key_blob */,
591 nullptr /* out_public_Key_data */));
592 }
593
CompareVBMeta(const base::FilePath & avb_image_path,const VBMetaData & expected_vbmeta)594 bool AvbUtilTest::CompareVBMeta(const base::FilePath& avb_image_path,
595 const VBMetaData& expected_vbmeta) {
596 if (!base::PathExists(avb_image_path)) return false;
597
598 std::string image_file_name = avb_image_path.RemoveExtension().BaseName().value();
599
600 base::FilePath extracted_vbmeta_path;
601 if (base::StartsWith(image_file_name, "vbmeta", base::CompareCase::INSENSITIVE_ASCII)) {
602 extracted_vbmeta_path = avb_image_path; // no need to extract if it's a vbmeta image.
603 } else {
604 extracted_vbmeta_path = ExtractVBMetaImage(avb_image_path, image_file_name + "-vbmeta.img");
605 }
606
607 // Gets file size of the vbmeta image.
608 int64_t extracted_vbmeta_size;
609 EXPECT_TRUE(base::GetFileSize(extracted_vbmeta_path, &extracted_vbmeta_size));
610
611 // Reads the vbmeta into a vector.
612 std::vector<uint8_t> extracted_vbmeta_content(extracted_vbmeta_size);
613 EXPECT_TRUE(base::ReadFile(extracted_vbmeta_path,
614 reinterpret_cast<char*>(extracted_vbmeta_content.data()),
615 extracted_vbmeta_size));
616
617 // Compares extracted_vbmeta_content with the expected_vbmeta.
618 EXPECT_EQ(expected_vbmeta.size(), extracted_vbmeta_size);
619 return memcmp(reinterpret_cast<void*>(extracted_vbmeta_content.data()),
620 reinterpret_cast<void*>(expected_vbmeta.data()), extracted_vbmeta_size) == 0;
621 }
622
TEST_F(AvbUtilTest,VerifyVBMetaDataWithoutFooter)623 TEST_F(AvbUtilTest, VerifyVBMetaDataWithoutFooter) {
624 // Generates chain partition descriptors.
625 base::FilePath rsa2048_public_key =
626 ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa2048.pem"));
627 base::FilePath rsa4096_public_key =
628 ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa4096.pem"));
629
630 // Makes a vbmeta image includeing 'boot' and 'system' chained descriptors.
631 auto vbmeta_path = GenerateVBMetaImage("vbmeta.img", "SHA256_RSA8192", 0,
632 data_dir_.Append("testkey_rsa8192.pem"),
633 {}, /* include_descriptor_image_paths */
634 {{"boot", 1, rsa2048_public_key}, /* chain_partitions */
635 {"system", 2, rsa4096_public_key}},
636 "--internal_release_string \"unit test\"");
637 EXPECT_EQ(
638 "Minimum libavb version: 1.0\n"
639 "Header Block: 256 bytes\n"
640 "Authentication Block: 1088 bytes\n"
641 "Auxiliary Block: 3840 bytes\n"
642 "Algorithm: SHA256_RSA8192\n"
643 "Rollback Index: 0\n"
644 "Flags: 0\n"
645 "Release String: 'unit test'\n"
646 "Descriptors:\n"
647 " Chain Partition descriptor:\n"
648 " Partition Name: boot\n"
649 " Rollback Index Location: 1\n"
650 " Public key (sha1): cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
651 " Chain Partition descriptor:\n"
652 " Partition Name: system\n"
653 " Rollback Index Location: 2\n"
654 " Public key (sha1): 2597c218aae470a130f61162feaae70afd97f011\n",
655 InfoImage("vbmeta.img"));
656
657 android::base::unique_fd fd(open(vbmeta_path.value().c_str(), O_RDONLY | O_CLOEXEC));
658 ASSERT_TRUE(fd > 0);
659
660 VBMetaVerifyResult verify_result;
661 std::string out_public_key_data;
662 std::unique_ptr<VBMetaData> vbmeta = VerifyVBMetaData(
663 fd, "vbmeta", "" /*expected_public_key_blob */, &out_public_key_data, &verify_result);
664 EXPECT_TRUE(vbmeta != nullptr);
665 EXPECT_EQ(VBMetaVerifyResult::kSuccess, verify_result);
666
667 auto rsa8192_public_key_blob = ExtractPublicKeyAvbBlob(data_dir_.Append("testkey_rsa8192.pem"));
668 EXPECT_EQ(rsa8192_public_key_blob, out_public_key_data);
669
670 // Checkes the returned vbmeta content is the same as that extracted via avbtool.
671 vbmeta->GetVBMetaHeader(true /* update_vbmeta_size */);
672 EXPECT_TRUE(CompareVBMeta(vbmeta_path, *vbmeta));
673 }
674
TEST_F(AvbUtilTest,VerifyVBMetaDataWithFooter)675 TEST_F(AvbUtilTest, VerifyVBMetaDataWithFooter) {
676 const size_t image_size = 10 * 1024 * 1024;
677 const size_t partition_size = 15 * 1024 * 1024;
678 base::FilePath system_path = GenerateImage("system.img", image_size);
679
680 // Appends AVB Hashtree Footer.
681 AddAvbFooter(system_path, "hashtree", "system", partition_size, "SHA512_RSA8192", 20,
682 data_dir_.Append("testkey_rsa8192.pem"), "d00df00d",
683 "--internal_release_string \"unit test\"");
684
685 android::base::unique_fd fd(open(system_path.value().c_str(), O_RDONLY | O_CLOEXEC));
686 ASSERT_TRUE(fd > 0);
687
688 VBMetaVerifyResult verify_result;
689 std::string out_public_key_data;
690 std::unique_ptr<VBMetaData> vbmeta = VerifyVBMetaData(
691 fd, "system", "" /*expected_public_key_blob */, &out_public_key_data, &verify_result);
692 EXPECT_TRUE(vbmeta != nullptr);
693 EXPECT_EQ(VBMetaVerifyResult::kSuccess, verify_result);
694
695 auto rsa8192_public_key_blob = ExtractPublicKeyAvbBlob(data_dir_.Append("testkey_rsa8192.pem"));
696 EXPECT_EQ(rsa8192_public_key_blob, out_public_key_data);
697
698 // Checkes the returned vbmeta content is the same as that extracted via avbtool.
699 EXPECT_TRUE(CompareVBMeta(system_path, *vbmeta));
700 }
701
702 // Modifies a random bit for a file, in the range of [offset, offset + length - 1].
703 // Length < 0 means only resets previous modification without introducing new modification.
ModifyFile(const base::FilePath & file_path,size_t offset,ssize_t length)704 void AvbUtilTest::ModifyFile(const base::FilePath& file_path, size_t offset, ssize_t length) {
705 static int last_modified_location = -1;
706 static std::string last_file_path;
707
708 int64_t file_size;
709 ASSERT_TRUE(base::GetFileSize(file_path, &file_size));
710
711 std::vector<uint8_t> file_content(file_size);
712 ASSERT_TRUE(base::ReadFile(file_path, reinterpret_cast<char*>(file_content.data()), file_size));
713
714 // Resets previous modification for consecutive calls on the same file.
715 if (last_file_path == file_path.value()) {
716 file_content[last_modified_location] ^= 0x80;
717 }
718
719 // Introduces a new modification.
720 if (length > 0) {
721 int modify_location = base::RandInt(offset, offset + length - 1);
722 file_content[modify_location] ^= 0x80;
723 last_file_path = file_path.value();
724 last_modified_location = modify_location;
725 }
726
727 ASSERT_EQ(file_size, static_cast<const size_t>(base::WriteFile(
728 file_path, reinterpret_cast<const char*>(file_content.data()),
729 file_content.size())));
730 }
731
TEST_F(AvbUtilTest,VerifyVBMetaDataError)732 TEST_F(AvbUtilTest, VerifyVBMetaDataError) {
733 const size_t image_size = 10 * 1024 * 1024;
734 const size_t partition_size = 15 * 1024 * 1024;
735 base::FilePath system_path = GenerateImage("system.img", image_size);
736
737 // Appends AVB Hashtree Footer.
738 AddAvbFooter(system_path, "hashtree", "system", partition_size, "SHA512_RSA8192", 20,
739 data_dir_.Append("testkey_rsa8192.pem"), "d00df00d",
740 "--internal_release_string \"unit test\"");
741
742 android::base::unique_fd fd(open(system_path.value().c_str(), O_RDONLY | O_CLOEXEC));
743 ASSERT_TRUE(fd > 0);
744
745 std::unique_ptr<AvbFooter> footer = GetAvbFooter(fd);
746 EXPECT_TRUE(footer != nullptr);
747
748 VBMetaVerifyResult verify_result;
749 std::string out_public_key_data;
750 std::unique_ptr<VBMetaData> vbmeta = VerifyVBMetaData(
751 fd, "system", "" /*expected_public_key_blob */, &out_public_key_data, &verify_result);
752 EXPECT_NE(nullptr, vbmeta);
753 EXPECT_EQ(VBMetaVerifyResult::kSuccess, verify_result);
754
755 auto rsa8192_public_key_blob = ExtractPublicKeyAvbBlob(data_dir_.Append("testkey_rsa8192.pem"));
756 EXPECT_EQ(rsa8192_public_key_blob, out_public_key_data);
757
758 // Modifies hash and signature, checks there is verification error.
759 auto header = vbmeta->GetVBMetaHeader(true /* update_vbmeta_size */);
760 size_t header_block_offset = 0;
761 size_t authentication_block_offset = header_block_offset + sizeof(AvbVBMetaImageHeader);
762
763 // Modifies the hash.
764 ModifyFile(system_path,
765 footer->vbmeta_offset + authentication_block_offset + header->hash_offset,
766 header->hash_size);
767 android::base::unique_fd hash_modified_fd(
768 open(system_path.value().c_str(), O_RDONLY | O_CLOEXEC));
769 ASSERT_TRUE(hash_modified_fd > 0);
770 // Should return ErrorVerification.
771 vbmeta = VerifyVBMetaData(hash_modified_fd, "system", "" /*expected_public_key_blob */,
772 nullptr /* out_public_key_data */, &verify_result);
773 EXPECT_NE(nullptr, vbmeta);
774 EXPECT_TRUE(CompareVBMeta(system_path, *vbmeta));
775 EXPECT_EQ(VBMetaVerifyResult::kErrorVerification, verify_result);
776
777 // Modifies the auxiliary data block.
778 size_t auxiliary_block_offset =
779 authentication_block_offset + header->authentication_data_block_size;
780 ModifyFile(system_path, footer->vbmeta_offset + auxiliary_block_offset,
781 header->auxiliary_data_block_size);
782 android::base::unique_fd aux_modified_fd(
783 open(system_path.value().c_str(), O_RDONLY | O_CLOEXEC));
784 ASSERT_TRUE(aux_modified_fd > 0);
785 // Should return ErrorVerification.
786 vbmeta = VerifyVBMetaData(aux_modified_fd, "system", "" /*expected_public_key_blob */,
787 nullptr /* out_public_key_data */, &verify_result);
788 EXPECT_NE(nullptr, vbmeta);
789 EXPECT_TRUE(CompareVBMeta(system_path, *vbmeta));
790 EXPECT_EQ(VBMetaVerifyResult::kErrorVerification, verify_result);
791
792 // Resets previous modification by setting offset to -1, and checks the verification can pass.
793 ModifyFile(system_path, 0 /* offset */, -1 /* length */);
794 android::base::unique_fd ok_fd(open(system_path.value().c_str(), O_RDONLY | O_CLOEXEC));
795 ASSERT_TRUE(ok_fd > 0);
796 // Should return ResultOK..
797 vbmeta = VerifyVBMetaData(ok_fd, "system", "" /*expected_public_key_blob */,
798 nullptr /* out_public_key_data */, &verify_result);
799 EXPECT_NE(nullptr, vbmeta);
800 EXPECT_TRUE(CompareVBMeta(system_path, *vbmeta));
801 EXPECT_EQ(VBMetaVerifyResult::kSuccess, verify_result);
802 }
803
TEST_F(AvbUtilTest,GetChainPartitionInfo)804 TEST_F(AvbUtilTest, GetChainPartitionInfo) {
805 // Generates a raw boot.img
806 const size_t boot_image_size = 5 * 1024 * 1024;
807 const size_t boot_partition_size = 10 * 1024 * 1024;
808 base::FilePath boot_path = GenerateImage("boot.img", boot_image_size);
809 // Adds AVB Hash Footer.
810 AddAvbFooter(boot_path, "hash", "boot", boot_partition_size, "SHA256_RSA2048", 10,
811 data_dir_.Append("testkey_rsa2048.pem"), "d00df00d",
812 "--internal_release_string \"unit test\"");
813
814 // Generates a raw system.img, use a smaller size to speed-up unit test.
815 const size_t system_image_size = 10 * 1024 * 1024;
816 const size_t system_partition_size = 15 * 1024 * 1024;
817 base::FilePath system_path = GenerateImage("system.img", system_image_size);
818 // Adds AVB Hashtree Footer.
819 AddAvbFooter(system_path, "hashtree", "system", system_partition_size, "SHA512_RSA4096", 20,
820 data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
821 "--internal_release_string \"unit test\"");
822
823 // Generates chain partition descriptors.
824 base::FilePath rsa2048_public_key =
825 ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa2048.pem"));
826 base::FilePath rsa4096_public_key =
827 ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa4096.pem"));
828 // Makes a vbmeta_system.img including the 'system' chained descriptor.
829 GenerateVBMetaImage("vbmeta_system.img", "SHA256_RSA4096", 0,
830 data_dir_.Append("testkey_rsa4096.pem"),
831 {}, /* include_descriptor_image_paths */
832 {{"system", 3, rsa4096_public_key}}, /* chain_partitions */
833 "--internal_release_string \"unit test\"");
834
835 // Makes a vbmeta image includeing 'boot' and 'vbmeta_system' chained descriptors.
836 GenerateVBMetaImage("vbmeta.img", "SHA256_RSA8192", 0, data_dir_.Append("testkey_rsa8192.pem"),
837 {}, /* include_descriptor_image_paths */
838 {{"boot", 1, rsa2048_public_key}, /* chain_partitions */
839 {"vbmeta_system", 2, rsa4096_public_key}},
840 "--internal_release_string \"unit test\"");
841
842 // Calculates the digest of all chained partitions, to ensure the chained is formed properly.
843 EXPECT_EQ("6f4bf815a651aa35ec7102a88b7906b91aef284bc5e20d0bf527c7d460da3266",
844 CalcVBMetaDigest("vbmeta.img", "sha256"));
845 // Loads the key blobs for comparison.
846 std::string expected_key_blob_2048;
847 EXPECT_TRUE(base::ReadFileToString(rsa2048_public_key, &expected_key_blob_2048));
848 std::string expected_key_blob_4096;
849 EXPECT_TRUE(base::ReadFileToString(rsa4096_public_key, &expected_key_blob_4096));
850
851 // Checks chain descriptors in vbmeta.img
852 EXPECT_EQ(
853 "Minimum libavb version: 1.0\n"
854 "Header Block: 256 bytes\n"
855 "Authentication Block: 1088 bytes\n"
856 "Auxiliary Block: 3840 bytes\n"
857 "Algorithm: SHA256_RSA8192\n"
858 "Rollback Index: 0\n"
859 "Flags: 0\n"
860 "Release String: 'unit test'\n"
861 "Descriptors:\n"
862 " Chain Partition descriptor:\n"
863 " Partition Name: boot\n"
864 " Rollback Index Location: 1\n"
865 " Public key (sha1): cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
866 " Chain Partition descriptor:\n"
867 " Partition Name: vbmeta_system\n"
868 " Rollback Index Location: 2\n"
869 " Public key (sha1): 2597c218aae470a130f61162feaae70afd97f011\n",
870 InfoImage("vbmeta.img"));
871
872 bool fatal_error = false;
873 auto chained_descriptors = GetChainPartitionInfo(LoadVBMetaData("vbmeta.img"), &fatal_error);
874 EXPECT_EQ(2, chained_descriptors.size()); // contains 'boot' and 'vbmeta_system'.
875 EXPECT_EQ(false, fatal_error);
876
877 EXPECT_EQ("boot", chained_descriptors[0].partition_name);
878 EXPECT_EQ(expected_key_blob_2048, chained_descriptors[0].public_key_blob);
879
880 EXPECT_EQ("vbmeta_system", chained_descriptors[1].partition_name);
881 EXPECT_EQ(expected_key_blob_4096, chained_descriptors[1].public_key_blob);
882
883 // Checks chain descriptors in vbmeta_system.img
884 EXPECT_EQ(
885 "Minimum libavb version: 1.0\n"
886 "Header Block: 256 bytes\n"
887 "Authentication Block: 576 bytes\n"
888 "Auxiliary Block: 2176 bytes\n"
889 "Algorithm: SHA256_RSA4096\n"
890 "Rollback Index: 0\n"
891 "Flags: 0\n"
892 "Release String: 'unit test'\n"
893 "Descriptors:\n"
894 " Chain Partition descriptor:\n"
895 " Partition Name: system\n"
896 " Rollback Index Location: 3\n"
897 " Public key (sha1): 2597c218aae470a130f61162feaae70afd97f011\n",
898 InfoImage("vbmeta_system.img"));
899
900 chained_descriptors = GetChainPartitionInfo(LoadVBMetaData("vbmeta_system.img"), &fatal_error);
901 EXPECT_EQ(1, chained_descriptors.size()); // contains 'system' only.
902 EXPECT_EQ(false, fatal_error);
903 EXPECT_EQ("system", chained_descriptors[0].partition_name);
904 EXPECT_EQ(expected_key_blob_4096, chained_descriptors[0].public_key_blob);
905 }
906
TEST_F(AvbUtilTest,GetChainPartitionInfoNone)907 TEST_F(AvbUtilTest, GetChainPartitionInfoNone) {
908 // Generates a raw boot.img
909 const size_t boot_image_size = 5 * 1024 * 1024;
910 const size_t boot_partition_size = 10 * 1024 * 1024;
911 base::FilePath boot_path = GenerateImage("boot.img", boot_image_size);
912 // Adds AVB Hash Footer.
913 AddAvbFooter(boot_path, "hash", "boot", boot_partition_size, "SHA256_RSA4096", 10,
914 data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
915 "--internal_release_string \"unit test\"");
916
917 // Generates a raw system.img, use a smaller size to speed-up unit test.
918 const size_t system_image_size = 10 * 1024 * 1024;
919 const size_t system_partition_size = 15 * 1024 * 1024;
920 base::FilePath system_path = GenerateImage("system.img", system_image_size);
921 // Adds AVB Hashtree Footer.
922 AddAvbFooter(system_path, "hashtree", "system", system_partition_size, "SHA512_RSA8192", 20,
923 data_dir_.Append("testkey_rsa8192.pem"), "d00df00d",
924 "--internal_release_string \"unit test\"");
925
926 // Makes a vbmeta.img including both 'boot' and 'system' descriptors.
927 GenerateVBMetaImage("vbmeta.img", "SHA256_RSA2048", 0, data_dir_.Append("testkey_rsa2048.pem"),
928 {boot_path, system_path}, /* include_descriptor_image_paths */
929 {}, /* chain_partitions */
930 "--internal_release_string \"unit test\"");
931 EXPECT_EQ("a069cbfc30c816cddf3b53f1ad53b7ca5d61a3d93845eb596bbb1b40caa1c62f",
932 CalcVBMetaDigest("vbmeta.img", "sha256"));
933
934 EXPECT_EQ(
935 "Minimum libavb version: 1.0\n"
936 "Header Block: 256 bytes\n"
937 "Authentication Block: 320 bytes\n"
938 "Auxiliary Block: 960 bytes\n"
939 "Algorithm: SHA256_RSA2048\n"
940 "Rollback Index: 0\n"
941 "Flags: 0\n"
942 "Release String: 'unit test'\n"
943 "Descriptors:\n"
944 " Hash descriptor:\n"
945 " Image Size: 5242880 bytes\n"
946 " Hash Algorithm: sha256\n"
947 " Partition Name: boot\n"
948 " Salt: d00df00d\n"
949 " Digest: "
950 "222dd01e98284a1fcd7781f85d1392e43a530511a64eff96db197db90ebc4df1\n"
951 " Flags: 0\n"
952 " Hashtree descriptor:\n"
953 " Version of dm-verity: 1\n"
954 " Image Size: 10485760 bytes\n"
955 " Tree Offset: 10485760\n"
956 " Tree Size: 86016 bytes\n"
957 " Data Block Size: 4096 bytes\n"
958 " Hash Block Size: 4096 bytes\n"
959 " FEC num roots: 2\n"
960 " FEC offset: 10571776\n"
961 " FEC size: 90112 bytes\n"
962 " Hash Algorithm: sha1\n"
963 " Partition Name: system\n"
964 " Salt: d00df00d\n"
965 " Root Digest: a3d5dd307341393d85de356c384ff543ec1ed81b\n"
966 " Flags: 0\n",
967 InfoImage("vbmeta.img"));
968
969 // Checks none of chain descriptors is found.
970 bool fatal_error = false;
971 auto chained_descriptors = GetChainPartitionInfo(LoadVBMetaData("vbmeta.img"), &fatal_error);
972 EXPECT_EQ(0, chained_descriptors.size()); // There is no chain descriptors.
973 EXPECT_EQ(false, fatal_error);
974 }
975
TEST_F(AvbUtilTest,LoadAndVerifyVbmetaByPath)976 TEST_F(AvbUtilTest, LoadAndVerifyVbmetaByPath) {
977 // Generates a raw system_other.img, use a smaller size to speed-up unit test.
978 const size_t system_image_size = 10 * 1024 * 1024;
979 const size_t system_partition_size = 15 * 1024 * 1024;
980 base::FilePath system_path = GenerateImage("system_other.img", system_image_size);
981
982 // Adds AVB Hashtree Footer.
983 AddAvbFooter(system_path, "hashtree", "system_other", system_partition_size, "SHA512_RSA4096",
984 20, data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
985 "--internal_release_string \"unit test\"");
986
987 std::string expected_key_blob_4096 =
988 ExtractPublicKeyAvbBlob(data_dir_.Append("testkey_rsa4096.pem"));
989
990 bool verification_disabled;
991 VBMetaVerifyResult verify_result;
992 std::string out_public_key_data;
993 std::unique_ptr<VBMetaData> vbmeta = LoadAndVerifyVbmetaByPath(
994 system_path.value(), "system_other", expected_key_blob_4096,
995 false /* allow_verification_error */, false /* rollback_protection */,
996 false /* is_chained_vbmeta */, &out_public_key_data, &verification_disabled,
997 &verify_result);
998
999 EXPECT_NE(nullptr, vbmeta);
1000 EXPECT_EQ(VBMetaVerifyResult::kSuccess, verify_result);
1001 EXPECT_EQ(false, verification_disabled);
1002 EXPECT_EQ(expected_key_blob_4096, out_public_key_data);
1003
1004 EXPECT_EQ(2112UL, vbmeta->size());
1005 EXPECT_EQ(system_path.value(), vbmeta->vbmeta_path());
1006 EXPECT_EQ("system_other", vbmeta->partition());
1007 EXPECT_TRUE(CompareVBMeta(system_path, *vbmeta));
1008 }
1009
TEST_F(AvbUtilTest,LoadAndVerifyVbmetaByPathErrorVerification)1010 TEST_F(AvbUtilTest, LoadAndVerifyVbmetaByPathErrorVerification) {
1011 // Generates a raw system_other.img, use a smaller size to speed-up unit test.
1012 const size_t system_image_size = 10 * 1024 * 1024;
1013 const size_t system_partition_size = 15 * 1024 * 1024;
1014 base::FilePath system_path = GenerateImage("system_other.img", system_image_size);
1015
1016 // Adds AVB Hashtree Footer.
1017 AddAvbFooter(system_path, "hashtree", "system_other", system_partition_size, "SHA512_RSA4096",
1018 20, data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
1019 "--internal_release_string \"unit test\"");
1020
1021 std::string expected_key_blob_4096 =
1022 ExtractPublicKeyAvbBlob(data_dir_.Append("testkey_rsa4096.pem"));
1023
1024 // Modifies the auxiliary data of system_other.img
1025 auto fd = OpenUniqueReadFd(system_path);
1026 auto system_footer = GetAvbFooter(fd);
1027 auto system_vbmeta = ExtractAndLoadVBMetaData(system_path, "system_other-vbmeta.img");
1028 auto system_header = system_vbmeta.GetVBMetaHeader(true /* update_vbmeta_size */);
1029 size_t header_block_offset = 0;
1030 size_t authentication_block_offset = header_block_offset + sizeof(AvbVBMetaImageHeader);
1031 size_t auxiliary_block_offset =
1032 authentication_block_offset + system_header->authentication_data_block_size;
1033
1034 // Modifies the hash.
1035 ModifyFile(
1036 system_path,
1037 (system_footer->vbmeta_offset + authentication_block_offset + system_header->hash_offset),
1038 system_header->hash_size);
1039
1040 VBMetaVerifyResult verify_result;
1041 // Not allow verification error.
1042 std::unique_ptr<VBMetaData> vbmeta = LoadAndVerifyVbmetaByPath(
1043 system_path.value(), "system_other", expected_key_blob_4096,
1044 false /* allow_verification_error */, false /* rollback_protection */,
1045 false /* is_chained_vbmeta */, nullptr /* out_public_key_data */,
1046 nullptr /* verification_disabled */, &verify_result);
1047 EXPECT_EQ(nullptr, vbmeta);
1048
1049 // Allow verification error.
1050 vbmeta = LoadAndVerifyVbmetaByPath(
1051 system_path.value(), "system_other", expected_key_blob_4096,
1052 true /* allow_verification_error */, false /* rollback_protection */,
1053 false /* is_chained_vbmeta */, nullptr /* out_public_key_data */,
1054 nullptr /* verification_disabled */, &verify_result);
1055 EXPECT_NE(nullptr, vbmeta);
1056 EXPECT_EQ(VBMetaVerifyResult::kErrorVerification, verify_result);
1057
1058 EXPECT_EQ(2112UL, vbmeta->size());
1059 EXPECT_EQ(system_path.value(), vbmeta->vbmeta_path());
1060 EXPECT_EQ("system_other", vbmeta->partition());
1061 EXPECT_TRUE(CompareVBMeta(system_path, *vbmeta));
1062
1063 // Modifies the auxiliary data block.
1064 ModifyFile(system_path, system_footer->vbmeta_offset + auxiliary_block_offset,
1065 system_header->auxiliary_data_block_size);
1066
1067 // Not allow verification error.
1068 vbmeta = LoadAndVerifyVbmetaByPath(
1069 system_path.value(), "system_other", expected_key_blob_4096,
1070 false /* allow_verification_error */, false /* rollback_protection */,
1071 false /* is_chained_vbmeta */, nullptr /* out_public_key_data */,
1072 nullptr /* verification_disabled */, &verify_result);
1073 EXPECT_EQ(nullptr, vbmeta);
1074
1075 // Allow verification error.
1076 vbmeta = LoadAndVerifyVbmetaByPath(
1077 system_path.value(), "system_other", expected_key_blob_4096,
1078 true /* allow_verification_error */, false /* rollback_protection */,
1079 false /* is_chained_vbmeta */, nullptr /* out_public_key_data */,
1080 nullptr /* verification_disabled */, &verify_result);
1081 EXPECT_NE(nullptr, vbmeta);
1082 EXPECT_EQ(VBMetaVerifyResult::kErrorVerification, verify_result);
1083 }
1084
TEST_F(AvbUtilTest,LoadAndVerifyVbmetaByPathUnexpectedPublicKey)1085 TEST_F(AvbUtilTest, LoadAndVerifyVbmetaByPathUnexpectedPublicKey) {
1086 // Generates a raw system_other.img, use a smaller size to speed-up unit test.
1087 const size_t system_image_size = 10 * 1024 * 1024;
1088 const size_t system_partition_size = 15 * 1024 * 1024;
1089 base::FilePath system_path = GenerateImage("system_other.img", system_image_size);
1090
1091 // Adds AVB Hashtree Footer.
1092 AddAvbFooter(system_path, "hashtree", "system_other", system_partition_size, "SHA512_RSA4096",
1093 20, data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
1094 "--internal_release_string \"unit test\"");
1095
1096 std::string unexpected_key_blob_2048 =
1097 ExtractPublicKeyAvbBlob(data_dir_.Append("testkey_rsa2048.pem"));
1098 std::string expected_key_blob_4096 =
1099 ExtractPublicKeyAvbBlob(data_dir_.Append("testkey_rsa4096.pem"));
1100
1101 // Uses the correct expected public key.
1102 VBMetaVerifyResult verify_result;
1103 std::string out_public_key_data;
1104 std::unique_ptr<VBMetaData> vbmeta = LoadAndVerifyVbmetaByPath(
1105 system_path.value(), "system_other", expected_key_blob_4096,
1106 false /* allow_verification_error */, false /* rollback_protection */,
1107 false /* is_chained_vbmeta */, &out_public_key_data,
1108 nullptr /* verification_disabled */, &verify_result);
1109 EXPECT_NE(nullptr, vbmeta);
1110 EXPECT_EQ(verify_result, VBMetaVerifyResult::kSuccess);
1111 EXPECT_EQ(expected_key_blob_4096, out_public_key_data);
1112 EXPECT_EQ(2112UL, vbmeta->size());
1113 EXPECT_EQ(system_path.value(), vbmeta->vbmeta_path());
1114 EXPECT_EQ("system_other", vbmeta->partition());
1115 EXPECT_TRUE(CompareVBMeta(system_path, *vbmeta));
1116
1117 // Uses the wrong expected public key with allow_verification_error set to false.
1118 vbmeta = LoadAndVerifyVbmetaByPath(
1119 system_path.value(), "system_other", unexpected_key_blob_2048,
1120 false /* allow_verification_error */, false /* rollback_protection */,
1121 false /* is_chained_vbmeta */, &out_public_key_data,
1122 nullptr /* verification_disabled */, &verify_result);
1123 EXPECT_EQ(nullptr, vbmeta);
1124 // Checks out_public_key_data is still loaded properly, if the error is due
1125 // to an unexpected public key instead of vbmeta image verification error.
1126 EXPECT_EQ(expected_key_blob_4096, out_public_key_data);
1127
1128 // Uses the wrong expected public key with allow_verification_error set to true.
1129 vbmeta = LoadAndVerifyVbmetaByPath(
1130 system_path.value(), "system_other", unexpected_key_blob_2048,
1131 true /* allow_verification_error */, false /* rollback_protection */,
1132 false /* is_chained_vbmeta */, &out_public_key_data,
1133 nullptr /* verification_disabled */, &verify_result);
1134 EXPECT_NE(nullptr, vbmeta);
1135 EXPECT_EQ(expected_key_blob_4096, out_public_key_data);
1136 EXPECT_EQ(verify_result, VBMetaVerifyResult::kErrorVerification);
1137 EXPECT_EQ(2112UL, vbmeta->size());
1138 EXPECT_EQ(system_path.value(), vbmeta->vbmeta_path());
1139 EXPECT_EQ("system_other", vbmeta->partition());
1140 EXPECT_TRUE(CompareVBMeta(system_path, *vbmeta));
1141 }
1142
TEST_F(AvbUtilTest,LoadAndVerifyVbmetaByPathVerificationDisabled)1143 TEST_F(AvbUtilTest, LoadAndVerifyVbmetaByPathVerificationDisabled) {
1144 // Generates a raw system_other.img, use a smaller size to speed-up unit test.
1145 const size_t system_image_size = 10 * 1024 * 1024;
1146 const size_t system_partition_size = 15 * 1024 * 1024;
1147 base::FilePath system_path = GenerateImage("system_other.img", system_image_size);
1148
1149 // Adds AVB Hashtree Footer.
1150 AddAvbFooter(system_path, "hashtree", "system_other", system_partition_size, "SHA512_RSA4096",
1151 20, data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
1152 "--internal_release_string \"unit test\"");
1153
1154 base::FilePath rsa4096_public_key =
1155 ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa4096.pem"));
1156
1157 std::string expected_key_blob_4096;
1158 EXPECT_TRUE(base::ReadFileToString(rsa4096_public_key, &expected_key_blob_4096));
1159
1160 // Sets disabled flag and expect the returned verification_disabled is true.
1161 SetVBMetaFlags(system_path, AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED);
1162 bool verification_disabled;
1163 VBMetaVerifyResult verify_result;
1164 std::string out_public_key_data;
1165 std::unique_ptr<VBMetaData> vbmeta = LoadAndVerifyVbmetaByPath(
1166 system_path.value(), "system_other", expected_key_blob_4096,
1167 true /* allow_verification_error */, false /* rollback_protection */,
1168 false /* is_chained_vbmeta */, nullptr /* out_public_key_data */,
1169 &verification_disabled, &verify_result);
1170
1171 EXPECT_NE(nullptr, vbmeta);
1172 EXPECT_EQ(VBMetaVerifyResult::kErrorVerification, verify_result);
1173 EXPECT_EQ(true, verification_disabled); // should be true.
1174
1175 EXPECT_EQ(2112UL, vbmeta->size());
1176 EXPECT_EQ(system_path.value(), vbmeta->vbmeta_path());
1177 EXPECT_EQ("system_other", vbmeta->partition());
1178 EXPECT_TRUE(CompareVBMeta(system_path, *vbmeta));
1179
1180 // Since the vbmeta flags is modified, vbmeta will be nullptr
1181 // if verification error isn't allowed.
1182 vbmeta = LoadAndVerifyVbmetaByPath(
1183 system_path.value(), "system_other", expected_key_blob_4096,
1184 false /* allow_verification_error */, false /* rollback_protection */,
1185 false /* is_chained_vbmeta */, nullptr /* out_public_key_data */,
1186 &verification_disabled, &verify_result);
1187 EXPECT_EQ(nullptr, vbmeta);
1188 }
1189
TEST_F(AvbUtilTest,LoadAndVerifyVbmetaByPartition)1190 TEST_F(AvbUtilTest, LoadAndVerifyVbmetaByPartition) {
1191 // Generates a raw boot.img
1192 const size_t boot_image_size = 5 * 1024 * 1024;
1193 const size_t boot_partition_size = 10 * 1024 * 1024;
1194 base::FilePath boot_path = GenerateImage("boot.img", boot_image_size);
1195
1196 // Adds AVB Hash Footer.
1197 AddAvbFooter(boot_path, "hash", "boot", boot_partition_size, "SHA256_RSA2048", 10,
1198 data_dir_.Append("testkey_rsa2048.pem"), "d00df00d",
1199 "--internal_release_string \"unit test\"");
1200
1201 // Generates a raw system.img, use a smaller size to speed-up unit test.
1202 const size_t system_image_size = 10 * 1024 * 1024;
1203 const size_t system_partition_size = 15 * 1024 * 1024;
1204 base::FilePath system_path = GenerateImage("system.img", system_image_size);
1205 // Adds AVB Hashtree Footer.
1206 AddAvbFooter(system_path, "hashtree", "system", system_partition_size, "SHA512_RSA4096", 20,
1207 data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
1208 "--internal_release_string \"unit test\"");
1209
1210 // Generates chain partition descriptors.
1211 base::FilePath rsa2048_public_key =
1212 ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa2048.pem"));
1213 base::FilePath rsa4096_public_key =
1214 ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa4096.pem"));
1215 // Makes a vbmeta_system.img including the 'system' chained descriptor.
1216 auto vbmeta_system_path = GenerateVBMetaImage(
1217 "vbmeta_system.img", "SHA256_RSA4096", 0, data_dir_.Append("testkey_rsa4096.pem"),
1218 {}, /* include_descriptor_image_paths */
1219 {{"system", 3, rsa4096_public_key}}, /* chain_partitions */
1220 "--internal_release_string \"unit test\"");
1221
1222 // Makes a vbmeta image includeing 'boot' and 'vbmeta_system' chained descriptors.
1223 auto vbmeta_path = GenerateVBMetaImage("vbmeta.img", "SHA256_RSA8192", 0,
1224 data_dir_.Append("testkey_rsa8192.pem"),
1225 {}, /* include_descriptor_image_paths */
1226 {{"boot", 1, rsa2048_public_key}, /* chain_partitions */
1227 {"vbmeta_system", 2, rsa4096_public_key}},
1228 "--internal_release_string \"unit test\"");
1229
1230 // Calculates the digest of all chained partitions, to ensure the chained is formed properly.
1231 EXPECT_EQ("6f4bf815a651aa35ec7102a88b7906b91aef284bc5e20d0bf527c7d460da3266",
1232 CalcVBMetaDigest("vbmeta.img", "sha256"));
1233
1234 // Starts to test LoadAndVerifyVbmetaByPartition.
1235 std::vector<VBMetaData> vbmeta_images;
1236 auto vbmeta_image_path = [this](const std::string& partition_name) {
1237 return test_dir_.Append(partition_name + ".img").value();
1238 };
1239
1240 EXPECT_EQ(VBMetaVerifyResult::kSuccess,
1241 LoadAndVerifyVbmetaByPartition(
1242 "vbmeta" /* partition_name */, "" /* ab_suffix */, "" /* other_suffix */,
1243 "" /* expected_public_key_blob*/, false /* allow_verification_error */,
1244 true /* load_chained_vbmeta */, true /* rollback_protection */, vbmeta_image_path,
1245 false /* is_chained_vbmeta*/, &vbmeta_images));
1246
1247 EXPECT_EQ(4UL, vbmeta_images.size()); // vbmeta, boot, vbmeta_system and system
1248 // Binary comparison for each vbmeta image.
1249 EXPECT_TRUE(CompareVBMeta(vbmeta_path, vbmeta_images[0]));
1250 EXPECT_TRUE(CompareVBMeta(boot_path, vbmeta_images[1]));
1251 EXPECT_TRUE(CompareVBMeta(vbmeta_system_path, vbmeta_images[2]));
1252 EXPECT_TRUE(CompareVBMeta(system_path, vbmeta_images[3]));
1253
1254 // Skip loading chained vbmeta images.
1255 vbmeta_images.clear();
1256 EXPECT_EQ(VBMetaVerifyResult::kSuccess,
1257 LoadAndVerifyVbmetaByPartition(
1258 "vbmeta" /* partition_name */, "" /* ab_suffix */, "" /* other_suffix */,
1259 "" /* expected_public_key_blob*/, false /* allow_verification_error */,
1260 false /* load_chained_vbmeta */, true /* rollback_protection */,
1261 vbmeta_image_path, false /* is_chained_vbmeta*/, &vbmeta_images));
1262 // Only vbmeta is loaded.
1263 EXPECT_EQ(1UL, vbmeta_images.size());
1264 EXPECT_TRUE(CompareVBMeta(vbmeta_path, vbmeta_images[0]));
1265 }
1266
TEST_F(AvbUtilTest,LoadAndVerifyVbmetaByPartitionWithSuffixes)1267 TEST_F(AvbUtilTest, LoadAndVerifyVbmetaByPartitionWithSuffixes) {
1268 // Tests the following chained partitions.
1269 // vbmeta_a.img
1270 // |--> boot_b.img (boot_other)
1271 // |--> vbmeta_system_b.img (vbmeta_system_other)
1272 // |--> system_a.img
1273
1274 // Generates a raw boot_b.img
1275 const size_t boot_image_size = 5 * 1024 * 1024;
1276 const size_t boot_partition_size = 10 * 1024 * 1024;
1277 base::FilePath boot_path = GenerateImage("boot_b.img", boot_image_size);
1278
1279 // Adds AVB Hash Footer.
1280 AddAvbFooter(boot_path, "hash", "boot", boot_partition_size, "SHA256_RSA2048", 10,
1281 data_dir_.Append("testkey_rsa2048.pem"), "d00df00d",
1282 "--internal_release_string \"unit test\"");
1283
1284 // Generates a raw system_a.img, use a smaller size to speed-up unit test.
1285 const size_t system_image_size = 10 * 1024 * 1024;
1286 const size_t system_partition_size = 15 * 1024 * 1024;
1287 base::FilePath system_path = GenerateImage("system_a.img", system_image_size);
1288 // Adds AVB Hashtree Footer.
1289 AddAvbFooter(system_path, "hashtree", "system", system_partition_size, "SHA512_RSA4096", 20,
1290 data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
1291 "--internal_release_string \"unit test\"");
1292
1293 // Generates chain partition descriptors.
1294 base::FilePath rsa2048_public_key =
1295 ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa2048.pem"));
1296 base::FilePath rsa4096_public_key =
1297 ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa4096.pem"));
1298 // Makes a vbmeta_system_b.img including the 'system' chained descriptor.
1299 auto vbmeta_system_path = GenerateVBMetaImage(
1300 "vbmeta_system_b.img", "SHA256_RSA4096", 0, data_dir_.Append("testkey_rsa4096.pem"),
1301 {}, /* include_descriptor_image_paths */
1302 {{"system", 3, rsa4096_public_key}}, /* chain_partitions */
1303 "--internal_release_string \"unit test\"");
1304
1305 // Makes a vbmeta_a.img includeing 'boot_other' and 'vbmeta_system_other' chained descriptors.
1306 auto vbmeta_path = GenerateVBMetaImage(
1307 "vbmeta_a.img", "SHA256_RSA8192", 0, data_dir_.Append("testkey_rsa8192.pem"),
1308 {}, /* include_descriptor_image_paths */
1309 {{"boot_other", 1, rsa2048_public_key}, /* chain_partitions */
1310 {"vbmeta_system_other", 2, rsa4096_public_key}},
1311 "--internal_release_string \"unit test\"");
1312
1313 // Starts to test LoadAndVerifyVbmetaByPartition with ab_suffix and ab_other_suffix.
1314 auto vbmeta_image_path = [this](const std::string& partition_name) {
1315 return test_dir_.Append(partition_name + ".img").value();
1316 };
1317
1318 std::vector<VBMetaData> vbmeta_images;
1319 EXPECT_EQ(VBMetaVerifyResult::kSuccess,
1320 LoadAndVerifyVbmetaByPartition(
1321 "vbmeta" /* partition_name */, "_a" /* ab_suffix */, "_b" /* other_suffix */,
1322 "" /* expected_public_key_blob*/, false /* allow_verification_error */,
1323 true /* load_chained_vbmeta */, true /* rollback_protection */, vbmeta_image_path,
1324 false /* is_chained_vbmeta*/, &vbmeta_images));
1325
1326 EXPECT_EQ(4UL, vbmeta_images.size()); // vbmeta, boot_other, vbmeta_system_other and system
1327 // Binary comparison for each vbmeta image.
1328 EXPECT_TRUE(CompareVBMeta(vbmeta_path, vbmeta_images[0]));
1329 EXPECT_TRUE(CompareVBMeta(boot_path, vbmeta_images[1]));
1330 EXPECT_TRUE(CompareVBMeta(vbmeta_system_path, vbmeta_images[2]));
1331 EXPECT_TRUE(CompareVBMeta(system_path, vbmeta_images[3]));
1332
1333 // Skips loading chained vbmeta images.
1334 vbmeta_images.clear();
1335 EXPECT_EQ(VBMetaVerifyResult::kSuccess,
1336 LoadAndVerifyVbmetaByPartition(
1337 "vbmeta" /* partition_name */, "_a" /* ab_suffix */, "_b" /* other_suffix */,
1338 "" /* expected_public_key_blob*/, false /* allow_verification_error */,
1339 false /* load_chained_vbmeta */, true /* rollback_protection */,
1340 vbmeta_image_path, false /* is_chained_vbmeta*/, &vbmeta_images));
1341 // Only vbmeta is loaded.
1342 EXPECT_EQ(1UL, vbmeta_images.size());
1343 EXPECT_TRUE(CompareVBMeta(vbmeta_path, vbmeta_images[0]));
1344
1345 // Using an invalid suffix for 'other' slot, checks it returns error.
1346 EXPECT_EQ(VBMetaVerifyResult::kError,
1347 LoadAndVerifyVbmetaByPartition(
1348 "vbmeta" /* partition_name */, "_a" /* ab_suffix */,
1349 "_invalid_suffix" /* other_suffix */, "" /* expected_public_key_blob*/,
1350 false /* allow_verification_error */, true /* load_chained_vbmeta */,
1351 true /* rollback_protection */, vbmeta_image_path, false /* is_chained_vbmeta*/,
1352 &vbmeta_images));
1353 }
1354
TEST_F(AvbUtilTest,LoadAndVerifyVbmetaByPartitionErrorVerification)1355 TEST_F(AvbUtilTest, LoadAndVerifyVbmetaByPartitionErrorVerification) {
1356 // Generates a raw boot.img
1357 const size_t boot_image_size = 5 * 1024 * 1024;
1358 const size_t boot_partition_size = 10 * 1024 * 1024;
1359 base::FilePath boot_path = GenerateImage("boot.img", boot_image_size);
1360
1361 // Adds AVB Hash Footer.
1362 AddAvbFooter(boot_path, "hash", "boot", boot_partition_size, "SHA256_RSA2048", 10,
1363 data_dir_.Append("testkey_rsa2048.pem"), "d00df00d",
1364 "--internal_release_string \"unit test\"");
1365
1366 // Generates a raw system.img, use a smaller size to speed-up unit test.
1367 const size_t system_image_size = 10 * 1024 * 1024;
1368 const size_t system_partition_size = 15 * 1024 * 1024;
1369 base::FilePath system_path = GenerateImage("system.img", system_image_size);
1370 // Adds AVB Hashtree Footer.
1371 AddAvbFooter(system_path, "hashtree", "system", system_partition_size, "SHA512_RSA4096", 20,
1372 data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
1373 "--internal_release_string \"unit test\"");
1374
1375 // Generates chain partition descriptors.
1376 base::FilePath rsa2048_public_key =
1377 ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa2048.pem"));
1378 base::FilePath rsa4096_public_key =
1379 ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa4096.pem"));
1380
1381 // Makes a vbmeta image includeing 'boot' and 'vbmeta_system' chained descriptors.
1382 auto vbmeta_path = GenerateVBMetaImage("vbmeta.img", "SHA256_RSA8192", 0,
1383 data_dir_.Append("testkey_rsa8192.pem"),
1384 {}, /* include_descriptor_image_paths */
1385 {{"boot", 1, rsa2048_public_key}, /* chain_partitions */
1386 {"system", 2, rsa4096_public_key}},
1387 "--internal_release_string \"unit test\"");
1388
1389 // Calculates the digest of all chained partitions, to ensure the chained is formed properly.
1390 EXPECT_EQ("abbe11b316901f3336e26630f64c4732dadbe14532186ac8640e4141a403721f",
1391 CalcVBMetaDigest("vbmeta.img", "sha256"));
1392
1393 auto vbmeta = LoadVBMetaData("vbmeta.img");
1394
1395 // Modifies hash, checks there is error if allow_verification_error is false.
1396 auto header = vbmeta.GetVBMetaHeader(true /* update_vbmeta_size */);
1397 size_t header_block_offset = 0;
1398 size_t authentication_block_offset = header_block_offset + sizeof(AvbVBMetaImageHeader);
1399
1400 // Modifies the hash.
1401 ModifyFile(vbmeta_path, authentication_block_offset + header->hash_offset, header->hash_size);
1402
1403 // Starts to test LoadAndVerifyVbmetaByPartition.
1404 std::vector<VBMetaData> vbmeta_images;
1405 auto vbmeta_image_path = [this](const std::string& partition_name) {
1406 return test_dir_.Append(partition_name + ".img").value();
1407 };
1408 EXPECT_EQ(VBMetaVerifyResult::kError,
1409 LoadAndVerifyVbmetaByPartition(
1410 "vbmeta" /* partition_name */, "" /* ab_suffix */, "" /* other_suffix */,
1411 "" /* expected_public_key_blob*/, false /* allow_verification_error */,
1412 true /* load_chained_vbmeta */, true /* rollback_protection */, vbmeta_image_path,
1413 false /* is_chained_vbmeta*/, &vbmeta_images));
1414 // Stops to load vbmeta because the top-level vbmeta has verification error.
1415 EXPECT_EQ(0UL, vbmeta_images.size());
1416
1417 // Tries again with verification error allowed.
1418 EXPECT_EQ(VBMetaVerifyResult::kErrorVerification,
1419 LoadAndVerifyVbmetaByPartition(
1420 "vbmeta" /* partition_name */, "" /* ab_suffix */, "", /* other_suffix */
1421 "" /* expected_public_key_blob*/, true /* allow_verification_error */,
1422 true /* load_chained_vbmeta */, true /* rollback_protection */, vbmeta_image_path,
1423 false /* is_chained_vbmeta*/, &vbmeta_images));
1424
1425 EXPECT_EQ(3UL, vbmeta_images.size()); // vbmeta, boot, and system
1426 // Binary comparison for each vbmeta image.
1427 EXPECT_TRUE(CompareVBMeta(vbmeta_path, vbmeta_images[0]));
1428 EXPECT_TRUE(CompareVBMeta(boot_path, vbmeta_images[1]));
1429 EXPECT_TRUE(CompareVBMeta(system_path, vbmeta_images[2]));
1430
1431 // Resets the modification of the hash.
1432 ModifyFile(vbmeta_path, 0 /* offset */, -1 /* length */);
1433
1434 // Modifies the auxiliary data of system.img
1435 auto fd = OpenUniqueReadFd(system_path);
1436 auto system_footer = GetAvbFooter(fd);
1437 auto system_vbmeta = ExtractAndLoadVBMetaData(system_path, "system-vbmeta.img");
1438 auto system_header = system_vbmeta.GetVBMetaHeader(true /* update_vbmeta_size */);
1439 size_t auxiliary_block_offset =
1440 authentication_block_offset + system_header->authentication_data_block_size;
1441
1442 // Modifies the auxiliary data block.
1443 ModifyFile(system_path, system_footer->vbmeta_offset + auxiliary_block_offset,
1444 system_header->auxiliary_data_block_size);
1445 vbmeta_images.clear();
1446 EXPECT_EQ(VBMetaVerifyResult::kError,
1447 LoadAndVerifyVbmetaByPartition(
1448 "vbmeta" /* partition_name */, "" /* ab_suffix */, "" /* other_suffix */,
1449 "" /* expected_public_key_blob*/, false /* allow_verification_error */,
1450 true /* load_chained_vbmeta */, true /* rollback_protection */, vbmeta_image_path,
1451 false /* is_chained_vbmeta*/, &vbmeta_images));
1452 // 'vbmeta', 'boot' but no 'system', because of verification error.
1453 EXPECT_EQ(2UL, vbmeta_images.size());
1454 // Binary comparison for the loaded 'vbmeta' and 'boot'.
1455 EXPECT_TRUE(CompareVBMeta(vbmeta_path, vbmeta_images[0]));
1456 EXPECT_TRUE(CompareVBMeta(boot_path, vbmeta_images[1]));
1457
1458 // Resets the modification of the auxiliary data.
1459 ModifyFile(system_path, 0 /* offset */, -1 /* length */);
1460
1461 // Sets the vbmeta header flags on a chained partition, which introduces an error.
1462 ModifyFile(system_path, system_footer->vbmeta_offset + offsetof(AvbVBMetaImageHeader, flags),
1463 sizeof(uint32_t));
1464 EXPECT_EQ(VBMetaVerifyResult::kError,
1465 LoadAndVerifyVbmetaByPartition(
1466 "vbmeta" /* partition_name */, "" /* ab_suffix */, "" /* other_suffix */,
1467 "" /* expected_public_key_blob*/, true /* allow_verification_error */,
1468 true /* load_chained_vbmeta */, true /* rollback_protection */, vbmeta_image_path,
1469 false /* is_chained_vbmeta*/, &vbmeta_images));
1470 }
1471
TEST_F(AvbUtilTest,LoadAndVerifyVbmetaByPartitionVerificationDisabled)1472 TEST_F(AvbUtilTest, LoadAndVerifyVbmetaByPartitionVerificationDisabled) {
1473 // Generates a raw boot.img
1474 const size_t boot_image_size = 5 * 1024 * 1024;
1475 const size_t boot_partition_size = 10 * 1024 * 1024;
1476 base::FilePath boot_path = GenerateImage("boot.img", boot_image_size);
1477
1478 // Adds AVB Hash Footer.
1479 AddAvbFooter(boot_path, "hash", "boot", boot_partition_size, "SHA256_RSA2048", 10,
1480 data_dir_.Append("testkey_rsa2048.pem"), "d00df00d",
1481 "--internal_release_string \"unit test\"");
1482
1483 // Generates a raw system.img, use a smaller size to speed-up unit test.
1484 const size_t system_image_size = 10 * 1024 * 1024;
1485 const size_t system_partition_size = 15 * 1024 * 1024;
1486 base::FilePath system_path = GenerateImage("system.img", system_image_size);
1487 // Adds AVB Hashtree Footer.
1488 AddAvbFooter(system_path, "hashtree", "system", system_partition_size, "SHA512_RSA4096", 20,
1489 data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
1490 "--internal_release_string \"unit test\"");
1491
1492 // Generates chain partition descriptors.
1493 base::FilePath rsa2048_public_key =
1494 ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa2048.pem"));
1495 base::FilePath rsa4096_public_key =
1496 ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa4096.pem"));
1497 // Makes a vbmeta_system.img including the 'system' chained descriptor.
1498 auto vbmeta_system_path = GenerateVBMetaImage(
1499 "vbmeta_system.img", "SHA256_RSA4096", 0, data_dir_.Append("testkey_rsa4096.pem"),
1500 {}, /* include_descriptor_image_paths */
1501 {{"system", 3, rsa4096_public_key}}, /* chain_partitions */
1502 "--internal_release_string \"unit test\"");
1503
1504 // Makes a vbmeta image includeing 'boot' and 'vbmeta_system' chained descriptors.
1505 auto vbmeta_path = GenerateVBMetaImage("vbmeta.img", "SHA256_RSA8192", 0,
1506 data_dir_.Append("testkey_rsa8192.pem"),
1507 {}, /* include_descriptor_image_paths */
1508 {{"boot", 1, rsa2048_public_key}, /* chain_partitions */
1509 {"vbmeta_system", 2, rsa4096_public_key}},
1510 "--internal_release_string \"unit test\"");
1511
1512 // Calculates the digest of all chained partitions, to ensure the chained is formed properly.
1513 EXPECT_EQ("6f4bf815a651aa35ec7102a88b7906b91aef284bc5e20d0bf527c7d460da3266",
1514 CalcVBMetaDigest("vbmeta.img", "sha256"));
1515
1516 // Starts to test LoadAndVerifyVbmetaByPartition.
1517 std::vector<VBMetaData> vbmeta_images;
1518 auto vbmeta_image_path = [this](const std::string& partition_name) {
1519 return test_dir_.Append(partition_name + ".img").value();
1520 };
1521
1522 EXPECT_EQ(VBMetaVerifyResult::kSuccess,
1523 LoadAndVerifyVbmetaByPartition(
1524 "vbmeta" /* partition_name */, "" /* ab_suffix */, "" /* other_suffix */,
1525 "" /* expected_public_key_blob*/, false /* allow_verification_error */,
1526 true /* load_chained_vbmeta */, true /* rollback_protection */, vbmeta_image_path,
1527 false /* is_chained_vbmeta*/, &vbmeta_images));
1528
1529 EXPECT_EQ(4UL, vbmeta_images.size()); // vbmeta, boot, vbmeta_system and system
1530 // Binary comparison for each vbmeta image.
1531 EXPECT_TRUE(CompareVBMeta(vbmeta_path, vbmeta_images[0]));
1532 EXPECT_TRUE(CompareVBMeta(boot_path, vbmeta_images[1]));
1533 EXPECT_TRUE(CompareVBMeta(vbmeta_system_path, vbmeta_images[2]));
1534 EXPECT_TRUE(CompareVBMeta(system_path, vbmeta_images[3]));
1535
1536 // Sets VERIFICATION_DISABLED to the top-level vbmeta.img
1537 SetVBMetaFlags(vbmeta_path, AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED);
1538 vbmeta_images.clear();
1539 EXPECT_EQ(VBMetaVerifyResult::kErrorVerification,
1540 LoadAndVerifyVbmetaByPartition(
1541 "vbmeta" /* partition_name */, "" /* ab_suffix */, "" /* other_suffix */,
1542 "" /* expected_public_key_blob*/, true /* allow_verification_error */,
1543 true /* load_chained_vbmeta */, true /* rollback_protection */, vbmeta_image_path,
1544 false /* is_chained_vbmeta*/, &vbmeta_images));
1545 EXPECT_EQ(1UL, vbmeta_images.size()); // Only vbmeta is loaded
1546 EXPECT_TRUE(CompareVBMeta(vbmeta_path, vbmeta_images[0]));
1547
1548 // HASHTREE_DISABLED still loads the chained vbmeta.
1549 SetVBMetaFlags(vbmeta_path, AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED);
1550 vbmeta_images.clear();
1551 EXPECT_EQ(VBMetaVerifyResult::kErrorVerification,
1552 LoadAndVerifyVbmetaByPartition(
1553 "vbmeta" /* partition_name */, "" /* ab_suffix */, "" /* other_suffix */,
1554 "" /* expected_public_key_blob*/, true /* allow_verification_error */,
1555 true /* load_chained_vbmeta */, true /* rollback_protection */, vbmeta_image_path,
1556 false /* is_chained_vbmeta*/, &vbmeta_images));
1557 EXPECT_EQ(4UL, vbmeta_images.size()); // vbmeta, boot, vbmeta_system and system
1558 // Binary comparison for each vbmeta image.
1559 EXPECT_TRUE(CompareVBMeta(vbmeta_path, vbmeta_images[0]));
1560 EXPECT_TRUE(CompareVBMeta(boot_path, vbmeta_images[1]));
1561 EXPECT_TRUE(CompareVBMeta(vbmeta_system_path, vbmeta_images[2]));
1562 EXPECT_TRUE(CompareVBMeta(system_path, vbmeta_images[3]));
1563 }
1564
TEST_F(AvbUtilTest,LoadAndVerifyVbmetaByPartitionUnexpectedPublicKey)1565 TEST_F(AvbUtilTest, LoadAndVerifyVbmetaByPartitionUnexpectedPublicKey) {
1566 // Generates chain partition descriptors.
1567 base::FilePath rsa2048_public_key =
1568 ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa2048.pem"));
1569 base::FilePath rsa4096_public_key =
1570 ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa4096.pem"));
1571 base::FilePath rsa8192_public_key =
1572 ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa8192.pem"));
1573
1574 // Makes a vbmeta image includeing 'boot' and 'vbmeta_system' chained descriptors.
1575 auto vbmeta_path = GenerateVBMetaImage("vbmeta.img", "SHA256_RSA8192", 0,
1576 data_dir_.Append("testkey_rsa8192.pem"),
1577 {}, /* include_descriptor_image_paths */
1578 {{"boot", 1, rsa2048_public_key}, /* chain_partitions */
1579 {"system", 2, rsa4096_public_key}},
1580 "--internal_release_string \"unit test\"");
1581 std::string expected_key_blob_4096;
1582 EXPECT_TRUE(base::ReadFileToString(rsa4096_public_key, &expected_key_blob_4096));
1583 std::string expected_key_blob_8192;
1584 EXPECT_TRUE(base::ReadFileToString(rsa8192_public_key, &expected_key_blob_8192));
1585
1586 auto vbmeta_image_path = [this](const std::string& partition_name) {
1587 return test_dir_.Append(partition_name + ".img").value();
1588 };
1589 std::vector<VBMetaData> vbmeta_images;
1590 // Uses the correct expected public key.
1591 EXPECT_EQ(VBMetaVerifyResult::kSuccess,
1592 LoadAndVerifyVbmetaByPartition(
1593 "vbmeta" /* partition_name */, "" /* ab_suffix */, "" /* other_suffix */,
1594 expected_key_blob_8192, true /* allow_verification_error */,
1595 false /* load_chained_vbmeta */, true /* rollback_protection */,
1596 vbmeta_image_path, false /* is_chained_vbmeta*/, &vbmeta_images));
1597
1598 // Uses the wrong expected public key with allow_verification_error set to true.
1599 vbmeta_images.clear();
1600 EXPECT_EQ(VBMetaVerifyResult::kErrorVerification,
1601 LoadAndVerifyVbmetaByPartition(
1602 "vbmeta" /* partition_name */, "" /* ab_suffix */, "" /* other_suffix */,
1603 expected_key_blob_4096, true /* allow_verification_error */,
1604 false /* load_chained_vbmeta */, true /* rollback_protection */,
1605 vbmeta_image_path, false /* is_chained_vbmeta*/, &vbmeta_images));
1606
1607 // Uses the wrong expected public key with allow_verification_error set to false.
1608 vbmeta_images.clear();
1609 EXPECT_EQ(VBMetaVerifyResult::kError,
1610 LoadAndVerifyVbmetaByPartition(
1611 "vbmeta" /* partition_name */, "" /* ab_suffix */, "" /* other_suffix */,
1612 expected_key_blob_4096, false /* allow_verification_error */,
1613 false /* load_chained_vbmeta */, true /* rollback_protection */,
1614 vbmeta_image_path, false /* is_chained_vbmeta*/, &vbmeta_images));
1615 }
1616
1617 } // namespace fs_avb_host_test
1618