Skip to content

Commit 690b256

Browse files
committed
Merge tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt
Pull fscrypt updates from Eric Biggers: "This release, we add support for inline encryption via the blk-crypto framework which was added in 5.8. Now when an ext4 or f2fs filesystem is mounted with '-o inlinecrypt', the contents of encrypted files will be encrypted/decrypted via blk-crypto, instead of directly using the crypto API. This model allows taking advantage of the inline encryption hardware that is integrated into the UFS or eMMC host controllers on most mobile SoCs. Note that this is just an alternate implementation; the ciphertext written to disk stays the same. (This pull request does *not* include support for direct I/O on encrypted files, which blk-crypto makes possible, since that part is still being discussed.) Besides the above feature update, there are also a few fixes and cleanups, e.g. strengthening some memory barriers that may be too weak. All these patches have been in linux-next with no reported issues. I've also tested them with the fscrypt xfstests, as usual. It's also been tested that the inline encryption support works with the support for Qualcomm and Mediatek inline encryption hardware that will be in the scsi pull request for 5.9. Also, several SoC vendors are already using a previous, functionally equivalent version of these patches" * tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt: fscrypt: don't load ->i_crypt_info before it's known to be valid fscrypt: document inline encryption support fscrypt: use smp_load_acquire() for ->i_crypt_info fscrypt: use smp_load_acquire() for ->s_master_keys fscrypt: use smp_load_acquire() for fscrypt_prepared_key fscrypt: switch fscrypt_do_sha256() to use the SHA-256 library fscrypt: restrict IV_INO_LBLK_* to AES-256-XTS fscrypt: rename FS_KEY_DERIVATION_NONCE_SIZE fscrypt: add comments that describe the HKDF info strings ext4: add inline encryption support f2fs: add inline encryption support fscrypt: add inline encryption support fs: introduce SB_INLINECRYPT
2 parents 6dec9f4 + 55e32c5 commit 690b256

File tree

24 files changed

+940
-139
lines changed

24 files changed

+940
-139
lines changed

Documentation/admin-guide/ext4.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,13 @@ When mounting an ext4 filesystem, the following option are accepted:
395395
Documentation/filesystems/dax.txt. Note that this option is
396396
incompatible with data=journal.
397397

398+
inlinecrypt
399+
When possible, encrypt/decrypt the contents of encrypted files using the
400+
blk-crypto framework rather than filesystem-layer encryption. This
401+
allows the use of inline encryption hardware. The on-disk format is
402+
unaffected. For more details, see
403+
Documentation/block/inline-encryption.rst.
404+
398405
Data Mode
399406
=========
400407
There are 3 different data modes:

Documentation/filesystems/f2fs.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,13 @@ compress_extension=%s Support adding specified extension, so that f2fs can enab
258258
on compression extension list and enable compression on
259259
these file by default rather than to enable it via ioctl.
260260
For other files, we can still enable compression via ioctl.
261+
inlinecrypt
262+
When possible, encrypt/decrypt the contents of encrypted
263+
files using the blk-crypto framework rather than
264+
filesystem-layer encryption. This allows the use of
265+
inline encryption hardware. The on-disk format is
266+
unaffected. For more details, see
267+
Documentation/block/inline-encryption.rst.
261268
====================== ============================================================
262269

263270
Debugfs Entries

Documentation/filesystems/fscrypt.rst

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,7 +1158,7 @@ setxattr() because of the special semantics of the encryption xattr.
11581158
were to be added to or removed from anything other than an empty
11591159
directory.) These structs are defined as follows::
11601160

1161-
#define FS_KEY_DERIVATION_NONCE_SIZE 16
1161+
#define FSCRYPT_FILE_NONCE_SIZE 16
11621162

11631163
#define FSCRYPT_KEY_DESCRIPTOR_SIZE 8
11641164
struct fscrypt_context_v1 {
@@ -1167,7 +1167,7 @@ directory.) These structs are defined as follows::
11671167
u8 filenames_encryption_mode;
11681168
u8 flags;
11691169
u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE];
1170-
u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE];
1170+
u8 nonce[FSCRYPT_FILE_NONCE_SIZE];
11711171
};
11721172

11731173
#define FSCRYPT_KEY_IDENTIFIER_SIZE 16
@@ -1178,7 +1178,7 @@ directory.) These structs are defined as follows::
11781178
u8 flags;
11791179
u8 __reserved[4];
11801180
u8 master_key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE];
1181-
u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE];
1181+
u8 nonce[FSCRYPT_FILE_NONCE_SIZE];
11821182
};
11831183

