Commit fd59ccc5 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'fscrypt_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/fscrypt

Pull fscrypt updates from Ted Ts'o:
 "Add bunch of cleanups, and add support for the Speck128/256
  algorithms.

  Yes, Speck is contrversial, but the intention is to use them only for
  the lowest end Android devices, where the alternative *really* is no
  encryption at all for data stored at rest"

* tag 'fscrypt_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/fscrypt:
  fscrypt: log the crypto algorithm implementations
  fscrypt: add Speck128/256 support
  fscrypt: only derive the needed portion of the key
  fscrypt: separate key lookup from key derivation
  fscrypt: use a common logging function
  fscrypt: remove internal key size constants
  fscrypt: remove unnecessary check for non-logon key type
  fscrypt: make fscrypt_operations.max_namelen an integer
  fscrypt: drop empty name check from fname_decrypt()
  fscrypt: drop max_namelen check from fname_decrypt()
  fscrypt: don't special-case EOPNOTSUPP from fscrypt_get_encryption_info()
  fscrypt: don't clear flags on crypto transform
  fscrypt: remove stale comment from fscrypt_d_revalidate()
  fscrypt: remove error messages for skcipher_request_alloc() failure
  fscrypt: remove unnecessary NULL check when allocating skcipher
  fscrypt: clean up after fscrypt_prepare_lookup() conversions
  fs, fscrypt: only define ->s_cop when FS_ENCRYPTION is enabled
  fscrypt: use unbound workqueue for decryption
