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_mgr_avb.h"
18
19 #include <errno.h>
20 #include <fcntl.h>
21 #include <inttypes.h>
22 #include <libgen.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28 #include <vector>
29
30 #include <android-base/file.h>
31 #include <android-base/parseint.h>
32 #include <android-base/properties.h>
33 #include <android-base/stringprintf.h>
34 #include <android-base/strings.h>
35 #include <android-base/unique_fd.h>
36 #include <cutils/properties.h>
37 #include <libavb/libavb.h>
38 #include <openssl/sha.h>
39 #include <sys/ioctl.h>
40 #include <utils/Compat.h>
41
42 #include "fs_mgr.h"
43 #include "fs_mgr_priv.h"
44 #include "fs_mgr_priv_avb_ops.h"
45 #include "fs_mgr_priv_dm_ioctl.h"
46 #include "fs_mgr_priv_sha.h"
47
48 /* The format of dm-verity construction parameters:
49 * <version> <dev> <hash_dev> <data_block_size> <hash_block_size>
50 * <num_data_blocks> <hash_start_block> <algorithm> <digest> <salt>
51 */
52 #define VERITY_TABLE_FORMAT \
53 "%u %s %s %u %u " \
54 "%" PRIu64 " %" PRIu64 " %s %s %s "
55
56 #define VERITY_TABLE_PARAMS(hashtree_desc, blk_device, digest, salt) \
57 hashtree_desc.dm_verity_version, blk_device, blk_device, hashtree_desc.data_block_size, \
58 hashtree_desc.hash_block_size, \
59 hashtree_desc.image_size / hashtree_desc.data_block_size, /* num_data_blocks. */ \
60 hashtree_desc.tree_offset / hashtree_desc.hash_block_size, /* hash_start_block. */ \
61 (char*)hashtree_desc.hash_algorithm, digest, salt
62
63 #define VERITY_TABLE_OPT_RESTART "restart_on_corruption"
64 #define VERITY_TABLE_OPT_IGNZERO "ignore_zero_blocks"
65
66 /* The default format of dm-verity optional parameters:
67 * <#opt_params> ignore_zero_blocks restart_on_corruption
68 */
69 #define VERITY_TABLE_OPT_DEFAULT_FORMAT "2 %s %s"
70 #define VERITY_TABLE_OPT_DEFAULT_PARAMS VERITY_TABLE_OPT_IGNZERO, VERITY_TABLE_OPT_RESTART
71
72 /* The FEC (forward error correction) format of dm-verity optional parameters:
73 * <#opt_params> use_fec_from_device <fec_dev>
74 * fec_roots <num> fec_blocks <num> fec_start <offset>
75 * ignore_zero_blocks restart_on_corruption
76 */
77 #define VERITY_TABLE_OPT_FEC_FORMAT \
78 "10 use_fec_from_device %s fec_roots %u fec_blocks %" PRIu64 " fec_start %" PRIu64 " %s %s"
79
80 /* Note that fec_blocks is the size that FEC covers, *not* the
81 * size of the FEC data. Since we use FEC for everything up until
82 * the FEC data, it's the same as the offset (fec_start).
83 */
84 #define VERITY_TABLE_OPT_FEC_PARAMS(hashtree_desc, blk_device) \
85 blk_device, hashtree_desc.fec_num_roots, \
86 hashtree_desc.fec_offset / hashtree_desc.data_block_size, /* fec_blocks */ \
87 hashtree_desc.fec_offset / hashtree_desc.data_block_size, /* fec_start */ \
88 VERITY_TABLE_OPT_IGNZERO, VERITY_TABLE_OPT_RESTART
89
nibble_value(const char & c,uint8_t * value)90 static inline bool nibble_value(const char& c, uint8_t* value) {
91 FS_MGR_CHECK(value != nullptr);
92
93 switch (c) {
94 case '0' ... '9':
95 *value = c - '0';
96 break;
97 case 'a' ... 'f':
98 *value = c - 'a' + 10;
99 break;
100 case 'A' ... 'F':
101 *value = c - 'A' + 10;
102 break;
103 default:
104 return false;
105 }
106
107 return true;
108 }
109
hex_to_bytes(uint8_t * bytes,size_t bytes_len,const std::string & hex)110 static bool hex_to_bytes(uint8_t* bytes, size_t bytes_len, const std::string& hex) {
111 FS_MGR_CHECK(bytes != nullptr);
112
113 if (hex.size() % 2 != 0) {
114 return false;
115 }
116 if (hex.size() / 2 > bytes_len) {
117 return false;
118 }
119 for (size_t i = 0, j = 0, n = hex.size(); i < n; i += 2, ++j) {
120 uint8_t high;
121 if (!nibble_value(hex[i], &high)) {
122 return false;
123 }
124 uint8_t low;
125 if (!nibble_value(hex[i + 1], &low)) {
126 return false;
127 }
128 bytes[j] = (high << 4) | low;
129 }
130 return true;
131 }
132
bytes_to_hex(const uint8_t * bytes,size_t bytes_len)133 static std::string bytes_to_hex(const uint8_t* bytes, size_t bytes_len) {
134 FS_MGR_CHECK(bytes != nullptr);
135
136 static const char* hex_digits = "0123456789abcdef";
137 std::string hex;
138
139 for (size_t i = 0; i < bytes_len; i++) {
140 hex.push_back(hex_digits[(bytes[i] & 0xF0) >> 4]);
141 hex.push_back(hex_digits[bytes[i] & 0x0F]);
142 }
143 return hex;
144 }
145
146 template <typename Hasher>
verify_vbmeta_digest(const AvbSlotVerifyData & verify_data,const uint8_t * expected_digest)147 static std::pair<size_t, bool> verify_vbmeta_digest(const AvbSlotVerifyData& verify_data,
148 const uint8_t* expected_digest) {
149 size_t total_size = 0;
150 Hasher hasher;
151 for (size_t n = 0; n < verify_data.num_vbmeta_images; n++) {
152 hasher.update(verify_data.vbmeta_images[n].vbmeta_data,
153 verify_data.vbmeta_images[n].vbmeta_size);
154 total_size += verify_data.vbmeta_images[n].vbmeta_size;
155 }
156
157 bool matched = (memcmp(hasher.finalize(), expected_digest, Hasher::DIGEST_SIZE) == 0);
158
159 return std::make_pair(total_size, matched);
160 }
161
162 // Reads the following values from kernel cmdline and provides the
163 // VerifyVbmetaImages() to verify AvbSlotVerifyData.
164 // - androidboot.vbmeta.device_state
165 // - androidboot.vbmeta.hash_alg
166 // - androidboot.vbmeta.size
167 // - androidboot.vbmeta.digest
168 class FsManagerAvbVerifier {
169 public:
170 // The factory method to return a unique_ptr<FsManagerAvbVerifier>
171 static std::unique_ptr<FsManagerAvbVerifier> Create();
172 bool VerifyVbmetaImages(const AvbSlotVerifyData& verify_data);
IsDeviceUnlocked()173 bool IsDeviceUnlocked() { return is_device_unlocked_; }
174
175 protected:
176 FsManagerAvbVerifier() = default;
177
178 private:
179 enum HashAlgorithm {
180 kInvalid = 0,
181 kSHA256 = 1,
182 kSHA512 = 2,
183 };
184
185 HashAlgorithm hash_alg_;
186 uint8_t digest_[SHA512_DIGEST_LENGTH];
187 size_t vbmeta_size_;
188 bool is_device_unlocked_;
189 };
190
Create()191 std::unique_ptr<FsManagerAvbVerifier> FsManagerAvbVerifier::Create() {
192 std::string cmdline;
193 if (!android::base::ReadFileToString("/proc/cmdline", &cmdline)) {
194 LERROR << "Failed to read /proc/cmdline";
195 return nullptr;
196 }
197
198 std::unique_ptr<FsManagerAvbVerifier> avb_verifier(new FsManagerAvbVerifier());
199 if (!avb_verifier) {
200 LERROR << "Failed to create unique_ptr<FsManagerAvbVerifier>";
201 return nullptr;
202 }
203
204 std::string digest;
205 std::string hash_alg;
206 for (const auto& entry : android::base::Split(android::base::Trim(cmdline), " ")) {
207 std::vector<std::string> pieces = android::base::Split(entry, "=");
208 const std::string& key = pieces[0];
209 const std::string& value = pieces[1];
210
211 if (key == "androidboot.vbmeta.device_state") {
212 avb_verifier->is_device_unlocked_ = (value == "unlocked");
213 } else if (key == "androidboot.vbmeta.hash_alg") {
214 hash_alg = value;
215 } else if (key == "androidboot.vbmeta.size") {
216 if (!android::base::ParseUint(value.c_str(), &avb_verifier->vbmeta_size_)) {
217 return nullptr;
218 }
219 } else if (key == "androidboot.vbmeta.digest") {
220 digest = value;
221 }
222 }
223
224 // Reads hash algorithm.
225 size_t expected_digest_size = 0;
226 if (hash_alg == "sha256") {
227 expected_digest_size = SHA256_DIGEST_LENGTH * 2;
228 avb_verifier->hash_alg_ = kSHA256;
229 } else if (hash_alg == "sha512") {
230 expected_digest_size = SHA512_DIGEST_LENGTH * 2;
231 avb_verifier->hash_alg_ = kSHA512;
232 } else {
233 LERROR << "Unknown hash algorithm: " << hash_alg.c_str();
234 return nullptr;
235 }
236
237 // Reads digest.
238 if (digest.size() != expected_digest_size) {
239 LERROR << "Unexpected digest size: " << digest.size()
240 << " (expected: " << expected_digest_size << ")";
241 return nullptr;
242 }
243
244 if (!hex_to_bytes(avb_verifier->digest_, sizeof(avb_verifier->digest_), digest)) {
245 LERROR << "Hash digest contains non-hexidecimal character: " << digest.c_str();
246 return nullptr;
247 }
248
249 return avb_verifier;
250 }
251
VerifyVbmetaImages(const AvbSlotVerifyData & verify_data)252 bool FsManagerAvbVerifier::VerifyVbmetaImages(const AvbSlotVerifyData& verify_data) {
253 if (verify_data.num_vbmeta_images == 0) {
254 LERROR << "No vbmeta images";
255 return false;
256 }
257
258 size_t total_size = 0;
259 bool digest_matched = false;
260
261 if (hash_alg_ == kSHA256) {
262 std::tie(total_size, digest_matched) =
263 verify_vbmeta_digest<SHA256Hasher>(verify_data, digest_);
264 } else if (hash_alg_ == kSHA512) {
265 std::tie(total_size, digest_matched) =
266 verify_vbmeta_digest<SHA512Hasher>(verify_data, digest_);
267 }
268
269 if (total_size != vbmeta_size_) {
270 LERROR << "total vbmeta size mismatch: " << total_size << " (expected: " << vbmeta_size_
271 << ")";
272 return false;
273 }
274
275 if (!digest_matched) {
276 LERROR << "vbmeta digest mismatch";
277 return false;
278 }
279
280 return true;
281 }
282
hashtree_load_verity_table(struct dm_ioctl * io,const std::string & dm_device_name,int fd,const std::string & blk_device,const AvbHashtreeDescriptor & hashtree_desc,const std::string & salt,const std::string & root_digest)283 static bool hashtree_load_verity_table(struct dm_ioctl* io, const std::string& dm_device_name,
284 int fd, const std::string& blk_device,
285 const AvbHashtreeDescriptor& hashtree_desc,
286 const std::string& salt, const std::string& root_digest) {
287 fs_mgr_verity_ioctl_init(io, dm_device_name, DM_STATUS_TABLE_FLAG);
288
289 // The buffer consists of [dm_ioctl][dm_target_spec][verity_params].
290 char* buffer = (char*)io;
291
292 // Builds the dm_target_spec arguments.
293 struct dm_target_spec* dm_target = (struct dm_target_spec*)&buffer[sizeof(struct dm_ioctl)];
294 io->target_count = 1;
295 dm_target->status = 0;
296 dm_target->sector_start = 0;
297 dm_target->length = hashtree_desc.image_size / 512;
298 strcpy(dm_target->target_type, "verity");
299
300 // Builds the verity params.
301 char* verity_params = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec);
302 size_t bufsize = DM_BUF_SIZE - (verity_params - buffer);
303
304 int res = 0;
305 if (hashtree_desc.fec_size > 0) {
306 res = snprintf(verity_params, bufsize, VERITY_TABLE_FORMAT VERITY_TABLE_OPT_FEC_FORMAT,
307 VERITY_TABLE_PARAMS(hashtree_desc, blk_device.c_str(), root_digest.c_str(),
308 salt.c_str()),
309 VERITY_TABLE_OPT_FEC_PARAMS(hashtree_desc, blk_device.c_str()));
310 } else {
311 res = snprintf(verity_params, bufsize, VERITY_TABLE_FORMAT VERITY_TABLE_OPT_DEFAULT_FORMAT,
312 VERITY_TABLE_PARAMS(hashtree_desc, blk_device.c_str(), root_digest.c_str(),
313 salt.c_str()),
314 VERITY_TABLE_OPT_DEFAULT_PARAMS);
315 }
316
317 if (res < 0 || (size_t)res >= bufsize) {
318 LERROR << "Error building verity table; insufficient buffer size?";
319 return false;
320 }
321
322 LINFO << "Loading verity table: '" << verity_params << "'";
323
324 // Sets ext target boundary.
325 verity_params += strlen(verity_params) + 1;
326 verity_params = (char*)(((unsigned long)verity_params + 7) & ~7);
327 dm_target->next = verity_params - buffer;
328
329 // Sends the ioctl to load the verity table.
330 if (ioctl(fd, DM_TABLE_LOAD, io)) {
331 PERROR << "Error loading verity table";
332 return false;
333 }
334
335 return true;
336 }
337
hashtree_dm_verity_setup(struct fstab_rec * fstab_entry,const AvbHashtreeDescriptor & hashtree_desc,const std::string & salt,const std::string & root_digest,bool wait_for_verity_dev)338 static bool hashtree_dm_verity_setup(struct fstab_rec* fstab_entry,
339 const AvbHashtreeDescriptor& hashtree_desc,
340 const std::string& salt, const std::string& root_digest,
341 bool wait_for_verity_dev) {
342 // Gets the device mapper fd.
343 android::base::unique_fd fd(open("/dev/device-mapper", O_RDWR));
344 if (fd < 0) {
345 PERROR << "Error opening device mapper";
346 return false;
347 }
348
349 // Creates the device.
350 alignas(dm_ioctl) char buffer[DM_BUF_SIZE];
351 struct dm_ioctl* io = (struct dm_ioctl*)buffer;
352 const std::string mount_point(basename(fstab_entry->mount_point));
353 if (!fs_mgr_create_verity_device(io, mount_point, fd)) {
354 LERROR << "Couldn't create verity device!";
355 return false;
356 }
357
358 // Gets the name of the device file.
359 std::string verity_blk_name;
360 if (!fs_mgr_get_verity_device_name(io, mount_point, fd, &verity_blk_name)) {
361 LERROR << "Couldn't get verity device number!";
362 return false;
363 }
364
365 // Loads the verity mapping table.
366 if (!hashtree_load_verity_table(io, mount_point, fd, std::string(fstab_entry->blk_device),
367 hashtree_desc, salt, root_digest)) {
368 LERROR << "Couldn't load verity table!";
369 return false;
370 }
371
372 // Activates the device.
373 if (!fs_mgr_resume_verity_table(io, mount_point, fd)) {
374 return false;
375 }
376
377 // Marks the underlying block device as read-only.
378 fs_mgr_set_blk_ro(fstab_entry->blk_device);
379
380 // Updates fstab_rec->blk_device to verity device name.
381 free(fstab_entry->blk_device);
382 fstab_entry->blk_device = strdup(verity_blk_name.c_str());
383
384 // Makes sure we've set everything up properly.
385 if (wait_for_verity_dev && fs_mgr_test_access(verity_blk_name.c_str()) < 0) {
386 return false;
387 }
388
389 return true;
390 }
391
get_hashtree_descriptor(const std::string & partition_name,const AvbSlotVerifyData & verify_data,AvbHashtreeDescriptor * out_hashtree_desc,std::string * out_salt,std::string * out_digest)392 static bool get_hashtree_descriptor(const std::string& partition_name,
393 const AvbSlotVerifyData& verify_data,
394 AvbHashtreeDescriptor* out_hashtree_desc, std::string* out_salt,
395 std::string* out_digest) {
396 bool found = false;
397 const uint8_t* desc_partition_name;
398
399 for (size_t i = 0; i < verify_data.num_vbmeta_images && !found; i++) {
400 // Get descriptors from vbmeta_images[i].
401 size_t num_descriptors;
402 std::unique_ptr<const AvbDescriptor* [], decltype(&avb_free)> descriptors(
403 avb_descriptor_get_all(verify_data.vbmeta_images[i].vbmeta_data,
404 verify_data.vbmeta_images[i].vbmeta_size, &num_descriptors),
405 avb_free);
406
407 if (!descriptors || num_descriptors < 1) {
408 continue;
409 }
410
411 // Ensures that hashtree descriptor is in /vbmeta or /boot or in
412 // the same partition for verity setup.
413 std::string vbmeta_partition_name(verify_data.vbmeta_images[i].partition_name);
414 if (vbmeta_partition_name != "vbmeta" &&
415 vbmeta_partition_name != "boot" && // for legacy device to append top-level vbmeta
416 vbmeta_partition_name != partition_name) {
417 LWARNING << "Skip vbmeta image at " << verify_data.vbmeta_images[i].partition_name
418 << " for partition: " << partition_name.c_str();
419 continue;
420 }
421
422 for (size_t j = 0; j < num_descriptors && !found; j++) {
423 AvbDescriptor desc;
424 if (!avb_descriptor_validate_and_byteswap(descriptors[j], &desc)) {
425 LWARNING << "Descriptor[" << j << "] is invalid";
426 continue;
427 }
428 if (desc.tag == AVB_DESCRIPTOR_TAG_HASHTREE) {
429 desc_partition_name = (const uint8_t*)descriptors[j] + sizeof(AvbHashtreeDescriptor);
430 if (!avb_hashtree_descriptor_validate_and_byteswap(
431 (AvbHashtreeDescriptor*)descriptors[j], out_hashtree_desc)) {
432 continue;
433 }
434 if (out_hashtree_desc->partition_name_len != partition_name.length()) {
435 continue;
436 }
437 // Notes that desc_partition_name is not NUL-terminated.
438 std::string hashtree_partition_name((const char*)desc_partition_name,
439 out_hashtree_desc->partition_name_len);
440 if (hashtree_partition_name == partition_name) {
441 found = true;
442 }
443 }
444 }
445 }
446
447 if (!found) {
448 LERROR << "Partition descriptor not found: " << partition_name.c_str();
449 return false;
450 }
451
452 const uint8_t* desc_salt = desc_partition_name + out_hashtree_desc->partition_name_len;
453 *out_salt = bytes_to_hex(desc_salt, out_hashtree_desc->salt_len);
454
455 const uint8_t* desc_digest = desc_salt + out_hashtree_desc->salt_len;
456 *out_digest = bytes_to_hex(desc_digest, out_hashtree_desc->root_digest_len);
457
458 return true;
459 }
460
Open(const fstab & fstab)461 FsManagerAvbUniquePtr FsManagerAvbHandle::Open(const fstab& fstab) {
462 FsManagerAvbOps avb_ops(fstab);
463 return DoOpen(&avb_ops);
464 }
465
Open(ByNameSymlinkMap && by_name_symlink_map)466 FsManagerAvbUniquePtr FsManagerAvbHandle::Open(ByNameSymlinkMap&& by_name_symlink_map) {
467 if (by_name_symlink_map.empty()) {
468 LERROR << "Empty by_name_symlink_map when opening FsManagerAvbHandle";
469 return nullptr;
470 }
471 FsManagerAvbOps avb_ops(std::move(by_name_symlink_map));
472 return DoOpen(&avb_ops);
473 }
474
DoOpen(FsManagerAvbOps * avb_ops)475 FsManagerAvbUniquePtr FsManagerAvbHandle::DoOpen(FsManagerAvbOps* avb_ops) {
476 // Gets the expected hash value of vbmeta images from kernel cmdline.
477 std::unique_ptr<FsManagerAvbVerifier> avb_verifier = FsManagerAvbVerifier::Create();
478 if (!avb_verifier) {
479 LERROR << "Failed to create FsManagerAvbVerifier";
480 return nullptr;
481 }
482
483 FsManagerAvbUniquePtr avb_handle(new FsManagerAvbHandle());
484 if (!avb_handle) {
485 LERROR << "Failed to allocate FsManagerAvbHandle";
486 return nullptr;
487 }
488
489 AvbSlotVerifyResult verify_result = avb_ops->AvbSlotVerify(
490 fs_mgr_get_slot_suffix(), avb_verifier->IsDeviceUnlocked(), &avb_handle->avb_slot_data_);
491
492 // Only allow two verify results:
493 // - AVB_SLOT_VERIFY_RESULT_OK.
494 // - AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION (for UNLOCKED state).
495 // If the device is UNLOCKED, i.e., |allow_verification_error| is true for
496 // AvbSlotVerify(), then the following return values are all non-fatal:
497 // * AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION
498 // * AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED
499 // * AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX
500 // The latter two results were checked by bootloader prior to start fs_mgr so
501 // we just need to handle the first result here. See *dummy* operations in
502 // FsManagerAvbOps and the comments in external/avb/libavb/avb_slot_verify.h
503 // for more details.
504 switch (verify_result) {
505 case AVB_SLOT_VERIFY_RESULT_OK:
506 avb_handle->status_ = kFsManagerAvbHandleSuccess;
507 break;
508 case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
509 if (!avb_verifier->IsDeviceUnlocked()) {
510 LERROR << "ERROR_VERIFICATION isn't allowed when the device is LOCKED";
511 return nullptr;
512 }
513 avb_handle->status_ = kFsManagerAvbHandleErrorVerification;
514 break;
515 default:
516 LERROR << "avb_slot_verify failed, result: " << verify_result;
517 return nullptr;
518 }
519
520 // Verifies vbmeta images against the digest passed from bootloader.
521 if (!avb_verifier->VerifyVbmetaImages(*avb_handle->avb_slot_data_)) {
522 LERROR << "VerifyVbmetaImages failed";
523 return nullptr;
524 }
525
526 // Sets the MAJOR.MINOR for init to set it into "ro.boot.avb_version".
527 avb_handle->avb_version_ =
528 android::base::StringPrintf("%d.%d", AVB_VERSION_MAJOR, AVB_VERSION_MINOR);
529
530 // Checks whether FLAGS_HASHTREE_DISABLED is set.
531 AvbVBMetaImageHeader vbmeta_header;
532 avb_vbmeta_image_header_to_host_byte_order(
533 (AvbVBMetaImageHeader*)avb_handle->avb_slot_data_->vbmeta_images[0].vbmeta_data,
534 &vbmeta_header);
535
536 bool hashtree_disabled =
537 ((AvbVBMetaImageFlags)vbmeta_header.flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED);
538 if (hashtree_disabled) {
539 avb_handle->status_ = kFsManagerAvbHandleHashtreeDisabled;
540 }
541
542 LINFO << "Returning avb_handle with status: " << avb_handle->status_;
543 return avb_handle;
544 }
545
SetUpAvb(struct fstab_rec * fstab_entry,bool wait_for_verity_dev)546 bool FsManagerAvbHandle::SetUpAvb(struct fstab_rec* fstab_entry, bool wait_for_verity_dev) {
547 if (!fstab_entry) return false;
548 if (!avb_slot_data_ || avb_slot_data_->num_vbmeta_images < 1) {
549 return false;
550 }
551
552 if (status_ == kFsManagerAvbHandleUninitialized) return false;
553 if (status_ == kFsManagerAvbHandleHashtreeDisabled) {
554 LINFO << "AVB HASHTREE disabled on:" << fstab_entry->mount_point;
555 return true;
556 }
557
558 std::string partition_name(basename(fstab_entry->mount_point));
559 if (!avb_validate_utf8((const uint8_t*)partition_name.c_str(), partition_name.length())) {
560 LERROR << "Partition name: " << partition_name.c_str() << " is not valid UTF-8.";
561 return false;
562 }
563
564 AvbHashtreeDescriptor hashtree_descriptor;
565 std::string salt;
566 std::string root_digest;
567 if (!get_hashtree_descriptor(partition_name, *avb_slot_data_, &hashtree_descriptor, &salt,
568 &root_digest)) {
569 return false;
570 }
571
572 // Converts HASHTREE descriptor to verity_table_params.
573 if (!hashtree_dm_verity_setup(fstab_entry, hashtree_descriptor, salt, root_digest,
574 wait_for_verity_dev)) {
575 return false;
576 }
577 return true;
578 }
579