/*
 * Copyright (C) 2016 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 "EncryptInplace.h"

#include <ext4_utils/ext4.h>
#include <ext4_utils/ext4_utils.h>
#include <f2fs_sparseblock.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>

#include <algorithm>

#include <android-base/logging.h>
#include <android-base/properties.h>

// HORRIBLE HACK, FIXME
#include "cryptfs.h"

// FIXME horrible cut-and-paste code
static inline int unix_read(int fd, void* buff, int len) {
    return TEMP_FAILURE_RETRY(read(fd, buff, len));
}

static inline int unix_write(int fd, const void* buff, int len) {
    return TEMP_FAILURE_RETRY(write(fd, buff, len));
}

#define CRYPT_SECTORS_PER_BUFSIZE (CRYPT_INPLACE_BUFSIZE / CRYPT_SECTOR_SIZE)

/* aligned 32K writes tends to make flash happy.
 * SD card association recommends it.
 */
#ifndef CONFIG_HW_DISK_ENCRYPTION
#define BLOCKS_AT_A_TIME 8
#else
#define BLOCKS_AT_A_TIME 1024
#endif

struct encryptGroupsData {
    int realfd;
    int cryptofd;
    off64_t numblocks;
    off64_t one_pct, cur_pct, new_pct;
    off64_t blocks_already_done, tot_numblocks;
    off64_t used_blocks_already_done, tot_used_blocks;
    const char* real_blkdev;
    const char* crypto_blkdev;
    int count;
    off64_t offset;
    char* buffer;
    off64_t last_written_sector;
    int completed;
    time_t time_started;
    int remaining_time;
    bool set_progress_properties;
};

static void update_progress(struct encryptGroupsData* data, int is_used) {
    data->blocks_already_done++;

    if (is_used) {
        data->used_blocks_already_done++;
    }
    if (data->tot_used_blocks) {
        data->new_pct = data->used_blocks_already_done / data->one_pct;
    } else {
        data->new_pct = data->blocks_already_done / data->one_pct;
    }

    if (!data->set_progress_properties) return;

    if (data->new_pct > data->cur_pct) {
        char buf[8];
        data->cur_pct = data->new_pct;
        snprintf(buf, sizeof(buf), "%" PRId64, data->cur_pct);
        android::base::SetProperty("vold.encrypt_progress", buf);
    }

    if (data->cur_pct >= 5) {
        struct timespec time_now;
        if (clock_gettime(CLOCK_MONOTONIC, &time_now)) {
            LOG(WARNING) << "Error getting time";
        } else {
            double elapsed_time = difftime(time_now.tv_sec, data->time_started);
            off64_t remaining_blocks = data->tot_used_blocks - data->used_blocks_already_done;
            int remaining_time =
                (int)(elapsed_time * remaining_blocks / data->used_blocks_already_done);

            // Change time only if not yet set, lower, or a lot higher for
            // best user experience
            if (data->remaining_time == -1 || remaining_time < data->remaining_time ||
                remaining_time > data->remaining_time + 60) {
                char buf[8];
                snprintf(buf, sizeof(buf), "%d", remaining_time);
                android::base::SetProperty("vold.encrypt_time_remaining", buf);
                data->remaining_time = remaining_time;
            }
        }
    }
}

static void log_progress(struct encryptGroupsData const* data, bool completed) {
    // Precondition - if completed data = 0 else data != 0

    // Track progress so we can skip logging blocks
    static off64_t offset = -1;

    // Need to close existing 'Encrypting from' log?
    if (completed || (offset != -1 && data->offset != offset)) {
        LOG(INFO) << "Encrypted to sector " << offset / info.block_size * CRYPT_SECTOR_SIZE;
        offset = -1;
    }

    // Need to start new 'Encrypting from' log?
    if (!completed && offset != data->offset) {
        LOG(INFO) << "Encrypting from sector " << data->offset / info.block_size * CRYPT_SECTOR_SIZE;
    }

    // Update offset
    if (!completed) {
        offset = data->offset + (off64_t)data->count * info.block_size;
    }
}

