Commit Graph

29 Commits

Author SHA1 Message Date
Satya Tangirala
9e7a6c5695 ANDROID: export fscrypt_limit_io_blocks()
The upstream version of the direct I/O on encrypted files patch series
missed exporting this function, which is needed if ext4 is built as a
module.

Bug: 162255927
Fixes: 0ea0eb628fee ("FROMLIST: fscrypt: Add functions for direct I/O support")
Change-Id: Ib827b4743423c7446436a47fcf95b255466288a3
Signed-off-by: Satya Tangirala <satyat@google.com>
2021-02-26 05:46:32 +00:00
Eric Biggers
c7615ef12b FROMLIST: fscrypt: Add functions for direct I/O support
Introduce fscrypt_dio_supported() to check whether a direct I/O request
is unsupported due to encryption constraints.

Also introduce fscrypt_limit_io_blocks() to limit how many blocks can be
added to a bio being prepared for direct I/O. This is needed for
filesystems that use the iomap direct I/O implementation to avoid DUN
wraparound in the middle of a bio (which is possible with the
IV_INO_LBLK_32 IV generation method). Elsewhere fscrypt_mergeable_bio()
is used for this, but iomap operates on logical ranges directly, so
filesystems using iomap won't have a chance to call fscrypt_mergeable_bio()
on every block added to a bio. So we need this function which limits a
logical range in one go.

Signed-off-by: Eric Biggers <ebiggers@google.com>
Co-developed-by: Satya Tangirala <satyat@google.com>
Signed-off-by: Satya Tangirala <satyat@google.com>

Bug: 162255927
Link: https://lore.kernel.org/r/20200724184501.1651378-2-satyat@google.com
Change-Id: I1dbd4f382d510d9b779d5e44a77fadf7040cf077
Signed-off-by: Eric Biggers <ebiggers@google.com>
2021-02-26 05:46:24 +00:00
Eric Biggers
d44ddbf417 ANDROID: revert fscrypt direct I/O support
Revert the direct I/O support for encrypted files so that we can bring
in the latest version of the patches from the mailing list.  This is
needed because in v5.5 and later, the ext4 support (via fs/iomap/) is
broken as-is -- not only is the second call to fscrypt_limit_dio_pages()
in the wrong place, but bios can exceed the intended nr_pages limit due
to multipage bvecs.  In order to fix this we need the v6 patches which
make fs/ext4/ handle the limiting instead of fs/iomap/.

