mbox series

[v2,0/3] add support for metadata encryption to F2FS

Message ID 20201217150435.1505269-1-satyat@google.com (mailing list archive)
Headers show
Series add support for metadata encryption to F2FS | expand

Message

Satya Tangirala Dec. 17, 2020, 3:04 p.m. UTC
This patch series adds support for metadata encryption to F2FS using
blk-crypto.

Currently, F2FS supports native file based encryption (FBE) via fscrypt.
FBE encrypts the contents of files that reside in folders with encryption
policies, as well as their filenames, but all other file contents
and filesystem metadata is stored unencrypted. We'd like to have metadata
and the contents of non-FBE files encrypted too, to protect data like
file sizes, xattrs, locations, etc. which can be valuable in certain
contexts.

The simplest way to do metadata encryption would be to run the filesystem
over dm-crypt (set up to encrypt all bios with the metadata encryption
key). This would essentially encrypt file contents twice (once with the FBE
key and once with the metadata encryption key).  On many android devices,
this is slower than we'd like, and also doesn't play well with inline
encryption engines (which only allow for one layer of encryption, so the
other layer must be done by the kernel crypto API).

Android currently has metadata encryption, and due to the drawbacks
listed above, doesn't use the above mentioned approach, and avoids
double encryption. Metadata encryption on android is currently
implemented using a new DM target (dm-default-key) that encrypts any
bio it receives that has data which has not previously been encrypted
(in practice, it checks for the presence of bio->bi_crypt_context, and
if it's missing, dm-default-key adds a bi_crypt_context to the bio with
the metadata encryption key that it was configured with). This works fine
as long as filesystems submit bios without bi_crypt_contexts for
filesystem metadata/unencrypted file contents, or submit bios with
bi_crypt_contexts for encrypted file contents. However, filesystems like
F2FS sometimes want to read the ciphertext of fscrypt encrypted data
contents (so F2FS will submit a bio without any bi_crypt_context, but
expects to receive ciphertext rather than the file contents decrypted
with the metadata encryption key). To address this issue, F2FS sets a flag
on the bio which essentially instructs dm-default-key not to add a
bi_crypt_context on that bio even though there isn't already one on it.
We'd like to try to come up with a metadata encryption solution that avoids
this layering violation.

The most natural solution that avoids double encryption and layering
violations is to let the filesystem take care of metadata encryption,
since the filesystem is what's responsible for knowing where the filesystem
metadata/unencrypted file contents/encrypted file contents are. This patch
series follows that approach, and adds support for metadata encryption to
F2FS and fscrypt.

Patch 1 replaces fscrypt_get_devices (which took an array of request_queues
and filled it up) with fscrypt_get_device, which takes a index of the
desired device and returns the device at that index (so the index passed
to fscrypt_get_device must be between 0 and (fscrypt_get_num_devices() - 1)
inclusive). This allows callers to avoid having to allocate an array to
pass to fscrypt_get_devices() when they only need to iterate through
each element in the array (and have no use for the array itself).

Patch 2 introduces some functions to fscrypt that help filesystems perform
metadata encryption. Any filesystem that wants to use metadata encryption
can call fscrypt_setup_metadata_encryption() with the super_block of the
filesystem, the encryption algorithm and the descriptor of the metadata
crypt key. The descriptor is looked up in the logon keyring of the
current session with "fscrypt:" as the prefix of the descriptor. The
metadata crypt key is not directly used for encryption - the actual
metadata encryption key is derived from this metadata key (refer to
fscrypt_setup_metadata_encryption() in fs/crypto/metadata_crypt.c for
details). 

The patch also introduces fscrypt_metadata_crypt_bio() which an FS should
call on a bio that the FS wants metadata crypted. The function will add
an encryption context with the metadata encryption key set up by the call
to the above mentioned fscrypt_setup_metadata_encryption().

The patch also introduces fscrypt_metadata_crypt_prepare_all_devices().
Filesystems that use multiple devices should call this function once all
the underlying devices have been determined. An FS might only be able to
determine all the underlying devices after some initial processing that
might already require metadata en/decryption, which is why this function
is separate from fscrypt_setup_metadata_encryption().

Finally, the patch makes the metadata crypt key for the filesystem part
of the key derivation process for all fscrypt file content encryption
keys used with that filesystem - this way, the file content encryption
keys are at least as strong as the metadata encryption key. For more
details please refer to fscrypt_mix_in_metadata_key() in
fs/crypto/metadata_crypt.c

Patch 3 wires up F2FS with the functions introduced in Patch 2. F2FS
will encrypt every block (that's not being encrypted by some other
encryption key, e.g. a per-file key) with the metadata encryption key
except the superblock (and the redundant copy of the superblock). The DUN
of a block is the offset of the block from the start of the F2FS
filesystem.

Please refer to the commit message for why the superblock was excluded from
en/decryption, and other limitations. The superblock and its copy are
stored in plaintext on disk. The encryption algorithm used for metadata
encryption is stored within the superblock itself. Changes to the userspace
tools (that are required to test out metadata encryption with F2FS) are
also being sent out - I'll post a link as a reply to this mail once it's
out.

Changes v1 => v2:
 - The metadata crypt key is no longer used directly for encryption. The
   actual metadata encryption key is now derived from the metadata crypt key.
   A key identifier is also derived from the metadata crypt key (and this
   identifier is verified at FS mount time). The key identifier is stored
   directly in the F2FS superblock, so there's no longer a need for any new
   mount options.
 - The metadata crypt key is now mixed into the key derivation process for
   all subkeys derived from fscrypt master keys
 - Make the metadata key payload in the keyring just the raw bytes of the
   key (instead of having it represent a struct fscrypt_key)
 - export some of the metadata_crypt.c functions, since F2FS can be built
   as a module
 - make FS_ENCRYPTION_METADATA depend on FS_ENCRYPTION_INLINE_CRYPT
 - fscrypt_set_bio_crypt_ctx() calls fscrypt_metadata_crypt_bio()
   directly, so filesystems only need to call fscrypt_set_bio_crypt_ctx()
 - Cleanups and updated docs

Satya Tangirala (3):
  fscrypt, f2fs: replace fscrypt_get_devices with fscrypt_get_device
  fscrypt: Add metadata encryption support
  f2fs: Add metadata encryption support

 Documentation/filesystems/fscrypt.rst |  86 +++++++-
 fs/crypto/Kconfig                     |  12 +
 fs/crypto/Makefile                    |   1 +
 fs/crypto/bio.c                       |   2 +-
 fs/crypto/fscrypt_private.h           |  46 ++++
 fs/crypto/hkdf.c                      |   1 +
 fs/crypto/inline_crypt.c              |  52 ++---
 fs/crypto/keyring.c                   |   4 +
 fs/crypto/metadata_crypt.c            | 303 ++++++++++++++++++++++++++
 fs/ext4/readpage.c                    |   2 +-
 fs/f2fs/data.c                        |  17 +-
 fs/f2fs/f2fs.h                        |   2 +
 fs/f2fs/super.c                       |  60 ++++-
 include/linux/f2fs_fs.h               |   7 +-
 include/linux/fs.h                    |  10 +
 include/linux/fscrypt.h               |  50 ++++-
 16 files changed, 586 insertions(+), 69 deletions(-)
 create mode 100644 fs/crypto/metadata_crypt.c

Comments

Satya Tangirala Dec. 17, 2020, 3:16 p.m. UTC | #1
On Thu, Dec 17, 2020 at 03:04:32PM +0000, Satya Tangirala wrote:
> Changes to the userspace
> tools (that are required to test out metadata encryption with F2FS) are
> also being sent out - I'll post a link as a reply to this mail once it's
> out.

The userspace changes are at
https://lore.kernel.org/linux-f2fs-devel/20201217151013.1513045-1-satyat@google.com/
Theodore Ts'o Dec. 17, 2020, 6:08 p.m. UTC | #2
On Thu, Dec 17, 2020 at 03:04:32PM +0000, Satya Tangirala wrote:
> This patch series adds support for metadata encryption to F2FS using
> blk-crypto.

Is there a companion patch series needed so that f2fstools can
check/repair a file system with metadata encryption enabled?

	       	    	   	- Ted