static int flush_outstanding_data(struct encryptGroupsData* data) {
    if (data->count == 0) {
        return 0;
    }

    LOG(DEBUG) << "Copying " << data->count << " blocks at offset " << data->offset;

    if (pread64(data->realfd, data->buffer, info.block_size * data->count, data->offset) <= 0) {
        LOG(ERROR) << "Error reading real_blkdev " << data->real_blkdev << " for inplace encrypt";
        return -1;
    }

    if (pwrite64(data->cryptofd, data->buffer, info.block_size * data->count, data->offset) <= 0) {
        LOG(ERROR) << "Error writing crypto_blkdev " << data->crypto_blkdev
                   << " for inplace encrypt";
        return -1;
    } else {
        log_progress(data, false);
    }

    data->count = 0;
    data->last_written_sector =
        (data->offset + data->count) / info.block_size * CRYPT_SECTOR_SIZE - 1;
    return 0;
}

static int encrypt_groups(struct encryptGroupsData* data) {
    unsigned int i;
    u8* block_bitmap = 0;
    unsigned int block;
    off64_t ret;
    int rc = -1;

    data->buffer = (char*)malloc(info.block_size * BLOCKS_AT_A_TIME);
    if (!data->buffer) {
        LOG(ERROR) << "Failed to allocate crypto buffer";
        goto errout;
    }

    block_bitmap = (u8*)malloc(info.block_size);
    if (!block_bitmap) {
        LOG(ERROR) << "failed to allocate block bitmap";
        goto errout;
    }

    for (i = 0; i < aux_info.groups; ++i) {
        LOG(INFO) << "Encrypting group " << i;

        u32 first_block = aux_info.first_data_block + i * info.blocks_per_group;
        u32 block_count = std::min(info.blocks_per_group, (u32)(aux_info.len_blocks - first_block));

        off64_t offset = (u64)info.block_size * aux_info.bg_desc[i].bg_block_bitmap;

        ret = pread64(data->realfd, block_bitmap, info.block_size, offset);
        if (ret != (int)info.block_size) {
            LOG(ERROR) << "failed to read all of block group bitmap " << i;
            goto errout;
        }

        offset = (u64)info.block_size * first_block;

        data->count = 0;

        for (block = 0; block < block_count; block++) {
            int used;

            if (aux_info.bg_desc[i].bg_flags & EXT4_BG_BLOCK_UNINIT) {
                // In block groups with an uninitialized block bitmap, we only
                // need to encrypt the backup superblock (if one is present).
                used = (ext4_bg_has_super_block(i) && block < 1 + aux_info.bg_desc_blocks);
            } else {
                used = bitmap_get_bit(block_bitmap, block);
            }

            update_progress(data, used);
            if (used) {
                if (data->count == 0) {
                    data->offset = offset;
                }
                data->count++;
            } else {
                if (flush_outstanding_data(data)) {
                    goto errout;
                }
            }

            offset += info.block_size;

            /* Write data if we are aligned or buffer size reached */
            if (offset % (info.block_size * BLOCKS_AT_A_TIME) == 0 ||
                data->count == BLOCKS_AT_A_TIME) {
                if (flush_outstanding_data(data)) {
                    goto errout;
                }
            }
        }
        if (flush_outstanding_data(data)) {
            goto errout;
        }
    }

    data->completed = 1;
    rc = 0;

errout:
    log_progress(0, true);
    free(data->buffer);
    free(block_bitmap);
    return rc;
}

