• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 "fs_avb/fs_avb.h"
18 
19 #include <fcntl.h>
20 #include <libgen.h>
21 #include <string.h>
22 #include <sys/ioctl.h>
23 #include <sys/types.h>
24 
25 #include <sstream>
26 #include <string>
27 #include <vector>
28 
29 #include <android-base/file.h>
30 #include <android-base/parseint.h>
31 #include <android-base/stringprintf.h>
32 #include <android-base/strings.h>
33 #include <libavb/libavb.h>
34 #include <libdm/dm.h>
35 
36 #include "avb_ops.h"
37 #include "avb_util.h"
38 #include "sha.h"
39 #include "util.h"
40 
41 using android::base::Basename;
42 using android::base::ParseUint;
43 using android::base::ReadFileToString;
44 using android::base::Split;
45 using android::base::StringPrintf;
46 
47 namespace android {
48 namespace fs_mgr {
49 
50 template <typename Hasher>
VerifyVbmetaDigest(const std::vector<VBMetaData> & vbmeta_images,const uint8_t * expected_digest)51 std::pair<size_t, bool> VerifyVbmetaDigest(const std::vector<VBMetaData>& vbmeta_images,
52                                            const uint8_t* expected_digest) {
53     size_t total_size = 0;
54     Hasher hasher;
55     for (const auto& vbmeta : vbmeta_images) {
56         hasher.update(vbmeta.data(), vbmeta.size());
57         total_size += vbmeta.size();
58     }
59 
60     bool matched = (memcmp(hasher.finalize(), expected_digest, Hasher::DIGEST_SIZE) == 0);
61 
62     return std::make_pair(total_size, matched);
63 }
64 
65 template <typename Hasher>
CalculateVbmetaDigest(const std::vector<VBMetaData> & vbmeta_images)66 std::pair<std::string, size_t> CalculateVbmetaDigest(const std::vector<VBMetaData>& vbmeta_images) {
67     std::string digest;
68     size_t total_size = 0;
69 
70     Hasher hasher;
71     for (const auto& vbmeta : vbmeta_images) {
72         hasher.update(vbmeta.data(), vbmeta.size());
73         total_size += vbmeta.size();
74     }
75 
76     // Converts digest bytes to a hex string.
77     digest = BytesToHex(hasher.finalize(), Hasher::DIGEST_SIZE);
78     return std::make_pair(digest, total_size);
79 }
80 
81 // class AvbVerifier
82 // -----------------
83 // Reads the following values from kernel cmdline and provides the
84 // VerifyVbmetaImages() to verify AvbSlotVerifyData.
85 //   - androidboot.vbmeta.hash_alg
86 //   - androidboot.vbmeta.size
87 //   - androidboot.vbmeta.digest
88 class AvbVerifier {
89   public:
90     // The factory method to return a unique_ptr<AvbVerifier>
91     static std::unique_ptr<AvbVerifier> Create();
92     bool VerifyVbmetaImages(const std::vector<VBMetaData>& vbmeta_images);
93 
94   protected:
95     AvbVerifier() = default;
96 
97   private:
98     HashAlgorithm hash_alg_;
99     uint8_t digest_[SHA512_DIGEST_LENGTH];
100     size_t vbmeta_size_;
101 };
102 
Create()103 std::unique_ptr<AvbVerifier> AvbVerifier::Create() {
104     std::unique_ptr<AvbVerifier> avb_verifier(new AvbVerifier());
105     if (!avb_verifier) {
106         LERROR << "Failed to create unique_ptr<AvbVerifier>";
107         return nullptr;
108     }
109 
110     std::string value;
111     if (!fs_mgr_get_boot_config("vbmeta.size", &value) ||
112         !ParseUint(value.c_str(), &avb_verifier->vbmeta_size_)) {
113         LERROR << "Invalid hash size: " << value.c_str();
114         return nullptr;
115     }
116 
117     // Reads hash algorithm.
118     size_t expected_digest_size = 0;
119     std::string hash_alg;
120     fs_mgr_get_boot_config("vbmeta.hash_alg", &hash_alg);
121     if (hash_alg == "sha256") {
122         expected_digest_size = SHA256_DIGEST_LENGTH * 2;
123         avb_verifier->hash_alg_ = HashAlgorithm::kSHA256;
124     } else if (hash_alg == "sha512") {
125         expected_digest_size = SHA512_DIGEST_LENGTH * 2;
126         avb_verifier->hash_alg_ = HashAlgorithm::kSHA512;
127     } else {
128         LERROR << "Unknown hash algorithm: " << hash_alg.c_str();
129         return nullptr;
130     }
131 
132     // Reads digest.
133     std::string digest;
134     fs_mgr_get_boot_config("vbmeta.digest", &digest);
135     if (digest.size() != expected_digest_size) {
136         LERROR << "Unexpected digest size: " << digest.size()
137                << " (expected: " << expected_digest_size << ")";
138         return nullptr;
139     }
140 
141     if (!HexToBytes(avb_verifier->digest_, sizeof(avb_verifier->digest_), digest)) {
142         LERROR << "Hash digest contains non-hexidecimal character: " << digest.c_str();
143         return nullptr;
144     }
145 
146     return avb_verifier;
147 }
148 
VerifyVbmetaImages(const std::vector<VBMetaData> & vbmeta_images)149 bool AvbVerifier::VerifyVbmetaImages(const std::vector<VBMetaData>& vbmeta_images) {
150     if (vbmeta_images.empty()) {
151         LERROR << "No vbmeta images";
152         return false;
153     }
154 
155     size_t total_size = 0;
156     bool digest_matched = false;
157 
158     if (hash_alg_ == HashAlgorithm::kSHA256) {
159         std::tie(total_size, digest_matched) =
160                 VerifyVbmetaDigest<SHA256Hasher>(vbmeta_images, digest_);
161     } else if (hash_alg_ == HashAlgorithm::kSHA512) {
162         std::tie(total_size, digest_matched) =
163                 VerifyVbmetaDigest<SHA512Hasher>(vbmeta_images, digest_);
164     }
165 
166     if (total_size != vbmeta_size_) {
167         LERROR << "total vbmeta size mismatch: " << total_size << " (expected: " << vbmeta_size_
168                << ")";
169         return false;
170     }
171 
172     if (!digest_matched) {
173         LERROR << "vbmeta digest mismatch";
174         return false;
175     }
176 
177     return true;
178 }
179 
180 // class AvbHandle
181 // ---------------
LoadAndVerifyVbmeta(const std::string & partition_name,const std::string & ab_suffix,const std::string & ab_other_suffix,const std::string & expected_public_key_path,const HashAlgorithm & hash_algorithm,bool allow_verification_error,bool load_chained_vbmeta,bool rollback_protection,std::function<std::string (const std::string &)> custom_device_path)182 AvbUniquePtr AvbHandle::LoadAndVerifyVbmeta(
183         const std::string& partition_name, const std::string& ab_suffix,
184         const std::string& ab_other_suffix, const std::string& expected_public_key_path,
185         const HashAlgorithm& hash_algorithm, bool allow_verification_error,
186         bool load_chained_vbmeta, bool rollback_protection,
187         std::function<std::string(const std::string&)> custom_device_path) {
188     AvbUniquePtr avb_handle(new AvbHandle());
189     if (!avb_handle) {
190         LERROR << "Failed to allocate AvbHandle";
191         return nullptr;
192     }
193 
194     std::string expected_key_blob;
195     if (!expected_public_key_path.empty()) {
196         if (access(expected_public_key_path.c_str(), F_OK) != 0) {
197             LERROR << "Expected public key path doesn't exist: " << expected_public_key_path;
198             return nullptr;
199         } else if (!ReadFileToString(expected_public_key_path, &expected_key_blob)) {
200             LERROR << "Failed to load: " << expected_public_key_path;
201             return nullptr;
202         }
203     }
204 
205     auto android_by_name_symlink = [](const std::string& partition_name_with_ab) {
206         return "/dev/block/by-name/" + partition_name_with_ab;
207     };
208 
209     auto device_path = custom_device_path ? custom_device_path : android_by_name_symlink;
210 
211     auto verify_result = LoadAndVerifyVbmetaByPartition(
212         partition_name, ab_suffix, ab_other_suffix, expected_key_blob, allow_verification_error,
213         load_chained_vbmeta, rollback_protection, device_path, false,
214         /* is_chained_vbmeta */ &avb_handle->vbmeta_images_);
215     switch (verify_result) {
216         case VBMetaVerifyResult::kSuccess:
217             avb_handle->status_ = AvbHandleStatus::kSuccess;
218             break;
219         case VBMetaVerifyResult::kErrorVerification:
220             avb_handle->status_ = AvbHandleStatus::kVerificationError;
221             break;
222         default:
223             LERROR << "LoadAndVerifyVbmetaByPartition failed, result: " << verify_result;
224             return nullptr;
225     }
226 
227     // Sanity check here because we have to use vbmeta_images_[0] below.
228     if (avb_handle->vbmeta_images_.size() < 1) {
229         LERROR << "LoadAndVerifyVbmetaByPartition failed, no vbmeta loaded";
230         return nullptr;
231     }
232 
233     // Sets the MAJOR.MINOR for init to set it into "ro.boot.avb_version".
234     avb_handle->avb_version_ = StringPrintf("%d.%d", AVB_VERSION_MAJOR, AVB_VERSION_MINOR);
235 
236     // Checks any disabled flag is set.
237     std::unique_ptr<AvbVBMetaImageHeader> vbmeta_header =
238             avb_handle->vbmeta_images_[0].GetVBMetaHeader();
239     bool verification_disabled = ((AvbVBMetaImageFlags)vbmeta_header->flags &
240                                   AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED);
241     bool hashtree_disabled =
242             ((AvbVBMetaImageFlags)vbmeta_header->flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED);
243     if (verification_disabled) {
244         avb_handle->status_ = AvbHandleStatus::kVerificationDisabled;
245     } else if (hashtree_disabled) {
246         avb_handle->status_ = AvbHandleStatus::kHashtreeDisabled;
247     }
248 
249     // Calculates the summary info for all vbmeta_images_;
250     std::string digest;
251     size_t total_size;
252     if (hash_algorithm == HashAlgorithm::kSHA256) {
253         std::tie(digest, total_size) =
254                 CalculateVbmetaDigest<SHA256Hasher>(avb_handle->vbmeta_images_);
255     } else if (hash_algorithm == HashAlgorithm::kSHA512) {
256         std::tie(digest, total_size) =
257                 CalculateVbmetaDigest<SHA512Hasher>(avb_handle->vbmeta_images_);
258     } else {
259         LERROR << "Invalid hash algorithm";
260         return nullptr;
261     }
262     avb_handle->vbmeta_info_ = VBMetaInfo(digest, hash_algorithm, total_size);
263 
264     LINFO << "Returning avb_handle with status: " << avb_handle->status_;
265     return avb_handle;
266 }
267 
LoadAndVerifyVbmeta(const FstabEntry & fstab_entry)268 AvbUniquePtr AvbHandle::LoadAndVerifyVbmeta(const FstabEntry& fstab_entry) {
269     if (fstab_entry.avb_keys.empty()) {
270         LERROR << "avb_keys=/path/to/key(s) is missing for " << fstab_entry.mount_point;
271         return nullptr;
272     }
273 
274     // Binds allow_verification_error and rollback_protection to device unlock state.
275     bool allow_verification_error = IsDeviceUnlocked();
276     bool rollback_protection = !allow_verification_error;
277 
278     std::string public_key_data;
279     bool verification_disabled = false;
280     VBMetaVerifyResult verify_result = VBMetaVerifyResult::kError;
281     std::unique_ptr<VBMetaData> vbmeta = LoadAndVerifyVbmetaByPath(
282             fstab_entry.blk_device, "" /* partition_name, no need for a standalone path */,
283             "" /* expected_public_key_blob, */, allow_verification_error, rollback_protection,
284             false /* not is_chained_vbmeta */, &public_key_data, &verification_disabled,
285             &verify_result);
286 
287     if (!vbmeta) {
288         LERROR << "Failed to load vbmeta: " << fstab_entry.blk_device;
289         return nullptr;
290     }
291 
292     AvbUniquePtr avb_handle(new AvbHandle());
293     if (!avb_handle) {
294         LERROR << "Failed to allocate AvbHandle";
295         return nullptr;
296     }
297     avb_handle->vbmeta_images_.emplace_back(std::move(*vbmeta));
298 
299     switch (verify_result) {
300         case VBMetaVerifyResult::kSuccess:
301             avb_handle->status_ = AvbHandleStatus::kSuccess;
302             break;
303         case VBMetaVerifyResult::kErrorVerification:
304             avb_handle->status_ = AvbHandleStatus::kVerificationError;
305             break;
306         default:
307             LERROR << "LoadAndVerifyVbmetaByPath failed, result: " << verify_result;
308             return nullptr;
309     }
310 
311     if (!ValidatePublicKeyBlob(public_key_data, Split(fstab_entry.avb_keys, ":"))) {
312         avb_handle->status_ = AvbHandleStatus::kVerificationError;
313         LWARNING << "Found unknown public key used to sign " << fstab_entry.mount_point;
314         if (!allow_verification_error) {
315             LERROR << "Unknown public key is not allowed";
316             return nullptr;
317         }
318     }
319 
320     if (verification_disabled) {
321         LINFO << "AVB verification disabled on: " << fstab_entry.mount_point;
322         avb_handle->status_ = AvbHandleStatus::kVerificationDisabled;
323     }
324 
325     LINFO << "Returning avb_handle for '" << fstab_entry.mount_point
326           << "' with status: " << avb_handle->status_;
327     return avb_handle;
328 }
329 
LoadAndVerifyVbmeta()330 AvbUniquePtr AvbHandle::LoadAndVerifyVbmeta() {
331     // Loads inline vbmeta images, starting from /vbmeta.
332     return LoadAndVerifyVbmeta("vbmeta", fs_mgr_get_slot_suffix(), fs_mgr_get_other_slot_suffix(),
333                                {} /* expected_public_key, already checked by bootloader */,
334                                HashAlgorithm::kSHA256,
335                                IsDeviceUnlocked(), /* allow_verification_error */
336                                true,               /* load_chained_vbmeta */
337                                false, /* rollback_protection, already checked by bootloader */
338                                nullptr /* custom_device_path */);
339 }
340 
341 // TODO(b/128807537): removes this function.
Open()342 AvbUniquePtr AvbHandle::Open() {
343     bool is_device_unlocked = IsDeviceUnlocked();
344 
345     AvbUniquePtr avb_handle(new AvbHandle());
346     if (!avb_handle) {
347         LERROR << "Failed to allocate AvbHandle";
348         return nullptr;
349     }
350 
351     FsManagerAvbOps avb_ops;
352     AvbSlotVerifyFlags flags = is_device_unlocked ? AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR
353                                                   : AVB_SLOT_VERIFY_FLAGS_NONE;
354     AvbSlotVerifyResult verify_result =
355             avb_ops.AvbSlotVerify(fs_mgr_get_slot_suffix(), flags, &avb_handle->vbmeta_images_);
356 
357     // Only allow the following verify results:
358     //   - AVB_SLOT_VERIFY_RESULT_OK.
359     //   - AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION (UNLOCKED only).
360     //     Might occur in either the top-level vbmeta or a chained vbmeta.
361     //   - AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED (UNLOCKED only).
362     //     Could only occur in a chained vbmeta. Because we have *dummy* operations in
363     //     FsManagerAvbOps such that avb_ops->validate_vbmeta_public_key() used to validate
364     //     the public key of the top-level vbmeta always pass in userspace here.
365     //
366     // The following verify result won't happen, because the *dummy* operation
367     // avb_ops->read_rollback_index() always returns the minimum value zero. So rollbacked
368     // vbmeta images, which should be caught in the bootloader stage, won't be detected here.
369     //   - AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX
370     switch (verify_result) {
371         case AVB_SLOT_VERIFY_RESULT_OK:
372             avb_handle->status_ = AvbHandleStatus::kSuccess;
373             break;
374         case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
375         case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
376             if (!is_device_unlocked) {
377                 LERROR << "ERROR_VERIFICATION / PUBLIC_KEY_REJECTED isn't allowed "
378                        << "if the device is LOCKED";
379                 return nullptr;
380             }
381             avb_handle->status_ = AvbHandleStatus::kVerificationError;
382             break;
383         default:
384             LERROR << "avb_slot_verify failed, result: " << verify_result;
385             return nullptr;
386     }
387 
388     // Sets the MAJOR.MINOR for init to set it into "ro.boot.avb_version".
389     avb_handle->avb_version_ = StringPrintf("%d.%d", AVB_VERSION_MAJOR, AVB_VERSION_MINOR);
390 
391     // Checks whether FLAGS_VERIFICATION_DISABLED is set:
392     //   - Only the top-level vbmeta struct is read.
393     //   - vbmeta struct in other partitions are NOT processed, including AVB HASH descriptor(s)
394     //     and AVB HASHTREE descriptor(s).
395     AvbVBMetaImageHeader vbmeta_header;
396     avb_vbmeta_image_header_to_host_byte_order(
397             (AvbVBMetaImageHeader*)avb_handle->vbmeta_images_[0].data(), &vbmeta_header);
398     bool verification_disabled = ((AvbVBMetaImageFlags)vbmeta_header.flags &
399                                   AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED);
400 
401     if (verification_disabled) {
402         avb_handle->status_ = AvbHandleStatus::kVerificationDisabled;
403     } else {
404         // Verifies vbmeta structs against the digest passed from bootloader in kernel cmdline.
405         std::unique_ptr<AvbVerifier> avb_verifier = AvbVerifier::Create();
406         if (!avb_verifier) {
407             LERROR << "Failed to create AvbVerifier";
408             return nullptr;
409         }
410         if (!avb_verifier->VerifyVbmetaImages(avb_handle->vbmeta_images_)) {
411             LERROR << "VerifyVbmetaImages failed";
412             return nullptr;
413         }
414 
415         // Checks whether FLAGS_HASHTREE_DISABLED is set.
416         bool hashtree_disabled = ((AvbVBMetaImageFlags)vbmeta_header.flags &
417                                   AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED);
418         if (hashtree_disabled) {
419             avb_handle->status_ = AvbHandleStatus::kHashtreeDisabled;
420         }
421     }
422 
423     LINFO << "Returning avb_handle with status: " << avb_handle->status_;
424     return avb_handle;
425 }
426 
SetUpStandaloneAvbHashtree(FstabEntry * fstab_entry,bool wait_for_verity_dev)427 AvbHashtreeResult AvbHandle::SetUpStandaloneAvbHashtree(FstabEntry* fstab_entry,
428                                                         bool wait_for_verity_dev) {
429     auto avb_handle = LoadAndVerifyVbmeta(*fstab_entry);
430     if (!avb_handle) {
431         return AvbHashtreeResult::kFail;
432     }
433 
434     return avb_handle->SetUpAvbHashtree(fstab_entry, wait_for_verity_dev);
435 }
436 
SetUpAvbHashtree(FstabEntry * fstab_entry,bool wait_for_verity_dev)437 AvbHashtreeResult AvbHandle::SetUpAvbHashtree(FstabEntry* fstab_entry, bool wait_for_verity_dev) {
438     if (!fstab_entry || status_ == AvbHandleStatus::kUninitialized || vbmeta_images_.size() < 1) {
439         return AvbHashtreeResult::kFail;
440     }
441 
442     if (status_ == AvbHandleStatus::kHashtreeDisabled ||
443         status_ == AvbHandleStatus::kVerificationDisabled) {
444         LINFO << "AVB HASHTREE disabled on: " << fstab_entry->mount_point;
445         return AvbHashtreeResult::kDisabled;
446     }
447 
448     if (!LoadAvbHashtreeToEnableVerity(fstab_entry, wait_for_verity_dev, vbmeta_images_,
449                                        fs_mgr_get_slot_suffix(), fs_mgr_get_other_slot_suffix())) {
450         return AvbHashtreeResult::kFail;
451     }
452 
453     return AvbHashtreeResult::kSuccess;
454 }
455 
TearDownAvbHashtree(FstabEntry * fstab_entry,bool wait)456 bool AvbHandle::TearDownAvbHashtree(FstabEntry* fstab_entry, bool wait) {
457     if (!fstab_entry) {
458         return false;
459     }
460 
461     const std::string device_name(GetVerityDeviceName(*fstab_entry));
462 
463     // TODO: remove duplicated code with UnmapDevice()
464     android::dm::DeviceMapper& dm = android::dm::DeviceMapper::Instance();
465     std::string path;
466     if (wait) {
467         dm.GetDmDevicePathByName(device_name, &path);
468     }
469     if (!dm.DeleteDevice(device_name)) {
470         return false;
471     }
472     if (!path.empty() && !WaitForFile(path, 1000ms, FileWaitMode::DoesNotExist)) {
473         return false;
474     }
475 
476     return true;
477 }
478 
GetSecurityPatchLevel(const FstabEntry & fstab_entry) const479 std::string AvbHandle::GetSecurityPatchLevel(const FstabEntry& fstab_entry) const {
480     if (vbmeta_images_.size() < 1) {
481         return "";
482     }
483     std::string avb_partition_name = DeriveAvbPartitionName(fstab_entry, fs_mgr_get_slot_suffix(),
484                                                             fs_mgr_get_other_slot_suffix());
485     auto avb_prop_name = "com.android.build." + avb_partition_name + ".security_patch";
486     return GetAvbPropertyDescriptor(avb_prop_name, vbmeta_images_);
487 }
488 
IsDeviceUnlocked()489 bool AvbHandle::IsDeviceUnlocked() {
490     return android::fs_mgr::IsDeviceUnlocked();
491 }
492 
493 }  // namespace fs_mgr
494 }  // namespace android
495