From: Jeshwanth Kumar N K <JESHWANTHKUMAR.NK(a)amd.com>
At present, the shared memory for TEE ring buffer, command buffer and
data buffer is allocated using get_free_pages(). The driver shares the
physical address of these buffers with PSP so that it can be mapped by
the Trusted OS.
In this patch series we have replaced get_free_pages() with
dma_alloc_coherent() to allocate shared memory to cleanup the existing
allocation method.
Rijo Thomas (3):
crypto: ccp - Add function to allocate and free memory using DMA APIs
crypto: ccp - Use psp_tee_alloc_buffer() and psp_tee_free_buffer()
tee: amdtee: Use psp_tee_alloc_buffer() and psp_tee_free_buffer()
drivers/crypto/ccp/psp-dev.c | 3 +
drivers/crypto/ccp/tee-dev.c | 119 ++++++++++++++++++----------
drivers/crypto/ccp/tee-dev.h | 11 +--
drivers/tee/amdtee/amdtee_private.h | 18 ++---
drivers/tee/amdtee/call.c | 74 ++++++++---------
drivers/tee/amdtee/core.c | 72 ++++++++++-------
drivers/tee/amdtee/shm_pool.c | 21 ++---
include/linux/psp-tee.h | 47 +++++++++++
8 files changed, 221 insertions(+), 144 deletions(-)
--
2.25.1
Add a separate documentation directory for TEE subsystem since it is a
standalone subsystem which already offers devices consumed by multiple
different subsystem drivers.
Split overall TEE subsystem documentation modularly where the first
module covers the overview of TEE subsystem itself along with generic
features. Then the further modules are dedicated to different TEE
implementations like:
- OP-TEE
- AMD-TEE
- and so on for future TEE implementation support.
Signed-off-by: Sumit Garg <sumit.garg(a)linaro.org>
---
Documentation/staging/index.rst | 1 -
Documentation/staging/tee.rst | 364 -------------------------------
Documentation/subsystem-apis.rst | 1 +
Documentation/tee/amd-tee.rst | 90 ++++++++
Documentation/tee/index.rst | 19 ++
Documentation/tee/op-tee.rst | 166 ++++++++++++++
Documentation/tee/tee.rst | 122 +++++++++++
MAINTAINERS | 2 +-
8 files changed, 399 insertions(+), 366 deletions(-)
delete mode 100644 Documentation/staging/tee.rst
create mode 100644 Documentation/tee/amd-tee.rst
create mode 100644 Documentation/tee/index.rst
create mode 100644 Documentation/tee/op-tee.rst
create mode 100644 Documentation/tee/tee.rst
diff --git a/Documentation/staging/index.rst b/Documentation/staging/index.rst
index ded8254bc0d7..71592f3ce89b 100644
--- a/Documentation/staging/index.rst
+++ b/Documentation/staging/index.rst
@@ -12,5 +12,4 @@ Unsorted Documentation
rpmsg
speculation
static-keys
- tee
xz
diff --git a/Documentation/staging/tee.rst b/Documentation/staging/tee.rst
deleted file mode 100644
index 22baa077a3b9..000000000000
--- a/Documentation/staging/tee.rst
+++ /dev/null
@@ -1,364 +0,0 @@
-=============
-TEE subsystem
-=============
-
-This document describes the TEE subsystem in Linux.
-
-A TEE (Trusted Execution Environment) is a trusted OS running in some
-secure environment, for example, TrustZone on ARM CPUs, or a separate
-secure co-processor etc. A TEE driver handles the details needed to
-communicate with the TEE.
-
-This subsystem deals with:
-
-- Registration of TEE drivers
-
-- Managing shared memory between Linux and the TEE
-
-- Providing a generic API to the TEE
-
-The TEE interface
-=================
-
-include/uapi/linux/tee.h defines the generic interface to a TEE.
-
-User space (the client) connects to the driver by opening /dev/tee[0-9]* or
-/dev/teepriv[0-9]*.
-
-- TEE_IOC_SHM_ALLOC allocates shared memory and returns a file descriptor
- which user space can mmap. When user space doesn't need the file
- descriptor any more, it should be closed. When shared memory isn't needed
- any longer it should be unmapped with munmap() to allow the reuse of
- memory.
-
-- TEE_IOC_VERSION lets user space know which TEE this driver handles and
- its capabilities.
-
-- TEE_IOC_OPEN_SESSION opens a new session to a Trusted Application.
-
-- TEE_IOC_INVOKE invokes a function in a Trusted Application.
-
-- TEE_IOC_CANCEL may cancel an ongoing TEE_IOC_OPEN_SESSION or TEE_IOC_INVOKE.
-
-- TEE_IOC_CLOSE_SESSION closes a session to a Trusted Application.
-
-There are two classes of clients, normal clients and supplicants. The latter is
-a helper process for the TEE to access resources in Linux, for example file
-system access. A normal client opens /dev/tee[0-9]* and a supplicant opens
-/dev/teepriv[0-9].
-
-Much of the communication between clients and the TEE is opaque to the
-driver. The main job for the driver is to receive requests from the
-clients, forward them to the TEE and send back the results. In the case of
-supplicants the communication goes in the other direction, the TEE sends
-requests to the supplicant which then sends back the result.
-
-The TEE kernel interface
-========================
-
-Kernel provides a TEE bus infrastructure where a Trusted Application is
-represented as a device identified via Universally Unique Identifier (UUID) and
-client drivers register a table of supported device UUIDs.
-
-TEE bus infrastructure registers following APIs:
-
-match():
- iterates over the client driver UUID table to find a corresponding
- match for device UUID. If a match is found, then this particular device is
- probed via corresponding probe API registered by the client driver. This
- process happens whenever a device or a client driver is registered with TEE
- bus.
-
-uevent():
- notifies user-space (udev) whenever a new device is registered on
- TEE bus for auto-loading of modularized client drivers.
-
-TEE bus device enumeration is specific to underlying TEE implementation, so it
-is left open for TEE drivers to provide corresponding implementation.
-
-Then TEE client driver can talk to a matched Trusted Application using APIs
-listed in include/linux/tee_drv.h.
-
-TEE client driver example
--------------------------
-
-Suppose a TEE client driver needs to communicate with a Trusted Application
-having UUID: ``ac6a4085-0e82-4c33-bf98-8eb8e118b6c2``, so driver registration
-snippet would look like::
-
- static const struct tee_client_device_id client_id_table[] = {
- {UUID_INIT(0xac6a4085, 0x0e82, 0x4c33,
- 0xbf, 0x98, 0x8e, 0xb8, 0xe1, 0x18, 0xb6, 0xc2)},
- {}
- };
-
- MODULE_DEVICE_TABLE(tee, client_id_table);
-
- static struct tee_client_driver client_driver = {
- .id_table = client_id_table,
- .driver = {
- .name = DRIVER_NAME,
- .bus = &tee_bus_type,
- .probe = client_probe,
- .remove = client_remove,
- },
- };
-
- static int __init client_init(void)
- {
- return driver_register(&client_driver.driver);
- }
-
- static void __exit client_exit(void)
- {
- driver_unregister(&client_driver.driver);
- }
-
- module_init(client_init);
- module_exit(client_exit);
-
-OP-TEE driver
-=============
-
-The OP-TEE driver handles OP-TEE [1] based TEEs. Currently it is only the ARM
-TrustZone based OP-TEE solution that is supported.
-
-Lowest level of communication with OP-TEE builds on ARM SMC Calling
-Convention (SMCCC) [2], which is the foundation for OP-TEE's SMC interface
-[3] used internally by the driver. Stacked on top of that is OP-TEE Message
-Protocol [4].
-
-OP-TEE SMC interface provides the basic functions required by SMCCC and some
-additional functions specific for OP-TEE. The most interesting functions are:
-
-- OPTEE_SMC_FUNCID_CALLS_UID (part of SMCCC) returns the version information
- which is then returned by TEE_IOC_VERSION
-
-- OPTEE_SMC_CALL_GET_OS_UUID returns the particular OP-TEE implementation, used
- to tell, for instance, a TrustZone OP-TEE apart from an OP-TEE running on a
- separate secure co-processor.
-
-- OPTEE_SMC_CALL_WITH_ARG drives the OP-TEE message protocol
-
-- OPTEE_SMC_GET_SHM_CONFIG lets the driver and OP-TEE agree on which memory
- range to used for shared memory between Linux and OP-TEE.
-
-The GlobalPlatform TEE Client API [5] is implemented on top of the generic
-TEE API.
-
-Picture of the relationship between the different components in the
-OP-TEE architecture::
-
- User space Kernel Secure world
- ~~~~~~~~~~ ~~~~~~ ~~~~~~~~~~~~
- +--------+ +-------------+
- | Client | | Trusted |
- +--------+ | Application |
- /\ +-------------+
- || +----------+ /\
- || |tee- | ||
- || |supplicant| \/
- || +----------+ +-------------+
- \/ /\ | TEE Internal|
- +-------+ || | API |
- + TEE | || +--------+--------+ +-------------+
- | Client| || | TEE | OP-TEE | | OP-TEE |
- | API | \/ | subsys | driver | | Trusted OS |
- +-------+----------------+----+-------+----+-----------+-------------+
- | Generic TEE API | | OP-TEE MSG |
- | IOCTL (TEE_IOC_*) | | SMCCC (OPTEE_SMC_CALL_*) |
- +-----------------------------+ +------------------------------+
-
-RPC (Remote Procedure Call) are requests from secure world to kernel driver
-or tee-supplicant. An RPC is identified by a special range of SMCCC return
-values from OPTEE_SMC_CALL_WITH_ARG. RPC messages which are intended for the
-kernel are handled by the kernel driver. Other RPC messages will be forwarded to
-tee-supplicant without further involvement of the driver, except switching
-shared memory buffer representation.
-
-OP-TEE device enumeration
--------------------------
-
-OP-TEE provides a pseudo Trusted Application: drivers/tee/optee/device.c in
-order to support device enumeration. In other words, OP-TEE driver invokes this
-application to retrieve a list of Trusted Applications which can be registered
-as devices on the TEE bus.
-
-OP-TEE notifications
---------------------
-
-There are two kinds of notifications that secure world can use to make
-normal world aware of some event.
-
-1. Synchronous notifications delivered with ``OPTEE_RPC_CMD_NOTIFICATION``
- using the ``OPTEE_RPC_NOTIFICATION_SEND`` parameter.
-2. Asynchronous notifications delivered with a combination of a non-secure
- edge-triggered interrupt and a fast call from the non-secure interrupt
- handler.
-
-Synchronous notifications are limited by depending on RPC for delivery,
-this is only usable when secure world is entered with a yielding call via
-``OPTEE_SMC_CALL_WITH_ARG``. This excludes such notifications from secure
-world interrupt handlers.
-
-An asynchronous notification is delivered via a non-secure edge-triggered
-interrupt to an interrupt handler registered in the OP-TEE driver. The
-actual notification value are retrieved with the fast call
-``OPTEE_SMC_GET_ASYNC_NOTIF_VALUE``. Note that one interrupt can represent
-multiple notifications.
-
-One notification value ``OPTEE_SMC_ASYNC_NOTIF_VALUE_DO_BOTTOM_HALF`` has a
-special meaning. When this value is received it means that normal world is
-supposed to make a yielding call ``OPTEE_MSG_CMD_DO_BOTTOM_HALF``. This
-call is done from the thread assisting the interrupt handler. This is a
-building block for OP-TEE OS in secure world to implement the top half and
-bottom half style of device drivers.
-
-OPTEE_INSECURE_LOAD_IMAGE Kconfig option
-----------------------------------------
-
-The OPTEE_INSECURE_LOAD_IMAGE Kconfig option enables the ability to load the
-BL32 OP-TEE image from the kernel after the kernel boots, rather than loading
-it from the firmware before the kernel boots. This also requires enabling the
-corresponding option in Trusted Firmware for Arm. The Trusted Firmware for Arm
-documentation [8] explains the security threat associated with enabling this as
-well as mitigations at the firmware and platform level.
-
-There are additional attack vectors/mitigations for the kernel that should be
-addressed when using this option.
-
-1. Boot chain security.
-
- * Attack vector: Replace the OP-TEE OS image in the rootfs to gain control of
- the system.
-
- * Mitigation: There must be boot chain security that verifies the kernel and
- rootfs, otherwise an attacker can modify the loaded OP-TEE binary by
- modifying it in the rootfs.
-
-2. Alternate boot modes.
-
- * Attack vector: Using an alternate boot mode (i.e. recovery mode), the
- OP-TEE driver isn't loaded, leaving the SMC hole open.
-
- * Mitigation: If there are alternate methods of booting the device, such as a
- recovery mode, it should be ensured that the same mitigations are applied
- in that mode.
-
-3. Attacks prior to SMC invocation.
-
- * Attack vector: Code that is executed prior to issuing the SMC call to load
- OP-TEE can be exploited to then load an alternate OS image.
-
- * Mitigation: The OP-TEE driver must be loaded before any potential attack
- vectors are opened up. This should include mounting of any modifiable
- filesystems, opening of network ports or communicating with external
- devices (e.g. USB).
-
-4. Blocking SMC call to load OP-TEE.
-
- * Attack vector: Prevent the driver from being probed, so the SMC call to
- load OP-TEE isn't executed when desired, leaving it open to being executed
- later and loading a modified OS.
-
- * Mitigation: It is recommended to build the OP-TEE driver as builtin driver
- rather than as a module to prevent exploits that may cause the module to
- not be loaded.
-
-AMD-TEE driver
-==============
-
-The AMD-TEE driver handles the communication with AMD's TEE environment. The
-TEE environment is provided by AMD Secure Processor.
-
-The AMD Secure Processor (formerly called Platform Security Processor or PSP)
-is a dedicated processor that features ARM TrustZone technology, along with a
-software-based Trusted Execution Environment (TEE) designed to enable
-third-party Trusted Applications. This feature is currently enabled only for
-APUs.
-
-The following picture shows a high level overview of AMD-TEE::
-
- |
- x86 |
- |
- User space (Kernel space) | AMD Secure Processor (PSP)
- ~~~~~~~~~~ ~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~~~~~~
- |
- +--------+ | +-------------+
- | Client | | | Trusted |
- +--------+ | | Application |
- /\ | +-------------+
- || | /\
- || | ||
- || | \/
- || | +----------+
- || | | TEE |
- || | | Internal |
- \/ | | API |
- +---------+ +-----------+---------+ +----------+
- | TEE | | TEE | AMD-TEE | | AMD-TEE |
- | Client | | subsystem | driver | | Trusted |
- | API | | | | | OS |
- +---------+-----------+----+------+---------+---------+----------+
- | Generic TEE API | | ASP | Mailbox |
- | IOCTL (TEE_IOC_*) | | driver | Register Protocol |
- +--------------------------+ +---------+--------------------+
-
-At the lowest level (in x86), the AMD Secure Processor (ASP) driver uses the
-CPU to PSP mailbox register to submit commands to the PSP. The format of the
-command buffer is opaque to the ASP driver. It's role is to submit commands to
-the secure processor and return results to AMD-TEE driver. The interface
-between AMD-TEE driver and AMD Secure Processor driver can be found in [6].
-
-The AMD-TEE driver packages the command buffer payload for processing in TEE.
-The command buffer format for the different TEE commands can be found in [7].
-
-The TEE commands supported by AMD-TEE Trusted OS are:
-
-* TEE_CMD_ID_LOAD_TA - loads a Trusted Application (TA) binary into
- TEE environment.
-* TEE_CMD_ID_UNLOAD_TA - unloads TA binary from TEE environment.
-* TEE_CMD_ID_OPEN_SESSION - opens a session with a loaded TA.
-* TEE_CMD_ID_CLOSE_SESSION - closes session with loaded TA
-* TEE_CMD_ID_INVOKE_CMD - invokes a command with loaded TA
-* TEE_CMD_ID_MAP_SHARED_MEM - maps shared memory
-* TEE_CMD_ID_UNMAP_SHARED_MEM - unmaps shared memory
-
-AMD-TEE Trusted OS is the firmware running on AMD Secure Processor.
-
-The AMD-TEE driver registers itself with TEE subsystem and implements the
-following driver function callbacks:
-
-* get_version - returns the driver implementation id and capability.
-* open - sets up the driver context data structure.
-* release - frees up driver resources.
-* open_session - loads the TA binary and opens session with loaded TA.
-* close_session - closes session with loaded TA and unloads it.
-* invoke_func - invokes a command with loaded TA.
-
-cancel_req driver callback is not supported by AMD-TEE.
-
-The GlobalPlatform TEE Client API [5] can be used by the user space (client) to
-talk to AMD's TEE. AMD's TEE provides a secure environment for loading, opening
-a session, invoking commands and closing session with TA.
-
-References
-==========
-
-[1] https://github.com/OP-TEE/optee_os
-
-[2] http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
-
-[3] drivers/tee/optee/optee_smc.h
-
-[4] drivers/tee/optee/optee_msg.h
-
-[5] http://www.globalplatform.org/specificationsdevice.asp look for
- "TEE Client API Specification v1.0" and click download.
-
-[6] include/linux/psp-tee.h
-
-[7] drivers/tee/amdtee/amdtee_if.h
-
-[8] https://trustedfirmware-a.readthedocs.io/en/latest/threat_model/threat_mode…
diff --git a/Documentation/subsystem-apis.rst b/Documentation/subsystem-apis.rst
index 90a0535a932a..1666f11de8df 100644
--- a/Documentation/subsystem-apis.rst
+++ b/Documentation/subsystem-apis.rst
@@ -86,3 +86,4 @@ Storage interfaces
misc-devices/index
peci/index
wmi/index
+ tee/index
diff --git a/Documentation/tee/amd-tee.rst b/Documentation/tee/amd-tee.rst
new file mode 100644
index 000000000000..51500fde7038
--- /dev/null
+++ b/Documentation/tee/amd-tee.rst
@@ -0,0 +1,90 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=============================================
+AMD-TEE (AMD's Trusted Execution Environment)
+=============================================
+
+The AMD-TEE driver handles the communication with AMD's TEE environment. The
+TEE environment is provided by AMD Secure Processor.
+
+The AMD Secure Processor (formerly called Platform Security Processor or PSP)
+is a dedicated processor that features ARM TrustZone technology, along with a
+software-based Trusted Execution Environment (TEE) designed to enable
+third-party Trusted Applications. This feature is currently enabled only for
+APUs.
+
+The following picture shows a high level overview of AMD-TEE::
+
+ |
+ x86 |
+ |
+ User space (Kernel space) | AMD Secure Processor (PSP)
+ ~~~~~~~~~~ ~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ |
+ +--------+ | +-------------+
+ | Client | | | Trusted |
+ +--------+ | | Application |
+ /\ | +-------------+
+ || | /\
+ || | ||
+ || | \/
+ || | +----------+
+ || | | TEE |
+ || | | Internal |
+ \/ | | API |
+ +---------+ +-----------+---------+ +----------+
+ | TEE | | TEE | AMD-TEE | | AMD-TEE |
+ | Client | | subsystem | driver | | Trusted |
+ | API | | | | | OS |
+ +---------+-----------+----+------+---------+---------+----------+
+ | Generic TEE API | | ASP | Mailbox |
+ | IOCTL (TEE_IOC_*) | | driver | Register Protocol |
+ +--------------------------+ +---------+--------------------+
+
+At the lowest level (in x86), the AMD Secure Processor (ASP) driver uses the
+CPU to PSP mailbox register to submit commands to the PSP. The format of the
+command buffer is opaque to the ASP driver. It's role is to submit commands to
+the secure processor and return results to AMD-TEE driver. The interface
+between AMD-TEE driver and AMD Secure Processor driver can be found in [1].
+
+The AMD-TEE driver packages the command buffer payload for processing in TEE.
+The command buffer format for the different TEE commands can be found in [2].
+
+The TEE commands supported by AMD-TEE Trusted OS are:
+
+* TEE_CMD_ID_LOAD_TA - loads a Trusted Application (TA) binary into
+ TEE environment.
+* TEE_CMD_ID_UNLOAD_TA - unloads TA binary from TEE environment.
+* TEE_CMD_ID_OPEN_SESSION - opens a session with a loaded TA.
+* TEE_CMD_ID_CLOSE_SESSION - closes session with loaded TA
+* TEE_CMD_ID_INVOKE_CMD - invokes a command with loaded TA
+* TEE_CMD_ID_MAP_SHARED_MEM - maps shared memory
+* TEE_CMD_ID_UNMAP_SHARED_MEM - unmaps shared memory
+
+AMD-TEE Trusted OS is the firmware running on AMD Secure Processor.
+
+The AMD-TEE driver registers itself with TEE subsystem and implements the
+following driver function callbacks:
+
+* get_version - returns the driver implementation id and capability.
+* open - sets up the driver context data structure.
+* release - frees up driver resources.
+* open_session - loads the TA binary and opens session with loaded TA.
+* close_session - closes session with loaded TA and unloads it.
+* invoke_func - invokes a command with loaded TA.
+
+cancel_req driver callback is not supported by AMD-TEE.
+
+The GlobalPlatform TEE Client API [3] can be used by the user space (client) to
+talk to AMD's TEE. AMD's TEE provides a secure environment for loading, opening
+a session, invoking commands and closing session with TA.
+
+References
+==========
+
+[1] include/linux/psp-tee.h
+
+[2] drivers/tee/amdtee/amdtee_if.h
+
+[3] http://www.globalplatform.org/specificationsdevice.asp look for
+ "TEE Client API Specification v1.0" and click download.
diff --git a/Documentation/tee/index.rst b/Documentation/tee/index.rst
new file mode 100644
index 000000000000..a23bd08847e5
--- /dev/null
+++ b/Documentation/tee/index.rst
@@ -0,0 +1,19 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=============
+TEE Subsystem
+=============
+
+.. toctree::
+ :maxdepth: 1
+
+ tee
+ op-tee
+ amd-tee
+
+.. only:: subproject and html
+
+ Indices
+ =======
+
+ * :ref:`genindex`
diff --git a/Documentation/tee/op-tee.rst b/Documentation/tee/op-tee.rst
new file mode 100644
index 000000000000..b0ac097d5547
--- /dev/null
+++ b/Documentation/tee/op-tee.rst
@@ -0,0 +1,166 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+====================================================
+OP-TEE (Open Portable Trusted Execution Environment)
+====================================================
+
+The OP-TEE driver handles OP-TEE [1] based TEEs. Currently it is only the ARM
+TrustZone based OP-TEE solution that is supported.
+
+Lowest level of communication with OP-TEE builds on ARM SMC Calling
+Convention (SMCCC) [2], which is the foundation for OP-TEE's SMC interface
+[3] used internally by the driver. Stacked on top of that is OP-TEE Message
+Protocol [4].
+
+OP-TEE SMC interface provides the basic functions required by SMCCC and some
+additional functions specific for OP-TEE. The most interesting functions are:
+
+- OPTEE_SMC_FUNCID_CALLS_UID (part of SMCCC) returns the version information
+ which is then returned by TEE_IOC_VERSION
+
+- OPTEE_SMC_CALL_GET_OS_UUID returns the particular OP-TEE implementation, used
+ to tell, for instance, a TrustZone OP-TEE apart from an OP-TEE running on a
+ separate secure co-processor.
+
+- OPTEE_SMC_CALL_WITH_ARG drives the OP-TEE message protocol
+
+- OPTEE_SMC_GET_SHM_CONFIG lets the driver and OP-TEE agree on which memory
+ range to used for shared memory between Linux and OP-TEE.
+
+The GlobalPlatform TEE Client API [5] is implemented on top of the generic
+TEE API.
+
+Picture of the relationship between the different components in the
+OP-TEE architecture::
+
+ User space Kernel Secure world
+ ~~~~~~~~~~ ~~~~~~ ~~~~~~~~~~~~
+ +--------+ +-------------+
+ | Client | | Trusted |
+ +--------+ | Application |
+ /\ +-------------+
+ || +----------+ /\
+ || |tee- | ||
+ || |supplicant| \/
+ || +----------+ +-------------+
+ \/ /\ | TEE Internal|
+ +-------+ || | API |
+ + TEE | || +--------+--------+ +-------------+
+ | Client| || | TEE | OP-TEE | | OP-TEE |
+ | API | \/ | subsys | driver | | Trusted OS |
+ +-------+----------------+----+-------+----+-----------+-------------+
+ | Generic TEE API | | OP-TEE MSG |
+ | IOCTL (TEE_IOC_*) | | SMCCC (OPTEE_SMC_CALL_*) |
+ +-----------------------------+ +------------------------------+
+
+RPC (Remote Procedure Call) are requests from secure world to kernel driver
+or tee-supplicant. An RPC is identified by a special range of SMCCC return
+values from OPTEE_SMC_CALL_WITH_ARG. RPC messages which are intended for the
+kernel are handled by the kernel driver. Other RPC messages will be forwarded to
+tee-supplicant without further involvement of the driver, except switching
+shared memory buffer representation.
+
+OP-TEE device enumeration
+-------------------------
+
+OP-TEE provides a pseudo Trusted Application: drivers/tee/optee/device.c in
+order to support device enumeration. In other words, OP-TEE driver invokes this
+application to retrieve a list of Trusted Applications which can be registered
+as devices on the TEE bus.
+
+OP-TEE notifications
+--------------------
+
+There are two kinds of notifications that secure world can use to make
+normal world aware of some event.
+
+1. Synchronous notifications delivered with ``OPTEE_RPC_CMD_NOTIFICATION``
+ using the ``OPTEE_RPC_NOTIFICATION_SEND`` parameter.
+2. Asynchronous notifications delivered with a combination of a non-secure
+ edge-triggered interrupt and a fast call from the non-secure interrupt
+ handler.
+
+Synchronous notifications are limited by depending on RPC for delivery,
+this is only usable when secure world is entered with a yielding call via
+``OPTEE_SMC_CALL_WITH_ARG``. This excludes such notifications from secure
+world interrupt handlers.
+
+An asynchronous notification is delivered via a non-secure edge-triggered
+interrupt to an interrupt handler registered in the OP-TEE driver. The
+actual notification value are retrieved with the fast call
+``OPTEE_SMC_GET_ASYNC_NOTIF_VALUE``. Note that one interrupt can represent
+multiple notifications.
+
+One notification value ``OPTEE_SMC_ASYNC_NOTIF_VALUE_DO_BOTTOM_HALF`` has a
+special meaning. When this value is received it means that normal world is
+supposed to make a yielding call ``OPTEE_MSG_CMD_DO_BOTTOM_HALF``. This
+call is done from the thread assisting the interrupt handler. This is a
+building block for OP-TEE OS in secure world to implement the top half and
+bottom half style of device drivers.
+
+OPTEE_INSECURE_LOAD_IMAGE Kconfig option
+----------------------------------------
+
+The OPTEE_INSECURE_LOAD_IMAGE Kconfig option enables the ability to load the
+BL32 OP-TEE image from the kernel after the kernel boots, rather than loading
+it from the firmware before the kernel boots. This also requires enabling the
+corresponding option in Trusted Firmware for Arm. The Trusted Firmware for Arm
+documentation [6] explains the security threat associated with enabling this as
+well as mitigations at the firmware and platform level.
+
+There are additional attack vectors/mitigations for the kernel that should be
+addressed when using this option.
+
+1. Boot chain security.
+
+ * Attack vector: Replace the OP-TEE OS image in the rootfs to gain control of
+ the system.
+
+ * Mitigation: There must be boot chain security that verifies the kernel and
+ rootfs, otherwise an attacker can modify the loaded OP-TEE binary by
+ modifying it in the rootfs.
+
+2. Alternate boot modes.
+
+ * Attack vector: Using an alternate boot mode (i.e. recovery mode), the
+ OP-TEE driver isn't loaded, leaving the SMC hole open.
+
+ * Mitigation: If there are alternate methods of booting the device, such as a
+ recovery mode, it should be ensured that the same mitigations are applied
+ in that mode.
+
+3. Attacks prior to SMC invocation.
+
+ * Attack vector: Code that is executed prior to issuing the SMC call to load
+ OP-TEE can be exploited to then load an alternate OS image.
+
+ * Mitigation: The OP-TEE driver must be loaded before any potential attack
+ vectors are opened up. This should include mounting of any modifiable
+ filesystems, opening of network ports or communicating with external
+ devices (e.g. USB).
+
+4. Blocking SMC call to load OP-TEE.
+
+ * Attack vector: Prevent the driver from being probed, so the SMC call to
+ load OP-TEE isn't executed when desired, leaving it open to being executed
+ later and loading a modified OS.
+
+ * Mitigation: It is recommended to build the OP-TEE driver as builtin driver
+ rather than as a module to prevent exploits that may cause the module to
+ not be loaded.
+
+References
+==========
+
+[1] https://github.com/OP-TEE/optee_os
+
+[2] http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
+
+[3] drivers/tee/optee/optee_smc.h
+
+[4] drivers/tee/optee/optee_msg.h
+
+[5] http://www.globalplatform.org/specificationsdevice.asp look for
+ "TEE Client API Specification v1.0" and click download.
+
+[6] https://trustedfirmware-a.readthedocs.io/en/latest/threat_model/threat_mode…
diff --git a/Documentation/tee/tee.rst b/Documentation/tee/tee.rst
new file mode 100644
index 000000000000..3a5ff925edb5
--- /dev/null
+++ b/Documentation/tee/tee.rst
@@ -0,0 +1,122 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===================================
+TEE (Trusted Execution Environment)
+===================================
+
+This document describes the TEE subsystem in Linux.
+
+Overview
+========
+
+A TEE is a trusted OS running in some secure environment, for example,
+TrustZone on ARM CPUs, or a separate secure co-processor etc. A TEE driver
+handles the details needed to communicate with the TEE.
+
+This subsystem deals with:
+
+- Registration of TEE drivers
+
+- Managing shared memory between Linux and the TEE
+
+- Providing a generic API to the TEE
+
+The TEE interface
+=================
+
+include/uapi/linux/tee.h defines the generic interface to a TEE.
+
+User space (the client) connects to the driver by opening /dev/tee[0-9]* or
+/dev/teepriv[0-9]*.
+
+- TEE_IOC_SHM_ALLOC allocates shared memory and returns a file descriptor
+ which user space can mmap. When user space doesn't need the file
+ descriptor any more, it should be closed. When shared memory isn't needed
+ any longer it should be unmapped with munmap() to allow the reuse of
+ memory.
+
+- TEE_IOC_VERSION lets user space know which TEE this driver handles and
+ its capabilities.
+
+- TEE_IOC_OPEN_SESSION opens a new session to a Trusted Application.
+
+- TEE_IOC_INVOKE invokes a function in a Trusted Application.
+
+- TEE_IOC_CANCEL may cancel an ongoing TEE_IOC_OPEN_SESSION or TEE_IOC_INVOKE.
+
+- TEE_IOC_CLOSE_SESSION closes a session to a Trusted Application.
+
+There are two classes of clients, normal clients and supplicants. The latter is
+a helper process for the TEE to access resources in Linux, for example file
+system access. A normal client opens /dev/tee[0-9]* and a supplicant opens
+/dev/teepriv[0-9].
+
+Much of the communication between clients and the TEE is opaque to the
+driver. The main job for the driver is to receive requests from the
+clients, forward them to the TEE and send back the results. In the case of
+supplicants the communication goes in the other direction, the TEE sends
+requests to the supplicant which then sends back the result.
+
+The TEE kernel interface
+========================
+
+Kernel provides a TEE bus infrastructure where a Trusted Application is
+represented as a device identified via Universally Unique Identifier (UUID) and
+client drivers register a table of supported device UUIDs.
+
+TEE bus infrastructure registers following APIs:
+
+match():
+ iterates over the client driver UUID table to find a corresponding
+ match for device UUID. If a match is found, then this particular device is
+ probed via corresponding probe API registered by the client driver. This
+ process happens whenever a device or a client driver is registered with TEE
+ bus.
+
+uevent():
+ notifies user-space (udev) whenever a new device is registered on
+ TEE bus for auto-loading of modularized client drivers.
+
+TEE bus device enumeration is specific to underlying TEE implementation, so it
+is left open for TEE drivers to provide corresponding implementation.
+
+Then TEE client driver can talk to a matched Trusted Application using APIs
+listed in include/linux/tee_drv.h.
+
+TEE client driver example
+-------------------------
+
+Suppose a TEE client driver needs to communicate with a Trusted Application
+having UUID: ``ac6a4085-0e82-4c33-bf98-8eb8e118b6c2``, so driver registration
+snippet would look like::
+
+ static const struct tee_client_device_id client_id_table[] = {
+ {UUID_INIT(0xac6a4085, 0x0e82, 0x4c33,
+ 0xbf, 0x98, 0x8e, 0xb8, 0xe1, 0x18, 0xb6, 0xc2)},
+ {}
+ };
+
+ MODULE_DEVICE_TABLE(tee, client_id_table);
+
+ static struct tee_client_driver client_driver = {
+ .id_table = client_id_table,
+ .driver = {
+ .name = DRIVER_NAME,
+ .bus = &tee_bus_type,
+ .probe = client_probe,
+ .remove = client_remove,
+ },
+ };
+
+ static int __init client_init(void)
+ {
+ return driver_register(&client_driver.driver);
+ }
+
+ static void __exit client_exit(void)
+ {
+ driver_unregister(&client_driver.driver);
+ }
+
+ module_init(client_init);
+ module_exit(client_exit);
diff --git a/MAINTAINERS b/MAINTAINERS
index dd5de540ec0b..81210663770b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21130,7 +21130,7 @@ M: Jens Wiklander <jens.wiklander(a)linaro.org>
R: Sumit Garg <sumit.garg(a)linaro.org>
L: op-tee(a)lists.trustedfirmware.org
S: Maintained
-F: Documentation/staging/tee.rst
+F: Documentation/tee/
F: drivers/tee/
F: include/linux/tee_drv.h
F: include/uapi/linux/tee.h
--
2.34.1
When calling TEE_InvokeTACommand() with a non-NULL memref of size
zero, function tee_svc_copy_param() will return
TEE_ERROR_BAD_PARAMETERS resulting in a panic later on.
In regard to the TEE_PARAM_TYPE_MEMREF_{INPUT,OUTPUT,INOUT} types, the
Global Platform specification says [1]:
params[i].memref.size SHALL be initialized with a memory buffer that
is accessible with the access rights described in the type. The
buffer can be NULL, in which case size SHALL be set to 0 .
Note that the specification only specifies that NULL implies a size of
zero. The reciprocal: "a size of zero implies NULL" is undefined.
It is even more confusing considering that non-NULL buffer with a size
of zero are explicitly allowed by the client API [2]:
This design allows a non-NULL buffer with a size of 0 bytes to allow
trivial integration with any implementations of the C library
malloc, in which is valid to allocate a zero byte buffer and receive
a non-NULL pointer which may not be de-referenced in return.
This could become a pitfall if a TA forwards a memref received from
the REE to another TA.
Allow the TAs to pass non-NULL memref of size zero to other TAs
through TEE_InvokeTACommand() by changing the non-NULL pointer into a
NULL one in such a case.
[1] TEE Internal Core API Specification – Public Release v1.3.1,
§4.9.4 "Operation Parameters in the Internal Client API"
Table 4-15: "Interpretation of params[i] on Entry to Internal Client API"
[2] TEE Client API Specification v1.0,
§4.5.4 TEEC_RegisterSharedMemory,
paragraph "Implementers' Notes"
Signed-off-by: Vincent Mailhol <mailhol.vincent(a)wanadoo.fr>
---
core/tee/tee_svc.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/core/tee/tee_svc.c b/core/tee/tee_svc.c
index f4158dca1..237a27de9 100644
--- a/core/tee/tee_svc.c
+++ b/core/tee/tee_svc.c
@@ -700,11 +700,13 @@ static TEE_Result tee_svc_copy_param(struct ts_session *sess,
case TEE_PARAM_TYPE_MEMREF_INOUT:
va = (void *)param->u[n].mem.offs;
s = param->u[n].mem.size;
- if (!va) {
- if (s)
- return TEE_ERROR_BAD_PARAMETERS;
+ if (!s) {
+ param->u[n].mem.mobj = NULL;
break;
}
+ if (!va)
+ return TEE_ERROR_BAD_PARAMETERS;
+
/* uTA cannot expose its private memory */
if (vm_buf_is_inside_um_private(&utc->uctx, va, s))
return TEE_ERROR_BAD_PARAMETERS;
--
2.25.1
This series introduces TEE system sessions for TEE service sessions that
require TEE to provision resources to prevent deadlock when clients call
the TEE.
This deadlock situation can happen when a TEE service is used by low
level system resources as for example when Linux kernel uses SCMI
service embedded in TEE for clock, reset, regulator, etc... controls.
This case is detailled in patch 2/4:
> This feature is needed to prevent a system deadlock when several TEE
> client applications invoke TEE, consuming all TEE thread contexts
> available in the secure world. The deadlock can happen in the OP-TEE
> driver for example if all these TEE threads issue an RPC call from TEE
> to Linux OS to access an eMMC RPMB partition (TEE secure storage) which
> device clock or regulator controller is accessed through an OP-TEE SCMI
> services. In that case, Linux SCMI driver must reach OP-TEE SCMI
> service without waiting until one of the consumed TEE threads is freed.
Etienne Carriere (4):
tee: optee: system call property
tee: system session
tee: optee: support tracking system threads
firmware: arm_scmi: optee: use optee system invocation
drivers/firmware/arm_scmi/optee.c | 4 +
drivers/tee/optee/call.c | 130 ++++++++++++++++++++++++++++--
drivers/tee/optee/core.c | 5 +-
drivers/tee/optee/ffa_abi.c | 13 +--
drivers/tee/optee/optee_private.h | 29 ++++++-
drivers/tee/optee/smc_abi.c | 31 ++++---
drivers/tee/tee_core.c | 8 ++
include/linux/tee_drv.h | 16 ++++
8 files changed, 209 insertions(+), 27 deletions(-)
---
Changes since v11:
- Changes patch 3/4, other are unchanged.
--
2.25.1
This series introduces the tee based EFI Runtime Variable Service.
The eMMC device is typically owned by the non-secure world(linux in
this case). There is an existing solution utilizing eMMC RPMB partition
for EFI Variables, it is implemented by interacting with
OP-TEE, StandaloneMM(as EFI Variable Service Pseudo TA), eMMC driver
and tee-supplicant. The last piece is the tee-based variable access
driver to interact with OP-TEE and StandaloneMM.
Changelog:
v7 -> v8
Only patch #3 "efi: Add tee-based EFI variable driver" is updated.
- fix typos
- refactor error handling, direct return if applicable
- use devm_add_action_or_reset() for closing of tee context/session
- remove obvious comment
v6 -> v7
Patch #1-#4 are not updated.
Patch #5 is added into this series, original patch is here:
https://lore.kernel.org/all/20230609094532.562934-1-ilias.apalodimas@linaro…
There are two issues in the v6 series and v7 series addresses those.
1) efivar ops is not restored when the tee-supplicant daemon terminates.
-> As the following patch says, user must remove the device before
terminating tee-supplicant daemon.
https://lore.kernel.org/all/20230728134832.326467-1-sumit.garg@linaro.org/
2) cause panic when someone remounts the efivarfs as RW even if
SetVariable is not supported
-> The fifth patch addresses this issue.
"[PATCH v7 5/5] efivarfs: force RO when remounting if SetVariable is
not supported"
v5 -> v6
- new patch #4 is added in this series, #1-#3 patches are unchanged.
automatically update super block flag when the efivarops support
SetVariable runtime service, so that user does not need to manually
remount the efivarfs as RW.
v4 -> v5
- rebase to efi-next based on v6.4-rc1
- set generic_ops.query_variable_info, it works as expected as follows.
$ df -h /sys/firmware/efi/efivars/
Filesystem Size Used Avail Use% Mounted on
efivarfs 16K 1.3K 15K 8% /sys/firmware/efi/efivars
v3 -> v4:
- replace the reference from EDK2 to PI Specification
- remove EDK2 source code reference comments
- prepare nonblocking variant of set_variable, it just returns
EFI_UNSUPPORTED
- remove redundant buffer size check
- argument name change in mm_communicate
- function interface changes in setup_mm_hdr to remove (void **) cast
v2 -> v3:
- add CONFIG_EFI dependency to TEE_STMM_EFI
- add missing return code check for tee_client_invoke_func()
- directly call efivars_register/unregister from tee_stmm_efi.c
rfc v1 -> v2:
- split patch into three patches, one for drivers/tee,
one for include/linux/efi.h, and one for the driver/firmware/efi/stmm
- context/session management into probe() and remove() same as other tee
client driver
- StMM variable driver is moved from driver/tee/optee to driver/firmware/efi
- use "tee" prefix instead of "optee" in driver/firmware/efi/stmm/tee_stmm_efi.c,
this file does not contain op-tee specific code, abstracted by tee layer and
StMM variable driver will work on other tee implementation.
- PTA_STMM_CMD_COMMUNICATE -> PTA_STMM_CMD_COMMUNICATE
- implement query_variable_store() but currently not used
- no use of TEEC_SUCCESS, it is defined in driver/tee/optee/optee_private.h.
Other tee client drivers use 0 instead of using TEEC_SUCCESS
- remove TEEC_ERROR_EXCESS_DATA status, it is referred just to output
error message
Ilias Apalodimas (1):
efivarfs: force RO when remounting if SetVariable is not supported
Masahisa Kojima (4):
efi: expose efivar generic ops register function
efi: Add EFI_ACCESS_DENIED status code
efi: Add tee-based EFI variable driver
efivarfs: automatically update super block flag
drivers/firmware/efi/Kconfig | 15 +
drivers/firmware/efi/Makefile | 1 +
drivers/firmware/efi/efi.c | 18 +
drivers/firmware/efi/stmm/mm_communication.h | 236 +++++++
drivers/firmware/efi/stmm/tee_stmm_efi.c | 612 +++++++++++++++++++
drivers/firmware/efi/vars.c | 8 +
fs/efivarfs/super.c | 45 ++
include/linux/efi.h | 12 +
8 files changed, 947 insertions(+)
create mode 100644 drivers/firmware/efi/stmm/mm_communication.h
create mode 100644 drivers/firmware/efi/stmm/tee_stmm_efi.c
base-commit: f6e6e95ce16205025b7b8680a66c30a0c4ec2270
--
2.30.2
Currently supplicant dependent optee device enumeration only registers
devices whenever tee-supplicant is invoked for the first time. But it
forgets to remove devices when tee-supplicant daemon stops running and
closes its context gracefully. This leads to following error for fTPM
driver during reboot/shutdown:
[ 73.466791] tpm tpm0: ftpm_tee_tpm_op_send: SUBMIT_COMMAND invoke error: 0xffff3024
Fix this by separating supplicant dependent devices so that the
user-space service can detach supplicant devices before closing the
supplicant. While at it use the global system workqueue for OP-TEE bus
scanning work rather than our own custom one.
Reported-by: Jan Kiszka <jan.kiszka(a)siemens.com>
Link: https://github.com/OP-TEE/optee_os/issues/6094
Fixes: 5f178bb71e3a ("optee: enable support for multi-stage bus enumeration")
Signed-off-by: Sumit Garg <sumit.garg(a)linaro.org>
---
Changes in v2:
Apologies for taking it too long push this v2. Actually I did brainstorm
how to best fix this tee-supplicant dependent device probing. Its hard
to predict the lifetime of user-space daemon from kernel space. So
following is the least intrusive approach:
- Use device names to seperate out tee-supplicant dependent devices via
this patch.
- Since user-space service is aware about tee-supplicant lifespan, so
allow the user-space service to unbind tee-supplicant dependent
devices before killing the supplicant. Following command has to be
added to the tee-supplicant service file.
$ for dev in /sys/bus/tee/devices/*; do if [[ "$dev" == *"optee-ta-supp-"* ]]; \
then echo $(basename "$dev") > $dev/driver/unbind; fi done
drivers/tee/optee/core.c | 13 ++-----------
drivers/tee/optee/device.c | 13 ++++++++++---
drivers/tee/optee/optee_private.h | 2 --
3 files changed, 12 insertions(+), 16 deletions(-)
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index d01ca47f7bde..8ee3c71bd989 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -15,7 +15,6 @@
#include <linux/string.h>
#include <linux/tee_drv.h>
#include <linux/types.h>
-#include <linux/workqueue.h>
#include "optee_private.h"
int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
@@ -110,12 +109,7 @@ int optee_open(struct tee_context *ctx, bool cap_memref_null)
if (!optee->scan_bus_done) {
INIT_WORK(&optee->scan_bus_work, optee_bus_scan);
- optee->scan_bus_wq = create_workqueue("optee_bus_scan");
- if (!optee->scan_bus_wq) {
- kfree(ctxdata);
- return -ECHILD;
- }
- queue_work(optee->scan_bus_wq, &optee->scan_bus_work);
+ schedule_work(&optee->scan_bus_work);
optee->scan_bus_done = true;
}
}
@@ -159,10 +153,7 @@ void optee_release_supp(struct tee_context *ctx)
struct optee *optee = tee_get_drvdata(ctx->teedev);
optee_release_helper(ctx, optee_close_session_helper);
- if (optee->scan_bus_wq) {
- destroy_workqueue(optee->scan_bus_wq);
- optee->scan_bus_wq = NULL;
- }
+
optee_supp_release(&optee->supp);
}
diff --git a/drivers/tee/optee/device.c b/drivers/tee/optee/device.c
index 64f0e047c23d..78fc0a15c463 100644
--- a/drivers/tee/optee/device.c
+++ b/drivers/tee/optee/device.c
@@ -60,9 +60,10 @@ static void optee_release_device(struct device *dev)
kfree(optee_device);
}
-static int optee_register_device(const uuid_t *device_uuid)
+static int optee_register_device(const uuid_t *device_uuid, u32 func)
{
struct tee_client_device *optee_device = NULL;
+ const char *dev_name_fmt = NULL;
int rc;
optee_device = kzalloc(sizeof(*optee_device), GFP_KERNEL);
@@ -71,7 +72,13 @@ static int optee_register_device(const uuid_t *device_uuid)
optee_device->dev.bus = &tee_bus_type;
optee_device->dev.release = optee_release_device;
- if (dev_set_name(&optee_device->dev, "optee-ta-%pUb", device_uuid)) {
+
+ if (func == PTA_CMD_GET_DEVICES_SUPP)
+ dev_name_fmt = "optee-ta-supp-%pUb";
+ else
+ dev_name_fmt = "optee-ta-%pUb";
+
+ if (dev_set_name(&optee_device->dev, dev_name_fmt, device_uuid)) {
kfree(optee_device);
return -ENOMEM;
}
@@ -142,7 +149,7 @@ static int __optee_enumerate_devices(u32 func)
num_devices = shm_size / sizeof(uuid_t);
for (idx = 0; idx < num_devices; idx++) {
- rc = optee_register_device(&device_uuid[idx]);
+ rc = optee_register_device(&device_uuid[idx], func);
if (rc)
goto out_shm;
}
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index 6dcecb83c893..af4aa266c3fb 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -193,7 +193,6 @@ struct optee_ops {
* @pool: shared memory pool
* @rpc_param_count: If > 0 number of RPC parameters to make room for
* @scan_bus_done flag if device registation was already done.
- * @scan_bus_wq workqueue to scan optee bus and register optee drivers
* @scan_bus_work workq to scan optee bus and register optee drivers
*/
struct optee {
@@ -212,7 +211,6 @@ struct optee {
struct tee_shm_pool *pool;
unsigned int rpc_param_count;
bool scan_bus_done;
- struct workqueue_struct *scan_bus_wq;
struct work_struct scan_bus_work;
};
--
2.34.1
[BCC all OP-TEE maintainers]
Hi OP-TEE maintainers & contributors,
OP-TEE v4.0.0 is scheduled to be released on 2023-10-20. So, now is
a good time to start testing the master branch on the various platforms
and report/fix any bugs.
The GitHub pull request for collecting Tested-by tags or any other
comments is https://github.com/OP-TEE/optee_os/pull/6341.
As usual, we will create a release candidate tag one week before the
release date for final testing.
Note that this is a major version update. We will be merging some pull
requests that may break backward compatibility in some (limited) way
just before creating the 4.0.0-rc1 tag. These pull requests have "[v4]" in
their title and can be found here:
https://github.com/OP-TEE/optee_os/pulls?q=is%3Apr+is%3Aopen+in%3Atitle+%5B…
In addition to that you can find some additional information related to
releases here: https://optee.readthedocs.io/en/latest/general/releases.html
Regards,
--
Jerome Forissier
This series introduces TEE system sessions for TEE service sessions that
require TEE to provision resources to prevent deadlock when clients call
the TEE.
This deadlock situation can happen when a TEE service is used by low
level system resources as for example when Linux kernel uses SCMI
service embedded in TEE for clock, reset, regulator, etc... controls.
This case is detailled in patch 2/4:
> This feature is needed to prevent a system deadlock when several TEE
> client applications invoke TEE, consuming all TEE thread contexts
> available in the secure world. The deadlock can happen in the OP-TEE
> driver for example if all these TEE threads issue an RPC call from TEE
> to Linux OS to access an eMMC RPMB partition (TEE secure storage) which
> device clock or regulator controller is accessed through an OP-TEE SCMI
> services. In that case, Linux SCMI driver must reach OP-TEE SCMI
> service without waiting until one of the consumed TEE threads is freed.
Etienne Carriere (4):
tee: optee: system call property
tee: system session
tee: optee: support tracking system threads
firmware: arm_scmi: optee: use optee system invocation
drivers/firmware/arm_scmi/optee.c | 4 +
drivers/tee/optee/call.c | 152 +++++++++++++++++++++++++++---
drivers/tee/optee/core.c | 5 +-
drivers/tee/optee/ffa_abi.c | 13 +--
drivers/tee/optee/optee_private.h | 33 ++++++-
drivers/tee/optee/smc_abi.c | 31 ++++--
drivers/tee/tee_core.c | 8 ++
include/linux/tee_drv.h | 16 ++++
8 files changed, 227 insertions(+), 35 deletions(-)
--
2.25.1
In a virtual environment, an application running in guest VM may want
to delegate security sensitive tasks to a Trusted Application (TA)
running within a Trusted Execution Environment (TEE). A TEE is a trusted
OS running in some secure environment, for example, TrustZone on ARM
CPUs, or a separate secure co-processor etc.
A virtual TEE device emulates a TEE within a guest VM. Such a virtual
TEE device supports multiple operations such as:
VIRTIO_TEE_CMD_OPEN_DEVICE – Open a communication channel with virtio
TEE device.
VIRTIO_TEE_CMD_CLOSE_DEVICE – Close communication channel with virtio
TEE device.
VIRTIO_TEE_CMD_GET_VERSION – Get version of virtio TEE.
VIRTIO_TEE_CMD_OPEN_SESSION – Open a session to communicate with
trusted application running in TEE.
VIRTIO_TEE_CMD_CLOSE_SESSION – Close a session to end communication
with trusted application running in TEE.
VIRTIO_TEE_CMD_INVOKE_FUNC – Invoke a command or function in trusted
application running in TEE.
VIRTIO_TEE_CMD_CANCEL_REQ – Cancel an ongoing command within TEE.
VIRTIO_TEE_CMD_REGISTER_MEM - Register shared memory with TEE.
VIRTIO_TEE_CMD_UNREGISTER_MEM - Unregister shared memory from TEE.
We would like to reserve device ID 46 for Virtio-TEE device.
Signed-off-by: Jeshwanth Kumar <jeshwanthkumar.nk(a)amd.com>
Reviewed-by: Rijo Thomas <Rijo-john.Thomas(a)amd.com>
Reviewed-by: Parav Pandit <parav(a)nvidia.com>
Acked-by: Sumit Garg <sumit.garg(a)linaro.org>
---
content.tex | 2 ++
1 file changed, 2 insertions(+)
diff --git a/content.tex b/content.tex
index 0a62dce..644aa4a 100644
--- a/content.tex
+++ b/content.tex
@@ -739,6 +739,8 @@ \chapter{Device Types}\label{sec:Device Types}
\hline
45 & SPI master \\
\hline
+46 & TEE device \\
+\hline
\end{tabular}
Some of the devices above are unspecified by this document,
--
2.25.1
Hello arm-soc maintainers,
Please pull this small AMDTEE driver fix addressing a possible
user-after-free vulnerability.
Note that this isn't a usual Arm driver update. This targets AMD instead,
but is part of the TEE subsystem.
Thanks,
Jens
The following changes since commit 2dde18cd1d8fac735875f2e4987f11817cc0bc2c:
Linux 6.5 (2023-08-27 14:49:51 -0700)
are available in the Git repository at:
https://git.linaro.org/people/jens.wiklander/linux-tee.git/ tags/amdtee-fix-for-v6.6
for you to fetch changes up to f4384b3e54ea813868bb81a861bf5b2406e15d8f:
tee: amdtee: fix use-after-free vulnerability in amdtee_close_session (2023-10-03 19:13:53 +0200)
----------------------------------------------------------------
AMDTEE fix possible use-after-free
----------------------------------------------------------------
Rijo Thomas (1):
tee: amdtee: fix use-after-free vulnerability in amdtee_close_session
drivers/tee/amdtee/core.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
There is a potential race condition in amdtee_close_session that may
cause use-after-free in amdtee_open_session. For instance, if a session
has refcount == 1, and one thread tries to free this session via:
kref_put(&sess->refcount, destroy_session);
the reference count will get decremented, and the next step would be to
call destroy_session(). However, if in another thread,
amdtee_open_session() is called before destroy_session() has completed
execution, alloc_session() may return 'sess' that will be freed up
later in destroy_session() leading to use-after-free in
amdtee_open_session.
To fix this issue, treat decrement of sess->refcount and removal of
'sess' from session list in destroy_session() as a critical section, so
that it is executed atomically.
Fixes: 757cc3e9ff1d ("tee: add AMD-TEE driver")
Cc: stable(a)vger.kernel.org
Signed-off-by: Rijo Thomas <Rijo-john.Thomas(a)amd.com>
---
v2:
* Introduced kref_put_mutex() as suggested by Sumit Garg.
drivers/tee/amdtee/core.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/tee/amdtee/core.c b/drivers/tee/amdtee/core.c
index 372d64756ed6..3c15f6a9e91c 100644
--- a/drivers/tee/amdtee/core.c
+++ b/drivers/tee/amdtee/core.c
@@ -217,12 +217,12 @@ static int copy_ta_binary(struct tee_context *ctx, void *ptr, void **ta,
return rc;
}
+/* mutex must be held by caller */
static void destroy_session(struct kref *ref)
{
struct amdtee_session *sess = container_of(ref, struct amdtee_session,
refcount);
- mutex_lock(&session_list_mutex);
list_del(&sess->list_node);
mutex_unlock(&session_list_mutex);
kfree(sess);
@@ -272,7 +272,8 @@ int amdtee_open_session(struct tee_context *ctx,
if (arg->ret != TEEC_SUCCESS) {
pr_err("open_session failed %d\n", arg->ret);
handle_unload_ta(ta_handle);
- kref_put(&sess->refcount, destroy_session);
+ kref_put_mutex(&sess->refcount, destroy_session,
+ &session_list_mutex);
goto out;
}
@@ -290,7 +291,8 @@ int amdtee_open_session(struct tee_context *ctx,
pr_err("reached maximum session count %d\n", TEE_NUM_SESSIONS);
handle_close_session(ta_handle, session_info);
handle_unload_ta(ta_handle);
- kref_put(&sess->refcount, destroy_session);
+ kref_put_mutex(&sess->refcount, destroy_session,
+ &session_list_mutex);
rc = -ENOMEM;
goto out;
}
@@ -331,7 +333,7 @@ int amdtee_close_session(struct tee_context *ctx, u32 session)
handle_close_session(ta_handle, session_info);
handle_unload_ta(ta_handle);
- kref_put(&sess->refcount, destroy_session);
+ kref_put_mutex(&sess->refcount, destroy_session, &session_list_mutex);
return 0;
}
--
2.25.1
There is a potential race condition in amdtee_close_session that may
cause use-after-free in amdtee_open_session. For instance, if a session
has refcount == 1, and one thread tries to free this session via:
kref_put(&sess->refcount, destroy_session);
the reference count will get decremented, and the next step would be to
call destroy_session(). However, if in another thread,
amdtee_open_session() is called before destroy_session() has completed
execution, alloc_session() may return 'sess' that will be freed up
later in destroy_session() leading to use-after-free in
amdtee_open_session.
To fix this issue, treat decrement of sess->refcount and invocation of
destroy_session() as a single critical section, so that it is executed
atomically.
Fixes: 757cc3e9ff1d ("tee: add AMD-TEE driver")
Cc: stable(a)vger.kernel.org
Signed-off-by: Rijo Thomas <Rijo-john.Thomas(a)amd.com>
---
drivers/tee/amdtee/core.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/tee/amdtee/core.c b/drivers/tee/amdtee/core.c
index 372d64756ed6..04cee03bec9d 100644
--- a/drivers/tee/amdtee/core.c
+++ b/drivers/tee/amdtee/core.c
@@ -217,14 +217,13 @@ static int copy_ta_binary(struct tee_context *ctx, void *ptr, void **ta,
return rc;
}
+/* mutex must be held by caller */
static void destroy_session(struct kref *ref)
{
struct amdtee_session *sess = container_of(ref, struct amdtee_session,
refcount);
- mutex_lock(&session_list_mutex);
list_del(&sess->list_node);
- mutex_unlock(&session_list_mutex);
kfree(sess);
}
@@ -272,7 +271,9 @@ int amdtee_open_session(struct tee_context *ctx,
if (arg->ret != TEEC_SUCCESS) {
pr_err("open_session failed %d\n", arg->ret);
handle_unload_ta(ta_handle);
+ mutex_lock(&session_list_mutex);
kref_put(&sess->refcount, destroy_session);
+ mutex_unlock(&session_list_mutex);
goto out;
}
@@ -290,7 +291,9 @@ int amdtee_open_session(struct tee_context *ctx,
pr_err("reached maximum session count %d\n", TEE_NUM_SESSIONS);
handle_close_session(ta_handle, session_info);
handle_unload_ta(ta_handle);
+ mutex_lock(&session_list_mutex);
kref_put(&sess->refcount, destroy_session);
+ mutex_unlock(&session_list_mutex);
rc = -ENOMEM;
goto out;
}
@@ -331,7 +334,9 @@ int amdtee_close_session(struct tee_context *ctx, u32 session)
handle_close_session(ta_handle, session_info);
handle_unload_ta(ta_handle);
+ mutex_lock(&session_list_mutex);
kref_put(&sess->refcount, destroy_session);
+ mutex_unlock(&session_list_mutex);
return 0;
}
--
2.25.1
+cc OP-TEE ML
On Tue, 26 Sept 2023 at 13:47, Rijo Thomas <Rijo-john.Thomas(a)amd.com> wrote:
>
> On 9/26/2023 1:19 PM, Sumit Garg wrote:
> > On Tue, 26 Sept 2023 at 12:53, Rijo Thomas <Rijo-john.Thomas(a)amd.com> wrote:
> >>
> >> On 9/26/2023 12:14 PM, Sumit Garg wrote:
> >>> +cc Alex
> >>>
> >>> On Tue, 26 Sept 2023 at 08:16, Jens Wiklander <jens.wiklander(a)linaro.org> wrote:
> >>>>
> >>>> Hi,
> >>>>
> >>>> [+cc Arnd]
> >>>>
> >>>> On Tue, Sep 26, 2023 at 8:00 AM Sumit Garg <sumit.garg(a)linaro.org> wrote:
> >>>>>
> >>>>> +cc Jens
> >>>>>
> >>>>>> In a virtual environment, an application running in guest VM may want
> >>>>>> to delegate security sensitive tasks to a Trusted Application (TA)
> >>>>>> running within a Trusted Execution Environment (TEE). A TEE is a trusted
> >>>>>> OS running in some secure environment, for example, TrustZone on ARM
> >>>>>> CPUs, or a separate secure co-processor etc.
> >>>>>
> >>>>> I have been exploring this area quite recently with an effort to have a common VIRIO interface which can support different trusted OS implementations. I guess you intend to test it with AMD-TEE, right? Any plans to test it with OP-TEE? As currently we have these two supported upstream.
> >>>>>
> >> Yes, we have tested with AMD-TEE. We have not yet tested with OP-TEE. Sure, we will try it out.
> >
> > Glad to hear that. I can help get it tested with OP-TEE as well.
> >
>
> We will test it out internally. Shall let you know in case we need help.
>
> >>
> >>>>> Do you currently have any virtio frontend/backend implementations for this?
> >>>>>
> >>
> >> Yes, we have. Frontend is a Linux virtio-TEE driver, and backend is virtio-TEE device emulated in QEMU.
> >> We used the Xen hypervisor.
> >
> > Can you share corresponding references? I can give it a try using Qemu with KVM.
> >
>
> We will share it in next couple of weeks. We have not yet hosted the code for external consumption.
>
> >>
> >>>>>>
> >>>>>> A virtual TEE device emulates a TEE within a guest VM. Such a virtual
> >>>>>> TEE device supports multiple operations such as:
> >>>>>>
> >>>>>> VIRTIO_TEE_CMD_OPEN_DEVICE – Open a communication channel with virtio
> >>>>>> TEE device.
> >>>>>> VIRTIO_TEE_CMD_CLOSE_DEVICE – Close communication channel with virtio
> >>>>>> TEE device.
> >>>>>> VIRTIO_TEE_CMD_GET_VERSION – Get version of virtio TEE.
> >>>>>> VIRTIO_TEE_CMD_OPEN_SESSION – Open a session to communicate with
> >>>>>> trusted application running in TEE.
> >>>>>> VIRTIO_TEE_CMD_CLOSE_SESSION – Close a session to end communication
> >>>>>> with trusted application running in TEE.
> >>>>>> VIRTIO_TEE_CMD_INVOKE_FUNC – Invoke a command or function in trusted
> >>>>>> application running in TEE.
> >>>>>> VIRTIO_TEE_CMD_CANCEL_REQ – Cancel an ongoing command within TEE.
> >>>>>>
> >>>>>
> >>>>> How about shared memory support? We would like to register guest pages with the trusted OS.
> >> We have a command VIRTIO_TEE_CMD_REGISTER_MEM for registering shared memory buffer with Trusted OS.
> >
> > I suppose the commit message has to be appended then. Do you have the
> > draft virtio-tee device specification ready for review? I would be
> > interested to review that.
> >
>
> Yes, the command is missed out in the commit message.
With the commit message updated to include support for shared memory,
feel free to add:
Acked-by: Sumit Garg <sumit.garg(a)linaro.org>
>
> We are in the process of preparing virtio-tee device specification. We will be sending it out to this
> list.
I would also suggest you to CC: op-tee(a)lists.trustedfirmware.org for review.
>
> >>
> >> In this command, the guest pages are copied into a shadow buffer in the host OS. And this shadow
> >> buffer is mapped with Trusted OS. So, buffer-copy is involved.
> >>
> >> One limitation, that we had was that the guest pages were non-contiguous. So, the number of physical
> >> pages that had to be mapped with Trusted OS was exceeding 64 entries when we were testing out the
> >> registering of guest pages. AMD-TEE Trusted OS can map a physically non-contiguous buffer, but the
> >> number of sg entries for such a buffer must be less than 64. So, we resorted to using a shadow buffer
> >> that is allocated within host, and gets mapped with Trusted OS.
> >
> > I don't think OP-TEE OS has such a limitation on non-contiguous pages.
> > So I would suggest you to keep VIRTIO_TEE_CMD_REGISTER_MEM as part of
> > the ABI. It can be an optional feature for a particular trusted OS
> > implementation to support.
> >
>
> Currently, the reg_mem (register memory) control is dictated by a flag in virtio-tee qemu code. This flag
> for our testing was hard-coded as false. We will enhance our code, so that it is configurable. The value
> of reg_mem shall be set to true/false depending upon whether the underlying TEE driver reports TEE_GEN_CAP_REG_MEM.
Sounds good to me.
-Sumit
>
> Thanks,
> Rijo
>
> > -Sumit
> >
> >>
> >> Thanks,
> >> Rijo
> >>
> >>>>
> >>>> Coincidently Arnd and I (among others) discussed this in person last
> >>>> week and the conclusion was that only temporary shared memory is
> >>>> possible with virtio. So the shared memory has to be set up and torn
> >>>> down by the host during each operation, typically open-session or
> >>>> invoke-func.
> >>>
> >>> Agree as I was part of those discussions. But I would like to
> >>> understand the reasoning behind it. Is there any restriction by VIRTIO
> >>> specification that we can't register guest page PAs to a device (TEE
> >>> in our case) to allow for zero copy transfers?
> >>>
> >>> Alex mentioned some references to virtio GPU device. I suppose I need
> >>> to dive into its implementation to see if there are any similarities
> >>> to our use-case.
> >>>
> >>>> That might not be optimal if trying to maximize
> >>>> performance, but it is portable.
> >>>
> >>> IMO, the ABI should be flexible enough to support a TEE with optimum
> >>> performance.
> >>>
> >>> -Sumit
> >>>
> >>>>
> >>>> Cheers,
> >>>> Jens
> >>>>
> >>>>>
> >>>>> -Sumit
> >>>>>
> >>>>>> We would like to reserve device ID 46 for Virtio-TEE device.
> >>>>>>
> >>>>>> Signed-off-by: Jeshwanth Kumar <jeshwanthkumar.nk(a)amd.com>
> >>>>>> ---
> >>>>>> content.tex | 2 ++
> >>>>>> 1 file changed, 2 insertions(+)
> >>>>>>
> >>>>>> diff --git a/content.tex b/content.tex
> >>>>>> index 0a62dce..644aa4a 100644
> >>>>>> --- a/content.tex
> >>>>>> +++ b/content.tex
> >>>>>> @@ -739,6 +739,8 @@ \chapter{Device Types}\label{sec:Device Types}
> >>>>>> \hline
> >>>>>> 45 & SPI master \\
> >>>>>> \hline
> >>>>>> +46 & TEE device \\
> >>>>>> +\hline
> >>>>>> \end{tabular}
> >>>>>>
> >>>>>> Some of the devices above are unspecified by this document,
Hi
Today Tuesday, September 26 it's time for another LOC monthly meeting.
Sorry for the short notice. For
time and connection details see the calendar at
https://www.trustedfirmware.org/meetings/
I have a few items for the agenda:
- Firmware handoff in OP-TEE https://github.com/OP-TEE/optee_os/pull/6308
- We've started to upstream a few PRs that will require bumping the
major version to 4
Any other topics?
Thanks,
Jens
Hi,
For legislative purposes, one of our Trusted Applications needs to show a
checksum to the end-user on our secure screen, to allow verification.
Albeit a bit unconventional use of it, we thought that the TA's own
checksum would be ideal for that, but we're having difficulties figuring
how to access that, if at all possible.
So I have to turn to you guys here: Is there any way for a TA to access its
own checksum? And if yes, could somebody please give me some pointers on
how to do this?
With kind regards,
Robert.
--
DISCLAIMER
De informatie, verzonden in of met dit e-mailbericht, is
vertrouwelijk en uitsluitend voor de geadresseerde(n) bestemd. Het gebruik
van de informatie in dit bericht, de openbaarmaking, vermenigvuldiging,
verspreiding en|of verstrekking daarvan aan derden is niet toegestaan.
Gebruik van deze informatie door anderen dan geadresseerde(n) is strikt
verboden. Aan deze informatie kunnen geen rechten worden ontleend. U wordt
verzocht bij onjuiste adressering de afzender direct te informeren door het
bericht te retourneren en het bericht uit uw computersysteem te verwijderen.
Hello arm-soc maintainers,
Please pull this small fix that removes a few unused function declarations
in the TEE subsystem.
Thanks,
Jens
The following changes since commit 2dde18cd1d8fac735875f2e4987f11817cc0bc2c:
Linux 6.5 (2023-08-27 14:49:51 -0700)
are available in the Git repository at:
https://git.linaro.org/people/jens.wiklander/linux-tee.git/ tags/optee-for-for-v6.6
for you to fetch changes up to 069969d6c5264d2348fd6cf0cedc00fd87ff3cee:
tee: Remove unused declarations (2023-09-13 08:16:24 +0200)
----------------------------------------------------------------
Remove a few unused declarations in TEE subsystem
----------------------------------------------------------------
Yue Haibing (1):
tee: Remove unused declarations
drivers/tee/optee/optee_private.h | 2 --
drivers/tee/tee_private.h | 2 --
2 files changed, 4 deletions(-)
Hi All,
Note you may have received another instance of this note but when I
attempted to send to all TF ML's simultaneously it seemed to fail, so
sending to each one at a time. Sorry about that. :/
We've created a Discord Server for real time chats/sharing. This solution
comes at no cost to the project, is set up with channels for each project,
includes a #general channel, and supports direct 1-1 chats between members,
all with the goal of improving collaboration between trustedfirmware.org
developers.
We encourage all to join! :) Instructions for joining can be found on
the TF.org
FAQ page <https://www.trustedfirmware.org/faq/>.
See you all there and please don't hesitate to reach out if you have any
questions!
Don Harbin
TrustedFirmware Community Manager
don.harbin(a)linaro.org
Hi All,
To all TF maillists in case all aren't yet aware.
We've created a Discord Server for real time chats/sharing. This solution
comes at no cost to the project, is set up with channels for each project,
includes a #general channel, and supports direct 1-1 chats between members,
all with the goal of improving collaboration between trustedfirmware.org
developers.
I've attached a recent screenshot from the #general channel as a sample of
the interface and usages.
We encourage all to join! :) Instructions for joining can be found on
the TF.org
FAQ page <https://www.trustedfirmware.org/faq/>.
See you all there and please don't hesitate to reach out if you have any
questions!
Don Harbin
TrustedFirmware Community Manager
don.harbin(a)linaro.org