From 806d10be2336f32cdca16c2540cbf3d548f2fec7 Mon Sep 17 00:00:00 2001 From: Paul Lawrence Date: Tue, 28 Apr 2015 22:07:10 +0000 Subject: [PATCH] Securely encrypt the master key Move all key management into vold Reuse vold's existing key management through the crypto footer to manage the device wide keys. Use ro.crypto.type flag to determine crypto type, which prevents any issues when running in block encrypted mode, as well as speeding up boot in block or no encryption. This is one of four changes to enable this functionality: https://android-review.googlesource.com/#/c/148586/ https://android-review.googlesource.com/#/c/148604/ https://android-review.googlesource.com/#/c/148606/ https://android-review.googlesource.com/#/c/148607/ Bug: 18151196 Change-Id: I6a8a18f43ae837e330e2785bd26c2c306ae1816b --- fs_mgr/fs_mgr.c | 12 +--------- init/builtins.cpp | 60 +++++++++++++++++++++-------------------------- rootdir/init.rc | 8 ++++--- 3 files changed, 33 insertions(+), 47 deletions(-) diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c index 47ea9aa50..d5e94ac7e 100644 --- a/fs_mgr/fs_mgr.c +++ b/fs_mgr/fs_mgr.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include @@ -483,16 +483,6 @@ static int handle_encryptable(struct fstab *fstab, const struct fstab_rec* rec) return FS_MGR_MNTALL_FAIL; } - // Link it to the normal place so ext4_crypt functions work normally - strlcat(tmp_mnt, "/unencrypted", sizeof(tmp_mnt)); - char link_path[PATH_MAX]; - strlcpy(link_path, rec->mount_point, sizeof(link_path)); - strlcat(link_path, "/unencrypted", sizeof(link_path)); - if (symlink(tmp_mnt, link_path)) { - ERROR("Error creating symlink to unencrypted directory\n"); - return FS_MGR_MNTALL_FAIL; - } - return FS_MGR_MNTALL_DEV_NON_DEFAULT_FILE_ENCRYPTED; } diff --git a/init/builtins.cpp b/init/builtins.cpp index 4567b04b4..d7723838e 100644 --- a/init/builtins.cpp +++ b/init/builtins.cpp @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include @@ -385,18 +385,6 @@ static int wipe_data_via_recovery() while (1) { pause(); } // never reached } -/* - * Callback to make a directory from the ext4 code - */ -static int do_mount_alls_make_dir(const char* dir) -{ - if (make_dir(dir, 0700) && errno != EEXIST) { - return -1; - } - - return 0; -} - /* * This function might request a reboot, in which case it will * not return. @@ -452,6 +440,7 @@ int do_mount_all(int nargs, char **args) property_set("vold.decrypt", "trigger_encryption"); } else if (ret == FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED) { property_set("ro.crypto.state", "encrypted"); + property_set("ro.crypto.type", "block"); property_set("vold.decrypt", "trigger_default_encryption"); } else if (ret == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) { property_set("ro.crypto.state", "unencrypted"); @@ -465,26 +454,11 @@ int do_mount_all(int nargs, char **args) ret = wipe_data_via_recovery(); /* If reboot worked, there is no return. */ } else if (ret == FS_MGR_MNTALL_DEV_DEFAULT_FILE_ENCRYPTED) { - // We have to create the key files here. Only init can call make_dir, - // and we can't do it from fs_mgr as then fs_mgr would depend on - // make_dir creating a circular dependency. - fstab = fs_mgr_read_fstab(args[1]); - for (int i = 0; i < fstab->num_entries; ++i) { - if (fs_mgr_is_file_encrypted(&fstab->recs[i])) { - if (e4crypt_create_device_key(fstab->recs[i].mount_point, - do_mount_alls_make_dir)) { - ERROR("Could not create device key on %s" - " - continue unencrypted\n", - fstab->recs[i].mount_point); - } - } - } - fs_mgr_free_fstab(fstab); - if (e4crypt_install_keyring()) { return -1; } property_set("ro.crypto.state", "encrypted"); + property_set("ro.crypto.type", "file"); // Although encrypted, we have device key, so we do not need to // do anything different from the nonencrypted case. @@ -494,6 +468,7 @@ int do_mount_all(int nargs, char **args) return -1; } property_set("ro.crypto.state", "encrypted"); + property_set("ro.crypto.type", "file"); property_set("vold.decrypt", "trigger_restart_min_framework"); } else if (ret > 0) { ERROR("fs_mgr_mount_all returned unexpected error %d\n", ret); @@ -840,11 +815,30 @@ int do_wait(int nargs, char **args) return -1; } -int do_installkey(int nargs, char **args) +/* + * Callback to make a directory from the ext4 code + */ +static int do_installkeys_ensure_dir_exists(const char* dir) { - if (nargs == 2) { - return e4crypt_install_key(args[1]); + if (make_dir(dir, 0700) && errno != EEXIST) { + return -1; } - return -1; + return 0; +} + +int do_installkey(int nargs, char **args) +{ + if (nargs != 2) { + return -1; + } + + char prop_value[PROP_VALUE_MAX] = {0}; + property_get("ro.crypto.type", prop_value); + if (strcmp(prop_value, "file")) { + return 0; + } + + return e4crypt_create_device_key(args[1], + do_installkeys_ensure_dir_exists); } diff --git a/rootdir/init.rc b/rootdir/init.rc index c00c590aa..3709b82db 100644 --- a/rootdir/init.rc +++ b/rootdir/init.rc @@ -220,14 +220,17 @@ on post-fs mkdir /cache/lost+found 0770 root root on post-fs-data - installkey /data - # We chown/chmod /data again so because mount is run as root + defaults chown system system /data chmod 0771 /data # We restorecon /data in case the userdata partition has been reset. restorecon /data + # Make sure we have the device encryption key + start logd + start vold + installkey /data + # Start bootcharting as soon as possible after the data partition is # mounted to collect more data. mkdir /data/bootchart 0755 shell shell @@ -449,7 +452,6 @@ on property:vold.decrypt=trigger_restart_min_framework class_start main on property:vold.decrypt=trigger_restart_framework - installkey /data class_start main class_start late_start