mbox series

[v10,00/15] Support for hardware-wrapped inline encryption keys

Message ID 20241213041958.202565-1-ebiggers@kernel.org
Headers show
Series Support for hardware-wrapped inline encryption keys | expand

Message

Eric Biggers Dec. 13, 2024, 4:19 a.m. UTC
This patchset is based on next-20241212 and is also available in git via:

    git fetch https://git.kernel.org/pub/scm/fs/fscrypt/linux.git wrapped-keys-v10

This patchset adds support for hardware-wrapped inline encryption keys, a
security feature supported by some SoCs.  It adds the block and fscrypt
framework for the feature as well as support for it with UFS on Qualcomm SoCs.

This feature is described in full detail in the included Documentation changes.
But to summarize, hardware-wrapped keys are inline encryption keys that are
wrapped (encrypted) by a key internal to the hardware so that they can only be
unwrapped (decrypted) by the hardware.  Initially keys are wrapped with a
permanent hardware key, but during actual use they are re-wrapped with a
per-boot ephemeral key for improved security.  The hardware supports importing
keys as well as generating keys itself.

This differs from the existing support for hardware-wrapped keys in the kernel
crypto API (also called "hardware-bound keys" in some places) in the same way
that the crypto API differs from blk-crypto: the crypto API is for general
crypto operations, whereas blk-crypto is for inline storage encryption.

