Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9dbe97b4 authored by Paul Lawrence's avatar Paul Lawrence
Browse files

Support metadata encryption

Bug: 29189559
Test: Angler, Marlin build and boot
Change-Id: Ia7b070781f5f16ff8bfd934569a2209c80c28385
parent 1395aac3
Loading
Loading
Loading
Loading
+46 −32
Original line number Original line Diff line number Diff line
@@ -721,6 +721,12 @@ static bool needs_block_encryption(const struct fstab_rec* rec)
    return false;
    return false;
}
}


static bool should_use_metadata_encryption(const struct fstab_rec* rec) {
    if (!(rec->fs_mgr_flags & (MF_FILEENCRYPTION | MF_FORCEFDEORFBE))) return false;
    if (!(rec->fs_mgr_flags & MF_KEYDIRECTORY)) return false;
    return true;
}

// Check to see if a mountable volume has encryption requirements
// Check to see if a mountable volume has encryption requirements
static int handle_encryptable(const struct fstab_rec* rec)
static int handle_encryptable(const struct fstab_rec* rec)
{
{
@@ -733,8 +739,14 @@ static int handle_encryptable(const struct fstab_rec* rec)
                     << " - allow continue unencrypted";
                     << " - allow continue unencrypted";
            return FS_MGR_MNTALL_DEV_NOT_ENCRYPTED;
            return FS_MGR_MNTALL_DEV_NOT_ENCRYPTED;
        }
        }
    } else if (should_use_metadata_encryption(rec)) {
        if (umount(rec->mount_point) == 0) {
            return FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION;
        } else {
            PERROR << "Could not umount " << rec->mount_point << " - fail since can't encrypt";
            return FS_MGR_MNTALL_FAIL;
        }
    } else if (rec->fs_mgr_flags & (MF_FILEENCRYPTION | MF_FORCEFDEORFBE)) {
    } else if (rec->fs_mgr_flags & (MF_FILEENCRYPTION | MF_FORCEFDEORFBE)) {
        // Deal with file level encryption
        LINFO << rec->mount_point << " is file encrypted";
        LINFO << rec->mount_point << " is file encrypted";
        return FS_MGR_MNTALL_DEV_FILE_ENCRYPTED;
        return FS_MGR_MNTALL_DEV_FILE_ENCRYPTED;
    } else if (fs_mgr_is_encryptable(rec)) {
    } else if (fs_mgr_is_encryptable(rec)) {
@@ -900,7 +912,6 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode)
            continue;
            continue;
        }
        }


        /* mount(2) returned an error, handle the encryptable/formattable case */
        bool wiped = partition_wiped(fstab->recs[top_idx].blk_device);
        bool wiped = partition_wiped(fstab->recs[top_idx].blk_device);
        bool crypt_footer = false;
        bool crypt_footer = false;
        if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
        if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
@@ -940,6 +951,8 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode)
                continue;
                continue;
            }
            }
        }
        }

        /* mount(2) returned an error, handle the encryptable/formattable case */
        if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
        if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
            fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) {
            fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) {
            if (wiped) {
            if (wiped) {
@@ -965,6 +978,9 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode)
                }
                }
            }
            }
            encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
            encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
        } else if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
                   should_use_metadata_encryption(&fstab->recs[attempted_idx])) {
            encryptable = FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED;
        } else {
        } else {
            if (fs_mgr_is_nofail(&fstab->recs[attempted_idx])) {
            if (fs_mgr_is_nofail(&fstab->recs[attempted_idx])) {
                PERROR << "Ignoring failure to mount an un-encryptable or wiped partition on"
                PERROR << "Ignoring failure to mount an un-encryptable or wiped partition on"
@@ -1256,48 +1272,46 @@ int fs_mgr_swapon_all(struct fstab *fstab)
    return ret;
    return ret;
}
}


/*
struct fstab_rec const* fs_mgr_get_crypt_entry(struct fstab const* fstab) {
 * key_loc must be at least PROPERTY_VALUE_MAX bytes long
    int i;
 *
 * real_blk_device must be at least PROPERTY_VALUE_MAX bytes long
 */
int fs_mgr_get_crypt_info(struct fstab *fstab, char *key_loc, char *real_blk_device, int size)
{
    int i = 0;


    if (!fstab) {
    if (!fstab) {
        return -1;
        return NULL;
    }
    /* Initialize return values to null strings */
    if (key_loc) {
        *key_loc = '\0';
    }
    if (real_blk_device) {
        *real_blk_device = '\0';
    }
    }


    /* Look for the encryptable partition to find the data */
    /* Look for the encryptable partition to find the data */
    for (i = 0; i < fstab->num_entries; i++) {
    for (i = 0; i < fstab->num_entries; i++) {
        /* Don't deal with vold managed enryptable partitions here */
        /* Don't deal with vold managed enryptable partitions here */
        if (fstab->recs[i].fs_mgr_flags & MF_VOLDMANAGED) {
        if (!(fstab->recs[i].fs_mgr_flags & MF_VOLDMANAGED) &&
            continue;
            (fstab->recs[i].fs_mgr_flags &
             (MF_CRYPT | MF_FORCECRYPT | MF_FORCEFDEORFBE | MF_FILEENCRYPTION))) {
            return &fstab->recs[i];
        }
        }
        if (!(fstab->recs[i].fs_mgr_flags
    }
              & (MF_CRYPT | MF_FORCECRYPT | MF_FORCEFDEORFBE))) {
    return NULL;
            continue;
}
}


        /* We found a match */
/*
 * key_loc must be at least PROPERTY_VALUE_MAX bytes long
 *
 * real_blk_device must be at least PROPERTY_VALUE_MAX bytes long
 */
void fs_mgr_get_crypt_info(struct fstab* fstab, char* key_loc, char* real_blk_device, size_t size) {
    struct fstab_rec const* rec = fs_mgr_get_crypt_entry(fstab);
    if (key_loc) {
    if (key_loc) {
            strlcpy(key_loc, fstab->recs[i].key_loc, size);
        if (rec) {
            strlcpy(key_loc, rec->key_loc, size);
        } else {
            *key_loc = '\0';
        }
    }
    }
    if (real_blk_device) {
    if (real_blk_device) {
            strlcpy(real_blk_device, fstab->recs[i].blk_device, size);
        if (rec) {
            strlcpy(real_blk_device, rec->blk_device, size);
        } else {
            *real_blk_device = '\0';
        }
        }
        break;
    }
    }

    return 0;
}
}


