1 /*
2  * Copyright (C) 2021 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 <vector>
18 
19 #include <android-base/file.h>
20 #include <android-base/logging.h>
21 #include <android-base/properties.h>
22 #include <android-base/unique_fd.h>
23 #include <android/api-level.h>
24 #include <bootimg.h>
25 #include <fs_avb/fs_avb_util.h>
26 #include <gtest/gtest.h>
27 #include <libavb/libavb.h>
28 #include <storage_literals/storage_literals.h>
29 #include <vintf/VintfObject.h>
30 #include <vintf/parse_string.h>
31 
32 #include "gsi_validation_utils.h"
33 
34 using namespace std::literals;
35 using namespace android::storage_literals;
36 
37 namespace {
38 
GetBlockDevicePath(const std::string & name)39 std::string GetBlockDevicePath(const std::string &name) {
40   return "/dev/block/by-name/" + name + fs_mgr_get_slot_suffix();
41 }
42 
43 class GkiBootImage {
44  public:
GkiBootImage(const uint8_t * data,size_t size)45   GkiBootImage(const uint8_t *data, size_t size) : data_(data, data + size) {}
46 
GetBootHeaderVersion(const void * data)47   static uint32_t GetBootHeaderVersion(const void *data) {
48     return static_cast<const boot_img_hdr_v0 *>(data)->header_version;
49   }
50 
header_version() const51   uint32_t header_version() const { return GetBootHeaderVersion(data()); }
52 
kernel_pages() const53   uint32_t kernel_pages() const { return GetNumberOfPages(kernel_size()); }
54 
ramdisk_pages() const55   uint32_t ramdisk_pages() const { return GetNumberOfPages(ramdisk_size()); }
56 
kernel_offset() const57   uint32_t kernel_offset() const {
58     // The first page must be the boot image header.
59     return page_size();
60   }
61 
ramdisk_offset() const62   uint32_t ramdisk_offset() const {
63     return kernel_offset() + kernel_pages() * page_size();
64   }
65 
66   virtual uint32_t page_size() const = 0;
67   virtual uint32_t os_version() const = 0;
68   virtual uint32_t kernel_size() const = 0;
69   virtual uint32_t ramdisk_size() const = 0;
70   virtual uint32_t signature_size() const = 0;
71   virtual uint32_t signature_offset() const = 0;
72 
GetNumberOfPages(uint32_t value) const73   uint32_t GetNumberOfPages(uint32_t value) const {
74     return (value + page_size() - 1) / page_size();
75   }
76 
GetKernel() const77   std::vector<uint8_t> GetKernel() const {
78     return Slice(kernel_offset(), kernel_size());
79   }
80 
81   // Get "effective" boot image. The pure boot image without any boot signature.
GetBootImage() const82   std::vector<uint8_t> GetBootImage() const {
83     return Slice(0, signature_offset());
84   }
85 
86   // Parse a vector of vbmeta image from the boot signature section.
GetBootSignatures() const87   std::vector<android::fs_mgr::VBMetaData> GetBootSignatures() const {
88     const auto begin_offset = std::clamp<size_t>(signature_offset(), 0, size());
89     const uint8_t *buffer = data() + begin_offset;
90     // begin_offset + remaining_bytes <= size() because boot_signature must be
91     // the last section.
92     size_t remaining_bytes =
93         std::clamp<size_t>(signature_size(), 0, size() - begin_offset);
94     // In case boot_signature is misaligned, shift to the first AVB magic, and
95     // treat it as the actual beginning of boot signature.
96     while (remaining_bytes >= AVB_MAGIC_LEN) {
97       if (!memcmp(buffer, AVB_MAGIC, AVB_MAGIC_LEN)) {
98         break;
99       }
100       ++buffer;
101       --remaining_bytes;
102     }
103     std::vector<android::fs_mgr::VBMetaData> vbmeta_images;
104     while (remaining_bytes >= sizeof(AvbVBMetaImageHeader)) {
105       if (memcmp(buffer, AVB_MAGIC, AVB_MAGIC_LEN) != 0) {
106         break;
107       }
108       // Extract only the header to calculate the vbmeta image size.
109       android::fs_mgr::VBMetaData vbmeta_header(
110           buffer, sizeof(AvbVBMetaImageHeader), "boot_signature");
111       if (!vbmeta_header.GetVBMetaHeader(/* update_vbmeta_size */ true)) {
112         GTEST_LOG_(ERROR) << __FUNCTION__
113                           << "(): VBMetaData::GetVBMetaHeader() failed.";
114         return {};
115       }
116       const auto vbmeta_image_size = vbmeta_header.size();
117       GTEST_LOG_(INFO) << __FUNCTION__ << "(): Found vbmeta image with size "
118                        << vbmeta_image_size;
119       if (vbmeta_image_size < sizeof(AvbVBMetaImageHeader)) {
120         GTEST_LOG_(ERROR) << __FUNCTION__
121                           << "(): Impossible-sized vbmeta image: "
122                           << vbmeta_image_size;
123         return {};
124       }
125 
126       if (vbmeta_image_size > remaining_bytes) {
127         GTEST_LOG_(ERROR)
128             << __FUNCTION__
129             << "(): Premature EOF when parsing GKI boot signature.";
130         return {};
131       }
132 
133       vbmeta_images.emplace_back(buffer, vbmeta_image_size, "boot_signature");
134       buffer += vbmeta_image_size;
135       remaining_bytes -= vbmeta_image_size;
136     }
137     return vbmeta_images;
138   }
139 
140   virtual ~GkiBootImage() = default;
141 
142  protected:
data() const143   const uint8_t *data() const { return data_.data(); }
144 
size() const145   size_t size() const { return data_.size(); }
146 
Slice(size_t offset,size_t length) const147   std::vector<uint8_t> Slice(size_t offset, size_t length) const {
148     const auto begin_offset = std::clamp<size_t>(offset, 0, size());
149     const auto end_offset =
150         std::clamp<size_t>(begin_offset + length, begin_offset, size());
151     const auto begin = data() + begin_offset;
152     const auto end = data() + end_offset;
153     return {begin, end};
154   }
155 
156  private:
157   std::vector<uint8_t> data_;
158 };
159 
160 class GkiBootImageV2 : public GkiBootImage {
161  public:
GkiBootImageV2(const uint8_t * data,size_t size)162   GkiBootImageV2(const uint8_t *data, size_t size) : GkiBootImage(data, size) {}
163 
boot_header() const164   const boot_img_hdr_v2 *boot_header() const {
165     return reinterpret_cast<const boot_img_hdr_v2 *>(data());
166   }
167 
page_size() const168   uint32_t page_size() const override { return boot_header()->page_size; }
169 
os_version() const170   uint32_t os_version() const override { return boot_header()->os_version; }
171 
kernel_size() const172   uint32_t kernel_size() const override { return boot_header()->kernel_size; }
173 
ramdisk_size() const174   uint32_t ramdisk_size() const override { return boot_header()->ramdisk_size; }
175 
signature_size() const176   uint32_t signature_size() const override {
177     // The last 16K bytes are by definition the GKI boot signature.
178     static constexpr uint32_t kBootSignatureSize = 16_KiB;
179     return kBootSignatureSize;
180   }
181 
signature_offset() const182   uint32_t signature_offset() const override {
183     if (size() < signature_size()) {
184       return 0;
185     }
186     return size() - signature_size();
187   }
188 
recovery_dtbo_size() const189   uint32_t recovery_dtbo_size() const {
190     return boot_header()->recovery_dtbo_size;
191   }
192 
recovery_dtbo_offset() const193   uint64_t recovery_dtbo_offset() const {
194     return boot_header()->recovery_dtbo_offset;
195   }
196 };
197 
198 class GkiBootImageV4 : public GkiBootImage {
199  public:
GkiBootImageV4(const uint8_t * data,size_t size)200   GkiBootImageV4(const uint8_t *data, size_t size) : GkiBootImage(data, size) {}
201 
boot_header() const202   const boot_img_hdr_v4 *boot_header() const {
203     return reinterpret_cast<const boot_img_hdr_v4 *>(data());
204   }
205 
page_size() const206   uint32_t page_size() const override {
207     static constexpr uint32_t kPageSize = 4096;
208     return kPageSize;
209   }
210 
os_version() const211   uint32_t os_version() const override { return boot_header()->os_version; }
212 
kernel_size() const213   uint32_t kernel_size() const override { return boot_header()->kernel_size; }
214 
ramdisk_size() const215   uint32_t ramdisk_size() const override { return boot_header()->ramdisk_size; }
216 
signature_size() const217   uint32_t signature_size() const override {
218     // For Android12 GKI, the |.signature_size| field is respected.
219     // For Android13+ GKI, the |.signature_size| field must be zero, and the
220     // last 16K bytes are by definition the GKI boot signature.
221     static constexpr uint32_t kBootSignatureSize = 16_KiB;
222     const uint32_t value = boot_header()->signature_size;
223     return value ? value : kBootSignatureSize;
224   }
225 
signature_offset() const226   uint32_t signature_offset() const override {
227     return ramdisk_offset() + ramdisk_pages() * page_size();
228   }
229 };
230 
GetAvbProperty(const std::string & name,const std::vector<android::fs_mgr::VBMetaData> & vbmeta_images)231 std::string GetAvbProperty(
232     const std::string &name,
233     const std::vector<android::fs_mgr::VBMetaData> &vbmeta_images) {
234   const std::string prop_name = "com.android.build." + name;
235   return android::fs_mgr::GetAvbPropertyDescriptor(prop_name, vbmeta_images);
236 }
237 
LoadAndVerifyGkiBootImage(std::vector<android::fs_mgr::VBMetaData> * boot_signature_images)238 std::unique_ptr<GkiBootImage> LoadAndVerifyGkiBootImage(
239     std::vector<android::fs_mgr::VBMetaData> *boot_signature_images) {
240   const std::string block_device_path = GetBlockDevicePath("boot");
241   const std::string TAG = __FUNCTION__ + "("s + block_device_path + ")";
242   SCOPED_TRACE(TAG);
243 
244   std::string block_device_data;
245   if (!android::base::ReadFileToString(block_device_path, &block_device_data,
246                                        /* follow_symlinks */ true)) {
247     ADD_FAILURE() << "Failed to read '" << block_device_path
248                   << "': " << strerror(errno);
249     return nullptr;
250   }
251   if (block_device_data.size() <= 4096) {
252     ADD_FAILURE() << "Size of '" << block_device_path
253                   << "' is impossibly small: " << block_device_data.size();
254     return nullptr;
255   }
256 
257   if (block_device_data.substr(0, BOOT_MAGIC_SIZE) != BOOT_MAGIC) {
258     ADD_FAILURE() << "Device has invalid boot magic: " << block_device_path;
259     return nullptr;
260   }
261 
262   // Remove the AVB footer and chained vbmeta image if there is any.
263   if (block_device_data.size() > AVB_FOOTER_SIZE) {
264     const uint8_t *footer_address =
265         reinterpret_cast<const uint8_t *>(block_device_data.data()) +
266         block_device_data.size() - AVB_FOOTER_SIZE;
267     AvbFooter vbmeta_footer;
268     if (avb_footer_validate_and_byteswap(
269             reinterpret_cast<const AvbFooter *>(footer_address),
270             &vbmeta_footer)) {
271       block_device_data.resize(vbmeta_footer.original_image_size);
272     }
273   }
274 
275   std::unique_ptr<GkiBootImage> boot_image;
276   const auto boot_header_version =
277       GkiBootImage::GetBootHeaderVersion(block_device_data.data());
278   if (boot_header_version == 4) {
279     boot_image = std::make_unique<GkiBootImageV4>(
280         reinterpret_cast<const uint8_t *>(block_device_data.data()),
281         block_device_data.size());
282   } else if (boot_header_version == 2) {
283     boot_image = std::make_unique<GkiBootImageV2>(
284         reinterpret_cast<const uint8_t *>(block_device_data.data()),
285         block_device_data.size());
286   } else {
287     ADD_FAILURE() << "Unexpected boot header version: " << boot_header_version;
288     return nullptr;
289   }
290 
291   *boot_signature_images = boot_image->GetBootSignatures();
292   if (boot_signature_images->empty()) {
293     ADD_FAILURE() << "Failed to load the boot signature.";
294     return nullptr;
295   }
296 
297   // Verify that the vbmeta images in boot_signature are certified.
298   for (const auto &vbmeta_image : *boot_signature_images) {
299     size_t pk_len;
300     const uint8_t *pk_data;
301     const auto vbmeta_verify_result = avb_vbmeta_image_verify(
302         vbmeta_image.data(), vbmeta_image.size(), &pk_data, &pk_len);
303     if (vbmeta_verify_result != AVB_VBMETA_VERIFY_RESULT_OK) {
304       ADD_FAILURE() << "Failed to verify boot_signature: "
305                     << avb_vbmeta_verify_result_to_string(vbmeta_verify_result);
306       return nullptr;
307     }
308     const std::string out_public_key_data(
309         reinterpret_cast<const char *>(pk_data), pk_len);
310     if (out_public_key_data.empty()) {
311       ADD_FAILURE() << "The GKI image descriptor is not signed.";
312       continue;
313     }
314     if (!ValidatePublicKeyBlob(out_public_key_data)) {
315       ADD_FAILURE()
316           << "The GKI image descriptor is not signed by an official key.";
317       continue;
318     }
319   }
320 
321   GTEST_LOG_(INFO) << TAG << ": boot.fingerprint: "
322                    << GetAvbProperty("boot.fingerprint",
323                                      *boot_signature_images);
324   GTEST_LOG_(INFO) << TAG
325                    << ": header version: " << boot_image->header_version()
326                    << ", kernel size: " << boot_image->kernel_size()
327                    << ", ramdisk size: " << boot_image->ramdisk_size()
328                    << ", signature size: " << boot_image->signature_size();
329 
330   return boot_image;
331 }
332 
333 // Verify image data integrity with an AVB hash descriptor.
VerifyImageDescriptor(const std::vector<uint8_t> & image,const android::fs_mgr::FsAvbHashDescriptor & descriptor)334 void VerifyImageDescriptor(
335     const std::vector<uint8_t> &image,
336     const android::fs_mgr::FsAvbHashDescriptor &descriptor) {
337   const std::string TAG = __FUNCTION__ + "("s + descriptor.partition_name + ")";
338   SCOPED_TRACE(TAG);
339 
340   ASSERT_EQ(image.size(), descriptor.image_size);
341 
342   const std::string &salt_str = descriptor.salt;
343   const std::string &expected_digest_str = descriptor.digest;
344 
345   const std::string hash_algorithm(
346       reinterpret_cast<const char *>(descriptor.hash_algorithm));
347   GTEST_LOG_(INFO) << TAG << ": hash_algorithm = " << hash_algorithm;
348 
349   std::unique_ptr<ShaHasher> hasher = CreateShaHasher(hash_algorithm);
350   ASSERT_NE(nullptr, hasher);
351 
352   std::vector<uint8_t> salt, expected_digest, out_digest;
353 
354   ASSERT_TRUE(HexToBytes(salt_str, &salt))
355       << "Invalid salt in descriptor: " << salt_str;
356   ASSERT_TRUE(HexToBytes(expected_digest_str, &expected_digest))
357       << "Invalid digest in descriptor: " << expected_digest_str;
358 
359   ASSERT_EQ(expected_digest.size(), hasher->GetDigestSize());
360   out_digest.resize(hasher->GetDigestSize());
361 
362   ASSERT_TRUE(hasher->CalculateDigest(image.data(), image.size(), salt.data(),
363                                       descriptor.salt_len, out_digest.data()))
364       << "Unable to calculate image digest.";
365 
366   ASSERT_EQ(out_digest.size(), expected_digest.size())
367       << "Calculated digest size does not match expected digest size.";
368 
369   ASSERT_EQ(out_digest, expected_digest)
370       << "Calculated digest does not match expected digest.";
371 }
372 }  // namespace
373 
374 class GkiComplianceTest : public testing::Test {
375  protected:
SetUp()376   void SetUp() override {
377     // Fetch device runtime information.
378     runtime_info = android::vintf::VintfObject::GetRuntimeInfo();
379     ASSERT_NE(nullptr, runtime_info);
380 
381     product_first_api_level = GetProductFirstApiLevel();
382 
383     /* Skip for non-arm64 kernels that do not mandate GKI yet. */
384     if (runtime_info->hardwareId() != "aarch64" &&
385         runtime_info->hardwareId() != "armv8l") {
386       GTEST_SKIP() << "Exempt from GKI test on non-arm64 kernel devices";
387     }
388 
389     GTEST_LOG_(INFO) << runtime_info->osName() << " "
390                      << runtime_info->osRelease();
391     GTEST_LOG_(INFO) << "Product first API level: " << product_first_api_level;
392   }
393 
394   bool ShouldSkipGkiComplianceV2();
395 
396   std::shared_ptr<const android::vintf::RuntimeInfo> runtime_info;
397   int product_first_api_level;
398 };
399 
ShouldSkipGkiComplianceV2()400 bool GkiComplianceTest::ShouldSkipGkiComplianceV2() {
401   /* Skip for devices if the kernel version is not >= 5.10. */
402   if (runtime_info->kernelVersion().dropMinor() <
403       android::vintf::Version{5, 10}) {
404     GTEST_LOG_(INFO) << "Exempt from GKI 2.0 test on kernel version: "
405                      << runtime_info->kernelVersion();
406     return true;
407   }
408   /* Skip for devices launched before Android S. */
409   if (product_first_api_level < __ANDROID_API_S__) {
410     GTEST_LOG_(INFO) << "Exempt from GKI 2.0 test on pre-S launched devices";
411     return true;
412   }
413   /*
414    * Skip for automotive devices if the kernel version is not >= 5.15 or
415    * the device is launched before Android T.
416    */
417   if (IsAutomotiveDevice()) {
418     if (runtime_info->kernelVersion().dropMinor() <
419         android::vintf::Version{5, 15}) {
420       GTEST_LOG_(INFO) << "Exempt from GKI test on kernel version: "
421                        << runtime_info->kernelVersion();
422       return true;
423     }
424     if (product_first_api_level < __ANDROID_API_T__) {
425       GTEST_LOG_(INFO) << "Exempt from GKI test on pre-T launched devices";
426       return true;
427     }
428   }
429   /*
430    * Skip for TV devices if the kernel version is not >= 5.15 or
431    * the device is launched before Android U.
432    */
433   if (IsTvDevice()) {
434     if (runtime_info->kernelVersion().dropMinor() <
435         android::vintf::Version{5, 15}) {
436       GTEST_LOG_(INFO) << "Exempt from GKI test on kernel version: "
437                        << runtime_info->kernelVersion();
438       return true;
439     }
440     if (product_first_api_level < __ANDROID_API_U__) {
441       GTEST_LOG_(INFO) << "Exempt from GKI test on pre-U launched TV devices";
442       return true;
443     }
444   }
445   return false;
446 }
447 
TEST_F(GkiComplianceTest,GkiComplianceV1)448 TEST_F(GkiComplianceTest, GkiComplianceV1) {
449   if (product_first_api_level < __ANDROID_API_R__) {
450     GTEST_SKIP() << "Exempt from GKI 1.0 test: product first API level ("
451                  << product_first_api_level << ") < " << __ANDROID_API_R__;
452   }
453   if (IsAutomotiveDevice()) {
454     GTEST_SKIP() << "Skip GKI vbmeta check for automotive devices";
455   }
456   if (IsTvDevice()) {
457     GTEST_SKIP() << "Exempt from GKI 1.0 test on TV devices";
458   }
459   /* Skip for devices if the kernel version is not 5.4. */
460   if (runtime_info->kernelVersion().dropMinor() !=
461       android::vintf::Version{5, 4}) {
462     GTEST_SKIP() << "Exempt from GKI 1.0 test on kernel version: "
463                  << runtime_info->kernelVersion();
464   }
465 
466   /* load vbmeta struct from boot, verify struct integrity */
467   std::string out_public_key_data;
468   android::fs_mgr::VBMetaVerifyResult out_verify_result;
469   const std::string boot_path = GetBlockDevicePath("boot");
470   std::unique_ptr<android::fs_mgr::VBMetaData> vbmeta =
471       android::fs_mgr::LoadAndVerifyVbmetaByPath(
472           boot_path, "boot", "" /* expected_key_blob */,
473           true /* allow verification error */, false /* rollback_protection */,
474           false /* is_chained_vbmeta */, &out_public_key_data,
475           nullptr /* out_verification_disabled */, &out_verify_result);
476 
477   ASSERT_TRUE(vbmeta) << "Verification of GKI vbmeta fails.";
478   ASSERT_FALSE(out_public_key_data.empty()) << "The GKI image is not signed.";
479   EXPECT_TRUE(ValidatePublicKeyBlob(out_public_key_data))
480       << "The GKI image is not signed by an official key.";
481   EXPECT_EQ(out_verify_result, android::fs_mgr::VBMetaVerifyResult::kSuccess)
482       << "Verification of the GKI vbmeta structure failed.";
483 
484   /* verify boot partition according to vbmeta structure */
485   std::unique_ptr<android::fs_mgr::FsAvbHashDescriptor> descriptor =
486       android::fs_mgr::GetHashDescriptor("boot", std::move(*vbmeta));
487   ASSERT_TRUE(descriptor)
488       << "Failed to load hash descriptor from boot.img vbmeta";
489 
490   android::base::unique_fd fd(open(boot_path.c_str(), O_RDONLY));
491   ASSERT_TRUE(fd.ok()) << "Fail to open boot partition. Try 'adb root'.";
492 
493   std::vector<uint8_t> boot_partition_vector;
494   boot_partition_vector.resize(descriptor->image_size);
495   ASSERT_TRUE(android::base::ReadFully(fd, boot_partition_vector.data(),
496                                        descriptor->image_size))
497       << "Could not read boot partition to vector.";
498 
499   ASSERT_NO_FATAL_FAILURE(
500       VerifyImageDescriptor(boot_partition_vector, *descriptor));
501 }
502 
503 // Verify the entire boot image.
TEST_F(GkiComplianceTest,GkiComplianceV2)504 TEST_F(GkiComplianceTest, GkiComplianceV2) {
505   if (ShouldSkipGkiComplianceV2()) {
506     GTEST_SKIP() << "Skipping GkiComplianceV2 test";
507   }
508 
509   // GKI 2.0 ensures getKernelLevel() to return valid value.
510   std::string error_msg;
511   const auto kernel_level =
512       android::vintf::VintfObject::GetInstance()->getKernelLevel(&error_msg);
513   ASSERT_NE(android::vintf::Level::UNSPECIFIED, kernel_level) << error_msg;
514 
515   std::vector<android::fs_mgr::VBMetaData> boot_signature_images;
516   std::unique_ptr<GkiBootImage> boot_image =
517       LoadAndVerifyGkiBootImage(&boot_signature_images);
518   ASSERT_NE(nullptr, boot_image);
519   ASSERT_LE(1, boot_signature_images.size());
520   EXPECT_EQ(4, boot_image->header_version());
521 
522   if (kernel_level >= android::vintf::Level::T) {
523     GTEST_LOG_(INFO)
524         << "Android T+ verification scheme. The GKI boot.img must contain only "
525            "the generic kernel but not the generic ramdisk.";
526     EXPECT_EQ(0, boot_image->ramdisk_size())
527         << "'boot' partition mustn't include a ramdisk image.";
528     EXPECT_EQ(0, boot_image->os_version())
529         << "OS version and security patch level should be defined in the "
530            "chained vbmeta image instead.";
531   }
532 
533   std::unique_ptr<android::fs_mgr::FsAvbHashDescriptor> boot_descriptor =
534       android::fs_mgr::GetHashDescriptor("boot", boot_signature_images);
535   ASSERT_NE(nullptr, boot_descriptor)
536       << "Failed to load the 'boot' hash descriptor.";
537   ASSERT_NO_FATAL_FAILURE(
538       VerifyImageDescriptor(boot_image->GetBootImage(), *boot_descriptor));
539 }
540 
541 // Verify only the 'generic_kernel' descriptor.
TEST_F(GkiComplianceTest,GkiComplianceV2_kernel)542 TEST_F(GkiComplianceTest, GkiComplianceV2_kernel) {
543   if (ShouldSkipGkiComplianceV2()) {
544     GTEST_SKIP() << "Skipping GkiComplianceV2 test";
545   }
546 
547   // GKI 2.0 ensures getKernelLevel() to return valid value.
548   std::string error_msg;
549   const auto kernel_level =
550       android::vintf::VintfObject::GetInstance()->getKernelLevel(&error_msg);
551   ASSERT_NE(android::vintf::Level::UNSPECIFIED, kernel_level) << error_msg;
552   if (kernel_level < android::vintf::Level::T) {
553     GTEST_SKIP() << "Skip for kernel level (" << kernel_level << ") < T ("
554                  << android::vintf::Level::T << ")";
555   }
556 
557   std::vector<android::fs_mgr::VBMetaData> boot_signature_images;
558   std::unique_ptr<GkiBootImage> boot_image =
559       LoadAndVerifyGkiBootImage(&boot_signature_images);
560   ASSERT_NE(nullptr, boot_image);
561   ASSERT_LE(1, boot_signature_images.size());
562 
563   std::unique_ptr<android::fs_mgr::FsAvbHashDescriptor>
564       generic_kernel_descriptor = android::fs_mgr::GetHashDescriptor(
565           "generic_kernel", boot_signature_images);
566   ASSERT_NE(nullptr, generic_kernel_descriptor)
567       << "Failed to load the 'generic_kernel' hash descriptor.";
568   ASSERT_NO_FATAL_FAILURE(VerifyImageDescriptor(boot_image->GetKernel(),
569                                                 *generic_kernel_descriptor));
570 }
571 
main(int argc,char * argv[])572 int main(int argc, char *argv[]) {
573   ::testing::InitGoogleTest(&argc, argv);
574   android::base::InitLogging(argv, android::base::StderrLogger);
575   return RUN_ALL_TESTS();
576 }
577