mirror of
https://git.yoctoproject.org/meta-arm
synced 2026-07-26 07:07:16 +00:00
980f559e87
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>
253 lines
6.8 KiB
Diff
253 lines
6.8 KiB
Diff
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
|
|
|