Commit 0b81d077 authored by Jaegeuk Kim's avatar Jaegeuk Kim

fs crypto: move per-file encryption from f2fs tree to fs/crypto

This patch adds the renamed functions moved from the f2fs crypto files.

1. definitions for per-file encryption used by ext4 and f2fs.

2. crypto.c for encrypt/decrypt functions
 a. IO preparation:
  - fscrypt_get_ctx / fscrypt_release_ctx
 b. before IOs:
  - fscrypt_encrypt_page
  - fscrypt_decrypt_page
  - fscrypt_zeroout_range
 c. after IOs:
  - fscrypt_decrypt_bio_pages
  - fscrypt_pullback_bio_page
  - fscrypt_restore_control_page

3. policy.c supporting context management.
 a. For ioctls:
  - fscrypt_process_policy
  - fscrypt_get_policy
 b. For context permission
  - fscrypt_has_permitted_context
  - fscrypt_inherit_context

4. keyinfo.c to handle permissions
  - fscrypt_get_encryption_info
  - fscrypt_free_encryption_info

5. fname.c to support filename encryption
 a. general wrapper functions
  - fscrypt_fname_disk_to_usr
  - fscrypt_fname_usr_to_disk
  - fscrypt_setup_filename
  - fscrypt_free_filename

 b. specific filename handling functions
  - fscrypt_fname_alloc_buffer
  - fscrypt_fname_free_buffer

6. Makefile and Kconfig

