24 Oct, 2020

1 commit


06 Oct, 2020

3 commits

  • bio_crypt_set_ctx() assumes its gfp_mask argument always includes
    __GFP_DIRECT_RECLAIM, so that the mempool_alloc() will always succeed.

    For now this assumption is still fine, since no callers violate it.
    Making bio_crypt_set_ctx() able to fail would add unneeded complexity.

    However, if a caller didn't use __GFP_DIRECT_RECLAIM, it would be very
    hard to notice the bug. Make it easier by adding a WARN_ON_ONCE().

    Signed-off-by: Eric Biggers
    Reviewed-by: Satya Tangirala
    Cc: Miaohe Lin
    Cc: Satya Tangirala
    Signed-off-by: Jens Axboe

    Eric Biggers
     
  • blk_crypto_rq_bio_prep() assumes its gfp_mask argument always includes
    __GFP_DIRECT_RECLAIM, so that the mempool_alloc() will always succeed.

    However, blk_crypto_rq_bio_prep() might be called with GFP_ATOMIC via
    setup_clone() in drivers/md/dm-rq.c.

    This case isn't currently reachable with a bio that actually has an
    encryption context. However, it's fragile to rely on this. Just make
    blk_crypto_rq_bio_prep() able to fail.

    Suggested-by: Satya Tangirala
    Signed-off-by: Eric Biggers
    Reviewed-by: Mike Snitzer
    Reviewed-by: Satya Tangirala
    Cc: Miaohe Lin
    Signed-off-by: Jens Axboe

    Eric Biggers
     
  • bio_crypt_clone() assumes its gfp_mask argument always includes
    __GFP_DIRECT_RECLAIM, so that the mempool_alloc() will always succeed.

    However, bio_crypt_clone() might be called with GFP_ATOMIC via
    setup_clone() in drivers/md/dm-rq.c, or with GFP_NOWAIT via
    kcryptd_io_read() in drivers/md/dm-crypt.c.

    Neither case is currently reachable with a bio that actually has an
    encryption context. However, it's fragile to rely on this. Just make
    bio_crypt_clone() able to fail, analogous to bio_integrity_clone().

    Reported-by: Miaohe Lin
    Signed-off-by: Eric Biggers
    Reviewed-by: Mike Snitzer
    Reviewed-by: Satya Tangirala
    Cc: Satya Tangirala
    Signed-off-by: Jens Axboe

    Eric Biggers
     

07 Aug, 2020

1 commit


01 Jul, 2020

2 commits

  • generic_make_request has always been very confusingly misnamed, so rename
    it to submit_bio_noacct to make it clear that it is submit_bio minus
    accounting and a few checks.

    Signed-off-by: Christoph Hellwig
    Signed-off-by: Jens Axboe

    Christoph Hellwig
     
  • fscrypt isn't supposed to try to use inline encryption if the key is
    wrapped but only blk-crypto-fallback is available. This logic got lost
    when updating to the latest inline encryption patchset. Restore it in
    blk_crypto_config_supported() where it should be now.

    Also drop a redundant check from blk_crypto_fallback_bio_prep().

    This fix should be folded into
    ANDROID-block-add-hardware-wrapped-key-support.patch

    Fixes: c2b86b727a41 ("FROMLIST: Update Inline Encryption from v6 to upstream version of patch series")
    Change-Id: I4f8a32ee30d700b499da36e55e74d279a86bb779
    Signed-off-by: Eric Biggers

    Eric Biggers
     

18 Jun, 2020

1 commit

  • 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
    Signed-off-by: Eric Biggers

    Satya Tangirala
     

15 May, 2020

1 commit

  • 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

    Eric Biggers
     

14 May, 2020

