diff --git a/drivers/mmc/host/cmdq_hci-crypto-qti.c b/drivers/mmc/host/cmdq_hci-crypto-qti.c index 9921a14c9cef..5617388475b9 100644 --- a/drivers/mmc/host/cmdq_hci-crypto-qti.c +++ b/drivers/mmc/host/cmdq_hci-crypto-qti.c @@ -131,19 +131,9 @@ static int cmdq_crypto_qti_derive_raw_secret(struct keyslot_manager *ksm, { int err = 0; - if (wrapped_key_size <= RAW_SECRET_SIZE) { - pr_err("%s: Invalid wrapped_key_size: %u\n", __func__, - wrapped_key_size); - err = -EINVAL; - return err; - } - if (secret_size != RAW_SECRET_SIZE) { - pr_err("%s: Invalid secret size: %u\n", __func__, secret_size); - err = -EINVAL; - return err; - } - memcpy(secret, wrapped_key, secret_size); - return 0; + err = crypto_qti_derive_raw_secret(wrapped_key, wrapped_key_size, + secret, secret_size); + return err; } static const struct keyslot_mgmt_ll_ops cmdq_crypto_qti_ksm_ops = { diff --git a/drivers/soc/qcom/crypto-qti-common.c b/drivers/soc/qcom/crypto-qti-common.c index cd2eaef78a10..e1be604e5d15 100644 --- a/drivers/soc/qcom/crypto-qti-common.c +++ b/drivers/soc/qcom/crypto-qti-common.c @@ -461,7 +461,11 @@ int crypto_qti_derive_raw_secret(const u8 *wrapped_key, return err; } - memcpy(secret, wrapped_key, secret_size); + if (wrapped_key_size > 64) + err = crypto_qti_tz_raw_secret(wrapped_key, wrapped_key_size, + secret, secret_size); + else + memcpy(secret, wrapped_key, secret_size); return err; } diff --git a/drivers/soc/qcom/crypto-qti-platform.h b/drivers/soc/qcom/crypto-qti-platform.h index a37e34895ee7..9c1167dccfe5 100644 --- a/drivers/soc/qcom/crypto-qti-platform.h +++ b/drivers/soc/qcom/crypto-qti-platform.h @@ -24,6 +24,9 @@ int crypto_qti_program_key(struct crypto_vops_qti_entry *ice_entry, unsigned int data_unit_mask, int capid); int crypto_qti_invalidate_key(struct crypto_vops_qti_entry *ice_entry, unsigned int slot); +int crypto_qti_tz_raw_secret(const u8 *wrapped_key, + unsigned int wrapped_key_size, u8 *secret, + unsigned int secret_size); #else static inline int crypto_qti_program_key( struct crypto_vops_qti_entry *ice_entry, @@ -38,6 +41,12 @@ static inline int crypto_qti_invalidate_key( { return 0; } +static int crypto_qti_tz_raw_secret(u8 *wrapped_key, + unsigned int wrapped_key_size, u8 *secret, + unsigned int secret_size) +{ + return 0; +} #endif /* CONFIG_QTI_CRYPTO_TZ */ static inline void crypto_qti_disable_platform( diff --git a/drivers/soc/qcom/crypto-qti-tz.c b/drivers/soc/qcom/crypto-qti-tz.c index 0ebdd1a1c9f8..50286a6fe141 100644 --- a/drivers/soc/qcom/crypto-qti-tz.c +++ b/drivers/soc/qcom/crypto-qti-tz.c @@ -25,6 +25,7 @@ unsigned int storage_type = SDCC_CE; #define ICE_BUFFER_SIZE 128 static uint8_t ice_buffer[ICE_BUFFER_SIZE]; +static uint8_t secret_buffer[32]; int crypto_qti_program_key(struct crypto_vops_qti_entry *ice_entry, const struct blk_crypto_key *key, @@ -56,7 +57,7 @@ int crypto_qti_program_key(struct crypto_vops_qti_entry *ice_entry, desc.arginfo = TZ_ES_CONFIG_SET_ICE_KEY_PARAM_ID; desc.args[0] = slot; desc.args[1] = virt_to_phys(tzbuf); - desc.args[2] = ICE_BUFFER_SIZE; + desc.args[2] = key->size; desc.args[3] = ICE_CIPHER_MODE_XTS_256; desc.args[4] = data_unit_mask; @@ -87,6 +88,43 @@ int crypto_qti_invalidate_key( return err; } +int crypto_qti_tz_raw_secret(const u8 *wrapped_key, + unsigned int wrapped_key_size, u8 *secret, + unsigned int secret_size) +{ + int err = 0; + uint32_t smc_id = 0; + + struct scm_desc desc = {0}; + char *tzbuf_key, *secret_key; + + tzbuf_key = ice_buffer; + secret_key = secret_buffer; + memcpy(tzbuf_key, wrapped_key, wrapped_key_size); + dmac_flush_range(tzbuf_key, tzbuf_key + wrapped_key_size); + + smc_id = TZ_ES_RETRIEVE_RAW_SECRET_CE_TYPE_ID; + desc.arginfo = TZ_ES_RETRIEVE_RAW_SECRET_CE_TYPE_PARAM_ID; + desc.args[0] = virt_to_phys(tzbuf_key); + desc.args[1] = wrapped_key_size; + desc.args[2] = virt_to_phys(secret_key); + desc.args[3] = secret_size; + + memset(secret_key, 0, secret_size); + dmac_flush_range(secret_key, secret_key + secret_size); + + err = scm_call2_noretry(smc_id, &desc); + if (err) { + pr_err("%s failed to retrieve raw secret\n", __func__, err); + return err; + } + + dmac_inv_range(secret_key, secret_key + secret_size); + memcpy(secret, secret_key, secret_size); + + return err; +} + static int crypto_qti_storage_type(unsigned int *s_type) { char boot[20] = {'\0'}; diff --git a/drivers/soc/qcom/crypto-qti-tz.h b/drivers/soc/qcom/crypto-qti-tz.h index bcb946096072..82c638092c36 100644 --- a/drivers/soc/qcom/crypto-qti-tz.h +++ b/drivers/soc/qcom/crypto-qti-tz.h @@ -19,6 +19,7 @@ #define TZ_ES_CONFIG_SET_ICE_KEY 0x4 #define TZ_ES_CONFIG_SET_ICE_KEY_CE_TYPE 0x5 #define TZ_ES_INVALIDATE_ICE_KEY_CE_TYPE 0x6 +#define TZ_ES_RETRIEVE_RAW_SECRET_CE_TYPE 0x7 #define TZ_ES_CONFIG_SET_ICE_KEY_CE_TYPE_ID \ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, TZ_SVC_ES, \ @@ -32,6 +33,10 @@ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, \ TZ_SVC_ES, TZ_ES_INVALIDATE_ICE_KEY_CE_TYPE) +#define TZ_ES_RETRIEVE_RAW_SECRET_CE_TYPE_ID \ + TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, \ + TZ_SVC_ES, TZ_ES_RETRIEVE_RAW_SECRET_CE_TYPE) + #define TZ_ES_INVALIDATE_ICE_KEY_ID \ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, \ TZ_SVC_ES, TZ_ES_INVALIDATE_ICE_KEY) @@ -57,6 +62,11 @@ TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL, \ TZ_SYSCALL_PARAM_TYPE_VAL) +#define TZ_ES_RETRIEVE_RAW_SECRET_CE_TYPE_PARAM_ID \ + TZ_SYSCALL_CREATE_PARAM_ID_4( \ + TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL, \ + TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL) + enum { ICE_CIPHER_MODE_XTS_128 = 0, ICE_CIPHER_MODE_CBC_128 = 1,