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