Skip to content

Commit c1f4cfd

Browse files
committed
Merge tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt
Pull fscrypt updates from Eric Biggers: "Some cleanups for fs/crypto/: - Split up the misleadingly-named FS_CRYPTO_BLOCK_SIZE constant. - Consistently report the encryption implementation that is being used. - Add helper functions for the test_dummy_encryption mount option that work properly with the new mount API. ext4 and f2fs will use these" * tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt: fscrypt: add new helper functions for test_dummy_encryption fscrypt: factor out fscrypt_policy_to_key_spec() fscrypt: log when starting to use inline encryption fscrypt: split up FS_CRYPTO_BLOCK_SIZE
2 parents ac2ab99 + 218d921 commit c1f4cfd

9 files changed

Lines changed: 238 additions & 97 deletions

File tree

fs/crypto/crypto.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ int fscrypt_crypt_block(const struct inode *inode, fscrypt_direction_t rw,
113113

114114
if (WARN_ON_ONCE(len <= 0))
115115
return -EINVAL;
116-
if (WARN_ON_ONCE(len % FS_CRYPTO_BLOCK_SIZE != 0))
116+
if (WARN_ON_ONCE(len % FSCRYPT_CONTENTS_ALIGNMENT != 0))
117117
return -EINVAL;
118118

119119
fscrypt_generate_iv(&iv, lblk_num, ci);
@@ -213,8 +213,8 @@ EXPORT_SYMBOL(fscrypt_encrypt_pagecache_blocks);
213213
* fscrypt_encrypt_block_inplace() - Encrypt a filesystem block in-place
214214
* @inode: The inode to which this block belongs
215215
* @page: The page containing the block to encrypt
216-
* @len: Size of block to encrypt. Doesn't need to be a multiple of the
217-
* fs block size, but must be a multiple of FS_CRYPTO_BLOCK_SIZE.
216+
* @len: Size of block to encrypt. This must be a multiple of
217+
* FSCRYPT_CONTENTS_ALIGNMENT.
218218
* @offs: Byte offset within @page at which the block to encrypt begins
219219
* @lblk_num: Filesystem logical block number of the block, i.e. the 0-based
220220
* number of the block within the file
@@ -283,8 +283,8 @@ EXPORT_SYMBOL(fscrypt_decrypt_pagecache_blocks);
283283
* fscrypt_decrypt_block_inplace() - Decrypt a filesystem block in-place
284284
* @inode: The inode to which this block belongs
285285
* @page: The page containing the block to decrypt
286-
* @len: Size of block to decrypt. Doesn't need to be a multiple of the
287-
* fs block size, but must be a multiple of FS_CRYPTO_BLOCK_SIZE.
286+
* @len: Size of block to decrypt. This must be a multiple of
287+
* FSCRYPT_CONTENTS_ALIGNMENT.
288288
* @offs: Byte offset within @page at which the block to decrypt begins
289289
* @lblk_num: Filesystem logical block number of the block, i.e. the 0-based
290290
* number of the block within the file

fs/crypto/fname.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@
1818
#include <crypto/skcipher.h>
1919
#include "fscrypt_private.h"
2020

21+
/*
22+
* The minimum message length (input and output length), in bytes, for all
23+
* filenames encryption modes. Filenames shorter than this will be zero-padded
24+
* before being encrypted.
25+
*/
26+
#define FSCRYPT_FNAME_MIN_MSG_LEN 16
27+
2128
/*
2229
* struct fscrypt_nokey_name - identifier for directory entry when key is absent
2330
*
@@ -267,7 +274,7 @@ bool fscrypt_fname_encrypted_size(const union fscrypt_policy *policy,
267274

268275
if (orig_len > max_len)
269276
return false;
270-
encrypted_len = max(orig_len, (u32)FS_CRYPTO_BLOCK_SIZE);
277+
encrypted_len = max_t(u32, orig_len, FSCRYPT_FNAME_MIN_MSG_LEN);
271278
encrypted_len = round_up(encrypted_len, padding);
272279
*encrypted_len_ret = min(encrypted_len, max_len);
273280
return true;
@@ -350,7 +357,7 @@ int fscrypt_fname_disk_to_usr(const struct inode *inode,
350357
return 0;
351358
}
352359

353-
if (iname->len < FS_CRYPTO_BLOCK_SIZE)
360+
if (iname->len < FSCRYPT_FNAME_MIN_MSG_LEN)
354361
return -EUCLEAN;
355362

356363
if (fscrypt_has_encryption_key(inode))

fs/crypto/fscrypt_private.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -545,8 +545,8 @@ struct key *
545545
fscrypt_find_master_key(struct super_block *sb,
546546
const struct fscrypt_key_specifier *mk_spec);
547547

548-
int fscrypt_add_test_dummy_key(struct super_block *sb,
549-
struct fscrypt_key_specifier *key_spec);
548+
int fscrypt_get_test_dummy_key_identifier(
549+
u8 key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]);
550550

551551
int fscrypt_verify_key_added(struct super_block *sb,
552552
const u8 identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]);
@@ -561,7 +561,9 @@ struct fscrypt_mode {
561561
int keysize; /* key size in bytes */
562562
int security_strength; /* security strength in bytes */
563563
int ivsize; /* IV size in bytes */
564-
int logged_impl_name;
564+
int logged_cryptoapi_impl;
565+
int logged_blk_crypto_native;
566+
int logged_blk_crypto_fallback;
565567
enum blk_crypto_mode_num blk_crypto_mode;
566568
};
567569