11841184
The context structs contain the same information as the corresponding
@@ -1204,6 +1204,18 @@ buffer. Some filesystems, such as UBIFS, already use temporary
12041204
buffers regardless of encryption. Other filesystems, such as ext4 and
12051205
F2FS, have to allocate bounce pages specially for encryption.
12061206

1207+
Fscrypt is also able to use inline encryption hardware instead of the
1208+
kernel crypto API for en/decryption of file contents. When possible,
1209+
and if directed to do so (by specifying the 'inlinecrypt' mount option
1210+
for an ext4/F2FS filesystem), it adds encryption contexts to bios and
1211+
uses blk-crypto to perform the en/decryption instead of making use of
1212+
the above read/write path changes. Of course, even if directed to
1213+
make use of inline encryption, fscrypt will only be able to do so if
1214+
either hardware inline encryption support is available for the
1215+
selected encryption algorithm or CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK
1216+
is selected. If neither is the case, fscrypt will fall back to using
1217+
the above mentioned read/write path changes for en/decryption.
1218+
12071219
Filename hashing and encoding
12081220
-----------------------------
12091221

@@ -1250,11 +1262,14 @@ Tests
12501262

12511263
To test fscrypt, use xfstests, which is Linux's de facto standard
12521264
filesystem test suite. First, run all the tests in the "encrypt"
1253-
group on the relevant filesystem(s). For example, to test ext4 and
1265+
group on the relevant filesystem(s). One can also run the tests
1266+
with the 'inlinecrypt' mount option to test the implementation for
1267+
inline encryption support. For example, to test ext4 and
12541268
f2fs encryption using `kvm-xfstests
12551269
<https://github.com/tytso/xfstests-bld/blob/master/Documentation/kvm-quickstart.md>`_::
12561270

12571271
kvm-xfstests -c ext4,f2fs -g encrypt
1272+
kvm-xfstests -c ext4,f2fs -g encrypt -m inlinecrypt
12581273

12591274
UBIFS encryption can also be tested this way, but it should be done in
12601275
a separate command, and it takes some time for kvm-xfstests to set up
@@ -1276,10 +1291,12 @@ This tests the encrypted I/O paths more thoroughly. To do this with
12761291
kvm-xfstests, use the "encrypt" filesystem configuration::
12771292

12781293
kvm-xfstests -c ext4/encrypt,f2fs/encrypt -g auto
1294+
kvm-xfstests -c ext4/encrypt,f2fs/encrypt -g auto -m inlinecrypt
12791295

12801296
Because this runs many more tests than "-g encrypt" does, it takes
12811297
much longer to run; so also consider using `gce-xfstests
12821298
<https://github.com/tytso/xfstests-bld/blob/master/Documentation/gce-xfstests.md>`_
12831299
instead of kvm-xfstests::
12841300

12851301
gce-xfstests -c ext4/encrypt,f2fs/encrypt -g auto
1302+
gce-xfstests -c ext4/encrypt,f2fs/encrypt -g auto -m inlinecrypt