static int cryptfs_enable_inplace_ext4(const char* crypto_blkdev, const char* real_blkdev,
                                       off64_t size, off64_t* size_already_done, off64_t tot_size,
                                       off64_t previously_encrypted_upto,
                                       bool set_progress_properties) {
    u32 i;
    struct encryptGroupsData data;
    int rc;  // Can't initialize without causing warning -Wclobbered
    int retries = RETRY_MOUNT_ATTEMPTS;
    struct timespec time_started = {0};

    if (previously_encrypted_upto > *size_already_done) {
        LOG(DEBUG) << "Not fast encrypting since resuming part way through";
        return -1;
    }

    memset(&data, 0, sizeof(data));
    data.real_blkdev = real_blkdev;
    data.crypto_blkdev = crypto_blkdev;
    data.set_progress_properties = set_progress_properties;

    LOG(DEBUG) << "Opening" << real_blkdev;
    if ((data.realfd = open(real_blkdev, O_RDWR | O_CLOEXEC)) < 0) {
        PLOG(ERROR) << "Error opening real_blkdev " << real_blkdev << " for inplace encrypt";
        rc = -1;
        goto errout;
    }

    LOG(DEBUG) << "Opening" << crypto_blkdev;
    // Wait until the block device appears.  Re-use the mount retry values since it is reasonable.
    while ((data.cryptofd = open(crypto_blkdev, O_WRONLY | O_CLOEXEC)) < 0) {
        if (--retries) {
            PLOG(ERROR) << "Error opening crypto_blkdev " << crypto_blkdev
                        << " for ext4 inplace encrypt, retrying";
            sleep(RETRY_MOUNT_DELAY_SECONDS);
        } else {
            PLOG(ERROR) << "Error opening crypto_blkdev " << crypto_blkdev
                        << " for ext4 inplace encrypt";
            rc = ENABLE_INPLACE_ERR_DEV;
            goto errout;
        }
    }

    if (setjmp(setjmp_env)) {  // NOLINT
        LOG(ERROR) << "Reading ext4 extent caused an exception";
        rc = -1;
        goto errout;
    }

    if (read_ext(data.realfd, 0) != 0) {
        LOG(ERROR) << "Failed to read ext4 extent";
        rc = -1;
        goto errout;
    }

    data.numblocks = size / CRYPT_SECTORS_PER_BUFSIZE;
    data.tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE;
    data.blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE;

    LOG(INFO) << "Encrypting ext4 filesystem in place...";

    data.tot_used_blocks = data.numblocks;
    for (i = 0; i < aux_info.groups; ++i) {
        data.tot_used_blocks -= aux_info.bg_desc[i].bg_free_blocks_count;
    }

    data.one_pct = data.tot_used_blocks / 100;
    data.cur_pct = 0;

    if (clock_gettime(CLOCK_MONOTONIC, &time_started)) {
        LOG(WARNING) << "Error getting time at start";
        // Note - continue anyway - we'll run with 0
    }
    data.time_started = time_started.tv_sec;
    data.remaining_time = -1;

    rc = encrypt_groups(&data);
    if (rc) {
        LOG(ERROR) << "Error encrypting groups";
        goto errout;
    }

    *size_already_done += data.completed ? size : data.last_written_sector;
    rc = 0;

errout:
    close(data.realfd);
    close(data.cryptofd);

    return rc;
}

static void log_progress_f2fs(u64 block, bool completed) {
    // Precondition - if completed data = 0 else data != 0

    // Track progress so we can skip logging blocks
    static u64 last_block = (u64)-1;

    // Need to close existing 'Encrypting from' log?
    if (completed || (last_block != (u64)-1 && block != last_block + 1)) {
        LOG(INFO) << "Encrypted to block " << last_block;
        last_block = -1;
    }

    // Need to start new 'Encrypting from' log?
    if (!completed && (last_block == (u64)-1 || block != last_block + 1)) {
        LOG(INFO) << "Encrypting from block " << block;
    }

    // Update offset
    if (!completed) {
        last_block = block;
    }
}

