mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-18 09:51:26 +00:00
371 lines
13 KiB
Diff
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
|
|
|