All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jens Wiklander <jens.wiklander@linaro.org>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v4 10/19] optee: support routing of rpmb data frames to mmc
Date: Tue, 25 Sep 2018 16:40:14 +0200	[thread overview]
Message-ID: <20180925144023.24555-11-jens.wiklander@linaro.org> (raw)
In-Reply-To: <20180925144023.24555-1-jens.wiklander@linaro.org>

Adds support in optee supplicant to route signed (MACed) RPMB frames
from OP-TEE Secure OS to MMC and vice versa to manipulate the RPMB
partition.

Tested-by: Igor Opaniuk <igor.opaniuk@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
---
 drivers/tee/optee/Makefile        |   1 +
 drivers/tee/optee/core.c          |   8 ++
 drivers/tee/optee/optee_private.h |  55 ++++++++-
 drivers/tee/optee/rpmb.c          | 181 ++++++++++++++++++++++++++++++
 drivers/tee/optee/supplicant.c    |   3 +
 5 files changed, 247 insertions(+), 1 deletion(-)
 create mode 100644 drivers/tee/optee/rpmb.c

diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile
index 6148feb474a5..928d3f80027f 100644
--- a/drivers/tee/optee/Makefile
+++ b/drivers/tee/optee/Makefile
@@ -2,3 +2,4 @@
 
 obj-y += core.o
 obj-y += supplicant.o
+obj-$(CONFIG_SUPPORT_EMMC_RPMB) += rpmb.o
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index 726382da9bb8..7f870f2f735d 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -315,6 +315,13 @@ static u32 do_call_with_arg(struct udevice *dev, struct optee_msg_arg *arg)
 			param.a3 = res.a3;
 			handle_rpc(dev, &param, &page_list);
 		} else {
+			/*
+			 * In case we've accessed RPMB to serve an RPC
+			 * request we need to restore the previously
+			 * selected partition as the caller may expect it
+			 * to remain unchanged.
+			 */
+			optee_suppl_rpmb_release(dev);
 			return call_err_to_res(res.a0);
 		}
 	}
@@ -651,4 +658,5 @@ U_BOOT_DRIVER(optee) = {
 	.probe = optee_probe,
 	.ops = &optee_ops,
 	.platdata_auto_alloc_size = sizeof(struct optee_pdata),
+	.priv_auto_alloc_size = sizeof(struct optee_private),
 };
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index 35adb83afcc7..9442d1c176bc 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -6,7 +6,60 @@
 #ifndef __OPTEE_PRIVATE_H
 #define __OPTEE_PRIVATE_H
 
+#include <tee.h>
+#include <log.h>
+
+/**
+ * struct optee_private - OP-TEE driver private data
+ * @rpmb_mmc:		mmc device for the RPMB partition
+ * @rpmb_dev_id:	mmc device id matching @rpmb_mmc
+ * @rpmb_original_part:	the previosly active partition on the mmc device,
+ *			used to restore active the partition when the RPMB
+ *			accesses are finished
+ */
+struct optee_private {
+	struct mmc *rpmb_mmc;
+	int rpmb_dev_id;
+	int rpmb_original_part;
+};
+
+struct optee_msg_arg;
+
+void optee_suppl_cmd(struct udevice *dev, struct tee_shm *shm_arg,
+		     void **page_list);
+
+#ifdef CONFIG_SUPPORT_EMMC_RPMB
+/**
+ * optee_suppl_cmd_rpmb() - route RPMB frames to mmc
+ * @dev:	device with the selected RPMB partition
+ * @arg:	OP-TEE message holding the frames to transmit to the mmc
+ *		and space for the response frames.
+ *
+ * Routes signed (MACed) RPMB frames from OP-TEE Secure OS to MMC and vice
+ * versa to manipulate the RPMB partition.
+ */
+void optee_suppl_cmd_rpmb(struct udevice *dev, struct optee_msg_arg *arg);
+
+/**
+ * optee_suppl_rpmb_release() - release mmc device
+ * @dev:	mmc device
+ *
+ * Releases the mmc device and restores the previously selected partition.
+ */
+void optee_suppl_rpmb_release(struct udevice *dev);
+#else
+static inline void optee_suppl_cmd_rpmb(struct udevice *dev,
+					struct optee_msg_arg *arg)
+{
+	debug("OPTEE_MSG_RPC_CMD_RPMB not implemented\n");
+	arg->ret = TEE_ERROR_NOT_IMPLEMENTED;
+}
+
+static inline void optee_suppl_rpmb_release(struct udevice *dev)
+{
+}
+#endif
+
 void *optee_alloc_and_init_page_list(void *buf, ulong len, u64 *phys_buf_ptr);
-void optee_suppl_cmd(struct udevice *dev, void *shm, void **page_list);
 
 #endif /* __OPTEE_PRIVATE_H */
