blob: 0fb752875880da0269ea69c999cb59efa12541b9 [file] [log] [blame]
<!--
Documentation/_templates/layout.html
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership. The
ASF licenses this file to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
-->
<!DOCTYPE html>
<html class="writer-html5" lang="en">
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Interfacing with OP-TEE &mdash; NuttX latest documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../_static/css/theme.css" />
<link rel="stylesheet" type="text/css" href="../_static/copybutton.css" />
<link rel="stylesheet" type="text/css" href="../_static/sphinx_collapse.css" />
<link rel="stylesheet" type="text/css" href="../_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css" />
<link rel="stylesheet" type="text/css" href="../_static/custom.css" />
<link rel="shortcut icon" href="../_static/favicon.ico"/>
<script src="../_static/jquery.js"></script>
<script src="../_static/_sphinx_javascript_frameworks_compat.js"></script>
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/sphinx_highlight.js"></script>
<script src="../_static/clipboard.min.js"></script>
<script src="../_static/copybutton.js"></script>
<script src="../_static/design-tabs.js"></script>
<script src="../_static/js/theme.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Standards" href="../standards/index.html" />
<link rel="prev" title="Rust in NuttX" href="rust.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="../index.html" class="icon icon-home"> NuttX
</a>
<!-- this version selector is quite ugly, should be probably replaced by something
more modern -->
<div class="version-selector">
<select onchange="javascript:location.href = this.value;">
<option value="../../latest" selected="selected">latest</option>
<option value="../../10.0.0" >10.0.0</option>
<option value="../../10.0.1" >10.0.1</option>
<option value="../../10.1.0" >10.1.0</option>
<option value="../../10.2.0" >10.2.0</option>
<option value="../../10.3.0" >10.3.0</option>
<option value="../../11.0.0" >11.0.0</option>
<option value="../../12.0.0" >12.0.0</option>
<option value="../../12.1.0" >12.1.0</option>
<option value="../../12.2.0" >12.2.0</option>
<option value="../../12.2.1" >12.2.1</option>
<option value="../../12.3.0" >12.3.0</option>
<option value="../../12.4.0" >12.4.0</option>
<option value="../../12.5.0" >12.5.0</option>
<option value="../../12.5.1" >12.5.1</option>
<option value="../../12.6.0" >12.6.0</option>
<option value="../../12.7.0" >12.7.0</option>
<option value="../../12.8.0" >12.8.0</option>
<option value="../../12.9.0" >12.9.0</option>
<option value="../../12.10.0" >12.10.0</option>
<option value="../../12.11.0" >12.11.0</option>
</select>
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption" role="heading"><span class="caption-text">Table of Contents</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../index.html">Home</a></li>
<li class="toctree-l1"><a class="reference internal" href="../introduction/index.html">Introduction</a></li>
<li class="toctree-l1"><a class="reference internal" href="../quickstart/index.html">Getting Started</a></li>
<li class="toctree-l1"><a class="reference internal" href="../contributing/index.html">Contributing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../introduction/inviolables.html">The Inviolable Principles of NuttX</a></li>
<li class="toctree-l1"><a class="reference internal" href="../platforms/index.html">Supported Platforms</a></li>
<li class="toctree-l1"><a class="reference internal" href="../components/index.html">OS Components</a></li>
<li class="toctree-l1"><a class="reference internal" href="../applications/index.html">Applications</a></li>
<li class="toctree-l1"><a class="reference internal" href="../implementation/index.html">Implementation Details</a></li>
<li class="toctree-l1"><a class="reference internal" href="../reference/index.html">API Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../faq/index.html">FAQ</a></li>
<li class="toctree-l1"><a class="reference internal" href="../debugging/index.html">Debugging</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Guides</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="nfs.html">NFS Client How-To</a></li>
<li class="toctree-l2"><a class="reference internal" href="nix_flake.html">Nix Flake for Reproducible Development</a></li>
<li class="toctree-l2"><a class="reference internal" href="usbtrace.html">USB Device Trace</a></li>
<li class="toctree-l2"><a class="reference internal" href="simulator.html">Simulator</a></li>
<li class="toctree-l2"><a class="reference internal" href="rndis.html">How to use RNDIS</a></li>
<li class="toctree-l2"><a class="reference internal" href="drivers.html">Drivers</a></li>
<li class="toctree-l2"><a class="reference internal" href="cpp_cmake.html">C++ Example using CMake</a></li>
<li class="toctree-l2"><a class="reference internal" href="pysimcoder.html">pysimCoder integration with NuttX</a></li>
<li class="toctree-l2"><a class="reference internal" href="customboards.html">Custom Boards How-To</a></li>
<li class="toctree-l2"><a class="reference internal" href="customapps.html">Custom Apps How-to</a></li>
<li class="toctree-l2"><a class="reference internal" href="citests.html">Running CI Test Locally</a></li>
<li class="toctree-l2"><a class="reference internal" href="zerolatencyinterrupts.html">High Performance: Zero Latency Interrupts, Maskable Nested Interrupts</a></li>
<li class="toctree-l2"><a class="reference internal" href="fortify.html">Fortify</a></li>
<li class="toctree-l2"><a class="reference internal" href="nestedinterrupts.html">Nested Interrupts</a></li>
<li class="toctree-l2"><a class="reference internal" href="ofloader.html">Open Flash Loader</a></li>
<li class="toctree-l2"><a class="reference internal" href="testingtcpip.html">Testing TCP/IP Network Stacks</a></li>
<li class="toctree-l2"><a class="reference internal" href="automounter.html">Auto-Mounter</a></li>
<li class="toctree-l2"><a class="reference internal" href="stm32nullpointer.html">STM32 Null Pointer Detection</a></li>
<li class="toctree-l2"><a class="reference internal" href="stm32ccm.html">STM32 CCM Allocator</a></li>
<li class="toctree-l2"><a class="reference internal" href="etcromfs.html">etc romfs</a></li>
<li class="toctree-l2"><a class="reference internal" href="thread_local_storage.html">Thread Local Storage</a></li>
<li class="toctree-l2"><a class="reference internal" href="devicetree.html">Device Tree</a></li>
<li class="toctree-l2"><a class="reference internal" href="changing_systemclockconfig.html">Changing the System Clock Configuration</a></li>
<li class="toctree-l2"><a class="reference internal" href="usingkernelthreads.html">Using Kernel Threads</a></li>
<li class="toctree-l2"><a class="reference internal" href="armv7m_runtimestackcheck.html">ARMv7-M Run Time Stack Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="include_files_board_h.html">Including Files in board.h</a></li>
<li class="toctree-l2"><a class="reference internal" href="specialstuff_in_nuttxheaderfiles.html">Why can’t I put my special stuff in NuttX header files?</a></li>
<li class="toctree-l2"><a class="reference internal" href="kernel_threads_with_custom_stacks.html">Kernel Threads with Custom Stacks</a></li>
<li class="toctree-l2"><a class="reference internal" href="versioning_and_task_names.html">Versioning and Task Names</a></li>
<li class="toctree-l2"><a class="reference internal" href="logging_rambuffer.html">Logging to a RAM Buffer</a></li>
<li class="toctree-l2"><a class="reference internal" href="ipv6.html">IPv6</a></li>
<li class="toctree-l2"><a class="reference internal" href="integrate_newlib.html">Integrating with Newlib</a></li>
<li class="toctree-l2"><a class="reference internal" href="protected_build.html">NuttX Protected Build</a></li>
<li class="toctree-l2"><a class="reference internal" href="platform_directories.html">Platform Directories</a></li>
<li class="toctree-l2"><a class="reference internal" href="port_drivers_to_stm32f7.html">Porting Drivers to the STM32 F7</a></li>
<li class="toctree-l2"><a class="reference internal" href="semihosting.html">Semihosting</a></li>
<li class="toctree-l2"><a class="reference internal" href="renode.html">Run NuttX on Renode</a></li>
<li class="toctree-l2"><a class="reference internal" href="signal_events_interrupt_handlers.html">Signaling Events from Interrupt Handlers</a></li>
<li class="toctree-l2"><a class="reference internal" href="signaling_sem_priority_inheritance.html">Signaling Semaphores and Priority Inheritance</a></li>
<li class="toctree-l2"><a class="reference internal" href="smaller_vector_tables.html">Smaller Vector Tables</a></li>
<li class="toctree-l2"><a class="reference internal" href="port.html">How to port</a></li>
<li class="toctree-l2"><a class="reference internal" href="updating_release_system_elf.html">Updating a Release System with ELF Programs</a></li>
<li class="toctree-l2"><a class="reference internal" href="partially_linked_elf.html">ELF Programs – With Symbol Tables</a></li>
<li class="toctree-l2"><a class="reference internal" href="fully_linked_elf.html">ELF Programs – No Symbol Tables</a></li>
<li class="toctree-l2"><a class="reference internal" href="building_nuttx_with_app_out_of_src_tree.html">Building NuttX with Applications Outside the Source Tree</a></li>
<li class="toctree-l2"><a class="reference internal" href="building_uclibcpp.html">Building uClibc++</a></li>
<li class="toctree-l2"><a class="reference internal" href="custom_app_directories.html">Custom Application Directories</a></li>
<li class="toctree-l2"><a class="reference internal" href="multiple_nsh_sessions.html">Multiple NSH Sessions</a></li>
<li class="toctree-l2"><a class="reference internal" href="nsh_network_link_management.html">NSH Network Link Management</a></li>
<li class="toctree-l2"><a class="reference internal" href="ram_rom_disks.html">RAM Disks and ROM Disks</a></li>
<li class="toctree-l2"><a class="reference internal" href="reading_can_msgs.html">Reading CAN Messages</a></li>
<li class="toctree-l2"><a class="reference internal" href="remove_device_drivers_nsh.html">Removing Device Drivers with NSH</a></li>
<li class="toctree-l2"><a class="reference internal" href="rust.html">Rust in NuttX</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Interfacing with OP-TEE</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#overview">Overview</a></li>
<li class="toctree-l3"><a class="reference internal" href="#enabling-the-op-tee-driver">Enabling the OP-TEE Driver</a></li>
<li class="toctree-l3"><a class="reference internal" href="#ioctls-supported">IOCTLs supported</a></li>
<li class="toctree-l3"><a class="reference internal" href="#typical-usage">Typical usage</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../standards/index.html">Standards</a></li>
<li class="toctree-l1"><a class="reference internal" href="../glossary.html">Glossary</a></li>
<li class="toctree-l1"><a class="reference internal" href="../logos/index.html">NuttX Logos</a></li>
<li class="toctree-l1"><a class="reference internal" href="../_tags/tagsindex.html">Tags</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../index.html">NuttX</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="../index.html" class="icon icon-home" aria-label="Home"></a></li>
<li class="breadcrumb-item"><a href="index.html">Guides</a></li>
<li class="breadcrumb-item active">Interfacing with OP-TEE</li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/apache/nuttx/blob/master/Documentation/guides/optee.rst" class="fa fa-github"> Edit on GitHub</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<section id="interfacing-with-op-tee">
<h1>Interfacing with OP-TEE<a class="headerlink" href="#interfacing-with-op-tee" title="Permalink to this heading"></a></h1>
<section id="overview">
<h2>Overview<a class="headerlink" href="#overview" title="Permalink to this heading"></a></h2>
<p>NuttX supports basic interfacing with OP-TEE OS through three different
transports: local network, RPMsg, and native Secure Monitor Calls (SMCs)
on arm. Tasks can interface with the OP-TEE driver (and in turn with the
OP-TEE OS) via IOCTLs on the TEE (<code class="docutils literal notranslate"><span class="pre">/dev/tee#</span></code>) character device. This
interface should allow use-of/integration-with libteec, although this is
not officially supported by NuttX, and is out of the scope of this guide.</p>
<p>The driver supports opening and closing sessions, allocating and registering
shared memory, and invoking functions on OP-TEE Trusted Applications (TAs).
The driver also supports, reverse direction commands called RPCs
(TA -&gt; Normal World). Some of the RPCs are handled completely by the kernel
driver while others require the TEE supplicant userspace process to be running
by having opened (<code class="docutils literal notranslate"><span class="pre">/dev/teepriv#</span></code>). Similarly to libteec, the supplicant
is not officially supported.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p><code class="docutils literal notranslate"><span class="pre">/dev/teepriv#</span></code> is reserved solely for the supplicant and shouldn’t be
used by any other NuttX application.</p>
</div>
</section>
<section id="enabling-the-op-tee-driver">
<h2>Enabling the OP-TEE Driver<a class="headerlink" href="#enabling-the-op-tee-driver" title="Permalink to this heading"></a></h2>
<p>The driver is enabled using one of:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_DEV_OPTEE_LOCAL</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_DEV_OPTEE_RPMSG</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_DEV_OPTEE_SMC</span></code></p></li>
</ul>
<p>All of the above require also <code class="docutils literal notranslate"><span class="pre">CONFIG_ALLOW_BSD_COMPONENTS</span></code> and
<code class="docutils literal notranslate"><span class="pre">CONFIG_FS_ANONMAP</span></code>. So, at a bare minimum, to enable the driver
one would need something like the following:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>CONFIG_ALLOW_BSD_COMPONENTS=y
CONFIG_DEV_OPTEE_SMC=y
CONFIG_FS_ANONMAP=y
</pre></div>
</div>
<p>Each implementation (local, RPMsg, or SMC) may have further dependencies
(e.g. RPMsg requires <code class="docutils literal notranslate"><span class="pre">CONFIG_NET_RPMSG</span></code> and more) and may have further
parameters to configure (e.g. RPMsg remote CPU name through
<code class="docutils literal notranslate"><span class="pre">CONFIG_OPTEE_REMOTE_CPU_NAME</span></code>).</p>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p><code class="docutils literal notranslate"><span class="pre">CONFIG_DEV_OPTEE_SMC</span></code> has only been tested on arm64. Also, please note
that in configurations with <code class="docutils literal notranslate"><span class="pre">CONFIG_ARM*_DCACHE_DISABLE=y</span></code> you might
encounter issues with shared memory depending on the state of the data
cache in Secure World.</p>
</div>
<p>If <code class="docutils literal notranslate"><span class="pre">CONFIG_DEV_OPTEE_SMC</span></code> is enabled we can also enable the kernel driver
for the TEE supplicant by using <code class="docutils literal notranslate"><span class="pre">CONFIG_DEV_OPTEE_SUPPLICANT</span></code>.</p>
<p>Successful registration of the driver can be verified by looking into
<code class="docutils literal notranslate"><span class="pre">/dev/tee0</span></code> and <code class="docutils literal notranslate"><span class="pre">/dev/teepriv0</span></code> (for the supplicant). For instance,
incompatibility with the TEE OS running in the system, will prevent the
<code class="docutils literal notranslate"><span class="pre">/dev/tee0</span></code> character device from being registered.</p>
</section>
<section id="ioctls-supported">
<h2>IOCTLs supported<a class="headerlink" href="#ioctls-supported" title="Permalink to this heading"></a></h2>
<p>All IOCTLs return negative error codes on failure. All of them return 0
on success unless otherwise specified (see <code class="docutils literal notranslate"><span class="pre">TEE_IOC_SHM_ALLOC</span></code>).</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">TEE_IOC_VERSION</span></code> : Query the version and capabilities of the TEE driver.</p>
<ul>
<li><p>Use the <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">tee_ioctl_version_data</span></code> to get the version and
capabilities. This driver supports OP-TEE so you should expect to
receive only <code class="docutils literal notranslate"><span class="pre">TEE_IMPL_ID_OPTEE</span></code> in <code class="docutils literal notranslate"><span class="pre">.impl_id</span></code> and <code class="docutils literal notranslate"><span class="pre">TEE_OPTEE_CAP_TZ</span></code>
in <code class="docutils literal notranslate"><span class="pre">.impl_caps</span></code>. The driver is GlobalPlatform compliant, and you should
always expect to receive <code class="docutils literal notranslate"><span class="pre">TEE_GEN_CAP_GP</span> <span class="pre">|</span> <span class="pre">TEE_GEN_CAP_MEMREF_NULL</span></code> in
<code class="docutils literal notranslate"><span class="pre">.gen_caps</span></code>. If using the SMC implementation, the driver supports also
shared memory registration, so you can expect also <code class="docutils literal notranslate"><span class="pre">TEE_GEN_CAP_REG_MEM</span></code>
in <code class="docutils literal notranslate"><span class="pre">.gen_caps</span></code>.</p></li>
</ul>
</li>
<li><p><code class="docutils literal notranslate"><span class="pre">TEE_IOC_OPEN_SESSION</span></code> : Open a session with a Trusted Application.</p>
<ul>
<li><p>Expects a <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">tee_ioctl_buf_data</span></code> pointer, pointing to a
<code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">tee_ioctl_open_session_arg</span></code> instance with at minimum, the <code class="docutils literal notranslate"><span class="pre">.uuid</span></code>
set. You can typically use <code class="docutils literal notranslate"><span class="pre">uuid_enc_be()</span></code> to encode a <code class="docutils literal notranslate"><span class="pre">uuid_t</span></code> struct
to the raw byte buffer expected in the <code class="docutils literal notranslate"><span class="pre">.uuid</span></code> field. After a successful
call, you can expect to get a session identifier back in the <code class="docutils literal notranslate"><span class="pre">.session</span></code>
field.</p></li>
</ul>
</li>
<li><p><code class="docutils literal notranslate"><span class="pre">TEE_IOC_CLOSE_SESSION</span></code> : Close a session with a Trusted Application.</p>
<ul>
<li><p>Expects a pointer to a <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">tee_ioctl_close_session_arg</span></code> with the
<code class="docutils literal notranslate"><span class="pre">.session</span></code> field set to the identifier of the session to close.</p></li>
</ul>
</li>
<li><p><code class="docutils literal notranslate"><span class="pre">TEE_IOC_INVOKE</span></code> : Invoke a function on a previously opened session to a Trusted Application.</p>
<ul>
<li><p>Expects a <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">tee_ioctl_buf_data</span></code> pointer, pointing to a
<code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">tee_ioctl_invoke_arg</span></code> instance. You can use the
<code class="docutils literal notranslate"><span class="pre">TEE_IOCTL_PARAM_SIZE()</span></code> macro to calculate the size of the
variable-length array of <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">tee_ioctl_param</span></code> parameters in the
invoke arguments struct. At minimum, the interface expects the fields
<code class="docutils literal notranslate"><span class="pre">.func</span></code>, <code class="docutils literal notranslate"><span class="pre">.session</span></code>, <code class="docutils literal notranslate"><span class="pre">.num_params</span></code>, and <code class="docutils literal notranslate"><span class="pre">.params</span></code> to be set.
<code class="docutils literal notranslate"><span class="pre">.cancel_id</span></code> can be optionally set to enable later canceling of this
command if needed.
You might notice that <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">tee_ioctl_param</span></code> has rather obscure field
names (<code class="docutils literal notranslate"><span class="pre">.a</span></code>, <code class="docutils literal notranslate"><span class="pre">.b</span></code>, <code class="docutils literal notranslate"><span class="pre">.c</span></code>). This can be improved with a union in the
future, but until then, please refer to <code class="docutils literal notranslate"><span class="pre">include/nuttx/tee.h</span></code> for details.
In short, for shared memory references, <code class="docutils literal notranslate"><span class="pre">.a</span></code> is the offset into the
shared memory buffer, <code class="docutils literal notranslate"><span class="pre">.b</span></code> is the size of the buffer, and <code class="docutils literal notranslate"><span class="pre">.c</span></code> is the
the shared memory identifier (<code class="docutils literal notranslate"><span class="pre">.id</span></code> field returned by
<code class="docutils literal notranslate"><span class="pre">TEE_IOC_SHM_ALLOC</span></code> or <code class="docutils literal notranslate"><span class="pre">TEE_IOC_SHM_REGISTER</span></code>).</p></li>
</ul>
</li>
<li><p><code class="docutils literal notranslate"><span class="pre">TEE_IOC_CANCEL</span></code> : Cancel a currently invoked command.</p>
<ul>
<li><p>Expects a <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">tee_ioctl_cancel_arg</span></code> pointer with the <code class="docutils literal notranslate"><span class="pre">.session</span></code>
and <code class="docutils literal notranslate"><span class="pre">.cancel_id</span></code> fields set.</p></li>
</ul>
</li>
<li><p><code class="docutils literal notranslate"><span class="pre">TEE_IOC_SHM_ALLOC</span></code> : Allocate shared memory between the user space and the secure OS.</p>
<ul>
<li><p>Expects a <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">tee_ioctl_shm_alloc_data</span></code> pointer with the <code class="docutils literal notranslate"><span class="pre">.size</span></code>
field set, and ignoring the <code class="docutils literal notranslate"><span class="pre">.flags</span></code> field. Upon successful return,
it returns the memory file descriptor one can use <code class="docutils literal notranslate"><span class="pre">mmap()</span></code> on (with
<code class="docutils literal notranslate"><span class="pre">MAP_SHARED</span></code>). It also returns an identifier for use in memory references
(<code class="docutils literal notranslate"><span class="pre">tee_ioctl_param.c</span></code> field) in <code class="docutils literal notranslate"><span class="pre">.id</span></code>.</p></li>
</ul>
</li>
<li><p><code class="docutils literal notranslate"><span class="pre">TEE_IOC_SHM_REGISTER</span></code> : Register a shared memory reference with the secure OS.</p>
<ul>
<li><p>Expects a pointer to a <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">tee_ioctl_shm_register_data</span></code> instance
with all fields set except <code class="docutils literal notranslate"><span class="pre">.id</span></code>. <code class="docutils literal notranslate"><span class="pre">.flags</span></code> can be any combination of
<code class="docutils literal notranslate"><span class="pre">TEE_SHM_REGISTER</span></code> and <code class="docutils literal notranslate"><span class="pre">TEE_SHM_SEC_REGISTER</span></code> but not <code class="docutils literal notranslate"><span class="pre">TEE_SHM_ALLOC</span></code>.
<code class="docutils literal notranslate"><span class="pre">TEE_SHM_REGISTER</span></code> registers the memory with the driver for automatic
cleanup (not freeing!) during <code class="docutils literal notranslate"><span class="pre">/dev/tee#</span></code> character device close.
<code class="docutils literal notranslate"><span class="pre">TEE_SHM_SEC_REGISTER</span></code> registers the memory with the secure OS for later
use in memrefs and is automatically de-registered during driver close if
<code class="docutils literal notranslate"><span class="pre">TEE_SHM_REGISTER</span></code> is also specified. <code class="docutils literal notranslate"><span class="pre">.addr</span></code> shall point to the (user)
memory to register and <code class="docutils literal notranslate"><span class="pre">.size</span></code> shall indicate its size. One may use the
returned <code class="docutils literal notranslate"><span class="pre">.id</span></code> field when specifying shared memory references
(<code class="docutils literal notranslate"><span class="pre">tee_ioctl_param.c</span></code> field).</p></li>
</ul>
</li>
<li><p><code class="docutils literal notranslate"><span class="pre">TEE_IOC_SUPPL_RECV</span></code> : Receive an RPC request from the OP-TEE that needs userspace interaction from the supplicant.</p>
<ul>
<li><p>Expects a pointer to a <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">tee_ioctl_buf_data</span></code> instance where the
<code class="docutils literal notranslate"><span class="pre">.buf_ptr</span></code> field points to a user allocated buffer that must hold a
<code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">tee_iocl_supp_send/recv_arg</span></code> followed by a number of
<code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">tee_ioctl_param</span></code> parameters. The <code class="docutils literal notranslate"><span class="pre">.buf_len</span></code> field communicates
to the kernel the length of that buffer. If the user passes a bigger number
of parameters than <code class="docutils literal notranslate"><span class="pre">OPTEE_MAX_PARAM_NUM</span></code> or smaller number of parameters than
the number sent by OP-TEE, the ioctl will fail. The TEE supplicant by default
uses 5 <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">tee_ioctl_param</span></code> parameters.</p></li>
</ul>
</li>
<li><p><code class="docutils literal notranslate"><span class="pre">TEE_IOC_SUPPL_SEND</span></code> : Respond to an RPC request from the OP-TEE that needed userspace interaction from the supplicant.</p>
<ul>
<li><p>Expects a pointer to a <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">tee_ioctl_buf_data</span></code> instance where the
<code class="docutils literal notranslate"><span class="pre">.buf_ptr</span></code> field points to a user allocated buffer that must hold a
<code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">tee_iocl_supp_send/recv_arg</span></code> followed by a number of
<code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">tee_ioctl_param</span></code> parameters. The <code class="docutils literal notranslate"><span class="pre">.buf_len</span></code> field communicates
to the kernel the length of that buffer. The number of parameters depends on
the size of expected RPC response by the OP-TEE.</p></li>
</ul>
</li>
</ul>
</section>
<section id="typical-usage">
<h2>Typical usage<a class="headerlink" href="#typical-usage" title="Permalink to this heading"></a></h2>
<ol class="arabic">
<li><p>Include the necessary headers:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;stdio.h&gt;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;stdlib.h&gt;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;fcntl.h&gt;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;unistd.h&gt;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;errno.h&gt;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;sys/ioctl.h&gt;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;nuttx/tee.h&gt;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;uuid.h&gt;</span>
</pre></div>
</div>
</li>
<li><p>Open the TEE character device</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">int</span><span class="w"> </span><span class="n">fd</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">open</span><span class="p">(</span><span class="s">&quot;/dev/tee0&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">O_RDONLY</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">O_NONBLOCK</span><span class="p">);</span>
</pre></div>
</div>
</li>
<li><p>Check the version and capabilities</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">struct</span><span class="w"> </span><span class="nc">tee_ioctl_version_data</span><span class="w"> </span><span class="n">ioc_ver</span><span class="p">;</span>
<span class="kt">int</span><span class="w"> </span><span class="n">ret</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ioctl</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span><span class="w"> </span><span class="n">TEE_IOC_VERSION</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">long</span><span class="p">)</span><span class="o">&amp;</span><span class="n">ioc_ver</span><span class="p">);</span>
<span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">ret</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">&quot;Failed to query TEE driver version and caps: %d, %s</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="n">ret</span><span class="p">,</span><span class="w"> </span><span class="n">strerror</span><span class="p">(</span><span class="n">errno</span><span class="p">));</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">ret</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="cm">/* check ioc_ver accordingly */</span>
</pre></div>
</div>
</li>
<li><p>Open a session with a Trusted Application</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">const</span><span class="w"> </span><span class="n">uuid_t</span><span class="w"> </span><span class="o">*</span><span class="n">uuid</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[...];</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">tee_ioctl_open_session_arg</span><span class="w"> </span><span class="n">ioc_opn</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">};</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">tee_ioctl_buf_data</span><span class="w"> </span><span class="n">ioc_buf</span><span class="p">;</span>
<span class="n">uuid_enc_be</span><span class="p">(</span><span class="o">&amp;</span><span class="n">ioc_opn</span><span class="p">.</span><span class="n">uuid</span><span class="p">,</span><span class="w"> </span><span class="n">uuid</span><span class="p">);</span>
<span class="n">ioc_buf</span><span class="p">.</span><span class="n">buf_ptr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="kt">uintptr_t</span><span class="p">)</span><span class="o">&amp;</span><span class="n">ioc_opn</span><span class="p">;</span>
<span class="n">ioc_buf</span><span class="p">.</span><span class="n">buf_len</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">sizeof</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">tee_ioctl_open_session_arg</span><span class="p">);</span>
<span class="n">ret</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ioctl</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span><span class="w"> </span><span class="n">TEE_IOC_OPEN_SESSION</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">long</span><span class="p">)</span><span class="o">&amp;</span><span class="n">ioc_buf</span><span class="p">);</span>
<span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">ret</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">ret</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="cm">/* use ioc_opn.session returned */</span>
</pre></div>
</div>
</li>
<li><p>Invoke a function of the Trusted Application</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">const</span><span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">num_params</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">tee_ioctl_invoke_arg</span><span class="w"> </span><span class="o">*</span><span class="n">ioc_args</span><span class="p">;</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">tee_ioctl_buf_data</span><span class="w"> </span><span class="n">ioc_buf</span><span class="p">;</span>
<span class="kt">size_t</span><span class="w"> </span><span class="n">ioc_args_len</span><span class="p">;</span>
<span class="n">ioc_args_len</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">sizeof</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">tee_ioctl_invoke_arg</span><span class="p">)</span><span class="w"> </span><span class="o">+</span>
<span class="w"> </span><span class="n">TEE_IOCTL_PARAM_SIZE</span><span class="p">(</span><span class="n">num_params</span><span class="p">);</span>
<span class="n">ioc_args</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">tee_ioctl_invoke_arg</span><span class="w"> </span><span class="o">*</span><span class="p">)</span><span class="n">calloc</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">ioc_args_len</span><span class="p">);</span>
<span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">ioc_args</span><span class="p">)</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="o">-</span><span class="n">ENOMEM</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="n">ioc_args</span><span class="o">-&gt;</span><span class="n">func</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&lt;</span><span class="n">SOME_FUNCTION_ID</span><span class="o">&gt;</span><span class="p">;</span>
<span class="n">ioc_args</span><span class="o">-&gt;</span><span class="n">session</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ioc_opn</span><span class="p">.</span><span class="n">session</span><span class="p">;</span>
<span class="n">ioc_args</span><span class="o">-&gt;</span><span class="n">num_params</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">num_params</span><span class="p">;</span>
<span class="n">ioc_args</span><span class="o">-&gt;</span><span class="n">params</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">attr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT</span><span class="p">;</span>
<span class="n">ioc_buf</span><span class="p">.</span><span class="n">buf_ptr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="kt">uintptr_t</span><span class="p">)</span><span class="n">ioc_args</span><span class="p">;</span>
<span class="n">ioc_buf</span><span class="p">.</span><span class="n">buf_len</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ioc_args_len</span><span class="p">;</span>
<span class="n">ret</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ioctl</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span><span class="w"> </span><span class="n">TEE_IOC_INVOKE</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">long</span><span class="p">)</span><span class="o">&amp;</span><span class="n">ioc_buf</span><span class="p">);</span>
<span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">ret</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">goto</span><span class="w"> </span><span class="n">err_with_args</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="cm">/* use result (if any) in ioc_args-&gt;params */</span>
</pre></div>
</div>
</li>
<li><p>Allocate shared memory through the driver</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">struct</span><span class="w"> </span><span class="nc">tee_ioctl_shm_alloc_data</span><span class="w"> </span><span class="n">ioc_alloc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">};</span>
<span class="kt">int</span><span class="w"> </span><span class="n">memfd</span><span class="p">;</span>
<span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">shm</span><span class="p">;</span>
<span class="n">ioc_alloc</span><span class="p">.</span><span class="n">size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1024</span><span class="p">;</span>
<span class="n">memfd</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ioctl</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span><span class="w"> </span><span class="n">TEE_IOC_SHM_ALLOC</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">long</span><span class="p">)</span><span class="o">&amp;</span><span class="n">ioc_alloc</span><span class="p">);</span>
<span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">memfd</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">memfd</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="n">shm</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">mmap</span><span class="p">(</span><span class="nb">NULL</span><span class="p">,</span><span class="w"> </span><span class="n">ioc_alloc</span><span class="p">.</span><span class="n">size</span><span class="p">,</span><span class="w"> </span><span class="n">PROT_READ</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">PROT_WRITE</span><span class="p">,</span><span class="w"> </span><span class="n">MAP_SHARED</span><span class="p">,</span>
<span class="w"> </span><span class="n">memfd</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
<span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">shm</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">MAP_FAILED</span><span class="p">)</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">close</span><span class="p">(</span><span class="n">memfd</span><span class="p">);</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="o">-</span><span class="n">ENOMEM</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
</pre></div>
</div>
</li>
<li><p>Register shared memory with the driver and the secure OS</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/* The following will fail if TEE_GEN_CAP_REG_MEM is not reported in</span>
<span class="cm"> * the returned `ioc_ver.gen_caps` in step 1 above</span>
<span class="cm"> * Note: user memory used does not have to be allocated through IOCTL</span>
<span class="cm"> */</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">tee_ioctl_shm_register_data</span><span class="w"> </span><span class="n">ioc_reg</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">};</span>
<span class="n">ioc_reg</span><span class="p">.</span><span class="n">addr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="kt">uintptr_t</span><span class="p">)</span><span class="o">&lt;</span><span class="n">some</span><span class="w"> </span><span class="n">user</span><span class="w"> </span><span class="n">memory</span><span class="w"> </span><span class="n">ptr</span><span class="o">&gt;</span><span class="p">;</span>
<span class="n">ioc_reg</span><span class="p">.</span><span class="n">length</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&lt;</span><span class="n">user</span><span class="w"> </span><span class="n">memory</span><span class="w"> </span><span class="n">size</span><span class="o">&gt;</span><span class="p">;</span>
<span class="n">memfd</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ioctl</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span><span class="w"> </span><span class="n">TEE_IOC_SHM_REGISTER</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">long</span><span class="p">)</span><span class="o">&amp;</span><span class="n">ioc_reg</span><span class="p">);</span>
<span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">memfd</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">ret</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="cm">/* use ioc_reg.id returned in OP-TEE parameters (e.g. open, invoke) */</span>
<span class="n">close</span><span class="p">(</span><span class="n">memfd</span><span class="p">);</span>
</pre></div>
</div>
</li>
<li><p>Use the registered shared memory in an invocation</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">const</span><span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">num_params</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">tee_ioctl_invoke_arg</span><span class="w"> </span><span class="o">*</span><span class="n">ioc_args</span><span class="p">;</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">tee_ioctl_buf_data</span><span class="w"> </span><span class="n">ioc_buf</span><span class="p">;</span>
<span class="kt">size_t</span><span class="w"> </span><span class="n">ioc_args_len</span><span class="p">;</span>
<span class="n">ioc_args_len</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">sizeof</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">tee_ioctl_invoke_arg</span><span class="p">)</span><span class="w"> </span><span class="o">+</span>
<span class="w"> </span><span class="n">TEE_IOCTL_PARAM_SIZE</span><span class="p">(</span><span class="n">num_params</span><span class="p">);</span>
<span class="n">ioc_args</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">tee_ioctl_invoke_arg</span><span class="w"> </span><span class="o">*</span><span class="p">)</span><span class="n">calloc</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">ioc_args_len</span><span class="p">);</span>
<span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">ioc_args</span><span class="p">)</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="o">-</span><span class="n">ENOMEM</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="n">ioc_args</span><span class="o">-&gt;</span><span class="n">func</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&lt;</span><span class="n">SOME_FUNCTION_ID</span><span class="o">&gt;</span><span class="p">;</span>
<span class="n">ioc_args</span><span class="o">-&gt;</span><span class="n">session</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ioc_opn</span><span class="p">.</span><span class="n">session</span><span class="p">;</span>
<span class="n">ioc_args</span><span class="o">-&gt;</span><span class="n">num_params</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">num_params</span><span class="p">;</span>
<span class="n">ioc_args</span><span class="o">-&gt;</span><span class="n">params</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">attr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT</span><span class="p">;</span>
<span class="n">ioc_args</span><span class="o">-&gt;</span><span class="n">params</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="n">ioc_args</span><span class="o">-&gt;</span><span class="n">params</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">b</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ioc_reg</span><span class="p">.</span><span class="n">length</span><span class="p">;</span>
<span class="n">ioc_args</span><span class="o">-&gt;</span><span class="n">params</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ioc_reg</span><span class="p">.</span><span class="n">id</span><span class="p">;</span>
<span class="n">ioc_buf</span><span class="p">.</span><span class="n">buf_ptr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="kt">uintptr_t</span><span class="p">)</span><span class="n">ioc_args</span><span class="p">;</span>
<span class="n">ioc_buf</span><span class="p">.</span><span class="n">buf_len</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ioc_args_len</span><span class="p">;</span>
<span class="n">ret</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ioctl</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span><span class="w"> </span><span class="n">TEE_IOC_INVOKE</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">long</span><span class="p">)</span><span class="o">&amp;</span><span class="n">ioc_buf</span><span class="p">);</span>
<span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">ret</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">goto</span><span class="w"> </span><span class="n">err_with_args</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="cm">/* use result (if any) in ioc_args-&gt;params */</span>
</pre></div>
</div>
</li>
<li><p>OP-TEE secure storage support through TEE supplicant</p>
<div class="highlight-shell notranslate"><div class="highlight"><pre><span></span>optee_supplicant<span class="w"> </span>-f<span class="w"> </span>/data/tee<span class="w"> </span>&gt;<span class="w"> </span>/dev/null<span class="w"> </span><span class="p">&amp;</span>
</pre></div>
</div>
</li>
</ol>
<p>This runs the OP-TEE supplicant in the background, using <code class="docutils literal notranslate"><span class="pre">/data/tee</span></code> as the
directory for the TEE file system. Output is redirected to <code class="docutils literal notranslate"><span class="pre">/dev/null</span></code> to
suppress standard output. Make sure that the userspace support for the
supplicant is enabled and that <code class="docutils literal notranslate"><span class="pre">/data</span></code> is mounted as read/write.</p>
<p>With the supplicant running, secure storage objects can be created, retrieved,
and managed by Trusted Applications (TAs). In a typical workflow, a Client
Application (CA) running on NuttX invokes a command in a TA that may need to
read from or create persistent objects. In such cases, certain RPCs generated
by OP-TEE are routed from the CA to the TEE supplicant for handling (provided
the supplicant is running in the background). Once the supplicant has processed
the request, it responds using <code class="docutils literal notranslate"><span class="pre">TEE_IOC_SUPPL_SEND</span></code>, and the kernel driver
delivers this response back to the CA in its context.</p>
<ol class="arabic simple">
<li><p>OP-TEE REE time request</p></li>
</ol>
<p>In this scenario, the userspace supplicant isn’t needed, as the response can be
handled directly by the kernel driver.</p>
<p>An OP-TEE application can request the current time from the NuttX clock using:</p>
<blockquote>
<div><div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">TEE_GetREETime</span><span class="p">(</span><span class="o">&amp;</span><span class="n">t</span><span class="p">);</span>
</pre></div>
</div>
</div></blockquote>
<p>The NuttX kernel driver will respond to the TA with the <code class="docutils literal notranslate"><span class="pre">CLOCK_REALTIME</span></code>
which represents the machine’s best-guess as to the current wall-clock.</p>
</section>
</section>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="rust.html" class="btn btn-neutral float-left" title="Rust in NuttX" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="../standards/index.html" class="btn btn-neutral float-right" title="Standards" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>&#169; Copyright 2023, The Apache Software Foundation.</p>
</div>
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>