/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>

#include <android-base/file.h>
#include <android-base/properties.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <crypto_utils/android_pubkey.h>
#include <cutils/properties.h>
#include <libdm/dm.h>
#include <logwrap/logwrap.h>
#include <openssl/obj_mac.h>
#include <openssl/rsa.h>
#include <openssl/sha.h>

#include "fec/io.h"

#include "fs_mgr.h"
#include "fs_mgr_dm_linear.h"
#include "fs_mgr_priv.h"

// Realistically, this file should be part of the android::fs_mgr namespace;
using namespace android::fs_mgr;

#define VERITY_TABLE_RSA_KEY "/verity_key"
#define VERITY_TABLE_HASH_IDX 8
#define VERITY_TABLE_SALT_IDX 9

#define VERITY_TABLE_OPT_RESTART "restart_on_corruption"
#define VERITY_TABLE_OPT_LOGGING "ignore_corruption"
#define VERITY_TABLE_OPT_IGNZERO "ignore_zero_blocks"

#define VERITY_TABLE_OPT_FEC_FORMAT \
    "use_fec_from_device %s fec_start %" PRIu64 " fec_blocks %" PRIu64 \
    " fec_roots %u " VERITY_TABLE_OPT_IGNZERO
#define VERITY_TABLE_OPT_FEC_ARGS 9

#define METADATA_MAGIC 0x01564c54
#define METADATA_TAG_MAX_LENGTH 63
#define METADATA_EOD "eod"

#define VERITY_LASTSIG_TAG "verity_lastsig"

#define VERITY_STATE_TAG "verity_state"
#define VERITY_STATE_HEADER 0x83c0ae9d
#define VERITY_STATE_VERSION 1

#define VERITY_KMSG_RESTART "dm-verity device corrupted"
#define VERITY_KMSG_BUFSIZE 1024

#define READ_BUF_SIZE 4096

#define __STRINGIFY(x) #x
#define STRINGIFY(x) __STRINGIFY(x)

struct verity_state {
    uint32_t header;
    uint32_t version;
    int32_t mode;
};

extern struct fs_info info;

static RSA *load_key(const char *path)
{
    uint8_t key_data[ANDROID_PUBKEY_ENCODED_SIZE];

    auto f = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path, "re"), fclose};
    if (!f) {
        LERROR << "Can't open " << path;
        return nullptr;
    }

    if (!fread(key_data, sizeof(key_data), 1, f.get())) {
        LERROR << "Could not read key!";
        return nullptr;
    }

    RSA* key = nullptr;
    if (!android_pubkey_decode(key_data, sizeof(key_data), &key)) {
        LERROR << "Could not parse key!";
        return nullptr;
    }

    return key;
}

static int verify_table(const uint8_t *signature, size_t signature_size,
        const char *table, uint32_t table_length)
{
    RSA *key;
    uint8_t hash_buf[SHA256_DIGEST_LENGTH];
    int retval = -1;

    // Hash the table
    SHA256((uint8_t*)table, table_length, hash_buf);

    // Now get the public key from the keyfile
    key = load_key(VERITY_TABLE_RSA_KEY);
    if (!key) {
        LERROR << "Couldn't load verity keys";
        goto out;
    }

    // verify the result
    if (!RSA_verify(NID_sha256, hash_buf, sizeof(hash_buf), signature,
                    signature_size, key)) {
        LERROR << "Couldn't verify table";
        goto out;
    }

    retval = 0;

out:
    RSA_free(key);
    return retval;
}

static int verify_verity_signature(const struct fec_verity_metadata& verity)
{
    if (verify_table(verity.signature, sizeof(verity.signature),
            verity.table, verity.table_length) == 0 ||
        verify_table(verity.ecc_signature, sizeof(verity.ecc_signature),
            verity.table, verity.table_length) == 0) {
        return 0;
    }

    return -1;
}

static int invalidate_table(char *table, size_t table_length)
{
    size_t n = 0;
    size_t idx = 0;
    size_t cleared = 0;

    while (n < table_length) {
        if (table[n++] == ' ') {
            ++idx;
        }

        if (idx != VERITY_TABLE_HASH_IDX && idx != VERITY_TABLE_SALT_IDX) {
            continue;
        }

        while (n < table_length && table[n] != ' ') {
            table[n++] = '0';
        }

        if (++cleared == 2) {
            return 0;
        }
    }

    return -1;
}

struct verity_table_params {
    char *table;
    int mode;
    struct fec_ecc_metadata ecc;
    const char *ecc_dev;
};

