keysetup.c (15936ca13dac032a3f4e6b4ba78add3880bddcf3) keysetup.c (5b421f08801fe8247dec368b3d323958f419e769)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Key setup facility for FS encryption support.
4 *
5 * Copyright (C) 2015, Google, Inc.
6 *
7 * Originally written by Michael Halcrow, Ildar Muslukhov, and Uday Savagaonkar.
8 * Heavily modified since then.

--- 42 unchanged lines hidden (view full) ---

51};
52
53static DEFINE_MUTEX(fscrypt_mode_key_setup_mutex);
54
55static struct fscrypt_mode *
56select_encryption_mode(const union fscrypt_policy *policy,
57 const struct inode *inode)
58{
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Key setup facility for FS encryption support.
4 *
5 * Copyright (C) 2015, Google, Inc.
6 *
7 * Originally written by Michael Halcrow, Ildar Muslukhov, and Uday Savagaonkar.
8 * Heavily modified since then.

--- 42 unchanged lines hidden (view full) ---

51};
52
53static DEFINE_MUTEX(fscrypt_mode_key_setup_mutex);
54
55static struct fscrypt_mode *
56select_encryption_mode(const union fscrypt_policy *policy,
57 const struct inode *inode)
58{
59 BUILD_BUG_ON(ARRAY_SIZE(fscrypt_modes) != FSCRYPT_MODE_MAX + 1);
60
59 if (S_ISREG(inode->i_mode))
60 return &fscrypt_modes[fscrypt_policy_contents_mode(policy)];
61
62 if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
63 return &fscrypt_modes[fscrypt_policy_fnames_mode(policy)];
64
65 WARN_ONCE(1, "fscrypt: filesystem tried to load encryption info for inode %lu, which is not encryptable (file type %d)\n",
66 inode->i_ino, (inode->i_mode & S_IFMT));

--- 96 unchanged lines hidden (view full) ---

163 struct fscrypt_mode *mode = ci->ci_mode;
164 const u8 mode_num = mode - fscrypt_modes;
165 struct fscrypt_prepared_key *prep_key;
166 u8 mode_key[FSCRYPT_MAX_KEY_SIZE];
167 u8 hkdf_info[sizeof(mode_num) + sizeof(sb->s_uuid)];
168 unsigned int hkdf_infolen = 0;
169 int err;
170
61 if (S_ISREG(inode->i_mode))
62 return &fscrypt_modes[fscrypt_policy_contents_mode(policy)];
63
64 if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
65 return &fscrypt_modes[fscrypt_policy_fnames_mode(policy)];
66
67 WARN_ONCE(1, "fscrypt: filesystem tried to load encryption info for inode %lu, which is not encryptable (file type %d)\n",
68 inode->i_ino, (inode->i_mode & S_IFMT));

--- 96 unchanged lines hidden (view full) ---

165 struct fscrypt_mode *mode = ci->ci_mode;
166 const u8 mode_num = mode - fscrypt_modes;
167 struct fscrypt_prepared_key *prep_key;
168 u8 mode_key[FSCRYPT_MAX_KEY_SIZE];
169 u8 hkdf_info[sizeof(mode_num) + sizeof(sb->s_uuid)];
170 unsigned int hkdf_infolen = 0;
171 int err;
172
171 if (WARN_ON(mode_num > __FSCRYPT_MODE_MAX))
173 if (WARN_ON(mode_num > FSCRYPT_MODE_MAX))
172 return -EINVAL;
173
174 prep_key = &keys[mode_num];
175 if (fscrypt_is_key_prepared(prep_key, ci)) {
176 ci->ci_enc_key = *prep_key;
177 return 0;
178 }
179

--- 150 unchanged lines hidden (view full) ---

330
331 return 0;
332}
333
334/*
335 * Find the master key, then set up the inode's actual encryption key.
336 *
337 * If the master key is found in the filesystem-level keyring, then the
174 return -EINVAL;
175
176 prep_key = &keys[mode_num];
177 if (fscrypt_is_key_prepared(prep_key, ci)) {
178 ci->ci_enc_key = *prep_key;
179 return 0;
180 }
181

--- 150 unchanged lines hidden (view full) ---

332
333 return 0;
334}
335
336/*
337 * Find the master key, then set up the inode's actual encryption key.
338 *
339 * If the master key is found in the filesystem-level keyring, then the
338 * corresponding 'struct key' is returned in *master_key_ret with
339 * ->mk_secret_sem read-locked. This is needed to ensure that only one task
340 * links the fscrypt_info into ->mk_decrypted_inodes (as multiple tasks may race
341 * to create an fscrypt_info for the same inode), and to synchronize the master
342 * key being removed with a new inode starting to use it.
340 * corresponding 'struct key' is returned in *master_key_ret with its semaphore
341 * read-locked. This is needed to ensure that only one task links the
342 * fscrypt_info into ->mk_decrypted_inodes (as multiple tasks may race to create
343 * an fscrypt_info for the same inode), and to synchronize the master key being
344 * removed with a new inode starting to use it.
343 */
344static int setup_file_encryption_key(struct fscrypt_info *ci,
345 bool need_dirhash_key,
346 struct key **master_key_ret)
347{
348 struct key *key;
349 struct fscrypt_master_key *mk = NULL;
350 struct fscrypt_key_specifier mk_spec;

--- 32 unchanged lines hidden (view full) ---

383 * the current task's subscribed keyrings too. Don't move this
384 * to before the search of ->s_master_keys, since users
385 * shouldn't be able to override filesystem-level keys.
386 */
387 return fscrypt_setup_v1_file_key_via_subscribed_keyrings(ci);
388 }
389
390 mk = key->payload.data[0];
345 */
346static int setup_file_encryption_key(struct fscrypt_info *ci,
347 bool need_dirhash_key,
348 struct key **master_key_ret)
349{
350 struct key *key;
351 struct fscrypt_master_key *mk = NULL;
352 struct fscrypt_key_specifier mk_spec;

--- 32 unchanged lines hidden (view full) ---

385 * the current task's subscribed keyrings too. Don't move this
386 * to before the search of ->s_master_keys, since users
387 * shouldn't be able to override filesystem-level keys.
388 */
389 return fscrypt_setup_v1_file_key_via_subscribed_keyrings(ci);
390 }
391
392 mk = key->payload.data[0];
391 down_read(&mk->mk_secret_sem);
393 down_read(&key->sem);
392
393 /* Has the secret been removed (via FS_IOC_REMOVE_ENCRYPTION_KEY)? */
394 if (!is_master_key_secret_present(&mk->mk_secret)) {
395 err = -ENOKEY;
396 goto out_release_key;
397 }
398
399 /*

--- 26 unchanged lines hidden (view full) ---

426 }
427 if (err)
428 goto out_release_key;
429
430 *master_key_ret = key;
431 return 0;
432
433out_release_key:
394
395 /* Has the secret been removed (via FS_IOC_REMOVE_ENCRYPTION_KEY)? */
396 if (!is_master_key_secret_present(&mk->mk_secret)) {
397 err = -ENOKEY;
398 goto out_release_key;
399 }
400
401 /*

--- 26 unchanged lines hidden (view full) ---

428 }
429 if (err)
430 goto out_release_key;
431
432 *master_key_ret = key;
433 return 0;
434
435out_release_key:
434 up_read(&mk->mk_secret_sem);
436 up_read(&key->sem);
435 key_put(key);
436 return err;
437}
438
439static void put_crypt_info(struct fscrypt_info *ci)
440{
441 struct key *key;
442

--- 86 unchanged lines hidden (view full) ---

529 &mk->mk_decrypted_inodes);
530 spin_unlock(&mk->mk_decrypted_inodes_lock);
531 }
532 crypt_info = NULL;
533 }
534 res = 0;
535out:
536 if (master_key) {
437 key_put(key);
438 return err;
439}
440
441static void put_crypt_info(struct fscrypt_info *ci)
442{
443 struct key *key;
444

--- 86 unchanged lines hidden (view full) ---

531 &mk->mk_decrypted_inodes);
532 spin_unlock(&mk->mk_decrypted_inodes_lock);
533 }
534 crypt_info = NULL;
535 }
536 res = 0;
537out:
538 if (master_key) {
537 struct fscrypt_master_key *mk = master_key->payload.data[0];
538
539 up_read(&mk->mk_secret_sem);
539 up_read(&master_key->sem);
540 key_put(master_key);
541 }
542 put_crypt_info(crypt_info);
543 return res;
544}
545
546/**
547 * fscrypt_get_encryption_info() - set up an inode's encryption key

--- 36 unchanged lines hidden (view full) ---

584 res = fscrypt_setup_encryption_info(inode, &policy,
585 fscrypt_context_nonce(&ctx),
586 IS_CASEFOLDED(inode) &&
587 S_ISDIR(inode->i_mode));
588 if (res == -ENOKEY)
589 res = 0;
590 return res;
591}
540 key_put(master_key);
541 }
542 put_crypt_info(crypt_info);
543 return res;
544}
545
546/**
547 * fscrypt_get_encryption_info() - set up an inode's encryption key

--- 36 unchanged lines hidden (view full) ---

584 res = fscrypt_setup_encryption_info(inode, &policy,
585 fscrypt_context_nonce(&ctx),
586 IS_CASEFOLDED(inode) &&
587 S_ISDIR(inode->i_mode));
588 if (res == -ENOKEY)
589 res = 0;
590 return res;
591}
592EXPORT_SYMBOL(fscrypt_get_encryption_info);
593
594/**
595 * fscrypt_prepare_new_inode() - prepare to create a new inode in a directory
596 * @dir: a possibly-encrypted directory
597 * @inode: the new inode. ->i_mode must be set already.
598 * ->i_ino doesn't need to be set yet.
599 * @encrypt_ret: (output) set to %true if the new inode will be encrypted
600 *

--- 104 unchanged lines hidden (view full) ---

705 * protected by the key were cleaned by sync_filesystem(). But if
706 * userspace is still using the files, inodes can be dirtied between
707 * then and now. We mustn't lose any writes, so skip dirty inodes here.
708 */
709 if (inode->i_state & I_DIRTY_ALL)
710 return 0;
711
712 /*
592
593/**
594 * fscrypt_prepare_new_inode() - prepare to create a new inode in a directory
595 * @dir: a possibly-encrypted directory
596 * @inode: the new inode. ->i_mode must be set already.
597 * ->i_ino doesn't need to be set yet.
598 * @encrypt_ret: (output) set to %true if the new inode will be encrypted
599 *

--- 104 unchanged lines hidden (view full) ---

704 * protected by the key were cleaned by sync_filesystem(). But if
705 * userspace is still using the files, inodes can be dirtied between
706 * then and now. We mustn't lose any writes, so skip dirty inodes here.
707 */
708 if (inode->i_state & I_DIRTY_ALL)
709 return 0;
710
711 /*
713 * Note: since we aren't holding ->mk_secret_sem, the result here can
712 * Note: since we aren't holding the key semaphore, the result here can
714 * immediately become outdated. But there's no correctness problem with
715 * unnecessarily evicting. Nor is there a correctness problem with not
716 * evicting while iput() is racing with the key being removed, since
717 * then the thread removing the key will either evict the inode itself
718 * or will correctly detect that it wasn't evicted due to the race.
719 */
720 return !is_master_key_secret_present(&mk->mk_secret);
721}
722EXPORT_SYMBOL_GPL(fscrypt_drop_inode);
713 * immediately become outdated. But there's no correctness problem with
714 * unnecessarily evicting. Nor is there a correctness problem with not
715 * evicting while iput() is racing with the key being removed, since
716 * then the thread removing the key will either evict the inode itself
717 * or will correctly detect that it wasn't evicted due to the race.
718 */
719 return !is_master_key_secret_present(&mk->mk_secret);
720}
721EXPORT_SYMBOL_GPL(fscrypt_drop_inode);