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