fs/buffer.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -320,9 +320,8 @@ static void decrypt_bh(struct work_struct *work)
320320
static void end_buffer_async_read_io(struct buffer_head *bh, int uptodate)
321321
{
322322
/* Decrypt if needed */
323-
if (uptodate && IS_ENABLED(CONFIG_FS_ENCRYPTION) &&
324-
IS_ENCRYPTED(bh->b_page->mapping->host) &&
325-
S_ISREG(bh->b_page->mapping->host->i_mode)) {
323+
if (uptodate &&
324+
fscrypt_inode_uses_fs_layer_crypto(bh->b_page->mapping->host)) {
326325
struct decrypt_bh_ctx *ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC);
327326

328327
if (ctx) {
@@ -3046,6 +3045,8 @@ static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh,
30463045
*/
30473046
bio = bio_alloc(GFP_NOIO, 1);
30483047

3048+
fscrypt_set_bio_crypt_ctx_bh(bio, bh, GFP_NOIO);
3049+
30493050
bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >> 9);
30503051
bio_set_dev(bio, bh->b_bdev);
30513052
bio->bi_write_hint = write_hint;

fs/crypto/Kconfig

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ config FS_ENCRYPTION
44
select CRYPTO
55
select CRYPTO_HASH
66
select CRYPTO_SKCIPHER
7+
select CRYPTO_LIB_SHA256
78
select KEYS
89
help
910
Enable encryption of files and directories. This
@@ -21,6 +22,11 @@ config FS_ENCRYPTION_ALGS
2122
select CRYPTO_CTS
2223
select CRYPTO_ECB
2324
select CRYPTO_HMAC
24-
select CRYPTO_SHA256
2525
select CRYPTO_SHA512
2626
select CRYPTO_XTS
27+
28+
config FS_ENCRYPTION_INLINE_CRYPT
29+
bool "Enable fscrypt to use inline crypto"
30+
depends on FS_ENCRYPTION && BLK_INLINE_ENCRYPTION
31+
help
32+
Enable fscrypt to use inline encryption hardware if available.

fs/crypto/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ fscrypto-y := crypto.o \
1111
policy.o
1212

1313
fscrypto-$(CONFIG_BLOCK) += bio.o
14+
fscrypto-$(CONFIG_FS_ENCRYPTION_INLINE_CRYPT) += inline_crypt.o

fs/crypto/bio.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,53 @@ void fscrypt_decrypt_bio(struct bio *bio)
4141
}
4242
EXPORT_SYMBOL(fscrypt_decrypt_bio);
4343

44+
static int fscrypt_zeroout_range_inline_crypt(const struct inode *inode,
45+
pgoff_t lblk, sector_t pblk,
46+
unsigned int len)
47+
{
48+
const unsigned int blockbits = inode->i_blkbits;
49+
const unsigned int blocks_per_page = 1 << (PAGE_SHIFT - blockbits);
50+
struct bio *bio;
51+
int ret, err = 0;
52+
int num_pages = 0;
53+
54+
/* This always succeeds since __GFP_DIRECT_RECLAIM is set. */
55+
bio = bio_alloc(GFP_NOFS, BIO_MAX_PAGES);
56+
57+
while (len) {
58+
unsigned int blocks_this_page = min(len, blocks_per_page);
59+
unsigned int bytes_this_page = blocks_this_page << blockbits;
60+
61+
if (num_pages == 0) {
62+
fscrypt_set_bio_crypt_ctx(bio, inode, lblk, GFP_NOFS);
63+
bio_set_dev(bio, inode->i_sb->s_bdev);
64+
bio->bi_iter.bi_sector =
65+
pblk << (blockbits - SECTOR_SHIFT);
66+
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
67+
}
68+
ret = bio_add_page(bio, ZERO_PAGE(0), bytes_this_page, 0);
69+
if (WARN_ON(ret != bytes_this_page)) {
70+
err = -EIO;
71+
goto out;
72+
}
73+
num_pages++;
74+
len -= blocks_this_page;
75+
lblk += blocks_this_page;
76+
pblk += blocks_this_page;
77+
if (num_pages == BIO_MAX_PAGES || !len ||
78+
!fscrypt_mergeable_bio(bio, inode, lblk)) {
79+
err = submit_bio_wait(bio);
80+
if (err)
81+
goto out;
82+
bio_reset(bio);
83+
num_pages = 0;
84+
}
85+
}
86+
out:
87+
bio_put(bio);
88+
return err;
89+
}
90+
4491
/**
4592
* fscrypt_zeroout_range() - zero out a range of blocks in an encrypted file
4693
* @inode: the file's inode
@@ -75,6 +122,10 @@ int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk,
75122
if (len == 0)
76123
return 0;
77124

125+
if (fscrypt_inode_uses_inline_crypto(inode))
126+
return fscrypt_zeroout_range_inline_crypt(inode, lblk, pblk,
127+
len);
128+
78129
BUILD_BUG_ON(ARRAY_SIZE(pages) > BIO_MAX_PAGES);
79130
nr_pages = min_t(unsigned int, ARRAY_SIZE(pages),
80131
(len + blocks_per_page - 1) >> blocks_per_page_bits);

fs/crypto/crypto.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num,
8484
WARN_ON_ONCE(lblk_num > U32_MAX);
8585
lblk_num = (u32)(ci->ci_hashed_ino + lblk_num);
8686
} else if (flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY) {
87-
memcpy(iv->nonce, ci->ci_nonce, FS_KEY_DERIVATION_NONCE_SIZE);
87+
memcpy(iv->nonce, ci->ci_nonce, FSCRYPT_FILE_NONCE_SIZE);
8888
}
8989
iv->lblk_num = cpu_to_le64(lblk_num);
9090
}
@@ -100,7 +100,7 @@ int fscrypt_crypt_block(const struct inode *inode, fscrypt_direction_t rw,
100100
DECLARE_CRYPTO_WAIT(wait);
101101
struct scatterlist dst, src;
102102
struct fscrypt_info *ci = inode->i_crypt_info;
103-
struct crypto_skcipher *tfm = ci->ci_ctfm;
103+
struct crypto_skcipher *tfm = ci->ci_enc_key.tfm;
104104
int res = 0;
105105

106106
if (WARN_ON_ONCE(len <= 0))

fs/crypto/fname.c

Lines changed: 12 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -61,30 +61,13 @@ struct fscrypt_nokey_name {
6161
*/
6262
#define FSCRYPT_NOKEY_NAME_MAX offsetofend(struct fscrypt_nokey_name, sha256)
6363

64-
static struct crypto_shash *sha256_hash_tfm;
65-
66-
static int fscrypt_do_sha256(const u8 *data, unsigned int data_len, u8 *result)
64+
static void fscrypt_do_sha256(const u8 *data, unsigned int data_len, u8 *result)
6765
{
68-
struct crypto_shash *tfm = READ_ONCE(sha256_hash_tfm);
69-
70-
if (unlikely(!tfm)) {
71-
struct crypto_shash *prev_tfm;
72-
73-
tfm = crypto_alloc_shash("sha256", 0, 0);
74-
if (IS_ERR(tfm)) {
75-
fscrypt_err(NULL,
76-
"Error allocating SHA-256 transform: %ld",
77-
PTR_ERR(tfm));
78-
return PTR_ERR(tfm);
79-
}
80-
prev_tfm = cmpxchg(&sha256_hash_tfm, NULL, tfm);
81-
if (prev_tfm) {
82-
crypto_free_shash(tfm);
83-
tfm = prev_tfm;
84-
}
85-
}
66+
struct sha256_state sctx;
8667

87-
return crypto_shash_tfm_digest(tfm, data, data_len, result);
68+
sha256_init(&sctx);
69+
sha256_update(&sctx, data, data_len);
70+
sha256_final(&sctx, result);
8871
}
8972

9073
static inline bool fscrypt_is_dot_dotdot(const struct qstr *str)
@@ -115,7 +98,7 @@ int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname,
11598
struct skcipher_request *req = NULL;
11699
DECLARE_CRYPTO_WAIT(wait);
117100
const struct fscrypt_info *ci = inode->i_crypt_info;
118-
struct crypto_skcipher *tfm = ci->ci_ctfm;
101+
struct crypto_skcipher *tfm = ci->ci_enc_key.tfm;
119102
union fscrypt_iv iv;
120103
struct scatterlist sg;
121104
int res;
@@ -171,7 +154,7 @@ static int fname_decrypt(const struct inode *inode,
171154
DECLARE_CRYPTO_WAIT(wait);
172155
struct scatterlist src_sg, dst_sg;
173156
const struct fscrypt_info *ci = inode->i_crypt_info;
174-
struct crypto_skcipher *tfm = ci->ci_ctfm;
157+
struct crypto_skcipher *tfm = ci->ci_enc_key.tfm;
175158
union fscrypt_iv iv;
176159
int res;
177160

@@ -349,7 +332,6 @@ int fscrypt_fname_disk_to_usr(const struct inode *inode,
349332
const struct qstr qname = FSTR_TO_QSTR(iname);
350333
struct fscrypt_nokey_name nokey_name;
351334
u32 size; /* size of the unencoded no-key name */
352-
int err;
353335

354336
if (fscrypt_is_dot_dotdot(&qname)) {
355337
oname->name[0] = '.';
@@ -387,11 +369,9 @@ int fscrypt_fname_disk_to_usr(const struct inode *inode,
387369
} else {
388370
memcpy(nokey_name.bytes, iname->name, sizeof(nokey_name.bytes));
389371
/* Compute strong hash of remaining part of name. */
390-
err = fscrypt_do_sha256(&iname->name[sizeof(nokey_name.bytes)],
391-
iname->len - sizeof(nokey_name.bytes),
392-
nokey_name.sha256);
393-
if (err)
394-
return err;
372+
fscrypt_do_sha256(&iname->name[sizeof(nokey_name.bytes)],
373+
iname->len - sizeof(nokey_name.bytes),
374+
nokey_name.sha256);
395375
size = FSCRYPT_NOKEY_NAME_MAX;
396376
}
397377
oname->len = base64_encode((const u8 *)&nokey_name, size, oname->name);
@@ -530,9 +510,8 @@ bool fscrypt_match_name(const struct fscrypt_name *fname,
530510
return false;
531511
if (memcmp(de_name, nokey_name->bytes, sizeof(nokey_name->bytes)))
532512
return false;
533-
if (fscrypt_do_sha256(&de_name[sizeof(nokey_name->bytes)],
534-
de_name_len - sizeof(nokey_name->bytes), sha256))
535-
return false;
513+
fscrypt_do_sha256(&de_name[sizeof(nokey_name->bytes)],
514+
de_name_len - sizeof(nokey_name->bytes), sha256);
536515
return !memcmp(sha256, nokey_name->sha256, sizeof(sha256));
537516
}
538517
EXPORT_SYMBOL_GPL(fscrypt_match_name);

0 commit comments

Comments
 (0)