Cc: Al Viro <viro@ftp.linux.org.uk>
Signed-off-by: default avatarMichael Halcrow <mhalcrow@google.com>
Signed-off-by: default avatarIldar Muslukhov <ildarm@google.com>
Signed-off-by: default avatarUday Savagaonkar <savagaon@google.com>
Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 59692b7c
...@@ -84,6 +84,8 @@ config MANDATORY_FILE_LOCKING ...@@ -84,6 +84,8 @@ config MANDATORY_FILE_LOCKING
To the best of my knowledge this is dead code that no one cares about. 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/notify/Kconfig"
source "fs/quota/Kconfig" source "fs/quota/Kconfig"
......
...@@ -30,6 +30,7 @@ obj-$(CONFIG_EVENTFD) += eventfd.o ...@@ -30,6 +30,7 @@ obj-$(CONFIG_EVENTFD) += eventfd.o
obj-$(CONFIG_USERFAULTFD) += userfaultfd.o obj-$(CONFIG_USERFAULTFD) += userfaultfd.o
obj-$(CONFIG_AIO) += aio.o obj-$(CONFIG_AIO) += aio.o
obj-$(CONFIG_FS_DAX) += dax.o obj-$(CONFIG_FS_DAX) += dax.o
obj-$(CONFIG_FS_ENCRYPTION) += crypto/
obj-$(CONFIG_FILE_LOCKING) += locks.o obj-$(CONFIG_FILE_LOCKING) += locks.o
obj-$(CONFIG_COMPAT) += compat.o compat_ioctl.o obj-$(CONFIG_COMPAT) += compat.o compat_ioctl.o
obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o
......
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.
obj-$(CONFIG_FS_ENCRYPTION) += fscrypto.o
fscrypto-y := crypto.o fname.o policy.o keyinfo.o
This diff is collapsed.
...@@ -76,15 +76,7 @@ config F2FS_FS_ENCRYPTION ...@@ -76,15 +76,7 @@ config F2FS_FS_ENCRYPTION
bool "F2FS Encryption" bool "F2FS Encryption"
depends on F2FS_FS depends on F2FS_FS
depends on F2FS_FS_XATTR depends on F2FS_FS_XATTR
select CRYPTO_AES select FS_ENCRYPTION
select CRYPTO_CBC
select CRYPTO_ECB
select CRYPTO_XTS
select CRYPTO_CTS
select CRYPTO_CTR
select CRYPTO_SHA256
select KEYS
select ENCRYPTED_KEYS
help help
Enable encryption of f2fs files and directories. This Enable encryption of f2fs files and directories. This
feature is similar to ecryptfs, but it is more memory feature is similar to ecryptfs, but it is more memory
......
...@@ -7,5 +7,3 @@ f2fs-$(CONFIG_F2FS_STAT_FS) += debug.o ...@@ -7,5 +7,3 @@ f2fs-$(CONFIG_F2FS_STAT_FS) += debug.o
f2fs-$(CONFIG_F2FS_FS_XATTR) += xattr.o f2fs-$(CONFIG_F2FS_FS_XATTR) += xattr.o
f2fs-$(CONFIG_F2FS_FS_POSIX_ACL) += acl.o f2fs-$(CONFIG_F2FS_FS_POSIX_ACL) += acl.o
f2fs-$(CONFIG_F2FS_IO_TRACE) += trace.o f2fs-$(CONFIG_F2FS_IO_TRACE) += trace.o
f2fs-$(CONFIG_F2FS_FS_ENCRYPTION) += crypto_policy.o crypto.o \
crypto_key.o crypto_fname.o
...@@ -34,9 +34,9 @@ static void f2fs_read_end_io(struct bio *bio) ...@@ -34,9 +34,9 @@ static void f2fs_read_end_io(struct bio *bio)
if (f2fs_bio_encrypted(bio)) { if (f2fs_bio_encrypted(bio)) {
if (bio->bi_error) { if (bio->bi_error) {
f2fs_release_crypto_ctx(bio->bi_private); fscrypt_release_ctx(bio->bi_private);
} else { } else {
f2fs_end_io_crypto_work(bio->bi_private, bio); fscrypt_decrypt_bio_pages(bio->bi_private, bio);
return; return;
} }
} }
...@@ -64,7 +64,7 @@ static void f2fs_write_end_io(struct bio *bio) ...@@ -64,7 +64,7 @@ static void f2fs_write_end_io(struct bio *bio)
bio_for_each_segment_all(bvec, bio, i) { bio_for_each_segment_all(bvec, bio, i) {
struct page *page = bvec->bv_page; struct page *page = bvec->bv_page;
f2fs_restore_and_release_control_page(&page); fscrypt_pullback_bio_page(&page, true);
if (unlikely(bio->bi_error)) { if (unlikely(bio->bi_error)) {
set_bit(AS_EIO, &page->mapping->flags); set_bit(AS_EIO, &page->mapping->flags);
...@@ -129,16 +129,10 @@ static bool __has_merged_page(struct f2fs_bio_info *io, struct inode *inode, ...@@ -129,16 +129,10 @@ static bool __has_merged_page(struct f2fs_bio_info *io, struct inode *inode,
bio_for_each_segment_all(bvec, io->bio, i) { bio_for_each_segment_all(bvec, io->bio, i) {
if (bvec->bv_page->mapping) { if (bvec->bv_page->mapping)
target = bvec->bv_page; target = bvec->bv_page;
} else { else
struct f2fs_crypto_ctx *ctx; target = fscrypt_control_page(bvec->bv_page);
/* encrypted page */
ctx = (struct f2fs_crypto_ctx *)page_private(
bvec->bv_page);
target = ctx->w.control_page;
}
if (inode && inode == target->mapping->host) if (inode && inode == target->mapping->host)
return true; return true;
...@@ -220,7 +214,8 @@ void f2fs_flush_merged_bios(struct f2fs_sb_info *sbi) ...@@ -220,7 +214,8 @@ void f2fs_flush_merged_bios(struct f2fs_sb_info *sbi)
int f2fs_submit_page_bio(struct f2fs_io_info *fio) int f2fs_submit_page_bio(struct f2fs_io_info *fio)
{ {
struct bio *bio; struct bio *bio;
struct page *page = fio->encrypted_page ? fio->encrypted_page : fio->page; struct page *page = fio->encrypted_page ?
fio->encrypted_page : fio->page;
trace_f2fs_submit_page_bio(page, fio); trace_f2fs_submit_page_bio(page, fio);
f2fs_trace_ios(fio, 0); f2fs_trace_ios(fio, 0);
...@@ -992,12 +987,12 @@ static int f2fs_mpage_readpages(struct address_space *mapping, ...@@ -992,12 +987,12 @@ static int f2fs_mpage_readpages(struct address_space *mapping,
bio = NULL; bio = NULL;
} }
if (bio == NULL) { if (bio == NULL) {
struct f2fs_crypto_ctx *ctx = NULL; struct fscrypt_ctx *ctx = NULL;
if (f2fs_encrypted_inode(inode) && if (f2fs_encrypted_inode(inode) &&
S_ISREG(inode->i_mode)) { S_ISREG(inode->i_mode)) {
ctx = f2fs_get_crypto_ctx(inode); ctx = fscrypt_get_ctx(inode);
if (IS_ERR(ctx)) if (IS_ERR(ctx))
goto set_error_page; goto set_error_page;
...@@ -1010,7 +1005,7 @@ static int f2fs_mpage_readpages(struct address_space *mapping, ...@@ -1010,7 +1005,7 @@ static int f2fs_mpage_readpages(struct address_space *mapping,
min_t(int, nr_pages, BIO_MAX_PAGES)); min_t(int, nr_pages, BIO_MAX_PAGES));
if (!bio) { if (!bio) {
if (ctx) if (ctx)
f2fs_release_crypto_ctx(ctx); fscrypt_release_ctx(ctx);
goto set_error_page; goto set_error_page;
} }
bio->bi_bdev = bdev; bio->bi_bdev = bdev;
...@@ -1102,7 +1097,7 @@ int do_write_data_page(struct f2fs_io_info *fio) ...@@ -1102,7 +1097,7 @@ int do_write_data_page(struct f2fs_io_info *fio)
f2fs_wait_on_encrypted_page_writeback(F2FS_I_SB(inode), f2fs_wait_on_encrypted_page_writeback(F2FS_I_SB(inode),
fio->old_blkaddr); fio->old_blkaddr);
fio->encrypted_page = f2fs_encrypt(inode, fio->page); fio->encrypted_page = fscrypt_encrypt_page(inode, fio->page);
if (IS_ERR(fio->encrypted_page)) { if (IS_ERR(fio->encrypted_page)) {
err = PTR_ERR(fio->encrypted_page); err = PTR_ERR(fio->encrypted_page);
goto out_writepage; goto out_writepage;
...@@ -1608,7 +1603,7 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, ...@@ -1608,7 +1603,7 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping,
/* avoid symlink page */ /* avoid symlink page */
if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) { if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) {
err = f2fs_decrypt(page); err = fscrypt_decrypt_page(page);
if (err) if (err)
goto fail; goto fail;
} }
......
...@@ -77,7 +77,7 @@ static unsigned long dir_block_index(unsigned int level, ...@@ -77,7 +77,7 @@ static unsigned long dir_block_index(unsigned int level,
} }
static struct f2fs_dir_entry *find_in_block(struct page *dentry_page, static struct f2fs_dir_entry *find_in_block(struct page *dentry_page,
struct f2fs_filename *fname, struct fscrypt_name *fname,
f2fs_hash_t namehash, f2fs_hash_t namehash,
int *max_slots, int *max_slots,
struct page **res_page) struct page **res_page)
...@@ -103,15 +103,15 @@ static struct f2fs_dir_entry *find_in_block(struct page *dentry_page, ...@@ -103,15 +103,15 @@ static struct f2fs_dir_entry *find_in_block(struct page *dentry_page,
return de; return de;
} }
struct f2fs_dir_entry *find_target_dentry(struct f2fs_filename *fname, struct f2fs_dir_entry *find_target_dentry(struct fscrypt_name *fname,
f2fs_hash_t namehash, int *max_slots, f2fs_hash_t namehash, int *max_slots,
struct f2fs_dentry_ptr *d) struct f2fs_dentry_ptr *d)
{ {
struct f2fs_dir_entry *de; struct f2fs_dir_entry *de;
unsigned long bit_pos = 0; unsigned long bit_pos = 0;
int max_len = 0; int max_len = 0;
struct f2fs_str de_name = FSTR_INIT(NULL, 0); struct fscrypt_str de_name = FSTR_INIT(NULL, 0);
struct f2fs_str *name = &fname->disk_name; struct fscrypt_str *name = &fname->disk_name;
if (max_slots) if (max_slots)
*max_slots = 0; *max_slots = 0;
...@@ -157,7 +157,7 @@ struct f2fs_dir_entry *find_target_dentry(struct f2fs_filename *fname, ...@@ -157,7 +157,7 @@ struct f2fs_dir_entry *find_target_dentry(struct f2fs_filename *fname,
static struct f2fs_dir_entry *find_in_level(struct inode *dir, static struct f2fs_dir_entry *find_in_level(struct inode *dir,
unsigned int level, unsigned int level,
struct f2fs_filename *fname, struct fscrypt_name *fname,
struct page **res_page) struct page **res_page)
{ {
struct qstr name = FSTR_TO_QSTR(&fname->disk_name); struct qstr name = FSTR_TO_QSTR(&fname->disk_name);
...@@ -218,12 +218,12 @@ struct f2fs_dir_entry *f2fs_find_entry(struct inode *dir, ...@@ -218,12 +218,12 @@ struct f2fs_dir_entry *f2fs_find_entry(struct inode *dir,
struct f2fs_dir_entry *de = NULL; struct f2fs_dir_entry *de = NULL;
unsigned int max_depth; unsigned int max_depth;
unsigned int level; unsigned int level;
struct f2fs_filename fname; struct fscrypt_name fname;
int err; int err;
*res_page = NULL; *res_page = NULL;
err = f2fs_fname_setup_filename(dir, child, 1, &fname); err = fscrypt_setup_filename(dir, child, 1, &fname);
if (err) if (err)
return NULL; return NULL;
...@@ -251,7 +251,7 @@ struct f2fs_dir_entry *f2fs_find_entry(struct inode *dir, ...@@ -251,7 +251,7 @@ struct f2fs_dir_entry *f2fs_find_entry(struct inode *dir,
break; break;
} }
out: out:
f2fs_fname_free_filename(&fname); fscrypt_free_filename(&fname);
return de; return de;
} }
...@@ -413,7 +413,7 @@ struct page *init_inode_metadata(struct inode *inode, struct inode *dir, ...@@ -413,7 +413,7 @@ struct page *init_inode_metadata(struct inode *inode, struct inode *dir,
goto put_error; goto put_error;
if (f2fs_encrypted_inode(dir) && f2fs_may_encrypt(inode)) { if (f2fs_encrypted_inode(dir) && f2fs_may_encrypt(inode)) {
err = f2fs_inherit_context(dir, inode, page); err = fscrypt_inherit_context(dir, inode, page, false);
if (err) if (err)
goto put_error; goto put_error;
} }
...@@ -536,11 +536,11 @@ int __f2fs_add_link(struct inode *dir, const struct qstr *name, ...@@ -536,11 +536,11 @@ int __f2fs_add_link(struct inode *dir, const struct qstr *name,
struct f2fs_dentry_block *dentry_blk = NULL; struct f2fs_dentry_block *dentry_blk = NULL;
struct f2fs_dentry_ptr d; struct f2fs_dentry_ptr d;
struct page *page = NULL; struct page *page = NULL;
struct f2fs_filename fname; struct fscrypt_name fname;
struct qstr new_name; struct qstr new_name;
int slots, err; int slots, err;
err = f2fs_fname_setup_filename(dir, name, 0, &fname); err = fscrypt_setup_filename(dir, name, 0, &fname);
if (err) if (err)
return err; return err;
...@@ -639,7 +639,7 @@ int __f2fs_add_link(struct inode *dir, const struct qstr *name, ...@@ -639,7 +639,7 @@ int __f2fs_add_link(struct inode *dir, const struct qstr *name,
kunmap(dentry_page); kunmap(dentry_page);
f2fs_put_page(dentry_page, 1); f2fs_put_page(dentry_page, 1);
out: out:
f2fs_fname_free_filename(&fname); fscrypt_free_filename(&fname);
f2fs_update_time(F2FS_I_SB(dir), REQ_TIME); f2fs_update_time(F2FS_I_SB(dir), REQ_TIME);
return err; return err;
} }
...@@ -781,12 +781,12 @@ bool f2fs_empty_dir(struct inode *dir) ...@@ -781,12 +781,12 @@ bool f2fs_empty_dir(struct inode *dir)
} }
bool f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d, bool f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d,
unsigned int start_pos, struct f2fs_str *fstr) unsigned int start_pos, struct fscrypt_str *fstr)
{ {
unsigned char d_type = DT_UNKNOWN; unsigned char d_type = DT_UNKNOWN;
unsigned int bit_pos; unsigned int bit_pos;
struct f2fs_dir_entry *de = NULL; struct f2fs_dir_entry *de = NULL;
struct f2fs_str de_name = FSTR_INIT(NULL, 0); struct fscrypt_str de_name = FSTR_INIT(NULL, 0);
bit_pos = ((unsigned long)ctx->pos % d->max); bit_pos = ((unsigned long)ctx->pos % d->max);
...@@ -820,8 +820,9 @@ bool f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d, ...@@ -820,8 +820,9 @@ bool f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d,
memcpy(de_name.name, d->filename[bit_pos], de_name.len); memcpy(de_name.name, d->filename[bit_pos], de_name.len);
ret = f2fs_fname_disk_to_usr(d->inode, &de->hash_code, ret = fscrypt_fname_disk_to_usr(d->inode,
&de_name, fstr); (u32)de->hash_code, 0,
&de_name, fstr);
kfree(de_name.name); kfree(de_name.name);
if (ret < 0) if (ret < 0)
return true; return true;
...@@ -849,16 +850,15 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx) ...@@ -849,16 +850,15 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx)
struct file_ra_state *ra = &file->f_ra; struct file_ra_state *ra = &file->f_ra;
unsigned int n = ((unsigned long)ctx->pos / NR_DENTRY_IN_BLOCK); unsigned int n = ((unsigned long)ctx->pos / NR_DENTRY_IN_BLOCK);
struct f2fs_dentry_ptr d; struct f2fs_dentry_ptr d;
struct f2fs_str fstr = FSTR_INIT(NULL, 0); struct fscrypt_str fstr = FSTR_INIT(NULL, 0);
int err = 0; int err = 0;
if (f2fs_encrypted_inode(inode)) { if (f2fs_encrypted_inode(inode)) {
err = f2fs_get_encryption_info(inode); err = fscrypt_get_encryption_info(inode);
if (err) if (err)
return err; return err;
err = f2fs_fname_crypto_alloc_buffer(inode, F2FS_NAME_LEN, err = fscrypt_fname_alloc_buffer(inode, F2FS_NAME_LEN, &fstr);
&fstr);
if (err < 0) if (err < 0)
return err; return err;
} }
...@@ -898,14 +898,14 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx) ...@@ -898,14 +898,14 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx)
f2fs_put_page(dentry_page, 1); f2fs_put_page(dentry_page, 1);
} }
out: out:
f2fs_fname_crypto_free_buffer(&fstr); fscrypt_fname_free_buffer(&fstr);
return err; return err;
} }
static int f2fs_dir_open(struct inode *inode, struct file *filp) static int f2fs_dir_open(struct inode *inode, struct file *filp)
{ {
if (f2fs_encrypted_inode(inode)) if (f2fs_encrypted_inode(inode))
return f2fs_get_encryption_info(inode) ? -EACCES : 0; return fscrypt_get_encryption_info(inode) ? -EACCES : 0;
return 0; return 0;
} }
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/bio.h> #include <linux/bio.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/fscrypto.h>
#ifdef CONFIG_F2FS_CHECK_FS #ifdef CONFIG_F2FS_CHECK_FS
#define f2fs_bug_on(sbi, condition) BUG_ON(condition) #define f2fs_bug_on(sbi, condition) BUG_ON(condition)
...@@ -231,12 +232,9 @@ static inline bool __has_cursum_space(struct f2fs_journal *journal, ...@@ -231,12 +232,9 @@ static inline bool __has_cursum_space(struct f2fs_journal *journal,
#define F2FS_IOC_WRITE_CHECKPOINT _IO(F2FS_IOCTL_MAGIC, 7) #define F2FS_IOC_WRITE_CHECKPOINT _IO(F2FS_IOCTL_MAGIC, 7)
#define F2FS_IOC_DEFRAGMENT _IO(F2FS_IOCTL_MAGIC, 8) #define F2FS_IOC_DEFRAGMENT _IO(F2FS_IOCTL_MAGIC, 8)
#define F2FS_IOC_SET_ENCRYPTION_POLICY \ #define F2FS_IOC_SET_ENCRYPTION_POLICY FS_IOC_SET_ENCRYPTION_POLICY
_IOR('f', 19, struct f2fs_encryption_policy) #define F2FS_IOC_GET_ENCRYPTION_POLICY FS_IOC_GET_ENCRYPTION_POLICY
#define F2FS_IOC_GET_ENCRYPTION_PWSALT \ #define F2FS_IOC_GET_ENCRYPTION_PWSALT FS_IOC_GET_ENCRYPTION_PWSALT
_IOW('f', 20, __u8[16])
#define F2FS_IOC_GET_ENCRYPTION_POLICY \
_IOW('f', 21, struct f2fs_encryption_policy)
/* /*
* should be same as XFS_IOC_GOINGDOWN. * should be same as XFS_IOC_GOINGDOWN.
...@@ -266,25 +264,6 @@ struct f2fs_defragment { ...@@ -266,25 +264,6 @@ struct f2fs_defragment {
* For INODE and NODE manager * For INODE and NODE manager
*/ */
/* for directory operations */ /* for directory operations */
struct f2fs_str {
unsigned char *name;
u32 len;
};
struct f2fs_filename {
const struct qstr *usr_fname;
struct f2fs_str disk_name;
f2fs_hash_t hash;
#ifdef CONFIG_F2FS_FS_ENCRYPTION
struct f2fs_str crypto_buf;
#endif
};
#define FSTR_INIT(n, l) { .name = n, .len = l }
#define FSTR_TO_QSTR(f) QSTR_INIT((f)->name, (f)->len)
#define fname_name(p) ((p)->disk_name.name)
#define fname_len(p) ((p)->disk_name.len)
struct f2fs_dentry_ptr { struct f2fs_dentry_ptr {
struct inode *inode; struct inode *inode;
const void *bitmap; const void *bitmap;
...@@ -412,15 +391,6 @@ struct f2fs_map_blocks { ...@@ -412,15 +391,6 @@ struct f2fs_map_blocks {
#define file_enc_name(inode) is_file(inode, FADVISE_ENC_NAME_BIT) #define file_enc_name(inode) is_file(inode, FADVISE_ENC_NAME_BIT)
#define file_set_enc_name(inode) set_file(inode, FADVISE_ENC_NAME_BIT) #define file_set_enc_name(inode) set_file(inode, FADVISE_ENC_NAME_BIT)
/* Encryption algorithms */
#define F2FS_ENCRYPTION_MODE_INVALID 0
#define F2FS_ENCRYPTION_MODE_AES_256_XTS 1
#define F2FS_ENCRYPTION_MODE_AES_256_GCM 2
#define F2FS_ENCRYPTION_MODE_AES_256_CBC 3
#define F2FS_ENCRYPTION_MODE_AES_256_CTS 4
#include "f2fs_crypto.h"
#define DEF_DIR_LEVEL 0 #define DEF_DIR_LEVEL 0
struct f2fs_inode_info { struct f2fs_inode_info {
...@@ -444,13 +414,7 @@ struct f2fs_inode_info { ...@@ -444,13 +414,7 @@ struct f2fs_inode_info {
struct list_head dirty_list; /* linked in global dirty list */ struct list_head dirty_list; /* linked in global dirty list */
struct list_head inmem_pages; /* inmemory pages managed by f2fs */ struct list_head inmem_pages; /* inmemory pages managed by f2fs */
struct mutex inmem_lock; /* lock for inmemory pages */ struct mutex inmem_lock; /* lock for inmemory pages */
struct extent_tree *extent_tree; /* cached extent_tree entry */ struct extent_tree *extent_tree; /* cached extent_tree entry */
#ifdef CONFIG_F2FS_FS_ENCRYPTION
/* Encryption params */
struct f2fs_crypt_info *i_crypt_info;
#endif
}; };
static inline void get_extent_info(struct extent_info *ext, static inline void get_extent_info(struct extent_info *ext,
...@@ -1741,10 +1705,10 @@ struct dentry *f2fs_get_parent(struct dentry *child); ...@@ -1741,10 +1705,10 @@ struct dentry *f2fs_get_parent(struct dentry *child);
extern unsigned char f2fs_filetype_table[F2FS_FT_MAX]; extern unsigned char f2fs_filetype_table[F2FS_FT_MAX];
void set_de_type(struct f2fs_dir_entry *, umode_t); void set_de_type(struct f2fs_dir_entry *, umode_t);
struct f2fs_dir_entry *find_target_dentry(struct f2fs_filename *, struct f2fs_dir_entry *find_target_dentry(struct fscrypt_name *,
f2fs_hash_t, int *, struct f2fs_dentry_ptr *); f2fs_hash_t, int *, struct f2fs_dentry_ptr *);
bool f2fs_fill_dentries(struct dir_context *, struct f2fs_dentry_ptr *, bool f2fs_fill_dentries(struct dir_context *, struct f2fs_dentry_ptr *,
unsigned int, struct f2fs_str *); unsigned int, struct fscrypt_str *);
void do_make_empty_dir(struct inode *, struct inode *, void do_make_empty_dir(struct inode *, struct inode *,
struct f2fs_dentry_ptr *); struct f2fs_dentry_ptr *);
struct page *init_inode_metadata(struct inode *, struct inode *, struct page *init_inode_metadata(struct inode *, struct inode *,
...@@ -2120,7 +2084,7 @@ int f2fs_convert_inline_inode(struct inode *); ...@@ -2120,7 +2084,7 @@ int f2fs_convert_inline_inode(struct inode *);
int f2fs_write_inline_data(struct inode *, struct page *); int f2fs_write_inline_data(struct inode *, struct page *);
bool recover_inline_data(struct inode *, struct page *); bool recover_inline_data(struct inode *, struct page *);
struct f2fs_dir_entry *find_in_inline_dir(struct inode *, struct f2fs_dir_entry *find_in_inline_dir(struct inode *,
struct f2fs_filename *, struct page **); struct fscrypt_name *, struct page **);
struct f2fs_dir_entry *f2fs_parent_inline_dir(struct inode *, struct page **); struct f2fs_dir_entry *f2fs_parent_inline_dir(struct inode *, struct page **);
int make_empty_inline_dir(struct inode *inode, struct inode *, struct page *); int make_empty_inline_dir(struct inode *inode, struct inode *, struct page *);
int f2fs_add_inline_entry(struct inode *, const struct qstr *, struct inode *, int f2fs_add_inline_entry(struct inode *, const struct qstr *, struct inode *,
...@@ -2129,7 +2093,7 @@ void f2fs_delete_inline_entry(struct f2fs_dir_entry *, struct page *, ...@@ -2129,7 +2093,7 @@ void f2fs_delete_inline_entry(struct f2fs_dir_entry *, struct page *,
struct inode *, struct inode *); struct inode *, struct inode *);
bool f2fs_empty_inline_dir(struct inode *); bool f2fs_empty_inline_dir(struct inode *);
int f2fs_read_inline_dir(struct file *, struct dir_context *, int f2fs_read_inline_dir(struct file *, struct dir_context *,
struct f2fs_str *); struct fscrypt_str *);
int f2fs_inline_data_fiemap(struct inode *, int f2fs_inline_data_fiemap(struct inode *,
struct fiemap_extent_info *, __u64, __u64); struct fiemap_extent_info *, __u64, __u64);
...@@ -2159,13 +2123,9 @@ void destroy_extent_cache(void); ...@@ -2159,13 +2123,9 @@ void destroy_extent_cache(void);
/* /*
* crypto support * crypto support
*/ */
static inline int f2fs_encrypted_inode(struct inode *inode) static inline bool f2fs_encrypted_inode(struct inode *inode)
{ {
#ifdef CONFIG_F2FS_FS_ENCRYPTION
return file_is_encrypt(inode); return file_is_encrypt(inode);
#else
return 0;
#endif
} }
static inline void f2fs_set_encrypted_inode(struct inode *inode) static inline void f2fs_set_encrypted_inode(struct inode *inode)
...@@ -2177,20 +2137,12 @@ static inline void f2fs_set_encrypted_inode(struct inode *inode) ...@@ -2177,20 +2137,12 @@ static inline void f2fs_set_encrypted_inode(struct inode *inode)
static inline bool f2fs_bio_encrypted(struct bio *bio) static inline bool f2fs_bio_encrypted(struct bio *bio)
{ {
#ifdef CONFIG_F2FS_FS_ENCRYPTION return bio->bi_private != NULL;
return unlikely(bio->bi_private != NULL);
#else
return false;
#endif
} }
static inline int f2fs_sb_has_crypto(struct super_block *sb) static inline int f2fs_sb_has_crypto(struct super_block *sb)
{ {
#ifdef CONFIG_F2FS_FS_ENCRYPTION
return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_ENCRYPT); return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_ENCRYPT);
#else
return 0;
#endif
} }
static inline bool f2fs_may_encrypt(struct inode *inode) static inline bool f2fs_may_encrypt(struct inode *inode)
...@@ -2204,86 +2156,28 @@ static inline bool f2fs_may_encrypt(struct inode *inode) ...@@ -2204,86 +2156,28 @@ static inline bool f2fs_may_encrypt(struct inode *inode)
#endif #endif
} }
/* crypto_policy.c */ #ifndef CONFIG_F2FS_FS_ENCRYPTION
int f2fs_is_child_context_consistent_with_parent(struct inode *, #define fscrypt_set_d_op(i)
struct inode *); #define fscrypt_get_ctx fscrypt_notsupp_get_ctx
int f2fs_inherit_context(struct inode *, struct inode *, struct page *); #define fscrypt_release_ctx fscrypt_notsupp_release_ctx
int f2fs_process_policy(const struct f2fs_encryption_policy *, struct inode *); #define fscrypt_encrypt_page fscrypt_notsupp_encrypt_page
int f2fs_get_policy(struct inode *, struct f2fs_encryption_policy *); #define fscrypt_decrypt_page fscrypt_notsupp_decrypt_page
#define fscrypt_decrypt_bio_pages fscrypt_notsupp_decrypt_bio_pages
/* crypt.c */ #define fscrypt_pullback_bio_page fscrypt_notsupp_pullback_bio_page
extern struct kmem_cache *f2fs_crypt_info_cachep; #define fscrypt_restore_control_page fscrypt_notsupp_restore_control_page
bool f2fs_valid_contents_enc_mode(uint32_t); #define fscrypt_zeroout_range fscrypt_notsupp_zeroout_range
uint32_t f2fs_validate_encryption_key_size(uint32_t, uint32_t); #define fscrypt_process_policy fscrypt_notsupp_process_policy
struct f2fs_crypto_ctx *f2fs_get_crypto_ctx(struct inode *); #define fscrypt_get_policy fscrypt_notsupp_get_policy
void f2fs_release_crypto_ctx(struct f2fs_crypto_ctx *); #define fscrypt_has_permitted_context fscrypt_notsupp_has_permitted_context
struct page *f2fs_encrypt(struct inode *, struct page *); #define fscrypt_inherit_context fscrypt_notsupp_inherit_context
int f2fs_decrypt(struct page *); #define fscrypt_get_encryption_info fscrypt_notsupp_get_encryption_info
void f2fs_end_io_crypto_work(struct f2fs_crypto_ctx *, struct bio *); #define fscrypt_put_encryption_info fscrypt_notsupp_put_encryption_info
#define fscrypt_setup_filename fscrypt_notsupp_setup_filename
/* crypto_key.c */ #define fscrypt_free_filename fscrypt_notsupp_free_filename
void f2fs_free_encryption_info(struct inode *, struct f2fs_crypt_info *); #define fscrypt_fname_encrypted_size fscrypt_notsupp_fname_encrypted_size
int _f2fs_get_encryption_info(struct inode *inode); #define fscrypt_fname_alloc_buffer fscrypt_notsupp_fname_alloc_buffer
#define fscrypt_fname_free_buffer fscrypt_notsupp_fname_free_buffer
/* crypto_fname.c */ #define fscrypt_fname_disk_to_usr fscrypt_notsupp_fname_disk_to_usr
bool f2fs_valid_filenames_enc_mode(uint32_t); #define fscrypt_fname_usr_to_disk fscrypt_notsupp_fname_usr_to_disk
u32 f2fs_fname_crypto_round_up(u32, u32);
unsigned f2fs_fname_encrypted_size(struct inode *, u32);
int f2fs_fname_crypto_alloc_buffer(struct inode *, u32, struct f2fs_str *);
int f2fs_fname_disk_to_usr(struct inode *, f2fs_hash_t *,
const struct f2fs_str *, struct f2fs_str *);
int f2fs_fname_usr_to_disk(struct inode *, const struct qstr *,
struct f2fs_str *);
#ifdef CONFIG_F2FS_FS_ENCRYPTION
void f2fs_restore_and_release_control_page(struct page **);
void f2fs_restore_control_page(struct page *);
int __init f2fs_init_crypto(void);
int f2fs_crypto_initialize(void);
void f2fs_exit_crypto(void);
int f2fs_has_encryption_key(struct inode *);
static inline int f2fs_get_encryption_info(struct inode *inode)
{
struct f2fs_crypt_info *ci = F2FS_I(inode)->i_crypt_info;
if (!ci ||
(ci->ci_keyring_key &&
(ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) |
(1 << KEY_FLAG_REVOKED) |
(1 << KEY_FLAG_DEAD)))))
return _f2fs_get_encryption_info(inode);
return 0;
}
void f2fs_fname_crypto_free_buffer(struct f2fs_str *);
int f2fs_fname_setup_filename(struct inode *, const struct qstr *,
int lookup, struct f2fs_filename *);
void f2fs_fname_free_filename(struct f2fs_filename *);
#else
static inline void f2fs_restore_and_release_control_page(struct page **p) { }
static inline void f2fs_restore_control_page(struct page *p) { }
static inline int __init f2fs_init_crypto(void) { return 0; }
static inline void f2fs_exit_crypto(void) { }
static inline int f2fs_has_encryption_key(struct inode *i) { return 0; }
static inline int f2fs_get_encryption_info(struct inode *i) { return 0; }
static inline void f2fs_fname_crypto_free_buffer(struct f2fs_str *p) { }
static inline int f2fs_fname_setup_filename(struct inode *dir,
const struct qstr *iname,
int lookup, struct f2fs_filename *fname)
{
memset(fname, 0, sizeof(struct f2fs_filename));
fname->usr_fname = iname;
fname->disk_name.name = (unsigned char *)iname->name;
fname->disk_name.len = iname->len;
return 0;
}
static inline void f2fs_fname_free_filename(struct f2fs_filename *fname) { }
#endif #endif
#endif #endif
/*
* linux/fs/f2fs/f2fs_crypto.h
*
* Copied from linux/fs/ext4/ext4_crypto.h
*
* Copyright (C) 2015, Google, Inc.
*
* This contains encryption header content for f2fs
*
* Written by Michael Halcrow, 2015.
* Modified by Jaegeuk Kim, 2015.
*/
#ifndef _F2FS_CRYPTO_H
#define _F2FS_CRYPTO_H
#include <linux/fs.h>
#define F2FS_KEY_DESCRIPTOR_SIZE 8
/* Policy provided via an ioctl on the topmost directory */
struct f2fs_encryption_policy {
char version;
char contents_encryption_mode;
char filenames_encryption_mode;
char flags;
char master_key_descriptor[F2FS_KEY_DESCRIPTOR_SIZE];
} __attribute__((__packed__));
#define F2FS_ENCRYPTION_CONTEXT_FORMAT_V1 1
#define F2FS_KEY_DERIVATION_NONCE_SIZE 16
#define F2FS_POLICY_FLAGS_PAD_4 0x00
#define F2FS_POLICY_FLAGS_PAD_8 0x01
#define F2FS_POLICY_FLAGS_PAD_16 0x02
#define F2FS_POLICY_FLAGS_PAD_32 0x03
#define F2FS_POLICY_FLAGS_PAD_MASK 0x03
#define F2FS_POLICY_FLAGS_VALID 0x03
/**
* 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 f2fs_encryption_context {
char format;
char contents_encryption_mode;
char filenames_encryption_mode;
char flags;
char master_key_descriptor[F2FS_KEY_DESCRIPTOR_SIZE];
char nonce[F2FS_KEY_DERIVATION_NONCE_SIZE];
} __attribute__((__packed__));
/* Encryption parameters */
#define F2FS_XTS_TWEAK_SIZE 16
#define F2FS_AES_128_ECB_KEY_SIZE 16
#define F2FS_AES_256_GCM_KEY_SIZE 32
#define F2FS_AES_256_CBC_KEY_SIZE 32
#define F2FS_AES_256_CTS_KEY_SIZE 32
#define F2FS_AES_256_XTS_KEY_SIZE 64
#define F2FS_MAX_KEY_SIZE 64
#define F2FS_KEY_DESC_PREFIX "f2fs:"
#define F2FS_KEY_DESC_PREFIX_SIZE 5
struct f2fs_encryption_key {
__u32 mode;
char raw[F2FS_MAX_KEY_SIZE];
__u32 size;
} __attribute__((__packed__));
struct f2fs_crypt_info {
char ci_data_mode;
char ci_filename_mode;
char ci_flags;
struct crypto_ablkcipher *ci_ctfm;
struct key *ci_keyring_key;
char ci_master_key[F2FS_KEY_DESCRIPTOR_SIZE];
};
#define F2FS_CTX_REQUIRES_FREE_ENCRYPT_FL 0x00000001
#define F2FS_WRITE_PATH_FL 0x00000002
struct f2fs_crypto_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 */
};
char flags; /* Flags */
};
struct f2fs_completion_result {
struct completion completion;
int res;
};
#define DECLARE_F2FS_COMPLETION_RESULT(ecr) \
struct f2fs_completion_result ecr = { \
COMPLETION_INITIALIZER((ecr).completion), 0 }
static inline int f2fs_encryption_key_size(int mode)
{
switch (mode) {
case F2FS_ENCRYPTION_MODE_AES_256_XTS:
return F2FS_AES_256_XTS_KEY_SIZE;
case F2FS_ENCRYPTION_MODE_AES_256_GCM:
return F2FS_AES_256_GCM_KEY_SIZE;
case F2FS_ENCRYPTION_MODE_AES_256_CBC:
return F2FS_AES_256_CBC_KEY_SIZE;
case F2FS_ENCRYPTION_MODE_AES_256_CTS:
return F2FS_AES_256_CTS_KEY_SIZE;
default:
BUG();
}
return 0;
}
#define F2FS_FNAME_NUM_SCATTER_ENTRIES 4
#define F2FS_CRYPTO_BLOCK_SIZE 16
#define F2FS_FNAME_CRYPTO_DIGEST_SIZE 32
/**
* For encrypted symlinks, the ciphertext length is stored at the beginning
* of the string in little-endian format.
*/
struct f2fs_encrypted_symlink_data {
__le16 len;
char encrypted_path[1];
} __attribute__((__packed__));
/**
* This function is used to calculate the disk space required to
* store a filename of length l in encrypted symlink format.
*/
static inline u32 encrypted_symlink_data_len(u32 l)
{
return (l + sizeof(struct f2fs_encrypted_symlink_data) - 1);
}
#endif /* _F2FS_CRYPTO_H */
...@@ -421,7 +421,7 @@ static int f2fs_file_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -421,7 +421,7 @@ static int f2fs_file_mmap(struct file *file, struct vm_area_struct *vma)
int err; int err;
if (f2fs_encrypted_inode(inode)) { if (f2fs_encrypted_inode(inode)) {
err = f2fs_get_encryption_info(inode); err = fscrypt_get_encryption_info(inode);
if (err) if (err)
return 0; return 0;
if (!f2fs_encrypted_inode(inode)) if (!f2fs_encrypted_inode(inode))
...@@ -443,10 +443,10 @@ static int f2fs_file_open(struct inode *inode, struct file *filp) ...@@ -443,10 +443,10 @@ static int f2fs_file_open(struct inode *inode, struct file *filp)
int ret = generic_file_open(inode, filp); int ret = generic_file_open(inode, filp);
if (!ret && f2fs_encrypted_inode(inode)) { if (!ret && f2fs_encrypted_inode(inode)) {
ret = f2fs_get_encryption_info(inode); ret = fscrypt_get_encryption_info(inode);
if (ret) if (ret)
return -EACCES; return -EACCES;
if (!f2fs_encrypted_inode(inode)) if (!fscrypt_has_encryption_key(inode))
return -ENOKEY; return -ENOKEY;
} }
return ret; return ret;
...@@ -526,7 +526,8 @@ static int truncate_partial_data_page(struct inode *inode, u64 from, ...@@ -526,7 +526,8 @@ static int truncate_partial_data_page(struct inode *inode, u64 from,
truncate_out: truncate_out:
f2fs_wait_on_page_writeback(page, DATA, true); f2fs_wait_on_page_writeback(page, DATA, true);
zero_user(page, offset, PAGE_CACHE_SIZE - offset); zero_user(page, offset, PAGE_CACHE_SIZE - offset);
if (!cache_only || !f2fs_encrypted_inode(inode) || !S_ISREG(inode->i_mode)) if (!cache_only || !f2fs_encrypted_inode(inode) ||
!S_ISREG(inode->i_mode))
set_page_dirty(page); set_page_dirty(page);
f2fs_put_page(page, 1); f2fs_put_page(page, 1);
return 0; return 0;
...@@ -674,7 +675,7 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr) ...@@ -674,7 +675,7 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr)
if (attr->ia_valid & ATTR_SIZE) { if (attr->ia_valid & ATTR_SIZE) {
if (f2fs_encrypted_inode(inode) && if (f2fs_encrypted_inode(inode) &&
f2fs_get_encryption_info(inode)) fscrypt_get_encryption_info(inode))
return -EACCES; return -EACCES;
if (attr->ia_size <= i_size_read(inode)) { if (attr->ia_size <= i_size_read(inode)) {
...@@ -1529,39 +1530,30 @@ static bool uuid_is_nonzero(__u8 u[16]) ...@@ -1529,39 +1530,30 @@ static bool uuid_is_nonzero(__u8 u[16])
static int f2fs_ioc_set_encryption_policy(struct file *filp, unsigned long arg) static int f2fs_ioc_set_encryption_policy(struct file *filp, unsigned long arg)
{ {
#ifdef CONFIG_F2FS_FS_ENCRYPTION struct fscrypt_policy policy;
struct f2fs_encryption_policy policy;
struct inode *inode = file_inode(filp); struct inode *inode = file_inode(filp);
if (copy_from_user(&policy, (struct f2fs_encryption_policy __user *)arg, if (copy_from_user(&policy, (struct fscrypt_policy __user *)arg,
sizeof(policy))) sizeof(policy)))
return -EFAULT; return -EFAULT;
f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
return f2fs_process_policy(&policy, inode); return fscrypt_process_policy(inode, &policy);
#else
return -EOPNOTSUPP;
#endif
} }
static int f2fs_ioc_get_encryption_policy(struct file *filp, unsigned long arg) static int f2fs_ioc_get_encryption_policy(struct file *filp, unsigned long arg)
{ {
#ifdef CONFIG_F2FS_FS_ENCRYPTION struct fscrypt_policy policy;
struct f2fs_encryption_policy policy;
struct inode *inode = file_inode(filp); struct inode *inode = file_inode(filp);
int err; int err;
err = f2fs_get_policy(inode, &policy); err = fscrypt_get_policy(inode, &policy);
if (err) if (err)
return err; return err;
if (copy_to_user((struct f2fs_encryption_policy __user *)arg, &policy, if (copy_to_user((struct fscrypt_policy __user *)arg, &policy, sizeof(policy)))
sizeof(policy)))
return -EFAULT; return -EFAULT;
return 0; return 0;
#else
return -EOPNOTSUPP;
#endif
} }
static int f2fs_ioc_get_encryption_pwsalt(struct file *filp, unsigned long arg) static int f2fs_ioc_get_encryption_pwsalt(struct file *filp, unsigned long arg)
...@@ -1873,8 +1865,8 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) ...@@ -1873,8 +1865,8 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
ssize_t ret; ssize_t ret;
if (f2fs_encrypted_inode(inode) && if (f2fs_encrypted_inode(inode) &&
!f2fs_has_encryption_key(inode) && !fscrypt_has_encryption_key(inode) &&
f2fs_get_encryption_info(inode)) fscrypt_get_encryption_info(inode))
return -EACCES; return -EACCES;
inode_lock(inode); inode_lock(inode);
......
...@@ -277,7 +277,7 @@ bool recover_inline_data(struct inode *inode, struct page *npage) ...@@ -277,7 +277,7 @@ bool recover_inline_data(struct inode *inode, struct page *npage)
} }
struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir, struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir,
struct f2fs_filename *fname, struct page **res_page) struct fscrypt_name *fname, struct page **res_page)
{ {
struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb);
struct f2fs_inline_dentry *inline_dentry; struct f2fs_inline_dentry *inline_dentry;
...@@ -535,7 +535,7 @@ bool f2fs_empty_inline_dir(struct inode *dir) ...@@ -535,7 +535,7 @@ bool f2fs_empty_inline_dir(struct inode *dir)
} }
int f2fs_read_inline_dir(struct file *file, struct dir_context *ctx, int f2fs_read_inline_dir(struct file *file, struct dir_context *ctx,
struct f2fs_str *fstr) struct fscrypt_str *fstr)
{ {
struct inode *inode = file_inode(file); struct inode *inode = file_inode(file);
struct f2fs_inline_dentry *inline_dentry = NULL; struct f2fs_inline_dentry *inline_dentry = NULL;
......
...@@ -389,10 +389,7 @@ void f2fs_evict_inode(struct inode *inode) ...@@ -389,10 +389,7 @@ void f2fs_evict_inode(struct inode *inode)
} }
} }
out_clear: out_clear:
#ifdef CONFIG_F2FS_FS_ENCRYPTION fscrypt_put_encryption_info(inode, NULL);
if (fi->i_crypt_info)
f2fs_free_encryption_info(inode, fi->i_crypt_info);
#endif
clear_inode(inode); clear_inode(inode);
} }
......
...@@ -169,7 +169,7 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir, ...@@ -169,7 +169,7 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir,
int err; int err;
if (f2fs_encrypted_inode(dir) && if (f2fs_encrypted_inode(dir) &&
!f2fs_is_child_context_consistent_with_parent(dir, inode)) !fscrypt_has_permitted_context(dir, inode))
return -EPERM; return -EPERM;
f2fs_balance_fs(sbi, true); f2fs_balance_fs(sbi, true);
...@@ -352,20 +352,20 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry, ...@@ -352,20 +352,20 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry,
struct f2fs_sb_info *sbi = F2FS_I_SB(dir); struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
struct inode *inode; struct inode *inode;
size_t len = strlen(symname); size_t len = strlen(symname);
struct f2fs_str disk_link = FSTR_INIT((char *)symname, len + 1); struct fscrypt_str disk_link = FSTR_INIT((char *)symname, len + 1);
struct f2fs_encrypted_symlink_data *sd = NULL; struct fscrypt_symlink_data *sd = NULL;
int err; int err;
if (f2fs_encrypted_inode(dir)) { if (f2fs_encrypted_inode(dir)) {
err = f2fs_get_encryption_info(dir); err = fscrypt_get_encryption_info(dir);
if (err) if (err)
return err; return err;
if (!f2fs_encrypted_inode(dir)) if (!fscrypt_has_encryption_key(dir))
return -EPERM; return -EPERM;
disk_link.len = (f2fs_fname_encrypted_size(dir, len) + disk_link.len = (fscrypt_fname_encrypted_size(dir, len) +
sizeof(struct f2fs_encrypted_symlink_data)); sizeof(struct fscrypt_symlink_data));
} }
if (disk_link.len > dir->i_sb->s_blocksize) if (disk_link.len > dir->i_sb->s_blocksize)
...@@ -393,7 +393,7 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry, ...@@ -393,7 +393,7 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry,
if (f2fs_encrypted_inode(inode)) { if (f2fs_encrypted_inode(inode)) {
struct qstr istr = QSTR_INIT(symname, len); struct qstr istr = QSTR_INIT(symname, len);
struct f2fs_str ostr; struct fscrypt_str ostr;
sd = kzalloc(disk_link.len, GFP_NOFS); sd = kzalloc(disk_link.len, GFP_NOFS);
if (!sd) { if (!sd) {
...@@ -401,18 +401,18 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry, ...@@ -401,18 +401,18 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry,
goto err_out; goto err_out;
} }
err = f2fs_get_encryption_info(inode); err = fscrypt_get_encryption_info(inode);
if (err) if (err)
goto err_out; goto err_out;
if (!f2fs_encrypted_inode(inode)) { if (!fscrypt_has_encryption_key(inode)) {
err = -EPERM; err = -EPERM;
goto err_out; goto err_out;
} }
ostr.name = sd->encrypted_path; ostr.name = sd->encrypted_path;
ostr.len = disk_link.len; ostr.len = disk_link.len;
err = f2fs_fname_usr_to_disk(inode, &istr, &ostr); err = fscrypt_fname_usr_to_disk(inode, &istr, &ostr);
if (err < 0) if (err < 0)
goto err_out; goto err_out;
...@@ -593,7 +593,7 @@ static int __f2fs_tmpfile(struct inode *dir, struct dentry *dentry, ...@@ -593,7 +593,7 @@ static int __f2fs_tmpfile(struct inode *dir, struct dentry *dentry,
static int f2fs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) static int f2fs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
{ {
if (f2fs_encrypted_inode(dir)) { if (f2fs_encrypted_inode(dir)) {
int err = f2fs_get_encryption_info(dir); int err = fscrypt_get_encryption_info(dir);
if (err) if (err)
return err; return err;
} }
...@@ -623,8 +623,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -623,8 +623,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
int err = -ENOENT; int err = -ENOENT;
if ((old_dir != new_dir) && f2fs_encrypted_inode(new_dir) && if ((old_dir != new_dir) && f2fs_encrypted_inode(new_dir) &&
!f2fs_is_child_context_consistent_with_parent(new_dir, !fscrypt_has_permitted_context(new_dir, old_inode)) {
old_inode)) {
err = -EPERM; err = -EPERM;
goto out; goto out;
} }
...@@ -804,11 +803,9 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -804,11 +803,9 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
int err = -ENOENT; int err = -ENOENT;
if ((f2fs_encrypted_inode(old_dir) || f2fs_encrypted_inode(new_dir)) && if ((f2fs_encrypted_inode(old_dir) || f2fs_encrypted_inode(new_dir)) &&
(old_dir != new_dir) && (old_dir != new_dir) &&
(!f2fs_is_child_context_consistent_with_parent(new_dir, (!fscrypt_has_permitted_context(new_dir, old_inode) ||
old_inode) || !fscrypt_has_permitted_context(old_dir, new_inode)))
!f2fs_is_child_context_consistent_with_parent(old_dir,
new_inode)))
return -EPERM; return -EPERM;
old_entry = f2fs_find_entry(old_dir, &old_dentry->d_name, &old_page); old_entry = f2fs_find_entry(old_dir, &old_dentry->d_name, &old_page);
...@@ -970,16 +967,15 @@ static int f2fs_rename2(struct inode *old_dir, struct dentry *old_dentry, ...@@ -970,16 +967,15 @@ static int f2fs_rename2(struct inode *old_dir, struct dentry *old_dentry,
return f2fs_rename(old_dir, old_dentry, new_dir, new_dentry, flags); return f2fs_rename(old_dir, old_dentry, new_dir, new_dentry, flags);
} }
#ifdef CONFIG_F2FS_FS_ENCRYPTION
static const char *f2fs_encrypted_get_link(struct dentry *dentry, static const char *f2fs_encrypted_get_link(struct dentry *dentry,
struct inode *inode, struct inode *inode,
struct delayed_call *done) struct delayed_call *done)
{ {
struct page *cpage = NULL; struct page *cpage = NULL;
char *caddr, *paddr = NULL; char *caddr, *paddr = NULL;
struct f2fs_str cstr = FSTR_INIT(NULL, 0); struct fscrypt_str cstr = FSTR_INIT(NULL, 0);
struct f2fs_str pstr = FSTR_INIT(NULL, 0); struct fscrypt_str pstr = FSTR_INIT(NULL, 0);
struct f2fs_encrypted_symlink_data *sd; struct fscrypt_symlink_data *sd;
loff_t size = min_t(loff_t, i_size_read(inode), PAGE_SIZE - 1); loff_t size = min_t(loff_t, i_size_read(inode), PAGE_SIZE - 1);
u32 max_size = inode->i_sb->s_blocksize; u32 max_size = inode->i_sb->s_blocksize;
int res; int res;
...@@ -987,7 +983,7 @@ static const char *f2fs_encrypted_get_link(struct dentry *dentry, ...@@ -987,7 +983,7 @@ static const char *f2fs_encrypted_get_link(struct dentry *dentry,
if (!dentry) if (!dentry)
return ERR_PTR(-ECHILD); return ERR_PTR(-ECHILD);
res = f2fs_get_encryption_info(inode); res = fscrypt_get_encryption_info(inode);
if (res) if (res)
return ERR_PTR(res); return ERR_PTR(res);
...@@ -998,7 +994,7 @@ static const char *f2fs_encrypted_get_link(struct dentry *dentry, ...@@ -998,7 +994,7 @@ static const char *f2fs_encrypted_get_link(struct dentry *dentry,
caddr[size] = 0; caddr[size] = 0;
/* Symlink is encrypted */ /* Symlink is encrypted */
sd = (struct f2fs_encrypted_symlink_data *)caddr; sd = (struct fscrypt_symlink_data *)caddr;
cstr.name = sd->encrypted_path; cstr.name = sd->encrypted_path;
cstr.len = le16_to_cpu(sd->len); cstr.len = le16_to_cpu(sd->len);
...@@ -1014,17 +1010,16 @@ static const char *f2fs_encrypted_get_link(struct dentry *dentry, ...@@ -1014,17 +1010,16 @@ static const char *f2fs_encrypted_get_link(struct dentry *dentry,
goto errout; goto errout;
} }
if ((cstr.len + sizeof(struct f2fs_encrypted_symlink_data) - 1) > if ((cstr.len + sizeof(struct fscrypt_symlink_data) - 1) > max_size) {
max_size) {
/* Symlink data on the disk is corrupted */ /* Symlink data on the disk is corrupted */
res = -EIO; res = -EIO;
goto errout; goto errout;
} }
res = f2fs_fname_crypto_alloc_buffer(inode, cstr.len, &pstr); res = fscrypt_fname_alloc_buffer(inode, cstr.len, &pstr);
if (res) if (res)
goto errout; goto errout;
res = f2fs_fname_disk_to_usr(inode, NULL, &cstr, &pstr); res = fscrypt_fname_disk_to_usr(inode, 0, 0, &cstr, &pstr);
if (res < 0) if (res < 0)
goto errout; goto errout;
...@@ -1037,7 +1032,7 @@ static const char *f2fs_encrypted_get_link(struct dentry *dentry, ...@@ -1037,7 +1032,7 @@ static const char *f2fs_encrypted_get_link(struct dentry *dentry,
set_delayed_call(done, kfree_link, paddr); set_delayed_call(done, kfree_link, paddr);
return paddr; return paddr;
errout: errout:
f2fs_fname_crypto_free_buffer(&pstr); fscrypt_fname_free_buffer(&pstr);
page_cache_release(cpage); page_cache_release(cpage);
return ERR_PTR(res); return ERR_PTR(res);
} }
...@@ -1054,7 +1049,6 @@ const struct inode_operations f2fs_encrypted_symlink_inode_operations = { ...@@ -1054,7 +1049,6 @@ const struct inode_operations f2fs_encrypted_symlink_inode_operations = {
.removexattr = generic_removexattr, .removexattr = generic_removexattr,
#endif #endif
}; };
#endif
const struct inode_operations f2fs_dir_inode_operations = { const struct inode_operations f2fs_dir_inode_operations = {
.create = f2fs_create, .create = f2fs_create,
......
...@@ -470,10 +470,6 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb) ...@@ -470,10 +470,6 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb)
/* Will be used by directory only */ /* Will be used by directory only */
fi->i_dir_level = F2FS_SB(sb)->dir_level; fi->i_dir_level = F2FS_SB(sb)->dir_level;
#ifdef CONFIG_F2FS_FS_ENCRYPTION
fi->i_crypt_info = NULL;
#endif
return &fi->vfs_inode; return &fi->vfs_inode;
} }
...@@ -507,11 +503,7 @@ static int f2fs_drop_inode(struct inode *inode) ...@@ -507,11 +503,7 @@ static int f2fs_drop_inode(struct inode *inode)
sb_end_intwrite(inode->i_sb); sb_end_intwrite(inode->i_sb);
#ifdef CONFIG_F2FS_FS_ENCRYPTION fscrypt_put_encryption_info(inode, NULL);
if (F2FS_I(inode)->i_crypt_info)
f2fs_free_encryption_info(inode,
F2FS_I(inode)->i_crypt_info);
#endif
spin_lock(&inode->i_lock); spin_lock(&inode->i_lock);
atomic_dec(&inode->i_count); atomic_dec(&inode->i_count);
} }
...@@ -891,6 +883,41 @@ static struct super_operations f2fs_sops = { ...@@ -891,6 +883,41 @@ static struct super_operations f2fs_sops = {
.remount_fs = f2fs_remount, .remount_fs = f2fs_remount,
}; };
#ifdef CONFIG_F2FS_FS_ENCRYPTION
static int f2fs_get_context(struct inode *inode, void *ctx, size_t len)
{
return f2fs_getxattr(inode, F2FS_XATTR_INDEX_ENCRYPTION,
F2FS_XATTR_NAME_ENCRYPTION_CONTEXT,
ctx, len, NULL);
}
static int f2fs_set_context(struct inode *inode, const void *ctx, size_t len,
void *fs_data)
{
return f2fs_setxattr(inode, F2FS_XATTR_INDEX_ENCRYPTION,
F2FS_XATTR_NAME_ENCRYPTION_CONTEXT,
ctx, len, fs_data, XATTR_CREATE);
}
static unsigned f2fs_max_namelen(struct inode *inode)
{
return S_ISLNK(inode->i_mode) ?
inode->i_sb->s_blocksize : F2FS_NAME_LEN;
}
static struct fscrypt_operations f2fs_cryptops = {
.get_context = f2fs_get_context,
.set_context = f2fs_set_context,
.is_encrypted = f2fs_encrypted_inode,
.empty_dir = f2fs_empty_dir,
.max_namelen = f2fs_max_namelen,
};
#else
static struct fscrypt_operations f2fs_cryptops = {
.is_encrypted = f2fs_encrypted_inode,
};
#endif
static struct inode *f2fs_nfs_get_inode(struct super_block *sb, static struct inode *f2fs_nfs_get_inode(struct super_block *sb,
u64 ino, u32 generation) u64 ino, u32 generation)
{ {
...@@ -1314,6 +1341,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -1314,6 +1341,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
get_random_bytes(&sbi->s_next_generation, sizeof(u32)); get_random_bytes(&sbi->s_next_generation, sizeof(u32));
sb->s_op = &f2fs_sops; sb->s_op = &f2fs_sops;
sb->s_cop = &f2fs_cryptops;
sb->s_xattr = f2fs_xattr_handlers; sb->s_xattr = f2fs_xattr_handlers;
sb->s_export_op = &f2fs_export_ops; sb->s_export_op = &f2fs_export_ops;
sb->s_magic = F2FS_SUPER_MAGIC; sb->s_magic = F2FS_SUPER_MAGIC;
...@@ -1619,13 +1647,9 @@ static int __init init_f2fs_fs(void) ...@@ -1619,13 +1647,9 @@ static int __init init_f2fs_fs(void)
err = -ENOMEM; err = -ENOMEM;
goto free_extent_cache; goto free_extent_cache;
} }
err = f2fs_init_crypto();
if (err)
goto free_kset;
err = register_shrinker(&f2fs_shrinker_info); err = register_shrinker(&f2fs_shrinker_info);
if (err) if (err)
goto free_crypto; goto free_kset;
err = register_filesystem(&f2fs_fs_type); err = register_filesystem(&f2fs_fs_type);
if (err) if (err)
...@@ -1640,8 +1664,6 @@ static int __init init_f2fs_fs(void) ...@@ -1640,8 +1664,6 @@ static int __init init_f2fs_fs(void)
unregister_filesystem(&f2fs_fs_type); unregister_filesystem(&f2fs_fs_type);
free_shrinker: free_shrinker:
unregister_shrinker(&f2fs_shrinker_info); unregister_shrinker(&f2fs_shrinker_info);
free_crypto:
f2fs_exit_crypto();
free_kset: free_kset:
kset_unregister(f2fs_kset); kset_unregister(f2fs_kset);
free_extent_cache: free_extent_cache:
...@@ -1664,7 +1686,6 @@ static void __exit exit_f2fs_fs(void) ...@@ -1664,7 +1686,6 @@ static void __exit exit_f2fs_fs(void)
f2fs_destroy_root_stats(); f2fs_destroy_root_stats();
unregister_shrinker(&f2fs_shrinker_info); unregister_shrinker(&f2fs_shrinker_info);
unregister_filesystem(&f2fs_fs_type); unregister_filesystem(&f2fs_fs_type);
f2fs_exit_crypto();
destroy_extent_cache(); destroy_extent_cache();
destroy_checkpoint_caches(); destroy_checkpoint_caches();
destroy_segment_manager_caches(); destroy_segment_manager_caches();
......
...@@ -228,6 +228,8 @@ struct dentry_operations { ...@@ -228,6 +228,8 @@ struct dentry_operations {
#define DCACHE_FALLTHRU 0x01000000 /* Fall through to lower layer */ #define DCACHE_FALLTHRU 0x01000000 /* Fall through to lower layer */
#define DCACHE_OP_SELECT_INODE 0x02000000 /* Unioned entry: dcache op selects inode */ #define DCACHE_OP_SELECT_INODE 0x02000000 /* Unioned entry: dcache op selects inode */
#define DCACHE_ENCRYPTED_WITH_KEY 0x04000000 /* dir is encrypted with a valid key */
extern seqlock_t rename_lock; extern seqlock_t rename_lock;
/* /*
......
...@@ -53,6 +53,8 @@ struct swap_info_struct; ...@@ -53,6 +53,8 @@ struct swap_info_struct;
struct seq_file; struct seq_file;
struct workqueue_struct; struct workqueue_struct;
struct iov_iter; struct iov_iter;
struct fscrypt_info;
struct fscrypt_operations;
extern void __init inode_init(void); extern void __init inode_init(void);
extern void __init inode_init_early(void); extern void __init inode_init_early(void);
...@@ -678,6 +680,10 @@ struct inode { ...@@ -678,6 +680,10 @@ struct inode {
struct hlist_head i_fsnotify_marks; struct hlist_head i_fsnotify_marks;
#endif #endif
#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
struct fscrypt_info *i_crypt_info;
#endif
void *i_private; /* fs or device private pointer */ void *i_private; /* fs or device private pointer */
}; };
...@@ -1323,6 +1329,8 @@ struct super_block { ...@@ -1323,6 +1329,8 @@ struct super_block {
#endif #endif
const struct xattr_handler **s_xattr; const struct xattr_handler **s_xattr;
const struct fscrypt_operations *s_cop;
struct hlist_bl_head s_anon; /* anonymous dentries for (nfs) exporting */ struct hlist_bl_head s_anon; /* anonymous dentries for (nfs) exporting */
struct list_head s_mounts; /* list of mounts; _not_ for fs use */ struct list_head s_mounts; /* list of mounts; _not_ for fs use */
struct block_device *s_bdev; struct block_device *s_bdev;
......
This diff is collapsed.
...@@ -246,6 +246,24 @@ struct fsxattr { ...@@ -246,6 +246,24 @@ struct fsxattr {
#define FS_IOC_FSGETXATTR _IOR ('X', 31, struct fsxattr) #define FS_IOC_FSGETXATTR _IOR ('X', 31, struct fsxattr)
#define FS_IOC_FSSETXATTR _IOW ('X', 32, struct fsxattr) #define FS_IOC_FSSETXATTR _IOW ('X', 32, struct fsxattr)
/*
* File system encryption support
*/
/* Policy provided via an ioctl on the topmost directory */
#define FS_KEY_DESCRIPTOR_SIZE 8
struct fscrypt_policy {
__u8 version;
__u8 contents_encryption_mode;
__u8 filenames_encryption_mode;
__u8 flags;
__u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE];
} __packed;
#define FS_IOC_SET_ENCRYPTION_POLICY _IOR('f', 19, struct fscrypt_policy)
#define FS_IOC_GET_ENCRYPTION_PWSALT _IOW('f', 20, __u8[16])
#define FS_IOC_GET_ENCRYPTION_POLICY _IOW('f', 21, struct fscrypt_policy)
/* /*
* Inode flags (FS_IOC_GETFLAGS / FS_IOC_SETFLAGS) * Inode flags (FS_IOC_GETFLAGS / FS_IOC_SETFLAGS)
* *
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment