From e8299d81a18d16b006019f37ec9d84921d5ff845 Mon Sep 17 00:00:00 2001 From: Paul Lawrence Date: Thu, 5 May 2016 11:01:42 -0700 Subject: [PATCH] Add fileencrypted=software/ice to fstab options Bug: 28616054 Change-Id: I34257870d388993d168f6541ef51ee2ce1067a7e --- ext4_utils/Android.mk | 1 + ext4_utils/ext4_crypt.cpp | 171 ------------------------------ ext4_utils/ext4_crypt.h | 6 +- ext4_utils/ext4_crypt_init_extensions.cpp | 29 +++-- 4 files changed, 16 insertions(+), 191 deletions(-) diff --git a/ext4_utils/Android.mk b/ext4_utils/Android.mk index a8362b22..e5431dd8 100644 --- a/ext4_utils/Android.mk +++ b/ext4_utils/Android.mk @@ -87,6 +87,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES := $(libext4_utils_src_files) \ ext4_crypt_init_extensions.cpp LOCAL_MODULE := libext4_utils_static +LOCAL_C_INCLUDES += system/core/init # Various instances of dereferencing a type-punned pointer in extent.c LOCAL_CFLAGS += -fno-strict-aliasing LOCAL_STATIC_LIBRARIES := \ diff --git a/ext4_utils/ext4_crypt.cpp b/ext4_utils/ext4_crypt.cpp index be77b791..72ce104d 100644 --- a/ext4_utils/ext4_crypt.cpp +++ b/ext4_utils/ext4_crypt.cpp @@ -16,182 +16,11 @@ #include "ext4_crypt.h" -#include -#include #include -#include - -#include -#include -#include -#include -#include - -#include #include -#define XATTR_NAME_ENCRYPTION_POLICY "encryption.policy" -#define EXT4_KEYREF_DELIMITER ((char)'.') - -// ext4enc:TODO Include structure from somewhere sensible -// MUST be in sync with ext4_crypto.c in kernel -#define EXT4_KEY_DESCRIPTOR_SIZE 8 -#define EXT4_KEY_DESCRIPTOR_SIZE_HEX 17 - -struct ext4_encryption_policy { - char version; - char contents_encryption_mode; - char filenames_encryption_mode; - char flags; - char master_key_descriptor[EXT4_KEY_DESCRIPTOR_SIZE]; -} __attribute__((__packed__)); - -#define EXT4_ENCRYPTION_MODE_AES_256_XTS 1 -#define EXT4_ENCRYPTION_MODE_AES_256_CTS 4 - -// ext4enc:TODO Get value from somewhere sensible -#define EXT4_IOC_SET_ENCRYPTION_POLICY _IOR('f', 19, struct ext4_encryption_policy) -#define EXT4_IOC_GET_ENCRYPTION_POLICY _IOW('f', 21, struct ext4_encryption_policy) - -#define HEX_LOOKUP "0123456789abcdef" - bool e4crypt_is_native() { char value[PROPERTY_VALUE_MAX]; property_get("ro.crypto.type", value, "none"); return !strcmp(value, "file"); } - -static void policy_to_hex(const char* policy, char* hex) { - for (size_t i = 0, j = 0; i < EXT4_KEY_DESCRIPTOR_SIZE; i++) { - hex[j++] = HEX_LOOKUP[(policy[i] & 0xF0) >> 4]; - hex[j++] = HEX_LOOKUP[policy[i] & 0x0F]; - } - hex[EXT4_KEY_DESCRIPTOR_SIZE_HEX - 1] = '\0'; -} - -static bool is_dir_empty(const char *dirname, bool *is_empty) -{ - int n = 0; - auto dirp = std::unique_ptr(opendir(dirname), closedir); - if (!dirp) { - PLOG(ERROR) << "Unable to read directory: " << dirname; - return false; - } - for (;;) { - errno = 0; - auto entry = readdir(dirp.get()); - if (!entry) { - if (errno) { - PLOG(ERROR) << "Unable to read directory: " << dirname; - return false; - } - break; - } - if (strcmp(entry->d_name, "lost+found") != 0) { // Skip lost+found - ++n; - if (n > 2) { - *is_empty = false; - return true; - } - } - } - *is_empty = true; - return true; -} - -static bool e4crypt_policy_set(const char *directory, const char *policy, size_t policy_length) { - if (policy_length != EXT4_KEY_DESCRIPTOR_SIZE) { - LOG(ERROR) << "Policy wrong length: " << policy_length; - return false; - } - int fd = open(directory, O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); - if (fd == -1) { - PLOG(ERROR) << "Failed to open directory " << directory; - return false; - } - - ext4_encryption_policy eep; - eep.version = 0; - eep.contents_encryption_mode = EXT4_ENCRYPTION_MODE_AES_256_XTS; - eep.filenames_encryption_mode = EXT4_ENCRYPTION_MODE_AES_256_CTS; - eep.flags = 0; - memcpy(eep.master_key_descriptor, policy, EXT4_KEY_DESCRIPTOR_SIZE); - if (ioctl(fd, EXT4_IOC_SET_ENCRYPTION_POLICY, &eep)) { - PLOG(ERROR) << "Failed to set encryption policy for " << directory; - close(fd); - return false; - } - close(fd); - - char policy_hex[EXT4_KEY_DESCRIPTOR_SIZE_HEX]; - policy_to_hex(policy, policy_hex); - LOG(INFO) << "Policy for " << directory << " set to " << policy_hex; - return true; -} - -static bool e4crypt_policy_get(const char *directory, char *policy, size_t policy_length) { - if (policy_length != EXT4_KEY_DESCRIPTOR_SIZE) { - LOG(ERROR) << "Policy wrong length: " << policy_length; - return false; - } - - int fd = open(directory, O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); - if (fd == -1) { - PLOG(ERROR) << "Failed to open directory " << directory; - return false; - } - - ext4_encryption_policy eep; - memset(&eep, 0, sizeof(ext4_encryption_policy)); - if (ioctl(fd, EXT4_IOC_GET_ENCRYPTION_POLICY, &eep) != 0) { - PLOG(ERROR) << "Failed to get encryption policy for " << directory; - close(fd); - return -1; - } - close(fd); - - if ((eep.version != 0) - || (eep.contents_encryption_mode != EXT4_ENCRYPTION_MODE_AES_256_XTS) - || (eep.filenames_encryption_mode != EXT4_ENCRYPTION_MODE_AES_256_CTS) - || (eep.flags != 0)) { - LOG(ERROR) << "Failed to find matching encryption policy for " << directory; - return false; - } - memcpy(policy, eep.master_key_descriptor, EXT4_KEY_DESCRIPTOR_SIZE); - - return true; -} - -static bool e4crypt_policy_check(const char *directory, const char *policy, size_t policy_length) { - if (policy_length != EXT4_KEY_DESCRIPTOR_SIZE) { - LOG(ERROR) << "Policy wrong length: " << policy_length; - return false; - } - char existing_policy[EXT4_KEY_DESCRIPTOR_SIZE]; - if (!e4crypt_policy_get(directory, existing_policy, EXT4_KEY_DESCRIPTOR_SIZE)) return false; - char existing_policy_hex[EXT4_KEY_DESCRIPTOR_SIZE_HEX]; - - policy_to_hex(existing_policy, existing_policy_hex); - - if (memcmp(policy, existing_policy, EXT4_KEY_DESCRIPTOR_SIZE) != 0) { - char policy_hex[EXT4_KEY_DESCRIPTOR_SIZE_HEX]; - policy_to_hex(policy, policy_hex); - LOG(ERROR) << "Found policy " << existing_policy_hex << " at " << directory - << " which doesn't match expected value " << policy_hex; - return false; - } - LOG(INFO) << "Found policy " << existing_policy_hex << " at " << directory - << " which matches expected value"; - return true; -} - -int e4crypt_policy_ensure(const char *directory, const char *policy, size_t policy_length) { - bool is_empty; - if (!is_dir_empty(directory, &is_empty)) return -1; - if (is_empty) { - if (!e4crypt_policy_set(directory, policy, policy_length)) return -1; - } else { - if (!e4crypt_policy_check(directory, policy, policy_length)) return -1; - } - return 0; -} diff --git a/ext4_utils/ext4_crypt.h b/ext4_utils/ext4_crypt.h index ddc09a71..8a83da19 100644 --- a/ext4_utils/ext4_crypt.h +++ b/ext4_utils/ext4_crypt.h @@ -20,11 +20,9 @@ __BEGIN_DECLS -bool e4crypt_is_native(); - -int e4crypt_policy_ensure(const char *directory, const char* policy, size_t policy_length); - static const char* e4crypt_unencrypted_folder = "/unencrypted"; static const char* e4crypt_key_ref = "/unencrypted/ref"; +bool e4crypt_is_native(); + __END_DECLS diff --git a/ext4_utils/ext4_crypt_init_extensions.cpp b/ext4_utils/ext4_crypt_init_extensions.cpp index c6baea74..0298b116 100644 --- a/ext4_utils/ext4_crypt_init_extensions.cpp +++ b/ext4_utils/ext4_crypt_init_extensions.cpp @@ -24,18 +24,11 @@ #include #include -#include -#include -#include -#include -#include - #include #include -#include -#include #include +#include #include "key_control.h" @@ -117,9 +110,6 @@ int e4crypt_set_directory_policy(const char* dir) return 0; } - // Special case various directories that must not be encrypted, - // often because their subdirectories must be encrypted. - // This isn't a nice way to do this, see b/26641735 std::vector directories_to_exclude = { "lost+found", "system_ce", "system_de", @@ -141,12 +131,19 @@ int e4crypt_set_directory_policy(const char* dir) KLOG_ERROR(TAG, "Unable to read system policy to set on %s\n", dir); return -1; } + + std::string hex_policy = bytes_to_hex((const uint8_t*)policy.c_str(), + policy.length()); + + const char* argv[] = { "/system/bin/vdc", "--wait", "cryptfs", + "ensure_policy", dir, hex_policy.c_str()}; + KLOG_INFO(TAG, "Setting policy on %s\n", dir); - int result = e4crypt_policy_ensure(dir, policy.c_str(), policy.size()); - if (result) { - KLOG_ERROR(TAG, "Setting %02x%02x%02x%02x policy on %s failed!\n", - policy[0], policy[1], policy[2], policy[3], dir); - return -1; + int rc = android_fork_execvp(6, (char**) argv, NULL, false, true); + if (rc) { + KLOG_ERROR(TAG, "Setting %s policy on %s failed!\n", + hex_policy.c_str(), dir); + return rc; } return 0; -- 2.11.0