[f2fs-dev] [PATCH] fsck.f2fs: fix incorrect block_addr of node/meta
Fix incorrect block_addr of node or meta inode into 0x1 during build_nat_area_bitmap(). Signed-off-by: Junling ZhengSigned-off-by: Liu Xue Signed-off-by: Sheng Yong --- fsck/mount.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/fsck/mount.c b/fsck/mount.c index 4c807f9..9360656 100644 --- a/fsck/mount.c +++ b/fsck/mount.c @@ -1664,7 +1664,14 @@ void build_nat_area_bitmap(struct f2fs_sb_info *sbi) if ((nid + i) == F2FS_NODE_INO(sbi) || (nid + i) == F2FS_META_INO(sbi)) { - ASSERT(nat_block->entries[i].block_addr != 0x0); + /* block_addr of node/meta inode should be 0x1 */ + if (le32_to_cpu(nat_block->entries[i].block_addr) != 0x1) { + FIX_MSG("ino: 0x%x node/meta inode, block_addr= 0x%x -> 0x1", + nid + i, le32_to_cpu(nat_block->entries[i].block_addr)); + nat_block->entries[i].block_addr = cpu_to_le32(0x1); + ret = dev_write_block(nat_block, block_addr); + ASSERT(ret >= 0); + } continue; } -- 1.9.1 -- Site24x7 APM Insight: Get Deep Visibility into Application Performance APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month Monitor end-to-end web transactions and take corrective actions now Troubleshoot faster and improve end-user experience. Signup Now! http://pubads.g.doubleclick.net/gampad/clk?id=272487151=/4140 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH v2] f2fs: Use cryptoapi crc32 functions
From: Keith MokThe crc function is done bit by bit. Optimize this by use cryptoapi crc32 function which is backed by h/w acceleration. Signed-off-by: Keith Mok --- fs/f2fs/Kconfig | 2 ++ fs/f2fs/checkpoint.c | 6 +++--- fs/f2fs/f2fs.h | 48 +++- fs/f2fs/super.c | 13 + 4 files changed, 45 insertions(+), 24 deletions(-) diff --git a/fs/f2fs/Kconfig b/fs/f2fs/Kconfig index b0a9dc9..f8b0e6f 100644 --- a/fs/f2fs/Kconfig +++ b/fs/f2fs/Kconfig @@ -1,6 +1,8 @@ config F2FS_FS tristate "F2FS filesystem support" depends on BLOCK + select CRYPTO + select CRYPTO_CRC32 help F2FS is based on Log-structured File System (LFS), which supports versatile "flash-friendly" features. The design has been focused on diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 3842af9..1dfaf47 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -621,7 +621,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi, goto invalid_cp1; crc = le32_to_cpu(*((__le32 *)((unsigned char *)cp_block + crc_offset))); - if (!f2fs_crc_valid(crc, cp_block, crc_offset)) + if (!f2fs_crc_valid(sbi, crc, cp_block, crc_offset)) goto invalid_cp1; pre_version = cur_cp_version(cp_block); @@ -636,7 +636,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi, goto invalid_cp2; crc = le32_to_cpu(*((__le32 *)((unsigned char *)cp_block + crc_offset))); - if (!f2fs_crc_valid(crc, cp_block, crc_offset)) + if (!f2fs_crc_valid(sbi, crc, cp_block, crc_offset)) goto invalid_cp2; cur_version = cur_cp_version(cp_block); @@ -1008,7 +1008,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) get_sit_bitmap(sbi, __bitmap_ptr(sbi, SIT_BITMAP)); get_nat_bitmap(sbi, __bitmap_ptr(sbi, NAT_BITMAP)); - crc32 = f2fs_crc32(ckpt, le32_to_cpu(ckpt->checksum_offset)); + crc32 = f2fs_crc32(sbi, ckpt, le32_to_cpu(ckpt->checksum_offset)); *((__le32 *)((unsigned char *)ckpt + le32_to_cpu(ckpt->checksum_offset))) = cpu_to_le32(crc32); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index ff79054..df1c305a 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -22,6 +22,7 @@ #include #include #include +#include #ifdef CONFIG_F2FS_CHECK_FS #define f2fs_bug_on(sbi, condition)BUG_ON(condition) @@ -84,27 +85,6 @@ struct f2fs_mount_info { #define F2FS_CLEAR_FEATURE(sb, mask) \ F2FS_SB(sb)->raw_super->feature &= ~cpu_to_le32(mask) -#define CRCPOLY_LE 0xedb88320 - -static inline __u32 f2fs_crc32(void *buf, size_t len) -{ - unsigned char *p = (unsigned char *)buf; - __u32 crc = F2FS_SUPER_MAGIC; - int i; - - while (len--) { - crc ^= *p++; - for (i = 0; i < 8; i++) - crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0); - } - return crc; -} - -static inline bool f2fs_crc_valid(__u32 blk_crc, void *buf, size_t buf_size) -{ - return f2fs_crc32(buf, buf_size) == blk_crc; -} - /* * For checkpoint manager */ @@ -844,6 +824,9 @@ struct f2fs_sb_info { struct list_head s_list; struct mutex umount_mutex; unsigned int shrinker_run_no; + + /* Reference to checksum algorithm driver via cryptoapi */ + struct crypto_shash *s_chksum_driver; }; static inline void f2fs_update_time(struct f2fs_sb_info *sbi, int type) @@ -874,6 +857,29 @@ static inline bool is_idle(struct f2fs_sb_info *sbi) /* * Inline functions */ +static inline u32 f2fs_crc32(struct f2fs_sb_info *sbi, const void *address, + unsigned int length) +{ + SHASH_DESC_ON_STACK(shash, sbi->s_chksum_driver); + u32 *ctx = (u32 *)shash_desc_ctx(shash); + int err; + + shash->tfm = sbi->s_chksum_driver; + shash->flags = 0; + *ctx = F2FS_SUPER_MAGIC; + + err = crypto_shash_update(shash, address, length); + BUG_ON(err); + + return *ctx; +} + +static inline bool f2fs_crc_valid(struct f2fs_sb_info *sbi, __u32 blk_crc, + void *buf, size_t buf_size) +{ + return f2fs_crc32(sbi, buf, buf_size) == blk_crc; +} + static inline struct f2fs_inode_info *F2FS_I(struct inode *inode) { return container_of(inode, struct f2fs_inode_info, vfs_inode); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 6134832..9630865 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -574,6 +574,8 @@ static void f2fs_put_super(struct super_block *sb) wait_for_completion(>s_kobj_unregister); sb->s_fs_info = NULL; + if (sbi->s_chksum_driver) +
Re: [f2fs-dev] [PATCH] f2fs: Use crypto crc32 functions
Will update the first BUG_ON by using SHASH_DESC_ON_STACK. 2016-03-02 10:21 GMT-08:00 Jaegeuk Kim: > Hi Keith, > >> +static inline __u32 f2fs_crc32(struct f2fs_sb_info *sbi, const void >> *address, >> +unsigned int length) >> +{ >> + struct { >> + struct shash_desc shash; >> + char ctx[4]; >> + } desc; >> + int err; >> + >> + BUG_ON(crypto_shash_descsize(sbi->s_chksum_driver) != >> sizeof(desc.ctx)); > > I can't accept this and the below BUG_ON, since this hits during the > checkpoint > procedure which is very critical for entire filesystem. > How about calling back the original method for the error cases? > > Thanks, > >> + >> + desc.shash.tfm = sbi->s_chksum_driver; >> + desc.shash.flags = 0; >> + *(u32 *)desc.ctx = F2FS_SUPER_MAGIC; >> + >> + err = crypto_shash_update(, address, length); >> + BUG_ON(err); >> + >> + return *(__u32 *)desc.ctx; >> +} >> + >> +static inline bool f2fs_crc_valid(struct f2fs_sb_info *sbi, __u32 blk_crc, >> + void *buf, size_t buf_size) >> +{ >> + return f2fs_crc32(sbi, buf, buf_size) == blk_crc; >> +} >> + >> static inline struct f2fs_inode_info *F2FS_I(struct inode *inode) >> { >> return container_of(inode, struct f2fs_inode_info, vfs_inode); >> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c >> index 6134832..9630865 100644 >> --- a/fs/f2fs/super.c >> +++ b/fs/f2fs/super.c >> @@ -574,6 +574,8 @@ static void f2fs_put_super(struct super_block *sb) >> wait_for_completion(>s_kobj_unregister); >> >> sb->s_fs_info = NULL; >> + if (sbi->s_chksum_driver) >> + crypto_free_shash(sbi->s_chksum_driver); >> kfree(sbi->raw_super); >> kfree(sbi); >> } >> @@ -1254,6 +1256,15 @@ try_onemore: >> if (!sbi) >> return -ENOMEM; >> >> + /* Load the checksum driver */ >> + sbi->s_chksum_driver = crypto_alloc_shash("crc32", 0, 0); >> + if (IS_ERR(sbi->s_chksum_driver)) { >> + f2fs_msg(sb, KERN_ERR, "Cannot load crc32 driver."); >> + err = PTR_ERR(sbi->s_chksum_driver); >> + sbi->s_chksum_driver = NULL; >> + goto free_sbi; >> + } >> + >> /* set a block size */ >> if (unlikely(!sb_set_blocksize(sb, F2FS_BLKSIZE))) { >> f2fs_msg(sb, KERN_ERR, "unable to set blocksize"); >> @@ -1506,6 +1517,8 @@ free_options: >> free_sb_buf: >> kfree(raw_super); >> free_sbi: >> + if (sbi->s_chksum_driver) >> + crypto_free_shash(sbi->s_chksum_driver); >> kfree(sbi); >> >> /* give only one another chance */ >> -- >> 2.5.1 -- Site24x7 APM Insight: Get Deep Visibility into Application Performance APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month Monitor end-to-end web transactions and take corrective actions now Troubleshoot faster and improve end-user experience. Signup Now! http://pubads.g.doubleclick.net/gampad/clk?id=272487151=/4140 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH 09/10] f2fs crypto: sync ext4_lookup and ext4_file_open
This patch tries to catch up with lookup and open policies in ext4. Signed-off-by: Jaegeuk Kim--- fs/f2fs/dir.c | 2 +- fs/f2fs/file.c | 4 fs/f2fs/namei.c | 23 +++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index f82e28b..479467e 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -855,7 +855,7 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx) if (f2fs_encrypted_inode(inode)) { err = fscrypt_get_encryption_info(inode); - if (err) + if (err && err != -ENOKEY) return err; err = fscrypt_fname_alloc_buffer(inode, F2FS_NAME_LEN, ); diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index f326764..533c2dc 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -441,6 +441,7 @@ static int f2fs_file_mmap(struct file *file, struct vm_area_struct *vma) static int f2fs_file_open(struct inode *inode, struct file *filp) { int ret = generic_file_open(inode, filp); + struct inode *dir = filp->f_path.dentry->d_parent->d_inode; if (!ret && f2fs_encrypted_inode(inode)) { ret = fscrypt_get_encryption_info(inode); @@ -449,6 +450,9 @@ static int f2fs_file_open(struct inode *inode, struct file *filp) if (!f2fs_encrypted_inode(inode)) return -ENOKEY; } + if (f2fs_encrypted_inode(dir) && + !fscrypt_has_permitted_context(dir, inode)) + return -EPERM; return ret; } diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 3bddd9f..7b07a47 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -262,6 +262,21 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry, int err = 0; unsigned int root_ino = F2FS_ROOT_INO(F2FS_I_SB(dir)); + if (f2fs_encrypted_inode(dir)) { + int res = fscrypt_get_encryption_info(dir); + + /* +* DCACHE_ENCRYPTED_WITH_KEY is set if the dentry is +* created while the directory was encrypted and we +* don't have access to the key. +*/ + if (fscrypt_has_encryption_key(dir)) + fscrypt_set_encrypted_dentry(dentry); + fscrypt_set_d_op(dentry); + if (res && res != -ENOKEY) + return ERR_PTR(res); + } + if (dentry->d_name.len > F2FS_NAME_LEN) return ERR_PTR(-ENAMETOOLONG); @@ -288,6 +303,14 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry, if (err) goto err_out; } + if (!IS_ERR(inode) && f2fs_encrypted_inode(dir) && + (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) && + !fscrypt_has_permitted_context(dir, inode)) { + bool nokey = f2fs_encrypted_inode(inode) && + !fscrypt_has_encryption_key(inode); + iput(inode); + return nokey ? ERR_PTR(-ENOKEY) : ERR_PTR(-EPERM); + } return d_splice_alias(inode, dentry); err_out: -- 2.6.3 -- Site24x7 APM Insight: Get Deep Visibility into Application Performance APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month Monitor end-to-end web transactions and take corrective actions now Troubleshoot faster and improve end-user experience. Signup Now! http://pubads.g.doubleclick.net/gampad/clk?id=272487151=/4140 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH 06/10] fs crypto: add Makefile and Kconfig
This patch adds a facility to enable per-file encryption. Arnd fixes a missing CONFIG_BLOCK check in the original patch. "The newly added generic crypto abstraction for file systems operates on 'struct bio' objects, which do not exist when CONFIG_BLOCK is disabled: fs/crypto/crypto.c: In function 'fscrypt_zeroout_range': fs/crypto/crypto.c:308:9: error: implicit declaration of function 'bio_alloc' [-Werror=implicit-function-declaration] This adds a Kconfig dependency that prevents FS_ENCRYPTION from being enabled without BLOCK." Signed-off-by: Arnd BergmannSigned-off-by: Jaegeuk Kim --- fs/Kconfig | 2 ++ fs/Makefile| 1 + fs/crypto/Kconfig | 18 ++ fs/crypto/Makefile | 3 +++ 4 files changed, 24 insertions(+) create mode 100644 fs/crypto/Kconfig create mode 100644 fs/crypto/Makefile diff --git a/fs/Kconfig b/fs/Kconfig index 9adee0d..9d75767 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -84,6 +84,8 @@ config MANDATORY_FILE_LOCKING To the best of my knowledge this is dead code that no one cares about. +source "fs/crypto/Kconfig" + source "fs/notify/Kconfig" source "fs/quota/Kconfig" diff --git a/fs/Makefile b/fs/Makefile index 79f5225..252c968 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_EVENTFD) += eventfd.o obj-$(CONFIG_USERFAULTFD) += userfaultfd.o obj-$(CONFIG_AIO) += aio.o obj-$(CONFIG_FS_DAX) += dax.o +obj-$(CONFIG_FS_ENCRYPTION)+= crypto/ obj-$(CONFIG_FILE_LOCKING) += locks.o obj-$(CONFIG_COMPAT) += compat.o compat_ioctl.o obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o diff --git a/fs/crypto/Kconfig b/fs/crypto/Kconfig new file mode 100644 index 000..92348fa --- /dev/null +++ b/fs/crypto/Kconfig @@ -0,0 +1,18 @@ +config FS_ENCRYPTION + tristate "FS Encryption (Per-file encryption)" + depends on BLOCK + select CRYPTO + select CRYPTO_AES + select CRYPTO_CBC + select CRYPTO_ECB + select CRYPTO_XTS + select CRYPTO_CTS + select CRYPTO_CTR + select CRYPTO_SHA256 + select KEYS + select ENCRYPTED_KEYS + help + Enable encryption of files and directories. This + feature is similar to ecryptfs, but it is more memory + efficient since it avoids caching the encrypted and + decrypted pages in the page cache. diff --git a/fs/crypto/Makefile b/fs/crypto/Makefile new file mode 100644 index 000..f17684c --- /dev/null +++ b/fs/crypto/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_FS_ENCRYPTION)+= fscrypto.o + +fscrypto-y := crypto.o fname.o policy.o keyinfo.o -- 2.6.3 -- Site24x7 APM Insight: Get Deep Visibility into Application Performance APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month Monitor end-to-end web transactions and take corrective actions now Troubleshoot faster and improve end-user experience. Signup Now! http://pubads.g.doubleclick.net/gampad/clk?id=272487151=/4140 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH 03/10] fs crypto: add policy.c to handle contexts
This patch adds policy.c supporting context management. 1. For ioctls: - fscrypt_process_policy - fscrypt_get_policy 2. For context permission - fscrypt_has_permitted_context - fscrypt_inherit_context Signed-off-by: Michael HalcrowSigned-off-by: Theodore Ts'o Signed-off-by: Ildar Muslukhov Signed-off-by: Jaegeuk Kim --- fs/crypto/policy.c | 229 +++ include/linux/fscrypto.h | 32 +++ 2 files changed, 261 insertions(+) create mode 100644 fs/crypto/policy.c diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c new file mode 100644 index 000..0f9961e --- /dev/null +++ b/fs/crypto/policy.c @@ -0,0 +1,229 @@ +/* + * Encryption policy functions for per-file encryption support. + * + * Copyright (C) 2015, Google, Inc. + * Copyright (C) 2015, Motorola Mobility. + * + * Written by Michael Halcrow, 2015. + * Modified by Jaegeuk Kim, 2015. + */ + +#include +#include +#include + +static int inode_has_encryption_context(struct inode *inode) +{ + if (!inode->i_sb->s_cop->get_context) + return 0; + return (inode->i_sb->s_cop->get_context(inode, NULL, 0L) > 0); +} + +/* + * check whether the policy is consistent with the encryption context + * for the inode + */ +static int is_encryption_context_consistent_with_policy(struct inode *inode, + const struct fscrypt_policy *policy) +{ + struct fscrypt_context ctx; + int res; + + if (!inode->i_sb->s_cop->get_context) + return 0; + + res = inode->i_sb->s_cop->get_context(inode, , sizeof(ctx)); + if (res != sizeof(ctx)) + return 0; + + return (memcmp(ctx.master_key_descriptor, policy->master_key_descriptor, + FS_KEY_DESCRIPTOR_SIZE) == 0 && + (ctx.flags == policy->flags) && + (ctx.contents_encryption_mode == +policy->contents_encryption_mode) && + (ctx.filenames_encryption_mode == +policy->filenames_encryption_mode)); +} + +static int create_encryption_context_from_policy(struct inode *inode, + const struct fscrypt_policy *policy) +{ + struct fscrypt_context ctx; + int res; + + if (!inode->i_sb->s_cop->set_context) + return -EOPNOTSUPP; + + if (inode->i_sb->s_cop->prepare_context) { + res = inode->i_sb->s_cop->prepare_context(inode); + if (res) + return res; + } + + ctx.format = FS_ENCRYPTION_CONTEXT_FORMAT_V1; + memcpy(ctx.master_key_descriptor, policy->master_key_descriptor, + FS_KEY_DESCRIPTOR_SIZE); + + if (!fscrypt_valid_contents_enc_mode( + policy->contents_encryption_mode)) { + printk(KERN_WARNING + "%s: Invalid contents encryption mode %d\n", __func__, + policy->contents_encryption_mode); + return -EINVAL; + } + + if (!fscrypt_valid_filenames_enc_mode( + policy->filenames_encryption_mode)) { + printk(KERN_WARNING + "%s: Invalid filenames encryption mode %d\n", __func__, + policy->filenames_encryption_mode); + return -EINVAL; + } + + if (policy->flags & ~FS_POLICY_FLAGS_VALID) + return -EINVAL; + + ctx.contents_encryption_mode = policy->contents_encryption_mode; + ctx.filenames_encryption_mode = policy->filenames_encryption_mode; + ctx.flags = policy->flags; + BUILD_BUG_ON(sizeof(ctx.nonce) != FS_KEY_DERIVATION_NONCE_SIZE); + get_random_bytes(ctx.nonce, FS_KEY_DERIVATION_NONCE_SIZE); + + return inode->i_sb->s_cop->set_context(inode, , sizeof(ctx), NULL); +} + +int fscrypt_process_policy(struct inode *inode, + const struct fscrypt_policy *policy) +{ + if (policy->version != 0) + return -EINVAL; + + if (!inode_has_encryption_context(inode)) { + if (!inode->i_sb->s_cop->empty_dir) + return -EOPNOTSUPP; + if (!inode->i_sb->s_cop->empty_dir(inode)) + return -ENOTEMPTY; + return create_encryption_context_from_policy(inode, policy); + } + + if (is_encryption_context_consistent_with_policy(inode, policy)) + return 0; + + printk(KERN_WARNING "%s: Policy inconsistent with encryption context\n", + __func__); + return -EINVAL; +} +EXPORT_SYMBOL(fscrypt_process_policy); + +int fscrypt_get_policy(struct inode *inode, struct fscrypt_policy *policy) +{ + struct fscrypt_context ctx; + int res; + + if
[f2fs-dev] [PATCH 04/10] fs crypto: add keyinfo.c to handle permissions
This patch adds keyinfo.c supporting key management. - fscrypt_get_encryption_info - fscrypt_free_encryption_info Signed-off-by: Michael HalcrowSigned-off-by: Ildar Muslukhov Signed-off-by: Theodore Ts'o Signed-off-by: Jaegeuk Kim --- fs/crypto/keyinfo.c | 278 +++ include/linux/fscrypto.h | 16 +++ 2 files changed, 294 insertions(+) create mode 100644 fs/crypto/keyinfo.c diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c new file mode 100644 index 000..cb61842 --- /dev/null +++ b/fs/crypto/keyinfo.c @@ -0,0 +1,278 @@ +/* + * key management facility for FS encryption support. + * + * Copyright (C) 2015, Google, Inc. + * + * This contains encryption key functions. + * + * Written by Michael Halcrow, Ildar Muslukhov, and Uday Savagaonkar, 2015. + */ + +#include +#include +#include +#include +#include +#include +#include + +static void derive_crypt_complete(struct crypto_async_request *req, int rc) +{ + struct fscrypt_completion_result *ecr = req->data; + + if (rc == -EINPROGRESS) + return; + + ecr->res = rc; + complete(>completion); +} + +/** + * derive_key_aes() - Derive a key using AES-128-ECB + * @deriving_key: Encryption key used for derivation. + * @source_key: Source key to which to apply derivation. + * @derived_key: Derived key. + * + * Return: Zero on success; non-zero otherwise. + */ +static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE], + u8 source_key[FS_AES_256_XTS_KEY_SIZE], + u8 derived_key[FS_AES_256_XTS_KEY_SIZE]) +{ + int res = 0; + struct ablkcipher_request *req = NULL; + DECLARE_FS_COMPLETION_RESULT(ecr); + struct scatterlist src_sg, dst_sg; + struct crypto_ablkcipher *tfm = crypto_alloc_ablkcipher("ecb(aes)", 0, + 0); + + if (IS_ERR(tfm)) { + res = PTR_ERR(tfm); + tfm = NULL; + goto out; + } + crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_REQ_WEAK_KEY); + req = ablkcipher_request_alloc(tfm, GFP_NOFS); + if (!req) { + res = -ENOMEM; + goto out; + } + ablkcipher_request_set_callback(req, + CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, + derive_crypt_complete, ); + res = crypto_ablkcipher_setkey(tfm, deriving_key, + FS_AES_128_ECB_KEY_SIZE); + if (res < 0) + goto out; + + sg_init_one(_sg, source_key, FS_AES_256_XTS_KEY_SIZE); + sg_init_one(_sg, derived_key, FS_AES_256_XTS_KEY_SIZE); + ablkcipher_request_set_crypt(req, _sg, _sg, + FS_AES_256_XTS_KEY_SIZE, NULL); + res = crypto_ablkcipher_encrypt(req); + if (res == -EINPROGRESS || res == -EBUSY) { + wait_for_completion(); + res = ecr.res; + } +out: + if (req) + ablkcipher_request_free(req); + if (tfm) + crypto_free_ablkcipher(tfm); + return res; +} + +static void put_crypt_info(struct fscrypt_info *ci) +{ + if (!ci) + return; + + if (ci->ci_keyring_key) + key_put(ci->ci_keyring_key); + crypto_free_ablkcipher(ci->ci_ctfm); + kmem_cache_free(fscrypt_info_cachep, ci); +} + +int get_crypt_info(struct inode *inode) +{ + struct fscrypt_info *crypt_info; + u8 full_key_descriptor[FS_KEY_DESC_PREFIX_SIZE + + (FS_KEY_DESCRIPTOR_SIZE * 2) + 1]; + struct key *keyring_key = NULL; + struct fscrypt_key *master_key; + struct fscrypt_context ctx; + const struct user_key_payload *ukp; + struct crypto_ablkcipher *ctfm; + const char *cipher_str; + u8 raw_key[FS_MAX_KEY_SIZE]; + u8 mode; + int res; + + res = fscrypt_initialize(); + if (res) + return res; + + if (!inode->i_sb->s_cop->get_context) + return -EOPNOTSUPP; +retry: + crypt_info = ACCESS_ONCE(inode->i_crypt_info); + if (crypt_info) { + if (!crypt_info->ci_keyring_key || + key_validate(crypt_info->ci_keyring_key) == 0) + return 0; + fscrypt_put_encryption_info(inode, crypt_info); + goto retry; + } + + res = inode->i_sb->s_cop->get_context(inode, , sizeof(ctx)); + if (res < 0) { + if (!fscrypt_dummy_context_enabled(inode)) + return res; + ctx.contents_encryption_mode = FS_ENCRYPTION_MODE_AES_256_XTS; + ctx.filenames_encryption_mode = FS_ENCRYPTION_MODE_AES_256_CTS; + ctx.flags = 0; + }
[f2fs-dev] [PATCH 10/10] ext4 crypto: migrate into vfs's crypto engine
This patch removes the most parts of internal crypto codes. And then, it modifies and adds some ext4-specific crypt codes to use the generic facility. Signed-off-by: Jaegeuk Kim--- fs/ext4/Kconfig | 12 +- fs/ext4/Makefile| 2 - fs/ext4/crypto.c| 525 fs/ext4/crypto_fname.c | 470 --- fs/ext4/crypto_key.c| 276 - fs/ext4/crypto_policy.c | 229 - fs/ext4/dir.c | 26 +-- fs/ext4/ext4.h | 195 ++ fs/ext4/ext4_crypto.h | 159 --- fs/ext4/file.c | 10 +- fs/ext4/ialloc.c| 7 +- fs/ext4/inline.c| 14 +- fs/ext4/inode.c | 8 +- fs/ext4/ioctl.c | 20 +- fs/ext4/namei.c | 120 +-- fs/ext4/page-io.c | 13 +- fs/ext4/readpage.c | 45 + fs/ext4/super.c | 85 +++- fs/ext4/symlink.c | 33 ++- 19 files changed, 271 insertions(+), 1978 deletions(-) delete mode 100644 fs/ext4/crypto.c delete mode 100644 fs/ext4/crypto_fname.c delete mode 100644 fs/ext4/crypto_key.c delete mode 100644 fs/ext4/crypto_policy.c delete mode 100644 fs/ext4/ext4_crypto.h diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig index b46e9fc..e38039f 100644 --- a/fs/ext4/Kconfig +++ b/fs/ext4/Kconfig @@ -99,17 +99,9 @@ config EXT4_FS_SECURITY extended attributes for file security labels, say N. config EXT4_ENCRYPTION - tristate "Ext4 Encryption" + bool "Ext4 Encryption" depends on EXT4_FS - select CRYPTO_AES - select CRYPTO_CBC - select CRYPTO_ECB - select CRYPTO_XTS - select CRYPTO_CTS - select CRYPTO_CTR - select CRYPTO_SHA256 - select KEYS - select ENCRYPTED_KEYS + select FS_ENCRYPTION help Enable encryption of ext4 files and directories. This feature is similar to ecryptfs, but it is more memory diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile index f52cf54..354103f 100644 --- a/fs/ext4/Makefile +++ b/fs/ext4/Makefile @@ -12,5 +12,3 @@ ext4-y:= balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o page-io.o \ ext4-$(CONFIG_EXT4_FS_POSIX_ACL) += acl.o ext4-$(CONFIG_EXT4_FS_SECURITY)+= xattr_security.o -ext4-$(CONFIG_EXT4_FS_ENCRYPTION) += crypto_policy.o crypto.o \ - crypto_key.o crypto_fname.o diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c deleted file mode 100644 index 38f7562..000 --- a/fs/ext4/crypto.c +++ /dev/null @@ -1,525 +0,0 @@ -/* - * linux/fs/ext4/crypto.c - * - * Copyright (C) 2015, Google, Inc. - * - * This contains encryption functions for ext4 - * - * Written by Michael Halcrow, 2014. - * - * Filename encryption additions - * Uday Savagaonkar, 2014 - * Encryption policy handling additions - * Ildar Muslukhov, 2014 - * - * This has not yet undergone a rigorous security audit. - * - * The usage of AES-XTS should conform to recommendations in NIST - * Special Publication 800-38E and IEEE P1619/D16. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ext4_extents.h" -#include "xattr.h" - -/* Encryption added and removed here! (L: */ - -static unsigned int num_prealloc_crypto_pages = 32; -static unsigned int num_prealloc_crypto_ctxs = 128; - -module_param(num_prealloc_crypto_pages, uint, 0444); -MODULE_PARM_DESC(num_prealloc_crypto_pages, -"Number of crypto pages to preallocate"); -module_param(num_prealloc_crypto_ctxs, uint, 0444); -MODULE_PARM_DESC(num_prealloc_crypto_ctxs, -"Number of crypto contexts to preallocate"); - -static mempool_t *ext4_bounce_page_pool; - -static LIST_HEAD(ext4_free_crypto_ctxs); -static DEFINE_SPINLOCK(ext4_crypto_ctx_lock); - -static struct kmem_cache *ext4_crypto_ctx_cachep; -struct kmem_cache *ext4_crypt_info_cachep; - -/** - * ext4_release_crypto_ctx() - Releases an encryption context - * @ctx: The encryption context to release. - * - * If the encryption context was allocated from the pre-allocated pool, returns - * it to that pool. Else, frees it. - * - * If there's a bounce page in the context, this frees that. - */ -void ext4_release_crypto_ctx(struct ext4_crypto_ctx *ctx) -{ - unsigned long flags; - - if (ctx->flags & EXT4_WRITE_PATH_FL && ctx->w.bounce_page) - mempool_free(ctx->w.bounce_page, ext4_bounce_page_pool); - ctx->w.bounce_page = NULL; - ctx->w.control_page = NULL; - if (ctx->flags & EXT4_CTX_REQUIRES_FREE_ENCRYPT_FL) { - kmem_cache_free(ext4_crypto_ctx_cachep, ctx); - } else { - spin_lock_irqsave(_crypto_ctx_lock, flags); - list_add(>free_list, _free_crypto_ctxs); -
[f2fs-dev] [PATCH v3 00/10] File-level Encryption Support by VFS
Change log from v2: - add missing Kconfig - support module compilation - change some data types to u8 Jaegeuk Kim (10): fs crypto: add basic definitions for per-file encryption fs crypto: add crypto.c for encrypt/decrypt functions fs crypto: add policy.c to handle contexts fs crypto: add keyinfo.c to handle permissions fs crypto: add fname.c to support filename encryption fs crypto: add Makefile and Kconfig fs crypto: add dentry revalidation facility in crypto f2fs crypto: migrate into vfs's crypto engine f2fs crypto: sync ext4_lookup and ext4_file_open ext4 crypto: migrate into vfs's crypto engine fs/Kconfig | 2 + fs/Makefile | 1 + fs/crypto/Kconfig| 18 ++ fs/crypto/Makefile | 3 + fs/crypto/crypto.c | 556 +++ fs/crypto/fname.c| 427 fs/crypto/keyinfo.c | 278 fs/crypto/policy.c | 229 +++ fs/ext4/Kconfig | 12 +- fs/ext4/Makefile | 2 - fs/ext4/crypto.c | 525 fs/ext4/crypto_fname.c | 470 --- fs/ext4/crypto_key.c | 276 --- fs/ext4/crypto_policy.c | 229 --- fs/ext4/dir.c| 26 ++- fs/ext4/ext4.h | 195 ++--- fs/ext4/ext4_crypto.h| 159 -- fs/ext4/file.c | 10 +- fs/ext4/ialloc.c | 7 +- fs/ext4/inline.c | 14 +- fs/ext4/inode.c | 8 +- fs/ext4/ioctl.c | 20 +- fs/ext4/namei.c | 120 +- fs/ext4/page-io.c| 13 +- fs/ext4/readpage.c | 45 +--- fs/ext4/super.c | 85 +++- fs/ext4/symlink.c| 33 ++- fs/f2fs/Kconfig | 10 +- fs/f2fs/Makefile | 2 - fs/f2fs/crypto.c | 473 fs/f2fs/crypto_fname.c | 446 - fs/f2fs/crypto_key.c | 267 --- fs/f2fs/crypto_policy.c | 210 -- fs/f2fs/data.c | 31 ++- fs/f2fs/dir.c| 46 ++-- fs/f2fs/f2fs.h | 172 +++ fs/f2fs/f2fs_crypto.h| 151 - fs/f2fs/file.c | 40 ++-- fs/f2fs/inline.c | 4 +- fs/f2fs/inode.c | 5 +- fs/f2fs/namei.c | 79 --- fs/f2fs/super.c | 55 +++-- include/linux/dcache.h | 2 + include/linux/fs.h | 8 + include/linux/fscrypto.h | 433 include/uapi/linux/fs.h | 18 ++ 46 files changed, 2423 insertions(+), 3792 deletions(-) create mode 100644 fs/crypto/Kconfig create mode 100644 fs/crypto/Makefile create mode 100644 fs/crypto/crypto.c create mode 100644 fs/crypto/fname.c create mode 100644 fs/crypto/keyinfo.c create mode 100644 fs/crypto/policy.c delete mode 100644 fs/ext4/crypto.c delete mode 100644 fs/ext4/crypto_fname.c delete mode 100644 fs/ext4/crypto_key.c delete mode 100644 fs/ext4/crypto_policy.c delete mode 100644 fs/ext4/ext4_crypto.h delete mode 100644 fs/f2fs/crypto.c delete mode 100644 fs/f2fs/crypto_fname.c delete mode 100644 fs/f2fs/crypto_key.c delete mode 100644 fs/f2fs/crypto_policy.c delete mode 100644 fs/f2fs/f2fs_crypto.h create mode 100644 include/linux/fscrypto.h -- 2.6.3 -- Site24x7 APM Insight: Get Deep Visibility into Application Performance APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month Monitor end-to-end web transactions and take corrective actions now Troubleshoot faster and improve end-user experience. Signup Now! http://pubads.g.doubleclick.net/gampad/clk?id=272487151=/4140 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH 08/10] f2fs crypto: migrate into vfs's crypto engine
This patch removes the most parts of internal crypto codes. And then, it modifies some f2fs-specific crypt codes to use the generic facility. Signed-off-by: Jaegeuk Kim--- fs/f2fs/Kconfig | 10 +- fs/f2fs/Makefile| 2 - fs/f2fs/crypto.c| 473 fs/f2fs/crypto_fname.c | 446 - fs/f2fs/crypto_key.c| 267 --- fs/f2fs/crypto_policy.c | 210 - fs/f2fs/data.c | 31 ++-- fs/f2fs/dir.c | 44 ++--- fs/f2fs/f2fs.h | 172 -- fs/f2fs/f2fs_crypto.h | 151 fs/f2fs/file.c | 36 ++-- fs/f2fs/inline.c| 4 +- fs/f2fs/inode.c | 5 +- fs/f2fs/namei.c | 56 +++--- fs/f2fs/super.c | 55 -- 15 files changed, 149 insertions(+), 1813 deletions(-) delete mode 100644 fs/f2fs/crypto.c delete mode 100644 fs/f2fs/crypto_fname.c delete mode 100644 fs/f2fs/crypto_key.c delete mode 100644 fs/f2fs/crypto_policy.c delete mode 100644 fs/f2fs/f2fs_crypto.h diff --git a/fs/f2fs/Kconfig b/fs/f2fs/Kconfig index b0a9dc9..402792b 100644 --- a/fs/f2fs/Kconfig +++ b/fs/f2fs/Kconfig @@ -76,15 +76,7 @@ config F2FS_FS_ENCRYPTION bool "F2FS Encryption" depends on F2FS_FS depends on F2FS_FS_XATTR - select CRYPTO_AES - select CRYPTO_CBC - select CRYPTO_ECB - select CRYPTO_XTS - select CRYPTO_CTS - select CRYPTO_CTR - select CRYPTO_SHA256 - select KEYS - select ENCRYPTED_KEYS + select FS_ENCRYPTION help Enable encryption of f2fs files and directories. This feature is similar to ecryptfs, but it is more memory diff --git a/fs/f2fs/Makefile b/fs/f2fs/Makefile index 08e101e..ca949ea 100644 --- a/fs/f2fs/Makefile +++ b/fs/f2fs/Makefile @@ -7,5 +7,3 @@ f2fs-$(CONFIG_F2FS_STAT_FS) += debug.o f2fs-$(CONFIG_F2FS_FS_XATTR) += xattr.o f2fs-$(CONFIG_F2FS_FS_POSIX_ACL) += acl.o f2fs-$(CONFIG_F2FS_IO_TRACE) += trace.o -f2fs-$(CONFIG_F2FS_FS_ENCRYPTION) += crypto_policy.o crypto.o \ - crypto_key.o crypto_fname.o diff --git a/fs/f2fs/crypto.c b/fs/f2fs/crypto.c deleted file mode 100644 index 3ef3786..000 --- a/fs/f2fs/crypto.c +++ /dev/null @@ -1,473 +0,0 @@ -/* - * linux/fs/f2fs/crypto.c - * - * Copied from linux/fs/ext4/crypto.c - * - * Copyright (C) 2015, Google, Inc. - * Copyright (C) 2015, Motorola Mobility - * - * This contains encryption functions for f2fs - * - * Written by Michael Halcrow, 2014. - * - * Filename encryption additions - * Uday Savagaonkar, 2014 - * Encryption policy handling additions - * Ildar Muslukhov, 2014 - * Remove ext4_encrypted_zeroout(), - * add f2fs_restore_and_release_control_page() - * Jaegeuk Kim, 2015. - * - * This has not yet undergone a rigorous security audit. - * - * The usage of AES-XTS should conform to recommendations in NIST - * Special Publication 800-38E and IEEE P1619/D16. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "f2fs.h" -#include "xattr.h" - -/* Encryption added and removed here! (L: */ - -static unsigned int num_prealloc_crypto_pages = 32; -static unsigned int num_prealloc_crypto_ctxs = 128; - -module_param(num_prealloc_crypto_pages, uint, 0444); -MODULE_PARM_DESC(num_prealloc_crypto_pages, - "Number of crypto pages to preallocate"); -module_param(num_prealloc_crypto_ctxs, uint, 0444); -MODULE_PARM_DESC(num_prealloc_crypto_ctxs, - "Number of crypto contexts to preallocate"); - -static mempool_t *f2fs_bounce_page_pool; - -static LIST_HEAD(f2fs_free_crypto_ctxs); -static DEFINE_SPINLOCK(f2fs_crypto_ctx_lock); - -static struct workqueue_struct *f2fs_read_workqueue; -static DEFINE_MUTEX(crypto_init); - -static struct kmem_cache *f2fs_crypto_ctx_cachep; -struct kmem_cache *f2fs_crypt_info_cachep; - -/** - * f2fs_release_crypto_ctx() - Releases an encryption context - * @ctx: The encryption context to release. - * - * If the encryption context was allocated from the pre-allocated pool, returns - * it to that pool. Else, frees it. - * - * If there's a bounce page in the context, this frees that. - */ -void f2fs_release_crypto_ctx(struct f2fs_crypto_ctx *ctx) -{ - unsigned long flags; - - if (ctx->flags & F2FS_WRITE_PATH_FL && ctx->w.bounce_page) { - mempool_free(ctx->w.bounce_page, f2fs_bounce_page_pool); - ctx->w.bounce_page = NULL; - } - ctx->w.control_page = NULL; - if (ctx->flags & F2FS_CTX_REQUIRES_FREE_ENCRYPT_FL) { - kmem_cache_free(f2fs_crypto_ctx_cachep, ctx); - } else { - spin_lock_irqsave(_crypto_ctx_lock, flags); - list_add(>free_list,
[f2fs-dev] [PATCH 01/10] fs crypto: add basic definitions for per-file encryption
This patch adds definitions for per-file encryption used by ext4 and f2fs. Signed-off-by: Jaegeuk Kim--- include/linux/fs.h | 8 ++ include/linux/fscrypto.h | 239 +++ include/uapi/linux/fs.h | 18 3 files changed, 265 insertions(+) create mode 100644 include/linux/fscrypto.h diff --git a/include/linux/fs.h b/include/linux/fs.h index ae68100..28fc121 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -53,6 +53,8 @@ struct swap_info_struct; struct seq_file; struct workqueue_struct; struct iov_iter; +struct fscrypt_info; +struct fscrypt_operations; extern void __init inode_init(void); extern void __init inode_init_early(void); @@ -678,6 +680,10 @@ struct inode { struct hlist_head i_fsnotify_marks; #endif +#if IS_ENABLED(CONFIG_FS_ENCRYPTION) + struct fscrypt_info *i_crypt_info; +#endif + void*i_private; /* fs or device private pointer */ }; @@ -1323,6 +1329,8 @@ struct super_block { #endif const struct xattr_handler **s_xattr; + const struct fscrypt_operations *s_cop; + struct hlist_bl_heads_anon; /* anonymous dentries for (nfs) exporting */ struct list_heads_mounts; /* list of mounts; _not_ for fs use */ struct block_device *s_bdev; diff --git a/include/linux/fscrypto.h b/include/linux/fscrypto.h new file mode 100644 index 000..4d83f08 --- /dev/null +++ b/include/linux/fscrypto.h @@ -0,0 +1,239 @@ +/* + * General per-file encryption definition + * + * Copyright (C) 2015, Google, Inc. + * + * Written by Michael Halcrow, 2015. + * Modified by Jaegeuk Kim, 2015. + */ + +#ifndef _LINUX_FSCRYPTO_H +#define _LINUX_FSCRYPTO_H + +#include +#include +#include +#include +#include +#include + +#define FS_KEY_DERIVATION_NONCE_SIZE 16 +#define FS_ENCRYPTION_CONTEXT_FORMAT_V11 + +#define FS_POLICY_FLAGS_PAD_4 0x00 +#define FS_POLICY_FLAGS_PAD_8 0x01 +#define FS_POLICY_FLAGS_PAD_16 0x02 +#define FS_POLICY_FLAGS_PAD_32 0x03 +#define FS_POLICY_FLAGS_PAD_MASK 0x03 +#define FS_POLICY_FLAGS_VALID 0x03 + +/* Encryption algorithms */ +#define FS_ENCRYPTION_MODE_INVALID 0 +#define FS_ENCRYPTION_MODE_AES_256_XTS 1 +#define FS_ENCRYPTION_MODE_AES_256_GCM 2 +#define FS_ENCRYPTION_MODE_AES_256_CBC 3 +#define FS_ENCRYPTION_MODE_AES_256_CTS 4 + +/** + * Encryption context for inode + * + * Protector format: + * 1 byte: Protector format (1 = this version) + * 1 byte: File contents encryption mode + * 1 byte: File names encryption mode + * 1 byte: Flags + * 8 bytes: Master Key descriptor + * 16 bytes: Encryption Key derivation nonce + */ +struct fscrypt_context { + u8 format; + u8 contents_encryption_mode; + u8 filenames_encryption_mode; + u8 flags; + u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE]; + u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE]; +} __packed; + +/* Encryption parameters */ +#define FS_XTS_TWEAK_SIZE 16 +#define FS_AES_128_ECB_KEY_SIZE16 +#define FS_AES_256_GCM_KEY_SIZE32 +#define FS_AES_256_CBC_KEY_SIZE32 +#define FS_AES_256_CTS_KEY_SIZE32 +#define FS_AES_256_XTS_KEY_SIZE64 +#define FS_MAX_KEY_SIZE64 + +#define FS_KEY_DESC_PREFIX "fscrypt:" +#define FS_KEY_DESC_PREFIX_SIZE8 + +/* This is passed in from userspace into the kernel keyring */ +struct fscrypt_key { + u32 mode; + u8 raw[FS_MAX_KEY_SIZE]; + u32 size; +} __packed; + +struct fscrypt_info { + u8 ci_data_mode; + u8 ci_filename_mode; + u8 ci_flags; + struct crypto_ablkcipher *ci_ctfm; + struct key *ci_keyring_key; + u8 ci_master_key[FS_KEY_DESCRIPTOR_SIZE]; +}; + +#define FS_CTX_REQUIRES_FREE_ENCRYPT_FL0x0001 +#define FS_WRITE_PATH_FL 0x0002 + +struct fscrypt_ctx { + union { + struct { + struct page *bounce_page; /* Ciphertext page */ + struct page *control_page; /* Original page */ + } w; + struct { + struct bio *bio; + struct work_struct work; + } r; + struct list_head free_list; /* Free list */ + }; + u8 flags; /* Flags */ + u8 mode;/* Encryption mode for tfm */ +}; + +struct fscrypt_completion_result { + struct completion completion; + int res; +}; + +#define DECLARE_FS_COMPLETION_RESULT(ecr) \ + struct fscrypt_completion_result ecr = { \ + COMPLETION_INITIALIZER((ecr).completion), 0 } + +static inline int fscrypt_key_size(int mode) +{ +
[f2fs-dev] [PATCH 02/10] fs crypto: add crypto.c for encrypt/decrypt functions
This patch adds crypto.c supporting encrypting and decrypting functions. 1. IO preparation: - fscrypt_get_ctx / fscrypt_release_ctx 2. before IOs: - fscrypt_encrypt_page - fscrypt_decrypt_page - fscrypt_zeroout_range 3. after IOs: - fscrypt_decrypt_bio_pages - fscrypt_pullback_bio_page - fscrypt_restore_control_page Signed-off-by: Michael HalcrowSigned-off-by: Ildar Muslukhov Signed-off-by: Theodore Ts'o Signed-off-by: Jaegeuk Kim --- fs/crypto/crypto.c | 507 +++ include/linux/fscrypto.h | 60 ++ 2 files changed, 567 insertions(+) create mode 100644 fs/crypto/crypto.c diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c new file mode 100644 index 000..928a34b --- /dev/null +++ b/fs/crypto/crypto.c @@ -0,0 +1,507 @@ +/* + * This contains encryption functions for per-file encryption. + * + * Copyright (C) 2015, Google, Inc. + * Copyright (C) 2015, Motorola Mobility + * + * Written by Michael Halcrow, 2014. + * + * Filename encryption additions + * Uday Savagaonkar, 2014 + * Encryption policy handling additions + * Ildar Muslukhov, 2014 + * Add fscrypt_pullback_bio_page() + * Jaegeuk Kim, 2015. + * + * This has not yet undergone a rigorous security audit. + * + * The usage of AES-XTS should conform to recommendations in NIST + * Special Publication 800-38E and IEEE P1619/D16. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static unsigned int num_prealloc_crypto_pages = 32; +static unsigned int num_prealloc_crypto_ctxs = 128; + +module_param(num_prealloc_crypto_pages, uint, 0444); +MODULE_PARM_DESC(num_prealloc_crypto_pages, + "Number of crypto pages to preallocate"); +module_param(num_prealloc_crypto_ctxs, uint, 0444); +MODULE_PARM_DESC(num_prealloc_crypto_ctxs, + "Number of crypto contexts to preallocate"); + +static mempool_t *fscrypt_bounce_page_pool = NULL; + +static LIST_HEAD(fscrypt_free_ctxs); +static DEFINE_SPINLOCK(fscrypt_ctx_lock); + +static struct workqueue_struct *fscrypt_read_workqueue; +static DEFINE_MUTEX(fscrypt_init_mutex); + +static struct kmem_cache *fscrypt_ctx_cachep; +struct kmem_cache *fscrypt_info_cachep; + +/** + * fscrypt_release_ctx() - Releases an encryption context + * @ctx: The encryption context to release. + * + * If the encryption context was allocated from the pre-allocated pool, returns + * it to that pool. Else, frees it. + * + * If there's a bounce page in the context, this frees that. + */ +void fscrypt_release_ctx(struct fscrypt_ctx *ctx) +{ + unsigned long flags; + + if (ctx->flags & FS_WRITE_PATH_FL && ctx->w.bounce_page) { + mempool_free(ctx->w.bounce_page, fscrypt_bounce_page_pool); + ctx->w.bounce_page = NULL; + } + ctx->w.control_page = NULL; + if (ctx->flags & FS_CTX_REQUIRES_FREE_ENCRYPT_FL) { + kmem_cache_free(fscrypt_ctx_cachep, ctx); + } else { + spin_lock_irqsave(_ctx_lock, flags); + list_add(>free_list, _free_ctxs); + spin_unlock_irqrestore(_ctx_lock, flags); + } +} +EXPORT_SYMBOL(fscrypt_release_ctx); + +/** + * fscrypt_get_ctx() - Gets an encryption context + * @inode: The inode for which we are doing the crypto + * + * Allocates and initializes an encryption context. + * + * Return: An allocated and initialized encryption context on success; error + * value or NULL otherwise. + */ +struct fscrypt_ctx *fscrypt_get_ctx(struct inode *inode) +{ + struct fscrypt_ctx *ctx = NULL; + struct fscrypt_info *ci = inode->i_crypt_info; + unsigned long flags; + + if (ci == NULL) + return ERR_PTR(-ENOKEY); + + /* +* We first try getting the ctx from a free list because in +* the common case the ctx will have an allocated and +* initialized crypto tfm, so it's probably a worthwhile +* optimization. For the bounce page, we first try getting it +* from the kernel allocator because that's just about as fast +* as getting it from a list and because a cache of free pages +* should generally be a "last resort" option for a filesystem +* to be able to do its job. +*/ + spin_lock_irqsave(_ctx_lock, flags); + ctx = list_first_entry_or_null(_free_ctxs, + struct fscrypt_ctx, free_list); + if (ctx) + list_del(>free_list); + spin_unlock_irqrestore(_ctx_lock, flags); + if (!ctx) { + ctx = kmem_cache_zalloc(fscrypt_ctx_cachep, GFP_NOFS); + if (!ctx) + return ERR_PTR(-ENOMEM); + ctx->flags |= FS_CTX_REQUIRES_FREE_ENCRYPT_FL; + } else { + ctx->flags &= ~FS_CTX_REQUIRES_FREE_ENCRYPT_FL; + } + ctx->flags &=
[f2fs-dev] [PATCH 07/10] fs crypto: add dentry revalidation facility in crypto
This patch is to support the following ext4 crypto change. commit 28b4c263961c47da84ed8b5be0b5116bad1133eb Author: Theodore Ts'oDate: Sun Feb 7 19:35:05 2016 -0500 ext4 crypto: revalidate dentry after adding or removing the key Cc: Theodore Ts'o Cc: Al Viro Signed-off-by: Jaegeuk Kim --- fs/crypto/crypto.c | 49 include/linux/dcache.h | 2 ++ include/linux/fscrypto.h | 20 3 files changed, 71 insertions(+) diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index 928a34b..96b18a7 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -27,6 +27,7 @@ #include #include #include +#include #include static unsigned int num_prealloc_crypto_pages = 32; @@ -339,6 +340,54 @@ errout: EXPORT_SYMBOL(fscrypt_zeroout_range); /* + * Validate dentries for encrypted directories to make sure we aren't + * potentially caching stale data after a key has been added or + * removed. + */ +static int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags) +{ + struct inode *dir = d_inode(dentry->d_parent); + struct fscrypt_info *ci = dir->i_crypt_info; + int dir_has_key, cached_with_key; + + if (!dir->i_sb->s_cop->is_encrypted(dir)) + return 0; + + if (ci && ci->ci_keyring_key && + (ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) | + (1 << KEY_FLAG_REVOKED) | + (1 << KEY_FLAG_DEAD + ci = NULL; + + /* this should eventually be an flag in d_flags */ + spin_lock(>d_lock); + cached_with_key = dentry->d_flags & DCACHE_ENCRYPTED_WITH_KEY; + spin_unlock(>d_lock); + dir_has_key = (ci != NULL); + + /* +* If the dentry was cached without the key, and it is a +* negative dentry, it might be a valid name. We can't check +* if the key has since been made available due to locking +* reasons, so we fail the validation so ext4_lookup() can do +* this check. +* +* We also fail the validation if the dentry was created with +* the key present, but we no longer have the key, or vice versa. +*/ + if ((!cached_with_key && d_is_negative(dentry)) || + (!cached_with_key && dir_has_key) || + (cached_with_key && !dir_has_key)) + return 0; + return 1; +} + +const struct dentry_operations fscrypt_d_ops = { + .d_revalidate = fscrypt_d_revalidate, +}; +EXPORT_SYMBOL(fscrypt_d_ops); + +/* * Call fscrypt_decrypt_page on every single page, reusing the encryption * context. */ diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 7781ce11..c7bdfc5 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -228,6 +228,8 @@ struct dentry_operations { #define DCACHE_FALLTHRU0x0100 /* Fall through to lower layer */ #define DCACHE_OP_SELECT_INODE 0x0200 /* Unioned entry: dcache op selects inode */ +#define DCACHE_ENCRYPTED_WITH_KEY 0x0400 /* dir is encrypted with a valid key */ + extern seqlock_t rename_lock; /* diff --git a/include/linux/fscrypto.h b/include/linux/fscrypto.h index 144541b..895cdac 100644 --- a/include/linux/fscrypto.h +++ b/include/linux/fscrypto.h @@ -237,6 +237,26 @@ static inline int fscrypt_has_encryption_key(struct inode *inode) #endif } +static inline void fscrypt_set_encrypted_dentry(struct dentry *dentry) +{ +#if IS_ENABLED(CONFIG_FS_ENCRYPTION) + spin_lock(>d_lock); + dentry->d_flags |= DCACHE_ENCRYPTED_WITH_KEY; + spin_unlock(>d_lock); +#endif +} + +#if IS_ENABLED(CONFIG_FS_ENCRYPTION) +extern const struct dentry_operations fscrypt_d_ops; +#endif + +static inline void fscrypt_set_d_op(struct dentry *dentry) +{ +#if IS_ENABLED(CONFIG_FS_ENCRYPTION) + d_set_d_op(dentry, _d_ops); +#endif +} + #if IS_ENABLED(CONFIG_FS_ENCRYPTION) /* crypto.c */ extern struct kmem_cache *fscrypt_info_cachep; -- 2.6.3 -- Site24x7 APM Insight: Get Deep Visibility into Application Performance APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month Monitor end-to-end web transactions and take corrective actions now Troubleshoot faster and improve end-user experience. Signup Now! http://pubads.g.doubleclick.net/gampad/clk?id=272487151=/4140 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH 05/10] fs crypto: add fname.c to support filename encryption
This patch adds fname.c supporting filename encryption. 1. general wrapper functions - fscrypt_fname_disk_to_usr - fscrypt_fname_usr_to_disk - fscrypt_setup_filename - fscrypt_free_filename 2. specific filename handling functions - fscrypt_fname_alloc_buffer - fscrypt_fname_free_buffer Signed-off-by: Uday SavagaonkarSigned-off-by: Ildar Muslukhov Signed-off-by: Michael Halcrow Signed-off-by: Theodore Ts'o Signed-off-by: Jaegeuk Kim --- fs/crypto/fname.c| 427 +++ include/linux/fscrypto.h | 66 2 files changed, 493 insertions(+) create mode 100644 fs/crypto/fname.c diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c new file mode 100644 index 000..5e4ddee --- /dev/null +++ b/fs/crypto/fname.c @@ -0,0 +1,427 @@ +/* + * This contains functions for filename crypto management + * + * Copyright (C) 2015, Google, Inc. + * Copyright (C) 2015, Motorola Mobility + * + * Written by Uday Savagaonkar, 2014. + * Modified by Jaegeuk Kim, 2015. + * + * This has not yet undergone a rigorous security audit. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static u32 size_round_up(size_t size, size_t blksize) +{ + return ((size + blksize - 1) / blksize) * blksize; +} + +/** + * dir_crypt_complete() - + */ +static void dir_crypt_complete(struct crypto_async_request *req, int res) +{ + struct fscrypt_completion_result *ecr = req->data; + + if (res == -EINPROGRESS) + return; + ecr->res = res; + complete(>completion); +} + +/** + * fname_encrypt() - + * + * This function encrypts the input filename, and returns the length of the + * ciphertext. Errors are returned as negative numbers. We trust the caller to + * allocate sufficient memory to oname string. + */ +static int fname_encrypt(struct inode *inode, + const struct qstr *iname, struct fscrypt_str *oname) +{ + u32 ciphertext_len; + struct ablkcipher_request *req = NULL; + DECLARE_FS_COMPLETION_RESULT(ecr); + struct fscrypt_info *ci = inode->i_crypt_info; + struct crypto_ablkcipher *tfm = ci->ci_ctfm; + int res = 0; + char iv[FS_CRYPTO_BLOCK_SIZE]; + struct scatterlist src_sg, dst_sg; + int padding = 4 << (ci->ci_flags & FS_POLICY_FLAGS_PAD_MASK); + char *workbuf, buf[32], *alloc_buf = NULL; + unsigned lim; + + lim = inode->i_sb->s_cop->max_namelen(inode); + if (iname->len <= 0 || iname->len > lim) + return -EIO; + + ciphertext_len = (iname->len < FS_CRYPTO_BLOCK_SIZE) ? + FS_CRYPTO_BLOCK_SIZE : iname->len; + ciphertext_len = size_round_up(ciphertext_len, padding); + ciphertext_len = (ciphertext_len > lim) ? lim : ciphertext_len; + + if (ciphertext_len <= sizeof(buf)) { + workbuf = buf; + } else { + alloc_buf = kmalloc(ciphertext_len, GFP_NOFS); + if (!alloc_buf) + return -ENOMEM; + workbuf = alloc_buf; + } + + /* Allocate request */ + req = ablkcipher_request_alloc(tfm, GFP_NOFS); + if (!req) { + printk_ratelimited(KERN_ERR + "%s: crypto_request_alloc() failed\n", __func__); + kfree(alloc_buf); + return -ENOMEM; + } + ablkcipher_request_set_callback(req, + CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, + dir_crypt_complete, ); + + /* Copy the input */ + memcpy(workbuf, iname->name, iname->len); + if (iname->len < ciphertext_len) + memset(workbuf + iname->len, 0, ciphertext_len - iname->len); + + /* Initialize IV */ + memset(iv, 0, FS_CRYPTO_BLOCK_SIZE); + + /* Create encryption request */ + sg_init_one(_sg, workbuf, ciphertext_len); + sg_init_one(_sg, oname->name, ciphertext_len); + ablkcipher_request_set_crypt(req, _sg, _sg, ciphertext_len, iv); + res = crypto_ablkcipher_encrypt(req); + if (res == -EINPROGRESS || res == -EBUSY) { + wait_for_completion(); + res = ecr.res; + } + kfree(alloc_buf); + ablkcipher_request_free(req); + if (res < 0) + printk_ratelimited(KERN_ERR + "%s: Error (error code %d)\n", __func__, res); + + oname->len = ciphertext_len; + return res; +} + +/* + * fname_decrypt() + * This function decrypts the input filename, and returns + * the length of the plaintext. + * Errors are returned as negative numbers. + * We trust the caller to allocate sufficient memory to oname string. + */ +static int fname_decrypt(struct inode *inode, + const struct
Re: [f2fs-dev] [PATCH] f2fs: Use crypto crc32 functions
Hi Keith, > +static inline __u32 f2fs_crc32(struct f2fs_sb_info *sbi, const void *address, > +unsigned int length) > +{ > + struct { > + struct shash_desc shash; > + char ctx[4]; > + } desc; > + int err; > + > + BUG_ON(crypto_shash_descsize(sbi->s_chksum_driver) != sizeof(desc.ctx)); I can't accept this and the below BUG_ON, since this hits during the checkpoint procedure which is very critical for entire filesystem. How about calling back the original method for the error cases? Thanks, > + > + desc.shash.tfm = sbi->s_chksum_driver; > + desc.shash.flags = 0; > + *(u32 *)desc.ctx = F2FS_SUPER_MAGIC; > + > + err = crypto_shash_update(, address, length); > + BUG_ON(err); > + > + return *(__u32 *)desc.ctx; > +} > + > +static inline bool f2fs_crc_valid(struct f2fs_sb_info *sbi, __u32 blk_crc, > + void *buf, size_t buf_size) > +{ > + return f2fs_crc32(sbi, buf, buf_size) == blk_crc; > +} > + > static inline struct f2fs_inode_info *F2FS_I(struct inode *inode) > { > return container_of(inode, struct f2fs_inode_info, vfs_inode); > diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c > index 6134832..9630865 100644 > --- a/fs/f2fs/super.c > +++ b/fs/f2fs/super.c > @@ -574,6 +574,8 @@ static void f2fs_put_super(struct super_block *sb) > wait_for_completion(>s_kobj_unregister); > > sb->s_fs_info = NULL; > + if (sbi->s_chksum_driver) > + crypto_free_shash(sbi->s_chksum_driver); > kfree(sbi->raw_super); > kfree(sbi); > } > @@ -1254,6 +1256,15 @@ try_onemore: > if (!sbi) > return -ENOMEM; > > + /* Load the checksum driver */ > + sbi->s_chksum_driver = crypto_alloc_shash("crc32", 0, 0); > + if (IS_ERR(sbi->s_chksum_driver)) { > + f2fs_msg(sb, KERN_ERR, "Cannot load crc32 driver."); > + err = PTR_ERR(sbi->s_chksum_driver); > + sbi->s_chksum_driver = NULL; > + goto free_sbi; > + } > + > /* set a block size */ > if (unlikely(!sb_set_blocksize(sb, F2FS_BLKSIZE))) { > f2fs_msg(sb, KERN_ERR, "unable to set blocksize"); > @@ -1506,6 +1517,8 @@ free_options: > free_sb_buf: > kfree(raw_super); > free_sbi: > + if (sbi->s_chksum_driver) > + crypto_free_shash(sbi->s_chksum_driver); > kfree(sbi); > > /* give only one another chance */ > -- > 2.5.1 -- Site24x7 APM Insight: Get Deep Visibility into Application Performance APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month Monitor end-to-end web transactions and take corrective actions now Troubleshoot faster and improve end-user experience. Signup Now! http://pubads.g.doubleclick.net/gampad/clk?id=272487151=/4140 ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel