On Mon, Dec 02, 2024 at 01:02:26PM +0100, Bartosz Golaszewski wrote: > From: Gaurav Kashyap <quic_gaurkash@xxxxxxxxxxx> > > Now that HWKM support has been added to ICE, extend the ICE driver to > support hardware wrapped keys programming coming in from the storage > controllers (UFS and eMMC). This is similar to raw keys where the call is > forwarded to Trustzone, however we also need to clear and re-enable > CFGE before and after programming the key. > > Derive software secret support is also added by forwarding the call to > the corresponding SCM API. > > Wrapped keys are only used if the new module parameter is set AND the > architecture supports HWKM. > > Tested-by: Neil Armstrong <neil.armstrong@xxxxxxxxxx> > Reviewed-by: Om Prakash Singh <quic_omprsing@xxxxxxxxxxx> > Signed-off-by: Gaurav Kashyap <quic_gaurkash@xxxxxxxxxxx> > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@xxxxxxxxxx> > --- > drivers/soc/qcom/ice.c | 128 ++++++++++++++++++++++++++++++++++++++++++++----- > include/soc/qcom/ice.h | 4 ++ > 2 files changed, 121 insertions(+), 11 deletions(-) > > diff --git a/drivers/soc/qcom/ice.c b/drivers/soc/qcom/ice.c > index 5f138e278554c..e83e74e39e44f 100644 > --- a/drivers/soc/qcom/ice.c > +++ b/drivers/soc/qcom/ice.c > @@ -28,6 +28,8 @@ > #define QCOM_ICE_REG_BIST_STATUS 0x0070 > #define QCOM_ICE_REG_ADVANCED_CONTROL 0x1000 > #define QCOM_ICE_REG_CONTROL 0x0 > +#define QCOM_ICE_LUT_KEYS_CRYPTOCFG_R16 0x4040 > + > /* QCOM ICE HWKM registers */ > #define QCOM_ICE_REG_HWKM_TZ_KM_CTL 0x1000 > #define QCOM_ICE_REG_HWKM_TZ_KM_STATUS 0x1004 > @@ -62,6 +64,8 @@ > #define QCOM_ICE_HWKM_DISABLE_CRC_CHECKS_VAL (BIT(1) | BIT(2)) > #define QCOM_ICE_HWKM_RSP_FIFO_CLEAR_VAL BIT(3) > > +#define QCOM_ICE_HWKM_CFG_ENABLE_VAL BIT(7) > + > /* BIST ("built-in self-test") status flags */ > #define QCOM_ICE_BIST_STATUS_MASK GENMASK(31, 28) > > @@ -69,6 +73,8 @@ > #define QCOM_ICE_FORCE_HW_KEY0_SETTING_MASK 0x2 > #define QCOM_ICE_FORCE_HW_KEY1_SETTING_MASK 0x4 > > +#define QCOM_ICE_LUT_KEYS_CRYPTOCFG_OFFSET 0x80 > + > #define QCOM_ICE_HWKM_REG_OFFSET 0x8000 > #define HWKM_OFFSET(reg) ((reg) + QCOM_ICE_HWKM_REG_OFFSET) > > @@ -78,6 +84,15 @@ > #define qcom_ice_readl(engine, reg) \ > readl((engine)->base + (reg)) > > +#define QCOM_ICE_LUT_CRYPTOCFG_SLOT_OFFSET(slot) \ > + (QCOM_ICE_LUT_KEYS_CRYPTOCFG_R16 + \ > + QCOM_ICE_LUT_KEYS_CRYPTOCFG_OFFSET * slot) > + > +static bool ufs_qcom_use_wrapped_keys; > +module_param_named(use_wrapped_keys, ufs_qcom_use_wrapped_keys, bool, 0660); > +MODULE_PARM_DESC(use_wrapped_keys, > +"Use HWKM for wrapped keys support if available on the platform"); This should go into the previous patch and it should be handled in qcom_ice_check_supported() instead. > + > struct qcom_ice { > struct device *dev; > void __iomem *base; [...] > @@ -313,24 +378,40 @@ int qcom_ice_program_key(struct qcom_ice *ice, > > /* Only AES-256-XTS has been tested so far. */ > if (algorithm_id != QCOM_ICE_CRYPTO_ALG_AES_XTS || > - key_size != QCOM_ICE_CRYPTO_KEY_SIZE_256) { > + (key_size != QCOM_ICE_CRYPTO_KEY_SIZE_256 && > + key_size != QCOM_ICE_CRYPTO_KEY_SIZE_WRAPPED)) { > dev_err_ratelimited(dev, > "Unhandled crypto capability; algorithm_id=%d, key_size=%d\n", > algorithm_id, key_size); > return -EINVAL; > } > > - memcpy(key.bytes, bkey->raw, AES_256_XTS_KEY_SIZE); > + if (ufs_qcom_use_wrapped_keys && I think it's too late to have the check here. > + (bkey->crypto_cfg.key_type == BLK_CRYPTO_KEY_TYPE_HW_WRAPPED)) { > + /* It is expected that HWKM init has completed before programming wrapped keys */ > + if (!ice->use_hwkm || !ice->hwkm_init_complete) { > + dev_err_ratelimited(dev, "HWKM not currently used or initialized\n"); > + return -EINVAL; > + } > + err = qcom_ice_program_wrapped_key(ice, bkey, data_unit_size, > + slot); > + } else { > + if (bkey->size != QCOM_ICE_CRYPTO_KEY_SIZE_256) > + dev_err_ratelimited(dev, > + "Incorrect key size; bkey->size=%d\n", > + algorithm_id); > + return -EINVAL; > + memcpy(key.bytes, bkey->raw, AES_256_XTS_KEY_SIZE); > > - /* The SCM call requires that the key words are encoded in big endian */ > - for (i = 0; i < ARRAY_SIZE(key.words); i++) > - __cpu_to_be32s(&key.words[i]); > + /* The SCM call requires that the key words are encoded in big endian */ > + for (i = 0; i < ARRAY_SIZE(key.words); i++) > + __cpu_to_be32s(&key.words[i]); > > - err = qcom_scm_ice_set_key(slot, key.bytes, AES_256_XTS_KEY_SIZE, > - QCOM_SCM_ICE_CIPHER_AES_256_XTS, > - data_unit_size); > - > - memzero_explicit(&key, sizeof(key)); > + err = qcom_scm_ice_set_key(slot, key.bytes, AES_256_XTS_KEY_SIZE, > + QCOM_SCM_ICE_CIPHER_AES_256_XTS, > + data_unit_size); > + memzero_explicit(&key, sizeof(key)); > + } > > return err; > } -- With best wishes Dmitry