typedef bool (*format_verity_table_func)(char *buf, const size_t bufsize,
        const struct verity_table_params *params);

static bool format_verity_table(char *buf, const size_t bufsize,
        const struct verity_table_params *params)
{
    const char *mode_flag = NULL;
    int res = -1;

    if (params->mode == VERITY_MODE_RESTART) {
        mode_flag = VERITY_TABLE_OPT_RESTART;
    } else if (params->mode == VERITY_MODE_LOGGING) {
        mode_flag = VERITY_TABLE_OPT_LOGGING;
    }

    if (params->ecc.valid) {
        if (mode_flag) {
            res = snprintf(buf, bufsize,
                    "%s %u %s " VERITY_TABLE_OPT_FEC_FORMAT,
                    params->table, 1 + VERITY_TABLE_OPT_FEC_ARGS, mode_flag, params->ecc_dev,
                    params->ecc.start / FEC_BLOCKSIZE, params->ecc.blocks, params->ecc.roots);
        } else {
            res = snprintf(buf, bufsize,
                    "%s %u " VERITY_TABLE_OPT_FEC_FORMAT,
                    params->table, VERITY_TABLE_OPT_FEC_ARGS, params->ecc_dev,
                    params->ecc.start / FEC_BLOCKSIZE, params->ecc.blocks, params->ecc.roots);
        }
    } else if (mode_flag) {
        res = snprintf(buf, bufsize, "%s 2 " VERITY_TABLE_OPT_IGNZERO " %s", params->table,
                    mode_flag);
    } else {
        res = snprintf(buf, bufsize, "%s 1 " VERITY_TABLE_OPT_IGNZERO, params->table);
    }

    if (res < 0 || (size_t)res >= bufsize) {
        LERROR << "Error building verity table; insufficient buffer size?";
        return false;
    }

    return true;
}

static bool format_legacy_verity_table(char *buf, const size_t bufsize,
        const struct verity_table_params *params)
{
    int res;

    if (params->mode == VERITY_MODE_EIO) {
        res = strlcpy(buf, params->table, bufsize);
    } else {
        res = snprintf(buf, bufsize, "%s %d", params->table, params->mode);
    }

    if (res < 0 || (size_t)res >= bufsize) {
        LERROR << "Error building verity table; insufficient buffer size?";
        return false;
    }

    return true;
}

static int load_verity_table(android::dm::DeviceMapper& dm, const std::string& name,
                             uint64_t device_size, const struct verity_table_params* params,
                             format_verity_table_func format) {
    android::dm::DmTable table;
    table.set_readonly(true);

    char buffer[DM_BUF_SIZE];
    if (!format(buffer, sizeof(buffer), params)) {
        LERROR << "Failed to format verity parameters";
        return -1;
    }

    android::dm::DmTargetVerityString target(0, device_size / 512, buffer);
    if (!table.AddTarget(std::make_unique<decltype(target)>(target))) {
        LERROR << "Failed to add verity target";
        return -1;
    }
    if (!dm.CreateDevice(name, table)) {
        LERROR << "Failed to create verity device \"" << name << "\"";
        return -1;
    }
    return 0;
}

static int check_verity_restart(const char *fname)
{
    char buffer[VERITY_KMSG_BUFSIZE + 1];
    int fd;
    int rc = 0;
    ssize_t size;
    struct stat s;

    fd = TEMP_FAILURE_RETRY(open(fname, O_RDONLY | O_CLOEXEC));

    if (fd == -1) {
        if (errno != ENOENT) {
            PERROR << "Failed to open " << fname;
        }
        goto out;
    }

    if (fstat(fd, &s) == -1) {
        PERROR << "Failed to fstat " << fname;
        goto out;
    }

    size = VERITY_KMSG_BUFSIZE;

    if (size > s.st_size) {
        size = s.st_size;
    }

    if (lseek(fd, s.st_size - size, SEEK_SET) == -1) {
        PERROR << "Failed to lseek " << (intmax_t)(s.st_size - size) << " " << fname;
        goto out;
    }

    if (!android::base::ReadFully(fd, buffer, size)) {
        PERROR << "Failed to read " << size << " bytes from " << fname;
        goto out;
    }

    buffer[size] = '\0';

    if (strstr(buffer, VERITY_KMSG_RESTART) != NULL) {
        rc = 1;
    }

out:
    if (fd != -1) {
        close(fd);
    }

    return rc;
}

