summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Lawrence <paullawrence@google.com>2015-04-10 07:47:30 -0700
committerPaul Lawrence <paullawrence@google.com>2015-05-29 17:50:27 +0000
commitdb1d49c70eec489cf3d60a4ec70a8e7c0f3f2b76 (patch)
treee5709d939a48f48b2a553caac903931e42df52e0
parentbc2eb8c3fd621605ff1ccaed04a71e6685acc974 (diff)
downloadextras-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.cpp74
-rw-r--r--ext4_utils/ext4_crypt_init_extensions.cpp7
-rw-r--r--ext4_utils/ext4_crypt_init_extensions.h2
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