static int encrypt_one_block_f2fs(u64 pos, void* data) {
    struct encryptGroupsData* priv_dat = (struct encryptGroupsData*)data;

    priv_dat->blocks_already_done = pos - 1;
    update_progress(priv_dat, 1);

    off64_t offset = pos * CRYPT_INPLACE_BUFSIZE;

    if (pread64(priv_dat->realfd, priv_dat->buffer, CRYPT_INPLACE_BUFSIZE, offset) <= 0) {
        LOG(ERROR) << "Error reading real_blkdev " << priv_dat->crypto_blkdev
                   << " for f2fs inplace encrypt";
        return -1;
    }

    if (pwrite64(priv_dat->cryptofd, priv_dat->buffer, CRYPT_INPLACE_BUFSIZE, offset) <= 0) {
        LOG(ERROR) << "Error writing crypto_blkdev " << priv_dat->crypto_blkdev
                   << " for f2fs inplace encrypt";
        return -1;
    } else {
        log_progress_f2fs(pos, false);
    }

    return 0;
}

static int cryptfs_enable_inplace_f2fs(const char* crypto_blkdev, const char* real_blkdev,
                                       off64_t size, off64_t* size_already_done, off64_t tot_size,
                                       off64_t previously_encrypted_upto,
                                       bool set_progress_properties) {
    struct encryptGroupsData data;
    struct f2fs_info* f2fs_info = NULL;
    int rc = ENABLE_INPLACE_ERR_OTHER;
    struct timespec time_started = {0};

    if (previously_encrypted_upto > *size_already_done) {
        LOG(DEBUG) << "Not fast encrypting since resuming part way through";
        return ENABLE_INPLACE_ERR_OTHER;
    }
    memset(&data, 0, sizeof(data));
    data.real_blkdev = real_blkdev;
    data.crypto_blkdev = crypto_blkdev;
    data.set_progress_properties = set_progress_properties;
    data.realfd = -1;
    data.cryptofd = -1;
    if ((data.realfd = open64(real_blkdev, O_RDWR | O_CLOEXEC)) < 0) {
        PLOG(ERROR) << "Error opening real_blkdev " << real_blkdev << " for f2fs inplace encrypt";
        goto errout;
    }
    if ((data.cryptofd = open64(crypto_blkdev, O_WRONLY | O_CLOEXEC)) < 0) {
        PLOG(ERROR) << "Error opening crypto_blkdev " << crypto_blkdev
                    << " for f2fs inplace encrypt";
        rc = ENABLE_INPLACE_ERR_DEV;
        goto errout;
    }

    f2fs_info = generate_f2fs_info(data.realfd);
    if (!f2fs_info) goto errout;

    data.numblocks = size / CRYPT_SECTORS_PER_BUFSIZE;
    data.tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE;
    data.blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE;

    data.tot_used_blocks = get_num_blocks_used(f2fs_info);

    data.one_pct = data.tot_used_blocks / 100;
    data.cur_pct = 0;
    if (clock_gettime(CLOCK_MONOTONIC, &time_started)) {
        LOG(WARNING) << "Error getting time at start";
        // Note - continue anyway - we'll run with 0
    }
    data.time_started = time_started.tv_sec;
    data.remaining_time = -1;


    data.buffer = (char*)malloc(f2fs_info->block_size);
    if (!data.buffer) {
        LOG(ERROR) << "Failed to allocate crypto buffer";
        goto errout;
    }

    data.count = 0;

    /* Currently, this either runs to completion, or hits a nonrecoverable error */
    rc = run_on_used_blocks(data.blocks_already_done, f2fs_info, &encrypt_one_block_f2fs, &data);

    if (rc) {
        LOG(ERROR) << "Error in running over f2fs blocks";
        rc = ENABLE_INPLACE_ERR_OTHER;
        goto errout;
    }

    *size_already_done += size;
    rc = 0;

errout:
    if (rc) LOG(ERROR) << "Failed to encrypt f2fs filesystem on " << real_blkdev;

    log_progress_f2fs(0, true);
    free(f2fs_info);
    free(data.buffer);
    close(data.realfd);
    close(data.cryptofd);

    return rc;
}