static int was_verity_restart()
{
    static const char* files[] = {
        // clang-format off
        "/sys/fs/pstore/console-ramoops-0",
        "/sys/fs/pstore/console-ramoops",
        "/proc/last_kmsg",
        NULL
        // clang-format on
    };
    int i;

    for (i = 0; files[i]; ++i) {
        if (check_verity_restart(files[i])) {
            return 1;
        }
    }

    return 0;
}

static int metadata_add(FILE *fp, long start, const char *tag,
        unsigned int length, off64_t *offset)
{
    if (fseek(fp, start, SEEK_SET) < 0 ||
        fprintf(fp, "%s %u\n", tag, length) < 0) {
        return -1;
    }

    *offset = ftell(fp);

    if (fseek(fp, length, SEEK_CUR) < 0 ||
        fprintf(fp, METADATA_EOD " 0\n") < 0) {
        return -1;
    }

    return 0;
}

static int metadata_find(const char *fname, const char *stag,
        unsigned int slength, off64_t *offset)
{
    char tag[METADATA_TAG_MAX_LENGTH + 1];
    int rc = -1;
    int n;
    long start = 0x4000; /* skip cryptfs metadata area */
    uint32_t magic;
    unsigned int length = 0;

    if (!fname) {
        return -1;
    }

    auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(fname, "re+"), fclose};

    if (!fp) {
        PERROR << "Failed to open " << fname;
        return -1;
    }

    /* check magic */
    if (fseek(fp.get(), start, SEEK_SET) < 0 || fread(&magic, sizeof(magic), 1, fp.get()) != 1) {
        PERROR << "Failed to read magic from " << fname;
        return -1;
    }

    if (magic != METADATA_MAGIC) {
        magic = METADATA_MAGIC;

        if (fseek(fp.get(), start, SEEK_SET) < 0 ||
            fwrite(&magic, sizeof(magic), 1, fp.get()) != 1) {
            PERROR << "Failed to write magic to " << fname;
            return -1;
        }

        rc = metadata_add(fp.get(), start + sizeof(magic), stag, slength, offset);
        if (rc < 0) {
            PERROR << "Failed to add metadata to " << fname;
        }

        return rc;
    }

    start += sizeof(magic);

    while (1) {
        n = fscanf(fp.get(), "%" STRINGIFY(METADATA_TAG_MAX_LENGTH) "s %u\n", tag, &length);

        if (n == 2 && strcmp(tag, METADATA_EOD)) {
            /* found a tag */
            start = ftell(fp.get());

            if (!strcmp(tag, stag) && length == slength) {
                *offset = start;
                return 0;
            }

            start += length;

            if (fseek(fp.get(), length, SEEK_CUR) < 0) {
                PERROR << "Failed to seek " << fname;
                return -1;
            }
        } else {
            rc = metadata_add(fp.get(), start, stag, slength, offset);
            if (rc < 0) {
                PERROR << "Failed to write metadata to " << fname;
            }
            return rc;
        }
    }
}

static int write_verity_state(const char *fname, off64_t offset, int32_t mode)
{
    int fd;
    int rc = -1;
    struct verity_state s = { VERITY_STATE_HEADER, VERITY_STATE_VERSION, mode };

    fd = TEMP_FAILURE_RETRY(open(fname, O_WRONLY | O_SYNC | O_CLOEXEC));

    if (fd == -1) {
        PERROR << "Failed to open " << fname;
        goto out;
    }

    if (TEMP_FAILURE_RETRY(pwrite64(fd, &s, sizeof(s), offset)) != sizeof(s)) {
        PERROR << "Failed to write " << sizeof(s) << " bytes to " << fname
               << " to offset " << offset;
        goto out;
    }

    rc = 0;

out:
    if (fd != -1) {
        close(fd);
    }

    return rc;
}

static int read_verity_state(const char *fname, off64_t offset, int *mode)
{
    int fd = -1;
    int rc = -1;
    struct verity_state s;

    fd = TEMP_FAILURE_RETRY(open(fname, O_RDONLY | O_CLOEXEC));

    if (fd == -1) {
        PERROR << "Failed to open " << fname;
        goto out;
    }

    if (TEMP_FAILURE_RETRY(pread64(fd, &s, sizeof(s), offset)) != sizeof(s)) {
        PERROR << "Failed to read " <<  sizeof(s) << " bytes from " << fname
               << " offset " << offset;
        goto out;
    }

    if (s.header != VERITY_STATE_HEADER) {
        /* space allocated, but no state written. write default state */
        *mode = VERITY_MODE_DEFAULT;
        rc = write_verity_state(fname, offset, *mode);
        goto out;
    }

    if (s.version != VERITY_STATE_VERSION) {
        LERROR << "Unsupported verity state version (" << s.version << ")";
        goto out;
    }

    if (s.mode < VERITY_MODE_EIO ||
        s.mode > VERITY_MODE_LAST) {
        LERROR << "Unsupported verity mode (" << s.mode << ")";
        goto out;
    }

    *mode = s.mode;
    rc = 0;

out:
    if (fd != -1) {
        close(fd);
    }

    return rc;
}