bool fs_mgr_load_verity_state(int* mode) {
bool fs_mgr_load_verity_state(int* mode) {
+37 −28
Original line number Original line Diff line number Diff line
@@ -31,6 +31,7 @@


struct fs_mgr_flag_values {
struct fs_mgr_flag_values {
    char *key_loc;
    char *key_loc;
    char* key_dir;
    char *verity_loc;
    char *verity_loc;
    long long part_length;
    long long part_length;
    char *label;
    char *label;
@@ -76,6 +77,7 @@ static struct flag_list fs_mgr_flags[] = {
    {"forceencrypt=", MF_FORCECRYPT},
    {"forceencrypt=", MF_FORCECRYPT},
    {"fileencryption=", MF_FILEENCRYPTION},
    {"fileencryption=", MF_FILEENCRYPTION},
    {"forcefdeorfbe=", MF_FORCEFDEORFBE},
    {"forcefdeorfbe=", MF_FORCEFDEORFBE},
    {"keydirectory=", MF_KEYDIRECTORY},
    {"nonremovable", MF_NONREMOVABLE},
    {"nonremovable", MF_NONREMOVABLE},
    {"voldmanaged=", MF_VOLDMANAGED},
    {"voldmanaged=", MF_VOLDMANAGED},
    {"length=", MF_LENGTH},
    {"length=", MF_LENGTH},
@@ -266,6 +268,11 @@ static int parse_flags(char *flags, struct flag_list *fl,
                    } else {
                    } else {
                        flag_vals->file_names_mode = EM_AES_256_CTS;
                        flag_vals->file_names_mode = EM_AES_256_CTS;
                    }
                    }
                } else if ((fl[i].flag == MF_KEYDIRECTORY) && flag_vals) {
                    /* The metadata flag is followed by an = and the
                     * directory for the keys.  Get it and return it.
                     */
                    flag_vals->key_dir = strdup(strchr(p, '=') + 1);
                } else if ((fl[i].flag == MF_LENGTH) && flag_vals) {
                } else if ((fl[i].flag == MF_LENGTH) && flag_vals) {
                    /* The length flag is followed by an = and the
                    /* The length flag is followed by an = and the
                     * size of the partition.  Get it and return it.
                     * size of the partition.  Get it and return it.
@@ -557,6 +564,7 @@ static struct fstab *fs_mgr_read_fstab_file(FILE *fstab_file)
        fstab->recs[cnt].fs_mgr_flags = parse_flags(p, fs_mgr_flags,
        fstab->recs[cnt].fs_mgr_flags = parse_flags(p, fs_mgr_flags,
                                                    &flag_vals, NULL, 0);
                                                    &flag_vals, NULL, 0);
        fstab->recs[cnt].key_loc = flag_vals.key_loc;
        fstab->recs[cnt].key_loc = flag_vals.key_loc;
        fstab->recs[cnt].key_dir = flag_vals.key_dir;
        fstab->recs[cnt].verity_loc = flag_vals.verity_loc;
        fstab->recs[cnt].verity_loc = flag_vals.verity_loc;
        fstab->recs[cnt].length = flag_vals.part_length;
        fstab->recs[cnt].length = flag_vals.part_length;
        fstab->recs[cnt].label = flag_vals.label;
        fstab->recs[cnt].label = flag_vals.label;
@@ -716,6 +724,7 @@ void fs_mgr_free_fstab(struct fstab *fstab)
        free(fstab->recs[i].fs_type);
        free(fstab->recs[i].fs_type);
        free(fstab->recs[i].fs_options);
        free(fstab->recs[i].fs_options);
        free(fstab->recs[i].key_loc);
        free(fstab->recs[i].key_loc);
        free(fstab->recs[i].key_dir);
        free(fstab->recs[i].label);
        free(fstab->recs[i].label);
    }
    }


+1 −0
Original line number Original line Diff line number Diff line
@@ -107,6 +107,7 @@
#define MF_ERASEBLKSIZE     0x800000
#define MF_ERASEBLKSIZE     0x800000
#define MF_LOGICALBLKSIZE  0X1000000
#define MF_LOGICALBLKSIZE  0X1000000
#define MF_AVB             0X2000000
#define MF_AVB             0X2000000
#define MF_KEYDIRECTORY 0X4000000


#define DM_BUF_SIZE 4096
#define DM_BUF_SIZE 4096


+5 −2
Original line number Original line Diff line number Diff line
@@ -72,6 +72,7 @@ struct fstab_rec {
    char *fs_options;
    char *fs_options;
    int fs_mgr_flags;
    int fs_mgr_flags;
    char *key_loc;
    char *key_loc;
    char* key_dir;
    char *verity_loc;
    char *verity_loc;
    long long length;
    long long length;
    char *label;
    char *label;
@@ -95,6 +96,8 @@ struct fstab *fs_mgr_read_fstab_dt();
struct fstab *fs_mgr_read_fstab(const char *fstab_path);
struct fstab *fs_mgr_read_fstab(const char *fstab_path);
void fs_mgr_free_fstab(struct fstab *fstab);
void fs_mgr_free_fstab(struct fstab *fstab);


#define FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED 7
#define FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION 6
#define FS_MGR_MNTALL_DEV_FILE_ENCRYPTED 5
#define FS_MGR_MNTALL_DEV_FILE_ENCRYPTED 5
#define FS_MGR_MNTALL_DEV_NEEDS_RECOVERY 4
#define FS_MGR_MNTALL_DEV_NEEDS_RECOVERY 4
#define FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION 3
#define FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION 3
@@ -112,8 +115,8 @@ int fs_mgr_do_mount(struct fstab *fstab, const char *n_name, char *n_blk_device,
int fs_mgr_do_mount_one(struct fstab_rec *rec);
int fs_mgr_do_mount_one(struct fstab_rec *rec);
int fs_mgr_do_tmpfs_mount(const char *n_name);
int fs_mgr_do_tmpfs_mount(const char *n_name);
int fs_mgr_unmount_all(struct fstab *fstab);
int fs_mgr_unmount_all(struct fstab *fstab);
int fs_mgr_get_crypt_info(struct fstab *fstab, char *key_loc,
struct fstab_rec const* fs_mgr_get_crypt_entry(struct fstab const* fstab);
                          char *real_blk_device, int size);
void fs_mgr_get_crypt_info(struct fstab* fstab, char* key_loc, char* real_blk_device, size_t size);
bool fs_mgr_load_verity_state(int* mode);
bool fs_mgr_load_verity_state(int* mode);
bool fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback);
bool fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback);
int fs_mgr_add_entry(struct fstab *fstab,
int fs_mgr_add_entry(struct fstab *fstab,
+17 −0
Original line number Original line Diff line number Diff line
@@ -481,6 +481,23 @@ static int queue_fs_event(int code) {
        // Although encrypted, we have device key, so we do not need to
        // Although encrypted, we have device key, so we do not need to
        // do anything different from the nonencrypted case.
        // do anything different from the nonencrypted case.
        ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
        ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
    } else if (code == FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED) {
        if (e4crypt_install_keyring()) {
            return -1;
        }
        property_set("ro.crypto.state", "encrypted");
        property_set("ro.crypto.type", "file");

        // defaultcrypto detects file/block encryption. init flow is same for each.
        ActionManager::GetInstance().QueueEventTrigger("defaultcrypto");
    } else if (code == FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION) {
        if (e4crypt_install_keyring()) {
            return -1;
        }
        property_set("ro.crypto.type", "file");

        // encrypt detects file/block encryption. init flow is same for each.
        ActionManager::GetInstance().QueueEventTrigger("encrypt");
    } else if (code > 0) {
    } else if (code > 0) {
        PLOG(ERROR) << "fs_mgr_mount_all returned unexpected error " << code;
        PLOG(ERROR) << "fs_mgr_mount_all returned unexpected error " << code;
    }
    }