162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Inline encryption support for fscrypt 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright 2019 Google LLC 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci/* 962306a36Sopenharmony_ci * With "inline encryption", the block layer handles the decryption/encryption 1062306a36Sopenharmony_ci * as part of the bio, instead of the filesystem doing the crypto itself via 1162306a36Sopenharmony_ci * crypto API. See Documentation/block/inline-encryption.rst. fscrypt still 1262306a36Sopenharmony_ci * provides the key and IV to use. 1362306a36Sopenharmony_ci */ 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include <linux/blk-crypto.h> 1662306a36Sopenharmony_ci#include <linux/blkdev.h> 1762306a36Sopenharmony_ci#include <linux/buffer_head.h> 1862306a36Sopenharmony_ci#include <linux/sched/mm.h> 1962306a36Sopenharmony_ci#include <linux/slab.h> 2062306a36Sopenharmony_ci#include <linux/uio.h> 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#include "fscrypt_private.h" 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cistatic struct block_device **fscrypt_get_devices(struct super_block *sb, 2562306a36Sopenharmony_ci unsigned int *num_devs) 2662306a36Sopenharmony_ci{ 2762306a36Sopenharmony_ci struct block_device **devs; 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci if (sb->s_cop->get_devices) { 3062306a36Sopenharmony_ci devs = sb->s_cop->get_devices(sb, num_devs); 3162306a36Sopenharmony_ci if (devs) 3262306a36Sopenharmony_ci return devs; 3362306a36Sopenharmony_ci } 3462306a36Sopenharmony_ci devs = kmalloc(sizeof(*devs), GFP_KERNEL); 3562306a36Sopenharmony_ci if (!devs) 3662306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 3762306a36Sopenharmony_ci devs[0] = sb->s_bdev; 3862306a36Sopenharmony_ci *num_devs = 1; 3962306a36Sopenharmony_ci return devs; 4062306a36Sopenharmony_ci} 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_cistatic unsigned int fscrypt_get_dun_bytes(const struct fscrypt_info *ci) 4362306a36Sopenharmony_ci{ 4462306a36Sopenharmony_ci struct super_block *sb = ci->ci_inode->i_sb; 4562306a36Sopenharmony_ci unsigned int flags = fscrypt_policy_flags(&ci->ci_policy); 4662306a36Sopenharmony_ci int ino_bits = 64, lblk_bits = 64; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci if (flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY) 4962306a36Sopenharmony_ci return offsetofend(union fscrypt_iv, nonce); 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci if (flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64) 5262306a36Sopenharmony_ci return sizeof(__le64); 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci if (flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) 5562306a36Sopenharmony_ci return sizeof(__le32); 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci /* Default case: IVs are just the file logical block number */ 5862306a36Sopenharmony_ci if (sb->s_cop->get_ino_and_lblk_bits) 5962306a36Sopenharmony_ci sb->s_cop->get_ino_and_lblk_bits(sb, &ino_bits, &lblk_bits); 6062306a36Sopenharmony_ci return DIV_ROUND_UP(lblk_bits, 8); 6162306a36Sopenharmony_ci} 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci/* 6462306a36Sopenharmony_ci * Log a message when starting to use blk-crypto (native) or blk-crypto-fallback 6562306a36Sopenharmony_ci * for an encryption mode for the first time. This is the blk-crypto 6662306a36Sopenharmony_ci * counterpart to the message logged when starting to use the crypto API for the 6762306a36Sopenharmony_ci * first time. A limitation is that these messages don't convey which specific 6862306a36Sopenharmony_ci * filesystems or files are using each implementation. However, *usually* 6962306a36Sopenharmony_ci * systems use just one implementation per mode, which makes these messages 7062306a36Sopenharmony_ci * helpful for debugging problems where the "wrong" implementation is used. 7162306a36Sopenharmony_ci */ 7262306a36Sopenharmony_cistatic void fscrypt_log_blk_crypto_impl(struct fscrypt_mode *mode, 7362306a36Sopenharmony_ci struct block_device **devs, 7462306a36Sopenharmony_ci unsigned int num_devs, 7562306a36Sopenharmony_ci const struct blk_crypto_config *cfg) 7662306a36Sopenharmony_ci{ 7762306a36Sopenharmony_ci unsigned int i; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci for (i = 0; i < num_devs; i++) { 8062306a36Sopenharmony_ci if (!IS_ENABLED(CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK) || 8162306a36Sopenharmony_ci blk_crypto_config_supported_natively(devs[i], cfg)) { 8262306a36Sopenharmony_ci if (!xchg(&mode->logged_blk_crypto_native, 1)) 8362306a36Sopenharmony_ci pr_info("fscrypt: %s using blk-crypto (native)\n", 8462306a36Sopenharmony_ci mode->friendly_name); 8562306a36Sopenharmony_ci } else if (!xchg(&mode->logged_blk_crypto_fallback, 1)) { 8662306a36Sopenharmony_ci pr_info("fscrypt: %s using blk-crypto-fallback\n", 8762306a36Sopenharmony_ci mode->friendly_name); 8862306a36Sopenharmony_ci } 8962306a36Sopenharmony_ci } 9062306a36Sopenharmony_ci} 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci/* Enable inline encryption for this file if supported. */ 9362306a36Sopenharmony_ciint fscrypt_select_encryption_impl(struct fscrypt_info *ci) 9462306a36Sopenharmony_ci{ 9562306a36Sopenharmony_ci const struct inode *inode = ci->ci_inode; 9662306a36Sopenharmony_ci struct super_block *sb = inode->i_sb; 9762306a36Sopenharmony_ci struct blk_crypto_config crypto_cfg; 9862306a36Sopenharmony_ci struct block_device **devs; 9962306a36Sopenharmony_ci unsigned int num_devs; 10062306a36Sopenharmony_ci unsigned int i; 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci /* The file must need contents encryption, not filenames encryption */ 10362306a36Sopenharmony_ci if (!S_ISREG(inode->i_mode)) 10462306a36Sopenharmony_ci return 0; 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci /* The crypto mode must have a blk-crypto counterpart */ 10762306a36Sopenharmony_ci if (ci->ci_mode->blk_crypto_mode == BLK_ENCRYPTION_MODE_INVALID) 10862306a36Sopenharmony_ci return 0; 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci /* The filesystem must be mounted with -o inlinecrypt */ 11162306a36Sopenharmony_ci if (!(sb->s_flags & SB_INLINECRYPT)) 11262306a36Sopenharmony_ci return 0; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci /* 11562306a36Sopenharmony_ci * When a page contains multiple logically contiguous filesystem blocks, 11662306a36Sopenharmony_ci * some filesystem code only calls fscrypt_mergeable_bio() for the first 11762306a36Sopenharmony_ci * block in the page. This is fine for most of fscrypt's IV generation 11862306a36Sopenharmony_ci * strategies, where contiguous blocks imply contiguous IVs. But it 11962306a36Sopenharmony_ci * doesn't work with IV_INO_LBLK_32. For now, simply exclude 12062306a36Sopenharmony_ci * IV_INO_LBLK_32 with blocksize != PAGE_SIZE from inline encryption. 12162306a36Sopenharmony_ci */ 12262306a36Sopenharmony_ci if ((fscrypt_policy_flags(&ci->ci_policy) & 12362306a36Sopenharmony_ci FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) && 12462306a36Sopenharmony_ci sb->s_blocksize != PAGE_SIZE) 12562306a36Sopenharmony_ci return 0; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci /* 12862306a36Sopenharmony_ci * On all the filesystem's block devices, blk-crypto must support the 12962306a36Sopenharmony_ci * crypto configuration that the file would use. 13062306a36Sopenharmony_ci */ 13162306a36Sopenharmony_ci crypto_cfg.crypto_mode = ci->ci_mode->blk_crypto_mode; 13262306a36Sopenharmony_ci crypto_cfg.data_unit_size = sb->s_blocksize; 13362306a36Sopenharmony_ci crypto_cfg.dun_bytes = fscrypt_get_dun_bytes(ci); 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci devs = fscrypt_get_devices(sb, &num_devs); 13662306a36Sopenharmony_ci if (IS_ERR(devs)) 13762306a36Sopenharmony_ci return PTR_ERR(devs); 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci for (i = 0; i < num_devs; i++) { 14062306a36Sopenharmony_ci if (!blk_crypto_config_supported(devs[i], &crypto_cfg)) 14162306a36Sopenharmony_ci goto out_free_devs; 14262306a36Sopenharmony_ci } 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci fscrypt_log_blk_crypto_impl(ci->ci_mode, devs, num_devs, &crypto_cfg); 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci ci->ci_inlinecrypt = true; 14762306a36Sopenharmony_ciout_free_devs: 14862306a36Sopenharmony_ci kfree(devs); 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci return 0; 15162306a36Sopenharmony_ci} 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ciint fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key, 15462306a36Sopenharmony_ci const u8 *raw_key, 15562306a36Sopenharmony_ci const struct fscrypt_info *ci) 15662306a36Sopenharmony_ci{ 15762306a36Sopenharmony_ci const struct inode *inode = ci->ci_inode; 15862306a36Sopenharmony_ci struct super_block *sb = inode->i_sb; 15962306a36Sopenharmony_ci enum blk_crypto_mode_num crypto_mode = ci->ci_mode->blk_crypto_mode; 16062306a36Sopenharmony_ci struct blk_crypto_key *blk_key; 16162306a36Sopenharmony_ci struct block_device **devs; 16262306a36Sopenharmony_ci unsigned int num_devs; 16362306a36Sopenharmony_ci unsigned int i; 16462306a36Sopenharmony_ci int err; 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci blk_key = kmalloc(sizeof(*blk_key), GFP_KERNEL); 16762306a36Sopenharmony_ci if (!blk_key) 16862306a36Sopenharmony_ci return -ENOMEM; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci err = blk_crypto_init_key(blk_key, raw_key, crypto_mode, 17162306a36Sopenharmony_ci fscrypt_get_dun_bytes(ci), sb->s_blocksize); 17262306a36Sopenharmony_ci if (err) { 17362306a36Sopenharmony_ci fscrypt_err(inode, "error %d initializing blk-crypto key", err); 17462306a36Sopenharmony_ci goto fail; 17562306a36Sopenharmony_ci } 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci /* Start using blk-crypto on all the filesystem's block devices. */ 17862306a36Sopenharmony_ci devs = fscrypt_get_devices(sb, &num_devs); 17962306a36Sopenharmony_ci if (IS_ERR(devs)) { 18062306a36Sopenharmony_ci err = PTR_ERR(devs); 18162306a36Sopenharmony_ci goto fail; 18262306a36Sopenharmony_ci } 18362306a36Sopenharmony_ci for (i = 0; i < num_devs; i++) { 18462306a36Sopenharmony_ci err = blk_crypto_start_using_key(devs[i], blk_key); 18562306a36Sopenharmony_ci if (err) 18662306a36Sopenharmony_ci break; 18762306a36Sopenharmony_ci } 18862306a36Sopenharmony_ci kfree(devs); 18962306a36Sopenharmony_ci if (err) { 19062306a36Sopenharmony_ci fscrypt_err(inode, "error %d starting to use blk-crypto", err); 19162306a36Sopenharmony_ci goto fail; 19262306a36Sopenharmony_ci } 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci /* 19562306a36Sopenharmony_ci * Pairs with the smp_load_acquire() in fscrypt_is_key_prepared(). 19662306a36Sopenharmony_ci * I.e., here we publish ->blk_key with a RELEASE barrier so that 19762306a36Sopenharmony_ci * concurrent tasks can ACQUIRE it. Note that this concurrency is only 19862306a36Sopenharmony_ci * possible for per-mode keys, not for per-file keys. 19962306a36Sopenharmony_ci */ 20062306a36Sopenharmony_ci smp_store_release(&prep_key->blk_key, blk_key); 20162306a36Sopenharmony_ci return 0; 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_cifail: 20462306a36Sopenharmony_ci kfree_sensitive(blk_key); 20562306a36Sopenharmony_ci return err; 20662306a36Sopenharmony_ci} 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_civoid fscrypt_destroy_inline_crypt_key(struct super_block *sb, 20962306a36Sopenharmony_ci struct fscrypt_prepared_key *prep_key) 21062306a36Sopenharmony_ci{ 21162306a36Sopenharmony_ci struct blk_crypto_key *blk_key = prep_key->blk_key; 21262306a36Sopenharmony_ci struct block_device **devs; 21362306a36Sopenharmony_ci unsigned int num_devs; 21462306a36Sopenharmony_ci unsigned int i; 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci if (!blk_key) 21762306a36Sopenharmony_ci return; 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci /* Evict the key from all the filesystem's block devices. */ 22062306a36Sopenharmony_ci devs = fscrypt_get_devices(sb, &num_devs); 22162306a36Sopenharmony_ci if (!IS_ERR(devs)) { 22262306a36Sopenharmony_ci for (i = 0; i < num_devs; i++) 22362306a36Sopenharmony_ci blk_crypto_evict_key(devs[i], blk_key); 22462306a36Sopenharmony_ci kfree(devs); 22562306a36Sopenharmony_ci } 22662306a36Sopenharmony_ci kfree_sensitive(blk_key); 22762306a36Sopenharmony_ci} 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_cibool __fscrypt_inode_uses_inline_crypto(const struct inode *inode) 23062306a36Sopenharmony_ci{ 23162306a36Sopenharmony_ci return inode->i_crypt_info->ci_inlinecrypt; 23262306a36Sopenharmony_ci} 23362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(__fscrypt_inode_uses_inline_crypto); 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_cistatic void fscrypt_generate_dun(const struct fscrypt_info *ci, u64 lblk_num, 23662306a36Sopenharmony_ci u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE]) 23762306a36Sopenharmony_ci{ 23862306a36Sopenharmony_ci union fscrypt_iv iv; 23962306a36Sopenharmony_ci int i; 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci fscrypt_generate_iv(&iv, lblk_num, ci); 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci BUILD_BUG_ON(FSCRYPT_MAX_IV_SIZE > BLK_CRYPTO_MAX_IV_SIZE); 24462306a36Sopenharmony_ci memset(dun, 0, BLK_CRYPTO_MAX_IV_SIZE); 24562306a36Sopenharmony_ci for (i = 0; i < ci->ci_mode->ivsize/sizeof(dun[0]); i++) 24662306a36Sopenharmony_ci dun[i] = le64_to_cpu(iv.dun[i]); 24762306a36Sopenharmony_ci} 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci/** 25062306a36Sopenharmony_ci * fscrypt_set_bio_crypt_ctx() - prepare a file contents bio for inline crypto 25162306a36Sopenharmony_ci * @bio: a bio which will eventually be submitted to the file 25262306a36Sopenharmony_ci * @inode: the file's inode 25362306a36Sopenharmony_ci * @first_lblk: the first file logical block number in the I/O 25462306a36Sopenharmony_ci * @gfp_mask: memory allocation flags - these must be a waiting mask so that 25562306a36Sopenharmony_ci * bio_crypt_set_ctx can't fail. 25662306a36Sopenharmony_ci * 25762306a36Sopenharmony_ci * If the contents of the file should be encrypted (or decrypted) with inline 25862306a36Sopenharmony_ci * encryption, then assign the appropriate encryption context to the bio. 25962306a36Sopenharmony_ci * 26062306a36Sopenharmony_ci * Normally the bio should be newly allocated (i.e. no pages added yet), as 26162306a36Sopenharmony_ci * otherwise fscrypt_mergeable_bio() won't work as intended. 26262306a36Sopenharmony_ci * 26362306a36Sopenharmony_ci * The encryption context will be freed automatically when the bio is freed. 26462306a36Sopenharmony_ci */ 26562306a36Sopenharmony_civoid fscrypt_set_bio_crypt_ctx(struct bio *bio, const struct inode *inode, 26662306a36Sopenharmony_ci u64 first_lblk, gfp_t gfp_mask) 26762306a36Sopenharmony_ci{ 26862306a36Sopenharmony_ci const struct fscrypt_info *ci; 26962306a36Sopenharmony_ci u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE]; 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci if (!fscrypt_inode_uses_inline_crypto(inode)) 27262306a36Sopenharmony_ci return; 27362306a36Sopenharmony_ci ci = inode->i_crypt_info; 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci fscrypt_generate_dun(ci, first_lblk, dun); 27662306a36Sopenharmony_ci bio_crypt_set_ctx(bio, ci->ci_enc_key.blk_key, dun, gfp_mask); 27762306a36Sopenharmony_ci} 27862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(fscrypt_set_bio_crypt_ctx); 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci/* Extract the inode and logical block number from a buffer_head. */ 28162306a36Sopenharmony_cistatic bool bh_get_inode_and_lblk_num(const struct buffer_head *bh, 28262306a36Sopenharmony_ci const struct inode **inode_ret, 28362306a36Sopenharmony_ci u64 *lblk_num_ret) 28462306a36Sopenharmony_ci{ 28562306a36Sopenharmony_ci struct page *page = bh->b_page; 28662306a36Sopenharmony_ci const struct address_space *mapping; 28762306a36Sopenharmony_ci const struct inode *inode; 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci /* 29062306a36Sopenharmony_ci * The ext4 journal (jbd2) can submit a buffer_head it directly created 29162306a36Sopenharmony_ci * for a non-pagecache page. fscrypt doesn't care about these. 29262306a36Sopenharmony_ci */ 29362306a36Sopenharmony_ci mapping = page_mapping(page); 29462306a36Sopenharmony_ci if (!mapping) 29562306a36Sopenharmony_ci return false; 29662306a36Sopenharmony_ci inode = mapping->host; 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ci *inode_ret = inode; 29962306a36Sopenharmony_ci *lblk_num_ret = ((u64)page->index << (PAGE_SHIFT - inode->i_blkbits)) + 30062306a36Sopenharmony_ci (bh_offset(bh) >> inode->i_blkbits); 30162306a36Sopenharmony_ci return true; 30262306a36Sopenharmony_ci} 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci/** 30562306a36Sopenharmony_ci * fscrypt_set_bio_crypt_ctx_bh() - prepare a file contents bio for inline 30662306a36Sopenharmony_ci * crypto 30762306a36Sopenharmony_ci * @bio: a bio which will eventually be submitted to the file 30862306a36Sopenharmony_ci * @first_bh: the first buffer_head for which I/O will be submitted 30962306a36Sopenharmony_ci * @gfp_mask: memory allocation flags 31062306a36Sopenharmony_ci * 31162306a36Sopenharmony_ci * Same as fscrypt_set_bio_crypt_ctx(), except this takes a buffer_head instead 31262306a36Sopenharmony_ci * of an inode and block number directly. 31362306a36Sopenharmony_ci */ 31462306a36Sopenharmony_civoid fscrypt_set_bio_crypt_ctx_bh(struct bio *bio, 31562306a36Sopenharmony_ci const struct buffer_head *first_bh, 31662306a36Sopenharmony_ci gfp_t gfp_mask) 31762306a36Sopenharmony_ci{ 31862306a36Sopenharmony_ci const struct inode *inode; 31962306a36Sopenharmony_ci u64 first_lblk; 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci if (bh_get_inode_and_lblk_num(first_bh, &inode, &first_lblk)) 32262306a36Sopenharmony_ci fscrypt_set_bio_crypt_ctx(bio, inode, first_lblk, gfp_mask); 32362306a36Sopenharmony_ci} 32462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(fscrypt_set_bio_crypt_ctx_bh); 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci/** 32762306a36Sopenharmony_ci * fscrypt_mergeable_bio() - test whether data can be added to a bio 32862306a36Sopenharmony_ci * @bio: the bio being built up 32962306a36Sopenharmony_ci * @inode: the inode for the next part of the I/O 33062306a36Sopenharmony_ci * @next_lblk: the next file logical block number in the I/O 33162306a36Sopenharmony_ci * 33262306a36Sopenharmony_ci * When building a bio which may contain data which should undergo inline 33362306a36Sopenharmony_ci * encryption (or decryption) via fscrypt, filesystems should call this function 33462306a36Sopenharmony_ci * to ensure that the resulting bio contains only contiguous data unit numbers. 33562306a36Sopenharmony_ci * This will return false if the next part of the I/O cannot be merged with the 33662306a36Sopenharmony_ci * bio because either the encryption key would be different or the encryption 33762306a36Sopenharmony_ci * data unit numbers would be discontiguous. 33862306a36Sopenharmony_ci * 33962306a36Sopenharmony_ci * fscrypt_set_bio_crypt_ctx() must have already been called on the bio. 34062306a36Sopenharmony_ci * 34162306a36Sopenharmony_ci * This function isn't required in cases where crypto-mergeability is ensured in 34262306a36Sopenharmony_ci * another way, such as I/O targeting only a single file (and thus a single key) 34362306a36Sopenharmony_ci * combined with fscrypt_limit_io_blocks() to ensure DUN contiguity. 34462306a36Sopenharmony_ci * 34562306a36Sopenharmony_ci * Return: true iff the I/O is mergeable 34662306a36Sopenharmony_ci */ 34762306a36Sopenharmony_cibool fscrypt_mergeable_bio(struct bio *bio, const struct inode *inode, 34862306a36Sopenharmony_ci u64 next_lblk) 34962306a36Sopenharmony_ci{ 35062306a36Sopenharmony_ci const struct bio_crypt_ctx *bc = bio->bi_crypt_context; 35162306a36Sopenharmony_ci u64 next_dun[BLK_CRYPTO_DUN_ARRAY_SIZE]; 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci if (!!bc != fscrypt_inode_uses_inline_crypto(inode)) 35462306a36Sopenharmony_ci return false; 35562306a36Sopenharmony_ci if (!bc) 35662306a36Sopenharmony_ci return true; 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci /* 35962306a36Sopenharmony_ci * Comparing the key pointers is good enough, as all I/O for each key 36062306a36Sopenharmony_ci * uses the same pointer. I.e., there's currently no need to support 36162306a36Sopenharmony_ci * merging requests where the keys are the same but the pointers differ. 36262306a36Sopenharmony_ci */ 36362306a36Sopenharmony_ci if (bc->bc_key != inode->i_crypt_info->ci_enc_key.blk_key) 36462306a36Sopenharmony_ci return false; 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci fscrypt_generate_dun(inode->i_crypt_info, next_lblk, next_dun); 36762306a36Sopenharmony_ci return bio_crypt_dun_is_contiguous(bc, bio->bi_iter.bi_size, next_dun); 36862306a36Sopenharmony_ci} 36962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(fscrypt_mergeable_bio); 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci/** 37262306a36Sopenharmony_ci * fscrypt_mergeable_bio_bh() - test whether data can be added to a bio 37362306a36Sopenharmony_ci * @bio: the bio being built up 37462306a36Sopenharmony_ci * @next_bh: the next buffer_head for which I/O will be submitted 37562306a36Sopenharmony_ci * 37662306a36Sopenharmony_ci * Same as fscrypt_mergeable_bio(), except this takes a buffer_head instead of 37762306a36Sopenharmony_ci * an inode and block number directly. 37862306a36Sopenharmony_ci * 37962306a36Sopenharmony_ci * Return: true iff the I/O is mergeable 38062306a36Sopenharmony_ci */ 38162306a36Sopenharmony_cibool fscrypt_mergeable_bio_bh(struct bio *bio, 38262306a36Sopenharmony_ci const struct buffer_head *next_bh) 38362306a36Sopenharmony_ci{ 38462306a36Sopenharmony_ci const struct inode *inode; 38562306a36Sopenharmony_ci u64 next_lblk; 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ci if (!bh_get_inode_and_lblk_num(next_bh, &inode, &next_lblk)) 38862306a36Sopenharmony_ci return !bio->bi_crypt_context; 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci return fscrypt_mergeable_bio(bio, inode, next_lblk); 39162306a36Sopenharmony_ci} 39262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(fscrypt_mergeable_bio_bh); 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_ci/** 39562306a36Sopenharmony_ci * fscrypt_dio_supported() - check whether DIO (direct I/O) is supported on an 39662306a36Sopenharmony_ci * inode, as far as encryption is concerned 39762306a36Sopenharmony_ci * @inode: the inode in question 39862306a36Sopenharmony_ci * 39962306a36Sopenharmony_ci * Return: %true if there are no encryption constraints that prevent DIO from 40062306a36Sopenharmony_ci * being supported; %false if DIO is unsupported. (Note that in the 40162306a36Sopenharmony_ci * %true case, the filesystem might have other, non-encryption-related 40262306a36Sopenharmony_ci * constraints that prevent DIO from actually being supported. Also, on 40362306a36Sopenharmony_ci * encrypted files the filesystem is still responsible for only allowing 40462306a36Sopenharmony_ci * DIO when requests are filesystem-block-aligned.) 40562306a36Sopenharmony_ci */ 40662306a36Sopenharmony_cibool fscrypt_dio_supported(struct inode *inode) 40762306a36Sopenharmony_ci{ 40862306a36Sopenharmony_ci int err; 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_ci /* If the file is unencrypted, no veto from us. */ 41162306a36Sopenharmony_ci if (!fscrypt_needs_contents_encryption(inode)) 41262306a36Sopenharmony_ci return true; 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_ci /* 41562306a36Sopenharmony_ci * We only support DIO with inline crypto, not fs-layer crypto. 41662306a36Sopenharmony_ci * 41762306a36Sopenharmony_ci * To determine whether the inode is using inline crypto, we have to set 41862306a36Sopenharmony_ci * up the key if it wasn't already done. This is because in the current 41962306a36Sopenharmony_ci * design of fscrypt, the decision of whether to use inline crypto or 42062306a36Sopenharmony_ci * not isn't made until the inode's encryption key is being set up. In 42162306a36Sopenharmony_ci * the DIO read/write case, the key will always be set up already, since 42262306a36Sopenharmony_ci * the file will be open. But in the case of statx(), the key might not 42362306a36Sopenharmony_ci * be set up yet, as the file might not have been opened yet. 42462306a36Sopenharmony_ci */ 42562306a36Sopenharmony_ci err = fscrypt_require_key(inode); 42662306a36Sopenharmony_ci if (err) { 42762306a36Sopenharmony_ci /* 42862306a36Sopenharmony_ci * Key unavailable or couldn't be set up. This edge case isn't 42962306a36Sopenharmony_ci * worth worrying about; just report that DIO is unsupported. 43062306a36Sopenharmony_ci */ 43162306a36Sopenharmony_ci return false; 43262306a36Sopenharmony_ci } 43362306a36Sopenharmony_ci return fscrypt_inode_uses_inline_crypto(inode); 43462306a36Sopenharmony_ci} 43562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(fscrypt_dio_supported); 43662306a36Sopenharmony_ci 43762306a36Sopenharmony_ci/** 43862306a36Sopenharmony_ci * fscrypt_limit_io_blocks() - limit I/O blocks to avoid discontiguous DUNs 43962306a36Sopenharmony_ci * @inode: the file on which I/O is being done 44062306a36Sopenharmony_ci * @lblk: the block at which the I/O is being started from 44162306a36Sopenharmony_ci * @nr_blocks: the number of blocks we want to submit starting at @lblk 44262306a36Sopenharmony_ci * 44362306a36Sopenharmony_ci * Determine the limit to the number of blocks that can be submitted in a bio 44462306a36Sopenharmony_ci * targeting @lblk without causing a data unit number (DUN) discontiguity. 44562306a36Sopenharmony_ci * 44662306a36Sopenharmony_ci * This is normally just @nr_blocks, as normally the DUNs just increment along 44762306a36Sopenharmony_ci * with the logical blocks. (Or the file is not encrypted.) 44862306a36Sopenharmony_ci * 44962306a36Sopenharmony_ci * In rare cases, fscrypt can be using an IV generation method that allows the 45062306a36Sopenharmony_ci * DUN to wrap around within logically contiguous blocks, and that wraparound 45162306a36Sopenharmony_ci * will occur. If this happens, a value less than @nr_blocks will be returned 45262306a36Sopenharmony_ci * so that the wraparound doesn't occur in the middle of a bio, which would 45362306a36Sopenharmony_ci * cause encryption/decryption to produce wrong results. 45462306a36Sopenharmony_ci * 45562306a36Sopenharmony_ci * Return: the actual number of blocks that can be submitted 45662306a36Sopenharmony_ci */ 45762306a36Sopenharmony_ciu64 fscrypt_limit_io_blocks(const struct inode *inode, u64 lblk, u64 nr_blocks) 45862306a36Sopenharmony_ci{ 45962306a36Sopenharmony_ci const struct fscrypt_info *ci; 46062306a36Sopenharmony_ci u32 dun; 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_ci if (!fscrypt_inode_uses_inline_crypto(inode)) 46362306a36Sopenharmony_ci return nr_blocks; 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_ci if (nr_blocks <= 1) 46662306a36Sopenharmony_ci return nr_blocks; 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_ci ci = inode->i_crypt_info; 46962306a36Sopenharmony_ci if (!(fscrypt_policy_flags(&ci->ci_policy) & 47062306a36Sopenharmony_ci FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32)) 47162306a36Sopenharmony_ci return nr_blocks; 47262306a36Sopenharmony_ci 47362306a36Sopenharmony_ci /* With IV_INO_LBLK_32, the DUN can wrap around from U32_MAX to 0. */ 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_ci dun = ci->ci_hashed_ino + lblk; 47662306a36Sopenharmony_ci 47762306a36Sopenharmony_ci return min_t(u64, nr_blocks, (u64)U32_MAX + 1 - dun); 47862306a36Sopenharmony_ci} 47962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(fscrypt_limit_io_blocks); 480