static int read_partition(const char *path, uint64_t size)
{
    char buf[READ_BUF_SIZE];
    ssize_t size_read;
    android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_CLOEXEC)));

    if (fd == -1) {
        PERROR << "Failed to open " << path;
        return -errno;
    }

    while (size) {
        size_read = TEMP_FAILURE_RETRY(read(fd, buf, READ_BUF_SIZE));
        if (size_read == -1) {
            PERROR << "Error in reading partition " << path;
            return -errno;
        }
        size -= size_read;
    }

    return 0;
}

static int compare_last_signature(const FstabEntry& entry, int* match) {
    char tag[METADATA_TAG_MAX_LENGTH + 1];
    int fd = -1;
    int rc = -1;
    off64_t offset = 0;
    struct fec_handle *f = NULL;
    struct fec_verity_metadata verity;
    uint8_t curr[SHA256_DIGEST_LENGTH];
    uint8_t prev[SHA256_DIGEST_LENGTH];

    *match = 1;

    if (fec_open(&f, entry.blk_device.c_str(), O_RDONLY, FEC_VERITY_DISABLE, FEC_DEFAULT_ROOTS) ==
        -1) {
        PERROR << "Failed to open '" << entry.blk_device << "'";
        return rc;
    }

    // read verity metadata
    if (fec_verity_get_metadata(f, &verity) == -1) {
        PERROR << "Failed to get verity metadata '" << entry.blk_device << "'";
        goto out;
    }

    SHA256(verity.signature, sizeof(verity.signature), curr);

    if (snprintf(tag, sizeof(tag), VERITY_LASTSIG_TAG "_%s", basename(entry.mount_point.c_str())) >=
        (int)sizeof(tag)) {
        LERROR << "Metadata tag name too long for " << entry.mount_point;
        goto out;
    }

    if (metadata_find(entry.verity_loc.c_str(), tag, SHA256_DIGEST_LENGTH, &offset) < 0) {
        goto out;
    }

    fd = TEMP_FAILURE_RETRY(open(entry.verity_loc.c_str(), O_RDWR | O_SYNC | O_CLOEXEC));

    if (fd == -1) {
        PERROR << "Failed to open " << entry.verity_loc;
        goto out;
    }

    if (TEMP_FAILURE_RETRY(pread64(fd, prev, sizeof(prev), offset)) != sizeof(prev)) {
        PERROR << "Failed to read " << sizeof(prev) << " bytes from " << entry.verity_loc
               << " offset " << offset;
        goto out;
    }

    *match = !memcmp(curr, prev, SHA256_DIGEST_LENGTH);

    if (!*match) {
        /* update current signature hash */
        if (TEMP_FAILURE_RETRY(pwrite64(fd, curr, sizeof(curr),
                offset)) != sizeof(curr)) {
            PERROR << "Failed to write " << sizeof(curr) << " bytes to " << entry.verity_loc
                   << " offset " << offset;
            goto out;
        }
    }

    rc = 0;

out:
    fec_close(f);
    return rc;
}

static int get_verity_state_offset(const FstabEntry& entry, off64_t* offset) {
    char tag[METADATA_TAG_MAX_LENGTH + 1];

    if (snprintf(tag, sizeof(tag), VERITY_STATE_TAG "_%s", basename(entry.mount_point.c_str())) >=
        (int)sizeof(tag)) {
        LERROR << "Metadata tag name too long for " << entry.mount_point;
        return -1;
    }

    return metadata_find(entry.verity_loc.c_str(), tag, sizeof(struct verity_state), offset);
}