@@ -621,6 +623,8 @@ int fscrypt_setup_v1_file_key_via_subscribed_keyrings(struct fscrypt_info *ci);
621623

622624
bool fscrypt_policies_equal(const union fscrypt_policy *policy1,
623625
const union fscrypt_policy *policy2);
626+
int fscrypt_policy_to_key_spec(const union fscrypt_policy *policy,
627+
struct fscrypt_key_specifier *key_spec);
624628
bool fscrypt_supported_policy(const union fscrypt_policy *policy_u,
625629
const struct inode *inode);
626630
int fscrypt_policy_from_context(union fscrypt_policy *policy_u,

fs/crypto/inline_crypt.c

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* provides the key and IV to use.
1313
*/
1414

15-
#include <linux/blk-crypto.h>
15+
#include <linux/blk-crypto-profile.h>
1616
#include <linux/blkdev.h>
1717
#include <linux/buffer_head.h>
1818
#include <linux/sched/mm.h>
@@ -64,6 +64,35 @@ static unsigned int fscrypt_get_dun_bytes(const struct fscrypt_info *ci)
6464
return DIV_ROUND_UP(lblk_bits, 8);
6565
}
6666

67+
/*
68+
* Log a message when starting to use blk-crypto (native) or blk-crypto-fallback
69+
* for an encryption mode for the first time. This is the blk-crypto
70+
* counterpart to the message logged when starting to use the crypto API for the
71+
* first time. A limitation is that these messages don't convey which specific
72+
* filesystems or files are using each implementation. However, *usually*
73+
* systems use just one implementation per mode, which makes these messages
74+
* helpful for debugging problems where the "wrong" implementation is used.
75+
*/
76+
static void fscrypt_log_blk_crypto_impl(struct fscrypt_mode *mode,
77+
struct request_queue **devs,
78+
int num_devs,
79+
const struct blk_crypto_config *cfg)
80+
{
81+
int i;
82+
83+
for (i = 0; i < num_devs; i++) {
84+
if (!IS_ENABLED(CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK) ||
85+
__blk_crypto_cfg_supported(devs[i]->crypto_profile, cfg)) {
86+
if (!xchg(&mode->logged_blk_crypto_native, 1))
87+
pr_info("fscrypt: %s using blk-crypto (native)\n",
88+
mode->friendly_name);
89+
} else if (!xchg(&mode->logged_blk_crypto_fallback, 1)) {
90+
pr_info("fscrypt: %s using blk-crypto-fallback\n",
91+
mode->friendly_name);
92+
}
93+
}
94+
}
95+
6796
/* Enable inline encryption for this file if supported. */
6897
int fscrypt_select_encryption_impl(struct fscrypt_info *ci)
6998
{
@@ -117,6 +146,8 @@ int fscrypt_select_encryption_impl(struct fscrypt_info *ci)
117146
goto out_free_devs;
118147
}
119148

149+
fscrypt_log_blk_crypto_impl(ci->ci_mode, devs, num_devs, &crypto_cfg);
150+
120151
ci->ci_inlinecrypt = true;
121152
out_free_devs:
122153
kfree(devs);

fs/crypto/keyring.c

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -688,28 +688,68 @@ int fscrypt_ioctl_add_key(struct file *filp, void __user *_uarg)
688688
}
689689
EXPORT_SYMBOL_GPL(fscrypt_ioctl_add_key);
690690

