[PATCH v2 3/3] mmc: sdhci-msm: Add additional algo mode for inline encryption

Md Sadre Alam posted 3 patches 2 months, 2 weeks ago
[PATCH v2 3/3] mmc: sdhci-msm: Add additional algo mode for inline encryption
Posted by Md Sadre Alam 2 months, 2 weeks ago
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

Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
---

Change in [v2]

* No change

Change in [v1]

* Added AES-XTS-128, AES-CBC-128, AES-CBS-256 algo mode support

 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 50be7a9274a1..da0c1dfa6594 100644
--- a/drivers/soc/qcom/ice.c
+++ b/drivers/soc/qcom/ice.c
@@ -20,6 +20,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 */
@@ -162,36 +165,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