int load_verity_state(const FstabEntry& entry, int* mode) {
    // unless otherwise specified, use EIO mode.
    *mode = VERITY_MODE_EIO;

    // use the kernel parameter if set.
    std::string veritymode;
    if (fs_mgr_get_boot_config("veritymode", &veritymode)) {
        if (veritymode == "enforcing") {
            *mode = VERITY_MODE_DEFAULT;
        }
        return 0;
    }

    off64_t offset = 0;
    if (get_verity_state_offset(entry, &offset) < 0) {
        /* fall back to stateless behavior */
        return 0;
    }

    if (was_verity_restart()) {
        /* device was restarted after dm-verity detected a corrupted
         * block, so use EIO mode */
        return write_verity_state(entry.verity_loc.c_str(), offset, *mode);
    }

    int match = 0;
    if (!compare_last_signature(entry, &match) && !match) {
        /* partition has been reflashed, reset dm-verity state */
        *mode = VERITY_MODE_DEFAULT;
        return write_verity_state(entry.verity_loc.c_str(), offset, *mode);
    }

    return read_verity_state(entry.verity_loc.c_str(), offset, mode);
}

// Update the verity table using the actual block device path.
// Two cases:
// Case-1: verity table is shared for devices with different by-name prefix.
// Example:
//   verity table token:       /dev/block/bootdevice/by-name/vendor
//   blk_device-1 (non-A/B):   /dev/block/platform/soc.0/7824900.sdhci/by-name/vendor
//   blk_device-2 (A/B):       /dev/block/platform/soc.0/f9824900.sdhci/by-name/vendor_a
//
// Case-2: append A/B suffix in the verity table.
// Example:
//   verity table token: /dev/block/platform/soc.0/7824900.sdhci/by-name/vendor
//   blk_device:         /dev/block/platform/soc.0/7824900.sdhci/by-name/vendor_a
static void update_verity_table_blk_device(const std::string& blk_device, char** table,
                                           bool slot_select) {
    bool updated = false;
    std::string result, ab_suffix;
    auto tokens = android::base::Split(*table, " ");

    // If slot_select is set, it means blk_device is already updated with ab_suffix.
    if (slot_select) ab_suffix = fs_mgr_get_slot_suffix();

    for (const auto& token : tokens) {
        std::string new_token;
        if (android::base::StartsWith(token, "/dev/block/")) {
            if (token == blk_device) return;  // no need to update if they're already the same.
            std::size_t found1 = blk_device.find("by-name");
            std::size_t found2 = token.find("by-name");
            if (found1 != std::string::npos && found2 != std::string::npos &&
                blk_device.substr(found1) == token.substr(found2) + ab_suffix) {
                new_token = blk_device;
            }
        }

        if (!new_token.empty()) {
            updated = true;
            LINFO << "Verity table: updated block device from '" << token << "' to '" << new_token
                  << "'";
        } else {
            new_token = token;
        }

        if (result.empty()) {
            result = new_token;
        } else {
            result += " " + new_token;
        }
    }

    if (!updated) {
        return;
    }

    free(*table);
    *table = strdup(result.c_str());
}