This feature is already being used by Android downstream for several years
(https://source.android.com/docs/security/features/encryption/hw-wrapped-keys),
but on other platforms userspace support will be provided via fscryptctl and
tests via xfstests (I have some old patches for this that need to be updated).

Maintainers, please consider merging the following preparatory patches for 6.14:

  - UFS / SCSI tree: patches 1-4
  - MMC tree: patches 5-7
  - Qualcomm / MSM tree: patch 8

Changed in v10:
  - Fixed bugs in qcom_scm_derive_sw_secret() and cqhci_crypto_init().
  - Added "ufs: qcom: fix crypto key eviction" and
    "mmc: sdhci-msm: fix crypto key eviction".
  - Split removing ufs_hba_variant_ops::program_key into its own patch.
  - Minor cleanups.
  - Added Tested-by.

Changed in v9 (relative to v7 patchset from Bartosz Golaszewski):
  - ufs-qcom and sdhci-msm now just initialize the blk_crypto_profile
    themselves, like what ufs-exynos was doing.  This avoids needing to add all
    the host-specific hooks for wrapped key support to the MMC and UFS core
    drivers.
  - When passing the blk_crypto_key further down the stack, it now replaces
    parameters like the algorithm ID, to avoid creating two sources of truth.
  - The module parameter qcom_ice.use_wrapped_keys should work correctly now.
  - The fscrypt support no longer uses a policy flag to indicate when a file is
    protected by a HW-wrapped key, since it was already implied by the file's
    key identifier being that of a HW-wrapped key.  Originally there was an
    issue where raw and HW-wrapped keys could share key identifiers, but I had
    fixed that earlier by introducing a new HKDF context byte.
  - The term "standard keys" is no longer used.  Now "raw keys" is consistently
    used instead.  I've found that people find the term "raw keys" to be more
    intuitive.  Also HW-wrapped keys could in principle be standardized.
  - I've reordered the patchset to place preparatory patches that don't depend
    on the actual HW-wrapped key support first.

For older changelogs, see
https://lore.kernel.org/r/20241202-wrapped-keys-v7-0-67c3ca3f3282@linaro.org and
https://lore.kernel.org/r/20231104211259.17448-1-ebiggers@kernel.org

Eric Biggers (13):
  ufs: qcom: fix crypto key eviction
  ufs: crypto: add ufs_hba_from_crypto_profile()
  ufs: qcom: convert to use UFSHCD_QUIRK_CUSTOM_CRYPTO_PROFILE
  ufs: crypto: remove ufs_hba_variant_ops::program_key
  mmc: sdhci-msm: fix crypto key eviction
  mmc: crypto: add mmc_from_crypto_profile()
  mmc: sdhci-msm: convert to use custom crypto profile
  soc: qcom: ice: make qcom_ice_program_key() take struct blk_crypto_key
  blk-crypto: add basic hardware-wrapped key support
  blk-crypto: show supported key types in sysfs
  blk-crypto: add ioctls to create and prepare hardware-wrapped keys
  fscrypt: add support for hardware-wrapped keys
  ufs: qcom: add support for wrapped keys

Gaurav Kashyap (2):
  firmware: qcom: scm: add calls for wrapped key support
  soc: qcom: ice: add HWKM support to the ICE driver

 Documentation/ABI/stable/sysfs-block          |  18 +
 Documentation/block/inline-encryption.rst     | 251 +++++++++++-
 Documentation/filesystems/fscrypt.rst         | 201 +++++++--
 .../userspace-api/ioctl/ioctl-number.rst      |   2 +
 block/blk-crypto-fallback.c                   |   7 +-
 block/blk-crypto-internal.h                   |  10 +
 block/blk-crypto-profile.c                    | 103 +++++
 block/blk-crypto-sysfs.c                      |  35 ++
 block/blk-crypto.c                            | 196 ++++++++-
 block/ioctl.c                                 |   5 +
 drivers/firmware/qcom/qcom_scm.c              | 214 ++++++++++
 drivers/firmware/qcom/qcom_scm.h              |   4 +
 drivers/md/dm-table.c                         |   1 +
 drivers/mmc/host/cqhci-crypto.c               |  46 +--
 drivers/mmc/host/cqhci.h                      |   8 +-
 drivers/mmc/host/sdhci-msm.c                  | 101 +++--
 drivers/soc/qcom/ice.c                        | 383 +++++++++++++++++-
 drivers/ufs/core/ufshcd-crypto.c              |  33 +-
 drivers/ufs/host/ufs-exynos.c                 |   3 +-
 drivers/ufs/host/ufs-qcom.c                   | 136 +++++--
 fs/crypto/fscrypt_private.h                   |  75 +++-
 fs/crypto/hkdf.c                              |   4 +-
 fs/crypto/inline_crypt.c                      |  42 +-
 fs/crypto/keyring.c                           | 157 +++++--
 fs/crypto/keysetup.c                          |  63 ++-
 fs/crypto/keysetup_v1.c                       |   4 +-
 include/linux/blk-crypto-profile.h            |  73 ++++
 include/linux/blk-crypto.h                    |  73 +++-
 include/linux/firmware/qcom/qcom_scm.h        |   8 +
 include/linux/mmc/host.h                      |   8 +
 include/soc/qcom/ice.h                        |  34 +-
 include/uapi/linux/blk-crypto.h               |  44 ++
 include/uapi/linux/fs.h                       |   6 +-
 include/uapi/linux/fscrypt.h                  |   7 +-
 include/ufs/ufshcd.h                          |  11 +-
 35 files changed, 2092 insertions(+), 274 deletions(-)
 create mode 100644 include/uapi/linux/blk-crypto.h


base-commit: 3e42dc9229c5950e84b1ed705f94ed75ed208228

Comments

Ulf Hansson Dec. 19, 2024, 1:48 p.m. UTC | #1
On Fri, 13 Dec 2024 at 05:20, Eric Biggers <ebiggers@kernel.org> wrote:
>
> From: Eric Biggers <ebiggers@google.com>
>
> Commit c7eed31e235c ("mmc: sdhci-msm: Switch to the new ICE API")
> introduced an incorrect check of the algorithm ID into the key eviction
> path, and thus qcom_ice_evict_key() is no longer ever called.  Fix it.
>
> Fixes: c7eed31e235c ("mmc: sdhci-msm: Switch to the new ICE API")
> Cc: stable@vger.kernel.org
> Cc: Abel Vesa <abel.vesa@linaro.org>
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Applied for fixes, thanks!

Kind regards
Uffe


> ---
>  drivers/mmc/host/sdhci-msm.c | 16 ++++++++--------
>  1 file changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
> index e00208535bd1..319f0ebbe652 100644
> --- a/drivers/mmc/host/sdhci-msm.c
> +++ b/drivers/mmc/host/sdhci-msm.c
> @@ -1865,24 +1865,24 @@ static int sdhci_msm_program_key(struct cqhci_host *cq_host,
>         struct sdhci_host *host = mmc_priv(cq_host->mmc);
>         struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>         struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
>         union cqhci_crypto_cap_entry cap;
>
> +       if (!(cfg->config_enable & CQHCI_CRYPTO_CONFIGURATION_ENABLE))
> +               return qcom_ice_evict_key(msm_host->ice, slot);
> +
>         /* Only AES-256-XTS has been tested so far. */
>         cap = cq_host->crypto_cap_array[cfg->crypto_cap_idx];
>         if (cap.algorithm_id != CQHCI_CRYPTO_ALG_AES_XTS ||
>                 cap.key_size != CQHCI_CRYPTO_KEY_SIZE_256)
>                 return -EINVAL;
>
> -       if (cfg->config_enable & CQHCI_CRYPTO_CONFIGURATION_ENABLE)
> -               return qcom_ice_program_key(msm_host->ice,
> -                                           QCOM_ICE_CRYPTO_ALG_AES_XTS,
> -                                           QCOM_ICE_CRYPTO_KEY_SIZE_256,
> -                                           cfg->crypto_key,
> -                                           cfg->data_unit_size, slot);
> -       else
> -               return qcom_ice_evict_key(msm_host->ice, slot);
> +       return qcom_ice_program_key(msm_host->ice,
> +                                   QCOM_ICE_CRYPTO_ALG_AES_XTS,
> +                                   QCOM_ICE_CRYPTO_KEY_SIZE_256,
> +                                   cfg->crypto_key,
> +                                   cfg->data_unit_size, slot);
>  }
>
>  #else /* CONFIG_MMC_CRYPTO */
>
>  static inline int sdhci_msm_ice_init(struct sdhci_msm_host *msm_host,
> --
> 2.47.1
>
Ulf Hansson Dec. 19, 2024, 1:48 p.m. UTC | #2
On Fri, 13 Dec 2024 at 05:20, Eric Biggers <ebiggers@kernel.org> wrote:
>
> From: Eric Biggers <ebiggers@google.com>
>
> As is being done in ufs-qcom, make the sdhci-msm driver override the
> full crypto profile rather than "just" key programming and eviction.
> This makes it much more straightforward to add support for
> hardware-wrapped inline encryption keys.  It also makes it easy to pass
> the original blk_crypto_key down to qcom_ice_program_key() once it is
> updated to require the key in that form.
>
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Applied for next, thanks!

Kind regards
Uffe


> ---
>  drivers/mmc/host/cqhci-crypto.c | 33 ++++++------
>  drivers/mmc/host/cqhci.h        |  8 ++-
>  drivers/mmc/host/sdhci-msm.c    | 94 ++++++++++++++++++++++++++-------
>  3 files changed, 94 insertions(+), 41 deletions(-)
>
> diff --git a/drivers/mmc/host/cqhci-crypto.c b/drivers/mmc/host/cqhci-crypto.c
> index 2951911d3f78..cb8044093402 100644
> --- a/drivers/mmc/host/cqhci-crypto.c
> +++ b/drivers/mmc/host/cqhci-crypto.c
> @@ -26,20 +26,17 @@ static inline struct cqhci_host *
>  cqhci_host_from_crypto_profile(struct blk_crypto_profile *profile)
>  {
>         return mmc_from_crypto_profile(profile)->cqe_private;
>  }
>
> -static int cqhci_crypto_program_key(struct cqhci_host *cq_host,
> -                                   const union cqhci_crypto_cfg_entry *cfg,
> -                                   int slot)
> +static void cqhci_crypto_program_key(struct cqhci_host *cq_host,
> +                                    const union cqhci_crypto_cfg_entry *cfg,
> +                                    int slot)
>  {
>         u32 slot_offset = cq_host->crypto_cfg_register + slot * sizeof(*cfg);
>         int i;
>
> -       if (cq_host->ops->program_key)
> -               return cq_host->ops->program_key(cq_host, cfg, slot);
> -
>         /* Clear CFGE */
>         cqhci_writel(cq_host, 0, slot_offset + 16 * sizeof(cfg->reg_val[0]));
>
>         /* Write the key */
>         for (i = 0; i < 16; i++) {
> @@ -50,11 +47,10 @@ static int cqhci_crypto_program_key(struct cqhci_host *cq_host,
>         cqhci_writel(cq_host, le32_to_cpu(cfg->reg_val[17]),
>                      slot_offset + 17 * sizeof(cfg->reg_val[0]));
>         /* Write dword 16, which includes the new value of CFGE */
>         cqhci_writel(cq_host, le32_to_cpu(cfg->reg_val[16]),
>                      slot_offset + 16 * sizeof(cfg->reg_val[0]));
> -       return 0;
>  }
>
>  static int cqhci_crypto_keyslot_program(struct blk_crypto_profile *profile,
>                                         const struct blk_crypto_key *key,
>                                         unsigned int slot)
> @@ -67,11 +63,10 @@ static int cqhci_crypto_keyslot_program(struct blk_crypto_profile *profile,
>                         &cqhci_crypto_algs[key->crypto_cfg.crypto_mode];
>         u8 data_unit_mask = key->crypto_cfg.data_unit_size / 512;
>         int i;
>         int cap_idx = -1;
>         union cqhci_crypto_cfg_entry cfg = {};
> -       int err;
>
>         BUILD_BUG_ON(CQHCI_CRYPTO_KEY_SIZE_INVALID != 0);
>         for (i = 0; i < cq_host->crypto_capabilities.num_crypto_cap; i++) {
>                 if (ccap_array[i].algorithm_id == alg->alg &&
>                     ccap_array[i].key_size == alg->key_size &&
> @@ -94,25 +89,26 @@ static int cqhci_crypto_keyslot_program(struct blk_crypto_profile *profile,
>                        key->raw + key->size/2, key->size/2);
>         } else {
>                 memcpy(cfg.crypto_key, key->raw, key->size);
>         }
>
> -       err = cqhci_crypto_program_key(cq_host, &cfg, slot);
> +       cqhci_crypto_program_key(cq_host, &cfg, slot);
>
>         memzero_explicit(&cfg, sizeof(cfg));
> -       return err;
> +       return 0;
>  }
>
>  static int cqhci_crypto_clear_keyslot(struct cqhci_host *cq_host, int slot)
>  {
>         /*
>          * Clear the crypto cfg on the device. Clearing CFGE
>          * might not be sufficient, so just clear the entire cfg.
>          */
>         union cqhci_crypto_cfg_entry cfg = {};
>
> -       return cqhci_crypto_program_key(cq_host, &cfg, slot);
> +       cqhci_crypto_program_key(cq_host, &cfg, slot);
> +       return 0;
>  }
>
>  static int cqhci_crypto_keyslot_evict(struct blk_crypto_profile *profile,
>                                       const struct blk_crypto_key *key,
>                                       unsigned int slot)
> @@ -165,20 +161,22 @@ cqhci_find_blk_crypto_mode(union cqhci_crypto_cap_entry cap)
>  int cqhci_crypto_init(struct cqhci_host *cq_host)
>  {
>         struct mmc_host *mmc = cq_host->mmc;
>         struct device *dev = mmc_dev(mmc);
>         struct blk_crypto_profile *profile = &mmc->crypto_profile;
> -       unsigned int num_keyslots;
>         unsigned int cap_idx;
>         enum blk_crypto_mode_num blk_mode_num;
>         unsigned int slot;
>         int err = 0;
>
>         if (!(mmc->caps2 & MMC_CAP2_CRYPTO) ||
>             !(cqhci_readl(cq_host, CQHCI_CAP) & CQHCI_CAP_CS))
>                 goto out;
>
> +       if (cq_host->ops->uses_custom_crypto_profile)
> +               goto profile_initialized;
> +
>         cq_host->crypto_capabilities.reg_val =
>                         cpu_to_le32(cqhci_readl(cq_host, CQHCI_CCAP));
>
>         cq_host->crypto_cfg_register =
>                 (u32)cq_host->crypto_capabilities.config_array_ptr * 0x100;
> @@ -193,13 +191,12 @@ int cqhci_crypto_init(struct cqhci_host *cq_host)
>
>         /*
>          * CCAP.CFGC is off by one, so the actual number of crypto
>          * configurations (a.k.a. keyslots) is CCAP.CFGC + 1.
>          */
> -       num_keyslots = cq_host->crypto_capabilities.config_count + 1;
> -
> -       err = devm_blk_crypto_profile_init(dev, profile, num_keyslots);
> +       err = devm_blk_crypto_profile_init(
> +               dev, profile, cq_host->crypto_capabilities.config_count + 1);
>         if (err)
>                 goto out;
>
>         profile->ll_ops = cqhci_crypto_ops;
>         profile->dev = dev;
> @@ -223,13 +220,15 @@ int cqhci_crypto_init(struct cqhci_host *cq_host)
>                         continue;
>                 profile->modes_supported[blk_mode_num] |=
>                         cq_host->crypto_cap_array[cap_idx].sdus_mask * 512;
>         }
>
> +profile_initialized:
> +
>         /* Clear all the keyslots so that we start in a known state. */
> -       for (slot = 0; slot < num_keyslots; slot++)
> -               cqhci_crypto_clear_keyslot(cq_host, slot);
> +       for (slot = 0; slot < profile->num_slots; slot++)
> +               profile->ll_ops.keyslot_evict(profile, NULL, slot);
>
>         /* CQHCI crypto requires the use of 128-bit task descriptors. */
>         cq_host->caps |= CQHCI_TASK_DESC_SZ_128;
>
>         return 0;
> diff --git a/drivers/mmc/host/cqhci.h b/drivers/mmc/host/cqhci.h
> index fab9d74445ba..ce189a1866b9 100644
> --- a/drivers/mmc/host/cqhci.h
> +++ b/drivers/mmc/host/cqhci.h
> @@ -287,17 +287,15 @@ struct cqhci_host_ops {
>         void (*disable)(struct mmc_host *mmc, bool recovery);
>         void (*update_dcmd_desc)(struct mmc_host *mmc, struct mmc_request *mrq,
>                                  u64 *data);
>         void (*pre_enable)(struct mmc_host *mmc);
>         void (*post_disable)(struct mmc_host *mmc);
> -#ifdef CONFIG_MMC_CRYPTO
> -       int (*program_key)(struct cqhci_host *cq_host,
> -                          const union cqhci_crypto_cfg_entry *cfg, int slot);
> -#endif
>         void (*set_tran_desc)(struct cqhci_host *cq_host, u8 **desc,
>                               dma_addr_t addr, int len, bool end, bool dma64);
> -
> +#ifdef CONFIG_MMC_CRYPTO
> +       bool uses_custom_crypto_profile;
> +#endif
>  };
>
>  static inline void cqhci_writel(struct cqhci_host *host, u32 val, int reg)
>  {
>         if (unlikely(host->ops->write_l))
> diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
> index 319f0ebbe652..4610f067faca 100644
> --- a/drivers/mmc/host/sdhci-msm.c
> +++ b/drivers/mmc/host/sdhci-msm.c
> @@ -1805,16 +1805,23 @@ static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock)
>   *                                                                           *
>  \*****************************************************************************/
>
>  #ifdef CONFIG_MMC_CRYPTO
>
> +static const struct blk_crypto_ll_ops sdhci_msm_crypto_ops; /* forward decl */
> +
>  static int sdhci_msm_ice_init(struct sdhci_msm_host *msm_host,
>                               struct cqhci_host *cq_host)
>  {
>         struct mmc_host *mmc = msm_host->mmc;
> +       struct blk_crypto_profile *profile = &mmc->crypto_profile;
>         struct device *dev = mmc_dev(mmc);
>         struct qcom_ice *ice;
> +       union cqhci_crypto_capabilities caps;
> +       union cqhci_crypto_cap_entry cap;
> +       int err;
> +       int i;
>
>         if (!(cqhci_readl(cq_host, CQHCI_CAP) & CQHCI_CAP_CS))
>                 return 0;
>
>         ice = of_qcom_ice_get(dev);
> @@ -1825,12 +1832,41 @@ static int sdhci_msm_ice_init(struct sdhci_msm_host *msm_host,
>
>         if (IS_ERR_OR_NULL(ice))
>                 return PTR_ERR_OR_ZERO(ice);
>
>         msm_host->ice = ice;
> -       mmc->caps2 |= MMC_CAP2_CRYPTO;
>
> +       /* Initialize the blk_crypto_profile */
> +
> +       caps.reg_val = cpu_to_le32(cqhci_readl(cq_host, CQHCI_CCAP));
> +
> +       /* The number of keyslots supported is (CFGC+1) */
> +       err = devm_blk_crypto_profile_init(dev, profile, caps.config_count + 1);
> +       if (err)
> +               return err;
> +
> +       profile->ll_ops = sdhci_msm_crypto_ops;
> +       profile->max_dun_bytes_supported = 4;
> +       profile->dev = dev;
> +
> +       /*
> +        * Currently this driver only supports AES-256-XTS.  All known versions
> +        * of ICE support it, but to be safe make sure it is really declared in
> +        * the crypto capability registers.  The crypto capability registers
> +        * also give the supported data unit size(s).
> +        */
> +       for (i = 0; i < caps.num_crypto_cap; i++) {
> +               cap.reg_val = cpu_to_le32(cqhci_readl(cq_host,
> +                                                     CQHCI_CRYPTOCAP +
> +                                                     i * sizeof(__le32)));
> +               if (cap.algorithm_id == CQHCI_CRYPTO_ALG_AES_XTS &&
> +                   cap.key_size == CQHCI_CRYPTO_KEY_SIZE_256)
> +                       profile->modes_supported[BLK_ENCRYPTION_MODE_AES_256_XTS] |=
> +                               cap.sdus_mask * 512;
> +       }
> +
> +       mmc->caps2 |= MMC_CAP2_CRYPTO;
>         return 0;
>  }
>
>  static void sdhci_msm_ice_enable(struct sdhci_msm_host *msm_host)
>  {
> @@ -1852,39 +1888,59 @@ static __maybe_unused int sdhci_msm_ice_suspend(struct sdhci_msm_host *msm_host)
>                 return qcom_ice_suspend(msm_host->ice);
>
>         return 0;
>  }
>
> -/*
> - * Program a key into a QC ICE keyslot, or evict a keyslot.  QC ICE requires
> - * vendor-specific SCM calls for this; it doesn't support the standard way.
> - */
> -static int sdhci_msm_program_key(struct cqhci_host *cq_host,
> -                                const union cqhci_crypto_cfg_entry *cfg,
> -                                int slot)
> +static inline struct sdhci_msm_host *
> +sdhci_msm_host_from_crypto_profile(struct blk_crypto_profile *profile)
>  {
> -       struct sdhci_host *host = mmc_priv(cq_host->mmc);
> +       struct mmc_host *mmc = mmc_from_crypto_profile(profile);
> +       struct sdhci_host *host = mmc_priv(mmc);
>         struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>         struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
> -       union cqhci_crypto_cap_entry cap;
>
> -       if (!(cfg->config_enable & CQHCI_CRYPTO_CONFIGURATION_ENABLE))
> -               return qcom_ice_evict_key(msm_host->ice, slot);
> +       return msm_host;
> +}
> +
> +/*
> + * Program a key into a QC ICE keyslot.  QC ICE requires a QC-specific SCM call
> + * for this; it doesn't support the standard way.
> + */
> +static int sdhci_msm_ice_keyslot_program(struct blk_crypto_profile *profile,
> +                                        const struct blk_crypto_key *key,
> +                                        unsigned int slot)
> +{
> +       struct sdhci_msm_host *msm_host =
> +               sdhci_msm_host_from_crypto_profile(profile);
>
>         /* Only AES-256-XTS has been tested so far. */
> -       cap = cq_host->crypto_cap_array[cfg->crypto_cap_idx];
> -       if (cap.algorithm_id != CQHCI_CRYPTO_ALG_AES_XTS ||
> -               cap.key_size != CQHCI_CRYPTO_KEY_SIZE_256)
> -               return -EINVAL;
> +       if (key->crypto_cfg.crypto_mode != BLK_ENCRYPTION_MODE_AES_256_XTS)
> +               return -EOPNOTSUPP;
>
>         return qcom_ice_program_key(msm_host->ice,
>                                     QCOM_ICE_CRYPTO_ALG_AES_XTS,
>                                     QCOM_ICE_CRYPTO_KEY_SIZE_256,
> -                                   cfg->crypto_key,
> -                                   cfg->data_unit_size, slot);
> +                                   key->raw,
> +                                   key->crypto_cfg.data_unit_size / 512,
> +                                   slot);
>  }
>
> +static int sdhci_msm_ice_keyslot_evict(struct blk_crypto_profile *profile,
> +                                      const struct blk_crypto_key *key,
> +                                      unsigned int slot)
> +{
> +       struct sdhci_msm_host *msm_host =
> +               sdhci_msm_host_from_crypto_profile(profile);
> +
> +       return qcom_ice_evict_key(msm_host->ice, slot);
> +}
> +
> +static const struct blk_crypto_ll_ops sdhci_msm_crypto_ops = {
> +       .keyslot_program        = sdhci_msm_ice_keyslot_program,
> +       .keyslot_evict          = sdhci_msm_ice_keyslot_evict,
> +};
> +
>  #else /* CONFIG_MMC_CRYPTO */
>
>  static inline int sdhci_msm_ice_init(struct sdhci_msm_host *msm_host,
>                                      struct cqhci_host *cq_host)
>  {
> @@ -1986,11 +2042,11 @@ static void sdhci_msm_set_timeout(struct sdhci_host *host, struct mmc_command *c
>
>  static const struct cqhci_host_ops sdhci_msm_cqhci_ops = {
>         .enable         = sdhci_msm_cqe_enable,
>         .disable        = sdhci_msm_cqe_disable,
>  #ifdef CONFIG_MMC_CRYPTO
> -       .program_key    = sdhci_msm_program_key,
> +       .uses_custom_crypto_profile = true,
>  #endif
>  };
>
>  static int sdhci_msm_cqe_add_host(struct sdhci_host *host,
>                                 struct platform_device *pdev)
> --
> 2.47.1
>
Eric Biggers Jan. 2, 2025, 6:38 p.m. UTC | #3
On Thu, Dec 12, 2024 at 08:19:43PM -0800, Eric Biggers wrote:
> Maintainers, please consider merging the following preparatory patches for 6.14:
> 
>   - UFS / SCSI tree: patches 1-4
>   - MMC tree: patches 5-7
>   - Qualcomm / MSM tree: patch 8

Happy new year everyone.

We are 1 of 3 so far, with Ulf having applied patches 5-7.

Martin, can you consider applying patches 1-4?

Bjorn, can you consider applying patch 8?

Additional reviews or acks from anyone on any of the patches in this series
would always be appreciated, of course.

Thank you!

- Eric
Martin K. Petersen Jan. 2, 2025, 6:40 p.m. UTC | #4
Eric,

> This patchset adds support for hardware-wrapped inline encryption
> keys, a security feature supported by some SoCs. It adds the block and
> fscrypt framework for the feature as well as support for it with UFS
> on Qualcomm SoCs.

Applied patches 1-4 to 6.14/scsi-staging, thanks!

I had originally queued patch 1 in 6.13/scsi-fixes but moved it to 6.14
and kept the stable tag to accommodate the rest of the series. Hope
that's OK given the short runway we have left for this release.
Eric Biggers Jan. 2, 2025, 6:44 p.m. UTC | #5
On Thu, Jan 02, 2025 at 01:40:48PM -0500, Martin K. Petersen wrote:
> 
> Eric,
> 
> > This patchset adds support for hardware-wrapped inline encryption
> > keys, a security feature supported by some SoCs. It adds the block and
> > fscrypt framework for the feature as well as support for it with UFS
> > on Qualcomm SoCs.
> 
> Applied patches 1-4 to 6.14/scsi-staging, thanks!
> 
> I had originally queued patch 1 in 6.13/scsi-fixes but moved it to 6.14
> and kept the stable tag to accommodate the rest of the series. Hope
> that's OK given the short runway we have left for this release.

Yes, that's fine.  Thanks.

- Eric
Bjorn Andersson Jan. 9, 2025, 6:27 p.m. UTC | #6
On Thu, 12 Dec 2024 20:19:43 -0800, Eric Biggers wrote:
> This patchset is based on next-20241212 and is also available in git via:
> 
>     git fetch https://git.kernel.org/pub/scm/fs/fscrypt/linux.git wrapped-keys-v10
> 
> This patchset adds support for hardware-wrapped inline encryption keys, a
> security feature supported by some SoCs.  It adds the block and fscrypt
> framework for the feature as well as support for it with UFS on Qualcomm SoCs.
> 
> [...]

Applied, thanks!

[08/15] firmware: qcom: scm: add calls for wrapped key support
        commit: 1d45a1cd9f3ae849db868e07e5fee5e5b37eff55

Best regards,
Bartosz Golaszewski Jan. 10, 2025, 8:44 a.m. UTC | #7
On Fri, Dec 13, 2024 at 5:20 AM Eric Biggers <ebiggers@kernel.org> wrote:
>
> This patchset is based on next-20241212 and is also available in git via:
>
>     git fetch https://git.kernel.org/pub/scm/fs/fscrypt/linux.git wrapped-keys-v10
>
> This patchset adds support for hardware-wrapped inline encryption keys, a
> security feature supported by some SoCs.  It adds the block and fscrypt
> framework for the feature as well as support for it with UFS on Qualcomm SoCs.
>
> This feature is described in full detail in the included Documentation changes.
> But to summarize, hardware-wrapped keys are inline encryption keys that are
> wrapped (encrypted) by a key internal to the hardware so that they can only be
> unwrapped (decrypted) by the hardware.  Initially keys are wrapped with a
> permanent hardware key, but during actual use they are re-wrapped with a
> per-boot ephemeral key for improved security.  The hardware supports importing
> keys as well as generating keys itself.
>
> This differs from the existing support for hardware-wrapped keys in the kernel
> crypto API (also called "hardware-bound keys" in some places) in the same way
> that the crypto API differs from blk-crypto: the crypto API is for general
> crypto operations, whereas blk-crypto is for inline storage encryption.
>
> This feature is already being used by Android downstream for several years
> (https://source.android.com/docs/security/features/encryption/hw-wrapped-keys),
> but on other platforms userspace support will be provided via fscryptctl and
> tests via xfstests (I have some old patches for this that need to be updated).
>
> Maintainers, please consider merging the following preparatory patches for 6.14:
>
>   - UFS / SCSI tree: patches 1-4
>   - MMC tree: patches 5-7
>   - Qualcomm / MSM tree: patch 8
>

IIUC The following patches will have to wait for the v6.15 cycle?

[PATCH v10 9/15] soc: qcom: ice: make qcom_ice_program_key() take
struct blk_crypto_key
[PATCH v10 10/15] blk-crypto: add basic hardware-wrapped key support
[PATCH v10 11/15] blk-crypto: show supported key types in sysfs
[PATCH v10 12/15] blk-crypto: add ioctls to create and prepare
hardware-wrapped keys
[PATCH v10 13/15] fscrypt: add support for hardware-wrapped keys
[PATCH v10 14/15] soc: qcom: ice: add HWKM support to the ICE driver
[PATCH v10 15/15] ufs: qcom: add support for wrapped keys

Bartosz
Eric Biggers Jan. 10, 2025, 7:10 p.m. UTC | #8
On Fri, Jan 10, 2025 at 09:44:07AM +0100, Bartosz Golaszewski wrote:
> On Fri, Dec 13, 2024 at 5:20 AM Eric Biggers <ebiggers@kernel.org> wrote:
> >
> > This patchset is based on next-20241212 and is also available in git via:
> >
> >     git fetch https://git.kernel.org/pub/scm/fs/fscrypt/linux.git wrapped-keys-v10
> >
> > This patchset adds support for hardware-wrapped inline encryption keys, a
> > security feature supported by some SoCs.  It adds the block and fscrypt
> > framework for the feature as well as support for it with UFS on Qualcomm SoCs.
> >
> > This feature is described in full detail in the included Documentation changes.
> > But to summarize, hardware-wrapped keys are inline encryption keys that are
> > wrapped (encrypted) by a key internal to the hardware so that they can only be
> > unwrapped (decrypted) by the hardware.  Initially keys are wrapped with a
> > permanent hardware key, but during actual use they are re-wrapped with a
> > per-boot ephemeral key for improved security.  The hardware supports importing
> > keys as well as generating keys itself.
> >
> > This differs from the existing support for hardware-wrapped keys in the kernel
> > crypto API (also called "hardware-bound keys" in some places) in the same way
> > that the crypto API differs from blk-crypto: the crypto API is for general
> > crypto operations, whereas blk-crypto is for inline storage encryption.
> >
> > This feature is already being used by Android downstream for several years
> > (https://source.android.com/docs/security/features/encryption/hw-wrapped-keys),
> > but on other platforms userspace support will be provided via fscryptctl and
> > tests via xfstests (I have some old patches for this that need to be updated).
> >
> > Maintainers, please consider merging the following preparatory patches for 6.14:
> >
> >   - UFS / SCSI tree: patches 1-4
> >   - MMC tree: patches 5-7
> >   - Qualcomm / MSM tree: patch 8
> >
> 
> IIUC The following patches will have to wait for the v6.15 cycle?
> 
> [PATCH v10 9/15] soc: qcom: ice: make qcom_ice_program_key() take
> struct blk_crypto_key
> [PATCH v10 10/15] blk-crypto: add basic hardware-wrapped key support
> [PATCH v10 11/15] blk-crypto: show supported key types in sysfs
> [PATCH v10 12/15] blk-crypto: add ioctls to create and prepare
> hardware-wrapped keys
> [PATCH v10 13/15] fscrypt: add support for hardware-wrapped keys
> [PATCH v10 14/15] soc: qcom: ice: add HWKM support to the ICE driver
> [PATCH v10 15/15] ufs: qcom: add support for wrapped keys

Yes, that's correct.

- Eric
Martin K. Petersen Jan. 10, 2025, 9:16 p.m. UTC | #9
On Thu, 12 Dec 2024 20:19:43 -0800, Eric Biggers wrote:

> This patchset is based on next-20241212 and is also available in git via:
> 
>     git fetch https://git.kernel.org/pub/scm/fs/fscrypt/linux.git wrapped-keys-v10
> 
> This patchset adds support for hardware-wrapped inline encryption keys, a
> security feature supported by some SoCs.  It adds the block and fscrypt
> framework for the feature as well as support for it with UFS on Qualcomm SoCs.
> 
> [...]

Applied to 6.14/scsi-queue, thanks!

[02/15] ufs: crypto: add ufs_hba_from_crypto_profile()
        https://git.kernel.org/mkp/scsi/c/75d0c649eca4
[03/15] ufs: qcom: convert to use UFSHCD_QUIRK_CUSTOM_CRYPTO_PROFILE
        https://git.kernel.org/mkp/scsi/c/30b32c647cf3
[04/15] ufs: crypto: remove ufs_hba_variant_ops::program_key
        https://git.kernel.org/mkp/scsi/c/409f21010d92