Satya Tangirala Dec. 17, 2020, 8:51 p.m. UTC | #3
On Thu, Dec 17, 2020 at 01:08:49PM -0500, Theodore Y. Ts'o wrote:
> On Thu, Dec 17, 2020 at 03:04:32PM +0000, Satya Tangirala wrote:
> > This patch series adds support for metadata encryption to F2FS using
> > blk-crypto.
> 
> Is there a companion patch series needed so that f2fstools can
> check/repair a file system with metadata encryption enabled?
> 
> 	       	    	   	- Ted
Yes! It's at
https://lore.kernel.org/linux-f2fs-devel/20201217151013.1513045-1-satyat@google.com/
Theodore Ts'o Dec. 17, 2020, 11:34 p.m. UTC | #4
On Thu, Dec 17, 2020 at 08:51:14PM +0000, Satya Tangirala wrote:
> On Thu, Dec 17, 2020 at 01:08:49PM -0500, Theodore Y. Ts'o wrote:
> > On Thu, Dec 17, 2020 at 03:04:32PM +0000, Satya Tangirala wrote:
> > > This patch series adds support for metadata encryption to F2FS using
> > > blk-crypto.
> > 
> > Is there a companion patch series needed so that f2fstools can
> > check/repair a file system with metadata encryption enabled?
> > 
> > 	       	    	   	- Ted
> Yes! It's at
> https://lore.kernel.org/linux-f2fs-devel/20201217151013.1513045-1-satyat@google.com/

Cool, I've been meaning to update f2fs-tools in Debian, and including
these patches will allow us to generate {kvm,gce,android}-xfstests
images with this support.  I'm hoping to get to it sometime betweeen
Christmas and New Year's.

I guess there will need to be some additional work needed to create
the f2fs image with a fixed keys for a particular file system in
xfstests-bld, and then mounting and checking said image with the
appropriatre keys as well.   Is that something you've put together?

Cheers,

						- Ted
Satya Tangirala Dec. 18, 2020, 12:05 a.m. UTC | #5
On Thu, Dec 17, 2020 at 06:34:27PM -0500, Theodore Y. Ts'o wrote:
> On Thu, Dec 17, 2020 at 08:51:14PM +0000, Satya Tangirala wrote:
> > On Thu, Dec 17, 2020 at 01:08:49PM -0500, Theodore Y. Ts'o wrote:
> > > On Thu, Dec 17, 2020 at 03:04:32PM +0000, Satya Tangirala wrote:
> > > > This patch series adds support for metadata encryption to F2FS using
> > > > blk-crypto.
> > > 
> > > Is there a companion patch series needed so that f2fstools can
> > > check/repair a file system with metadata encryption enabled?
> > > 
> > > 	       	    	   	- Ted
> > Yes! It's at
> > https://lore.kernel.org/linux-f2fs-devel/20201217151013.1513045-1-satyat@google.com/
> 
> Cool, I've been meaning to update f2fs-tools in Debian, and including
> these patches will allow us to generate {kvm,gce,android}-xfstests
> images with this support.  I'm hoping to get to it sometime betweeen
> Christmas and New Year's.
> 
> I guess there will need to be some additional work needed to create
> the f2fs image with a fixed keys for a particular file system in
> xfstests-bld, and then mounting and checking said image with the
> appropriatre keys as well.   Is that something you've put together?
> 
I did put something together that sets up metadata encryption on the disks
used by kvm-xfstests. The main code changes were to add a fixed
metadata encryption key with keyctl, and export MKFS_OPTIONS with the
metadata encryption options.

The mkfs options are the only options that need direct modification because
the rest of the tools (fsck/dump etc.) automatically do the right thing if
the FS superblock has the metadata encryption options. But the rest of the
tools do need the metadata encryption key to be present, and some
xfstests/other parts of the harness code clear the keyrings directly, so I
had a few more hacky changes to re-add the keys when they're cleared.
Some more hacky changes were needed because some xfstests override
MKFS_OPTIONS. I'll be happy to send what I have to you/put it up somewhere.
I'll also try to clean up the code a little, but my knowledge of xfstests
is definitely limited so it might take a little while.
> Cheers,
> 
> 						- Ted