ANDROID: add dm-default-key target for ICE metadata encryption

Add a device-mapper target "dm-default-key" which assigns an encryption
key to bios that don't already have one.  This will be used on Android's
userdata partition, so that all data not already encrypted with ext4
encryption is still encrypted with a default key (which will not be
derived from a user credential but will still be protected in some way).

Currently this feature depends on inline encryption support in hardware
via Qualcomm ICE; no software fallback is implemented yet.

An alternate approach considered was to introduce a block device ioctl
which would associate an encryption key with a struct block_device,
which would then be used as the default for bios issued to that
block_device.  However, that approach had some issues which made the dm
target seem like the better solution, and perhaps more likely to be
accepted upstream in some form someday (at least, once we have
vendor-independent inline encryption support upstream).  Specifically:

1.) The struct block_device for a partition really only represents a
    part of some underlying disk along with some state associated with
    its current users.  Notably, the block_device for a given partition
    is not guaranteed to stay around while no one has it opened or
    mounted.  This means that any extra state like an encryption key we
    may try to tie a block_device can be lost if there is a period of
    time when no one is using the block device.  Granted, this can't
    happen while the filesystem on the device is mounted, and it also
    can't happen on systems that use tmpfs for their /dev because the
    block_device will be pinned by the device node.  But either way, a
    dm target does not have this problem.

2.) The block_device for a partition doesn't have its own request_queue
    or queue_limits.  One way in which this could cause problems is that
    the disk could support discard requests and have discard_zeroes_data
    set to true, which specifies that data read back following a discard
    is guaranteed to be zeros.  That will not be true for an encrypted
    partition, so any filesystem that issues zeroouts (which the block
    layer may implement with discard) would potentially be broken.  We
    can handle this correctly in a dm target since each dm device has
    its own request_queue and we can disable discard_zeroes_data, just
    as dm-crypt does for example.

3.) Since the block layer remaps bios from partitions to the devices
    containing them, we'd still need to have ->bi_crypt_key and
    initialize it somewhere, e.g. in generic_make_request_checks()
    before it does the partition remapping.  We can't simply read
    ->bi_bdev->bd_default_key from the PFK module.

4.) With a block device ioctl, we'd need to carefully handle the cases
    where the ioctl is executed while someone else has the block device
    open (fail with EBUSY?) or while the block device's mapping already
    has pages cached (sync and invalidate them?).  This would not be too
    difficult, but with a dm target neither of these is a problem.

Change-Id: Ia3884842004cfb84d315ef38e54ab4f35b48cf5f
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Shivaprasad Hongal <shongal@codeaurora.org>
Signed-off-by: Neeraj Soni <neersoni@codeaurora.org>
3 files changed