Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be797251 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "qseecom: Add support for LTE OTA key mgmt"

parents 4e2de0cd 3bc3ba16
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -59,6 +59,17 @@ enum qseecom_qceos_cmd_id {
	QSEOS_TEE_OPEN_SESSION,
	QSEOS_TEE_INVOKE_COMMAND,
	QSEOS_TEE_CLOSE_SESSION,
	QSEOS_FSM_LTE_INIT_DB = 0x100,
	QSEOS_FSM_LTE_STORE_KENB = 0x101,
	QSEOS_FSM_LTE_GEN_KEYS = 0x102,
	QSEOS_FSM_LTE_GET_KEY_OFFSETS = 0x103,
	QSEOS_FSM_LTE_GEN_KENB_STAR = 0x104,
	QSEOS_FSM_LTE_GET_KENB_STAR = 0x105,
	QSEOS_FSM_LTE_STORE_NH = 0x106,
	QSEOS_FSM_LTE_DELETE_NH = 0x107,
	QSEOS_FSM_LTE_DELETE_KEYS = 0x108,
	QSEOS_FSM_IKE_CMD_SIGN = 0x200,
	QSEOS_FSM_IKE_CMD_PROV_KEY = 0x201,
	QSEOS_CMD_MAX     = 0xEFFFFFFF
};

@@ -219,4 +230,12 @@ __packed struct qseecom_qteec_ireq {
	uint32_t    resp_len;
};

__packed struct qseecom_client_send_fsm_key_req {
	uint32_t qsee_cmd_id;
	void     *req_ptr;
	uint32_t req_len;
	void     *rsp_ptr;
	uint32_t rsp_len;
};

#endif /* __QSEECOMI_H_ */
+90 −4
Original line number Diff line number Diff line
@@ -1086,13 +1086,80 @@ int __qseecom_process_rpmb_svc_cmd(struct qseecom_dev_handle *data_ptr,
	return ret;
}

int __qseecom_process_fsm_key_svc_cmd(struct qseecom_dev_handle *data_ptr,
		struct qseecom_send_svc_cmd_req *req_ptr,
		struct qseecom_client_send_fsm_key_req *send_svc_ireq_ptr)
{
	int ret = 0;
	uint32_t reqd_len_sb_in = 0;

	if ((req_ptr == NULL) || (send_svc_ireq_ptr == NULL)) {
		pr_err("Error with pointer: req_ptr = %p, send_svc_ptr = %p\n",
			req_ptr, send_svc_ireq_ptr);
		return -EINVAL;
	}

	if (((uint32_t)req_ptr->cmd_req_buf <
			data_ptr->client.user_virt_sb_base)
			|| ((uint32_t)req_ptr->cmd_req_buf >=
			(data_ptr->client.user_virt_sb_base +
			data_ptr->client.sb_length))) {
		pr_err("cmd buffer address not within shared bufffer\n");
		return -EINVAL;
	}

	if (((uint32_t)req_ptr->resp_buf < data_ptr->client.user_virt_sb_base)
			|| ((uint32_t)req_ptr->resp_buf >=
			(data_ptr->client.user_virt_sb_base +
			data_ptr->client.sb_length))){
		pr_err("response buffer address not within shared bufffer\n");
		return -EINVAL;
	}

	if ((req_ptr->cmd_req_len == 0) || (req_ptr->resp_len == 0) ||
		req_ptr->cmd_req_len > data_ptr->client.sb_length ||
		req_ptr->resp_len > data_ptr->client.sb_length) {
		pr_err("cmd buffer length or response buffer length not valid\n");
		return -EINVAL;
	}

	if (req_ptr->cmd_req_len > UINT_MAX - req_ptr->resp_len) {
		pr_err("Integer overflow detected in req_len & rsp_len, exiting now\n");
		return -EINVAL;
	}

