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