On android-mainline, this fixes a failure in vts_kernel_encryption_test
(specifically, FBEPolicyTest#TestAesEmmcOptimizedPolicy) when run on a
device that uses the inlinecrypt mount option on ext4 (e.g. db845c).

Bug: 162255927
Bug: 171462575
Change-Id: I0da753dc9e0e7bc8d84bbcadfdfcdb9328cdb8d8
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Satya Tangirala <satyat@google.com>
2021-02-26 05:46:07 +00:00
Greg Kroah-Hartman
3428a2f782 Merge 585e5b17b9 ("Merge tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt") into android-mainline
Steps on the way to 5.10-rc4

Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: I8554ba37704bee02192ff6117d4909fde568fca2
2020-11-13 08:26:07 +01:00
Eric Biggers
d19d8d345e fscrypt: fix inline encryption not used on new files
The new helper function fscrypt_prepare_new_inode() runs before
S_ENCRYPTED has been set on the new inode.  This accidentally made
fscrypt_select_encryption_impl() never enable inline encryption on newly
created files, due to its use of fscrypt_needs_contents_encryption()
which only returns true when S_ENCRYPTED is set.

Fix this by using S_ISREG() directly instead of
fscrypt_needs_contents_encryption(), analogous to what
select_encryption_mode() does.

I didn't notice this earlier because by design, the user-visible
behavior is the same (other than performance, potentially) regardless of
whether inline encryption is used or not.

Fixes: a992b20cd4 ("fscrypt: add fscrypt_prepare_new_inode() and fscrypt_set_context()")
Reviewed-by: Satya Tangirala <satyat@google.com>
Link: https://lore.kernel.org/r/20201111015224.303073-1-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@google.com>
2020-11-11 20:59:07 -08:00
Greg Kroah-Hartman
9d77f49849 Merge 6f5032a852 ("Merge tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt") into android-mainline
Steps on the way to 5.10-rc1

Change-Id: Ifceecc1b9f94ea893484002c69aeb7b82d246f64
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
2020-10-23 11:56:31 +02:00
Eric Biggers
9dad5feb49 fscrypt: stop pretending that key setup is nofs-safe
fscrypt_get_encryption_info() has never actually been safe to call in a
context that needs GFP_NOFS, since it calls crypto_alloc_skcipher().

crypto_alloc_skcipher() isn't GFP_NOFS-safe, even if called under
memalloc_nofs_save().  This is because it may load kernel modules, and
also because it internally takes crypto_alg_sem.  Other tasks can do
GFP_KERNEL allocations while holding crypto_alg_sem for write.

The use of fscrypt_init_mutex isn't GFP_NOFS-safe either.

So, stop pretending that fscrypt_get_encryption_info() is nofs-safe.
I.e., when it allocates memory, just use GFP_KERNEL instead of GFP_NOFS.

Note, another reason to do this is that GFP_NOFS is deprecated in favor
of using memalloc_nofs_save() in the proper places.

Acked-by: Jeff Layton <jlayton@kernel.org>
Link: https://lore.kernel.org/r/20200917041136.178600-10-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@google.com>
2020-09-22 06:48:42 -07:00
Greg Kroah-Hartman
a17a563d16 Merge 449dc8c970 ("Merge tag 'for-v5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply") into android-mainline
Merges along the way to 5.9-rc1

resolves conflicts in:
	Documentation/ABI/testing/sysfs-class-power
	drivers/power/supply/power_supply_sysfs.c
	fs/crypto/inline_crypt.c

Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: Ia087834f54fb4e5269d68c3c404747ceed240701
2020-08-08 13:07:20 +02:00
Waiman Long
453431a549 mm, treewide: rename kzfree() to kfree_sensitive()
As said by Linus:

  A symmetric naming is only helpful if it implies symmetries in use.
  Otherwise it's actively misleading.

  In "kzalloc()", the z is meaningful and an important part of what the
  caller wants.

  In "kzfree()", the z is actively detrimental, because maybe in the
  future we really _might_ want to use that "memfill(0xdeadbeef)" or
  something. The "zero" part of the interface isn't even _relevant_.

The main reason that kzfree() exists is to clear sensitive information
that should not be leaked to other future users of the same memory
objects.

Rename kzfree() to kfree_sensitive() to follow the example of the recently
added kvfree_sensitive() and make the intention of the API more explicit.
In addition, memzero_explicit() is used to clear the memory to make sure
that it won't get optimized away by the compiler.

The renaming is done by using the command sequence:

  git grep -w --name-only kzfree |\
  xargs sed -i 's/kzfree/kfree_sensitive/'

followed by some editing of the kfree_sensitive() kerneldoc and adding
a kzfree backward compatibility macro in slab.h.

[akpm@linux-foundation.org: fs/crypto/inline_crypt.c needs linux/slab.h]
[akpm@linux-foundation.org: fix fs/crypto/inline_crypt.c some more]

Suggested-by: Joe Perches <joe@perches.com>
Signed-off-by: Waiman Long <longman@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Acked-by: David Howells <dhowells@redhat.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Cc: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Cc: James Morris <jmorris@namei.org>
Cc: "Serge E. Hallyn" <serge@hallyn.com>
Cc: Joe Perches <joe@perches.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Dan Carpenter <dan.carpenter@oracle.com>
Cc: "Jason A . Donenfeld" <Jason@zx2c4.com>
Link: http://lkml.kernel.org/r/20200616154311.12314-3-longman@redhat.com
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2020-08-07 11:33:22 -07:00
Eric Biggers
98777a7eb7 Merge commit 382625d0d4 ("Merge tag 'for-5.9/block-20200802' of git://git.kernel.dk/linux-block") into android-mainline
Conflicts:
	drivers/md/dm-bow.c
	drivers/md/dm-default-key.c
	drivers/md/dm.c
	fs/crypto/inline_crypt.c

Replace bdev->bd_queue with bdev_get_queue(bdev).

Bug: 129280212
Bug: 160883801
Bug: 160885805
Bug: 162257830
Change-Id: I9b0b295472080dfc0990dcb769205e68d706ce0e
Signed-off-by: Eric Biggers <ebiggers@google.com>
2020-08-06 10:07:17 -07:00
Eric Biggers
f58685e5fe Merge commit 3208167a86 ("Merge tag 'filelock-v5.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/jlayton/linux") into android-mainline
Resolve merge conflicts in fs/crypto/ caused by the non-upstream changes
for metadata encryption support [1] and wrapped key support [2].

[1] https://android.googlesource.com/kernel/common-patches/+/refs/heads/master/android-mainline/ANDROID-dm-add-dm-default-key-target-for-metadata-encryption.patch
[2] https://android.googlesource.com/kernel/common-patches/+/refs/heads/master/android-mainline/ANDROID-fscrypt-add-support-for-hardware-wrapped-keys.patch

Conflicts:
	fs/crypto/fscrypt_private.h
	fs/crypto/inline_crypt.c
	fs/crypto/keysetup.c
	fs/crypto/keysetup_v1.c
	fs/f2fs/data.c
	include/linux/fscrypt.h

Bug: 160885805
Bug: 160883801
Test: kvm-xfstests -c ext4,f2fs -g encrypt
Change-Id: Icdc9e61b2286c78ba04cec1c9dca421bff545716
Signed-off-by: Eric Biggers <ebiggers@google.com>
2020-08-04 11:40:15 -07:00
Eric Biggers
55e32c54bb fscrypt: don't load ->i_crypt_info before it's known to be valid
In fscrypt_set_bio_crypt_ctx(), ->i_crypt_info isn't known to be
non-NULL until we check fscrypt_inode_uses_inline_crypto().  So, load
->i_crypt_info after the check rather than before.  This makes no
difference currently, but it prevents people from introducing bugs where
the pointer is dereferenced when it may be NULL.

Suggested-by: Dave Chinner <david@fromorbit.com>
Cc: Satya Tangirala <satyat@google.com>
Link: https://lore.kernel.org/r/20200727174158.121456-1-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@google.com>
2020-07-30 14:21:50 -07:00
Eric Biggers
97c6327f71 fscrypt: use smp_load_acquire() for fscrypt_prepared_key
Normally smp_store_release() or cmpxchg_release() is paired with
smp_load_acquire().  Sometimes smp_load_acquire() can be replaced with
the more lightweight READ_ONCE().  However, for this to be safe, all the
published memory must only be accessed in a way that involves the
pointer itself.  This may not be the case if allocating the object also
involves initializing a static or global variable, for example.

fscrypt_prepared_key includes a pointer to a crypto_skcipher object,
which is internal to and is allocated by the crypto subsystem.  By using
READ_ONCE() for it, we're relying on internal implementation details of
the crypto subsystem.

Remove this fragile assumption by using smp_load_acquire() instead.

(Note: I haven't seen any real-world problems here.  This change is just
fixing the code to be guaranteed correct and less fragile.)

Fixes: 5fee36095c ("fscrypt: add inline encryption support")
Cc: Satya Tangirala <satyat@google.com>
Link: https://lore.kernel.org/r/20200721225920.114347-3-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@google.com>
2020-07-21 16:02:13 -07:00
Eric Biggers
27b2ed4395 ANDROID: update to latest fscrypt and UFS inline crypto patches
Update to match the latest fscrypt and UFS inline encryption patches:

fscrypt patches queued in fscrypt/master for 5.9:
    https://lore.kernel.org/r/20200702015607.1215430-2-satyat@google.com
    https://lore.kernel.org/r/20200702015607.1215430-3-satyat@google.com
    https://lore.kernel.org/r/20200702015607.1215430-4-satyat@google.com
    https://lore.kernel.org/r/20200702015607.1215430-5-satyat@google.com

UFS patches queued in scsi/5.9/scsi-queue:
    https://lore.kernel.org/r/20200706200414.2027450-2-satyat@google.com
    https://lore.kernel.org/r/20200706200414.2027450-3-satyat@google.com
    https://lore.kernel.org/r/20200706200414.2027450-4-satyat@google.com

fscrypt patches under discussion (direct I/O support):
    https://lore.kernel.org/r/20200709194751.2579207-2-satyat@google.com
    https://lore.kernel.org/r/20200709194751.2579207-3-satyat@google.com
    https://lore.kernel.org/r/20200709194751.2579207-4-satyat@google.com
    https://lore.kernel.org/r/20200709194751.2579207-5-satyat@google.com
    https://lore.kernel.org/r/20200709194751.2579207-6-satyat@google.com

UFS patches under discussion (program_key variant op):
    https://lore.kernel.org/r/20200710072013.177481-5-ebiggers@kernel.org

Bug: 137270441
Change-Id: I70c827b2106287f7296f5ed00717561f2d7e160a
Signed-off-by: Eric Biggers <ebiggers@google.com>
2020-07-14 10:30:33 -07:00
Satya Tangirala
a79db694f3 ANDROID: fscrypt: fix DUN contiguity with inline encryption + IV_INO_LBLK_32 policies
IV_INO_LBLK_32 policies introduced the possibility that logically
contiguous data blocks might not have contiguous DUNs (because of
potential DUN wraparound). As such, whenever a page is merged into a
bio, fscrypt_mergeable_bio() must be called to check DUN contiguity.
Fix fscrypt_zeroout_range_inline_crypt by calling
fscrypt_mergeable_bio() before each page merge.

Further, fscrypt inline encryption does not handle the case when the DUN
wraps around within a page (which can happen when the data unit size !=
PAGE_SIZE). For now, we handle that by disallowing inline encryption
with IV_INO_LBLK_32 policies when the data unit size != PAGE_SIZE (and
dropping the now redundant check for this in fscrypt_dio_supported()).

Fixes: c2b86b727a ("FROMLIST: Update Inline Encryption from v6 to upstream version of patch series")
Change-Id: I9cb414fcc284b197b9d3d1b9643029c6b875df5a
Signed-off-by: Satya Tangirala <satyat@google.com>
2020-07-14 15:48:33 +00:00
Satya Tangirala
5fee36095c fscrypt: add inline encryption support
Add support for inline encryption to fs/crypto/.  With "inline
encryption", the block layer handles the decryption/encryption as part
of the bio, instead of the filesystem doing the crypto itself via
Linux's crypto API. This model is needed in order to take advantage of
the inline encryption hardware present on most modern mobile SoCs.

To use inline encryption, the filesystem needs to be mounted with
'-o inlinecrypt'. Blk-crypto will then be used instead of the traditional
filesystem-layer crypto whenever possible to encrypt the contents
of any encrypted files in that filesystem. Fscrypt still provides the key
and IV to use, and the actual ciphertext on-disk is still the same;
therefore it's testable using the existing fscrypt ciphertext verification
tests.

Note that since blk-crypto has a fallback to Linux's crypto API, and
also supports all the encryption modes currently supported by fscrypt,
this feature is usable and testable even without actual inline
encryption hardware.

Per-filesystem changes will be needed to set encryption contexts when
submitting bios and to implement the 'inlinecrypt' mount option.  This
patch just adds the common code.

Signed-off-by: Satya Tangirala <satyat@google.com>
Reviewed-by: Jaegeuk Kim <jaegeuk@kernel.org>
Reviewed-by: Eric Biggers <ebiggers@google.com>
Reviewed-by: Theodore Ts'o <tytso@mit.edu>
Link: https://lore.kernel.org/r/20200702015607.1215430-3-satyat@google.com
Co-developed-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Eric Biggers <ebiggers@google.com>
2020-07-08 10:29:30 -07:00
Satya Tangirala
c2b86b727a FROMLIST: Update Inline Encryption from v6 to upstream version of patch series
The block layer patches for inline encryption are now in upstream, so
update Android to the upstream version of inline encryption. The
fscrypt/f2fs/ext4 patches are also updated to the latest version sent
upstream (since they can't be updated separately from the block layer
patches).

Changes v6 => v7:
 - Keyslot management is now done on a per-request basis rather than a
   per-bio basis.
 - Storage drivers can now specify the maximum number of bytes they
   can accept for the data unit number (DUN) for each crypto algorithm,
   and upper layers can specify the minimum number of bytes of DUN they
   want with the blk_crypto_key they send with the bio - a driver is
   only considered to support a blk_crypto_key if the driver supports at
   least as many DUN bytes as the upper layer wants. This is necessary
   because storage drivers may not support as many bytes as the
   algorithm specification dictates (for e.g. UFS only supports 8 byte
   DUNs for AES-256-XTS, even though the algorithm specification
   says DUNs are 16 bytes long).
 - Introduce SB_INLINECRYPT to keep track of whether inline encryption
   is enabled for a filesystem (instead of using an fscrypt_operation).
 - Expose keyslot manager declaration and embed it within ufs_hba to
   clean up code.
 - Make blk-crypto preclude blk-integrity.
 - Some bug fixes
 - Introduce UFSHCD_QUIRK_BROKEN_CRYPTO for UFS drivers that don't
   support inline encryption (yet)

Changes v7 => v8:
 - Pass a struct blk_ksm_keyslot * around instead of slot numbers which
   simplifies some functions and passes around arguments with better types
 - Make bios with no encryption context avoid making calls into blk-crypto
   by checking for the presence of bi_crypt_context before making the call
 - Make blk-integrity preclude inline encryption support at probe time
 - Many many cleanups

Changes v8 => v9:
 - Don't open code bio_has_crypt_ctx into callers of blk-crypto functions.
 - Lots of cleanups

Changes v9 => v10:
 - Incorporate Eric's fix for allowing en/decryption to happen as usual via
   fscrypt in the case that hardware doesn't support the desired crypto
   configuration, but blk-crypto-fallback is disabled. (Introduce
   struct blk_crypto_config and blk_crypto_config_supported for fscrypt
   to call, to check that either blk-crypto-fallback is enabled or the
   device supports the crypto configuration).
 - Update docs
 - Lots of cleanups

Changes v10 => v11:
 - We now allocate a new bio_crypt_ctx for each request instead of
   pulling and reusing the one in the bio inserted into the request. The
   bio_crypt_ctx of a bio is freed after the bio is ended.
 - Make each blk_ksm_keyslot store a pointer to the blk_crypto_key
   instead of a copy of the blk_crypto_key, so that each blk_crypto_key
   will have its own keyslot. We also won't need to compute the siphash
   for a blk_crypto_key anymore.
 - Minor cleanups

Changes v11 => v12:
 - Inlined some fscrypt functions
 - Minor cleanups and improved comments

Changes v12 => v13:
 - Updated docs
 - Minor cleanups
 - rebased onto linux-block/for-next

Changes v13 => fscrypt/f2fs/ext4 upstream patch series
 - rename struct fscrypt_info::ci_key to ci_enc_key
 - set dun bytes more precisely in fscrypt
 - cleanups

Bug: 137270441
Test: Test cuttlefish boots both with and without inlinecrypt mount
      option specified in fstab, while using both F2FS and EXT4 for
      userdata.img. Also verified ciphertext via
      "atest -v vts_kernel_encryption_test"
      Also tested by running gce-xfstests on both the
      auto and encrypt test groups on EXT4 and F2FS both with and
      without the inlinecrypt mount option. The UFS changes were
      tested on a Pixel 4 device.
Link: https://lore.kernel.org/linux-block/20200514003727.69001-1-satyat@google.com/
Link: https://lore.kernel.org/linux-fscrypt/20200617075732.213198-1-satyat@google.com/
Link: https://lore.kernel.org/linux-scsi/20200617081841.218985-1-satyat@google.com/
Change-Id: I57c10d370bf006c9dfcf173f21a720413017761e
Signed-off-by: Satya Tangirala <satyat@google.com>
Signed-off-by: Eric Biggers <ebiggers@google.com>
2020-06-17 17:17:30 -07:00
Eric Biggers
8d6c90c9d6 ANDROID: fscrypt: handle direct I/O with IV_INO_LBLK_32
With the existing fscrypt IV generation methods, each file's data blocks
have contiguous DUNs.  Therefore the direct I/O code "just worked"
because it only submits logically contiguous bios.  But with
IV_INO_LBLK_32, the direct I/O code breaks because the DUN can wrap from
0xffffffff to 0.  We can't submit bios across such boundaries.

This is especially difficult to handle when block_size != PAGE_SIZE,
since in that case the DUN can wrap in the middle of a page.  Punt on
this case for now and just handle block_size == PAGE_SIZE.

Add and use a new function fscrypt_dio_supported() to check whether a
direct I/O request is unsupported due to encryption constraints.

Then, update fs/direct-io.c (used by f2fs, and by ext4 in kernel v5.4
and earlier) and fs/iomap/direct-io.c (used by ext4 in kernel v5.5 and
later) to avoid submitting I/O across a DUN discontinuity.

(This is needed in ACK now because ACK already supports direct I/O with
inline crypto.  I'll be sending this upstream along with the encrypted
direct I/O support itself once its prerequisites are closer to landing.)

Test: For now, just manually tested direct I/O on ext4 and f2fs in the
      DUN discontinuity case.
Bug: 144046242
Change-Id: I0c0b0b20a73ade35c3660cc6f9c09d49d3853ba5
Signed-off-by: Eric Biggers <ebiggers@google.com>
2020-05-21 10:09:43 -07:00
Eric Biggers
06a813d6df BACKPORT: FROMLIST: fscrypt: add support for IV_INO_LBLK_32 policies
The eMMC inline crypto standard will only specify 32 DUN bits (a.k.a. IV
bits), unlike UFS's 64.  IV_INO_LBLK_64 is therefore not applicable, but
an encryption format which uses one key per policy and permits the
moving of encrypted file contents (as f2fs's garbage collector requires)
is still desirable.

To support such hardware, add a new encryption format IV_INO_LBLK_32
that makes the best use of the 32 bits: the IV is set to
'SipHash-2-4(inode_number) + file_logical_block_number mod 2^32', where
the SipHash key is derived from the fscrypt master key.  We hash only
the inode number and not also the block number, because we need to
maintain contiguity of DUNs to merge bios.

Unlike with IV_INO_LBLK_64, with this format IV reuse is possible; this
is unavoidable given the size of the DUN.  This means this format should
only be used where the requirements of the first paragraph apply.
However, the hash spreads out the IVs in the whole usable range, and the
use of a keyed hash makes it difficult for an attacker to determine
which files use which IVs.

Besides the above differences, this flag works like IV_INO_LBLK_64 in
that on ext4 it is only allowed if the stable_inodes feature has been
enabled to prevent inode numbers and the filesystem UUID from changing.

Signed-off-by: Eric Biggers <ebiggers@google.com>

Link: https://lore.kernel.org/r/20200515204141.251098-1-ebiggers@kernel.org

(Resolved conflicts with inline encryption support.  Besides the
 necessary "straightforward" merge resolutions, also made
 fscrypt_get_dun_bytes() aware of IV_INO_LBLK_32 and made IV_INO_LBLK_32
 usable with wrapped keys.)

Test: 'atest vts_kernel_encryption_test' on Cuttlefish with
      the IV_INO_LBLK_32 test added (http://aosp/1315024).

      Also tested enabling this in the fstab for Cuttlefish
      (using http://aosp/1315886).

      Also ran 'kvm-xfstests -c ext4,f2fs -g encrypt', including my
      work-in-progress xfstest for IV_INO_LBLK_32.

Bug: 144046242
Change-Id: I57df71d502bde0475efc906a0812102063ff2f2a
Signed-off-by: Eric Biggers <ebiggers@google.com>
2020-05-21 10:05:57 -07:00
Eric Biggers
6ed01439dc ANDROID: fscrypt: set dun_bytes more precisely
Make fscrypt set dun_bytes to only what it actually needs, so that it
can make use of inline crypto hardware in more cases.

Bug: 144046242
Bug: 153512828
Change-Id: I36f90ea6b64ef51a9d58ffb069d2cba74965c239
Signed-off-by: Eric Biggers <ebiggers@google.com>
2020-05-14 18:33:43 +00:00
Eric Biggers
7705813551 ANDROID: block: backport the ability to specify max_dun_bytes
Backport a fix from the v7 inline crypto patchset which ensures that the
block layer knows the number of DUN bytes the inline encryption hardware
supports, so that hardware isn't used when it shouldn't be.

(This unfortunately means introducing some increasing long argument
lists; this was all already fixed up in later versions of the patchset.)

To avoid breaking the KMI for drivers, don't add a dun_bytes argument to
keyslot_manager_create() but rather allow drivers to call
keyslot_manager_set_max_dun_bytes() to override the default.  Also,
don't add dun_bytes as a new field in 'struct blk_crypto_key' but rather
pack it into the existing 'hash' field which is for block layer use.

Bug: 144046242
Bug: 153512828
Change-Id: I285f36557fb3eafc5f2f64727ef1740938b59dd7
Signed-off-by: Eric Biggers <ebiggers@google.com>
2020-05-14 18:33:25 +00:00
Eric Biggers
3ddb60ffd2 ANDROID: fscrypt: fall back to filesystem-layer crypto when needed
When the filesystem is mounted with '-o inlinecrypt', make fscrypt fall
back to filesystem-layer crypto when inline crypto won't work, e.g. due
to the hardware not supporting the encryption algorithm.

When blk-crypto-fallback is disabled, this fixes '-o inlinecrypt' to not
break any fscrypt policies that would otherwise work.

This is needed for VtsKernelEncryptionTest to pass on some devices.

Bug: 137270441
Bug: 151100202
Test: 'atest vts_kernel_encryption_test' on Pixel 4 with the
      inline crypto patches backported, and also on Cuttlefish.
Change-Id: I3e730df4608efb12d7126d1a85faddcccb566764
Signed-off-by: Eric Biggers <ebiggers@google.com>
2020-04-04 16:32:26 +00:00
Eric Biggers
935b0c41ff ANDROID: block: require drivers to declare supported crypto key type(s)
We need a way to tell which type of keys the inline crypto hardware
supports (standard, wrapped, or both), so that fallbacks can be used
when needed (either blk-crypto-fallback, or fscrypt fs-layer crypto).

We can't simply assume that

    keyslot_mgmt_ll_ops::derive_raw_secret == NULL

means only standard keys are supported and that

    keyslot_mgmt_ll_ops::derive_raw_secret != NULL

means that only wrapped keys are supported, because device-mapper
devices always implement this method.  Also, hardware might support both
types of keys.

Therefore, add a field keyslot_manager::features which contains a
bitmask of flags which indicate the supported types of keys.  Drivers
will need to fill this in.  This patch makes the UFS standard crypto
code set BLK_CRYPTO_FEATURE_STANDARD_KEYS, but UFS variant drivers may
need to set BLK_CRYPTO_FEATURE_WRAPPED_KEYS instead.

Then, make keyslot_manager_crypto_mode_supported() take the key type
into account.

Bug: 137270441
Bug: 151100202
Test: 'atest vts_kernel_encryption_test' on Pixel 4 with the
      inline crypto patches backported, and also on Cuttlefish.
Change-Id: Ied846c2767c1fd2f438792dcfd3649157e68b005
Signed-off-by: Eric Biggers <ebiggers@google.com>
2020-04-04 16:32:16 +00:00
Barani Muthukumaran
f5ecdc54d7 ANDROID: block: Prevent crypto fallback for wrapped keys
blk-crypto-fallback does not support wrapped keys, hence
prevent falling back when program_key fails. Add 'is_hw_wrapped'
flag to blk-crypto-key to mention if the key is wrapped
when the key is initialized.

Bug: 147209885

Test: Validate FBE, simulate a failure in the underlying blk
      device and ensure the call fails without falling back
      to blk-crypto-fallback.

Change-Id: I8bc301ca1ac9e55ba6ab622e8325486916b45c56
Signed-off-by: Barani Muthukumaran <bmuthuku@codeaurora.org>
2020-02-13 01:36:41 +00:00
Eric Biggers
cb39ec0c10 ANDROID: dm: add dm-default-key target for metadata encryption
Add a device-mapper target "dm-default-key" which assigns an encryption
key to bios that aren't for the contents of an encrypted file.

This ensures that all blocks on-disk will be encrypted with some key,
without the performance hit of file contents being encrypted twice when
fscrypt (File-Based Encryption) is used.

It is only appropriate to use dm-default-key when key configuration is
tightly controlled, like it is in Android, such that all fscrypt keys
are at least as hard to compromise as the default key.

Compared to the original version of dm-default-key, this has been
modified to use the new vendor-independent inline encryption framework
(which works even when no inline encryption hardware is present), the
table syntax has been changed to match dm-crypt, and support for
specifying Adiantum encryption has been added.  These changes also mean
that dm-default-key now always explicitly specifies the DUN (the IV).

Also, to handle f2fs moving blocks of encrypted files around without the
key, and to handle ext4 and f2fs filesystems mounted without
'-o inlinecrypt', the mapping logic is no longer "set a key on the bio
if it doesn't have one already", but rather "set a key on the bio unless
the bio has the bi_skip_dm_default_key flag set".  Filesystems set this
flag on *all* bios for encrypted file contents, regardless of whether
they are encrypting/decrypting the file using inline encryption or the
traditional filesystem-layer encryption, or moving the raw data.

For the bi_skip_dm_default_key flag, a new field in struct bio is used
rather than a bit in bi_opf so that fscrypt_set_bio_crypt_ctx() can set
the flag, minimizing the changes needed to filesystems.  (bi_opf is
usually overwritten after fscrypt_set_bio_crypt_ctx() is called.)

Bug: 137270441
Bug: 147814592
Change-Id: I69c9cd1e968ccf990e4ad96e5115b662237f5095
Signed-off-by: Eric Biggers <ebiggers@google.com>
2020-01-24 10:53:45 -08:00
Barani Muthukumaran
155acee851 ANDROID: fscrypt: add support for hardware-wrapped keys
To prevent keys from being compromised if an attacker acquires read
access to kernel memory, some inline encryption hardware supports
protecting the keys in hardware without software having access to or the
ability to set the plaintext keys.  Instead, software only sees "wrapped
keys", which may differ on every boot.  The keys can be initially
generated either by software (in which case they need to be imported to
hardware to be wrapped), or directly by the hardware.

Add support for this type of hardware by allowing keys to be flagged as
hardware-wrapped and encryption policies to be flagged as needing a
hardware-wrapped key.  When used, fscrypt will pass the wrapped key
directly to the inline encryption hardware to encrypt file contents.
The hardware is responsible for internally unwrapping the key and
deriving the actual file contents encryption key.

fscrypt also asks the inline encryption hardware to derive a
cryptographically isolated software "secret", which fscrypt then uses as
the master key for all other purposes besides file contents encryption,
e.g. to derive filenames encryption keys and the key identifier.

Bug: 147209885

Change-Id: I58d1a37f5ba8cf178b80036b813e0bc99512ef3b
Co-developed-by: Gaurav Kashyap <gaurkash@codeaurora.org>
Signed-off-by: Gaurav Kashyap <gaurkash@codeaurora.org>
Signed-off-by: Barani Muthukumaran <bmuthuku@codeaurora.org>
Signed-off-by: Eric Biggers <ebiggers@google.com>
2020-01-20 22:50:36 +00:00
Barani Muthukumaran
d739474ec2 ANDROID: block: provide key size as input to inline crypto APIs
Currently, blk-crypto uses the algorithm to determine the size of keys.
However, some inline encryption hardware supports protecting keys from
software by wrapping the storage keys with an ephemeral key.  Since
these wrapped keys are not of a fixed size, add the capability to
provide the key size when initializing a blk_crypto_key, and update the
keyslot manager to take size into account when comparing keys.

Bug: 147209885

Change-Id: I9bf26d06d18a2d671c51111b4896abe4df303988
Co-developed-by: Gaurav Kashyap <gaurkash@codeaurora.org>
Signed-off-by: Gaurav Kashyap <gaurkash@codeaurora.org>
Signed-off-by: Barani Muthukumaran <bmuthuku@codeaurora.org>
Signed-off-by: Eric Biggers <ebiggers@google.com>
2020-01-20 22:50:14 +00:00
Satya Tangirala
cfd7e6c13c FROMLIST: Update Inline Encryption from v5 to v6 of patch series
Changes v5 => v6:
 - Blk-crypto's kernel crypto API fallback is no longer restricted to
   8-byte DUNs. It's also now separately configurable from blk-crypto, and
   can be disabled entirely, while still allowing the kernel to use inline
   encryption hardware. Further, struct bio_crypt_ctx takes up less space,
   and no longer contains the information needed by the crypto API
   fallback - the fallback allocates the required memory when necessary.
 - Blk-crypto now supports all file content encryption modes supported by
   fscrypt.
 - Fixed bio merging logic in blk-merge.c
 - Fscrypt now supports inline encryption with the direct key policy, since
   blk-crypto now has support for larger DUNs.
 - Keyslot manager now uses a hashtable to lookup which keyslot contains
   any particular key (thanks Eric!)
 - Fscrypt support for inline encryption now handles filesystems with
   multiple underlying block devices (thanks Eric!)
 - Numerous cleanups

Bug: 137270441
Test: refer to I26376479ee38259b8c35732cb3a1d7e15f9b05a3
Change-Id: I13e2e327e0b4784b394cb1e7cf32a04856d95f01
Link: https://lore.kernel.org/linux-block/20191218145136.172774-1-satyat@google.com/
Signed-off-by: Satya Tangirala <satyat@google.com>
2020-01-13 07:12:15 -08:00
Satya Tangirala
f5f6acfb1c FROMLIST: fscrypt: add inline encryption support
Add support for inline encryption to fs/crypto/.  With "inline
encryption", the block layer handles the decryption/encryption as part
of the bio, instead of the filesystem doing the crypto itself via
Linux's crypto API.  This model is needed in order to take advantage of
the inline encryption hardware present on most modern mobile SoCs.

To use inline encryption, the filesystem needs to be mounted with
'-o inlinecrypt'.  The contents of any AES-256-XTS encrypted files will
then be encrypted using blk-crypto, instead of using the traditional
filesystem-layer crypto.  fscrypt still provides the key and IV to use,
and the actual ciphertext on-disk is still the same; therefore it's
testable using the existing fscrypt ciphertext verification tests.

Note that since blk-crypto has a fallack to Linux's crypto API, this
feature is usable and testable even without actual inline encryption
hardware.

Per-filesystem changes will be needed to set encryption contexts when
submitting bios and to implement the 'inlinecrypt' mount option.  This
patch just adds the common code.

Bug: 137270441
Test: tested as series; see Ie1b77f7615d6a7a60fdc9105c7ab2200d17636a8
Change-Id: I72e7e29db017404cdf7b5125718b5ba9590d31b4
Co-developed-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Satya Tangirala <satyat@google.com>
Link: https://patchwork.kernel.org/patch/11214761/
2019-10-30 22:01:39 +00:00