wlan-ap-Telecominfraproject/feeds/qca-wifi-7/ipq53xx/patches-6.1/0518-qcom-scm-Add-QWES-scm-call-support.patch
John Crispin 68cf54d9f7 qca-wifi-7: update to ath12.5.5
Signed-off-by: John Crispin <john@phrozen.org>
2025-02-27 12:45:52 +01:00

371 lines
13 KiB
Diff

From 29ab97ac89770b7cbd29b2a2af4bd505b9a5d4bd Mon Sep 17 00:00:00 2001
From: Riddhi Aggarwal <quic_riddagga@quicinc.com>
Date: Fri, 22 Sep 2023 13:45:16 +0530
Subject: [PATCH] qcom: scm: Add QWES scm call support
This change adds scm call support for Qwes ephimeral key generation,
get attestation response and get provision response from TZ.
Change-Id: I31a048f204d373e5e667520e62dc5fd10815b474
Signed-off-by: Poovendhan Selvaraj <quic_poovendh@quicinc.com>
---
drivers/firmware/qcom_scm.c | 266 ++++++++++++++++++++++++++++++++++++
drivers/firmware/qcom_scm.h | 18 +++
drivers/soc/qcom/Makefile | 1 +
include/linux/qcom_scm.h | 9 ++
4 files changed, 294 insertions(+)
diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c
index a51a8367eb47..0fae73f2ee39 100644
--- a/drivers/firmware/qcom_scm.c
+++ b/drivers/firmware/qcom_scm.c
@@ -1583,6 +1583,46 @@ int qti_seccrypt_clearkey(void)
}
EXPORT_SYMBOL(qti_seccrypt_clearkey);
+int qcom_scm_get_device_attestation_ephimeral_key(void *key_buf,
+ u32 key_buf_len, u32 *key_len)
+{
+ int ret;
+ ret = __qti_scm_get_device_attestation_ephimeral_key(__scm->dev,
+ key_buf, key_buf_len, key_len);
+ return ret;
+
+}
+EXPORT_SYMBOL(qcom_scm_get_device_attestation_ephimeral_key);
+
+int qcom_scm_get_device_attestation_response(void *req_buf,
+ u32 req_buf_len, void *extclaim_buf, u32 extclaim_buf_len,
+ void *resp_buf, u32 resp_buf_len, u32 *attest_resp_len)
+{
+ int ret;
+
+ ret = __qti_scm_get_device_attestation_response(__scm->dev, req_buf,
+ req_buf_len, extclaim_buf, extclaim_buf_len, resp_buf,
+ resp_buf_len, attest_resp_len);
+
+ return ret;
+
+}
+EXPORT_SYMBOL(qcom_scm_get_device_attestation_response);
+
+int qcom_scm_get_device_provision_response(void *provreq_buf,
+ u32 provreq_buf_len, void *provresp_buf, u32 provresp_buf_len,
+ u32 *prov_resp_size)
+{
+ int ret;
+
+ ret = __qti_scm_get_device_provision_response(__scm->dev, provreq_buf,
+ provreq_buf_len, provresp_buf, provresp_buf_len, prov_resp_size);
+
+ return ret;
+
+}
+EXPORT_SYMBOL(qcom_scm_get_device_provision_response);
+
int __qti_set_qcekey_sec(struct device *dev, void *confBuf, int size)
{
int ret;
@@ -1653,6 +1693,232 @@ int __qti_seccrypt_clearkey(struct device *dev)
return ret ? : res.result[0];
}
+/**
+* __qti_scm_get_device_attestation_ephimeral_key() - Get M3 public ephimeral key from TME-L
+*
+* key_buf: key buffer to store the M3 public ephimeral key and this is populated by TME-L
+* key_buf_len: key buffer length
+* key_len : Size of the M3 Ephimeral public key. This is populated by TME-L after
+* storing the key in the key buffer.
+*
+* This function can be used to get the M3 public ephimeral key from the TME-L.
+ */
+int __qti_scm_get_device_attestation_ephimeral_key(struct device *dev,
+ void *key_buf, u32 key_buf_len, u32 *key_len)
+{
+ int ret;
+ struct qcom_scm_desc desc = {
+ .svc = QCOM_SCM_QWES_SVC_ID,
+ .cmd = QCOM_SCM_QWES_INIT_ATTEST,
+ .arginfo = QCOM_SCM_ARGS(3, QCOM_SCM_VAL, QCOM_SCM_VAL, QCOM_SCM_RW),
+ .owner = ARM_SMCCC_OWNER_SIP,
+ };
+ struct qcom_scm_res res;
+
+ dma_addr_t dma_key_buf;
+ dma_addr_t dma_key_len;
+
+ dma_key_buf = dma_map_single(dev, key_buf, key_buf_len, DMA_FROM_DEVICE);
+ ret = dma_mapping_error(dev, dma_key_buf);
+ if (ret != 0) {
+ pr_err("%s: DMA Mapping Error : %d\n", __func__, ret);
+ return ret;
+ }
+
+ dma_key_len = dma_map_single(dev, key_len, sizeof(u32), DMA_FROM_DEVICE);
+ ret = dma_mapping_error(dev, dma_key_len);
+ if (ret != 0) {
+ pr_err("%s: DMA Mapping Error : %d\n", __func__, ret);
+ goto dma_unmap_key_buf;
+ }
+
+ desc.args[0] = dma_key_buf;
+ desc.args[1] = key_buf_len;
+ desc.args[2] = dma_key_len;
+
+ ret = qcom_scm_call(__scm->dev, &desc, &res);
+
+ dma_unmap_single(dev, dma_key_len, sizeof(unsigned int), DMA_FROM_DEVICE);
+
+dma_unmap_key_buf:
+ dma_unmap_single(dev, dma_key_buf, key_buf_len, DMA_FROM_DEVICE);
+
+ return ret ? : res.result[0];
+}
+
+/**
+ * __qti_scm_get_device_attestation_response() - Get attestation response from TME-L
+ *
+ * req_buf: attestation request buffer, it contains a attestation request.
+ * req_buf_len: attestation request buffer length.
+ * extclaim_buf: External claim buffer, it also contains attestation request when the
+ attestation request is more than 2KB.
+ * extclaim_buf_len: size of external buffer.
+ * resp_buf: Response Buffer passed to TME to store the Attestation report response.
+ * TME will used this buffer to populate the Attestation report.
+ * resp_buf_len: size of the response buffer.
+ * attest_resp_len: Length of the Attestation report response. This is populated by TME
+ * after storing the attestation response.
+ *
+ * This function can be used to get the attestation response binary from TME-L by
+ * passing the attestation report through req_buf and extclaim_buf.
+ */
+int __qti_scm_get_device_attestation_response(struct device *dev,
+ void *req_buf, u32 req_buf_len, void *extclaim_buf,
+ u32 extclaim_buf_len, void *resp_buf, u32 resp_buf_len,
+ u32 *attest_resp_len)
+{
+ int ret;
+ struct qcom_scm_desc desc = {
+ .svc = QCOM_SCM_QWES_SVC_ID,
+ .cmd = QCOM_SCM_QWES_ATTEST_REPORT,
+ .arginfo = QCOM_SCM_ARGS(7, QCOM_SCM_VAL, QCOM_SCM_VAL,
+ QCOM_SCM_VAL, QCOM_SCM_VAL, QCOM_SCM_VAL,
+ QCOM_SCM_VAL, QCOM_SCM_RW),
+ .owner = ARM_SMCCC_OWNER_SIP,
+ };
+ struct qcom_scm_res res;
+
+ dma_addr_t dma_req_buf;
+ dma_addr_t dma_claim_buf = 0;
+ dma_addr_t dma_resp_buf;
+ dma_addr_t dma_resp_len;
+
+ dma_req_buf = dma_map_single(dev, req_buf, req_buf_len,
+ DMA_FROM_DEVICE);
+ ret = dma_mapping_error(dev, dma_req_buf);
+ if (ret != 0) {
+ pr_err("%s: DMA Mapping Error : %d\n", __func__, ret);
+ return ret;
+ }
+
+ if (extclaim_buf != NULL) {
+ dma_claim_buf = dma_map_single(dev, extclaim_buf, extclaim_buf_len,
+ DMA_FROM_DEVICE);
+ ret = dma_mapping_error(dev, dma_claim_buf);
+ if (ret != 0) {
+ pr_err("%s: DMA Mapping Error : %d\n", __func__, ret);
+ goto dma_unmap_req_buf;
+ }
+ }
+
+ dma_resp_buf = dma_map_single(dev, resp_buf, resp_buf_len,
+ DMA_FROM_DEVICE);
+ ret = dma_mapping_error(dev, dma_resp_buf);
+ if (ret != 0) {
+ pr_err("%s: DMA Mapping Error : %d\n", __func__, ret);
+ goto dma_unmap_extclaim_buf;
+ }
+
+ dma_resp_len = dma_map_single(dev, attest_resp_len,
+ sizeof(unsigned int), DMA_FROM_DEVICE);
+ ret = dma_mapping_error(dev, dma_req_buf);
+ if (ret != 0) {
+ pr_err("%s: DMA Mapping Error : %d\n", __func__, ret);
+ goto dma_unmap_resp_buf;
+ }
+ desc.args[0] = dma_req_buf;
+ desc.args[1] = req_buf_len;
+ desc.args[2] = dma_claim_buf;
+ desc.args[3] = extclaim_buf_len;
+ desc.args[4] = dma_resp_buf;
+ desc.args[5] = resp_buf_len;
+ desc.args[6] = dma_resp_len;
+
+ ret = qcom_scm_call(__scm->dev, &desc, &res);
+
+ dma_unmap_single(dev, dma_resp_len, sizeof(unsigned int),
+ DMA_FROM_DEVICE);
+dma_unmap_resp_buf:
+ dma_unmap_single(dev, dma_resp_buf, resp_buf_len, DMA_FROM_DEVICE);
+
+dma_unmap_extclaim_buf:
+ if (extclaim_buf != NULL) {
+ dma_unmap_single(dev, dma_claim_buf, extclaim_buf_len,
+ DMA_FROM_DEVICE);
+ }
+
+dma_unmap_req_buf:
+ dma_unmap_single(dev, dma_req_buf, req_buf_len, DMA_FROM_DEVICE);
+
+ return ret ? : res.result[0];
+}
+
+/**
+ *__qti_scm_get_device_provision_response() - Get device provisioning response from TME-L
+ *
+ * provreq_buf: Provsion request buffer, it contains a provision request.
+ * provreq_buf_len: Provision request buffer length.
+ * provresp_buf: Provision response buffer passed to TME to store the Provision response.
+ * TME will used this buffer to populate the provision response.
+ * provresp_buf_len: size allocated to provision response buffer.
+ * attest_resp_len: Length of the provision response. This is populated by TME
+ * after storing the provision response.
+ *
+ * This function can be used to get the provision response from TME-L by
+ * passing the provision report through prov_req.bin file.
+ */
+int __qti_scm_get_device_provision_response(struct device *dev,
+ void *provreq_buf, u32 provreq_buf_len,
+ void *provresp_buf, u32 provresp_buf_len, u32 *prov_resp_size)
+{
+ int ret;
+ struct qcom_scm_desc desc = {
+ .svc = QCOM_SCM_QWES_SVC_ID,
+ .cmd = QCOM_SCM_QWES_DEVICE_PROVISION,
+ .arginfo = QCOM_SCM_ARGS(5, QCOM_SCM_VAL, QCOM_SCM_VAL,
+ QCOM_SCM_VAL, QCOM_SCM_VAL, QCOM_SCM_RW),
+ .owner = ARM_SMCCC_OWNER_SIP,
+ };
+ struct qcom_scm_res res;
+
+ dma_addr_t dma_req_buf;
+ dma_addr_t dma_resp_buf;
+ dma_addr_t dma_prov_resp_size;
+
+ dma_req_buf = dma_map_single(dev, provreq_buf, provreq_buf_len,
+ DMA_FROM_DEVICE);
+ ret = dma_mapping_error(dev, dma_req_buf);
+ if (ret != 0) {
+ pr_err("%s: DMA Mapping Error : %d\n", __func__, ret);
+ return ret;
+ }
+
+ dma_resp_buf = dma_map_single(dev, provresp_buf, provresp_buf_len,
+ DMA_FROM_DEVICE);
+ ret = dma_mapping_error(dev, dma_resp_buf);
+ if (ret != 0) {
+ pr_err("%s: DMA Mapping Error : %d\n", __func__, ret);
+ goto dma_unmap_req_buf;
+ }
+
+ dma_prov_resp_size = dma_map_single(dev, prov_resp_size,
+ sizeof(unsigned int), DMA_FROM_DEVICE);
+ ret = dma_mapping_error(dev, dma_req_buf);
+ if (ret != 0) {
+ pr_err("%s: DMA Mapping Error : %d\n", __func__, ret);
+ goto dma_unmap_resp_buf;
+ }
+
+ desc.args[0] = dma_req_buf;
+ desc.args[1] = provreq_buf_len;
+ desc.args[2] = dma_resp_buf;
+ desc.args[3] = provresp_buf_len;
+ desc.args[4] = dma_prov_resp_size;
+
+ ret = qcom_scm_call(__scm->dev, &desc, &res);
+
+ dma_unmap_single(dev, dma_prov_resp_size, sizeof(unsigned int),
+ DMA_FROM_DEVICE);
+dma_unmap_resp_buf:
+ dma_unmap_single(dev, dma_resp_buf, provresp_buf_len, DMA_FROM_DEVICE);
+
+dma_unmap_req_buf:
+ dma_unmap_single(dev, dma_req_buf, provreq_buf_len, DMA_FROM_DEVICE);
+
+ return ret ? : res.result[0];
+}
+
int qcom_scm_enable_try_mode(void)
{
int ret;
diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h
index efe5b8328483..2b8159fae4de 100644
--- a/drivers/firmware/qcom_scm.h
+++ b/drivers/firmware/qcom_scm.h
@@ -166,6 +166,15 @@ extern int __qti_scm_tz_hvc_log(struct device *dev, u32 svc_id, u32 cmd_id,
#define QCOM_SCM_QCE_ENC_DEC_CMD 0xB
#define QCOM_SCM_QCE_UNLOCK_CMD 0x4
#define QCOM_SCM_SECCRYPT_CLRKEY_CMD 0xC
+
+/*
+ * QCOM_SCM_QWES_SVC - commands related to Qwes feature
+ */
+#define QCOM_SCM_QWES_SVC_ID 0x1E
+#define QCOM_SCM_QWES_INIT_ATTEST 0x01
+#define QCOM_SCM_QWES_ATTEST_REPORT 0x02
+#define QCOM_SCM_QWES_DEVICE_PROVISION 0x03
+
extern int __qti_sec_crypt(struct device *dev, void *confBuf, int size);
extern int __qti_seccrypt_clearkey(struct device *dev);
extern int __qti_set_qcekey_sec(struct device *dev, void *confBuf, int size);
@@ -205,6 +214,15 @@ extern int __qti_scm_aes(struct device *dev, uint32_t req_addr,
extern int __qti_scm_aes_clear_key_handle(struct device *dev, uint32_t key_handle, u32 cmd_id);
extern int __qcom_remove_xpu_scm_call_available(struct device *dev, u32 svc_id,
u32 cmd_id);
+extern int __qti_scm_get_device_attestation_ephimeral_key(struct device *dev,
+ void *key_buf, u32 key_buf_len, u32 *key_len);
+extern int __qti_scm_get_device_attestation_response(struct device *dev,
+ void *req_buf, u32 req_buf_len, void *extclaim_buf,
+ u32 extclaim_buf_len, void *resp_buf,
+ u32 resp_buf_len, u32 *attest_resp_len);
+extern int __qti_scm_get_device_provision_response(struct device *dev,
+ void *provreq_buf, u32 provreq_buf_len, void *provresp_buf,
+ u32 provresp_buf_len, u32 *prov_resp_size);
/* common error codes */
#define QCOM_SCM_V2_EBUSY -12
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index c6a6c3234f0b..6c35fdaa4ac8 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -35,4 +35,5 @@ obj-$(CONFIG_IPQ_DEBUG) += ipq-debug.o
obj-$(CONFIG_MSM_RPM_LOG) += rpm_log.o
obj-$(CONFIG_QTI_TZ_LOG) += tz_log.o
obj-$(CONFIG_QTI_LICENSE_MANAGER) += license_manager.o
+obj-$(CONFIG_QTI_LICENSE_MANAGER) += qwes.o
obj-$(CONFIG_QTI_APSS_ACC) += cpu_ops.o cpu_pwr_ctl.o
diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h
index c115601e50b9..c608dcf361c0 100644
--- a/include/linux/qcom_scm.h
+++ b/include/linux/qcom_scm.h
@@ -293,6 +293,15 @@ extern int qti_scm_get_ecdsa_blob(u32 svc_id, u32 cmd_id, dma_addr_t nonce_buf,
u32 nonce_buf_len, dma_addr_t ecdsa_buf, u32 ecdsa_buf_len,
u32 *ecdsa_consumed_len);
+extern int qcom_scm_get_device_attestation_ephimeral_key(void *key_buf,
+ u32 key_buf_len, u32 *key_len);
+extern int qcom_scm_get_device_attestation_response(void *req_buf,
+ u32 req_buf_len, void *extclaim_buf, u32 extclaim_buf_len,
+ void *resp_buf, u32 resp_buf_len, u32 *attest_resp_len);
+extern int qcom_scm_get_device_provision_response(void *provreq_buf,
+ u32 provreq_buf_len, void *provresp_buf, u32 provresp_buf_len,
+ u32 *prov_resp_size);
+
extern bool qcom_scm_sec_auth_available(unsigned int scm_cmd_id);
extern int qcom_scm_get_ipq5332_fuse_list(struct fuse_payload *fuse, size_t size);
extern int qcom_sec_upgrade_auth(unsigned int scm_cmd_id,
--
2.34.1