Skip to content

Commit

Permalink
Merge tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscr…
Browse files Browse the repository at this point in the history
…ypt/fscrypt

Pull fscrypt updates from Eric Biggers:

 - Add the IV_INO_LBLK_32 encryption policy flag which modifies the
   encryption to be optimized for eMMC inline encryption hardware.

 - Make the test_dummy_encryption mount option for ext4 and f2fs support
   v2 encryption policies.

 - Fix kerneldoc warnings and some coding style inconsistencies.

* tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt:
  fscrypt: add support for IV_INO_LBLK_32 policies
  fscrypt: make test_dummy_encryption use v2 by default
  fscrypt: support test_dummy_encryption=v2
  fscrypt: add fscrypt_add_test_dummy_key()
  linux/parser.h: add include guards
  fscrypt: remove unnecessary extern keywords
  fscrypt: name all function parameters
  fscrypt: fix all kerneldoc warnings
  • Loading branch information
Linus Torvalds committed Jun 1, 2020
2 parents 829f3b9 + e3b1078 commit afdb0f2
Show file tree
Hide file tree
Showing 18 changed files with 737 additions and 302 deletions.
6 changes: 5 additions & 1 deletion Documentation/filesystems/f2fs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,12 @@ fsync_mode=%s Control the policy of fsync. Currently supports "posix",
pass, but the performance will regress. "nobarrier" is
based on "posix", but doesn't issue flush command for
non-atomic files likewise "nobarrier" mount option.
test_dummy_encryption Enable dummy encryption, which provides a fake fscrypt
test_dummy_encryption
test_dummy_encryption=%s
Enable dummy encryption, which provides a fake fscrypt
context. The fake fscrypt context is used by xfstests.
The argument may be either "v1" or "v2", in order to
select the corresponding fscrypt policy version.
checkpoint=%s[:%u[%]] Set to "disable" to turn off checkpointing. Set to "enable"
to reenable checkpointing. Is enabled by default. While
disabled, any unmounting or unexpected shutdowns will cause
Expand Down
33 changes: 29 additions & 4 deletions Documentation/filesystems/fscrypt.rst
Original file line number Diff line number Diff line change
Expand Up @@ -292,8 +292,22 @@ files' data differently, inode numbers are included in the IVs.
Consequently, shrinking the filesystem may not be allowed.

This format is optimized for use with inline encryption hardware
compliant with the UFS or eMMC standards, which support only 64 IV
bits per I/O request and may have only a small number of keyslots.
compliant with the UFS standard, which supports only 64 IV bits per
I/O request and may have only a small number of keyslots.

IV_INO_LBLK_32 policies
-----------------------

IV_INO_LBLK_32 policies work like IV_INO_LBLK_64, except that for
IV_INO_LBLK_32, the inode number is hashed with SipHash-2-4 (where the
SipHash key is derived from the master key) and added to the file
logical block number mod 2^32 to produce a 32-bit IV.

This format is optimized for use with inline encryption hardware
compliant with the eMMC v5.2 standard, which supports only 32 IV bits
per I/O request and may have only a small number of keyslots. This
format results in some level of IV reuse, so it should only be used
when necessary due to hardware limitations.

Key identifiers
---------------
Expand Down Expand Up @@ -369,6 +383,10 @@ a little endian number, except that:
to 32 bits and is placed in bits 0-31 of the IV. The inode number
(which is also limited to 32 bits) is placed in bits 32-63.

- With `IV_INO_LBLK_32 policies`_, the logical block number is limited
to 32 bits and is placed in bits 0-31 of the IV. The inode number
is then hashed and added mod 2^32.