diff --git a/drivers/tee/optee/rpmb.c b/drivers/tee/optee/rpmb.c
new file mode 100644
index 000000000000..955155b3f8b1
--- /dev/null
+++ b/drivers/tee/optee/rpmb.c
@@ -0,0 +1,181 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+ * Copyright (c) 2018 Linaro Limited
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <log.h>
+#include <tee.h>
+#include <mmc.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 void release_mmc(struct optee_private *priv)
+{
+	int rc;
+
+	if (!priv->rpmb_mmc)
+		return;
+
+	rc = blk_select_hwpart_devnum(IF_TYPE_MMC, priv->rpmb_dev_id,
+				      priv->rpmb_original_part);
+	if (rc)
+		debug("%s: blk_select_hwpart_devnum() failed: %d\n",
+		      __func__, rc);
+
+	priv->rpmb_mmc = NULL;
+}
+
+static struct mmc *get_mmc(struct optee_private *priv, int dev_id)
+{
+	struct mmc *mmc;
+	int rc;
+
+	if (priv->rpmb_mmc && priv->rpmb_dev_id == dev_id)
+		return priv->rpmb_mmc;
+
+	release_mmc(priv);
+
+	mmc = find_mmc_device(dev_id);
+	if (!mmc) {
+		debug("Cannot find RPMB device\n");
+		return NULL;
+	}
+	if (!(mmc->version & MMC_VERSION_MMC)) {
+		debug("Device id %d is not an eMMC device\n", dev_id);
+		return NULL;
+	}
+	if (mmc->version < MMC_VERSION_4_41) {
+		debug("Device id %d: RPMB not supported before version 4.41\n",
+		      dev_id);
+		return NULL;
+	}
+
+	priv->rpmb_original_part = mmc_get_blk_desc(mmc)->hwpart;
+
+	rc = blk_select_hwpart_devnum(IF_TYPE_MMC, dev_id, MMC_PART_RPMB);
+	if (rc) {
+		debug("Device id %d: cannot select RPMB partition: %d\n",
+		      dev_id, rc);
+		return NULL;
+	}
+
+	priv->rpmb_mmc = mmc;
+	priv->rpmb_dev_id = dev_id;
+	return mmc;
+}
+
+static u32 rpmb_get_dev_info(u16 dev_id, struct rpmb_dev_info *info)
+{
+	struct mmc *mmc = find_mmc_device(dev_id);
+
+	if (!mmc)
+		return TEE_ERROR_ITEM_NOT_FOUND;
+
+	if (!mmc->ext_csd)
+		return TEE_ERROR_GENERIC;
+
+	memcpy(info->cid, mmc->cid, sizeof(info->cid));
+	info->rel_wr_sec_c = mmc->ext_csd[222];
+	info->rpmb_size_mult = mmc->ext_csd[168];
+	info->ret_code = RPMB_CMD_GET_DEV_INFO_RET_OK;
+
+	return TEE_SUCCESS;
+}
+
+static u32 rpmb_process_request(struct optee_private *priv, void *req,
+				ulong req_size, void *rsp, ulong rsp_size)
+{
+	struct rpmb_req *sreq = req;
+	struct mmc *mmc;
+
+	if (req_size < sizeof(*sreq))
+		return TEE_ERROR_BAD_PARAMETERS;
+
+	switch (sreq->cmd) {
+	case RPMB_CMD_DATA_REQ:
+		mmc = get_mmc(priv, sreq->dev_id);
+		if (!mmc)
+			return TEE_ERROR_ITEM_NOT_FOUND;
+		if (mmc_rpmb_route_frames(mmc, RPMB_REQ_DATA(req),
+					  req_size - sizeof(struct rpmb_req),
+					  rsp, rsp_size))
+			return TEE_ERROR_BAD_PARAMETERS;
+		return TEE_SUCCESS;
+
+	case RPMB_CMD_GET_DEV_INFO:
+		if (req_size != sizeof(struct rpmb_req) ||
+		    rsp_size != sizeof(struct rpmb_dev_info)) {
+			debug("Invalid req/rsp size\n");
+			return TEE_ERROR_BAD_PARAMETERS;
+		}
+		return rpmb_get_dev_info(sreq->dev_id, rsp);
+
+	default:
+		debug("Unsupported RPMB command: %d\n", sreq->cmd);
+		return TEE_ERROR_BAD_PARAMETERS;
+	}
+}
+
+void optee_suppl_cmd_rpmb(struct udevice *dev, 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 = TEE_ERROR_BAD_PARAMETERS;
+		return;
+	}
+
+	req_shm = (struct tee_shm *)(ulong)arg->params[0].u.rmem.shm_ref;
+	req_buf = (u8 *)req_shm->addr + 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->addr + arg->params[1].u.rmem.offs;
+	rsp_size = arg->params[1].u.rmem.size;
+
+	arg->ret = rpmb_process_request(dev_get_priv(dev), req_buf, req_size,
+					rsp_buf, rsp_size);
+}
+
+void optee_suppl_rpmb_release(struct udevice *dev)
+{
+	release_mmc(dev_get_priv(dev));
+}
diff --git a/drivers/tee/optee/supplicant.c b/drivers/tee/optee/supplicant.c
index 2239b1bf7b37..b1ea65bdb2e3 100644
--- a/drivers/tee/optee/supplicant.c
+++ b/drivers/tee/optee/supplicant.c
@@ -85,6 +85,9 @@ void optee_suppl_cmd(struct udevice *dev, struct tee_shm *shm_arg,
 		debug("OPTEE_MSG_RPC_CMD_FS not implemented\n");
 		arg->ret = TEE_ERROR_NOT_IMPLEMENTED;
 		break;
+	case OPTEE_MSG_RPC_CMD_RPMB:
+		optee_suppl_cmd_rpmb(dev, arg);
+		break;
 	default:
 		arg->ret = TEE_ERROR_NOT_IMPLEMENTED;
 	}