parents 6567af78 e1cc40e5
...@@ -191,11 +191,21 @@ Currently, the following pairs of encryption modes are supported: ...@@ -191,11 +191,21 @@ Currently, the following pairs of encryption modes are supported:
- AES-256-XTS for contents and AES-256-CTS-CBC for filenames - AES-256-XTS for contents and AES-256-CTS-CBC for filenames
- AES-128-CBC for contents and AES-128-CTS-CBC for filenames - AES-128-CBC for contents and AES-128-CTS-CBC for filenames
- Speck128/256-XTS for contents and Speck128/256-CTS-CBC for filenames
It is strongly recommended to use AES-256-XTS for contents encryption. It is strongly recommended to use AES-256-XTS for contents encryption.
AES-128-CBC was added only for low-powered embedded devices with AES-128-CBC was added only for low-powered embedded devices with
crypto accelerators such as CAAM or CESA that do not support XTS. crypto accelerators such as CAAM or CESA that do not support XTS.
Similarly, Speck128/256 support was only added for older or low-end
CPUs which cannot do AES fast enough -- especially ARM CPUs which have
NEON instructions but not the Cryptography Extensions -- and for which
it would not otherwise be feasible to use encryption at all. It is
not recommended to use Speck on CPUs that have AES instructions.
Speck support is only available if it has been enabled in the crypto
API via CONFIG_CRYPTO_SPECK. Also, on ARM platforms, to get
acceptable performance CONFIG_CRYPTO_SPECK_NEON must be enabled.
New encryption modes can be added relatively easily, without changes New encryption modes can be added relatively easily, without changes
to individual filesystems. However, authenticated encryption (AE) to individual filesystems. However, authenticated encryption (AE)
modes are not currently supported because of the difficulty of dealing modes are not currently supported because of the difficulty of dealing
......
...@@ -156,12 +156,8 @@ int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw, ...@@ -156,12 +156,8 @@ int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw,
} }
req = skcipher_request_alloc(tfm, gfp_flags); req = skcipher_request_alloc(tfm, gfp_flags);
if (!req) { if (!req)
printk_ratelimited(KERN_ERR
"%s: crypto_request_alloc() failed\n",
__func__);
return -ENOMEM; return -ENOMEM;
}
skcipher_request_set_callback( skcipher_request_set_callback(
req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
...@@ -178,9 +174,10 @@ int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw, ...@@ -178,9 +174,10 @@ int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw,
res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
skcipher_request_free(req); skcipher_request_free(req);
if (res) { if (res) {
printk_ratelimited(KERN_ERR fscrypt_err(inode->i_sb,
"%s: crypto_skcipher_encrypt() returned %d\n", "%scryption failed for inode %lu, block %llu: %d",
__func__, res); (rw == FS_DECRYPT ? "de" : "en"),
inode->i_ino, lblk_num, res);
return res; return res;
} }
return 0; return 0;
...@@ -326,7 +323,6 @@ static int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags) ...@@ -326,7 +323,6 @@ static int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags)
return 0; return 0;
} }
/* this should eventually be an flag in d_flags */
spin_lock(&dentry->d_lock); spin_lock(&dentry->d_lock);
cached_with_key = dentry->d_flags & DCACHE_ENCRYPTED_WITH_KEY; cached_with_key = dentry->d_flags & DCACHE_ENCRYPTED_WITH_KEY;
spin_unlock(&dentry->d_lock); spin_unlock(&dentry->d_lock);
...@@ -353,7 +349,6 @@ static int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags) ...@@ -353,7 +349,6 @@ static int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags)
const struct dentry_operations fscrypt_d_ops = { const struct dentry_operations fscrypt_d_ops = {
.d_revalidate = fscrypt_d_revalidate, .d_revalidate = fscrypt_d_revalidate,
}; };
EXPORT_SYMBOL(fscrypt_d_ops);
void fscrypt_restore_control_page(struct page *page) void fscrypt_restore_control_page(struct page *page)
{ {
...@@ -422,13 +417,43 @@ int fscrypt_initialize(unsigned int cop_flags) ...@@ -422,13 +417,43 @@ int fscrypt_initialize(unsigned int cop_flags)
return res; return res;
} }
void fscrypt_msg(struct super_block *sb, const char *level,
const char *fmt, ...)
{
static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL,
DEFAULT_RATELIMIT_BURST);
struct va_format vaf;
va_list args;
if (!__ratelimit(&rs))
return;
va_start(args, fmt);
vaf.fmt = fmt;
vaf.va = &args;
if (sb)
printk("%sfscrypt (%s): %pV\n", level, sb->s_id, &vaf);
else
printk("%sfscrypt: %pV\n", level, &vaf);
va_end(args);
}
/** /**
* fscrypt_init() - Set up for fs encryption. * fscrypt_init() - Set up for fs encryption.
*/ */
static int __init fscrypt_init(void) static int __init fscrypt_init(void)
{ {
/*
* Use an unbound workqueue to allow bios to be decrypted in parallel
* even when they happen to complete on the same CPU. This sacrifices
* locality, but it's worthwhile since decryption is CPU-intensive.
*
* Also use a high-priority workqueue to prioritize decryption work,
* which blocks reads from completing, over regular application tasks.
*/
fscrypt_read_workqueue = alloc_workqueue("fscrypt_read_queue", fscrypt_read_workqueue = alloc_workqueue("fscrypt_read_queue",
WQ_HIGHPRI, 0); WQ_UNBOUND | WQ_HIGHPRI,
num_online_cpus());
if (!fscrypt_read_workqueue) if (!fscrypt_read_workqueue)
goto fail; goto fail;
......
...@@ -59,11 +59,8 @@ int fname_encrypt(struct inode *inode, const struct qstr *iname, ...@@ -59,11 +59,8 @@ int fname_encrypt(struct inode *inode, const struct qstr *iname,
/* Set up the encryption request */ /* Set up the encryption request */
req = skcipher_request_alloc(tfm, GFP_NOFS); req = skcipher_request_alloc(tfm, GFP_NOFS);
if (!req) { if (!req)
printk_ratelimited(KERN_ERR
"%s: skcipher_request_alloc() failed\n", __func__);
return -ENOMEM; return -ENOMEM;
}
skcipher_request_set_callback(req, skcipher_request_set_callback(req,
CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
crypto_req_done, &wait); crypto_req_done, &wait);
...@@ -74,8 +71,9 @@ int fname_encrypt(struct inode *inode, const struct qstr *iname, ...@@ -74,8 +71,9 @@ int fname_encrypt(struct inode *inode, const struct qstr *iname,
res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
skcipher_request_free(req); skcipher_request_free(req);
if (res < 0) { if (res < 0) {
printk_ratelimited(KERN_ERR fscrypt_err(inode->i_sb,
"%s: Error (error code %d)\n", __func__, res); "Filename encryption failed for inode %lu: %d",
inode->i_ino, res);
return res; return res;
} }
...@@ -96,23 +94,14 @@ static int fname_decrypt(struct inode *inode, ...@@ -96,23 +94,14 @@ static int fname_decrypt(struct inode *inode,
struct skcipher_request *req = NULL; struct skcipher_request *req = NULL;
DECLARE_CRYPTO_WAIT(wait); DECLARE_CRYPTO_WAIT(wait);
struct scatterlist src_sg, dst_sg; struct scatterlist src_sg, dst_sg;
struct fscrypt_info *ci = inode->i_crypt_info; struct crypto_skcipher *tfm = inode->i_crypt_info->ci_ctfm;
struct crypto_skcipher *tfm = ci->ci_ctfm;
int res = 0; int res = 0;
char iv[FS_CRYPTO_BLOCK_SIZE]; char iv[FS_CRYPTO_BLOCK_SIZE];
unsigned lim;
lim = inode->i_sb->s_cop->max_namelen(inode);
if (iname->len <= 0 || iname->len > lim)
return -EIO;
/* Allocate request */ /* Allocate request */
req = skcipher_request_alloc(tfm, GFP_NOFS); req = skcipher_request_alloc(tfm, GFP_NOFS);
if (!req) { if (!req)
printk_ratelimited(KERN_ERR
"%s: crypto_request_alloc() failed\n", __func__);
return -ENOMEM; return -ENOMEM;
}
skcipher_request_set_callback(req, skcipher_request_set_callback(req,
CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
crypto_req_done, &wait); crypto_req_done, &wait);
...@@ -127,8 +116,9 @@ static int fname_decrypt(struct inode *inode, ...@@ -127,8 +116,9 @@ static int fname_decrypt(struct inode *inode,
res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait); res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait);
skcipher_request_free(req); skcipher_request_free(req);
if (res < 0) { if (res < 0) {
printk_ratelimited(KERN_ERR fscrypt_err(inode->i_sb,
"%s: Error (error code %d)\n", __func__, res); "Filename decryption failed for inode %lu: %d",
inode->i_ino, res);
return res; return res;
} }
...@@ -341,12 +331,12 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname, ...@@ -341,12 +331,12 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
return 0; return 0;
} }
ret = fscrypt_get_encryption_info(dir); ret = fscrypt_get_encryption_info(dir);
if (ret && ret != -EOPNOTSUPP) if (ret)
return ret; return ret;
if (dir->i_crypt_info) { if (dir->i_crypt_info) {
if (!fscrypt_fname_encrypted_size(dir, iname->len, if (!fscrypt_fname_encrypted_size(dir, iname->len,
dir->i_sb->s_cop->max_namelen(dir), dir->i_sb->s_cop->max_namelen,
&fname->crypto_buf.len)) &fname->crypto_buf.len))
return -ENAMETOOLONG; return -ENAMETOOLONG;
fname->crypto_buf.name = kmalloc(fname->crypto_buf.len, fname->crypto_buf.name = kmalloc(fname->crypto_buf.len,
......
...@@ -18,14 +18,6 @@ ...@@ -18,14 +18,6 @@
/* Encryption parameters */ /* Encryption parameters */
#define FS_IV_SIZE 16 #define FS_IV_SIZE 16
#define FS_AES_128_ECB_KEY_SIZE 16
#define FS_AES_128_CBC_KEY_SIZE 16
#define FS_AES_128_CTS_KEY_SIZE 16
#define FS_AES_256_GCM_KEY_SIZE 32
#define FS_AES_256_CBC_KEY_SIZE 32
#define FS_AES_256_CTS_KEY_SIZE 32
#define FS_AES_256_XTS_KEY_SIZE 64
#define FS_KEY_DERIVATION_NONCE_SIZE 16 #define FS_KEY_DERIVATION_NONCE_SIZE 16
/** /**
...@@ -91,6 +83,10 @@ static inline bool fscrypt_valid_enc_modes(u32 contents_mode, ...@@ -91,6 +83,10 @@ static inline bool fscrypt_valid_enc_modes(u32 contents_mode,
filenames_mode == FS_ENCRYPTION_MODE_AES_256_CTS) filenames_mode == FS_ENCRYPTION_MODE_AES_256_CTS)
return true; return true;
if (contents_mode == FS_ENCRYPTION_MODE_SPECK128_256_XTS &&
filenames_mode == FS_ENCRYPTION_MODE_SPECK128_256_CTS)
return true;
return false; return false;
} }
...@@ -106,6 +102,15 @@ extern int fscrypt_do_page_crypto(const struct inode *inode, ...@@ -106,6 +102,15 @@ extern int fscrypt_do_page_crypto(const struct inode *inode,
gfp_t gfp_flags); gfp_t gfp_flags);
extern struct page *fscrypt_alloc_bounce_page(struct fscrypt_ctx *ctx, extern struct page *fscrypt_alloc_bounce_page(struct fscrypt_ctx *ctx,
gfp_t gfp_flags); gfp_t gfp_flags);
extern const struct dentry_operations fscrypt_d_ops;
extern void __printf(3, 4) __cold
fscrypt_msg(struct super_block *sb, const char *level, const char *fmt, ...);
#define fscrypt_warn(sb, fmt, ...) \
fscrypt_msg(sb, KERN_WARNING, fmt, ##__VA_ARGS__)
#define fscrypt_err(sb, fmt, ...) \
fscrypt_msg(sb, KERN_ERR, fmt, ##__VA_ARGS__)
/* fname.c */ /* fname.c */
extern int fname_encrypt(struct inode *inode, const struct qstr *iname, extern int fname_encrypt(struct inode *inode, const struct qstr *iname,
......
...@@ -39,7 +39,8 @@ int fscrypt_file_open(struct inode *inode, struct file *filp) ...@@ -39,7 +39,8 @@ int fscrypt_file_open(struct inode *inode, struct file *filp)
dir = dget_parent(file_dentry(filp)); dir = dget_parent(file_dentry(filp));
if (IS_ENCRYPTED(d_inode(dir)) && if (IS_ENCRYPTED(d_inode(dir)) &&
!fscrypt_has_permitted_context(d_inode(dir), inode)) { !fscrypt_has_permitted_context(d_inode(dir), inode)) {
pr_warn_ratelimited("fscrypt: inconsistent encryption contexts: %lu/%lu", fscrypt_warn(inode->i_sb,
"inconsistent encryption contexts: %lu/%lu",
d_inode(dir)->i_ino, inode->i_ino); d_inode(dir)->i_ino, inode->i_ino);
err = -EPERM; err = -EPERM;
} }
......
This diff is collapsed.
...@@ -1267,19 +1267,13 @@ static bool ext4_dummy_context(struct inode *inode) ...@@ -1267,19 +1267,13 @@ static bool ext4_dummy_context(struct inode *inode)
return DUMMY_ENCRYPTION_ENABLED(EXT4_SB(inode->i_sb)); return DUMMY_ENCRYPTION_ENABLED(EXT4_SB(inode->i_sb));
} }
static unsigned ext4_max_namelen(struct inode *inode)
{
return S_ISLNK(inode->i_mode) ? inode->i_sb->s_blocksize :
EXT4_NAME_LEN;
}
static const struct fscrypt_operations ext4_cryptops = { static const struct fscrypt_operations ext4_cryptops = {
.key_prefix = "ext4:", .key_prefix = "ext4:",
.get_context = ext4_get_context, .get_context = ext4_get_context,
.set_context = ext4_set_context, .set_context = ext4_set_context,
.dummy_context = ext4_dummy_context, .dummy_context = ext4_dummy_context,
.empty_dir = ext4_empty_dir, .empty_dir = ext4_empty_dir,
.max_namelen = ext4_max_namelen, .max_namelen = EXT4_NAME_LEN,
}; };
#endif #endif
......
...@@ -1930,19 +1930,13 @@ static bool f2fs_dummy_context(struct inode *inode) ...@@ -1930,19 +1930,13 @@ static bool f2fs_dummy_context(struct inode *inode)
return DUMMY_ENCRYPTION_ENABLED(F2FS_I_SB(inode)); return DUMMY_ENCRYPTION_ENABLED(F2FS_I_SB(inode));
} }
static unsigned f2fs_max_namelen(struct inode *inode)
{
return S_ISLNK(inode->i_mode) ?
inode->i_sb->s_blocksize : F2FS_NAME_LEN;
}
static const struct fscrypt_operations f2fs_cryptops = { static const struct fscrypt_operations f2fs_cryptops = {
.key_prefix = "f2fs:", .key_prefix = "f2fs:",
.get_context = f2fs_get_context, .get_context = f2fs_get_context,
.set_context = f2fs_set_context, .set_context = f2fs_set_context,
.dummy_context = f2fs_dummy_context, .dummy_context = f2fs_dummy_context,
.empty_dir = f2fs_empty_dir, .empty_dir = f2fs_empty_dir,
.max_namelen = f2fs_max_namelen, .max_namelen = F2FS_NAME_LEN,
}; };
#endif #endif
......
...@@ -24,14 +24,6 @@ static bool ubifs_crypt_empty_dir(struct inode *inode) ...@@ -24,14 +24,6 @@ static bool ubifs_crypt_empty_dir(struct inode *inode)
return ubifs_check_dir_empty(inode) == 0; return ubifs_check_dir_empty(inode) == 0;
} }
static unsigned int ubifs_crypt_max_namelen(struct inode *inode)
{
if (S_ISLNK(inode->i_mode))
return UBIFS_MAX_INO_DATA;
else
return UBIFS_MAX_NLEN;
}
int ubifs_encrypt(const struct inode *inode, struct ubifs_data_node *dn, int ubifs_encrypt(const struct inode *inode, struct ubifs_data_node *dn,
unsigned int in_len, unsigned int *out_len, int block) unsigned int in_len, unsigned int *out_len, int block)
{ {
...@@ -89,5 +81,5 @@ const struct fscrypt_operations ubifs_crypt_operations = { ...@@ -89,5 +81,5 @@ const struct fscrypt_operations ubifs_crypt_operations = {
.get_context = ubifs_crypt_get_context, .get_context = ubifs_crypt_get_context,
.set_context = ubifs_crypt_set_context, .set_context = ubifs_crypt_set_context,
.empty_dir = ubifs_crypt_empty_dir, .empty_dir = ubifs_crypt_empty_dir,
.max_namelen = ubifs_crypt_max_namelen, .max_namelen = UBIFS_MAX_NLEN,
}; };
...@@ -1364,9 +1364,9 @@ struct super_block { ...@@ -1364,9 +1364,9 @@ struct super_block {
void *s_security; void *s_security;
#endif #endif
const struct xattr_handler **s_xattr; const struct xattr_handler **s_xattr;
#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
const struct fscrypt_operations *s_cop; const struct fscrypt_operations *s_cop;
#endif
struct hlist_bl_head s_roots; /* alternate root dentries for NFS */ struct hlist_bl_head s_roots; /* alternate root dentries for NFS */
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;
......
...@@ -64,16 +64,6 @@ static inline void fscrypt_restore_control_page(struct page *page) ...@@ -64,16 +64,6 @@ static inline void fscrypt_restore_control_page(struct page *page)
return; return;
} }
static inline void fscrypt_set_d_op(struct dentry *dentry)
{
return;
}
static inline void fscrypt_set_encrypted_dentry(struct dentry *dentry)
{
return;
}
/* policy.c */ /* policy.c */
static inline int fscrypt_ioctl_set_policy(struct file *filp, static inline int fscrypt_ioctl_set_policy(struct file *filp,
const void __user *arg) const void __user *arg)
......
...@@ -29,7 +29,7 @@ struct fscrypt_operations { ...@@ -29,7 +29,7 @@ struct fscrypt_operations {
int (*set_context)(struct inode *, const void *, size_t, void *); int (*set_context)(struct inode *, const void *, size_t, void *);
bool (*dummy_context)(struct inode *); bool (*dummy_context)(struct inode *);
bool (*empty_dir)(struct inode *); bool (*empty_dir)(struct inode *);
unsigned (*max_namelen)(struct inode *); unsigned int max_namelen;
}; };
struct fscrypt_ctx { struct fscrypt_ctx {
...@@ -74,20 +74,6 @@ static inline struct page *fscrypt_control_page(struct page *page) ...@@ -74,20 +74,6 @@ static inline struct page *fscrypt_control_page(struct page *page)
extern void fscrypt_restore_control_page(struct page *); extern void fscrypt_restore_control_page(struct page *);
extern const struct dentry_operations fscrypt_d_ops;
static inline void fscrypt_set_d_op(struct dentry *dentry)
{
d_set_d_op(dentry, &fscrypt_d_ops);
}
static inline void fscrypt_set_encrypted_dentry(struct dentry *dentry)
{
spin_lock(&dentry->d_lock);
dentry->d_flags |= DCACHE_ENCRYPTED_WITH_KEY;
spin_unlock(&dentry->d_lock);
}
/* policy.c */ /* policy.c */
extern int fscrypt_ioctl_set_policy(struct file *, const void __user *); extern int fscrypt_ioctl_set_policy(struct file *, const void __user *);
extern int fscrypt_ioctl_get_policy(struct file *, void __user *); extern int fscrypt_ioctl_get_policy(struct file *, void __user *);
......
...@@ -279,6 +279,8 @@ struct fsxattr { ...@@ -279,6 +279,8 @@ struct fsxattr {
#define FS_ENCRYPTION_MODE_AES_256_CTS 4 #define FS_ENCRYPTION_MODE_AES_256_CTS 4
#define FS_ENCRYPTION_MODE_AES_128_CBC 5 #define FS_ENCRYPTION_MODE_AES_128_CBC 5
#define FS_ENCRYPTION_MODE_AES_128_CTS 6 #define FS_ENCRYPTION_MODE_AES_128_CTS 6
#define FS_ENCRYPTION_MODE_SPECK128_256_XTS 7
#define FS_ENCRYPTION_MODE_SPECK128_256_CTS 8
struct fscrypt_policy { struct fscrypt_policy {
__u8 version; __u8 version;
......
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