// prepares the verity enabled (MF_VERIFY / MF_VERIFYATBOOT) fstab record for
// mount. The 'wait_for_verity_dev' parameter makes this function wait for the
// verity device to get created before return
int fs_mgr_setup_verity(FstabEntry* entry, bool wait_for_verity_dev) {
    int retval = FS_MGR_SETUP_VERITY_FAIL;
    int fd = -1;
    std::string verity_blk_name;
    struct fec_handle *f = NULL;
    struct fec_verity_metadata verity;
    struct verity_table_params params = { .table = NULL };

    const std::string mount_point(basename(entry->mount_point.c_str()));
    bool verified_at_boot = false;

    android::dm::DeviceMapper& dm = android::dm::DeviceMapper::Instance();

    if (fec_open(&f, entry->blk_device.c_str(), O_RDONLY, FEC_VERITY_DISABLE, FEC_DEFAULT_ROOTS) <
        0) {
        PERROR << "Failed to open '" << entry->blk_device << "'";
        return retval;
    }

    // read verity metadata
    if (fec_verity_get_metadata(f, &verity) < 0) {
        PERROR << "Failed to get verity metadata '" << entry->blk_device << "'";
        // Allow verity disabled when the device is unlocked without metadata
        if (fs_mgr_is_device_unlocked()) {
            retval = FS_MGR_SETUP_VERITY_SKIPPED;
            LWARNING << "Allow invalid metadata when the device is unlocked";
        }
        goto out;
    }

#ifdef ALLOW_ADBD_DISABLE_VERITY
    if (verity.disabled) {
        retval = FS_MGR_SETUP_VERITY_DISABLED;
        LINFO << "Attempt to cleanly disable verity - only works in USERDEBUG/ENG";
        goto out;
    }
#endif

    // read ecc metadata
    if (fec_ecc_get_metadata(f, &params.ecc) < 0) {
        params.ecc.valid = false;
    }

    params.ecc_dev = entry->blk_device.c_str();

    if (load_verity_state(*entry, &params.mode) < 0) {
        /* if accessing or updating the state failed, switch to the default
         * safe mode. This makes sure the device won't end up in an endless
         * restart loop, and no corrupted data will be exposed to userspace
         * without a warning. */
        params.mode = VERITY_MODE_EIO;
    }

    if (!verity.table) {
        goto out;
    }

    params.table = strdup(verity.table);
    if (!params.table) {
        goto out;
    }

    // verify the signature on the table
    if (verify_verity_signature(verity) < 0) {
        // Allow signature verification error when the device is unlocked
        if (fs_mgr_is_device_unlocked()) {
            retval = FS_MGR_SETUP_VERITY_SKIPPED;
            LWARNING << "Allow signature verification error when the device is unlocked";
            goto out;
        }
        if (params.mode == VERITY_MODE_LOGGING) {
            // the user has been warned, allow mounting without dm-verity
            retval = FS_MGR_SETUP_VERITY_SKIPPED;
            goto out;
        }

        // invalidate root hash and salt to trigger device-specific recovery
        if (invalidate_table(params.table, verity.table_length) < 0) {
            goto out;
        }
    }

    LINFO << "Enabling dm-verity for " << mount_point.c_str()
          << " (mode " << params.mode << ")";

    // Update the verity params using the actual block device path
    update_verity_table_blk_device(entry->blk_device, &params.table,
                                   entry->fs_mgr_flags.slot_select);

    // load the verity mapping table
    if (load_verity_table(dm, mount_point, verity.data_size, &params, format_verity_table) == 0) {
        goto loaded;
    }

    if (params.ecc.valid) {
        // kernel may not support error correction, try without
        LINFO << "Disabling error correction for " << mount_point.c_str();
        params.ecc.valid = false;

        if (load_verity_table(dm, mount_point, verity.data_size, &params, format_verity_table) == 0) {
            goto loaded;
        }
    }

    // try the legacy format for backwards compatibility
    if (load_verity_table(dm, mount_point, verity.data_size, &params, format_legacy_verity_table) ==
        0) {
        goto loaded;
    }

    if (params.mode != VERITY_MODE_EIO) {
        // as a last resort, EIO mode should always be supported
        LINFO << "Falling back to EIO mode for " << mount_point.c_str();
        params.mode = VERITY_MODE_EIO;

        if (load_verity_table(dm, mount_point, verity.data_size, &params,
                              format_legacy_verity_table) == 0) {
            goto loaded;
        }
    }

    LERROR << "Failed to load verity table for " << mount_point.c_str();
    goto out;

loaded:
    if (!dm.GetDmDevicePathByName(mount_point, &verity_blk_name)) {
        LERROR << "Couldn't get verity device number!";
        goto out;
    }

    // mark the underlying block device as read-only
    fs_mgr_set_blk_ro(entry->blk_device);

    // Verify the entire partition in one go
    // If there is an error, allow it to mount as a normal verity partition.
    if (entry->fs_mgr_flags.verify_at_boot) {
        LINFO << "Verifying partition " << entry->blk_device << " at boot";
        int err = read_partition(verity_blk_name.c_str(), verity.data_size);
        if (!err) {
            LINFO << "Verified verity partition " << entry->blk_device << " at boot";
            verified_at_boot = true;
        }
    }

    // assign the new verity block device as the block device
    if (!verified_at_boot) {
        entry->blk_device = verity_blk_name;
    } else if (!dm.DeleteDevice(mount_point)) {
        LERROR << "Failed to remove verity device " << mount_point.c_str();
        goto out;
    }

    // make sure we've set everything up properly
    if (wait_for_verity_dev && !fs_mgr_wait_for_file(entry->blk_device, 1s)) {
        goto out;
    }

    retval = FS_MGR_SETUP_VERITY_SUCCESS;

out:
    if (fd != -1) {
        close(fd);
    }

    fec_close(f);
    free(params.table);

    return retval;
}

bool fs_mgr_teardown_verity(FstabEntry* entry, bool wait) {
    const std::string mount_point(basename(entry->mount_point.c_str()));
    if (!android::fs_mgr::UnmapDevice(mount_point, wait ? 1000ms : 0ms)) {
        return false;
    }
    LINFO << "Unmapped verity device " << mount_point;
    return true;
}
