Add support for AES-XTS-128, AES-CBC-128 and AES-CBS-256 modes for inline encryption. Since ICE (Inline Crypto Engine) supports these all modes Co-developed-by: Vignesh Viswanathan <quic_viswanat@xxxxxxxxxxx> Signed-off-by: Vignesh Viswanathan <quic_viswanat@xxxxxxxxxxx> Signed-off-by: Md Sadre Alam <quic_mdalam@xxxxxxxxxxx> --- drivers/mmc/host/sdhci-msm.c | 10 ++---- drivers/soc/qcom/ice.c | 65 +++++++++++++++++++++++++++++++----- 2 files changed, 58 insertions(+), 17 deletions(-) diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index e113b99a3eab..fc1db58373ce 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -1867,17 +1867,11 @@ static int sdhci_msm_program_key(struct cqhci_host *cq_host, struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); union cqhci_crypto_cap_entry cap; - /* 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, + return qcom_ice_program_key(msm_host->ice, cap.algorithm_id, + cap.key_size, cfg->crypto_key, cfg->data_unit_size, slot); else return qcom_ice_evict_key(msm_host->ice, slot); diff --git a/drivers/soc/qcom/ice.c b/drivers/soc/qcom/ice.c index fbab7fe5c652..f387b884c516 100644 --- a/drivers/soc/qcom/ice.c +++ b/drivers/soc/qcom/ice.c @@ -19,6 +19,9 @@ #include <soc/qcom/ice.h> +#define AES_128_CBC_KEY_SIZE 16 +#define AES_256_CBC_KEY_SIZE 32 +#define AES_128_XTS_KEY_SIZE 32 #define AES_256_XTS_KEY_SIZE 64 /* QCOM ICE registers */ @@ -161,36 +164,80 @@ int qcom_ice_suspend(struct qcom_ice *ice) } EXPORT_SYMBOL_GPL(qcom_ice_suspend); +static int qcom_ice_get_algo_mode(struct qcom_ice *ice, u8 algorithm_id, + u8 key_size, enum qcom_scm_ice_cipher *cipher, + u32 *key_len) +{ + struct device *dev = ice->dev; + + switch (key_size) { + case QCOM_ICE_CRYPTO_KEY_SIZE_128: + fallthrough; + case QCOM_ICE_CRYPTO_KEY_SIZE_256: + break; + default: + dev_err(dev, "Unhandled crypto key size %d\n", key_size); + return -EINVAL; + } + + switch (algorithm_id) { + case QCOM_ICE_CRYPTO_ALG_AES_XTS: + if (key_size == QCOM_ICE_CRYPTO_KEY_SIZE_256) { + *cipher = QCOM_SCM_ICE_CIPHER_AES_256_XTS; + *key_len = AES_256_XTS_KEY_SIZE; + } else { + *cipher = QCOM_SCM_ICE_CIPHER_AES_128_XTS; + *key_len = AES_128_XTS_KEY_SIZE; + } + break; + case QCOM_ICE_CRYPTO_ALG_BITLOCKER_AES_CBC: + if (key_size == QCOM_ICE_CRYPTO_KEY_SIZE_256) { + *cipher = QCOM_SCM_ICE_CIPHER_AES_256_CBC; + *key_len = AES_256_CBC_KEY_SIZE; + } else { + *cipher = QCOM_SCM_ICE_CIPHER_AES_128_CBC; + *key_len = AES_128_CBC_KEY_SIZE; + } + break; + default: + dev_err_ratelimited(dev, "Unhandled crypto capability; algorithm_id=%d, key_size=%d\n", + algorithm_id, key_size); + return -EINVAL; + } + + dev_info(dev, "cipher: %d key_size: %d", *cipher, *key_len); + + return 0; +} + int qcom_ice_program_key(struct qcom_ice *ice, u8 algorithm_id, u8 key_size, const u8 crypto_key[], u8 data_unit_size, int slot) { struct device *dev = ice->dev; + enum qcom_scm_ice_cipher cipher; union { u8 bytes[AES_256_XTS_KEY_SIZE]; u32 words[AES_256_XTS_KEY_SIZE / sizeof(u32)]; } key; int i; int err; + u32 key_len; - /* 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) { - dev_err_ratelimited(dev, - "Unhandled crypto capability; algorithm_id=%d, key_size=%d\n", - algorithm_id, key_size); + if (qcom_ice_get_algo_mode(ice, algorithm_id, key_size, &cipher, &key_len)) { + dev_err(dev, "Unhandled crypto capability; algorithm_id=%d, key_size=%d\n", + algorithm_id, key_size); return -EINVAL; } - memcpy(key.bytes, crypto_key, AES_256_XTS_KEY_SIZE); + memcpy(key.bytes, crypto_key, key_len); /* 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, + err = qcom_scm_ice_set_key(slot, key.bytes, key_len, cipher, data_unit_size); memzero_explicit(&key, sizeof(key)); -- 2.34.1