@@ -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);
@@ -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));