static int cryptfs_enable_inplace_full(const char* crypto_blkdev, const char* real_blkdev,
                                       off64_t size, off64_t* size_already_done, off64_t tot_size,
                                       off64_t previously_encrypted_upto,
                                       bool set_progress_properties) {
    int realfd, cryptofd;
    char* buf[CRYPT_INPLACE_BUFSIZE];
    int rc = ENABLE_INPLACE_ERR_OTHER;
    off64_t numblocks, i, remainder;
    off64_t one_pct, cur_pct, new_pct;
    off64_t blocks_already_done, tot_numblocks;

    if ((realfd = open(real_blkdev, O_RDONLY | O_CLOEXEC)) < 0) {
        PLOG(ERROR) << "Error opening real_blkdev " << real_blkdev << " for inplace encrypt";
        return ENABLE_INPLACE_ERR_OTHER;
    }

    if ((cryptofd = open(crypto_blkdev, O_WRONLY | O_CLOEXEC)) < 0) {
        PLOG(ERROR) << "Error opening crypto_blkdev " << crypto_blkdev << " for inplace encrypt";
        close(realfd);
        return ENABLE_INPLACE_ERR_DEV;
    }

    /* This is pretty much a simple loop of reading 4K, and writing 4K.
     * The size passed in is the number of 512 byte sectors in the filesystem.
     * So compute the number of whole 4K blocks we should read/write,
     * and the remainder.
     */
    numblocks = size / CRYPT_SECTORS_PER_BUFSIZE;
    remainder = size % CRYPT_SECTORS_PER_BUFSIZE;
    tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE;
    blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE;

    LOG(ERROR) << "Encrypting filesystem in place...";

    i = previously_encrypted_upto + 1 - *size_already_done;

    if (lseek64(realfd, i * CRYPT_SECTOR_SIZE, SEEK_SET) < 0) {
        PLOG(ERROR) << "Cannot seek to previously encrypted point on " << real_blkdev;
        goto errout;
    }

    if (lseek64(cryptofd, i * CRYPT_SECTOR_SIZE, SEEK_SET) < 0) {
        PLOG(ERROR) << "Cannot seek to previously encrypted point on " << crypto_blkdev;
        goto errout;
    }

    for (; i < size && i % CRYPT_SECTORS_PER_BUFSIZE != 0; ++i) {
        if (unix_read(realfd, buf, CRYPT_SECTOR_SIZE) <= 0) {
            PLOG(ERROR) << "Error reading initial sectors from real_blkdev " << real_blkdev
                        << " for inplace encrypt";
            goto errout;
        }
        if (unix_write(cryptofd, buf, CRYPT_SECTOR_SIZE) <= 0) {
            PLOG(ERROR) << "Error writing initial sectors to crypto_blkdev " << crypto_blkdev
                        << " for inplace encrypt";
            goto errout;
        } else {
            LOG(INFO) << "Encrypted 1 block at " << i;
        }
    }

    one_pct = tot_numblocks / 100;
    cur_pct = 0;
    /* process the majority of the filesystem in blocks */
    for (i /= CRYPT_SECTORS_PER_BUFSIZE; i < numblocks; i++) {
        new_pct = (i + blocks_already_done) / one_pct;
        if (set_progress_properties && new_pct > cur_pct) {
            char property_buf[8];

            cur_pct = new_pct;
            snprintf(property_buf, sizeof(property_buf), "%" PRId64, cur_pct);
            android::base::SetProperty("vold.encrypt_progress", property_buf);
        }
        if (unix_read(realfd, buf, CRYPT_INPLACE_BUFSIZE) <= 0) {
            PLOG(ERROR) << "Error reading real_blkdev " << real_blkdev << " for inplace encrypt";
            goto errout;
        }
        if (unix_write(cryptofd, buf, CRYPT_INPLACE_BUFSIZE) <= 0) {
            PLOG(ERROR) << "Error writing crypto_blkdev " << crypto_blkdev << " for inplace encrypt";
            goto errout;
        } else {
            LOG(DEBUG) << "Encrypted " << CRYPT_SECTORS_PER_BUFSIZE << " block at "
                       << i * CRYPT_SECTORS_PER_BUFSIZE;
        }
    }

    /* Do any remaining sectors */
    for (i = 0; i < remainder; i++) {
        if (unix_read(realfd, buf, CRYPT_SECTOR_SIZE) <= 0) {
            LOG(ERROR) << "Error reading final sectors from real_blkdev " << real_blkdev
                       << " for inplace encrypt";
            goto errout;
        }
        if (unix_write(cryptofd, buf, CRYPT_SECTOR_SIZE) <= 0) {
            LOG(ERROR) << "Error writing final sectors to crypto_blkdev " << crypto_blkdev
                       << " for inplace encrypt";
            goto errout;
        } else {
            LOG(INFO) << "Encrypted 1 block at next location";
        }
    }

    *size_already_done += size;
    rc = 0;

errout:
    close(realfd);
    close(cryptofd);

    return rc;
}

