1
0
mirror of https://git.yoctoproject.org/meta-arm synced 2026-06-06 14:50:03 +00:00

arm-bsp/linux: add ffa transport in optee driver for TC0

This patch adds FF-A transport driver for optee driver. This is based
on prototype version released by Arm and its port for android11-5.4-lts
kernel.

Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Change-Id: I991895881c069767854ae8a0722cdc282b221dd9
Signed-off-by: Jon Mason <jon.mason@arm.com>
This commit is contained in:
Arunachalam Ganapathy
2021-01-12 15:20:48 +00:00
committed by Jon Mason
parent 44a3c5cf80
commit 980f559e87
5 changed files with 3500 additions and 0 deletions
@@ -77,6 +77,10 @@ SRC_URI_append_tc0 = " \
file://0007-firmware-arm_scmi-Add-fast_switch_possible-api.patch \
file://0008-cpufreq-arm_scmi-Set-fast_switch_possible-conditiona.patch \
file://0009-driver-firmware-Initial-version-of-ffa-driver-based-.patch \
file://0010-tee-add-support-for-session-s-client-UUID-generation.patch \
file://0011-tee-optee-Add-support-for-session-login-client-UUID-.patch \
file://0012-driver-optee-Support-for-ffa-transport.patch \
file://0013-tee-optee-fix-mem-handle-removal-in-ffa_shm_unregist.patch \
"
#
@@ -0,0 +1,252 @@
Upstream-Status: Backport [https://github.com/linaro-swg/linux/commit/e33bcbab16d1c0dd85d72bec275308369ad901f5#diff-317c0445401e56bde9d2ee0e0bb2758b0362a4099dca8e535dd20f1f649ecfc8]
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
From 69a50f4234d8fb143d499e92e3f0f67009bae586 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Vesa=20J=C3=A4=C3=A4skel=C3=A4inen?=
<vesa.jaaskelainen@vaisala.com>
Date: Wed, 22 Apr 2020 15:28:07 +0300
Subject: [PATCH] tee: add support for session's client UUID generation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
TEE Client API defines that from user space only information needed for
specified login operations is group identifier for group based logins.
REE kernel is expected to formulate trustworthy client UUID and pass that
to TEE environment. REE kernel is required to verify that provided group
identifier for group based logins matches calling processes group
memberships.
TEE specification only defines that the information passed from REE
environment to TEE environment is encoded into on UUID.
In order to guarantee trustworthiness of client UUID user space is not
allowed to freely pass client UUID.
UUIDv5 form is used encode variable amount of information needed for
different login types.
Signed-off-by: Vesa Jääskeläinen <vesa.jaaskelainen@vaisala.com>
Change-Id: I414f68d7485f95277d292fcb2646cc41bd57e62a
---
drivers/tee/Kconfig | 1 +
drivers/tee/tee_core.c | 143 ++++++++++++++++++++++++++++++++++++++++
include/linux/tee_drv.h | 16 +++++
3 files changed, 160 insertions(+)
diff --git a/drivers/tee/Kconfig b/drivers/tee/Kconfig
index 676ffcb64985..5a56317f3f4e 100644
--- a/drivers/tee/Kconfig
+++ b/drivers/tee/Kconfig
@@ -3,6 +3,7 @@
config TEE
tristate "Trusted Execution Environment support"
depends on HAVE_ARM_SMCCC || COMPILE_TEST
+ select CRYPTO_SHA1
select DMA_SHARED_BUFFER
select GENERIC_ALLOCATOR
help
diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c
index 0f16d9ffd8d1..3d32a2ca48c3 100644
--- a/drivers/tee/tee_core.c
+++ b/drivers/tee/tee_core.c
@@ -6,18 +6,33 @@
#define pr_fmt(fmt) "%s: " fmt, __func__
#include <linux/cdev.h>
+#include <linux/cred.h>
#include <linux/fs.h>
#include <linux/idr.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/tee_drv.h>
#include <linux/uaccess.h>
+#include <crypto/hash.h>
+#include <crypto/sha.h>
#include "tee_private.h"
#define TEE_NUM_DEVICES 32
#define TEE_IOCTL_PARAM_SIZE(x) (sizeof(struct tee_param) * (x))
+#define TEE_UUID_NS_NAME_SIZE 128
+
+/*
+ * TEE Client UUID name space identifier (UUIDv4)
+ *
+ * Value here is random UUID that is allocated as name space identifier for
+ * forming Client UUID's for TEE environment using UUIDv5 scheme.
+ */
+static const uuid_t tee_client_uuid_ns = UUID_INIT(0x58ac9ca0, 0x2086, 0x4683,
+ 0xa1, 0xb8, 0xec, 0x4b,
+ 0xc0, 0x8e, 0x01, 0xb6);
+
/*
* Unprivileged devices in the lower half range and privileged devices in
* the upper half range.
@@ -111,6 +126,134 @@ static int tee_release(struct inode *inode, struct file *filp)
return 0;
}
+/**
+ * uuid_v5() - Calculate UUIDv5
+ * @uuid: Resulting UUID
+ * @ns: Name space ID for UUIDv5 function
+ * @name: Name for UUIDv5 function
+ * @size: Size of name
+ *
+ * UUIDv5 is specific in RFC 4122.
+ *
+ * This implements section (for SHA-1):
+ * 4.3. Algorithm for Creating a Name-Based UUID
+ */
+static int uuid_v5(uuid_t *uuid, const uuid_t *ns, const void *name,
+ size_t size)
+{
+ unsigned char hash[SHA1_DIGEST_SIZE];
+ struct crypto_shash *shash = NULL;
+ struct shash_desc *desc = NULL;
+ int rc;
+
+ shash = crypto_alloc_shash("sha1", 0, 0);
+ if (IS_ERR(shash)) {
+ rc = PTR_ERR(shash);
+ pr_err("shash(sha1) allocation failed\n");
+ return rc;
+ }
+
+ desc = kzalloc(sizeof(*desc) + crypto_shash_descsize(shash),
+ GFP_KERNEL);
+ if (IS_ERR(desc)) {
+ rc = PTR_ERR(desc);
+ goto out;
+ }
+
+ desc->tfm = shash;
+
+ rc = crypto_shash_init(desc);
+ if (rc < 0)
+ goto out2;
+
+ rc = crypto_shash_update(desc, (const u8 *)ns, sizeof(*ns));
+ if (rc < 0)
+ goto out2;
+
+ rc = crypto_shash_update(desc, (const u8 *)name, size);
+ if (rc < 0)
+ goto out2;
+
+ rc = crypto_shash_final(desc, hash);
+ if (rc < 0)
+ goto out2;
+
+ memcpy(uuid->b, hash, UUID_SIZE);
+
+ /* Tag for version 5 */
+ uuid->b[6] = (hash[6] & 0x0F) | 0x50;
+ uuid->b[8] = (hash[8] & 0x3F) | 0x80;
+
+out2:
+ kfree(desc);
+
+out:
+ crypto_free_shash(shash);
+ return rc;
+}
+
+int tee_session_calc_client_uuid(uuid_t *uuid, u32 connection_method,
+ const u8 connection_data[TEE_IOCTL_UUID_LEN])
+{
+ const char *application_id = NULL;
+ gid_t ns_grp = (gid_t)-1;
+ kgid_t grp = INVALID_GID;
+ char *name = NULL;
+ int rc;
+
+ if (connection_method == TEE_IOCTL_LOGIN_PUBLIC) {
+ /* Nil UUID to be passed to TEE environment */
+ uuid_copy(uuid, &uuid_null);
+ return 0;
+ }
+
+ /*
+ * In Linux environment client UUID is based on UUIDv5.
+ *
+ * Determine client UUID with following semantics for 'name':
+ *
+ * For TEEC_LOGIN_USER:
+ * uid=<uid>
+ *
+ * For TEEC_LOGIN_GROUP:
+ * gid=<gid>
+ *
+ */
+
+ name = kzalloc(TEE_UUID_NS_NAME_SIZE, GFP_KERNEL);
+ if (!name)
+ return -ENOMEM;
+
+ switch (connection_method) {
+ case TEE_IOCTL_LOGIN_USER:
+ scnprintf(name, TEE_UUID_NS_NAME_SIZE, "uid=%x",
+ current_euid().val);
+ break;
+
+ case TEE_IOCTL_LOGIN_GROUP:
+ memcpy(&ns_grp, connection_data, sizeof(gid_t));
+ grp = make_kgid(current_user_ns(), ns_grp);
+ if (!gid_valid(grp) || !in_egroup_p(grp)) {
+ rc = -EPERM;
+ goto out;
+ }
+
+ scnprintf(name, TEE_UUID_NS_NAME_SIZE, "gid=%x", grp.val);
+ break;
+
+ default:
+ rc = -EINVAL;
+ goto out;
+ }
+
+ rc = uuid_v5(uuid, &tee_client_uuid_ns, name, strlen(name));
+out:
+ kfree(name);
+
+ return rc;
+}
+EXPORT_SYMBOL_GPL(tee_session_calc_client_uuid);
+
static int tee_ioctl_version(struct tee_context *ctx,
struct tee_ioctl_version_data __user *uvers)
{
diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h
index 7a03f68fb982..545a57f61a5e 100644
--- a/include/linux/tee_drv.h
+++ b/include/linux/tee_drv.h
@@ -166,6 +166,22 @@ int tee_device_register(struct tee_device *teedev);
*/
void tee_device_unregister(struct tee_device *teedev);
+/**
+ * tee_session_calc_client_uuid() - Calculates client UUID for session
+ * @uuid: Resulting UUID
+ * @connection_method: Connection method for session (TEE_IOCTL_LOGIN_*)
+ * @connectuon_data: Connection data for opening session
+ *
+ * Based on connection method calculates UUIDv5 based client UUID.
+ *
+ * For group based logins verifies that calling process has specified
+ * credentials.
+ *
+ * @return < 0 on failure
+ */
+int tee_session_calc_client_uuid(uuid_t *uuid, u32 connection_method,
+ const u8 connection_data[TEE_IOCTL_UUID_LEN]);
+
/**
* struct tee_shm - shared memory object
* @teedev: device used to allocate the object
--
2.26.2
@@ -0,0 +1,43 @@
Upstream-Status: Backport [https://github.com/linaro-swg/linux/commit/c5b4312bea5d5e5e3d4f0af640e2ef8a1c1bb167#diff-2d83bca4adf0468bdb51b155a5df495e0226f7971f4150cfffbf043fe3b5a279]
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
From c6c4046d8fcd34a4b8da9d844ce592951780ba8c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Vesa=20J=C3=A4=C3=A4skel=C3=A4inen?=
<vesa.jaaskelainen@vaisala.com>
Date: Wed, 22 Apr 2020 15:30:39 +0300
Subject: [PATCH] tee: optee: Add support for session login client UUID
generation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Adds support for client UUID generation for OP-TEE. For group based session
logins membership is verified.
Signed-off-by: Vesa Jääskeläinen <vesa.jaaskelainen@vaisala.com>
---
drivers/tee/optee/call.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
index cf2367ba08d6..dbed3f480dc0 100644
--- a/drivers/tee/optee/call.c
+++ b/drivers/tee/optee/call.c
@@ -233,9 +233,13 @@ int optee_open_session(struct tee_context *ctx,
msg_arg->params[1].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT |
OPTEE_MSG_ATTR_META;
memcpy(&msg_arg->params[0].u.value, arg->uuid, sizeof(arg->uuid));
- memcpy(&msg_arg->params[1].u.value, arg->uuid, sizeof(arg->clnt_uuid));
msg_arg->params[1].u.value.c = arg->clnt_login;
+ rc = tee_session_calc_client_uuid((uuid_t *)&msg_arg->params[1].u.value,
+ arg->clnt_login, arg->clnt_uuid);
+ if (rc)
+ goto out;
+
rc = optee_to_msg_param(msg_arg->params + 2, arg->num_params, param);
if (rc)
goto out;
--
2.26.2
@@ -0,0 +1,51 @@
From 957e0145899813017a6a2b7f863a4a2b4e4b75aa Mon Sep 17 00:00:00 2001
From: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Date: Tue, 5 Jan 2021 09:27:41 +0000
Subject: [PATCH] tee: optee: fix mem handle removal in ffa_shm_unregister
Remove ffa memory handle before calling mem_reclaim. This enables the
handle to be re-used by another thread once mem_claim for that handle
is completed.
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Change-Id: I7294bd71f2bbc28514eaa09ae757dd216bc7df45
Upstream-Status: Pending [Not submitted to upstream yet]
---
drivers/tee/optee/call.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
index ac89ab42a43f..9c9480add0b5 100644
--- a/drivers/tee/optee/call.c
+++ b/drivers/tee/optee/call.c
@@ -843,6 +843,10 @@ int optee_ffa_shm_unregister_supp(struct tee_context *ctx,
{
struct optee *optee = tee_get_drvdata(ctx->teedev);
int rc = 0;
+ u64 handle = shm->sec_world_id;
+
+ optee_shm_rem_ffa_handle(optee, handle);
+ shm->sec_world_id = 0;
/*
* We're skipping the OPTEE_FFA_YIELDING_CALL_UNREGISTER_SHM call
@@ -850,14 +854,10 @@ int optee_ffa_shm_unregister_supp(struct tee_context *ctx,
* this ID.
*/
- rc = optee->ffa.ops->mem_reclaim(shm->sec_world_id, 0);
+ rc = optee->ffa.ops->mem_reclaim(handle, 0);
if (rc)
pr_err("mem_reclain: %d", rc);
- optee_shm_rem_ffa_handle(optee, shm->sec_world_id);
-
- shm->sec_world_id = 0;
-
return rc;
}
#endif /*CONFIG_ARM_FFA_TRANSPORT*/
--
2.26.2