-- 
2.17.1

  parent reply	other threads:[~2018-09-25 14:40 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-25 14:40 [U-Boot] [PATCH v4 00/19] AVB using OP-TEE Jens Wiklander
2018-09-25 14:40 ` [U-Boot] [PATCH v4 01/19] dm: fdt: scan for devices under /firmware too Jens Wiklander
2018-10-08  1:40   ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 02/19] cmd: avb read_rb: print rb_idx in hexadecimal Jens Wiklander
2018-10-08  1:40   ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 03/19] cmd: avb: print error message if command fails Jens Wiklander
2018-10-08  1:40   ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 04/19] mmc: rpmb: add mmc_rpmb_route_frames() Jens Wiklander
2018-10-02 11:21   ` Simon Glass
2018-10-08  1:40   ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 05/19] Add UCLASS_TEE for Trusted Execution Environment Jens Wiklander
2018-10-08  1:40   ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 06/19] dt/bindings: add bindings for optee Jens Wiklander
2018-10-08  1:40   ` [U-Boot] [U-Boot,v4,06/19] " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 07/19] tee: add OP-TEE driver Jens Wiklander
2018-10-08  1:40   ` [U-Boot] [U-Boot,v4,07/19] " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 08/19] Documentation: tee uclass and op-tee driver Jens Wiklander
2018-10-08  1:40   ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 09/19] arm: dt: hikey: Add optee node Jens Wiklander
2018-10-08  1:40   ` [U-Boot] [U-Boot,v4,09/19] " Tom Rini
2018-09-25 14:40 ` Jens Wiklander [this message]
2018-10-02 11:21   ` [U-Boot] [PATCH v4 10/19] optee: support routing of rpmb data frames to mmc Simon Glass
2018-10-08  1:40   ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 11/19] tee: optee: support AVB trusted application Jens Wiklander
2018-10-02 11:21   ` Simon Glass
2018-10-08  1:41   ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 12/19] sandbox: dt: add sandbox_tee node Jens Wiklander
2018-10-08  1:41   ` [U-Boot] [U-Boot,v4,12/19] " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 13/19] sandbox: imply CONFIG_TEE (TEE uclass) Jens Wiklander
2018-10-08  1:41   ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 14/19] tee: add sandbox driver Jens Wiklander
2018-10-02 11:21   ` Simon Glass
2018-10-08  1:41   ` [U-Boot] [U-Boot,v4,14/19] " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 15/19] test: tee: test TEE uclass Jens Wiklander
2018-10-08  1:41   ` [U-Boot] [U-Boot,v4,15/19] " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 16/19] avb_verify: support using OP-TEE TA AVB Jens Wiklander
2018-10-08  1:41   ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 17/19] test_avb: Update pymark.buildconfigspec information for the AVB tests Jens Wiklander
2018-10-08  1:41   ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 18/19] avb_verify: support sandbox configuration Jens Wiklander
2018-10-02 11:21   ` Simon Glass
2018-10-08  1:41   ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-09-25 14:40 ` [U-Boot] [PATCH v4 19/19] Kconfig: sandbox: enable cmd_avb and dependencies Jens Wiklander
2018-10-08  1:41   ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-10-02 11:21 ` [U-Boot] [PATCH v4 00/19] AVB using OP-TEE Simon Glass
2018-10-08  7:18   ` Jens Wiklander
2018-10-09  3:40     ` Simon Glass

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180925144023.24555-11-jens.wiklander@linaro.org \
    --to=jens.wiklander@linaro.org \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.