/* returns on of the ENABLE_INPLACE_* return codes */
int cryptfs_enable_inplace(const char* crypto_blkdev, const char* real_blkdev, off64_t size,
                           off64_t* size_already_done, off64_t tot_size,
                           off64_t previously_encrypted_upto, bool set_progress_properties) {
    int rc_ext4, rc_f2fs, rc_full;
    LOG(DEBUG) << "cryptfs_enable_inplace(" << crypto_blkdev << ", " << real_blkdev << ", " << size
               << ", " << size_already_done << ", " << tot_size << ", " << previously_encrypted_upto
               << ", " << set_progress_properties << ")";
    if (previously_encrypted_upto) {
        LOG(DEBUG) << "Continuing encryption from " << previously_encrypted_upto;
    }

    if (*size_already_done + size < previously_encrypted_upto) {
        LOG(DEBUG) << "cryptfs_enable_inplace already done";
        *size_already_done += size;
        return 0;
    }

    /* TODO: identify filesystem type.
     * As is, cryptfs_enable_inplace_ext4 will fail on an f2fs partition, and
     * then we will drop down to cryptfs_enable_inplace_f2fs.
     * */
    if ((rc_ext4 = cryptfs_enable_inplace_ext4(crypto_blkdev, real_blkdev, size, size_already_done,
                                               tot_size, previously_encrypted_upto,
                                               set_progress_properties)) == 0) {
        LOG(DEBUG) << "cryptfs_enable_inplace_ext4 success";
        return 0;
    }
    LOG(DEBUG) << "cryptfs_enable_inplace_ext4()=" << rc_ext4;

    if ((rc_f2fs = cryptfs_enable_inplace_f2fs(crypto_blkdev, real_blkdev, size, size_already_done,
                                               tot_size, previously_encrypted_upto,
                                               set_progress_properties)) == 0) {
        LOG(DEBUG) << "cryptfs_enable_inplace_f2fs success";
        return 0;
    }
    LOG(DEBUG) << "cryptfs_enable_inplace_f2fs()=" << rc_f2fs;

    rc_full =
        cryptfs_enable_inplace_full(crypto_blkdev, real_blkdev, size, size_already_done, tot_size,
                                    previously_encrypted_upto, set_progress_properties);
    LOG(DEBUG) << "cryptfs_enable_inplace_full()=" << rc_full;

    /* Hack for b/17898962, the following is the symptom... */
    if (rc_ext4 == ENABLE_INPLACE_ERR_DEV && rc_f2fs == ENABLE_INPLACE_ERR_DEV &&
        rc_full == ENABLE_INPLACE_ERR_DEV) {
        LOG(DEBUG) << "ENABLE_INPLACE_ERR_DEV";
        return ENABLE_INPLACE_ERR_DEV;
    }
    return rc_full;
}