691-
/*
692-
* Add the key for '-o test_dummy_encryption' to the filesystem keyring.
693-
*
694-
* Use a per-boot random key to prevent people from misusing this option.
695-
*/
696-
int fscrypt_add_test_dummy_key(struct super_block *sb,
697-
struct fscrypt_key_specifier *key_spec)
691+
static void
692+
fscrypt_get_test_dummy_secret(struct fscrypt_master_key_secret *secret)
698693
{
699694
static u8 test_key[FSCRYPT_MAX_KEY_SIZE];
695+
696+
get_random_once(test_key, FSCRYPT_MAX_KEY_SIZE);
697+
698+
memset(secret, 0, sizeof(*secret));
699+
secret->size = FSCRYPT_MAX_KEY_SIZE;
700+
memcpy(secret->raw, test_key, FSCRYPT_MAX_KEY_SIZE);
701+
}
702+
703+
int fscrypt_get_test_dummy_key_identifier(
704+
u8 key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE])
705+
{
700706
struct fscrypt_master_key_secret secret;
701707
int err;
702708

703-
get_random_once(test_key, FSCRYPT_MAX_KEY_SIZE);
709+
fscrypt_get_test_dummy_secret(&secret);
704710

705-
memset(&secret, 0, sizeof(secret));
706-
secret.size = FSCRYPT_MAX_KEY_SIZE;
707-
memcpy(secret.raw, test_key, FSCRYPT_MAX_KEY_SIZE);
711+
err = fscrypt_init_hkdf(&secret.hkdf, secret.raw, secret.size);
712+
if (err)
713+
goto out;
714+
err = fscrypt_hkdf_expand(&secret.hkdf, HKDF_CONTEXT_KEY_IDENTIFIER,
715+
NULL, 0, key_identifier,
716+
FSCRYPT_KEY_IDENTIFIER_SIZE);
717+
out:
718+
wipe_master_key_secret(&secret);
719+
return err;
720+
}
721+
722+
/**
723+
* fscrypt_add_test_dummy_key() - add the test dummy encryption key
724+
* @sb: the filesystem instance to add the key to
725+
* @dummy_policy: the encryption policy for test_dummy_encryption
726+
*
727+
* If needed, add the key for the test_dummy_encryption mount option to the
728+
* filesystem. To prevent misuse of this mount option, a per-boot random key is
729+
* used instead of a hardcoded one. This makes it so that any encrypted files
730+
* created using this option won't be accessible after a reboot.
731+
*
732+
* Return: 0 on success, -errno on failure
733+
*/
734+
int fscrypt_add_test_dummy_key(struct super_block *sb,
735+
const struct fscrypt_dummy_policy *dummy_policy)
736+
{
737+
const union fscrypt_policy *policy = dummy_policy->policy;
738+
struct fscrypt_key_specifier key_spec;
739+
struct fscrypt_master_key_secret secret;
740+
int err;
708741

709-
err = add_master_key(sb, &secret, key_spec);
742+
if (!policy)
743+
return 0;
744+
err = fscrypt_policy_to_key_spec(policy, &key_spec);
745+
if (err)
746+
return err;
747+
fscrypt_get_test_dummy_secret(&secret);
748+
err = add_master_key(sb, &secret, &key_spec);
710749
wipe_master_key_secret(&secret);
711750
return err;
712751
}
752+
EXPORT_SYMBOL_GPL(fscrypt_add_test_dummy_key);
713753

714754
/*
715755
* Verify that the current user has added a master key with the given identifier

fs/crypto/keysetup.c

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ fscrypt_allocate_skcipher(struct fscrypt_mode *mode, const u8 *raw_key,
9494
mode->cipher_str, PTR_ERR(tfm));
9595
return tfm;
9696
}
97-
if (!xchg(&mode->logged_impl_name, 1)) {
97+
if (!xchg(&mode->logged_cryptoapi_impl, 1)) {
9898
/*
9999
* fscrypt performance can vary greatly depending on which
100100
* crypto algorithm implementation is used. Help people debug
@@ -425,23 +425,9 @@ static int setup_file_encryption_key(struct fscrypt_info *ci,
425425
if (err)
426426
return err;
427427

428-
switch (ci->ci_policy.version) {
429-
case FSCRYPT_POLICY_V1:
430-
mk_spec.type = FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR;
431-
memcpy(mk_spec.u.descriptor,
432-
ci->ci_policy.v1.master_key_descriptor,
433-
FSCRYPT_KEY_DESCRIPTOR_SIZE);
434-
break;
435-
case FSCRYPT_POLICY_V2:
436-
mk_spec.type = FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER;
437-
memcpy(mk_spec.u.identifier,
438-
ci->ci_policy.v2.master_key_identifier,
439-
FSCRYPT_KEY_IDENTIFIER_SIZE);
440-
break;
441-
default:
442-
WARN_ON(1);
443-
return -EINVAL;
444-
}
428+
err = fscrypt_policy_to_key_spec(&ci->ci_policy, &mk_spec);
429+
if (err)
430+
return err;
445431

446432
key = fscrypt_find_master_key(ci->ci_inode->i_sb, &mk_spec);
447433
if (IS_ERR(key)) {

0 commit comments

Comments
 (0)