	reqd_len_sb_in = req_ptr->cmd_req_len + req_ptr->resp_len;
	if (reqd_len_sb_in > data_ptr->client.sb_length) {
		pr_debug("Not enough memory to fit cmd_buf and resp_buf. ");
		pr_debug("Required: %u, Available: %u\n",
				reqd_len_sb_in, data_ptr->client.sb_length);
		return -ENOMEM;
	}

	send_svc_ireq_ptr->qsee_cmd_id = req_ptr->cmd_id;
	send_svc_ireq_ptr->req_len = req_ptr->cmd_req_len;
	send_svc_ireq_ptr->rsp_ptr = (void *)(__qseecom_uvirt_to_kphys(data_ptr,
					(uint32_t)req_ptr->resp_buf));
	send_svc_ireq_ptr->rsp_len = req_ptr->resp_len;

	send_svc_ireq_ptr->req_ptr = (void *)(__qseecom_uvirt_to_kphys(data_ptr,
					(uint32_t)req_ptr->cmd_req_buf));


	return ret;
}

static int qseecom_send_service_cmd(struct qseecom_dev_handle *data,
				void __user *argp)
{
	int ret = 0;
	struct qseecom_client_send_service_ireq send_svc_ireq;
	struct qseecom_client_send_fsm_key_req send_fsm_key_svc_ireq;
	struct qseecom_command_scm_resp resp;
	struct qseecom_send_svc_cmd_req req;
	void   *send_req_ptr;
	size_t req_buf_size;

	/*struct qseecom_command_scm_resp resp;*/

	if (copy_from_user(&req,
@@ -1102,7 +1169,7 @@ static int qseecom_send_service_cmd(struct qseecom_dev_handle *data,
		return -EFAULT;
	}

	if (req.resp_buf == NULL) {
	if ((req.resp_buf == NULL) || (req.cmd_req_buf == NULL)) {
		pr_err("cmd buffer or response buffer is null\n");
		return -EINVAL;
	}
@@ -1112,8 +1179,27 @@ static int qseecom_send_service_cmd(struct qseecom_dev_handle *data,
	switch (req.cmd_id) {
	case QSEOS_RPMB_PROVISION_KEY_COMMAND:
	case QSEOS_RPMB_ERASE_COMMAND:
		send_req_ptr = &send_svc_ireq;
		req_buf_size = sizeof(send_svc_ireq);
		if (__qseecom_process_rpmb_svc_cmd(data, &req,
				&send_svc_ireq))
				send_req_ptr))
			return -EINVAL;
		break;
	case QSEOS_FSM_LTE_INIT_DB:
	case QSEOS_FSM_LTE_STORE_KENB:
	case QSEOS_FSM_LTE_GEN_KEYS:
	case QSEOS_FSM_LTE_GET_KEY_OFFSETS:
	case QSEOS_FSM_LTE_GEN_KENB_STAR:
	case QSEOS_FSM_LTE_GET_KENB_STAR:
	case QSEOS_FSM_LTE_STORE_NH:
	case QSEOS_FSM_LTE_DELETE_NH:
	case QSEOS_FSM_LTE_DELETE_KEYS:
	case QSEOS_FSM_IKE_CMD_SIGN:
	case QSEOS_FSM_IKE_CMD_PROV_KEY:
		send_req_ptr = &send_fsm_key_svc_ireq;
		req_buf_size = sizeof(send_fsm_key_svc_ireq);
		if (__qseecom_process_fsm_key_svc_cmd(data, &req,
				send_req_ptr))
			return -EINVAL;
		break;
	default:
@@ -1145,8 +1231,8 @@ static int qseecom_send_service_cmd(struct qseecom_dev_handle *data,
	msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
				data->client.sb_virt, data->client.sb_length,
				ION_IOC_CLEAN_INV_CACHES);
	ret = scm_call(SCM_SVC_TZSCHEDULER, 1, (const void *) &send_svc_ireq,
					sizeof(send_svc_ireq),
	ret = scm_call(SCM_SVC_TZSCHEDULER, 1, (const void *) send_req_ptr,
					req_buf_size,
					&resp, sizeof(resp));
	msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
				data->client.sb_virt, data->client.sb_length,