1 ext4 crypto: separate kernel and userspace structure for the key
3 Use struct ext4_encryption_key only for the master key passed via the
6 For internal kernel space users, we now use struct ext4_crypt_info.
7 This will allow us to put information from the policy structure so we
8 can cache it and avoid needing to constantly looking up the extended
9 attribute. We will do this in a spearate patch. This patch is mostly
10 mechnical to make it easier for patch review.
12 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
14 fs/ext4/crypto.c | 18 +++++++++---------
15 fs/ext4/crypto_fname.c | 33 ++++++++++-----------------------
16 fs/ext4/crypto_key.c | 21 +++++++++++----------
18 fs/ext4/ext4_crypto.h | 15 +++++++++++----
19 fs/ext4/super.c | 2 +-
20 6 files changed, 43 insertions(+), 48 deletions(-)
22 diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c
23 index 8ff1527..918200e 100644
24 --- a/fs/ext4/crypto.c
25 +++ b/fs/ext4/crypto.c
26 @@ -118,7 +118,7 @@ struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode)
27 struct ext4_crypto_ctx *ctx = NULL;
30 - struct ext4_encryption_key *key = &EXT4_I(inode)->i_encryption_key;
31 + struct ext4_crypt_info *ci = &EXT4_I(inode)->i_crypt_info;
33 if (!ext4_read_workqueue)
35 @@ -152,14 +152,14 @@ struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode)
37 /* Allocate a new Crypto API context if we don't already have
38 * one or if it isn't the right mode. */
39 - BUG_ON(key->mode == EXT4_ENCRYPTION_MODE_INVALID);
40 - if (ctx->tfm && (ctx->mode != key->mode)) {
41 + BUG_ON(ci->ci_mode == EXT4_ENCRYPTION_MODE_INVALID);
42 + if (ctx->tfm && (ctx->mode != ci->ci_mode)) {
43 crypto_free_tfm(ctx->tfm);
45 ctx->mode = EXT4_ENCRYPTION_MODE_INVALID;
48 - switch (key->mode) {
49 + switch (ci->ci_mode) {
50 case EXT4_ENCRYPTION_MODE_AES_256_XTS:
51 ctx->tfm = crypto_ablkcipher_tfm(
52 crypto_alloc_ablkcipher("xts(aes)", 0, 0));
53 @@ -177,9 +177,9 @@ struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode)
57 - ctx->mode = key->mode;
58 + ctx->mode = ci->ci_mode;
60 - BUG_ON(key->size != ext4_encryption_key_size(key->mode));
61 + BUG_ON(ci->ci_size != ext4_encryption_key_size(ci->ci_mode));
63 /* There shouldn't be a bounce page attached to the crypto
64 * context at this point. */
65 @@ -322,7 +322,7 @@ static int ext4_page_crypto(struct ext4_crypto_ctx *ctx,
69 - BUG_ON(ctx->mode != ei->i_encryption_key.mode);
70 + BUG_ON(ctx->mode != ei->i_crypt_info.ci_mode);
72 if (ctx->mode != EXT4_ENCRYPTION_MODE_AES_256_XTS) {
73 printk_ratelimited(KERN_ERR
74 @@ -334,8 +334,8 @@ static int ext4_page_crypto(struct ext4_crypto_ctx *ctx,
75 crypto_ablkcipher_clear_flags(atfm, ~0);
76 crypto_tfm_set_flags(ctx->tfm, CRYPTO_TFM_REQ_WEAK_KEY);
78 - res = crypto_ablkcipher_setkey(atfm, ei->i_encryption_key.raw,
79 - ei->i_encryption_key.size);
80 + res = crypto_ablkcipher_setkey(atfm, ei->i_crypt_info.ci_raw,
81 + ei->i_crypt_info.ci_size);
83 printk_ratelimited(KERN_ERR
84 "%s: crypto_ablkcipher_setkey() failed\n",
85 diff --git a/fs/ext4/crypto_fname.c b/fs/ext4/crypto_fname.c
86 index 23d7f1d..d9f08dd 100644
87 --- a/fs/ext4/crypto_fname.c
88 +++ b/fs/ext4/crypto_fname.c
89 @@ -278,33 +278,24 @@ void ext4_put_fname_crypto_ctx(struct ext4_fname_crypto_ctx **ctx)
93 - * ext4_search_fname_crypto_ctx() -
95 -static struct ext4_fname_crypto_ctx *ext4_search_fname_crypto_ctx(
96 - const struct ext4_encryption_key *key)
102 * ext4_alloc_fname_crypto_ctx() -
104 struct ext4_fname_crypto_ctx *ext4_alloc_fname_crypto_ctx(
105 - const struct ext4_encryption_key *key)
106 + const struct ext4_crypt_info *ci)
108 struct ext4_fname_crypto_ctx *ctx;
110 ctx = kmalloc(sizeof(struct ext4_fname_crypto_ctx), GFP_NOFS);
112 return ERR_PTR(-ENOMEM);
113 - if (key->mode == EXT4_ENCRYPTION_MODE_INVALID) {
114 + if (ci->ci_mode == EXT4_ENCRYPTION_MODE_INVALID) {
115 /* This will automatically set key mode to invalid
116 * As enum for ENCRYPTION_MODE_INVALID is zero */
117 - memset(&ctx->key, 0, sizeof(ctx->key));
118 + memset(&ctx->ci, 0, sizeof(ctx->ci));
120 - memcpy(&ctx->key, key, sizeof(struct ext4_encryption_key));
121 + memcpy(&ctx->ci, ci, sizeof(struct ext4_crypt_info));
123 - ctx->has_valid_key = (EXT4_ENCRYPTION_MODE_INVALID == key->mode)
124 + ctx->has_valid_key = (EXT4_ENCRYPTION_MODE_INVALID == ci->ci_mode)
126 ctx->ctfm_key_is_ready = 0;
128 @@ -335,21 +326,17 @@ struct ext4_fname_crypto_ctx *ext4_get_fname_crypto_ctx(
129 if (!ext4_has_encryption_key(inode))
130 ext4_generate_encryption_key(inode);
132 - /* Get a crypto context based on the key.
133 - * A new context is allocated if no context matches the requested key.
135 - ctx = ext4_search_fname_crypto_ctx(&(ei->i_encryption_key));
137 - ctx = ext4_alloc_fname_crypto_ctx(&(ei->i_encryption_key));
138 + /* Get a crypto context based on the key. */
139 + ctx = ext4_alloc_fname_crypto_ctx(&(ei->i_crypt_info));
143 ctx->flags = ei->i_crypt_policy_flags;
144 if (ctx->has_valid_key) {
145 - if (ctx->key.mode != EXT4_ENCRYPTION_MODE_AES_256_CTS) {
146 + if (ctx->ci.ci_mode != EXT4_ENCRYPTION_MODE_AES_256_CTS) {
147 printk_once(KERN_WARNING
148 "ext4: unsupported key mode %d\n",
151 return ERR_PTR(-ENOKEY);
154 @@ -389,7 +376,7 @@ struct ext4_fname_crypto_ctx *ext4_get_fname_crypto_ctx(
156 * we directly use the inode master key */
157 res = crypto_ablkcipher_setkey(ctx->ctfm,
158 - ctx->key.raw, ctx->key.size);
159 + ctx->ci.ci_raw, ctx->ci.ci_size);
161 ext4_put_fname_crypto_ctx(&ctx);
162 return ERR_PTR(-EIO);
163 diff --git a/fs/ext4/crypto_key.c b/fs/ext4/crypto_key.c
164 index 52170d0..ec6635d 100644
165 --- a/fs/ext4/crypto_key.c
166 +++ b/fs/ext4/crypto_key.c
167 @@ -91,7 +91,7 @@ out:
168 int ext4_generate_encryption_key(struct inode *inode)
170 struct ext4_inode_info *ei = EXT4_I(inode);
171 - struct ext4_encryption_key *crypt_key = &ei->i_encryption_key;
172 + struct ext4_crypt_info *crypt_info = &ei->i_crypt_info;
173 char full_key_descriptor[EXT4_KEY_DESC_PREFIX_SIZE +
174 (EXT4_KEY_DESCRIPTOR_SIZE * 2) + 1];
175 struct key *keyring_key = NULL;
176 @@ -112,17 +112,17 @@ int ext4_generate_encryption_key(struct inode *inode)
178 ei->i_crypt_policy_flags = ctx.flags;
179 if (S_ISREG(inode->i_mode))
180 - crypt_key->mode = ctx.contents_encryption_mode;
181 + crypt_info->ci_mode = ctx.contents_encryption_mode;
182 else if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
183 - crypt_key->mode = ctx.filenames_encryption_mode;
184 + crypt_info->ci_mode = ctx.filenames_encryption_mode;
186 printk(KERN_ERR "ext4 crypto: Unsupported inode type.\n");
189 - crypt_key->size = ext4_encryption_key_size(crypt_key->mode);
190 - BUG_ON(!crypt_key->size);
191 + crypt_info->ci_size = ext4_encryption_key_size(crypt_info->ci_mode);
192 + BUG_ON(!crypt_info->ci_size);
193 if (DUMMY_ENCRYPTION_ENABLED(sbi)) {
194 - memset(crypt_key->raw, 0x42, EXT4_AES_256_XTS_KEY_SIZE);
195 + memset(crypt_info->ci_raw, 0x42, EXT4_AES_256_XTS_KEY_SIZE);
198 memcpy(full_key_descriptor, EXT4_KEY_DESC_PREFIX,
199 @@ -148,19 +148,20 @@ int ext4_generate_encryption_key(struct inode *inode)
200 BUILD_BUG_ON(EXT4_AES_128_ECB_KEY_SIZE !=
201 EXT4_KEY_DERIVATION_NONCE_SIZE);
202 BUG_ON(master_key->size != EXT4_AES_256_XTS_KEY_SIZE);
203 - res = ext4_derive_key_aes(ctx.nonce, master_key->raw, crypt_key->raw);
204 + res = ext4_derive_key_aes(ctx.nonce, master_key->raw,
205 + crypt_info->ci_raw);
208 key_put(keyring_key);
210 - crypt_key->mode = EXT4_ENCRYPTION_MODE_INVALID;
211 + crypt_info->ci_mode = EXT4_ENCRYPTION_MODE_INVALID;
215 int ext4_has_encryption_key(struct inode *inode)
217 struct ext4_inode_info *ei = EXT4_I(inode);
218 - struct ext4_encryption_key *crypt_key = &ei->i_encryption_key;
219 + struct ext4_crypt_info *crypt_info = &ei->i_crypt_info;
221 - return (crypt_key->mode != EXT4_ENCRYPTION_MODE_INVALID);
222 + return (crypt_info->ci_mode != EXT4_ENCRYPTION_MODE_INVALID);
224 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
225 index 8071a0a..e20a06c 100644
228 @@ -955,7 +955,7 @@ struct ext4_inode_info {
230 #ifdef CONFIG_EXT4_FS_ENCRYPTION
231 /* Encryption params */
232 - struct ext4_encryption_key i_encryption_key;
233 + struct ext4_crypt_info i_crypt_info;
237 diff --git a/fs/ext4/ext4_crypto.h b/fs/ext4/ext4_crypto.h
238 index 552424a..deecbe8 100644
239 --- a/fs/ext4/ext4_crypto.h
240 +++ b/fs/ext4/ext4_crypto.h
241 @@ -66,10 +66,17 @@ struct ext4_encryption_context {
242 #define EXT4_KEY_DESC_PREFIX "ext4:"
243 #define EXT4_KEY_DESC_PREFIX_SIZE 5
245 +/* This is passed in from userspace into the kernel keyring */
246 struct ext4_encryption_key {
248 - char raw[EXT4_MAX_KEY_SIZE];
251 + char raw[EXT4_MAX_KEY_SIZE];
253 +} __attribute__((__packed__));
255 +struct ext4_crypt_info {
256 + unsigned char ci_mode;
257 + unsigned char ci_size;
258 + char ci_raw[EXT4_MAX_KEY_SIZE];
261 #define EXT4_CTX_REQUIRES_FREE_ENCRYPT_FL 0x00000001
262 @@ -125,7 +132,7 @@ struct ext4_fname_crypto_ctx {
264 struct crypto_ablkcipher *ctfm;
265 struct crypto_hash *htfm;
266 - struct ext4_encryption_key key;
267 + struct ext4_crypt_info ci;
269 unsigned has_valid_key : 1;
270 unsigned ctfm_key_is_ready : 1;
271 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
272 index f9ebd58..a2eb108 100644
273 --- a/fs/ext4/super.c
274 +++ b/fs/ext4/super.c
275 @@ -877,7 +877,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
276 atomic_set(&ei->i_unwritten, 0);
277 INIT_WORK(&ei->i_rsv_conversion_work, ext4_end_io_rsv_work);
278 #ifdef CONFIG_EXT4_FS_ENCRYPTION
279 - ei->i_encryption_key.mode = EXT4_ENCRYPTION_MODE_INVALID;
280 + ei->i_crypt_info.ci_mode = EXT4_ENCRYPTION_MODE_INVALID;
283 return &ei->vfs_inode;