• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * linux/fs/ext4/crypto_policy.c
3  *
4  * Copyright (C) 2015, Google, Inc.
5  *
6  * This contains encryption policy functions for ext4
7  *
8  * Written by Michael Halcrow, 2015.
9  */
10 
11 #include <linux/random.h>
12 #include <linux/string.h>
13 #include <linux/types.h>
14 
15 #include "ext4.h"
16 #include "xattr.h"
17 
ext4_inode_has_encryption_context(struct inode * inode)18 static int ext4_inode_has_encryption_context(struct inode *inode)
19 {
20 	int res = ext4_xattr_get(inode, EXT4_XATTR_INDEX_ENCRYPTION,
21 				 EXT4_XATTR_NAME_ENCRYPTION_CONTEXT, NULL, 0);
22 	return (res > 0);
23 }
24 
25 /*
26  * check whether the policy is consistent with the encryption context
27  * for the inode
28  */
ext4_is_encryption_context_consistent_with_policy(struct inode * inode,const struct ext4_encryption_policy * policy)29 static int ext4_is_encryption_context_consistent_with_policy(
30 	struct inode *inode, const struct ext4_encryption_policy *policy)
31 {
32 	struct ext4_encryption_context ctx;
33 	int res = ext4_xattr_get(inode, EXT4_XATTR_INDEX_ENCRYPTION,
34 				 EXT4_XATTR_NAME_ENCRYPTION_CONTEXT, &ctx,
35 				 sizeof(ctx));
36 	if (res != sizeof(ctx))
37 		return 0;
38 	return (memcmp(ctx.master_key_descriptor, policy->master_key_descriptor,
39 			EXT4_KEY_DESCRIPTOR_SIZE) == 0 &&
40 		(ctx.flags ==
41 		 policy->flags) &&
42 		(ctx.contents_encryption_mode ==
43 		 policy->contents_encryption_mode) &&
44 		(ctx.filenames_encryption_mode ==
45 		 policy->filenames_encryption_mode));
46 }
47 
ext4_create_encryption_context_from_policy(struct inode * inode,const struct ext4_encryption_policy * policy)48 static int ext4_create_encryption_context_from_policy(
49 	struct inode *inode, const struct ext4_encryption_policy *policy)
50 {
51 	struct ext4_encryption_context ctx;
52 	int res = 0;
53 
54 	res = ext4_convert_inline_data(inode);
55 	if (res)
56 		return res;
57 
58 	ctx.format = EXT4_ENCRYPTION_CONTEXT_FORMAT_V1;
59 	memcpy(ctx.master_key_descriptor, policy->master_key_descriptor,
60 	       EXT4_KEY_DESCRIPTOR_SIZE);
61 	if (!ext4_valid_contents_enc_mode(policy->contents_encryption_mode)) {
62 		printk(KERN_WARNING
63 		       "%s: Invalid contents encryption mode %d\n", __func__,
64 			policy->contents_encryption_mode);
65 		return -EINVAL;
66 	}
67 	if (!ext4_valid_filenames_enc_mode(policy->filenames_encryption_mode)) {
68 		printk(KERN_WARNING
69 		       "%s: Invalid filenames encryption mode %d\n", __func__,
70 			policy->filenames_encryption_mode);
71 		return -EINVAL;
72 	}
73 	if (policy->flags & ~EXT4_POLICY_FLAGS_VALID)
74 		return -EINVAL;
75 	ctx.contents_encryption_mode = policy->contents_encryption_mode;
76 	ctx.filenames_encryption_mode = policy->filenames_encryption_mode;
77 	ctx.flags = policy->flags;
78 	BUILD_BUG_ON(sizeof(ctx.nonce) != EXT4_KEY_DERIVATION_NONCE_SIZE);
79 	get_random_bytes(ctx.nonce, EXT4_KEY_DERIVATION_NONCE_SIZE);
80 
81 	res = ext4_xattr_set(inode, EXT4_XATTR_INDEX_ENCRYPTION,
82 			     EXT4_XATTR_NAME_ENCRYPTION_CONTEXT, &ctx,
83 			     sizeof(ctx), 0);
84 	if (!res)
85 		ext4_set_inode_flag(inode, EXT4_INODE_ENCRYPT);
86 	return res;
87 }
88 
ext4_process_policy(const struct ext4_encryption_policy * policy,struct inode * inode)89 int ext4_process_policy(const struct ext4_encryption_policy *policy,
90 			struct inode *inode)
91 {
92 	if (policy->version != 0)
93 		return -EINVAL;
94 
95 	if (!ext4_inode_has_encryption_context(inode)) {
96 		if (!S_ISDIR(inode->i_mode))
97 			return -EINVAL;
98 		if (!ext4_empty_dir(inode))
99 			return -ENOTEMPTY;
100 		return ext4_create_encryption_context_from_policy(inode,
101 								  policy);
102 	}
103 
104 	if (ext4_is_encryption_context_consistent_with_policy(inode, policy))
105 		return 0;
106 
107 	printk(KERN_WARNING "%s: Policy inconsistent with encryption context\n",
108 	       __func__);
109 	return -EINVAL;
110 }
111 
ext4_get_policy(struct inode * inode,struct ext4_encryption_policy * policy)112 int ext4_get_policy(struct inode *inode, struct ext4_encryption_policy *policy)
113 {
114 	struct ext4_encryption_context ctx;
115 
116 	int res = ext4_xattr_get(inode, EXT4_XATTR_INDEX_ENCRYPTION,
117 				 EXT4_XATTR_NAME_ENCRYPTION_CONTEXT,
118 				 &ctx, sizeof(ctx));
119 	if (res != sizeof(ctx))
120 		return -ENOENT;
121 	if (ctx.format != EXT4_ENCRYPTION_CONTEXT_FORMAT_V1)
122 		return -EINVAL;
123 	policy->version = 0;
124 	policy->contents_encryption_mode = ctx.contents_encryption_mode;
125 	policy->filenames_encryption_mode = ctx.filenames_encryption_mode;
126 	policy->flags = ctx.flags;
127 	memcpy(&policy->master_key_descriptor, ctx.master_key_descriptor,
128 	       EXT4_KEY_DESCRIPTOR_SIZE);
129 	return 0;
130 }
131 
ext4_is_child_context_consistent_with_parent(struct inode * parent,struct inode * child)132 int ext4_is_child_context_consistent_with_parent(struct inode *parent,
133 						 struct inode *child)
134 {
135 	struct ext4_crypt_info *parent_ci, *child_ci;
136 	int res;
137 
138 	if ((parent == NULL) || (child == NULL)) {
139 		pr_err("parent %p child %p\n", parent, child);
140 		BUG_ON(1);
141 	}
142 	/* no restrictions if the parent directory is not encrypted */
143 	if (!ext4_encrypted_inode(parent))
144 		return 1;
145 	/* if the child directory is not encrypted, this is always a problem */
146 	if (!ext4_encrypted_inode(child))
147 		return 0;
148 	res = ext4_get_encryption_info(parent);
149 	if (res)
150 		return 0;
151 	res = ext4_get_encryption_info(child);
152 	if (res)
153 		return 0;
154 	parent_ci = EXT4_I(parent)->i_crypt_info;
155 	child_ci = EXT4_I(child)->i_crypt_info;
156 	if (!parent_ci && !child_ci)
157 		return 1;
158 	if (!parent_ci || !child_ci)
159 		return 0;
160 
161 	return (memcmp(parent_ci->ci_master_key,
162 		       child_ci->ci_master_key,
163 		       EXT4_KEY_DESCRIPTOR_SIZE) == 0 &&
164 		(parent_ci->ci_data_mode == child_ci->ci_data_mode) &&
165 		(parent_ci->ci_filename_mode == child_ci->ci_filename_mode) &&
166 		(parent_ci->ci_flags == child_ci->ci_flags));
167 }
168 
169 /**
170  * ext4_inherit_context() - Sets a child context from its parent
171  * @parent: Parent inode from which the context is inherited.
172  * @child:  Child inode that inherits the context from @parent.
173  *
174  * Return: Zero on success, non-zero otherwise
175  */
ext4_inherit_context(struct inode * parent,struct inode * child)176 int ext4_inherit_context(struct inode *parent, struct inode *child)
177 {
178 	struct ext4_encryption_context ctx;
179 	struct ext4_crypt_info *ci;
180 	int res;
181 
182 	res = ext4_get_encryption_info(parent);
183 	if (res < 0)
184 		return res;
185 	ci = EXT4_I(parent)->i_crypt_info;
186 	if (ci == NULL)
187 		return -ENOKEY;
188 
189 	ctx.format = EXT4_ENCRYPTION_CONTEXT_FORMAT_V1;
190 	if (DUMMY_ENCRYPTION_ENABLED(EXT4_SB(parent->i_sb))) {
191 		ctx.contents_encryption_mode = EXT4_ENCRYPTION_MODE_AES_256_XTS;
192 		ctx.filenames_encryption_mode =
193 			EXT4_ENCRYPTION_MODE_AES_256_CTS;
194 		ctx.flags = 0;
195 		memset(ctx.master_key_descriptor, 0x42,
196 		       EXT4_KEY_DESCRIPTOR_SIZE);
197 		res = 0;
198 	} else {
199 		ctx.contents_encryption_mode = ci->ci_data_mode;
200 		ctx.filenames_encryption_mode = ci->ci_filename_mode;
201 		ctx.flags = ci->ci_flags;
202 		memcpy(ctx.master_key_descriptor, ci->ci_master_key,
203 		       EXT4_KEY_DESCRIPTOR_SIZE);
204 	}
205 	get_random_bytes(ctx.nonce, EXT4_KEY_DERIVATION_NONCE_SIZE);
206 	res = ext4_xattr_set(child, EXT4_XATTR_INDEX_ENCRYPTION,
207 			     EXT4_XATTR_NAME_ENCRYPTION_CONTEXT, &ctx,
208 			     sizeof(ctx), 0);
209 	if (!res) {
210 		ext4_set_inode_flag(child, EXT4_INODE_ENCRYPT);
211 		ext4_clear_inode_state(child, EXT4_STATE_MAY_INLINE_DATA);
212 		res = ext4_get_encryption_info(child);
213 	}
214 	return res;
215 }
216