Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
a551d7c8
Commit
a551d7c8
authored
Dec 12, 2016
by
Theodore Ts'o
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'fscrypt' into dev
parents
0cb80b48
6a34e4d2
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
242 additions
and
221 deletions
+242
-221
MAINTAINERS
MAINTAINERS
+1
-0
fs/crypto/Kconfig
fs/crypto/Kconfig
+0
-2
fs/crypto/crypto.c
fs/crypto/crypto.c
+83
-55
fs/crypto/fname.c
fs/crypto/fname.c
+2
-2
fs/crypto/fscrypt_private.h
fs/crypto/fscrypt_private.h
+93
-0
fs/crypto/keyinfo.c
fs/crypto/keyinfo.c
+4
-4
fs/crypto/policy.c
fs/crypto/policy.c
+22
-14
fs/ext4/ext4.h
fs/ext4/ext4.h
+2
-2
fs/ext4/inode.c
fs/ext4/inode.c
+0
-1
fs/ext4/ioctl.c
fs/ext4/ioctl.c
+4
-28
fs/f2fs/data.c
fs/f2fs/data.c
+0
-1
fs/f2fs/f2fs.h
fs/f2fs/f2fs.h
+2
-2
fs/f2fs/file.c
fs/f2fs/file.c
+2
-17
include/linux/fscrypto.h
include/linux/fscrypto.h
+13
-93
include/uapi/linux/fs.h
include/uapi/linux/fs.h
+14
-0
No files found.
MAINTAINERS
View file @
a551d7c8
...
...
@@ -5138,6 +5138,7 @@ F: include/linux/fscache*.h
FS-CRYPTO: FILE SYSTEM LEVEL ENCRYPTION SUPPORT
M: Theodore Y. Ts'o <tytso@mit.edu>
M: Jaegeuk Kim <jaegeuk@kernel.org>
L: linux-fsdevel@vger.kernel.org
S: Supported
F: fs/crypto/
F: include/linux/fscrypto.h
...
...
fs/crypto/Kconfig
View file @
a551d7c8
...
...
@@ -8,9 +8,7 @@ config FS_ENCRYPTION
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
...
...
fs/crypto/crypto.c
View file @
a551d7c8
...
...
@@ -27,7 +27,7 @@
#include <linux/bio.h>
#include <linux/dcache.h>
#include <linux/namei.h>
#include
<linux/fscrypto.h>
#include
"fscrypt_private.h"
static
unsigned
int
num_prealloc_crypto_pages
=
32
;
static
unsigned
int
num_prealloc_crypto_ctxs
=
128
;
...
...
@@ -63,7 +63,7 @@ void fscrypt_release_ctx(struct fscrypt_ctx *ctx)
{
unsigned
long
flags
;
if
(
ctx
->
flags
&
FS_
WRITE_PATH
_FL
&&
ctx
->
w
.
bounce_page
)
{
if
(
ctx
->
flags
&
FS_
CTX_HAS_BOUNCE_BUFFER
_FL
&&
ctx
->
w
.
bounce_page
)
{
mempool_free
(
ctx
->
w
.
bounce_page
,
fscrypt_bounce_page_pool
);
ctx
->
w
.
bounce_page
=
NULL
;
}
...
...
@@ -121,7 +121,7 @@ struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *inode, gfp_t gfp_flags)
}
else
{
ctx
->
flags
&=
~
FS_CTX_REQUIRES_FREE_ENCRYPT_FL
;
}
ctx
->
flags
&=
~
FS_
WRITE_PATH
_FL
;
ctx
->
flags
&=
~
FS_
CTX_HAS_BOUNCE_BUFFER
_FL
;
return
ctx
;
}
EXPORT_SYMBOL
(
fscrypt_get_ctx
);
...
...
@@ -147,9 +147,9 @@ typedef enum {
}
fscrypt_direction_t
;
static
int
do_page_crypto
(
const
struct
inode
*
inode
,
fscrypt_direction_t
rw
,
pgoff_t
index
,
fscrypt_direction_t
rw
,
u64
lblk_num
,
struct
page
*
src_page
,
struct
page
*
dest_page
,
unsigned
int
src_len
,
unsigned
int
src_offset
,
unsigned
int
len
,
unsigned
int
offs
,
gfp_t
gfp_flags
)
{
struct
{
...
...
@@ -163,6 +163,8 @@ static int do_page_crypto(const struct inode *inode,
struct
crypto_skcipher
*
tfm
=
ci
->
ci_ctfm
;
int
res
=
0
;
BUG_ON
(
len
==
0
);
req
=
skcipher_request_alloc
(
tfm
,
gfp_flags
);
if
(
!
req
)
{
printk_ratelimited
(
KERN_ERR
...
...
@@ -176,14 +178,14 @@ static int do_page_crypto(const struct inode *inode,
page_crypt_complete
,
&
ecr
);
BUILD_BUG_ON
(
sizeof
(
xts_tweak
)
!=
FS_XTS_TWEAK_SIZE
);
xts_tweak
.
index
=
cpu_to_le64
(
index
);
xts_tweak
.
index
=
cpu_to_le64
(
lblk_num
);
memset
(
xts_tweak
.
padding
,
0
,
sizeof
(
xts_tweak
.
padding
));
sg_init_table
(
&
dst
,
1
);
sg_set_page
(
&
dst
,
dest_page
,
src_len
,
src_offset
);
sg_set_page
(
&
dst
,
dest_page
,
len
,
offs
);
sg_init_table
(
&
src
,
1
);
sg_set_page
(
&
src
,
src_page
,
src_len
,
src_offset
);
skcipher_request_set_crypt
(
req
,
&
src
,
&
dst
,
src_
len
,
&
xts_tweak
);
sg_set_page
(
&
src
,
src_page
,
len
,
offs
);
skcipher_request_set_crypt
(
req
,
&
src
,
&
dst
,
len
,
&
xts_tweak
);
if
(
rw
==
FS_DECRYPT
)
res
=
crypto_skcipher_decrypt
(
req
);
else
...
...
@@ -208,69 +210,87 @@ static struct page *alloc_bounce_page(struct fscrypt_ctx *ctx, gfp_t gfp_flags)
ctx
->
w
.
bounce_page
=
mempool_alloc
(
fscrypt_bounce_page_pool
,
gfp_flags
);
if
(
ctx
->
w
.
bounce_page
==
NULL
)
return
ERR_PTR
(
-
ENOMEM
);
ctx
->
flags
|=
FS_
WRITE_PATH
_FL
;
ctx
->
flags
|=
FS_
CTX_HAS_BOUNCE_BUFFER
_FL
;
return
ctx
->
w
.
bounce_page
;
}
/**
* fscypt_encrypt_page() - Encrypts a page
* @inode: The inode for which the encryption should take place
* @plaintext_page: The page to encrypt. Must be locked.
* @plaintext_len: Length of plaintext within page
* @plaintext_offset: Offset of plaintext within page
* @index: Index for encryption. This is mainly the page index, but
* but might be different for multiple calls on same page.
* @gfp_flags: The gfp flag for memory allocation
* @inode: The inode for which the encryption should take place
* @page: The page to encrypt. Must be locked for bounce-page
* encryption.
* @len: Length of data to encrypt in @page and encrypted
* data in returned page.
* @offs: Offset of data within @page and returned
* page holding encrypted data.
* @lblk_num: Logical block number. This must be unique for multiple
* calls with same inode, except when overwriting
* previously written data.
* @gfp_flags: The gfp flag for memory allocation
*
* Encrypts
plaintext_page using the ctx encryption context. If
*
the filesystem supports it, encryption is performed in-place, otherwise a
*
new ciphertext_page is allocated and returned
.
* Encrypts
@page using the ctx encryption context. Performs encryption
*
either in-place or into a newly allocated bounce page.
*
Called on the page write path
.
*
* Called on the page write path. The caller must call
* Bounce page allocation is the default.
* In this case, the contents of @page are encrypted and stored in an
* allocated bounce page. @page has to be locked and the caller must call
* fscrypt_restore_control_page() on the returned ciphertext page to
* release the bounce buffer and the encryption context.
*
* Return: An allocated page with the encrypted content on success. Else, an
* In-place encryption is used by setting the FS_CFLG_OWN_PAGES flag in
* fscrypt_operations. Here, the input-page is returned with its content
* encrypted.
*
* Return: A page with the encrypted content on success. Else, an
* error value or NULL.
*/
struct
page
*
fscrypt_encrypt_page
(
const
struct
inode
*
inode
,
struct
page
*
p
laintext_p
age
,
unsigned
int
plaintext_
len
,
unsigned
int
plaintext_offset
,
pgoff_t
index
,
gfp_t
gfp_flags
)
struct
page
*
page
,
unsigned
int
len
,
unsigned
int
offs
,
u64
lblk_num
,
gfp_t
gfp_flags
)
{
struct
fscrypt_ctx
*
ctx
;
struct
page
*
ciphertext_page
=
p
laintext_p
age
;
struct
page
*
ciphertext_page
=
page
;
int
err
;
BUG_ON
(
plaintext_len
%
FS_CRYPTO_BLOCK_SIZE
!=
0
);
BUG_ON
(
len
%
FS_CRYPTO_BLOCK_SIZE
!=
0
);
if
(
inode
->
i_sb
->
s_cop
->
flags
&
FS_CFLG_OWN_PAGES
)
{
/* with inplace-encryption we just encrypt the page */
err
=
do_page_crypto
(
inode
,
FS_ENCRYPT
,
lblk_num
,
page
,
ciphertext_page
,
len
,
offs
,
gfp_flags
);
if
(
err
)
return
ERR_PTR
(
err
);
return
ciphertext_page
;
}
BUG_ON
(
!
PageLocked
(
page
));
ctx
=
fscrypt_get_ctx
(
inode
,
gfp_flags
);
if
(
IS_ERR
(
ctx
))
return
(
struct
page
*
)
ctx
;
if
(
!
(
inode
->
i_sb
->
s_cop
->
flags
&
FS_CFLG_INPLACE_ENCRYPTION
))
{
/* The encryption operation will require a bounce page. */
ciphertext_page
=
alloc_bounce_page
(
ctx
,
gfp_flags
);
if
(
IS_ERR
(
ciphertext_page
))
goto
errout
;
}
/* The encryption operation will require a bounce page. */
ciphertext_page
=
alloc_bounce_page
(
ctx
,
gfp_flags
);
if
(
IS_ERR
(
ciphertext_page
))
goto
errout
;
ctx
->
w
.
control_page
=
plaintext_page
;
err
=
do_page_crypto
(
inode
,
FS_ENCRYPT
,
index
,
plaintext_page
,
ciphertext_page
,
plaintext_len
,
plaintext_offset
,
gfp_flags
);
ctx
->
w
.
control_page
=
page
;
err
=
do_page_crypto
(
inode
,
FS_ENCRYPT
,
lblk_num
,
page
,
ciphertext_page
,
len
,
offs
,
gfp_flags
);
if
(
err
)
{
ciphertext_page
=
ERR_PTR
(
err
);
goto
errout
;
}
if
(
!
(
inode
->
i_sb
->
s_cop
->
flags
&
FS_CFLG_INPLACE_ENCRYPTION
))
{
SetPagePrivate
(
ciphertext_page
);
set_page_private
(
ciphertext_page
,
(
unsigned
long
)
ctx
);
lock_page
(
ciphertext_page
);
}
SetPagePrivate
(
ciphertext_page
);
set_page_private
(
ciphertext_page
,
(
unsigned
long
)
ctx
);
lock_page
(
ciphertext_page
);
return
ciphertext_page
;
errout:
...
...
@@ -281,11 +301,12 @@ EXPORT_SYMBOL(fscrypt_encrypt_page);
/**
* fscrypt_decrypt_page() - Decrypts a page in-place
* @inode: Encrypted inode to decrypt.
* @page: The page to decrypt. Must be locked.
* @len: Number of bytes in @page to be decrypted.
* @offs: Start of data in @page.
* @index: Index for encryption.
* @inode: The corresponding inode for the page to decrypt.
* @page: The page to decrypt. Must be locked in case
* it is a writeback page (FS_CFLG_OWN_PAGES unset).
* @len: Number of bytes in @page to be decrypted.
* @offs: Start of data in @page.
* @lblk_num: Logical block number.
*
* Decrypts page in-place using the ctx encryption context.
*
...
...
@@ -294,10 +315,13 @@ EXPORT_SYMBOL(fscrypt_encrypt_page);
* Return: Zero on success, non-zero otherwise.
*/
int
fscrypt_decrypt_page
(
const
struct
inode
*
inode
,
struct
page
*
page
,
unsigned
int
len
,
unsigned
int
offs
,
pgoff_t
index
)
unsigned
int
len
,
unsigned
int
offs
,
u64
lblk_num
)
{
return
do_page_crypto
(
inode
,
FS_DECRYPT
,
page
->
index
,
page
,
page
,
len
,
offs
,
GFP_NOFS
);
if
(
!
(
inode
->
i_sb
->
s_cop
->
flags
&
FS_CFLG_OWN_PAGES
))
BUG_ON
(
!
PageLocked
(
page
));
return
do_page_crypto
(
inode
,
FS_DECRYPT
,
lblk_num
,
page
,
page
,
len
,
offs
,
GFP_NOFS
);
}
EXPORT_SYMBOL
(
fscrypt_decrypt_page
);
...
...
@@ -501,17 +525,22 @@ static void fscrypt_destroy(void)
/**
* fscrypt_initialize() - allocate major buffers for fs encryption.
* @cop_flags: fscrypt operations flags
*
* We only call this when we start accessing encrypted files, since it
* results in memory getting allocated that wouldn't otherwise be used.
*
* Return: Zero on success, non-zero otherwise.
*/
int
fscrypt_initialize
(
void
)
int
fscrypt_initialize
(
unsigned
int
cop_flags
)
{
int
i
,
res
=
-
ENOMEM
;
if
(
fscrypt_bounce_page_pool
)
/*
* No need to allocate a bounce page pool if there already is one or
* this FS won't use it.
*/
if
(
cop_flags
&
FS_CFLG_OWN_PAGES
||
fscrypt_bounce_page_pool
)
return
0
;
mutex_lock
(
&
fscrypt_init_mutex
);
...
...
@@ -540,7 +569,6 @@ int fscrypt_initialize(void)
mutex_unlock
(
&
fscrypt_init_mutex
);
return
res
;
}
EXPORT_SYMBOL
(
fscrypt_initialize
);
/**
* fscrypt_init() - Set up for fs encryption.
...
...
fs/crypto/fname.c
View file @
a551d7c8
...
...
@@ -12,7 +12,7 @@
#include <linux/scatterlist.h>
#include <linux/ratelimit.h>
#include
<linux/fscrypto.h>
#include
"fscrypt_private.h"
/**
* fname_crypt_complete() - completion callback for filename crypto
...
...
@@ -350,7 +350,7 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
fname
->
disk_name
.
len
=
iname
->
len
;
return
0
;
}
ret
=
get_crypt_info
(
dir
);
ret
=
fscrypt_
get_crypt_info
(
dir
);
if
(
ret
&&
ret
!=
-
EOPNOTSUPP
)
return
ret
;
...
...
fs/crypto/fscrypt_private.h
0 → 100644
View file @
a551d7c8
/*
* fscrypt_private.h
*
* Copyright (C) 2015, Google, Inc.
*
* This contains encryption key functions.
*
* Written by Michael Halcrow, Ildar Muslukhov, and Uday Savagaonkar, 2015.
*/
#ifndef _FSCRYPT_PRIVATE_H
#define _FSCRYPT_PRIVATE_H
#include <linux/fscrypto.h>
#define FS_FNAME_CRYPTO_DIGEST_SIZE 32
/* Encryption parameters */
#define FS_XTS_TWEAK_SIZE 16
#define FS_AES_128_ECB_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_MAX_KEY_SIZE 64
#define FS_KEY_DESC_PREFIX "fscrypt:"
#define FS_KEY_DESC_PREFIX_SIZE 8
#define FS_KEY_DERIVATION_NONCE_SIZE 16
/**
* 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
;
#define FS_ENCRYPTION_CONTEXT_FORMAT_V1 1
/* This is passed in from userspace into the kernel keyring */
struct
fscrypt_key
{
u32
mode
;
u8
raw
[
FS_MAX_KEY_SIZE
];
u32
size
;
}
__packed
;
/*
* A pointer to this structure is stored in the file system's in-core
* representation of an inode.
*/
struct
fscrypt_info
{
u8
ci_data_mode
;
u8
ci_filename_mode
;
u8
ci_flags
;
struct
crypto_skcipher
*
ci_ctfm
;
struct
key
*
ci_keyring_key
;
u8
ci_master_key
[
FS_KEY_DESCRIPTOR_SIZE
];
};
#define FS_CTX_REQUIRES_FREE_ENCRYPT_FL 0x00000001
#define FS_CTX_HAS_BOUNCE_BUFFER_FL 0x00000002
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 }
/* crypto.c */
int
fscrypt_initialize
(
unsigned
int
cop_flags
);
/* keyinfo.c */
extern
int
fscrypt_get_crypt_info
(
struct
inode
*
);
#endif
/* _FSCRYPT_PRIVATE_H */
fs/crypto/keyinfo.c
View file @
a551d7c8
...
...
@@ -10,7 +10,7 @@
#include <keys/user-type.h>
#include <linux/scatterlist.h>
#include
<linux/fscrypto.h>
#include
"fscrypt_private.h"
static
void
derive_crypt_complete
(
struct
crypto_async_request
*
req
,
int
rc
)
{
...
...
@@ -178,7 +178,7 @@ static void put_crypt_info(struct fscrypt_info *ci)
kmem_cache_free
(
fscrypt_info_cachep
,
ci
);
}
int
get_crypt_info
(
struct
inode
*
inode
)
int
fscrypt_
get_crypt_info
(
struct
inode
*
inode
)
{
struct
fscrypt_info
*
crypt_info
;
struct
fscrypt_context
ctx
;
...
...
@@ -188,7 +188,7 @@ int get_crypt_info(struct inode *inode)
u8
*
raw_key
=
NULL
;
int
res
;
res
=
fscrypt_initialize
();
res
=
fscrypt_initialize
(
inode
->
i_sb
->
s_cop
->
flags
);
if
(
res
)
return
res
;
...
...
@@ -327,7 +327,7 @@ int fscrypt_get_encryption_info(struct inode *inode)
(
ci
->
ci_keyring_key
->
flags
&
((
1
<<
KEY_FLAG_INVALIDATED
)
|
(
1
<<
KEY_FLAG_REVOKED
)
|
(
1
<<
KEY_FLAG_DEAD
)))))
return
get_crypt_info
(
inode
);
return
fscrypt_
get_crypt_info
(
inode
);
return
0
;
}
EXPORT_SYMBOL
(
fscrypt_get_encryption_info
);
fs/crypto/policy.c
View file @
a551d7c8
...
...
@@ -10,8 +10,8 @@
#include <linux/random.h>
#include <linux/string.h>
#include <linux/fscrypto.h>
#include <linux/mount.h>
#include "fscrypt_private.h"
static
int
inode_has_encryption_context
(
struct
inode
*
inode
)
{
...
...
@@ -93,16 +93,19 @@ static int create_encryption_context_from_policy(struct inode *inode,
return
inode
->
i_sb
->
s_cop
->
set_context
(
inode
,
&
ctx
,
sizeof
(
ctx
),
NULL
);
}
int
fscrypt_process_policy
(
struct
file
*
filp
,
const
struct
fscrypt_policy
*
policy
)
int
fscrypt_ioctl_set_policy
(
struct
file
*
filp
,
const
void
__user
*
arg
)
{
struct
fscrypt_policy
policy
;
struct
inode
*
inode
=
file_inode
(
filp
);
int
ret
;
if
(
copy_from_user
(
&
policy
,
arg
,
sizeof
(
policy
)))
return
-
EFAULT
;
if
(
!
inode_owner_or_capable
(
inode
))
return
-
EACCES
;
if
(
policy
->
version
!=
0
)
if
(
policy
.
version
!=
0
)
return
-
EINVAL
;
ret
=
mnt_want_write_file
(
filp
);
...
...
@@ -120,9 +123,9 @@ int fscrypt_process_policy(struct file *filp,
ret
=
-
ENOTEMPTY
;
else
ret
=
create_encryption_context_from_policy
(
inode
,
policy
);
&
policy
);
}
else
if
(
!
is_encryption_context_consistent_with_policy
(
inode
,
policy
))
{
&
policy
))
{
printk
(
KERN_WARNING
"%s: Policy inconsistent with encryption context
\n
"
,
__func__
);
...
...
@@ -134,11 +137,13 @@ int fscrypt_process_policy(struct file *filp,
mnt_drop_write_file
(
filp
);
return
ret
;
}
EXPORT_SYMBOL
(
fscrypt_
process
_policy
);
EXPORT_SYMBOL
(
fscrypt_
ioctl_set
_policy
);
int
fscrypt_
get_policy
(
struct
inode
*
inode
,
struct
fscrypt_policy
*
policy
)
int
fscrypt_
ioctl_get_policy
(
struct
file
*
filp
,
void
__user
*
arg
)
{
struct
inode
*
inode
=
file_inode
(
filp
);
struct
fscrypt_context
ctx
;
struct
fscrypt_policy
policy
;
int
res
;
if
(
!
inode
->
i_sb
->
s_cop
->
get_context
||
...
...
@@ -151,15 +156,18 @@ int fscrypt_get_policy(struct inode *inode, struct fscrypt_policy *policy)
if
(
ctx
.
format
!=
FS_ENCRYPTION_CONTEXT_FORMAT_V1
)
return
-
EINVAL
;
policy
->
version
=
0
;
policy
->
contents_encryption_mode
=
ctx
.
contents_encryption_mode
;
policy
->
filenames_encryption_mode
=
ctx
.
filenames_encryption_mode
;
policy
->
flags
=
ctx
.
flags
;
memcpy
(
&
policy
->
master_key_descriptor
,
ctx
.
master_key_descriptor
,
policy
.
version
=
0
;
policy
.
contents_encryption_mode
=
ctx
.
contents_encryption_mode
;
policy
.
filenames_encryption_mode
=
ctx
.
filenames_encryption_mode
;
policy
.
flags
=
ctx
.
flags
;
memcpy
(
policy
.
master_key_descriptor
,
ctx
.
master_key_descriptor
,
FS_KEY_DESCRIPTOR_SIZE
);
if
(
copy_to_user
(
arg
,
&
policy
,
sizeof
(
policy
)))
return
-
EFAULT
;
return
0
;
}
EXPORT_SYMBOL
(
fscrypt_get_policy
);
EXPORT_SYMBOL
(
fscrypt_
ioctl_
get_policy
);
int
fscrypt_has_permitted_context
(
struct
inode
*
parent
,
struct
inode
*
child
)
{
...
...
fs/ext4/ext4.h
View file @
a551d7c8
...
...
@@ -2329,8 +2329,8 @@ static inline void ext4_fname_free_filename(struct ext4_filename *fname) { }
#define fscrypt_pullback_bio_page fscrypt_notsupp_pullback_bio_page
#define fscrypt_restore_control_page fscrypt_notsupp_restore_control_page
#define fscrypt_zeroout_range fscrypt_notsupp_zeroout_range
#define fscrypt_
process_policy fscrypt_notsupp_process
_policy
#define fscrypt_
get_policy fscrypt_notsupp
_get_policy
#define fscrypt_
ioctl_set_policy fscrypt_notsupp_ioctl_set
_policy
#define fscrypt_
ioctl_get_policy fscrypt_notsupp_ioctl
_get_policy
#define fscrypt_has_permitted_context fscrypt_notsupp_has_permitted_context
#define fscrypt_inherit_context fscrypt_notsupp_inherit_context
#define fscrypt_get_encryption_info fscrypt_notsupp_get_encryption_info
...
...
fs/ext4/inode.c
View file @
a551d7c8
...
...
@@ -3851,7 +3851,6 @@ static int __ext4_block_zero_page_range(handle_t *handle,
/* We expect the key to be set. */
BUG_ON
(
!
fscrypt_has_encryption_key
(
inode
));
BUG_ON
(
blocksize
!=
PAGE_SIZE
);
BUG_ON
(
!
PageLocked
(
page
));
WARN_ON_ONCE
(
fscrypt_decrypt_page
(
page
->
mapping
->
host
,
page
,
PAGE_SIZE
,
0
,
page
->
index
));
}
...
...
fs/ext4/ioctl.c
View file @
a551d7c8
...
...
@@ -787,22 +787,12 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
}
case
EXT4_IOC_PRECACHE_EXTENTS
:
return
ext4_ext_precache
(
inode
);
case
EXT4_IOC_SET_ENCRYPTION_POLICY
:
{
#ifdef CONFIG_EXT4_FS_ENCRYPTION
struct
fscrypt_policy
policy
;
case
EXT4_IOC_SET_ENCRYPTION_POLICY
:
if
(
!
ext4_has_feature_encrypt
(
sb
))
return
-
EOPNOTSUPP
;
return
fscrypt_ioctl_set_policy
(
filp
,
(
const
void
__user
*
)
arg
);
if
(
copy_from_user
(
&
policy
,
(
struct
fscrypt_policy
__user
*
)
arg
,
sizeof
(
policy
)))
return
-
EFAULT
;
return
fscrypt_process_policy
(
filp
,
&
policy
);
#else
return
-
EOPNOTSUPP
;
#endif
}
case
EXT4_IOC_GET_ENCRYPTION_PWSALT
:
{
#ifdef CONFIG_EXT4_FS_ENCRYPTION
int
err
,
err2
;
...
...
@@ -843,23 +833,9 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
return
-
EOPNOTSUPP
;
#endif
}
case
EXT4_IOC_GET_ENCRYPTION_POLICY
:
{
#ifdef CONFIG_EXT4_FS_ENCRYPTION
struct
fscrypt_policy
policy
;
int
err
=
0
;
case
EXT4_IOC_GET_ENCRYPTION_POLICY
:
return
fscrypt_ioctl_get_policy
(
filp
,
(
void
__user
*
)
arg
);
if
(
!
ext4_encrypted_inode
(
inode
))
return
-
ENOENT
;
err
=
fscrypt_get_policy
(
inode
,
&
policy
);
if
(
err
)
return
err
;
if
(
copy_to_user
((
void
__user
*
)
arg
,
&
policy
,
sizeof
(
policy
)))
return
-
EFAULT
;
return
0
;
#else
return
-
EOPNOTSUPP
;
#endif
}
case
EXT4_IOC_FSGETXATTR
:
{
struct
fsxattr
fa
;
...
...
fs/f2fs/data.c
View file @
a551d7c8
...
...
@@ -1194,7 +1194,6 @@ int do_write_data_page(struct f2fs_io_info *fio)
f2fs_wait_on_encrypted_page_writeback
(
F2FS_I_SB
(
inode
),
fio
->
old_blkaddr
);
retry_encrypt:
BUG_ON
(
!
PageLocked
(
fio
->
page
));
fio
->
encrypted_page
=
fscrypt_encrypt_page
(
inode
,
fio
->
page
,
PAGE_SIZE
,
0
,
fio
->
page
->
index
,
...
...
fs/f2fs/f2fs.h
View file @
a551d7c8
...
...
@@ -2453,8 +2453,8 @@ static inline bool f2fs_may_encrypt(struct inode *inode)
#define fscrypt_pullback_bio_page fscrypt_notsupp_pullback_bio_page
#define fscrypt_restore_control_page fscrypt_notsupp_restore_control_page
#define fscrypt_zeroout_range fscrypt_notsupp_zeroout_range
#define fscrypt_
process_policy fscrypt_notsupp_process
_policy
#define fscrypt_
get_policy fscrypt_notsupp
_get_policy
#define fscrypt_
ioctl_set_policy fscrypt_notsupp_ioctl_set
_policy
#define fscrypt_
ioctl_get_policy fscrypt_notsupp_ioctl
_get_policy
#define fscrypt_has_permitted_context fscrypt_notsupp_has_permitted_context
#define fscrypt_inherit_context fscrypt_notsupp_inherit_context
#define fscrypt_get_encryption_info fscrypt_notsupp_get_encryption_info
...
...
fs/f2fs/file.c
View file @
a551d7c8
...
...
@@ -1752,31 +1752,16 @@ static bool uuid_is_nonzero(__u8 u[16])
static
int
f2fs_ioc_set_encryption_policy
(
struct
file
*
filp
,
unsigned
long
arg
)
{
struct
fscrypt_policy
policy
;
struct
inode
*
inode
=
file_inode
(
filp
);
if
(
copy_from_user
(
&
policy
,
(
struct
fscrypt_policy
__user
*
)
arg
,
sizeof
(
policy
)))
return
-
EFAULT
;
f2fs_update_time
(
F2FS_I_SB
(
inode
),
REQ_TIME
);
return
fscrypt_
process_policy
(
filp
,
&
policy
);
return
fscrypt_
ioctl_set_policy
(
filp
,
(
const
void
__user
*
)
arg
);
}
static
int
f2fs_ioc_get_encryption_policy
(
struct
file
*
filp
,
unsigned
long
arg
)
{
struct
fscrypt_policy
policy
;
struct
inode
*
inode
=
file_inode
(
filp
);
int
err
;
err
=
fscrypt_get_policy
(
inode
,
&
policy
);
if
(
err
)
return
err
;
if
(
copy_to_user
((
struct
fscrypt_policy
__user
*
)
arg
,
&
policy
,
sizeof
(
policy
)))
return
-
EFAULT
;
return
0
;
return
fscrypt_ioctl_get_policy
(
filp
,
(
void
__user
*
)
arg
);
}
static
int
f2fs_ioc_get_encryption_pwsalt
(
struct
file
*
filp
,
unsigned
long
arg
)
...
...
include/linux/fscrypto.h
View file @
a551d7c8
...
...
@@ -18,73 +18,9 @@
#include <crypto/skcipher.h>
#include <uapi/linux/fs.h>
#define FS_KEY_DERIVATION_NONCE_SIZE 16
#define FS_ENCRYPTION_CONTEXT_FORMAT_V1 1
#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_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_MAX_KEY_SIZE 64
#define FS_KEY_DESC_PREFIX "fscrypt:"
#define FS_KEY_DESC_PREFIX_SIZE 8
/* 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_skcipher
*
ci_ctfm
;
struct
key
*
ci_keyring_key
;
u8
ci_master_key
[
FS_KEY_DESCRIPTOR_SIZE
];
};
#define FS_CRYPTO_BLOCK_SIZE 16
#define FS_CTX_REQUIRES_FREE_ENCRYPT_FL 0x00000001
#define FS_WRITE_PATH_FL 0x00000002
struct
fscrypt_info
;
struct
fscrypt_ctx
{
union
{
...
...
@@ -102,19 +38,6 @@ struct fscrypt_ctx {
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 }
#define FS_FNAME_NUM_SCATTER_ENTRIES 4
#define FS_CRYPTO_BLOCK_SIZE 16
#define FS_FNAME_CRYPTO_DIGEST_SIZE 32
/**
* For encrypted symlinks, the ciphertext length is stored at the beginning
* of the string in little-endian format.
...
...
@@ -156,7 +79,7 @@ struct fscrypt_name {
/*
* fscrypt superblock flags
*/
#define FS_CFLG_
INPLACE_ENCRYPTION
(1U << 1)
#define FS_CFLG_
OWN_PAGES
(1U << 1)
/*
* crypto opertions for filesystems
...
...
@@ -244,28 +167,25 @@ static inline void fscrypt_set_d_op(struct dentry *dentry)
#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
/* crypto.c */
extern
struct
kmem_cache
*
fscrypt_info_cachep
;
int
fscrypt_initialize
(
void
);
extern
struct
fscrypt_ctx
*
fscrypt_get_ctx
(
const
struct
inode
*
,
gfp_t
);
extern
void
fscrypt_release_ctx
(
struct
fscrypt_ctx
*
);
extern
struct
page
*
fscrypt_encrypt_page
(
const
struct
inode
*
,
struct
page
*
,
unsigned
int
,
unsigned
int
,
pgoff_t
,
gfp_t
);
u64
,
gfp_t
);
extern
int
fscrypt_decrypt_page
(
const
struct
inode
*
,
struct
page
*
,
unsigned
int
,
unsigned
int
,
pgoff_t
);
unsigned
int
,
u64
);
extern
void
fscrypt_decrypt_bio_pages
(
struct
fscrypt_ctx
*
,
struct
bio
*
);
extern
void
fscrypt_pullback_bio_page
(
struct
page
**
,
bool
);
extern
void
fscrypt_restore_control_page
(
struct
page
*
);
extern
int
fscrypt_zeroout_range
(
const
struct
inode
*
,
pgoff_t
,
sector_t
,
unsigned
int
);
/* policy.c */
extern
int
fscrypt_
process_policy
(
struct
file
*
,
const
struct
fscrypt_policy
*
);
extern
int
fscrypt_
get_policy
(
struct
inode
*
,
struct
fscrypt_policy
*
);
extern
int
fscrypt_
ioctl_set_policy
(
struct
file
*
,
const
void
__user
*
);
extern
int
fscrypt_
ioctl_get_policy
(
struct
file
*
,
void
__user
*
);
extern
int
fscrypt_has_permitted_context
(
struct
inode
*
,
struct
inode
*
);
extern
int
fscrypt_inherit_context
(
struct
inode
*
,
struct
inode
*
,
void
*
,
bool
);
/* keyinfo.c */
extern
int
get_crypt_info
(
struct
inode
*
);
extern
int
fscrypt_get_encryption_info
(
struct
inode
*
);
extern
void
fscrypt_put_encryption_info
(
struct
inode
*
,
struct
fscrypt_info
*
);
...
...
@@ -299,14 +219,14 @@ static inline struct page *fscrypt_notsupp_encrypt_page(const struct inode *i,
struct
page
*
p
,
unsigned
int
len
,
unsigned
int
offs
,
pgoff_t
index
,
gfp_t
f
)
u64
lblk_num
,
gfp_t
f
)
{
return
ERR_PTR
(
-
EOPNOTSUPP
);
}
static
inline
int
fscrypt_notsupp_decrypt_page
(
const
struct
inode
*
i
,
struct
page
*
p
,
unsigned
int
len
,
unsigned
int
offs
,
pgoff_t
index
)
u64
lblk_num
)
{
return
-
EOPNOTSUPP
;
}
...
...
@@ -334,14 +254,14 @@ static inline int fscrypt_notsupp_zeroout_range(const struct inode *i, pgoff_t p
}
/* policy.c */
static
inline
int
fscrypt_notsupp_
process
_policy
(
struct
file
*
f
,
const
struct
fscrypt_policy
*
p
)
static
inline
int
fscrypt_notsupp_
ioctl_set
_policy
(
struct
file
*
f
,
const
void
__user
*
arg
)
{
return
-
EOPNOTSUPP
;
}
static
inline
int
fscrypt_notsupp_
get_policy
(
struct
inode
*
i
,
struct
fscrypt_policy
*
p
)
static
inline
int
fscrypt_notsupp_
ioctl_get_policy
(
struct
file
*
f
,
void
__user
*
arg
)
{
return
-
EOPNOTSUPP
;
}
...
...
include/uapi/linux/fs.h
View file @
a551d7c8
...
...
@@ -254,6 +254,20 @@ struct fsxattr {
/* Policy provided via an ioctl on the topmost directory */
#define FS_KEY_DESCRIPTOR_SIZE 8
#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
struct
fscrypt_policy
{
__u8
version
;
__u8
contents_encryption_mode
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment