From: Jens Wiklander <jens.wiklander@linaro.org>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 08/10] optee: support routing of rpmb data frames to mmc
Date: Mon, 13 Aug 2018 17:53:45 +0200 [thread overview]
Message-ID: <20180813155347.13844-9-jens.wiklander@linaro.org> (raw)
In-Reply-To: <20180813155347.13844-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.
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 | 31 ++++-
drivers/tee/optee/rpmb.c | 184 ++++++++++++++++++++++++++++++
drivers/tee/optee/supplicant.c | 3 +
5 files changed, 226 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 a810f3b965de..5f308a0c6a96 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -280,6 +280,13 @@ static u32 do_call_with_arg(struct udevice *dev, struct optee_msg_arg *arg)
param.a3 = res.a3;
handle_rpc(dev, ¶m, &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);
}
}
@@ -611,4 +618,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 daa470f812a9..b76979d21011 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -6,7 +6,36 @@
#ifndef __OPTEE_PRIVATE_H
#define __OPTEE_PRIVATE_H
+#include <tee.h>
+#include <log.h>
+
+struct optee_private {
+ struct mmc *rpmb_mmc;
+ int rpmb_dev_id;
+ char 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
+void optee_suppl_cmd_rpmb(struct udevice *dev, struct optee_msg_arg *arg);
+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..c1447a5561c2
--- /dev/null
+++ b/drivers/tee/optee/rpmb.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+ * Copyright (c) 2018 Linaro Limited
+ */
+
+#include <common.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;
+ }
+
+#ifdef CONFIG_BLK
+ priv->rpmb_original_part = mmc_get_blk_desc(mmc)->hwpart;
+#else
+ priv->rpmb_original_part = mmc->block_dev.hwpart;
+#endif
+
+ 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 6965055bd1b5..14cb8717522c 100644
--- a/drivers/tee/optee/supplicant.c
+++ b/drivers/tee/optee/supplicant.c
@@ -81,6 +81,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
next prev parent reply other threads:[~2018-08-13 15:53 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-08-13 15:53 [U-Boot] [PATCH 00/10] AVB using OP-TEE Jens Wiklander
2018-08-13 15:53 ` [U-Boot] [PATCH 01/10] dm: fdt: scan for devices under /firmware too Jens Wiklander
2018-08-15 14:17 ` Tom Rini
2018-08-15 14:30 ` Michal Simek
2018-08-15 14:34 ` Tom Rini
2018-08-15 14:50 ` Michal Simek
2018-08-15 15:31 ` Rob Herring
2018-08-15 15:43 ` Tom Rini
2018-08-13 15:53 ` [U-Boot] [PATCH 02/10] cmd: avb read_rb: print rb_idx in hexadecimal Jens Wiklander
2018-08-14 11:34 ` Igor Opaniuk
2018-08-13 15:53 ` [U-Boot] [PATCH 03/10] mmc: rpmb: add mmc_rpmb_route_frames() Jens Wiklander
2018-08-16 12:13 ` Igor Opaniuk
2018-08-22 13:52 ` Jens Wiklander
2018-08-13 15:53 ` [U-Boot] [PATCH 04/10] Add UCLASS_TEE for Trusted Execution Environment Jens Wiklander
2018-08-16 12:14 ` Igor Opaniuk
2018-08-17 12:48 ` Simon Glass
2018-08-21 9:20 ` Jens Wiklander
2018-08-23 10:45 ` Simon Glass
2018-08-23 11:11 ` Jens Wiklander
2018-08-23 16:31 ` Simon Glass
2018-08-13 15:53 ` [U-Boot] [PATCH 05/10] dt/bindings: add bindings for optee Jens Wiklander
2018-08-13 15:53 ` [U-Boot] [PATCH 06/10] tee: add OP-TEE driver Jens Wiklander
2018-08-16 12:17 ` Igor Opaniuk
2018-08-13 15:53 ` [U-Boot] [PATCH 07/10] arm: dt: hikey: Add optee node Jens Wiklander
2018-08-13 15:53 ` Jens Wiklander [this message]
2018-08-16 12:23 ` [U-Boot] [PATCH 08/10] optee: support routing of rpmb data frames to mmc Igor Opaniuk
2018-08-13 15:53 ` [U-Boot] [PATCH 09/10] tee: optee: support AVB trusted application Jens Wiklander
2018-08-16 12:22 ` Igor Opaniuk
2018-08-19 12:42 ` Igor Opaniuk
2018-08-13 15:53 ` [U-Boot] [PATCH 10/10] avb_verify: support using OP-TEE TA AVB Jens Wiklander
2018-08-14 11:20 ` Igor Opaniuk
2018-08-16 12:17 ` Igor Opaniuk
2018-08-23 10:45 ` [U-Boot] [PATCH 00/10] AVB using OP-TEE Simon Glass
2018-08-23 11:23 ` Jens Wiklander
2018-08-23 12:15 ` Igor Opaniuk
2018-08-23 16:31 ` Simon Glass
2018-08-28 6:11 ` Jens Wiklander
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=20180813155347.13844-9-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox