diff options
author | Paul Lawrence <paullawrence@google.com> | 2015-04-10 07:47:30 -0700 |
---|---|---|
committer | Paul Lawrence <paullawrence@google.com> | 2015-05-29 17:50:27 +0000 |
commit | db1d49c70eec489cf3d60a4ec70a8e7c0f3f2b76 (patch) | |
tree | e5709d939a48f48b2a553caac903931e42df52e0 | |
parent | bc2eb8c3fd621605ff1ccaed04a71e6685acc974 (diff) | |
download | extras-db1d49c70eec489cf3d60a4ec70a8e7c0f3f2b76.tar.gz |
DO NOT MERGE New ext4enc kernel switching from xattrs to ioctl
(cherry-picked from commit 9f53fb4abca1ee3af7b537c95445161db4b81f86)
This is one of three changes to enable this functionality:
https://android-review.googlesource.com/#/c/146259/
https://android-review.googlesource.com/#/c/146264/
https://android-review.googlesource.com/#/c/146265/
Bug: 18151196
Change-Id: I05b96f49b8848e82484a500e4536bdb4d2cdd635
-rw-r--r-- | ext4_utils/ext4_crypt.cpp | 74 | ||||
-rw-r--r-- | ext4_utils/ext4_crypt_init_extensions.cpp | 7 | ||||
-rw-r--r-- | ext4_utils/ext4_crypt_init_extensions.h | 2 |
3 files changed, 41 insertions, 42 deletions
diff --git a/ext4_utils/ext4_crypt.cpp b/ext4_utils/ext4_crypt.cpp index 7d3dc91e..69358ba8 100644 --- a/ext4_utils/ext4_crypt.cpp +++ b/ext4_utils/ext4_crypt.cpp @@ -11,9 +11,11 @@ #include <string.h> #include <unistd.h> -#include <sys/xattr.h> +#include <fcntl.h> +#include <asm/ioctl.h> #include <sys/syscall.h> #include <sys/stat.h> +#include <sys/types.h> #include <cutils/klog.h> @@ -24,12 +26,20 @@ // ext4enc:TODO Include structure from somewhere sensible // MUST be in sync with ext4_crypto.c in kernel -#define EXT4_MAX_KEY_SIZE 76 -struct ext4_encryption_key { - uint32_t mode; - char raw[EXT4_MAX_KEY_SIZE]; - uint32_t size; -}; +#define EXT4_KEY_DESCRIPTOR_SIZE 8 +struct ext4_encryption_policy { + char version; + char contents_encryption_mode; + char filenames_encryption_mode; + 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) /* Validate that all path items are available and accessible. */ static int is_path_valid(const char *path) @@ -42,32 +52,6 @@ static int is_path_valid(const char *path) return 1; } -/* Checks whether the policy provided is valid */ -static int is_keyref_valid(const char *keyref) -{ - char *period = 0; - size_t key_location_len = 0; - - /* Key ref must have a key and location delimiter character. */ - period = strchr(keyref, EXT4_KEYREF_DELIMITER); - if (!period) { - return 0; - } - - /* period must be >= keyref. */ - key_location_len = period - keyref; - - if (strncmp(keyref, "@t", key_location_len) == 0 || - strncmp(keyref, "@p", key_location_len) == 0 || - strncmp(keyref, "@s", key_location_len) == 0 || - strncmp(keyref, "@u", key_location_len) == 0 || - strncmp(keyref, "@g", key_location_len) == 0 || - strncmp(keyref, "@us", key_location_len) == 0) - return 1; - - return 0; -} - static int is_dir_empty(const char *dirname) { int n = 0; @@ -86,13 +70,13 @@ static int is_dir_empty(const char *dirname) return n <= 2; } -int do_policy_set(const char *directory, const char *policy) +int do_policy_set(const char *directory, const char *policy, int policy_length) { struct stat st; ssize_t ret; - if (!is_keyref_valid(policy)) { - KLOG_ERROR(TAG, "Policy has invalid format.\n"); + if (policy_length != EXT4_KEY_DESCRIPTOR_SIZE) { + KLOG_ERROR("Policy wrong length\n"); return -EINVAL; } @@ -112,12 +96,24 @@ int do_policy_set(const char *directory, const char *policy) return -EINVAL; } - ret = lsetxattr(directory, XATTR_NAME_ENCRYPTION_POLICY, policy, - strlen(policy), 0); + int fd = open(directory, O_DIRECTORY); + if (fd == -1) { + KLOG_ERROR(TAG, "Failed to open directory (%s)\n", directory); + return -EINVAL; + } + + 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; + memcpy(eep.master_key_descriptor, policy, EXT4_KEY_DESCRIPTOR_SIZE); + ret = ioctl(fd, EXT4_IOC_SET_ENCRYPTION_POLICY, &eep); + auto preserve_errno = errno; + close(fd); if (ret) { KLOG_ERROR(TAG, "Failed to set encryption policy for %s: %s\n", - directory, strerror(errno)); + directory, strerror(preserve_errno)); return -EINVAL; } diff --git a/ext4_utils/ext4_crypt_init_extensions.cpp b/ext4_utils/ext4_crypt_init_extensions.cpp index 3b7df6dd..cd0a02ac 100644 --- a/ext4_utils/ext4_crypt_init_extensions.cpp +++ b/ext4_utils/ext4_crypt_init_extensions.cpp @@ -101,7 +101,6 @@ int e4crypt_create_device_key(const char* dir, } // Make sure folder exists. Use make_dir to set selinux permissions. - KLOG_INFO(TAG, "Creating test device key\n"); if (ensure_dir_exists(UnencryptedProperties::GetPath(dir).c_str())) { KLOG_ERROR(TAG, "Failed to create %s with error %s\n", UnencryptedProperties::GetPath(dir).c_str(), @@ -152,8 +151,12 @@ int e4crypt_set_directory_policy(const char* dir) UnencryptedProperties props("/data"); std::string policy = props.Get<std::string>(properties::ref); + if (policy.empty()) { + return 0; + } + KLOG_INFO(TAG, "Setting policy %s\n", policy.c_str()); - int result = do_policy_set(dir, policy.c_str()); + int result = do_policy_set(dir, policy.c_str(), policy.size()); if (result) { KLOG_ERROR(TAG, "Setting %s policy on %s failed!\n", policy.c_str(), dir); diff --git a/ext4_utils/ext4_crypt_init_extensions.h b/ext4_utils/ext4_crypt_init_extensions.h index 17f5b2e0..79311246 100644 --- a/ext4_utils/ext4_crypt_init_extensions.h +++ b/ext4_utils/ext4_crypt_init_extensions.h @@ -10,6 +10,6 @@ int e4crypt_create_device_key(const char* path, int ensure_dir_exists(const char* dir)); int e4crypt_set_directory_policy(const char* path); bool e4crypt_non_default_key(const char* path); -int do_policy_set(const char *directory, const char *policy); +int do_policy_set(const char *directory, const char *policy, int policy_length); __END_DECLS |