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