2 commits

  • Blk-crypto delegates crypto operations to inline encryption hardware
    when available. The separately configurable blk-crypto-fallback contains
    a software fallback to the kernel crypto API - when enabled, blk-crypto
    will use this fallback for en/decryption when inline encryption hardware
    is not available.

    This lets upper layers not have to worry about whether or not the
    underlying device has support for inline encryption before deciding to
    specify an encryption context for a bio. It also allows for testing
    without actual inline encryption hardware - in particular, it makes it
    possible to test the inline encryption code in ext4 and f2fs simply by
    running xfstests with the inlinecrypt mount option, which in turn allows
    for things like the regular upstream regression testing of ext4 to cover
    the inline encryption code paths.

    For more details, refer to Documentation/block/inline-encryption.rst.

    Signed-off-by: Satya Tangirala
    Reviewed-by: Eric Biggers
    Signed-off-by: Jens Axboe

    Satya Tangirala
     
  • We must have some way of letting a storage device driver know what
    encryption context it should use for en/decrypting a request. However,
    it's the upper layers (like the filesystem/fscrypt) that know about and
    manages encryption contexts. As such, when the upper layer submits a bio
    to the block layer, and this bio eventually reaches a device driver with
    support for inline encryption, the device driver will need to have been
    told the encryption context for that bio.

    We want to communicate the encryption context from the upper layer to the
    storage device along with the bio, when the bio is submitted to the block
    layer. To do this, we add a struct bio_crypt_ctx to struct bio, which can
    represent an encryption context (note that we can't use the bi_private
    field in struct bio to do this because that field does not function to pass
    information across layers in the storage stack). We also introduce various
    functions to manipulate the bio_crypt_ctx and make the bio/request merging
    logic aware of the bio_crypt_ctx.

    We also make changes to blk-mq to make it handle bios with encryption
    contexts. blk-mq can merge many bios into the same request. These bios need
    to have contiguous data unit numbers (the necessary changes to blk-merge
    are also made to ensure this) - as such, it suffices to keep the data unit
    number of just the first bio, since that's all a storage driver needs to
    infer the data unit number to use for each data block in each bio in a
    request. blk-mq keeps track of the encryption context to be used for all
    the bios in a request with the request's rq_crypt_ctx. When the first bio
    is added to an empty request, blk-mq will program the encryption context
    of that bio into the request_queue's keyslot manager, and store the
    returned keyslot in the request's rq_crypt_ctx. All the functions to
    operate on encryption contexts are in blk-crypto.c.

    Upper layers only need to call bio_crypt_set_ctx with the encryption key,
    algorithm and data_unit_num; they don't have to worry about getting a
    keyslot for each encryption context, as blk-mq/blk-crypto handles that.
    Blk-crypto also makes it possible for request-based layered devices like
    dm-rq to make use of inline encryption hardware by cloning the
    rq_crypt_ctx and programming a keyslot in the new request_queue when
    necessary.

    Note that any user of the block layer can submit bios with an
    encryption context, such as filesystems, device-mapper targets, etc.

    Signed-off-by: Satya Tangirala
    Reviewed-by: Eric Biggers
    Reviewed-by: Christoph Hellwig
    Signed-off-by: Jens Axboe

    Satya Tangirala
     

05 Apr, 2020

2 commits

  • 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

    Eric Biggers
     
  • If blk-crypto-fallback is needed but is disabled by kconfig, make
    blk_crypto_start_using_mode() return an error rather than succeeding.
    Use ENOPKG, which matches the error code used by fscrypt when crypto API
    support is missing with fs-layer encryption.

    Also, if blk-crypto-fallback is needed but the algorithm is missing from
    the kernel's crypto API, change the error code from ENOENT to ENOPKG.

    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: Iedf00ca8e48c74a5d4c40b12712f38738a04ef11
    Signed-off-by: Eric Biggers

    Eric Biggers
     

13 Feb, 2020

1 commit

  • 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

    Barani Muthukumaran
     

25 Jan, 2020

1 commit


21 Jan, 2020

1 commit

  • 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
    Signed-off-by: Gaurav Kashyap
    Signed-off-by: Barani Muthukumaran
    Signed-off-by: Eric Biggers

    Barani Muthukumaran
     

13 Jan, 2020

1 commit

  • 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

    Satya Tangirala
     

31 Oct, 2019

1 commit

  • We introduce blk-crypto, which manages programming keyslots for struct
    bios. With blk-crypto, filesystems only need to call bio_crypt_set_ctx with
    the encryption key, algorithm and data_unit_num; they don't have to worry
    about getting a keyslot for each encryption context, as blk-crypto handles
    that. Blk-crypto also makes it possible for layered devices like device
    mapper to make use of inline encryption hardware.

    Blk-crypto delegates crypto operations to inline encryption hardware when
    available, and also contains a software fallback to the kernel crypto API.
    For more details, refer to Documentation/block/inline-encryption.rst.

    Bug: 137270441
    Test: tested as series; see Ie1b77f7615d6a7a60fdc9105c7ab2200d17636a8
    Change-Id: I7df59fef0c1e90043b1899c5a95973e23afac0c5
    Signed-off-by: Satya Tangirala
    Link: https://patchwork.kernel.org/patch/11214731/

    Satya Tangirala