[PATCH 7/9] tee: optee: implement RPMB support

Sascha Hauer s.hauer at pengutronix.de
Wed Mar 12 05:16:22 PDT 2025


This implements the OPTEE_RPC_CMD_RPMB RPC call. For data requests we
call into the MMC specific RPMB implementation.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/tee/optee/Makefile        |   1 +
 drivers/tee/optee/optee_private.h |  10 +++
 drivers/tee/optee/rpc.c           |   3 +
 drivers/tee/optee/rpmb.c          | 128 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 142 insertions(+)

diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile
index 5e71af77ee..f68352aa4e 100644
--- a/drivers/tee/optee/Makefile
+++ b/drivers/tee/optee/Makefile
@@ -6,3 +6,4 @@ optee-objs += call.o
 optee-objs += rpc.o
 optee-objs += device.o
 optee-objs += smc_abi.o
+obj-$(CONFIG_MCI_MMC_RPMB) += rpmb.o
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index d739a6c609..bb9ac1b068 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -179,4 +179,14 @@ static inline void reg_pair_from_64(u32 *reg0, u32 *reg1, u64 val)
 /* Registration of the ABIs */
 int optee_smc_abi_register(void);
 
+#ifdef CONFIG_MCI_MMC_RPMB
+void optee_suppl_cmd_rpmb(struct tee_context *ctx, struct optee_msg_arg *arg);
+#else
+static inline void optee_suppl_cmd_rpmb(struct tee_context *ctx, struct optee_msg_arg *arg)
+{
+	pr_debug("OPTEE_MSG_RPC_CMD_RPMB not implemented\n");
+	arg->ret = TEEC_ERROR_NOT_IMPLEMENTED;
+}
+#endif
+
 #endif /*OPTEE_PRIVATE_H*/
diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c
index bdb2a9da74..182a06ec91 100644
--- a/drivers/tee/optee/rpc.c
+++ b/drivers/tee/optee/rpc.c
@@ -64,6 +64,9 @@ void optee_rpc_cmd(struct tee_context *ctx, struct optee *optee,
 	case OPTEE_RPC_CMD_SHM_FREE:
 		cmd_shm_free(arg);
 		break;
+	case OPTEE_RPC_CMD_RPMB:
+		optee_suppl_cmd_rpmb(ctx, arg);
+		break;
 	default:
 		arg->ret = TEEC_ERROR_NOT_IMPLEMENTED;
 	}
diff --git a/drivers/tee/optee/rpmb.c b/drivers/tee/optee/rpmb.c
new file mode 100644
index 0000000000..da115796f4
--- /dev/null
+++ b/drivers/tee/optee/rpmb.c
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+ * Copyright (c) 2018 Linaro Limited
+ */
+
+#define pr_fmt(fmt)     "optee-rpmb: " fmt
+
+#include <mci.h>
+
+#include "optee_msg.h"
+#include "optee_private.h"
+
+/*
+ * Request and response definitions must be in sync with the secure side of
+ * OP-TEE.
+ */
+
+/* Request */
+struct rpmb_req {
+	u16 cmd;
+#define RPMB_CMD_DATA_REQ      0x00
+#define RPMB_CMD_GET_DEV_INFO  0x01
+	u16 dev_id;
+	u16 block_count;
+	/* Optional data frames (rpmb_data_frame) follow */
+};
+
+#define RPMB_REQ_DATA(req) ((void *)((struct rpmb_req *)(req) + 1))
+
+/* Response to device info request */
+struct rpmb_dev_info {
+	u8 cid[16];
+	u8 rpmb_size_mult;	/* EXT CSD-slice 168: RPMB Size */
+	u8 rel_wr_sec_c;	/* EXT CSD-slice 222: Reliable Write Sector */
+				/*                    Count */
+	u8 ret_code;
+#define RPMB_CMD_GET_DEV_INFO_RET_OK     0x00
+#define RPMB_CMD_GET_DEV_INFO_RET_ERROR  0x01
+};
+
+static u32 rpmb_get_dev_info(struct mci *mci, struct rpmb_dev_info *info)
+{
+	int i;
+
+	if (!mci->ext_csd)
+		return TEEC_ERROR_GENERIC;
+
+	for (i = 0; i < ARRAY_SIZE(mci->raw_cid); i++)
+		((u32 *) info->cid)[i] = cpu_to_be32(mci->raw_cid[i]);
+
+	info->rel_wr_sec_c = mci->ext_csd[222];
+	info->rpmb_size_mult = mci->ext_csd[168];
+	info->ret_code = RPMB_CMD_GET_DEV_INFO_RET_OK;
+
+	return TEEC_SUCCESS;
+}
+
+static u32 rpmb_process_request(struct tee_context *ctx, void *req,
+				ulong req_size, void *rsp, ulong rsp_size)
+{
+	struct rpmb_req *sreq = req;
+	struct mci *mci = mci_get_rpmb_dev();
+
+	if (req_size < sizeof(*sreq))
+		return TEEC_ERROR_BAD_PARAMETERS;
+
+	if (!mci)
+		return TEEC_ERROR_ITEM_NOT_FOUND;
+
+	switch (sreq->cmd) {
+	case RPMB_CMD_DATA_REQ:
+		if (mci_rpmb_route_frames(mci, RPMB_REQ_DATA(req),
+					  req_size - sizeof(struct rpmb_req),
+					  rsp, rsp_size))
+			return TEEC_ERROR_BAD_PARAMETERS;
+		return TEEC_SUCCESS;
+
+	case RPMB_CMD_GET_DEV_INFO:
+		if (rsp_size != sizeof(struct rpmb_dev_info)) {
+			pr_debug("Invalid req/rsp size\n");
+			return TEEC_ERROR_BAD_PARAMETERS;
+		}
+
+		/*
+		 * We do not have any way in barebox to associate a dev_id with a
+		 * corresponding eMMC device. For now we assume that only a single
+		 * eMMC is present in the system which is assumed to have dev_id 0.
+		 */
+		if (sreq->dev_id != 0) {
+			pr_err("Unexpected RPMB dev_id %u\n", sreq->dev_id);
+			return TEEC_ERROR_ITEM_NOT_FOUND;
+		}
+
+		return rpmb_get_dev_info(mci, rsp);
+
+	default:
+		pr_debug("Unsupported RPMB command: %d\n", sreq->cmd);
+		return TEEC_ERROR_BAD_PARAMETERS;
+	}
+}
+
+void optee_suppl_cmd_rpmb(struct tee_context *ctx, struct optee_msg_arg *arg)
+{
+	struct tee_shm *req_shm;
+	struct tee_shm *rsp_shm;
+	void *req_buf;
+	void *rsp_buf;
+	ulong req_size;
+	ulong rsp_size;
+
+	if (arg->num_params != 2 ||
+	    arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_RMEM_INPUT ||
+	    arg->params[1].attr != OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT) {
+		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
+		return;
+	}
+
+	req_shm = (struct tee_shm *)(ulong)arg->params[0].u.rmem.shm_ref;
+	req_buf = (u8 *)req_shm->kaddr + arg->params[0].u.rmem.offs;
+	req_size = arg->params[0].u.rmem.size;
+
+	rsp_shm = (struct tee_shm *)(ulong)arg->params[1].u.rmem.shm_ref;
+	rsp_buf = (u8 *)rsp_shm->kaddr + arg->params[1].u.rmem.offs;
+	rsp_size = arg->params[1].u.rmem.size;
+
+	arg->ret = rpmb_process_request(ctx, req_buf, req_size,
+					rsp_buf, rsp_size);
+}

-- 
2.39.5




More information about the barebox mailing list