Note that because file logical block numbers are included in the IVs,
filesystems must enforce that blocks are never shifted around within
encrypted files, e.g. via "collapse range" or "insert range".
Expand Down Expand Up @@ -465,8 +483,15 @@ This structure must be initialized as follows:
(0x3).
- FSCRYPT_POLICY_FLAG_DIRECT_KEY: See `DIRECT_KEY policies`_.
- FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64: See `IV_INO_LBLK_64
policies`_. This is mutually exclusive with DIRECT_KEY and is not
supported on v1 policies.
policies`_.
- FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32: See `IV_INO_LBLK_32
policies`_.

v1 encryption policies only support the PAD_* and DIRECT_KEY flags.
The other flags are only supported by v2 encryption policies.

The DIRECT_KEY, IV_INO_LBLK_64, and IV_INO_LBLK_32 flags are
mutually exclusive.

- For v2 encryption policies, ``__reserved`` must be zeroed.

Expand Down
15 changes: 12 additions & 3 deletions fs/crypto/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ struct page *fscrypt_alloc_bounce_page(gfp_t gfp_flags)

/**
* fscrypt_free_bounce_page() - free a ciphertext bounce page
* @bounce_page: the bounce page to free, or NULL
*
* Free a bounce page that was allocated by fscrypt_encrypt_pagecache_blocks(),
* or by fscrypt_alloc_bounce_page() directly.
Expand All @@ -76,8 +77,12 @@ void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num,
memset(iv, 0, ci->ci_mode->ivsize);

if (flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64) {
WARN_ON_ONCE((u32)lblk_num != lblk_num);
WARN_ON_ONCE(lblk_num > U32_MAX);
WARN_ON_ONCE(ci->ci_inode->i_ino > U32_MAX);
lblk_num |= (u64)ci->ci_inode->i_ino << 32;
} else if (flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) {
WARN_ON_ONCE(lblk_num > U32_MAX);
lblk_num = (u32)(ci->ci_hashed_ino + lblk_num);
} else if (flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY) {
memcpy(iv->nonce, ci->ci_nonce, FS_KEY_DERIVATION_NONCE_SIZE);
}
Expand Down Expand Up @@ -132,7 +137,8 @@ int fscrypt_crypt_block(const struct inode *inode, fscrypt_direction_t rw,
}

/**
* fscrypt_encrypt_pagecache_blocks() - Encrypt filesystem blocks from a pagecache page
* fscrypt_encrypt_pagecache_blocks() - Encrypt filesystem blocks from a
* pagecache page
* @page: The locked pagecache page containing the block(s) to encrypt
* @len: Total size of the block(s) to encrypt. Must be a nonzero
* multiple of the filesystem's block size.
Expand Down Expand Up @@ -222,7 +228,8 @@ int fscrypt_encrypt_block_inplace(const struct inode *inode, struct page *page,
EXPORT_SYMBOL(fscrypt_encrypt_block_inplace);

/**
* fscrypt_decrypt_pagecache_blocks() - Decrypt filesystem blocks in a pagecache page
* fscrypt_decrypt_pagecache_blocks() - Decrypt filesystem blocks in a
* pagecache page
* @page: The locked pagecache page containing the block(s) to decrypt
* @len: Total size of the block(s) to decrypt. Must be a nonzero
* multiple of the filesystem's block size.
Expand Down Expand Up @@ -346,6 +353,8 @@ void fscrypt_msg(const struct inode *inode, const char *level,

/**
* fscrypt_init() - Set up for fs encryption.
*
* Return: 0 on success; -errno on failure
*/
static int __init fscrypt_init(void)
{
Expand Down
52 changes: 38 additions & 14 deletions fs/crypto/fname.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include <crypto/skcipher.h>
#include "fscrypt_private.h"

/**
/*
* struct fscrypt_nokey_name - identifier for directory entry when key is absent
*
* When userspace lists an encrypted directory without access to the key, the
Expand Down Expand Up @@ -100,9 +100,12 @@ static inline bool fscrypt_is_dot_dotdot(const struct qstr *str)

/**
* fscrypt_fname_encrypt() - encrypt a filename
*
* The output buffer must be at least as large as the input buffer.
* Any extra space is filled with NUL padding before encryption.
* @inode: inode of the parent directory (for regular filenames)
* or of the symlink (for symlink targets)
* @iname: the filename to encrypt
* @out: (output) the encrypted filename
* @olen: size of the encrypted filename. It must be at least @iname->len.
* Any extra space is filled with NUL padding before encryption.
*
* Return: 0 on success, -errno on failure
*/
Expand Down Expand Up @@ -152,8 +155,11 @@ int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname,

/**
* fname_decrypt() - decrypt a filename
*
* The caller must have allocated sufficient memory for the @oname string.
* @inode: inode of the parent directory (for regular filenames)
* or of the symlink (for symlink targets)
* @iname: the encrypted filename to decrypt
* @oname: (output) the decrypted filename. The caller must have allocated
* enough space for this, e.g. using fscrypt_fname_alloc_buffer().
*
* Return: 0 on success, -errno on failure
*/
Expand Down Expand Up @@ -201,7 +207,10 @@ static const char lookup_table[65] =
#define BASE64_CHARS(nbytes) DIV_ROUND_UP((nbytes) * 4, 3)

/**
* base64_encode() -
* base64_encode() - base64-encode some bytes
* @src: the bytes to encode
* @len: number of bytes to encode
* @dst: (output) the base64-encoded string. Not NUL-terminated.
*
* Encodes the input string using characters from the set [A-Za-z0-9+,].
* The encoded string is roughly 4/3 times the size of the input string.
Expand Down Expand Up @@ -267,7 +276,12 @@ bool fscrypt_fname_encrypted_size(const struct inode *inode, u32 orig_len,
}

/**
* fscrypt_fname_alloc_buffer - allocate a buffer for presented filenames
* fscrypt_fname_alloc_buffer() - allocate a buffer for presented filenames
* @inode: inode of the parent directory (for regular filenames)
* or of the symlink (for symlink targets)
* @max_encrypted_len: maximum length of encrypted filenames the buffer will be
* used to present
* @crypto_str: (output) buffer to allocate
*
* Allocate a buffer that is large enough to hold any decrypted or encoded
* filename (null-terminated), for the given maximum encrypted filename length.
Expand All @@ -292,9 +306,10 @@ int fscrypt_fname_alloc_buffer(const struct inode *inode,
EXPORT_SYMBOL(fscrypt_fname_alloc_buffer);

/**
* fscrypt_fname_free_buffer - free the buffer for presented filenames
* fscrypt_fname_free_buffer() - free a buffer for presented filenames
* @crypto_str: the buffer to free
*
* Free the buffer allocated by fscrypt_fname_alloc_buffer().
* Free a buffer that was allocated by fscrypt_fname_alloc_buffer().
*/
void fscrypt_fname_free_buffer(struct fscrypt_str *crypto_str)
{
Expand All @@ -306,10 +321,19 @@ void fscrypt_fname_free_buffer(struct fscrypt_str *crypto_str)
EXPORT_SYMBOL(fscrypt_fname_free_buffer);

/**
* fscrypt_fname_disk_to_usr() - converts a filename from disk space to user
* space
*
* The caller must have allocated sufficient memory for the @oname string.
* fscrypt_fname_disk_to_usr() - convert an encrypted filename to
* user-presentable form
* @inode: inode of the parent directory (for regular filenames)
* or of the symlink (for symlink targets)
* @hash: first part of the name's dirhash, if applicable. This only needs to
* be provided if the filename is located in an indexed directory whose
* encryption key may be unavailable. Not needed for symlink targets.
* @minor_hash: second part of the name's dirhash, if applicable
* @iname: encrypted filename to convert. May also be "." or "..", which
* aren't actually encrypted.
* @oname: output buffer for the user-presentable filename. The caller must
* have allocated enough space for this, e.g. using
* fscrypt_fname_alloc_buffer().
*
* If the key is available, we'll decrypt the disk name. Otherwise, we'll
* encode it for presentation in fscrypt_nokey_name format.
Expand Down
Loading

0 comments on commit afdb0f2

Please sign in to comment.