2 * Copyright (c) 2015 Google, Inc.
5 #define TAG "ext4_utils"
12 #include <sys/xattr.h>
13 #include <sys/syscall.h>
16 #include <cutils/klog.h>
18 #include "ext4_crypt.h"
20 /* keyring keyctl commands */
21 #define KEYCTL_SETPERM 5 /* set permissions for a key in a keyring */
22 #define KEYCTL_UNLINK 9 /* unlink a key from a keyring */
23 #define KEYCTL_SEARCH 10 /* search for a key in a keyring */
25 #define XATTR_NAME_ENCRYPTION_POLICY "encryption.policy"
26 #define EXT4_KEYREF_DELIMITER ((char)'.')
28 /* Validate that all path items are available and accessible. */
29 static int is_path_valid(const char *path)
31 if (access(path, W_OK)) {
32 KLOG_ERROR(TAG, "Can't access %s: %s\n",strerror(errno), path);
39 /* Checks whether the policy provided is valid */
40 static int is_keyref_valid(const char *keyref)
43 size_t key_location_len = 0;
45 /* Key ref must have a key and location delimiter character. */
46 period = strchr(keyref, EXT4_KEYREF_DELIMITER);
51 /* period must be >= keyref. */
52 key_location_len = period - keyref;
54 if (strncmp(keyref, "@t", key_location_len) == 0 ||
55 strncmp(keyref, "@p", key_location_len) == 0 ||
56 strncmp(keyref, "@s", key_location_len) == 0 ||
57 strncmp(keyref, "@u", key_location_len) == 0 ||
58 strncmp(keyref, "@g", key_location_len) == 0 ||
59 strncmp(keyref, "@us", key_location_len) == 0)
65 static int is_dir_empty(const char *dirname)
71 dir = opendir(dirname);
72 while ((d = readdir(dir)) != NULL) {
73 if (strcmp(d->d_name, "lost+found") == 0) {
74 // Skip lost+found directory
83 int do_policy_set(const char *directory, const char *policy)
88 if (!is_keyref_valid(policy)) {
89 KLOG_ERROR(TAG, "Policy has invalid format.\n");
93 if (!is_path_valid(directory)) {
98 if (!S_ISDIR(st.st_mode)) {
99 KLOG_ERROR(TAG, "Can only set policy on a directory (%s)\n", directory);
103 if (!is_dir_empty(directory)) {
104 KLOG_ERROR(TAG, "Can only set policy on an empty directory (%s)\n", directory);
108 ret = lsetxattr(directory, XATTR_NAME_ENCRYPTION_POLICY, policy,
112 KLOG_ERROR(TAG, "Failed to set encryption policy for %s: %s\n",
113 directory, strerror(errno));
117 KLOG_INFO(TAG, "Encryption policy for %s is set to %s\n", directory, policy);
121 static long keyctl(int cmd, ...)
124 unsigned long arg2, arg3, arg4, arg5;
127 arg2 = va_arg(va, unsigned long);
128 arg3 = va_arg(va, unsigned long);
129 arg4 = va_arg(va, unsigned long);
130 arg5 = va_arg(va, unsigned long);
132 return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5);
135 key_serial_t add_key(const char *type,
136 const char *description,
141 return syscall(__NR_add_key, type, description, payload, plen, ringid);
144 long keyctl_setperm(key_serial_t id, int permissions)
146 return keyctl(KEYCTL_SETPERM, id, permissions);