| <!-- |
| 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 — 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 -> 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"><stdio.h></span> |
| <span class="cp">#include</span><span class="w"> </span><span class="cpf"><stdlib.h></span> |
| <span class="cp">#include</span><span class="w"> </span><span class="cpf"><fcntl.h></span> |
| <span class="cp">#include</span><span class="w"> </span><span class="cpf"><unistd.h></span> |
| <span class="cp">#include</span><span class="w"> </span><span class="cpf"><errno.h></span> |
| <span class="cp">#include</span><span class="w"> </span><span class="cpf"><sys/ioctl.h></span> |
| <span class="cp">#include</span><span class="w"> </span><span class="cpf"><nuttx/tee.h></span> |
| <span class="cp">#include</span><span class="w"> </span><span class="cpf"><uuid.h></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">"/dev/tee0"</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">&</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"><</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">"Failed to query TEE driver version and caps: %d, %s</span><span class="se">\n</span><span class="s">"</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">&</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">&</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">&</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"><</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">-></span><span class="n">func</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o"><</span><span class="n">SOME_FUNCTION_ID</span><span class="o">></span><span class="p">;</span> |
| <span class="n">ioc_args</span><span class="o">-></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">-></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">-></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">&</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"><</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->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">&</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"><</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"><</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">></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"><</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">></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">&</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"><</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">-></span><span class="n">func</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o"><</span><span class="n">SOME_FUNCTION_ID</span><span class="o">></span><span class="p">;</span> |
| <span class="n">ioc_args</span><span class="o">-></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">-></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">-></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">-></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">-></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">-></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">&</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"><</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->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>><span class="w"> </span>/dev/null<span class="w"> </span><span class="p">&</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">&</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>© Copyright 2023, The Apache Software Foundation.</p> |
| </div> |
| |
| |
| |
| </footer> |
| </div> |
| </div> |
| </section> |
| </div> |
| <script> |
| jQuery(function () { |
| SphinxRtdTheme.Navigation.enable(true); |
| }); |
| </script> |
| |
| </body> |
| </html> |