Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
0adda907 | 2 | /* |
3ec4f2a6 | 3 | * Key setup facility for FS encryption support. |
0adda907 JK |
4 | * |
5 | * Copyright (C) 2015, Google, Inc. | |
6 | * | |
3ec4f2a6 EB |
7 | * Originally written by Michael Halcrow, Ildar Muslukhov, and Uday Savagaonkar. |
8 | * Heavily modified since then. | |
0adda907 | 9 | */ |
0b81d077 | 10 | |
a575784c | 11 | #include <crypto/skcipher.h> |
0109ce76 EB |
12 | #include <linux/key.h> |
13 | ||
3325bea5 | 14 | #include "fscrypt_private.h" |
0adda907 | 15 | |
85af90e5 | 16 | struct fscrypt_mode fscrypt_modes[] = { |
3b6df59b | 17 | [FSCRYPT_MODE_AES_256_XTS] = { |
e1cc40e5 EB |
18 | .friendly_name = "AES-256-XTS", |
19 | .cipher_str = "xts(aes)", | |
20 | .keysize = 64, | |
8094c3ce | 21 | .ivsize = 16, |
e1cc40e5 | 22 | }, |
3b6df59b | 23 | [FSCRYPT_MODE_AES_256_CTS] = { |
e1cc40e5 EB |
24 | .friendly_name = "AES-256-CTS-CBC", |
25 | .cipher_str = "cts(cbc(aes))", | |
26 | .keysize = 32, | |
8094c3ce | 27 | .ivsize = 16, |
e1cc40e5 | 28 | }, |
3b6df59b | 29 | [FSCRYPT_MODE_AES_128_CBC] = { |
4006d799 EB |
30 | .friendly_name = "AES-128-CBC-ESSIV", |
31 | .cipher_str = "essiv(cbc(aes),sha256)", | |
e1cc40e5 | 32 | .keysize = 16, |
8094c3ce | 33 | .ivsize = 16, |
e1cc40e5 | 34 | }, |
3b6df59b | 35 | [FSCRYPT_MODE_AES_128_CTS] = { |
e1cc40e5 EB |
36 | .friendly_name = "AES-128-CTS-CBC", |
37 | .cipher_str = "cts(cbc(aes))", | |
38 | .keysize = 16, | |
8094c3ce EB |
39 | .ivsize = 16, |
40 | }, | |
3b6df59b | 41 | [FSCRYPT_MODE_ADIANTUM] = { |
8094c3ce EB |
42 | .friendly_name = "Adiantum", |
43 | .cipher_str = "adiantum(xchacha12,aes)", | |
44 | .keysize = 32, | |
45 | .ivsize = 32, | |
e1cc40e5 | 46 | }, |
b7e7cf7a DW |
47 | }; |
48 | ||
e1cc40e5 | 49 | static struct fscrypt_mode * |
5dae460c EB |
50 | select_encryption_mode(const union fscrypt_policy *policy, |
51 | const struct inode *inode) | |
8f39850d | 52 | { |
e1cc40e5 | 53 | if (S_ISREG(inode->i_mode)) |
85af90e5 | 54 | return &fscrypt_modes[fscrypt_policy_contents_mode(policy)]; |
e1cc40e5 EB |
55 | |
56 | if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) | |
85af90e5 | 57 | return &fscrypt_modes[fscrypt_policy_fnames_mode(policy)]; |
8f39850d | 58 | |
e1cc40e5 EB |
59 | WARN_ONCE(1, "fscrypt: filesystem tried to load encryption info for inode %lu, which is not encryptable (file type %d)\n", |
60 | inode->i_ino, (inode->i_mode & S_IFMT)); | |
61 | return ERR_PTR(-EINVAL); | |
8f39850d EB |
62 | } |
63 | ||
3ec4f2a6 | 64 | /* Create a symmetric cipher object for the given encryption mode and key */ |
0109ce76 EB |
65 | struct crypto_skcipher *fscrypt_allocate_skcipher(struct fscrypt_mode *mode, |
66 | const u8 *raw_key, | |
67 | const struct inode *inode) | |
8094c3ce EB |
68 | { |
69 | struct crypto_skcipher *tfm; | |
70 | int err; | |
71 | ||
72 | tfm = crypto_alloc_skcipher(mode->cipher_str, 0, 0); | |
73 | if (IS_ERR(tfm)) { | |
29a98c1c | 74 | if (PTR_ERR(tfm) == -ENOENT) { |
a4d14e91 EB |
75 | fscrypt_warn(inode, |
76 | "Missing crypto API support for %s (API name: \"%s\")", | |
77 | mode->friendly_name, mode->cipher_str); | |
29a98c1c EB |
78 | return ERR_PTR(-ENOPKG); |
79 | } | |
80 | fscrypt_err(inode, "Error allocating '%s' transform: %ld", | |
81 | mode->cipher_str, PTR_ERR(tfm)); | |
8094c3ce EB |
82 | return tfm; |
83 | } | |
ff73c2c0 | 84 | if (!xchg(&mode->logged_impl_name, 1)) { |
8094c3ce EB |
85 | /* |
86 | * fscrypt performance can vary greatly depending on which | |
87 | * crypto algorithm implementation is used. Help people debug | |
88 | * performance problems by logging the ->cra_driver_name the | |
ff73c2c0 | 89 | * first time a mode is used. |
8094c3ce | 90 | */ |
8094c3ce | 91 | pr_info("fscrypt: %s using implementation \"%s\"\n", |
6e1adb88 | 92 | mode->friendly_name, crypto_skcipher_driver_name(tfm)); |
8094c3ce | 93 | } |
c64cfb98 EB |
94 | if (WARN_ON(crypto_skcipher_ivsize(tfm) != mode->ivsize)) { |
95 | err = -EINVAL; | |
96 | goto err_free_tfm; | |
97 | } | |
231baecd | 98 | crypto_skcipher_set_flags(tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); |
8094c3ce EB |
99 | err = crypto_skcipher_setkey(tfm, raw_key, mode->keysize); |
100 | if (err) | |
101 | goto err_free_tfm; | |
102 | ||
103 | return tfm; | |
104 | ||
105 | err_free_tfm: | |
106 | crypto_free_skcipher(tfm); | |
107 | return ERR_PTR(err); | |
108 | } | |
109 | ||
f592efe7 EB |
110 | /* Given a per-file encryption key, set up the file's crypto transform object */ |
111 | int fscrypt_set_per_file_enc_key(struct fscrypt_info *ci, const u8 *raw_key) | |
8094c3ce | 112 | { |
4006d799 | 113 | struct crypto_skcipher *tfm; |
3ec4f2a6 | 114 | |
f592efe7 | 115 | tfm = fscrypt_allocate_skcipher(ci->ci_mode, raw_key, ci->ci_inode); |
4006d799 EB |
116 | if (IS_ERR(tfm)) |
117 | return PTR_ERR(tfm); | |
8094c3ce | 118 | |
4006d799 | 119 | ci->ci_ctfm = tfm; |
b103fb76 | 120 | ci->ci_owns_key = true; |
8094c3ce EB |
121 | return 0; |
122 | } | |
123 | ||
f592efe7 EB |
124 | static int setup_per_mode_enc_key(struct fscrypt_info *ci, |
125 | struct fscrypt_master_key *mk, | |
126 | struct crypto_skcipher **tfms, | |
127 | u8 hkdf_context, bool include_fs_uuid) | |
5dae460c | 128 | { |
b103fb76 EB |
129 | const struct inode *inode = ci->ci_inode; |
130 | const struct super_block *sb = inode->i_sb; | |
5dae460c | 131 | struct fscrypt_mode *mode = ci->ci_mode; |
85af90e5 | 132 | const u8 mode_num = mode - fscrypt_modes; |
5dae460c EB |
133 | struct crypto_skcipher *tfm, *prev_tfm; |
134 | u8 mode_key[FSCRYPT_MAX_KEY_SIZE]; | |
b103fb76 EB |
135 | u8 hkdf_info[sizeof(mode_num) + sizeof(sb->s_uuid)]; |
136 | unsigned int hkdf_infolen = 0; | |
5dae460c EB |
137 | int err; |
138 | ||
b103fb76 | 139 | if (WARN_ON(mode_num > __FSCRYPT_MODE_MAX)) |
5dae460c EB |
140 | return -EINVAL; |
141 | ||
142 | /* pairs with cmpxchg() below */ | |
b103fb76 | 143 | tfm = READ_ONCE(tfms[mode_num]); |
5dae460c EB |
144 | if (likely(tfm != NULL)) |
145 | goto done; | |
146 | ||
147 | BUILD_BUG_ON(sizeof(mode_num) != 1); | |
b103fb76 EB |
148 | BUILD_BUG_ON(sizeof(sb->s_uuid) != 16); |
149 | BUILD_BUG_ON(sizeof(hkdf_info) != 17); | |
150 | hkdf_info[hkdf_infolen++] = mode_num; | |
151 | if (include_fs_uuid) { | |
152 | memcpy(&hkdf_info[hkdf_infolen], &sb->s_uuid, | |
153 | sizeof(sb->s_uuid)); | |
154 | hkdf_infolen += sizeof(sb->s_uuid); | |
155 | } | |
5dae460c | 156 | err = fscrypt_hkdf_expand(&mk->mk_secret.hkdf, |
b103fb76 | 157 | hkdf_context, hkdf_info, hkdf_infolen, |
5dae460c EB |
158 | mode_key, mode->keysize); |
159 | if (err) | |
160 | return err; | |
b103fb76 | 161 | tfm = fscrypt_allocate_skcipher(mode, mode_key, inode); |
5dae460c EB |
162 | memzero_explicit(mode_key, mode->keysize); |
163 | if (IS_ERR(tfm)) | |
164 | return PTR_ERR(tfm); | |
165 | ||
166 | /* pairs with READ_ONCE() above */ | |
b103fb76 | 167 | prev_tfm = cmpxchg(&tfms[mode_num], NULL, tfm); |
5dae460c EB |
168 | if (prev_tfm != NULL) { |
169 | crypto_free_skcipher(tfm); | |
170 | tfm = prev_tfm; | |
171 | } | |
172 | done: | |
173 | ci->ci_ctfm = tfm; | |
174 | return 0; | |
175 | } | |
176 | ||
aa408f83 DR |
177 | int fscrypt_derive_dirhash_key(struct fscrypt_info *ci, |
178 | const struct fscrypt_master_key *mk) | |
179 | { | |
180 | int err; | |
181 | ||
182 | err = fscrypt_hkdf_expand(&mk->mk_secret.hkdf, HKDF_CONTEXT_DIRHASH_KEY, | |
183 | ci->ci_nonce, FS_KEY_DERIVATION_NONCE_SIZE, | |
184 | (u8 *)&ci->ci_dirhash_key, | |
185 | sizeof(ci->ci_dirhash_key)); | |
186 | if (err) | |
187 | return err; | |
188 | ci->ci_dirhash_key_initialized = true; | |
189 | return 0; | |
190 | } | |
191 | ||
5dae460c EB |
192 | static int fscrypt_setup_v2_file_key(struct fscrypt_info *ci, |
193 | struct fscrypt_master_key *mk) | |
194 | { | |
5dae460c EB |
195 | int err; |
196 | ||
197 | if (ci->ci_policy.v2.flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY) { | |
198 | /* | |
f592efe7 EB |
199 | * DIRECT_KEY: instead of deriving per-file encryption keys, the |
200 | * per-file nonce will be included in all the IVs. But unlike | |
201 | * v1 policies, for v2 policies in this case we don't encrypt | |
202 | * with the master key directly but rather derive a per-mode | |
203 | * encryption key. This ensures that the master key is | |
204 | * consistently used only for HKDF, avoiding key reuse issues. | |
5dae460c | 205 | */ |
f592efe7 EB |
206 | err = setup_per_mode_enc_key(ci, mk, mk->mk_direct_tfms, |
207 | HKDF_CONTEXT_DIRECT_KEY, false); | |
b103fb76 EB |
208 | } else if (ci->ci_policy.v2.flags & |
209 | FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64) { | |
210 | /* | |
211 | * IV_INO_LBLK_64: encryption keys are derived from (master_key, | |
212 | * mode_num, filesystem_uuid), and inode number is included in | |
213 | * the IVs. This format is optimized for use with inline | |
214 | * encryption hardware compliant with the UFS or eMMC standards. | |
215 | */ | |
f592efe7 EB |
216 | err = setup_per_mode_enc_key(ci, mk, mk->mk_iv_ino_lblk_64_tfms, |
217 | HKDF_CONTEXT_IV_INO_LBLK_64_KEY, | |
218 | true); | |
aa408f83 DR |
219 | } else { |
220 | u8 derived_key[FSCRYPT_MAX_KEY_SIZE]; | |
5dae460c | 221 | |
aa408f83 | 222 | err = fscrypt_hkdf_expand(&mk->mk_secret.hkdf, |
f592efe7 | 223 | HKDF_CONTEXT_PER_FILE_ENC_KEY, |
aa408f83 DR |
224 | ci->ci_nonce, |
225 | FS_KEY_DERIVATION_NONCE_SIZE, | |
226 | derived_key, ci->ci_mode->keysize); | |
227 | if (err) | |
228 | return err; | |
229 | ||
f592efe7 | 230 | err = fscrypt_set_per_file_enc_key(ci, derived_key); |
aa408f83 DR |
231 | memzero_explicit(derived_key, ci->ci_mode->keysize); |
232 | } | |
5dae460c EB |
233 | if (err) |
234 | return err; | |
235 | ||
aa408f83 DR |
236 | /* Derive a secret dirhash key for directories that need it. */ |
237 | if (S_ISDIR(ci->ci_inode->i_mode) && IS_CASEFOLDED(ci->ci_inode)) { | |
238 | err = fscrypt_derive_dirhash_key(ci, mk); | |
239 | if (err) | |
240 | return err; | |
241 | } | |
242 | ||
243 | return 0; | |
5dae460c EB |
244 | } |
245 | ||
3ec4f2a6 EB |
246 | /* |
247 | * Find the master key, then set up the inode's actual encryption key. | |
b1c0ec35 EB |
248 | * |
249 | * If the master key is found in the filesystem-level keyring, then the | |
250 | * corresponding 'struct key' is returned in *master_key_ret with | |
23c688b5 EB |
251 | * ->mk_secret_sem read-locked. This is needed to ensure that only one task |
252 | * links the fscrypt_info into ->mk_decrypted_inodes (as multiple tasks may race | |
253 | * to create an fscrypt_info for the same inode), and to synchronize the master | |
254 | * key being removed with a new inode starting to use it. | |
3ec4f2a6 | 255 | */ |
b1c0ec35 EB |
256 | static int setup_file_encryption_key(struct fscrypt_info *ci, |
257 | struct key **master_key_ret) | |
3ec4f2a6 | 258 | { |
22d94f49 EB |
259 | struct key *key; |
260 | struct fscrypt_master_key *mk = NULL; | |
261 | struct fscrypt_key_specifier mk_spec; | |
262 | int err; | |
263 | ||
5dae460c EB |
264 | switch (ci->ci_policy.version) { |
265 | case FSCRYPT_POLICY_V1: | |
266 | mk_spec.type = FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR; | |
267 | memcpy(mk_spec.u.descriptor, | |
268 | ci->ci_policy.v1.master_key_descriptor, | |
269 | FSCRYPT_KEY_DESCRIPTOR_SIZE); | |
270 | break; | |
271 | case FSCRYPT_POLICY_V2: | |
272 | mk_spec.type = FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER; | |
273 | memcpy(mk_spec.u.identifier, | |
274 | ci->ci_policy.v2.master_key_identifier, | |
275 | FSCRYPT_KEY_IDENTIFIER_SIZE); | |
276 | break; | |
277 | default: | |
278 | WARN_ON(1); | |
279 | return -EINVAL; | |
280 | } | |
22d94f49 EB |
281 | |
282 | key = fscrypt_find_master_key(ci->ci_inode->i_sb, &mk_spec); | |
283 | if (IS_ERR(key)) { | |
5dae460c EB |
284 | if (key != ERR_PTR(-ENOKEY) || |
285 | ci->ci_policy.version != FSCRYPT_POLICY_V1) | |
22d94f49 EB |
286 | return PTR_ERR(key); |
287 | ||
5dae460c EB |
288 | /* |
289 | * As a legacy fallback for v1 policies, search for the key in | |
290 | * the current task's subscribed keyrings too. Don't move this | |
291 | * to before the search of ->s_master_keys, since users | |
292 | * shouldn't be able to override filesystem-level keys. | |
293 | */ | |
22d94f49 EB |
294 | return fscrypt_setup_v1_file_key_via_subscribed_keyrings(ci); |
295 | } | |
296 | ||
297 | mk = key->payload.data[0]; | |
23c688b5 | 298 | down_read(&mk->mk_secret_sem); |
b1c0ec35 EB |
299 | |
300 | /* Has the secret been removed (via FS_IOC_REMOVE_ENCRYPTION_KEY)? */ | |
301 | if (!is_master_key_secret_present(&mk->mk_secret)) { | |
302 | err = -ENOKEY; | |
303 | goto out_release_key; | |
304 | } | |
22d94f49 | 305 | |
5dae460c EB |
306 | /* |
307 | * Require that the master key be at least as long as the derived key. | |
308 | * Otherwise, the derived key cannot possibly contain as much entropy as | |
309 | * that required by the encryption mode it will be used for. For v1 | |
310 | * policies it's also required for the KDF to work at all. | |
311 | */ | |
22d94f49 EB |
312 | if (mk->mk_secret.size < ci->ci_mode->keysize) { |
313 | fscrypt_warn(NULL, | |
314 | "key with %s %*phN is too short (got %u bytes, need %u+ bytes)", | |
315 | master_key_spec_type(&mk_spec), | |
316 | master_key_spec_len(&mk_spec), (u8 *)&mk_spec.u, | |
317 | mk->mk_secret.size, ci->ci_mode->keysize); | |
318 | err = -ENOKEY; | |
319 | goto out_release_key; | |
320 | } | |
321 | ||
5dae460c EB |
322 | switch (ci->ci_policy.version) { |
323 | case FSCRYPT_POLICY_V1: | |
324 | err = fscrypt_setup_v1_file_key(ci, mk->mk_secret.raw); | |
325 | break; | |
326 | case FSCRYPT_POLICY_V2: | |
327 | err = fscrypt_setup_v2_file_key(ci, mk); | |
328 | break; | |
329 | default: | |
330 | WARN_ON(1); | |
331 | err = -EINVAL; | |
332 | break; | |
333 | } | |
b1c0ec35 EB |
334 | if (err) |
335 | goto out_release_key; | |
336 | ||
337 | *master_key_ret = key; | |
338 | return 0; | |
22d94f49 EB |
339 | |
340 | out_release_key: | |
23c688b5 | 341 | up_read(&mk->mk_secret_sem); |
22d94f49 EB |
342 | key_put(key); |
343 | return err; | |
3ec4f2a6 EB |
344 | } |
345 | ||
8094c3ce EB |
346 | static void put_crypt_info(struct fscrypt_info *ci) |
347 | { | |
b1c0ec35 EB |
348 | struct key *key; |
349 | ||
8094c3ce EB |
350 | if (!ci) |
351 | return; | |
352 | ||
4006d799 | 353 | if (ci->ci_direct_key) |
0109ce76 | 354 | fscrypt_put_direct_key(ci->ci_direct_key); |
b103fb76 | 355 | else if (ci->ci_owns_key) |
8094c3ce | 356 | crypto_free_skcipher(ci->ci_ctfm); |
b1c0ec35 EB |
357 | |
358 | key = ci->ci_master_key; | |
359 | if (key) { | |
360 | struct fscrypt_master_key *mk = key->payload.data[0]; | |
361 | ||
362 | /* | |
363 | * Remove this inode from the list of inodes that were unlocked | |
364 | * with the master key. | |
365 | * | |
366 | * In addition, if we're removing the last inode from a key that | |
367 | * already had its secret removed, invalidate the key so that it | |
368 | * gets removed from ->s_master_keys. | |
369 | */ | |
370 | spin_lock(&mk->mk_decrypted_inodes_lock); | |
371 | list_del(&ci->ci_master_key_link); | |
372 | spin_unlock(&mk->mk_decrypted_inodes_lock); | |
373 | if (refcount_dec_and_test(&mk->mk_refcount)) | |
374 | key_invalidate(key); | |
375 | key_put(key); | |
376 | } | |
6f99756d | 377 | memzero_explicit(ci, sizeof(*ci)); |
8094c3ce EB |
378 | kmem_cache_free(fscrypt_info_cachep, ci); |
379 | } | |
380 | ||
1b53cf98 | 381 | int fscrypt_get_encryption_info(struct inode *inode) |
0adda907 | 382 | { |
0b81d077 | 383 | struct fscrypt_info *crypt_info; |
5dae460c | 384 | union fscrypt_context ctx; |
e1cc40e5 | 385 | struct fscrypt_mode *mode; |
b1c0ec35 | 386 | struct key *master_key = NULL; |
0adda907 JK |
387 | int res; |
388 | ||
e37a784d | 389 | if (fscrypt_has_encryption_key(inode)) |
1b53cf98 EB |
390 | return 0; |
391 | ||
f32d7ac2 | 392 | res = fscrypt_initialize(inode->i_sb->s_cop->flags); |
cfc4d971 JK |
393 | if (res) |
394 | return res; | |
0b81d077 | 395 | |
0b81d077 JK |
396 | res = inode->i_sb->s_cop->get_context(inode, &ctx, sizeof(ctx)); |
397 | if (res < 0) { | |
5bbdcbbb | 398 | if (!fscrypt_dummy_context_enabled(inode) || |
63f668f0 EB |
399 | IS_ENCRYPTED(inode)) { |
400 | fscrypt_warn(inode, | |
401 | "Error %d getting encryption context", | |
402 | res); | |
0b81d077 | 403 | return res; |
63f668f0 | 404 | } |
5bbdcbbb TT |
405 | /* Fake up a context for an unencrypted directory */ |
406 | memset(&ctx, 0, sizeof(ctx)); | |
5dae460c EB |
407 | ctx.version = FSCRYPT_CONTEXT_V1; |
408 | ctx.v1.contents_encryption_mode = FSCRYPT_MODE_AES_256_XTS; | |
409 | ctx.v1.filenames_encryption_mode = FSCRYPT_MODE_AES_256_CTS; | |
410 | memset(ctx.v1.master_key_descriptor, 0x42, | |
3b6df59b | 411 | FSCRYPT_KEY_DESCRIPTOR_SIZE); |
5dae460c | 412 | res = sizeof(ctx.v1); |
63f668f0 | 413 | } |
0adda907 | 414 | |
8094c3ce | 415 | crypt_info = kmem_cache_zalloc(fscrypt_info_cachep, GFP_NOFS); |
0adda907 JK |
416 | if (!crypt_info) |
417 | return -ENOMEM; | |
418 | ||
59dc6a8e EB |
419 | crypt_info->ci_inode = inode; |
420 | ||
5dae460c EB |
421 | res = fscrypt_policy_from_context(&crypt_info->ci_policy, &ctx, res); |
422 | if (res) { | |
423 | fscrypt_warn(inode, | |
424 | "Unrecognized or corrupt encryption context"); | |
425 | goto out; | |
426 | } | |
427 | ||
428 | switch (ctx.version) { | |
429 | case FSCRYPT_CONTEXT_V1: | |
430 | memcpy(crypt_info->ci_nonce, ctx.v1.nonce, | |
431 | FS_KEY_DERIVATION_NONCE_SIZE); | |
432 | break; | |
433 | case FSCRYPT_CONTEXT_V2: | |
434 | memcpy(crypt_info->ci_nonce, ctx.v2.nonce, | |
435 | FS_KEY_DERIVATION_NONCE_SIZE); | |
436 | break; | |
437 | default: | |
438 | WARN_ON(1); | |
439 | res = -EINVAL; | |
440 | goto out; | |
441 | } | |
442 | ||
443 | if (!fscrypt_supported_policy(&crypt_info->ci_policy, inode)) { | |
444 | res = -EINVAL; | |
445 | goto out; | |
446 | } | |
640778fb | 447 | |
5dae460c | 448 | mode = select_encryption_mode(&crypt_info->ci_policy, inode); |
e1cc40e5 EB |
449 | if (IS_ERR(mode)) { |
450 | res = PTR_ERR(mode); | |
26bf3dc7 | 451 | goto out; |
e1cc40e5 | 452 | } |
8094c3ce EB |
453 | WARN_ON(mode->ivsize > FSCRYPT_MAX_IV_SIZE); |
454 | crypt_info->ci_mode = mode; | |
8f39850d | 455 | |
b1c0ec35 | 456 | res = setup_file_encryption_key(crypt_info, &master_key); |
26bf3dc7 JK |
457 | if (res) |
458 | goto out; | |
459 | ||
b1c0ec35 EB |
460 | if (cmpxchg_release(&inode->i_crypt_info, NULL, crypt_info) == NULL) { |
461 | if (master_key) { | |
462 | struct fscrypt_master_key *mk = | |
463 | master_key->payload.data[0]; | |
464 | ||
465 | refcount_inc(&mk->mk_refcount); | |
466 | crypt_info->ci_master_key = key_get(master_key); | |
467 | spin_lock(&mk->mk_decrypted_inodes_lock); | |
468 | list_add(&crypt_info->ci_master_key_link, | |
469 | &mk->mk_decrypted_inodes); | |
470 | spin_unlock(&mk->mk_decrypted_inodes_lock); | |
471 | } | |
1b53cf98 | 472 | crypt_info = NULL; |
b1c0ec35 EB |
473 | } |
474 | res = 0; | |
26bf3dc7 | 475 | out: |
b1c0ec35 | 476 | if (master_key) { |
23c688b5 EB |
477 | struct fscrypt_master_key *mk = master_key->payload.data[0]; |
478 | ||
479 | up_read(&mk->mk_secret_sem); | |
b1c0ec35 EB |
480 | key_put(master_key); |
481 | } | |
0b81d077 | 482 | if (res == -ENOKEY) |
26bf3dc7 | 483 | res = 0; |
0b81d077 | 484 | put_crypt_info(crypt_info); |
0adda907 JK |
485 | return res; |
486 | } | |
1b53cf98 | 487 | EXPORT_SYMBOL(fscrypt_get_encryption_info); |
0adda907 | 488 | |
2c58d548 EB |
489 | /** |
490 | * fscrypt_put_encryption_info - free most of an inode's fscrypt data | |
491 | * | |
492 | * Free the inode's fscrypt_info. Filesystems must call this when the inode is | |
493 | * being evicted. An RCU grace period need not have elapsed yet. | |
494 | */ | |
3d204e24 | 495 | void fscrypt_put_encryption_info(struct inode *inode) |
0adda907 | 496 | { |
3d204e24 EB |
497 | put_crypt_info(inode->i_crypt_info); |
498 | inode->i_crypt_info = NULL; | |
0b81d077 JK |
499 | } |
500 | EXPORT_SYMBOL(fscrypt_put_encryption_info); | |
2c58d548 EB |
501 | |
502 | /** | |
503 | * fscrypt_free_inode - free an inode's fscrypt data requiring RCU delay | |
504 | * | |
505 | * Free the inode's cached decrypted symlink target, if any. Filesystems must | |
506 | * call this after an RCU grace period, just before they free the inode. | |
507 | */ | |
508 | void fscrypt_free_inode(struct inode *inode) | |
509 | { | |
510 | if (IS_ENCRYPTED(inode) && S_ISLNK(inode->i_mode)) { | |
511 | kfree(inode->i_link); | |
512 | inode->i_link = NULL; | |
513 | } | |
514 | } | |
515 | EXPORT_SYMBOL(fscrypt_free_inode); | |
b1c0ec35 EB |
516 | |
517 | /** | |
518 | * fscrypt_drop_inode - check whether the inode's master key has been removed | |
519 | * | |
520 | * Filesystems supporting fscrypt must call this from their ->drop_inode() | |
521 | * method so that encrypted inodes are evicted as soon as they're no longer in | |
522 | * use and their master key has been removed. | |
523 | * | |
524 | * Return: 1 if fscrypt wants the inode to be evicted now, otherwise 0 | |
525 | */ | |
526 | int fscrypt_drop_inode(struct inode *inode) | |
527 | { | |
528 | const struct fscrypt_info *ci = READ_ONCE(inode->i_crypt_info); | |
529 | const struct fscrypt_master_key *mk; | |
530 | ||
531 | /* | |
532 | * If ci is NULL, then the inode doesn't have an encryption key set up | |
533 | * so it's irrelevant. If ci_master_key is NULL, then the master key | |
534 | * was provided via the legacy mechanism of the process-subscribed | |
535 | * keyrings, so we don't know whether it's been removed or not. | |
536 | */ | |
537 | if (!ci || !ci->ci_master_key) | |
538 | return 0; | |
539 | mk = ci->ci_master_key->payload.data[0]; | |
540 | ||
2b4eae95 EB |
541 | /* |
542 | * With proper, non-racy use of FS_IOC_REMOVE_ENCRYPTION_KEY, all inodes | |
543 | * protected by the key were cleaned by sync_filesystem(). But if | |
544 | * userspace is still using the files, inodes can be dirtied between | |
545 | * then and now. We mustn't lose any writes, so skip dirty inodes here. | |
546 | */ | |
547 | if (inode->i_state & I_DIRTY_ALL) | |
548 | return 0; | |
549 | ||
b1c0ec35 | 550 | /* |
23c688b5 | 551 | * Note: since we aren't holding ->mk_secret_sem, the result here can |
b1c0ec35 EB |
552 | * immediately become outdated. But there's no correctness problem with |
553 | * unnecessarily evicting. Nor is there a correctness problem with not | |
554 | * evicting while iput() is racing with the key being removed, since | |
555 | * then the thread removing the key will either evict the inode itself | |
556 | * or will correctly detect that it wasn't evicted due to the race. | |
557 | */ | |
558 | return !is_master_key_secret_present(&mk->mk_secret); | |
559 | } | |
560 | EXPORT_SYMBOL_GPL(fscrypt_drop_inode); |